1 /* 2 * Copyright (C) 2002-2010 The DOSBox Team 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19 CASE_D(0x01) /* ADD Ed,Gd */ 20 RMEdGd(ADDD);break; 21 CASE_D(0x03) /* ADD Gd,Ed */ 22 RMGdEd(ADDD);break; 23 CASE_D(0x05) /* ADD EAX,Id */ 24 EAXId(ADDD);break; 25 CASE_D(0x06) /* PUSH ES */ 26 Push_32(SegValue(es));break; 27 CASE_D(0x07) /* POP ES */ 28 if (CPU_PopSeg(es,true)) RUNEXCEPTION(); 29 break; 30 CASE_D(0x09) /* OR Ed,Gd */ 31 RMEdGd(ORD);break; 32 CASE_D(0x0b) /* OR Gd,Ed */ 33 RMGdEd(ORD);break; 34 CASE_D(0x0d) /* OR EAX,Id */ 35 EAXId(ORD);break; 36 CASE_D(0x0e) /* PUSH CS */ 37 Push_32(SegValue(cs));break; 38 CASE_D(0x11) /* ADC Ed,Gd */ 39 RMEdGd(ADCD);break; 40 CASE_D(0x13) /* ADC Gd,Ed */ 41 RMGdEd(ADCD);break; 42 CASE_D(0x15) /* ADC EAX,Id */ 43 EAXId(ADCD);break; 44 CASE_D(0x16) /* PUSH SS */ 45 Push_32(SegValue(ss));break; 46 CASE_D(0x17) /* POP SS */ 47 if (CPU_PopSeg(ss,true)) RUNEXCEPTION(); 48 CPU_Cycles++; 49 break; 50 CASE_D(0x19) /* SBB Ed,Gd */ 51 RMEdGd(SBBD);break; 52 CASE_D(0x1b) /* SBB Gd,Ed */ 53 RMGdEd(SBBD);break; 54 CASE_D(0x1d) /* SBB EAX,Id */ 55 EAXId(SBBD);break; 56 CASE_D(0x1e) /* PUSH DS */ 57 Push_32(SegValue(ds));break; 58 CASE_D(0x1f) /* POP DS */ 59 if (CPU_PopSeg(ds,true)) RUNEXCEPTION(); 60 break; 61 CASE_D(0x21) /* AND Ed,Gd */ 62 RMEdGd(ANDD);break; 63 CASE_D(0x23) /* AND Gd,Ed */ 64 RMGdEd(ANDD);break; 65 CASE_D(0x25) /* AND EAX,Id */ 66 EAXId(ANDD);break; 67 CASE_D(0x29) /* SUB Ed,Gd */ 68 RMEdGd(SUBD);break; 69 CASE_D(0x2b) /* SUB Gd,Ed */ 70 RMGdEd(SUBD);break; 71 CASE_D(0x2d) /* SUB EAX,Id */ 72 EAXId(SUBD);break; 73 CASE_D(0x31) /* XOR Ed,Gd */ 74 RMEdGd(XORD);break; 75 CASE_D(0x33) /* XOR Gd,Ed */ 76 RMGdEd(XORD);break; 77 CASE_D(0x35) /* XOR EAX,Id */ 78 EAXId(XORD);break; 79 CASE_D(0x39) /* CMP Ed,Gd */ 80 RMEdGd(CMPD);break; 81 CASE_D(0x3b) /* CMP Gd,Ed */ 82 RMGdEd(CMPD);break; 83 CASE_D(0x3d) /* CMP EAX,Id */ 84 EAXId(CMPD);break; 85 CASE_D(0x40) /* INC EAX */ 86 INCD(reg_eax,LoadRd,SaveRd);break; 87 CASE_D(0x41) /* INC ECX */ 88 INCD(reg_ecx,LoadRd,SaveRd);break; 89 CASE_D(0x42) /* INC EDX */ 90 INCD(reg_edx,LoadRd,SaveRd);break; 91 CASE_D(0x43) /* INC EBX */ 92 INCD(reg_ebx,LoadRd,SaveRd);break; 93 CASE_D(0x44) /* INC ESP */ 94 INCD(reg_esp,LoadRd,SaveRd);break; 95 CASE_D(0x45) /* INC EBP */ 96 INCD(reg_ebp,LoadRd,SaveRd);break; 97 CASE_D(0x46) /* INC ESI */ 98 INCD(reg_esi,LoadRd,SaveRd);break; 99 CASE_D(0x47) /* INC EDI */ 100 INCD(reg_edi,LoadRd,SaveRd);break; 101 CASE_D(0x48) /* DEC EAX */ 102 DECD(reg_eax,LoadRd,SaveRd);break; 103 CASE_D(0x49) /* DEC ECX */ 104 DECD(reg_ecx,LoadRd,SaveRd);break; 105 CASE_D(0x4a) /* DEC EDX */ 106 DECD(reg_edx,LoadRd,SaveRd);break; 107 CASE_D(0x4b) /* DEC EBX */ 108 DECD(reg_ebx,LoadRd,SaveRd);break; 109 CASE_D(0x4c) /* DEC ESP */ 110 DECD(reg_esp,LoadRd,SaveRd);break; 111 CASE_D(0x4d) /* DEC EBP */ 112 DECD(reg_ebp,LoadRd,SaveRd);break; 113 CASE_D(0x4e) /* DEC ESI */ 114 DECD(reg_esi,LoadRd,SaveRd);break; 115 CASE_D(0x4f) /* DEC EDI */ 116 DECD(reg_edi,LoadRd,SaveRd);break; 117 CASE_D(0x50) /* PUSH EAX */ 118 Push_32(reg_eax);break; 119 CASE_D(0x51) /* PUSH ECX */ 120 Push_32(reg_ecx);break; 121 CASE_D(0x52) /* PUSH EDX */ 122 Push_32(reg_edx);break; 123 CASE_D(0x53) /* PUSH EBX */ 124 Push_32(reg_ebx);break; 125 CASE_D(0x54) /* PUSH ESP */ 126 Push_32(reg_esp);break; 127 CASE_D(0x55) /* PUSH EBP */ 128 Push_32(reg_ebp);break; 129 CASE_D(0x56) /* PUSH ESI */ 130 Push_32(reg_esi);break; 131 CASE_D(0x57) /* PUSH EDI */ 132 Push_32(reg_edi);break; 133 CASE_D(0x58) /* POP EAX */ 134 reg_eax=Pop_32();break; 135 CASE_D(0x59) /* POP ECX */ 136 reg_ecx=Pop_32();break; 137 CASE_D(0x5a) /* POP EDX */ 138 reg_edx=Pop_32();break; 139 CASE_D(0x5b) /* POP EBX */ 140 reg_ebx=Pop_32();break; 141 CASE_D(0x5c) /* POP ESP */ 142 reg_esp=Pop_32();break; 143 CASE_D(0x5d) /* POP EBP */ 144 reg_ebp=Pop_32();break; 145 CASE_D(0x5e) /* POP ESI */ 146 reg_esi=Pop_32();break; 147 CASE_D(0x5f) /* POP EDI */ 148 reg_edi=Pop_32();break; 149 CASE_D(0x60) /* PUSHAD */ 150 { 151 Bitu tmpesp = reg_esp; 152 Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); 153 Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); 154 }; break; 155 CASE_D(0x61) /* POPAD */ 156 reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP 157 reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); 158 break; 159 CASE_D(0x62) /* BOUND Ed */ 160 { 161 Bit32s bound_min, bound_max; 162 GetRMrd;GetEAa; 163 bound_min=LoadMd(eaa); 164 bound_max=LoadMd(eaa+4); 165 if ( (((Bit32s)*rmrd) < bound_min) || (((Bit32s)*rmrd) > bound_max) ) { 166 EXCEPTION(5); 167 } 168 } 169 break; 170 CASE_D(0x63) /* ARPL Ed,Rd */ 171 { 172 if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; 173 GetRMrw; 174 if (rm >= 0xc0 ) { 175 GetEArd;Bitu new_sel=(Bit16u)*eard; 176 CPU_ARPL(new_sel,*rmrw); 177 *eard=(Bit32u)new_sel; 178 } else { 179 GetEAa;Bitu new_sel=LoadMw(eaa); 180 CPU_ARPL(new_sel,*rmrw); 181 SaveMd(eaa,(Bit32u)new_sel); 182 } 183 } 184 break; 185 CASE_D(0x68) /* PUSH Id */ 186 Push_32(Fetchd());break; 187 CASE_D(0x69) /* IMUL Gd,Ed,Id */ 188 RMGdEdOp3(DIMULD,Fetchds()); 189 break; 190 CASE_D(0x6a) /* PUSH Ib */ 191 Push_32(Fetchbs());break; 192 CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ 193 RMGdEdOp3(DIMULD,Fetchbs()); 194 break; 195 CASE_D(0x6d) /* INSD */ 196 if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); 197 DoString(R_INSD);break; 198 CASE_D(0x6f) /* OUTSD */ 199 if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); 200 DoString(R_OUTSD);break; 201 CASE_D(0x70) /* JO */ 202 JumpCond32_b(TFLG_O);break; 203 CASE_D(0x71) /* JNO */ 204 JumpCond32_b(TFLG_NO);break; 205 CASE_D(0x72) /* JB */ 206 JumpCond32_b(TFLG_B);break; 207 CASE_D(0x73) /* JNB */ 208 JumpCond32_b(TFLG_NB);break; 209 CASE_D(0x74) /* JZ */ 210 JumpCond32_b(TFLG_Z);break; 211 CASE_D(0x75) /* JNZ */ 212 JumpCond32_b(TFLG_NZ);break; 213 CASE_D(0x76) /* JBE */ 214 JumpCond32_b(TFLG_BE);break; 215 CASE_D(0x77) /* JNBE */ 216 JumpCond32_b(TFLG_NBE);break; 217 CASE_D(0x78) /* JS */ 218 JumpCond32_b(TFLG_S);break; 219 CASE_D(0x79) /* JNS */ 220 JumpCond32_b(TFLG_NS);break; 221 CASE_D(0x7a) /* JP */ 222 JumpCond32_b(TFLG_P);break; 223 CASE_D(0x7b) /* JNP */ 224 JumpCond32_b(TFLG_NP);break; 225 CASE_D(0x7c) /* JL */ 226 JumpCond32_b(TFLG_L);break; 227 CASE_D(0x7d) /* JNL */ 228 JumpCond32_b(TFLG_NL);break; 229 CASE_D(0x7e) /* JLE */ 230 JumpCond32_b(TFLG_LE);break; 231 CASE_D(0x7f) /* JNLE */ 232 JumpCond32_b(TFLG_NLE);break; 233 CASE_D(0x81) /* Grpl Ed,Id */ 234 { 235 GetRM;Bitu which=(rm>>3)&7; 236 if (rm >= 0xc0) { 237 GetEArd;Bit32u id=Fetchd(); 238 switch (which) { 239 case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; 240 case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; 241 case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; 242 case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; 243 case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; 244 case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; 245 case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; 246 case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; 247 } 248 } else { 249 GetEAa;Bit32u id=Fetchd(); 250 switch (which) { 251 case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; 252 case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; 253 case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; 254 case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; 255 case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; 256 case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; 257 case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; 258 case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; 259 } 260 } 261 } 262 break; 263 CASE_D(0x83) /* Grpl Ed,Ix */ 264 { 265 GetRM;Bitu which=(rm>>3)&7; 266 if (rm >= 0xc0) { 267 GetEArd;Bit32u id=(Bit32s)Fetchbs(); 268 switch (which) { 269 case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; 270 case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; 271 case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; 272 case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; 273 case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; 274 case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; 275 case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; 276 case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; 277 } 278 } else { 279 GetEAa;Bit32u id=(Bit32s)Fetchbs(); 280 switch (which) { 281 case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; 282 case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; 283 case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; 284 case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; 285 case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; 286 case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; 287 case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; 288 case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; 289 } 290 } 291 } 292 break; 293 CASE_D(0x85) /* TEST Ed,Gd */ 294 RMEdGd(TESTD);break; 295 CASE_D(0x87) /* XCHG Ed,Gd */ 296 { 297 GetRMrd;Bit32u oldrmrd=*rmrd; 298 if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} 299 else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} 300 break; 301 } 302 CASE_D(0x89) /* MOV Ed,Gd */ 303 { 304 GetRMrd; 305 if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;} 306 else {GetEAa;SaveMd(eaa,*rmrd);} 307 break; 308 } 309 CASE_D(0x8b) /* MOV Gd,Ed */ 310 { 311 GetRMrd; 312 if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;} 313 else {GetEAa;*rmrd=LoadMd(eaa);} 314 break; 315 } 316 CASE_D(0x8c) /* Mov Ew,Sw */ 317 { 318 GetRM;Bit16u val;Bitu which=(rm>>3)&7; 319 switch (which) { 320 case 0x00: /* MOV Ew,ES */ 321 val=SegValue(es);break; 322 case 0x01: /* MOV Ew,CS */ 323 val=SegValue(cs);break; 324 case 0x02: /* MOV Ew,SS */ 325 val=SegValue(ss);break; 326 case 0x03: /* MOV Ew,DS */ 327 val=SegValue(ds);break; 328 case 0x04: /* MOV Ew,FS */ 329 val=SegValue(fs);break; 330 case 0x05: /* MOV Ew,GS */ 331 val=SegValue(gs);break; 332 default: 333 LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); 334 goto illegal_opcode; 335 } 336 if (rm >= 0xc0 ) {GetEArd;*eard=val;} 337 else {GetEAa;SaveMw(eaa,val);} 338 break; 339 } 340 CASE_D(0x8d) /* LEA Gd */ 341 { 342 //Little hack to always use segprefixed version 343 GetRMrd; 344 BaseDS=BaseSS=0; 345 if (TEST_PREFIX_ADDR) { 346 *rmrd=(Bit32u)(*EATable[256+rm])(); 347 } else { 348 *rmrd=(Bit32u)(*EATable[rm])(); 349 } 350 break; 351 } 352 CASE_D(0x8f) /* POP Ed */ 353 { 354 Bit32u val=Pop_32(); 355 GetRM; 356 if (rm >= 0xc0 ) {GetEArd;*eard=val;} 357 else {GetEAa;SaveMd(eaa,val);} 358 break; 359 } 360 CASE_D(0x91) /* XCHG ECX,EAX */ 361 { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;} 362 CASE_D(0x92) /* XCHG EDX,EAX */ 363 { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;} 364 break; 365 CASE_D(0x93) /* XCHG EBX,EAX */ 366 { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;} 367 break; 368 CASE_D(0x94) /* XCHG ESP,EAX */ 369 { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;} 370 break; 371 CASE_D(0x95) /* XCHG EBP,EAX */ 372 { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;} 373 break; 374 CASE_D(0x96) /* XCHG ESI,EAX */ 375 { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;} 376 break; 377 CASE_D(0x97) /* XCHG EDI,EAX */ 378 { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;} 379 break; 380 CASE_D(0x98) /* CWDE */ 381 reg_eax=(Bit16s)reg_ax;break; 382 CASE_D(0x99) /* CDQ */ 383 if (reg_eax & 0x80000000) reg_edx=0xffffffff; 384 else reg_edx=0; 385 break; 386 CASE_D(0x9a) /* CALL FAR Ad */ 387 { 388 Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); 389 FillFlags(); 390 CPU_CALL(true,newcs,newip,GETIP); 391 #if CPU_TRAP_CHECK 392 if (GETFLAG(TF)) { 393 cpudecoder=CPU_Core_Normal_Trap_Run; 394 return CBRET_NONE; 395 } 396 #endif 397 continue; 398 } 399 CASE_D(0x9c) /* PUSHFD */ 400 if (CPU_PUSHF(true)) RUNEXCEPTION(); 401 break; 402 CASE_D(0x9d) /* POPFD */ 403 if (CPU_POPF(true)) RUNEXCEPTION(); 404 #if CPU_TRAP_CHECK 405 if (GETFLAG(TF)) { 406 cpudecoder=CPU_Core_Normal_Trap_Run; 407 goto decode_end; 408 } 409 #endif 410 #if CPU_PIC_CHECK 411 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; 412 #endif 413 break; 414 CASE_D(0xa1) /* MOV EAX,Od */ 415 { 416 GetEADirect; 417 reg_eax=LoadMd(eaa); 418 } 419 break; 420 CASE_D(0xa3) /* MOV Od,EAX */ 421 { 422 GetEADirect; 423 SaveMd(eaa,reg_eax); 424 } 425 break; 426 CASE_D(0xa5) /* MOVSD */ 427 DoString(R_MOVSD);break; 428 CASE_D(0xa7) /* CMPSD */ 429 DoString(R_CMPSD);break; 430 CASE_D(0xa9) /* TEST EAX,Id */ 431 EAXId(TESTD);break; 432 CASE_D(0xab) /* STOSD */ 433 DoString(R_STOSD);break; 434 CASE_D(0xad) /* LODSD */ 435 DoString(R_LODSD);break; 436 CASE_D(0xaf) /* SCASD */ 437 DoString(R_SCASD);break; 438 CASE_D(0xb8) /* MOV EAX,Id */ 439 reg_eax=Fetchd();break; 440 CASE_D(0xb9) /* MOV ECX,Id */ 441 reg_ecx=Fetchd();break; 442 CASE_D(0xba) /* MOV EDX,Iw */ 443 reg_edx=Fetchd();break; 444 CASE_D(0xbb) /* MOV EBX,Id */ 445 reg_ebx=Fetchd();break; 446 CASE_D(0xbc) /* MOV ESP,Id */ 447 reg_esp=Fetchd();break; 448 CASE_D(0xbd) /* MOV EBP.Id */ 449 reg_ebp=Fetchd();break; 450 CASE_D(0xbe) /* MOV ESI,Id */ 451 reg_esi=Fetchd();break; 452 CASE_D(0xbf) /* MOV EDI,Id */ 453 reg_edi=Fetchd();break; 454 CASE_D(0xc1) /* GRP2 Ed,Ib */ 455 GRP2D(Fetchb());break; 456 CASE_D(0xc2) /* RETN Iw */ 457 reg_eip=Pop_32(); 458 reg_esp+=Fetchw(); 459 continue; 460 CASE_D(0xc3) /* RETN */ 461 reg_eip=Pop_32(); 462 continue; 463 CASE_D(0xc4) /* LES */ 464 { 465 GetRMrd; 466 if (rm >= 0xc0) goto illegal_opcode; 467 GetEAa; 468 if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); 469 *rmrd=LoadMd(eaa); 470 break; 471 } 472 CASE_D(0xc5) /* LDS */ 473 { 474 GetRMrd; 475 if (rm >= 0xc0) goto illegal_opcode; 476 GetEAa; 477 if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); 478 *rmrd=LoadMd(eaa); 479 break; 480 } 481 CASE_D(0xc7) /* MOV Ed,Id */ 482 { 483 GetRM; 484 if (rm >= 0xc0) {GetEArd;*eard=Fetchd();} 485 else {GetEAa;SaveMd(eaa,Fetchd());} 486 break; 487 } 488 CASE_D(0xc8) /* ENTER Iw,Ib */ 489 { 490 Bitu bytes=Fetchw(); 491 Bitu level=Fetchb(); 492 CPU_ENTER(true,bytes,level); 493 } 494 break; 495 CASE_D(0xc9) /* LEAVE */ 496 reg_esp&=cpu.stack.notmask; 497 reg_esp|=(reg_ebp&cpu.stack.mask); 498 reg_ebp=Pop_32(); 499 break; 500 CASE_D(0xca) /* RETF Iw */ 501 { 502 Bitu words=Fetchw(); 503 FillFlags(); 504 CPU_RET(true,words,GETIP); 505 continue; 506 } 507 CASE_D(0xcb) /* RETF */ 508 { 509 FillFlags(); 510 CPU_RET(true,0,GETIP); 511 continue; 512 } 513 CASE_D(0xcf) /* IRET */ 514 { 515 CPU_IRET(true,GETIP); 516 #if CPU_TRAP_CHECK 517 if (GETFLAG(TF)) { 518 cpudecoder=CPU_Core_Normal_Trap_Run; 519 return CBRET_NONE; 520 } 521 #endif 522 #if CPU_PIC_CHECK 523 if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; 524 #endif 525 continue; 526 } 527 CASE_D(0xd1) /* GRP2 Ed,1 */ 528 GRP2D(1);break; 529 CASE_D(0xd3) /* GRP2 Ed,CL */ 530 GRP2D(reg_cl);break; 531 CASE_D(0xe0) /* LOOPNZ */ 532 if (TEST_PREFIX_ADDR) { 533 JumpCond32_b(--reg_ecx && !get_ZF()); 534 } else { 535 JumpCond32_b(--reg_cx && !get_ZF()); 536 } 537 break; 538 CASE_D(0xe1) /* LOOPZ */ 539 if (TEST_PREFIX_ADDR) { 540 JumpCond32_b(--reg_ecx && get_ZF()); 541 } else { 542 JumpCond32_b(--reg_cx && get_ZF()); 543 } 544 break; 545 CASE_D(0xe2) /* LOOP */ 546 if (TEST_PREFIX_ADDR) { 547 JumpCond32_b(--reg_ecx); 548 } else { 549 JumpCond32_b(--reg_cx); 550 } 551 break; 552 CASE_D(0xe3) /* JCXZ */ 553 JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); 554 break; 555 CASE_D(0xe5) /* IN EAX,Ib */ 556 { 557 Bitu port=Fetchb(); 558 if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); 559 reg_eax=IO_ReadD(port); 560 break; 561 } 562 CASE_D(0xe7) /* OUT Ib,EAX */ 563 { 564 Bitu port=Fetchb(); 565 if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); 566 IO_WriteD(port,reg_eax); 567 break; 568 } 569 CASE_D(0xe8) /* CALL Jd */ 570 { 571 Bit32s addip=Fetchds(); 572 SAVEIP; 573 Push_32(reg_eip); 574 reg_eip+=addip; 575 continue; 576 } 577 CASE_D(0xe9) /* JMP Jd */ 578 { 579 Bit32s addip=Fetchds(); 580 SAVEIP; 581 reg_eip+=addip; 582 continue; 583 } 584 CASE_D(0xea) /* JMP Ad */ 585 { 586 Bit32u newip=Fetchd(); 587 Bit16u newcs=Fetchw(); 588 FillFlags(); 589 CPU_JMP(true,newcs,newip,GETIP); 590 #if CPU_TRAP_CHECK 591 if (GETFLAG(TF)) { 592 cpudecoder=CPU_Core_Normal_Trap_Run; 593 return CBRET_NONE; 594 } 595 #endif 596 continue; 597 } 598 CASE_D(0xeb) /* JMP Jb */ 599 { 600 Bit32s addip=Fetchbs(); 601 SAVEIP; 602 reg_eip+=addip; 603 continue; 604 } 605 CASE_D(0xed) /* IN EAX,DX */ 606 reg_eax=IO_ReadD(reg_dx); 607 break; 608 CASE_D(0xef) /* OUT DX,EAX */ 609 IO_WriteD(reg_dx,reg_eax); 610 break; 611 CASE_D(0xf7) /* GRP3 Ed(,Id) */ 612 { 613 GetRM;Bitu which=(rm>>3)&7; 614 switch (which) { 615 case 0x00: /* TEST Ed,Id */ 616 case 0x01: /* TEST Ed,Id Undocumented*/ 617 { 618 if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);} 619 else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);} 620 break; 621 } 622 case 0x02: /* NOT Ed */ 623 { 624 if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} 625 else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} 626 break; 627 } 628 case 0x03: /* NEG Ed */ 629 { 630 lflags.type=t_NEGd; 631 if (rm >= 0xc0 ) { 632 GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d; 633 *eard=lf_resd; 634 } else { 635 GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d; 636 SaveMd(eaa,lf_resd); 637 } 638 break; 639 } 640 case 0x04: /* MUL EAX,Ed */ 641 RMEd(MULD); 642 break; 643 case 0x05: /* IMUL EAX,Ed */ 644 RMEd(IMULD); 645 break; 646 case 0x06: /* DIV Ed */ 647 RMEd(DIVD); 648 break; 649 case 0x07: /* IDIV Ed */ 650 RMEd(IDIVD); 651 break; 652 } 653 break; 654 } 655 CASE_D(0xff) /* GRP 5 Ed */ 656 { 657 GetRM;Bitu which=(rm>>3)&7; 658 switch (which) { 659 case 0x00: /* INC Ed */ 660 RMEd(INCD); 661 break; 662 case 0x01: /* DEC Ed */ 663 RMEd(DECD); 664 break; 665 case 0x02: /* CALL NEAR Ed */ 666 if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} 667 else {GetEAa;reg_eip=LoadMd(eaa);} 668 Push_32(GETIP); 669 continue; 670 case 0x03: /* CALL FAR Ed */ 671 { 672 if (rm >= 0xc0) goto illegal_opcode; 673 GetEAa; 674 Bit32u newip=LoadMd(eaa); 675 Bit16u newcs=LoadMw(eaa+4); 676 FillFlags(); 677 CPU_CALL(true,newcs,newip,GETIP); 678 #if CPU_TRAP_CHECK 679 if (GETFLAG(TF)) { 680 cpudecoder=CPU_Core_Normal_Trap_Run; 681 return CBRET_NONE; 682 } 683 #endif 684 continue; 685 } 686 case 0x04: /* JMP NEAR Ed */ 687 if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} 688 else {GetEAa;reg_eip=LoadMd(eaa);} 689 continue; 690 case 0x05: /* JMP FAR Ed */ 691 { 692 if (rm >= 0xc0) goto illegal_opcode; 693 GetEAa; 694 Bit32u newip=LoadMd(eaa); 695 Bit16u newcs=LoadMw(eaa+4); 696 FillFlags(); 697 CPU_JMP(true,newcs,newip,GETIP); 698 #if CPU_TRAP_CHECK 699 if (GETFLAG(TF)) { 700 cpudecoder=CPU_Core_Normal_Trap_Run; 701 return CBRET_NONE; 702 } 703 #endif 704 continue; 705 } 706 break; 707 case 0x06: /* Push Ed */ 708 if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);} 709 else {GetEAa;Push_32(LoadMd(eaa));} 710 break; 711 default: 712 LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",which); 713 goto illegal_opcode; 714 } 715 break; 716 } 717 718 719