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_B(0x00) /* ADD Eb,Gb */ 20 RMEbGb(ADDB);break; 21 CASE_W(0x01) /* ADD Ew,Gw */ 22 RMEwGw(ADDW);break; 23 CASE_B(0x02) /* ADD Gb,Eb */ 24 RMGbEb(ADDB);break; 25 CASE_W(0x03) /* ADD Gw,Ew */ 26 RMGwEw(ADDW);break; 27 CASE_B(0x04) /* ADD AL,Ib */ 28 ALIb(ADDB);break; 29 CASE_W(0x05) /* ADD AX,Iw */ 30 AXIw(ADDW);break; 31 CASE_W(0x06) /* PUSH ES */ 32 Push_16(SegValue(es));break; 33 CASE_W(0x07) /* POP ES */ 34 if (CPU_PopSeg(es,false)) RUNEXCEPTION(); 35 break; 36 CASE_B(0x08) /* OR Eb,Gb */ 37 RMEbGb(ORB);break; 38 CASE_W(0x09) /* OR Ew,Gw */ 39 RMEwGw(ORW);break; 40 CASE_B(0x0a) /* OR Gb,Eb */ 41 RMGbEb(ORB);break; 42 CASE_W(0x0b) /* OR Gw,Ew */ 43 RMGwEw(ORW);break; 44 CASE_B(0x0c) /* OR AL,Ib */ 45 ALIb(ORB);break; 46 CASE_W(0x0d) /* OR AX,Iw */ 47 AXIw(ORW);break; 48 CASE_W(0x0e) /* PUSH CS */ 49 Push_16(SegValue(cs));break; 50 CASE_B(0x0f) /* 2 byte opcodes*/ 51 core.opcode_index|=OPCODE_0F; 52 goto restart_opcode; 53 break; 54 CASE_B(0x10) /* ADC Eb,Gb */ 55 RMEbGb(ADCB);break; 56 CASE_W(0x11) /* ADC Ew,Gw */ 57 RMEwGw(ADCW);break; 58 CASE_B(0x12) /* ADC Gb,Eb */ 59 RMGbEb(ADCB);break; 60 CASE_W(0x13) /* ADC Gw,Ew */ 61 RMGwEw(ADCW);break; 62 CASE_B(0x14) /* ADC AL,Ib */ 63 ALIb(ADCB);break; 64 CASE_W(0x15) /* ADC AX,Iw */ 65 AXIw(ADCW);break; 66 CASE_W(0x16) /* PUSH SS */ 67 Push_16(SegValue(ss));break; 68 CASE_W(0x17) /* POP SS */ 69 if (CPU_PopSeg(ss,false)) RUNEXCEPTION(); 70 CPU_Cycles++; //Always do another instruction 71 break; 72 CASE_B(0x18) /* SBB Eb,Gb */ 73 RMEbGb(SBBB);break; 74 CASE_W(0x19) /* SBB Ew,Gw */ 75 RMEwGw(SBBW);break; 76 CASE_B(0x1a) /* SBB Gb,Eb */ 77 RMGbEb(SBBB);break; 78 CASE_W(0x1b) /* SBB Gw,Ew */ 79 RMGwEw(SBBW);break; 80 CASE_B(0x1c) /* SBB AL,Ib */ 81 ALIb(SBBB);break; 82 CASE_W(0x1d) /* SBB AX,Iw */ 83 AXIw(SBBW);break; 84 CASE_W(0x1e) /* PUSH DS */ 85 Push_16(SegValue(ds));break; 86 CASE_W(0x1f) /* POP DS */ 87 if (CPU_PopSeg(ds,false)) RUNEXCEPTION(); 88 break; 89 CASE_B(0x20) /* AND Eb,Gb */ 90 RMEbGb(ANDB);break; 91 CASE_W(0x21) /* AND Ew,Gw */ 92 RMEwGw(ANDW);break; 93 CASE_B(0x22) /* AND Gb,Eb */ 94 RMGbEb(ANDB);break; 95 CASE_W(0x23) /* AND Gw,Ew */ 96 RMGwEw(ANDW);break; 97 CASE_B(0x24) /* AND AL,Ib */ 98 ALIb(ANDB);break; 99 CASE_W(0x25) /* AND AX,Iw */ 100 AXIw(ANDW);break; 101 CASE_B(0x26) /* SEG ES: */ 102 DO_PREFIX_SEG(es);break; 103 CASE_B(0x27) /* DAA */ 104 DAA();break; 105 CASE_B(0x28) /* SUB Eb,Gb */ 106 RMEbGb(SUBB);break; 107 CASE_W(0x29) /* SUB Ew,Gw */ 108 RMEwGw(SUBW);break; 109 CASE_B(0x2a) /* SUB Gb,Eb */ 110 RMGbEb(SUBB);break; 111 CASE_W(0x2b) /* SUB Gw,Ew */ 112 RMGwEw(SUBW);break; 113 CASE_B(0x2c) /* SUB AL,Ib */ 114 ALIb(SUBB);break; 115 CASE_W(0x2d) /* SUB AX,Iw */ 116 AXIw(SUBW);break; 117 CASE_B(0x2e) /* SEG CS: */ 118 DO_PREFIX_SEG(cs);break; 119 CASE_B(0x2f) /* DAS */ 120 DAS();break; 121 CASE_B(0x30) /* XOR Eb,Gb */ 122 RMEbGb(XORB);break; 123 CASE_W(0x31) /* XOR Ew,Gw */ 124 RMEwGw(XORW);break; 125 CASE_B(0x32) /* XOR Gb,Eb */ 126 RMGbEb(XORB);break; 127 CASE_W(0x33) /* XOR Gw,Ew */ 128 RMGwEw(XORW);break; 129 CASE_B(0x34) /* XOR AL,Ib */ 130 ALIb(XORB);break; 131 CASE_W(0x35) /* XOR AX,Iw */ 132 AXIw(XORW);break; 133 CASE_B(0x36) /* SEG SS: */ 134 DO_PREFIX_SEG(ss);break; 135 CASE_B(0x37) /* AAA */ 136 AAA();break; 137 CASE_B(0x38) /* CMP Eb,Gb */ 138 RMEbGb(CMPB);break; 139 CASE_W(0x39) /* CMP Ew,Gw */ 140 RMEwGw(CMPW);break; 141 CASE_B(0x3a) /* CMP Gb,Eb */ 142 RMGbEb(CMPB);break; 143 CASE_W(0x3b) /* CMP Gw,Ew */ 144 RMGwEw(CMPW);break; 145 CASE_B(0x3c) /* CMP AL,Ib */ 146 ALIb(CMPB);break; 147 CASE_W(0x3d) /* CMP AX,Iw */ 148 AXIw(CMPW);break; 149 CASE_B(0x3e) /* SEG DS: */ 150 DO_PREFIX_SEG(ds);break; 151 CASE_B(0x3f) /* AAS */ 152 AAS();break; 153 CASE_W(0x40) /* INC AX */ 154 INCW(reg_ax,LoadRw,SaveRw);break; 155 CASE_W(0x41) /* INC CX */ 156 INCW(reg_cx,LoadRw,SaveRw);break; 157 CASE_W(0x42) /* INC DX */ 158 INCW(reg_dx,LoadRw,SaveRw);break; 159 CASE_W(0x43) /* INC BX */ 160 INCW(reg_bx,LoadRw,SaveRw);break; 161 CASE_W(0x44) /* INC SP */ 162 INCW(reg_sp,LoadRw,SaveRw);break; 163 CASE_W(0x45) /* INC BP */ 164 INCW(reg_bp,LoadRw,SaveRw);break; 165 CASE_W(0x46) /* INC SI */ 166 INCW(reg_si,LoadRw,SaveRw);break; 167 CASE_W(0x47) /* INC DI */ 168 INCW(reg_di,LoadRw,SaveRw);break; 169 CASE_W(0x48) /* DEC AX */ 170 DECW(reg_ax,LoadRw,SaveRw);break; 171 CASE_W(0x49) /* DEC CX */ 172 DECW(reg_cx,LoadRw,SaveRw);break; 173 CASE_W(0x4a) /* DEC DX */ 174 DECW(reg_dx,LoadRw,SaveRw);break; 175 CASE_W(0x4b) /* DEC BX */ 176 DECW(reg_bx,LoadRw,SaveRw);break; 177 CASE_W(0x4c) /* DEC SP */ 178 DECW(reg_sp,LoadRw,SaveRw);break; 179 CASE_W(0x4d) /* DEC BP */ 180 DECW(reg_bp,LoadRw,SaveRw);break; 181 CASE_W(0x4e) /* DEC SI */ 182 DECW(reg_si,LoadRw,SaveRw);break; 183 CASE_W(0x4f) /* DEC DI */ 184 DECW(reg_di,LoadRw,SaveRw);break; 185 CASE_W(0x50) /* PUSH AX */ 186 Push_16(reg_ax);break; 187 CASE_W(0x51) /* PUSH CX */ 188 Push_16(reg_cx);break; 189 CASE_W(0x52) /* PUSH DX */ 190 Push_16(reg_dx);break; 191 CASE_W(0x53) /* PUSH BX */ 192 Push_16(reg_bx);break; 193 CASE_W(0x54) /* PUSH SP */ 194 Push_16(reg_sp);break; 195 CASE_W(0x55) /* PUSH BP */ 196 Push_16(reg_bp);break; 197 CASE_W(0x56) /* PUSH SI */ 198 Push_16(reg_si);break; 199 CASE_W(0x57) /* PUSH DI */ 200 Push_16(reg_di);break; 201 CASE_W(0x58) /* POP AX */ 202 reg_ax=Pop_16();break; 203 CASE_W(0x59) /* POP CX */ 204 reg_cx=Pop_16();break; 205 CASE_W(0x5a) /* POP DX */ 206 reg_dx=Pop_16();break; 207 CASE_W(0x5b) /* POP BX */ 208 reg_bx=Pop_16();break; 209 CASE_W(0x5c) /* POP SP */ 210 reg_sp=Pop_16();break; 211 CASE_W(0x5d) /* POP BP */ 212 reg_bp=Pop_16();break; 213 CASE_W(0x5e) /* POP SI */ 214 reg_si=Pop_16();break; 215 CASE_W(0x5f) /* POP DI */ 216 reg_di=Pop_16();break; 217 CASE_W(0x60) /* PUSHA */ 218 { 219 Bit16u old_sp=reg_sp; 220 Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); 221 Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); 222 } 223 break; 224 CASE_W(0x61) /* POPA */ 225 reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP 226 reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); 227 break; 228 CASE_W(0x62) /* BOUND */ 229 { 230 Bit16s bound_min, bound_max; 231 GetRMrw;GetEAa; 232 bound_min=LoadMw(eaa); 233 bound_max=LoadMw(eaa+2); 234 if ( (((Bit16s)*rmrw) < bound_min) || (((Bit16s)*rmrw) > bound_max) ) { 235 EXCEPTION(5); 236 } 237 } 238 break; 239 CASE_W(0x63) /* ARPL Ew,Rw */ 240 { 241 if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; 242 GetRMrw; 243 if (rm >= 0xc0 ) { 244 GetEArw;Bitu new_sel=*earw; 245 CPU_ARPL(new_sel,*rmrw); 246 *earw=(Bit16u)new_sel; 247 } else { 248 GetEAa;Bitu new_sel=LoadMw(eaa); 249 CPU_ARPL(new_sel,*rmrw); 250 SaveMw(eaa,(Bit16u)new_sel); 251 } 252 } 253 break; 254 CASE_B(0x64) /* SEG FS: */ 255 DO_PREFIX_SEG(fs);break; 256 CASE_B(0x65) /* SEG GS: */ 257 DO_PREFIX_SEG(gs);break; 258 CASE_B(0x66) /* Operand Size Prefix */ 259 core.opcode_index=(cpu.code.big^0x1)*0x200; 260 goto restart_opcode; 261 CASE_B(0x67) /* Address Size Prefix */ 262 DO_PREFIX_ADDR(); 263 CASE_W(0x68) /* PUSH Iw */ 264 Push_16(Fetchw());break; 265 CASE_W(0x69) /* IMUL Gw,Ew,Iw */ 266 RMGwEwOp3(DIMULW,Fetchws()); 267 break; 268 CASE_W(0x6a) /* PUSH Ib */ 269 Push_16(Fetchbs()); 270 break; 271 CASE_W(0x6b) /* IMUL Gw,Ew,Ib */ 272 RMGwEwOp3(DIMULW,Fetchbs()); 273 break; 274 CASE_B(0x6c) /* INSB */ 275 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 276 DoString(R_INSB);break; 277 CASE_W(0x6d) /* INSW */ 278 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 279 DoString(R_INSW);break; 280 CASE_B(0x6e) /* OUTSB */ 281 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 282 DoString(R_OUTSB);break; 283 CASE_W(0x6f) /* OUTSW */ 284 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 285 DoString(R_OUTSW);break; 286 CASE_W(0x70) /* JO */ 287 JumpCond16_b(TFLG_O);break; 288 CASE_W(0x71) /* JNO */ 289 JumpCond16_b(TFLG_NO);break; 290 CASE_W(0x72) /* JB */ 291 JumpCond16_b(TFLG_B);break; 292 CASE_W(0x73) /* JNB */ 293 JumpCond16_b(TFLG_NB);break; 294 CASE_W(0x74) /* JZ */ 295 JumpCond16_b(TFLG_Z);break; 296 CASE_W(0x75) /* JNZ */ 297 JumpCond16_b(TFLG_NZ);break; 298 CASE_W(0x76) /* JBE */ 299 JumpCond16_b(TFLG_BE);break; 300 CASE_W(0x77) /* JNBE */ 301 JumpCond16_b(TFLG_NBE);break; 302 CASE_W(0x78) /* JS */ 303 JumpCond16_b(TFLG_S);break; 304 CASE_W(0x79) /* JNS */ 305 JumpCond16_b(TFLG_NS);break; 306 CASE_W(0x7a) /* JP */ 307 JumpCond16_b(TFLG_P);break; 308 CASE_W(0x7b) /* JNP */ 309 JumpCond16_b(TFLG_NP);break; 310 CASE_W(0x7c) /* JL */ 311 JumpCond16_b(TFLG_L);break; 312 CASE_W(0x7d) /* JNL */ 313 JumpCond16_b(TFLG_NL);break; 314 CASE_W(0x7e) /* JLE */ 315 JumpCond16_b(TFLG_LE);break; 316 CASE_W(0x7f) /* JNLE */ 317 JumpCond16_b(TFLG_NLE);break; 318 CASE_B(0x80) /* Grpl Eb,Ib */ 319 CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ 320 { 321 GetRM;Bitu which=(rm>>3)&7; 322 if (rm>= 0xc0) { 323 GetEArb;Bit8u ib=Fetchb(); 324 switch (which) { 325 case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; 326 case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break; 327 case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break; 328 case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break; 329 case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break; 330 case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break; 331 case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break; 332 case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break; 333 } 334 } else { 335 GetEAa;Bit8u ib=Fetchb(); 336 switch (which) { 337 case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; 338 case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break; 339 case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break; 340 case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break; 341 case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break; 342 case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break; 343 case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break; 344 case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break; 345 } 346 } 347 break; 348 } 349 CASE_W(0x81) /* Grpl Ew,Iw */ 350 { 351 GetRM;Bitu which=(rm>>3)&7; 352 if (rm>= 0xc0) { 353 GetEArw;Bit16u iw=Fetchw(); 354 switch (which) { 355 case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; 356 case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; 357 case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; 358 case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; 359 case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; 360 case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; 361 case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; 362 case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; 363 } 364 } else { 365 GetEAa;Bit16u iw=Fetchw(); 366 switch (which) { 367 case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; 368 case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; 369 case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; 370 case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; 371 case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; 372 case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; 373 case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; 374 case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; 375 } 376 } 377 break; 378 } 379 CASE_W(0x83) /* Grpl Ew,Ix */ 380 { 381 GetRM;Bitu which=(rm>>3)&7; 382 if (rm>= 0xc0) { 383 GetEArw;Bit16u iw=(Bit16s)Fetchbs(); 384 switch (which) { 385 case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; 386 case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; 387 case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; 388 case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; 389 case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; 390 case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; 391 case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; 392 case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; 393 } 394 } else { 395 GetEAa;Bit16u iw=(Bit16s)Fetchbs(); 396 switch (which) { 397 case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; 398 case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; 399 case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; 400 case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; 401 case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; 402 case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; 403 case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; 404 case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; 405 } 406 } 407 break; 408 } 409 CASE_B(0x84) /* TEST Eb,Gb */ 410 RMEbGb(TESTB); 411 break; 412 CASE_W(0x85) /* TEST Ew,Gw */ 413 RMEwGw(TESTW); 414 break; 415 CASE_B(0x86) /* XCHG Eb,Gb */ 416 { 417 GetRMrb;Bit8u oldrmrb=*rmrb; 418 if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} 419 else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} 420 break; 421 } 422 CASE_W(0x87) /* XCHG Ew,Gw */ 423 { 424 GetRMrw;Bit16u oldrmrw=*rmrw; 425 if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} 426 else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} 427 break; 428 } 429 CASE_B(0x88) /* MOV Eb,Gb */ 430 { 431 GetRMrb; 432 if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} 433 else { 434 if (cpu.pmode) { 435 if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) { 436 Descriptor desc; 437 cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); 438 if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { 439 CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); 440 continue; 441 } 442 } 443 } 444 GetEAa;SaveMb(eaa,*rmrb); 445 } 446 break; 447 } 448 CASE_W(0x89) /* MOV Ew,Gw */ 449 { 450 GetRMrw; 451 if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} 452 else {GetEAa;SaveMw(eaa,*rmrw);} 453 break; 454 } 455 CASE_B(0x8a) /* MOV Gb,Eb */ 456 { 457 GetRMrb; 458 if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} 459 else {GetEAa;*rmrb=LoadMb(eaa);} 460 break; 461 } 462 CASE_W(0x8b) /* MOV Gw,Ew */ 463 { 464 GetRMrw; 465 if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} 466 else {GetEAa;*rmrw=LoadMw(eaa);} 467 break; 468 } 469 CASE_W(0x8c) /* Mov Ew,Sw */ 470 { 471 GetRM;Bit16u val;Bitu which=(rm>>3)&7; 472 switch (which) { 473 case 0x00: /* MOV Ew,ES */ 474 val=SegValue(es);break; 475 case 0x01: /* MOV Ew,CS */ 476 val=SegValue(cs);break; 477 case 0x02: /* MOV Ew,SS */ 478 val=SegValue(ss);break; 479 case 0x03: /* MOV Ew,DS */ 480 val=SegValue(ds);break; 481 case 0x04: /* MOV Ew,FS */ 482 val=SegValue(fs);break; 483 case 0x05: /* MOV Ew,GS */ 484 val=SegValue(gs);break; 485 default: 486 LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); 487 goto illegal_opcode; 488 } 489 if (rm >= 0xc0 ) {GetEArw;*earw=val;} 490 else {GetEAa;SaveMw(eaa,val);} 491 break; 492 } 493 CASE_W(0x8d) /* LEA Gw */ 494 { 495 //Little hack to always use segprefixed version 496 BaseDS=BaseSS=0; 497 GetRMrw; 498 if (TEST_PREFIX_ADDR) { 499 *rmrw=(Bit16u)(*EATable[256+rm])(); 500 } else { 501 *rmrw=(Bit16u)(*EATable[rm])(); 502 } 503 break; 504 } 505 CASE_B(0x8e) /* MOV Sw,Ew */ 506 { 507 GetRM;Bit16u val;Bitu which=(rm>>3)&7; 508 if (rm >= 0xc0 ) {GetEArw;val=*earw;} 509 else {GetEAa;val=LoadMw(eaa);} 510 switch (which) { 511 case 0x02: /* MOV SS,Ew */ 512 CPU_Cycles++; //Always do another instruction 513 case 0x00: /* MOV ES,Ew */ 514 case 0x03: /* MOV DS,Ew */ 515 case 0x05: /* MOV GS,Ew */ 516 case 0x04: /* MOV FS,Ew */ 517 if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION(); 518 break; 519 default: 520 goto illegal_opcode; 521 } 522 break; 523 } 524 CASE_W(0x8f) /* POP Ew */ 525 { 526 Bit16u val=Pop_16(); 527 GetRM; 528 if (rm >= 0xc0 ) {GetEArw;*earw=val;} 529 else {GetEAa;SaveMw(eaa,val);} 530 break; 531 } 532 CASE_B(0x90) /* NOP */ 533 break; 534 CASE_W(0x91) /* XCHG CX,AX */ 535 { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } 536 break; 537 CASE_W(0x92) /* XCHG DX,AX */ 538 { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } 539 break; 540 CASE_W(0x93) /* XCHG BX,AX */ 541 { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } 542 break; 543 CASE_W(0x94) /* XCHG SP,AX */ 544 { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } 545 break; 546 CASE_W(0x95) /* XCHG BP,AX */ 547 { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } 548 break; 549 CASE_W(0x96) /* XCHG SI,AX */ 550 { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } 551 break; 552 CASE_W(0x97) /* XCHG DI,AX */ 553 { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } 554 break; 555 CASE_W(0x98) /* CBW */ 556 reg_ax=(Bit8s)reg_al;break; 557 CASE_W(0x99) /* CWD */ 558 if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0; 559 break; 560 CASE_W(0x9a) /* CALL Ap */ 561 { 562 FillFlags(); 563 Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); 564 CPU_CALL(false,newcs,newip,GETIP); 565 #if CPU_TRAP_CHECK 566 if (GETFLAG(TF)) { 567 cpudecoder=CPU_Core_Normal_Trap_Run; 568 return CBRET_NONE; 569 } 570 #endif 571 continue; 572 } 573 CASE_B(0x9b) /* WAIT */ 574 break; /* No waiting here */ 575 CASE_W(0x9c) /* PUSHF */ 576 if (CPU_PUSHF(false)) RUNEXCEPTION(); 577 break; 578 CASE_W(0x9d) /* POPF */ 579 if (CPU_POPF(false)) RUNEXCEPTION(); 580 #if CPU_TRAP_CHECK 581 if (GETFLAG(TF)) { 582 cpudecoder=CPU_Core_Normal_Trap_Run; 583 goto decode_end; 584 } 585 #endif 586 #if CPU_PIC_CHECK 587 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; 588 #endif 589 break; 590 CASE_B(0x9e) /* SAHF */ 591 SETFLAGSb(reg_ah); 592 break; 593 CASE_B(0x9f) /* LAHF */ 594 FillFlags(); 595 reg_ah=reg_flags&0xff; 596 break; 597 CASE_B(0xa0) /* MOV AL,Ob */ 598 { 599 GetEADirect; 600 reg_al=LoadMb(eaa); 601 } 602 break; 603 CASE_W(0xa1) /* MOV AX,Ow */ 604 { 605 GetEADirect; 606 reg_ax=LoadMw(eaa); 607 } 608 break; 609 CASE_B(0xa2) /* MOV Ob,AL */ 610 { 611 GetEADirect; 612 SaveMb(eaa,reg_al); 613 } 614 break; 615 CASE_W(0xa3) /* MOV Ow,AX */ 616 { 617 GetEADirect; 618 SaveMw(eaa,reg_ax); 619 } 620 break; 621 CASE_B(0xa4) /* MOVSB */ 622 DoString(R_MOVSB);break; 623 CASE_W(0xa5) /* MOVSW */ 624 DoString(R_MOVSW);break; 625 CASE_B(0xa6) /* CMPSB */ 626 DoString(R_CMPSB);break; 627 CASE_W(0xa7) /* CMPSW */ 628 DoString(R_CMPSW);break; 629 CASE_B(0xa8) /* TEST AL,Ib */ 630 ALIb(TESTB);break; 631 CASE_W(0xa9) /* TEST AX,Iw */ 632 AXIw(TESTW);break; 633 CASE_B(0xaa) /* STOSB */ 634 DoString(R_STOSB);break; 635 CASE_W(0xab) /* STOSW */ 636 DoString(R_STOSW);break; 637 CASE_B(0xac) /* LODSB */ 638 DoString(R_LODSB);break; 639 CASE_W(0xad) /* LODSW */ 640 DoString(R_LODSW);break; 641 CASE_B(0xae) /* SCASB */ 642 DoString(R_SCASB);break; 643 CASE_W(0xaf) /* SCASW */ 644 DoString(R_SCASW);break; 645 CASE_B(0xb0) /* MOV AL,Ib */ 646 reg_al=Fetchb();break; 647 CASE_B(0xb1) /* MOV CL,Ib */ 648 reg_cl=Fetchb();break; 649 CASE_B(0xb2) /* MOV DL,Ib */ 650 reg_dl=Fetchb();break; 651 CASE_B(0xb3) /* MOV BL,Ib */ 652 reg_bl=Fetchb();break; 653 CASE_B(0xb4) /* MOV AH,Ib */ 654 reg_ah=Fetchb();break; 655 CASE_B(0xb5) /* MOV CH,Ib */ 656 reg_ch=Fetchb();break; 657 CASE_B(0xb6) /* MOV DH,Ib */ 658 reg_dh=Fetchb();break; 659 CASE_B(0xb7) /* MOV BH,Ib */ 660 reg_bh=Fetchb();break; 661 CASE_W(0xb8) /* MOV AX,Iw */ 662 reg_ax=Fetchw();break; 663 CASE_W(0xb9) /* MOV CX,Iw */ 664 reg_cx=Fetchw();break; 665 CASE_W(0xba) /* MOV DX,Iw */ 666 reg_dx=Fetchw();break; 667 CASE_W(0xbb) /* MOV BX,Iw */ 668 reg_bx=Fetchw();break; 669 CASE_W(0xbc) /* MOV SP,Iw */ 670 reg_sp=Fetchw();break; 671 CASE_W(0xbd) /* MOV BP.Iw */ 672 reg_bp=Fetchw();break; 673 CASE_W(0xbe) /* MOV SI,Iw */ 674 reg_si=Fetchw();break; 675 CASE_W(0xbf) /* MOV DI,Iw */ 676 reg_di=Fetchw();break; 677 CASE_B(0xc0) /* GRP2 Eb,Ib */ 678 GRP2B(Fetchb());break; 679 CASE_W(0xc1) /* GRP2 Ew,Ib */ 680 GRP2W(Fetchb());break; 681 CASE_W(0xc2) /* RETN Iw */ 682 reg_eip=Pop_16(); 683 reg_esp+=Fetchw(); 684 continue; 685 CASE_W(0xc3) /* RETN */ 686 reg_eip=Pop_16(); 687 continue; 688 CASE_W(0xc4) /* LES */ 689 { 690 GetRMrw; 691 if (rm >= 0xc0) goto illegal_opcode; 692 GetEAa; 693 if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); 694 *rmrw=LoadMw(eaa); 695 break; 696 } 697 CASE_W(0xc5) /* LDS */ 698 { 699 GetRMrw; 700 if (rm >= 0xc0) goto illegal_opcode; 701 GetEAa; 702 if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); 703 *rmrw=LoadMw(eaa); 704 break; 705 } 706 CASE_B(0xc6) /* MOV Eb,Ib */ 707 { 708 GetRM; 709 if (rm >= 0xc0) {GetEArb;*earb=Fetchb();} 710 else {GetEAa;SaveMb(eaa,Fetchb());} 711 break; 712 } 713 CASE_W(0xc7) /* MOV EW,Iw */ 714 { 715 GetRM; 716 if (rm >= 0xc0) {GetEArw;*earw=Fetchw();} 717 else {GetEAa;SaveMw(eaa,Fetchw());} 718 break; 719 } 720 CASE_W(0xc8) /* ENTER Iw,Ib */ 721 { 722 Bitu bytes=Fetchw(); 723 Bitu level=Fetchb(); 724 CPU_ENTER(false,bytes,level); 725 } 726 break; 727 CASE_W(0xc9) /* LEAVE */ 728 reg_esp&=cpu.stack.notmask; 729 reg_esp|=(reg_ebp&cpu.stack.mask); 730 reg_bp=Pop_16(); 731 break; 732 CASE_W(0xca) /* RETF Iw */ 733 { 734 Bitu words=Fetchw(); 735 FillFlags(); 736 CPU_RET(false,words,GETIP); 737 continue; 738 } 739 CASE_W(0xcb) /* RETF */ 740 FillFlags(); 741 CPU_RET(false,0,GETIP); 742 continue; 743 CASE_B(0xcc) /* INT3 */ 744 #if C_DEBUG 745 FillFlags(); 746 if (DEBUG_Breakpoint()) 747 return debugCallback; 748 #endif 749 CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); 750 #if CPU_TRAP_CHECK 751 cpu.trap_skip=true; 752 #endif 753 continue; 754 CASE_B(0xcd) /* INT Ib */ 755 { 756 Bit8u num=Fetchb(); 757 #if C_DEBUG 758 FillFlags(); 759 if (DEBUG_IntBreakpoint(num)) { 760 return debugCallback; 761 } 762 #endif 763 CPU_SW_Interrupt(num,GETIP); 764 #if CPU_TRAP_CHECK 765 cpu.trap_skip=true; 766 #endif 767 continue; 768 } 769 CASE_B(0xce) /* INTO */ 770 if (get_OF()) { 771 CPU_SW_Interrupt(4,GETIP); 772 #if CPU_TRAP_CHECK 773 cpu.trap_skip=true; 774 #endif 775 continue; 776 } 777 break; 778 CASE_W(0xcf) /* IRET */ 779 { 780 CPU_IRET(false,GETIP); 781 #if CPU_TRAP_CHECK 782 if (GETFLAG(TF)) { 783 cpudecoder=CPU_Core_Normal_Trap_Run; 784 return CBRET_NONE; 785 } 786 #endif 787 #if CPU_PIC_CHECK 788 if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; 789 #endif 790 continue; 791 } 792 CASE_B(0xd0) /* GRP2 Eb,1 */ 793 GRP2B(1);break; 794 CASE_W(0xd1) /* GRP2 Ew,1 */ 795 GRP2W(1);break; 796 CASE_B(0xd2) /* GRP2 Eb,CL */ 797 GRP2B(reg_cl);break; 798 CASE_W(0xd3) /* GRP2 Ew,CL */ 799 GRP2W(reg_cl);break; 800 CASE_B(0xd4) /* AAM Ib */ 801 AAM(Fetchb());break; 802 CASE_B(0xd5) /* AAD Ib */ 803 AAD(Fetchb());break; 804 CASE_B(0xd6) /* SALC */ 805 reg_al = get_CF() ? 0xFF : 0; 806 break; 807 CASE_B(0xd7) /* XLAT */ 808 if (TEST_PREFIX_ADDR) { 809 reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al)); 810 } else { 811 reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al)); 812 } 813 break; 814 #ifdef CPU_FPU 815 CASE_B(0xd8) /* FPU ESC 0 */ 816 FPU_ESC(0);break; 817 CASE_B(0xd9) /* FPU ESC 1 */ 818 FPU_ESC(1);break; 819 CASE_B(0xda) /* FPU ESC 2 */ 820 FPU_ESC(2);break; 821 CASE_B(0xdb) /* FPU ESC 3 */ 822 FPU_ESC(3);break; 823 CASE_B(0xdc) /* FPU ESC 4 */ 824 FPU_ESC(4);break; 825 CASE_B(0xdd) /* FPU ESC 5 */ 826 FPU_ESC(5);break; 827 CASE_B(0xde) /* FPU ESC 6 */ 828 FPU_ESC(6);break; 829 CASE_B(0xdf) /* FPU ESC 7 */ 830 FPU_ESC(7);break; 831 #else 832 CASE_B(0xd8) /* FPU ESC 0 */ 833 CASE_B(0xd9) /* FPU ESC 1 */ 834 CASE_B(0xda) /* FPU ESC 2 */ 835 CASE_B(0xdb) /* FPU ESC 3 */ 836 CASE_B(0xdc) /* FPU ESC 4 */ 837 CASE_B(0xdd) /* FPU ESC 5 */ 838 CASE_B(0xde) /* FPU ESC 6 */ 839 CASE_B(0xdf) /* FPU ESC 7 */ 840 { 841 LOG(LOG_CPU,LOG_NORMAL)("FPU used"); 842 Bit8u rm=Fetchb(); 843 if (rm<0xc0) GetEAa; 844 } 845 break; 846 #endif 847 CASE_W(0xe0) /* LOOPNZ */ 848 if (TEST_PREFIX_ADDR) { 849 JumpCond16_b(--reg_ecx && !get_ZF()); 850 } else { 851 JumpCond16_b(--reg_cx && !get_ZF()); 852 } 853 break; 854 CASE_W(0xe1) /* LOOPZ */ 855 if (TEST_PREFIX_ADDR) { 856 JumpCond16_b(--reg_ecx && get_ZF()); 857 } else { 858 JumpCond16_b(--reg_cx && get_ZF()); 859 } 860 break; 861 CASE_W(0xe2) /* LOOP */ 862 if (TEST_PREFIX_ADDR) { 863 JumpCond16_b(--reg_ecx); 864 } else { 865 JumpCond16_b(--reg_cx); 866 } 867 break; 868 CASE_W(0xe3) /* JCXZ */ 869 JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); 870 break; 871 CASE_B(0xe4) /* IN AL,Ib */ 872 { 873 Bitu port=Fetchb(); 874 if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); 875 reg_al=IO_ReadB(port); 876 break; 877 } 878 CASE_W(0xe5) /* IN AX,Ib */ 879 { 880 Bitu port=Fetchb(); 881 if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); 882 reg_al=IO_ReadW(port); 883 break; 884 } 885 CASE_B(0xe6) /* OUT Ib,AL */ 886 { 887 Bitu port=Fetchb(); 888 if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); 889 IO_WriteB(port,reg_al); 890 break; 891 } 892 CASE_W(0xe7) /* OUT Ib,AX */ 893 { 894 Bitu port=Fetchb(); 895 if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); 896 IO_WriteW(port,reg_ax); 897 break; 898 } 899 CASE_W(0xe8) /* CALL Jw */ 900 { 901 Bit16u addip=Fetchws(); 902 SAVEIP; 903 Push_16(reg_eip); 904 reg_eip=(Bit16u)(reg_eip+addip); 905 continue; 906 } 907 CASE_W(0xe9) /* JMP Jw */ 908 { 909 Bit16u addip=Fetchws(); 910 SAVEIP; 911 reg_eip=(Bit16u)(reg_eip+addip); 912 continue; 913 } 914 CASE_W(0xea) /* JMP Ap */ 915 { 916 Bit16u newip=Fetchw(); 917 Bit16u newcs=Fetchw(); 918 FillFlags(); 919 CPU_JMP(false,newcs,newip,GETIP); 920 #if CPU_TRAP_CHECK 921 if (GETFLAG(TF)) { 922 cpudecoder=CPU_Core_Normal_Trap_Run; 923 return CBRET_NONE; 924 } 925 #endif 926 continue; 927 } 928 CASE_W(0xeb) /* JMP Jb */ 929 { 930 Bit16s addip=Fetchbs(); 931 SAVEIP; 932 reg_eip=(Bit16u)(reg_eip+addip); 933 continue; 934 } 935 CASE_B(0xec) /* IN AL,DX */ 936 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 937 reg_al=IO_ReadB(reg_dx); 938 break; 939 CASE_W(0xed) /* IN AX,DX */ 940 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 941 reg_ax=IO_ReadW(reg_dx); 942 break; 943 CASE_B(0xee) /* OUT DX,AL */ 944 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 945 IO_WriteB(reg_dx,reg_al); 946 break; 947 CASE_W(0xef) /* OUT DX,AX */ 948 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 949 IO_WriteW(reg_dx,reg_ax); 950 break; 951 CASE_B(0xf0) /* LOCK */ 952 LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ 953 break; 954 CASE_B(0xf1) /* ICEBP */ 955 CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); 956 #if CPU_TRAP_CHECK 957 cpu.trap_skip=true; 958 #endif 959 continue; 960 CASE_B(0xf2) /* REPNZ */ 961 DO_PREFIX_REP(false); 962 break; 963 CASE_B(0xf3) /* REPZ */ 964 DO_PREFIX_REP(true); 965 break; 966 CASE_B(0xf4) /* HLT */ 967 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); 968 FillFlags(); 969 CPU_HLT(GETIP); 970 return CBRET_NONE; //Needs to return for hlt cpu core 971 CASE_B(0xf5) /* CMC */ 972 FillFlags(); 973 SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); 974 break; 975 CASE_B(0xf6) /* GRP3 Eb(,Ib) */ 976 { 977 GetRM;Bitu which=(rm>>3)&7; 978 switch (which) { 979 case 0x00: /* TEST Eb,Ib */ 980 case 0x01: /* TEST Eb,Ib Undocumented*/ 981 { 982 if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} 983 else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} 984 break; 985 } 986 case 0x02: /* NOT Eb */ 987 { 988 if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} 989 else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} 990 break; 991 } 992 case 0x03: /* NEG Eb */ 993 { 994 lflags.type=t_NEGb; 995 if (rm >= 0xc0 ) { 996 GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b; 997 *earb=lf_resb; 998 } else { 999 GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b; 1000 SaveMb(eaa,lf_resb); 1001 } 1002 break; 1003 } 1004 case 0x04: /* MUL AL,Eb */ 1005 RMEb(MULB); 1006 break; 1007 case 0x05: /* IMUL AL,Eb */ 1008 RMEb(IMULB); 1009 break; 1010 case 0x06: /* DIV Eb */ 1011 RMEb(DIVB); 1012 break; 1013 case 0x07: /* IDIV Eb */ 1014 RMEb(IDIVB); 1015 break; 1016 } 1017 break; 1018 } 1019 CASE_W(0xf7) /* GRP3 Ew(,Iw) */ 1020 { 1021 GetRM;Bitu which=(rm>>3)&7; 1022 switch (which) { 1023 case 0x00: /* TEST Ew,Iw */ 1024 case 0x01: /* TEST Ew,Iw Undocumented*/ 1025 { 1026 if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} 1027 else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} 1028 break; 1029 } 1030 case 0x02: /* NOT Ew */ 1031 { 1032 if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} 1033 else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} 1034 break; 1035 } 1036 case 0x03: /* NEG Ew */ 1037 { 1038 lflags.type=t_NEGw; 1039 if (rm >= 0xc0 ) { 1040 GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w; 1041 *earw=lf_resw; 1042 } else { 1043 GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w; 1044 SaveMw(eaa,lf_resw); 1045 } 1046 break; 1047 } 1048 case 0x04: /* MUL AX,Ew */ 1049 RMEw(MULW); 1050 break; 1051 case 0x05: /* IMUL AX,Ew */ 1052 RMEw(IMULW) 1053 break; 1054 case 0x06: /* DIV Ew */ 1055 RMEw(DIVW) 1056 break; 1057 case 0x07: /* IDIV Ew */ 1058 RMEw(IDIVW) 1059 break; 1060 } 1061 break; 1062 } 1063 CASE_B(0xf8) /* CLC */ 1064 FillFlags(); 1065 SETFLAGBIT(CF,false); 1066 break; 1067 CASE_B(0xf9) /* STC */ 1068 FillFlags(); 1069 SETFLAGBIT(CF,true); 1070 break; 1071 CASE_B(0xfa) /* CLI */ 1072 if (CPU_CLI()) RUNEXCEPTION(); 1073 break; 1074 CASE_B(0xfb) /* STI */ 1075 if (CPU_STI()) RUNEXCEPTION(); 1076 #if CPU_PIC_CHECK 1077 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; 1078 #endif 1079 break; 1080 CASE_B(0xfc) /* CLD */ 1081 SETFLAGBIT(DF,false); 1082 cpu.direction=1; 1083 break; 1084 CASE_B(0xfd) /* STD */ 1085 SETFLAGBIT(DF,true); 1086 cpu.direction=-1; 1087 break; 1088 CASE_B(0xfe) /* GRP4 Eb */ 1089 { 1090 GetRM;Bitu which=(rm>>3)&7; 1091 switch (which) { 1092 case 0x00: /* INC Eb */ 1093 RMEb(INCB); 1094 break; 1095 case 0x01: /* DEC Eb */ 1096 RMEb(DECB); 1097 break; 1098 case 0x07: /* CallBack */ 1099 { 1100 Bitu cb=Fetchw(); 1101 FillFlags();SAVEIP; 1102 return cb; 1103 } 1104 default: 1105 E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); 1106 break; 1107 } 1108 break; 1109 } 1110 CASE_W(0xff) /* GRP5 Ew */ 1111 { 1112 GetRM;Bitu which=(rm>>3)&7; 1113 switch (which) { 1114 case 0x00: /* INC Ew */ 1115 RMEw(INCW); 1116 break; 1117 case 0x01: /* DEC Ew */ 1118 RMEw(DECW); 1119 break; 1120 case 0x02: /* CALL Ev */ 1121 if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} 1122 else {GetEAa;reg_eip=LoadMw(eaa);} 1123 Push_16(GETIP); 1124 continue; 1125 case 0x03: /* CALL Ep */ 1126 { 1127 if (rm >= 0xc0) goto illegal_opcode; 1128 GetEAa; 1129 Bit16u newip=LoadMw(eaa); 1130 Bit16u newcs=LoadMw(eaa+2); 1131 FillFlags(); 1132 CPU_CALL(false,newcs,newip,GETIP); 1133 #if CPU_TRAP_CHECK 1134 if (GETFLAG(TF)) { 1135 cpudecoder=CPU_Core_Normal_Trap_Run; 1136 return CBRET_NONE; 1137 } 1138 #endif 1139 continue; 1140 } 1141 break; 1142 case 0x04: /* JMP Ev */ 1143 if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} 1144 else {GetEAa;reg_eip=LoadMw(eaa);} 1145 continue; 1146 case 0x05: /* JMP Ep */ 1147 { 1148 if (rm >= 0xc0) goto illegal_opcode; 1149 GetEAa; 1150 Bit16u newip=LoadMw(eaa); 1151 Bit16u newcs=LoadMw(eaa+2); 1152 FillFlags(); 1153 CPU_JMP(false,newcs,newip,GETIP); 1154 #if CPU_TRAP_CHECK 1155 if (GETFLAG(TF)) { 1156 cpudecoder=CPU_Core_Normal_Trap_Run; 1157 return CBRET_NONE; 1158 } 1159 #endif 1160 continue; 1161 } 1162 break; 1163 case 0x06: /* PUSH Ev */ 1164 if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} 1165 else {GetEAa;Push_16(LoadMw(eaa));} 1166 break; 1167 default: 1168 LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",which); 1169 goto illegal_opcode; 1170 } 1171 break; 1172 } 1173 1174 1175 1176 1177