Timer and divider implemented
authorslack <slack@codemaniacs.com>
Sat, 5 Jul 2008 01:30:09 +0000 (03:30 +0200)
committerslack <slack@codemaniacs.com>
Sat, 5 Jul 2008 01:30:09 +0000 (03:30 +0200)
GBMemory.cc
GBMemory.h
gbcore.cc
gbcore.h

index 60b052ed8b5a932a58208a4f78f1631cdc075039..ebd1b5e3fa93ad4e0f2e1990a56b320381e7e0e8 100644 (file)
@@ -14,7 +14,12 @@ void GBMemory::write(int addr, u8 value)
        else if (addr < 0xE000) WRAM[addr - WRAM_BASE] = value;
        else if (addr < 0xFE00) write(addr-0x2000, value);
        else if (addr < 0xFEA0) core->video.write_OAM (addr, value);
-       else if (addr >= 0xFF00) high[addr-0xFF00] = value;
+       else if (addr >= 0xFF00) {
+               high[addr-0xFF00] = value;
+               if (addr == DIV) {
+                       high[I_DIV] = 0;
+               }
+       }
        else {
                std::ostringstream errmsg;
                errmsg << "Invalid write address 0x" << 
@@ -39,7 +44,8 @@ u8  GBMemory::read(int addr) const
                errmsg << "Invalid read address 0x" << 
                        std::hex << std::setw(4) << std::setfill('0') << addr;
                logger.error(errmsg.str());
-               return *(static_cast<u8*>(0));
+               //return *(static_cast<u8*>(0));
+               return 0;
        }
 }
 
index a8c0784aa9e9c134ca1b3adcd68daedf71fe4f7c..4d44aa790e27438797a3907fd82339ee9f8cb3b2 100644 (file)
@@ -41,6 +41,10 @@ class GBMemory
        void write(int addr, u8 value);
        
        public:
+       static const u16 DIV  = 0xFF04; // Divider register     (R/W)
+       static const u16 TIMA = 0xFF05; // Timer counter        (R/W)
+       static const u16 TMA  = 0xFF06; // Timer modulo         (R/W)
+       static const u16 TAC  = 0xFF07; // Timer control        (R/W)
        static const u16 LCDC = 0xFF40; // LCD Control          (R/W)
        static const u16 STAT = 0xFF41; // LCD Status           (R/W)
        static const u16 SCY  = 0xFF42; // Scroll Y             (R/W)
@@ -54,9 +58,13 @@ class GBMemory
        static const u16 OBP1 = 0xFF49; // Object Pallete 1 data(R/W)
        static const u16 DMA  = 0xFF46; // DMA Transfer & Start addr (W)
        static const u16 IF   = 0xFF0F; // Interrupt flag       (R/W)
-       static const u16 IE   = 0xFF0F; // Interrupt enable       (R/W)
+       static const u16 IE   = 0xFF0F; // Interrupt enable     (R/W)
 
        private:
+       static const u16 I_DIV  = 0xFF04 - IO_BASE; // Divider register     (R/W)
+       static const u16 I_TIMA = 0xFF05 - IO_BASE; // Timer counter        (R/W)
+       static const u16 I_TMA  = 0xFF06 - IO_BASE; // Timer modulo         (R/W)
+       static const u16 I_TAC  = 0xFF07 - IO_BASE; // Timer control        (R/W)
        static const u16 I_LCDC = 0xFF40 - IO_BASE; // LCD Control          (R/W)
        static const u16 I_STAT = 0xFF41 - IO_BASE; // LCD Status           (R/W)
        static const u16 I_SCY  = 0xFF42 - IO_BASE; // Scroll Y             (R/W)
index db85565881ca045b8015b4f2da6c8f90f9ffb43c..90e40ba39477b18d0562db05db12d7f8779839f8 100644 (file)
--- a/gbcore.cc
+++ b/gbcore.cc
@@ -17,9 +17,12 @@ GameBoy::GameBoy(std::string rom_name, GameBoyType type):
        regs(),
        IME(1),
        HALT(0),
+       STOP(0),
        cycle_count(0),
        cycles_until_video_update(0),
        cycles_until_next_instruction(0),
+       divider_count(0),
+       timer_count(0),
        breakpoints(),
        last_breakpoint_id(0)
 {
@@ -48,7 +51,20 @@ void GameBoy::reset()
        regs.HL = 0x014D;
        regs.SP = 0xFFFE;
 
-       for (int i=0; i<0xFFFF; i++)
+       // Clear VRAM, external RAM and work RAM
+       for (int i=0x8000; i<0xE000; i++)
+       {
+               memory.write(i, 0);
+       }
+
+       // Clear OAM
+       for (int i=0xFE00; i<0xFEA0; i++)
+       {
+               memory.write(i, 0);
+       }
+
+       // Clear HRAM
+       for (int i=0xFF80; i<0xFFFF; i++)
        {
                memory.write(i, 0);
        }
@@ -117,1208 +133,1234 @@ GameBoy::run_status GameBoy::run_cycle()
 {
        cycle_count += CYCLE_STEP;
 
-       if (cycles_until_next_instruction > 0)
-       {
-               if (cycles_until_video_update <= 0)
-                       cycles_until_video_update = video.update();
-               
-               cycles_until_video_update -= CYCLE_STEP;
-               cycles_until_next_instruction -= CYCLE_STEP;
-               
-               if (cycles_until_next_instruction > 0) return WAIT;
-               else return NORMAL;
-       }
-
-       // Check for interrupts before opcode fetching
-       u8 IE=memory.high[GBMemory::I_IE];
-       //logger.trace("IME=", int(IME), " IE=", int(IE));
-       if (IME && IE)
+       if (cycles_until_next_instruction <= 0)
        {
-               u8 IF = memory.high[GBMemory::I_IF];
-               //logger.trace("Dispatching interrupts: IE=", int(IE), " IF=", int(IF));
-               if (IF)
+               // Check for interrupts before opcode fetching
+               u8 IE=memory.high[GBMemory::I_IE];
+               //logger.trace("IME=", int(IME), " IE=", int(IE));
+               if (IME && IE)
                {
-                       if ((IF & IRQ_VBLANK) && (IE & IRQ_VBLANK)) 
+                       u8 IF = memory.high[GBMemory::I_IF];
+                       //logger.trace("Dispatching interrupts: IE=", int(IE), " IF=", int(IF));
+                       if (IF)
                        {
-                               IME = 0;
-                               IF &= (~IRQ_VBLANK);
-                               do_call(0x40);
-                               logger.trace("VBLANK IRQ");
-                               HALT=false;
-                       }
-                       else if ((IF & IRQ_LCD_STAT) && (IE & IRQ_LCD_STAT))
-                       {
-                               IME = 0;
-                               IF &= (~IRQ_LCD_STAT);
-                               do_call(0x48);
-                               logger.trace("LCD STAT IRQ");
-                               HALT=false;
-                       } 
-                       else if ((IF & IRQ_TIMER) && (IE & IRQ_TIMER))
-                       {
-                               IME = 0;
-                               IF &= (~IRQ_TIMER);
-                               do_call(0x50);
-                               logger.trace("TIMER IRQ");
-                               HALT=false;
-                       }
-                       else if ((IF & IRQ_SERIAL) && (IE & IRQ_SERIAL))   
-                       {
-                               IME = 0;
-                               IF &= (~IRQ_SERIAL);
-                               do_call(0x58);
-                               logger.trace("SERIAL IRQ");
-                               HALT=false;
-                       }
-                       else if ((IF & IRQ_JOYPAD) && (IE & IRQ_JOYPAD))     
-                       {
-                               IME = 0;
-                               IF &= (~IRQ_JOYPAD);
-                               do_call(0x60);
-                               logger.trace("JOYPAD IRQ");
-                               HALT=false;
+                               if ((IF & IRQ_VBLANK) && (IE & IRQ_VBLANK)) 
+                               {
+                                       IME = 0;
+                                       IF &= (~IRQ_VBLANK);
+                                       do_call(0x40);
+                                       logger.trace("VBLANK IRQ");
+                                       HALT=false;
+                               }
+                               else if ((IF & IRQ_LCD_STAT) && (IE & IRQ_LCD_STAT))
+                               {
+                                       IME = 0;
+                                       IF &= (~IRQ_LCD_STAT);
+                                       do_call(0x48);
+                                       logger.trace("LCD STAT IRQ");
+                                       HALT=false;
+                               } 
+                               else if ((IF & IRQ_TIMER) && (IE & IRQ_TIMER))
+                               {
+                                       IME = 0;
+                                       IF &= (~IRQ_TIMER);
+                                       do_call(0x50);
+                                       logger.trace("TIMER IRQ");
+                                       HALT=false;
+                               }
+                               else if ((IF & IRQ_SERIAL) && (IE & IRQ_SERIAL))   
+                               {
+                                       IME = 0;
+                                       IF &= (~IRQ_SERIAL);
+                                       do_call(0x58);
+                                       logger.trace("SERIAL IRQ");
+                                       HALT=false;
+                               }
+                               else if ((IF & IRQ_JOYPAD) && (IE & IRQ_JOYPAD))     
+                               {
+                                       IME = 0;
+                                       IF &= (~IRQ_JOYPAD);
+                                       do_call(0x60);
+                                       logger.trace("JOYPAD IRQ");
+                                       HALT=false;
+                               }
                        }
+                       memory.high[GBMemory::I_IF] = IF;
                }
-               memory.high[GBMemory::I_IF] = IF;
-       }
 
-       /*
-       for(BreakpointMap::iterator i=breakpoints.begin();
-                       i != breakpoints.end();
-                       i++)
-       {
-               if (i->second.addr == regs.PC && i->second.enabled)
-                       return BREAKPOINT;
-       }
-       */
-       
-       int opcode;
-       opcode = memory.read(regs.PC++);
+               for(BreakpointMap::iterator i=breakpoints.begin();
+                               i != breakpoints.end();
+                               i++)
+               {
+                       if (i->second.addr == regs.PC && i->second.enabled)
+                               return BREAKPOINT;
+               }
+               
+               int opcode;
+               opcode = memory.read(regs.PC++);
 
-       if (!(HALT || STOP))
-       {
-               switch(opcode & 0x80)
+               if (!(HALT || STOP))
                {
-                       case 0x00:
-                       switch(opcode)
+                       switch(opcode & 0x80)
                        {
-                               // LD n, nn
-                               for_each_register(0x3E, 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, LD_reg_nn)
-
-                               // LD r1,r2
-                               for_each_register(0x7F, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, LD_A_reg)
-                               for_each_register(0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, LD_B_reg)
-                               for_each_register(0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, LD_C_reg)
-                               for_each_register(0x57, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, LD_D_reg)
-                               for_each_register(0x5F, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, LD_E_reg)
-                               for_each_register(0x67, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, LD_H_reg)
-                               for_each_register(0x6F, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, LD_L_reg)
-                               
-                               // LD reg, (HL)
-                               for_each_register(0x7E, 0x46, 0x4E, 0x56, 0x5E, 0x66, 0x6E, LD_reg__HL_)
+                               case 0x00:
+                               switch(opcode)
+                               {
+                                       // LD n, nn
+                                       for_each_register(0x3E, 0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, LD_reg_nn)
+
+                                       // LD r1,r2
+                                       for_each_register(0x7F, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, LD_A_reg)
+                                       for_each_register(0x47, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, LD_B_reg)
+                                       for_each_register(0x4F, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, LD_C_reg)
+                                       for_each_register(0x57, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, LD_D_reg)
+                                       for_each_register(0x5F, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, LD_E_reg)
+                                       for_each_register(0x67, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, LD_H_reg)
+                                       for_each_register(0x6F, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, LD_L_reg)
+                                       
+                                       // LD reg, (HL)
+                                       for_each_register(0x7E, 0x46, 0x4E, 0x56, 0x5E, 0x66, 0x6E, LD_reg__HL_)
 
-                               // LD (HL), reg
-                               for_each_register(0x77, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, LD__HL__reg)
-                               
-                               case 0x36: // LD (HL), n
-                                       memory.write(regs.HL, memory.read(regs.PC++));
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               
-                               // LD A, mem
-                               case 0x0A: // LD A, (BC)
-                                       regs.A = memory.read(regs.BC);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               case 0x1A: // LD A, (DE)
-                                       regs.A = memory.read(regs.DE);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               
-                               // LD mem, A
-                               case 0x02: // LD (BC), A
-                                       memory.write(regs.BC, regs.A);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               case 0x12: // LD (DE), A
-                                       memory.write(regs.DE, regs.A);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // LD (HL), reg
+                                       for_each_register(0x77, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, LD__HL__reg)
+                                       
+                                       case 0x36: // LD (HL), n
+                                               memory.write(regs.HL, memory.read(regs.PC++));
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       
+                                       // LD A, mem
+                                       case 0x0A: // LD A, (BC)
+                                               regs.A = memory.read(regs.BC);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       case 0x1A: // LD A, (DE)
+                                               regs.A = memory.read(regs.DE);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       
+                                       // LD mem, A
+                                       case 0x02: // LD (BC), A
+                                               memory.write(regs.BC, regs.A);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       case 0x12: // LD (DE), A
+                                               memory.write(regs.DE, regs.A);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               // LD A, (HLD); LD A, (HL-); LDD A,(HL);
-                               case 0x3A:
-                                       regs.A = memory.read(regs.HL);
-                                       --regs.HL;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               // LD (HLD), A; LD (HL-), A; LDD (HL), A;
-                               case 0x32:
-                                       memory.write(regs.HL, regs.A);
-                                       --regs.HL;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               // LD A, (HLI); LD A, (HL+); LDI A, (HL);
-                               case 0x2A:
-                                       regs.A = memory.read(regs.HL);
-                                       ++regs.HL;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               // LD (HLI), A; LD (HL+), A; LDI (HL), A;
-                               case 0x22:
-                                       memory.write(regs.HL, regs.A);
-                                       ++regs.HL;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // LD A, (HLD); LD A, (HL-); LDD A,(HL);
+                                       case 0x3A:
+                                               regs.A = memory.read(regs.HL);
+                                               --regs.HL;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       // LD (HLD), A; LD (HL-), A; LDD (HL), A;
+                                       case 0x32:
+                                               memory.write(regs.HL, regs.A);
+                                               --regs.HL;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       // LD A, (HLI); LD A, (HL+); LDI A, (HL);
+                                       case 0x2A:
+                                               regs.A = memory.read(regs.HL);
+                                               ++regs.HL;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       // LD (HLI), A; LD (HL+), A; LDI (HL), A;
+                                       case 0x22:
+                                               memory.write(regs.HL, regs.A);
+                                               ++regs.HL;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               // LD n, nn
-                               case 0x01: // LD BC, nn
-                                       regs.BC = memory.read16(regs.PC);
-                                       regs.PC +=2;
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               case 0x11: // LD DE, nn
-                                       regs.DE = memory.read16(regs.PC);
-                                       regs.PC +=2;
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               case 0x21: // LD HL, nn
-                                       regs.HL = memory.read16(regs.PC);
-                                       regs.PC +=2;
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               case 0x31: // LD SP, nn
-                                       regs.SP = memory.read16(regs.PC);
-                                       regs.PC +=2;
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               
+                                       // LD n, nn
+                                       case 0x01: // LD BC, nn
+                                               regs.BC = memory.read16(regs.PC);
+                                               regs.PC +=2;
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       case 0x11: // LD DE, nn
+                                               regs.DE = memory.read16(regs.PC);
+                                               regs.PC +=2;
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       case 0x21: // LD HL, nn
+                                               regs.HL = memory.read16(regs.PC);
+                                               regs.PC +=2;
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       case 0x31: // LD SP, nn
+                                               regs.SP = memory.read16(regs.PC);
+                                               regs.PC +=2;
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       
 
-                               // LD (nn), SP
-                               case 0x08: {
-                                       int addr = memory.read16(regs.PC);
-                                       regs.PC += 2;
-                                       memory.write(addr, regs.SP);
-                                       cycles_until_next_instruction = 20; 
-                                       break;
-                                       }
+                                       // LD (nn), SP
+                                       case 0x08: {
+                                               int addr = memory.read16(regs.PC);
+                                               regs.PC += 2;
+                                               memory.write(addr, regs.SP);
+                                               cycles_until_next_instruction = 20; 
+                                               break;
+                                               }
 
-                               // INC n
-                               for_each_register(0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, INC_reg)
-
-                               case 0x34: {//INC (HL)
-                                       int half_res = (memory.read(regs.HL) & 0x0F) + 1; 
-                                       memory.write(regs.HL, memory.read(regs.HL) - 1); 
-                                       reset_flag(ADD_SUB_FLAG); 
-                                       set_flag_if (memory.read(regs.HL) == 0, ZERO_FLAG); 
-                                       set_flag_if (half_res > 0x0F,      HALF_CARRY_FLAG); 
-                                       cycles_until_next_instruction = 12; 
-                                       break; 
-                                       }       
-
-                               // DEC n
-                               for_each_register(0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, DEC_reg)
-
-                               case 0x35: {//DEC (HL)
-                                       int half_res = (memory.read(regs.HL) & 0x0F) - 1; 
-                                       memory.write(regs.HL, memory.read(regs.HL) - 1); 
-                                       set_flag(ADD_SUB_FLAG); 
-                                       set_flag_if (memory.read(regs.HL) == 0, ZERO_FLAG); 
-                                       set_flag_if (half_res < 0,         HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 12; 
-                                       break; 
-                                       }
+                                       // INC n
+                                       for_each_register(0x3C, 0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, INC_reg)
+
+                                       case 0x34: {//INC (HL)
+                                               int half_res = (memory.read(regs.HL) & 0x0F) + 1; 
+                                               memory.write(regs.HL, memory.read(regs.HL) - 1); 
+                                               reset_flag(ADD_SUB_FLAG); 
+                                               set_flag_if (memory.read(regs.HL) == 0, ZERO_FLAG); 
+                                               set_flag_if (half_res > 0x0F,      HALF_CARRY_FLAG); 
+                                               cycles_until_next_instruction = 12; 
+                                               break; 
+                                               }       
+
+                                       // DEC n
+                                       for_each_register(0x3D, 0x05, 0x0D, 0x15, 0x1D, 0x25, 0x2D, DEC_reg)
+
+                                       case 0x35: {//DEC (HL)
+                                               int half_res = (memory.read(regs.HL) & 0x0F) - 1; 
+                                               memory.write(regs.HL, memory.read(regs.HL) - 1); 
+                                               set_flag(ADD_SUB_FLAG); 
+                                               set_flag_if (memory.read(regs.HL) == 0, ZERO_FLAG); 
+                                               set_flag_if (half_res < 0,         HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 12; 
+                                               break; 
+                                               }
 
-                               // 16-bit ALU
-                               // ADD HL, n
-                               for_each_register16(0x09, 0x19, 0x29, 0x39, ADD_HL_reg16)
+                                       // 16-bit ALU
+                                       // ADD HL, n
+                                       for_each_register16(0x09, 0x19, 0x29, 0x39, ADD_HL_reg16)
 
-                               // INC nn
-                               for_each_register16(0x03, 0x13, 0x23, 0x33, INC_reg16)
+                                       // INC nn
+                                       for_each_register16(0x03, 0x13, 0x23, 0x33, INC_reg16)
 
-                               // DEC nn
-                               for_each_register16(0x0B, 0x1B, 0x2B, 0x3B, DEC_reg16)
+                                       // DEC nn
+                                       for_each_register16(0x0B, 0x1B, 0x2B, 0x3B, DEC_reg16)
 
 
-                               // DAA http://www.worldofspectrum.org/faq/reference/z80reference.htm#DAA
-                               case 0x27: {
-                                       u8 corr_factor = 0;
-                                       if (regs.A > 0x99 || check_flag(CARRY_FLAG)) {
-                                               corr_factor = 0x60;
-                                               set_flag(CARRY_FLAG);
-                                       } else {
-                                               reset_flag(CARRY_FLAG);
-                                       }
+                                       // DAA http://www.worldofspectrum.org/faq/reference/z80reference.htm#DAA
+                                       case 0x27: {
+                                               u8 corr_factor = 0;
+                                               if (regs.A > 0x99 || check_flag(CARRY_FLAG)) {
+                                                       corr_factor = 0x60;
+                                                       set_flag(CARRY_FLAG);
+                                               } else {
+                                                       reset_flag(CARRY_FLAG);
+                                               }
 
-                                       if (regs.A & 0x0F > 9 || check_flag(HALF_CARRY_FLAG)) {
-                                               corr_factor |= 0x06;
-                                       }
+                                               if (regs.A & 0x0F > 9 || check_flag(HALF_CARRY_FLAG)) {
+                                                       corr_factor |= 0x06;
+                                               }
+
+                                               if (!check_flag(ADD_SUB_FLAG)) {
+                                                       regs.A += corr_factor;
+                                               } else {
+                                                       regs.A -= corr_factor;
+                                               }
 
-                                       if (!check_flag(ADD_SUB_FLAG)) {
-                                               regs.A += corr_factor;
-                                       } else {
-                                               regs.A -= corr_factor;
+                                               set_flag_if(regs.A==0, ZERO_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG); // GBCPUman.pdf contradicts previous reference :P
+                                               cycles_until_next_instruction = 4; 
+                                               break;
                                        }
 
-                                       set_flag_if(regs.A==0, ZERO_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG); // GBCPUman.pdf contradicts previous reference :P
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
+                                       // CPL
+                                       case 0x2F:
+                                               regs.A = ~regs.A;
+                                               set_flag(HALF_CARRY_FLAG);
+                                               set_flag(ADD_SUB_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                               // CPL
-                               case 0x2F:
-                                       regs.A = ~regs.A;
-                                       set_flag(HALF_CARRY_FLAG);
-                                       set_flag(ADD_SUB_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       // CCF
+                                       case 0x3F:
+                                               if (check_flag(CARRY_FLAG))
+                                                       reset_flag(CARRY_FLAG);
+                                               else
+                                                       set_flag(CARRY_FLAG);
 
-                               // CCF
-                               case 0x3F:
-                                       if (check_flag(CARRY_FLAG))
-                                               reset_flag(CARRY_FLAG);
-                                       else
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+
+                                       // SCF
+                                       case 0x37:
                                                set_flag(CARRY_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       // NOP
+                                       case 0x00:
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                               // SCF
-                               case 0x37:
-                                       set_flag(CARRY_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       // HALT
+                                       case 0x76:
+                                               HALT = true;
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                               // NOP
-                               case 0x00:
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       // STOP
+                                       case 0x10: {
+                                               int sub_opcode = memory.read(regs.PC++);
+                                               if (sub_opcode == 0x00) {
+                                                       HALT = true;
+                                               } else {
+                                                       logger.critical("Unknown sub-opcode ", 
+                                                               std::hex, std::setw(2), std::setfill('0'),
+                                                               sub_opcode, " after 0x10");
+                                               }
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+                                       }
+                                       
+                                       // Rotates and shifts
+                                       // RLCA
+                                       case 0x07: {
+                                               u8 bit7 = regs.A >>7;
+                                               regs.A = (regs.A << 1) | bit7;
+                                               set_flag_if(regs.A == 0, ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               // TODO: Check which of GBCPUman.pdf or
+                                               // worldofspectrum z80 reference is correct
+                                               //
+                                               //set_flag_if(bit7, CARRY_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+                                       }
 
-                               // HALT
-                               case 0x76:
-                                       HALT = true;
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       // RLA (through carry)
+                                       case 0x17: {
+                                               u8 bit7 = regs.A >> 7;
+                                               regs.A = (regs.A << 1) | check_flag(CARRY_FLAG);
+                                               set_flag_if(bit7, CARRY_FLAG);
+                                               set_flag_if(regs.A == 0, ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+                                       }
+                                       
+                                       // RRCA
+                                       case 0x0F: {
+                                               u8 bit0 = regs.A & 1;
+                                               regs.A = (regs.A >> 1) | (bit0 << 7);
+                                               set_flag_if(regs.A == 0, ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               // TODO: Check which of GBCPUman.pdf or
+                                               // worldofspectrum z80 reference is correct
+                                               //
+                                               //set_flag_if(bit0, CARRY_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+                                       }
 
-                               // STOP
-                               case 0x10: {
-                                       int sub_opcode = memory.read(regs.PC++);
-                                       if (sub_opcode == 0x00) {
-                                               HALT = true;
-                                       } else {
-                                               logger.critical("Unknown sub-opcode ", 
-                                                       std::hex, std::setw(2), std::setfill('0'),
-                                                       sub_opcode, " after 0x10");
+                                       // RRA (through carry)
+                                       case 0x1F: {
+                                               u8 bit0 = regs.A & 1;
+                                               regs.A = (regs.A >> 1) | (check_flag(CARRY_FLAG) << 7);
+                                               set_flag_if(bit0, CARRY_FLAG);
+                                               set_flag_if(regs.A == 0, ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 4; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
-                               
-                               // Rotates and shifts
-                               // RLCA
-                               case 0x07: {
-                                       u8 bit7 = regs.A >>7;
-                                       regs.A = (regs.A << 1) | bit7;
-                                       set_flag_if(regs.A == 0, ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       // TODO: Check which of GBCPUman.pdf or
-                                       // worldofspectrum z80 reference is correct
-                                       //
-                                       //set_flag_if(bit7, CARRY_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
 
-                               // RLA (through carry)
-                               case 0x17: {
-                                       u8 bit7 = regs.A >> 7;
-                                       regs.A = (regs.A << 1) | check_flag(CARRY_FLAG);
-                                       set_flag_if(bit7, CARRY_FLAG);
-                                       set_flag_if(regs.A == 0, ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
-                               
-                               // RRCA
-                               case 0x0F: {
-                                       u8 bit0 = regs.A & 1;
-                                       regs.A = (regs.A >> 1) | (bit0 << 7);
-                                       set_flag_if(regs.A == 0, ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       // TODO: Check which of GBCPUman.pdf or
-                                       // worldofspectrum z80 reference is correct
-                                       //
-                                       //set_flag_if(bit0, CARRY_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
+                                       
+                                       // JR n
+                                       case 0x18:
+                                               // -1 because PC is now pointing past the opcode
+                                               regs.PC += static_cast<s8>(memory.read(regs.PC++));
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               // RRA (through carry)
-                               case 0x1F: {
-                                       u8 bit0 = regs.A & 1;
-                                       regs.A = (regs.A >> 1) | (check_flag(CARRY_FLAG) << 7);
-                                       set_flag_if(bit0, CARRY_FLAG);
-                                       set_flag_if(regs.A == 0, ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                               }
+                                       // JR cc, n
+                                       case 0x20: { // JR NZ, n
+                                               s8 offset = static_cast<s8>(memory.read(regs.PC++));
+                                               if (!check_flag(ZERO_FLAG)) 
+                                                       regs.PC += offset;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       }
 
-                               
-                               // JR n
-                               case 0x18:
-                                       // -1 because PC is now pointing past the opcode
-                                       regs.PC += static_cast<s8>(memory.read(regs.PC++));
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       case 0x28: { // JR Z, n
+                                               s8 offset = static_cast<s8>(memory.read(regs.PC++));
+                                               if (check_flag(ZERO_FLAG)) 
+                                                       regs.PC += offset;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       }
 
-                               // JR cc, n
-                               case 0x20: { // JR NZ, n
-                                       s8 offset = static_cast<s8>(memory.read(regs.PC++));
-                                       if (!check_flag(ZERO_FLAG)) 
-                                               regs.PC += offset;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               }
+                                       case 0x30: { // JR NC, n
+                                               s8 offset = static_cast<s8>(memory.read(regs.PC++));
+                                               if (!check_flag(CARRY_FLAG)) 
+                                                       regs.PC += offset;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       }
 
-                               case 0x28: { // JR Z, n
-                                       s8 offset = static_cast<s8>(memory.read(regs.PC++));
-                                       if (check_flag(ZERO_FLAG)) 
-                                               regs.PC += offset;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               }
+                                       case 0x38: { // JR C, n
+                                               s8 offset = static_cast<s8>(memory.read(regs.PC++));
+                                               if (check_flag(CARRY_FLAG)) 
+                                                       regs.PC += offset;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       }
 
-                               case 0x30: { // JR NC, n
-                                       s8 offset = static_cast<s8>(memory.read(regs.PC++));
-                                       if (!check_flag(CARRY_FLAG)) 
-                                               regs.PC += offset;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               }
 
-                               case 0x38: { // JR C, n
-                                       s8 offset = static_cast<s8>(memory.read(regs.PC++));
-                                       if (check_flag(CARRY_FLAG)) 
-                                               regs.PC += offset;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               }
+                               
+                                       default:
+                                               std::ostringstream errmsg;
+                                               errmsg << "Unknown opcode 0x";
+                                               errmsg << std::hex << std::setw(2) << std::setfill('0') << opcode;
+                                               errmsg << " at 0x" << std::hex << std::setw(4) << regs.PC-1;
+                                               errmsg << " (cycle count = " << std::dec << cycle_count << ")";
+                                               logger.critical(errmsg.str());
+                                               break;
 
+                               } // end switch
+                               break;
+                               case 0x80:
+                               switch(opcode)
+                               {
+                                       case 0xFA: // LD A, (nn)
+                                               regs.A = memory.read(memory.read16(regs.PC));
+                                               regs.PC+=2;
+                                               cycles_until_next_instruction = 16; 
+                                               break;
+                                       case 0xEA: // LD (nn), A
+                                               memory.write(memory.read16(regs.PC), regs.A);
+                                               regs.PC+=2;
+                                               cycles_until_next_instruction = 16; 
+                                               break;
 
-                       
-                               default:
-                                       std::ostringstream errmsg;
-                                       errmsg << "Unknown opcode 0x";
-                                       errmsg << std::hex << std::setw(2) << std::setfill('0') << opcode;
-                                       errmsg << " at 0x" << std::hex << std::setw(4) << regs.PC-1;
-                                       errmsg << " (cycle count = " << std::dec << cycle_count << ")";
-                                       logger.critical(errmsg.str());
-                                       break;
+                                       // LD A, (C)
+                                       case 0xF2:
+                                               regs.A = memory.read(0xFF00 + regs.C);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       // LD (C), A
+                                       case 0xE2:
+                                               memory.write(0xFF00 + regs.C, regs.A);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       // LDH (n), A
+                                       case 0xE0: {
+                                               memory.high[memory.read(regs.PC++)] =  regs.A;
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       }
+                                       // LDH A, (n)
+                                       case 0xF0:
+                                               regs.A = memory.high[memory.read(regs.PC++)];
+                                               cycles_until_next_instruction = 12; 
+                                               break;
 
-                       } // end switch
-                       break;
-                       case 0x80:
-                       switch(opcode)
-                       {
-                               case 0xFA: // LD A, (nn)
-                                       regs.A = memory.read(memory.read16(regs.PC));
-                                       regs.PC+=2;
-                                       cycles_until_next_instruction = 16; 
-                                       break;
-                               case 0xEA: // LD (nn), A
-                                       memory.write(memory.read16(regs.PC), regs.A);
-                                       regs.PC+=2;
-                                       cycles_until_next_instruction = 16; 
-                                       break;
+                                       // LD SP, HL
+                                       case 0xF9:
+                                               regs.SP = regs.HL;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               // LD A, (C)
-                               case 0xF2:
-                                       regs.A = memory.read(0xFF00 + regs.C);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               // LD (C), A
-                               case 0xE2:
-                                       memory.write(0xFF00 + regs.C, regs.A);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               // LDH (n), A
-                               case 0xE0: {
-                                       memory.high[memory.read(regs.PC++)] =  regs.A;
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
-                               // LDH A, (n)
-                               case 0xF0:
-                                       regs.A = memory.high[memory.read(regs.PC++)];
-                                       cycles_until_next_instruction = 12; 
-                                       break;
+                                       // LD HL, SP+n
+                                       // LDHL SP, n
+                                       case 0xF8: {
+                                               s8 offset = memory.read(regs.PC++);
+                                               int res = regs.SP + offset;
+                                               
+                                               // TODO: Verificar si los flags van asi
+                                               set_flag_if (res > 0xFFFF, CARRY_FLAG);
 
-                               // LD SP, HL
-                               case 0xF9:
-                                       regs.SP = regs.HL;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                               // TODO: hacer lo apropiado con el half-carry flag
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(ZERO_FLAG);
 
-                               // LD HL, SP+n
-                               // LDHL SP, n
-                               case 0xF8: {
-                                       s8 offset = memory.read(regs.PC++);
-                                       int res = regs.SP + offset;
+                                               regs.HL = static_cast<u16>(res & 0xFFFF);
+                                               cycles_until_next_instruction = 12; 
+                                               break; 
+                                               }
+
+                                       // PUSH nn
+                                       PUSH(0xF5, A, flags)
+                                       PUSH(0xC5, B, C)
+                                       PUSH(0xD5, D, E)
+                                       PUSH(0xE5, H, L)
+
+                                       // POP nn
+                                       POP(0xF1, A, flags)
+                                       POP(0xC1, B, C)
+                                       POP(0xD1, D, E)
+                                       POP(0xE1, H, L)
+
+                                       // 8-bit ALU
+                                       // ADD A,reg
+                                       for_each_register(0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, ADD_A_reg)
                                        
-                                       // TODO: Verificar si los flags van asi
-                                       set_flag_if (res > 0xFFFF, CARRY_FLAG);
+                                       case 0x86: {// ADD A, (HL)
+                                               int res = regs.A + memory.read(regs.HL);
+                                               int half_res = (regs.A & 0x0F) + (memory.read(regs.HL) & 0x0F);
+                                               regs.A = static_cast<u8>(res);
+                                               
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res > 0xFF,      CARRY_FLAG);
+                                               set_flag_if (regs.A == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
+                                       case 0xC6: {//ADD A, #
+                                               int inm = memory.read(regs.PC++);
+                                               int res = regs.A + inm;
+                                               int half_res = (regs.A & 0x0F) + (inm & 0x0F);
+                                               regs.A = static_cast<u8>(res);
+                                               
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res > 0xFF,      CARRY_FLAG);
+                                               set_flag_if (regs.A == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
 
-                                       // TODO: hacer lo apropiado con el half-carry flag
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(ZERO_FLAG);
+                                       // ADC A, n
+                                       for_each_register(0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, ADC_A_reg)
 
-                                       regs.HL = static_cast<u16>(res & 0xFFFF);
-                                       cycles_until_next_instruction = 12; 
-                                       break; 
-                                       }
+                                       case 0x8E: {// ADC A, (HL)
+                                               int carry = (check_flag(CARRY_FLAG)? 1 : 0);
+                                               int res = regs.A + memory.read(regs.HL) + carry;
+                                               int half_res = (regs.A & 0x0F) + (memory.read(regs.HL) & 0x0F) + carry;
+                                               regs.A = static_cast<u8>(res);
+                                               
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res > 0xFF,      CARRY_FLAG);
+                                               set_flag_if (regs.A == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
+                                       case 0xCE: {//ADC A, #
+                                               int carry = (check_flag(CARRY_FLAG)? 1 : 0);
+                                               int inm = memory.read(regs.PC++);
+                                               int res = regs.A + inm + carry;
+                                               int half_res = (regs.A & 0x0F) + (inm & 0x0F) + carry;
+                                               regs.A = static_cast<u8>(res);
+                                               
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res > 0xFF,      CARRY_FLAG);
+                                               set_flag_if (regs.A == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
 
-                               // PUSH nn
-                               PUSH(0xF5, A, flags)
-                               PUSH(0xC5, B, C)
-                               PUSH(0xD5, D, E)
-                               PUSH(0xE5, H, L)
-
-                               // POP nn
-                               POP(0xF1, A, flags)
-                               POP(0xC1, B, C)
-                               POP(0xD1, D, E)
-                               POP(0xE1, H, L)
-
-                               // 8-bit ALU
-                               // ADD A,reg
-                               for_each_register(0x87, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, ADD_A_reg)
-                               
-                               case 0x86: {// ADD A, (HL)
-                                       int res = regs.A + memory.read(regs.HL);
-                                       int half_res = (regs.A & 0x0F) + (memory.read(regs.HL) & 0x0F);
-                                       regs.A = static_cast<u8>(res);
-                                       
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res > 0xFF,      CARRY_FLAG);
-                                       set_flag_if (regs.A == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
-                               case 0xC6: {//ADD A, #
-                                       int inm = memory.read(regs.PC++);
-                                       int res = regs.A + inm;
-                                       int half_res = (regs.A & 0x0F) + (inm & 0x0F);
-                                       regs.A = static_cast<u8>(res);
-                                       
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res > 0xFF,      CARRY_FLAG);
-                                       set_flag_if (regs.A == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
+                                       // SUB n
+                                       for_each_register(0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, SUB_reg)
 
-                               // ADC A, n
-                               for_each_register(0x8F, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, ADC_A_reg)
+                                       case 0x96: {//SUB (HL)
+                                               int res = regs.A - memory.read(regs.HL);
+                                               int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F);
+                                               regs.A = static_cast<u8>(res);
 
-                               case 0x8E: {// ADC A, (HL)
-                                       int carry = (check_flag(CARRY_FLAG)? 1 : 0);
-                                       int res = regs.A + memory.read(regs.HL) + carry;
-                                       int half_res = (regs.A & 0x0F) + (memory.read(regs.HL) & 0x0F) + carry;
-                                       regs.A = static_cast<u8>(res);
-                                       
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res > 0xFF,      CARRY_FLAG);
-                                       set_flag_if (regs.A == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
-                               case 0xCE: {//ADC A, #
-                                       int carry = (check_flag(CARRY_FLAG)? 1 : 0);
-                                       int inm = memory.read(regs.PC++);
-                                       int res = regs.A + inm + carry;
-                                       int half_res = (regs.A & 0x0F) + (inm & 0x0F) + carry;
-                                       regs.A = static_cast<u8>(res);
+                                               set_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res < 0,      CARRY_FLAG);
+                                               set_flag_if (res == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res < 0, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
                                        
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res > 0xFF,      CARRY_FLAG);
-                                       set_flag_if (regs.A == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res > 0x0F, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
-
-                               // SUB n
-                               for_each_register(0x97, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, SUB_reg)
-
-                               case 0x96: {//SUB (HL)
-                                       int res = regs.A - memory.read(regs.HL);
-                                       int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F);
-                                       regs.A = static_cast<u8>(res);
+                                       case 0xD6: {//SUB #
+                                               int inm = memory.read(regs.PC++);
+                                               int res = regs.A - inm;
+                                               int half_res = (regs.A & 0x0F) - (inm & 0x0F);
+                                               regs.A = static_cast<u8>(res);
+
+                                               set_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res < 0,      CARRY_FLAG);
+                                               set_flag_if (res == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res < 0, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
 
-                                       set_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res < 0,      CARRY_FLAG);
-                                       set_flag_if (res == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res < 0, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
-                               
-                               case 0xD6: {//SUB #
-                                       int inm = memory.read(regs.PC++);
-                                       int res = regs.A - inm;
-                                       int half_res = (regs.A & 0x0F) - (inm & 0x0F);
-                                       regs.A = static_cast<u8>(res);
-
-                                       set_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res < 0,      CARRY_FLAG);
-                                       set_flag_if (res == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res < 0, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
+                                       // SBC n
+                                       for_each_register(0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, SBC_reg)
 
-                               // SBC n
-                               for_each_register(0x9F, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, SBC_reg)
+                                       case 0x9E: {//SBC (HL)
+                                               int carry = (check_flag(CARRY_FLAG)? 1 : 0);
+                                               int res = regs.A - memory.read(regs.HL) - carry;
+                                               int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F) - carry;
+                                               regs.A = static_cast<u8>(res);
 
-                               case 0x9E: {//SBC (HL)
-                                       int carry = (check_flag(CARRY_FLAG)? 1 : 0);
-                                       int res = regs.A - memory.read(regs.HL) - carry;
-                                       int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F) - carry;
-                                       regs.A = static_cast<u8>(res);
+                                               set_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res < 0,      CARRY_FLAG);
+                                               set_flag_if (res == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res < 0, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
 
-                                       set_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res < 0,      CARRY_FLAG);
-                                       set_flag_if (res == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res < 0, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
+                                       // There is no SBC inm
 
-                               // There is no SBC inm
+                                       // AND n
+                                       for_each_register(0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, AND_reg)
 
-                               // AND n
-                               for_each_register(0xA7, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, AND_reg)
+                                       case 0xA6: //AND (HL)
+                                               regs.A &= memory.read(regs.HL);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xA6: //AND (HL)
-                                       regs.A &= memory.read(regs.HL);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       case 0xE6: //AND inm
+                                               regs.A &= memory.read(regs.PC++);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xE6: //AND inm
-                                       regs.A &= memory.read(regs.PC++);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // OR n
+                                       for_each_register(0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, OR_reg)
 
-                               // OR n
-                               for_each_register(0xB7, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, OR_reg)
+                                       case 0xB6: //OR (HL)
+                                               regs.A |= memory.read(regs.HL);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xB6: //OR (HL)
-                                       regs.A |= memory.read(regs.HL);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       case 0xF6: //OR inm
+                                               regs.A |= memory.read(regs.PC++);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xF6: //OR inm
-                                       regs.A |= memory.read(regs.PC++);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // XOR n
+                                       for_each_register(0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, XOR_reg)
 
-                               // XOR n
-                               for_each_register(0xAF, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, XOR_reg)
+                                       case 0xAE: //XOR (HL)
+                                               regs.A ^= memory.read(regs.HL);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xAE: //XOR (HL)
-                                       regs.A ^= memory.read(regs.HL);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       case 0xEE: //XOR inm
+                                               regs.A ^= memory.read(regs.PC++);
+                                               if (regs.A == 0) set_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               reset_flag(HALF_CARRY_FLAG);
+                                               reset_flag(CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                       
+                                       // CP n
+                                       for_each_register(0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, CP_reg)
+
+                                       case 0xBE: {//CP (HL)
+                                               int res = regs.A - memory.read(regs.HL);
+                                               int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F);
+
+                                               set_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res < 0,      CARRY_FLAG);
+                                               set_flag_if (res == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res < 0, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
+                                       
+                                       case 0xFE: {//CP #
+                                               int inm = memory.read(regs.PC++);
+                                               int res = regs.A - inm;
+                                               int half_res = (regs.A & 0x0F) - (inm & 0x0F);
+
+                                               set_flag(ADD_SUB_FLAG);
+                                               set_flag_if (res < 0,      CARRY_FLAG);
+                                               set_flag_if (res == 0,     ZERO_FLAG);
+                                               set_flag_if (half_res < 0, HALF_CARRY_FLAG);
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+                                               }
 
-                               case 0xEE: //XOR inm
-                                       regs.A ^= memory.read(regs.PC++);
-                                       if (regs.A == 0) set_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       reset_flag(HALF_CARRY_FLAG);
-                                       reset_flag(CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               
-                               // CP n
-                               for_each_register(0xBF, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, CP_reg)
-
-                               case 0xBE: {//CP (HL)
-                                       int res = regs.A - memory.read(regs.HL);
-                                       int half_res = (regs.A & 0x0F) - (memory.read(regs.HL) & 0x0F);
-
-                                       set_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res < 0,      CARRY_FLAG);
-                                       set_flag_if (res == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res < 0, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                                       }
-                               
-                               case 0xFE: {//CP #
-                                       int inm = memory.read(regs.PC++);
-                                       int res = regs.A - inm;
-                                       int half_res = (regs.A & 0x0F) - (inm & 0x0F);
-
-                                       set_flag(ADD_SUB_FLAG);
-                                       set_flag_if (res < 0,      CARRY_FLAG);
-                                       set_flag_if (res == 0,     ZERO_FLAG);
-                                       set_flag_if (half_res < 0, HALF_CARRY_FLAG);
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // ADD SP, #
+                                       case 0xE8: {
+                                               // FIXME: No se que hacer con el half carry, en 4 o en 11?
+                                               int n = static_cast<s8>(memory.read(regs.PC++));
+                                               int res = regs.SP + n;
+                                               regs.SP = static_cast<u8>(res);
+                                               reset_flag(ZERO_FLAG);
+                                               reset_flag(ADD_SUB_FLAG);
+                                               set_flag_if(res > 0xFFFF, CARRY_FLAG);
+                                               cycles_until_next_instruction = 16; 
+                                               break;
                                        }
 
-                               // ADD SP, #
-                               case 0xE8: {
-                                       // FIXME: No se que hacer con el half carry, en 4 o en 11?
-                                       int n = static_cast<s8>(memory.read(regs.PC++));
-                                       int res = regs.SP + n;
-                                       regs.SP = static_cast<u8>(res);
-                                       reset_flag(ZERO_FLAG);
-                                       reset_flag(ADD_SUB_FLAG);
-                                       set_flag_if(res > 0xFFFF, CARRY_FLAG);
-                                       cycles_until_next_instruction = 16; 
-                                       break;
-                               }
-
-                               // Miscellaneous instructions
-                               case 0xCB: {
-                                       int sub_opcode = memory.read(regs.PC++);
-                                       switch(sub_opcode)
-                                       {
-                                               // SWAP n
-                                               for_each_register(0x37, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, SWAP_reg)
-
-                                               // SWAP (HL)
-                                               case 0x36: {
-                                                       u8 tmp = memory.read(regs.HL);
-                                                       tmp = ((tmp & 0x0F) << 4) | ((tmp & 0xF0)>>4);
-                                                       memory.write(regs.HL, tmp);
-                               
-                                                       set_flag_if(tmp==0, ZERO_FLAG);
-                                                       reset_flag(CARRY_FLAG);
-                                                       reset_flag(HALF_CARRY_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG);
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                       // Miscellaneous instructions
+                                       case 0xCB: {
+                                               int sub_opcode = memory.read(regs.PC++);
+                                               switch(sub_opcode)
+                                               {
+                                                       // SWAP n
+                                                       for_each_register(0x37, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, SWAP_reg)
+
+                                                       // SWAP (HL)
+                                                       case 0x36: {
+                                                               u8 tmp = memory.read(regs.HL);
+                                                               tmp = ((tmp & 0x0F) << 4) | ((tmp & 0xF0)>>4);
+                                                               memory.write(regs.HL, tmp);
+                                       
+                                                               set_flag_if(tmp==0, ZERO_FLAG);
+                                                               reset_flag(CARRY_FLAG);
+                                                               reset_flag(HALF_CARRY_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG);
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               // RLC n
-                                               for_each_register(0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, RLC_reg)
-
-                                               // RLC (HL)
-                                               case 0x06: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       u8 bit7 = value >> 7;
-                                                       value = (value << 1) | bit7;
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(value == 0, ZERO_FLAG); 
-                                                       reset_flag(ADD_SUB_FLAG); 
-                                                       reset_flag(HALF_CARRY_FLAG); 
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                                       // RLC n
+                                                       for_each_register(0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, RLC_reg)
+
+                                                       // RLC (HL)
+                                                       case 0x06: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               u8 bit7 = value >> 7;
+                                                               value = (value << 1) | bit7;
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(value == 0, ZERO_FLAG); 
+                                                               reset_flag(ADD_SUB_FLAG); 
+                                                               reset_flag(HALF_CARRY_FLAG); 
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               // RL n (through carry)
-                                               for_each_register(0x17, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, RL_reg)
-
-                                               // RL (HL) (through carry)
-                                               case 0x16: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       u8 bit7 = value >> 7;
-                                                       value = (value << 1) | check_flag(CARRY_FLAG);
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(bit7, CARRY_FLAG);
-                                                       set_flag_if(value == 0, ZERO_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG); 
-                                                       reset_flag(HALF_CARRY_FLAG); 
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                                       // RL n (through carry)
+                                                       for_each_register(0x17, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, RL_reg)
+
+                                                       // RL (HL) (through carry)
+                                                       case 0x16: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               u8 bit7 = value >> 7;
+                                                               value = (value << 1) | check_flag(CARRY_FLAG);
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(bit7, CARRY_FLAG);
+                                                               set_flag_if(value == 0, ZERO_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG); 
+                                                               reset_flag(HALF_CARRY_FLAG); 
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               // RRC n
-                                               for_each_register(0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, RRC_reg)
-
-                                               // RRC (HL)
-                                               case 0x0E: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       u8 bit0 = value & 1;
-                                                       value = (value >> 1) | (bit0 << 7);
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(value == 0, ZERO_FLAG); 
-                                                       reset_flag(ADD_SUB_FLAG); 
-                                                       reset_flag(HALF_CARRY_FLAG); 
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                                       // RRC n
+                                                       for_each_register(0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, RRC_reg)
+
+                                                       // RRC (HL)
+                                                       case 0x0E: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               u8 bit0 = value & 1;
+                                                               value = (value >> 1) | (bit0 << 7);
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(value == 0, ZERO_FLAG); 
+                                                               reset_flag(ADD_SUB_FLAG); 
+                                                               reset_flag(HALF_CARRY_FLAG); 
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               // RR n (through carry)
-                                               for_each_register(0x1F, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, RR_reg)
-
-                                               // RR (HL) (through carry)
-                                               case 0x1E: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       u8 bit0 = value & 1;
-                                                       value = (value >> 1) | (check_flag(CARRY_FLAG) << 7);
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(bit0, CARRY_FLAG);
-                                                       set_flag_if(value == 0, ZERO_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG); 
-                                                       reset_flag(HALF_CARRY_FLAG); 
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
-                                               
-                                               // SLA n
-                                               for_each_register(0x27, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, SLA_reg)
-
-                                               // SLA (HL)
-                                               case 0x26: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       bool carry = (value & 0x80) != 0;
-                                                       value <<= 1;
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(value == 0, ZERO_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG);
-                                                       reset_flag(HALF_CARRY_FLAG);
-                                                       set_flag_if(carry, CARRY_FLAG);
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
-                                               
-                                               // SRA n
-                                               for_each_register(0x2F, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, SRA_reg)
-
-                                               // SRA (HL)
-                                               case 0x2E: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       bool carry = (value & 0x01) != 0;
-                                                       u8 MSB = value & 0x80;
-                                                       value = (value >> 1) | MSB;
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(value == 0, ZERO_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG);
-                                                       reset_flag(HALF_CARRY_FLAG);
-                                                       set_flag_if(carry, CARRY_FLAG);
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                                       // RR n (through carry)
+                                                       for_each_register(0x1F, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, RR_reg)
+
+                                                       // RR (HL) (through carry)
+                                                       case 0x1E: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               u8 bit0 = value & 1;
+                                                               value = (value >> 1) | (check_flag(CARRY_FLAG) << 7);
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(bit0, CARRY_FLAG);
+                                                               set_flag_if(value == 0, ZERO_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG); 
+                                                               reset_flag(HALF_CARRY_FLAG); 
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
+                                                       
+                                                       // SLA n
+                                                       for_each_register(0x27, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, SLA_reg)
+
+                                                       // SLA (HL)
+                                                       case 0x26: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               bool carry = (value & 0x80) != 0;
+                                                               value <<= 1;
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(value == 0, ZERO_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG);
+                                                               reset_flag(HALF_CARRY_FLAG);
+                                                               set_flag_if(carry, CARRY_FLAG);
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
+                                                       
+                                                       // SRA n
+                                                       for_each_register(0x2F, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, SRA_reg)
+
+                                                       // SRA (HL)
+                                                       case 0x2E: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               bool carry = (value & 0x01) != 0;
+                                                               u8 MSB = value & 0x80;
+                                                               value = (value >> 1) | MSB;
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(value == 0, ZERO_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG);
+                                                               reset_flag(HALF_CARRY_FLAG);
+                                                               set_flag_if(carry, CARRY_FLAG);
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               // SRL n
-                                               for_each_register(0x3F, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, SRL_reg)
-
-                                               // SRL (HL)
-                                               case 0x3E: {
-                                                       u8 value = memory.read(regs.HL);
-                                                       bool carry = (value & 0x01) != 0;
-                                                       value >>= 1;
-                                                       memory.write(regs.HL, value);
-                                                       set_flag_if(value == 0, ZERO_FLAG);
-                                                       reset_flag(ADD_SUB_FLAG);
-                                                       reset_flag(HALF_CARRY_FLAG);
-                                                       set_flag_if(carry, CARRY_FLAG);
-                                                       cycles_until_next_instruction = 16; 
-                                                       break;
-                                               }
+                                                       // SRL n
+                                                       for_each_register(0x3F, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, SRL_reg)
+
+                                                       // SRL (HL)
+                                                       case 0x3E: {
+                                                               u8 value = memory.read(regs.HL);
+                                                               bool carry = (value & 0x01) != 0;
+                                                               value >>= 1;
+                                                               memory.write(regs.HL, value);
+                                                               set_flag_if(value == 0, ZERO_FLAG);
+                                                               reset_flag(ADD_SUB_FLAG);
+                                                               reset_flag(HALF_CARRY_FLAG);
+                                                               set_flag_if(carry, CARRY_FLAG);
+                                                               cycles_until_next_instruction = 16; 
+                                                               break;
+                                                       }
 
-                                               default: {
-                                                       int bit_op = sub_opcode >> 6;
-                                                       int reg = sub_opcode & 7;
-                                                       int b   = (sub_opcode >> 3) & 7;
-                                                       bool res;
-                                                       switch (bit_op)
-                                                       {
-                                                               case 1: // BIT
-                                                                       switch(reg)
-                                                                       {
-                                                                               case 0:
-                                                                                       res = check_bit(regs.B, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 1:
-                                                                                       res = check_bit(regs.C, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 2:
-                                                                                       res = check_bit(regs.D, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 3:
-                                                                                       res = check_bit(regs.E, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 4:
-                                                                                       res = check_bit(regs.H, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 5:
-                                                                                       res = check_bit(regs.L, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 6:
-                                                                                       res = check_bit(memory.read(regs.HL), b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 16; 
-                                                                                       break;
-                                                                               case 7:
-                                                                                       res = check_bit(regs.A, b);
-                                                                                       set_flag_if(res == false, ZERO_FLAG);
-                                                                                       reset_flag(ADD_SUB_FLAG);
-                                                                                       set_flag(HALF_CARRY_FLAG);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                       }
-                                                                       break;
-
-                                                               case 2: // RES
-                                                                       switch(reg)
-                                                                       {
-                                                                               case 0:
-                                                                                       regs.B = reset_bit(regs.B, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 1:
-                                                                                       regs.C = reset_bit(regs.C, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 2:
-                                                                                       regs.D = reset_bit(regs.D, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 3:
-                                                                                       regs.E = reset_bit(regs.E, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 4:
-                                                                                       regs.H = reset_bit(regs.H, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 5:
-                                                                                       regs.L = reset_bit(regs.L, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 6:
-                                                                                       memory.write(regs.HL, reset_bit(memory.read(regs.HL), b));
-                                                                                       cycles_until_next_instruction = 16; 
-                                                                                       break;
-                                                                               case 7:
-                                                                                       regs.A = reset_bit(regs.A, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                       }
-                                                                       break;
-
-                                                               case 3: // SET
-                                                                       switch(reg)
-                                                                       {
-                                                                               case 0:
-                                                                                       regs.B = set_bit(regs.B, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 1:
-                                                                                       regs.C = set_bit(regs.C, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 2:
-                                                                                       regs.D = set_bit(regs.D, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 3:
-                                                                                       regs.E = set_bit(regs.E, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 4:
-                                                                                       regs.H = set_bit(regs.H, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 5:
-                                                                                       regs.L = set_bit(regs.L, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                               case 6:
-                                                                                       memory.write(regs.HL, set_bit(memory.read(regs.HL), b));
-                                                                                       cycles_until_next_instruction = 16; 
-                                                                                       break;
-                                                                               case 7:
-                                                                                       regs.A = set_bit(regs.A, b);
-                                                                                       cycles_until_next_instruction = 8; 
-                                                                                       break;
-                                                                       }
-                                                                       break;
-                                                               
-                                                               default:
-                                                                       logger.critical("Unknown sub-opcode after 0xCB");
-                                                                       break;
+                                                       default: {
+                                                               int bit_op = sub_opcode >> 6;
+                                                               int reg = sub_opcode & 7;
+                                                               int b   = (sub_opcode >> 3) & 7;
+                                                               bool res;
+                                                               switch (bit_op)
+                                                               {
+                                                                       case 1: // BIT
+                                                                               switch(reg)
+                                                                               {
+                                                                                       case 0:
+                                                                                               res = check_bit(regs.B, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 1:
+                                                                                               res = check_bit(regs.C, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 2:
+                                                                                               res = check_bit(regs.D, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 3:
+                                                                                               res = check_bit(regs.E, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 4:
+                                                                                               res = check_bit(regs.H, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 5:
+                                                                                               res = check_bit(regs.L, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 6:
+                                                                                               res = check_bit(memory.read(regs.HL), b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 16; 
+                                                                                               break;
+                                                                                       case 7:
+                                                                                               res = check_bit(regs.A, b);
+                                                                                               set_flag_if(res == false, ZERO_FLAG);
+                                                                                               reset_flag(ADD_SUB_FLAG);
+                                                                                               set_flag(HALF_CARRY_FLAG);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                               }
+                                                                               break;
+
+                                                                       case 2: // RES
+                                                                               switch(reg)
+                                                                               {
+                                                                                       case 0:
+                                                                                               regs.B = reset_bit(regs.B, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 1:
+                                                                                               regs.C = reset_bit(regs.C, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 2:
+                                                                                               regs.D = reset_bit(regs.D, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 3:
+                                                                                               regs.E = reset_bit(regs.E, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 4:
+                                                                                               regs.H = reset_bit(regs.H, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 5:
+                                                                                               regs.L = reset_bit(regs.L, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 6:
+                                                                                               memory.write(regs.HL, reset_bit(memory.read(regs.HL), b));
+                                                                                               cycles_until_next_instruction = 16; 
+                                                                                               break;
+                                                                                       case 7:
+                                                                                               regs.A = reset_bit(regs.A, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                               }
+                                                                               break;
+
+                                                                       case 3: // SET
+                                                                               switch(reg)
+                                                                               {
+                                                                                       case 0:
+                                                                                               regs.B = set_bit(regs.B, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 1:
+                                                                                               regs.C = set_bit(regs.C, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 2:
+                                                                                               regs.D = set_bit(regs.D, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 3:
+                                                                                               regs.E = set_bit(regs.E, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 4:
+                                                                                               regs.H = set_bit(regs.H, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 5:
+                                                                                               regs.L = set_bit(regs.L, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                                       case 6:
+                                                                                               memory.write(regs.HL, set_bit(memory.read(regs.HL), b));
+                                                                                               cycles_until_next_instruction = 16; 
+                                                                                               break;
+                                                                                       case 7:
+                                                                                               regs.A = set_bit(regs.A, b);
+                                                                                               cycles_until_next_instruction = 8; 
+                                                                                               break;
+                                                                               }
+                                                                               break;
+                                                                       
+                                                                       default:
+                                                                               logger.critical("Unknown sub-opcode after 0xCB");
+                                                                               break;
+                                                               }
                                                        }
+                                                               
                                                }
-                                                       
+                                               break;
                                        }
-                                       break;
-                               }
-                               // DI
-                               case 0xF3:
-                                       IME = 0;
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-
-                               // EI
-                               case 0xFB:
-                                       IME = 1;
-                                       cycles_until_next_instruction = 4; 
-                                       break;
-                                          
-                               // Jumps
-                               // JP nn
-                               case 0xC3:
-                                       regs.PC = memory.read16(regs.PC);
-                                       cycles_until_next_instruction = 12; 
-                                       break;
+                                       // DI
+                                       case 0xF3:
+                                               IME = 0;
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                               // JP cc, nn
-                               case 0xC2: { // JP NZ, nn
-                                       u16 dst = memory.read16(regs.PC);
-                                       if (!check_flag(ZERO_FLAG))
-                                               regs.PC = dst;
-                                       else
-                                               regs.PC += 2; // if !cc, skip 2 dst bytes
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
+                                       // EI
+                                       case 0xFB:
+                                               IME = 1;
+                                               cycles_until_next_instruction = 4; 
+                                               break;
+                                                  
+                                       // Jumps
+                                       // JP nn
+                                       case 0xC3:
+                                               regs.PC = memory.read16(regs.PC);
+                                               cycles_until_next_instruction = 12; 
+                                               break;
 
-                               case 0xCA: { // JP Z, nn
-                                       u16 dst = memory.read16(regs.PC);
-                                       if (check_flag(ZERO_FLAG))
-                                               regs.PC = dst;
-                                       else
-                                               regs.PC += 2; // if !cc, skip 2 dst bytes
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
+                                       // JP cc, nn
+                                       case 0xC2: { // JP NZ, nn
+                                               u16 dst = memory.read16(regs.PC);
+                                               if (!check_flag(ZERO_FLAG))
+                                                       regs.PC = dst;
+                                               else
+                                                       regs.PC += 2; // if !cc, skip 2 dst bytes
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       }
 
-                               case 0xD2: { // JP NC, nn
-                                       u16 dst = memory.read16(regs.PC);
-                                       if (!check_flag(CARRY_FLAG))
-                                               regs.PC = dst;
-                                       else
-                                               regs.PC += 2; // if !cc, skip 2 dst bytes
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
+                                       case 0xCA: { // JP Z, nn
+                                               u16 dst = memory.read16(regs.PC);
+                                               if (check_flag(ZERO_FLAG))
+                                                       regs.PC = dst;
+                                               else
+                                                       regs.PC += 2; // if !cc, skip 2 dst bytes
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       }
 
-                               case 0xDA: { // JP C, nn
-                                       u16 dst = memory.read16(regs.PC);
-                                       if (check_flag(CARRY_FLAG))
-                                               regs.PC = dst;
-                                       else
-                                               regs.PC += 2; // if !cc, skip 2 dst bytes
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
+                                       case 0xD2: { // JP NC, nn
+                                               u16 dst = memory.read16(regs.PC);
+                                               if (!check_flag(CARRY_FLAG))
+                                                       regs.PC = dst;
+                                               else
+                                                       regs.PC += 2; // if !cc, skip 2 dst bytes
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       }
 
-                               // JP (HL)
-                               case 0xE9:
-                                       regs.PC = regs.HL;
-                                       cycles_until_next_instruction = 4; 
-                                       break;
+                                       case 0xDA: { // JP C, nn
+                                               u16 dst = memory.read16(regs.PC);
+                                               if (check_flag(CARRY_FLAG))
+                                                       regs.PC = dst;
+                                               else
+                                                       regs.PC += 2; // if !cc, skip 2 dst bytes
+                                               cycles_until_next_instruction = 12; 
+                                               break;
+                                       }
 
-                               // Calls
-                               // CALL nn
-                               case 0xCD: {
-                                       u16 addr = memory.read16(regs.PC);
-                                       regs.PC += 2;
-                                       do_call(addr);
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
+                                       // JP (HL)
+                                       case 0xE9:
+                                               regs.PC = regs.HL;
+                                               cycles_until_next_instruction = 4; 
+                                               break;
 
-                               // CALL cc, nn
-                               case 0xC4: { // CALL NZ, nn
-                                       if (!check_flag(ZERO_FLAG)) {
+                                       // Calls
+                                       // CALL nn
+                                       case 0xCD: {
                                                u16 addr = memory.read16(regs.PC);
                                                regs.PC += 2;
                                                do_call(addr);
-                                       } else {
-                                               regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                               cycles_until_next_instruction = 12; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
 
-                               case 0xCC: { // CALL Z, nn
-                                       if (check_flag(ZERO_FLAG)) {
-                                               u16 addr = memory.read16(regs.PC);
-                                               regs.PC += 2;
-                                               do_call(addr);
-                                       } else {
-                                               regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                       // CALL cc, nn
+                                       case 0xC4: { // CALL NZ, nn
+                                               if (!check_flag(ZERO_FLAG)) {
+                                                       u16 addr = memory.read16(regs.PC);
+                                                       regs.PC += 2;
+                                                       do_call(addr);
+                                               } else {
+                                                       regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                               }
+                                               cycles_until_next_instruction = 12; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
 
-                               case 0xD4: { // CALL NC, nn
-                                       if (!check_flag(CARRY_FLAG)) {
-                                               u16 addr = memory.read16(regs.PC);
-                                               regs.PC += 2;
-                                               do_call(addr);
-                                       } else {
-                                               regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                       case 0xCC: { // CALL Z, nn
+                                               if (check_flag(ZERO_FLAG)) {
+                                                       u16 addr = memory.read16(regs.PC);
+                                                       regs.PC += 2;
+                                                       do_call(addr);
+                                               } else {
+                                                       regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                               }
+                                               cycles_until_next_instruction = 12; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
 
-                               case 0xDC: { // CALL C, nn
-                                       if (check_flag(CARRY_FLAG)) {
-                                               u16 addr = memory.read16(regs.PC);
-                                               regs.PC += 2;
-                                               do_call(addr);
-                                       } else {
-                                               regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                       case 0xD4: { // CALL NC, nn
+                                               if (!check_flag(CARRY_FLAG)) {
+                                                       u16 addr = memory.read16(regs.PC);
+                                                       regs.PC += 2;
+                                                       do_call(addr);
+                                               } else {
+                                                       regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                               }
+                                               cycles_until_next_instruction = 12; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 12; 
-                                       break;
-                               }
 
-                               // Restarts
-                               RST(0xC7, 0x00)
-                               RST(0xCF, 0x08)
-                               RST(0xD7, 0x10)
-                               RST(0xDF, 0x18)
-                               RST(0xE7, 0x20)
-                               RST(0xEF, 0x28)
-                               RST(0xF7, 0x30)
-                               RST(0xFF, 0x38)
-
-                               // Returns
-                               // RET
-                               case 0xC9: {
-                                       u16 retaddr = memory.read16(regs.SP);
-                                       regs.SP += 2;
-                                       regs.PC = retaddr;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-                               }
-
-                               // RET cc
-                               case 0xC0:  // RET NZ
-                                       if (!check_flag(ZERO_FLAG)) { 
-                                               u16 retaddr = memory.read16(regs.SP);
-                                               regs.SP += 2;
-                                               regs.PC = retaddr;
+                                       case 0xDC: { // CALL C, nn
+                                               if (check_flag(CARRY_FLAG)) {
+                                                       u16 addr = memory.read16(regs.PC);
+                                                       regs.PC += 2;
+                                                       do_call(addr);
+                                               } else {
+                                                       regs.PC += 2; // if !cc, skip 2 (nn) bytes
+                                               }
+                                               cycles_until_next_instruction = 12; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 8; 
-                                       break;
 
-                               case 0xC8:  // RET Z
-                                       if (check_flag(ZERO_FLAG)) { 
+                                       // Restarts
+                                       RST(0xC7, 0x00)
+                                       RST(0xCF, 0x08)
+                                       RST(0xD7, 0x10)
+                                       RST(0xDF, 0x18)
+                                       RST(0xE7, 0x20)
+                                       RST(0xEF, 0x28)
+                                       RST(0xF7, 0x30)
+                                       RST(0xFF, 0x38)
+
+                                       // Returns
+                                       // RET
+                                       case 0xC9: {
                                                u16 retaddr = memory.read16(regs.SP);
                                                regs.SP += 2;
                                                regs.PC = retaddr;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 8; 
-                                       break;
 
-                               case 0xD0:  // RET NC
-                                       if (!check_flag(CARRY_FLAG)) { 
-                                               u16 retaddr = memory.read16(regs.SP);
-                                               regs.SP += 2;
-                                               regs.PC = retaddr;
-                                       }
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       // RET cc
+                                       case 0xC0:  // RET NZ
+                                               if (!check_flag(ZERO_FLAG)) { 
+                                                       u16 retaddr = memory.read16(regs.SP);
+                                                       regs.SP += 2;
+                                                       regs.PC = retaddr;
+                                               }
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+
+                                       case 0xC8:  // RET Z
+                                               if (check_flag(ZERO_FLAG)) { 
+                                                       u16 retaddr = memory.read16(regs.SP);
+                                                       regs.SP += 2;
+                                                       regs.PC = retaddr;
+                                               }
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+
+                                       case 0xD0:  // RET NC
+                                               if (!check_flag(CARRY_FLAG)) { 
+                                                       u16 retaddr = memory.read16(regs.SP);
+                                                       regs.SP += 2;
+                                                       regs.PC = retaddr;
+                                               }
+                                               cycles_until_next_instruction = 8; 
+                                               break;
 
-                               case 0xD8:  // RET C
-                                       if (check_flag(CARRY_FLAG)) { 
+                                       case 0xD8:  // RET C
+                                               if (check_flag(CARRY_FLAG)) { 
+                                                       u16 retaddr = memory.read16(regs.SP);
+                                                       regs.SP += 2;
+                                                       regs.PC = retaddr;
+                                               }
+                                               cycles_until_next_instruction = 8; 
+                                               break;
+
+                                       // RETI
+                                       case 0xD9: {
+                                               // RET && EI
                                                u16 retaddr = memory.read16(regs.SP);
                                                regs.SP += 2;
                                                regs.PC = retaddr;
+                                               IME=1;
+                                               cycles_until_next_instruction = 8; 
+                                               break;
                                        }
-                                       cycles_until_next_instruction = 8; 
-                                       break;
-
-                               // RETI
-                               case 0xD9: {
-                                       // RET && EI
-                                       u16 retaddr = memory.read16(regs.SP);
-                                       regs.SP += 2;
-                                       regs.PC = retaddr;
-                                       IME=1;
-                                       cycles_until_next_instruction = 8; 
-                                       break;
+                                       
+                                       default:
+                                               std::ostringstream errmsg;
+                                               errmsg << "Unknown opcode 0x";
+                                               errmsg << std::hex << std::setw(2) << std::setfill('0') << opcode;
+                                               errmsg << " at 0x" << std::hex << std::setw(4) << regs.PC-1;
+                                               errmsg << " (cycle count = " << std::dec << cycle_count << ")";
+                                               logger.critical(errmsg.str());
+                                               break;
                                }
-                               
-                               default:
-                                       std::ostringstream errmsg;
-                                       errmsg << "Unknown opcode 0x";
-                                       errmsg << std::hex << std::setw(2) << std::setfill('0') << opcode;
-                                       errmsg << " at 0x" << std::hex << std::setw(4) << regs.PC-1;
-                                       errmsg << " (cycle count = " << std::dec << cycle_count << ")";
-                                       logger.critical(errmsg.str());
-                                       break;
+                               break;
                        }
-                       break;
                }
        }
 
+       // Video
        if (cycles_until_video_update <= 0)
                cycles_until_video_update = video.update();
-       
        cycles_until_video_update -= CYCLE_STEP;
-       cycles_until_next_instruction -= CYCLE_STEP;
        
+       // Divider
+       divider_count++;
+       if (divider_count == 0)
+       {
+               memory.high[GBMemory::I_DIV]++;
+       }
+       
+       // Timer
+       //   Bit 2    - Timer Stop  (0=Stop, 1=Start)
+       //   Bits 1-0 - Input Clock Select
+       //   00:   4096 Hz - every 1024 cycles
+       //   01: 262144 Hz - every 16 cycles
+       //   10:  65536 Hz - every 64 cycles
+       //   11:  16384 Hz - every 256 cycles
+       u8 TAC = memory.high[GBMemory::I_TAC];
+       if (TAC & 0x04)
+       {
+               timer_count++;
+               u32 limit;
+               u32 val = TAC & 0x03;
+               if (val)
+                       limit = 16 << (2*val);
+               else
+                       limit = 1024;
+
+               if (timer_count >= limit)
+               {
+                       timer_count = 0;
+                       if (++memory.high[GBMemory::I_TIMA] == 0)
+                       {
+                               memory.high[GBMemory::I_TIMA] = memory.high[GBMemory::I_TMA];
+                               irq(IRQ_TIMER);
+                       }
+               }
+       }       
+
+
+       cycles_until_next_instruction -= CYCLE_STEP;
        if (cycles_until_next_instruction > 0) return WAIT;
        else return NORMAL;
 }
index 9469d9cfb5f01a56358ac55c9237a935e0fb618a..d8bf8bb55ce4e2686bfb134664d98a1fe137c719 100644 (file)
--- a/gbcore.h
+++ b/gbcore.h
@@ -73,6 +73,8 @@ class GameBoy
        u32 cycle_count;
        u32 cycles_until_video_update;
        u32 cycles_until_next_instruction;
+       u8  divider_count; // resets every 256 cycles, so we don't need a cmp
+       u32 timer_count;
        static const u32 CYCLE_STEP = 4;
        
        inline void do_call(u16 addr)