gameboy wormboy manboy gameworm gameman wormgame mangame manworm

Dependencies:   mbed SDFileSystem2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cpu.cpp Source File

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 }