DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_normal/prefix_66.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_D(0x01)                                                                                            /* ADD Ed,Gd */
00020                 RMEdGd(ADDD);break;     
00021         CASE_D(0x03)                                                                                            /* ADD Gd,Ed */
00022                 RMGdEd(ADDD);break;
00023         CASE_D(0x05)                                                                                            /* ADD EAX,Id */
00024                 EAXId(ADDD);break;
00025         CASE_D(0x06)                                                                                            /* PUSH ES */           
00026                 Push_32(SegValue(es));break;
00027         CASE_D(0x07)                                                                                            /* POP ES */
00028                 if (CPU_PopSeg(es,true)) RUNEXCEPTION();
00029                 break;
00030         CASE_D(0x09)                                                                                            /* OR Ed,Gd */
00031                 RMEdGd(ORD);break;
00032         CASE_D(0x0b)                                                                                            /* OR Gd,Ed */
00033                 RMGdEd(ORD);break;
00034         CASE_D(0x0d)                                                                                            /* OR EAX,Id */
00035                 EAXId(ORD);break;
00036         CASE_D(0x0e)                                                                                            /* PUSH CS */           
00037                 Push_32(SegValue(cs));break;
00038         CASE_D(0x11)                                                                                            /* ADC Ed,Gd */
00039                 RMEdGd(ADCD);break;     
00040         CASE_D(0x13)                                                                                            /* ADC Gd,Ed */
00041                 RMGdEd(ADCD);break;
00042         CASE_D(0x15)                                                                                            /* ADC EAX,Id */
00043                 EAXId(ADCD);break;
00044         CASE_D(0x16)                                                                                            /* PUSH SS */
00045                 Push_32(SegValue(ss));break;
00046         CASE_D(0x17)                                                                                            /* POP SS */
00047                 if (CPU_PopSeg(ss,true)) RUNEXCEPTION();
00048                 CPU_Cycles++;
00049                 break;
00050         CASE_D(0x19)                                                                                            /* SBB Ed,Gd */
00051                 RMEdGd(SBBD);break;
00052         CASE_D(0x1b)                                                                                            /* SBB Gd,Ed */
00053                 RMGdEd(SBBD);break;
00054         CASE_D(0x1d)                                                                                            /* SBB EAX,Id */
00055                 EAXId(SBBD);break;
00056         CASE_D(0x1e)                                                                                            /* PUSH DS */           
00057                 Push_32(SegValue(ds));break;
00058         CASE_D(0x1f)                                                                                            /* POP DS */
00059                 if (CPU_PopSeg(ds,true)) RUNEXCEPTION();
00060                 break;
00061         CASE_D(0x21)                                                                                            /* AND Ed,Gd */
00062                 RMEdGd(ANDD);break;     
00063         CASE_D(0x23)                                                                                            /* AND Gd,Ed */
00064                 RMGdEd(ANDD);break;
00065         CASE_D(0x25)                                                                                            /* AND EAX,Id */
00066                 EAXId(ANDD);break;
00067         CASE_D(0x29)                                                                                            /* SUB Ed,Gd */
00068                 RMEdGd(SUBD);break;
00069         CASE_D(0x2b)                                                                                            /* SUB Gd,Ed */
00070                 RMGdEd(SUBD);break;
00071         CASE_D(0x2d)                                                                                            /* SUB EAX,Id */
00072                 EAXId(SUBD);break;
00073         CASE_D(0x31)                                                                                            /* XOR Ed,Gd */
00074                 RMEdGd(XORD);break;     
00075         CASE_D(0x33)                                                                                            /* XOR Gd,Ed */
00076                 RMGdEd(XORD);break;
00077         CASE_D(0x35)                                                                                            /* XOR EAX,Id */
00078                 EAXId(XORD);break;
00079         CASE_D(0x39)                                                                                            /* CMP Ed,Gd */
00080                 RMEdGd(CMPD);break;
00081         CASE_D(0x3b)                                                                                            /* CMP Gd,Ed */
00082                 RMGdEd(CMPD);break;
00083         CASE_D(0x3d)                                                                                            /* CMP EAX,Id */
00084                 EAXId(CMPD);break;
00085         CASE_D(0x40)                                                                                            /* INC EAX */
00086                 INCD(reg_eax,LoadRd,SaveRd);break;
00087         CASE_D(0x41)                                                                                            /* INC ECX */
00088                 INCD(reg_ecx,LoadRd,SaveRd);break;
00089         CASE_D(0x42)                                                                                            /* INC EDX */
00090                 INCD(reg_edx,LoadRd,SaveRd);break;
00091         CASE_D(0x43)                                                                                            /* INC EBX */
00092                 INCD(reg_ebx,LoadRd,SaveRd);break;
00093         CASE_D(0x44)                                                                                            /* INC ESP */
00094                 INCD(reg_esp,LoadRd,SaveRd);break;
00095         CASE_D(0x45)                                                                                            /* INC EBP */
00096                 INCD(reg_ebp,LoadRd,SaveRd);break;
00097         CASE_D(0x46)                                                                                            /* INC ESI */
00098                 INCD(reg_esi,LoadRd,SaveRd);break;
00099         CASE_D(0x47)                                                                                            /* INC EDI */
00100                 INCD(reg_edi,LoadRd,SaveRd);break;
00101         CASE_D(0x48)                                                                                            /* DEC EAX */
00102                 DECD(reg_eax,LoadRd,SaveRd);break;
00103         CASE_D(0x49)                                                                                            /* DEC ECX */
00104                 DECD(reg_ecx,LoadRd,SaveRd);break;
00105         CASE_D(0x4a)                                                                                            /* DEC EDX */
00106                 DECD(reg_edx,LoadRd,SaveRd);break;
00107         CASE_D(0x4b)                                                                                            /* DEC EBX */
00108                 DECD(reg_ebx,LoadRd,SaveRd);break;
00109         CASE_D(0x4c)                                                                                            /* DEC ESP */
00110                 DECD(reg_esp,LoadRd,SaveRd);break;
00111         CASE_D(0x4d)                                                                                            /* DEC EBP */
00112                 DECD(reg_ebp,LoadRd,SaveRd);break;
00113         CASE_D(0x4e)                                                                                            /* DEC ESI */
00114                 DECD(reg_esi,LoadRd,SaveRd);break;
00115         CASE_D(0x4f)                                                                                            /* DEC EDI */
00116                 DECD(reg_edi,LoadRd,SaveRd);break;
00117         CASE_D(0x50)                                                                                            /* PUSH EAX */
00118                 Push_32(reg_eax);break;
00119         CASE_D(0x51)                                                                                            /* PUSH ECX */
00120                 Push_32(reg_ecx);break;
00121         CASE_D(0x52)                                                                                            /* PUSH EDX */
00122                 Push_32(reg_edx);break;
00123         CASE_D(0x53)                                                                                            /* PUSH EBX */
00124                 Push_32(reg_ebx);break;
00125         CASE_D(0x54)                                                                                            /* PUSH ESP */
00126                 Push_32(reg_esp);break;
00127         CASE_D(0x55)                                                                                            /* PUSH EBP */
00128                 Push_32(reg_ebp);break;
00129         CASE_D(0x56)                                                                                            /* PUSH ESI */
00130                 Push_32(reg_esi);break;
00131         CASE_D(0x57)                                                                                            /* PUSH EDI */
00132                 Push_32(reg_edi);break;
00133         CASE_D(0x58)                                                                                            /* POP EAX */
00134                 reg_eax=Pop_32();break;
00135         CASE_D(0x59)                                                                                            /* POP ECX */
00136                 reg_ecx=Pop_32();break;
00137         CASE_D(0x5a)                                                                                            /* POP EDX */
00138                 reg_edx=Pop_32();break;
00139         CASE_D(0x5b)                                                                                            /* POP EBX */
00140                 reg_ebx=Pop_32();break;
00141         CASE_D(0x5c)                                                                                            /* POP ESP */
00142                 reg_esp=Pop_32();break;
00143         CASE_D(0x5d)                                                                                            /* POP EBP */
00144                 reg_ebp=Pop_32();break;
00145         CASE_D(0x5e)                                                                                            /* POP ESI */
00146                 reg_esi=Pop_32();break;
00147         CASE_D(0x5f)                                                                                            /* POP EDI */
00148                 reg_edi=Pop_32();break;
00149         CASE_D(0x60)                                                                                            /* PUSHAD */
00150                 {
00151                         Bit32u old_esp = reg_esp;
00152                         try {
00153                                 Bit32u tmpesp = reg_esp;
00154                                 Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
00155                                 Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
00156                         }
00157                         catch (GuestPageFaultException &pf) {
00158                                 (void)pf;
00159                                 LOG_MSG("PUSHAD interrupted by page fault");
00160                                 reg_esp = old_esp;
00161                                 throw;
00162                         }
00163                 } break;
00164         CASE_D(0x61)                                                                                            /* POPAD */
00165                 {
00166                         Bit32u old_esp = reg_esp;
00167                         try {
00168                                 reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
00169                                 reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
00170                         }
00171                         catch (GuestPageFaultException &pf) {
00172                                 (void)pf;
00173                                 LOG_MSG("POPAD interrupted by page fault");
00174                                 reg_esp = old_esp;
00175                                 throw;
00176                         }
00177                 } break;
00178         CASE_D(0x62)                                                                                            /* BOUND Ed */
00179                 {
00180                         Bit32s bound_min, bound_max;
00181                         GetRMrd;GetEAa;
00182                         bound_min=(Bit32s)LoadMd(eaa);
00183                         bound_max=(Bit32s)LoadMd(eaa+4);
00184                         if ( (((Bit32s)*rmrd) < bound_min) || (((Bit32s)*rmrd) > bound_max) ) {
00185                                 EXCEPTION(5);
00186                         }
00187                 }
00188                 break;
00189         CASE_D(0x63)                                                                                            /* ARPL Ed,Rd */
00190                 {
00191                         if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode;
00192                         GetRMrw;
00193                         if (rm >= 0xc0 ) {
00194                                 GetEArd;Bitu new_sel=(Bit16u)*eard;
00195                                 CPU_ARPL(new_sel,*rmrw);
00196                                 *eard=(Bit32u)new_sel;
00197                         } else {
00198                                 GetEAa;Bitu new_sel=LoadMw(eaa);
00199                                 CPU_ARPL(new_sel,*rmrw);
00200                                 SaveMd(eaa,(Bit32u)new_sel);
00201                         }
00202                 }
00203                 break;
00204         CASE_D(0x68)                                                                                            /* PUSH Id */
00205                 Push_32(Fetchd());break;
00206         CASE_D(0x69)                                                                                            /* IMUL Gd,Ed,Id */
00207                 RMGdEdOp3(DIMULD,Fetchds());
00208                 break;
00209         CASE_D(0x6a)                                                                                            /* PUSH Ib */
00210                 Push_32((Bit32u)Fetchbs());break;
00211         CASE_D(0x6b)                                                                                            /* IMUL Gd,Ed,Ib */
00212                 RMGdEdOp3(DIMULD,Fetchbs());
00213                 break;
00214         CASE_D(0x6d)                                                                                            /* INSD */
00215                 if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
00216                 DoString(R_INSD);break;
00217         CASE_D(0x6f)                                                                                            /* OUTSD */
00218                 if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
00219                 DoString(R_OUTSD);break;
00220         CASE_D(0x70)                                                                                            /* JO */
00221                 JumpCond32_b(TFLG_O);break;
00222         CASE_D(0x71)                                                                                            /* JNO */
00223                 JumpCond32_b(TFLG_NO);break;
00224         CASE_D(0x72)                                                                                            /* JB */
00225                 JumpCond32_b(TFLG_B);break;
00226         CASE_D(0x73)                                                                                            /* JNB */
00227                 JumpCond32_b(TFLG_NB);break;
00228         CASE_D(0x74)                                                                                            /* JZ */
00229                 JumpCond32_b(TFLG_Z);break;
00230         CASE_D(0x75)                                                                                            /* JNZ */
00231                 JumpCond32_b(TFLG_NZ);break;
00232         CASE_D(0x76)                                                                                            /* JBE */
00233                 JumpCond32_b(TFLG_BE);break;
00234         CASE_D(0x77)                                                                                            /* JNBE */
00235                 JumpCond32_b(TFLG_NBE);break;
00236         CASE_D(0x78)                                                                                            /* JS */
00237                 JumpCond32_b(TFLG_S);break;
00238         CASE_D(0x79)                                                                                            /* JNS */
00239                 JumpCond32_b(TFLG_NS);break;
00240         CASE_D(0x7a)                                                                                            /* JP */
00241                 JumpCond32_b(TFLG_P);break;
00242         CASE_D(0x7b)                                                                                            /* JNP */
00243                 JumpCond32_b(TFLG_NP);break;
00244         CASE_D(0x7c)                                                                                            /* JL */
00245                 JumpCond32_b(TFLG_L);break;
00246         CASE_D(0x7d)                                                                                            /* JNL */
00247                 JumpCond32_b(TFLG_NL);break;
00248         CASE_D(0x7e)                                                                                            /* JLE */
00249                 JumpCond32_b(TFLG_LE);break;
00250         CASE_D(0x7f)                                                                                            /* JNLE */
00251                 JumpCond32_b(TFLG_NLE);break;
00252         CASE_D(0x81)                                                                                            /* Grpl Ed,Id */
00253                 {
00254                         GetRM;Bitu which=(rm>>3)&7;
00255                         if (rm >= 0xc0) {
00256                                 GetEArd;Bit32u id=Fetchd();
00257                                 switch (which) {
00258                                 case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
00259                                 case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
00260                                 case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
00261                                 case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
00262                                 case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
00263                                 case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
00264                                 case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
00265                                 case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
00266                                 }
00267                         } else {
00268                                 GetEAa;Bit32u id=Fetchd();
00269                                 switch (which) {
00270                                 case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
00271                                 case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
00272                                 case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
00273                                 case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
00274                                 case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
00275                                 case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
00276                                 case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
00277                                 case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
00278                                 }
00279                         }
00280                 }
00281                 break;
00282         CASE_D(0x83)                                                                                            /* Grpl Ed,Ix */
00283                 {
00284                         GetRM;Bitu which=(rm>>3)&7;
00285                         if (rm >= 0xc0) {
00286                                 GetEArd;Bit32u id=(Bit32u)Fetchbs();
00287                                 switch (which) {
00288                                 case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
00289                                 case 0x01: ORD(*eard,id,LoadRd,SaveRd);break;
00290                                 case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break;
00291                                 case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break;
00292                                 case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break;
00293                                 case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break;
00294                                 case 0x06:XORD(*eard,id,LoadRd,SaveRd);break;
00295                                 case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break;
00296                                 }
00297                         } else {
00298                                 GetEAa;Bit32u id=(Bit32u)Fetchbs();
00299                                 switch (which) {
00300                                 case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
00301                                 case 0x01: ORD(eaa,id,LoadMd,SaveMd);break;
00302                                 case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break;
00303                                 case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break;
00304                                 case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break;
00305                                 case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break;
00306                                 case 0x06:XORD(eaa,id,LoadMd,SaveMd);break;
00307                                 case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break;
00308                                 }
00309                         }
00310                 }
00311                 break;
00312         CASE_D(0x85)                                                                                            /* TEST Ed,Gd */
00313                 RMEdGd(TESTD);break;
00314         CASE_D(0x87)                                                                                            /* XCHG Ed,Gd */
00315                 {       
00316                         GetRMrd;Bit32u oldrmrd=*rmrd;
00317                         if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;}
00318                         else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);}
00319                         break;
00320                 }
00321         CASE_D(0x89)                                                                                            /* MOV Ed,Gd */
00322                 {       
00323                         GetRMrd;
00324                         if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
00325                         else {GetEAa;SaveMd(eaa,*rmrd);}
00326                         break;
00327                 }
00328         CASE_D(0x8b)                                                                                            /* MOV Gd,Ed */
00329                 {       
00330                         GetRMrd;
00331                         if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
00332                         else {GetEAa;*rmrd=LoadMd(eaa);}
00333                         break;
00334                 }
00335         CASE_D(0x8c)                                                                                            /* Mov Ew,Sw */
00336                         {
00337                                 GetRM;Bit16u val;Bitu which=(rm>>3)&7;
00338                                 switch (which) {
00339                                 case 0x00:                                      /* MOV Ew,ES */
00340                                         val=SegValue(es);break;
00341                                 case 0x01:                                      /* MOV Ew,CS */
00342                                         val=SegValue(cs);break;
00343                                 case 0x02:                                      /* MOV Ew,SS */
00344                                         val=SegValue(ss);break;
00345                                 case 0x03:                                      /* MOV Ew,DS */
00346                                         val=SegValue(ds);break;
00347                                 case 0x04:                                      /* MOV Ew,FS */
00348                                         val=SegValue(fs);break;
00349                                 case 0x05:                                      /* MOV Ew,GS */
00350                                         val=SegValue(gs);break;
00351                                 default:
00352                                         LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte");
00353                                         goto illegal_opcode;
00354                                 }
00355                                 if (rm >= 0xc0 ) {GetEArd;*eard=val;}
00356                                 else {GetEAa;SaveMw(eaa,val);}
00357                                 break;
00358                         }       
00359         CASE_D(0x8d)                                                                                            /* LEA Gd */
00360                 {
00361                         //Little hack to always use segprefixed version
00362                         GetRMrd;
00363                         BaseDS=BaseSS=0;
00364                         if (TEST_PREFIX_ADDR) {
00365                                 *rmrd=(Bit32u)(*EATable[256+rm])();
00366                         } else {
00367                                 *rmrd=(Bit32u)(*EATable[rm])();
00368                         }
00369                         break;
00370                 }
00371         CASE_D(0x8f)                                                                                            /* POP Ed */
00372                 {
00373                         Bit32u old_esp = reg_esp;
00374 
00375                         try {
00376                                 Bit32u val=Pop_32();
00377                                 GetRM;
00378                                 if (rm >= 0xc0 ) {GetEArd;*eard=val;}
00379                                 else {GetEAa;SaveMd(eaa,val);}
00380                         }
00381                         catch (GuestPageFaultException &pf) {
00382                                 (void)pf;
00383                                 reg_esp = old_esp;
00384                                 throw;
00385                         }
00386                 } break;
00387         CASE_D(0x91)                                                                                            /* XCHG ECX,EAX */
00388                 { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;}
00389         CASE_D(0x92)                                                                                            /* XCHG EDX,EAX */
00390                 { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;}
00391                 break;
00392         CASE_D(0x93)                                                                                            /* XCHG EBX,EAX */
00393                 { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;}
00394                 break;
00395         CASE_D(0x94)                                                                                            /* XCHG ESP,EAX */
00396                 { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;}
00397                 break;
00398         CASE_D(0x95)                                                                                            /* XCHG EBP,EAX */
00399                 { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;}
00400                 break;
00401         CASE_D(0x96)                                                                                            /* XCHG ESI,EAX */
00402                 { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;}
00403                 break;
00404         CASE_D(0x97)                                                                                            /* XCHG EDI,EAX */
00405                 { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;}
00406                 break;
00407         CASE_D(0x98)                                                                                            /* CWDE */
00408                 reg_eax=(Bit32u)((Bit16s)reg_ax);break;
00409         CASE_D(0x99)                                                                                            /* CDQ */
00410                 if (reg_eax & 0x80000000) reg_edx=0xffffffff;
00411                 else reg_edx=0;
00412                 break;
00413         CASE_D(0x9a)                                                                                            /* CALL FAR Ad */
00414                 { 
00415                         Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
00416                         FillFlags();
00417                         CPU_CALL(true,newcs,newip,GETIP);
00418 #if CPU_TRAP_CHECK
00419                         if (GETFLAG(TF)) {      
00420                                 cpudecoder=CPU_TRAP_DECODER;
00421                                 return CBRET_NONE;
00422                         }
00423 #endif
00424                         continue;
00425                 }
00426         CASE_D(0x9c)                                                                                            /* PUSHFD */
00427                 if (CPU_PUSHF(true)) RUNEXCEPTION();
00428                 break;
00429         CASE_D(0x9d)                                                                                            /* POPFD */
00430                 if (CPU_POPF(true)) RUNEXCEPTION();
00431 #if CPU_TRAP_CHECK
00432                 if (GETFLAG(TF)) {      
00433                         cpudecoder=CPU_TRAP_DECODER;
00434                         goto decode_end;
00435                 }
00436 #endif
00437 #if CPU_PIC_CHECK
00438                 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
00439 #endif
00440                 break;
00441         CASE_D(0xa1)                                                                                            /* MOV EAX,Od */
00442                 { /* NTS: GetEADirect may jump instead to the GP# trigger code if the offset exceeds the segment limit.
00443                           For whatever reason, NOT signalling GP# in that condition prevents Windows 95 OSR2 from starting a DOS VM. Weird. */
00444                         GetEADirect(4);
00445                         reg_eax=LoadMd(eaa);
00446                 }
00447                 break;
00448         CASE_D(0xa3)                                                                                            /* MOV Od,EAX */
00449                 {
00450                         GetEADirect(4);
00451                         SaveMd(eaa,reg_eax);
00452                 }
00453                 break;
00454         CASE_D(0xa5)                                                                                            /* MOVSD */
00455                 DoString(R_MOVSD);break;
00456         CASE_D(0xa7)                                                                                            /* CMPSD */
00457                 DoString(R_CMPSD);break;
00458         CASE_D(0xa9)                                                                                            /* TEST EAX,Id */
00459                 EAXId(TESTD);break;
00460         CASE_D(0xab)                                                                                            /* STOSD */
00461                 DoString(R_STOSD);break;
00462         CASE_D(0xad)                                                                                            /* LODSD */
00463                 DoString(R_LODSD);break;
00464         CASE_D(0xaf)                                                                                            /* SCASD */
00465                 DoString(R_SCASD);break;
00466         CASE_D(0xb8)                                                                                            /* MOV EAX,Id */
00467                 reg_eax=Fetchd();break;
00468         CASE_D(0xb9)                                                                                            /* MOV ECX,Id */
00469                 reg_ecx=Fetchd();break;
00470         CASE_D(0xba)                                                                                            /* MOV EDX,Iw */
00471                 reg_edx=Fetchd();break;
00472         CASE_D(0xbb)                                                                                            /* MOV EBX,Id */
00473                 reg_ebx=Fetchd();break;
00474         CASE_D(0xbc)                                                                                            /* MOV ESP,Id */
00475                 reg_esp=Fetchd();break;
00476         CASE_D(0xbd)                                                                                            /* MOV EBP.Id */
00477                 reg_ebp=Fetchd();break;
00478         CASE_D(0xbe)                                                                                            /* MOV ESI,Id */
00479                 reg_esi=Fetchd();break;
00480         CASE_D(0xbf)                                                                                            /* MOV EDI,Id */
00481                 reg_edi=Fetchd();break;
00482         CASE_D(0xc1)                                                                                            /* GRP2 Ed,Ib */
00483                 GRP2D(Fetchb());break;
00484         CASE_D(0xc2)                                                                                            /* RETN Iw */
00485                 {
00486                         Bit32u old_esp = reg_esp;
00487 
00488                         try {
00489                                 /* this is structured either to complete RET or leave registers unmodified if interrupted by page fault */
00490                                 Bit32u new_eip = Pop_32();
00491                                 reg_esp += Fetchw();
00492                                 reg_eip = new_eip;
00493                         }
00494                         catch (GuestPageFaultException &pf) {
00495                                 (void)pf;
00496                                 reg_esp = old_esp; /* restore stack pointer */
00497                                 throw;
00498                         }
00499                 } continue;
00500         CASE_D(0xc3)                                                                                            /* RETN */
00501                 reg_eip=Pop_32();
00502                 continue;
00503         CASE_D(0xc4)                                                                                            /* LES */
00504                 {       
00505                         GetRMrd;
00506                         if (rm >= 0xc0) goto illegal_opcode;
00507                         GetEAa;
00508                         if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION();
00509                         *rmrd=LoadMd(eaa);
00510                         break;
00511                 }
00512         CASE_D(0xc5)                                                                                            /* LDS */
00513                 {       
00514                         GetRMrd;
00515                         if (rm >= 0xc0) goto illegal_opcode;
00516                         GetEAa;
00517                         if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION();
00518                         *rmrd=LoadMd(eaa);
00519                         break;
00520                 }
00521         CASE_D(0xc7)                                                                                            /* MOV Ed,Id */
00522                 {
00523                         GetRM;
00524                         if (rm >= 0xc0) {GetEArd;*eard=Fetchd();}
00525                         else {GetEAa;SaveMd(eaa,Fetchd());}
00526                         break;
00527                 }
00528         CASE_D(0xc8)                                                                                            /* ENTER Iw,Ib */
00529                 {
00530                         Bitu bytes=Fetchw();
00531                         Bitu level=Fetchb();
00532                         CPU_ENTER(true,bytes,level);
00533                 }
00534                 break;
00535         CASE_D(0xc9)                                                                                            /* LEAVE */
00536                 {
00537                         Bit32u old_esp = reg_esp;
00538 
00539                         reg_esp &= cpu.stack.notmask;
00540                         reg_esp |= reg_ebp&cpu.stack.mask;
00541                         try {
00542                                 reg_ebp = Pop_32();
00543                         }
00544                         catch (GuestPageFaultException &pf) {
00545                                 (void)pf;
00546                                 reg_esp = old_esp;
00547                                 throw;
00548                         }
00549                 } break;
00550         CASE_D(0xca)                                                                                            /* RETF Iw */
00551                 { 
00552                         Bitu words=Fetchw();
00553                         FillFlags();
00554                         CPU_RET(true,words,GETIP);
00555                         continue;
00556                 }
00557         CASE_D(0xcb)                                                                                            /* RETF */                      
00558                 { 
00559                         FillFlags();
00560             CPU_RET(true,0,GETIP);
00561                         continue;
00562                 }
00563         CASE_D(0xcf)                                                                                            /* IRET */
00564                 {
00565                         CPU_IRET(true,GETIP);
00566 #if CPU_TRAP_CHECK
00567                         if (GETFLAG(TF)) {      
00568                                 cpudecoder=CPU_TRAP_DECODER;
00569                                 return CBRET_NONE;
00570                         }
00571 #endif
00572 #if CPU_PIC_CHECK
00573                         if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
00574 #endif
00575                         continue;
00576                 }
00577         CASE_D(0xd1)                                                                                            /* GRP2 Ed,1 */
00578                 GRP2D(1);break;
00579         CASE_D(0xd3)                                                                                            /* GRP2 Ed,CL */
00580                 GRP2D(reg_cl);break;
00581         CASE_D(0xe0)                                                                                            /* LOOPNZ */
00582                 if (TEST_PREFIX_ADDR) {
00583                         JumpCond32_b(--reg_ecx && !get_ZF());
00584                 } else {
00585                         JumpCond32_b(--reg_cx && !get_ZF());
00586                 }
00587                 break;
00588         CASE_D(0xe1)                                                                                            /* LOOPZ */
00589                 if (TEST_PREFIX_ADDR) {
00590                         JumpCond32_b(--reg_ecx && get_ZF());
00591                 } else {
00592                         JumpCond32_b(--reg_cx && get_ZF());
00593                 }
00594                 break;
00595         CASE_D(0xe2)                                                                                            /* LOOP */
00596                 if (TEST_PREFIX_ADDR) { 
00597                         JumpCond32_b(--reg_ecx);
00598                 } else {
00599                         JumpCond32_b(--reg_cx);
00600                 }
00601                 break;
00602         CASE_D(0xe3)                                                                                            /* JCXZ */
00603                 JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
00604                 break;
00605         CASE_D(0xe5)                                                                                            /* IN EAX,Ib */
00606                 {
00607                         Bitu port=Fetchb();
00608                         if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
00609                         reg_eax=IO_ReadD(port);
00610                         break;
00611                 }
00612         CASE_D(0xe7)                                                                                            /* OUT Ib,EAX */
00613                 {
00614                         Bitu port=Fetchb();
00615                         if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
00616                         IO_WriteD(port,reg_eax);
00617                         break;
00618                 }
00619         CASE_D(0xe8)                                                                                            /* CALL Jd */
00620                 { 
00621                         /* must not adjust (E)IP until we have completed the instruction.
00622                          * if interrupted by a page fault, EIP must be unmodified. */
00623                         Bit32s addip=Fetchds();
00624                         Bit32u here=GETIP;
00625                         Push_32(here);
00626                         reg_eip=(Bit32u)((Bit32u)addip+here);
00627                         continue;
00628                 }
00629         CASE_D(0xe9)                                                                                            /* JMP Jd */
00630                 { 
00631                         Bit32s addip=Fetchds();
00632                         SAVEIP;
00633                         reg_eip+=(Bit32u)addip;
00634                         continue;
00635                 }
00636         CASE_D(0xea)                                                                                            /* JMP Ad */
00637                 { 
00638                         Bit32u newip=Fetchd();
00639                         Bit16u newcs=Fetchw();
00640                         FillFlags();
00641                         CPU_JMP(true,newcs,newip,GETIP);
00642 #if CPU_TRAP_CHECK
00643                         if (GETFLAG(TF)) {      
00644                                 cpudecoder=CPU_TRAP_DECODER;
00645                                 return CBRET_NONE;
00646                         }
00647 #endif
00648                         continue;
00649                 }
00650         CASE_D(0xeb)                                                                                            /* JMP Jb */
00651                 { 
00652                         Bit32s addip=Fetchbs();
00653                         SAVEIP;
00654                         reg_eip+=(Bit32u)addip;
00655                         continue;
00656                 }
00657         CASE_D(0xed)                                                                                            /* IN EAX,DX */
00658                 reg_eax=IO_ReadD(reg_dx);
00659                 break;
00660         CASE_D(0xef)                                                                                            /* OUT DX,EAX */
00661                 IO_WriteD(reg_dx,reg_eax);
00662                 break;
00663         CASE_D(0xf7)                                                                                            /* GRP3 Ed(,Id) */
00664                 { 
00665                         GetRM;Bitu which=(rm>>3)&7;
00666                         switch (which) {
00667                         case 0x00:                                                                                      /* TEST Ed,Id */
00668                         case 0x01:                                                                                      /* TEST Ed,Id Undocumented*/
00669                                 {
00670                                         if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
00671                                         else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
00672                                         break;
00673                                 }
00674                         case 0x02:                                                                                      /* NOT Ed */
00675                                 {
00676                                         if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
00677                                         else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
00678                                         break;
00679                                 }
00680                         case 0x03:                                                                                      /* NEG Ed */
00681                                 {
00682                                         lflags.type=t_NEGd;
00683                                         if (rm >= 0xc0 ) {
00684                                                         GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d;
00685                                                 *eard=lf_resd;
00686                                         } else {
00687                                                 GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d;
00688                                                         SaveMd(eaa,lf_resd);
00689                                         }
00690                                         break;
00691                                 }
00692                         case 0x04:                                                                                      /* MUL EAX,Ed */
00693                                 RMEd(MULD);
00694                                 break;
00695                         case 0x05:                                                                                      /* IMUL EAX,Ed */
00696                                 RMEd(IMULD);
00697                                 break;
00698                         case 0x06:                                                                                      /* DIV Ed */
00699                                 RMEd(DIVD);
00700                                 break;
00701                         case 0x07:                                                                                      /* IDIV Ed */
00702                                 RMEd(IDIVD);
00703                                 break;
00704                         }
00705                         break;
00706                 }
00707         CASE_D(0xff)                                                                                            /* GRP 5 Ed */
00708                 {
00709                         GetRM;Bitu which=(rm>>3)&7;
00710                         switch (which) {
00711                         case 0x00:                                                                                      /* INC Ed */
00712                                 RMEd(INCD);
00713                                 break;          
00714                         case 0x01:                                                                                      /* DEC Ed */
00715                                 RMEd(DECD);
00716                                 break;
00717                         case 0x02:                                                                                      /* CALL NEAR Ed */
00718                                 { /* either EIP is set to the call address or EIP does not change if interrupted by PF */
00719                                         Bit32u new_eip;
00720                                         if (rm >= 0xc0 ) {GetEArd;new_eip=*eard;}
00721                                         else {GetEAa;new_eip=LoadMd(eaa);}
00722                                         Push_32(GETIP); /* <- PF can happen here */
00723                                         reg_eip = new_eip;
00724                                 }
00725                                 continue;
00726                         case 0x03:                                                                                      /* CALL FAR Ed */
00727                                 {
00728                                         if (rm >= 0xc0) goto illegal_opcode;
00729                                         GetEAa;
00730                                         Bit32u newip=LoadMd(eaa);
00731                                         Bit16u newcs=LoadMw(eaa+4);
00732                                         FillFlags();
00733                                         CPU_CALL(true,newcs,newip,GETIP);
00734 #if CPU_TRAP_CHECK
00735                                         if (GETFLAG(TF)) {      
00736                                                 cpudecoder=CPU_TRAP_DECODER;
00737                                                 return CBRET_NONE;
00738                                         }
00739 #endif
00740                                         continue;
00741                                 }
00742                         case 0x04:                                                                                      /* JMP NEAR Ed */       
00743                                 if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;}
00744                                 else {GetEAa;reg_eip=LoadMd(eaa);}
00745                                 continue;
00746                         case 0x05:                                                                                      /* JMP FAR Ed */        
00747                                 {
00748                                         if (rm >= 0xc0) goto illegal_opcode;
00749                                         GetEAa;
00750                                         Bit32u newip=LoadMd(eaa);
00751                                         Bit16u newcs=LoadMw(eaa+4);
00752                                         FillFlags();
00753                                         CPU_JMP(true,newcs,newip,GETIP);
00754 #if CPU_TRAP_CHECK
00755                                         if (GETFLAG(TF)) {      
00756                                                 cpudecoder=CPU_TRAP_DECODER;
00757                                                 return CBRET_NONE;
00758                                         }
00759 #endif
00760                                         continue;
00761                                 }
00762                                 break;
00763                         case 0x06:                                                                                      /* Push Ed */
00764                                 if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
00765                                 else {GetEAa;Push_32(LoadMd(eaa));}
00766                                 break;
00767                         default:
00768                                 LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",(int)which);
00769                                 goto illegal_opcode;
00770                         }
00771                         break;
00772                 }
00773 
00774