I\'ve ported my library x86Lib to mbed. It fully emulates the 8086 processor, but a few things I\'m still working on. Notable missing things are interrupts. Previously I used exceptions for interrupts, but exceptions aren\'t supported with the mbed compiler. It is also quite slow
maths.cpp
00001 /** 00002 Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls <http://www.Earlz.biz.tm> 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions 00007 are met: 00008 00009 1. Redistributions of source code must retain the above copyright 00010 notice, this list of conditions and the following disclaimer. 00011 2. Redistributions in binary form must reproduce the above copyright 00012 notice, this list of conditions and the following disclaimer in the 00013 documentation and/or other materials provided with the distribution. 00014 3. The name of the author may not be used to endorse or promote products 00015 derived from this software without specific prior written permission. 00016 00017 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 00018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00019 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00020 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00021 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00022 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 00023 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00024 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00025 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00026 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 This file is part of the x86Lib project. 00029 **/ 00030 #define X86LIB_BUILD 00031 #include <x86Lib.h> 00032 namespace x86Lib{ 00033 using namespace std; 00034 00035 00036 00037 00038 // TODO (Jordan#4#): Get AF stuff working in this!! 00039 uint8_t x86CPU::Sub8(uint8_t base,uint8_t subt){ 00040 int8_t result; 00041 if(subt>base){freg.cf=1;}else{freg.cf=0;} 00042 if((int16_t)base-subt>127 || (int16_t)base-subt<-127){ 00043 freg.of=1; 00044 }else{ 00045 freg.of=0; 00046 } 00047 result=base-subt; 00048 if(result==0){freg.zf=1;}else{freg.zf=0;} 00049 CalculatePF8(result); //do pf 00050 CalculateSF8(result); //do sf 00051 base&=0xF; 00052 subt&=0xF; 00053 freg.af = (((base-subt) & ~0xf) != 0); //thank you http://stackoverflow.com/questions/4513746/explain-how-the-af-flag-works-in-an-x86-instructions 00054 return result; 00055 } 00056 00057 uint16_t x86CPU::Sub16(uint16_t base,uint16_t subt){ 00058 int16_t result; 00059 uint16_t mirror; 00060 if(subt>base){freg.cf=1;}else{freg.cf=0;} 00061 if((int32_t)base-subt>32767 || (int32_t)base-subt<-32767){ 00062 freg.of=1; 00063 }else{ 00064 freg.of=0; 00065 } 00066 mirror=base-subt; 00067 result=mirror; 00068 if(result==0){freg.zf=1;}else{freg.zf=0;} 00069 CalculatePF16(result); //do pf 00070 CalculateSF16(result); //do sf 00071 base&=0xF; 00072 subt&=0xF; 00073 freg.af = (((base-subt) & ~0xf) != 0); 00074 return mirror; 00075 } 00076 00077 uint8_t x86CPU::Add8(uint8_t base,uint8_t adder){ 00078 int8_t result; 00079 if(adder+base>255){freg.cf=1;}else{freg.cf=0;} 00080 if((int16_t)base+adder>127 || (int16_t)base+adder<-127){ 00081 freg.of=1; 00082 }else{ 00083 freg.of=0; 00084 } 00085 result=base+adder; 00086 if(result==0){freg.zf=1;}else{freg.zf=0;} 00087 CalculatePF8(result); //do pf 00088 CalculateSF8(result); //do sf 00089 base&=0x0F; 00090 adder&=0x0F; 00091 freg.af = ((int16_t)base+adder > 15); 00092 return result; 00093 } 00094 00095 uint16_t x86CPU::Add16(uint16_t base,uint16_t adder){ 00096 int16_t result; 00097 if((uint32_t)adder+base>(uint32_t)65535){freg.cf=1;}else{freg.cf=0;} 00098 if((int32_t)base+adder>32767 || (int32_t)base+adder<-32767){ 00099 freg.of=1; 00100 }else{ 00101 freg.of=0; 00102 } 00103 result=base+adder; 00104 if(result==0){freg.zf=1;}else{freg.zf=0;} 00105 CalculatePF16(result); //do pf 00106 CalculateSF16(result); //do sf 00107 base&=0x0F; 00108 adder&=0x0F; 00109 freg.af = ((int16_t)base+adder > 15); 00110 return result; 00111 } 00112 00113 00114 00115 00116 uint8_t x86CPU::And8(uint8_t base,uint8_t mask){ 00117 freg.of=0; 00118 freg.cf=0; 00119 base=base&mask; 00120 CalculatePF8(base); 00121 CalculateSF8(base); 00122 if(base==0){ 00123 freg.zf=1; 00124 }else{ 00125 freg.zf=0; 00126 } 00127 return base; 00128 } 00129 00130 uint16_t x86CPU::And16(uint16_t base,uint16_t mask){ 00131 freg.of=0; 00132 freg.cf=0; 00133 base=base&mask; 00134 CalculatePF16(base); 00135 CalculateSF16(base); 00136 if(base==0){ 00137 freg.zf=1; 00138 }else{ 00139 freg.zf=0; 00140 } 00141 return base; 00142 } 00143 00144 //Not affects no flags, so just use ~ 00145 00146 00147 uint8_t x86CPU::Or8(uint8_t base,uint8_t mask){ 00148 freg.of=0; 00149 freg.cf=0; 00150 base=base|mask; 00151 CalculatePF8(base); 00152 CalculateSF8(base); 00153 if(base==0){ 00154 freg.zf=1; 00155 }else{ 00156 freg.zf=0; 00157 } 00158 return base; 00159 } 00160 00161 uint16_t x86CPU::Or16(uint16_t base,uint16_t mask){ 00162 freg.of=0; 00163 freg.cf=0; 00164 base=base|mask; 00165 CalculatePF16(base); 00166 CalculateSF16(base); 00167 if(base==0){ 00168 freg.zf=1; 00169 }else{ 00170 freg.zf=0; 00171 } 00172 return base; 00173 } 00174 00175 uint8_t x86CPU::Xor8(uint8_t base,uint8_t mask){ 00176 freg.of=0; 00177 freg.cf=0; 00178 base=base^mask; 00179 CalculatePF8(base); 00180 CalculateSF8(base); 00181 if(base==0){ 00182 freg.zf=1; 00183 }else{ 00184 freg.zf=0; 00185 } 00186 return base; 00187 } 00188 00189 uint16_t x86CPU::Xor16(uint16_t base,uint16_t mask){ 00190 freg.of=0; 00191 freg.cf=0; 00192 base=base^mask; 00193 CalculatePF16(base); 00194 CalculateSF16(base); 00195 if(base==0){ 00196 freg.zf=1; 00197 }else{ 00198 freg.zf=0; 00199 } 00200 return base; 00201 } 00202 00203 uint8_t x86CPU::ShiftLogicalRight8(uint8_t base,uint8_t count){ 00204 count&=0x1F; //only use bottom 5 bits 00205 if(count==0){ 00206 CalculatePF8(base); 00207 CalculateSF8(base); 00208 freg.zf=1; 00209 return base; 00210 } 00211 freg.of=(base&0x80)>>7; 00212 freg.cf=(base>>(count-1))&1; 00213 base=base>>count; 00214 freg.of=freg.of^((base&0x80)>>7); //if the sign bit changed, then set it to 1 00215 CalculatePF8(base); 00216 CalculateSF8(base); 00217 if(base==0){ 00218 freg.zf=1; 00219 }else{ 00220 freg.zf=0; 00221 } 00222 freg.of=0; 00223 return base; 00224 } 00225 00226 uint16_t x86CPU::ShiftLogicalRight16(uint16_t base,uint8_t count){ 00227 count&=0x1F; //only use bottom 5 bits 00228 if(count==0){ 00229 CalculatePF16(base); 00230 CalculateSF16(base); 00231 freg.zf=1; 00232 return base; 00233 } 00234 freg.of=(base&0x8000)>>15; 00235 freg.cf=(base>>(count-1))&1; 00236 base=base>>count; 00237 freg.of=freg.of^((base&0x8000)>>15); //if the sign bit changed, then set it to 1 00238 CalculatePF16(base); 00239 CalculateSF16(base); 00240 if(base==0){ 00241 freg.zf=1; 00242 }else{ 00243 freg.zf=0; 00244 } 00245 freg.of=0; 00246 return base; 00247 } 00248 uint8_t x86CPU::ShiftArithmeticRight8(uint8_t base,uint8_t count){ 00249 count&=0x1F; //only use bottom 5 bits 00250 if(count==0){ 00251 CalculatePF8(base); 00252 CalculateSF8(base); 00253 freg.zf=1; 00254 return base; 00255 } 00256 freg.cf=(base>>(count-1))&1; 00257 if((base&0x80)!=0){ 00258 base=(base>>count)|(~(0xFF>>count)); //this replaces displaced zero bits with the sign bit 00259 }else{ 00260 base=(base>>count); 00261 } 00262 freg.of=0; 00263 CalculatePF8(base); 00264 CalculateSF8(base); 00265 if(base==0){ 00266 freg.zf=1; 00267 }else{ 00268 freg.zf=0; 00269 } 00270 freg.of=0; 00271 return base; 00272 } 00273 uint16_t x86CPU::ShiftArithmeticRight16(uint16_t base,uint8_t count){ 00274 count&=0x1F; //only use bottom 5 bits 00275 if(count==0){ 00276 CalculatePF16(base); 00277 CalculateSF16(base); 00278 freg.zf=1; 00279 return base; 00280 } 00281 freg.cf=(base>>(count-1))&1; 00282 if((base&0x8000)!=0){ 00283 base=(base>>count)|(~(0xFFFF>>count)); //this replaces displaced zero bits with the sign bit 00284 }else{ 00285 base=(base>>count); 00286 } 00287 freg.of=0; 00288 CalculatePF16(base); 00289 CalculateSF16(base); 00290 if(base==0){ 00291 freg.zf=1; 00292 }else{ 00293 freg.zf=0; 00294 } 00295 freg.of=0; 00296 return base; 00297 } 00298 00299 uint8_t x86CPU::ShiftLogicalLeft8(uint8_t base,uint8_t count){ 00300 count&=0x1F; //only use bottom 5 bits 00301 if(count==0){ 00302 CalculatePF8(base); 00303 CalculateSF8(base); 00304 freg.zf=1; 00305 return base; 00306 } 00307 freg.of=(base&0x80)>>7; 00308 freg.cf=((base<<(count-1))&0x80)>>7; 00309 base=base<<count; 00310 freg.of=freg.of^((base&0x80)>>7); //if the sign bit changed, then set it to 1 00311 CalculatePF8(base); 00312 CalculateSF8(base); 00313 if(base==0){ 00314 freg.zf=1; 00315 }else{ 00316 freg.zf=0; 00317 } 00318 freg.of=0; 00319 return base; 00320 } 00321 00322 uint16_t x86CPU::ShiftLogicalLeft16(uint16_t base,uint8_t count){ 00323 count&=0x1F; //only use bottom 5 bits 00324 if(count==0){ 00325 CalculatePF16(base); 00326 CalculateSF16(base); 00327 freg.zf=1; 00328 return base; 00329 } 00330 freg.of=(base&0x8000)>>15; 00331 freg.cf=((base<<(count-1))&0x8000)>>15; 00332 base=base<<count; 00333 freg.of=freg.of^((base&0x8000)>>15); //if the sign bit changed, then set it to 1 00334 CalculatePF16(base); 00335 CalculateSF16(base); 00336 if(base==0){ 00337 freg.zf=1; 00338 }else{ 00339 freg.zf=0; 00340 } 00341 return base; 00342 } 00343 00344 /**ToDo: Possibly adapt BOCHS source so that we avoid this loop crap...**/ 00345 uint8_t x86CPU::RotateRight8(uint8_t base,uint8_t count){ 00346 freg.of=(base&0x80)>>7; 00347 while(count>0){ 00348 freg.cf=(base&0x01); 00349 base=(freg.cf<<7)|(base>>1); 00350 count--; 00351 } 00352 freg.of=freg.of^((base&0x80)>>7); 00353 return base; 00354 } 00355 00356 uint16_t x86CPU::RotateRight16(uint16_t base,uint8_t count){ 00357 freg.of=(base&0x8000)>>15; 00358 while(count>0){ 00359 freg.cf=(base&0x01); 00360 base=(freg.cf<<15)|(base>>1); 00361 count--; 00362 } 00363 freg.of=freg.of^((base&0x80)>>15); 00364 return base; 00365 } 00366 00367 uint8_t x86CPU::RotateLeft8(uint8_t base,uint8_t count){ 00368 freg.of=(base&0x80)>>7; 00369 while(count>0){ 00370 freg.cf=(base&0x80)>>7; 00371 base=(freg.cf)|(base<<1); 00372 count--; 00373 } 00374 freg.of=freg.of^((base&0x80)>>7); 00375 return base; 00376 } 00377 00378 uint16_t x86CPU::RotateLeft16(uint16_t base,uint8_t count){ 00379 freg.of=(base&0x8000)>>15; 00380 while(count>0){ 00381 freg.cf=(base&0x8000)>>15; 00382 base=(freg.cf)|(base<<1); 00383 count--; 00384 } 00385 freg.of=freg.of^((base&0x8000)>>15); 00386 return base; 00387 } 00388 00389 uint8_t x86CPU::RotateCarryLeft8(uint8_t base,uint8_t count){ 00390 freg.of=(base&0x80)>>7; 00391 while(count>0){ 00392 freg.r0=freg.cf; //reserved bit as a temp variable... 00393 freg.cf=(base&0x80)>>7; 00394 base=(base<<1); 00395 base|=freg.r0; //puts (old)CF in it's place 00396 count--; 00397 } 00398 freg.of=freg.of^((base&0x80)>>7); 00399 return base; 00400 } 00401 00402 uint16_t x86CPU::RotateCarryLeft16(uint16_t base,uint8_t count){ 00403 freg.of=(base&0x8000)>>15; 00404 while(count>0){ 00405 freg.r0=freg.cf; //reserved bit as a temp variable... 00406 freg.cf=(base&0x8000)>>15; 00407 base=(base<<1); 00408 base=(base&0xFFFE)|freg.r0; //zeros the 0 bit and puts (old)CF in it's place 00409 count--; 00410 } 00411 freg.of=freg.of^((base&0x8000)>>15); 00412 return base; 00413 } 00414 00415 uint8_t x86CPU::RotateCarryRight8(uint8_t base,uint8_t count){ 00416 freg.of=(base&0x80)>>7; 00417 while(count>0){ 00418 freg.r0=freg.cf; 00419 freg.cf=(base&0x01); 00420 base=(freg.r0<<7)|(base>>1); 00421 count--; 00422 } 00423 freg.of=freg.of^((base&0x80)>>7); 00424 return base; 00425 } 00426 00427 uint16_t x86CPU::RotateCarryRight16(uint16_t base,uint8_t count){ 00428 freg.of=(base&0x8000)>>15; 00429 while(count>0){ 00430 freg.r0=freg.cf; 00431 freg.cf=(base&0x01); 00432 base=(freg.r0<<15)|(base>>1); 00433 count--; 00434 } 00435 freg.of=freg.of^((base&0x8000)>>15); 00436 return base; 00437 } 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 void x86CPU::op16_sub_al_imm8(){ //0x2C 00448 *regs8[AL]=Sub8(*regs8[AL],op_cache[1]); 00449 eip++; 00450 } 00451 00452 void x86CPU::op16_sub_ax_imm16(){ //0x2D..yay! 2D and not 3! 00453 *regs16[AX]=Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]); 00454 eip+=2; 00455 } 00456 00457 void x86CPU::op16_sub_rm8_r8(){ 00458 eip++; 00459 ModRM16 rm8(this); 00460 rm8.WriteByter(Sub8(rm8.ReadByter(),*regs8[rm8.GetExtra()])); 00461 //finally learning the power of deconstructors! 00462 } 00463 00464 void x86CPU::op16_sub_rm16_r16(){ 00465 eip++; 00466 ModRM16 rm16(this); 00467 rm16.WriteWordr(Sub16(rm16.ReadWordr(),*regs16[rm16.GetExtra()])); 00468 } 00469 void x86CPU::op16_sub_r8_rm8(){ 00470 eip++; 00471 ModRM16 rm8(this); 00472 *regs8[rm8.GetExtra()]=Sub8(*regs8[rm8.GetExtra()],rm8.ReadByter()); 00473 } 00474 00475 void x86CPU::op16_sub_r16_rm16(){ 00476 eip++; 00477 ModRM16 rm16(this); 00478 *regs16[rm16.GetExtra()]=Sub16(*regs16[rm16.GetExtra()],rm16.ReadWordr()); 00479 } 00480 00481 void x86CPU::op16_sub_rm8_imm8(ModRM16 &rm8){ //group 0x80 /5 00482 rm8.WriteByter(Sub8(rm8.ReadByter(),ReadByte(cCS,eip+rm8.GetLength()))); 00483 } 00484 00485 void x86CPU::op16_sub_rm16_imm16(ModRM16 &rm){ //Group 0x81 /5 00486 rm.WriteWordr(Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()))); 00487 } 00488 00489 void x86CPU::op16_sub_rm16_imm8(ModRM16 &rm){ //group 0x83 /5 00490 rm.WriteWordr(Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())))); 00491 } 00492 00493 /****/ 00494 void x86CPU::op16_sbb_al_imm8(){ 00495 *regs8[AL]=Sub8(*regs8[AL],op_cache[1]-freg.cf); 00496 eip++; 00497 } 00498 00499 void x86CPU::op16_sbb_ax_imm16(){ 00500 *regs16[AX]=Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]-freg.cf); 00501 eip++; 00502 eip++; 00503 } 00504 00505 void x86CPU::op16_sbb_rm8_r8(){ 00506 eip++; 00507 ModRM16 rm8(this); 00508 rm8.WriteByter(Sub8(rm8.ReadByter(),*regs8[rm8.GetExtra()]-freg.cf)); 00509 } 00510 00511 void x86CPU::op16_sbb_rm16_r16(){ 00512 eip++; 00513 ModRM16 rm16(this); 00514 rm16.WriteWordr(Sub16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]-freg.cf)); 00515 } 00516 void x86CPU::op16_sbb_r8_rm8(){ 00517 eip++; 00518 ModRM16 rm8(this); 00519 *regs8[rm8.GetExtra()]=Sub8(*regs8[rm8.GetExtra()],rm8.ReadByter()-freg.cf); 00520 } 00521 00522 void x86CPU::op16_sbb_r16_rm16(){ 00523 eip++; 00524 ModRM16 rm16(this); 00525 *regs16[rm16.GetExtra()]=Sub16(*regs16[rm16.GetExtra()],rm16.ReadWordr()-freg.cf); 00526 } 00527 00528 void x86CPU::op16_sbb_rm8_imm8(ModRM16 &rm8){ //group 0x80 00529 rm8.WriteByter(Sub8(rm8.ReadByter(),ReadByte(cCS,eip+rm8.GetLength())-freg.cf)); 00530 } 00531 00532 void x86CPU::op16_sbb_rm16_imm16(ModRM16 &rm){ //Group 0x81 00533 rm.WriteWordr(Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())-freg.cf)); 00534 } 00535 00536 void x86CPU::op16_sbb_rm16_imm8(ModRM16 &rm){ //group 0x83 00537 rm.WriteWordr(Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())-freg.cf))); 00538 } 00539 00540 00541 void x86CPU::op16_dec_r16(){ //0x48+r 00542 freg.r0=freg.cf; 00543 *regs16[(op_cache[0]-0x48)]=Sub16(*regs16[(op_cache[0]-0x48)],1); 00544 freg.cf=freg.r0; 00545 } 00546 00547 void x86CPU::op16_dec_rm8(ModRM16& rm){ 00548 freg.r0=freg.cf; 00549 rm.WriteByter(Sub8(rm.ReadByter(),1)); 00550 freg.cf=freg.r0; 00551 } 00552 00553 void x86CPU::op16_dec_rm16(ModRM16& rm){ 00554 freg.r0=freg.cf; 00555 rm.WriteWordr(Sub16(rm.ReadWordr(),1)); 00556 freg.cf=freg.r0; 00557 } 00558 00559 00560 00561 00562 00563 00564 //cmp and sub are so similar, that they are both going in here... 00565 void x86CPU::op16_cmp_al_imm8(){ 00566 Sub8(*regs8[AL],op_cache[1]); 00567 eip++; 00568 } 00569 00570 void x86CPU::op16_cmp_ax_imm16(){ 00571 Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]); 00572 eip+=2; 00573 } 00574 00575 void x86CPU::op16_cmp_rm8_r8(){ 00576 eip++; 00577 ModRM16 rm(this); 00578 Sub8(rm.ReadByter(),*regs8[rm.GetExtra()]); 00579 } 00580 00581 void x86CPU::op16_cmp_rm16_r16(){ 00582 eip++; 00583 ModRM16 rm(this); 00584 Sub16(rm.ReadWordr(),*regs16[rm.GetExtra()]); 00585 } 00586 00587 void x86CPU::op16_cmp_r8_rm8(){ 00588 eip++; 00589 ModRM16 rm(this); 00590 Sub8(*regs16[rm.GetExtra()],rm.ReadByter()); 00591 } 00592 00593 void x86CPU::op16_cmp_r16_rm16(){ 00594 eip++; 00595 ModRM16 rm(this); 00596 Sub16(*regs16[rm.GetExtra()],rm.ReadWordr()); 00597 } 00598 00599 void x86CPU::op16_cmp_rm8_imm8(ModRM16 &rm){ //group 80 /7 00600 Sub8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength())); 00601 } 00602 00603 void x86CPU::op16_cmp_rm16_imm16(ModRM16 &rm){ //group 81 /7 00604 Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())); 00605 } 00606 00607 void x86CPU::op16_cmp_rm16_imm8(ModRM16 &rm){ //group 83 /7 00608 Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))); 00609 } 00610 00611 00612 00613 00614 00615 00616 void x86CPU::op16_add_al_imm8(){ 00617 *regs8[AL]=Add8(*regs8[AL],op_cache[1]); 00618 eip++; 00619 } 00620 00621 void x86CPU::op16_add_ax_imm8(){ 00622 *regs16[AX]=Add16(*regs16[AX],*(uint16_t*)&op_cache[1]); 00623 eip++; 00624 eip++; 00625 } 00626 00627 void x86CPU::op16_add_rm8_r8(){ 00628 eip++; 00629 ModRM16 rm8(this); 00630 rm8.WriteByter(Add8(rm8.ReadByter(),*regs8[rm8.GetExtra()])); 00631 } 00632 00633 void x86CPU::op16_add_rm16_r16(){ 00634 eip++; 00635 ModRM16 rm16(this); 00636 rm16.WriteWordr(Add16(rm16.ReadWordr(),*regs16[rm16.GetExtra()])); 00637 } 00638 00639 void x86CPU::op16_add_r8_rm8(){ 00640 eip++; 00641 ModRM16 rm(this); 00642 *regs8[rm.GetExtra()]=Add8(*regs8[rm.GetExtra()],rm.ReadByter()); 00643 } 00644 00645 void x86CPU::op16_add_r16_rm16(){ 00646 eip++; 00647 ModRM16 rm(this); 00648 *regs16[rm.GetExtra()]=Add16(*regs16[rm.GetExtra()],rm.ReadWordr()); 00649 } 00650 00651 void x86CPU::op16_add_rm8_imm8(ModRM16 &rm){ //Group 0x80 /0 00652 rm.WriteByter(Add8(rm.ReadWordr(),ReadByte(cCS,eip+rm.GetLength()))); 00653 } 00654 00655 void x86CPU::op16_add_rm16_imm16(ModRM16 &rm){ //Group 0x81 /0 00656 rm.WriteWordr(Add16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()))); 00657 } 00658 00659 void x86CPU::op16_add_rm16_imm8(ModRM16 &rm){ //group 0x83 /0 00660 rm.WriteWordr(Add16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())))); 00661 } 00662 00663 00664 /****/ 00665 void x86CPU::op16_adc_al_imm8(){ 00666 *regs8[AL]=Add8(*regs8[AL],op_cache[1]+freg.cf); 00667 eip++; 00668 } 00669 00670 void x86CPU::op16_adc_ax_imm8(){ 00671 *regs16[AX]=Add16(*regs16[AX],*(uint16_t*)&op_cache[1]+freg.cf); 00672 eip++; 00673 eip++; 00674 } 00675 00676 void x86CPU::op16_adc_rm8_r8(){ 00677 eip++; 00678 ModRM16 rm8(this); 00679 rm8.WriteByter(Add8(rm8.ReadByter(),*regs8[rm8.GetExtra()]+freg.cf)); 00680 } 00681 00682 void x86CPU::op16_adc_rm16_r16(){ 00683 eip++; 00684 ModRM16 rm16(this); 00685 rm16.WriteWordr(Add16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]+freg.cf)); 00686 } 00687 00688 void x86CPU::op16_adc_r8_rm8(){ 00689 eip++; 00690 ModRM16 rm(this); 00691 *regs8[rm.GetExtra()]=Add8(*regs8[rm.GetExtra()],rm.ReadByter()+freg.cf); 00692 } 00693 00694 void x86CPU::op16_adc_r16_rm16(){ 00695 eip++; 00696 ModRM16 rm(this); 00697 *regs16[rm.GetExtra()]=Add16(*regs16[rm.GetExtra()],rm.ReadWordr()+freg.cf); 00698 } 00699 00700 void x86CPU::op16_adc_rm8_imm8(ModRM16 &rm){ //Group 0x80 /2 00701 rm.WriteByter(Add8(rm.ReadWordr(),ReadByte(cCS,eip+rm.GetLength())+freg.cf)); 00702 } 00703 00704 void x86CPU::op16_adc_rm16_imm16(ModRM16 &rm){ //Group 0x81 /2 00705 rm.WriteWordr(Add16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())+freg.cf)); 00706 } 00707 00708 void x86CPU::op16_adc_rm16_imm8(ModRM16 &rm){ //group 0x83 /2 00709 rm.WriteWordr(Add16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))+freg.cf)); 00710 } 00711 00712 00713 00714 void x86CPU::op16_inc_r16(){ //0x40+r 00715 freg.r0=freg.cf; 00716 *regs16[(op_cache[0]-0x40)]=Add16(*regs16[(op_cache[0]-0x40)],1); 00717 freg.cf=freg.r0; 00718 } 00719 00720 void x86CPU::op16_inc_rm8(ModRM16 &rm){ 00721 freg.r0=freg.cf; //yay for reserved flags! 00722 rm.WriteByter(Add8(rm.ReadByter(),1)); 00723 freg.cf=freg.r0; 00724 } 00725 00726 void x86CPU::op16_inc_rm16(ModRM16 &rm){ 00727 freg.r0=freg.cf; 00728 rm.WriteWordr(Add16(rm.ReadWordr(),1)); 00729 freg.cf=freg.r0; 00730 } 00731 00732 void x86CPU::op16_neg_rm8(ModRM16 &rm){ 00733 uint8_t tmp=rm.ReadByter(); 00734 if(tmp==0xFF){ 00735 freg.of=1; 00736 return; 00737 } 00738 rm.WriteByter(Sub8(0,tmp)); 00739 if(tmp==0){ 00740 freg.cf=0; 00741 }else{ 00742 freg.cf=1; 00743 } 00744 } 00745 void x86CPU::op16_neg_rm16(ModRM16 &rm){ 00746 uint16_t tmp=rm.ReadWordr(); 00747 if(tmp==0xFFFF){ 00748 freg.of=1; 00749 return; 00750 } 00751 rm.WriteWordr(Sub16(0,tmp)); 00752 if(tmp==0){ 00753 freg.cf=0; 00754 }else{ 00755 freg.cf=1; 00756 } 00757 } 00758 00759 00760 00761 void x86CPU::op16_div_rm8(ModRM16 &rm){ 00762 if(rm.ReadByter()==0){ 00763 Onx86LibError(); 00764 //throw CpuInt_excp(DIV0_IEXCP); 00765 } 00766 if(((*regs16[AX])/rm.ReadByter())>0xFF){ 00767 Onx86LibError(); 00768 //throw CpuInt_excp(DIV0_IEXCP); 00769 } 00770 *regs8[AL]=(*regs16[AX])/rm.ReadByter(); 00771 *regs8[AH]=(*regs16[AX])%rm.ReadByter(); 00772 } 00773 00774 void x86CPU::op16_div_rm16(ModRM16 &rm){ 00775 if(rm.ReadWordr()==0){ 00776 Onx86LibError(); 00777 //throw CpuInt_excp(DIV0_IEXCP); 00778 } 00779 if((((*regs16[DX]<<16)|(*regs16[AX]))/rm.ReadWordr())>0xFFFF){ 00780 Onx86LibError(); 00781 //throw CpuInt_excp(DIV0_IEXCP); 00782 } 00783 *regs8[AX]=((*regs16[DX]<<16)|(*regs16[AX]))/rm.ReadWordr(); 00784 *regs8[DX]=((*regs16[DX]<<16)|(*regs16[AX]))%rm.ReadWordr(); 00785 } 00786 00787 00788 void x86CPU::op16_idiv_rm8(ModRM16 &rm){ //This WORKS! both signed, and unsigned! 00789 //grrr...who the crap does signed division anyway!? 00790 if(rm.ReadByter()==0){ 00791 Onx86LibError(); 00792 //throw CpuInt_excp(DIV0_IEXCP); 00793 } 00794 uint8_t tmp=rm.ReadByter(); 00795 bool store1,store2; 00796 00797 tmp=Unsign8(tmp,store1); 00798 *regs16[AX]=Unsign16(*regs16[AX],store2); 00799 if(((*regs16[AX])/tmp)>0xFF){ 00800 Onx86LibError(); 00801 //throw CpuInt_excp(DIV0_IEXCP); 00802 } 00803 00804 *regs8[AL]=(*regs16[AX])/tmp; 00805 *regs8[AH]=(*regs16[AX])%tmp; 00806 00807 *regs8[AL]=Resign8(*regs8[AL],store1^store2); 00808 } 00809 00810 void x86CPU::op16_idiv_rm16(ModRM16 &rm){ 00811 if(rm.ReadWordr()==0){ 00812 Onx86LibError(); 00813 //throw CpuInt_excp(DIV0_IEXCP); 00814 } 00815 uint16_t tmp=rm.ReadWordr(); 00816 bool store1,store2; 00817 tmp=Unsign16(tmp,store1); 00818 static uint32_t tmp2=Unsign32(((*regs16[DX])<<16)|(*regs16[AX]),store2); 00819 00820 if((tmp2/tmp)>0xFFFF){ 00821 Onx86LibError(); 00822 //throw CpuInt_excp(DIV0_IEXCP); 00823 } 00824 *regs16[AX]=tmp2/tmp; 00825 *regs16[DX]=tmp2%tmp; 00826 00827 *regs16[AX]=Resign16(*regs16[AX],store1^store2); 00828 } 00829 00830 00831 00832 void x86CPU::op16_mul_rm8(ModRM16 &rm){ 00833 *regs16[AX]=(*regs8[AL])*rm.ReadByter(); 00834 if((*regs8[AH])>0){ //if tophalf of result has anything in it 00835 freg.cf=1; 00836 freg.of=1; 00837 }else{ 00838 freg.cf=0; 00839 freg.of=0; 00840 } 00841 } 00842 00843 00844 void x86CPU::op16_mul_rm16(ModRM16 &rm){ 00845 uint32_t result; 00846 result=(*regs16[AX])*rm.ReadWordr(); 00847 *regs16[AX]=result&0x0000FFFF; 00848 *regs16[DX]=(result&0xFFFF0000)>>16; 00849 if((*regs16[DX])>0){ //if tophalf of result has anything in it 00850 freg.cf=1; 00851 freg.of=1; 00852 }else{ 00853 freg.cf=0; 00854 freg.of=0; 00855 } 00856 } 00857 00858 void x86CPU::op16_imul_rm8(ModRM16 &rm){ 00859 bool store1,store2; 00860 *regs16[AX]=Unsign8(*regs8[AL],store1)*Unsign8(rm.ReadByter(),store2); 00861 if(*regs8[AX]>0){ 00862 freg.of=1; 00863 freg.cf=1; 00864 }else{ 00865 freg.of=0; 00866 freg.cf=0; 00867 } 00868 *regs16[AX]=Resign16(*regs16[AX],store1^store2); 00869 } 00870 00871 void x86CPU::op16_imul_rm16(ModRM16 &rm){ 00872 bool store1,store2; 00873 uint32_t result=Unsign16(*regs16[AX],store1)*Unsign16(rm.ReadWordr(),store2); 00874 if((result&0xFFFF0000)>0){ 00875 freg.of=1; 00876 freg.cf=1; 00877 }else{ 00878 freg.of=0; 00879 freg.cf=0; 00880 } 00881 result=Resign32(result,store1^store2); 00882 *regs16[DX]=(result&0xFFFF0000)>>16; 00883 *regs16[AX]=(result&0xFFFF); 00884 } 00885 00886 00887 00888 void x86CPU::op16_and_rm8_r8(){ 00889 eip++; 00890 ModRM16 rm(this); 00891 rm.WriteByter(And8(rm.ReadByter(),*regs8[rm.GetExtra()])); 00892 } 00893 00894 void x86CPU::op16_and_rm16_r16(){ 00895 eip++; 00896 ModRM16 rm(this); 00897 rm.WriteWordr(And16(rm.ReadWordr(),*regs16[rm.GetExtra()])); 00898 } 00899 00900 void x86CPU::op16_and_r8_rm8(){ 00901 eip++; 00902 ModRM16 rm(this); 00903 *regs8[rm.GetExtra()]=And8(*regs8[rm.GetExtra()],rm.ReadByter()); 00904 } 00905 00906 void x86CPU::op16_and_r16_rm16(){ 00907 eip++; 00908 ModRM16 rm(this); 00909 *regs16[rm.GetExtra()]=And16(*regs16[rm.GetExtra()],rm.ReadWordr()); 00910 } 00911 00912 void x86CPU::op16_and_al_imm8(){ 00913 eip++; 00914 *regs8[AL]=And8(*regs8[AL],op_cache[1]); 00915 } 00916 00917 void x86CPU::op16_and_ax_imm16(){ 00918 eip++; 00919 eip++; 00920 *regs16[AX]=And16(*regs16[AX],*(uint16_t*)&op_cache[1]); 00921 } 00922 00923 void x86CPU::op16_and_rm8_imm8(ModRM16& rm){ 00924 rm.WriteByter(And8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength()))); 00925 } 00926 00927 void x86CPU::op16_and_rm16_imm16(ModRM16& rm){ 00928 rm.WriteWordr(And16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()))); 00929 } 00930 00931 void x86CPU::op16_and_rm16_imm8(ModRM16& rm){ 00932 rm.WriteWordr(And16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())))); 00933 //gotta love parentheses... 00934 } 00935 00936 void x86CPU::op16_or_rm8_r8(){ 00937 eip++; 00938 ModRM16 rm(this); 00939 rm.WriteByter(Or8(rm.ReadByter(),*regs8[rm.GetExtra()])); 00940 } 00941 00942 void x86CPU::op16_or_rm16_r16(){ 00943 eip++; 00944 ModRM16 rm(this); 00945 rm.WriteWordr(Or16(rm.ReadWordr(),*regs16[rm.GetExtra()])); 00946 } 00947 00948 void x86CPU::op16_or_r8_rm8(){ 00949 eip++; 00950 ModRM16 rm(this); 00951 *regs8[rm.GetExtra()]=Or8(*regs8[rm.GetExtra()],rm.ReadByter()); 00952 } 00953 00954 void x86CPU::op16_or_r16_rm16(){ 00955 eip++; 00956 ModRM16 rm(this); 00957 *regs16[rm.GetExtra()]=Or16(*regs16[rm.GetExtra()],rm.ReadWordr()); 00958 } 00959 00960 void x86CPU::op16_or_al_imm8(){ 00961 eip++; 00962 *regs8[AL]=Or8(*regs8[AL],op_cache[1]); 00963 } 00964 00965 void x86CPU::op16_or_ax_imm16(){ 00966 eip++; 00967 eip++; 00968 *regs16[AX]=Or16(*regs16[AX],*(uint16_t*)&op_cache[1]); 00969 } 00970 00971 void x86CPU::op16_or_rm8_imm8(ModRM16& rm){ 00972 rm.WriteByter(Or8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength()))); 00973 } 00974 00975 void x86CPU::op16_or_rm16_imm16(ModRM16& rm){ 00976 rm.WriteWordr(Or16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()))); 00977 } 00978 00979 void x86CPU::op16_or_rm16_imm8(ModRM16& rm){ 00980 rm.WriteWordr(Or16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())))); 00981 //gotta love parentheses... 00982 } 00983 00984 00985 00986 void x86CPU::op16_xor_rm8_r8(){ 00987 eip++; 00988 ModRM16 rm(this); 00989 rm.WriteByter(Xor8(rm.ReadByter(),*regs8[rm.GetExtra()])); 00990 } 00991 00992 void x86CPU::op16_xor_rm16_r16(){ 00993 eip++; 00994 ModRM16 rm(this); 00995 rm.WriteWordr(Xor16(rm.ReadWordr(),*regs16[rm.GetExtra()])); 00996 } 00997 00998 void x86CPU::op16_xor_r8_rm8(){ 00999 eip++; 01000 ModRM16 rm(this); 01001 *regs8[rm.GetExtra()]=Xor8(*regs8[rm.GetExtra()],rm.ReadByter()); 01002 } 01003 01004 void x86CPU::op16_xor_r16_rm16(){ 01005 eip++; 01006 ModRM16 rm(this); 01007 *regs16[rm.GetExtra()]=Xor16(*regs16[rm.GetExtra()],rm.ReadWordr()); 01008 } 01009 01010 void x86CPU::op16_xor_al_imm8(){ 01011 eip++; 01012 *regs8[AL]=Xor8(*regs8[AL],op_cache[1]); 01013 } 01014 01015 void x86CPU::op16_xor_ax_imm16(){ 01016 eip++; 01017 eip++; 01018 *regs16[AX]=Xor16(*regs16[AX],*(uint16_t*)&op_cache[1]); 01019 } 01020 01021 void x86CPU::op16_xor_rm8_imm8(ModRM16& rm){ 01022 rm.WriteByter(Xor8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength()))); 01023 } 01024 01025 void x86CPU::op16_xor_rm16_imm16(ModRM16& rm){ 01026 rm.WriteWordr(Xor16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()))); 01027 } 01028 01029 void x86CPU::op16_xor_rm16_imm8(ModRM16& rm){ 01030 rm.WriteWordr(Xor16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())))); 01031 //gotta love parentheses... 01032 } 01033 01034 void x86CPU::op16_test_rm8_r8(){ 01035 eip++; 01036 ModRM16 rm(this); 01037 And8(rm.ReadByter(),*regs8[rm.GetExtra()]); 01038 } 01039 01040 void x86CPU::op16_test_rm16_r16(){ 01041 eip++; 01042 ModRM16 rm(this); 01043 And16(rm.ReadWordr(),*regs16[rm.GetExtra()]); 01044 } 01045 void x86CPU::op16_test_al_imm8(){ 01046 eip++; 01047 And8(*regs8[AL],op_cache[1]); 01048 } 01049 void x86CPU::op16_test_ax_imm16(){ 01050 eip++; 01051 eip++; 01052 And16(*regs16[AX],*(uint16_t*)&op_cache[1]); 01053 } 01054 01055 void x86CPU::op16_test_rm8_imm8(ModRM16& rm){ 01056 And8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength())); 01057 } 01058 01059 void x86CPU::op16_test_rm16_imm16(ModRM16& rm){ 01060 And16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())); 01061 } 01062 01063 void x86CPU::op16_test_rm16_imm8(ModRM16& rm){ 01064 And16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))); 01065 //gotta love parentheses... 01066 } 01067 01068 01069 void x86CPU::op16_shr_rm8_cl(ModRM16 &rm){ 01070 rm.WriteByter(ShiftLogicalRight8(rm.ReadByter(),*regs8[CL])); 01071 } 01072 void x86CPU::op16_shr_rm16_cl(ModRM16 &rm){ 01073 rm.WriteWordr(ShiftLogicalRight16(rm.ReadWordr(),*regs8[CL])); 01074 } 01075 01076 void x86CPU::op16_shl_rm8_cl(ModRM16 &rm){ 01077 rm.WriteByter(ShiftLogicalLeft8(rm.ReadByter(),*regs8[CL])); 01078 } 01079 void x86CPU::op16_shl_rm16_cl(ModRM16 &rm){ 01080 rm.WriteWordr(ShiftLogicalLeft16(rm.ReadWordr(),*regs8[CL])); 01081 } 01082 01083 void x86CPU::op16_sar_rm8_cl(ModRM16 &rm){ 01084 rm.WriteByter(ShiftArithmeticRight8(rm.ReadByter(),*regs8[CL])); 01085 } 01086 void x86CPU::op16_sar_rm16_cl(ModRM16 &rm){ 01087 rm.WriteWordr(ShiftArithmeticRight16(rm.ReadWordr(),*regs8[CL])); 01088 } 01089 01090 void x86CPU::op16_rol_rm8_cl(ModRM16 &rm){ 01091 rm.WriteByter(RotateLeft8(rm.ReadByter(),*regs8[CL])); 01092 } 01093 void x86CPU::op16_rol_rm16_cl(ModRM16 &rm){ 01094 rm.WriteWordr(RotateLeft16(rm.ReadWordr(),*regs8[CL])); 01095 } 01096 01097 void x86CPU::op16_ror_rm8_cl(ModRM16 &rm){ 01098 rm.WriteByter(RotateRight8(rm.ReadByter(),*regs8[CL])); 01099 } 01100 void x86CPU::op16_ror_rm16_cl(ModRM16 &rm){ 01101 rm.WriteWordr(RotateRight16(rm.ReadWordr(),*regs8[CL])); 01102 } 01103 01104 01105 void x86CPU::op16_rcl_rm8_cl(ModRM16 &rm){ 01106 rm.WriteByter(RotateCarryLeft8(rm.ReadByter(),*regs8[CL])); 01107 } 01108 void x86CPU::op16_rcl_rm16_cl(ModRM16 &rm){ 01109 rm.WriteWordr(RotateCarryLeft16(rm.ReadWordr(),*regs8[CL])); 01110 } 01111 01112 void x86CPU::op16_rcr_rm8_cl(ModRM16 &rm){ 01113 rm.WriteByter(RotateCarryRight8(rm.ReadByter(),*regs8[CL])); 01114 } 01115 void x86CPU::op16_rcr_rm16_cl(ModRM16 &rm){ 01116 rm.WriteWordr(RotateCarryRight16(rm.ReadWordr(),*regs8[CL])); 01117 } 01118 01119 01120 /****/ 01121 void x86CPU::op16_shr_rm8_1(ModRM16 &rm){ 01122 rm.WriteByter(ShiftLogicalRight8(rm.ReadByter(),1)); 01123 } 01124 void x86CPU::op16_shr_rm16_1(ModRM16 &rm){ 01125 rm.WriteWordr(ShiftLogicalRight16(rm.ReadWordr(),1)); 01126 } 01127 01128 void x86CPU::op16_shl_rm8_1(ModRM16 &rm){ 01129 rm.WriteByter(ShiftLogicalLeft8(rm.ReadByter(),1)); 01130 } 01131 void x86CPU::op16_shl_rm16_1(ModRM16 &rm){ 01132 rm.WriteWordr(ShiftLogicalLeft16(rm.ReadWordr(),1)); 01133 } 01134 01135 void x86CPU::op16_sar_rm8_1(ModRM16 &rm){ 01136 rm.WriteByter(ShiftArithmeticRight8(rm.ReadByter(),1)); 01137 } 01138 void x86CPU::op16_sar_rm16_1(ModRM16 &rm){ 01139 rm.WriteWordr(ShiftArithmeticRight16(rm.ReadWordr(),1)); 01140 } 01141 01142 void x86CPU::op16_rol_rm8_1(ModRM16 &rm){ 01143 rm.WriteByter(RotateLeft8(rm.ReadByter(),1)); 01144 } 01145 void x86CPU::op16_rol_rm16_1(ModRM16 &rm){ 01146 rm.WriteWordr(RotateLeft16(rm.ReadWordr(),1)); 01147 } 01148 01149 void x86CPU::op16_ror_rm8_1(ModRM16 &rm){ 01150 rm.WriteByter(RotateRight8(rm.ReadByter(),1)); 01151 } 01152 void x86CPU::op16_ror_rm16_1(ModRM16 &rm){ 01153 rm.WriteWordr(RotateRight16(rm.ReadWordr(),1)); 01154 } 01155 01156 01157 void x86CPU::op16_rcl_rm8_1(ModRM16 &rm){ 01158 rm.WriteByter(RotateCarryLeft8(rm.ReadByter(),1)); 01159 } 01160 void x86CPU::op16_rcl_rm16_1(ModRM16 &rm){ 01161 rm.WriteWordr(RotateCarryLeft16(rm.ReadWordr(),1)); 01162 } 01163 01164 void x86CPU::op16_rcr_rm8_1(ModRM16 &rm){ 01165 rm.WriteByter(RotateCarryRight8(rm.ReadByter(),1)); 01166 } 01167 void x86CPU::op16_rcr_rm16_1(ModRM16 &rm){ 01168 rm.WriteWordr(RotateCarryRight16(rm.ReadWordr(),1)); 01169 } 01170 01171 void x86CPU::op16_not_rm8(ModRM16 &rm){ 01172 rm.WriteByter(~(rm.ReadByter())); 01173 } 01174 01175 void x86CPU::op16_not_rm16(ModRM16 &rm){ 01176 rm.WriteWordr(~(rm.ReadWordr())); 01177 } 01178 01179 01180 01181 01182 /** 01183 BCD Opcodes for Open86 01184 By: Alboin, 3-16-07 01185 Modified to work with x86Lib by Jordan(hckr83) 01186 **/ 01187 01188 01189 /* Opcode: 0x37 */ 01190 void x86CPU::op16_aaa() { 01191 if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) { 01192 *regs8[AL] += 6; 01193 *regs8[AH]++; 01194 freg.af = 1; 01195 freg.cf = 1; 01196 } 01197 else { 01198 freg.af = 0; 01199 freg.cf = 0; 01200 } 01201 *regs8[AL] = *regs8[AL] & 0x0f; 01202 } 01203 01204 01205 /* Opcode: 0x27 */ 01206 void x86CPU::op16_daa() { 01207 if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) { 01208 *regs8[AL] += 6; 01209 *regs8[AH]++; 01210 } 01211 else 01212 freg.af = 0; 01213 01214 if(*regs8[AL] > 0x9f || freg.cf == 1) { 01215 *regs8[AL] = *regs8[AL] + 0x60; 01216 freg.cf = 1; 01217 } 01218 else 01219 freg.cf = 0; 01220 } 01221 01222 /* Opcode: 0x2F */ 01223 void x86CPU::op16_das() { 01224 if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) { 01225 *regs8[AL] -= 6; 01226 freg.af = 1; 01227 } 01228 else 01229 freg.af = 0; 01230 01231 if(*regs8[AL] > 0x9f || freg.cf == 1) { 01232 *regs8[AL] -= 0x60; 01233 freg.cf = 1; 01234 } 01235 else 01236 freg.cf = 0; 01237 } 01238 01239 /* Opcode: 0x3F */ 01240 void x86CPU::op16_aas() { 01241 if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) { 01242 *regs8[AL] -= 6; 01243 *regs8[AH]--; 01244 freg.af = 1; 01245 freg.cf = 1; 01246 } 01247 else { 01248 freg.af = 0; 01249 freg.cf = 0; 01250 } 01251 *regs8[AL] = *regs8[AL] & 0x0f; 01252 } 01253 01254 01255 01256 void x86CPU::op16_aad(){ 01257 //AAD is a weird opcode because it is two bytes 01258 //for "apparently" no reason. But really, it is just 01259 //undocumented... the 0x0A in the second byte is for 01260 //multiplecation...but it can be changed... 01261 *regs8[AL]=(*regs8[AH])*(op_cache[1])+*regs8[AL]; 01262 *regs8[AH]=0; 01263 } 01264 01265 void x86CPU::op16_aam(){ 01266 //same wiht the 0x0A operand as above.. 01267 if(op_cache[1]==0){ 01268 Onx86LibError(); 01269 //throw CpuInt_excp(DIV0_IEXCP); 01270 } 01271 *regs8[AH]=(*regs8[AL])/op_cache[1]; 01272 *regs8[AL]=(*regs8[AL])%op_cache[1]; 01273 } 01274 01275 01276 01277 01278 01279 01280 01281 01282 01283 01284 }; 01285 01286 01287
Generated on Sat Jul 16 2022 03:55:43 by 1.7.2