1 static UINT8 I386OP(shift_rotate8)(i386_state *cpustate, UINT8 modrm, UINT32 value, UINT8 shift)
3 UINT32 src = value & 0xff;
7 CYCLES_RM(cpustate,modrm, 3, 7);
8 } else if( shift == 1 ) {
9 switch( (modrm >> 3) & 0x7 )
11 case 0: /* ROL rm8, 1 */
12 cpustate->CF = (src & 0x80) ? 1 : 0;
13 dst = (src << 1) + cpustate->CF;
14 cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
15 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
17 case 1: /* ROR rm8, 1 */
18 cpustate->CF = (src & 0x1) ? 1 : 0;
19 dst = (cpustate->CF << 7) | (src >> 1);
20 cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
21 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
23 case 2: /* RCL rm8, 1 */
24 dst = (src << 1) + cpustate->CF;
25 cpustate->CF = (src & 0x80) ? 1 : 0;
26 cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
27 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
29 case 3: /* RCR rm8, 1 */
30 dst = (cpustate->CF << 7) | (src >> 1);
31 cpustate->CF = src & 0x1;
32 cpustate->OF = ((src ^ dst) & 0x80) ? 1 : 0;
33 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
35 case 4: /* SHL/SAL rm8, 1 */
38 cpustate->CF = (src & 0x80) ? 1 : 0;
39 cpustate->OF = (((cpustate->CF << 7) ^ dst) & 0x80) ? 1 : 0;
41 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
43 case 5: /* SHR rm8, 1 */
45 cpustate->CF = src & 0x1;
46 cpustate->OF = (dst & 0x80) ? 1 : 0;
48 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
50 case 7: /* SAR rm8, 1 */
51 dst = (INT8)(src) >> 1;
52 cpustate->CF = src & 0x1;
55 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
60 switch( (modrm >> 3) & 0x7 )
62 case 0: /* ROL rm8, i8 */
67 cpustate->CF = src & 1;
68 cpustate->OF = (src & 1) ^ ((src >> 7) & 1);
73 dst = ((src & ((UINT8)0xff >> shift)) << shift) |
74 ((src & ((UINT8)0xff << (8-shift))) >> (8-shift));
75 cpustate->CF = dst & 0x1;
76 cpustate->OF = (dst & 1) ^ (dst >> 7);
77 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
79 case 1: /* ROR rm8, i8 */
84 cpustate->CF = (src >> 7) & 1;
85 cpustate->OF = ((src >> 7) & 1) ^ ((src >> 6) & 1);
90 dst = ((src & ((UINT8)0xff << shift)) >> shift) |
91 ((src & ((UINT8)0xff >> (8-shift))) << (8-shift));
92 cpustate->CF = (dst >> 7) & 1;
93 cpustate->OF = ((dst >> 7) ^ (dst >> 6)) & 1;
94 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
96 case 2: /* RCL rm8, i8 */
98 dst = ((src & ((UINT8)0xff >> shift)) << shift) |
99 ((src & ((UINT8)0xff << (9-shift))) >> (9-shift)) |
100 (cpustate->CF << (shift-1));
101 if(shift) cpustate->CF = (src >> (8-shift)) & 0x1;
102 cpustate->OF = cpustate->CF ^ ((dst >> 7) & 1);
103 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
105 case 3: /* RCR rm8, i8 */
107 dst = ((src & ((UINT8)0xff << shift)) >> shift) |
108 ((src & ((UINT8)0xff >> (8-shift))) << (9-shift)) |
109 (cpustate->CF << (8-shift));
110 if(shift) cpustate->CF = (src >> (shift-1)) & 0x1;
111 cpustate->OF = ((dst >> 7) ^ (dst >> 6)) & 1;
112 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM);
114 case 4: /* SHL/SAL rm8, i8 */
118 cpustate->CF = (shift <= 8) && ((src >> (8 - shift)) & 1);
120 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
122 case 5: /* SHR rm8, i8 */
125 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
127 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
129 case 7: /* SAR rm8, i8 */
131 dst = (INT8)src >> shift;
132 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
134 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
144 static void I386OP(adc_rm8_r8)(i386_state *cpustate) // Opcode 0x10
147 UINT8 modrm = FETCH(cpustate);
148 if( modrm >= 0xc0 ) {
149 src = LOAD_REG8(modrm);
150 dst = LOAD_RM8(modrm);
151 dst = ADC8(cpustate, dst, src, cpustate->CF);
152 STORE_RM8(modrm, dst);
153 CYCLES(cpustate,CYCLES_ALU_REG_REG);
155 UINT32 ea = GetEA(cpustate,modrm,1);
156 src = LOAD_REG8(modrm);
157 dst = READ8(cpustate,ea);
158 dst = ADC8(cpustate, dst, src, cpustate->CF);
159 WRITE8(cpustate,ea, dst);
160 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
164 static void I386OP(adc_r8_rm8)(i386_state *cpustate) // Opcode 0x12
167 UINT8 modrm = FETCH(cpustate);
168 if( modrm >= 0xc0 ) {
169 src = LOAD_RM8(modrm);
170 dst = LOAD_REG8(modrm);
171 dst = ADC8(cpustate, dst, src, cpustate->CF);
172 STORE_REG8(modrm, dst);
173 CYCLES(cpustate,CYCLES_ALU_REG_REG);
175 UINT32 ea = GetEA(cpustate,modrm,0);
176 src = READ8(cpustate,ea);
177 dst = LOAD_REG8(modrm);
178 dst = ADC8(cpustate, dst, src, cpustate->CF);
179 STORE_REG8(modrm, dst);
180 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
184 static void I386OP(adc_al_i8)(i386_state *cpustate) // Opcode 0x14
187 src = FETCH(cpustate);
189 dst = ADC8(cpustate, dst, src, cpustate->CF);
191 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
194 static void I386OP(add_rm8_r8)(i386_state *cpustate) // Opcode 0x00
197 UINT8 modrm = FETCH(cpustate);
198 if( modrm >= 0xc0 ) {
199 src = LOAD_REG8(modrm);
200 dst = LOAD_RM8(modrm);
201 dst = ADD8(cpustate,dst, src);
202 STORE_RM8(modrm, dst);
203 CYCLES(cpustate,CYCLES_ALU_REG_REG);
205 UINT32 ea = GetEA(cpustate,modrm,1);
206 src = LOAD_REG8(modrm);
207 dst = READ8(cpustate,ea);
208 dst = ADD8(cpustate,dst, src);
209 WRITE8(cpustate,ea, dst);
210 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
214 static void I386OP(add_r8_rm8)(i386_state *cpustate) // Opcode 0x02
217 UINT8 modrm = FETCH(cpustate);
218 if( modrm >= 0xc0 ) {
219 src = LOAD_RM8(modrm);
220 dst = LOAD_REG8(modrm);
221 dst = ADD8(cpustate,dst, src);
222 STORE_REG8(modrm, dst);
223 CYCLES(cpustate,CYCLES_ALU_REG_REG);
225 UINT32 ea = GetEA(cpustate,modrm,0);
226 src = READ8(cpustate,ea);
227 dst = LOAD_REG8(modrm);
228 dst = ADD8(cpustate,dst, src);
229 STORE_REG8(modrm, dst);
230 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
234 static void I386OP(add_al_i8)(i386_state *cpustate) // Opcode 0x04
237 src = FETCH(cpustate);
239 dst = ADD8(cpustate,dst, src);
241 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
244 static void I386OP(and_rm8_r8)(i386_state *cpustate) // Opcode 0x20
247 UINT8 modrm = FETCH(cpustate);
248 if( modrm >= 0xc0 ) {
249 src = LOAD_REG8(modrm);
250 dst = LOAD_RM8(modrm);
251 dst = AND8(cpustate,dst, src);
252 STORE_RM8(modrm, dst);
253 CYCLES(cpustate,CYCLES_ALU_REG_REG);
255 UINT32 ea = GetEA(cpustate,modrm,1);
256 src = LOAD_REG8(modrm);
257 dst = READ8(cpustate,ea);
258 dst = AND8(cpustate,dst, src);
259 WRITE8(cpustate,ea, dst);
260 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
264 static void I386OP(and_r8_rm8)(i386_state *cpustate) // Opcode 0x22
267 UINT8 modrm = FETCH(cpustate);
268 if( modrm >= 0xc0 ) {
269 src = LOAD_RM8(modrm);
270 dst = LOAD_REG8(modrm);
271 dst = AND8(cpustate,dst, src);
272 STORE_REG8(modrm, dst);
273 CYCLES(cpustate,CYCLES_ALU_REG_REG);
275 UINT32 ea = GetEA(cpustate,modrm,0);
276 src = READ8(cpustate,ea);
277 dst = LOAD_REG8(modrm);
278 dst = AND8(cpustate,dst, src);
279 STORE_REG8(modrm, dst);
280 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
284 static void I386OP(and_al_i8)(i386_state *cpustate) // Opcode 0x24
287 src = FETCH(cpustate);
289 dst = AND8(cpustate,dst, src);
291 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
294 static void I386OP(clc)(i386_state *cpustate) // Opcode 0xf8
297 CYCLES(cpustate,CYCLES_CLC);
300 static void I386OP(cld)(i386_state *cpustate) // Opcode 0xfc
303 CYCLES(cpustate,CYCLES_CLD);
306 static void I386OP(cli)(i386_state *cpustate) // Opcode 0xfa
310 UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
311 if(cpustate->CPL > IOPL)
315 CYCLES(cpustate,CYCLES_CLI);
318 static void I386OP(cmc)(i386_state *cpustate) // Opcode 0xf5
321 CYCLES(cpustate,CYCLES_CMC);
324 static void I386OP(cmp_rm8_r8)(i386_state *cpustate) // Opcode 0x38
327 UINT8 modrm = FETCH(cpustate);
328 if( modrm >= 0xc0 ) {
329 src = LOAD_REG8(modrm);
330 dst = LOAD_RM8(modrm);
331 SUB8(cpustate,dst, src);
332 CYCLES(cpustate,CYCLES_CMP_REG_REG);
334 UINT32 ea = GetEA(cpustate,modrm,0);
335 src = LOAD_REG8(modrm);
336 dst = READ8(cpustate,ea);
337 SUB8(cpustate,dst, src);
338 CYCLES(cpustate,CYCLES_CMP_REG_MEM);
342 static void I386OP(cmp_r8_rm8)(i386_state *cpustate) // Opcode 0x3a
345 UINT8 modrm = FETCH(cpustate);
346 if( modrm >= 0xc0 ) {
347 src = LOAD_RM8(modrm);
348 dst = LOAD_REG8(modrm);
349 SUB8(cpustate,dst, src);
350 CYCLES(cpustate,CYCLES_CMP_REG_REG);
352 UINT32 ea = GetEA(cpustate,modrm,0);
353 src = READ8(cpustate,ea);
354 dst = LOAD_REG8(modrm);
355 SUB8(cpustate,dst, src);
356 CYCLES(cpustate,CYCLES_CMP_MEM_REG);
360 static void I386OP(cmp_al_i8)(i386_state *cpustate) // Opcode 0x3c
363 src = FETCH(cpustate);
365 SUB8(cpustate,dst, src);
366 CYCLES(cpustate,CYCLES_CMP_IMM_ACC);
369 static void I386OP(cmpsb)(i386_state *cpustate) // Opcode 0xa6
373 if( cpustate->segment_prefix ) {
374 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
376 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
378 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
379 src = READ8(cpustate,eas);
380 dst = READ8(cpustate,ead);
381 SUB8(cpustate,src, dst);
384 CYCLES(cpustate,CYCLES_CMPS);
387 static void I386OP(in_al_i8)(i386_state *cpustate) // Opcode 0xe4
389 UINT16 port = FETCH(cpustate);
390 UINT8 data = READPORT8(cpustate, port);
392 CYCLES(cpustate,CYCLES_IN_VAR);
395 static void I386OP(in_al_dx)(i386_state *cpustate) // Opcode 0xec
397 UINT16 port = REG16(DX);
398 UINT8 data = READPORT8(cpustate, port);
400 CYCLES(cpustate,CYCLES_IN);
403 static void I386OP(ja_rel8)(i386_state *cpustate) // Opcode 0x77
405 INT8 disp = FETCH(cpustate);
406 if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
407 NEAR_BRANCH(cpustate,disp);
408 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
410 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
414 static void I386OP(jbe_rel8)(i386_state *cpustate) // Opcode 0x76
416 INT8 disp = FETCH(cpustate);
417 if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
418 NEAR_BRANCH(cpustate,disp);
419 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
421 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
425 static void I386OP(jc_rel8)(i386_state *cpustate) // Opcode 0x72
427 INT8 disp = FETCH(cpustate);
428 if( cpustate->CF != 0 ) {
429 NEAR_BRANCH(cpustate,disp);
430 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
432 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
436 static void I386OP(jg_rel8)(i386_state *cpustate) // Opcode 0x7f
438 INT8 disp = FETCH(cpustate);
439 if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
440 NEAR_BRANCH(cpustate,disp);
441 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
443 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
447 static void I386OP(jge_rel8)(i386_state *cpustate) // Opcode 0x7d
449 INT8 disp = FETCH(cpustate);
450 if(cpustate->SF == cpustate->OF) {
451 NEAR_BRANCH(cpustate,disp);
452 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
454 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
458 static void I386OP(jl_rel8)(i386_state *cpustate) // Opcode 0x7c
460 INT8 disp = FETCH(cpustate);
461 if( (cpustate->SF != cpustate->OF) ) {
462 NEAR_BRANCH(cpustate,disp);
463 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
465 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
469 static void I386OP(jle_rel8)(i386_state *cpustate) // Opcode 0x7e
471 INT8 disp = FETCH(cpustate);
472 if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
473 NEAR_BRANCH(cpustate,disp);
474 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
476 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
480 static void I386OP(jnc_rel8)(i386_state *cpustate) // Opcode 0x73
482 INT8 disp = FETCH(cpustate);
483 if( cpustate->CF == 0 ) {
484 NEAR_BRANCH(cpustate,disp);
485 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
487 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
491 static void I386OP(jno_rel8)(i386_state *cpustate) // Opcode 0x71
493 INT8 disp = FETCH(cpustate);
494 if( cpustate->OF == 0 ) {
495 NEAR_BRANCH(cpustate,disp);
496 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
498 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
502 static void I386OP(jnp_rel8)(i386_state *cpustate) // Opcode 0x7b
504 INT8 disp = FETCH(cpustate);
505 if( cpustate->PF == 0 ) {
506 NEAR_BRANCH(cpustate,disp);
507 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
509 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
513 static void I386OP(jns_rel8)(i386_state *cpustate) // Opcode 0x79
515 INT8 disp = FETCH(cpustate);
516 if( cpustate->SF == 0 ) {
517 NEAR_BRANCH(cpustate,disp);
518 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
520 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
524 static void I386OP(jnz_rel8)(i386_state *cpustate) // Opcode 0x75
526 INT8 disp = FETCH(cpustate);
527 if( cpustate->ZF == 0 ) {
528 NEAR_BRANCH(cpustate,disp);
529 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
531 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
535 static void I386OP(jo_rel8)(i386_state *cpustate) // Opcode 0x70
537 INT8 disp = FETCH(cpustate);
538 if( cpustate->OF != 0 ) {
539 NEAR_BRANCH(cpustate,disp);
540 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
542 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
546 static void I386OP(jp_rel8)(i386_state *cpustate) // Opcode 0x7a
548 INT8 disp = FETCH(cpustate);
549 if( cpustate->PF != 0 ) {
550 NEAR_BRANCH(cpustate,disp);
551 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
553 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
557 static void I386OP(js_rel8)(i386_state *cpustate) // Opcode 0x78
559 INT8 disp = FETCH(cpustate);
560 if( cpustate->SF != 0 ) {
561 NEAR_BRANCH(cpustate,disp);
562 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
564 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
568 static void I386OP(jz_rel8)(i386_state *cpustate) // Opcode 0x74
570 INT8 disp = FETCH(cpustate);
571 if( cpustate->ZF != 0 ) {
572 NEAR_BRANCH(cpustate,disp);
573 CYCLES(cpustate,CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */
575 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
579 static void I386OP(jmp_rel8)(i386_state *cpustate) // Opcode 0xeb
581 INT8 disp = FETCH(cpustate);
582 NEAR_BRANCH(cpustate,disp);
583 CYCLES(cpustate,CYCLES_JMP_SHORT); /* TODO: Timing = 7 + m */
586 static void I386OP(lahf)(i386_state *cpustate) // Opcode 0x9f
588 REG8(AH) = get_flags(cpustate) & 0xd7;
589 CYCLES(cpustate,CYCLES_LAHF);
592 static void I386OP(lodsb)(i386_state *cpustate) // Opcode 0xac
595 if( cpustate->segment_prefix ) {
596 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
598 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
600 REG8(AL) = READ8(cpustate,eas);
602 CYCLES(cpustate,CYCLES_LODS);
605 static void I386OP(mov_rm8_r8)(i386_state *cpustate) // Opcode 0x88
608 UINT8 modrm = FETCH(cpustate);
609 if( modrm >= 0xc0 ) {
610 src = LOAD_REG8(modrm);
611 STORE_RM8(modrm, src);
612 CYCLES(cpustate,CYCLES_MOV_REG_REG);
614 UINT32 ea = GetEA(cpustate,modrm,1);
615 src = LOAD_REG8(modrm);
616 WRITE8(cpustate,ea, src);
617 CYCLES(cpustate,CYCLES_MOV_REG_MEM);
621 static void I386OP(mov_r8_rm8)(i386_state *cpustate) // Opcode 0x8a
624 UINT8 modrm = FETCH(cpustate);
625 if( modrm >= 0xc0 ) {
626 src = LOAD_RM8(modrm);
627 STORE_REG8(modrm, src);
628 CYCLES(cpustate,CYCLES_MOV_REG_REG);
630 UINT32 ea = GetEA(cpustate,modrm,0);
631 src = READ8(cpustate,ea);
632 STORE_REG8(modrm, src);
633 CYCLES(cpustate,CYCLES_MOV_MEM_REG);
637 static void I386OP(mov_rm8_i8)(i386_state *cpustate) // Opcode 0xc6
639 UINT8 modrm = FETCH(cpustate);
640 if( modrm >= 0xc0 ) {
641 UINT8 value = FETCH(cpustate);
642 STORE_RM8(modrm, value);
643 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
645 UINT32 ea = GetEA(cpustate,modrm,1);
646 UINT8 value = FETCH(cpustate);
647 WRITE8(cpustate,ea, value);
648 CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
652 static void I386OP(mov_r32_cr)(i386_state *cpustate) // Opcode 0x0f 20
654 if(PROTECTED_MODE && cpustate->CPL)
656 UINT8 modrm = FETCH(cpustate);
657 UINT8 cr = (modrm >> 3) & 0x7;
659 STORE_RM32(modrm, cpustate->cr[cr]);
660 CYCLES(cpustate,CYCLES_MOV_CR_REG);
663 static void I386OP(mov_r32_dr)(i386_state *cpustate) // Opcode 0x0f 21
665 if(PROTECTED_MODE && cpustate->CPL)
667 UINT8 modrm = FETCH(cpustate);
668 UINT8 dr = (modrm >> 3) & 0x7;
670 STORE_RM32(modrm, cpustate->dr[dr]);
677 CYCLES(cpustate,CYCLES_MOV_REG_DR0_3);
681 CYCLES(cpustate,CYCLES_MOV_REG_DR6_7);
686 static void I386OP(mov_cr_r32)(i386_state *cpustate) // Opcode 0x0f 22
688 if(PROTECTED_MODE && cpustate->CPL)
690 UINT8 modrm = FETCH(cpustate);
691 UINT8 cr = (modrm >> 3) & 0x7;
692 UINT32 data = LOAD_RM32(modrm);
696 data &= 0xfffeffff; // wp not supported on 386
697 CYCLES(cpustate,CYCLES_MOV_REG_CR0);
699 case 2: CYCLES(cpustate,CYCLES_MOV_REG_CR2); break;
701 CYCLES(cpustate,CYCLES_MOV_REG_CR3);
702 vtlb_flush_dynamic(cpustate->vtlb);
704 case 4: CYCLES(cpustate,1); break; // TODO
706 logerror("i386: mov_cr_r32 CR%d!\n", cr);
709 cpustate->cr[cr] = data;
712 static void I386OP(mov_dr_r32)(i386_state *cpustate) // Opcode 0x0f 23
714 if(PROTECTED_MODE && cpustate->CPL)
716 UINT8 modrm = FETCH(cpustate);
717 UINT8 dr = (modrm >> 3) & 0x7;
719 cpustate->dr[dr] = LOAD_RM32(modrm);
726 CYCLES(cpustate,CYCLES_MOV_DR0_3_REG);
730 CYCLES(cpustate,CYCLES_MOV_DR6_7_REG);
733 logerror("i386: mov_dr_r32 DR%d!\n", dr);
738 static void I386OP(mov_al_m8)(i386_state *cpustate) // Opcode 0xa0
741 if( cpustate->address_size ) {
742 offset = FETCH32(cpustate);
744 offset = FETCH16(cpustate);
746 /* TODO: Not sure if this is correct... */
747 if( cpustate->segment_prefix ) {
748 ea = i386_translate(cpustate, cpustate->segment_override, offset, 0 );
750 ea = i386_translate(cpustate, DS, offset, 0 );
752 REG8(AL) = READ8(cpustate,ea);
753 CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
756 static void I386OP(mov_m8_al)(i386_state *cpustate) // Opcode 0xa2
759 if( cpustate->address_size ) {
760 offset = FETCH32(cpustate);
762 offset = FETCH16(cpustate);
764 /* TODO: Not sure if this is correct... */
765 if( cpustate->segment_prefix ) {
766 ea = i386_translate(cpustate, cpustate->segment_override, offset, 1 );
768 ea = i386_translate(cpustate, DS, offset, 1 );
770 WRITE8(cpustate, ea, REG8(AL) );
771 CYCLES(cpustate,CYCLES_MOV_MEM_ACC);
774 static void I386OP(mov_rm16_sreg)(i386_state *cpustate) // Opcode 0x8c
776 UINT8 modrm = FETCH(cpustate);
777 int s = (modrm >> 3) & 0x7;
779 if( modrm >= 0xc0 ) {
780 if(cpustate->operand_size)
781 STORE_RM32(modrm, cpustate->sreg[s].selector);
783 STORE_RM16(modrm, cpustate->sreg[s].selector);
784 CYCLES(cpustate,CYCLES_MOV_SREG_REG);
786 UINT32 ea = GetEA(cpustate,modrm,1);
787 WRITE16(cpustate,ea, cpustate->sreg[s].selector);
788 CYCLES(cpustate,CYCLES_MOV_SREG_MEM);
792 static void I386OP(mov_sreg_rm16)(i386_state *cpustate) // Opcode 0x8e
795 UINT8 modrm = FETCH(cpustate);
797 int s = (modrm >> 3) & 0x7;
799 if( modrm >= 0xc0 ) {
800 selector = LOAD_RM16(modrm);
801 CYCLES(cpustate,CYCLES_MOV_REG_SREG);
803 UINT32 ea = GetEA(cpustate,modrm,0);
804 selector = READ16(cpustate,ea);
805 CYCLES(cpustate,CYCLES_MOV_MEM_SREG);
808 i386_sreg_load(cpustate,selector,s,&fault);
809 if((s == SS) && !fault)
811 if(cpustate->IF != 0) // if external interrupts are enabled
813 cpustate->IF = 0; // reset IF for the next instruction
814 cpustate->delayed_interrupt_enable = 1;
819 static void I386OP(mov_al_i8)(i386_state *cpustate) // Opcode 0xb0
821 REG8(AL) = FETCH(cpustate);
822 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
825 static void I386OP(mov_cl_i8)(i386_state *cpustate) // Opcode 0xb1
827 REG8(CL) = FETCH(cpustate);
828 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
831 static void I386OP(mov_dl_i8)(i386_state *cpustate) // Opcode 0xb2
833 REG8(DL) = FETCH(cpustate);
834 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
837 static void I386OP(mov_bl_i8)(i386_state *cpustate) // Opcode 0xb3
839 REG8(BL) = FETCH(cpustate);
840 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
843 static void I386OP(mov_ah_i8)(i386_state *cpustate) // Opcode 0xb4
845 REG8(AH) = FETCH(cpustate);
846 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
849 static void I386OP(mov_ch_i8)(i386_state *cpustate) // Opcode 0xb5
851 REG8(CH) = FETCH(cpustate);
852 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
855 static void I386OP(mov_dh_i8)(i386_state *cpustate) // Opcode 0xb6
857 REG8(DH) = FETCH(cpustate);
858 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
861 static void I386OP(mov_bh_i8)(i386_state *cpustate) // Opcode 0xb7
863 REG8(BH) = FETCH(cpustate);
864 CYCLES(cpustate,CYCLES_MOV_IMM_REG);
867 static void I386OP(movsb)(i386_state *cpustate) // Opcode 0xa4
871 if( cpustate->segment_prefix ) {
872 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
874 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
876 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
877 v = READ8(cpustate,eas);
878 WRITE8(cpustate,ead, v);
881 CYCLES(cpustate,CYCLES_MOVS);
884 static void I386OP(or_rm8_r8)(i386_state *cpustate) // Opcode 0x08
887 UINT8 modrm = FETCH(cpustate);
888 if( modrm >= 0xc0 ) {
889 src = LOAD_REG8(modrm);
890 dst = LOAD_RM8(modrm);
891 dst = OR8(cpustate,dst, src);
892 STORE_RM8(modrm, dst);
893 CYCLES(cpustate,CYCLES_ALU_REG_REG);
895 UINT32 ea = GetEA(cpustate,modrm,1);
896 src = LOAD_REG8(modrm);
897 dst = READ8(cpustate,ea);
898 dst = OR8(cpustate,dst, src);
899 WRITE8(cpustate,ea, dst);
900 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
904 static void I386OP(or_r8_rm8)(i386_state *cpustate) // Opcode 0x0a
907 UINT8 modrm = FETCH(cpustate);
908 if( modrm >= 0xc0 ) {
909 src = LOAD_RM8(modrm);
910 dst = LOAD_REG8(modrm);
911 dst = OR8(cpustate,dst, src);
912 STORE_REG8(modrm, dst);
913 CYCLES(cpustate,CYCLES_ALU_REG_REG);
915 UINT32 ea = GetEA(cpustate,modrm,0);
916 src = READ8(cpustate,ea);
917 dst = LOAD_REG8(modrm);
918 dst = OR8(cpustate,dst, src);
919 STORE_REG8(modrm, dst);
920 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
924 static void I386OP(or_al_i8)(i386_state *cpustate) // Opcode 0x0c
927 src = FETCH(cpustate);
929 dst = OR8(cpustate,dst, src);
931 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
934 static void I386OP(out_al_i8)(i386_state *cpustate) // Opcode 0xe6
936 UINT16 port = FETCH(cpustate);
937 UINT8 data = REG8(AL);
938 WRITEPORT8(cpustate, port, data);
939 CYCLES(cpustate,CYCLES_OUT_VAR);
942 static void I386OP(out_al_dx)(i386_state *cpustate) // Opcode 0xee
944 UINT16 port = REG16(DX);
945 UINT8 data = REG8(AL);
946 WRITEPORT8(cpustate, port, data);
947 CYCLES(cpustate,CYCLES_OUT);
951 static void I386OP(arpl)(i386_state *cpustate) // Opcode 0x63
954 UINT8 modrm = FETCH(cpustate);
957 if(PROTECTED_MODE && !V8086_MODE)
959 if( modrm >= 0xc0 ) {
960 src = LOAD_REG16(modrm);
961 dst = LOAD_RM16(modrm);
962 if( (dst&0x3) < (src&0x3) ) {
963 dst = (dst&0xfffc) | (src&0x3);
965 STORE_RM16(modrm, dst);
968 UINT32 ea = GetEA(cpustate, modrm,1);
969 src = LOAD_REG16(modrm);
970 dst = READ16(cpustate, ea);
971 if( (dst&0x3) < (src&0x3) ) {
972 dst = (dst&0xfffc) | (src&0x3);
974 WRITE16(cpustate, ea, dst);
980 i386_trap(cpustate, 6, 0, 0); // invalid opcode in real mode or v8086 mode
983 static void I386OP(push_i8)(i386_state *cpustate) // Opcode 0x6a
985 UINT8 value = FETCH(cpustate);
986 PUSH8(cpustate,value);
987 CYCLES(cpustate,CYCLES_PUSH_IMM);
990 static void I386OP(ins_generic)(i386_state *cpustate, int size)
997 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
1001 vb = READPORT8(cpustate, REG16(DX));
1002 WRITE8(cpustate,ead, vb);
1005 vw = READPORT16(cpustate, REG16(DX));
1006 WRITE16(cpustate,ead, vw);
1009 vd = READPORT32(cpustate, REG16(DX));
1010 WRITE32(cpustate,ead, vd);
1014 if(cpustate->address_size)
1015 REG32(EDI) += ((cpustate->DF) ? -1 : 1) * size;
1017 REG16(DI) += ((cpustate->DF) ? -1 : 1) * size;
1018 CYCLES(cpustate,CYCLES_INS); // TODO: Confirm this value
1021 static void I386OP(insb)(i386_state *cpustate) // Opcode 0x6c
1023 I386OP(ins_generic)(cpustate, 1);
1026 static void I386OP(insw)(i386_state *cpustate) // Opcode 0x6d
1028 I386OP(ins_generic)(cpustate, 2);
1031 static void I386OP(insd)(i386_state *cpustate) // Opcode 0x6d
1033 I386OP(ins_generic)(cpustate, 4);
1036 static void I386OP(outs_generic)(i386_state *cpustate, int size)
1043 if( cpustate->segment_prefix ) {
1044 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
1046 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
1051 vb = READ8(cpustate,eas);
1052 WRITEPORT8(cpustate, REG16(DX), vb);
1055 vw = READ16(cpustate,eas);
1056 WRITEPORT16(cpustate, REG16(DX), vw);
1059 vd = READ32(cpustate,eas);
1060 WRITEPORT32(cpustate, REG16(DX), vd);
1064 if(cpustate->address_size)
1065 REG32(ESI) += ((cpustate->DF) ? -1 : 1) * size;
1067 REG16(SI) += ((cpustate->DF) ? -1 : 1) * size;
1068 CYCLES(cpustate,CYCLES_OUTS); // TODO: Confirm this value
1071 static void I386OP(outsb)(i386_state *cpustate) // Opcode 0x6e
1073 I386OP(outs_generic)(cpustate, 1);
1076 static void I386OP(outsw)(i386_state *cpustate) // Opcode 0x6f
1078 I386OP(outs_generic)(cpustate, 2);
1081 static void I386OP(outsd)(i386_state *cpustate) // Opcode 0x6f
1083 I386OP(outs_generic)(cpustate, 4);
1086 static void I386OP(repeat)(i386_state *cpustate, int invert_flag)
1088 UINT32 repeated_eip = cpustate->eip;
1089 UINT32 repeated_pc = cpustate->pc;
1090 UINT8 opcode; // = FETCH(cpustate);
1093 INT32 cycle_base = 0, cycle_adjustment = 0;
1094 UINT8 prefix_flag=1;
1099 repeated_eip = cpustate->eip;
1100 repeated_pc = cpustate->pc;
1101 opcode = FETCH(cpustate);
1104 if (invert_flag == 0)
1105 I386OP(decode_three_bytef3)(cpustate); // sse f3 0f
1107 I386OP(decode_three_bytef2)(cpustate); // sse f2 0f
1110 cpustate->segment_override=ES;
1111 cpustate->segment_prefix=1;
1114 cpustate->segment_override=CS;
1115 cpustate->segment_prefix=1;
1118 cpustate->segment_override=SS;
1119 cpustate->segment_prefix=1;
1122 cpustate->segment_override=DS;
1123 cpustate->segment_prefix=1;
1126 cpustate->segment_override=FS;
1127 cpustate->segment_prefix=1;
1130 cpustate->segment_override=GS;
1131 cpustate->segment_prefix=1;
1134 cpustate->operand_size ^= 1;
1135 cpustate->xmm_operand_size ^= 1;
1138 cpustate->address_size ^= 1;
1143 } while (prefix_flag);
1146 if( cpustate->segment_prefix ) {
1147 // FIXME: the following does not work if both address override and segment override are used
1148 i386_translate(cpustate, cpustate->segment_override, cpustate->sreg[cpustate->segment_prefix].d ? REG32(ESI) : REG16(SI), -1 );
1151 i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), -1 );
1153 i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), -1 );
1159 /* INSB, INSW, INSD */
1160 // TODO: cycle count
1162 cycle_adjustment = -4;
1168 /* OUTSB, OUTSW, OUTSD */
1169 // TODO: cycle count
1171 cycle_adjustment = -4;
1177 /* MOVSB, MOVSW, MOVSD */
1179 cycle_adjustment = -4;
1185 /* CMPSB, CMPSW, CMPSD */
1187 cycle_adjustment = -1;
1188 flag = &cpustate->ZF;
1193 /* LODSB, LODSW, LODSD */
1195 cycle_adjustment = 1;
1201 /* STOSB, STOSW, STOSD */
1203 cycle_adjustment = 0;
1209 /* SCASB, SCASW, SCASD */
1211 cycle_adjustment = 0;
1212 flag = &cpustate->ZF;
1216 CYCLES(cpustate,CYCLES_NOP);
1225 fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
1229 if( cpustate->address_size ) {
1230 if( REG32(ECX) == 0 )
1233 if( REG16(CX) == 0 )
1237 /* now actually perform the repeat */
1238 CYCLES_NUM(cycle_base);
1241 cpustate->eip = repeated_eip;
1242 cpustate->pc = repeated_pc;
1245 I386OP(decode_opcode)(cpustate);
1249 cpustate->eip = cpustate->prev_eip;
1253 CYCLES_NUM(cycle_adjustment);
1255 if (cpustate->address_size)
1256 count = --REG32(ECX);
1258 count = --REG16(CX);
1259 if (cpustate->cycles <= 0)
1262 while( count && (!flag || (invert_flag ? !*flag : *flag)) );
1266 /* if we run out of cycles to execute, and we are still in the repeat, we need
1267 * to exit this instruction in such a way to go right back into it when we have
1268 * time to execute cycles */
1269 if(flag && (invert_flag ? *flag : !*flag))
1271 cpustate->eip = cpustate->prev_eip;
1272 CHANGE_PC(cpustate,cpustate->eip);
1273 CYCLES_NUM(-cycle_base);
1276 static void I386OP(rep)(i386_state *cpustate) // Opcode 0xf3
1278 I386OP(repeat)(cpustate, 0);
1281 static void I386OP(repne)(i386_state *cpustate) // Opcode 0xf2
1283 I386OP(repeat)(cpustate, 1);
1286 static void I386OP(sahf)(i386_state *cpustate) // Opcode 0x9e
1288 set_flags(cpustate, (get_flags(cpustate) & 0xffffff00) | (REG8(AH) & 0xd7) );
1289 CYCLES(cpustate,CYCLES_SAHF);
1292 static void I386OP(sbb_rm8_r8)(i386_state *cpustate) // Opcode 0x18
1295 UINT8 modrm = FETCH(cpustate);
1296 if( modrm >= 0xc0 ) {
1297 src = LOAD_REG8(modrm);
1298 dst = LOAD_RM8(modrm);
1299 dst = SBB8(cpustate, dst, src, cpustate->CF);
1300 STORE_RM8(modrm, dst);
1301 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1303 UINT32 ea = GetEA(cpustate,modrm,1);
1304 src = LOAD_REG8(modrm);
1305 dst = READ8(cpustate,ea);
1306 dst = SBB8(cpustate, dst, src, cpustate->CF);
1307 WRITE8(cpustate,ea, dst);
1308 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1312 static void I386OP(sbb_r8_rm8)(i386_state *cpustate) // Opcode 0x1a
1315 UINT8 modrm = FETCH(cpustate);
1316 if( modrm >= 0xc0 ) {
1317 src = LOAD_RM8(modrm);
1318 dst = LOAD_REG8(modrm);
1319 dst = SBB8(cpustate, dst, src, cpustate->CF);
1320 STORE_REG8(modrm, dst);
1321 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1323 UINT32 ea = GetEA(cpustate,modrm,0);
1324 src = READ8(cpustate,ea);
1325 dst = LOAD_REG8(modrm);
1326 dst = SBB8(cpustate, dst, src, cpustate->CF);
1327 STORE_REG8(modrm, dst);
1328 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
1332 static void I386OP(sbb_al_i8)(i386_state *cpustate) // Opcode 0x1c
1335 src = FETCH(cpustate);
1337 dst = SBB8(cpustate, dst, src, cpustate->CF);
1339 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1342 static void I386OP(scasb)(i386_state *cpustate) // Opcode 0xae
1346 eas = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
1347 src = READ8(cpustate,eas);
1349 SUB8(cpustate,dst, src);
1350 BUMP_DI(cpustate,1);
1351 CYCLES(cpustate,CYCLES_SCAS);
1354 static void I386OP(setalc)(i386_state *cpustate) // Opcode 0xd6 (undocumented)
1356 if( cpustate->CF ) {
1364 static void I386OP(seta_rm8)(i386_state *cpustate) // Opcode 0x0f 97
1366 UINT8 modrm = FETCH(cpustate);
1368 if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
1371 if( modrm >= 0xc0 ) {
1372 STORE_RM8(modrm, value);
1373 CYCLES(cpustate,CYCLES_SETCC_REG);
1375 UINT32 ea = GetEA(cpustate,modrm,1);
1376 WRITE8(cpustate,ea, value);
1377 CYCLES(cpustate,CYCLES_SETCC_MEM);
1381 static void I386OP(setbe_rm8)(i386_state *cpustate) // Opcode 0x0f 96
1383 UINT8 modrm = FETCH(cpustate);
1385 if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
1388 if( modrm >= 0xc0 ) {
1389 STORE_RM8(modrm, value);
1390 CYCLES(cpustate,CYCLES_SETCC_REG);
1392 UINT32 ea = GetEA(cpustate,modrm,1);
1393 WRITE8(cpustate,ea, value);
1394 CYCLES(cpustate,CYCLES_SETCC_MEM);
1398 static void I386OP(setc_rm8)(i386_state *cpustate) // Opcode 0x0f 92
1400 UINT8 modrm = FETCH(cpustate);
1402 if( cpustate->CF != 0 ) {
1405 if( modrm >= 0xc0 ) {
1406 STORE_RM8(modrm, value);
1407 CYCLES(cpustate,CYCLES_SETCC_REG);
1409 UINT32 ea = GetEA(cpustate,modrm,1);
1410 WRITE8(cpustate,ea, value);
1411 CYCLES(cpustate,CYCLES_SETCC_MEM);
1415 static void I386OP(setg_rm8)(i386_state *cpustate) // Opcode 0x0f 9f
1417 UINT8 modrm = FETCH(cpustate);
1419 if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
1422 if( modrm >= 0xc0 ) {
1423 STORE_RM8(modrm, value);
1424 CYCLES(cpustate,CYCLES_SETCC_REG);
1426 UINT32 ea = GetEA(cpustate,modrm,1);
1427 WRITE8(cpustate,ea, value);
1428 CYCLES(cpustate,CYCLES_SETCC_MEM);
1432 static void I386OP(setge_rm8)(i386_state *cpustate) // Opcode 0x0f 9d
1434 UINT8 modrm = FETCH(cpustate);
1436 if(cpustate->SF == cpustate->OF) {
1439 if( modrm >= 0xc0 ) {
1440 STORE_RM8(modrm, value);
1441 CYCLES(cpustate,CYCLES_SETCC_REG);
1443 UINT32 ea = GetEA(cpustate,modrm,1);
1444 WRITE8(cpustate,ea, value);
1445 CYCLES(cpustate,CYCLES_SETCC_MEM);
1449 static void I386OP(setl_rm8)(i386_state *cpustate) // Opcode 0x0f 9c
1451 UINT8 modrm = FETCH(cpustate);
1453 if( cpustate->SF != cpustate->OF ) {
1456 if( modrm >= 0xc0 ) {
1457 STORE_RM8(modrm, value);
1458 CYCLES(cpustate,CYCLES_SETCC_REG);
1460 UINT32 ea = GetEA(cpustate,modrm,1);
1461 WRITE8(cpustate,ea, value);
1462 CYCLES(cpustate,CYCLES_SETCC_MEM);
1466 static void I386OP(setle_rm8)(i386_state *cpustate) // Opcode 0x0f 9e
1468 UINT8 modrm = FETCH(cpustate);
1470 if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
1473 if( modrm >= 0xc0 ) {
1474 STORE_RM8(modrm, value);
1475 CYCLES(cpustate,CYCLES_SETCC_REG);
1477 UINT32 ea = GetEA(cpustate,modrm,1);
1478 WRITE8(cpustate,ea, value);
1479 CYCLES(cpustate,CYCLES_SETCC_MEM);
1483 static void I386OP(setnc_rm8)(i386_state *cpustate) // Opcode 0x0f 93
1485 UINT8 modrm = FETCH(cpustate);
1487 if( cpustate->CF == 0 ) {
1490 if( modrm >= 0xc0 ) {
1491 STORE_RM8(modrm, value);
1492 CYCLES(cpustate,CYCLES_SETCC_REG);
1494 UINT32 ea = GetEA(cpustate,modrm,1);
1495 WRITE8(cpustate,ea, value);
1496 CYCLES(cpustate,CYCLES_SETCC_MEM);
1500 static void I386OP(setno_rm8)(i386_state *cpustate) // Opcode 0x0f 91
1502 UINT8 modrm = FETCH(cpustate);
1504 if( cpustate->OF == 0 ) {
1507 if( modrm >= 0xc0 ) {
1508 STORE_RM8(modrm, value);
1509 CYCLES(cpustate,CYCLES_SETCC_REG);
1511 UINT32 ea = GetEA(cpustate,modrm,1);
1512 WRITE8(cpustate,ea, value);
1513 CYCLES(cpustate,CYCLES_SETCC_MEM);
1517 static void I386OP(setnp_rm8)(i386_state *cpustate) // Opcode 0x0f 9b
1519 UINT8 modrm = FETCH(cpustate);
1521 if( cpustate->PF == 0 ) {
1524 if( modrm >= 0xc0 ) {
1525 STORE_RM8(modrm, value);
1526 CYCLES(cpustate,CYCLES_SETCC_REG);
1528 UINT32 ea = GetEA(cpustate,modrm,1);
1529 WRITE8(cpustate,ea, value);
1530 CYCLES(cpustate,CYCLES_SETCC_MEM);
1534 static void I386OP(setns_rm8)(i386_state *cpustate) // Opcode 0x0f 99
1536 UINT8 modrm = FETCH(cpustate);
1538 if( cpustate->SF == 0 ) {
1541 if( modrm >= 0xc0 ) {
1542 STORE_RM8(modrm, value);
1543 CYCLES(cpustate,CYCLES_SETCC_REG);
1545 UINT32 ea = GetEA(cpustate,modrm,1);
1546 WRITE8(cpustate,ea, value);
1547 CYCLES(cpustate,CYCLES_SETCC_MEM);
1551 static void I386OP(setnz_rm8)(i386_state *cpustate) // Opcode 0x0f 95
1553 UINT8 modrm = FETCH(cpustate);
1555 if( cpustate->ZF == 0 ) {
1558 if( modrm >= 0xc0 ) {
1559 STORE_RM8(modrm, value);
1560 CYCLES(cpustate,CYCLES_SETCC_REG);
1562 UINT32 ea = GetEA(cpustate,modrm,1);
1563 WRITE8(cpustate,ea, value);
1564 CYCLES(cpustate,CYCLES_SETCC_MEM);
1568 static void I386OP(seto_rm8)(i386_state *cpustate) // Opcode 0x0f 90
1570 UINT8 modrm = FETCH(cpustate);
1572 if( cpustate->OF != 0 ) {
1575 if( modrm >= 0xc0 ) {
1576 STORE_RM8(modrm, value);
1577 CYCLES(cpustate,CYCLES_SETCC_REG);
1579 UINT32 ea = GetEA(cpustate,modrm,1);
1580 WRITE8(cpustate,ea, value);
1581 CYCLES(cpustate,CYCLES_SETCC_MEM);
1585 static void I386OP(setp_rm8)(i386_state *cpustate) // Opcode 0x0f 9a
1587 UINT8 modrm = FETCH(cpustate);
1589 if( cpustate->PF != 0 ) {
1592 if( modrm >= 0xc0 ) {
1593 STORE_RM8(modrm, value);
1594 CYCLES(cpustate,CYCLES_SETCC_REG);
1596 UINT32 ea = GetEA(cpustate,modrm,1);
1597 WRITE8(cpustate,ea, value);
1598 CYCLES(cpustate,CYCLES_SETCC_MEM);
1602 static void I386OP(sets_rm8)(i386_state *cpustate) // Opcode 0x0f 98
1604 UINT8 modrm = FETCH(cpustate);
1606 if( cpustate->SF != 0 ) {
1609 if( modrm >= 0xc0 ) {
1610 STORE_RM8(modrm, value);
1611 CYCLES(cpustate,CYCLES_SETCC_REG);
1613 UINT32 ea = GetEA(cpustate,modrm,1);
1614 WRITE8(cpustate,ea, value);
1615 CYCLES(cpustate,CYCLES_SETCC_MEM);
1619 static void I386OP(setz_rm8)(i386_state *cpustate) // Opcode 0x0f 94
1621 UINT8 modrm = FETCH(cpustate);
1623 if( cpustate->ZF != 0 ) {
1626 if( modrm >= 0xc0 ) {
1627 STORE_RM8(modrm, value);
1628 CYCLES(cpustate,CYCLES_SETCC_REG);
1630 UINT32 ea = GetEA(cpustate,modrm,1);
1631 WRITE8(cpustate,ea, value);
1632 CYCLES(cpustate,CYCLES_SETCC_MEM);
1636 static void I386OP(stc)(i386_state *cpustate) // Opcode 0xf9
1639 CYCLES(cpustate,CYCLES_STC);
1642 static void I386OP(std)(i386_state *cpustate) // Opcode 0xfd
1645 CYCLES(cpustate,CYCLES_STD);
1648 static void I386OP(sti)(i386_state *cpustate) // Opcode 0xfb
1652 UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
1653 if(cpustate->CPL > IOPL)
1656 cpustate->delayed_interrupt_enable = 1; // IF is set after the next instruction.
1657 CYCLES(cpustate,CYCLES_STI);
1660 static void I386OP(stosb)(i386_state *cpustate) // Opcode 0xaa
1663 ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
1664 WRITE8(cpustate,ead, REG8(AL));
1665 BUMP_DI(cpustate,1);
1666 CYCLES(cpustate,CYCLES_STOS);
1669 static void I386OP(sub_rm8_r8)(i386_state *cpustate) // Opcode 0x28
1672 UINT8 modrm = FETCH(cpustate);
1673 if( modrm >= 0xc0 ) {
1674 src = LOAD_REG8(modrm);
1675 dst = LOAD_RM8(modrm);
1676 dst = SUB8(cpustate,dst, src);
1677 STORE_RM8(modrm, dst);
1678 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1680 UINT32 ea = GetEA(cpustate,modrm,1);
1681 src = LOAD_REG8(modrm);
1682 dst = READ8(cpustate,ea);
1683 dst = SUB8(cpustate,dst, src);
1684 WRITE8(cpustate,ea, dst);
1685 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1689 static void I386OP(sub_r8_rm8)(i386_state *cpustate) // Opcode 0x2a
1692 UINT8 modrm = FETCH(cpustate);
1693 if( modrm >= 0xc0 ) {
1694 src = LOAD_RM8(modrm);
1695 dst = LOAD_REG8(modrm);
1696 dst = SUB8(cpustate,dst, src);
1697 STORE_REG8(modrm, dst);
1698 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1700 UINT32 ea = GetEA(cpustate,modrm,0);
1701 src = READ8(cpustate,ea);
1702 dst = LOAD_REG8(modrm);
1703 dst = SUB8(cpustate,dst, src);
1704 STORE_REG8(modrm, dst);
1705 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
1709 static void I386OP(sub_al_i8)(i386_state *cpustate) // Opcode 0x2c
1712 src = FETCH(cpustate);
1714 dst = SUB8(cpustate,dst, src);
1716 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1719 static void I386OP(test_al_i8)(i386_state *cpustate) // Opcode 0xa8
1721 UINT8 src = FETCH(cpustate);
1722 UINT8 dst = REG8(AL);
1727 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1730 static void I386OP(test_rm8_r8)(i386_state *cpustate) // Opcode 0x84
1733 UINT8 modrm = FETCH(cpustate);
1734 if( modrm >= 0xc0 ) {
1735 src = LOAD_REG8(modrm);
1736 dst = LOAD_RM8(modrm);
1741 CYCLES(cpustate,CYCLES_TEST_REG_REG);
1743 UINT32 ea = GetEA(cpustate,modrm,0);
1744 src = LOAD_REG8(modrm);
1745 dst = READ8(cpustate,ea);
1750 CYCLES(cpustate,CYCLES_TEST_REG_MEM);
1754 static void I386OP(xchg_r8_rm8)(i386_state *cpustate) // Opcode 0x86
1756 UINT8 modrm = FETCH(cpustate);
1757 if( modrm >= 0xc0 ) {
1758 UINT8 src = LOAD_RM8(modrm);
1759 UINT8 dst = LOAD_REG8(modrm);
1760 STORE_REG8(modrm, src);
1761 STORE_RM8(modrm, dst);
1762 CYCLES(cpustate,CYCLES_XCHG_REG_REG);
1764 UINT32 ea = GetEA(cpustate,modrm,1);
1765 UINT8 src = READ8(cpustate,ea);
1766 UINT8 dst = LOAD_REG8(modrm);
1767 WRITE8(cpustate,ea, dst);
1768 STORE_REG8(modrm, src);
1769 CYCLES(cpustate,CYCLES_XCHG_REG_MEM);
1773 static void I386OP(xor_rm8_r8)(i386_state *cpustate) // Opcode 0x30
1776 UINT8 modrm = FETCH(cpustate);
1777 if( modrm >= 0xc0 ) {
1778 src = LOAD_REG8(modrm);
1779 dst = LOAD_RM8(modrm);
1780 dst = XOR8(cpustate,dst, src);
1781 STORE_RM8(modrm, dst);
1782 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1784 UINT32 ea = GetEA(cpustate,modrm,1);
1785 src = LOAD_REG8(modrm);
1786 dst = READ8(cpustate,ea);
1787 dst = XOR8(cpustate,dst, src);
1788 WRITE8(cpustate,ea, dst);
1789 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1793 static void I386OP(xor_r8_rm8)(i386_state *cpustate) // Opcode 0x32
1796 UINT8 modrm = FETCH(cpustate);
1797 if( modrm >= 0xc0 ) {
1798 src = LOAD_RM8(modrm);
1799 dst = LOAD_REG8(modrm);
1800 dst = XOR8(cpustate,dst, src);
1801 STORE_REG8(modrm, dst);
1802 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1804 UINT32 ea = GetEA(cpustate,modrm,0);
1805 src = READ8(cpustate,ea);
1806 dst = LOAD_REG8(modrm);
1807 dst = XOR8(cpustate,dst, src);
1808 STORE_REG8(modrm, dst);
1809 CYCLES(cpustate,CYCLES_ALU_MEM_REG);
1813 static void I386OP(xor_al_i8)(i386_state *cpustate) // Opcode 0x34
1816 src = FETCH(cpustate);
1818 dst = XOR8(cpustate,dst, src);
1820 CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1825 static void I386OP(group80_8)(i386_state *cpustate) // Opcode 0x80
1829 UINT8 modrm = FETCH(cpustate);
1831 switch( (modrm >> 3) & 0x7 )
1833 case 0: // ADD Rm8, i8
1834 if( modrm >= 0xc0 ) {
1835 dst = LOAD_RM8(modrm);
1836 src = FETCH(cpustate);
1837 dst = ADD8(cpustate,dst, src);
1838 STORE_RM8(modrm, dst);
1839 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1841 ea = GetEA(cpustate,modrm,0);
1842 dst = READ8(cpustate,ea);
1843 src = FETCH(cpustate);
1844 dst = ADD8(cpustate,dst, src);
1845 WRITE8(cpustate,ea, dst);
1846 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1849 case 1: // OR Rm8, i8
1850 if( modrm >= 0xc0 ) {
1851 dst = LOAD_RM8(modrm);
1852 src = FETCH(cpustate);
1853 dst = OR8(cpustate,dst, src);
1854 STORE_RM8(modrm, dst);
1855 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1857 ea = GetEA(cpustate,modrm,1);
1858 dst = READ8(cpustate,ea);
1859 src = FETCH(cpustate);
1860 dst = OR8(cpustate,dst, src);
1861 WRITE8(cpustate,ea, dst);
1862 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1865 case 2: // ADC Rm8, i8
1866 if( modrm >= 0xc0 ) {
1867 dst = LOAD_RM8(modrm);
1868 src = FETCH(cpustate);
1869 dst = ADC8(cpustate, dst, src, cpustate->CF);
1870 STORE_RM8(modrm, dst);
1871 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1873 ea = GetEA(cpustate,modrm,1);
1874 dst = READ8(cpustate,ea);
1875 src = FETCH(cpustate);
1876 dst = ADC8(cpustate, dst, src, cpustate->CF);
1877 WRITE8(cpustate,ea, dst);
1878 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1881 case 3: // SBB Rm8, i8
1882 if( modrm >= 0xc0 ) {
1883 dst = LOAD_RM8(modrm);
1884 src = FETCH(cpustate);
1885 dst = SBB8(cpustate, dst, src, cpustate->CF);
1886 STORE_RM8(modrm, dst);
1887 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1889 ea = GetEA(cpustate,modrm,1);
1890 dst = READ8(cpustate,ea);
1891 src = FETCH(cpustate);
1892 dst = SBB8(cpustate, dst, src, cpustate->CF);
1893 WRITE8(cpustate,ea, dst);
1894 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1897 case 4: // AND Rm8, i8
1898 if( modrm >= 0xc0 ) {
1899 dst = LOAD_RM8(modrm);
1900 src = FETCH(cpustate);
1901 dst = AND8(cpustate,dst, src);
1902 STORE_RM8(modrm, dst);
1903 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1905 ea = GetEA(cpustate,modrm,1);
1906 dst = READ8(cpustate,ea);
1907 src = FETCH(cpustate);
1908 dst = AND8(cpustate,dst, src);
1909 WRITE8(cpustate,ea, dst);
1910 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1913 case 5: // SUB Rm8, i8
1914 if( modrm >= 0xc0 ) {
1915 dst = LOAD_RM8(modrm);
1916 src = FETCH(cpustate);
1917 dst = SUB8(cpustate,dst, src);
1918 STORE_RM8(modrm, dst);
1919 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1921 ea = GetEA(cpustate,modrm,1);
1922 dst = READ8(cpustate,ea);
1923 src = FETCH(cpustate);
1924 dst = SUB8(cpustate,dst, src);
1925 WRITE8(cpustate,ea, dst);
1926 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1929 case 6: // XOR Rm8, i8
1930 if( modrm >= 0xc0 ) {
1931 dst = LOAD_RM8(modrm);
1932 src = FETCH(cpustate);
1933 dst = XOR8(cpustate,dst, src);
1934 STORE_RM8(modrm, dst);
1935 CYCLES(cpustate,CYCLES_ALU_REG_REG);
1937 ea = GetEA(cpustate,modrm,1);
1938 dst = READ8(cpustate,ea);
1939 src = FETCH(cpustate);
1940 dst = XOR8(cpustate,dst, src);
1941 WRITE8(cpustate,ea, dst);
1942 CYCLES(cpustate,CYCLES_ALU_REG_MEM);
1945 case 7: // CMP Rm8, i8
1946 if( modrm >= 0xc0 ) {
1947 dst = LOAD_RM8(modrm);
1948 src = FETCH(cpustate);
1949 SUB8(cpustate,dst, src);
1950 CYCLES(cpustate,CYCLES_CMP_REG_REG);
1952 ea = GetEA(cpustate,modrm,0);
1953 dst = READ8(cpustate,ea);
1954 src = FETCH(cpustate);
1955 SUB8(cpustate,dst, src);
1956 CYCLES(cpustate,CYCLES_CMP_REG_MEM);
1962 static void I386OP(groupC0_8)(i386_state *cpustate) // Opcode 0xc0
1965 UINT8 modrm = FETCH(cpustate);
1968 if( modrm >= 0xc0 ) {
1969 dst = LOAD_RM8(modrm);
1970 shift = FETCH(cpustate) & 0x1f;
1971 dst = i386_shift_rotate8(cpustate, modrm, dst, shift);
1972 STORE_RM8(modrm, dst);
1974 UINT32 ea = GetEA(cpustate,modrm,1);
1975 dst = READ8(cpustate,ea);
1976 shift = FETCH(cpustate) & 0x1f;
1977 dst = i386_shift_rotate8(cpustate, modrm, dst, shift);
1978 WRITE8(cpustate,ea, dst);
1982 static void I386OP(groupD0_8)(i386_state *cpustate) // Opcode 0xd0
1985 UINT8 modrm = FETCH(cpustate);
1987 if( modrm >= 0xc0 ) {
1988 dst = LOAD_RM8(modrm);
1989 dst = i386_shift_rotate8(cpustate, modrm, dst, 1);
1990 STORE_RM8(modrm, dst);
1992 UINT32 ea = GetEA(cpustate,modrm,1);
1993 dst = READ8(cpustate,ea);
1994 dst = i386_shift_rotate8(cpustate, modrm, dst, 1);
1995 WRITE8(cpustate,ea, dst);
1999 static void I386OP(groupD2_8)(i386_state *cpustate) // Opcode 0xd2
2002 UINT8 modrm = FETCH(cpustate);
2004 if( modrm >= 0xc0 ) {
2005 dst = LOAD_RM8(modrm);
2006 dst = i386_shift_rotate8(cpustate, modrm, dst, REG8(CL));
2007 STORE_RM8(modrm, dst);
2009 UINT32 ea = GetEA(cpustate,modrm,1);
2010 dst = READ8(cpustate,ea);
2011 dst = i386_shift_rotate8(cpustate, modrm, dst, REG8(CL));
2012 WRITE8(cpustate,ea, dst);
2016 static void I386OP(groupF6_8)(i386_state *cpustate) // Opcode 0xf6
2018 UINT8 modrm = FETCH(cpustate);
2020 switch( (modrm >> 3) & 0x7 )
2022 case 0: /* TEST Rm8, i8 */
2023 if( modrm >= 0xc0 ) {
2024 UINT8 dst = LOAD_RM8(modrm);
2025 UINT8 src = FETCH(cpustate);
2027 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2029 CYCLES(cpustate,CYCLES_TEST_IMM_REG);
2031 UINT32 ea = GetEA(cpustate,modrm,0);
2032 UINT8 dst = READ8(cpustate,ea);
2033 UINT8 src = FETCH(cpustate);
2035 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2037 CYCLES(cpustate,CYCLES_TEST_IMM_MEM);
2040 case 2: /* NOT Rm8 */
2041 if( modrm >= 0xc0 ) {
2042 UINT8 dst = LOAD_RM8(modrm);
2044 STORE_RM8(modrm, dst);
2045 CYCLES(cpustate,CYCLES_NOT_REG);
2047 UINT32 ea = GetEA(cpustate,modrm,1);
2048 UINT8 dst = READ8(cpustate,ea);
2050 WRITE8(cpustate,ea, dst);
2051 CYCLES(cpustate,CYCLES_NOT_MEM);
2054 case 3: /* NEG Rm8 */
2055 if( modrm >= 0xc0 ) {
2056 UINT8 dst = LOAD_RM8(modrm);
2057 dst = SUB8(cpustate, 0, dst );
2058 STORE_RM8(modrm, dst);
2059 CYCLES(cpustate,CYCLES_NEG_REG);
2061 UINT32 ea = GetEA(cpustate,modrm,1);
2062 UINT8 dst = READ8(cpustate,ea);
2063 dst = SUB8(cpustate, 0, dst );
2064 WRITE8(cpustate,ea, dst);
2065 CYCLES(cpustate,CYCLES_NEG_MEM);
2068 case 4: /* MUL AL, Rm8 */
2072 if( modrm >= 0xc0 ) {
2073 src = LOAD_RM8(modrm);
2074 CYCLES(cpustate,CYCLES_MUL8_ACC_REG); /* TODO: Correct multiply timing */
2076 UINT32 ea = GetEA(cpustate,modrm,0);
2077 src = READ8(cpustate,ea);
2078 CYCLES(cpustate,CYCLES_MUL8_ACC_MEM); /* TODO: Correct multiply timing */
2082 result = (UINT16)src * (UINT16)dst;
2083 REG16(AX) = (UINT16)result;
2085 cpustate->CF = cpustate->OF = (REG16(AX) > 0xff);
2088 case 5: /* IMUL AL, Rm8 */
2092 if( modrm >= 0xc0 ) {
2093 src = (INT16)(INT8)LOAD_RM8(modrm);
2094 CYCLES(cpustate,CYCLES_IMUL8_ACC_REG); /* TODO: Correct multiply timing */
2096 UINT32 ea = GetEA(cpustate,modrm,0);
2097 src = (INT16)(INT8)READ8(cpustate,ea);
2098 CYCLES(cpustate,CYCLES_IMUL8_ACC_MEM); /* TODO: Correct multiply timing */
2101 dst = (INT16)(INT8)REG8(AL);
2104 REG16(AX) = (UINT16)result;
2106 cpustate->CF = cpustate->OF = !(result == (INT16)(INT8)result);
2109 case 6: /* DIV AL, Rm8 */
2111 UINT16 quotient, remainder, result;
2113 if( modrm >= 0xc0 ) {
2114 src = LOAD_RM8(modrm);
2115 CYCLES(cpustate,CYCLES_DIV8_ACC_REG);
2117 UINT32 ea = GetEA(cpustate,modrm,0);
2118 src = READ8(cpustate,ea);
2119 CYCLES(cpustate,CYCLES_DIV8_ACC_MEM);
2122 quotient = (UINT16)REG16(AX);
2124 remainder = quotient % (UINT16)src;
2125 result = quotient / (UINT16)src;
2126 if( result > 0xff ) {
2127 /* TODO: Divide error */
2129 REG8(AH) = (UINT8)remainder & 0xff;
2130 REG8(AL) = (UINT8)result & 0xff;
2132 // this flag is actually undefined, enable on non-cyrix
2133 if (cpustate->cpuid_id0 != 0x69727943)
2137 i386_trap(cpustate, 0, 0, 0);
2141 case 7: /* IDIV AL, Rm8 */
2143 INT16 quotient, remainder, result;
2145 if( modrm >= 0xc0 ) {
2146 src = LOAD_RM8(modrm);
2147 CYCLES(cpustate,CYCLES_IDIV8_ACC_REG);
2149 UINT32 ea = GetEA(cpustate,modrm,0);
2150 src = READ8(cpustate,ea);
2151 CYCLES(cpustate,CYCLES_IDIV8_ACC_MEM);
2154 quotient = (INT16)REG16(AX);
2156 remainder = quotient % (INT16)(INT8)src;
2157 result = quotient / (INT16)(INT8)src;
2158 if( result > 0xff ) {
2159 /* TODO: Divide error */
2161 REG8(AH) = (UINT8)remainder & 0xff;
2162 REG8(AL) = (UINT8)result & 0xff;
2164 // this flag is actually undefined, enable on non-cyrix
2165 if (cpustate->cpuid_id0 != 0x69727943)
2169 i386_trap(cpustate, 0, 0, 0);
2176 static void I386OP(groupFE_8)(i386_state *cpustate) // Opcode 0xfe
2178 UINT8 modrm = FETCH(cpustate);
2180 switch( (modrm >> 3) & 0x7 )
2182 case 0: /* INC Rm8 */
2183 if( modrm >= 0xc0 ) {
2184 UINT8 dst = LOAD_RM8(modrm);
2185 dst = INC8(cpustate,dst);
2186 STORE_RM8(modrm, dst);
2187 CYCLES(cpustate,CYCLES_INC_REG);
2189 UINT32 ea = GetEA(cpustate,modrm,1);
2190 UINT8 dst = READ8(cpustate,ea);
2191 dst = INC8(cpustate,dst);
2192 WRITE8(cpustate,ea, dst);
2193 CYCLES(cpustate,CYCLES_INC_MEM);
2196 case 1: /* DEC Rm8 */
2197 if( modrm >= 0xc0 ) {
2198 UINT8 dst = LOAD_RM8(modrm);
2199 dst = DEC8(cpustate,dst);
2200 STORE_RM8(modrm, dst);
2201 CYCLES(cpustate,CYCLES_DEC_REG);
2203 UINT32 ea = GetEA(cpustate,modrm,1);
2204 UINT8 dst = READ8(cpustate,ea);
2205 dst = DEC8(cpustate,dst);
2206 WRITE8(cpustate,ea, dst);
2207 CYCLES(cpustate,CYCLES_DEC_MEM);
2210 case 6: /* PUSH Rm8*/
2213 if( modrm >= 0xc0 ) {
2214 value = LOAD_RM8(modrm);
2216 UINT32 ea = GetEA(cpustate,modrm,0);
2217 value = READ8(cpustate,ea);
2219 if( cpustate->operand_size ) {
2220 PUSH32(cpustate,value);
2222 PUSH16(cpustate,value);
2224 CYCLES(cpustate,CYCLES_PUSH_RM);
2228 report_invalid_modrm(cpustate, "groupFE_8", modrm);
2235 static void I386OP(segment_CS)(i386_state *cpustate) // Opcode 0x2e
2237 cpustate->segment_prefix = 1;
2238 cpustate->segment_override = CS;
2240 I386OP(decode_opcode)(cpustate);
2243 static void I386OP(segment_DS)(i386_state *cpustate) // Opcode 0x3e
2245 cpustate->segment_prefix = 1;
2246 cpustate->segment_override = DS;
2247 CYCLES(cpustate,0); // TODO: Specify cycle count
2248 I386OP(decode_opcode)(cpustate);
2251 static void I386OP(segment_ES)(i386_state *cpustate) // Opcode 0x26
2253 cpustate->segment_prefix = 1;
2254 cpustate->segment_override = ES;
2255 CYCLES(cpustate,0); // TODO: Specify cycle count
2256 I386OP(decode_opcode)(cpustate);
2259 static void I386OP(segment_FS)(i386_state *cpustate) // Opcode 0x64
2261 cpustate->segment_prefix = 1;
2262 cpustate->segment_override = FS;
2263 CYCLES(cpustate,1); // TODO: Specify cycle count
2264 I386OP(decode_opcode)(cpustate);
2267 static void I386OP(segment_GS)(i386_state *cpustate) // Opcode 0x65
2269 cpustate->segment_prefix = 1;
2270 cpustate->segment_override = GS;
2271 CYCLES(cpustate,1); // TODO: Specify cycle count
2272 I386OP(decode_opcode)(cpustate);
2275 static void I386OP(segment_SS)(i386_state *cpustate) // Opcode 0x36
2277 cpustate->segment_prefix = 1;
2278 cpustate->segment_override = SS;
2279 CYCLES(cpustate,0); // TODO: Specify cycle count
2280 I386OP(decode_opcode)(cpustate);
2283 static void I386OP(operand_size)(i386_state *cpustate) // Opcode prefix 0x66
2285 if(cpustate->operand_prefix == 0)
2287 cpustate->operand_size ^= 1;
2288 cpustate->xmm_operand_size ^= 1;
2289 cpustate->operand_prefix = 1;
2291 cpustate->opcode = FETCH(cpustate);
2292 if (cpustate->opcode == 0x0f)
2293 I386OP(decode_three_byte66)(cpustate);
2296 if( cpustate->operand_size )
2297 cpustate->opcode_table1_32[cpustate->opcode](cpustate);
2299 cpustate->opcode_table1_16[cpustate->opcode](cpustate);
2303 static void I386OP(address_size)(i386_state *cpustate) // Opcode 0x67
2305 if(cpustate->address_prefix == 0)
2307 cpustate->address_size ^= 1;
2308 cpustate->address_prefix = 1;
2310 I386OP(decode_opcode)(cpustate);
2313 static void I386OP(nop)(i386_state *cpustate) // Opcode 0x90
2315 CYCLES(cpustate,CYCLES_NOP);
2318 static void I386OP(int3)(i386_state *cpustate) // Opcode 0xcc
2320 CYCLES(cpustate,CYCLES_INT3);
2321 cpustate->ext = 0; // not an external interrupt
2322 i386_trap(cpustate,3, 1, 0);
2326 static void I386OP(int)(i386_state *cpustate) // Opcode 0xcd
2328 int interrupt = FETCH(cpustate);
2329 CYCLES(cpustate,CYCLES_INT);
2330 #ifdef I386_BIOS_CALL
2333 cpustate->ext = 0; // not an external interrupt
2334 i386_trap(cpustate,interrupt, 1, 0);
2338 static void I386OP(into)(i386_state *cpustate) // Opcode 0xce
2340 if( cpustate->OF ) {
2342 i386_trap(cpustate,4, 1, 0);
2344 CYCLES(cpustate,CYCLES_INTO_OF1);
2348 CYCLES(cpustate,CYCLES_INTO_OF0);
2352 static UINT32 i386_escape_ea; // hack around GCC 4.6 error because we need the side effects of GetEA()
2353 static void I386OP(escape)(i386_state *cpustate) // Opcodes 0xd8 - 0xdf
2355 UINT8 modrm = FETCH(cpustate);
2358 i386_escape_ea = GetEA(cpustate,modrm,0);
2360 CYCLES(cpustate,3); // TODO: confirm this
2361 (void) LOAD_RM8(modrm);
2364 static void I386OP(hlt)(i386_state *cpustate) // Opcode 0xf4
2366 if(PROTECTED_MODE && cpustate->CPL != 0)
2368 cpustate->halted = 1;
2369 CYCLES(cpustate,CYCLES_HLT);
2370 if (cpustate->cycles > 0)
2371 cpustate->cycles = 0;
2374 static void I386OP(decimal_adjust)(i386_state *cpustate, int direction)
2376 UINT8 tmpAL = REG8(AL);
2377 UINT8 tmpCF = cpustate->CF;
2379 if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
2381 UINT16 t= (UINT16)REG8(AL) + (direction * 0x06);
2382 REG8(AL) = (UINT8)t&0xff;
2390 if (tmpCF || (tmpAL > 0x99))
2392 REG8(AL) += (direction * 0x60);
2399 static void I386OP(daa)(i386_state *cpustate) // Opcode 0x27
2401 I386OP(decimal_adjust)(cpustate, +1);
2402 CYCLES(cpustate,CYCLES_DAA);
2405 static void I386OP(das)(i386_state *cpustate) // Opcode 0x2f
2407 I386OP(decimal_adjust)(cpustate, -1);
2408 CYCLES(cpustate,CYCLES_DAS);
2411 static void I386OP(aaa)(i386_state *cpustate) // Opcode 0x37
2413 if( ( (REG8(AL) & 0x0f) > 9) || (cpustate->AF != 0) ) {
2414 REG16(AX) = REG16(AX) + 6;
2415 REG8(AH) = REG8(AH) + 1;
2422 REG8(AL) = REG8(AL) & 0x0f;
2423 CYCLES(cpustate,CYCLES_AAA);
2426 static void I386OP(aas)(i386_state *cpustate) // Opcode 0x3f
2428 if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
2441 CYCLES(cpustate,CYCLES_AAS);
2444 static void I386OP(aad)(i386_state *cpustate) // Opcode 0xd5
2446 UINT8 tempAL = REG8(AL);
2447 UINT8 tempAH = REG8(AH);
2448 UINT8 i = FETCH(cpustate);
2450 REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
2452 SetSZPF8( REG8(AL) );
2453 CYCLES(cpustate,CYCLES_AAD);
2456 static void I386OP(aam)(i386_state *cpustate) // Opcode 0xd4
2458 UINT8 tempAL = REG8(AL);
2459 UINT8 i = FETCH(cpustate);
2463 i386_trap(cpustate, 0, 0, 0);
2466 REG8(AH) = tempAL / i;
2467 REG8(AL) = tempAL % i;
2468 SetSZPF8( REG8(AL) );
2469 CYCLES(cpustate,CYCLES_AAM);
2472 static void I386OP(clts)(i386_state *cpustate) // Opcode 0x0f 0x06
2474 // Privileged instruction, CPL must be zero. Can be used in real or v86 mode.
2475 if(PROTECTED_MODE && cpustate->CPL != 0)
2477 cpustate->cr[0] &= ~0x08; /* clear TS bit */
2478 CYCLES(cpustate,CYCLES_CLTS);
2481 static void I386OP(wait)(i386_state *cpustate) // Opcode 0x9B
2486 static void I386OP(lock)(i386_state *cpustate) // Opcode 0xf0
2488 // lock doesn't depend on iopl on 386
2489 cpustate->lock = true;
2490 CYCLES(cpustate,CYCLES_LOCK); // TODO: Determine correct cycle count
2491 I386OP(decode_opcode)(cpustate);
2494 static void I386OP(mov_r32_tr)(i386_state *cpustate) // Opcode 0x0f 24
2497 CYCLES(cpustate,1); // TODO: correct cycle count
2500 static void I386OP(mov_tr_r32)(i386_state *cpustate) // Opcode 0x0f 26
2503 CYCLES(cpustate,1); // TODO: correct cycle count
2506 static void I386OP(loadall)(i386_state *cpustate) // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
2508 fatalerror("i386: LOADALL unimplemented at %08X\n", cpustate->pc - 1);
2511 static void I386OP(invalid)(i386_state *cpustate)
2513 report_invalid_opcode(cpustate);
2514 i386_trap(cpustate, 6, 0, 0);
2517 static void I386OP(xlat)(i386_state *cpustate) // Opcode 0xd7
2520 if( cpustate->segment_prefix ) {
2521 if(!cpustate->address_size)
2523 ea = i386_translate(cpustate, cpustate->segment_override, REG16(BX) + REG8(AL), 0 );
2527 ea = i386_translate(cpustate, cpustate->segment_override, REG32(EBX) + REG8(AL), 0 );
2530 if(!cpustate->address_size)
2532 ea = i386_translate(cpustate, DS, REG16(BX) + REG8(AL), 0 );
2536 ea = i386_translate(cpustate, DS, REG32(EBX) + REG8(AL), 0 );
2539 REG8(AL) = READ8(cpustate,ea);
2540 CYCLES(cpustate,CYCLES_XLAT);