OSDN Git Service

[General] Merge upstream 2015-01-31 , pc8801ma is still not working correct.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mame / emu / cpu / i386 / i386ops.c
1 static UINT8 I386OP(shift_rotate8)(i386_state *cpustate, UINT8 modrm, UINT32 value, UINT8 shift)
2 {
3         UINT32 src = value & 0xff;
4         UINT8 dst = value;
5
6         if( shift == 0 ) {
7                 CYCLES_RM(cpustate,modrm, 3, 7);
8         } else if( shift == 1 ) {
9                 switch( (modrm >> 3) & 0x7 )
10                 {
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);
16                                 break;
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);
22                                 break;
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);
28                                 break;
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);
34                                 break;
35                         case 4:         /* SHL/SAL rm8, 1 */
36                         case 6:
37                                 dst = src << 1;
38                                 cpustate->CF = (src & 0x80) ? 1 : 0;
39                                 cpustate->OF = (((cpustate->CF << 7) ^ dst) & 0x80) ? 1 : 0;
40                                 SetSZPF8(dst);
41                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
42                                 break;
43                         case 5:         /* SHR rm8, 1 */
44                                 dst = src >> 1;
45                                 cpustate->CF = src & 0x1;
46                                 cpustate->OF = (dst & 0x80) ? 1 : 0;
47                                 SetSZPF8(dst);
48                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
49                                 break;
50                         case 7:         /* SAR rm8, 1 */
51                                 dst = (INT8)(src) >> 1;
52                                 cpustate->CF = src & 0x1;
53                                 cpustate->OF = 0;
54                                 SetSZPF8(dst);
55                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
56                                 break;
57                 }
58
59         } else {
60                 switch( (modrm >> 3) & 0x7 )
61                 {
62                         case 0:         /* ROL rm8, i8 */
63                                 if(!(shift & 7))
64                                 {
65                                         if(shift & 0x18)
66                                         {
67                                                 cpustate->CF = src & 1;
68                                                 cpustate->OF = (src & 1) ^ ((src >> 7) & 1);
69                                         }
70                                         break;
71                                 }
72                                 shift &= 7;
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);
78                                 break;
79                         case 1:         /* ROR rm8, i8 */
80                                 if(!(shift & 7))
81                                 {
82                                         if(shift & 0x18)
83                                         {
84                                                 cpustate->CF = (src >> 7) & 1;
85                                                 cpustate->OF = ((src >> 7) & 1) ^ ((src >> 6) & 1);
86                                         }
87                                         break;
88                                 }
89                                 shift &= 7;
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);
95                                 break;
96                         case 2:         /* RCL rm8, i8 */
97                                 shift %= 9;
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);
104                                 break;
105                         case 3:         /* RCR rm8, i8 */
106                                 shift %= 9;
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);
113                                 break;
114                         case 4:         /* SHL/SAL rm8, i8 */
115                         case 6:
116                                 shift &= 31;
117                                 dst = src << shift;
118                                 cpustate->CF = (shift <= 8) && ((src >> (8 - shift)) & 1);
119                                 SetSZPF8(dst);
120                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
121                                 break;
122                         case 5:         /* SHR rm8, i8 */
123                                 shift &= 31;
124                                 dst = src >> shift;
125                                 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
126                                 SetSZPF8(dst);
127                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
128                                 break;
129                         case 7:         /* SAR rm8, i8 */
130                                 shift &= 31;
131                                 dst = (INT8)src >> shift;
132                                 cpustate->CF = (src & (1 << (shift-1))) ? 1 : 0;
133                                 SetSZPF8(dst);
134                                 CYCLES_RM(cpustate,modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM);
135                                 break;
136                 }
137         }
138
139         return dst;
140 }
141
142
143
144 static void I386OP(adc_rm8_r8)(i386_state *cpustate)        // Opcode 0x10
145 {
146         UINT8 src, dst;
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);
154         } else {
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);
161         }
162 }
163
164 static void I386OP(adc_r8_rm8)(i386_state *cpustate)        // Opcode 0x12
165 {
166         UINT8 src, dst;
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);
174         } else {
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);
181         }
182 }
183
184 static void I386OP(adc_al_i8)(i386_state *cpustate)     // Opcode 0x14
185 {
186         UINT8 src, dst;
187         src = FETCH(cpustate);
188         dst = REG8(AL);
189         dst = ADC8(cpustate, dst, src, cpustate->CF);
190         REG8(AL) = dst;
191         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
192 }
193
194 static void I386OP(add_rm8_r8)(i386_state *cpustate)        // Opcode 0x00
195 {
196         UINT8 src, dst;
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);
204         } else {
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);
211         }
212 }
213
214 static void I386OP(add_r8_rm8)(i386_state *cpustate)        // Opcode 0x02
215 {
216         UINT8 src, dst;
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);
224         } else {
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);
231         }
232 }
233
234 static void I386OP(add_al_i8)(i386_state *cpustate)     // Opcode 0x04
235 {
236         UINT8 src, dst;
237         src = FETCH(cpustate);
238         dst = REG8(AL);
239         dst = ADD8(cpustate,dst, src);
240         REG8(AL) = dst;
241         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
242 }
243
244 static void I386OP(and_rm8_r8)(i386_state *cpustate)        // Opcode 0x20
245 {
246         UINT8 src, dst;
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);
254         } else {
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);
261         }
262 }
263
264 static void I386OP(and_r8_rm8)(i386_state *cpustate)        // Opcode 0x22
265 {
266         UINT8 src, dst;
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);
274         } else {
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);
281         }
282 }
283
284 static void I386OP(and_al_i8)(i386_state *cpustate)         // Opcode 0x24
285 {
286         UINT8 src, dst;
287         src = FETCH(cpustate);
288         dst = REG8(AL);
289         dst = AND8(cpustate,dst, src);
290         REG8(AL) = dst;
291         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
292 }
293
294 static void I386OP(clc)(i386_state *cpustate)               // Opcode 0xf8
295 {
296         cpustate->CF = 0;
297         CYCLES(cpustate,CYCLES_CLC);
298 }
299
300 static void I386OP(cld)(i386_state *cpustate)               // Opcode 0xfc
301 {
302         cpustate->DF = 0;
303         CYCLES(cpustate,CYCLES_CLD);
304 }
305
306 static void I386OP(cli)(i386_state *cpustate)               // Opcode 0xfa
307 {
308         if(PROTECTED_MODE)
309         {
310                 UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
311                 if(cpustate->CPL > IOPL)
312                         FAULT(FAULT_GP,0);
313         }
314         cpustate->IF = 0;
315         CYCLES(cpustate,CYCLES_CLI);
316 }
317
318 static void I386OP(cmc)(i386_state *cpustate)               // Opcode 0xf5
319 {
320         cpustate->CF ^= 1;
321         CYCLES(cpustate,CYCLES_CMC);
322 }
323
324 static void I386OP(cmp_rm8_r8)(i386_state *cpustate)        // Opcode 0x38
325 {
326         UINT8 src, dst;
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);
333         } else {
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);
339         }
340 }
341
342 static void I386OP(cmp_r8_rm8)(i386_state *cpustate)        // Opcode 0x3a
343 {
344         UINT8 src, dst;
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);
351         } else {
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);
357         }
358 }
359
360 static void I386OP(cmp_al_i8)(i386_state *cpustate)         // Opcode 0x3c
361 {
362         UINT8 src, dst;
363         src = FETCH(cpustate);
364         dst = REG8(AL);
365         SUB8(cpustate,dst, src);
366         CYCLES(cpustate,CYCLES_CMP_IMM_ACC);
367 }
368
369 static void I386OP(cmpsb)(i386_state *cpustate)             // Opcode 0xa6
370 {
371         UINT32 eas, ead;
372         UINT8 src, dst;
373         if( cpustate->segment_prefix ) {
374                 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
375         } else {
376                 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
377         }
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);
382         BUMP_SI(cpustate,1);
383         BUMP_DI(cpustate,1);
384         CYCLES(cpustate,CYCLES_CMPS);
385 }
386
387 static void I386OP(in_al_i8)(i386_state *cpustate)          // Opcode 0xe4
388 {
389         UINT16 port = FETCH(cpustate);
390         UINT8 data = READPORT8(cpustate, port);
391         REG8(AL) = data;
392         CYCLES(cpustate,CYCLES_IN_VAR);
393 }
394
395 static void I386OP(in_al_dx)(i386_state *cpustate)          // Opcode 0xec
396 {
397         UINT16 port = REG16(DX);
398         UINT8 data = READPORT8(cpustate, port);
399         REG8(AL) = data;
400         CYCLES(cpustate,CYCLES_IN);
401 }
402
403 static void I386OP(ja_rel8)(i386_state *cpustate)           // Opcode 0x77
404 {
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 */
409         } else {
410                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
411         }
412 }
413
414 static void I386OP(jbe_rel8)(i386_state *cpustate)          // Opcode 0x76
415 {
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 */
420         } else {
421                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
422         }
423 }
424
425 static void I386OP(jc_rel8)(i386_state *cpustate)           // Opcode 0x72
426 {
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 */
431         } else {
432                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
433         }
434 }
435
436 static void I386OP(jg_rel8)(i386_state *cpustate)           // Opcode 0x7f
437 {
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 */
442         } else {
443                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
444         }
445 }
446
447 static void I386OP(jge_rel8)(i386_state *cpustate)          // Opcode 0x7d
448 {
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 */
453         } else {
454                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
455         }
456 }
457
458 static void I386OP(jl_rel8)(i386_state *cpustate)           // Opcode 0x7c
459 {
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 */
464         } else {
465                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
466         }
467 }
468
469 static void I386OP(jle_rel8)(i386_state *cpustate)      // Opcode 0x7e
470 {
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 */
475         } else {
476                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
477         }
478 }
479
480 static void I386OP(jnc_rel8)(i386_state *cpustate)          // Opcode 0x73
481 {
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 */
486         } else {
487                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
488         }
489 }
490
491 static void I386OP(jno_rel8)(i386_state *cpustate)          // Opcode 0x71
492 {
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 */
497         } else {
498                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
499         }
500 }
501
502 static void I386OP(jnp_rel8)(i386_state *cpustate)          // Opcode 0x7b
503 {
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 */
508         } else {
509                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
510         }
511 }
512
513 static void I386OP(jns_rel8)(i386_state *cpustate)          // Opcode 0x79
514 {
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 */
519         } else {
520                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
521         }
522 }
523
524 static void I386OP(jnz_rel8)(i386_state *cpustate)          // Opcode 0x75
525 {
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 */
530         } else {
531                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
532         }
533 }
534
535 static void I386OP(jo_rel8)(i386_state *cpustate)           // Opcode 0x70
536 {
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 */
541         } else {
542                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
543         }
544 }
545
546 static void I386OP(jp_rel8)(i386_state *cpustate)           // Opcode 0x7a
547 {
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 */
552         } else {
553                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
554         }
555 }
556
557 static void I386OP(js_rel8)(i386_state *cpustate)           // Opcode 0x78
558 {
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 */
563         } else {
564                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
565         }
566 }
567
568 static void I386OP(jz_rel8)(i386_state *cpustate)           // Opcode 0x74
569 {
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 */
574         } else {
575                 CYCLES(cpustate,CYCLES_JCC_DISP8_NOBRANCH);
576         }
577 }
578
579 static void I386OP(jmp_rel8)(i386_state *cpustate)          // Opcode 0xeb
580 {
581         INT8 disp = FETCH(cpustate);
582         NEAR_BRANCH(cpustate,disp);
583         CYCLES(cpustate,CYCLES_JMP_SHORT);      /* TODO: Timing = 7 + m */
584 }
585
586 static void I386OP(lahf)(i386_state *cpustate)              // Opcode 0x9f
587 {
588         REG8(AH) = get_flags(cpustate) & 0xd7;
589         CYCLES(cpustate,CYCLES_LAHF);
590 }
591
592 static void I386OP(lodsb)(i386_state *cpustate)             // Opcode 0xac
593 {
594         UINT32 eas;
595         if( cpustate->segment_prefix ) {
596                 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
597         } else {
598                 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
599         }
600         REG8(AL) = READ8(cpustate,eas);
601         BUMP_SI(cpustate,1);
602         CYCLES(cpustate,CYCLES_LODS);
603 }
604
605 static void I386OP(mov_rm8_r8)(i386_state *cpustate)        // Opcode 0x88
606 {
607         UINT8 src;
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);
613         } else {
614                 UINT32 ea = GetEA(cpustate,modrm,1);
615                 src = LOAD_REG8(modrm);
616                 WRITE8(cpustate,ea, src);
617                 CYCLES(cpustate,CYCLES_MOV_REG_MEM);
618         }
619 }
620
621 static void I386OP(mov_r8_rm8)(i386_state *cpustate)        // Opcode 0x8a
622 {
623         UINT8 src;
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);
629         } else {
630                 UINT32 ea = GetEA(cpustate,modrm,0);
631                 src = READ8(cpustate,ea);
632                 STORE_REG8(modrm, src);
633                 CYCLES(cpustate,CYCLES_MOV_MEM_REG);
634         }
635 }
636
637 static void I386OP(mov_rm8_i8)(i386_state *cpustate)        // Opcode 0xc6
638 {
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);
644         } else {
645                 UINT32 ea = GetEA(cpustate,modrm,1);
646                 UINT8 value = FETCH(cpustate);
647                 WRITE8(cpustate,ea, value);
648                 CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
649         }
650 }
651
652 static void I386OP(mov_r32_cr)(i386_state *cpustate)        // Opcode 0x0f 20
653 {
654         if(PROTECTED_MODE && cpustate->CPL)
655                 FAULT(FAULT_GP, 0);
656         UINT8 modrm = FETCH(cpustate);
657         UINT8 cr = (modrm >> 3) & 0x7;
658
659         STORE_RM32(modrm, cpustate->cr[cr]);
660         CYCLES(cpustate,CYCLES_MOV_CR_REG);
661 }
662
663 static void I386OP(mov_r32_dr)(i386_state *cpustate)        // Opcode 0x0f 21
664 {
665         if(PROTECTED_MODE && cpustate->CPL)
666                 FAULT(FAULT_GP, 0);
667         UINT8 modrm = FETCH(cpustate);
668         UINT8 dr = (modrm >> 3) & 0x7;
669
670         STORE_RM32(modrm, cpustate->dr[dr]);
671         switch(dr)
672         {
673                 case 0:
674                 case 1:
675                 case 2:
676                 case 3:
677                         CYCLES(cpustate,CYCLES_MOV_REG_DR0_3);
678                         break;
679                 case 6:
680                 case 7:
681                         CYCLES(cpustate,CYCLES_MOV_REG_DR6_7);
682                         break;
683         }
684 }
685
686 static void I386OP(mov_cr_r32)(i386_state *cpustate)        // Opcode 0x0f 22
687 {
688         if(PROTECTED_MODE && cpustate->CPL)
689                 FAULT(FAULT_GP, 0);
690         UINT8 modrm = FETCH(cpustate);
691         UINT8 cr = (modrm >> 3) & 0x7;
692         UINT32 data = LOAD_RM32(modrm);
693         switch(cr)
694         {
695                 case 0:
696                         data &= 0xfffeffff; // wp not supported on 386
697                         CYCLES(cpustate,CYCLES_MOV_REG_CR0);
698                         break;
699                 case 2: CYCLES(cpustate,CYCLES_MOV_REG_CR2); break;
700                 case 3:
701                         CYCLES(cpustate,CYCLES_MOV_REG_CR3);
702                         vtlb_flush_dynamic(cpustate->vtlb);
703                         break;
704                 case 4: CYCLES(cpustate,1); break; // TODO
705                 default:
706                         logerror("i386: mov_cr_r32 CR%d!\n", cr);
707                         return;
708         }
709         cpustate->cr[cr] = data;
710 }
711
712 static void I386OP(mov_dr_r32)(i386_state *cpustate)        // Opcode 0x0f 23
713 {
714         if(PROTECTED_MODE && cpustate->CPL)
715                 FAULT(FAULT_GP, 0);
716         UINT8 modrm = FETCH(cpustate);
717         UINT8 dr = (modrm >> 3) & 0x7;
718
719         cpustate->dr[dr] = LOAD_RM32(modrm);
720         switch(dr)
721         {
722                 case 0:
723                 case 1:
724                 case 2:
725                 case 3:
726                         CYCLES(cpustate,CYCLES_MOV_DR0_3_REG);
727                         break;
728                 case 6:
729                 case 7:
730                         CYCLES(cpustate,CYCLES_MOV_DR6_7_REG);
731                         break;
732                 default:
733                         logerror("i386: mov_dr_r32 DR%d!\n", dr);
734                         return;
735         }
736 }
737
738 static void I386OP(mov_al_m8)(i386_state *cpustate)         // Opcode 0xa0
739 {
740         UINT32 offset, ea;
741         if( cpustate->address_size ) {
742                 offset = FETCH32(cpustate);
743         } else {
744                 offset = FETCH16(cpustate);
745         }
746         /* TODO: Not sure if this is correct... */
747         if( cpustate->segment_prefix ) {
748                 ea = i386_translate(cpustate, cpustate->segment_override, offset, 0 );
749         } else {
750                 ea = i386_translate(cpustate, DS, offset, 0 );
751         }
752         REG8(AL) = READ8(cpustate,ea);
753         CYCLES(cpustate,CYCLES_MOV_IMM_MEM);
754 }
755
756 static void I386OP(mov_m8_al)(i386_state *cpustate)         // Opcode 0xa2
757 {
758         UINT32 offset, ea;
759         if( cpustate->address_size ) {
760                 offset = FETCH32(cpustate);
761         } else {
762                 offset = FETCH16(cpustate);
763         }
764         /* TODO: Not sure if this is correct... */
765         if( cpustate->segment_prefix ) {
766                 ea = i386_translate(cpustate, cpustate->segment_override, offset, 1 );
767         } else {
768                 ea = i386_translate(cpustate, DS, offset, 1 );
769         }
770         WRITE8(cpustate, ea, REG8(AL) );
771         CYCLES(cpustate,CYCLES_MOV_MEM_ACC);
772 }
773
774 static void I386OP(mov_rm16_sreg)(i386_state *cpustate)     // Opcode 0x8c
775 {
776         UINT8 modrm = FETCH(cpustate);
777         int s = (modrm >> 3) & 0x7;
778
779         if( modrm >= 0xc0 ) {
780                 if(cpustate->operand_size)
781                         STORE_RM32(modrm, cpustate->sreg[s].selector);
782                 else
783                         STORE_RM16(modrm, cpustate->sreg[s].selector);
784                 CYCLES(cpustate,CYCLES_MOV_SREG_REG);
785         } else {
786                 UINT32 ea = GetEA(cpustate,modrm,1);
787                 WRITE16(cpustate,ea, cpustate->sreg[s].selector);
788                 CYCLES(cpustate,CYCLES_MOV_SREG_MEM);
789         }
790 }
791
792 static void I386OP(mov_sreg_rm16)(i386_state *cpustate)     // Opcode 0x8e
793 {
794         UINT16 selector;
795         UINT8 modrm = FETCH(cpustate);
796         bool fault;
797         int s = (modrm >> 3) & 0x7;
798
799         if( modrm >= 0xc0 ) {
800                 selector = LOAD_RM16(modrm);
801                 CYCLES(cpustate,CYCLES_MOV_REG_SREG);
802         } else {
803                 UINT32 ea = GetEA(cpustate,modrm,0);
804                 selector = READ16(cpustate,ea);
805                 CYCLES(cpustate,CYCLES_MOV_MEM_SREG);
806         }
807
808         i386_sreg_load(cpustate,selector,s,&fault);
809         if((s == SS) && !fault)
810         {
811                 if(cpustate->IF != 0) // if external interrupts are enabled
812                 {
813                         cpustate->IF = 0;  // reset IF for the next instruction
814                         cpustate->delayed_interrupt_enable = 1;
815                 }
816         }
817 }
818
819 static void I386OP(mov_al_i8)(i386_state *cpustate)         // Opcode 0xb0
820 {
821         REG8(AL) = FETCH(cpustate);
822         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
823 }
824
825 static void I386OP(mov_cl_i8)(i386_state *cpustate)         // Opcode 0xb1
826 {
827         REG8(CL) = FETCH(cpustate);
828         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
829 }
830
831 static void I386OP(mov_dl_i8)(i386_state *cpustate)         // Opcode 0xb2
832 {
833         REG8(DL) = FETCH(cpustate);
834         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
835 }
836
837 static void I386OP(mov_bl_i8)(i386_state *cpustate)         // Opcode 0xb3
838 {
839         REG8(BL) = FETCH(cpustate);
840         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
841 }
842
843 static void I386OP(mov_ah_i8)(i386_state *cpustate)         // Opcode 0xb4
844 {
845         REG8(AH) = FETCH(cpustate);
846         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
847 }
848
849 static void I386OP(mov_ch_i8)(i386_state *cpustate)         // Opcode 0xb5
850 {
851         REG8(CH) = FETCH(cpustate);
852         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
853 }
854
855 static void I386OP(mov_dh_i8)(i386_state *cpustate)         // Opcode 0xb6
856 {
857         REG8(DH) = FETCH(cpustate);
858         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
859 }
860
861 static void I386OP(mov_bh_i8)(i386_state *cpustate)         // Opcode 0xb7
862 {
863         REG8(BH) = FETCH(cpustate);
864         CYCLES(cpustate,CYCLES_MOV_IMM_REG);
865 }
866
867 static void I386OP(movsb)(i386_state *cpustate)             // Opcode 0xa4
868 {
869         UINT32 eas, ead;
870         UINT8 v;
871         if( cpustate->segment_prefix ) {
872                 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
873         } else {
874                 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
875         }
876         ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
877         v = READ8(cpustate,eas);
878         WRITE8(cpustate,ead, v);
879         BUMP_SI(cpustate,1);
880         BUMP_DI(cpustate,1);
881         CYCLES(cpustate,CYCLES_MOVS);
882 }
883
884 static void I386OP(or_rm8_r8)(i386_state *cpustate)         // Opcode 0x08
885 {
886         UINT8 src, dst;
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);
894         } else {
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);
901         }
902 }
903
904 static void I386OP(or_r8_rm8)(i386_state *cpustate)         // Opcode 0x0a
905 {
906         UINT8 src, dst;
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);
914         } else {
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);
921         }
922 }
923
924 static void I386OP(or_al_i8)(i386_state *cpustate)          // Opcode 0x0c
925 {
926         UINT8 src, dst;
927         src = FETCH(cpustate);
928         dst = REG8(AL);
929         dst = OR8(cpustate,dst, src);
930         REG8(EAX) = dst;
931         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
932 }
933
934 static void I386OP(out_al_i8)(i386_state *cpustate)         // Opcode 0xe6
935 {
936         UINT16 port = FETCH(cpustate);
937         UINT8 data = REG8(AL);
938         WRITEPORT8(cpustate, port, data);
939         CYCLES(cpustate,CYCLES_OUT_VAR);
940 }
941
942 static void I386OP(out_al_dx)(i386_state *cpustate)         // Opcode 0xee
943 {
944         UINT16 port = REG16(DX);
945         UINT8 data = REG8(AL);
946         WRITEPORT8(cpustate, port, data);
947         CYCLES(cpustate,CYCLES_OUT);
948 }
949
950
951 static void I386OP(arpl)(i386_state *cpustate)           // Opcode 0x63
952 {
953         UINT16 src, dst;
954         UINT8 modrm = FETCH(cpustate);
955         UINT8 flag = 0;
956
957         if(PROTECTED_MODE && !V8086_MODE)
958         {
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);
964                                 flag = 1;
965                                 STORE_RM16(modrm, dst);
966                         }
967                 } else {
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);
973                                 flag = 1;
974                                 WRITE16(cpustate, ea, dst);
975                         }
976                 }
977                 SetZF(flag);
978         }
979         else
980                 i386_trap(cpustate, 6, 0, 0);  // invalid opcode in real mode or v8086 mode
981 }
982
983 static void I386OP(push_i8)(i386_state *cpustate)           // Opcode 0x6a
984 {
985         UINT8 value = FETCH(cpustate);
986         PUSH8(cpustate,value);
987         CYCLES(cpustate,CYCLES_PUSH_IMM);
988 }
989
990 static void I386OP(ins_generic)(i386_state *cpustate, int size)
991 {
992         UINT32 ead;
993         UINT8 vb;
994         UINT16 vw;
995         UINT32 vd;
996
997         ead = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 1 );
998
999         switch(size) {
1000         case 1:
1001                 vb = READPORT8(cpustate, REG16(DX));
1002                 WRITE8(cpustate,ead, vb);
1003                 break;
1004         case 2:
1005                 vw = READPORT16(cpustate, REG16(DX));
1006                 WRITE16(cpustate,ead, vw);
1007                 break;
1008         case 4:
1009                 vd = READPORT32(cpustate, REG16(DX));
1010                 WRITE32(cpustate,ead, vd);
1011                 break;
1012         }
1013
1014         if(cpustate->address_size)
1015                 REG32(EDI) += ((cpustate->DF) ? -1 : 1) * size;
1016         else
1017                 REG16(DI) += ((cpustate->DF) ? -1 : 1) * size;
1018         CYCLES(cpustate,CYCLES_INS);    // TODO: Confirm this value
1019 }
1020
1021 static void I386OP(insb)(i386_state *cpustate)              // Opcode 0x6c
1022 {
1023         I386OP(ins_generic)(cpustate, 1);
1024 }
1025
1026 static void I386OP(insw)(i386_state *cpustate)              // Opcode 0x6d
1027 {
1028         I386OP(ins_generic)(cpustate, 2);
1029 }
1030
1031 static void I386OP(insd)(i386_state *cpustate)              // Opcode 0x6d
1032 {
1033         I386OP(ins_generic)(cpustate, 4);
1034 }
1035
1036 static void I386OP(outs_generic)(i386_state *cpustate, int size)
1037 {
1038         UINT32 eas;
1039         UINT8 vb;
1040         UINT16 vw;
1041         UINT32 vd;
1042
1043         if( cpustate->segment_prefix ) {
1044                 eas = i386_translate(cpustate, cpustate->segment_override, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
1045         } else {
1046                 eas = i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), 0 );
1047         }
1048
1049         switch(size) {
1050         case 1:
1051                 vb = READ8(cpustate,eas);
1052                 WRITEPORT8(cpustate, REG16(DX), vb);
1053                 break;
1054         case 2:
1055                 vw = READ16(cpustate,eas);
1056                 WRITEPORT16(cpustate, REG16(DX), vw);
1057                 break;
1058         case 4:
1059                 vd = READ32(cpustate,eas);
1060                 WRITEPORT32(cpustate, REG16(DX), vd);
1061                 break;
1062         }
1063
1064         if(cpustate->address_size)
1065                 REG32(ESI) += ((cpustate->DF) ? -1 : 1) * size;
1066         else
1067                 REG16(SI) += ((cpustate->DF) ? -1 : 1) * size;
1068         CYCLES(cpustate,CYCLES_OUTS);   // TODO: Confirm this value
1069 }
1070
1071 static void I386OP(outsb)(i386_state *cpustate)             // Opcode 0x6e
1072 {
1073         I386OP(outs_generic)(cpustate, 1);
1074 }
1075
1076 static void I386OP(outsw)(i386_state *cpustate)             // Opcode 0x6f
1077 {
1078         I386OP(outs_generic)(cpustate, 2);
1079 }
1080
1081 static void I386OP(outsd)(i386_state *cpustate)             // Opcode 0x6f
1082 {
1083         I386OP(outs_generic)(cpustate, 4);
1084 }
1085
1086 static void I386OP(repeat)(i386_state *cpustate, int invert_flag)
1087 {
1088         UINT32 repeated_eip = cpustate->eip;
1089         UINT32 repeated_pc = cpustate->pc;
1090         UINT8 opcode; // = FETCH(cpustate);
1091 //  UINT32 eas, ead;
1092         UINT32 count;
1093         INT32 cycle_base = 0, cycle_adjustment = 0;
1094         UINT8 prefix_flag=1;
1095         UINT8 *flag = NULL;
1096
1097
1098         do {
1099         repeated_eip = cpustate->eip;
1100         repeated_pc = cpustate->pc;
1101         opcode = FETCH(cpustate);
1102         switch(opcode) {
1103                 case 0x0f:
1104                 if (invert_flag == 0)
1105                         I386OP(decode_three_bytef3)(cpustate); // sse f3 0f
1106                 else
1107                         I386OP(decode_three_bytef2)(cpustate); // sse f2 0f
1108                 return;
1109                 case 0x26:
1110                 cpustate->segment_override=ES;
1111                 cpustate->segment_prefix=1;
1112                 break;
1113                 case 0x2e:
1114                 cpustate->segment_override=CS;
1115                 cpustate->segment_prefix=1;
1116                 break;
1117                 case 0x36:
1118                 cpustate->segment_override=SS;
1119                 cpustate->segment_prefix=1;
1120                 break;
1121                 case 0x3e:
1122                 cpustate->segment_override=DS;
1123                 cpustate->segment_prefix=1;
1124                 break;
1125                 case 0x64:
1126                 cpustate->segment_override=FS;
1127                 cpustate->segment_prefix=1;
1128                 break;
1129                 case 0x65:
1130                 cpustate->segment_override=GS;
1131                 cpustate->segment_prefix=1;
1132                 break;
1133                 case 0x66:
1134                 cpustate->operand_size ^= 1;
1135                 cpustate->xmm_operand_size ^= 1;
1136                 break;
1137                 case 0x67:
1138                 cpustate->address_size ^= 1;
1139                 break;
1140                 default:
1141                 prefix_flag=0;
1142         }
1143         } while (prefix_flag);
1144
1145
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 );
1149         } else {
1150                 //eas =
1151                 i386_translate(cpustate, DS, cpustate->address_size ? REG32(ESI) : REG16(SI), -1 );
1152         }
1153         i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), -1 );
1154
1155         switch(opcode)
1156         {
1157                 case 0x6c:
1158                 case 0x6d:
1159                         /* INSB, INSW, INSD */
1160                         // TODO: cycle count
1161                         cycle_base = 8;
1162                         cycle_adjustment = -4;
1163                         flag = NULL;
1164                         break;
1165
1166                 case 0x6e:
1167                 case 0x6f:
1168                         /* OUTSB, OUTSW, OUTSD */
1169                         // TODO: cycle count
1170                         cycle_base = 8;
1171                         cycle_adjustment = -4;
1172                         flag = NULL;
1173                         break;
1174
1175                 case 0xa4:
1176                 case 0xa5:
1177                         /* MOVSB, MOVSW, MOVSD */
1178                         cycle_base = 8;
1179                         cycle_adjustment = -4;
1180                         flag = NULL;
1181                         break;
1182
1183                 case 0xa6:
1184                 case 0xa7:
1185                         /* CMPSB, CMPSW, CMPSD */
1186                         cycle_base = 5;
1187                         cycle_adjustment = -1;
1188                         flag = &cpustate->ZF;
1189                         break;
1190
1191                 case 0xac:
1192                 case 0xad:
1193                         /* LODSB, LODSW, LODSD */
1194                         cycle_base = 5;
1195                         cycle_adjustment = 1;
1196                         flag = NULL;
1197                         break;
1198
1199                 case 0xaa:
1200                 case 0xab:
1201                         /* STOSB, STOSW, STOSD */
1202                         cycle_base = 5;
1203                         cycle_adjustment = 0;
1204                         flag = NULL;
1205                         break;
1206
1207                 case 0xae:
1208                 case 0xaf:
1209                         /* SCASB, SCASW, SCASD */
1210                         cycle_base = 5;
1211                         cycle_adjustment = 0;
1212                         flag = &cpustate->ZF;
1213                         break;
1214
1215                 case 0x90:
1216                         CYCLES(cpustate,CYCLES_NOP);
1217                         return;
1218
1219                 case 0xc2: // sigh
1220                 case 0xc3:
1221                         cpustate->pc--;
1222                         return;
1223
1224                 default:
1225                         fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
1226                         break;
1227         }
1228
1229         if( cpustate->address_size ) {
1230                 if( REG32(ECX) == 0 )
1231                         return;
1232         } else {
1233                 if( REG16(CX) == 0 )
1234                         return;
1235         }
1236
1237         /* now actually perform the repeat */
1238         CYCLES_NUM(cycle_base);
1239         do
1240         {
1241                 cpustate->eip = repeated_eip;
1242                 cpustate->pc = repeated_pc;
1243                 try
1244                 {
1245                         I386OP(decode_opcode)(cpustate);
1246                 }
1247                 catch (UINT64 e)
1248                 {
1249                         cpustate->eip = cpustate->prev_eip;
1250                         throw e;
1251                 }
1252
1253                 CYCLES_NUM(cycle_adjustment);
1254
1255                 if (cpustate->address_size)
1256                         count = --REG32(ECX);
1257                 else
1258                         count = --REG16(CX);
1259                 if (cpustate->cycles <= 0)
1260                         goto outofcycles;
1261         }
1262         while( count && (!flag || (invert_flag ? !*flag : *flag)) );
1263         return;
1264
1265 outofcycles:
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))
1270                 return;
1271         cpustate->eip = cpustate->prev_eip;
1272         CHANGE_PC(cpustate,cpustate->eip);
1273         CYCLES_NUM(-cycle_base);
1274 }
1275
1276 static void I386OP(rep)(i386_state *cpustate)               // Opcode 0xf3
1277 {
1278         I386OP(repeat)(cpustate, 0);
1279 }
1280
1281 static void I386OP(repne)(i386_state *cpustate)             // Opcode 0xf2
1282 {
1283         I386OP(repeat)(cpustate, 1);
1284 }
1285
1286 static void I386OP(sahf)(i386_state *cpustate)              // Opcode 0x9e
1287 {
1288         set_flags(cpustate, (get_flags(cpustate) & 0xffffff00) | (REG8(AH) & 0xd7) );
1289         CYCLES(cpustate,CYCLES_SAHF);
1290 }
1291
1292 static void I386OP(sbb_rm8_r8)(i386_state *cpustate)        // Opcode 0x18
1293 {
1294         UINT8 src, dst;
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);
1302         } else {
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);
1309         }
1310 }
1311
1312 static void I386OP(sbb_r8_rm8)(i386_state *cpustate)        // Opcode 0x1a
1313 {
1314         UINT8 src, dst;
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);
1322         } else {
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);
1329         }
1330 }
1331
1332 static void I386OP(sbb_al_i8)(i386_state *cpustate)         // Opcode 0x1c
1333 {
1334         UINT8 src, dst;
1335         src = FETCH(cpustate);
1336         dst = REG8(AL);
1337         dst = SBB8(cpustate, dst, src, cpustate->CF);
1338         REG8(EAX) = dst;
1339         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1340 }
1341
1342 static void I386OP(scasb)(i386_state *cpustate)             // Opcode 0xae
1343 {
1344         UINT32 eas;
1345         UINT8 src, dst;
1346         eas = i386_translate(cpustate, ES, cpustate->address_size ? REG32(EDI) : REG16(DI), 0 );
1347         src = READ8(cpustate,eas);
1348         dst = REG8(AL);
1349         SUB8(cpustate,dst, src);
1350         BUMP_DI(cpustate,1);
1351         CYCLES(cpustate,CYCLES_SCAS);
1352 }
1353
1354 static void I386OP(setalc)(i386_state *cpustate)            // Opcode 0xd6 (undocumented)
1355 {
1356         if( cpustate->CF ) {
1357                 REG8(AL) = 0xff;
1358         } else {
1359                 REG8(AL) = 0;
1360         }
1361         CYCLES(cpustate,3);
1362 }
1363
1364 static void I386OP(seta_rm8)(i386_state *cpustate)          // Opcode 0x0f 97
1365 {
1366         UINT8 modrm = FETCH(cpustate);
1367         UINT8 value = 0;
1368         if( cpustate->CF == 0 && cpustate->ZF == 0 ) {
1369                 value = 1;
1370         }
1371         if( modrm >= 0xc0 ) {
1372                 STORE_RM8(modrm, value);
1373                 CYCLES(cpustate,CYCLES_SETCC_REG);
1374         } else {
1375                 UINT32 ea = GetEA(cpustate,modrm,1);
1376                 WRITE8(cpustate,ea, value);
1377                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1378         }
1379 }
1380
1381 static void I386OP(setbe_rm8)(i386_state *cpustate)         // Opcode 0x0f 96
1382 {
1383         UINT8 modrm = FETCH(cpustate);
1384         UINT8 value = 0;
1385         if( cpustate->CF != 0 || cpustate->ZF != 0 ) {
1386                 value = 1;
1387         }
1388         if( modrm >= 0xc0 ) {
1389                 STORE_RM8(modrm, value);
1390                 CYCLES(cpustate,CYCLES_SETCC_REG);
1391         } else {
1392                 UINT32 ea = GetEA(cpustate,modrm,1);
1393                 WRITE8(cpustate,ea, value);
1394                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1395         }
1396 }
1397
1398 static void I386OP(setc_rm8)(i386_state *cpustate)          // Opcode 0x0f 92
1399 {
1400         UINT8 modrm = FETCH(cpustate);
1401         UINT8 value = 0;
1402         if( cpustate->CF != 0 ) {
1403                 value = 1;
1404         }
1405         if( modrm >= 0xc0 ) {
1406                 STORE_RM8(modrm, value);
1407                 CYCLES(cpustate,CYCLES_SETCC_REG);
1408         } else {
1409                 UINT32 ea = GetEA(cpustate,modrm,1);
1410                 WRITE8(cpustate,ea, value);
1411                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1412         }
1413 }
1414
1415 static void I386OP(setg_rm8)(i386_state *cpustate)          // Opcode 0x0f 9f
1416 {
1417         UINT8 modrm = FETCH(cpustate);
1418         UINT8 value = 0;
1419         if( cpustate->ZF == 0 && (cpustate->SF == cpustate->OF) ) {
1420                 value = 1;
1421         }
1422         if( modrm >= 0xc0 ) {
1423                 STORE_RM8(modrm, value);
1424                 CYCLES(cpustate,CYCLES_SETCC_REG);
1425         } else {
1426                 UINT32 ea = GetEA(cpustate,modrm,1);
1427                 WRITE8(cpustate,ea, value);
1428                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1429         }
1430 }
1431
1432 static void I386OP(setge_rm8)(i386_state *cpustate)         // Opcode 0x0f 9d
1433 {
1434         UINT8 modrm = FETCH(cpustate);
1435         UINT8 value = 0;
1436         if(cpustate->SF == cpustate->OF) {
1437                 value = 1;
1438         }
1439         if( modrm >= 0xc0 ) {
1440                 STORE_RM8(modrm, value);
1441                 CYCLES(cpustate,CYCLES_SETCC_REG);
1442         } else {
1443                 UINT32 ea = GetEA(cpustate,modrm,1);
1444                 WRITE8(cpustate,ea, value);
1445                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1446         }
1447 }
1448
1449 static void I386OP(setl_rm8)(i386_state *cpustate)          // Opcode 0x0f 9c
1450 {
1451         UINT8 modrm = FETCH(cpustate);
1452         UINT8 value = 0;
1453         if( cpustate->SF != cpustate->OF ) {
1454                 value = 1;
1455         }
1456         if( modrm >= 0xc0 ) {
1457                 STORE_RM8(modrm, value);
1458                 CYCLES(cpustate,CYCLES_SETCC_REG);
1459         } else {
1460                 UINT32 ea = GetEA(cpustate,modrm,1);
1461                 WRITE8(cpustate,ea, value);
1462                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1463         }
1464 }
1465
1466 static void I386OP(setle_rm8)(i386_state *cpustate)         // Opcode 0x0f 9e
1467 {
1468         UINT8 modrm = FETCH(cpustate);
1469         UINT8 value = 0;
1470         if( cpustate->ZF != 0 || (cpustate->SF != cpustate->OF) ) {
1471                 value = 1;
1472         }
1473         if( modrm >= 0xc0 ) {
1474                 STORE_RM8(modrm, value);
1475                 CYCLES(cpustate,CYCLES_SETCC_REG);
1476         } else {
1477                 UINT32 ea = GetEA(cpustate,modrm,1);
1478                 WRITE8(cpustate,ea, value);
1479                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1480         }
1481 }
1482
1483 static void I386OP(setnc_rm8)(i386_state *cpustate)         // Opcode 0x0f 93
1484 {
1485         UINT8 modrm = FETCH(cpustate);
1486         UINT8 value = 0;
1487         if( cpustate->CF == 0 ) {
1488                 value = 1;
1489         }
1490         if( modrm >= 0xc0 ) {
1491                 STORE_RM8(modrm, value);
1492                 CYCLES(cpustate,CYCLES_SETCC_REG);
1493         } else {
1494                 UINT32 ea = GetEA(cpustate,modrm,1);
1495                 WRITE8(cpustate,ea, value);
1496                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1497         }
1498 }
1499
1500 static void I386OP(setno_rm8)(i386_state *cpustate)         // Opcode 0x0f 91
1501 {
1502         UINT8 modrm = FETCH(cpustate);
1503         UINT8 value = 0;
1504         if( cpustate->OF == 0 ) {
1505                 value = 1;
1506         }
1507         if( modrm >= 0xc0 ) {
1508                 STORE_RM8(modrm, value);
1509                 CYCLES(cpustate,CYCLES_SETCC_REG);
1510         } else {
1511                 UINT32 ea = GetEA(cpustate,modrm,1);
1512                 WRITE8(cpustate,ea, value);
1513                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1514         }
1515 }
1516
1517 static void I386OP(setnp_rm8)(i386_state *cpustate)         // Opcode 0x0f 9b
1518 {
1519         UINT8 modrm = FETCH(cpustate);
1520         UINT8 value = 0;
1521         if( cpustate->PF == 0 ) {
1522                 value = 1;
1523         }
1524         if( modrm >= 0xc0 ) {
1525                 STORE_RM8(modrm, value);
1526                 CYCLES(cpustate,CYCLES_SETCC_REG);
1527         } else {
1528                 UINT32 ea = GetEA(cpustate,modrm,1);
1529                 WRITE8(cpustate,ea, value);
1530                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1531         }
1532 }
1533
1534 static void I386OP(setns_rm8)(i386_state *cpustate)         // Opcode 0x0f 99
1535 {
1536         UINT8 modrm = FETCH(cpustate);
1537         UINT8 value = 0;
1538         if( cpustate->SF == 0 ) {
1539                 value = 1;
1540         }
1541         if( modrm >= 0xc0 ) {
1542                 STORE_RM8(modrm, value);
1543                 CYCLES(cpustate,CYCLES_SETCC_REG);
1544         } else {
1545                 UINT32 ea = GetEA(cpustate,modrm,1);
1546                 WRITE8(cpustate,ea, value);
1547                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1548         }
1549 }
1550
1551 static void I386OP(setnz_rm8)(i386_state *cpustate)         // Opcode 0x0f 95
1552 {
1553         UINT8 modrm = FETCH(cpustate);
1554         UINT8 value = 0;
1555         if( cpustate->ZF == 0 ) {
1556                 value = 1;
1557         }
1558         if( modrm >= 0xc0 ) {
1559                 STORE_RM8(modrm, value);
1560                 CYCLES(cpustate,CYCLES_SETCC_REG);
1561         } else {
1562                 UINT32 ea = GetEA(cpustate,modrm,1);
1563                 WRITE8(cpustate,ea, value);
1564                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1565         }
1566 }
1567
1568 static void I386OP(seto_rm8)(i386_state *cpustate)          // Opcode 0x0f 90
1569 {
1570         UINT8 modrm = FETCH(cpustate);
1571         UINT8 value = 0;
1572         if( cpustate->OF != 0 ) {
1573                 value = 1;
1574         }
1575         if( modrm >= 0xc0 ) {
1576                 STORE_RM8(modrm, value);
1577                 CYCLES(cpustate,CYCLES_SETCC_REG);
1578         } else {
1579                 UINT32 ea = GetEA(cpustate,modrm,1);
1580                 WRITE8(cpustate,ea, value);
1581                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1582         }
1583 }
1584
1585 static void I386OP(setp_rm8)(i386_state *cpustate)          // Opcode 0x0f 9a
1586 {
1587         UINT8 modrm = FETCH(cpustate);
1588         UINT8 value = 0;
1589         if( cpustate->PF != 0 ) {
1590                 value = 1;
1591         }
1592         if( modrm >= 0xc0 ) {
1593                 STORE_RM8(modrm, value);
1594                 CYCLES(cpustate,CYCLES_SETCC_REG);
1595         } else {
1596                 UINT32 ea = GetEA(cpustate,modrm,1);
1597                 WRITE8(cpustate,ea, value);
1598                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1599         }
1600 }
1601
1602 static void I386OP(sets_rm8)(i386_state *cpustate)          // Opcode 0x0f 98
1603 {
1604         UINT8 modrm = FETCH(cpustate);
1605         UINT8 value = 0;
1606         if( cpustate->SF != 0 ) {
1607                 value = 1;
1608         }
1609         if( modrm >= 0xc0 ) {
1610                 STORE_RM8(modrm, value);
1611                 CYCLES(cpustate,CYCLES_SETCC_REG);
1612         } else {
1613                 UINT32 ea = GetEA(cpustate,modrm,1);
1614                 WRITE8(cpustate,ea, value);
1615                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1616         }
1617 }
1618
1619 static void I386OP(setz_rm8)(i386_state *cpustate)          // Opcode 0x0f 94
1620 {
1621         UINT8 modrm = FETCH(cpustate);
1622         UINT8 value = 0;
1623         if( cpustate->ZF != 0 ) {
1624                 value = 1;
1625         }
1626         if( modrm >= 0xc0 ) {
1627                 STORE_RM8(modrm, value);
1628                 CYCLES(cpustate,CYCLES_SETCC_REG);
1629         } else {
1630                 UINT32 ea = GetEA(cpustate,modrm,1);
1631                 WRITE8(cpustate,ea, value);
1632                 CYCLES(cpustate,CYCLES_SETCC_MEM);
1633         }
1634 }
1635
1636 static void I386OP(stc)(i386_state *cpustate)               // Opcode 0xf9
1637 {
1638         cpustate->CF = 1;
1639         CYCLES(cpustate,CYCLES_STC);
1640 }
1641
1642 static void I386OP(std)(i386_state *cpustate)               // Opcode 0xfd
1643 {
1644         cpustate->DF = 1;
1645         CYCLES(cpustate,CYCLES_STD);
1646 }
1647
1648 static void I386OP(sti)(i386_state *cpustate)               // Opcode 0xfb
1649 {
1650         if(PROTECTED_MODE)
1651         {
1652                 UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1);
1653                 if(cpustate->CPL > IOPL)
1654                         FAULT(FAULT_GP,0);
1655         }
1656         cpustate->delayed_interrupt_enable = 1;  // IF is set after the next instruction.
1657         CYCLES(cpustate,CYCLES_STI);
1658 }
1659
1660 static void I386OP(stosb)(i386_state *cpustate)             // Opcode 0xaa
1661 {
1662         UINT32 ead;
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);
1667 }
1668
1669 static void I386OP(sub_rm8_r8)(i386_state *cpustate)        // Opcode 0x28
1670 {
1671         UINT8 src, dst;
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);
1679         } else {
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);
1686         }
1687 }
1688
1689 static void I386OP(sub_r8_rm8)(i386_state *cpustate)        // Opcode 0x2a
1690 {
1691         UINT8 src, dst;
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);
1699         } else {
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);
1706         }
1707 }
1708
1709 static void I386OP(sub_al_i8)(i386_state *cpustate)         // Opcode 0x2c
1710 {
1711         UINT8 src, dst;
1712         src = FETCH(cpustate);
1713         dst = REG8(EAX);
1714         dst = SUB8(cpustate,dst, src);
1715         REG8(EAX) = dst;
1716         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1717 }
1718
1719 static void I386OP(test_al_i8)(i386_state *cpustate)        // Opcode 0xa8
1720 {
1721         UINT8 src = FETCH(cpustate);
1722         UINT8 dst = REG8(AL);
1723         dst = src & dst;
1724         SetSZPF8(dst);
1725         cpustate->CF = 0;
1726         cpustate->OF = 0;
1727         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1728 }
1729
1730 static void I386OP(test_rm8_r8)(i386_state *cpustate)       // Opcode 0x84
1731 {
1732         UINT8 src, dst;
1733         UINT8 modrm = FETCH(cpustate);
1734         if( modrm >= 0xc0 ) {
1735                 src = LOAD_REG8(modrm);
1736                 dst = LOAD_RM8(modrm);
1737                 dst = src & dst;
1738                 SetSZPF8(dst);
1739                 cpustate->CF = 0;
1740                 cpustate->OF = 0;
1741                 CYCLES(cpustate,CYCLES_TEST_REG_REG);
1742         } else {
1743                 UINT32 ea = GetEA(cpustate,modrm,0);
1744                 src = LOAD_REG8(modrm);
1745                 dst = READ8(cpustate,ea);
1746                 dst = src & dst;
1747                 SetSZPF8(dst);
1748                 cpustate->CF = 0;
1749                 cpustate->OF = 0;
1750                 CYCLES(cpustate,CYCLES_TEST_REG_MEM);
1751         }
1752 }
1753
1754 static void I386OP(xchg_r8_rm8)(i386_state *cpustate)       // Opcode 0x86
1755 {
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);
1763         } else {
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);
1770         }
1771 }
1772
1773 static void I386OP(xor_rm8_r8)(i386_state *cpustate)        // Opcode 0x30
1774 {
1775         UINT8 src, dst;
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);
1783         } else {
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);
1790         }
1791 }
1792
1793 static void I386OP(xor_r8_rm8)(i386_state *cpustate)        // Opcode 0x32
1794 {
1795         UINT32 src, dst;
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);
1803         } else {
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);
1810         }
1811 }
1812
1813 static void I386OP(xor_al_i8)(i386_state *cpustate)         // Opcode 0x34
1814 {
1815         UINT8 src, dst;
1816         src = FETCH(cpustate);
1817         dst = REG8(AL);
1818         dst = XOR8(cpustate,dst, src);
1819         REG8(AL) = dst;
1820         CYCLES(cpustate,CYCLES_ALU_IMM_ACC);
1821 }
1822
1823
1824
1825 static void I386OP(group80_8)(i386_state *cpustate)         // Opcode 0x80
1826 {
1827         UINT32 ea;
1828         UINT8 src, dst;
1829         UINT8 modrm = FETCH(cpustate);
1830
1831         switch( (modrm >> 3) & 0x7 )
1832         {
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);
1840                         } else {
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);
1847                         }
1848                         break;
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);
1856                         } else {
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);
1863                         }
1864                         break;
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);
1872                         } else {
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);
1879                         }
1880                         break;
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);
1888                         } else {
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);
1895                         }
1896                         break;
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);
1904                         } else {
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);
1911                         }
1912                         break;
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);
1920                         } else {
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);
1927                         }
1928                         break;
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);
1936                         } else {
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);
1943                         }
1944                         break;
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);
1951                         } else {
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);
1957                         }
1958                         break;
1959         }
1960 }
1961
1962 static void I386OP(groupC0_8)(i386_state *cpustate)         // Opcode 0xc0
1963 {
1964         UINT8 dst;
1965         UINT8 modrm = FETCH(cpustate);
1966         UINT8 shift;
1967
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);
1973         } else {
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);
1979         }
1980 }
1981
1982 static void I386OP(groupD0_8)(i386_state *cpustate)         // Opcode 0xd0
1983 {
1984         UINT8 dst;
1985         UINT8 modrm = FETCH(cpustate);
1986
1987         if( modrm >= 0xc0 ) {
1988                 dst = LOAD_RM8(modrm);
1989                 dst = i386_shift_rotate8(cpustate, modrm, dst, 1);
1990                 STORE_RM8(modrm, dst);
1991         } else {
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);
1996         }
1997 }
1998
1999 static void I386OP(groupD2_8)(i386_state *cpustate)         // Opcode 0xd2
2000 {
2001         UINT8 dst;
2002         UINT8 modrm = FETCH(cpustate);
2003
2004         if( modrm >= 0xc0 ) {
2005                 dst = LOAD_RM8(modrm);
2006                 dst = i386_shift_rotate8(cpustate, modrm, dst, REG8(CL));
2007                 STORE_RM8(modrm, dst);
2008         } else {
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);
2013         }
2014 }
2015
2016 static void I386OP(groupF6_8)(i386_state *cpustate)         // Opcode 0xf6
2017 {
2018         UINT8 modrm = FETCH(cpustate);
2019
2020         switch( (modrm >> 3) & 0x7 )
2021         {
2022                 case 0:         /* TEST Rm8, i8 */
2023                         if( modrm >= 0xc0 ) {
2024                                 UINT8 dst = LOAD_RM8(modrm);
2025                                 UINT8 src = FETCH(cpustate);
2026                                 dst &= src;
2027                                 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2028                                 SetSZPF8(dst);
2029                                 CYCLES(cpustate,CYCLES_TEST_IMM_REG);
2030                         } else {
2031                                 UINT32 ea = GetEA(cpustate,modrm,0);
2032                                 UINT8 dst = READ8(cpustate,ea);
2033                                 UINT8 src = FETCH(cpustate);
2034                                 dst &= src;
2035                                 cpustate->CF = cpustate->OF = cpustate->AF = 0;
2036                                 SetSZPF8(dst);
2037                                 CYCLES(cpustate,CYCLES_TEST_IMM_MEM);
2038                         }
2039                         break;
2040                 case 2:         /* NOT Rm8 */
2041                         if( modrm >= 0xc0 ) {
2042                                 UINT8 dst = LOAD_RM8(modrm);
2043                                 dst = ~dst;
2044                                 STORE_RM8(modrm, dst);
2045                                 CYCLES(cpustate,CYCLES_NOT_REG);
2046                         } else {
2047                                 UINT32 ea = GetEA(cpustate,modrm,1);
2048                                 UINT8 dst = READ8(cpustate,ea);
2049                                 dst = ~dst;
2050                                 WRITE8(cpustate,ea, dst);
2051                                 CYCLES(cpustate,CYCLES_NOT_MEM);
2052                         }
2053                         break;
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);
2060                         } else {
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);
2066                         }
2067                         break;
2068                 case 4:         /* MUL AL, Rm8 */
2069                         {
2070                                 UINT16 result;
2071                                 UINT8 src, dst;
2072                                 if( modrm >= 0xc0 ) {
2073                                         src = LOAD_RM8(modrm);
2074                                         CYCLES(cpustate,CYCLES_MUL8_ACC_REG);       /* TODO: Correct multiply timing */
2075                                 } else {
2076                                         UINT32 ea = GetEA(cpustate,modrm,0);
2077                                         src = READ8(cpustate,ea);
2078                                         CYCLES(cpustate,CYCLES_MUL8_ACC_MEM);       /* TODO: Correct multiply timing */
2079                                 }
2080
2081                                 dst = REG8(AL);
2082                                 result = (UINT16)src * (UINT16)dst;
2083                                 REG16(AX) = (UINT16)result;
2084
2085                                 cpustate->CF = cpustate->OF = (REG16(AX) > 0xff);
2086                         }
2087                         break;
2088                 case 5:         /* IMUL AL, Rm8 */
2089                         {
2090                                 INT16 result;
2091                                 INT16 src, dst;
2092                                 if( modrm >= 0xc0 ) {
2093                                         src = (INT16)(INT8)LOAD_RM8(modrm);
2094                                         CYCLES(cpustate,CYCLES_IMUL8_ACC_REG);      /* TODO: Correct multiply timing */
2095                                 } else {
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 */
2099                                 }
2100
2101                                 dst = (INT16)(INT8)REG8(AL);
2102                                 result = src * dst;
2103
2104                                 REG16(AX) = (UINT16)result;
2105
2106                                 cpustate->CF = cpustate->OF = !(result == (INT16)(INT8)result);
2107                         }
2108                         break;
2109                 case 6:         /* DIV AL, Rm8 */
2110                         {
2111                                 UINT16 quotient, remainder, result;
2112                                 UINT8 src;
2113                                 if( modrm >= 0xc0 ) {
2114                                         src = LOAD_RM8(modrm);
2115                                         CYCLES(cpustate,CYCLES_DIV8_ACC_REG);
2116                                 } else {
2117                                         UINT32 ea = GetEA(cpustate,modrm,0);
2118                                         src = READ8(cpustate,ea);
2119                                         CYCLES(cpustate,CYCLES_DIV8_ACC_MEM);
2120                                 }
2121
2122                                 quotient = (UINT16)REG16(AX);
2123                                 if( src ) {
2124                                         remainder = quotient % (UINT16)src;
2125                                         result = quotient / (UINT16)src;
2126                                         if( result > 0xff ) {
2127                                                 /* TODO: Divide error */
2128                                         } else {
2129                                                 REG8(AH) = (UINT8)remainder & 0xff;
2130                                                 REG8(AL) = (UINT8)result & 0xff;
2131
2132                                                 // this flag is actually undefined, enable on non-cyrix
2133                                                 if (cpustate->cpuid_id0 != 0x69727943)
2134                                                         cpustate->CF = 1;
2135                                         }
2136                                 } else {
2137                                         i386_trap(cpustate, 0, 0, 0);
2138                                 }
2139                         }
2140                         break;
2141                 case 7:         /* IDIV AL, Rm8 */
2142                         {
2143                                 INT16 quotient, remainder, result;
2144                                 UINT8 src;
2145                                 if( modrm >= 0xc0 ) {
2146                                         src = LOAD_RM8(modrm);
2147                                         CYCLES(cpustate,CYCLES_IDIV8_ACC_REG);
2148                                 } else {
2149                                         UINT32 ea = GetEA(cpustate,modrm,0);
2150                                         src = READ8(cpustate,ea);
2151                                         CYCLES(cpustate,CYCLES_IDIV8_ACC_MEM);
2152                                 }
2153
2154                                 quotient = (INT16)REG16(AX);
2155                                 if( src ) {
2156                                         remainder = quotient % (INT16)(INT8)src;
2157                                         result = quotient / (INT16)(INT8)src;
2158                                         if( result > 0xff ) {
2159                                                 /* TODO: Divide error */
2160                                         } else {
2161                                                 REG8(AH) = (UINT8)remainder & 0xff;
2162                                                 REG8(AL) = (UINT8)result & 0xff;
2163
2164                                                 // this flag is actually undefined, enable on non-cyrix
2165                                                 if (cpustate->cpuid_id0 != 0x69727943)
2166                                                         cpustate->CF = 1;
2167                                         }
2168                                 } else {
2169                                         i386_trap(cpustate, 0, 0, 0);
2170                                 }
2171                         }
2172                         break;
2173         }
2174 }
2175
2176 static void I386OP(groupFE_8)(i386_state *cpustate)         // Opcode 0xfe
2177 {
2178         UINT8 modrm = FETCH(cpustate);
2179
2180         switch( (modrm >> 3) & 0x7 )
2181         {
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);
2188                         } else {
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);
2194                         }
2195                         break;
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);
2202                         } else {
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);
2208                         }
2209                         break;
2210                 case 6:         /* PUSH Rm8*/
2211                         {
2212                                 UINT8 value;
2213                                 if( modrm >= 0xc0 ) {
2214                                         value = LOAD_RM8(modrm);
2215                                 } else {
2216                                         UINT32 ea = GetEA(cpustate,modrm,0);
2217                                         value = READ8(cpustate,ea);
2218                                 }
2219                                 if( cpustate->operand_size ) {
2220                                         PUSH32(cpustate,value);
2221                                 } else {
2222                                         PUSH16(cpustate,value);
2223                                 }
2224                                 CYCLES(cpustate,CYCLES_PUSH_RM);
2225                         }
2226                         break;
2227                 default:
2228                         report_invalid_modrm(cpustate, "groupFE_8", modrm);
2229                         break;
2230         }
2231 }
2232
2233
2234
2235 static void I386OP(segment_CS)(i386_state *cpustate)        // Opcode 0x2e
2236 {
2237         cpustate->segment_prefix = 1;
2238         cpustate->segment_override = CS;
2239
2240         I386OP(decode_opcode)(cpustate);
2241 }
2242
2243 static void I386OP(segment_DS)(i386_state *cpustate)        // Opcode 0x3e
2244 {
2245         cpustate->segment_prefix = 1;
2246         cpustate->segment_override = DS;
2247         CYCLES(cpustate,0); // TODO: Specify cycle count
2248         I386OP(decode_opcode)(cpustate);
2249 }
2250
2251 static void I386OP(segment_ES)(i386_state *cpustate)        // Opcode 0x26
2252 {
2253         cpustate->segment_prefix = 1;
2254         cpustate->segment_override = ES;
2255         CYCLES(cpustate,0); // TODO: Specify cycle count
2256         I386OP(decode_opcode)(cpustate);
2257 }
2258
2259 static void I386OP(segment_FS)(i386_state *cpustate)        // Opcode 0x64
2260 {
2261         cpustate->segment_prefix = 1;
2262         cpustate->segment_override = FS;
2263         CYCLES(cpustate,1); // TODO: Specify cycle count
2264         I386OP(decode_opcode)(cpustate);
2265 }
2266
2267 static void I386OP(segment_GS)(i386_state *cpustate)        // Opcode 0x65
2268 {
2269         cpustate->segment_prefix = 1;
2270         cpustate->segment_override = GS;
2271         CYCLES(cpustate,1); // TODO: Specify cycle count
2272         I386OP(decode_opcode)(cpustate);
2273 }
2274
2275 static void I386OP(segment_SS)(i386_state *cpustate)        // Opcode 0x36
2276 {
2277         cpustate->segment_prefix = 1;
2278         cpustate->segment_override = SS;
2279         CYCLES(cpustate,0); // TODO: Specify cycle count
2280         I386OP(decode_opcode)(cpustate);
2281 }
2282
2283 static void I386OP(operand_size)(i386_state *cpustate)      // Opcode prefix 0x66
2284 {
2285         if(cpustate->operand_prefix == 0)
2286         {
2287                 cpustate->operand_size ^= 1;
2288                 cpustate->xmm_operand_size ^= 1;
2289                 cpustate->operand_prefix = 1;
2290         }
2291         cpustate->opcode = FETCH(cpustate);
2292         if (cpustate->opcode == 0x0f)
2293                 I386OP(decode_three_byte66)(cpustate);
2294         else
2295         {
2296                 if( cpustate->operand_size )
2297                         cpustate->opcode_table1_32[cpustate->opcode](cpustate);
2298                 else
2299                         cpustate->opcode_table1_16[cpustate->opcode](cpustate);
2300         }
2301 }
2302
2303 static void I386OP(address_size)(i386_state *cpustate)      // Opcode 0x67
2304 {
2305         if(cpustate->address_prefix == 0)
2306         {
2307                 cpustate->address_size ^= 1;
2308                 cpustate->address_prefix = 1;
2309         }
2310         I386OP(decode_opcode)(cpustate);
2311 }
2312
2313 static void I386OP(nop)(i386_state *cpustate)               // Opcode 0x90
2314 {
2315         CYCLES(cpustate,CYCLES_NOP);
2316 }
2317
2318 static void I386OP(int3)(i386_state *cpustate)              // Opcode 0xcc
2319 {
2320         CYCLES(cpustate,CYCLES_INT3);
2321         cpustate->ext = 0; // not an external interrupt
2322         i386_trap(cpustate,3, 1, 0);
2323         cpustate->ext = 1;
2324 }
2325
2326 static void I386OP(int)(i386_state *cpustate)               // Opcode 0xcd
2327 {
2328         int interrupt = FETCH(cpustate);
2329         CYCLES(cpustate,CYCLES_INT);
2330 #ifdef I386_BIOS_CALL
2331         BIOS_INT(interrupt)
2332 #endif
2333         cpustate->ext = 0; // not an external interrupt
2334         i386_trap(cpustate,interrupt, 1, 0);
2335         cpustate->ext = 1;
2336 }
2337
2338 static void I386OP(into)(i386_state *cpustate)              // Opcode 0xce
2339 {
2340         if( cpustate->OF ) {
2341                 cpustate->ext = 0;
2342                 i386_trap(cpustate,4, 1, 0);
2343                 cpustate->ext = 1;
2344                 CYCLES(cpustate,CYCLES_INTO_OF1);
2345         }
2346         else
2347         {
2348                 CYCLES(cpustate,CYCLES_INTO_OF0);
2349         }
2350 }
2351
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
2354 {
2355         UINT8 modrm = FETCH(cpustate);
2356         if(modrm < 0xc0)
2357         {
2358                 i386_escape_ea = GetEA(cpustate,modrm,0);
2359         }
2360         CYCLES(cpustate,3); // TODO: confirm this
2361         (void) LOAD_RM8(modrm);
2362 }
2363
2364 static void I386OP(hlt)(i386_state *cpustate)               // Opcode 0xf4
2365 {
2366         if(PROTECTED_MODE && cpustate->CPL != 0)
2367                 FAULT(FAULT_GP,0);
2368         cpustate->halted = 1;
2369         CYCLES(cpustate,CYCLES_HLT);
2370         if (cpustate->cycles > 0)
2371                 cpustate->cycles = 0;
2372 }
2373
2374 static void I386OP(decimal_adjust)(i386_state *cpustate, int direction)
2375 {
2376         UINT8 tmpAL = REG8(AL);
2377         UINT8 tmpCF = cpustate->CF;
2378
2379         if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
2380         {
2381                 UINT16 t= (UINT16)REG8(AL) + (direction * 0x06);
2382                 REG8(AL) = (UINT8)t&0xff;
2383                 cpustate->AF = 1;
2384                 if (t & 0x100)
2385                         cpustate->CF = 1;
2386                 if (direction > 0)
2387                         tmpAL = REG8(AL);
2388         }
2389
2390         if (tmpCF || (tmpAL > 0x99))
2391         {
2392                 REG8(AL) += (direction * 0x60);
2393                 cpustate->CF = 1;
2394         }
2395
2396         SetSZPF8(REG8(AL));
2397 }
2398
2399 static void I386OP(daa)(i386_state *cpustate)               // Opcode 0x27
2400 {
2401         I386OP(decimal_adjust)(cpustate, +1);
2402         CYCLES(cpustate,CYCLES_DAA);
2403 }
2404
2405 static void I386OP(das)(i386_state *cpustate)               // Opcode 0x2f
2406 {
2407         I386OP(decimal_adjust)(cpustate, -1);
2408         CYCLES(cpustate,CYCLES_DAS);
2409 }
2410
2411 static void I386OP(aaa)(i386_state *cpustate)               // Opcode 0x37
2412 {
2413         if( ( (REG8(AL) & 0x0f) > 9) || (cpustate->AF != 0) ) {
2414                 REG16(AX) = REG16(AX) + 6;
2415                 REG8(AH) = REG8(AH) + 1;
2416                 cpustate->AF = 1;
2417                 cpustate->CF = 1;
2418         } else {
2419                 cpustate->AF = 0;
2420                 cpustate->CF = 0;
2421         }
2422         REG8(AL) = REG8(AL) & 0x0f;
2423         CYCLES(cpustate,CYCLES_AAA);
2424 }
2425
2426 static void I386OP(aas)(i386_state *cpustate)               // Opcode 0x3f
2427 {
2428         if (cpustate->AF || ((REG8(AL) & 0xf) > 9))
2429         {
2430                 REG16(AX) -= 6;
2431                 REG8(AH) -= 1;
2432                 cpustate->AF = 1;
2433                 cpustate->CF = 1;
2434         }
2435         else
2436         {
2437                 cpustate->AF = 0;
2438                 cpustate->CF = 0;
2439         }
2440         REG8(AL) &= 0x0f;
2441         CYCLES(cpustate,CYCLES_AAS);
2442 }
2443
2444 static void I386OP(aad)(i386_state *cpustate)               // Opcode 0xd5
2445 {
2446         UINT8 tempAL = REG8(AL);
2447         UINT8 tempAH = REG8(AH);
2448         UINT8 i = FETCH(cpustate);
2449
2450         REG8(AL) = (tempAL + (tempAH * i)) & 0xff;
2451         REG8(AH) = 0;
2452         SetSZPF8( REG8(AL) );
2453         CYCLES(cpustate,CYCLES_AAD);
2454 }
2455
2456 static void I386OP(aam)(i386_state *cpustate)               // Opcode 0xd4
2457 {
2458         UINT8 tempAL = REG8(AL);
2459         UINT8 i = FETCH(cpustate);
2460
2461         if(!i)
2462         {
2463                 i386_trap(cpustate, 0, 0, 0);
2464                 return;
2465         }
2466         REG8(AH) = tempAL / i;
2467         REG8(AL) = tempAL % i;
2468         SetSZPF8( REG8(AL) );
2469         CYCLES(cpustate,CYCLES_AAM);
2470 }
2471
2472 static void I386OP(clts)(i386_state *cpustate)              // Opcode 0x0f 0x06
2473 {
2474         // Privileged instruction, CPL must be zero.  Can be used in real or v86 mode.
2475         if(PROTECTED_MODE && cpustate->CPL != 0)
2476                 FAULT(FAULT_GP,0)
2477         cpustate->cr[0] &= ~0x08;   /* clear TS bit */
2478         CYCLES(cpustate,CYCLES_CLTS);
2479 }
2480
2481 static void I386OP(wait)(i386_state *cpustate)              // Opcode 0x9B
2482 {
2483         // TODO
2484 }
2485
2486 static void I386OP(lock)(i386_state *cpustate)              // Opcode 0xf0
2487 {
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);
2492 }
2493
2494 static void I386OP(mov_r32_tr)(i386_state *cpustate)        // Opcode 0x0f 24
2495 {
2496         FETCH(cpustate);
2497         CYCLES(cpustate,1);     // TODO: correct cycle count
2498 }
2499
2500 static void I386OP(mov_tr_r32)(i386_state *cpustate)        // Opcode 0x0f 26
2501 {
2502         FETCH(cpustate);
2503         CYCLES(cpustate,1);     // TODO: correct cycle count
2504 }
2505
2506 static void I386OP(loadall)(i386_state *cpustate)       // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
2507 {
2508         fatalerror("i386: LOADALL unimplemented at %08X\n", cpustate->pc - 1);
2509 }
2510
2511 static void I386OP(invalid)(i386_state *cpustate)
2512 {
2513         report_invalid_opcode(cpustate);
2514         i386_trap(cpustate, 6, 0, 0);
2515 }
2516
2517 static void I386OP(xlat)(i386_state *cpustate)          // Opcode 0xd7
2518 {
2519         UINT32 ea;
2520         if( cpustate->segment_prefix ) {
2521                 if(!cpustate->address_size)
2522                 {
2523                         ea = i386_translate(cpustate, cpustate->segment_override, REG16(BX) + REG8(AL), 0 );
2524                 }
2525                 else
2526                 {
2527                         ea = i386_translate(cpustate, cpustate->segment_override, REG32(EBX) + REG8(AL), 0 );
2528                 }
2529         } else {
2530                 if(!cpustate->address_size)
2531                 {
2532                         ea = i386_translate(cpustate, DS, REG16(BX) + REG8(AL), 0 );
2533                 }
2534                 else
2535                 {
2536                         ea = i386_translate(cpustate, DS, REG32(EBX) + REG8(AL), 0 );
2537                 }
2538         }
2539         REG8(AL) = READ8(cpustate,ea);
2540         CYCLES(cpustate,CYCLES_XLAT);
2541 }