gameboy wormboy manboy gameworm gameman wormgame mangame manworm
Dependencies: mbed SDFileSystem2
cpu.cpp
00001 // Implementation of OPCODES and cpu step function 00002 00003 #define NDEBUG 00004 #include <assert.h> 00005 00006 #include "cpu.h" 00007 #include "mem.h" 00008 00009 // cpu registers, halted state, and timers 00010 CpuState globalState; 00011 00012 typedef void OpcodeHandler(u8 opcode); 00013 00014 // the GB has several invalid opcodes 00015 void invHandler(u8 opcode) { 00016 printf("got invalid opcode 0x%x\n", opcode); 00017 assert(false); 00018 } 00019 00020 //////////////////////////////// 00021 // CB Opcode Helper Functions // 00022 //////////////////////////////// 00023 00024 u8 rlcReg(u8 value, bool isA) { 00025 u8 result = value; 00026 clearAllFlags(); 00027 if((result & 0x80) != 0) { 00028 setCarryFlag(); 00029 result <<= 1; 00030 result |= 0x1; 00031 } else { 00032 result <<= 1; 00033 } 00034 if(!isA) { 00035 if((u8)result == 0) { 00036 setZeroFlag(); 00037 } 00038 } 00039 return result; 00040 } 00041 00042 u8 rlReg(u8 value, bool isA) { 00043 u8 carry = getCarryFlag() ? (u8)1 : (u8)0; 00044 u8 result = value; 00045 clearAllFlags(); 00046 if((result & 0x80) != 0) { 00047 setCarryFlag(); 00048 } 00049 result <<= 1; 00050 result |= carry; 00051 if(!isA) { 00052 if((u8)result == 0) { 00053 setZeroFlag(); 00054 } 00055 } 00056 return result; 00057 } 00058 00059 u8 rrc(u8 value, bool isA) { 00060 u8 result = value; 00061 clearAllFlags(); 00062 if((result & 1) != 0) { 00063 setCarryFlag(); 00064 result >>= 1; 00065 result |= 0x80; 00066 } else { 00067 result >>= 1; 00068 } 00069 if(!isA) { 00070 if((u8)result == 0) { 00071 setZeroFlag(); 00072 } 00073 } 00074 return result; 00075 } 00076 00077 u8 rr(u8 value, bool isA) { 00078 u8 carry = getCarryFlag() ? (u8)0x80 : (u8)0x00; 00079 u8 result = value; 00080 clearAllFlags(); 00081 if((result & 1) != 0) { 00082 setCarryFlag(); 00083 } 00084 result >>= 1; 00085 result |= carry; 00086 if(!isA) { 00087 if((u8)result == 0) { 00088 setZeroFlag(); 00089 } 00090 } 00091 return result; 00092 } 00093 00094 u8 srl(u8 value) { 00095 u8 result = value; 00096 clearAllFlags(); 00097 if(result & 1) { 00098 setCarryFlag(); 00099 } 00100 result >>= 1; 00101 if(result == 0) { 00102 setZeroFlag(); 00103 } 00104 return result; 00105 } 00106 00107 u8 sla(u8 value) { 00108 clearAllFlags(); 00109 if(value & 0x80) { 00110 setCarryFlag(); 00111 } 00112 u8 result = value << 1; 00113 if(result == 0) { 00114 setZeroFlag(); 00115 } 00116 return result; 00117 } 00118 00119 u8 sra(u8 value) { 00120 u8 result = value; 00121 clearAllFlags(); 00122 if(result & 1) { 00123 setCarryFlag(); 00124 } 00125 if((result & 0x80)) { 00126 result >>= 1; 00127 result |= 0x80; 00128 } else { 00129 result >>= 1; 00130 } 00131 if(result == 0) { 00132 setZeroFlag(); 00133 } 00134 return result; 00135 } 00136 00137 u8 swapRegister(u8 value) { 00138 u8 low = value & 0xf; 00139 u8 hi = (value >> 4) & 0xf; 00140 u8 result = (low << 4) + hi; 00141 clearAllFlags(); 00142 if((u8)result == 0) { 00143 setZeroFlag(); 00144 } 00145 return result; 00146 } 00147 00148 00149 //////////////////////////////// 00150 // CB Opcodes // 00151 //////////////////////////////// 00152 00153 void SLA_A(u8 opcode) { // 0x27 00154 globalState.pc++; 00155 globalState.cycleCount += 8; 00156 globalState.a = sla(globalState.a); 00157 } 00158 00159 void SLA_B(u8 opcode) { // 0x20 00160 globalState.pc++; 00161 globalState.cycleCount += 8; 00162 globalState.bc.hi = sla(globalState.bc.hi); 00163 } 00164 00165 void SLA_C(u8 opcode) { // 0x21 00166 globalState.pc++; 00167 globalState.cycleCount += 8; 00168 globalState.bc.lo = sla(globalState.bc.lo); 00169 } 00170 00171 void SLA_D(u8 opcode) { // 0x22 00172 globalState.pc++; 00173 globalState.cycleCount += 8; 00174 globalState.de.hi = sla(globalState.de.hi); 00175 } 00176 00177 void SLA_E(u8 opcode) { // 0x23 00178 globalState.pc++; 00179 globalState.cycleCount += 8; 00180 globalState.de.lo = sla(globalState.de.lo); 00181 } 00182 00183 void SLA_H(u8 opcode) { // 0x24 00184 globalState.pc++; 00185 globalState.cycleCount += 8; 00186 globalState.hl.hi = sla(globalState.hl.hi); 00187 } 00188 00189 void SLA_L(u8 opcode) { // 0x25 00190 globalState.pc++; 00191 globalState.cycleCount += 8; 00192 globalState.hl.lo = sla(globalState.hl.lo); 00193 } 00194 00195 void SLA_DHL(u8 opcode) { // 0x26 00196 globalState.pc++; 00197 globalState.cycleCount += 16; 00198 writeByte(sla(readByte(globalState.hl.v)), globalState.hl.v); 00199 } 00200 00201 void SRA_A(u8 opcode) { // 0x2f 00202 globalState.pc++; 00203 globalState.cycleCount += 8; 00204 globalState.a = sra(globalState.a); 00205 } 00206 00207 void SRA_B(u8 opcode) { // 0x28 00208 globalState.pc++; 00209 globalState.cycleCount += 8; 00210 globalState.bc.hi = sra(globalState.bc.hi); 00211 } 00212 00213 void SRA_C(u8 opcode) { // 0x29 00214 globalState.pc++; 00215 globalState.cycleCount += 8; 00216 globalState.bc.lo = sra(globalState.bc.lo); 00217 } 00218 00219 void SRA_D(u8 opcode) { // 0x2a 00220 globalState.pc++; 00221 globalState.cycleCount += 8; 00222 globalState.de.hi = sra(globalState.de.hi); 00223 } 00224 00225 void SRA_E(u8 opcode) { // 0x2b 00226 globalState.pc++; 00227 globalState.cycleCount += 8; 00228 globalState.de.lo = sra(globalState.de.lo); 00229 } 00230 00231 void SRA_H(u8 opcode) { // 0x2c 00232 globalState.pc++; 00233 globalState.cycleCount += 8; 00234 globalState.hl.hi = sra(globalState.hl.hi); 00235 } 00236 00237 void SRA_L(u8 opcode) { // 0x2d 00238 globalState.pc++; 00239 globalState.cycleCount += 8; 00240 globalState.hl.lo = sra(globalState.hl.lo); 00241 } 00242 00243 void SRA_DHL(u8 opcode) { // 0x2e 00244 globalState.pc++; 00245 globalState.cycleCount += 16; 00246 writeByte(sra(readByte(globalState.hl.v)), globalState.hl.v); 00247 } 00248 00249 00250 void SRL_A(u8 opcode) { // 0x3f 00251 globalState.pc++; 00252 globalState.cycleCount += 8; 00253 globalState.a = srl(globalState.a); 00254 } 00255 00256 void SRL_B(u8 opcode) { // 0x38 00257 globalState.pc++; 00258 globalState.cycleCount += 8; 00259 globalState.bc.hi = srl(globalState.bc.hi); 00260 } 00261 00262 void SRL_C(u8 opcode) { // 0x39 00263 globalState.pc++; 00264 globalState.cycleCount += 8; 00265 globalState.bc.lo = srl(globalState.bc.lo); 00266 } 00267 00268 void SRL_D(u8 opcode) { // 0x3a 00269 globalState.pc++; 00270 globalState.cycleCount += 8; 00271 globalState.de.hi = srl(globalState.de.hi); 00272 } 00273 00274 void SRL_E(u8 opcode) { // 0x3b 00275 globalState.pc++; 00276 globalState.cycleCount += 8; 00277 globalState.de.lo = srl(globalState.de.lo); 00278 } 00279 00280 void SRL_H(u8 opcode) { // 0x3c 00281 globalState.pc++; 00282 globalState.cycleCount += 8; 00283 globalState.hl.hi = srl(globalState.hl.hi); 00284 } 00285 00286 void SRL_L(u8 opcode) { // 0x3d 00287 globalState.pc++; 00288 globalState.cycleCount += 8; 00289 globalState.hl.lo = srl(globalState.hl.lo); 00290 } 00291 00292 void SRL_DHL(u8 opcode) { // 0x3e 00293 globalState.pc++; 00294 globalState.cycleCount += 16; 00295 writeByte(srl(readByte(globalState.hl.v)), globalState.hl.v); 00296 } 00297 00298 void RR_A(u8 opcode) { // 0x1f 00299 globalState.pc++; 00300 globalState.cycleCount += 8; 00301 globalState.a = rr(globalState.a, false); 00302 } 00303 00304 void RR_B(u8 opcode) { // 0x18 00305 globalState.pc++; 00306 globalState.cycleCount += 8; 00307 globalState.bc.hi = rr(globalState.bc.hi, false); 00308 } 00309 00310 void RR_C(u8 opcode) { // 0x19 00311 globalState.pc++; 00312 globalState.cycleCount += 8; 00313 globalState.bc.lo = rr(globalState.bc.lo, false); 00314 } 00315 00316 void RR_D(u8 opcode) { // 0x1a 00317 globalState.pc++; 00318 globalState.cycleCount += 8; 00319 globalState.de.hi = rr(globalState.de.hi, false); 00320 } 00321 00322 void RR_E(u8 opcode) { // 0x1b 00323 globalState.pc++; 00324 globalState.cycleCount += 8; 00325 globalState.de.lo = rr(globalState.de.lo, false); 00326 } 00327 00328 void RR_H(u8 opcode) { // 0x1c 00329 globalState.pc++; 00330 globalState.cycleCount += 8; 00331 globalState.hl.hi = rr(globalState.hl.hi, false); 00332 } 00333 00334 void RR_L(u8 opcode) { // 0x1d 00335 globalState.pc++; 00336 globalState.cycleCount += 8; 00337 globalState.hl.lo = rr(globalState.hl.lo, false); 00338 } 00339 00340 void RR_DHL(u8 opcode) { // 0x1e 00341 globalState.pc++; 00342 globalState.cycleCount += 16; 00343 writeByte(rr(readByte(globalState.hl.v), false), globalState.hl.v); 00344 } 00345 00346 void RL_A(u8 opcode) { // 0x17 00347 globalState.pc++; 00348 globalState.cycleCount += 8; 00349 globalState.a = rlReg(globalState.a, false); 00350 } 00351 00352 void RL_B(u8 opcode) { // 0x10 00353 globalState.pc++; 00354 globalState.cycleCount += 8; 00355 globalState.bc.hi = rlReg(globalState.bc.hi, false); 00356 } 00357 00358 void RL_C(u8 opcode) { // 0x11 00359 globalState.pc++; 00360 globalState.cycleCount += 8; 00361 globalState.bc.lo = rlReg(globalState.bc.lo, false); 00362 } 00363 00364 void RL_D(u8 opcode) { // 0x12 00365 globalState.pc++; 00366 globalState.cycleCount += 8; 00367 globalState.de.hi = rlReg(globalState.de.hi, false); 00368 } 00369 00370 void RL_E(u8 opcode) { // 0x13 00371 globalState.pc++; 00372 globalState.cycleCount += 8; 00373 globalState.de.lo = rlReg(globalState.de.lo, false); 00374 } 00375 00376 void RL_H(u8 opcode) { // 0x14 00377 globalState.pc++; 00378 globalState.cycleCount += 8; 00379 globalState.hl.hi = rlReg(globalState.hl.hi, false); 00380 } 00381 00382 void RL_L(u8 opcode) { // 0x15 00383 globalState.pc++; 00384 globalState.cycleCount += 8; 00385 globalState.hl.lo = rlReg(globalState.hl.lo, false); 00386 } 00387 00388 void RL_DHL(u8 opcode) { // 0x16 00389 globalState.pc++; 00390 globalState.cycleCount += 16; 00391 writeByte(rlReg(readByte(globalState.hl.v), false), globalState.hl.v); 00392 } 00393 00394 void SWAP_A(u8 opcode) { // 37 00395 globalState.pc++; 00396 globalState.cycleCount += 8; 00397 globalState.a = swapRegister(globalState.a); 00398 } 00399 00400 void SWAP_B(u8 opcode) { // 30 00401 globalState.pc++; 00402 globalState.cycleCount += 8; 00403 globalState.bc.hi = swapRegister(globalState.bc.hi); 00404 } 00405 00406 void SWAP_C(u8 opcode) { // 31 00407 globalState.pc++; 00408 globalState.cycleCount += 8; 00409 globalState.bc.lo = swapRegister(globalState.bc.lo); 00410 } 00411 00412 void SWAP_D(u8 opcode) { // 32 00413 globalState.pc++; 00414 globalState.cycleCount += 8; 00415 globalState.de.hi = swapRegister(globalState.de.hi); 00416 } 00417 00418 void SWAP_E(u8 opcode) { // 33 00419 globalState.pc++; 00420 globalState.cycleCount += 8; 00421 globalState.de.lo = swapRegister(globalState.de.lo); 00422 } 00423 00424 void SWAP_H(u8 opcode) { // 34 00425 globalState.pc++; 00426 globalState.cycleCount += 8; 00427 globalState.hl.hi = swapRegister(globalState.hl.hi); 00428 } 00429 00430 void SWAP_L(u8 opcode) { // 35 00431 globalState.pc++; 00432 globalState.cycleCount += 8; 00433 globalState.hl.lo = swapRegister(globalState.hl.lo); 00434 } 00435 00436 void SWAP_DHL(u8 opcode) { // 36 00437 globalState.pc++; 00438 globalState.cycleCount += 16; 00439 writeByte(swapRegister(readByte(globalState.hl.v)), globalState.hl.v); 00440 } 00441 00442 void RLC_A(u8 opcode) { // 07 00443 globalState.pc++; 00444 globalState.cycleCount += 8; 00445 globalState.a = rlcReg(globalState.a, false); 00446 } 00447 00448 void RLC_B(u8 opcode) { // 00 00449 globalState.pc++; 00450 globalState.cycleCount += 8; 00451 globalState.bc.hi = rlcReg(globalState.bc.hi, false); 00452 } 00453 00454 void RLC_C(u8 opcode) { // 01 00455 globalState.pc++; 00456 globalState.cycleCount += 8; 00457 globalState.bc.lo = rlcReg(globalState.bc.lo, false); 00458 } 00459 00460 void RLC_D(u8 opcode) { // 02 00461 globalState.pc++; 00462 globalState.cycleCount += 8; 00463 globalState.de.hi = rlcReg(globalState.de.hi, false); 00464 } 00465 00466 void RLC_E(u8 opcode) { // 03 00467 globalState.pc++; 00468 globalState.cycleCount += 8; 00469 globalState.de.lo = rlcReg(globalState.de.lo, false); 00470 } 00471 00472 void RLC_H(u8 opcode) { // 04 00473 globalState.pc++; 00474 globalState.cycleCount += 8; 00475 globalState.hl.hi = rlcReg(globalState.hl.hi, false); 00476 } 00477 00478 void RLC_L(u8 opcode) { // 05 00479 globalState.pc++; 00480 globalState.cycleCount += 8; 00481 globalState.hl.lo = rlcReg(globalState.hl.lo, false); 00482 } 00483 00484 void RLC_DHL(u8 opcode) { // 06 00485 globalState.pc++; 00486 globalState.cycleCount += 16; 00487 u8 result = rlcReg(readByte(globalState.hl.v), false); 00488 writeByte(result, globalState.hl.v); 00489 } 00490 00491 00492 void RRC_A(u8 opcode) { // 0f 00493 globalState.pc++; 00494 globalState.cycleCount += 8; 00495 globalState.a = rrc(globalState.a, false); 00496 } 00497 00498 void RRC_B(u8 opcode) { // 08 00499 globalState.pc++; 00500 globalState.cycleCount += 8; 00501 globalState.bc.hi = rrc(globalState.bc.hi, false); 00502 } 00503 00504 void RRC_C(u8 opcode) { // 09 00505 globalState.pc++; 00506 globalState.cycleCount += 8; 00507 globalState.bc.lo = rrc(globalState.bc.lo, false); 00508 } 00509 00510 void RRC_D(u8 opcode) { // 0a 00511 globalState.pc++; 00512 globalState.cycleCount += 8; 00513 globalState.de.hi = rrc(globalState.de.hi, false); 00514 } 00515 00516 void RRC_E(u8 opcode) { // 0b 00517 globalState.pc++; 00518 globalState.cycleCount += 8; 00519 globalState.de.lo = rrc(globalState.de.lo, false); 00520 } 00521 00522 void RRC_H(u8 opcode) { // 0c 00523 globalState.pc++; 00524 globalState.cycleCount += 8; 00525 globalState.hl.hi = rrc(globalState.hl.hi, false); 00526 } 00527 00528 void RRC_L(u8 opcode) { // 0d 00529 globalState.pc++; 00530 globalState.cycleCount += 8; 00531 globalState.hl.lo = rrc(globalState.hl.lo, false); 00532 } 00533 00534 void RRC_DHL(u8 opcode) { // 0e 00535 globalState.pc++; 00536 globalState.cycleCount += 16; 00537 u8 result = rrc(readByte(globalState.hl.v), false); 00538 writeByte(result, globalState.hl.v); 00539 } 00540 00541 00542 void bit_B_set(u8 opcode) { 00543 u8 bitID = (opcode - (u8)0xC0) >> 3; 00544 assert(bitID < 8); 00545 globalState.bc.hi |= (1 << bitID); 00546 globalState.pc += 1; 00547 globalState.cycleCount += 8; 00548 } 00549 00550 void bit_C_set(u8 opcode) { 00551 u8 bitID = (opcode - (u8)0xC1) >> 3; 00552 assert(bitID < 8); 00553 globalState.bc.lo |= (1 << bitID); 00554 globalState.pc += 1; 00555 globalState.cycleCount += 8; 00556 } 00557 00558 void bit_D_set(u8 opcode) { 00559 u8 bitID = (opcode - (u8)0xC2) >> 3; 00560 assert(bitID < 8); 00561 globalState.de.hi |= (1 << bitID); 00562 globalState.pc += 1; 00563 globalState.cycleCount += 8; 00564 } 00565 00566 void bit_E_set(u8 opcode) { 00567 u8 bitID = (opcode - (u8)0xC3) >> 3; 00568 assert(bitID < 8); 00569 globalState.de.lo |= (1 << bitID); 00570 globalState.pc += 1; 00571 globalState.cycleCount += 8; 00572 } 00573 00574 void bit_H_set(u8 opcode) { 00575 u8 bitID = (opcode - (u8)0xC4) >> 3; 00576 assert(bitID < 8); 00577 globalState.hl.hi |= (1 << bitID); 00578 globalState.pc += 1; 00579 globalState.cycleCount += 8; 00580 } 00581 00582 void bit_L_set(u8 opcode) { 00583 u8 bitID = (opcode - (u8)0xC5) >> 3; 00584 assert(bitID < 8); 00585 globalState.hl.lo |= (1 << bitID); 00586 globalState.pc += 1; 00587 globalState.cycleCount += 8; 00588 } 00589 00590 void bit_DHL_set(u8 opcode) { 00591 u8 bitID = (opcode - (u8)0xC6) >> 3; 00592 assert(bitID < 8); 00593 u8 value = readByte(globalState.hl.v); 00594 value |= (1 << bitID); 00595 writeByte(value, globalState.hl.v); 00596 globalState.pc += 1; 00597 globalState.cycleCount += 16; 00598 } 00599 00600 void bit_A_set(u8 opcode) { 00601 u8 bitID = (opcode - (u8)0xC7) >> 3; 00602 assert(bitID < 8); 00603 globalState.a |= (1 << bitID); 00604 globalState.pc += 1; 00605 globalState.cycleCount += 8; 00606 } 00607 00608 void bit_B_res(u8 opcode) { 00609 u8 bitID = (opcode - (u8)0x80) >> 3; 00610 assert(bitID < 8); 00611 globalState.bc.hi &= ~(1 << bitID); 00612 globalState.pc += 1; 00613 globalState.cycleCount += 8; 00614 } 00615 00616 void bit_C_res(u8 opcode) { 00617 u8 bitID = (opcode - (u8)0x81) >> 3; 00618 assert(bitID < 8); 00619 globalState.bc.lo &= ~(1 << bitID); 00620 globalState.pc += 1; 00621 globalState.cycleCount += 8; 00622 } 00623 00624 void bit_D_res(u8 opcode) { 00625 u8 bitID = (opcode - (u8)0x82) >> 3; 00626 assert(bitID < 8); 00627 globalState.de.hi &= ~(1 << bitID); 00628 globalState.pc += 1; 00629 globalState.cycleCount += 8; 00630 } 00631 00632 void bit_E_res(u8 opcode) { 00633 u8 bitID = (opcode - (u8)0x83) >> 3; 00634 assert(bitID < 8); 00635 globalState.de.lo &= ~(1 << bitID); 00636 globalState.pc += 1; 00637 globalState.cycleCount += 8; 00638 } 00639 00640 void bit_H_res(u8 opcode) { 00641 u8 bitID = (opcode - (u8)0x84) >> 3; 00642 assert(bitID < 8); 00643 globalState.hl.hi &= ~(1 << bitID); 00644 globalState.pc += 1; 00645 globalState.cycleCount += 8; 00646 } 00647 00648 void bit_L_res(u8 opcode) { 00649 u8 bitID = (opcode - (u8)0x85) >> 3; 00650 assert(bitID < 8); 00651 globalState.hl.lo &= ~(1 << bitID); 00652 globalState.pc += 1; 00653 globalState.cycleCount += 8; 00654 } 00655 00656 void bit_DHL_res(u8 opcode) { 00657 u8 bitID = (opcode - (u8)0x86) >> 3; 00658 assert(bitID < 8); 00659 u8 value = readByte(globalState.hl.v); 00660 value &= ~(1 << bitID); 00661 writeByte(value, globalState.hl.v); 00662 globalState.pc += 1; 00663 globalState.cycleCount += 16; 00664 } 00665 00666 void bit_A_res(u8 opcode) { 00667 u8 bitID = (opcode - (u8)0x87) >> 3; 00668 assert(bitID < 8); 00669 globalState.a &= ~(1 << bitID); 00670 globalState.pc += 1; 00671 globalState.cycleCount += 8; 00672 } 00673 00674 void bit_A_test(u8 opcode) { 00675 u8 bitID = (opcode - (u8)0x47) >> 3; 00676 assert(bitID < 8); 00677 //printf("check bit %d of A\n", bitID); 00678 u8 val = globalState.a; 00679 if(((val >> bitID) & 1) == 0) { 00680 setZeroFlag(); 00681 } else { 00682 clearZeroFlag(); 00683 } 00684 setHalfCarryFlag(); 00685 clearSubtractFlag(); 00686 globalState.pc += 1; 00687 globalState.cycleCount += 8; 00688 } 00689 00690 void bit_B_test(u8 opcode) { 00691 u8 bitID = (opcode - (u8)0x40) >> 3; 00692 //printf("B opcode 0x%x bitId %d\n", opcode, bitID); 00693 assert(bitID < 8); 00694 //printf("check bit %d of B\n", bitID); 00695 u8 val = globalState.bc.hi; 00696 if(((val >> bitID) & 1) == 0) { 00697 setZeroFlag(); 00698 } else { 00699 clearZeroFlag(); 00700 } 00701 setHalfCarryFlag(); 00702 clearSubtractFlag(); 00703 globalState.pc += 1; 00704 globalState.cycleCount += 8; 00705 } 00706 00707 00708 void bit_C_test(u8 opcode) { 00709 u8 bitID = (opcode - (u8)0x41) >> 3; 00710 assert(bitID < 8); 00711 //printf("check bit %d of C\n", bitID); 00712 u8 val = globalState.bc.lo; 00713 if(((val >> bitID) & 1) == 0) { 00714 setZeroFlag(); 00715 } else { 00716 clearZeroFlag(); 00717 } 00718 setHalfCarryFlag(); 00719 clearSubtractFlag(); 00720 globalState.pc += 1; 00721 globalState.cycleCount += 8; 00722 } 00723 00724 void bit_D_test(u8 opcode) { 00725 u8 bitID = (opcode - (u8)0x42) >> 3; 00726 assert(bitID < 8); 00727 //printf("check bit %d of D\n", bitID); 00728 u8 val = globalState.de.hi; 00729 if(((val >> bitID) & 1) == 0) { 00730 setZeroFlag(); 00731 } else { 00732 clearZeroFlag(); 00733 } 00734 setHalfCarryFlag(); 00735 clearSubtractFlag(); 00736 globalState.pc += 1; 00737 globalState.cycleCount += 8; 00738 } 00739 00740 void bit_E_test(u8 opcode) { 00741 u8 bitID = (opcode - (u8)0x43) >> 3; 00742 assert(bitID < 8); 00743 //printf("check bit %d of E\n", bitID); 00744 u8 val = globalState.de.lo; 00745 if(((val >> bitID) & 1) == 0) { 00746 setZeroFlag(); 00747 } else { 00748 clearZeroFlag(); 00749 } 00750 setHalfCarryFlag(); 00751 clearSubtractFlag(); 00752 globalState.pc += 1; 00753 globalState.cycleCount += 8; 00754 } 00755 00756 void bit_H_test(u8 opcode) { 00757 u8 bitID = (opcode - (u8)0x44) >> 3; 00758 assert(bitID < 8); 00759 //printf("check bit %d of H\n", bitID); 00760 u8 val = globalState.hl.hi; 00761 if(((val >> bitID) & 1) == 0) { 00762 setZeroFlag(); 00763 } else { 00764 clearZeroFlag(); 00765 } 00766 setHalfCarryFlag(); 00767 clearSubtractFlag(); 00768 globalState.pc += 1; 00769 globalState.cycleCount += 8; 00770 } 00771 00772 void bit_L_test(u8 opcode) { 00773 u8 bitID = (opcode - (u8)0x45) >> 3; 00774 assert(bitID < 8); 00775 //printf("check bit %d of L\n", bitID); 00776 u8 val = globalState.hl.lo; 00777 if(((val >> bitID) & 1) == 0) { 00778 setZeroFlag(); 00779 } else { 00780 clearZeroFlag(); 00781 } 00782 setHalfCarryFlag(); 00783 clearSubtractFlag(); 00784 globalState.pc += 1; 00785 globalState.cycleCount += 8; 00786 } 00787 00788 void bit_DHL_test(u8 opcode) { 00789 u8 bitID = (opcode - (u8)0x45) >> 3; 00790 assert(bitID < 8); 00791 //printf("check bit %d of L\n", bitID); 00792 u8 val = readByte(globalState.hl.v); 00793 if(((val >> bitID) & 1) == 0) { 00794 setZeroFlag(); 00795 } else { 00796 clearZeroFlag(); 00797 } 00798 setHalfCarryFlag(); 00799 clearSubtractFlag(); 00800 globalState.pc += 1; 00801 globalState.cycleCount += 16; 00802 } 00803 00804 // CB-prefixed opcode handler table 00805 static OpcodeHandler* opcode_cbs[256] = 00806 {RLC_B, RLC_C, RLC_D, RLC_E, RLC_H, RLC_L, RLC_DHL, RLC_A, // 0x0 - 0x7 00807 RRC_B, RRC_C, RRC_D, RRC_E, RRC_H, RRC_L, RRC_DHL, RRC_A, // 0x8 - 0xf 00808 RL_B, RL_C, RL_D, RL_E, RL_H, RL_L, RL_DHL, RL_A, // 0x10 - 0x17 00809 RR_B, RR_C, RR_D, RR_E, RR_H, RR_L, RR_DHL, RR_A, // 0x18 - 0x1f 00810 SLA_B, SLA_C, SLA_D, SLA_E, SLA_H, SLA_L, SLA_DHL, SLA_A, // 0x20 - 0x27 00811 SRA_B, SRA_C, SRA_D, SRA_E, SRA_H, SRA_L, SRA_DHL, SRA_A, // 0x28 - 0x2f 00812 SWAP_B, SWAP_C, SWAP_D, SWAP_E, SWAP_H, SWAP_L, SWAP_DHL, SWAP_A, // 0x30 - 0x37 00813 SRL_B, SRL_C, SRL_D, SRL_E, SRL_H, SRL_L, SRL_DHL, SRL_A, // 0x38 - 0x3f 00814 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x40 - 0x47 00815 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x48 - 0x4f 00816 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x50 - 0x57 00817 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x58 - 0x5f 00818 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x60 - 0x67 00819 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x68 - 0x6f 00820 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x70 - 0x77 00821 bit_B_test, bit_C_test, bit_D_test, bit_E_test, bit_H_test, bit_L_test, bit_DHL_test, bit_A_test, // 0x78 - 0x7f 00822 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0x80 - 0x8 00823 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0x88 - 0x8f 00824 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0x90 - 0x97 00825 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0x98 - 0x9f 00826 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0xa0 - 0xa7 00827 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0xa8 - 0xaf 00828 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0xb0 - 0xb7 00829 bit_B_res, bit_C_res, bit_D_res, bit_E_res, bit_H_res, bit_L_res, bit_DHL_res, bit_A_res, // 0xb8 - 0xbf 00830 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xc0 - 0xc7 00831 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xc8 - 0xcf 00832 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xd0 - 0xd7 00833 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xd8 - 0xdf 00834 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xe0 - 0xe7 00835 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xe8 - 0xef 00836 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set , // 0xf0 - 0xf7 00837 bit_B_set, bit_C_set, bit_D_set, bit_E_set, bit_H_set, bit_L_set, bit_DHL_set, bit_A_set }; // 0xf8 - 0xff 00838 00839 00840 //////////////////////////////// 00841 // Opcodes // 00842 //////////////////////////////// 00843 void LD_B_n(u8 opocde) { // 06 00844 u8 imm = readByte(++globalState.pc); 00845 globalState.pc++; 00846 globalState.bc.hi = imm; 00847 globalState.cycleCount += 8; 00848 } 00849 00850 void LD_C_n(u8 opocde) { // 0E 00851 u8 imm = readByte(++globalState.pc); 00852 globalState.pc++; 00853 globalState.bc.lo = imm; 00854 globalState.cycleCount += 8; 00855 } 00856 00857 void LD_D_n(u8 opocde) { // 16 00858 u8 imm = readByte(++globalState.pc); 00859 globalState.pc++; 00860 globalState.de.hi = imm; 00861 globalState.cycleCount += 8; 00862 } 00863 00864 void LD_E_n(u8 opocde) { // 1e 00865 u8 imm = readByte(++globalState.pc); 00866 globalState.pc++; 00867 globalState.de.lo = imm; 00868 globalState.cycleCount += 8; 00869 } 00870 00871 void LD_H_n(u8 opocde) { // 26 00872 u8 imm = readByte(++globalState.pc); 00873 globalState.pc++; 00874 globalState.hl.hi = imm; 00875 globalState.cycleCount += 8; 00876 } 00877 00878 void LD_L_n(u8 opocde) { // 2e 00879 u8 imm = readByte(++globalState.pc); 00880 globalState.pc++; 00881 globalState.hl.lo = imm; 00882 globalState.cycleCount += 8; 00883 } 00884 00885 // REGISTER-REGISTER LOADS (REGISTER A) 00886 void LD_A_A(u8 opcode) { // 0x7f 00887 globalState.pc++; 00888 globalState.cycleCount += 4; 00889 globalState.a = globalState.a; 00890 } 00891 00892 void LD_A_B(u8 opcode) { // 0x78 00893 globalState.pc++; 00894 globalState.cycleCount += 4; 00895 globalState.a = globalState.bc.hi; 00896 } 00897 00898 void LD_A_C(u8 opcode) { // 0x79 00899 globalState.pc++; 00900 globalState.cycleCount += 4; 00901 globalState.a = globalState.bc.lo; 00902 } 00903 00904 void LD_A_D(u8 opcode) { // 0x7a 00905 globalState.pc++; 00906 globalState.cycleCount += 4; 00907 globalState.a = globalState.de.hi; 00908 } 00909 00910 void LD_A_E(u8 opcode) { // 0x7b 00911 globalState.pc++; 00912 globalState.cycleCount += 4; 00913 globalState.a = globalState.de.lo; 00914 } 00915 00916 void LD_A_H(u8 opcode) { // 0x7c 00917 globalState.pc++; 00918 globalState.cycleCount += 4; 00919 globalState.a = globalState.hl.hi; 00920 } 00921 00922 void LD_A_L(u8 opcode) { // 0x7d 00923 globalState.pc++; 00924 globalState.cycleCount += 4; 00925 globalState.a = globalState.hl.lo; 00926 } 00927 00928 void LD_A_DHL(u8 opcode) { // 0x7e 00929 globalState.pc++; 00930 globalState.cycleCount += 8; 00931 globalState.a = readByte(globalState.hl.v); 00932 } 00933 00934 00935 00936 // REGISTER-REGISTER LOADS (REGISTER B) 00937 void LD_B_B(u8 opcode) { // 0x40 00938 globalState.pc++; 00939 globalState.cycleCount += 4; 00940 globalState.bc.hi = globalState.bc.hi; 00941 } 00942 00943 void LD_B_C(u8 opcode) { // 0x41 00944 globalState.pc++; 00945 globalState.cycleCount += 4; 00946 globalState.bc.hi = globalState.bc.lo; 00947 } 00948 00949 void LD_B_D(u8 opcode) { // 0x42 00950 globalState.pc++; 00951 globalState.cycleCount += 4; 00952 globalState.bc.hi = globalState.de.hi; 00953 } 00954 00955 void LD_B_E(u8 opcode) { // 0x43 00956 globalState.pc++; 00957 globalState.cycleCount += 4; 00958 globalState.bc.hi = globalState.de.lo; 00959 } 00960 00961 void LD_B_H(u8 opcode) { // 0x44 00962 globalState.pc++; 00963 globalState.cycleCount += 4; 00964 globalState.bc.hi = globalState.hl.hi; 00965 } 00966 00967 void LD_B_L(u8 opcode) { // 0x45 00968 globalState.pc++; 00969 globalState.cycleCount += 4; 00970 globalState.bc.hi = globalState.hl.lo; 00971 } 00972 00973 void LD_B_DHL(u8 opcode) { // 0x46 00974 globalState.pc++; 00975 globalState.cycleCount += 8; 00976 globalState.bc.hi = readByte(globalState.hl.v); 00977 } 00978 00979 00980 00981 // REGISTER-REGISTER LOADS (REGISTER C) 00982 void LD_C_B(u8 opcode) { // 0x48 00983 globalState.pc++; 00984 globalState.cycleCount += 4; 00985 globalState.bc.lo = globalState.bc.hi; 00986 } 00987 00988 void LD_C_C(u8 opcode) { // 0x49 00989 globalState.pc++; 00990 globalState.cycleCount += 4; 00991 globalState.bc.lo = globalState.bc.lo; 00992 } 00993 00994 void LD_C_D(u8 opcode) { // 0x4a 00995 globalState.pc++; 00996 globalState.cycleCount += 4; 00997 globalState.bc.lo = globalState.de.hi; 00998 } 00999 01000 void LD_C_E(u8 opcode) { // 0x4b 01001 globalState.pc++; 01002 globalState.cycleCount += 4; 01003 globalState.bc.lo = globalState.de.lo; 01004 } 01005 01006 void LD_C_H(u8 opcode) { // 0x4c 01007 globalState.pc++; 01008 globalState.cycleCount += 4; 01009 globalState.bc.lo = globalState.hl.hi; 01010 } 01011 01012 void LD_C_L(u8 opcode) { // 0x4d 01013 globalState.pc++; 01014 globalState.cycleCount += 4; 01015 globalState.bc.lo = globalState.hl.lo; 01016 } 01017 01018 void LD_C_DHL(u8 opcode) { // 0x4e 01019 globalState.pc++; 01020 globalState.cycleCount += 8; 01021 globalState.bc.lo = readByte(globalState.hl.v); 01022 } 01023 01024 01025 01026 // REGISTER-REGISTER LOADS (REGISTER D) 01027 void LD_D_B(u8 opcode) { // 0x50 01028 globalState.pc++; 01029 globalState.cycleCount += 4; 01030 globalState.de.hi = globalState.bc.hi; 01031 } 01032 01033 void LD_D_C(u8 opcode) { // 0x51 01034 globalState.pc++; 01035 globalState.cycleCount += 4; 01036 globalState.de.hi = globalState.bc.lo; 01037 } 01038 01039 void LD_D_D(u8 opcode) { // 0x52 01040 globalState.pc++; 01041 globalState.cycleCount += 4; 01042 globalState.de.hi = globalState.de.hi; 01043 } 01044 01045 void LD_D_E(u8 opcode) { // 0x53 01046 globalState.pc++; 01047 globalState.cycleCount += 4; 01048 globalState.de.hi = globalState.de.lo; 01049 } 01050 01051 void LD_D_H(u8 opcode) { // 0x54 01052 globalState.pc++; 01053 globalState.cycleCount += 4; 01054 globalState.de.hi = globalState.hl.hi; 01055 } 01056 01057 void LD_D_L(u8 opcode) { // 0x55 01058 globalState.pc++; 01059 globalState.cycleCount += 4; 01060 globalState.de.hi = globalState.hl.lo; 01061 } 01062 01063 void LD_D_DHL(u8 opcode) { // 0x56 01064 globalState.pc++; 01065 globalState.cycleCount += 8; 01066 globalState.de.hi = readByte(globalState.hl.v); 01067 } 01068 01069 01070 // REGISTER-REGISTER LOADS (REGISTER E) 01071 void LD_E_B(u8 opcode) { // 0x58 01072 globalState.pc++; 01073 globalState.cycleCount += 4; 01074 globalState.de.lo = globalState.bc.hi; 01075 } 01076 01077 void LD_E_C(u8 opcode) { // 0x59 01078 globalState.pc++; 01079 globalState.cycleCount += 4; 01080 globalState.de.lo = globalState.bc.lo; 01081 } 01082 01083 void LD_E_D(u8 opcode) { // 0x5a 01084 globalState.pc++; 01085 globalState.cycleCount += 4; 01086 globalState.de.lo = globalState.de.hi; 01087 } 01088 01089 void LD_E_E(u8 opcode) { // 0x5b 01090 globalState.pc++; 01091 globalState.cycleCount += 4; 01092 globalState.de.lo = globalState.de.lo; 01093 } 01094 01095 void LD_E_H(u8 opcode) { // 0x5c 01096 globalState.pc++; 01097 globalState.cycleCount += 4; 01098 globalState.de.lo = globalState.hl.hi; 01099 } 01100 01101 void LD_E_L(u8 opcode) { // 0x5d 01102 globalState.pc++; 01103 globalState.cycleCount += 4; 01104 globalState.de.lo = globalState.hl.lo; 01105 } 01106 01107 void LD_E_DHL(u8 opcode) { // 0x5e 01108 globalState.pc++; 01109 globalState.cycleCount += 8; 01110 globalState.de.lo = readByte(globalState.hl.v); 01111 } 01112 01113 // REGISTER-REGISTER LOADS (REGISTER H) 01114 void LD_H_B(u8 opcode) { // 0x60 01115 globalState.pc++; 01116 globalState.cycleCount += 4; 01117 globalState.hl.hi = globalState.bc.hi; 01118 } 01119 01120 void LD_H_C(u8 opcode) { // 0x61 01121 globalState.pc++; 01122 globalState.cycleCount += 4; 01123 globalState.hl.hi = globalState.bc.lo; 01124 } 01125 01126 void LD_H_D(u8 opcode) { // 0x62 01127 globalState.pc++; 01128 globalState.cycleCount += 4; 01129 globalState.hl.hi = globalState.de.hi; 01130 } 01131 01132 void LD_H_E(u8 opcode) { // 0x63 01133 globalState.pc++; 01134 globalState.cycleCount += 4; 01135 globalState.hl.hi = globalState.de.lo; 01136 } 01137 01138 void LD_H_H(u8 opcode) { // 0x64 01139 globalState.pc++; 01140 globalState.cycleCount += 4; 01141 globalState.hl.hi = globalState.hl.hi; 01142 } 01143 01144 void LD_H_L(u8 opcode) { // 0x65 01145 globalState.pc++; 01146 globalState.cycleCount += 4; 01147 globalState.hl.hi = globalState.hl.lo; 01148 } 01149 01150 void LD_H_DHL(u8 opcode) { // 0x66 01151 globalState.pc++; 01152 globalState.cycleCount += 8; 01153 globalState.hl.hi = readByte(globalState.hl.v); 01154 } 01155 01156 // REGISTER-REGISTER LOADS (REGISTER L) 01157 void LD_L_B(u8 opcode) { // 0x60 01158 globalState.pc++; 01159 globalState.cycleCount += 4; 01160 globalState.hl.lo = globalState.bc.hi; 01161 } 01162 01163 void LD_L_C(u8 opcode) { // 0x61 01164 globalState.pc++; 01165 globalState.cycleCount += 4; 01166 globalState.hl.lo = globalState.bc.lo; 01167 } 01168 01169 void LD_L_D(u8 opcode) { // 0x62 01170 globalState.pc++; 01171 globalState.cycleCount += 4; 01172 globalState.hl.lo = globalState.de.hi; 01173 } 01174 01175 void LD_L_E(u8 opcode) { // 0x63 01176 globalState.pc++; 01177 globalState.cycleCount += 4; 01178 globalState.hl.lo = globalState.de.lo; 01179 } 01180 01181 void LD_L_H(u8 opcode) { // 0x64 01182 globalState.pc++; 01183 globalState.cycleCount += 4; 01184 globalState.hl.lo = globalState.hl.hi; 01185 } 01186 01187 void LD_L_L(u8 opcode) { // 0x65 01188 globalState.pc++; 01189 globalState.cycleCount += 4; 01190 globalState.hl.lo = globalState.hl.lo; 01191 } 01192 01193 void LD_L_DHL(u8 opcode) { // 0x66 01194 globalState.pc++; 01195 globalState.cycleCount += 8; 01196 globalState.hl.lo = readByte(globalState.hl.v); 01197 } 01198 01199 // REGISTER-REGISTER LOADS (REGISTER (HL)) 01200 void LD_DHL_B(u8 opcode) { // 0x70 01201 globalState.pc++; 01202 globalState.cycleCount += 8; 01203 writeByte(globalState.bc.hi, globalState.hl.v); 01204 } 01205 01206 void LD_DHL_C(u8 opcode) { // 0x71 01207 globalState.pc++; 01208 globalState.cycleCount += 8; 01209 writeByte(globalState.bc.lo, globalState.hl.v); 01210 } 01211 01212 void LD_DHL_D(u8 opcode) { // 0x72 01213 globalState.pc++; 01214 globalState.cycleCount += 8; 01215 writeByte(globalState.de.hi, globalState.hl.v); 01216 } 01217 01218 void LD_DHL_E(u8 opcode) { // 0x73 01219 globalState.pc++; 01220 globalState.cycleCount += 8; 01221 writeByte(globalState.de.lo, globalState.hl.v); 01222 } 01223 01224 void LD_DHL_H(u8 opcode) { // 0x74 01225 globalState.pc++; 01226 globalState.cycleCount += 8; 01227 writeByte(globalState.hl.hi, globalState.hl.v); 01228 } 01229 01230 void LD_DHL_L(u8 opcode) { // 0x75 01231 globalState.pc++; 01232 globalState.cycleCount += 8; 01233 writeByte(globalState.hl.lo, globalState.hl.v); 01234 } 01235 01236 // Random 01237 void LD_DHL_n(u8 opcode) { // 0x36 01238 u8 imm = readByte(++globalState.pc); 01239 globalState.pc++; 01240 globalState.cycleCount += 12; 01241 writeByte(imm, globalState.hl.v); 01242 } 01243 01244 // Load Into Register A Specials 01245 void LD_A_DBC(u8 opcode) { // 0A 01246 globalState.pc++; 01247 globalState.cycleCount += 8; 01248 globalState.a = readByte(globalState.bc.v); 01249 } 01250 01251 void LD_A_DDE(u8 opcode) { // 1A 01252 globalState.pc++; 01253 globalState.cycleCount += 8; 01254 globalState.a = readByte(globalState.de.v); 01255 } 01256 01257 01258 void LD_A_Dnn(u8 opcode) { // FA 01259 globalState.pc++; 01260 globalState.cycleCount += 16; 01261 globalState.a = readByte(readU16(globalState.pc)); 01262 globalState.pc += 2; 01263 } 01264 01265 void LD_A_n(u8 opocde) { // 0x3e 01266 u8 imm = readByte(++globalState.pc); 01267 globalState.pc++; 01268 globalState.a = imm; 01269 globalState.cycleCount += 8; 01270 } 01271 01272 // LOAD FROM REGISTER A 01273 void LD_B_A(u8 opcode) { // 0x47 01274 globalState.pc++; 01275 globalState.cycleCount += 4; 01276 globalState.bc.hi = globalState.a; 01277 } 01278 01279 void LD_C_A(u8 opcode) { // 0x4f 01280 globalState.pc++; 01281 globalState.cycleCount += 4; 01282 globalState.bc.lo = globalState.a; 01283 } 01284 01285 void LD_D_A(u8 opcode) { // 0x57 01286 globalState.pc++; 01287 globalState.cycleCount += 4; 01288 globalState.de.hi = globalState.a; 01289 } 01290 01291 void LD_E_A(u8 opcode) { // 0x5f 01292 globalState.pc++; 01293 globalState.cycleCount += 4; 01294 globalState.de.lo = globalState.a; 01295 } 01296 01297 void LD_H_A(u8 opcode) { // 0x67 01298 globalState.pc++; 01299 globalState.cycleCount += 4; 01300 globalState.hl.hi = globalState.a; 01301 } 01302 01303 void LD_L_A(u8 opcode) { // 0x6f 01304 globalState.pc++; 01305 globalState.cycleCount += 4; 01306 globalState.hl.lo = globalState.a; 01307 } 01308 01309 void LD_DBC_A(u8 opcode) { // 0x02 01310 globalState.pc++; 01311 globalState.cycleCount += 8; 01312 writeByte(globalState.a, globalState.bc.v); 01313 } 01314 01315 void LD_DDE_A(u8 opcode) { // 0x12 01316 globalState.pc++; 01317 globalState.cycleCount += 8; 01318 writeByte(globalState.a, globalState.de.v); 01319 } 01320 01321 void LD_DHL_A(u8 opcode) { // 0x77 01322 globalState.pc++; 01323 globalState.cycleCount += 8; 01324 writeByte(globalState.a, globalState.hl.v); 01325 } 01326 01327 void LD_Dnn_A(u8 opcode) { // 0xea 01328 globalState.pc++; 01329 globalState.cycleCount += 16; 01330 writeByte(globalState.a, readU16(globalState.pc)); 01331 globalState.pc += 2; 01332 } 01333 01334 // Load A with memory offset from 0xff00 01335 void LD_A_FF00_C(u8 opcode) { //0xf2 01336 globalState.pc++; 01337 globalState.cycleCount += 8; 01338 globalState.a = readByte((u16)0xff00 + globalState.bc.lo); 01339 } 01340 01341 // Store A with memory offset from 0xff00 01342 void LD_FF00_C_A(u8 opcode) { // 0xe2 01343 globalState.pc++; 01344 writeByte(globalState.a, (u16)0xff00 + globalState.bc.lo); 01345 globalState.cycleCount += 8; 01346 } 01347 01348 // Load (HL) into A, decrement HL 01349 void LDD_A_DHL(u8 opcode) { // 0x3a 01350 globalState.pc++; 01351 globalState.cycleCount += 8; 01352 globalState.a = readByte(globalState.hl.v); 01353 globalState.hl.v--; 01354 } 01355 01356 // Load A into (HL), decrement HL 01357 void LDD_DHL_A(u8 opcode) { // 0x32 01358 writeByte(globalState.a, globalState.hl.v); 01359 globalState.hl.v--; 01360 globalState.pc += 1; 01361 globalState.cycleCount += 8; 01362 } 01363 01364 // Load (HL) into A, increment HL 01365 void LDI_A_DHL(u8 opcode){ // 0x2a 01366 globalState.pc += 1; 01367 globalState.cycleCount += 8; 01368 globalState.a = readByte(globalState.hl.v); 01369 globalState.hl.v++; 01370 } 01371 01372 // Load A into (HL), increment HL 01373 void LDI_DHL_A(u8 opcode) { // 0x22 01374 writeByte(globalState.a, globalState.hl.v); 01375 globalState.hl.v++; 01376 globalState.pc += 1; 01377 globalState.cycleCount += 8; 01378 } 01379 // page 75 01380 01381 // Store A into FF00 + n 01382 void LD_FF00_n_A(u8 opcode) { //0xe0 01383 u8 imm = readByte(++globalState.pc); 01384 globalState.pc++; 01385 writeByte(globalState.a, (u16)0xff00 + imm); 01386 globalState.cycleCount += 12; 01387 } 01388 01389 // Load A with FF00 + n 01390 void LD_A_FF00_n(u8 opcode) { // 0xf0 01391 u8 imm = readByte(++globalState.pc); 01392 globalState.pc++; 01393 globalState.a = readByte((u16)0xff00 + imm); 01394 globalState.cycleCount += 12; 01395 } 01396 01397 // 16-bit loads 01398 void LD_BC_nn(u8 opcode) { // 0x01 01399 u16 imm = readU16(globalState.pc + (u16)1); 01400 globalState.bc.v = imm; 01401 globalState.pc += 3; 01402 globalState.cycleCount += 12; 01403 } 01404 01405 void LD_DE_nn(u8 opcode) { // 0x11 01406 u16 imm = readU16(globalState.pc + (u16)1); 01407 globalState.de.v = imm; 01408 globalState.pc += 3; 01409 globalState.cycleCount += 12; 01410 } 01411 01412 void LD_HL_nn(u8 opcode) { // 0x21 01413 u16 imm = readU16(globalState.pc + (u16)1); 01414 globalState.hl.v = imm; 01415 globalState.pc += 3; 01416 globalState.cycleCount += 12; 01417 } 01418 01419 void LD_SP_nn(u8 opcode) { // 0x31 01420 u16 imm = readU16(globalState.pc + (u16)1); 01421 globalState.sp = imm; 01422 globalState.pc += 3; 01423 globalState.cycleCount += 12; 01424 } 01425 01426 void LD_SP_HL(u8 opcode) { // 0xf9 01427 globalState.sp = globalState.hl.v; 01428 globalState.pc++; 01429 globalState.cycleCount += 8; 01430 } 01431 01432 // load effective address relative to stack pointer 01433 void LD_HL_SP_n(u8 opcode) { //0xf8 01434 globalState.pc++; 01435 globalState.cycleCount += 12; 01436 s8 imm = readByte(globalState.pc); 01437 globalState.pc++; 01438 clearAllFlags(); 01439 u16 result = globalState.sp + imm; 01440 if(((globalState.sp ^ imm ^ result) & 0x100) == 0x100) { 01441 setCarryFlag(); 01442 } 01443 if(((globalState.sp ^ imm ^ result) & 0x10) == 0x10) { 01444 setHalfCarryFlag(); 01445 } 01446 globalState.hl.v = result; 01447 } 01448 01449 // store stack pointer 01450 void LD_Dnn_SP(u8 opcode) { // 08 01451 globalState.pc++; 01452 u16 addr = readU16(globalState.pc); 01453 globalState.pc+=2; 01454 globalState.cycleCount += 20; 01455 writeU16(globalState.sp, addr); 01456 } 01457 01458 // push U16 register onto stack 01459 void PUSH_AF(u8 opcode) { // 0xf5 01460 globalState.pc++; 01461 globalState.cycleCount += 16; 01462 writeU16(globalState.f + (((u16)globalState.a) << 8), globalState.sp - (u16)2); 01463 globalState.sp -= 2; 01464 } 01465 01466 void PUSH_BC(u8 opcode) { // 0xc5 01467 globalState.pc++; 01468 globalState.cycleCount += 16; 01469 writeU16(globalState.bc.v, globalState.sp - (u16)2); 01470 globalState.sp -= 2; 01471 } 01472 01473 void PUSH_DE(u8 opcode) { // 0xd5 01474 globalState.pc++; 01475 globalState.cycleCount += 16; 01476 writeU16(globalState.de.v, globalState.sp - (u16)2); 01477 globalState.sp -= 2; 01478 } 01479 01480 void PUSH_HL(u8 opcode) { // 0xe5 01481 globalState.pc++; 01482 globalState.cycleCount += 16; 01483 writeU16(globalState.hl.v, globalState.sp - (u16)2); 01484 globalState.sp -= 2; 01485 } 01486 01487 // POP U16 register from stack 01488 void POP_AF(u8 opcode) { // 0xf1 01489 globalState.pc++; 01490 globalState.cycleCount += 12; 01491 u16 v = readU16(globalState.sp); 01492 globalState.sp += 2; 01493 globalState.a = (u8)(v >> 8); 01494 globalState.f = (u8)(v & 0xf0); 01495 } 01496 01497 void POP_BC(u8 opcode) { // 0xc1 01498 globalState.pc++; 01499 globalState.cycleCount += 12; 01500 u16 v = readU16(globalState.sp); 01501 globalState.sp += 2; 01502 globalState.bc.v = v; 01503 } 01504 01505 void POP_DE(u8 opcode) { // 0xd1 01506 globalState.pc++; 01507 globalState.cycleCount += 12; 01508 u16 v = readU16(globalState.sp); 01509 globalState.sp += 2; 01510 globalState.de.v = v; 01511 } 01512 01513 void POP_HL(u8 opcode) { // 0xe1 01514 globalState.pc++; 01515 globalState.cycleCount += 12; 01516 u16 v = readU16(globalState.sp); 01517 globalState.sp += 2; 01518 globalState.hl.v = v; 01519 } 01520 01521 void addToA(u8 number) { 01522 int result = globalState.a + number; 01523 int carryBits = globalState.a ^ number ^ result; 01524 globalState.a = (u8)result; 01525 clearAllFlags(); 01526 01527 if((u8)result == 0){ 01528 setZeroFlag(); 01529 } 01530 01531 if((carryBits & 0x100) != 0) { 01532 setCarryFlag(); 01533 } 01534 if((carryBits & 0x10) != 0) { 01535 setHalfCarryFlag(); 01536 } 01537 } 01538 01539 // ADD Opcodes 01540 void ADD_A(u8 opcode) { // 0x87 01541 globalState.pc++; 01542 globalState.cycleCount += 4; 01543 addToA(globalState.a); 01544 } 01545 01546 void ADD_B(u8 opcode) { // 0x80 01547 globalState.pc++; 01548 globalState.cycleCount += 4; 01549 addToA(globalState.bc.hi); 01550 } 01551 01552 void ADD_C(u8 opcode) { // 0x81 01553 globalState.pc++; 01554 globalState.cycleCount += 4; 01555 addToA(globalState.bc.lo); 01556 } 01557 01558 void ADD_D(u8 opcode) { // 0x82 01559 globalState.pc++; 01560 globalState.cycleCount += 4; 01561 addToA(globalState.de.hi); 01562 } 01563 01564 void ADD_E(u8 opcode) { // 0x83 01565 globalState.pc++; 01566 globalState.cycleCount += 4; 01567 addToA(globalState.de.lo); 01568 } 01569 01570 void ADD_H(u8 opcode) { // 0x84 01571 globalState.pc++; 01572 globalState.cycleCount += 4; 01573 addToA(globalState.hl.hi); 01574 } 01575 01576 void ADD_L(u8 opcode) { // 0x85 01577 globalState.pc++; 01578 globalState.cycleCount += 4; 01579 addToA(globalState.hl.lo); 01580 } 01581 01582 void ADD_DHL(u8 opcode) { // 0x86 01583 globalState.pc++; 01584 globalState.cycleCount += 8; 01585 addToA(readByte(globalState.hl.v)); 01586 } 01587 01588 void ADD_n(u8 opcode) { // 0xC6 01589 u8 imm = readByte(++globalState.pc); 01590 globalState.pc++; 01591 globalState.cycleCount += 8; 01592 addToA(imm); 01593 } 01594 01595 void adcToA(u8 number) { 01596 int carry = getCarryFlag() ? 1 : 0; 01597 int result = globalState.a + number + carry; 01598 clearAllFlags(); 01599 if((u8)result == 0) { 01600 setZeroFlag(); 01601 } 01602 if(result > 0xff) { 01603 setCarryFlag(); 01604 } 01605 if(((globalState.a & 0xf) + (number & 0xf) + carry) > 0xf) { 01606 setHalfCarryFlag(); 01607 } 01608 globalState.a = (u8) result; 01609 } 01610 01611 // ADC Opcodes 01612 void ADC_A(u8 opcode) { // 0x8f 01613 globalState.pc++; 01614 globalState.cycleCount += 4; 01615 adcToA(globalState.a); 01616 } 01617 01618 void ADC_B(u8 opcode) { // 0x88 01619 globalState.pc++; 01620 globalState.cycleCount += 4; 01621 adcToA(globalState.bc.hi); 01622 } 01623 01624 void ADC_C(u8 opcode) { // 0x89 01625 globalState.pc++; 01626 globalState.cycleCount += 4; 01627 adcToA(globalState.bc.lo); 01628 } 01629 01630 void ADC_D(u8 opcode) { // 0x8a 01631 globalState.pc++; 01632 globalState.cycleCount += 4; 01633 adcToA(globalState.de.hi); 01634 } 01635 01636 void ADC_E(u8 opcode) { // 0x8b 01637 globalState.pc++; 01638 globalState.cycleCount += 4; 01639 adcToA(globalState.de.lo); 01640 } 01641 01642 void ADC_H(u8 opcode) { // 0x8c 01643 globalState.pc++; 01644 globalState.cycleCount += 4; 01645 adcToA(globalState.hl.hi); 01646 } 01647 01648 void ADC_L(u8 opcode) { // 0x8d 01649 globalState.pc++; 01650 globalState.cycleCount += 4; 01651 adcToA(globalState.hl.lo); 01652 } 01653 01654 void ADC_DHL(u8 opcode) { // 0x8e 01655 globalState.pc++; 01656 globalState.cycleCount += 8; 01657 adcToA(readByte(globalState.hl.v)); 01658 } 01659 01660 void ADC_n(u8 opcode) { // 0xCe 01661 u8 imm = readByte(++globalState.pc); 01662 globalState.pc++; 01663 globalState.cycleCount += 8; 01664 adcToA(imm); 01665 } 01666 01667 void subToA(u8 number) { 01668 int result = globalState.a - number; 01669 int carryBits = globalState.a ^ number ^ result; 01670 globalState.a = (u8)result; 01671 clearAllFlags(); 01672 setSubtractFlag(); 01673 if((u8)result == 0) { 01674 setZeroFlag(); 01675 } 01676 if((carryBits & 0x100) != 0) { 01677 setCarryFlag(); 01678 } 01679 if((carryBits & 0x10) != 0) { 01680 setHalfCarryFlag(); 01681 } 01682 } 01683 01684 // SUB Opcodes 01685 void SUB_A(u8 opcode) { // 0x97 01686 globalState.pc++; 01687 globalState.cycleCount += 4; 01688 subToA(globalState.a); 01689 } 01690 01691 void SUB_B(u8 opcode) { // 0x90 01692 globalState.pc++; 01693 globalState.cycleCount += 4; 01694 subToA(globalState.bc.hi); 01695 } 01696 01697 void SUB_C(u8 opcode) { // 0x91 01698 globalState.pc++; 01699 globalState.cycleCount += 4; 01700 subToA(globalState.bc.lo); 01701 } 01702 01703 void SUB_D(u8 opcode) { // 0x92 01704 globalState.pc++; 01705 globalState.cycleCount += 4; 01706 subToA(globalState.de.hi); 01707 } 01708 01709 void SUB_E(u8 opcode) { // 0x93 01710 globalState.pc++; 01711 globalState.cycleCount += 4; 01712 subToA(globalState.de.lo); 01713 } 01714 01715 void SUB_H(u8 opcode) { // 0x94 01716 globalState.pc++; 01717 globalState.cycleCount += 4; 01718 subToA(globalState.hl.hi); 01719 } 01720 01721 void SUB_L(u8 opcode) { // 0x95 01722 globalState.pc++; 01723 globalState.cycleCount += 4; 01724 subToA(globalState.hl.lo); 01725 } 01726 01727 void SUB_DHL(u8 opcode) { // 0x96 01728 globalState.pc++; 01729 globalState.cycleCount += 8; 01730 subToA(readByte(globalState.hl.v)); 01731 } 01732 01733 void SUB_n(u8 opcode) { // 0xD6 01734 u8 imm = readByte(++globalState.pc); 01735 globalState.pc++; 01736 globalState.cycleCount += 8; 01737 subToA(imm); 01738 } 01739 01740 void sbcToA(u8 number) { 01741 int carry = getCarryFlag() ? 1 : 0; 01742 int result = globalState.a - number - carry; 01743 clearAllFlags(); 01744 setSubtractFlag(); 01745 if((u8)result == 0) { 01746 setZeroFlag(); 01747 } 01748 if(result < 0) { 01749 setCarryFlag(); 01750 } 01751 if(((globalState.a & 0xf) - (number & 0xf) - carry) < 0) { 01752 setHalfCarryFlag(); 01753 } 01754 globalState.a = (u8)result; 01755 } 01756 01757 // SBC Opcodes 01758 void SBC_A(u8 opcode) { // 0x9f 01759 globalState.pc++; 01760 globalState.cycleCount += 4; 01761 sbcToA(globalState.a); 01762 } 01763 01764 void SBC_B(u8 opcode) { // 0x98 01765 globalState.pc++; 01766 globalState.cycleCount += 4; 01767 sbcToA(globalState.bc.hi); 01768 } 01769 01770 void SBC_C(u8 opcode) { // 0x99 01771 globalState.pc++; 01772 globalState.cycleCount += 4; 01773 sbcToA(globalState.bc.lo); 01774 } 01775 01776 void SBC_D(u8 opcode) { // 0x9a 01777 globalState.pc++; 01778 globalState.cycleCount += 4; 01779 sbcToA(globalState.de.hi); 01780 } 01781 01782 void SBC_E(u8 opcode) { // 0x9b 01783 globalState.pc++; 01784 globalState.cycleCount += 4; 01785 sbcToA(globalState.de.lo); 01786 } 01787 01788 void SBC_H(u8 opcode) { // 0x9c 01789 globalState.pc++; 01790 globalState.cycleCount += 4; 01791 sbcToA(globalState.hl.hi); 01792 } 01793 01794 void SBC_L(u8 opcode) { // 0x9d 01795 globalState.pc++; 01796 globalState.cycleCount += 4; 01797 sbcToA(globalState.hl.lo); 01798 } 01799 01800 void SBC_DHL(u8 opcode) { // 0x9e 01801 globalState.pc++; 01802 globalState.cycleCount += 8; 01803 sbcToA(readByte(globalState.hl.v)); 01804 } 01805 01806 void SBC_n(u8 opcode) { // 0xDe 01807 u8 imm = readByte(++globalState.pc); 01808 globalState.pc++; 01809 globalState.cycleCount += 8; 01810 sbcToA(imm); 01811 } 01812 01813 void andtoA(u8 number) { 01814 u8 result = globalState.a & number; 01815 globalState.a = result; 01816 clearAllFlags(); 01817 setHalfCarryFlag(); 01818 if((u8)result == 0) { 01819 setZeroFlag(); 01820 } 01821 } 01822 01823 // AND Opcodes 01824 void AND_A(u8 opcode) { // 0xa7 01825 globalState.pc++; 01826 globalState.cycleCount += 4; 01827 andtoA(globalState.a); 01828 } 01829 01830 void AND_B(u8 opcode) { // 0xa0 01831 globalState.pc++; 01832 globalState.cycleCount += 4; 01833 andtoA(globalState.bc.hi); 01834 } 01835 01836 void AND_C(u8 opcode) { // 0xa1 01837 globalState.pc++; 01838 globalState.cycleCount += 4; 01839 andtoA(globalState.bc.lo); 01840 } 01841 01842 void AND_D(u8 opcode) { // 0xa2 01843 globalState.pc++; 01844 globalState.cycleCount += 4; 01845 andtoA(globalState.de.hi); 01846 } 01847 01848 void AND_E(u8 opcode) { // 0xa3 01849 globalState.pc++; 01850 globalState.cycleCount += 4; 01851 andtoA(globalState.de.lo); 01852 } 01853 01854 void AND_H(u8 opcode) { // 0xa4 01855 globalState.pc++; 01856 globalState.cycleCount += 4; 01857 andtoA(globalState.hl.hi); 01858 } 01859 01860 void AND_L(u8 opcode) { // 0xa5 01861 globalState.pc++; 01862 globalState.cycleCount += 4; 01863 andtoA(globalState.hl.lo); 01864 } 01865 01866 void AND_DHL(u8 opcode) { // 0xa6 01867 globalState.pc++; 01868 globalState.cycleCount += 8; 01869 andtoA(readByte(globalState.hl.v)); 01870 } 01871 01872 void AND_n(u8 opcode) { // 0xe6 01873 u8 imm = readByte(++globalState.pc); 01874 globalState.pc++; 01875 globalState.cycleCount += 8; 01876 andtoA(imm); 01877 } 01878 01879 void xorToA(u8 number) { 01880 u8 result = globalState.a ^ number; 01881 globalState.a = result; 01882 clearAllFlags(); 01883 if((u8)result == 0) { 01884 setZeroFlag(); 01885 } 01886 } 01887 01888 // XOR Opcodes 01889 void XOR_A(u8 opcode) { // 0xaf 01890 globalState.pc++; 01891 globalState.cycleCount += 4; 01892 xorToA(globalState.a); 01893 } 01894 01895 void XOR_B(u8 opcode) { // 0xa8 01896 globalState.pc++; 01897 globalState.cycleCount += 4; 01898 xorToA(globalState.bc.hi); 01899 } 01900 01901 void XOR_C(u8 opcode) { // 0xa9 01902 globalState.pc++; 01903 globalState.cycleCount += 4; 01904 xorToA(globalState.bc.lo); 01905 } 01906 01907 void XOR_D(u8 opcode) { // 0xaa 01908 globalState.pc++; 01909 globalState.cycleCount += 4; 01910 xorToA(globalState.de.hi); 01911 } 01912 01913 void XOR_E(u8 opcode) { // 0xab 01914 globalState.pc++; 01915 globalState.cycleCount += 4; 01916 xorToA(globalState.de.lo); 01917 } 01918 01919 void XOR_H(u8 opcode) { // 0xac 01920 globalState.pc++; 01921 globalState.cycleCount += 4; 01922 xorToA(globalState.hl.hi); 01923 } 01924 01925 void XOR_L(u8 opcode) { // 0xad 01926 globalState.pc++; 01927 globalState.cycleCount += 4; 01928 xorToA(globalState.hl.lo); 01929 } 01930 01931 void XOR_DHL(u8 opcode) { // 0xae 01932 globalState.pc++; 01933 globalState.cycleCount += 8; 01934 xorToA(readByte(globalState.hl.v)); 01935 } 01936 01937 void XOR_n(u8 opcode) { // 0xee 01938 u8 imm = readByte(++globalState.pc); 01939 globalState.pc++; 01940 globalState.cycleCount += 8; 01941 xorToA(imm); 01942 } 01943 01944 void orToA(u8 number) { 01945 u8 result = globalState.a | number; 01946 globalState.a = result; 01947 clearAllFlags(); 01948 if((u8)result == 0) { 01949 setZeroFlag(); 01950 } 01951 } 01952 01953 // OR Opcodes 01954 void OR_A(u8 opcode) { // 0xb7 01955 globalState.pc++; 01956 globalState.cycleCount += 4; 01957 orToA(globalState.a); 01958 } 01959 01960 void OR_B(u8 opcode) { // 0xb0 01961 globalState.pc++; 01962 globalState.cycleCount += 4; 01963 orToA(globalState.bc.hi); 01964 } 01965 01966 void OR_C(u8 opcode) { // 0xb1 01967 globalState.pc++; 01968 globalState.cycleCount += 4; 01969 orToA(globalState.bc.lo); 01970 } 01971 01972 void OR_D(u8 opcode) { // 0xb2 01973 globalState.pc++; 01974 globalState.cycleCount += 4; 01975 orToA(globalState.de.hi); 01976 } 01977 01978 void OR_E(u8 opcode) { // 0xb3 01979 globalState.pc++; 01980 globalState.cycleCount += 4; 01981 orToA(globalState.de.lo); 01982 } 01983 01984 void OR_H(u8 opcode) { // 0xb4 01985 globalState.pc++; 01986 globalState.cycleCount += 4; 01987 orToA(globalState.hl.hi); 01988 } 01989 01990 void OR_L(u8 opcode) { // 0xb5 01991 globalState.pc++; 01992 globalState.cycleCount += 4; 01993 orToA(globalState.hl.lo); 01994 } 01995 01996 void OR_DHL(u8 opcode) { // 0xb6 01997 globalState.pc++; 01998 globalState.cycleCount += 8; 01999 orToA(readByte(globalState.hl.v)); 02000 } 02001 02002 void OR_n(u8 opcode) { // 0xf6 02003 u8 imm = readByte(++globalState.pc); 02004 globalState.pc++; 02005 globalState.cycleCount += 8; 02006 orToA(imm); 02007 } 02008 02009 void cpToA(u8 number) { 02010 clearAllFlags(); 02011 setSubtractFlag(); 02012 if(globalState.a < number) { 02013 setCarryFlag(); 02014 } 02015 if(globalState.a == number) { 02016 setZeroFlag(); 02017 } 02018 if(((globalState.a - number) & 0xf) > (globalState.a & 0xf)) { 02019 setHalfCarryFlag(); 02020 } 02021 } 02022 02023 // CP Opcodes 02024 void CP_A(u8 opcode) { // 0xbf 02025 globalState.pc++; 02026 globalState.cycleCount += 4; 02027 cpToA(globalState.a); 02028 } 02029 02030 void CP_B(u8 opcode) { // 0xb8 02031 globalState.pc++; 02032 globalState.cycleCount += 4; 02033 cpToA(globalState.bc.hi); 02034 } 02035 02036 void CP_C(u8 opcode) { // 0xb9 02037 globalState.pc++; 02038 globalState.cycleCount += 4; 02039 cpToA(globalState.bc.lo); 02040 } 02041 02042 void CP_D(u8 opcode) { // 0xba 02043 globalState.pc++; 02044 globalState.cycleCount += 4; 02045 cpToA(globalState.de.hi); 02046 } 02047 02048 void CP_E(u8 opcode) { // 0xbb 02049 globalState.pc++; 02050 globalState.cycleCount += 4; 02051 cpToA(globalState.de.lo); 02052 } 02053 02054 void CP_H(u8 opcode) { // 0xbc 02055 globalState.pc++; 02056 globalState.cycleCount += 4; 02057 cpToA(globalState.hl.hi); 02058 } 02059 02060 void CP_L(u8 opcode) { // 0xbd 02061 globalState.pc++; 02062 globalState.cycleCount += 4; 02063 cpToA(globalState.hl.lo); 02064 } 02065 02066 void CP_DHL(u8 opcode) { // 0xbe 02067 globalState.pc++; 02068 globalState.cycleCount += 8; 02069 cpToA(readByte(globalState.hl.v)); 02070 } 02071 02072 void CP_n(u8 opcode) { // 0xfe 02073 u8 imm = readByte(++globalState.pc); 02074 globalState.pc++; 02075 globalState.cycleCount += 8; 02076 cpToA(imm); 02077 } 02078 02079 void DecodeCB(u8 opcode) { 02080 globalState.pc += 1; 02081 u8 newOpcode = readByte(globalState.pc); 02082 opcode_cbs[newOpcode](newOpcode); 02083 } 02084 02085 u8 increment(u8 in) { 02086 u8 result = in + (u8)1; 02087 if(getCarryFlag()) { 02088 clearAllFlags(); 02089 setCarryFlag(); 02090 } else { 02091 clearAllFlags(); 02092 } 02093 if(result == 0) { 02094 setZeroFlag(); 02095 } 02096 if((result & 0x0f) == 0x00) { 02097 setHalfCarryFlag(); 02098 } 02099 return result; 02100 } 02101 02102 void INC_A(u8 opcode) { // 0x3c 02103 globalState.a = increment(globalState.a); 02104 globalState.pc++; 02105 globalState.cycleCount += 4; 02106 } 02107 02108 void INC_B(u8 opcode) { // 0x04 02109 globalState.bc.hi = increment(globalState.bc.hi); 02110 globalState.pc++; 02111 globalState.cycleCount += 4; 02112 } 02113 02114 void INC_C(u8 opcode) { // 0x0c 02115 globalState.bc.lo = increment(globalState.bc.lo); 02116 globalState.pc++; 02117 globalState.cycleCount += 4; 02118 } 02119 02120 void INC_D(u8 opcode) { // 0x14 02121 globalState.de.hi = increment(globalState.de.hi); 02122 globalState.pc++; 02123 globalState.cycleCount += 4; 02124 } 02125 02126 void INC_E(u8 opcode) { // 0x1c 02127 globalState.de.lo = increment(globalState.de.lo); 02128 globalState.pc++; 02129 globalState.cycleCount += 4; 02130 } 02131 02132 void INC_H(u8 opcode) { // 0x24 02133 globalState.hl.hi = increment(globalState.hl.hi); 02134 globalState.pc++; 02135 globalState.cycleCount += 4; 02136 } 02137 02138 void INC_L(u8 opcode) { // 0x2c 02139 globalState.hl.lo = increment(globalState.hl.lo); 02140 globalState.pc++; 02141 globalState.cycleCount += 4; 02142 } 02143 02144 void INC_DHL(u8 opcode) { // 0x34 02145 // todo this one is hard. 02146 u8 v = readByte(globalState.hl.v); 02147 writeByte(increment(v), globalState.hl.v); 02148 globalState.pc++; 02149 globalState.cycleCount += 12; 02150 } 02151 02152 u8 decrement(u8 in) { 02153 u8 result = in - (u8)1; 02154 if(getCarryFlag()) { 02155 clearAllFlags(); 02156 setCarryFlag(); 02157 } else { 02158 clearAllFlags(); 02159 } 02160 setSubtractFlag(); 02161 if(result == 0) { 02162 setZeroFlag(); 02163 } 02164 if((result & 0xf) == 0xf) { 02165 setHalfCarryFlag(); 02166 } 02167 return result; 02168 } 02169 02170 void DEC_A(u8 opcode) { // 0x3d 02171 globalState.a = decrement(globalState.a); 02172 globalState.pc++; 02173 globalState.cycleCount += 4; 02174 } 02175 02176 void DEC_B(u8 opcode) { // 0x05 02177 globalState.bc.hi = decrement(globalState.bc.hi); 02178 globalState.pc++; 02179 globalState.cycleCount += 4; 02180 } 02181 02182 void DEC_C(u8 opcode) { // 0x0d 02183 globalState.bc.lo = decrement(globalState.bc.lo); 02184 globalState.pc++; 02185 globalState.cycleCount += 4; 02186 } 02187 02188 void DEC_D(u8 opcode) { // 0x15 02189 globalState.de.hi = decrement(globalState.de.hi); 02190 globalState.pc++; 02191 globalState.cycleCount += 4; 02192 } 02193 02194 void DEC_E(u8 opcode) { // 0x1d 02195 globalState.de.lo = decrement(globalState.de.lo); 02196 globalState.pc++; 02197 globalState.cycleCount += 4; 02198 } 02199 02200 void DEC_H(u8 opcode) { // 0x25 02201 globalState.hl.hi = decrement(globalState.hl.hi); 02202 globalState.pc++; 02203 globalState.cycleCount += 4; 02204 } 02205 02206 void DEC_L(u8 opcode) { // 0x2d 02207 globalState.hl.lo = decrement(globalState.hl.lo); 02208 globalState.pc++; 02209 globalState.cycleCount += 4; 02210 } 02211 02212 void DEC_DHL(u8 opcode) { // 0x35 02213 // todo this one is hard. 02214 u8 v = readByte(globalState.hl.v); 02215 writeByte(decrement(v), globalState.hl.v); 02216 globalState.pc++; 02217 globalState.cycleCount += 12; 02218 } 02219 02220 void addToHl(u16 number) { 02221 int result = globalState.hl.v + number; 02222 if(getZeroFlag()) { 02223 clearAllFlags(); 02224 setZeroFlag(); 02225 } else { 02226 clearAllFlags(); 02227 } 02228 if(result & 0x10000) { 02229 setCarryFlag(); 02230 } 02231 if((globalState.hl.v ^ number ^ (result & 0xffff)) & 0x1000) { 02232 setHalfCarryFlag(); 02233 } 02234 globalState.hl.v = (u16)result; 02235 } 02236 02237 void ADD_HL_BC(u8 opcode) { // 09 02238 globalState.pc++; 02239 globalState.cycleCount += 8; 02240 addToHl(globalState.bc.v); 02241 } 02242 02243 void ADD_HL_DE(u8 opcode) { // 19 02244 globalState.pc++; 02245 globalState.cycleCount += 8; 02246 addToHl(globalState.de.v); 02247 } 02248 02249 void ADD_HL_HL(u8 opcode) { // 29 02250 globalState.pc++; 02251 globalState.cycleCount += 8; 02252 addToHl(globalState.hl.v); 02253 } 02254 02255 void ADD_HL_SP(u8 opcode) { // 39 02256 globalState.pc++; 02257 globalState.cycleCount += 8; 02258 addToHl(globalState.sp); 02259 } 02260 02261 void ADD_SP_n(u8 opcode) { // E8 02262 s8 number = readByte(++globalState.pc); 02263 globalState.pc++; 02264 globalState.cycleCount += 16; 02265 int result = globalState.sp + number; 02266 clearAllFlags(); 02267 if(((globalState.sp ^ number ^ (result & 0xffff)) & 0x100) == 0x100) { 02268 setCarryFlag(); 02269 } 02270 if(((globalState.sp ^ number ^ (result & 0xffff)) & 0x10) == 0x10) { 02271 setHalfCarryFlag(); 02272 } 02273 globalState.sp = (u16)result; 02274 } 02275 02276 // 16 bit incs 02277 void INC_BC(u8 opcode) { // 03 02278 globalState.pc++; 02279 globalState.cycleCount += 8; 02280 globalState.bc.v++; 02281 } 02282 02283 void INC_DE(u8 opcode) { // 13 02284 globalState.pc++; 02285 globalState.cycleCount += 8; 02286 globalState.de.v++; 02287 } 02288 02289 void INC_HL(u8 opcode) { // 23 02290 globalState.pc++; 02291 globalState.cycleCount += 8; 02292 globalState.hl.v++; 02293 } 02294 02295 void INC_SP(u8 opcode) { // 33 02296 globalState.pc++; 02297 globalState.cycleCount += 8; 02298 globalState.sp++; 02299 } 02300 02301 // 16 bit decs 02302 void DEC_BC(u8 opcode) { // 0B 02303 globalState.pc++; 02304 globalState.cycleCount += 8; 02305 globalState.bc.v--; 02306 } 02307 02308 void DEC_DE(u8 opcode) { // 1B 02309 globalState.pc++; 02310 globalState.cycleCount += 8; 02311 globalState.de.v--; 02312 } 02313 02314 void DEC_HL(u8 opcode) { // 2B 02315 globalState.pc++; 02316 globalState.cycleCount += 8; 02317 globalState.hl.v--; 02318 } 02319 02320 void DEC_SP(u8 opcode) { // 3B 02321 globalState.pc++; 02322 globalState.cycleCount += 8; 02323 globalState.sp--; 02324 } 02325 02326 void DAA(u8 opcode) { // 0x27 02327 globalState.pc++; 02328 globalState.cycleCount += 4; 02329 u8 a = globalState.a; 02330 02331 if(!getSubtractFlag()) { 02332 if(getCarryFlag() || a > 0x99) { 02333 a += 0x60; 02334 setCarryFlag(); 02335 } 02336 if(getHalfCarryFlag() || (a & 0x0f) > 0x09) { 02337 a += 0x6; 02338 } 02339 } else { 02340 if(getCarryFlag()) { 02341 a -= 0x60; 02342 } 02343 if(getHalfCarryFlag()) { 02344 a -= 0x6; 02345 } 02346 } 02347 clearZeroFlag(); 02348 clearHalfCarryFlag(); 02349 if(a == 0) { 02350 setZeroFlag(); 02351 } 02352 globalState.a = (u8)a; 02353 } 02354 02355 void CPL(u8 opcode) { // 0x2f 02356 globalState.pc++; 02357 globalState.cycleCount += 4; 02358 globalState.a = ~globalState.a; 02359 setHalfCarryFlag(); 02360 setSubtractFlag(); 02361 } 02362 02363 void CCF(u8 opcode) { // 0x3f 02364 globalState.pc++; 02365 globalState.cycleCount += 4; 02366 if(getCarryFlag()) { 02367 clearCarryFlag(); 02368 } else { 02369 setCarryFlag(); 02370 } 02371 clearHalfCarryFlag(); 02372 clearSubtractFlag(); 02373 } 02374 02375 void SCF(u8 opcode) { // 0x37 02376 globalState.pc++; 02377 globalState.cycleCount += 4; 02378 clearHalfCarryFlag(); 02379 clearSubtractFlag(); 02380 setCarryFlag(); 02381 } 02382 02383 void NOP(u8 opcode) { // 00 02384 globalState.pc++; 02385 globalState.cycleCount += 4; 02386 } 02387 02388 02389 void HALT(u8 opcode) { // 76 02390 globalState.cycleCount += 4; 02391 globalState.pc++; 02392 //if(globalState.ime) { 02393 globalState.halt = true; 02394 //} 02395 02396 } 02397 02398 void STOP(u8 opcode) { // 10 (00) 02399 printf("stop not yet implemented\n"); 02400 assert(false); 02401 } 02402 02403 void DI(u8 opcode) { // F3 02404 // todo instruction after bs 02405 globalState.ime = 0; 02406 globalState.cycleCount += 4; 02407 globalState.pc++; 02408 // printf("di not yet implemented\n"); 02409 // assert(false); 02410 } 02411 02412 void EI(u8 opcode) { // FB 02413 globalState.ime = 1; 02414 globalState.cycleCount += 4; 02415 globalState.pc++; 02416 } 02417 02418 void RLCA(u8 opcode) { // 07 02419 globalState.pc++; 02420 globalState.cycleCount += 4; 02421 globalState.a = rlcReg(globalState.a, true); 02422 } 02423 02424 void RLA(u8 opcode) { // 17 02425 globalState.pc++; 02426 globalState.cycleCount += 4; 02427 globalState.a = rlReg(globalState.a, true); 02428 } 02429 02430 void RRCA(u8 opcode) { // 0x0f 02431 globalState.pc++; 02432 globalState.cycleCount += 4; 02433 globalState.a = rrc(globalState.a, true); 02434 } 02435 02436 void RRA(u8 opcode) { // 0x1f 02437 globalState.pc++; 02438 globalState.cycleCount += 4; 02439 globalState.a = rr(globalState.a, true); 02440 } 02441 02442 void JP_nn(u8 opcodes) { // 0xc3 02443 globalState.pc++; 02444 u16 addr = readU16(globalState.pc); 02445 globalState.pc += 2; 02446 globalState.cycleCount += 12; 02447 globalState.pc = addr; 02448 } 02449 02450 void JP_NZ_nn(u8 opcodes) { // 0xc2 02451 globalState.pc++; 02452 u16 addr = readU16(globalState.pc); 02453 globalState.pc += 2; 02454 if(!getZeroFlag()) { 02455 globalState.pc = addr; 02456 } 02457 globalState.cycleCount += 12; 02458 } 02459 02460 void JP_Z_nn(u8 opcodes) { // 0xca 02461 globalState.pc++; 02462 u16 addr = readU16(globalState.pc); 02463 globalState.pc += 2; 02464 if(getZeroFlag()) { 02465 globalState.pc = addr; 02466 } 02467 globalState.cycleCount += 12; 02468 } 02469 02470 void JP_NC_nn(u8 opcodes) { // 0xd2 02471 globalState.pc++; 02472 u16 addr = readU16(globalState.pc); 02473 globalState.pc += 2; 02474 if(!getCarryFlag()) { 02475 globalState.pc = addr; 02476 } 02477 globalState.cycleCount += 12; 02478 } 02479 02480 void JP_C_nn(u8 opcodes) { // 0xda 02481 globalState.pc++; 02482 u16 addr = readU16(globalState.pc); 02483 globalState.pc += 2; 02484 if(getCarryFlag()) { 02485 globalState.pc = addr; 02486 } 02487 globalState.cycleCount += 12; 02488 } 02489 02490 void JP_HL(u8 opcodes) { // 0xe9 02491 globalState.pc = globalState.hl.v; 02492 globalState.cycleCount += 4; 02493 } 02494 02495 void JR_n(u8 opcode) { // 18 02496 s8 imm = readByte(++globalState.pc); 02497 globalState.pc++; 02498 globalState.pc += imm; 02499 globalState.cycleCount += 8; 02500 } 02501 02502 void JR_NZ(u8 opcode) { // 20 02503 s8 imm = readByte(++globalState.pc); 02504 globalState.pc++; 02505 if(!getZeroFlag()){ 02506 globalState.pc += imm; 02507 } 02508 globalState.cycleCount += 8; 02509 } 02510 02511 void JR_Z(u8 opcode) { // 28 02512 s8 imm = readByte(++globalState.pc); 02513 globalState.pc++; 02514 if(getZeroFlag()){ 02515 globalState.pc += imm; 02516 } 02517 globalState.cycleCount += 8; 02518 } 02519 02520 void JR_NC(u8 opcode) { // 30 02521 s8 imm = readByte(++globalState.pc); 02522 globalState.pc++; 02523 if(!getCarryFlag()){ 02524 globalState.pc += imm; 02525 } 02526 globalState.cycleCount += 8; 02527 } 02528 02529 void JR_C(u8 opcode) { // 38 02530 s8 imm = readByte(++globalState.pc); 02531 globalState.pc++; 02532 if(getCarryFlag()){ 02533 globalState.pc += imm; 02534 } 02535 globalState.cycleCount += 8; 02536 } 02537 02538 02539 void CALL_nn(u8 opcode) { // 0xCD 02540 globalState.pc++; 02541 u16 addr = readU16(globalState.pc); 02542 //printf("call address 0x%x\n", addr); 02543 globalState.pc += 2; 02544 writeU16(globalState.pc, globalState.sp - (u16)2); 02545 globalState.sp -= 2; 02546 globalState.pc = addr; 02547 globalState.cycleCount += 12; 02548 } 02549 02550 void CALL_NZ(u8 opcode) { // 0xC4 02551 globalState.pc++; 02552 u16 addr = readU16(globalState.pc); 02553 globalState.pc += 2; 02554 if(!getZeroFlag()) { 02555 writeU16(globalState.pc, globalState.sp - (u16)2); 02556 globalState.sp -= 2; 02557 globalState.pc = addr; 02558 } 02559 globalState.cycleCount += 12; 02560 } 02561 02562 void CALL_Z(u8 opcode) { // 0xCc 02563 globalState.pc++; 02564 u16 addr = readU16(globalState.pc); 02565 globalState.pc += 2; 02566 if(getZeroFlag()) { 02567 writeU16(globalState.pc, globalState.sp - (u16)2); 02568 globalState.sp -= 2; 02569 globalState.pc = addr; 02570 } 02571 globalState.cycleCount += 12; 02572 } 02573 02574 02575 void CALL_NC(u8 opcode) { // 0d4 02576 globalState.pc++; 02577 u16 addr = readU16(globalState.pc); 02578 globalState.pc += 2; 02579 if(!getCarryFlag()) { 02580 writeU16(globalState.pc, globalState.sp - (u16)2); 02581 globalState.sp -= 2; 02582 globalState.pc = addr; 02583 } 02584 globalState.cycleCount += 12; 02585 } 02586 02587 void CALL_C(u8 opcode) { // 0xdc 02588 globalState.pc++; 02589 u16 addr = readU16(globalState.pc); 02590 globalState.pc += 2; 02591 if(getCarryFlag()) { 02592 writeU16(globalState.pc, globalState.sp - (u16)2); 02593 globalState.sp -= 2; 02594 globalState.pc = addr; 02595 } 02596 globalState.cycleCount += 12; 02597 } 02598 02599 void REST_00(u8 opcode) { // 0xc7 02600 globalState.pc++; 02601 writeU16(globalState.pc, globalState.sp - (u16)2); 02602 globalState.sp -= 2; 02603 globalState.pc = 0x0000; 02604 globalState.cycleCount += 32; 02605 } 02606 02607 void REST_08(u8 opcode) { // 0xcf 02608 globalState.pc++; 02609 writeU16(globalState.pc, globalState.sp - (u16)2); 02610 globalState.sp -= 2; 02611 globalState.pc = 0x0008; 02612 globalState.cycleCount += 32; 02613 } 02614 02615 void REST_10(u8 opcode) { // 0xd7 02616 globalState.pc++; 02617 writeU16(globalState.pc, globalState.sp - (u16)2); 02618 globalState.sp -= 2; 02619 globalState.pc = 0x0010; 02620 globalState.cycleCount += 32; 02621 } 02622 02623 void REST_18(u8 opcode) { // 0xdf 02624 globalState.pc++; 02625 writeU16(globalState.pc, globalState.sp - (u16)2); 02626 globalState.sp -= 2; 02627 globalState.pc = 0x0018; 02628 globalState.cycleCount += 32; 02629 } 02630 02631 void REST_20(u8 opcode) { // 0xe7 02632 globalState.pc++; 02633 writeU16(globalState.pc, globalState.sp - (u16)2); 02634 globalState.sp -= 2; 02635 globalState.pc = 0x0020; 02636 globalState.cycleCount += 32; 02637 } 02638 02639 void REST_28(u8 opcode) { // 0xef 02640 globalState.pc++; 02641 writeU16(globalState.pc, globalState.sp - (u16)2); 02642 globalState.sp -= 2; 02643 globalState.pc = 0x0028; 02644 globalState.cycleCount += 32; 02645 } 02646 02647 void REST_30(u8 opcode) { // 0xf7 02648 globalState.pc++; 02649 writeU16(globalState.pc, globalState.sp - (u16)2); 02650 globalState.sp -= 2; 02651 globalState.pc = 0x0030; 02652 globalState.cycleCount += 32; 02653 } 02654 02655 void REST_38(u8 opcode) { // 0xff 02656 globalState.pc++; 02657 writeU16(globalState.pc, globalState.sp - (u16)2); 02658 globalState.sp -= 2; 02659 globalState.pc = 0x0038; 02660 globalState.cycleCount += 32; 02661 } 02662 02663 void RET(u8 opcode) { // 0xc9 02664 globalState.pc++; 02665 globalState.cycleCount += 8; 02666 globalState.pc = readU16(globalState.sp); 02667 globalState.sp += 2; 02668 } 02669 02670 void RET_NZ(u8 opcode) { // 0xc0 02671 globalState.pc++; 02672 globalState.cycleCount += 8; 02673 if(!getZeroFlag()) { 02674 globalState.pc = readU16(globalState.sp); 02675 globalState.sp += 2; 02676 } 02677 } 02678 02679 void RET_Z(u8 opcode) { // 0xc8 02680 globalState.pc++; 02681 globalState.cycleCount += 8; 02682 if(getZeroFlag()) { 02683 globalState.pc = readU16(globalState.sp); 02684 globalState.sp += 2; 02685 } 02686 } 02687 02688 void RET_NC(u8 opcode) { // 0xd0 02689 globalState.pc++; 02690 globalState.cycleCount += 8; 02691 if(!getCarryFlag()) { 02692 globalState.pc = readU16(globalState.sp); 02693 globalState.sp += 2; 02694 } 02695 } 02696 02697 void RET_C(u8 opcode) { // 0xd8 02698 globalState.pc++; 02699 globalState.cycleCount += 8; 02700 if(getCarryFlag()) { 02701 globalState.pc = readU16(globalState.sp); 02702 globalState.sp += 2; 02703 } 02704 } 02705 02706 void RETI(u8 opcode) { // 0xd9 02707 globalState.pc++; 02708 globalState.cycleCount += 8; 02709 globalState.pc = readU16(globalState.sp); 02710 globalState.sp += 2; 02711 globalState.ime = 1; 02712 } 02713 02714 // normal opcode handler table 02715 static OpcodeHandler* opcodes[256] = 02716 {NOP, LD_BC_nn, LD_DBC_A, INC_BC, INC_B, DEC_B, LD_B_n, RLCA, // 0x0 - 0x7 02717 LD_Dnn_SP, ADD_HL_BC, LD_A_DBC, DEC_BC, INC_C, DEC_C, LD_C_n, RRCA, // 0x8 - 0xf 02718 STOP, LD_DE_nn, LD_DDE_A, INC_DE, INC_D, DEC_D, LD_D_n, RLA, // 0x10 - 0x17 02719 JR_n, ADD_HL_DE, LD_A_DDE, DEC_DE, INC_E, DEC_E, LD_E_n, RRA, // 0x18 - 0x1f 02720 JR_NZ, LD_HL_nn, LDI_DHL_A, INC_HL, INC_H, DEC_H, LD_H_n, DAA, // 0x20 - 0x27 02721 JR_Z, ADD_HL_HL, LDI_A_DHL, DEC_HL, INC_L, DEC_L, LD_L_n, CPL, // 0x28 - 0x2f 02722 JR_NC, LD_SP_nn, LDD_DHL_A, INC_SP, INC_DHL, DEC_DHL, LD_DHL_n, SCF, // 0x30 - 0x37 02723 JR_C, ADD_HL_SP, LDD_A_DHL, DEC_SP, INC_A, DEC_A, LD_A_n, CCF, // 0x38 - 0x3f 02724 LD_B_B, LD_B_C, LD_B_D, LD_B_E, LD_B_H, LD_B_L, LD_B_DHL, LD_B_A, // 0x40 - 0x47 02725 LD_C_B, LD_C_C, LD_C_D, LD_C_E, LD_C_H, LD_C_L, LD_C_DHL, LD_C_A, // 0x48 - 0x4f 02726 LD_D_B, LD_D_C, LD_D_D, LD_D_E, LD_D_H, LD_D_L, LD_D_DHL, LD_D_A, // 0x50 - 0x57 02727 LD_E_B, LD_E_C, LD_E_D, LD_E_E, LD_E_H, LD_E_L, LD_E_DHL, LD_E_A, // 0x58 - 0x5f 02728 LD_H_B, LD_H_C, LD_H_D, LD_H_E, LD_H_H, LD_H_L, LD_H_DHL, LD_H_A, // 0x60 - 0x67 02729 LD_L_B, LD_L_C, LD_L_D, LD_L_E, LD_L_H, LD_L_L, LD_L_DHL, LD_L_A, // 0x68 - 0x6f 02730 LD_DHL_B, LD_DHL_C, LD_DHL_D, LD_DHL_E, LD_DHL_H, LD_DHL_L, HALT, LD_DHL_A, // 0x70 - 0x77 02731 LD_A_B, LD_A_C, LD_A_D, LD_A_E, LD_A_H, LD_A_L, LD_A_DHL, LD_A_A , // 0x78 - 0x7f 02732 ADD_B, ADD_C, ADD_D, ADD_E, ADD_H, ADD_L, ADD_DHL, ADD_A, // 0x80 - 0x87 02733 ADC_B, ADC_C, ADC_D, ADC_E, ADC_H, ADC_L, ADC_DHL, ADC_A, // 0x88 - 0x8f 02734 SUB_B, SUB_C, SUB_D, SUB_E, SUB_H, SUB_L, SUB_DHL, SUB_A, // 0x90 - 0x97 02735 SBC_B, SBC_C, SBC_D, SBC_E, SBC_H, SBC_L, SBC_DHL, SBC_A, // 0x98 - 0x9f 02736 AND_B, AND_C, AND_D, AND_E, AND_H, AND_L, AND_DHL, AND_A, // 0xa0 - 0xa7 02737 XOR_B, XOR_C, XOR_D, XOR_E, XOR_H, XOR_L, XOR_DHL, XOR_A, // 0xa8 - 0xaf 02738 OR_B, OR_C, OR_D, OR_E, OR_H, OR_L, OR_DHL, OR_A, // 0xb0 - 0xb7 02739 CP_B, CP_C, CP_D, CP_E, CP_H, CP_L, CP_DHL, CP_A, // 0xb8 - 0xbf 02740 RET_NZ, POP_BC, JP_NZ_nn, JP_nn, CALL_NZ, PUSH_BC, ADD_n, REST_00, // 0xc0 - 0xc7 02741 RET_Z, RET, JP_Z_nn, DecodeCB, CALL_Z, CALL_nn, ADC_n, REST_08, // 0xc8 - 0xcf 02742 RET_NC, POP_DE, JP_NC_nn, invHandler, CALL_NC, PUSH_DE, SUB_n, REST_10, // 0xd0 - 0xd7 02743 RET_C, RETI, JP_C_nn, invHandler, CALL_C, invHandler, SBC_n, REST_18, // 0xd8 - 0xdf 02744 LD_FF00_n_A, POP_HL, LD_FF00_C_A, invHandler, invHandler, PUSH_HL, AND_n, REST_20, // 0xe0 - 0xe7 02745 ADD_SP_n, JP_HL, LD_Dnn_A, invHandler, invHandler, invHandler, XOR_n, REST_28, // 0xe8 - 0xef 02746 LD_A_FF00_n, POP_AF, LD_A_FF00_C, DI, invHandler, PUSH_AF, OR_n, REST_30, // 0xf0 - 0xf7 02747 LD_HL_SP_n, LD_SP_HL, LD_A_Dnn, EI, invHandler, invHandler, CP_n, REST_38}; // 0xf8 - 0xff 02748 02749 02750 // reset the globalState structure, including registers and timers 02751 void resetCpu() { 02752 globalState.f = 0x1; // or 0x11? ( 02753 globalState.a = 0xb0; // maybe f, a swap?? 02754 globalState.bc.v = 0x0013; 02755 globalState.de.v = 0x00d8; 02756 globalState.hl.v = 0x014d; 02757 globalState.sp = 0xfffe; 02758 globalState.pc = 0x0; 02759 globalState.halt = false; 02760 globalState.cycleCount = 0; 02761 globalState.divOffset = 0; 02762 globalState.timSubcount = 0; 02763 } 02764 02765 // set the globalState so the next call to step() will run an ISR 02766 void interrupt(u16 addr) { 02767 globalState.ime = 0; // disable interrupts 02768 writeU16(globalState.pc, globalState.sp - (u16)2); // push pc to stack 02769 globalState.sp -= 2; // push pc to stack 02770 globalState.cycleCount += 12; // timing 02771 globalState.pc = addr; // jump to ISR 02772 } 02773 02774 // timer speeds: once this number of clock cycles has elapsed, the timer ticks. 02775 static u32 timReset[4] = {(1 << 10), (1 << 4), (1 << 6), (1 << 8)}; 02776 02777 // step the CPU 1 instruction 02778 // returns number of clock cycles 02779 u32 cpuStep() { 02780 uint64_t oldCycleCount = globalState.cycleCount; 02781 02782 // update div register 02783 globalMemState.ioRegs[IO_DIV] = (u8)((globalState.cycleCount - globalState.divOffset) >> 8); 02784 02785 // execute, if we aren't halted. 02786 if(!globalState.halt) { 02787 // fetch opcode 02788 u8 opcode = readByte(globalState.pc); 02789 // execute opcode 02790 opcodes[opcode](opcode); 02791 } 02792 02793 assert(false); 02794 // interrupts 02795 if(globalState.ime && globalMemState.upperRam[0x7f] && globalMemState.ioRegs[IO_IF]) { 02796 02797 // mask interrupts with the interrupt enable register at 0xffff. 02798 u8 interrupts = globalMemState.upperRam[0x7f] & globalMemState.ioRegs[IO_IF]; 02799 02800 if(interrupts & 0x01) { 02801 globalMemState.ioRegs[IO_IF] &= ~1; 02802 interrupt(VBLANK_INTERRUPT); 02803 globalState.halt = false; 02804 } else if(interrupts & 0x02) { 02805 globalMemState.ioRegs[IO_IF] &= ~2; 02806 interrupt(LCDC_INTERRUPT); 02807 globalState.halt = false; 02808 } else if(interrupts & 0x04) { 02809 globalMemState.ioRegs[IO_IF] &= ~4; 02810 interrupt(TIMER_INTERRUPT); 02811 globalState.halt = false; 02812 } else if(interrupts & 0x08) { 02813 globalMemState.ioRegs[IO_IF] &= ~8; 02814 interrupt(SERIAL_INTERRUPT); 02815 globalState.halt = false; 02816 } else if(interrupts & 0x10) { 02817 globalMemState.ioRegs[IO_IF] &= ~0x10; 02818 interrupt(HIGH_TO_LOW_P10_P13); 02819 globalState.halt = false; 02820 } 02821 } 02822 02823 // even if we have IME off, and we're halted, we're supposed to check IF and IE register 02824 // this won't fire an interrupt, but will get us out of halt 02825 // this behavior isn't well documented, but was required to pass cpu_instr.gb 02826 // (though none of the games seem to need it...) 02827 if(globalState.halt) { 02828 globalState.cycleCount += 800; // just to keep ticking the timer... 02829 u8 interrupts = globalMemState.upperRam[0x7f] & globalMemState.ioRegs[IO_IF]; 02830 if(interrupts & 0x01) { 02831 globalState.halt = false; 02832 } else if(interrupts & 0x02) { 02833 globalState.halt = false; 02834 } else if(interrupts & 0x04) { 02835 globalState.halt = false; 02836 } else if(interrupts & 0x08) { 02837 globalState.halt = false; 02838 } else if(interrupts & 0x10) { 02839 globalState.halt = false; 02840 } 02841 } 02842 02843 02844 // cycle count 02845 uint64_t cyclesThisIteration = globalState.cycleCount - oldCycleCount; 02846 02847 // update timer 02848 u8 tac = globalMemState.ioRegs[IO_TAC]; 02849 bool ten = ((tac >> 2) & 1) != 0; // timer enable? 02850 if(ten) { 02851 u8 tclk = (tac & (u8)3); // timer speed 02852 globalState.timSubcount += cyclesThisIteration; 02853 if(globalState.timSubcount >= timReset[tclk]) { // timer tick 02854 globalState.timSubcount = 0; 02855 u8 timv = globalMemState.ioRegs[IO_TIMA]; // check for overflow 02856 if(timv == 255) { 02857 globalMemState.ioRegs[IO_IF] |= 4; // set interrupt 02858 globalMemState.ioRegs[IO_TIMA] = globalMemState.ioRegs[IO_TMA]; // reset 02859 } else { 02860 globalMemState.ioRegs[IO_TIMA] = timv + (u8)1; // increment. 02861 } 02862 } 02863 } 02864 02865 return (u32)cyclesThisIteration; 02866 } 02867 02868 bool getZeroFlag() { 02869 return (globalState.f & 0x80) != 0; 02870 } 02871 02872 bool getSubtractFlag() { 02873 return (globalState.f & 0x40) != 0; 02874 } 02875 02876 bool getHalfCarryFlag() { 02877 return (globalState.f & 0x20) != 0; 02878 } 02879 02880 bool getCarryFlag() { 02881 return (globalState.f & 0x10) != 0; 02882 } 02883 02884 void setZeroFlag() { 02885 globalState.f = globalState.f | (u8)0x80; 02886 } 02887 02888 void setSubtractFlag() { 02889 globalState.f = globalState.f | (u8)0x40; 02890 } 02891 02892 void setHalfCarryFlag() { 02893 globalState.f = globalState.f | (u8)0x20; 02894 } 02895 02896 void setCarryFlag() { 02897 globalState.f = globalState.f | (u8)0x10; 02898 } 02899 02900 void clearZeroFlag(){ 02901 globalState.f = globalState.f & ~((u8)0x80); 02902 } 02903 02904 void clearSubtractFlag(){ 02905 globalState.f = globalState.f & ~((u8)0x40); 02906 } 02907 02908 void clearHalfCarryFlag(){ 02909 globalState.f = globalState.f & ~((u8)0x20); 02910 } 02911 02912 void clearCarryFlag(){ 02913 globalState.f = globalState.f & ~((u8)0x10); 02914 } 02915 02916 void clearAllFlags() { 02917 clearZeroFlag(); 02918 clearSubtractFlag(); 02919 clearHalfCarryFlag(); 02920 clearCarryFlag(); 02921 }
Generated on Thu Jul 14 2022 01:44:52 by 1.7.2