1 /* 2 * Copyright (C) 2002-2021 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 along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 GetRMrw; 496 if (rm >= 0xc0) goto illegal_opcode; 497 //Little hack to always use segprefixed version 498 BaseDS=BaseSS=0; 499 if (TEST_PREFIX_ADDR) { 500 *rmrw=(Bit16u)(*EATable[256+rm])(); 501 } else { 502 *rmrw=(Bit16u)(*EATable[rm])(); 503 } 504 break; 505 } 506 CASE_B(0x8e) /* MOV Sw,Ew */ 507 { 508 GetRM;Bit16u val;Bitu which=(rm>>3)&7; 509 if (rm >= 0xc0 ) {GetEArw;val=*earw;} 510 else {GetEAa;val=LoadMw(eaa);} 511 switch (which) { 512 case 0x02: /* MOV SS,Ew */ 513 CPU_Cycles++; //Always do another instruction 514 [[fallthrough]]; 515 case 0x00: /* MOV ES,Ew */ 516 case 0x03: /* MOV DS,Ew */ 517 case 0x05: /* MOV GS,Ew */ 518 case 0x04: /* MOV FS,Ew */ 519 if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION(); 520 break; 521 default: 522 goto illegal_opcode; 523 } 524 break; 525 } 526 CASE_W(0x8f) /* POP Ew */ 527 { 528 Bit16u val=Pop_16(); 529 GetRM; 530 if (rm >= 0xc0 ) {GetEArw;*earw=val;} 531 else {GetEAa;SaveMw(eaa,val);} 532 break; 533 } 534 CASE_B(0x90) /* NOP */ 535 break; 536 CASE_W(0x91) /* XCHG CX,AX */ 537 { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } 538 break; 539 CASE_W(0x92) /* XCHG DX,AX */ 540 { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } 541 break; 542 CASE_W(0x93) /* XCHG BX,AX */ 543 { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } 544 break; 545 CASE_W(0x94) /* XCHG SP,AX */ 546 { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } 547 break; 548 CASE_W(0x95) /* XCHG BP,AX */ 549 { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } 550 break; 551 CASE_W(0x96) /* XCHG SI,AX */ 552 { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } 553 break; 554 CASE_W(0x97) /* XCHG DI,AX */ 555 { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } 556 break; 557 CASE_W(0x98) /* CBW */ 558 reg_ax=(Bit8s)reg_al;break; 559 CASE_W(0x99) /* CWD */ 560 if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0; 561 break; 562 CASE_W(0x9a) /* CALL Ap */ 563 { 564 FillFlags(); 565 Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); 566 CPU_CALL(false,newcs,newip,GETIP); 567 #if CPU_TRAP_CHECK 568 if (GETFLAG(TF)) { 569 cpudecoder=CPU_TRAP_DECODER; 570 return CBRET_NONE; 571 } 572 #endif 573 continue; 574 } 575 CASE_B(0x9b) /* WAIT */ 576 break; /* No waiting here */ 577 CASE_W(0x9c) /* PUSHF */ 578 if (CPU_PUSHF(false)) RUNEXCEPTION(); 579 break; 580 CASE_W(0x9d) /* POPF */ 581 if (CPU_POPF(false)) RUNEXCEPTION(); 582 #if CPU_TRAP_CHECK 583 if (GETFLAG(TF)) { 584 cpudecoder=CPU_TRAP_DECODER; 585 goto decode_end; 586 } 587 #endif 588 #if CPU_PIC_CHECK 589 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; 590 #endif 591 break; 592 CASE_B(0x9e) /* SAHF */ 593 SETFLAGSb(reg_ah); 594 break; 595 CASE_B(0x9f) /* LAHF */ 596 FillFlags(); 597 reg_ah=reg_flags&0xff; 598 break; 599 CASE_B(0xa0) /* MOV AL,Ob */ 600 { 601 GetEADirect; 602 reg_al=LoadMb(eaa); 603 } 604 break; 605 CASE_W(0xa1) /* MOV AX,Ow */ 606 { 607 GetEADirect; 608 reg_ax=LoadMw(eaa); 609 } 610 break; 611 CASE_B(0xa2) /* MOV Ob,AL */ 612 { 613 GetEADirect; 614 SaveMb(eaa,reg_al); 615 } 616 break; 617 CASE_W(0xa3) /* MOV Ow,AX */ 618 { 619 GetEADirect; 620 SaveMw(eaa,reg_ax); 621 } 622 break; 623 CASE_B(0xa4) /* MOVSB */ 624 DoString(R_MOVSB);break; 625 CASE_W(0xa5) /* MOVSW */ 626 DoString(R_MOVSW);break; 627 CASE_B(0xa6) /* CMPSB */ 628 DoString(R_CMPSB);break; 629 CASE_W(0xa7) /* CMPSW */ 630 DoString(R_CMPSW);break; 631 CASE_B(0xa8) /* TEST AL,Ib */ 632 ALIb(TESTB);break; 633 CASE_W(0xa9) /* TEST AX,Iw */ 634 AXIw(TESTW);break; 635 CASE_B(0xaa) /* STOSB */ 636 DoString(R_STOSB);break; 637 CASE_W(0xab) /* STOSW */ 638 DoString(R_STOSW);break; 639 CASE_B(0xac) /* LODSB */ 640 DoString(R_LODSB);break; 641 CASE_W(0xad) /* LODSW */ 642 DoString(R_LODSW);break; 643 CASE_B(0xae) /* SCASB */ 644 DoString(R_SCASB);break; 645 CASE_W(0xaf) /* SCASW */ 646 DoString(R_SCASW);break; 647 CASE_B(0xb0) /* MOV AL,Ib */ 648 reg_al=Fetchb();break; 649 CASE_B(0xb1) /* MOV CL,Ib */ 650 reg_cl=Fetchb();break; 651 CASE_B(0xb2) /* MOV DL,Ib */ 652 reg_dl=Fetchb();break; 653 CASE_B(0xb3) /* MOV BL,Ib */ 654 reg_bl=Fetchb();break; 655 CASE_B(0xb4) /* MOV AH,Ib */ 656 reg_ah=Fetchb();break; 657 CASE_B(0xb5) /* MOV CH,Ib */ 658 reg_ch=Fetchb();break; 659 CASE_B(0xb6) /* MOV DH,Ib */ 660 reg_dh=Fetchb();break; 661 CASE_B(0xb7) /* MOV BH,Ib */ 662 reg_bh=Fetchb();break; 663 CASE_W(0xb8) /* MOV AX,Iw */ 664 reg_ax=Fetchw();break; 665 CASE_W(0xb9) /* MOV CX,Iw */ 666 reg_cx=Fetchw();break; 667 CASE_W(0xba) /* MOV DX,Iw */ 668 reg_dx=Fetchw();break; 669 CASE_W(0xbb) /* MOV BX,Iw */ 670 reg_bx=Fetchw();break; 671 CASE_W(0xbc) /* MOV SP,Iw */ 672 reg_sp=Fetchw();break; 673 CASE_W(0xbd) /* MOV BP.Iw */ 674 reg_bp=Fetchw();break; 675 CASE_W(0xbe) /* MOV SI,Iw */ 676 reg_si=Fetchw();break; 677 CASE_W(0xbf) /* MOV DI,Iw */ 678 reg_di=Fetchw();break; 679 CASE_B(0xc0) /* GRP2 Eb,Ib */ 680 GRP2B(Fetchb());break; 681 CASE_W(0xc1) /* GRP2 Ew,Ib */ 682 GRP2W(Fetchb());break; 683 CASE_W(0xc2) /* RETN Iw */ 684 reg_eip=Pop_16(); 685 reg_esp+=Fetchw(); 686 continue; 687 CASE_W(0xc3) /* RETN */ 688 reg_eip=Pop_16(); 689 continue; 690 CASE_W(0xc4) /* LES */ 691 { 692 GetRMrw; 693 if (rm >= 0xc0) goto illegal_opcode; 694 GetEAa; 695 if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); 696 *rmrw=LoadMw(eaa); 697 break; 698 } 699 CASE_W(0xc5) /* LDS */ 700 { 701 GetRMrw; 702 if (rm >= 0xc0) goto illegal_opcode; 703 GetEAa; 704 if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); 705 *rmrw=LoadMw(eaa); 706 break; 707 } 708 CASE_B(0xc6) /* MOV Eb,Ib */ 709 { 710 GetRM; 711 if (rm >= 0xc0) {GetEArb;*earb=Fetchb();} 712 else {GetEAa;SaveMb(eaa,Fetchb());} 713 break; 714 } 715 CASE_W(0xc7) /* MOV EW,Iw */ 716 { 717 GetRM; 718 if (rm >= 0xc0) {GetEArw;*earw=Fetchw();} 719 else {GetEAa;SaveMw(eaa,Fetchw());} 720 break; 721 } 722 CASE_W(0xc8) /* ENTER Iw,Ib */ 723 { 724 Bitu bytes=Fetchw(); 725 Bitu level=Fetchb(); 726 CPU_ENTER(false,bytes,level); 727 } 728 break; 729 CASE_W(0xc9) /* LEAVE */ 730 reg_esp&=cpu.stack.notmask; 731 reg_esp|=(reg_ebp&cpu.stack.mask); 732 reg_bp=Pop_16(); 733 break; 734 CASE_W(0xca) /* RETF Iw */ 735 { 736 Bitu words=Fetchw(); 737 FillFlags(); 738 CPU_RET(false,words,GETIP); 739 continue; 740 } 741 CASE_W(0xcb) /* RETF */ 742 FillFlags(); 743 CPU_RET(false,0,GETIP); 744 continue; 745 CASE_B(0xcc) /* INT3 */ 746 #if C_DEBUG 747 FillFlags(); 748 if (DEBUG_Breakpoint()) 749 return debugCallback; 750 #endif 751 CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); 752 #if CPU_TRAP_CHECK 753 cpu.trap_skip=true; 754 #endif 755 continue; 756 CASE_B(0xcd) /* INT Ib */ 757 { 758 Bit8u num=Fetchb(); 759 #if C_DEBUG 760 FillFlags(); 761 if (DEBUG_IntBreakpoint(num)) { 762 return debugCallback; 763 } 764 #endif 765 CPU_SW_Interrupt(num,GETIP); 766 #if CPU_TRAP_CHECK 767 cpu.trap_skip=true; 768 #endif 769 continue; 770 } 771 CASE_B(0xce) /* INTO */ 772 if (get_OF()) { 773 CPU_SW_Interrupt(4,GETIP); 774 #if CPU_TRAP_CHECK 775 cpu.trap_skip=true; 776 #endif 777 continue; 778 } 779 break; 780 CASE_W(0xcf) /* IRET */ 781 { 782 CPU_IRET(false,GETIP); 783 #if CPU_TRAP_CHECK 784 if (GETFLAG(TF)) { 785 cpudecoder=CPU_TRAP_DECODER; 786 return CBRET_NONE; 787 } 788 #endif 789 #if CPU_PIC_CHECK 790 if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; 791 #endif 792 continue; 793 } 794 CASE_B(0xd0) /* GRP2 Eb,1 */ 795 GRP2B(1);break; 796 CASE_W(0xd1) /* GRP2 Ew,1 */ 797 GRP2W(1);break; 798 CASE_B(0xd2) /* GRP2 Eb,CL */ 799 GRP2B(reg_cl);break; 800 CASE_W(0xd3) /* GRP2 Ew,CL */ 801 GRP2W(reg_cl);break; 802 CASE_B(0xd4) /* AAM Ib */ 803 AAM(Fetchb());break; 804 CASE_B(0xd5) /* AAD Ib */ 805 AAD(Fetchb());break; 806 CASE_B(0xd6) /* SALC */ 807 reg_al = get_CF() ? 0xFF : 0; 808 break; 809 CASE_B(0xd7) /* XLAT */ 810 if (TEST_PREFIX_ADDR) { 811 reg_al = LoadMb(BaseDS + (reg_ebx + reg_al)); 812 } else { 813 reg_al = LoadMb(BaseDS + (Bit16u)(reg_bx + reg_al)); 814 } 815 break; 816 #ifdef CPU_FPU 817 CASE_B(0xd8) /* FPU ESC 0 */ 818 FPU_ESC(0);break; 819 CASE_B(0xd9) /* FPU ESC 1 */ 820 FPU_ESC(1);break; 821 CASE_B(0xda) /* FPU ESC 2 */ 822 FPU_ESC(2);break; 823 CASE_B(0xdb) /* FPU ESC 3 */ 824 FPU_ESC(3);break; 825 CASE_B(0xdc) /* FPU ESC 4 */ 826 FPU_ESC(4);break; 827 CASE_B(0xdd) /* FPU ESC 5 */ 828 FPU_ESC(5);break; 829 CASE_B(0xde) /* FPU ESC 6 */ 830 FPU_ESC(6);break; 831 CASE_B(0xdf) /* FPU ESC 7 */ 832 FPU_ESC(7);break; 833 #else 834 CASE_B(0xd8) /* FPU ESC 0 */ 835 CASE_B(0xd9) /* FPU ESC 1 */ 836 CASE_B(0xda) /* FPU ESC 2 */ 837 CASE_B(0xdb) /* FPU ESC 3 */ 838 CASE_B(0xdc) /* FPU ESC 4 */ 839 CASE_B(0xdd) /* FPU ESC 5 */ 840 CASE_B(0xde) /* FPU ESC 6 */ 841 CASE_B(0xdf) /* FPU ESC 7 */ 842 { 843 LOG(LOG_CPU,LOG_NORMAL)("FPU used"); 844 Bit8u rm=Fetchb(); 845 if (rm<0xc0) GetEAa; 846 } 847 break; 848 #endif 849 CASE_W(0xe0) /* LOOPNZ */ 850 if (TEST_PREFIX_ADDR) { 851 JumpCond16_b(--reg_ecx && !get_ZF()); 852 } else { 853 JumpCond16_b(--reg_cx && !get_ZF()); 854 } 855 break; 856 CASE_W(0xe1) /* LOOPZ */ 857 if (TEST_PREFIX_ADDR) { 858 JumpCond16_b(--reg_ecx && get_ZF()); 859 } else { 860 JumpCond16_b(--reg_cx && get_ZF()); 861 } 862 break; 863 CASE_W(0xe2) /* LOOP */ 864 if (TEST_PREFIX_ADDR) { 865 JumpCond16_b(--reg_ecx); 866 } else { 867 JumpCond16_b(--reg_cx); 868 } 869 break; 870 CASE_W(0xe3) /* JCXZ */ 871 JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); 872 break; 873 CASE_B(0xe4) /* IN AL,Ib */ 874 { 875 Bitu port=Fetchb(); 876 if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); 877 reg_al=IO_ReadB(port); 878 break; 879 } 880 CASE_W(0xe5) /* IN AX,Ib */ 881 { 882 Bitu port=Fetchb(); 883 if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); 884 reg_ax=IO_ReadW(port); 885 break; 886 } 887 CASE_B(0xe6) /* OUT Ib,AL */ 888 { 889 Bitu port=Fetchb(); 890 if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); 891 IO_WriteB(port,reg_al); 892 break; 893 } 894 CASE_W(0xe7) /* OUT Ib,AX */ 895 { 896 Bitu port=Fetchb(); 897 if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); 898 IO_WriteW(port,reg_ax); 899 break; 900 } 901 CASE_W(0xe8) /* CALL Jw */ 902 { 903 Bit16u addip=Fetchws(); 904 SAVEIP; 905 Push_16(reg_eip); 906 reg_eip=(Bit16u)(reg_eip+addip); 907 continue; 908 } 909 CASE_W(0xe9) /* JMP Jw */ 910 { 911 Bit16u addip=Fetchws(); 912 SAVEIP; 913 reg_eip=(Bit16u)(reg_eip+addip); 914 continue; 915 } 916 CASE_W(0xea) /* JMP Ap */ 917 { 918 Bit16u newip=Fetchw(); 919 Bit16u newcs=Fetchw(); 920 FillFlags(); 921 CPU_JMP(false,newcs,newip,GETIP); 922 #if CPU_TRAP_CHECK 923 if (GETFLAG(TF)) { 924 cpudecoder=CPU_TRAP_DECODER; 925 return CBRET_NONE; 926 } 927 #endif 928 continue; 929 } 930 CASE_W(0xeb) /* JMP Jb */ 931 { 932 Bit16s addip=Fetchbs(); 933 SAVEIP; 934 reg_eip=(Bit16u)(reg_eip+addip); 935 continue; 936 } 937 CASE_B(0xec) /* IN AL,DX */ 938 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 939 reg_al=IO_ReadB(reg_dx); 940 break; 941 CASE_W(0xed) /* IN AX,DX */ 942 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 943 reg_ax=IO_ReadW(reg_dx); 944 break; 945 CASE_B(0xee) /* OUT DX,AL */ 946 if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); 947 IO_WriteB(reg_dx,reg_al); 948 break; 949 CASE_W(0xef) /* OUT DX,AX */ 950 if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); 951 IO_WriteW(reg_dx,reg_ax); 952 break; 953 CASE_B(0xf0) /* LOCK */ 954 LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ 955 break; 956 CASE_B(0xf1) /* ICEBP */ 957 CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); 958 #if CPU_TRAP_CHECK 959 cpu.trap_skip=true; 960 #endif 961 continue; 962 CASE_B(0xf2) /* REPNZ */ 963 DO_PREFIX_REP(false); 964 break; 965 CASE_B(0xf3) /* REPZ */ 966 DO_PREFIX_REP(true); 967 break; 968 CASE_B(0xf4) /* HLT */ 969 if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); 970 FillFlags(); 971 CPU_HLT(GETIP); 972 return CBRET_NONE; //Needs to return for hlt cpu core 973 CASE_B(0xf5) /* CMC */ 974 FillFlags(); 975 SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); 976 break; 977 CASE_B(0xf6) /* GRP3 Eb(,Ib) */ 978 { 979 GetRM;Bitu which=(rm>>3)&7; 980 switch (which) { 981 case 0x00: /* TEST Eb,Ib */ 982 case 0x01: /* TEST Eb,Ib Undocumented*/ 983 { 984 if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} 985 else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} 986 break; 987 } 988 case 0x02: /* NOT Eb */ 989 { 990 if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} 991 else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} 992 break; 993 } 994 case 0x03: /* NEG Eb */ 995 { 996 lflags.type=t_NEGb; 997 if (rm >= 0xc0 ) { 998 GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b; 999 *earb=lf_resb; 1000 } else { 1001 GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b; 1002 SaveMb(eaa,lf_resb); 1003 } 1004 break; 1005 } 1006 case 0x04: /* MUL AL,Eb */ 1007 RMEb(MULB); 1008 break; 1009 case 0x05: /* IMUL AL,Eb */ 1010 RMEb(IMULB); 1011 break; 1012 case 0x06: /* DIV Eb */ 1013 RMEb(DIVB); 1014 break; 1015 case 0x07: /* IDIV Eb */ 1016 RMEb(IDIVB); 1017 break; 1018 } 1019 break; 1020 } 1021 CASE_W(0xf7) /* GRP3 Ew(,Iw) */ 1022 { 1023 GetRM;Bitu which=(rm>>3)&7; 1024 switch (which) { 1025 case 0x00: /* TEST Ew,Iw */ 1026 case 0x01: /* TEST Ew,Iw Undocumented*/ 1027 { 1028 if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} 1029 else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} 1030 break; 1031 } 1032 case 0x02: /* NOT Ew */ 1033 { 1034 if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} 1035 else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} 1036 break; 1037 } 1038 case 0x03: /* NEG Ew */ 1039 { 1040 lflags.type=t_NEGw; 1041 if (rm >= 0xc0 ) { 1042 GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w; 1043 *earw=lf_resw; 1044 } else { 1045 GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w; 1046 SaveMw(eaa,lf_resw); 1047 } 1048 break; 1049 } 1050 case 0x04: /* MUL AX,Ew */ 1051 RMEw(MULW); 1052 break; 1053 case 0x05: /* IMUL AX,Ew */ 1054 RMEw(IMULW) 1055 break; 1056 case 0x06: /* DIV Ew */ 1057 RMEw(DIVW) 1058 break; 1059 case 0x07: /* IDIV Ew */ 1060 RMEw(IDIVW) 1061 break; 1062 } 1063 break; 1064 } 1065 CASE_B(0xf8) /* CLC */ 1066 FillFlags(); 1067 SETFLAGBIT(CF,false); 1068 break; 1069 CASE_B(0xf9) /* STC */ 1070 FillFlags(); 1071 SETFLAGBIT(CF,true); 1072 break; 1073 CASE_B(0xfa) /* CLI */ 1074 if (CPU_CLI()) RUNEXCEPTION(); 1075 break; 1076 CASE_B(0xfb) /* STI */ 1077 if (CPU_STI()) RUNEXCEPTION(); 1078 #if CPU_PIC_CHECK 1079 if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; 1080 #endif 1081 break; 1082 CASE_B(0xfc) /* CLD */ 1083 SETFLAGBIT(DF,false); 1084 cpu.direction=1; 1085 break; 1086 CASE_B(0xfd) /* STD */ 1087 SETFLAGBIT(DF,true); 1088 cpu.direction=-1; 1089 break; 1090 CASE_B(0xfe) /* GRP4 Eb */ 1091 { 1092 GetRM;Bitu which=(rm>>3)&7; 1093 switch (which) { 1094 case 0x00: /* INC Eb */ 1095 RMEb(INCB); 1096 break; 1097 case 0x01: /* DEC Eb */ 1098 RMEb(DECB); 1099 break; 1100 case 0x07: /* CallBack */ 1101 { 1102 Bitu cb=Fetchw(); 1103 FillFlags();SAVEIP; 1104 return cb; 1105 } 1106 default: 1107 E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); 1108 break; 1109 } 1110 break; 1111 } 1112 CASE_W(0xff) /* GRP5 Ew */ 1113 { 1114 GetRM;Bitu which=(rm>>3)&7; 1115 switch (which) { 1116 case 0x00: /* INC Ew */ 1117 RMEw(INCW); 1118 break; 1119 case 0x01: /* DEC Ew */ 1120 RMEw(DECW); 1121 break; 1122 case 0x02: /* CALL Ev */ 1123 if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} 1124 else {GetEAa;reg_eip=LoadMw(eaa);} 1125 Push_16(GETIP); 1126 continue; 1127 case 0x03: /* CALL Ep */ 1128 { 1129 if (rm >= 0xc0) goto illegal_opcode; 1130 GetEAa; 1131 Bit16u newip=LoadMw(eaa); 1132 Bit16u newcs=LoadMw(eaa+2); 1133 FillFlags(); 1134 CPU_CALL(false,newcs,newip,GETIP); 1135 #if CPU_TRAP_CHECK 1136 if (GETFLAG(TF)) { 1137 cpudecoder=CPU_TRAP_DECODER; 1138 return CBRET_NONE; 1139 } 1140 #endif 1141 continue; 1142 } 1143 break; 1144 case 0x04: /* JMP Ev */ 1145 if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} 1146 else {GetEAa;reg_eip=LoadMw(eaa);} 1147 continue; 1148 case 0x05: /* JMP Ep */ 1149 { 1150 if (rm >= 0xc0) goto illegal_opcode; 1151 GetEAa; 1152 Bit16u newip=LoadMw(eaa); 1153 Bit16u newcs=LoadMw(eaa+2); 1154 FillFlags(); 1155 CPU_JMP(false,newcs,newip,GETIP); 1156 #if CPU_TRAP_CHECK 1157 if (GETFLAG(TF)) { 1158 cpudecoder=CPU_TRAP_DECODER; 1159 return CBRET_NONE; 1160 } 1161 #endif 1162 continue; 1163 } 1164 break; 1165 case 0x06: /* PUSH Ev */ 1166 if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} 1167 else {GetEAa;Push_16(LoadMw(eaa));} 1168 break; 1169 default: 1170 LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",static_cast<uint32_t>(which)); 1171 goto illegal_opcode; 1172 } 1173 break; 1174 } 1175 1176 1177 1178 1179