DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_normal/prefix_none.h
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019         CASE_B(0x00)                                                                                            /* ADD Eb,Gb */
00020                 RMEbGb(ADDB);break;
00021         CASE_W(0x01)                                                                                            /* ADD Ew,Gw */
00022                 RMEwGw(ADDW);break;     
00023         CASE_B(0x02)                                                                                            /* ADD Gb,Eb */
00024                 RMGbEb(ADDB);break;
00025         CASE_W(0x03)                                                                                            /* ADD Gw,Ew */
00026                 RMGwEw(ADDW);break;
00027         CASE_B(0x04)                                                                                            /* ADD AL,Ib */
00028                 ALIb(ADDB);break;
00029         CASE_W(0x05)                                                                                            /* ADD AX,Iw */
00030                 AXIw(ADDW);break;
00031         CASE_W(0x06)                                                                                            /* PUSH ES */           
00032                 Push_16(SegValue(es));break;
00033         CASE_W(0x07)                                                                                            /* POP ES */
00034                 if (CPU_PopSeg(es,false)) RUNEXCEPTION();
00035                 break;
00036         CASE_B(0x08)                                                                                            /* OR Eb,Gb */
00037                 RMEbGb(ORB);break;
00038         CASE_W(0x09)                                                                                            /* OR Ew,Gw */
00039                 RMEwGw(ORW);break;
00040         CASE_B(0x0a)                                                                                            /* OR Gb,Eb */
00041                 RMGbEb(ORB);break;
00042         CASE_W(0x0b)                                                                                            /* OR Gw,Ew */
00043                 RMGwEw(ORW);break;
00044         CASE_B(0x0c)                                                                                            /* OR AL,Ib */
00045                 ALIb(ORB);break;
00046         CASE_W(0x0d)                                                                                            /* OR AX,Iw */
00047                 AXIw(ORW);break;
00048         CASE_W(0x0e)                                                                                            /* PUSH CS */           
00049                 Push_16(SegValue(cs));break;
00050         CASE_B(0x0f)                                                                                            /* 2 byte opcodes*/
00051 #if CPU_CORE < CPU_ARCHTYPE_286
00052                 if (CPU_ArchitectureType < CPU_ARCHTYPE_286) {
00053                         /* 8086 emulation: treat as "POP CS" */
00054                         if (CPU_PopSeg(cs,false)) RUNEXCEPTION();
00055                         break;
00056                 }
00057                 else
00058 #endif
00059                 {
00060                         core.opcode_index|=OPCODE_0F;
00061                         goto restart_opcode;
00062                 } break;
00063         CASE_B(0x10)                                                                                            /* ADC Eb,Gb */
00064                 RMEbGb(ADCB);break;
00065         CASE_W(0x11)                                                                                            /* ADC Ew,Gw */
00066                 RMEwGw(ADCW);break;     
00067         CASE_B(0x12)                                                                                            /* ADC Gb,Eb */
00068                 RMGbEb(ADCB);break;
00069         CASE_W(0x13)                                                                                            /* ADC Gw,Ew */
00070                 RMGwEw(ADCW);break;
00071         CASE_B(0x14)                                                                                            /* ADC AL,Ib */
00072                 ALIb(ADCB);break;
00073         CASE_W(0x15)                                                                                            /* ADC AX,Iw */
00074                 AXIw(ADCW);break;
00075         CASE_W(0x16)                                                                                            /* PUSH SS */           
00076                 Push_16(SegValue(ss));break;
00077         CASE_W(0x17)                                                                                            /* POP SS */
00078                 if (CPU_PopSeg(ss,false)) RUNEXCEPTION();
00079                 CPU_Cycles++; //Always do another instruction
00080                 break;
00081         CASE_B(0x18)                                                                                            /* SBB Eb,Gb */
00082                 RMEbGb(SBBB);break;
00083         CASE_W(0x19)                                                                                            /* SBB Ew,Gw */
00084                 RMEwGw(SBBW);break;
00085         CASE_B(0x1a)                                                                                            /* SBB Gb,Eb */
00086                 RMGbEb(SBBB);break;
00087         CASE_W(0x1b)                                                                                            /* SBB Gw,Ew */
00088                 RMGwEw(SBBW);break;
00089         CASE_B(0x1c)                                                                                            /* SBB AL,Ib */
00090                 ALIb(SBBB);break;
00091         CASE_W(0x1d)                                                                                            /* SBB AX,Iw */
00092                 AXIw(SBBW);break;
00093         CASE_W(0x1e)                                                                                            /* PUSH DS */           
00094                 Push_16(SegValue(ds));break;
00095         CASE_W(0x1f)                                                                                            /* POP DS */
00096                 if (CPU_PopSeg(ds,false)) RUNEXCEPTION();
00097                 break;
00098         CASE_B(0x20)                                                                                            /* AND Eb,Gb */
00099                 RMEbGb(ANDB);break;
00100         CASE_W(0x21)                                                                                            /* AND Ew,Gw */
00101                 RMEwGw(ANDW);break;     
00102         CASE_B(0x22)                                                                                            /* AND Gb,Eb */
00103                 RMGbEb(ANDB);break;
00104         CASE_W(0x23)                                                                                            /* AND Gw,Ew */
00105                 RMGwEw(ANDW);break;
00106         CASE_B(0x24)                                                                                            /* AND AL,Ib */
00107                 ALIb(ANDB);break;
00108         CASE_W(0x25)                                                                                            /* AND AX,Iw */
00109                 AXIw(ANDW);break;
00110         CASE_B(0x26)                                                                                            /* SEG ES: */
00111                 DO_PREFIX_SEG(es);break;
00112         CASE_B(0x27)                                                                                            /* DAA */
00113                 DAA();break;
00114         CASE_B(0x28)                                                                                            /* SUB Eb,Gb */
00115                 RMEbGb(SUBB);break;
00116         CASE_W(0x29)                                                                                            /* SUB Ew,Gw */
00117                 RMEwGw(SUBW);break;
00118         CASE_B(0x2a)                                                                                            /* SUB Gb,Eb */
00119                 RMGbEb(SUBB);break;
00120         CASE_W(0x2b)                                                                                            /* SUB Gw,Ew */
00121                 RMGwEw(SUBW);break;
00122         CASE_B(0x2c)                                                                                            /* SUB AL,Ib */
00123                 ALIb(SUBB);break;
00124         CASE_W(0x2d)                                                                                            /* SUB AX,Iw */
00125                 AXIw(SUBW);break;
00126         CASE_B(0x2e)                                                                                            /* SEG CS: */
00127                 DO_PREFIX_SEG(cs);break;
00128         CASE_B(0x2f)                                                                                            /* DAS */
00129                 DAS();break;  
00130         CASE_B(0x30)                                                                                            /* XOR Eb,Gb */
00131                 RMEbGb(XORB);break;
00132         CASE_W(0x31)                                                                                            /* XOR Ew,Gw */
00133                 RMEwGw(XORW);break;     
00134         CASE_B(0x32)                                                                                            /* XOR Gb,Eb */
00135                 RMGbEb(XORB);break;
00136         CASE_W(0x33)                                                                                            /* XOR Gw,Ew */
00137                 RMGwEw(XORW);break;
00138         CASE_B(0x34)                                                                                            /* XOR AL,Ib */
00139                 ALIb(XORB);break;
00140         CASE_W(0x35)                                                                                            /* XOR AX,Iw */
00141                 AXIw(XORW);break;
00142         CASE_B(0x36)                                                                                            /* SEG SS: */
00143                 DO_PREFIX_SEG(ss);break;
00144         CASE_B(0x37)                                                                                            /* AAA */
00145                 AAA();break;  
00146         CASE_B(0x38)                                                                                            /* CMP Eb,Gb */
00147                 RMEbGb(CMPB);break;
00148         CASE_W(0x39)                                                                                            /* CMP Ew,Gw */
00149                 RMEwGw(CMPW);break;
00150         CASE_B(0x3a)                                                                                            /* CMP Gb,Eb */
00151                 RMGbEb(CMPB);break;
00152         CASE_W(0x3b)                                                                                            /* CMP Gw,Ew */
00153                 RMGwEw(CMPW);break;
00154         CASE_B(0x3c)                                                                                            /* CMP AL,Ib */
00155                 ALIb(CMPB);break;
00156         CASE_W(0x3d)                                                                                            /* CMP AX,Iw */
00157                 AXIw(CMPW);break;
00158         CASE_B(0x3e)                                                                                            /* SEG DS: */
00159                 DO_PREFIX_SEG(ds);break;
00160         CASE_B(0x3f)                                                                                            /* AAS */
00161                 AAS();break;
00162         CASE_W(0x40)                                                                                            /* INC AX */
00163                 INCW(reg_ax,LoadRw,SaveRw);break;
00164         CASE_W(0x41)                                                                                            /* INC CX */
00165                 INCW(reg_cx,LoadRw,SaveRw);break;
00166         CASE_W(0x42)                                                                                            /* INC DX */
00167                 INCW(reg_dx,LoadRw,SaveRw);break;
00168         CASE_W(0x43)                                                                                            /* INC BX */
00169                 INCW(reg_bx,LoadRw,SaveRw);break;
00170         CASE_W(0x44)                                                                                            /* INC SP */
00171                 INCW(reg_sp,LoadRw,SaveRw);break;
00172         CASE_W(0x45)                                                                                            /* INC BP */
00173                 INCW(reg_bp,LoadRw,SaveRw);break;
00174         CASE_W(0x46)                                                                                            /* INC SI */
00175                 INCW(reg_si,LoadRw,SaveRw);break;
00176         CASE_W(0x47)                                                                                            /* INC DI */
00177                 INCW(reg_di,LoadRw,SaveRw);break;
00178         CASE_W(0x48)                                                                                            /* DEC AX */
00179                 DECW(reg_ax,LoadRw,SaveRw);break;
00180         CASE_W(0x49)                                                                                            /* DEC CX */
00181                 DECW(reg_cx,LoadRw,SaveRw);break;
00182         CASE_W(0x4a)                                                                                            /* DEC DX */
00183                 DECW(reg_dx,LoadRw,SaveRw);break;
00184         CASE_W(0x4b)                                                                                            /* DEC BX */
00185                 DECW(reg_bx,LoadRw,SaveRw);break;
00186         CASE_W(0x4c)                                                                                            /* DEC SP */
00187                 DECW(reg_sp,LoadRw,SaveRw);break;
00188         CASE_W(0x4d)                                                                                            /* DEC BP */
00189                 DECW(reg_bp,LoadRw,SaveRw);break;
00190         CASE_W(0x4e)                                                                                            /* DEC SI */
00191                 DECW(reg_si,LoadRw,SaveRw);break;
00192         CASE_W(0x4f)                                                                                            /* DEC DI */
00193                 DECW(reg_di,LoadRw,SaveRw);break;
00194         CASE_W(0x50)                                                                                            /* PUSH AX */
00195                 Push_16(reg_ax);break;
00196         CASE_W(0x51)                                                                                            /* PUSH CX */
00197                 Push_16(reg_cx);break;
00198         CASE_W(0x52)                                                                                            /* PUSH DX */
00199                 Push_16(reg_dx);break;
00200         CASE_W(0x53)                                                                                            /* PUSH BX */
00201                 Push_16(reg_bx);break;
00202         CASE_W(0x54)                                                                                            /* PUSH SP */
00203                 if (CPU_ArchitectureType >= CPU_ARCHTYPE_286)
00204                         Push_16(reg_sp);
00205                 else /* 8086 decrements SP then pushes it */
00206                         Push_16(reg_sp-2u);
00207                 break;
00208         CASE_W(0x55)                                                                                            /* PUSH BP */
00209                 Push_16(reg_bp);break;
00210         CASE_W(0x56)                                                                                            /* PUSH SI */
00211                 Push_16(reg_si);break;
00212         CASE_W(0x57)                                                                                            /* PUSH DI */
00213                 Push_16(reg_di);break;
00214         CASE_W(0x58)                                                                                            /* POP AX */
00215                 reg_ax=Pop_16();break;
00216         CASE_W(0x59)                                                                                            /* POP CX */
00217                 reg_cx=Pop_16();break;
00218         CASE_W(0x5a)                                                                                            /* POP DX */
00219                 reg_dx=Pop_16();break;
00220         CASE_W(0x5b)                                                                                            /* POP BX */
00221                 reg_bx=Pop_16();break;
00222         CASE_W(0x5c)                                                                                            /* POP SP */
00223                 reg_sp=Pop_16();break;
00224         CASE_W(0x5d)                                                                                            /* POP BP */
00225                 reg_bp=Pop_16();break;
00226         CASE_W(0x5e)                                                                                            /* POP SI */
00227                 reg_si=Pop_16();break;
00228         CASE_W(0x5f)                                                                                            /* POP DI */
00229                 reg_di=Pop_16();break;
00230         CASE_W(0x60)                                                                                            /* PUSHA */
00231                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00232                 {
00233                         Bit32u old_esp = reg_esp;
00234                         try {
00235                                 Bit16u old_sp = (CPU_ArchitectureType >= CPU_ARCHTYPE_286 ? reg_sp : (reg_sp-10));
00236                                 Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx);
00237                                 Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di);
00238                         }
00239                         catch (GuestPageFaultException &pf) {
00240                                 (void)pf;
00241                                 LOG_MSG("PUSHA interrupted by page fault");
00242                                 reg_esp = old_esp;
00243                                 throw;
00244                         }
00245                 } break;
00246         CASE_W(0x61)                                                                                            /* POPA */
00247                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00248                 {
00249                         Bit32u old_esp = reg_esp;
00250                         try {
00251                                 reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP
00252                                 reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16();
00253                         }
00254                         catch (GuestPageFaultException &pf) {
00255                                 (void)pf;
00256                                 LOG_MSG("POPA interrupted by page fault");
00257                                 reg_esp = old_esp;
00258                                 throw;
00259                         }
00260                 } break;
00261         CASE_W(0x62)                                                                                            /* BOUND */
00262                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00263                 {
00264                         Bit16s bound_min, bound_max;
00265                         GetRMrw;GetEAa;
00266                         bound_min=(Bit16s)LoadMw(eaa);
00267                         bound_max=(Bit16s)LoadMw(eaa+2u);
00268                         if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) {
00269                                 EXCEPTION(5);
00270                         }
00271                 }
00272                 break;
00273         CASE_W(0x63)                                                                                            /* ARPL Ew,Rw */
00274                 if (CPU_ArchitectureType<CPU_ARCHTYPE_286) goto illegal_opcode;
00275                 {
00276                         if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
00277                         GetRMrw;
00278                         if (rm >= 0xc0 ) {
00279                                 GetEArw;Bitu new_sel=*earw;
00280                                 CPU_ARPL(new_sel,*rmrw);
00281                                 *earw=(Bit16u)new_sel;
00282                         } else {
00283                                 GetEAa;Bitu new_sel=LoadMw(eaa);
00284                                 CPU_ARPL(new_sel,*rmrw);
00285                                 SaveMw(eaa,(Bit16u)new_sel);
00286                         }
00287                 }
00288                 break;
00289         CASE_B(0x64)                                                                                            /* SEG FS: */
00290                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00291                 DO_PREFIX_SEG(fs);break;
00292         CASE_B(0x65)                                                                                            /* SEG GS: */
00293                 if (CPU_ArchitectureType<CPU_ARCHTYPE_386) goto illegal_opcode;
00294                 DO_PREFIX_SEG(gs);break;
00295 #if CPU_CORE >= CPU_ARCHTYPE_386
00296         CASE_B(0x66)                                                                                            /* Operand Size Prefix (386+) */
00297                 core.opcode_index=(cpu.code.big^0x1u)*0x200u;
00298                 goto restart_opcode;
00299 #endif
00300 #if CPU_CORE >= CPU_ARCHTYPE_386
00301         CASE_B(0x67)                                                                                            /* Address Size Prefix (386+) */
00302                 DO_PREFIX_ADDR();
00303 #endif
00304         CASE_W(0x68)                                                                                            /* PUSH Iw */
00305                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00306                 Push_16(Fetchw());break;
00307         CASE_W(0x69)                                                                                            /* IMUL Gw,Ew,Iw */
00308                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00309                 RMGwEwOp3(DIMULW,Fetchws());
00310                 break;
00311         CASE_W(0x6a)                                                                                            /* PUSH Ib */
00312                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00313                 Push_16((Bit16u)Fetchbs());
00314                 break;
00315         CASE_W(0x6b)                                                                                            /* IMUL Gw,Ew,Ib */
00316                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00317                 RMGwEwOp3(DIMULW,Fetchbs());
00318                 break;
00319         CASE_B(0x6c)                                                                                            /* INSB */
00320                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00321                 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
00322                 DoString(R_INSB);break;
00323         CASE_W(0x6d)                                                                                            /* INSW */
00324                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00325                 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
00326                 DoString(R_INSW);break;
00327         CASE_B(0x6e)                                                                                            /* OUTSB */
00328                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00329                 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
00330                 DoString(R_OUTSB);break;
00331         CASE_W(0x6f)                                                                                            /* OUTSW */
00332                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00333                 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
00334                 DoString(R_OUTSW);break;
00335         CASE_W(0x70)                                                                                            /* JO */
00336                 JumpCond16_b(TFLG_O);break;
00337         CASE_W(0x71)                                                                                            /* JNO */
00338                 JumpCond16_b(TFLG_NO);break;
00339         CASE_W(0x72)                                                                                            /* JB */
00340                 JumpCond16_b(TFLG_B);break;
00341         CASE_W(0x73)                                                                                            /* JNB */
00342                 JumpCond16_b(TFLG_NB);break;
00343         CASE_W(0x74)                                                                                            /* JZ */
00344                 JumpCond16_b(TFLG_Z);break;
00345         CASE_W(0x75)                                                                                            /* JNZ */
00346                 JumpCond16_b(TFLG_NZ);break;
00347         CASE_W(0x76)                                                                                            /* JBE */
00348                 JumpCond16_b(TFLG_BE);break;
00349         CASE_W(0x77)                                                                                            /* JNBE */
00350                 JumpCond16_b(TFLG_NBE);break;
00351         CASE_W(0x78)                                                                                            /* JS */
00352                 JumpCond16_b(TFLG_S);break;
00353         CASE_W(0x79)                                                                                            /* JNS */
00354                 JumpCond16_b(TFLG_NS);break;
00355         CASE_W(0x7a)                                                                                            /* JP */
00356                 JumpCond16_b(TFLG_P);break;
00357         CASE_W(0x7b)                                                                                            /* JNP */
00358                 JumpCond16_b(TFLG_NP);break;
00359         CASE_W(0x7c)                                                                                            /* JL */
00360                 JumpCond16_b(TFLG_L);break;
00361         CASE_W(0x7d)                                                                                            /* JNL */
00362                 JumpCond16_b(TFLG_NL);break;
00363         CASE_W(0x7e)                                                                                            /* JLE */
00364                 JumpCond16_b(TFLG_LE);break;
00365         CASE_W(0x7f)                                                                                            /* JNLE */
00366                 JumpCond16_b(TFLG_NLE);break;
00367         CASE_B(0x80)                                                                                            /* Grpl Eb,Ib */
00368         CASE_B(0x82)                                                                                            /* Grpl Eb,Ib Mirror instruction*/
00369                 {
00370                         GetRM;Bitu which=(rm>>3)&7;
00371                         if (rm>= 0xc0) {
00372                                 GetEArb;Bit8u ib=Fetchb();
00373                                 switch (which) {
00374                                 case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break;
00375                                 case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break;
00376                                 case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break;
00377                                 case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break;
00378                                 case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break;
00379                                 case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break;
00380                                 case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break;
00381                                 case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break;
00382                                 }
00383                         } else {
00384                                 GetEAa;Bit8u ib=Fetchb();
00385                                 switch (which) {
00386                                 case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break;
00387                                 case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break;
00388                                 case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break;
00389                                 case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break;
00390                                 case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break;
00391                                 case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break;
00392                                 case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break;
00393                                 case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break;
00394                                 }
00395                         }
00396                         break;
00397                 }
00398         CASE_W(0x81)                                                                                            /* Grpl Ew,Iw */
00399                 {
00400                         GetRM;Bitu which=(rm>>3)&7;
00401                         if (rm>= 0xc0) {
00402                                 GetEArw;Bit16u iw=Fetchw();
00403                                 switch (which) {
00404                                 case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break;
00405                                 case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break;
00406                                 case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break;
00407                                 case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break;
00408                                 case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break;
00409                                 case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break;
00410                                 case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break;
00411                                 case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break;
00412                                 }
00413                         } else {
00414                                 GetEAa;Bit16u iw=Fetchw();
00415                                 switch (which) {
00416                                 case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break;
00417                                 case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break;
00418                                 case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break;
00419                                 case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break;
00420                                 case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break;
00421                                 case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break;
00422                                 case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break;
00423                                 case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break;
00424                                 }
00425                         }
00426                         break;
00427                 }
00428         CASE_W(0x83)                                                                                            /* Grpl Ew,Ix */
00429                 {
00430                         GetRM;Bitu which=(rm>>3)&7;
00431                         if (rm>= 0xc0) {
00432                                 GetEArw;Bit16u iw=(Bit16u)Fetchbs();
00433                                 switch (which) {
00434                                 case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break;
00435                                 case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break;
00436                                 case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break;
00437                                 case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break;
00438                                 case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break;
00439                                 case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break;
00440                                 case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break;
00441                                 case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break;
00442                                 }
00443                         } else {
00444                                 GetEAa;Bit16u iw=(Bit16u)Fetchbs();
00445                                 switch (which) {
00446                                 case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break;
00447                                 case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break;
00448                                 case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break;
00449                                 case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break;
00450                                 case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break;
00451                                 case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break;
00452                                 case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break;
00453                                 case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break;
00454                                 }
00455                         }
00456                         break;
00457                 }
00458         CASE_B(0x84)                                                                                            /* TEST Eb,Gb */
00459                 RMEbGb(TESTB);
00460                 break;
00461         CASE_W(0x85)                                                                                            /* TEST Ew,Gw */
00462                 RMEwGw(TESTW);
00463                 break;
00464         CASE_B(0x86)                                                                                            /* XCHG Eb,Gb */
00465                 {       
00466                         GetRMrb;Bit8u oldrmrb=*rmrb;
00467                         if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;}
00468                         else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);}
00469                         break;
00470                 }
00471         CASE_W(0x87)                                                                                            /* XCHG Ew,Gw */
00472                 {       
00473                         GetRMrw;Bit16u oldrmrw=*rmrw;
00474                         if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;}
00475                         else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);}
00476                         break;
00477                 }
00478         CASE_B(0x88)                                                                                            /* MOV Eb,Gb */
00479                 {       
00480                         GetRMrb;
00481                         if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;}
00482                         else {
00483                                 if (cpu.pmode) {
00484                                         if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) {
00485                                                 Descriptor desc;
00486                                                 cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc);
00487                                                 if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) {
00488                                                         CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc);
00489                                                         continue;
00490                                                 }
00491                                         }
00492                                 }
00493                                 GetEAa;SaveMb(eaa,*rmrb);
00494                         }
00495                         break;
00496                 }
00497         CASE_W(0x89)                                                                                            /* MOV Ew,Gw */
00498                 {       
00499                         GetRMrw;
00500                         if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;}
00501                         else {GetEAa;SaveMw(eaa,*rmrw);}
00502                         break;
00503                 }
00504         CASE_B(0x8a)                                                                                            /* MOV Gb,Eb */
00505                 {       
00506                         GetRMrb;
00507                         if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;}
00508                         else {GetEAa;*rmrb=LoadMb(eaa);}
00509                         break;
00510                 }
00511         CASE_W(0x8b)                                                                                            /* MOV Gw,Ew */
00512                 {       
00513                         GetRMrw;
00514                         if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
00515                         else {GetEAa;*rmrw=LoadMw(eaa);}
00516                         break;
00517                 }
00518         CASE_W(0x8c)                                                                                            /* Mov Ew,Sw */
00519                 {
00520                         GetRM;Bit16u val;Bitu which=(rm>>3)&7;
00521                         switch (which) {
00522                         case 0x00:                                      /* MOV Ew,ES */
00523                                 val=SegValue(es);break;
00524                         case 0x01:                                      /* MOV Ew,CS */
00525                                 val=SegValue(cs);break;
00526                         case 0x02:                                      /* MOV Ew,SS */
00527                                 val=SegValue(ss);break;
00528                         case 0x03:                                      /* MOV Ew,DS */
00529                                 val=SegValue(ds);break;
00530                         case 0x04:                                      /* MOV Ew,FS */
00531                                 val=SegValue(fs);break;
00532                         case 0x05:                                      /* MOV Ew,GS */
00533                                 val=SegValue(gs);break;
00534                         default:
00535                                 LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
00536                                 goto illegal_opcode;
00537                         }
00538                         if (rm >= 0xc0 ) {GetEArw;*earw=val;}
00539                         else {GetEAa;SaveMw(eaa,val);}
00540                         break;
00541                 }
00542         CASE_W(0x8d)                                                                                            /* LEA Gw */
00543                 {
00544                         //Little hack to always use segprefixed version
00545                         BaseDS=BaseSS=0;
00546                         GetRMrw;
00547                         if (TEST_PREFIX_ADDR) {
00548                                 *rmrw=(Bit16u)(*EATable[256+rm])();
00549                         } else {
00550                                 *rmrw=(Bit16u)(*EATable[rm])();
00551                         }
00552                         break;
00553                 }
00554         CASE_B(0x8e)                                                                                            /* MOV Sw,Ew */
00555                 {
00556                         GetRM;Bit16u val;Bitu which=(rm>>3)&7;
00557                         if (rm >= 0xc0 ) {GetEArw;val=*earw;}
00558                         else {GetEAa;val=LoadMw(eaa);}
00559                         switch (which) {
00560 #if CPU_CORE <= CPU_ARCHTYPE_8086
00561                         case 0x01:                                      /* MOV CS,Ew (8086 only) */
00562 #endif
00563                         case 0x02:                                      /* MOV SS,Ew */
00564                                 CPU_Cycles++; //Always do another instruction
00565                         case 0x00:                                      /* MOV ES,Ew */
00566                         case 0x03:                                      /* MOV DS,Ew */
00567                         case 0x05:                                      /* MOV GS,Ew */
00568                         case 0x04:                                      /* MOV FS,Ew */
00569                                 if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION();
00570                                 break;
00571                         default:
00572                                 goto illegal_opcode;
00573                         }
00574                         break;
00575                 }                                                       
00576         CASE_W(0x8f)                                                                                            /* POP Ew */
00577                 {
00578                         Bit32u old_esp = reg_esp;
00579 
00580                         try {
00581                                 Bit16u val=Pop_16();
00582                                 GetRM;
00583                                 if (rm >= 0xc0 ) {GetEArw;*earw=val;}
00584                                 else {GetEAa;SaveMw(eaa,val);}
00585                         }
00586                         catch (GuestPageFaultException &pf) {
00587                                 (void)pf;
00588                                 reg_esp = old_esp;
00589                                 throw;
00590                         }
00591                 } break;
00592         CASE_B(0x90)                                                                                            /* NOP */
00593                 break;
00594         CASE_W(0x91)                                                                                            /* XCHG CX,AX */
00595                 { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; }
00596                 break;
00597         CASE_W(0x92)                                                                                            /* XCHG DX,AX */
00598                 { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; }
00599                 break;
00600         CASE_W(0x93)                                                                                            /* XCHG BX,AX */
00601                 { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; }
00602                 break;
00603         CASE_W(0x94)                                                                                            /* XCHG SP,AX */
00604                 { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; }
00605                 break;
00606         CASE_W(0x95)                                                                                            /* XCHG BP,AX */
00607                 { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; }
00608                 break;
00609         CASE_W(0x96)                                                                                            /* XCHG SI,AX */
00610                 { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; }
00611                 break;
00612         CASE_W(0x97)                                                                                            /* XCHG DI,AX */
00613                 { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; }
00614                 break;
00615         CASE_W(0x98)                                                                                            /* CBW */
00616                 reg_ax=(Bit16u)((Bit8s)reg_al);break;
00617         CASE_W(0x99)                                                                                            /* CWD */
00618                 if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0;
00619                 break;
00620         CASE_W(0x9a)                                                                                            /* CALL Ap */
00621                 { 
00622                         FillFlags();
00623                         Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
00624                         CPU_CALL(false,newcs,newip,GETIP);
00625 #if CPU_TRAP_CHECK
00626                         if (GETFLAG(TF)) {      
00627                                 cpudecoder=CPU_Core_Normal_Trap_Run;
00628                                 return CBRET_NONE;
00629                         }
00630 #endif
00631                         continue;
00632                 }
00633         CASE_B(0x9b)                                                                                            /* WAIT */
00634                 break; /* No waiting here */
00635         CASE_W(0x9c)                                                                                            /* PUSHF */
00636                 if (CPU_PUSHF(false)) RUNEXCEPTION();
00637                 break;
00638         CASE_W(0x9d)                                                                                            /* POPF */
00639                 if (CPU_POPF(false)) RUNEXCEPTION();
00640 #if CPU_TRAP_CHECK
00641                 if (GETFLAG(TF)) {      
00642                         cpudecoder=CPU_Core_Normal_Trap_Run;
00643                         goto decode_end;
00644                 }
00645 #endif
00646 #if     CPU_PIC_CHECK
00647                 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
00648 #endif
00649                 break;
00650         CASE_B(0x9e)                                                                                            /* SAHF */
00651                 SETFLAGSb(reg_ah);
00652                 break;
00653         CASE_B(0x9f)                                                                                            /* LAHF */
00654                 FillFlags();
00655                 reg_ah=reg_flags&0xff;
00656                 break;
00657         CASE_B(0xa0)                                                                                            /* MOV AL,Ob */
00658                 { /* NTS: GetEADirect may jump instead to the GP# trigger code if the offset exceeds the segment limit.
00659                           For whatever reason, NOT signalling GP# in that condition prevents Windows 95 OSR2 from starting a DOS VM. Weird. */
00660                         GetEADirect(1);
00661                         reg_al=LoadMb(eaa);
00662                 }
00663                 break;
00664         CASE_W(0xa1)                                                                                            /* MOV AX,Ow */
00665                 { /* NTS: GetEADirect may jump instead to the GP# trigger code if the offset exceeds the segment limit.
00666                           For whatever reason, NOT signalling GP# in that condition prevents Windows 95 OSR2 from starting a DOS VM. Weird. */
00667                         GetEADirect(2);
00668                         reg_ax=LoadMw(eaa);
00669                 }
00670                 break;
00671         CASE_B(0xa2)                                                                                            /* MOV Ob,AL */
00672                 { /* NTS: GetEADirect may jump instead to the GP# trigger code if the offset exceeds the segment limit.
00673                           For whatever reason, NOT signalling GP# in that condition prevents Windows 95 OSR2 from starting a DOS VM. Weird. */
00674                         GetEADirect(1);
00675                         SaveMb(eaa,reg_al);
00676                 }
00677                 break;
00678         CASE_W(0xa3)                                                                                            /* MOV Ow,AX */
00679                 { /* NTS: GetEADirect may jump instead to the GP# trigger code if the offset exceeds the segment limit.
00680                           For whatever reason, NOT signalling GP# in that condition prevents Windows 95 OSR2 from starting a DOS VM. Weird. */
00681                         GetEADirect(2);
00682                         SaveMw(eaa,reg_ax);
00683                 }
00684                 break;
00685         CASE_B(0xa4)                                                                                            /* MOVSB */
00686                 DoString(R_MOVSB);break;
00687         CASE_W(0xa5)                                                                                            /* MOVSW */
00688                 DoString(R_MOVSW);break;
00689         CASE_B(0xa6)                                                                                            /* CMPSB */
00690                 DoString(R_CMPSB);break;
00691         CASE_W(0xa7)                                                                                            /* CMPSW */
00692                 DoString(R_CMPSW);break;
00693         CASE_B(0xa8)                                                                                            /* TEST AL,Ib */
00694                 ALIb(TESTB);break;
00695         CASE_W(0xa9)                                                                                            /* TEST AX,Iw */
00696                 AXIw(TESTW);break;
00697         CASE_B(0xaa)                                                                                            /* STOSB */
00698                 DoString(R_STOSB);break;
00699         CASE_W(0xab)                                                                                            /* STOSW */
00700                 DoString(R_STOSW);break;
00701         CASE_B(0xac)                                                                                            /* LODSB */
00702                 DoString(R_LODSB);break;
00703         CASE_W(0xad)                                                                                            /* LODSW */
00704                 DoString(R_LODSW);break;
00705         CASE_B(0xae)                                                                                            /* SCASB */
00706                 DoString(R_SCASB);break;
00707         CASE_W(0xaf)                                                                                            /* SCASW */
00708                 DoString(R_SCASW);break;
00709         CASE_B(0xb0)                                                                                            /* MOV AL,Ib */
00710                 reg_al=Fetchb();break;
00711         CASE_B(0xb1)                                                                                            /* MOV CL,Ib */
00712                 reg_cl=Fetchb();break;
00713         CASE_B(0xb2)                                                                                            /* MOV DL,Ib */
00714                 reg_dl=Fetchb();break;
00715         CASE_B(0xb3)                                                                                            /* MOV BL,Ib */
00716                 reg_bl=Fetchb();break;
00717         CASE_B(0xb4)                                                                                            /* MOV AH,Ib */
00718                 reg_ah=Fetchb();break;
00719         CASE_B(0xb5)                                                                                            /* MOV CH,Ib */
00720                 reg_ch=Fetchb();break;
00721         CASE_B(0xb6)                                                                                            /* MOV DH,Ib */
00722                 reg_dh=Fetchb();break;
00723         CASE_B(0xb7)                                                                                            /* MOV BH,Ib */
00724                 reg_bh=Fetchb();break;
00725         CASE_W(0xb8)                                                                                            /* MOV AX,Iw */
00726                 reg_ax=Fetchw();break;
00727         CASE_W(0xb9)                                                                                            /* MOV CX,Iw */
00728                 reg_cx=Fetchw();break;
00729         CASE_W(0xba)                                                                                            /* MOV DX,Iw */
00730                 reg_dx=Fetchw();break;
00731         CASE_W(0xbb)                                                                                            /* MOV BX,Iw */
00732                 reg_bx=Fetchw();break;
00733         CASE_W(0xbc)                                                                                            /* MOV SP,Iw */
00734                 reg_sp=Fetchw();break;
00735         CASE_W(0xbd)                                                                                            /* MOV BP.Iw */
00736                 reg_bp=Fetchw();break;
00737         CASE_W(0xbe)                                                                                            /* MOV SI,Iw */
00738                 reg_si=Fetchw();break;
00739         CASE_W(0xbf)                                                                                            /* MOV DI,Iw */
00740                 reg_di=Fetchw();break;
00741 #if CPU_CORE >= CPU_ARCHTYPE_80186
00742         CASE_B(0xc0)                                                                                            /* GRP2 Eb,Ib */
00743                 if (CPU_ArchitectureType < CPU_ARCHTYPE_80186) abort();
00744                 GRP2B(Fetchb());break;
00745         CASE_W(0xc1)                                                                                            /* GRP2 Ew,Ib */
00746                 if (CPU_ArchitectureType < CPU_ARCHTYPE_80186) abort();
00747                 GRP2W(Fetchb());break;
00748 #endif
00749         CASE_W(0xc2)                                                                                            /* RETN Iw */
00750                 {
00751                         Bit32u old_esp = reg_esp;
00752 
00753                         try {
00754                                 /* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
00755                                 Bit32u new_eip = Pop_16();
00756                                 reg_esp += Fetchw();
00757                                 reg_eip = new_eip;
00758                         }
00759                         catch (GuestPageFaultException &pf) {
00760                                 (void)pf;
00761                                 reg_esp = old_esp; /* restore stack pointer */
00762                                 throw;
00763                         }
00764                 } continue;
00765         CASE_W(0xc3)                                                                                            /* RETN */
00766                 reg_eip=Pop_16();
00767                 continue;
00768         CASE_W(0xc4)                                                                                            /* LES */
00769                 {       
00770                         GetRMrw;
00771                         if (rm >= 0xc0) goto illegal_opcode;
00772                         GetEAa;
00773                         if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION();
00774                         *rmrw=LoadMw(eaa);
00775                         break;
00776                 }
00777         CASE_W(0xc5)                                                                                            /* LDS */
00778                 {       
00779                         GetRMrw;
00780                         if (rm >= 0xc0) goto illegal_opcode;
00781                         GetEAa;
00782                         if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION();
00783                         *rmrw=LoadMw(eaa);
00784                         break;
00785                 }
00786         CASE_B(0xc6)                                                                                            /* MOV Eb,Ib */
00787                 {
00788                         GetRM;
00789                         if (rm >= 0xc0) {GetEArb;*earb=Fetchb();}
00790                         else {GetEAa;SaveMb(eaa,Fetchb());}
00791                         break;
00792                 }
00793         CASE_W(0xc7)                                                                                            /* MOV EW,Iw */
00794                 {
00795                         GetRM;
00796                         if (rm >= 0xc0) {GetEArw;*earw=Fetchw();}
00797                         else {GetEAa;SaveMw(eaa,Fetchw());}
00798                         break;
00799                 }
00800         CASE_W(0xc8)                                                                                            /* ENTER Iw,Ib */
00801                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00802                 {
00803                         Bitu bytes=Fetchw();
00804                         Bitu level=Fetchb();
00805                         CPU_ENTER(false,bytes,level);
00806                 }
00807                 break;
00808         CASE_W(0xc9)                                                                                            /* LEAVE */
00809                 if (CPU_ArchitectureType<CPU_ARCHTYPE_80186) goto illegal_opcode;
00810                 {
00811                         Bit32u old_esp = reg_esp;
00812 
00813                         reg_esp &= cpu.stack.notmask;
00814                         reg_esp |= reg_ebp&cpu.stack.mask;
00815                         try {
00816                                 reg_bp = Pop_16();
00817                         }
00818                         catch (GuestPageFaultException &pf) {
00819                                 (void)pf;
00820                                 reg_esp = old_esp;
00821                                 throw;
00822                         }
00823                 } break;
00824         CASE_W(0xca)                                                                                            /* RETF Iw */
00825                 {
00826                         Bitu words=Fetchw();
00827                         FillFlags();
00828                         CPU_RET(false,words,GETIP);
00829                         continue;
00830                 }
00831         CASE_W(0xcb)                                                                                            /* RETF */                      
00832                 FillFlags();
00833                 CPU_RET(false,0,GETIP);
00834                 continue;
00835         CASE_B(0xcc)                                                                                            /* INT3 */
00836 #if C_DEBUG     
00837                 FillFlags();
00838                 if (DEBUG_Breakpoint())
00839                         return (Bits)debugCallback;
00840                 if (DEBUG_IntBreakpoint(3))
00841                         return (Bits)debugCallback;
00842 #endif                  
00843                 CPU_SW_Interrupt_NoIOPLCheck(3,GETIP);
00844 #if CPU_TRAP_CHECK
00845                 cpu.trap_skip=true;
00846 #endif
00847                 continue;
00848         CASE_B(0xcd)                                                                                            /* INT Ib */    
00849                 {
00850                         Bit8u num=Fetchb();
00851 #if C_DEBUG
00852                         FillFlags();
00853                         if (DEBUG_IntBreakpoint(num)) {
00854                                 return (Bits)debugCallback;
00855                         }
00856 #endif
00857                         CPU_SW_Interrupt(num,GETIP);
00858 #if CPU_TRAP_CHECK
00859                         cpu.trap_skip=true;
00860 #endif
00861                         continue;
00862                 }
00863         CASE_B(0xce)                                                                                            /* INTO */
00864                 if (get_OF()) {
00865                         CPU_SW_Interrupt(4,GETIP);
00866 #if CPU_TRAP_CHECK
00867                         cpu.trap_skip=true;
00868 #endif
00869                         continue;
00870                 }
00871                 break;
00872         CASE_W(0xcf)                                                                                            /* IRET */
00873                 {
00874                         CPU_IRET(false,GETIP);
00875 #if CPU_TRAP_CHECK
00876                         if (GETFLAG(TF)) {      
00877                                 cpudecoder=CPU_Core_Normal_Trap_Run;
00878                                 return CBRET_NONE;
00879                         }
00880 #endif
00881 #if CPU_PIC_CHECK
00882                         if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
00883 #endif
00884                         continue;
00885                 }
00886         CASE_B(0xd0)                                                                                            /* GRP2 Eb,1 */
00887                 GRP2B(1);break;
00888         CASE_W(0xd1)                                                                                            /* GRP2 Ew,1 */
00889                 GRP2W(1);break;
00890         CASE_B(0xd2)                                                                                            /* GRP2 Eb,CL */
00891                 GRP2B(reg_cl);break;
00892         CASE_W(0xd3)                                                                                            /* GRP2 Ew,CL */
00893                 GRP2W(reg_cl);break;
00894         CASE_B(0xd4)                                                                                            /* AAM Ib */
00895                 AAM(Fetchb());break;
00896         CASE_B(0xd5)                                                                                            /* AAD Ib */
00897                 AAD(Fetchb());break;
00898         CASE_B(0xd6)                                                                                            /* SALC */
00899                 reg_al = get_CF() ? 0xFF : 0;
00900                 break;
00901         CASE_B(0xd7)                                                                                            /* XLAT */
00902                 if (TEST_PREFIX_ADDR) {
00903                         reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al));
00904                 } else {
00905                         reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al));
00906                 }
00907                 break;
00908 #ifdef CPU_FPU
00909         CASE_B(0xd8)                                                                                            /* FPU ESC 0 */
00910                 if (enable_fpu) {
00911                         FPU_ESC(0);
00912                 }
00913                 else {
00914                         Bit8u rm=Fetchb();
00915                         if (rm<0xc0) { GetEAa; (void)eaa; }
00916                 }
00917                 break;
00918         CASE_B(0xd9)                                                                                            /* FPU ESC 1 */
00919                 if (enable_fpu) {
00920                         FPU_ESC(1);
00921                 }
00922                 else {
00923                         Bit8u rm=Fetchb();
00924                         if (rm<0xc0) { GetEAa; (void)eaa; }
00925                 }
00926                 break;
00927         CASE_B(0xda)                                                                                            /* FPU ESC 2 */
00928                 if (enable_fpu) {
00929                         FPU_ESC(2);
00930                 }
00931                 else {
00932                         Bit8u rm=Fetchb();
00933                         if (rm<0xc0) { GetEAa; (void)eaa; }
00934                 }
00935                 break;
00936         CASE_B(0xdb)                                                                                            /* FPU ESC 3 */
00937                 if (enable_fpu) {
00938                         FPU_ESC(3);
00939                 }
00940                 else {
00941                         Bit8u rm=Fetchb();
00942                         if (rm<0xc0) { GetEAa; (void)eaa; }
00943                 }
00944                 break;
00945         CASE_B(0xdc)                                                                                            /* FPU ESC 4 */
00946                 if (enable_fpu) {
00947                         FPU_ESC(4);
00948                 }
00949                 else {
00950                         Bit8u rm=Fetchb();
00951                         if (rm<0xc0) { GetEAa; (void)eaa; }
00952                 }
00953                 break;
00954         CASE_B(0xdd)                                                                                            /* FPU ESC 5 */
00955                 if (enable_fpu) {
00956                         FPU_ESC(5);
00957                 }
00958                 else {
00959                         Bit8u rm=Fetchb();
00960                         if (rm<0xc0) { GetEAa; (void)eaa; }
00961                 }
00962                 break;
00963         CASE_B(0xde)                                                                                            /* FPU ESC 6 */
00964                 if (enable_fpu) {
00965                         FPU_ESC(6);
00966                 }
00967                 else {
00968                         Bit8u rm=Fetchb();
00969                         if (rm<0xc0) { GetEAa; (void)eaa; }
00970                 }
00971                 break;
00972         CASE_B(0xdf)                                                                                            /* FPU ESC 7 */
00973                 if (enable_fpu) {
00974                         FPU_ESC(7);
00975                 }
00976                 else {
00977                         Bit8u rm=Fetchb();
00978                         if (rm<0xc0) { GetEAa; (void)eaa; }
00979                 }
00980                 break;
00981 #else 
00982         CASE_B(0xd8)                                                                                            /* FPU ESC 0 */
00983         CASE_B(0xd9)                                                                                            /* FPU ESC 1 */
00984         CASE_B(0xda)                                                                                            /* FPU ESC 2 */
00985         CASE_B(0xdb)                                                                                            /* FPU ESC 3 */
00986         CASE_B(0xdc)                                                                                            /* FPU ESC 4 */
00987         CASE_B(0xdd)                                                                                            /* FPU ESC 5 */
00988         CASE_B(0xde)                                                                                            /* FPU ESC 6 */
00989         CASE_B(0xdf)                                                                                            /* FPU ESC 7 */
00990                 {
00991                         LOG(LOG_CPU,LOG_NORMAL)("FPU used");
00992                         Bit8u rm=Fetchb();
00993                         if (rm<0xc0) GetEAa;
00994                 }
00995                 break;
00996 #endif
00997         CASE_W(0xe0)                                                                                            /* LOOPNZ */
00998                 if (TEST_PREFIX_ADDR) {
00999                         JumpCond16_b(--reg_ecx && !get_ZF());
01000                 } else {
01001                         JumpCond16_b(--reg_cx && !get_ZF());
01002                 }
01003                 break;
01004         CASE_W(0xe1)                                                                                            /* LOOPZ */
01005                 if (TEST_PREFIX_ADDR) {
01006                         JumpCond16_b(--reg_ecx && get_ZF());
01007                 } else {
01008                         JumpCond16_b(--reg_cx && get_ZF());
01009                 }
01010                 break;
01011         CASE_W(0xe2)                                                                                            /* LOOP */
01012                 if (TEST_PREFIX_ADDR) { 
01013                         JumpCond16_b(--reg_ecx);
01014                 } else {
01015                         JumpCond16_b(--reg_cx);
01016                 }
01017                 break;
01018         CASE_W(0xe3)                                                                                            /* JCXZ */
01019                 JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
01020                 break;
01021         CASE_B(0xe4)                                                                                            /* IN AL,Ib */
01022                 {       
01023                         Bitu port=Fetchb();
01024                         if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
01025                         reg_al=IO_ReadB(port);
01026                         break;
01027                 }
01028         CASE_W(0xe5)                                                                                            /* IN AX,Ib */
01029                 {       
01030                         Bitu port=Fetchb();
01031                         if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
01032                         reg_ax=IO_ReadW(port);
01033                         break;
01034                 }
01035         CASE_B(0xe6)                                                                                            /* OUT Ib,AL */
01036                 {
01037                         Bitu port=Fetchb();
01038                         if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
01039                         IO_WriteB(port,reg_al);
01040                         break;
01041                 }               
01042         CASE_W(0xe7)                                                                                            /* OUT Ib,AX */
01043                 {
01044                         Bitu port=Fetchb();
01045                         if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
01046                         IO_WriteW(port,reg_ax);
01047                         break;
01048                 }
01049         CASE_W(0xe8)                                                                                            /* CALL Jw */
01050                 { 
01051                         /* must not adjust (E)IP until we have completed the instruction.
01052                          * if interrupted by a page fault, EIP must be unmodified. */
01053                         Bit16u addip=(Bit16u)Fetchws();
01054                         Bit16u here=GETIP;
01055                         Push_16(here);
01056                         reg_eip=(Bit16u)(addip+here);
01057                         continue;
01058                 }
01059         CASE_W(0xe9)                                                                                            /* JMP Jw */
01060                 { 
01061                         Bit16u addip=(Bit16u)Fetchws();
01062                         SAVEIP;
01063                         reg_eip=(Bit16u)(reg_eip+addip);
01064                         continue;
01065                 }
01066         CASE_W(0xea)                                                                                            /* JMP Ap */
01067                 { 
01068                         Bit16u newip=Fetchw();
01069                         Bit16u newcs=Fetchw();
01070                         FillFlags();
01071                         CPU_JMP(false,newcs,newip,GETIP);
01072 #if CPU_TRAP_CHECK
01073                         if (GETFLAG(TF)) {      
01074                                 cpudecoder=CPU_Core_Normal_Trap_Run;
01075                                 return CBRET_NONE;
01076                         }
01077 #endif
01078                         continue;
01079                 }
01080         CASE_W(0xeb)                                                                                            /* JMP Jb */
01081                 { 
01082                         Bit16s addip=Fetchbs();
01083                         SAVEIP;
01084                         reg_eip=(Bit16u)(reg_eip+(Bit32u)addip);
01085                         continue;
01086                 }
01087         CASE_B(0xec)                                                                                            /* IN AL,DX */
01088                 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
01089                 reg_al=IO_ReadB(reg_dx);
01090                 break;
01091         CASE_W(0xed)                                                                                            /* IN AX,DX */
01092                 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
01093                 reg_ax=IO_ReadW(reg_dx);
01094                 break;
01095         CASE_B(0xee)                                                                                            /* OUT DX,AL */
01096                 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
01097                 IO_WriteB(reg_dx,reg_al);
01098                 break;
01099         CASE_W(0xef)                                                                                            /* OUT DX,AX */
01100                 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
01101                 IO_WriteW(reg_dx,reg_ax);
01102                 break;
01103         CASE_B(0xf0)                                                                                            /* LOCK */
01104 // todo: make an option to show this
01105 //              LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */
01106                 break;
01107         CASE_B(0xf1)                                                                                            /* ICEBP */
01108                 CPU_SW_Interrupt_NoIOPLCheck(1,GETIP);
01109 #if CPU_TRAP_CHECK
01110                 cpu.trap_skip=true;
01111 #endif
01112                 continue;
01113         CASE_B(0xf2)                                                                                            /* REPNZ */
01114                 DO_PREFIX_REP(false);   
01115                 break;          
01116         CASE_B(0xf3)                                                                                            /* REPZ */
01117                 DO_PREFIX_REP(true);    
01118                 break;          
01119         CASE_B(0xf4)                                                                                            /* HLT */
01120                 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
01121                 FillFlags();
01122                 CPU_HLT(GETIP);
01123                 return CBRET_NONE;              //Needs to return for hlt cpu core
01124         CASE_B(0xf5)                                                                                            /* CMC */
01125                 FillFlags();
01126                 SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
01127                 break;
01128         CASE_B(0xf6)                                                                                            /* GRP3 Eb(,Ib) */
01129                 {       
01130                         GetRM;Bitu which=(rm>>3)&7;
01131                         switch (which) {
01132                         case 0x00:                                                                                      /* TEST Eb,Ib */
01133                         case 0x01:                                                                                      /* TEST Eb,Ib Undocumented*/
01134                                 {
01135                                         if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)}
01136                                         else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);}
01137                                         break;
01138                                 }
01139                         case 0x02:                                                                                      /* NOT Eb */
01140                                 {
01141                                         if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;}
01142                                         else {GetEAa;SaveMb(eaa,~LoadMb(eaa));}
01143                                         break;
01144                                 }
01145                         case 0x03:                                                                                      /* NEG Eb */
01146                                 {
01147                                         lflags.type=t_NEGb;
01148                                         if (rm >= 0xc0 ) {
01149                                                 GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b;
01150                                                 *earb=lf_resb;
01151                                         } else {
01152                                                 GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b;
01153                                                 SaveMb(eaa,lf_resb);
01154                                         }
01155                                         break;
01156                                 }
01157                         case 0x04:                                                                                      /* MUL AL,Eb */
01158                                 RMEb(MULB);
01159                                 break;
01160                         case 0x05:                                                                                      /* IMUL AL,Eb */
01161                                 RMEb(IMULB);
01162                                 break;
01163                         case 0x06:                                                                                      /* DIV Eb */
01164                                 RMEb(DIVB);
01165                                 break;
01166                         case 0x07:                                                                                      /* IDIV Eb */
01167                                 RMEb(IDIVB);
01168                                 break;
01169                         }
01170                         break;
01171                 }
01172         CASE_W(0xf7)                                                                                            /* GRP3 Ew(,Iw) */
01173                 { 
01174                         GetRM;Bitu which=(rm>>3)&7;
01175                         switch (which) {
01176                         case 0x00:                                                                                      /* TEST Ew,Iw */
01177                         case 0x01:                                                                                      /* TEST Ew,Iw Undocumented*/
01178                                 {
01179                                         if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);}
01180                                         else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);}
01181                                         break;
01182                                 }
01183                         case 0x02:                                                                                      /* NOT Ew */
01184                                 {
01185                                         if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;}
01186                                         else {GetEAa;SaveMw(eaa,(Bitu)(~LoadMw(eaa)));}
01187                                         break;
01188                                 }
01189                         case 0x03:                                                                                      /* NEG Ew */
01190                                 {
01191                                         lflags.type=t_NEGw;
01192                                         if (rm >= 0xc0 ) {
01193                                                 GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w;
01194                                                 *earw=lf_resw;
01195                                         } else {
01196                                                 GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w;
01197                                                 SaveMw(eaa,lf_resw);
01198                                         }
01199                                         break;
01200                                 }
01201                         case 0x04:                                                                                      /* MUL AX,Ew */
01202                                 RMEw(MULW);
01203                                 break;
01204                         case 0x05:                                                                                      /* IMUL AX,Ew */
01205                                 RMEw(IMULW)
01206                                 break;
01207                         case 0x06:                                                                                      /* DIV Ew */
01208                                 RMEw(DIVW)
01209                                 break;
01210                         case 0x07:                                                                                      /* IDIV Ew */
01211                                 RMEw(IDIVW)
01212                                 break;
01213                         }
01214                         break;
01215                 }
01216         CASE_B(0xf8)                                                                                            /* CLC */
01217                 FillFlags();
01218                 SETFLAGBIT(CF,false);
01219                 break;
01220         CASE_B(0xf9)                                                                                            /* STC */
01221                 FillFlags();
01222                 SETFLAGBIT(CF,true);
01223                 break;
01224         CASE_B(0xfa)                                                                                            /* CLI */
01225 do_cli: if (CPU_CLI()) RUNEXCEPTION();
01226                 break;
01227         CASE_B(0xfb)                                                                                            /* STI */
01228                 if (CPU_STI()) RUNEXCEPTION();
01229 #if CPU_PIC_CHECK
01230                 if (GETFLAG(IF) && PIC_IRQCheck) {
01231             // NTS: Do not immmediately break execution, but set the cycle count to a minimal
01232             //      value so that if a CLI follows immediately the interrupt will be ignored.
01233             //
01234             //      It turns out on a 486 that STI+CLI (right next to each other) does not
01235             //      trigger the CPU to process interrupts. Like this:
01236             //
01237             //      STI
01238             //      CLI
01239             //
01240             //      The FM music driver for the PC-98 version of Peret em Heru appears to have
01241             //      STI+CLI sequences for some reason in certain subroutines within the FM
01242             //      music interrupt handler, which should not be trigger points to process
01243             //      interrupts because the FM interrupt is non-reentrant and Peret is also
01244             //      calling another entry point to the FM driver from IRQ 2 (vsync). If
01245             //      IRQ 2 is processed while the FM interrupt is processing at the STI, the
01246             //      stack switch will overwrite the first and the FM interrupt will return
01247             //      by stale data and crash.
01248             //
01249             //      [https://github.com/joncampbell123/dosbox-x/issues/1162]
01250             //
01251             // NTS: The prior fix that set CPU_Cycles = 4 causes the normal core to get stuck
01252             //      and never break out (hanging DOSBox-X) when running PC-98 game Night Slave,
01253             //      so that isn't a long-term option.
01254             {
01255                 Bit8u b = FetchPeekb();
01256                 if (b == 0xFAu) {
01257                     /* if the next opcode is CLI, then do CLI right here before the normal core
01258                      * has any chance to break and handle interrupts */
01259                     FetchDiscardb(); // discard opcode we peeked, and then go execute it
01260                     CPU_Cycles--; // we're executing another instruction, which should eat one CPU cycle
01261                     goto do_cli;
01262                 }
01263             }
01264             // otherwise, break for interrupt handling as normal
01265             if (CPU_Cycles > 2) {
01266                 CPU_CycleLeft += CPU_Cycles - 2;
01267                 CPU_Cycles = 2;
01268             }
01269             else {
01270                 goto decode_end;
01271             }
01272         }
01273 #endif
01274                 break;
01275         CASE_B(0xfc)                                                                                            /* CLD */
01276                 SETFLAGBIT(DF,false);
01277                 cpu.direction=1;
01278                 break;
01279         CASE_B(0xfd)                                                                                            /* STD */
01280                 SETFLAGBIT(DF,true);
01281                 cpu.direction=-1;
01282                 break;
01283         CASE_B(0xfe)                                                                                            /* GRP4 Eb */
01284                 {
01285                         GetRM;Bitu which=(rm>>3)&7;
01286                         switch (which) {
01287                         case 0x00:                                                                              /* INC Eb */
01288                                 RMEb(INCB);
01289                                 break;          
01290                         case 0x01:                                                                              /* DEC Eb */
01291                                 RMEb(DECB);
01292                                 break;
01293                         case 0x07:                                                                              /* CallBack */
01294                                 {
01295                                         Bitu cb=Fetchw();
01296                                         FillFlags();SAVEIP;
01297                                         return (Bits)cb;
01298                                 }
01299                         default:
01300                                 LOG(LOG_CPU,LOG_DEBUG)("Illegal GRP4 Call %d",(rm>>3) & 7);
01301                                 goto illegal_opcode;
01302                         }
01303                         break;
01304                 }
01305         CASE_W(0xff)                                                                                            /* GRP5 Ew */
01306                 {
01307                         GetRM;Bitu which=(rm>>3)&7;
01308                         switch (which) {
01309                         case 0x00:                                                                              /* INC Ew */
01310                                 RMEw(INCW);
01311                                 break;          
01312                         case 0x01:                                                                              /* DEC Ew */
01313                                 RMEw(DECW);
01314                                 break;          
01315                         case 0x02:                                                                              /* CALL Ev */
01316                                 { /* either EIP is set to the call address or EIP does not change if interrupted by PF */
01317                                         Bit16u new_eip;
01318                                         if (rm >= 0xc0 ) {GetEArw;new_eip=*earw;}
01319                                         else {GetEAa;new_eip=LoadMw(eaa);}
01320                                         Push_16(GETIP); /* <- PF may happen here */
01321                                         reg_eip = new_eip;
01322                                 }
01323                                 continue;
01324                         case 0x03:                                                                              /* CALL Ep */
01325                                 {
01326                                         if (rm >= 0xc0) goto illegal_opcode;
01327                                         GetEAa;
01328                                         Bit16u newip=LoadMw(eaa);
01329                                         Bit16u newcs=LoadMw(eaa+2);
01330                                         FillFlags();
01331                                         CPU_CALL(false,newcs,newip,GETIP);
01332 #if CPU_TRAP_CHECK
01333                                         if (GETFLAG(TF)) {      
01334                                                 cpudecoder=CPU_Core_Normal_Trap_Run;
01335                                                 return CBRET_NONE;
01336                                         }
01337 #endif
01338                                         continue;
01339                                 }
01340                                 break;
01341                         case 0x04:                                                                              /* JMP Ev */    
01342                                 if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;}
01343                                 else {GetEAa;reg_eip=LoadMw(eaa);}
01344                                 continue;
01345                         case 0x05:                                                                              /* JMP Ep */    
01346                                 {
01347                                         if (rm >= 0xc0) goto illegal_opcode;
01348                                         GetEAa;
01349                                         Bit16u newip=LoadMw(eaa);
01350                                         Bit16u newcs=LoadMw(eaa+2);
01351                                         FillFlags();
01352                                         CPU_JMP(false,newcs,newip,GETIP);
01353 #if CPU_TRAP_CHECK
01354                                         if (GETFLAG(TF)) {      
01355                                                 cpudecoder=CPU_Core_Normal_Trap_Run;
01356                                                 return CBRET_NONE;
01357                                         }
01358 #endif
01359                                         continue;
01360                                 }
01361                                 break;
01362                         case 0x06:                                                                              /* PUSH Ev */
01363                                 if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);}
01364                                 else {GetEAa;Push_16(LoadMw(eaa));}
01365                                 break;
01366                         default:
01367                                 goto illegal_opcode;
01368                         }
01369                         break;
01370                 }
01371                         
01372 
01373 
01374