OSDN Git Service

[VM][I286][I386][PC9801][FMR50] Add pseudo-cycles args to pseudo-bios for i86/286...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mame / emu / cpu / i86 / instr86.c
1 /****************************************************************************
2 *             real mode i286 emulator v1.4 by Fabrice Frances               *
3 *               (initial work based on David Hedley's pcemu)                *
4 ****************************************************************************/
5
6 /*
7  * file will be included in all cpu variants
8  * put non i86 instructions in own files (i286, i386, nec)
9  * function renaming will be added when necessary
10  * timing value should move to separate array
11  */
12
13 /*
14     PHS - 2010-12-29
15
16     Moved several instruction stubs so that they are compiled separately for
17     the 8086 and 80186. The instructions affected are :
18
19     _pop_ss, _es, _cs, _ss, _ds, _mov_sregw and _sti
20
21     This is because they call the next instruction directly as it cannot be
22     interrupted. If they are not compiled separately when executing on an
23     80186, the wrong set of instructions are used (the 8086 set). This has
24     the serious effect of ignoring the next instruction, as invalid, *IF*
25     it is an 80186 specific instruction.
26
27 */
28
29 #undef ICOUNT
30
31 #define ICOUNT cpustate->icount
32
33 #if defined(I80286)
34 #define BIOS_CALL_86(s,p) i286_call_pseudo_bios(s,p)
35         extern bool i286_call_pseudo_bios(i80286_state *cpustate, uint32_t PC);
36 #else
37 #define BIOS_CALL_86(s,p) i86_call_pseudo_bios(s,p)
38         extern bool i86_call_pseudo_bios(i8086_state *cpustate, uint32_t PC);
39 #endif
40
41 #if !defined(I80186)
42 static void PREFIX86(_interrupt)(i8086_state *cpustate, unsigned int_num)
43 {
44         unsigned dest_seg, dest_off;
45         WORD ip = cpustate->pc - cpustate->base[CS];
46
47         if (int_num == -1)
48                 int_num = cpustate->pic->get_intr_ack();
49
50 #ifdef I80286
51         if (PM) {
52                 i80286_interrupt_descriptor(cpustate, int_num, 0, 0);
53         } else {
54 #endif
55                 dest_off = ReadWord(int_num*4);
56                 dest_seg = ReadWord(int_num*4+2);
57
58                 PREFIX(_pushf(cpustate));
59                 cpustate->TF = cpustate->IF = 0;
60                 PUSH(cpustate->sregs[CS]);
61                 PUSH(ip);
62                 cpustate->sregs[CS] = (WORD)dest_seg;
63                 cpustate->base[CS] = SegBase(CS);
64                 cpustate->pc = (cpustate->base[CS] + dest_off) & AMASK;
65                 CHANGE_PC(cpustate->pc);
66 #ifdef I80286
67         }
68 #endif
69         cpustate->extra_cycles += timing.exception;
70 }
71
72 static void PREFIX86(_trap)(i8086_state *cpustate)
73 {
74         PREFIX(_instruction)[FETCHOP](cpustate);
75         PREFIX(_interrupt)(cpustate, 1);
76 }
77 #endif
78
79 #ifndef I80186
80 static void PREFIX86(_rotate_shift_Byte)(i8086_state *cpustate, unsigned ModRM, unsigned count, unsigned src)
81 {
82 //  unsigned src = (unsigned)GetRMByte(ModRM);
83         unsigned dst=src;
84
85         if (count==0)
86         {
87                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m8_base;
88         }
89         else if (count==1)
90         {
91                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m8_1;
92
93                 switch (ModRM & 0x38)
94                 {
95                 case 0x00:  /* ROL eb,1 */
96                         cpustate->CarryVal = src & 0x80;
97                         dst=(src<<1)+CF;
98                         PutbackRMByte(ModRM,dst);
99                         cpustate->OverVal = (src^dst)&0x80;
100                         break;
101                 case 0x08:  /* ROR eb,1 */
102                         cpustate->CarryVal = src & 0x01;
103                         dst = ((CF<<8)+src) >> 1;
104                         PutbackRMByte(ModRM,dst);
105                         cpustate->OverVal = (src^dst)&0x80;
106                         break;
107                 case 0x10:  /* RCL eb,1 */
108                         dst=(src<<1)+CF;
109                         PutbackRMByte(ModRM,dst);
110                         SetCFB(dst);
111                         cpustate->OverVal = (src^dst)&0x80;
112                         break;
113                 case 0x18:  /* RCR eb,1 */
114                         dst = ((CF<<8)+src) >> 1;
115                         PutbackRMByte(ModRM,dst);
116                         cpustate->CarryVal = src & 0x01;
117                         cpustate->OverVal = (src^dst)&0x80;
118                         break;
119                 case 0x20:  /* SHL eb,1 */
120                 case 0x30:
121                         dst = src << 1;
122                         PutbackRMByte(ModRM,dst);
123                         SetCFB(dst);
124                         cpustate->OverVal = (src^dst)&0x80;
125                         cpustate->AuxVal = 1;
126                         SetSZPF_Byte(dst);
127                         break;
128                 case 0x28:  /* SHR eb,1 */
129                         dst = src >> 1;
130                         PutbackRMByte(ModRM,dst);
131                         cpustate->CarryVal = src & 0x01;
132                         cpustate->OverVal = src & 0x80;
133                         cpustate->AuxVal = 1;
134                         SetSZPF_Byte(dst);
135                         break;
136                 case 0x38:  /* SAR eb,1 */
137                         dst = ((INT8)src) >> 1;
138                         PutbackRMByte(ModRM,dst);
139                         cpustate->CarryVal = src & 0x01;
140                         cpustate->OverVal = 0;
141                         cpustate->AuxVal = 1;
142                         SetSZPF_Byte(dst);
143                         break;
144                 }
145         }
146         else
147         {
148                 int tmpcf = CF;
149                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m8_bit * count);
150
151                 switch (ModRM & 0x38)
152                 {
153                 case 0x00:  /* ROL eb,count */
154                         for (; count > 0; count--)
155                         {
156                                 cpustate->CarryVal = dst & 0x80;
157                                 dst = (dst << 1) + CF;
158                         }
159                         PutbackRMByte(ModRM,(BYTE)dst);
160                         break;
161                 case 0x08:  /* ROR eb,count */
162                         for (; count > 0; count--)
163                         {
164                                 cpustate->CarryVal = dst & 0x01;
165                                 dst = (dst >> 1) + (CF << 7);
166                         }
167                         PutbackRMByte(ModRM,(BYTE)dst);
168                         break;
169                 case 0x10:  /* RCL eb,count */
170                         for (; count > 0; count--)
171                         {
172                                 dst = (dst << 1) + tmpcf;
173                                 tmpcf = (int)((dst & 0x100) != 0);
174                         }
175                         PutbackRMByte(ModRM,(BYTE)dst);
176                         cpustate->CarryVal = tmpcf;
177                         break;
178                 case 0x18:  /* RCR eb,count */
179                         for (; count > 0; count--)
180                         {
181                                 dst = (tmpcf<<8)+dst;
182                                 tmpcf = dst & 0x01;
183                                 dst >>= 1;
184                         }
185                         PutbackRMByte(ModRM,(BYTE)dst);
186                         cpustate->CarryVal = tmpcf;
187                         break;
188                 case 0x20:
189                 case 0x30:  /* SHL eb,count */
190                         for(int i=0;i<count;i++) dst<<= 1;
191                         SetCFB(dst);
192                         cpustate->AuxVal = 1;
193                         SetSZPF_Byte(dst);
194                         PutbackRMByte(ModRM,(BYTE)dst);
195                         break;
196                 case 0x28:  /* SHR eb,count */
197                         for(int i=0;i<count-1;i++) dst>>= 1;
198                         cpustate->CarryVal = dst & 0x1;
199                         dst >>= 1;
200                         SetSZPF_Byte(dst);
201                         cpustate->AuxVal = 1;
202                         PutbackRMByte(ModRM,(BYTE)dst);
203                         break;
204                 case 0x38:  /* SAR eb,count */
205                         for(int i=0;i<count-1;i++) dst = ((INT8)dst) >> 1;
206                         cpustate->CarryVal = dst & 0x1;
207                         dst = ((INT8)((BYTE)dst)) >> 1;
208                         SetSZPF_Byte(dst);
209                         cpustate->AuxVal = 1;
210                         PutbackRMByte(ModRM,(BYTE)dst);
211                         break;
212                 }
213         }
214 }
215
216 static void PREFIX86(_rotate_shift_Word)(i8086_state *cpustate, unsigned ModRM, unsigned count, unsigned src)
217 {
218 //  unsigned src = GetRMWord(ModRM);
219         unsigned dst=src;
220
221         if (count==0)
222         {
223                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base : timing.rot_m16_base;
224         }
225         else if (count==1)
226         {
227                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_1 : timing.rot_m16_1;
228
229                 switch (ModRM & 0x38)
230                 {
231 #if 0
232                 case 0x00:  /* ROL ew,1 */
233                         tmp2 = (tmp << 1) + CF;
234                         SetCFW(tmp2);
235                         cpustate->OverVal = !(!(tmp & 0x4000)) != CF;
236                         PutbackRMWord(ModRM,tmp2);
237                         break;
238                 case 0x08:  /* ROR ew,1 */
239                         cpustate->CarryVal = tmp & 0x01;
240                         tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
241                         cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
242                         PutbackRMWord(ModRM,tmp2);
243                         break;
244                 case 0x10:  /* RCL ew,1 */
245                         tmp2 = (tmp << 1) + CF;
246                         SetCFW(tmp2);
247                         cpustate->OverVal = (tmp ^ (tmp << 1)) & 0x8000;
248                         PutbackRMWord(ModRM,tmp2);
249                         break;
250                 case 0x18:  /* RCR ew,1 */
251                         tmp2 = (tmp >> 1) + ((unsigned)CF << 15);
252                         cpustate->OverVal = !(!(tmp & 0x8000)) != CF;
253                         cpustate->CarryVal = tmp & 0x01;
254                         PutbackRMWord(ModRM,tmp2);
255                         break;
256                 case 0x20:  /* SHL ew,1 */
257                 case 0x30:
258                         tmp <<= 1;
259
260                         SetCFW(tmp);
261                         SetOFW_Add(tmp,tmp2,tmp2);
262                         cpustate->AuxVal = 1;
263                         SetSZPF_Word(tmp);
264
265                         PutbackRMWord(ModRM,tmp);
266                         break;
267                 case 0x28:  /* SHR ew,1 */
268                         cpustate->CarryVal = tmp & 0x01;
269                         cpustate->OverVal = tmp & 0x8000;
270
271                         tmp2 = tmp >> 1;
272
273                         SetSZPF_Word(tmp2);
274                         cpustate->AuxVal = 1;
275                         PutbackRMWord(ModRM,tmp2);
276                         break;
277                         case 0x38:  /* SAR ew,1 */
278                         cpustate->CarryVal = tmp & 0x01;
279                         cpustate->OverVal = 0;
280
281                         tmp2 = (tmp >> 1) | (tmp & 0x8000);
282
283                         SetSZPF_Word(tmp2);
284                         cpustate->AuxVal = 1;
285                         PutbackRMWord(ModRM,tmp2);
286                         break;
287 #else
288                 case 0x00:  /* ROL ew,1 */
289                         cpustate->CarryVal = src & 0x8000;
290                         dst=(src<<1)+CF;
291                         PutbackRMWord(ModRM,dst);
292                         cpustate->OverVal = (src^dst)&0x8000;
293                         break;
294                 case 0x08:  /* ROR ew,1 */
295                         cpustate->CarryVal = src & 0x01;
296                         dst = ((CF<<16)+src) >> 1;
297                         PutbackRMWord(ModRM,dst);
298                         cpustate->OverVal = (src^dst)&0x8000;
299                         break;
300                 case 0x10:  /* RCL ew,1 */
301                         dst=(src<<1)+CF;
302                         PutbackRMWord(ModRM,dst);
303                         SetCFW(dst);
304                         cpustate->OverVal = (src^dst)&0x8000;
305                         break;
306                 case 0x18:  /* RCR ew,1 */
307                         dst = ((CF<<16)+src) >> 1;
308                         PutbackRMWord(ModRM,dst);
309                         cpustate->CarryVal = src & 0x01;
310                         cpustate->OverVal = (src^dst)&0x8000;
311                         break;
312                 case 0x20:  /* SHL ew,1 */
313                 case 0x30:
314                         dst = src << 1;
315                         PutbackRMWord(ModRM,dst);
316                         SetCFW(dst);
317                         cpustate->OverVal = (src^dst)&0x8000;
318                         cpustate->AuxVal = 1;
319                         SetSZPF_Word(dst);
320                         break;
321                 case 0x28:  /* SHR ew,1 */
322                         dst = src >> 1;
323                         PutbackRMWord(ModRM,dst);
324                         cpustate->CarryVal = src & 0x01;
325                         cpustate->OverVal = src & 0x8000;
326                         cpustate->AuxVal = 1;
327                         SetSZPF_Word(dst);
328                         break;
329                 case 0x38:  /* SAR ew,1 */
330                         dst = ((INT16)src) >> 1;
331                         PutbackRMWord(ModRM,dst);
332                         cpustate->CarryVal = src & 0x01;
333                         cpustate->OverVal = 0;
334                         cpustate->AuxVal = 1;
335                         SetSZPF_Word(dst);
336                         break;
337 #endif
338                 }
339         }
340         else
341         {
342                 int tmpcf = CF;
343                 ICOUNT -= (ModRM >= 0xc0) ? timing.rot_reg_base + (timing.rot_reg_bit * count) : timing.rot_m8_base + (timing.rot_m16_bit * count);
344
345                 switch (ModRM & 0x38)
346                 {
347                 case 0x00:  /* ROL ew,count */
348                         for (; count > 0; count--)
349                         {
350                                 cpustate->CarryVal = dst & 0x8000;
351                                 dst = (dst << 1) + CF;
352                         }
353                         PutbackRMWord(ModRM,dst);
354                         break;
355                 case 0x08:  /* ROR ew,count */
356                         for (; count > 0; count--)
357                         {
358                                 cpustate->CarryVal = dst & 0x01;
359                                 dst = (dst >> 1) + (CF << 15);
360                         }
361                         PutbackRMWord(ModRM,dst);
362                         break;
363                 case 0x10:  /* RCL ew,count */
364                         for (; count > 0; count--)
365                         {
366                                 dst = (dst << 1) + tmpcf;
367                                 tmpcf = (int)((dst & 0x10000) != 0);
368                         }
369                         PutbackRMWord(ModRM,dst);
370                         cpustate->CarryVal = tmpcf;
371                         break;
372                 case 0x18:  /* RCR ew,count */
373                         for (; count > 0; count--)
374                         {
375                                 dst = dst + (tmpcf << 16);
376                                 tmpcf = dst & 0x01;
377                                 dst >>= 1;
378                         }
379                         PutbackRMWord(ModRM,dst);
380                         cpustate->CarryVal = tmpcf;
381                         break;
382                 case 0x20:
383                 case 0x30:  /* SHL ew,count */
384                         for(int i=0;i<count;i++) dst<<= 1;
385                         SetCFW(dst);
386                         cpustate->AuxVal = 1;
387                         SetSZPF_Word(dst);
388                         PutbackRMWord(ModRM,dst);
389                         break;
390                 case 0x28:  /* SHR ew,count */
391                         for(int i=0;i<count-1;i++) dst>>= 1;
392                         cpustate->CarryVal = dst & 0x1;
393                         dst >>= 1;
394                         SetSZPF_Word(dst);
395                         cpustate->AuxVal = 1;
396                         PutbackRMWord(ModRM,dst);
397                         break;
398                 case 0x38:  /* SAR ew,count */
399                         for(int i=0;i<count-1;i++) dst = ((INT16)dst) >> 1;
400                         cpustate->CarryVal = dst & 0x01;
401                         dst = ((INT16)((WORD)dst)) >> 1;
402                         SetSZPF_Word(dst);
403                         cpustate->AuxVal = 1;
404                         PutbackRMWord(ModRM,dst);
405                         break;
406                 }
407         }
408 }
409 #endif
410
411 static void PREFIX(rep)(i8086_state *cpustate,int flagval)
412 {
413         /* Handles rep- and repnz- prefixes. flagval is the value of ZF for the
414              loop  to continue for CMPS and SCAS instructions. */
415
416         unsigned next = FETCHOP;
417
418         switch(next)
419         {
420         case 0x26:  /* ES: */
421                 cpustate->seg_prefix = TRUE;
422                 cpustate->prefix_seg = ES;
423                 if (!cpustate->rep_in_progress)
424                         ICOUNT -= timing.override;
425                 PREFIX(rep)(cpustate, flagval);
426                 break;
427         case 0x2e:  /* CS: */
428                 cpustate->seg_prefix = TRUE;
429                 cpustate->prefix_seg = CS;
430                 if (!cpustate->rep_in_progress)
431                         ICOUNT -= timing.override;
432                 PREFIX(rep)(cpustate, flagval);
433                 break;
434         case 0x36:  /* SS: */
435                 cpustate->seg_prefix = TRUE;
436                 cpustate->prefix_seg = SS;
437                 if (!cpustate->rep_in_progress)
438                         ICOUNT -= timing.override;
439                 PREFIX(rep)(cpustate, flagval);
440                 break;
441         case 0x3e:  /* DS: */
442                 cpustate->seg_prefix = TRUE;
443                 cpustate->prefix_seg = DS;
444                 if (!cpustate->rep_in_progress)
445                         ICOUNT -= timing.override;
446                 PREFIX(rep)(cpustate, flagval);
447                 break;
448 #ifndef I8086
449         case 0x6c:  /* REP INSB */
450 #ifdef I80286
451                 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
452 #endif
453                 if (!cpustate->rep_in_progress)
454                         ICOUNT -= timing.rep_ins8_base;
455                 cpustate->rep_in_progress = FALSE;
456                 while(cpustate->regs.w[CX])
457                 {
458 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
459                         PutMemB(ES,cpustate->regs.w[DI],read_port_byte(cpustate->regs.w[DX]));
460                         cpustate->regs.w[CX]--;
461                         cpustate->regs.w[DI] += cpustate->DirVal;
462                         ICOUNT -= timing.rep_ins8_count;
463                 }
464                 break;
465         case 0x6d:  /* REP INSW */
466 #ifdef I80286
467                 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
468 #endif
469                 if (!cpustate->rep_in_progress)
470                         ICOUNT -= timing.rep_ins16_base;
471                 cpustate->rep_in_progress = FALSE;
472                 while(cpustate->regs.w[CX])
473                 {
474 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
475                         PutMemW(ES,cpustate->regs.w[DI],read_port_word(cpustate->regs.w[DX]));
476                         cpustate->regs.w[CX]--;
477                         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
478                         ICOUNT -= timing.rep_ins16_count;
479                 }
480                 break;
481         case 0x6e:  /* REP OUTSB */
482 #ifdef I80286
483                 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
484 #endif
485                 if (!cpustate->rep_in_progress)
486                         ICOUNT -= timing.rep_outs8_base;
487                 cpustate->rep_in_progress = FALSE;
488                 while(cpustate->regs.w[CX])
489                 {
490 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
491                         write_port_byte(cpustate->regs.w[DX],GetMemB(DS,cpustate->regs.w[SI]));
492                         cpustate->regs.w[CX]--;
493                         cpustate->regs.w[SI] += cpustate->DirVal; /* GOL 11/27/01 */
494                         ICOUNT -= timing.rep_outs8_count;
495                 }
496                 break;
497         case 0x6f:  /* REP OUTSW */
498 #ifdef I80286
499                 if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
500 #endif
501                 if (!cpustate->rep_in_progress)
502                         ICOUNT -= timing.rep_outs16_base;
503                 cpustate->rep_in_progress = FALSE;
504                 while(cpustate->regs.w[CX])
505                 {
506 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
507                         write_port_word(cpustate->regs.w[DX],GetMemW(DS,cpustate->regs.w[SI]));
508                         cpustate->regs.w[CX]--;
509                         cpustate->regs.w[SI] += 2 * cpustate->DirVal; /* GOL 11/27/01 */
510                         ICOUNT -= timing.rep_outs16_count;
511                 }
512                 break;
513 #endif
514         case 0xa4:  /* REP MOVSB */
515                 if (!cpustate->rep_in_progress)
516                         ICOUNT -= timing.rep_movs8_base;
517                 cpustate->rep_in_progress = FALSE;
518                 while(cpustate->regs.w[CX])
519                 {
520                         BYTE tmp;
521
522 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
523                         tmp = GetMemB(DS,cpustate->regs.w[SI]);
524                         PutMemB(ES,cpustate->regs.w[DI], tmp);
525                         cpustate->regs.w[CX]--;
526                         cpustate->regs.w[DI] += cpustate->DirVal;
527                         cpustate->regs.w[SI] += cpustate->DirVal;
528                         ICOUNT -= timing.rep_movs8_count;
529                 }
530                 break;
531         case 0xa5:  /* REP MOVSW */
532                 if (!cpustate->rep_in_progress)
533                         ICOUNT -= timing.rep_movs16_base;
534                 cpustate->rep_in_progress = FALSE;
535                 while(cpustate->regs.w[CX])
536                 {
537                         WORD tmp;
538
539 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
540                         tmp = GetMemW(DS,cpustate->regs.w[SI]);
541                         PutMemW(ES,cpustate->regs.w[DI], tmp);
542                         cpustate->regs.w[CX]--;
543                         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
544                         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
545                         ICOUNT -= timing.rep_movs16_count;
546                 }
547                 break;
548         case 0xa6:  /* REP(N)E CMPSB */
549                 if (!cpustate->rep_in_progress)
550                         ICOUNT -= timing.rep_cmps8_base;
551                 cpustate->rep_in_progress = FALSE;
552                 cpustate->ZeroVal = !flagval;
553                 while(cpustate->regs.w[CX] && (ZF == flagval))
554                 {
555                         unsigned dst, src;
556
557 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
558                         dst = GetMemB(ES, cpustate->regs.w[DI]);
559                         src = GetMemB(DS, cpustate->regs.w[SI]);
560                         SUBB(src,dst); /* opposite of the usual convention */
561                         cpustate->regs.w[CX]--;
562                         cpustate->regs.w[DI] += cpustate->DirVal;
563                         cpustate->regs.w[SI] += cpustate->DirVal;
564                         ICOUNT -= timing.rep_cmps8_count;
565                 }
566                 break;
567         case 0xa7:  /* REP(N)E CMPSW */
568                 if (!cpustate->rep_in_progress)
569                         ICOUNT -= timing.rep_cmps16_base;
570                 cpustate->rep_in_progress = FALSE;
571                 cpustate->ZeroVal = !flagval;
572                 while(cpustate->regs.w[CX] && (ZF == flagval))
573                 {
574                         unsigned dst, src;
575
576 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
577                         dst = GetMemW(ES, cpustate->regs.w[DI]);
578                         src = GetMemW(DS, cpustate->regs.w[SI]);
579                         SUBW(src,dst); /* opposite of the usual convention */
580                         cpustate->regs.w[CX]--;
581                         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
582                         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
583                         ICOUNT -= timing.rep_cmps16_count;
584                 }
585                 break;
586         case 0xaa:  /* REP STOSB */
587                 if (!cpustate->rep_in_progress)
588                         ICOUNT -= timing.rep_stos8_base;
589                 cpustate->rep_in_progress = FALSE;
590                 while(cpustate->regs.w[CX])
591                 {
592 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
593                         PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
594                         cpustate->regs.w[CX]--;
595                         cpustate->regs.w[DI] += cpustate->DirVal;
596                         ICOUNT -= timing.rep_stos8_count;
597                 }
598                 break;
599         case 0xab:  /* REP STOSW */
600                 if (!cpustate->rep_in_progress)
601                         ICOUNT -= timing.rep_stos16_base;
602                 cpustate->rep_in_progress = FALSE;
603                 while(cpustate->regs.w[CX])
604                 {
605 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
606                         PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
607                         cpustate->regs.w[CX]--;
608                         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
609                         ICOUNT -= timing.rep_stos16_count;
610                 }
611                 break;
612         case 0xac:  /* REP LODSB */
613                 if (!cpustate->rep_in_progress)
614                         ICOUNT -= timing.rep_lods8_base;
615                 cpustate->rep_in_progress = FALSE;
616                 while(cpustate->regs.w[CX])
617                 {
618 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
619                         cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
620                         cpustate->regs.w[CX]--;
621                         cpustate->regs.w[SI] += cpustate->DirVal;
622                         ICOUNT -= timing.rep_lods8_count;
623                 }
624                 break;
625         case 0xad:  /* REP LODSW */
626                 if (!cpustate->rep_in_progress)
627                         ICOUNT -= timing.rep_lods16_base;
628                 cpustate->rep_in_progress = FALSE;
629                 while(cpustate->regs.w[CX])
630                 {
631 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
632                         cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
633                         cpustate->regs.w[CX]--;
634                         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
635                         ICOUNT -= timing.rep_lods16_count;
636                 }
637                 break;
638         case 0xae:  /* REP(N)E SCASB */
639                 if (!cpustate->rep_in_progress)
640                         ICOUNT -= timing.rep_scas8_base;
641                 cpustate->rep_in_progress = FALSE;
642                 cpustate->ZeroVal = !flagval;
643                 while(cpustate->regs.w[CX] && (ZF == flagval))
644                 {
645                         unsigned src, dst;
646
647 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
648                         src = GetMemB(ES, cpustate->regs.w[DI]);
649                         dst = cpustate->regs.b[AL];
650                         SUBB(dst,src);
651                         cpustate->regs.w[CX]--;
652                         cpustate->regs.w[DI] += cpustate->DirVal;
653                         ICOUNT -= timing.rep_scas8_count;
654                 }
655                 break;
656         case 0xaf:  /* REP(N)E SCASW */
657                 if (!cpustate->rep_in_progress)
658                         ICOUNT -= timing.rep_scas16_base;
659                 cpustate->rep_in_progress = FALSE;
660                 cpustate->ZeroVal = !flagval;
661                 while(cpustate->regs.w[CX] && (ZF == flagval))
662                 {
663                         unsigned src, dst;
664
665 //                      if (ICOUNT <= 0) { cpustate->pc = cpustate->prevpc; cpustate->rep_in_progress = TRUE; break; }
666                         src = GetMemW(ES, cpustate->regs.w[DI]);
667                         dst = cpustate->regs.w[AX];
668                         SUBW(dst,src);
669                         cpustate->regs.w[CX]--;
670                         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
671                         ICOUNT -= timing.rep_scas16_count;
672                 }
673                 break;
674         default:
675                 PREFIX(_instruction)[next](cpustate);
676         }
677 }
678
679 #ifndef I80186
680 static void PREFIX86(_add_br8)(i8086_state *cpustate)    /* Opcode 0x00 */
681 {
682         DEF_br8(dst,src);
683         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
684         ADDB(dst,src);
685         PutbackRMByte(ModRM,dst);
686 }
687
688 static void PREFIX86(_add_wr16)(i8086_state *cpustate)    /* Opcode 0x01 */
689 {
690         DEF_wr16(dst,src);
691         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
692         ADDW(dst,src);
693         PutbackRMWord(ModRM,dst);
694 }
695
696 static void PREFIX86(_add_r8b)(i8086_state *cpustate)    /* Opcode 0x02 */
697 {
698         DEF_r8b(dst,src);
699         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
700         ADDB(dst,src);
701         RegByte(ModRM)=dst;
702 }
703
704 static void PREFIX86(_add_r16w)(i8086_state *cpustate)    /* Opcode 0x03 */
705 {
706         DEF_r16w(dst,src);
707         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
708         ADDW(dst,src);
709         RegWord(ModRM)=dst;
710 }
711
712
713 static void PREFIX86(_add_ald8)(i8086_state *cpustate)    /* Opcode 0x04 */
714 {
715         DEF_ald8(dst,src);
716         ICOUNT -= timing.alu_ri8;
717         ADDB(dst,src);
718         cpustate->regs.b[AL]=dst;
719 }
720
721
722 static void PREFIX86(_add_axd16)(i8086_state *cpustate)    /* Opcode 0x05 */
723 {
724         DEF_axd16(dst,src);
725         ICOUNT -= timing.alu_ri16;
726         ADDW(dst,src);
727         cpustate->regs.w[AX]=dst;
728 }
729
730
731 static void PREFIX86(_push_es)(i8086_state *cpustate)    /* Opcode 0x06 */
732 {
733         ICOUNT -= timing.push_seg;
734         PUSH(cpustate->sregs[ES]);
735 }
736
737
738 static void PREFIX86(_pop_es)(i8086_state *cpustate)    /* Opcode 0x07 */
739 {
740 #ifdef I80286
741         i80286_pop_seg(cpustate,ES);
742 #else
743         POP(cpustate->sregs[ES]);
744         cpustate->base[ES] = SegBase(ES);
745 #endif
746         ICOUNT -= timing.pop_seg;
747 }
748
749 static void PREFIX86(_or_br8)(i8086_state *cpustate)    /* Opcode 0x08 */
750 {
751         DEF_br8(dst,src);
752         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
753         ORB(dst,src);
754         PutbackRMByte(ModRM,dst);
755 }
756
757 static void PREFIX86(_or_wr16)(i8086_state *cpustate)    /* Opcode 0x09 */
758 {
759         DEF_wr16(dst,src);
760         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
761         ORW(dst,src);
762         PutbackRMWord(ModRM,dst);
763 }
764
765 static void PREFIX86(_or_r8b)(i8086_state *cpustate)    /* Opcode 0x0a */
766 {
767         DEF_r8b(dst,src);
768         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
769         ORB(dst,src);
770         RegByte(ModRM)=dst;
771 }
772
773 static void PREFIX86(_or_r16w)(i8086_state *cpustate)    /* Opcode 0x0b */
774 {
775         DEF_r16w(dst,src);
776         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
777         ORW(dst,src);
778         RegWord(ModRM)=dst;
779 }
780
781 static void PREFIX86(_or_ald8)(i8086_state *cpustate)    /* Opcode 0x0c */
782 {
783         DEF_ald8(dst,src);
784         ICOUNT -= timing.alu_ri8;
785         ORB(dst,src);
786         cpustate->regs.b[AL]=dst;
787 }
788
789 static void PREFIX86(_or_axd16)(i8086_state *cpustate)    /* Opcode 0x0d */
790 {
791         DEF_axd16(dst,src);
792         ICOUNT -= timing.alu_ri16;
793         ORW(dst,src);
794         cpustate->regs.w[AX]=dst;
795 }
796
797 static void PREFIX86(_push_cs)(i8086_state *cpustate)    /* Opcode 0x0e */
798 {
799         ICOUNT -= timing.push_seg;
800         PUSH(cpustate->sregs[CS]);
801 }
802
803 #ifndef I80286
804 static void PREFIX86(_pop_cs)(i8086_state *cpustate)    /* Opcode 0x0f */
805 {
806         int ip = cpustate->pc - cpustate->base[CS];
807         ICOUNT -= timing.push_seg;
808         POP(cpustate->sregs[CS]);
809         cpustate->base[CS] = SegBase(CS);
810         cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
811         CHANGE_PC(cpustate->pc);
812 }
813 #endif
814
815 static void PREFIX86(_adc_br8)(i8086_state *cpustate)    /* Opcode 0x10 */
816 {
817         int tmpcf;
818         DEF_br8(dst,src);
819         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
820         src+=CF;
821         ADCB(dst,src,tmpcf);
822         PutbackRMByte(ModRM,dst);
823         cpustate->CarryVal = tmpcf;
824 }
825
826 static void PREFIX86(_adc_wr16)(i8086_state *cpustate)    /* Opcode 0x11 */
827 {
828         int tmpcf;
829         DEF_wr16(dst,src);
830         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
831         src+=CF;
832         ADCW(dst,src,tmpcf);
833         PutbackRMWord(ModRM,dst);
834         cpustate->CarryVal = tmpcf;
835 }
836
837 static void PREFIX86(_adc_r8b)(i8086_state *cpustate)    /* Opcode 0x12 */
838 {
839         DEF_r8b(dst,src);
840         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
841         src+=CF;
842         ADDB(dst,src);
843         RegByte(ModRM)=dst;
844 }
845
846 static void PREFIX86(_adc_r16w)(i8086_state *cpustate)    /* Opcode 0x13 */
847 {
848         DEF_r16w(dst,src);
849         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
850         src+=CF;
851         ADDW(dst,src);
852         RegWord(ModRM)=dst;
853 }
854
855 static void PREFIX86(_adc_ald8)(i8086_state *cpustate)    /* Opcode 0x14 */
856 {
857         DEF_ald8(dst,src);
858         ICOUNT -= timing.alu_ri8;
859         src+=CF;
860         ADDB(dst,src);
861         cpustate->regs.b[AL] = dst;
862 }
863
864 static void PREFIX86(_adc_axd16)(i8086_state *cpustate)    /* Opcode 0x15 */
865 {
866         DEF_axd16(dst,src);
867         ICOUNT -= timing.alu_ri16;
868         src+=CF;
869         ADDW(dst,src);
870         cpustate->regs.w[AX]=dst;
871 }
872
873 static void PREFIX86(_push_ss)(i8086_state *cpustate)    /* Opcode 0x16 */
874 {
875         PUSH(cpustate->sregs[SS]);
876         ICOUNT -= timing.push_seg;
877 }
878
879 static void PREFIX86(_sbb_br8)(i8086_state *cpustate)    /* Opcode 0x18 */
880 {
881         int tmpcf;
882         DEF_br8(dst,src);
883         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
884         src+=CF;
885         SBBB(dst,src,tmpcf);
886         PutbackRMByte(ModRM,dst);
887         cpustate->CarryVal = tmpcf;
888 }
889
890 static void PREFIX86(_sbb_wr16)(i8086_state *cpustate)    /* Opcode 0x19 */
891 {
892         int tmpcf;
893         DEF_wr16(dst,src);
894         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
895         src+=CF;
896         SBBW(dst,src,tmpcf);
897         PutbackRMWord(ModRM,dst);
898         cpustate->CarryVal = tmpcf;
899 }
900
901 static void PREFIX86(_sbb_r8b)(i8086_state *cpustate)    /* Opcode 0x1a */
902 {
903         DEF_r8b(dst,src);
904         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
905         src+=CF;
906         SUBB(dst,src);
907         RegByte(ModRM)=dst;
908 }
909
910 static void PREFIX86(_sbb_r16w)(i8086_state *cpustate)    /* Opcode 0x1b */
911 {
912         DEF_r16w(dst,src);
913         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
914         src+=CF;
915         SUBW(dst,src);
916         RegWord(ModRM)= dst;
917 }
918
919 static void PREFIX86(_sbb_ald8)(i8086_state *cpustate)    /* Opcode 0x1c */
920 {
921         DEF_ald8(dst,src);
922         ICOUNT -= timing.alu_ri8;
923         src+=CF;
924         SUBB(dst,src);
925         cpustate->regs.b[AL] = dst;
926 }
927
928 static void PREFIX86(_sbb_axd16)(i8086_state *cpustate)    /* Opcode 0x1d */
929 {
930         DEF_axd16(dst,src);
931         ICOUNT -= timing.alu_ri16;
932         src+=CF;
933         SUBW(dst,src);
934         cpustate->regs.w[AX]=dst;
935 }
936
937 static void PREFIX86(_push_ds)(i8086_state *cpustate)    /* Opcode 0x1e */
938 {
939         PUSH(cpustate->sregs[DS]);
940         ICOUNT -= timing.push_seg;
941 }
942
943 static void PREFIX86(_pop_ds)(i8086_state *cpustate)    /* Opcode 0x1f */
944 {
945 #ifdef I80286
946         i80286_pop_seg(cpustate,DS);
947 #else
948         POP(cpustate->sregs[DS]);
949         cpustate->base[DS] = SegBase(DS);
950 #endif
951         ICOUNT -= timing.push_seg;
952 }
953
954 static void PREFIX86(_and_br8)(i8086_state *cpustate)    /* Opcode 0x20 */
955 {
956         DEF_br8(dst,src);
957         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
958         ANDB(dst,src);
959         PutbackRMByte(ModRM,dst);
960 }
961
962 static void PREFIX86(_and_wr16)(i8086_state *cpustate)    /* Opcode 0x21 */
963 {
964         DEF_wr16(dst,src);
965         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
966         ANDW(dst,src);
967         PutbackRMWord(ModRM,dst);
968 }
969
970 static void PREFIX86(_and_r8b)(i8086_state *cpustate)    /* Opcode 0x22 */
971 {
972         DEF_r8b(dst,src);
973         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
974         ANDB(dst,src);
975         RegByte(ModRM)=dst;
976 }
977
978 static void PREFIX86(_and_r16w)(i8086_state *cpustate)    /* Opcode 0x23 */
979 {
980         DEF_r16w(dst,src);
981         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
982         ANDW(dst,src);
983         RegWord(ModRM)=dst;
984 }
985
986 static void PREFIX86(_and_ald8)(i8086_state *cpustate)    /* Opcode 0x24 */
987 {
988         DEF_ald8(dst,src);
989         ICOUNT -= timing.alu_ri8;
990         ANDB(dst,src);
991         cpustate->regs.b[AL] = dst;
992 }
993
994 static void PREFIX86(_and_axd16)(i8086_state *cpustate)    /* Opcode 0x25 */
995 {
996         DEF_axd16(dst,src);
997         ICOUNT -= timing.alu_ri16;
998         ANDW(dst,src);
999         cpustate->regs.w[AX]=dst;
1000 }
1001
1002 static void PREFIX86(_daa)(i8086_state *cpustate)    /* Opcode 0x27 */
1003 {
1004         if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
1005         {
1006                 int tmp;
1007                 cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] + 6;
1008                 cpustate->AuxVal = 1;
1009                 cpustate->CarryVal |= tmp & 0x100;
1010         }
1011
1012         if (CF || (cpustate->regs.b[AL] > 0x9f))
1013         {
1014                 cpustate->regs.b[AL] += 0x60;
1015                 cpustate->CarryVal = 1;
1016         }
1017
1018         SetSZPF_Byte(cpustate->regs.b[AL]);
1019         ICOUNT -= timing.daa;
1020 }
1021
1022 static void PREFIX86(_sub_br8)(i8086_state *cpustate)    /* Opcode 0x28 */
1023 {
1024         DEF_br8(dst,src);
1025         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
1026         SUBB(dst,src);
1027         PutbackRMByte(ModRM,dst);
1028 }
1029
1030 static void PREFIX86(_sub_wr16)(i8086_state *cpustate)    /* Opcode 0x29 */
1031 {
1032         DEF_wr16(dst,src);
1033         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
1034         SUBW(dst,src);
1035         PutbackRMWord(ModRM,dst);
1036 }
1037
1038 static void PREFIX86(_sub_r8b)(i8086_state *cpustate)    /* Opcode 0x2a */
1039 {
1040         DEF_r8b(dst,src);
1041         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
1042         SUBB(dst,src);
1043         RegByte(ModRM)=dst;
1044 }
1045
1046 static void PREFIX86(_sub_r16w)(i8086_state *cpustate)    /* Opcode 0x2b */
1047 {
1048         DEF_r16w(dst,src);
1049         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
1050         SUBW(dst,src);
1051         RegWord(ModRM)=dst;
1052 }
1053
1054 static void PREFIX86(_sub_ald8)(i8086_state *cpustate)    /* Opcode 0x2c */
1055 {
1056         DEF_ald8(dst,src);
1057         ICOUNT -= timing.alu_ri8;
1058         SUBB(dst,src);
1059         cpustate->regs.b[AL] = dst;
1060 }
1061
1062 static void PREFIX86(_sub_axd16)(i8086_state *cpustate)    /* Opcode 0x2d */
1063 {
1064         DEF_axd16(dst,src);
1065         ICOUNT -= timing.alu_ri16;
1066         SUBW(dst,src);
1067         cpustate->regs.w[AX]=dst;
1068 }
1069
1070 static void PREFIX86(_das)(i8086_state *cpustate)    /* Opcode 0x2f */
1071 {
1072         UINT8 tmpAL=cpustate->regs.b[AL];
1073         if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
1074         {
1075                 int tmp;
1076                 cpustate->regs.b[AL] = tmp = cpustate->regs.b[AL] - 6;
1077                 cpustate->AuxVal = 1;
1078                 cpustate->CarryVal |= tmp & 0x100;
1079         }
1080
1081         if (CF || (tmpAL > 0x9f))
1082         {
1083                 cpustate->regs.b[AL] -= 0x60;
1084                 cpustate->CarryVal = 1;
1085         }
1086
1087         SetSZPF_Byte(cpustate->regs.b[AL]);
1088         ICOUNT -= timing.das;
1089 }
1090
1091 static void PREFIX86(_xor_br8)(i8086_state *cpustate)    /* Opcode 0x30 */
1092 {
1093         DEF_br8(dst,src);
1094         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_mr8;
1095         XORB(dst,src);
1096         PutbackRMByte(ModRM,dst);
1097 }
1098
1099 static void PREFIX86(_xor_wr16)(i8086_state *cpustate)    /* Opcode 0x31 */
1100 {
1101         DEF_wr16(dst,src);
1102         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_mr16;
1103         XORW(dst,src);
1104         PutbackRMWord(ModRM,dst);
1105 }
1106
1107 static void PREFIX86(_xor_r8b)(i8086_state *cpustate)    /* Opcode 0x32 */
1108 {
1109         DEF_r8b(dst,src);
1110         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
1111         XORB(dst,src);
1112         RegByte(ModRM)=dst;
1113 }
1114
1115 static void PREFIX86(_xor_r16w)(i8086_state *cpustate)    /* Opcode 0x33 */
1116 {
1117         DEF_r16w(dst,src);
1118         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
1119         XORW(dst,src);
1120         RegWord(ModRM)=dst;
1121 }
1122
1123 static void PREFIX86(_xor_ald8)(i8086_state *cpustate)    /* Opcode 0x34 */
1124 {
1125         DEF_ald8(dst,src);
1126         ICOUNT -= timing.alu_ri8;
1127         XORB(dst,src);
1128         cpustate->regs.b[AL] = dst;
1129 }
1130
1131 static void PREFIX86(_xor_axd16)(i8086_state *cpustate)    /* Opcode 0x35 */
1132 {
1133         DEF_axd16(dst,src);
1134         ICOUNT -= timing.alu_ri16;
1135         XORW(dst,src);
1136         cpustate->regs.w[AX]=dst;
1137 }
1138
1139 static void PREFIX86(_aaa)(i8086_state *cpustate)    /* Opcode 0x37 */
1140 {
1141         UINT8 ALcarry=1;
1142         if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
1143
1144         if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
1145         {
1146                 cpustate->regs.b[AL] += 6;
1147                 cpustate->regs.b[AH] += ALcarry;
1148                 cpustate->AuxVal = 1;
1149                 cpustate->CarryVal = 1;
1150         }
1151         else
1152         {
1153                 cpustate->AuxVal = 0;
1154                 cpustate->CarryVal = 0;
1155         }
1156         cpustate->regs.b[AL] &= 0x0F;
1157         ICOUNT -= timing.aaa;
1158 }
1159
1160 static void PREFIX86(_cmp_br8)(i8086_state *cpustate)    /* Opcode 0x38 */
1161 {
1162         DEF_br8(dst,src);
1163         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
1164         SUBB(dst,src);
1165 }
1166
1167 static void PREFIX86(_cmp_wr16)(i8086_state *cpustate)    /* Opcode 0x39 */
1168 {
1169         DEF_wr16(dst,src);
1170         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
1171         SUBW(dst,src);
1172 }
1173
1174 static void PREFIX86(_cmp_r8b)(i8086_state *cpustate)    /* Opcode 0x3a */
1175 {
1176         DEF_r8b(dst,src);
1177         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
1178         SUBB(dst,src);
1179 }
1180
1181 static void PREFIX86(_cmp_r16w)(i8086_state *cpustate)    /* Opcode 0x3b */
1182 {
1183         DEF_r16w(dst,src);
1184         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
1185         SUBW(dst,src);
1186 }
1187
1188 static void PREFIX86(_cmp_ald8)(i8086_state *cpustate)    /* Opcode 0x3c */
1189 {
1190         DEF_ald8(dst,src);
1191         ICOUNT -= timing.alu_ri8;
1192         SUBB(dst,src);
1193 }
1194
1195 static void PREFIX86(_cmp_axd16)(i8086_state *cpustate)    /* Opcode 0x3d */
1196 {
1197         DEF_axd16(dst,src);
1198         ICOUNT -= timing.alu_ri16;
1199         SUBW(dst,src);
1200 }
1201
1202 static void PREFIX86(_aas)(i8086_state *cpustate)    /* Opcode 0x3f */
1203 {
1204 //  UINT8 ALcarry=1;
1205 //  if (cpustate->regs.b[AL]>0xf9) ALcarry=2;
1206
1207         if (AF || ((cpustate->regs.b[AL] & 0xf) > 9))
1208         {
1209                 cpustate->regs.b[AL] -= 6;
1210                 cpustate->regs.b[AH] -= 1;
1211                 cpustate->AuxVal = 1;
1212                 cpustate->CarryVal = 1;
1213         }
1214         else
1215         {
1216                 cpustate->AuxVal = 0;
1217                 cpustate->CarryVal = 0;
1218         }
1219         cpustate->regs.b[AL] &= 0x0F;
1220         ICOUNT -= timing.aas;
1221 }
1222
1223 #define IncWordReg(Reg)                     \
1224 {                                           \
1225         unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
1226         unsigned tmp1 = tmp+1;                  \
1227         SetOFW_Add(tmp1,tmp,1);                 \
1228         SetAF(tmp1,tmp,1);                      \
1229         SetSZPF_Word(tmp1);                     \
1230         cpustate->regs.w[Reg]=tmp1;                     \
1231         ICOUNT -= timing.incdec_r16;            \
1232 }
1233
1234 static void PREFIX86(_inc_ax)(i8086_state *cpustate)    /* Opcode 0x40 */
1235 {
1236         IncWordReg(AX);
1237 }
1238
1239 static void PREFIX86(_inc_cx)(i8086_state *cpustate)    /* Opcode 0x41 */
1240 {
1241         IncWordReg(CX);
1242 }
1243
1244 static void PREFIX86(_inc_dx)(i8086_state *cpustate)    /* Opcode 0x42 */
1245 {
1246         IncWordReg(DX);
1247 }
1248
1249 static void PREFIX(_inc_bx)(i8086_state *cpustate)    /* Opcode 0x43 */
1250 {
1251         IncWordReg(BX);
1252 }
1253
1254 static void PREFIX86(_inc_sp)(i8086_state *cpustate)    /* Opcode 0x44 */
1255 {
1256         IncWordReg(SP);
1257 }
1258
1259 static void PREFIX86(_inc_bp)(i8086_state *cpustate)    /* Opcode 0x45 */
1260 {
1261         IncWordReg(BP);
1262 }
1263
1264 static void PREFIX86(_inc_si)(i8086_state *cpustate)    /* Opcode 0x46 */
1265 {
1266         IncWordReg(SI);
1267 }
1268
1269 static void PREFIX86(_inc_di)(i8086_state *cpustate)    /* Opcode 0x47 */
1270 {
1271         IncWordReg(DI);
1272 }
1273
1274 #define DecWordReg(Reg)                     \
1275 {                                           \
1276         unsigned tmp = (unsigned)cpustate->regs.w[Reg]; \
1277         unsigned tmp1 = tmp-1;                  \
1278         SetOFW_Sub(tmp1,1,tmp);                 \
1279         SetAF(tmp1,tmp,1);                      \
1280         SetSZPF_Word(tmp1);                     \
1281         cpustate->regs.w[Reg]=tmp1;                     \
1282         ICOUNT -= timing.incdec_r16;            \
1283 }
1284
1285 static void PREFIX86(_dec_ax)(i8086_state *cpustate)    /* Opcode 0x48 */
1286 {
1287         DecWordReg(AX);
1288 }
1289
1290 static void PREFIX86(_dec_cx)(i8086_state *cpustate)    /* Opcode 0x49 */
1291 {
1292         DecWordReg(CX);
1293 }
1294
1295 static void PREFIX86(_dec_dx)(i8086_state *cpustate)    /* Opcode 0x4a */
1296 {
1297         DecWordReg(DX);
1298 }
1299
1300 static void PREFIX86(_dec_bx)(i8086_state *cpustate)    /* Opcode 0x4b */
1301 {
1302         DecWordReg(BX);
1303 }
1304
1305 static void PREFIX86(_dec_sp)(i8086_state *cpustate)    /* Opcode 0x4c */
1306 {
1307         DecWordReg(SP);
1308 }
1309
1310 static void PREFIX86(_dec_bp)(i8086_state *cpustate)    /* Opcode 0x4d */
1311 {
1312         DecWordReg(BP);
1313 }
1314
1315 static void PREFIX86(_dec_si)(i8086_state *cpustate)    /* Opcode 0x4e */
1316 {
1317         DecWordReg(SI);
1318 }
1319
1320 static void PREFIX86(_dec_di)(i8086_state *cpustate)    /* Opcode 0x4f */
1321 {
1322         DecWordReg(DI);
1323 }
1324
1325 static void PREFIX86(_push_ax)(i8086_state *cpustate)    /* Opcode 0x50 */
1326 {
1327         ICOUNT -= timing.push_r16;
1328         PUSH(cpustate->regs.w[AX]);
1329 }
1330
1331 static void PREFIX86(_push_cx)(i8086_state *cpustate)    /* Opcode 0x51 */
1332 {
1333         ICOUNT -= timing.push_r16;
1334         PUSH(cpustate->regs.w[CX]);
1335 }
1336
1337 static void PREFIX86(_push_dx)(i8086_state *cpustate)    /* Opcode 0x52 */
1338 {
1339         ICOUNT -= timing.push_r16;
1340         PUSH(cpustate->regs.w[DX]);
1341 }
1342
1343 static void PREFIX86(_push_bx)(i8086_state *cpustate)    /* Opcode 0x53 */
1344 {
1345         ICOUNT -= timing.push_r16;
1346         PUSH(cpustate->regs.w[BX]);
1347 }
1348
1349 static void PREFIX86(_push_sp)(i8086_state *cpustate)    /* Opcode 0x54 */
1350 {
1351         ICOUNT -= timing.push_r16;
1352 #ifdef I80286
1353         PUSH(cpustate->regs.w[SP]+2);
1354 #else
1355         PUSH(cpustate->regs.w[SP]);
1356 #endif
1357 }
1358
1359 static void PREFIX86(_push_bp)(i8086_state *cpustate)    /* Opcode 0x55 */
1360 {
1361         ICOUNT -= timing.push_r16;
1362         PUSH(cpustate->regs.w[BP]);
1363 }
1364
1365
1366 static void PREFIX86(_push_si)(i8086_state *cpustate)    /* Opcode 0x56 */
1367 {
1368         ICOUNT -= timing.push_r16;
1369         PUSH(cpustate->regs.w[SI]);
1370 }
1371
1372 static void PREFIX86(_push_di)(i8086_state *cpustate)    /* Opcode 0x57 */
1373 {
1374         ICOUNT -= timing.push_r16;
1375         PUSH(cpustate->regs.w[DI]);
1376 }
1377
1378 static void PREFIX86(_pop_ax)(i8086_state *cpustate)    /* Opcode 0x58 */
1379 {
1380         ICOUNT -= timing.pop_r16;
1381         POP(cpustate->regs.w[AX]);
1382 }
1383
1384 static void PREFIX86(_pop_cx)(i8086_state *cpustate)    /* Opcode 0x59 */
1385 {
1386         ICOUNT -= timing.pop_r16;
1387         POP(cpustate->regs.w[CX]);
1388 }
1389
1390 static void PREFIX86(_pop_dx)(i8086_state *cpustate)    /* Opcode 0x5a */
1391 {
1392         ICOUNT -= timing.pop_r16;
1393         POP(cpustate->regs.w[DX]);
1394 }
1395
1396 static void PREFIX86(_pop_bx)(i8086_state *cpustate)    /* Opcode 0x5b */
1397 {
1398         ICOUNT -= timing.pop_r16;
1399         POP(cpustate->regs.w[BX]);
1400 }
1401
1402 static void PREFIX86(_pop_sp)(i8086_state *cpustate)    /* Opcode 0x5c */
1403 {
1404         ICOUNT -= timing.pop_r16;
1405         POP(cpustate->regs.w[SP]);
1406 }
1407
1408 static void PREFIX86(_pop_bp)(i8086_state *cpustate)    /* Opcode 0x5d */
1409 {
1410         ICOUNT -= timing.pop_r16;
1411         POP(cpustate->regs.w[BP]);
1412 }
1413
1414 static void PREFIX86(_pop_si)(i8086_state *cpustate)    /* Opcode 0x5e */
1415 {
1416         ICOUNT -= timing.pop_r16;
1417         POP(cpustate->regs.w[SI]);
1418 }
1419
1420 static void PREFIX86(_pop_di)(i8086_state *cpustate)    /* Opcode 0x5f */
1421 {
1422         ICOUNT -= timing.pop_r16;
1423         POP(cpustate->regs.w[DI]);
1424 }
1425
1426 static void PREFIX86(_jo)(i8086_state *cpustate)    /* Opcode 0x70 */
1427 {
1428         int tmp = (int)((INT8)FETCH);
1429         if (OF)
1430         {
1431                 cpustate->pc += tmp;
1432                 ICOUNT -= timing.jcc_t;
1433 /* ASG - can probably assume this is safe
1434         CHANGE_PC(cpustate->pc);*/
1435         } else ICOUNT -= timing.jcc_nt;
1436 }
1437
1438 static void PREFIX86(_jno)(i8086_state *cpustate)    /* Opcode 0x71 */
1439 {
1440         int tmp = (int)((INT8)FETCH);
1441         if (!OF) {
1442                 cpustate->pc += tmp;
1443                 ICOUNT -= timing.jcc_t;
1444 /* ASG - can probably assume this is safe
1445         CHANGE_PC(cpustate->pc);*/
1446         } else ICOUNT -= timing.jcc_nt;
1447 }
1448
1449 static void PREFIX86(_jb)(i8086_state *cpustate)    /* Opcode 0x72 */
1450 {
1451         int tmp = (int)((INT8)FETCH);
1452         if (CF) {
1453                 cpustate->pc += tmp;
1454                 ICOUNT -= timing.jcc_t;
1455 /* ASG - can probably assume this is safe
1456         CHANGE_PC(cpustate->pc);*/
1457         } else ICOUNT -= timing.jcc_nt;
1458 }
1459
1460 static void PREFIX86(_jnb)(i8086_state *cpustate)    /* Opcode 0x73 */
1461 {
1462         int tmp = (int)((INT8)FETCH);
1463         if (!CF) {
1464                 cpustate->pc += tmp;
1465                 ICOUNT -= timing.jcc_t;
1466 /* ASG - can probably assume this is safe
1467         CHANGE_PC(cpustate->pc);*/
1468         } else ICOUNT -= timing.jcc_nt;
1469 }
1470
1471 static void PREFIX86(_jz)(i8086_state *cpustate)    /* Opcode 0x74 */
1472 {
1473         int tmp = (int)((INT8)FETCH);
1474         if (ZF) {
1475                 cpustate->pc += tmp;
1476                 ICOUNT -= timing.jcc_t;
1477 /* ASG - can probably assume this is safe
1478         CHANGE_PC(cpustate->pc);*/
1479         } else ICOUNT -= timing.jcc_nt;
1480 }
1481
1482 static void PREFIX86(_jnz)(i8086_state *cpustate)    /* Opcode 0x75 */
1483 {
1484         int tmp = (int)((INT8)FETCH);
1485         if (!ZF) {
1486                 cpustate->pc += tmp;
1487                 ICOUNT -= timing.jcc_t;
1488 /* ASG - can probably assume this is safe
1489         CHANGE_PC(cpustate->pc);*/
1490         } else ICOUNT -= timing.jcc_nt;
1491 }
1492
1493 static void PREFIX86(_jbe)(i8086_state *cpustate)    /* Opcode 0x76 */
1494 {
1495         int tmp = (int)((INT8)FETCH);
1496         if (CF || ZF) {
1497                 cpustate->pc += tmp;
1498                 ICOUNT -= timing.jcc_t;
1499 /* ASG - can probably assume this is safe
1500         CHANGE_PC(cpustate->pc);*/
1501         } else ICOUNT -= timing.jcc_nt;
1502 }
1503
1504 static void PREFIX86(_jnbe)(i8086_state *cpustate)    /* Opcode 0x77 */
1505 {
1506         int tmp = (int)((INT8)FETCH);
1507         if (!(CF || ZF)) {
1508                 cpustate->pc += tmp;
1509                 ICOUNT -= timing.jcc_t;
1510 /* ASG - can probably assume this is safe
1511         CHANGE_PC(cpustate->pc);*/
1512         } else ICOUNT -= timing.jcc_nt;
1513 }
1514
1515 static void PREFIX86(_js)(i8086_state *cpustate)    /* Opcode 0x78 */
1516 {
1517         int tmp = (int)((INT8)FETCH);
1518         if (SF) {
1519                 cpustate->pc += tmp;
1520                 ICOUNT -= timing.jcc_t;
1521 /* ASG - can probably assume this is safe
1522         CHANGE_PC(cpustate->pc);*/
1523         } else ICOUNT -= timing.jcc_nt;
1524 }
1525
1526 static void PREFIX86(_jns)(i8086_state *cpustate)    /* Opcode 0x79 */
1527 {
1528         int tmp = (int)((INT8)FETCH);
1529         if (!SF) {
1530                 cpustate->pc += tmp;
1531                 ICOUNT -= timing.jcc_t;
1532 /* ASG - can probably assume this is safe
1533         CHANGE_PC(cpustate->pc);*/
1534         } else ICOUNT -= timing.jcc_nt;
1535 }
1536
1537 static void PREFIX86(_jp)(i8086_state *cpustate)    /* Opcode 0x7a */
1538 {
1539         int tmp = (int)((INT8)FETCH);
1540         if (PF) {
1541                 cpustate->pc += tmp;
1542                 ICOUNT -= timing.jcc_t;
1543 /* ASG - can probably assume this is safe
1544         CHANGE_PC(cpustate->pc);*/
1545         } else ICOUNT -= timing.jcc_nt;
1546 }
1547
1548 static void PREFIX86(_jnp)(i8086_state *cpustate)    /* Opcode 0x7b */
1549 {
1550         int tmp = (int)((INT8)FETCH);
1551         if (!PF) {
1552                 cpustate->pc += tmp;
1553                 ICOUNT -= timing.jcc_t;
1554 /* ASG - can probably assume this is safe
1555         CHANGE_PC(cpustate->pc);*/
1556         } else ICOUNT -= timing.jcc_nt;
1557 }
1558
1559 static void PREFIX86(_jl)(i8086_state *cpustate)    /* Opcode 0x7c */
1560 {
1561         int tmp = (int)((INT8)FETCH);
1562         if ((SF!=OF)&&!ZF) {
1563                 cpustate->pc += tmp;
1564                 ICOUNT -= timing.jcc_t;
1565 /* ASG - can probably assume this is safe
1566         CHANGE_PC(cpustate->pc);*/
1567         } else ICOUNT -= timing.jcc_nt;
1568 }
1569
1570 static void PREFIX86(_jnl)(i8086_state *cpustate)    /* Opcode 0x7d */
1571 {
1572         int tmp = (int)((INT8)FETCH);
1573 //      if (ZF||(SF==OF)) {
1574         if (SF==OF) {
1575                 cpustate->pc += tmp;
1576                 ICOUNT -= timing.jcc_t;
1577 /* ASG - can probably assume this is safe
1578         CHANGE_PC(cpustate->pc);*/
1579         } else ICOUNT -= timing.jcc_nt;
1580 }
1581
1582 static void PREFIX86(_jle)(i8086_state *cpustate)    /* Opcode 0x7e */
1583 {
1584         int tmp = (int)((INT8)FETCH);
1585         if (ZF||(SF!=OF)) {
1586                 cpustate->pc += tmp;
1587                 ICOUNT -= timing.jcc_t;
1588 /* ASG - can probably assume this is safe
1589         CHANGE_PC(cpustate->pc);*/
1590         } else ICOUNT -= timing.jcc_nt;
1591 }
1592
1593 static void PREFIX86(_jnle)(i8086_state *cpustate)    /* Opcode 0x7f */
1594 {
1595         int tmp = (int)((INT8)FETCH);
1596         if ((SF==OF)&&!ZF) {
1597                 cpustate->pc += tmp;
1598                 ICOUNT -= timing.jcc_t;
1599 /* ASG - can probably assume this is safe
1600         CHANGE_PC(cpustate->pc);*/
1601         } else ICOUNT -= timing.jcc_nt;
1602 }
1603
1604 static void PREFIX86(_80pre)(i8086_state *cpustate)    /* Opcode 0x80 */
1605 {
1606         unsigned ModRM = FETCHOP;
1607         unsigned dst = GetRMByte(ModRM);
1608         unsigned src = FETCH;
1609         int tmpcf;
1610
1611         switch (ModRM & 0x38)
1612         {
1613         case 0x00:  /* ADD eb,d8 */
1614                 ADDB(dst,src);
1615                 PutbackRMByte(ModRM,dst);
1616                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1617                 break;
1618         case 0x08:  /* OR eb,d8 */
1619                 ORB(dst,src);
1620                 PutbackRMByte(ModRM,dst);
1621                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1622                 break;
1623         case 0x10:  /* ADC eb,d8 */
1624                 src+=CF;
1625                 ADCB(dst,src,tmpcf);
1626                 PutbackRMByte(ModRM,dst);
1627                 cpustate->CarryVal = tmpcf;
1628                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1629                 break;
1630         case 0x18:  /* SBB eb,b8 */
1631                 src+=CF;
1632                 SBBB(dst,src,tmpcf);
1633                 PutbackRMByte(ModRM,dst);
1634                 cpustate->CarryVal = tmpcf;
1635                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1636                 break;
1637         case 0x20:  /* AND eb,d8 */
1638                 ANDB(dst,src);
1639                 PutbackRMByte(ModRM,dst);
1640                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1641                 break;
1642         case 0x28:  /* SUB eb,d8 */
1643                 SUBB(dst,src);
1644                 PutbackRMByte(ModRM,dst);
1645                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1646                 break;
1647         case 0x30:  /* XOR eb,d8 */
1648                 XORB(dst,src);
1649                 PutbackRMByte(ModRM,dst);
1650                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1651                 break;
1652         case 0x38:  /* CMP eb,d8 */
1653                 SUBB(dst,src);
1654                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
1655                 break;
1656         }
1657 }
1658
1659
1660 static void PREFIX86(_81pre)(i8086_state *cpustate)    /* Opcode 0x81 */
1661 {
1662         unsigned ModRM = FETCH;
1663         unsigned dst = GetRMWord(ModRM);
1664         unsigned src = FETCH;
1665         int tmpcf;
1666         src+= (FETCH << 8);
1667
1668         switch (ModRM & 0x38)
1669         {
1670         case 0x00:  /* ADD ew,d16 */
1671                 ADDW(dst,src);
1672                 PutbackRMWord(ModRM,dst);
1673                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1674                 break;
1675         case 0x08:  /* OR ew,d16 */
1676                 ORW(dst,src);
1677                 PutbackRMWord(ModRM,dst);
1678                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1679                 break;
1680         case 0x10:  /* ADC ew,d16 */
1681                 src+=CF;
1682                 ADCW(dst,src,tmpcf);
1683                 PutbackRMWord(ModRM,dst);
1684                 cpustate->CarryVal = tmpcf;
1685                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1686                 break;
1687         case 0x18:  /* SBB ew,d16 */
1688                 src+=CF;
1689                 SBBW(dst,src,tmpcf);
1690                 PutbackRMWord(ModRM,dst);
1691                 cpustate->CarryVal = tmpcf;
1692                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1693                 break;
1694         case 0x20:  /* AND ew,d16 */
1695                 ANDW(dst,src);
1696                 PutbackRMWord(ModRM,dst);
1697                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1698                 break;
1699         case 0x28:  /* SUB ew,d16 */
1700                 SUBW(dst,src);
1701                 PutbackRMWord(ModRM,dst);
1702                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1703                 break;
1704         case 0x30:  /* XOR ew,d16 */
1705                 XORW(dst,src);
1706                 PutbackRMWord(ModRM,dst);
1707                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16;
1708                 break;
1709         case 0x38:  /* CMP ew,d16 */
1710                 SUBW(dst,src);
1711                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
1712                 break;
1713         }
1714 }
1715
1716 static void PREFIX86(_82pre)(i8086_state *cpustate)  /* Opcode 0x82 */
1717 {
1718         unsigned ModRM = FETCH;
1719         unsigned dst = GetRMByte(ModRM);
1720         unsigned src = FETCH;
1721         int tmpcf;
1722
1723         switch (ModRM & 0x38)
1724         {
1725         case 0x00:  /* ADD eb,d8 */
1726                 ADDB(dst,src);
1727                 PutbackRMByte(ModRM,dst);
1728                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1729                 break;
1730         case 0x08:  /* OR eb,d8 */
1731                 ORB(dst,src);
1732                 PutbackRMByte(ModRM,dst);
1733                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1734                 break;
1735         case 0x10:  /* ADC eb,d8 */
1736                 src+=CF;
1737                 ADCB(dst,src,tmpcf);
1738                 PutbackRMByte(ModRM,dst);
1739                 cpustate->CarryVal = tmpcf;
1740                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1741                 break;
1742         case 0x18:  /* SBB eb,d8 */
1743                 src+=CF;
1744                 SBBB(dst,src,tmpcf);
1745                 PutbackRMByte(ModRM,dst);
1746                 cpustate->CarryVal = tmpcf;
1747                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1748                 break;
1749         case 0x20:  /* AND eb,d8 */
1750                 ANDB(dst,src);
1751                 PutbackRMByte(ModRM,dst);
1752                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1753                 break;
1754         case 0x28:  /* SUB eb,d8 */
1755                 SUBB(dst,src);
1756                 PutbackRMByte(ModRM,dst);
1757                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1758                 break;
1759         case 0x30:  /* XOR eb,d8 */
1760                 XORB(dst,src);
1761                 PutbackRMByte(ModRM,dst);
1762                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8;
1763                 break;
1764         case 0x38:  /* CMP eb,d8 */
1765                 SUBB(dst,src);
1766                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
1767                 break;
1768         }
1769 }
1770
1771 static void PREFIX86(_83pre)(i8086_state *cpustate)    /* Opcode 0x83 */
1772 {
1773         unsigned ModRM = FETCH;
1774         unsigned dst = GetRMWord(ModRM);
1775         unsigned src = (WORD)((INT16)((INT8)FETCH));
1776         int tmpcf;
1777
1778         switch (ModRM & 0x38)
1779         {
1780         case 0x00:  /* ADD ew,d16 */
1781                 ADDW(dst,src);
1782                 PutbackRMWord(ModRM,dst);
1783                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1784                 break;
1785         case 0x08:  /* OR ew,d16 */
1786                 ORW(dst,src);
1787                 PutbackRMWord(ModRM,dst);
1788                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1789                 break;
1790         case 0x10:  /* ADC ew,d16 */
1791                 src+=CF;
1792                 ADCW(dst,src,tmpcf);
1793                 PutbackRMWord(ModRM,dst);
1794                 cpustate->CarryVal = tmpcf;
1795                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1796                 break;
1797         case 0x18:  /* SBB ew,d16 */
1798                 src+=CF;
1799                 SBBW(dst,src,tmpcf);
1800                 PutbackRMWord(ModRM,dst);
1801                 cpustate->CarryVal = tmpcf;
1802                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1803                 break;
1804         case 0x20:  /* AND ew,d16 */
1805                 ANDW(dst,src);
1806                 PutbackRMWord(ModRM,dst);
1807                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1808                 break;
1809         case 0x28:  /* SUB ew,d16 */
1810                 SUBW(dst,src);
1811                 PutbackRMWord(ModRM,dst);
1812                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1813                 break;
1814         case 0x30:  /* XOR ew,d16 */
1815                 XORW(dst,src);
1816                 PutbackRMWord(ModRM,dst);
1817                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8;
1818                 break;
1819         case 0x38:  /* CMP ew,d16 */
1820                 SUBW(dst,src);
1821                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_r16i8 : timing.alu_m16i8_ro;
1822                 break;
1823         }
1824 }
1825
1826 static void PREFIX86(_test_br8)(i8086_state *cpustate)    /* Opcode 0x84 */
1827 {
1828         DEF_br8(dst,src);
1829         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr8 : timing.alu_rm8;
1830         ANDB(dst,src);
1831 }
1832
1833 static void PREFIX86(_test_wr16)(i8086_state *cpustate)    /* Opcode 0x85 */
1834 {
1835         DEF_wr16(dst,src);
1836         ICOUNT -= (ModRM >= 0xc0) ? timing.alu_rr16 : timing.alu_rm16;
1837         ANDW(dst,src);
1838 }
1839
1840 static void PREFIX86(_xchg_br8)(i8086_state *cpustate)    /* Opcode 0x86 */
1841 {
1842         DEF_br8(dst,src);
1843         ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr8 : timing.xchg_rm8;
1844         PutbackRMByte(ModRM,src);
1845         RegByte(ModRM)=dst;
1846 }
1847
1848 static void PREFIX86(_xchg_wr16)(i8086_state *cpustate)    /* Opcode 0x87 */
1849 {
1850         DEF_wr16(dst,src);
1851         ICOUNT -= (ModRM >= 0xc0) ? timing.xchg_rr16 : timing.xchg_rm16;
1852         PutbackRMWord(ModRM,src);
1853         RegWord(ModRM)=dst;
1854 }
1855
1856 static void PREFIX86(_mov_br8)(i8086_state *cpustate)    /* Opcode 0x88 */
1857 {
1858         unsigned ModRM = FETCH;
1859         BYTE src = RegByte(ModRM);
1860         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_mr8;
1861         PutRMByte(ModRM,src);
1862 }
1863
1864 static void PREFIX86(_mov_wr16)(i8086_state *cpustate)    /* Opcode 0x89 */
1865 {
1866         unsigned ModRM = FETCH;
1867         WORD src = RegWord(ModRM);
1868         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr16 : timing.mov_mr16;
1869         PutRMWord(ModRM,src);
1870 }
1871
1872 static void PREFIX86(_mov_r8b)(i8086_state *cpustate)    /* Opcode 0x8a */
1873 {
1874         unsigned ModRM = FETCH;
1875         BYTE src = GetRMByte(ModRM);
1876         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm8;
1877         RegByte(ModRM)=src;
1878 }
1879
1880 static void PREFIX86(_mov_r16w)(i8086_state *cpustate)    /* Opcode 0x8b */
1881 {
1882         unsigned ModRM = FETCH;
1883         WORD src = GetRMWord(ModRM);
1884         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rr8 : timing.mov_rm16;
1885         RegWord(ModRM)=src;
1886 }
1887
1888 static void PREFIX86(_mov_wsreg)(i8086_state *cpustate)    /* Opcode 0x8c */
1889 {
1890         unsigned ModRM = FETCH;
1891         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_rs : timing.mov_ms;
1892 #ifndef I8086
1893         if (ModRM & 0x20) { /* HJB 12/13/98 1xx is invalid */
1894                 cpustate->pc = cpustate->prevpc;
1895                 return PREFIX86(_invalid)(cpustate);
1896         }
1897
1898         PutRMWord(ModRM,cpustate->sregs[(ModRM & 0x38) >> 3]);
1899 #else
1900         PutRMWord(ModRM,cpustate->sregs[(ModRM & 0x18) >> 3]); /* confirmed on hw: modrm bit 5 ignored */
1901 #endif
1902 }
1903
1904 static void PREFIX86(_lea)(i8086_state *cpustate)    /* Opcode 0x8d */
1905 {
1906         unsigned ModRM = FETCH;
1907         ICOUNT -= timing.lea;
1908         (void)(*GetEA[ModRM])(cpustate);
1909         RegWord(ModRM)=cpustate->eo;    /* HJB 12/13/98 effective offset (no segment part) */
1910 }
1911
1912 static void PREFIX86(_popw)(i8086_state *cpustate)    /* Opcode 0x8f */
1913 {
1914         unsigned ModRM = FETCH;
1915                 WORD tmp;
1916         tmp = ReadWord(cpustate->base[SS] + cpustate->regs.w[SP]);
1917         ICOUNT -= (ModRM >= 0xc0) ? timing.pop_r16 : timing.pop_m16;
1918         PutRMWord(ModRM,tmp);
1919         cpustate->regs.w[SP] += 2;
1920 }
1921
1922
1923 #define XchgAXReg(Reg)              \
1924 {                                   \
1925         WORD tmp;                       \
1926         tmp = cpustate->regs.w[Reg];            \
1927         cpustate->regs.w[Reg] = cpustate->regs.w[AX];   \
1928         cpustate->regs.w[AX] = tmp;             \
1929         ICOUNT -= timing.xchg_ar16;     \
1930 }
1931
1932
1933 static void PREFIX86(_nop)(i8086_state *cpustate)    /* Opcode 0x90 */
1934 {
1935         /* this is XchgAXReg(AX); */
1936         ICOUNT -= timing.nop;
1937 }
1938
1939 static void PREFIX86(_xchg_axcx)(i8086_state *cpustate)    /* Opcode 0x91 */
1940 {
1941         XchgAXReg(CX);
1942 }
1943
1944 static void PREFIX86(_xchg_axdx)(i8086_state *cpustate)    /* Opcode 0x92 */
1945 {
1946         XchgAXReg(DX);
1947 }
1948
1949 static void PREFIX86(_xchg_axbx)(i8086_state *cpustate)    /* Opcode 0x93 */
1950 {
1951         XchgAXReg(BX);
1952 }
1953
1954 static void PREFIX86(_xchg_axsp)(i8086_state *cpustate)    /* Opcode 0x94 */
1955 {
1956         XchgAXReg(SP);
1957 }
1958
1959 static void PREFIX86(_xchg_axbp)(i8086_state *cpustate)    /* Opcode 0x95 */
1960 {
1961         XchgAXReg(BP);
1962 }
1963
1964 static void PREFIX86(_xchg_axsi)(i8086_state *cpustate)    /* Opcode 0x96 */
1965 {
1966         XchgAXReg(SI);
1967 }
1968
1969 static void PREFIX86(_xchg_axdi)(i8086_state *cpustate)    /* Opcode 0x97 */
1970 {
1971         XchgAXReg(DI);
1972 }
1973
1974 static void PREFIX86(_cbw)(i8086_state *cpustate)    /* Opcode 0x98 */
1975 {
1976         ICOUNT -= timing.cbw;
1977         cpustate->regs.b[AH] = (cpustate->regs.b[AL] & 0x80) ? 0xff : 0;
1978 }
1979
1980 static void PREFIX86(_cwd)(i8086_state *cpustate)    /* Opcode 0x99 */
1981 {
1982         ICOUNT -= timing.cwd;
1983         cpustate->regs.w[DX] = (cpustate->regs.b[AH] & 0x80) ? 0xffff : 0;
1984 }
1985
1986 static void PREFIX86(_call_far)(i8086_state *cpustate)
1987 {
1988         unsigned int tmp, tmp2;
1989         WORD cs, ip;
1990
1991         tmp = FETCH;
1992         tmp += FETCH << 8;
1993
1994         tmp2 = FETCH;
1995         tmp2 += FETCH << 8;
1996
1997         ICOUNT -= timing.call_far;
1998         if(BIOS_CALL_86(cpustate, ((tmp2 << 4) + tmp) & AMASK)) {
1999                 ICOUNT -= timing.ret_far;
2000                 return;
2001         }
2002
2003         ip = cpustate->pc - cpustate->base[CS];
2004         cs = cpustate->sregs[CS];
2005
2006 #ifdef I80286
2007         i80286_code_descriptor(cpustate, tmp2, tmp, 2);
2008 #else
2009         cpustate->sregs[CS] = (WORD)tmp2;
2010         cpustate->base[CS] = SegBase(CS);
2011         cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
2012 #endif
2013         PUSH(cs);
2014         PUSH(ip);
2015         CHANGE_PC(cpustate->pc);
2016 }
2017
2018 static void PREFIX86(_wait)(i8086_state *cpustate)    /* Opcode 0x9b */
2019 {
2020 #ifdef I80286
2021         if ((cpustate->msw&0x0a) == 0x0a) throw TRAP(FPU_UNAVAILABLE,-1);
2022 #endif
2023         if (cpustate->test_state)
2024         {
2025                 ICOUNT = 0;
2026                 cpustate->pc--;
2027         }
2028         else
2029                 ICOUNT -= timing.wait;
2030 }
2031
2032 static void PREFIX86(_pushf)(i8086_state *cpustate)    /* Opcode 0x9c */
2033 {
2034         unsigned tmp;
2035         ICOUNT -= timing.pushf;
2036
2037         tmp = CompressFlags();
2038 #ifdef I80286
2039         if(!PM) ( tmp &= ~0xf000 );
2040 #endif
2041         PUSH( tmp );
2042 }
2043
2044 #ifndef I80286
2045 static void PREFIX86(_popf)(i8086_state *cpustate)    /* Opcode 0x9d */
2046 {
2047         unsigned tmp;
2048         POP(tmp);
2049         ICOUNT -= timing.popf;
2050
2051         ExpandFlags(tmp);
2052         cpustate->flags = tmp;
2053         cpustate->flags = CompressFlags();
2054
2055         if (cpustate->TF) PREFIX(_trap)(cpustate);
2056
2057         /* if the IF is set, and an interrupt is pending, signal an interrupt */
2058         if (cpustate->IF && cpustate->irq_state) {
2059                 PREFIX(_interrupt)(cpustate, (UINT32)-1);
2060                 cpustate->irq_state = 0;
2061         }
2062 }
2063 #endif
2064
2065 static void PREFIX86(_sahf)(i8086_state *cpustate)    /* Opcode 0x9e */
2066 {
2067         unsigned tmp = (CompressFlags() & 0xff00) | (cpustate->regs.b[AH] & 0xd5);
2068         ICOUNT -= timing.sahf;
2069         ExpandFlags(tmp);
2070 }
2071
2072 static void PREFIX86(_lahf)(i8086_state *cpustate)    /* Opcode 0x9f */
2073 {
2074         cpustate->regs.b[AH] = CompressFlags() & 0xff;
2075         ICOUNT -= timing.lahf;
2076 }
2077
2078
2079 static void PREFIX86(_mov_aldisp)(i8086_state *cpustate)    /* Opcode 0xa0 */
2080 {
2081         unsigned addr;
2082
2083         addr = FETCH;
2084         addr += FETCH << 8;
2085
2086         ICOUNT -= timing.mov_am8;
2087         cpustate->regs.b[AL] = GetMemB(DS, addr);
2088 }
2089
2090 static void PREFIX86(_mov_axdisp)(i8086_state *cpustate)    /* Opcode 0xa1 */
2091 {
2092         unsigned addr;
2093
2094         addr = FETCH;
2095         addr += FETCH << 8;
2096
2097         ICOUNT -= timing.mov_am16;
2098         cpustate->regs.w[AX] = GetMemW(DS, addr);
2099 }
2100
2101 static void PREFIX86(_mov_dispal)(i8086_state *cpustate)    /* Opcode 0xa2 */
2102 {
2103         unsigned addr;
2104
2105         addr = FETCH;
2106         addr += FETCH << 8;
2107
2108         ICOUNT -= timing.mov_ma8;
2109         PutMemB(DS, addr, cpustate->regs.b[AL]);
2110 }
2111
2112 static void PREFIX86(_mov_dispax)(i8086_state *cpustate)    /* Opcode 0xa3 */
2113 {
2114         unsigned addr;
2115
2116         addr = FETCH;
2117         addr += FETCH << 8;
2118
2119         ICOUNT -= timing.mov_ma16;
2120         PutMemW(DS, addr, cpustate->regs.w[AX]);
2121 }
2122
2123 static void PREFIX86(_movsb)(i8086_state *cpustate)    /* Opcode 0xa4 */
2124 {
2125         BYTE tmp = GetMemB(DS,cpustate->regs.w[SI]);
2126         PutMemB(ES,cpustate->regs.w[DI], tmp);
2127         cpustate->regs.w[DI] += cpustate->DirVal;
2128         cpustate->regs.w[SI] += cpustate->DirVal;
2129         ICOUNT -= timing.movs8;
2130 }
2131
2132 static void PREFIX86(_movsw)(i8086_state *cpustate)    /* Opcode 0xa5 */
2133 {
2134         WORD tmp = GetMemW(DS,cpustate->regs.w[SI]);
2135         PutMemW(ES,cpustate->regs.w[DI], tmp);
2136         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
2137         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
2138         ICOUNT -= timing.movs16;
2139 }
2140
2141 static void PREFIX86(_cmpsb)(i8086_state *cpustate)    /* Opcode 0xa6 */
2142 {
2143         unsigned dst = GetMemB(ES, cpustate->regs.w[DI]);
2144         unsigned src = GetMemB(DS, cpustate->regs.w[SI]);
2145         SUBB(src,dst); /* opposite of the usual convention */
2146         cpustate->regs.w[DI] += cpustate->DirVal;
2147         cpustate->regs.w[SI] += cpustate->DirVal;
2148         ICOUNT -= timing.cmps8;
2149 }
2150
2151 static void PREFIX86(_cmpsw)(i8086_state *cpustate)    /* Opcode 0xa7 */
2152 {
2153         unsigned dst = GetMemW(ES, cpustate->regs.w[DI]);
2154         unsigned src = GetMemW(DS, cpustate->regs.w[SI]);
2155         SUBW(src,dst); /* opposite of the usual convention */
2156         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
2157         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
2158         ICOUNT -= timing.cmps16;
2159 }
2160
2161 static void PREFIX86(_test_ald8)(i8086_state *cpustate)    /* Opcode 0xa8 */
2162 {
2163         DEF_ald8(dst,src);
2164         ICOUNT -= timing.alu_ri8;
2165         ANDB(dst,src);
2166 }
2167
2168 static void PREFIX86(_test_axd16)(i8086_state *cpustate)    /* Opcode 0xa9 */
2169 {
2170         DEF_axd16(dst,src);
2171         ICOUNT -= timing.alu_ri16;
2172         ANDW(dst,src);
2173 }
2174
2175 static void PREFIX86(_stosb)(i8086_state *cpustate)    /* Opcode 0xaa */
2176 {
2177         PutMemB(ES,cpustate->regs.w[DI],cpustate->regs.b[AL]);
2178         cpustate->regs.w[DI] += cpustate->DirVal;
2179         ICOUNT -= timing.stos8;
2180 }
2181
2182 static void PREFIX86(_stosw)(i8086_state *cpustate)    /* Opcode 0xab */
2183 {
2184         PutMemW(ES,cpustate->regs.w[DI],cpustate->regs.w[AX]);
2185         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
2186         ICOUNT -= timing.stos16;
2187 }
2188
2189 static void PREFIX86(_lodsb)(i8086_state *cpustate)    /* Opcode 0xac */
2190 {
2191         cpustate->regs.b[AL] = GetMemB(DS,cpustate->regs.w[SI]);
2192         cpustate->regs.w[SI] += cpustate->DirVal;
2193         ICOUNT -= timing.lods8;
2194 }
2195
2196 static void PREFIX86(_lodsw)(i8086_state *cpustate)    /* Opcode 0xad */
2197 {
2198         cpustate->regs.w[AX] = GetMemW(DS,cpustate->regs.w[SI]);
2199         cpustate->regs.w[SI] += 2 * cpustate->DirVal;
2200         ICOUNT -= timing.lods16;
2201 }
2202
2203 static void PREFIX86(_scasb)(i8086_state *cpustate)    /* Opcode 0xae */
2204 {
2205         unsigned src = GetMemB(ES, cpustate->regs.w[DI]);
2206         unsigned dst = cpustate->regs.b[AL];
2207         SUBB(dst,src);
2208         cpustate->regs.w[DI] += cpustate->DirVal;
2209         ICOUNT -= timing.scas8;
2210 }
2211
2212 static void PREFIX86(_scasw)(i8086_state *cpustate)    /* Opcode 0xaf */
2213 {
2214         unsigned src = GetMemW(ES, cpustate->regs.w[DI]);
2215         unsigned dst = cpustate->regs.w[AX];
2216         SUBW(dst,src);
2217         cpustate->regs.w[DI] += 2 * cpustate->DirVal;
2218         ICOUNT -= timing.scas16;
2219 }
2220
2221 static void PREFIX86(_mov_ald8)(i8086_state *cpustate)    /* Opcode 0xb0 */
2222 {
2223         cpustate->regs.b[AL] = FETCH;
2224         ICOUNT -= timing.mov_ri8;
2225 }
2226
2227 static void PREFIX86(_mov_cld8)(i8086_state *cpustate)    /* Opcode 0xb1 */
2228 {
2229         cpustate->regs.b[CL] = FETCH;
2230         ICOUNT -= timing.mov_ri8;
2231 }
2232
2233 static void PREFIX86(_mov_dld8)(i8086_state *cpustate)    /* Opcode 0xb2 */
2234 {
2235         cpustate->regs.b[DL] = FETCH;
2236         ICOUNT -= timing.mov_ri8;
2237 }
2238
2239 static void PREFIX86(_mov_bld8)(i8086_state *cpustate)    /* Opcode 0xb3 */
2240 {
2241         cpustate->regs.b[BL] = FETCH;
2242         ICOUNT -= timing.mov_ri8;
2243 }
2244
2245 static void PREFIX86(_mov_ahd8)(i8086_state *cpustate)    /* Opcode 0xb4 */
2246 {
2247         cpustate->regs.b[AH] = FETCH;
2248         ICOUNT -= timing.mov_ri8;
2249 }
2250
2251 static void PREFIX86(_mov_chd8)(i8086_state *cpustate)    /* Opcode 0xb5 */
2252 {
2253         cpustate->regs.b[CH] = FETCH;
2254         ICOUNT -= timing.mov_ri8;
2255 }
2256
2257 static void PREFIX86(_mov_dhd8)(i8086_state *cpustate)    /* Opcode 0xb6 */
2258 {
2259         cpustate->regs.b[DH] = FETCH;
2260         ICOUNT -= timing.mov_ri8;
2261 }
2262
2263 static void PREFIX86(_mov_bhd8)(i8086_state *cpustate)    /* Opcode 0xb7 */
2264 {
2265         cpustate->regs.b[BH] = FETCH;
2266         ICOUNT -= timing.mov_ri8;
2267 }
2268
2269 static void PREFIX86(_mov_axd16)(i8086_state *cpustate)    /* Opcode 0xb8 */
2270 {
2271         cpustate->regs.b[AL] = FETCH;
2272         cpustate->regs.b[AH] = FETCH;
2273         ICOUNT -= timing.mov_ri16;
2274 }
2275
2276 static void PREFIX86(_mov_cxd16)(i8086_state *cpustate)    /* Opcode 0xb9 */
2277 {
2278         cpustate->regs.b[CL] = FETCH;
2279         cpustate->regs.b[CH] = FETCH;
2280         ICOUNT -= timing.mov_ri16;
2281 }
2282
2283 static void PREFIX86(_mov_dxd16)(i8086_state *cpustate)    /* Opcode 0xba */
2284 {
2285         cpustate->regs.b[DL] = FETCH;
2286         cpustate->regs.b[DH] = FETCH;
2287         ICOUNT -= timing.mov_ri16;
2288 }
2289
2290 static void PREFIX86(_mov_bxd16)(i8086_state *cpustate)    /* Opcode 0xbb */
2291 {
2292         cpustate->regs.b[BL] = FETCH;
2293         cpustate->regs.b[BH] = FETCH;
2294         ICOUNT -= timing.mov_ri16;
2295 }
2296
2297 static void PREFIX86(_mov_spd16)(i8086_state *cpustate)    /* Opcode 0xbc */
2298 {
2299         cpustate->regs.b[SPL] = FETCH;
2300         cpustate->regs.b[SPH] = FETCH;
2301         ICOUNT -= timing.mov_ri16;
2302 }
2303
2304 static void PREFIX86(_mov_bpd16)(i8086_state *cpustate)    /* Opcode 0xbd */
2305 {
2306         cpustate->regs.b[BPL] = FETCH;
2307         cpustate->regs.b[BPH] = FETCH;
2308         ICOUNT -= timing.mov_ri16;
2309 }
2310
2311 static void PREFIX86(_mov_sid16)(i8086_state *cpustate)    /* Opcode 0xbe */
2312 {
2313         cpustate->regs.b[SIL] = FETCH;
2314         cpustate->regs.b[SIH] = FETCH;
2315         ICOUNT -= timing.mov_ri16;
2316 }
2317
2318 static void PREFIX86(_mov_did16)(i8086_state *cpustate)    /* Opcode 0xbf */
2319 {
2320         cpustate->regs.b[DIL] = FETCH;
2321         cpustate->regs.b[DIH] = FETCH;
2322         ICOUNT -= timing.mov_ri16;
2323 }
2324
2325 static void PREFIX86(_ret_d16)(i8086_state *cpustate)    /* Opcode 0xc2 */
2326 {
2327         unsigned count = FETCH;
2328         count += FETCH << 8;
2329         POP(cpustate->pc);
2330         cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
2331         cpustate->regs.w[SP]+=count;
2332         ICOUNT -= timing.ret_near_imm;
2333         CHANGE_PC(cpustate->pc);
2334 }
2335
2336 static void PREFIX86(_ret)(i8086_state *cpustate)    /* Opcode 0xc3 */
2337 {
2338         POP(cpustate->pc);
2339         cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
2340         ICOUNT -= timing.ret_near;
2341         CHANGE_PC(cpustate->pc);
2342 }
2343
2344 static void PREFIX86(_les_dw)(i8086_state *cpustate)    /* Opcode 0xc4 */
2345 {
2346         unsigned ModRM = FETCH;
2347         WORD tmp = GetRMWord(ModRM);
2348
2349 #ifdef I80286
2350         i80286_data_descriptor(cpustate,ES,GetnextRMWord);
2351 #else
2352         cpustate->sregs[ES] = GetnextRMWord;
2353         cpustate->base[ES] = SegBase(ES);
2354 #endif
2355         RegWord(ModRM)= tmp;
2356         ICOUNT -= timing.load_ptr;
2357 }
2358
2359 static void PREFIX86(_lds_dw)(i8086_state *cpustate)    /* Opcode 0xc5 */
2360 {
2361         unsigned ModRM = FETCH;
2362         WORD tmp = GetRMWord(ModRM);
2363
2364 #ifdef I80286
2365         i80286_data_descriptor(cpustate,DS,GetnextRMWord);
2366 #else
2367         cpustate->sregs[DS] = GetnextRMWord;
2368         cpustate->base[DS] = SegBase(DS);
2369 #endif
2370         RegWord(ModRM)=tmp;
2371         ICOUNT -= timing.load_ptr;
2372 }
2373
2374 static void PREFIX86(_mov_bd8)(i8086_state *cpustate)    /* Opcode 0xc6 */
2375 {
2376         unsigned ModRM = FETCH;
2377         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri8 : timing.mov_mi8;
2378         PutImmRMByte(ModRM);
2379 }
2380
2381 static void PREFIX86(_mov_wd16)(i8086_state *cpustate)    /* Opcode 0xc7 */
2382 {
2383         unsigned ModRM = FETCH;
2384         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_ri16 : timing.mov_mi16;
2385         PutImmRMWord(ModRM);
2386 }
2387
2388 #ifndef I80286
2389 static void PREFIX86(_retf_d16)(i8086_state *cpustate)    /* Opcode 0xca */
2390 {
2391         unsigned count = FETCH;
2392         count += FETCH << 8;
2393
2394         POP(cpustate->pc);
2395         POP(cpustate->sregs[CS]);
2396         cpustate->base[CS] = SegBase(CS);
2397         cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
2398         cpustate->regs.w[SP]+=count;
2399         ICOUNT -= timing.ret_far_imm;
2400         CHANGE_PC(cpustate->pc);
2401 }
2402
2403 static void PREFIX86(_retf)(i8086_state *cpustate)    /* Opcode 0xcb */
2404 {
2405         POP(cpustate->pc);
2406         POP(cpustate->sregs[CS]);
2407         cpustate->base[CS] = SegBase(CS);
2408         cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
2409         ICOUNT -= timing.ret_far;
2410         CHANGE_PC(cpustate->pc);
2411 }
2412 #endif
2413
2414 static void PREFIX86(_int3)(i8086_state *cpustate)    /* Opcode 0xcc */
2415 {
2416         ICOUNT -= timing.int3;
2417         PREFIX(_interrupt)(cpustate, 3);
2418 }
2419
2420 #ifdef I80286
2421 extern void i80286_code_descriptor(i80286_state *cpustate, UINT16 selector, UINT16 offset, int gate);
2422 #endif
2423 static void PREFIX86(_int)(i8086_state *cpustate)    /* Opcode 0xcd */
2424 {
2425         unsigned int_num = FETCH;
2426         ICOUNT -= timing.int_imm;
2427
2428 #ifdef I86_PSEUDO_BIOS
2429         cpustate->regs.w[8] = 0x0000;
2430         cpustate->regs.w[9] = 0x0000;
2431         if(cpustate->bios != NULL && cpustate->bios->bios_int_i86(int_num, cpustate->regs.w, cpustate->sregs, &cpustate->ZeroVal, &cpustate->CarryVal, &(cpustate->icount), &(cpustate->total_icount))) {
2432                 ICOUNT -= timing.iret;
2433 #if 1           
2434                 if((cpustate->regs.w[8] != 0x0000) || (cpustate->regs.w[9] != 0x0000)) {
2435                         UINT32 hi = cpustate->regs.w[9];
2436                         UINT32 lo = cpustate->regs.w[8];
2437                         UINT32 addr = (hi << 16) | lo;
2438 #ifdef I80286
2439                         i80286_code_descriptor(cpustate, cpustate->sregs[1],lo, 1);
2440 #else
2441                         cpustate->base[CS] = SegBase(CS);
2442                         cpustate->pc = (cpustate->base[CS] + addr) & AMASK;
2443 #endif
2444                         //printf("PC=%04x:%04x\n", cpustate->sregs[CS], cpustate->pc);
2445                 }
2446 #endif
2447                 return;
2448         }
2449 #endif
2450         PREFIX(_interrupt)(cpustate, int_num);
2451 }
2452
2453 static void PREFIX86(_into)(i8086_state *cpustate)    /* Opcode 0xce */
2454 {
2455         if (OF) {
2456                 ICOUNT -= timing.into_t;
2457                 PREFIX(_interrupt)(cpustate, 4);
2458         } else ICOUNT -= timing.into_nt;
2459 }
2460
2461 #ifndef I80286
2462 static void PREFIX86(_iret)(i8086_state *cpustate)    /* Opcode 0xcf */
2463 {
2464         ICOUNT -= timing.iret;
2465         POP(cpustate->pc);
2466         POP(cpustate->sregs[CS]);
2467         cpustate->base[CS] = SegBase(CS);
2468         cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
2469                 PREFIX(_popf)(cpustate);
2470         CHANGE_PC(cpustate->pc);
2471
2472         /* if the IF is set, and an interrupt is pending, signal an interrupt */
2473         if (cpustate->IF && cpustate->irq_state) {
2474                 PREFIX(_interrupt)(cpustate, (UINT32)-1);
2475                 cpustate->irq_state = 0;
2476         }
2477 }
2478 #endif
2479
2480 static void PREFIX86(_rotshft_b)(i8086_state *cpustate)    /* Opcode 0xd0 */
2481 {
2482         unsigned ModRM = FETCHOP;
2483         PREFIX(_rotate_shift_Byte)(cpustate,ModRM,1,GetRMByte(ModRM));
2484 }
2485
2486
2487 static void PREFIX86(_rotshft_w)(i8086_state *cpustate)    /* Opcode 0xd1 */
2488 {
2489         unsigned ModRM = FETCHOP;
2490         PREFIX(_rotate_shift_Word)(cpustate,ModRM,1,GetRMWord(ModRM));
2491 }
2492
2493
2494 #ifdef I8086
2495 static void PREFIX86(_rotshft_bcl)(i8086_state *cpustate)    /* Opcode 0xd2 */
2496 {
2497         unsigned ModRM = FETCHOP;
2498         PREFIX(_rotate_shift_Byte)(cpustate,ModRM,cpustate->regs.b[CL],GetRMByte(ModRM));
2499 }
2500
2501 static void PREFIX86(_rotshft_wcl)(i8086_state *cpustate)    /* Opcode 0xd3 */
2502 {
2503         unsigned ModRM = FETCHOP;
2504         PREFIX(_rotate_shift_Word)(cpustate,ModRM,cpustate->regs.b[CL],GetRMWord(ModRM));
2505 }
2506 #endif
2507
2508 /* OB: Opcode works on NEC V-Series but not the Variants              */
2509 /*     one could specify any byte value as operand but the NECs */
2510 /*     always substitute 0x0a.              */
2511 static void PREFIX86(_aam)(i8086_state *cpustate)    /* Opcode 0xd4 */
2512 {
2513         unsigned mult = FETCH;
2514
2515         ICOUNT -= timing.aam;
2516         if (mult == 0)
2517                 PREFIX(_interrupt)(cpustate, 0);
2518         else
2519         {
2520                 cpustate->regs.b[AH] = cpustate->regs.b[AL] / mult;
2521                 cpustate->regs.b[AL] %= mult;
2522
2523                 SetSZPF_Word(cpustate->regs.w[AX]);
2524         }
2525 }
2526
2527 static void PREFIX86(_aad)(i8086_state *cpustate)    /* Opcode 0xd5 */
2528 {
2529         unsigned mult = FETCH;
2530
2531         ICOUNT -= timing.aad;
2532
2533         cpustate->regs.b[AL] = cpustate->regs.b[AH] * mult + cpustate->regs.b[AL];
2534         cpustate->regs.b[AH] = 0;
2535
2536         SetZF(cpustate->regs.b[AL]);
2537         SetPF(cpustate->regs.b[AL]);
2538         cpustate->SignVal = 0;
2539 }
2540
2541
2542 static void PREFIX86(_xlat)(i8086_state *cpustate)    /* Opcode 0xd7 */
2543 {
2544         unsigned dest = cpustate->regs.w[BX]+cpustate->regs.b[AL];
2545
2546         ICOUNT -= timing.xlat;
2547         cpustate->regs.b[AL] = GetMemB(DS, dest);
2548 }
2549
2550 #ifndef I80286
2551 static void PREFIX86(_escape)(i8086_state *cpustate)    /* Opcodes 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde and 0xdf */
2552 {
2553         unsigned ModRM = FETCH;
2554         ICOUNT -= timing.nop;
2555         GetRMByte(ModRM);
2556 }
2557 #endif
2558
2559 static void PREFIX86(_loopne)(i8086_state *cpustate)    /* Opcode 0xe0 */
2560 {
2561         int disp = (int)((INT8)FETCH);
2562         unsigned tmp = cpustate->regs.w[CX]-1;
2563
2564         cpustate->regs.w[CX]=tmp;
2565
2566         if (!ZF && tmp) {
2567                 ICOUNT -= timing.loop_t;
2568                 cpustate->pc += disp;
2569 /* ASG - can probably assume this is safe
2570         CHANGE_PC(cpustate->pc);*/
2571         } else ICOUNT -= timing.loop_nt;
2572 }
2573
2574 static void PREFIX86(_loope)(i8086_state *cpustate)    /* Opcode 0xe1 */
2575 {
2576         int disp = (int)((INT8)FETCH);
2577         unsigned tmp = cpustate->regs.w[CX]-1;
2578
2579         cpustate->regs.w[CX]=tmp;
2580
2581         if (ZF && tmp) {
2582                 ICOUNT -= timing.loope_t;
2583                         cpustate->pc += disp;
2584 /* ASG - can probably assume this is safe
2585          CHANGE_PC(cpustate->pc);*/
2586         } else ICOUNT -= timing.loope_nt;
2587 }
2588
2589 static void PREFIX86(_loop)(i8086_state *cpustate)    /* Opcode 0xe2 */
2590 {
2591         int disp = (int)((INT8)FETCH);
2592         unsigned tmp = cpustate->regs.w[CX]-1;
2593
2594         cpustate->regs.w[CX]=tmp;
2595
2596         if (tmp) {
2597                 ICOUNT -= timing.loop_t;
2598                 cpustate->pc += disp;
2599 /* ASG - can probably assume this is safe
2600         CHANGE_PC(cpustate->pc);*/
2601         } else ICOUNT -= timing.loop_nt;
2602 }
2603
2604 static void PREFIX86(_jcxz)(i8086_state *cpustate)    /* Opcode 0xe3 */
2605 {
2606         int disp = (int)((INT8)FETCH);
2607
2608         if (cpustate->regs.w[CX] == 0) {
2609                 ICOUNT -= timing.jcxz_t;
2610                 cpustate->pc += disp;
2611 /* ASG - can probably assume this is safe
2612         CHANGE_PC(cpustate->pc);*/
2613         } else
2614                 ICOUNT -= timing.jcxz_nt;
2615 }
2616
2617 static void PREFIX86(_inal)(i8086_state *cpustate)    /* Opcode 0xe4 */
2618 {
2619         unsigned port;
2620 #ifdef I80286
2621         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2622 #endif
2623         port = FETCH;
2624
2625         ICOUNT -= timing.in_imm8;
2626         cpustate->regs.b[AL] = read_port_byte(port);
2627 }
2628
2629 static void PREFIX86(_inax)(i8086_state *cpustate)    /* Opcode 0xe5 */
2630 {
2631         unsigned port;
2632 #ifdef I80286
2633         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2634 #endif
2635         port = FETCH;
2636
2637         ICOUNT -= timing.in_imm16;
2638         cpustate->regs.w[AX] = read_port_word(port);
2639 }
2640
2641 static void PREFIX86(_outal)(i8086_state *cpustate)    /* Opcode 0xe6 */
2642 {
2643         unsigned port;
2644 #ifdef I80286
2645         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2646 #endif
2647         port = FETCH;
2648
2649         ICOUNT -= timing.out_imm8;
2650         write_port_byte(port, cpustate->regs.b[AL]);
2651 }
2652
2653 static void PREFIX86(_outax)(i8086_state *cpustate)    /* Opcode 0xe7 */
2654 {
2655         unsigned port;
2656 #ifdef I80286
2657         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2658 #endif
2659         port = FETCH;
2660
2661         ICOUNT -= timing.out_imm16;
2662         write_port_word(port, cpustate->regs.w[AX]);
2663 }
2664
2665 static void PREFIX86(_call_d16)(i8086_state *cpustate)    /* Opcode 0xe8 */
2666 {
2667         WORD ip, tmp;
2668
2669         FETCHWORD(tmp);
2670         ip = cpustate->pc - cpustate->base[CS];
2671         PUSH(ip);
2672         ip += tmp;
2673         cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
2674         ICOUNT -= timing.call_near;
2675         CHANGE_PC(cpustate->pc);
2676 }
2677
2678 static void PREFIX86(_jmp_d16)(i8086_state *cpustate)    /* Opcode 0xe9 */
2679 {
2680         WORD ip, tmp;
2681
2682         FETCHWORD(tmp);
2683         ip = cpustate->pc - cpustate->base[CS] + tmp;
2684         cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
2685         ICOUNT -= timing.jmp_near;
2686         CHANGE_PC(cpustate->pc);
2687 }
2688
2689 static void PREFIX86(_jmp_far)(i8086_state *cpustate)    /* Opcode 0xea */
2690 {
2691         unsigned tmp,tmp1;
2692
2693         tmp = FETCH;
2694         tmp += FETCH << 8;
2695
2696         tmp1 = FETCH;
2697         tmp1 += FETCH << 8;
2698
2699 #ifdef I80286
2700         i80286_code_descriptor(cpustate, tmp1,tmp, 1);
2701 #else
2702         cpustate->sregs[CS] = (WORD)tmp1;
2703         cpustate->base[CS] = SegBase(CS);
2704         cpustate->pc = (cpustate->base[CS] + tmp) & AMASK;
2705 #endif
2706         ICOUNT -= timing.jmp_far;
2707         CHANGE_PC(cpustate->pc);
2708 }
2709
2710 static void PREFIX86(_jmp_d8)(i8086_state *cpustate)    /* Opcode 0xeb */
2711 {
2712         int tmp = (int)((INT8)FETCH);
2713         cpustate->pc += tmp;
2714 /* ASG - can probably assume this is safe
2715     CHANGE_PC(cpustate->pc);*/
2716         ICOUNT -= timing.jmp_short;
2717 }
2718
2719 static void PREFIX86(_inaldx)(i8086_state *cpustate)    /* Opcode 0xec */
2720 {
2721 #ifdef I80286
2722         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2723 #endif
2724         ICOUNT -= timing.in_dx8;
2725         cpustate->regs.b[AL] = read_port_byte(cpustate->regs.w[DX]);
2726 }
2727
2728 static void PREFIX86(_inaxdx)(i8086_state *cpustate)    /* Opcode 0xed */
2729 {
2730         unsigned port = cpustate->regs.w[DX];
2731 #ifdef I80286
2732         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2733 #endif
2734         ICOUNT -= timing.in_dx16;
2735         cpustate->regs.w[AX] = read_port_word(port);
2736 }
2737
2738 static void PREFIX86(_outdxal)(i8086_state *cpustate)    /* Opcode 0xee */
2739 {
2740 #ifdef I80286
2741         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2742 #endif
2743         ICOUNT -= timing.out_dx8;
2744         write_port_byte(cpustate->regs.w[DX], cpustate->regs.b[AL]);
2745 }
2746
2747 static void PREFIX86(_outdxax)(i8086_state *cpustate)    /* Opcode 0xef */
2748 {
2749         unsigned port = cpustate->regs.w[DX];
2750 #ifdef I80286
2751         if (PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT, 0);
2752 #endif
2753         ICOUNT -= timing.out_dx16;
2754         write_port_word(port, cpustate->regs.w[AX]);
2755 }
2756
2757 /* I think thats not a V20 instruction...*/
2758 static void PREFIX86(_lock)(i8086_state *cpustate)    /* Opcode 0xf0 */
2759 {
2760 #ifdef I80286
2761         if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
2762 #endif
2763         ICOUNT -= timing.nop;
2764         PREFIX(_instruction)[FETCHOP](cpustate);  /* un-interruptible */
2765 }
2766 #endif
2767
2768 static void PREFIX(_pop_ss)(i8086_state *cpustate)    /* Opcode 0x17 */
2769 {
2770 #ifdef I80286
2771         i80286_pop_seg(cpustate, SS);
2772 #else
2773         POP(cpustate->sregs[SS]);
2774         cpustate->base[SS] = SegBase(SS);
2775 #endif
2776         ICOUNT -= timing.pop_seg;
2777         PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
2778 }
2779
2780 static void PREFIX(_es)(i8086_state *cpustate)    /* Opcode 0x26 */
2781 {
2782         cpustate->seg_prefix = TRUE;
2783         cpustate->prefix_seg = ES;
2784         ICOUNT -= timing.override;
2785         PREFIX(_instruction)[FETCHOP](cpustate);
2786 }
2787
2788 static void PREFIX(_cs)(i8086_state *cpustate)    /* Opcode 0x2e */
2789 {
2790         cpustate->seg_prefix = TRUE;
2791         cpustate->prefix_seg = CS;
2792         ICOUNT -= timing.override;
2793         PREFIX(_instruction)[FETCHOP](cpustate);
2794 }
2795
2796 static void PREFIX(_ss)(i8086_state *cpustate)    /* Opcode 0x36 */
2797 {
2798         cpustate->seg_prefix = TRUE;
2799         cpustate->prefix_seg = SS;
2800         ICOUNT -= timing.override;
2801         PREFIX(_instruction)[FETCHOP](cpustate);
2802 }
2803
2804 static void PREFIX(_ds)(i8086_state *cpustate)    /* Opcode 0x3e */
2805 {
2806         cpustate->seg_prefix = TRUE;
2807         cpustate->prefix_seg = DS;
2808         ICOUNT -= timing.override;
2809         PREFIX(_instruction)[FETCHOP](cpustate);
2810 }
2811
2812 static void PREFIX(_mov_sregw)(i8086_state *cpustate)    /* Opcode 0x8e */
2813 {
2814         unsigned ModRM = FETCH;
2815         WORD src = GetRMWord(ModRM);
2816
2817         ICOUNT -= (ModRM >= 0xc0) ? timing.mov_sr : timing.mov_sm;
2818 #ifdef I80286
2819         switch (ModRM & 0x38)
2820         {
2821         case 0x00:  /* mov es,ew */
2822                 i80286_data_descriptor(cpustate,ES,src);
2823                 break;
2824         case 0x18:  /* mov ds,ew */
2825                 i80286_data_descriptor(cpustate,DS,src);
2826                 break;
2827         case 0x10:  /* mov ss,ew */
2828                 i80286_data_descriptor(cpustate,SS,src);
2829                 cpustate->seg_prefix = FALSE;
2830                 PREFIX(_instruction)[FETCHOP](cpustate);
2831                 break;
2832         case 0x08:  /* mov cs,ew */
2833                 PREFIX(_invalid)(cpustate);
2834                 break;  /* doesn't do a jump far */
2835         }
2836 #else
2837 #ifndef I80186
2838         switch (ModRM & 0x18) /* confirmed on hw: modrm bit 5 ignored */
2839 #else
2840         switch (ModRM & 0x38)
2841 #endif
2842         {
2843         case 0x00:  /* mov es,ew */
2844                 cpustate->sregs[ES] = src;
2845                 cpustate->base[ES] = SegBase(ES);
2846                 break;
2847         case 0x18:  /* mov ds,ew */
2848                 cpustate->sregs[DS] = src;
2849                 cpustate->base[DS] = SegBase(DS);
2850                 break;
2851         case 0x10:  /* mov ss,ew */
2852                 cpustate->sregs[SS] = src;
2853                 cpustate->base[SS] = SegBase(SS); /* no interrupt allowed before next instr */
2854                 cpustate->seg_prefix = FALSE;
2855                 PREFIX(_instruction)[FETCHOP](cpustate);
2856                 break;
2857         case 0x08:  /* mov cs,ew */
2858 #ifndef I80186
2859                 int ip = cpustate->pc - cpustate->base[CS];
2860                 cpustate->sregs[CS] = src;
2861                 cpustate->base[CS] = SegBase(CS);
2862                 cpustate->pc = (ip + cpustate->base[CS]) & AMASK;
2863                 CHANGE_PC(cpustate->pc);
2864 #else
2865                 PREFIX86(_invalid)(cpustate);
2866 #endif
2867                 break;
2868         }
2869 #endif
2870 }
2871
2872 static void PREFIX(_repne)(i8086_state *cpustate)    /* Opcode 0xf2 */
2873 {
2874                 PREFIX(rep)(cpustate, 0);
2875 }
2876
2877 static void PREFIX(_repe)(i8086_state *cpustate)    /* Opcode 0xf3 */
2878 {
2879         PREFIX(rep)(cpustate, 1);
2880 }
2881
2882 static void PREFIX(_sti)(i8086_state *cpustate)    /* Opcode 0xfb */
2883 {
2884 #ifdef I80286
2885         if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
2886 #endif
2887         ICOUNT -= timing.flag_ops;
2888         SetIF(1);
2889         PREFIX(_instruction)[FETCHOP](cpustate); /* no interrupt before next instruction */
2890
2891         /* if an interrupt is pending, signal an interrupt */
2892         if (cpustate->irq_state) {
2893 #ifdef I80286
2894                 i80286_interrupt_descriptor(cpustate, cpustate->pic->get_intr_ack(), 2, -1);
2895 #else
2896                 PREFIX86(_interrupt)(cpustate, (UINT32)-1);
2897 #endif
2898                 cpustate->irq_state = 0;
2899         }
2900 }
2901
2902 #ifndef I80186
2903 static void PREFIX86(_hlt)(i8086_state *cpustate)    /* Opcode 0xf4 */
2904 {
2905 #ifdef I80286
2906         if(PM && (CPL!=0)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
2907 #endif
2908         cpustate->halted=1;
2909         ICOUNT = 0;
2910 }
2911
2912 static void PREFIX86(_cmc)(i8086_state *cpustate)    /* Opcode 0xf5 */
2913 {
2914         ICOUNT -= timing.flag_ops;
2915         cpustate->CarryVal = !CF;
2916 }
2917
2918 static void PREFIX86(_f6pre)(i8086_state *cpustate)
2919 {
2920         /* Opcode 0xf6 */
2921         unsigned ModRM = FETCH;
2922         unsigned tmp = (unsigned)GetRMByte(ModRM);
2923         unsigned tmp2;
2924
2925
2926         switch (ModRM & 0x38)
2927         {
2928         case 0x00:  /* TEST Eb, data8 */
2929         case 0x08:  /* ??? */
2930                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri8 : timing.alu_mi8_ro;
2931                 tmp &= FETCH;
2932
2933                 cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
2934                 SetSZPF_Byte(tmp);
2935                 break;
2936
2937         case 0x10:  /* NOT Eb */
2938                 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
2939                 PutbackRMByte(ModRM,~tmp);
2940                 break;
2941
2942                 case 0x18:  /* NEG Eb */
2943                 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r8 : timing.negnot_m8;
2944                 tmp2=0;
2945                 SUBB(tmp2,tmp);
2946                 PutbackRMByte(ModRM,tmp2);
2947                 break;
2948         case 0x20:  /* MUL AL, Eb */
2949                 ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r8 : timing.mul_m8;
2950                 {
2951                         UINT16 result;
2952                         tmp2 = cpustate->regs.b[AL];
2953
2954                         SetSF((INT8)tmp2);
2955                         SetPF(tmp2);
2956
2957                         result = (UINT16)tmp2*tmp;
2958                         cpustate->regs.w[AX]=(WORD)result;
2959
2960                         SetZF(cpustate->regs.w[AX]);
2961                         cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.b[AH] != 0);
2962                 }
2963                 break;
2964                 case 0x28:  /* IMUL AL, Eb */
2965                 ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r8 : timing.imul_m8;
2966                 {
2967                         INT16 result;
2968
2969                         tmp2 = (unsigned)cpustate->regs.b[AL];
2970
2971                         SetSF((INT8)tmp2);
2972                         SetPF(tmp2);
2973
2974                         result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
2975                         cpustate->regs.w[AX]=(WORD)result;
2976
2977                         SetZF(cpustate->regs.w[AX]);
2978
2979                         cpustate->CarryVal = cpustate->OverVal = (result >> 7 != 0) && (result >> 7 != -1);
2980                 }
2981                 break;
2982         case 0x30:  /* DIV AL, Ew */
2983                 ICOUNT -= (ModRM >= 0xc0) ? timing.div_r8 : timing.div_m8;
2984                 {
2985                         UINT16 result;
2986
2987                         result = cpustate->regs.w[AX];
2988
2989                         if (tmp)
2990                         {
2991                                 if ((result / tmp) > 0xff)
2992                                 {
2993                                         PREFIX(_interrupt)(cpustate, 0);
2994                                         break;
2995                                 }
2996                                 else
2997                                 {
2998                                         cpustate->regs.b[AH] = result % tmp;
2999                                         cpustate->regs.b[AL] = result / tmp;
3000                                 }
3001                         }
3002                         else
3003                         {
3004                                 PREFIX(_interrupt)(cpustate, 0);
3005                                 break;
3006                         }
3007                 }
3008                 break;
3009         case 0x38:  /* IDIV AL, Ew */
3010                 ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r8 : timing.idiv_m8;
3011                 {
3012
3013                         INT16 result;
3014
3015                         result = cpustate->regs.w[AX];
3016
3017                         if (tmp)
3018                         {
3019                                 tmp2 = result % (INT16)((INT8)tmp);
3020
3021                                 if ((result /= (INT16)((INT8)tmp)) > 0xff)
3022                                 {
3023                                         PREFIX(_interrupt)(cpustate, 0);
3024                                         break;
3025                                 }
3026                                 else
3027                                 {
3028                                         cpustate->regs.b[AL] = result;
3029                                         cpustate->regs.b[AH] = tmp2;
3030                                 }
3031                         }
3032                         else
3033                         {
3034                                 PREFIX(_interrupt)(cpustate, 0);
3035                                 break;
3036                         }
3037                 }
3038                 break;
3039         }
3040 }
3041
3042
3043 static void PREFIX86(_f7pre)(i8086_state *cpustate)
3044 {
3045         /* Opcode 0xf7 */
3046         unsigned ModRM = FETCH;
3047                 unsigned tmp = GetRMWord(ModRM);
3048         unsigned tmp2;
3049
3050
3051         switch (ModRM & 0x38)
3052         {
3053         case 0x00:  /* TEST Ew, data16 */
3054         case 0x08:  /* ??? */
3055                 ICOUNT -= (ModRM >= 0xc0) ? timing.alu_ri16 : timing.alu_mi16_ro;
3056                 tmp2 = FETCH;
3057                 tmp2 += FETCH << 8;
3058
3059                 tmp &= tmp2;
3060
3061                 cpustate->CarryVal = cpustate->OverVal = cpustate->AuxVal = 0;
3062                 SetSZPF_Word(tmp);
3063                 break;
3064
3065         case 0x10:  /* NOT Ew */
3066                 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
3067                 tmp = ~tmp;
3068                 PutbackRMWord(ModRM,tmp);
3069                 break;
3070
3071         case 0x18:  /* NEG Ew */
3072                 ICOUNT -= (ModRM >= 0xc0) ? timing.negnot_r16 : timing.negnot_m16;
3073                 tmp2 = 0;
3074                 SUBW(tmp2,tmp);
3075                 PutbackRMWord(ModRM,tmp2);
3076                 break;
3077         case 0x20:  /* MUL AX, Ew */
3078                 ICOUNT -= (ModRM >= 0xc0) ? timing.mul_r16 : timing.mul_m16;
3079                 {
3080                         UINT32 result;
3081                         tmp2 = cpustate->regs.w[AX];
3082
3083                         SetSF((INT16)tmp2);
3084                         SetPF(tmp2);
3085
3086                         result = (UINT32)tmp2*tmp;
3087                         cpustate->regs.w[AX]=(WORD)result;
3088                         result >>= 16;
3089                         cpustate->regs.w[DX]=result;
3090
3091                         SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
3092                         cpustate->CarryVal = cpustate->OverVal = (cpustate->regs.w[DX] != 0);
3093                 }
3094                 break;
3095
3096         case 0x28:  /* IMUL AX, Ew */
3097                 ICOUNT -= (ModRM >= 0xc0) ? timing.imul_r16 : timing.imul_m16;
3098                 {
3099                         INT32 result;
3100
3101                         tmp2 = cpustate->regs.w[AX];
3102
3103                         SetSF((INT16)tmp2);
3104                         SetPF(tmp2);
3105
3106                         result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
3107                         cpustate->CarryVal = cpustate->OverVal = (result >> 15 != 0) && (result >> 15 != -1);
3108
3109                         cpustate->regs.w[AX]=(WORD)result;
3110                         result = (WORD)(result >> 16);
3111                         cpustate->regs.w[DX]=result;
3112
3113                         SetZF(cpustate->regs.w[AX] | cpustate->regs.w[DX]);
3114                 }
3115                 break;
3116                 case 0x30:  /* DIV AX, Ew */
3117                 ICOUNT -= (ModRM >= 0xc0) ? timing.div_r16 : timing.div_m16;
3118                 {
3119                         UINT32 result;
3120
3121                         result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
3122
3123                         if (tmp)
3124                         {
3125                                 tmp2 = result % tmp;
3126                                 if ((result / tmp) > 0xffff)
3127                                 {
3128                                         PREFIX(_interrupt)(cpustate, 0);
3129                                         break;
3130                                 }
3131                                 else
3132                                 {
3133                                         cpustate->regs.w[DX]=tmp2;
3134                                         result /= tmp;
3135                                         cpustate->regs.w[AX]=result;
3136                                 }
3137                         }
3138                         else
3139                         {
3140                                 PREFIX(_interrupt)(cpustate, 0);
3141                                 break;
3142                         }
3143                 }
3144                 break;
3145         case 0x38:  /* IDIV AX, Ew */
3146                 ICOUNT -= (ModRM >= 0xc0) ? timing.idiv_r16 : timing.idiv_m16;
3147                 {
3148                         INT32 result;
3149
3150                         result = (cpustate->regs.w[DX] << 16) + cpustate->regs.w[AX];
3151
3152                         if (tmp)
3153                         {
3154                                 tmp2 = result % (INT32)((INT16)tmp);
3155                                 if ((result /= (INT32)((INT16)tmp)) > 0xffff)
3156                                 {
3157                                         PREFIX(_interrupt)(cpustate, 0);
3158                                         break;
3159                                 }
3160                                 else
3161                                 {
3162                                         cpustate->regs.w[AX]=result;
3163                                         cpustate->regs.w[DX]=tmp2;
3164                                 }
3165                         }
3166                         else
3167                         {
3168                                 PREFIX(_interrupt)(cpustate, 0);
3169                                 break;
3170                         }
3171                 }
3172                 break;
3173         }
3174 }
3175
3176
3177 static void PREFIX86(_clc)(i8086_state *cpustate)    /* Opcode 0xf8 */
3178 {
3179         ICOUNT -= timing.flag_ops;
3180         cpustate->CarryVal = 0;
3181 }
3182
3183 static void PREFIX86(_stc)(i8086_state *cpustate)    /* Opcode 0xf9 */
3184 {
3185         ICOUNT -= timing.flag_ops;
3186         cpustate->CarryVal = 1;
3187 }
3188
3189 static void PREFIX86(_cli)(i8086_state *cpustate)    /* Opcode 0xfa */
3190 {
3191 #ifdef I80286
3192         if(PM && (CPL>IOPL)) throw TRAP(GENERAL_PROTECTION_FAULT,0);
3193 #endif
3194         ICOUNT -= timing.flag_ops;
3195         SetIF(0);
3196 }
3197
3198 static void PREFIX86(_cld)(i8086_state *cpustate)    /* Opcode 0xfc */
3199 {
3200         ICOUNT -= timing.flag_ops;
3201         SetDF(0);
3202 }
3203
3204 static void PREFIX86(_std)(i8086_state *cpustate)    /* Opcode 0xfd */
3205 {
3206         ICOUNT -= timing.flag_ops;
3207         SetDF(1);
3208 }
3209
3210 static void PREFIX86(_fepre)(i8086_state *cpustate)    /* Opcode 0xfe */
3211 {
3212         unsigned ModRM = FETCH;
3213         unsigned tmp = GetRMByte(ModRM);
3214         unsigned tmp1;
3215
3216         ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r8 : timing.incdec_m8;
3217         if ((ModRM & 0x38) == 0)  /* INC eb */
3218         {
3219                 tmp1 = tmp+1;
3220                 SetOFB_Add(tmp1,tmp,1);
3221         }
3222         else  /* DEC eb */
3223         {
3224                 tmp1 = tmp-1;
3225                 SetOFB_Sub(tmp1,1,tmp);
3226         }
3227
3228         SetAF(tmp1,tmp,1);
3229         SetSZPF_Byte(tmp1);
3230
3231         PutbackRMByte(ModRM,(BYTE)tmp1);
3232 }
3233
3234
3235 static void PREFIX86(_ffpre)(i8086_state *cpustate)    /* Opcode 0xff */
3236 {
3237         unsigned ModRM = FETCHOP;
3238         unsigned tmp;
3239         unsigned tmp1, tmp2;
3240         WORD ip;
3241
3242         switch(ModRM & 0x38)
3243         {
3244         case 0x00:  /* INC ew */
3245                 ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
3246                 tmp = GetRMWord(ModRM);
3247                 tmp1 = tmp+1;
3248
3249                 SetOFW_Add(tmp1,tmp,1);
3250                 SetAF(tmp1,tmp,1);
3251                 SetSZPF_Word(tmp1);
3252
3253                 PutbackRMWord(ModRM,(WORD)tmp1);
3254                 break;
3255
3256         case 0x08:  /* DEC ew */
3257                 ICOUNT -= (ModRM >= 0xc0) ? timing.incdec_r16 : timing.incdec_m16;
3258                 tmp = GetRMWord(ModRM);
3259                 tmp1 = tmp-1;
3260
3261                 SetOFW_Sub(tmp1,1,tmp);
3262                 SetAF(tmp1,tmp,1);
3263                 SetSZPF_Word(tmp1);
3264
3265                 PutbackRMWord(ModRM,(WORD)tmp1);
3266                 break;
3267
3268         case 0x10:  /* CALL ew */
3269                 ICOUNT -= (ModRM >= 0xc0) ? timing.call_r16 : timing.call_m16;
3270                 tmp = GetRMWord(ModRM);
3271                 ip = cpustate->pc - cpustate->base[CS];
3272                 PUSH(ip);
3273                 cpustate->pc = (cpustate->base[CS] + (WORD)tmp) & AMASK;
3274                 CHANGE_PC(cpustate->pc);
3275                 break;
3276
3277         case 0x18:  /* CALL FAR ea */
3278                 ICOUNT -= timing.call_m32;
3279                 tmp = cpustate->sregs[CS];  /* HJB 12/13/98 need to skip displacements of cpustate->ea */
3280                 tmp1 = GetRMWord(ModRM);
3281                 tmp2 = GetnextRMWord;
3282                 if(BIOS_CALL_86(cpustate, ((tmp2 << 4) + tmp1) & AMASK)) {
3283                         ICOUNT -= timing.ret_far;
3284                         return;
3285                 }
3286 //#endif
3287                 ip = cpustate->pc - cpustate->base[CS];
3288 #ifdef I80286
3289                 i80286_code_descriptor(cpustate, tmp2, tmp1, 2);
3290 #else
3291                 cpustate->sregs[CS] = tmp2;
3292                 cpustate->base[CS] = SegBase(CS);
3293                 cpustate->pc = (cpustate->base[CS] + tmp1) & AMASK;
3294 #endif
3295                 PUSH(tmp);
3296                 PUSH(ip);
3297                 CHANGE_PC(cpustate->pc);
3298                 break;
3299
3300         case 0x20:  /* JMP ea */
3301                 ICOUNT -= (ModRM >= 0xc0) ? timing.jmp_r16 : timing.jmp_m16;
3302                 ip = GetRMWord(ModRM);
3303                 cpustate->pc = (cpustate->base[CS] + ip) & AMASK;
3304                 CHANGE_PC(cpustate->pc);
3305                 break;
3306
3307         case 0x28:  /* JMP FAR ea */
3308                 ICOUNT -= timing.jmp_m32;
3309
3310 #ifdef I80286
3311                 tmp = GetRMWord(ModRM);
3312                 i80286_code_descriptor(cpustate, GetnextRMWord, tmp, 1);
3313 #else
3314                 cpustate->pc = GetRMWord(ModRM);
3315                 cpustate->sregs[CS] = GetnextRMWord;
3316                 cpustate->base[CS] = SegBase(CS);
3317                 cpustate->pc = (cpustate->pc + cpustate->base[CS]) & AMASK;
3318 #endif
3319                 CHANGE_PC(cpustate->pc);
3320                 break;
3321
3322         case 0x30:  /* PUSH ea */
3323                 ICOUNT -= (ModRM >= 0xc0) ? timing.push_r16 : timing.push_m16;
3324                 tmp = GetRMWord(ModRM);
3325                 PUSH(tmp);
3326                 break;
3327         default:
3328                 tmp = GetRMWord(ModRM);  // 286 doesn't matter but 8086?
3329                 return PREFIX(_invalid)(cpustate);
3330         }
3331 }
3332
3333
3334 static void PREFIX86(_invalid)(i8086_state *cpustate)
3335 {
3336         logerror("illegal instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-1), cpustate->pc);
3337 #ifdef I80286
3338         throw TRAP(ILLEGAL_INSTRUCTION,-1);
3339 #else
3340         /* i8086/i8088 ignore an invalid opcode. */
3341         /* i80186/i80188 probably also ignore an invalid opcode. */
3342         ICOUNT -= 10;
3343 #endif
3344 }
3345
3346 #ifndef I80286
3347 static void PREFIX86(_invalid_2b)(i8086_state *cpustate)
3348 {
3349         unsigned ModRM = FETCH;
3350         GetRMByte(ModRM);
3351         logerror("illegal 2 byte instruction %.2x at %.5x\n",PEEKBYTE(cpustate->pc-2), cpustate->pc-2);
3352         ICOUNT -= 10;
3353 }
3354 #endif
3355
3356 #undef BIOS_CALL_86
3357 #endif