diff --git a/gameboy/cpu/core/core.cpp b/gameboy/cpu/core/core.cpp index 296c3391..b1eb86cb 100755 --- a/gameboy/cpu/core/core.cpp +++ b/gameboy/cpu/core/core.cpp @@ -1,18 +1,9 @@ #ifdef CPU_CPP +#include "table.cpp" #include "disassembler.cpp" -unsigned opcode_counter = 0; - -void CPU::op_unknown() { - uint8 opcode = bus.read(--r[PC]); - print( - "CPU: unknown opcode [", hex<2>(opcode), "]\n", - "af:", hex<4>(r[AF]), " bc:", hex<4>(r[BC]), " de:", hex<4>(r[DE]), " hl:", hex<4>(r[HL]), " ", - "sp:", hex<4>(r[SP]), " pc:", hex<4>(r[PC]), "\n", - "ly:", decimal<3, ' '>(lcd.status.ly), " exec:", opcode_counter, "\n" - ); - while(true) scheduler.exit(); +void CPU::op_xx() { } void CPU::op_cb() { @@ -34,10 +25,28 @@ template void CPU::op_ld_r_hl() { r[x] = op_read(r[HL]); } +template void CPU::op_ld_hl_r() { + op_write(r[HL], r[x]); +} + void CPU::op_ld_hl_n() { op_write(r[HL], op_read(r[PC]++)); } +template void CPU::op_ld_a_rr() { + r[A] = op_read(r[x]); +} + +void CPU::op_ld_a_nn() { + uint8 lo = op_read(r[PC]++); + uint8 hi = op_read(r[PC]++); + r[A] = op_read((hi << 8) | (lo << 0)); +} + +template void CPU::op_ld_rr_a() { + op_write(r[x], r[A]); +} + void CPU::op_ld_nn_a() { uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); @@ -56,6 +65,11 @@ void CPU::op_ld_ffc_a() { op_write(0xff00 + r[C], r[A]); } +void CPU::op_ldi_hl_a() { + op_write(r[HL], r[A]); + r[HL]++; +} + void CPU::op_ldi_a_hl() { r[A] = op_read(r[HL]); r[HL]++; @@ -66,6 +80,11 @@ void CPU::op_ldd_hl_a() { r[HL]--; } +void CPU::op_ldd_a_hl() { + r[A] = op_read(r[HL]); + r[HL]--; +} + //16-bit load commands template void CPU::op_ld_rr_nn() { @@ -73,6 +92,17 @@ template void CPU::op_ld_rr_nn() { r[x] |= op_read(r[PC]++) << 8; } +void CPU::op_ld_nn_sp() { + uint16 addr = op_read(r[PC]++) << 0; + addr |= op_read(r[PC]++) << 8; + op_write(addr + 0, r[SP] >> 0); + op_write(addr + 1, r[SP] >> 8); +} + +void CPU::op_ld_sp_hl() { + r[SP] = r[HL]; +} + template void CPU::op_push_rr() { op_write(--r[SP], r[x] >> 8); op_write(--r[SP], r[x] >> 0); @@ -86,58 +116,111 @@ template void CPU::op_pop_rr() { //8-bit arithmetic commands -template void CPU::op_add_a_r() { - uint16 rb = (r[A] + r[x]); - uint16 rn = (r[A] & 0x0f) + (r[x] & 0x0f); - r[A] = rb; - r.f.z = (uint8)rb == 0; +void CPU::opi_add_a(uint8 x) { + uint16 rh = r[A] + x; + uint16 rl = (r[A] & 0x0f) + (x & 0x0f); + r[A] = rh; + r.f.z = (uint8)rh == 0; r.f.n = 0; - r.f.h = rn > 0x0f; - r.f.c = rb > 0xff; + r.f.h = rl > 0x0f; + r.f.c = rh > 0xff; } -template void CPU::op_and_r() { - r[A] &= r[x]; - r.f.z = r[A] == 0; +template void CPU::op_add_a_r() { opi_add_a(r[x]); } +void CPU::op_add_a_n() { opi_add_a(op_read(r[PC]++)); } +void CPU::op_add_a_hl() { opi_add_a(op_read(r[HL])); } + +void CPU::opi_adc_a(uint8 x) { + uint16 rh = r[A] + x + r.f.c; + uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c; + r[A] = rh; + r.f.z = (uint8)rh == 0; r.f.n = 0; - r.f.h = 1; - r.f.c = 0; + r.f.h = rl > 0x0f; + r.f.c = rh > 0x0f; } -void CPU::op_and_n() { - r[A] &= op_read(r[PC]++); - r.f.z = r[A] == 0; - r.f.n = 0; - r.f.h = 1; - r.f.c = 0; -} +template void CPU::op_adc_a_r() { opi_adc_a(r[x]); } +void CPU::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); } +void CPU::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); } -template void CPU::op_xor_r() { - r[A] ^= r[x]; - r.f.z = r[A] == 0; - r.f.n = 0; - r.f.h = 0; - r.f.c = 0; -} - -template void CPU::op_or_r() { - r[A] |= r[x]; - r.f.z = r[A] == 0; - r.f.n = 0; - r.f.h = 0; - r.f.c = 0; -} - -void CPU::op_cp_n() { - uint8 data = op_read(r[PC]++); - uint16 rb = (r[A] - data); - uint16 rn = (r[A] & 0x0f) - (data & 0x0f); - r.f.z = (uint8)rb == 0; +void CPU::opi_sub_a(uint8 x) { + uint16 rh = r[A] - x; + uint16 rl = (r[A] & 0x0f) - (x & 0x0f); + r[A] = rh; + r.f.z = (uint8)rh == 0; r.f.n = 1; - r.f.h = rn > 0x0f; - r.f.c = rb > 0xff; + r.f.h = rl > 0x0f; + r.f.c = rh > 0xff; } +template void CPU::op_sub_a_r() { opi_sub_a(r[x]); } +void CPU::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); } +void CPU::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); } + +void CPU::opi_sbc_a(uint8 x) { + uint16 rh = r[A] - x - r.f.c; + uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c; + r[A] = rh; + r.f.z = (uint8)rh == 0; + r.f.n = 1; + r.f.h = rl > 0x0f; + r.f.c = rh > 0xff; +} + +template void CPU::op_sbc_a_r() { opi_sbc_a(r[x]); } +void CPU::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); } +void CPU::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); } + +void CPU::opi_and_a(uint8 x) { + r[A] &= x; + r.f.z = r[A] == 0; + r.f.n = 0; + r.f.h = 1; + r.f.c = 0; +} + +template void CPU::op_and_a_r() { opi_and_a(r[x]); } +void CPU::op_and_a_n() { opi_and_a(op_read(r[PC]++)); } +void CPU::op_and_a_hl() { opi_and_a(op_read(r[HL])); } + +void CPU::opi_xor_a(uint8 x) { + r[A] ^= x; + r.f.z = r[A] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = 0; +} + +template void CPU::op_xor_a_r() { opi_xor_a(r[x]); } +void CPU::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); } +void CPU::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); } + +void CPU::opi_or_a(uint8 x) { + r[A] |= x; + r.f.z = r[A] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = 0; +} + +template void CPU::op_or_a_r() { opi_or_a(r[x]); } +void CPU::op_or_a_n() { opi_or_a(op_read(r[PC]++)); } +void CPU::op_or_a_hl() { opi_or_a(op_read(r[HL])); } + +void CPU::opi_cp_a(uint8 x) { + uint16 rh = r[A] - x; + uint16 rl = (r[A] & 0x0f) - (x & 0x0f); + r.f.z = (uint8)rh == 0; + r.f.n = 1; + r.f.h = rl > 0x0f; + r.f.c = rh > 0x0f; +} + +template void CPU::op_cp_a_r() { opi_cp_a(r[x]); } +void CPU::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); } +void CPU::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); } + template void CPU::op_inc_r() { r[x]++; r.f.z = r[x] == 0; @@ -145,6 +228,14 @@ template void CPU::op_inc_r() { r.f.h = (r[x] & 0x0f) == 0x00; } +void CPU::op_inc_hl() { + uint8 n = op_read(r[HL]); + op_write(r[HL], ++n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = (n & 0x0f) == 0x00; +} + template void CPU::op_dec_r() { r[x]--; r.f.z = r[x] == 0; @@ -152,6 +243,32 @@ template void CPU::op_dec_r() { r.f.h = (r[x] & 0x0f) == 0x0f; } +void CPU::op_dec_hl() { + uint8 n = op_read(r[HL]); + op_write(r[HL], --n); + r.f.z = n == 0; + r.f.n = 1; + r.f.h = (n & 0x0f) == 0x0f; +} + +void CPU::op_daa() { + signed a = r[A]; + if(r.f.n == 0) { + if(r.f.h || (a & 0x0f) > 0x09) a += 0x06; + if(r.f.c || (a & 0xff) > 0x9f) a += 0x60; + } else { + if(r.f.h) { + a -= 0x06; + if(r.f.c == 0) a &= 0xff; + } + if(r.f.c) a -= 0x60; + } + r[A] = a; + r.f.z = r[A] == 0; + r.f.h = 0; + r.f.c = a & 0x100; +} + void CPU::op_cpl() { r[A] ^= 0xff; r.f.n = 1; @@ -177,8 +294,156 @@ template void CPU::op_dec_rr() { r[x]--; } +void CPU::op_add_sp_n() { + signed n = (int8)op_read(r[PC]++); + r.f.z = 0; + r.f.n = 0; + r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f; + r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff; + r[SP] += n; +} + +void CPU::op_ld_hl_sp_n() { + signed n = (int8)op_read(r[PC]++); + r.f.z = 0; + r.f.n = 0; + r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f; + r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff; + r[HL] = r[SP] + n; +} + //rotate/shift commands +void CPU::op_rlca() { + r[A] = (r[A] << 1) | (r[A] >> 7); + r.f.z = 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = r[A] & 0x01; +} + +void CPU::op_rla() { + bool c = r[A] & 0x80; + r[A] = (r[A] << 1) | (c << 0); + r.f.z = 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_rrca() { + r[A] = (r[A] >> 1) | (r[A] << 7); + r.f.z = 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = r[A] & 0x80; +} + +void CPU::op_rra() { + bool c = r[A] & 0x01; + r[A] = (r[A] >> 1) | (c << 7); + r.f.z = 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +template void CPU::op_rlc_r() { + r[x] = (r[x] << 1) | (r[x] >> 7); + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = r[x] & 0x01; +} + +void CPU::op_rlc_hl() { + uint8 n = op_read(r[HL]); + n = (n << 1) | (n >> 7); + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = n & 0x01; +} + +template void CPU::op_rl_r() { + bool c = r[x] & 0x80; + r[x] = (r[x] << 1) | (r.f.c << 0); + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_rl_hl() { + uint8 n = op_read(r[HL]); + bool c = n & 0x80; + n = (n << 1) | (r.f.c << 0); + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +template void CPU::op_rrc_r() { + r[x] = (r[x] >> 1) | (r[x] << 7); + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = r[x] & 0x80; +} + +void CPU::op_rrc_hl() { + uint8 n = op_read(r[HL]); + n = (n >> 1) | (n << 7); + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = n & 0x80; +} + +template void CPU::op_rr_r() { + bool c = r[x] & 0x01; + r[x] = (r[x] >> 1) | (r.f.c << 7); + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_rr_hl() { + uint8 n = op_read(r[HL]); + bool c = n & 0x01; + n = (n >> 1) | (r.f.c << 7); + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +template void CPU::op_sla_r() { + bool c = r[x] & 0x80; + r[x] <<= 1; + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_sla_hl() { + uint8 n = op_read(r[HL]); + bool c = n & 0x80; + n <<= 1; + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + template void CPU::op_swap_r() { r[x] = (r[x] << 4) | (r[x] >> 4); r.f.z = r[x] == 0; @@ -187,6 +452,56 @@ template void CPU::op_swap_r() { r.f.c = 0; } +void CPU::op_swap_hl() { + uint8 n = op_read(r[HL]); + n = (n << 4) | (n >> 4); + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = 0; +} + +template void CPU::op_sra_r() { + bool c = r[x] & 0x01; + r[x] = (int8)r[x] >> 1; + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_sra_hl() { + uint8 n = op_read(r[HL]); + bool c = n & 0x01; + n = (int8)n >> 1; + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +template void CPU::op_srl_r() { + bool c = r[x] & 0x01; + r[x] >>= 1; + r.f.z = r[x] == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + +void CPU::op_srl_hl() { + uint8 n = op_read(r[HL]); + bool c = n & 0x01; + n >>= 1; + op_write(r[HL], n); + r.f.z = n == 0; + r.f.n = 0; + r.f.h = 0; + r.f.c = c; +} + //single-bit commands template void CPU::op_bit_n_r() { @@ -195,19 +510,58 @@ template void CPU::op_bit_n_r() { r.f.h = 1; } +template void CPU::op_bit_n_hl() { + uint8 n = op_read(r[HL]); + r.f.z = (n & (1 << b)) == 0; + r.f.n = 0; + r.f.h = 1; +} + template void CPU::op_set_n_r() { r[x] |= 1 << b; } +template void CPU::op_set_n_hl() { + uint8 n = op_read(r[HL]); + n |= 1 << b; + op_write(r[HL], n); +} + template void CPU::op_res_n_r() { r[x] &= ~(1 << b); } +template void CPU::op_res_n_hl() { + uint8 n = op_read(r[HL]); + n &= ~(1 << b); + op_write(r[HL], n); +} + //control commands +void CPU::op_ccf() { + r.f.n = 0; + r.f.h = 0; + r.f.c = !r.f.c; +} + +void CPU::op_scf() { + r.f.n = 0; + r.f.h = 0; + r.f.c = 1; +} + void CPU::op_nop() { } +void CPU::op_halt() { + //TODO +} + +void CPU::op_stop() { + //TODO +} + void CPU::op_di() { status.ime = 0; } @@ -229,6 +583,21 @@ void CPU::op_jp_hl() { r[PC] = r[HL]; } +template void CPU::op_jp_f_nn() { + uint8 lo = op_read(r[PC]++); + uint8 hi = op_read(r[PC]++); + if(r.f[x] == y) { + r[PC] = (hi << 8) | (lo << 0); + op_io(); + } +} + +void CPU::op_jr_n() { + int8 n = op_read(r[PC]++); + r[PC] += n; + op_io(); +} + template void CPU::op_jr_f_n() { int8 n = op_read(r[PC]++); if(r.f[x] == y) { @@ -238,15 +607,25 @@ template void CPU::op_jr_f_n() { } void CPU::op_call_nn() { - uint16 dest = r[PC] + 2; - op_write(--r[SP], dest >> 8); - op_write(--r[SP], dest >> 0); uint8 lo = op_read(r[PC]++); uint8 hi = op_read(r[PC]++); + op_write(--r[SP], r[PC] >> 8); + op_write(--r[SP], r[PC] >> 0); r[PC] = (hi << 8) | (lo << 0); op_io(); } +template void CPU::op_call_f_nn() { + uint8 lo = op_read(r[PC]++); + uint8 hi = op_read(r[PC]++); + if(r.f[x] == y) { + op_write(--r[SP], r[PC] >> 8); + op_write(--r[SP], r[PC] >> 0); + r[PC] = (hi << 8) | (lo << 0); + op_io(); + } +} + void CPU::op_ret() { uint8 lo = op_read(r[SP]++); uint8 hi = op_read(r[SP]++); @@ -254,6 +633,24 @@ void CPU::op_ret() { op_io(); } +template void CPU::op_ret_f() { + op_io(); + if(r.f[x] == y) { + uint8 lo = op_read(r[SP]++); + uint8 hi = op_read(r[SP]++); + r[PC] = (hi << 8) | (lo << 0); + op_io(); + } +} + +void CPU::op_reti() { + uint8 lo = op_read(r[SP]++); + uint8 hi = op_read(r[SP]++); + r[PC] = (hi << 8) | (lo << 0); + op_io(); + status.ime = 1; +} + template void CPU::op_rst_n() { op_write(--r[SP], r[PC] >> 8); op_write(--r[SP], r[PC] >> 0); @@ -261,335 +658,4 @@ template void CPU::op_rst_n() { op_io(); } -//opcode tables - -void CPU::initialize_opcode_table() { - for(unsigned n = 0; n < 256; n++) opcode_table[n] = &CPU::op_unknown; - for(unsigned n = 0; n < 256; n++) opcode_table_cb[n] = &CPU::op_unknown; - - opcode_table[0x00] = &CPU::op_nop; - opcode_table[0x01] = &CPU::op_ld_rr_nn; - opcode_table[0x03] = &CPU::op_inc_rr; - opcode_table[0x05] = &CPU::op_dec_r; - opcode_table[0x06] = &CPU::op_ld_r_n; - opcode_table[0x09] = &CPU::op_add_hl_rr; - opcode_table[0x0b] = &CPU::op_dec_rr; - opcode_table[0x0c] = &CPU::op_inc_r; - opcode_table[0x0d] = &CPU::op_dec_r; - opcode_table[0x0e] = &CPU::op_ld_r_n; - opcode_table[0x11] = &CPU::op_ld_rr_nn; - opcode_table[0x13] = &CPU::op_inc_rr; - opcode_table[0x16] = &CPU::op_ld_r_n; - opcode_table[0x19] = &CPU::op_add_hl_rr; - opcode_table[0x1b] = &CPU::op_dec_rr; - opcode_table[0x1e] = &CPU::op_ld_r_n; - opcode_table[0x20] = &CPU::op_jr_f_n; - opcode_table[0x21] = &CPU::op_ld_rr_nn; - opcode_table[0x23] = &CPU::op_inc_rr; - opcode_table[0x26] = &CPU::op_ld_r_n; - opcode_table[0x29] = &CPU::op_add_hl_rr; - opcode_table[0x2a] = &CPU::op_ldi_a_hl; - opcode_table[0x2b] = &CPU::op_dec_rr; - opcode_table[0x2e] = &CPU::op_ld_r_n; - opcode_table[0x2f] = &CPU::op_cpl; - opcode_table[0x31] = &CPU::op_ld_rr_nn; - opcode_table[0x32] = &CPU::op_ldd_hl_a; - opcode_table[0x33] = &CPU::op_inc_rr; - opcode_table[0x36] = &CPU::op_ld_hl_n; - opcode_table[0x39] = &CPU::op_add_hl_rr; - opcode_table[0x3b] = &CPU::op_dec_rr; - opcode_table[0x3e] = &CPU::op_ld_r_n; - opcode_table[0x40] = &CPU::op_ld_r_r; - opcode_table[0x41] = &CPU::op_ld_r_r; - opcode_table[0x42] = &CPU::op_ld_r_r; - opcode_table[0x43] = &CPU::op_ld_r_r; - opcode_table[0x44] = &CPU::op_ld_r_r; - opcode_table[0x45] = &CPU::op_ld_r_r; - opcode_table[0x46] = &CPU::op_ld_r_hl; - opcode_table[0x47] = &CPU::op_ld_r_r; - opcode_table[0x48] = &CPU::op_ld_r_r; - opcode_table[0x49] = &CPU::op_ld_r_r; - opcode_table[0x4a] = &CPU::op_ld_r_r; - opcode_table[0x4b] = &CPU::op_ld_r_r; - opcode_table[0x4c] = &CPU::op_ld_r_r; - opcode_table[0x4d] = &CPU::op_ld_r_r; - opcode_table[0x4e] = &CPU::op_ld_r_hl; - opcode_table[0x4f] = &CPU::op_ld_r_r; - opcode_table[0x50] = &CPU::op_ld_r_r; - opcode_table[0x51] = &CPU::op_ld_r_r; - opcode_table[0x52] = &CPU::op_ld_r_r; - opcode_table[0x53] = &CPU::op_ld_r_r; - opcode_table[0x54] = &CPU::op_ld_r_r; - opcode_table[0x55] = &CPU::op_ld_r_r; - opcode_table[0x56] = &CPU::op_ld_r_hl; - opcode_table[0x57] = &CPU::op_ld_r_r; - opcode_table[0x58] = &CPU::op_ld_r_r; - opcode_table[0x59] = &CPU::op_ld_r_r; - opcode_table[0x5a] = &CPU::op_ld_r_r; - opcode_table[0x5b] = &CPU::op_ld_r_r; - opcode_table[0x5c] = &CPU::op_ld_r_r; - opcode_table[0x5d] = &CPU::op_ld_r_r; - opcode_table[0x5e] = &CPU::op_ld_r_hl; - opcode_table[0x5f] = &CPU::op_ld_r_r; - opcode_table[0x60] = &CPU::op_ld_r_r; - opcode_table[0x61] = &CPU::op_ld_r_r; - opcode_table[0x62] = &CPU::op_ld_r_r; - opcode_table[0x63] = &CPU::op_ld_r_r; - opcode_table[0x64] = &CPU::op_ld_r_r; - opcode_table[0x65] = &CPU::op_ld_r_r; - opcode_table[0x66] = &CPU::op_ld_r_hl; - opcode_table[0x67] = &CPU::op_ld_r_r; - opcode_table[0x68] = &CPU::op_ld_r_r; - opcode_table[0x69] = &CPU::op_ld_r_r; - opcode_table[0x6a] = &CPU::op_ld_r_r; - opcode_table[0x6b] = &CPU::op_ld_r_r; - opcode_table[0x6c] = &CPU::op_ld_r_r; - opcode_table[0x6d] = &CPU::op_ld_r_r; - opcode_table[0x6e] = &CPU::op_ld_r_hl; - opcode_table[0x6f] = &CPU::op_ld_r_r; - opcode_table[0x78] = &CPU::op_ld_r_r; - opcode_table[0x79] = &CPU::op_ld_r_r; - opcode_table[0x7a] = &CPU::op_ld_r_r; - opcode_table[0x7b] = &CPU::op_ld_r_r; - opcode_table[0x7c] = &CPU::op_ld_r_r; - opcode_table[0x7d] = &CPU::op_ld_r_r; - opcode_table[0x7e] = &CPU::op_ld_r_hl; - opcode_table[0x7f] = &CPU::op_ld_r_r; - opcode_table[0x80] = &CPU::op_add_a_r; - opcode_table[0x81] = &CPU::op_add_a_r; - opcode_table[0x82] = &CPU::op_add_a_r; - opcode_table[0x83] = &CPU::op_add_a_r; - opcode_table[0x84] = &CPU::op_add_a_r; - opcode_table[0x85] = &CPU::op_add_a_r; - opcode_table[0x87] = &CPU::op_add_a_r; - opcode_table[0xa0] = &CPU::op_and_r; - opcode_table[0xa1] = &CPU::op_and_r; - opcode_table[0xa2] = &CPU::op_and_r; - opcode_table[0xa3] = &CPU::op_and_r; - opcode_table[0xa4] = &CPU::op_and_r; - opcode_table[0xa5] = &CPU::op_and_r; - opcode_table[0xa7] = &CPU::op_and_r; - opcode_table[0xa8] = &CPU::op_xor_r; - opcode_table[0xa9] = &CPU::op_xor_r; - opcode_table[0xaa] = &CPU::op_xor_r; - opcode_table[0xab] = &CPU::op_xor_r; - opcode_table[0xac] = &CPU::op_xor_r; - opcode_table[0xad] = &CPU::op_xor_r; - opcode_table[0xaf] = &CPU::op_xor_r; - opcode_table[0xb0] = &CPU::op_or_r; - opcode_table[0xb1] = &CPU::op_or_r; - opcode_table[0xb2] = &CPU::op_or_r; - opcode_table[0xb3] = &CPU::op_or_r; - opcode_table[0xb4] = &CPU::op_or_r; - opcode_table[0xb5] = &CPU::op_or_r; - opcode_table[0xb7] = &CPU::op_or_r; - opcode_table[0xc1] = &CPU::op_pop_rr; - opcode_table[0xc3] = &CPU::op_jp_nn; - opcode_table[0xc5] = &CPU::op_push_rr; - opcode_table[0xc7] = &CPU::op_rst_n<0x00>; - opcode_table[0xc9] = &CPU::op_ret; - opcode_table[0xcb] = &CPU::op_cb; - opcode_table[0xcd] = &CPU::op_call_nn; - opcode_table[0xcf] = &CPU::op_rst_n<0x08>; - opcode_table[0xd1] = &CPU::op_pop_rr; - opcode_table[0xd5] = &CPU::op_push_rr; - opcode_table[0xd7] = &CPU::op_rst_n<0x10>; - opcode_table[0xdf] = &CPU::op_rst_n<0x18>; - opcode_table[0xe0] = &CPU::op_ld_ffn_a; - opcode_table[0xe1] = &CPU::op_pop_rr; - opcode_table[0xe2] = &CPU::op_ld_ffc_a; - opcode_table[0xe5] = &CPU::op_push_rr; - opcode_table[0xe6] = &CPU::op_and_n; - opcode_table[0xe7] = &CPU::op_rst_n<0x20>; - opcode_table[0xe9] = &CPU::op_jp_hl; - opcode_table[0xea] = &CPU::op_ld_nn_a; - opcode_table[0xef] = &CPU::op_rst_n<0x28>; - opcode_table[0xf0] = &CPU::op_ld_a_ffn; - opcode_table[0xf1] = &CPU::op_pop_rr; - opcode_table[0xf3] = &CPU::op_di; - opcode_table[0xf5] = &CPU::op_push_rr; - opcode_table[0xf7] = &CPU::op_rst_n<0x30>; - opcode_table[0xfb] = &CPU::op_ei; - opcode_table[0xfe] = &CPU::op_cp_n; - opcode_table[0xff] = &CPU::op_rst_n<0x38>; - - opcode_table_cb[0x37] = &CPU::op_swap_r; - opcode_table_cb[0x40] = &CPU::op_bit_n_r<0, B>; - opcode_table_cb[0x41] = &CPU::op_bit_n_r<0, C>; - opcode_table_cb[0x42] = &CPU::op_bit_n_r<0, D>; - opcode_table_cb[0x43] = &CPU::op_bit_n_r<0, E>; - opcode_table_cb[0x44] = &CPU::op_bit_n_r<0, H>; - opcode_table_cb[0x45] = &CPU::op_bit_n_r<0, L>; - opcode_table_cb[0x47] = &CPU::op_bit_n_r<0, A>; - opcode_table_cb[0x48] = &CPU::op_bit_n_r<1, B>; - opcode_table_cb[0x49] = &CPU::op_bit_n_r<1, C>; - opcode_table_cb[0x4a] = &CPU::op_bit_n_r<1, D>; - opcode_table_cb[0x4b] = &CPU::op_bit_n_r<1, E>; - opcode_table_cb[0x4c] = &CPU::op_bit_n_r<1, H>; - opcode_table_cb[0x4d] = &CPU::op_bit_n_r<1, L>; - opcode_table_cb[0x4f] = &CPU::op_bit_n_r<1, A>; - opcode_table_cb[0x50] = &CPU::op_bit_n_r<2, B>; - opcode_table_cb[0x51] = &CPU::op_bit_n_r<2, C>; - opcode_table_cb[0x52] = &CPU::op_bit_n_r<2, D>; - opcode_table_cb[0x53] = &CPU::op_bit_n_r<2, E>; - opcode_table_cb[0x54] = &CPU::op_bit_n_r<2, H>; - opcode_table_cb[0x55] = &CPU::op_bit_n_r<2, L>; - opcode_table_cb[0x57] = &CPU::op_bit_n_r<2, A>; - opcode_table_cb[0x58] = &CPU::op_bit_n_r<3, B>; - opcode_table_cb[0x59] = &CPU::op_bit_n_r<3, C>; - opcode_table_cb[0x5a] = &CPU::op_bit_n_r<3, D>; - opcode_table_cb[0x5b] = &CPU::op_bit_n_r<3, E>; - opcode_table_cb[0x5c] = &CPU::op_bit_n_r<3, H>; - opcode_table_cb[0x5d] = &CPU::op_bit_n_r<3, L>; - opcode_table_cb[0x5f] = &CPU::op_bit_n_r<3, A>; - opcode_table_cb[0x60] = &CPU::op_bit_n_r<4, B>; - opcode_table_cb[0x61] = &CPU::op_bit_n_r<4, C>; - opcode_table_cb[0x62] = &CPU::op_bit_n_r<4, D>; - opcode_table_cb[0x63] = &CPU::op_bit_n_r<4, E>; - opcode_table_cb[0x64] = &CPU::op_bit_n_r<4, H>; - opcode_table_cb[0x65] = &CPU::op_bit_n_r<4, L>; - opcode_table_cb[0x67] = &CPU::op_bit_n_r<4, A>; - opcode_table_cb[0x68] = &CPU::op_bit_n_r<5, B>; - opcode_table_cb[0x69] = &CPU::op_bit_n_r<5, C>; - opcode_table_cb[0x6a] = &CPU::op_bit_n_r<5, D>; - opcode_table_cb[0x6b] = &CPU::op_bit_n_r<5, E>; - opcode_table_cb[0x6c] = &CPU::op_bit_n_r<5, H>; - opcode_table_cb[0x6d] = &CPU::op_bit_n_r<5, L>; - opcode_table_cb[0x6f] = &CPU::op_bit_n_r<5, A>; - opcode_table_cb[0x70] = &CPU::op_bit_n_r<6, B>; - opcode_table_cb[0x71] = &CPU::op_bit_n_r<6, C>; - opcode_table_cb[0x72] = &CPU::op_bit_n_r<6, D>; - opcode_table_cb[0x73] = &CPU::op_bit_n_r<6, E>; - opcode_table_cb[0x74] = &CPU::op_bit_n_r<6, H>; - opcode_table_cb[0x75] = &CPU::op_bit_n_r<6, L>; - opcode_table_cb[0x77] = &CPU::op_bit_n_r<6, A>; - opcode_table_cb[0x78] = &CPU::op_bit_n_r<7, B>; - opcode_table_cb[0x79] = &CPU::op_bit_n_r<7, C>; - opcode_table_cb[0x7a] = &CPU::op_bit_n_r<7, D>; - opcode_table_cb[0x7b] = &CPU::op_bit_n_r<7, E>; - opcode_table_cb[0x7c] = &CPU::op_bit_n_r<7, H>; - opcode_table_cb[0x7d] = &CPU::op_bit_n_r<7, L>; - opcode_table_cb[0x7f] = &CPU::op_bit_n_r<7, A>; - opcode_table_cb[0x80] = &CPU::op_res_n_r<0, B>; - opcode_table_cb[0x81] = &CPU::op_res_n_r<0, C>; - opcode_table_cb[0x82] = &CPU::op_res_n_r<0, D>; - opcode_table_cb[0x83] = &CPU::op_res_n_r<0, E>; - opcode_table_cb[0x84] = &CPU::op_res_n_r<0, H>; - opcode_table_cb[0x85] = &CPU::op_res_n_r<0, L>; - opcode_table_cb[0x87] = &CPU::op_res_n_r<0, A>; - opcode_table_cb[0x88] = &CPU::op_res_n_r<1, B>; - opcode_table_cb[0x89] = &CPU::op_res_n_r<1, C>; - opcode_table_cb[0x8a] = &CPU::op_res_n_r<1, D>; - opcode_table_cb[0x8b] = &CPU::op_res_n_r<1, E>; - opcode_table_cb[0x8c] = &CPU::op_res_n_r<1, H>; - opcode_table_cb[0x8d] = &CPU::op_res_n_r<1, L>; - opcode_table_cb[0x8f] = &CPU::op_res_n_r<1, A>; - opcode_table_cb[0x90] = &CPU::op_res_n_r<2, B>; - opcode_table_cb[0x91] = &CPU::op_res_n_r<2, C>; - opcode_table_cb[0x92] = &CPU::op_res_n_r<2, D>; - opcode_table_cb[0x93] = &CPU::op_res_n_r<2, E>; - opcode_table_cb[0x94] = &CPU::op_res_n_r<2, H>; - opcode_table_cb[0x95] = &CPU::op_res_n_r<2, L>; - opcode_table_cb[0x97] = &CPU::op_res_n_r<2, A>; - opcode_table_cb[0x98] = &CPU::op_res_n_r<3, B>; - opcode_table_cb[0x99] = &CPU::op_res_n_r<3, C>; - opcode_table_cb[0x9a] = &CPU::op_res_n_r<3, D>; - opcode_table_cb[0x9b] = &CPU::op_res_n_r<3, E>; - opcode_table_cb[0x9c] = &CPU::op_res_n_r<3, H>; - opcode_table_cb[0x9d] = &CPU::op_res_n_r<3, L>; - opcode_table_cb[0x9f] = &CPU::op_res_n_r<3, A>; - opcode_table_cb[0xa0] = &CPU::op_res_n_r<4, B>; - opcode_table_cb[0xa1] = &CPU::op_res_n_r<4, C>; - opcode_table_cb[0xa2] = &CPU::op_res_n_r<4, D>; - opcode_table_cb[0xa3] = &CPU::op_res_n_r<4, E>; - opcode_table_cb[0xa4] = &CPU::op_res_n_r<4, H>; - opcode_table_cb[0xa5] = &CPU::op_res_n_r<4, L>; - opcode_table_cb[0xa7] = &CPU::op_res_n_r<4, A>; - opcode_table_cb[0xa8] = &CPU::op_res_n_r<5, B>; - opcode_table_cb[0xa9] = &CPU::op_res_n_r<5, C>; - opcode_table_cb[0xaa] = &CPU::op_res_n_r<5, D>; - opcode_table_cb[0xab] = &CPU::op_res_n_r<5, E>; - opcode_table_cb[0xac] = &CPU::op_res_n_r<5, H>; - opcode_table_cb[0xad] = &CPU::op_res_n_r<5, L>; - opcode_table_cb[0xaf] = &CPU::op_res_n_r<5, A>; - opcode_table_cb[0xb0] = &CPU::op_res_n_r<6, B>; - opcode_table_cb[0xb1] = &CPU::op_res_n_r<6, C>; - opcode_table_cb[0xb2] = &CPU::op_res_n_r<6, D>; - opcode_table_cb[0xb3] = &CPU::op_res_n_r<6, E>; - opcode_table_cb[0xb4] = &CPU::op_res_n_r<6, H>; - opcode_table_cb[0xb5] = &CPU::op_res_n_r<6, L>; - opcode_table_cb[0xb7] = &CPU::op_res_n_r<6, A>; - opcode_table_cb[0xb8] = &CPU::op_res_n_r<7, B>; - opcode_table_cb[0xb9] = &CPU::op_res_n_r<7, C>; - opcode_table_cb[0xba] = &CPU::op_res_n_r<7, D>; - opcode_table_cb[0xbb] = &CPU::op_res_n_r<7, E>; - opcode_table_cb[0xbc] = &CPU::op_res_n_r<7, H>; - opcode_table_cb[0xbd] = &CPU::op_res_n_r<7, L>; - opcode_table_cb[0xbf] = &CPU::op_res_n_r<7, A>; - opcode_table_cb[0xc0] = &CPU::op_set_n_r<0, B>; - opcode_table_cb[0xc1] = &CPU::op_set_n_r<0, C>; - opcode_table_cb[0xc2] = &CPU::op_set_n_r<0, D>; - opcode_table_cb[0xc3] = &CPU::op_set_n_r<0, E>; - opcode_table_cb[0xc4] = &CPU::op_set_n_r<0, H>; - opcode_table_cb[0xc5] = &CPU::op_set_n_r<0, L>; - opcode_table_cb[0xc7] = &CPU::op_set_n_r<0, A>; - opcode_table_cb[0xc8] = &CPU::op_set_n_r<1, B>; - opcode_table_cb[0xc9] = &CPU::op_set_n_r<1, C>; - opcode_table_cb[0xca] = &CPU::op_set_n_r<1, D>; - opcode_table_cb[0xcb] = &CPU::op_set_n_r<1, E>; - opcode_table_cb[0xcc] = &CPU::op_set_n_r<1, H>; - opcode_table_cb[0xcd] = &CPU::op_set_n_r<1, L>; - opcode_table_cb[0xcf] = &CPU::op_set_n_r<1, A>; - opcode_table_cb[0xd0] = &CPU::op_set_n_r<2, B>; - opcode_table_cb[0xd1] = &CPU::op_set_n_r<2, C>; - opcode_table_cb[0xd2] = &CPU::op_set_n_r<2, D>; - opcode_table_cb[0xd3] = &CPU::op_set_n_r<2, E>; - opcode_table_cb[0xd4] = &CPU::op_set_n_r<2, H>; - opcode_table_cb[0xd5] = &CPU::op_set_n_r<2, L>; - opcode_table_cb[0xd7] = &CPU::op_set_n_r<2, A>; - opcode_table_cb[0xd8] = &CPU::op_set_n_r<3, B>; - opcode_table_cb[0xd9] = &CPU::op_set_n_r<3, C>; - opcode_table_cb[0xda] = &CPU::op_set_n_r<3, D>; - opcode_table_cb[0xdb] = &CPU::op_set_n_r<3, E>; - opcode_table_cb[0xdc] = &CPU::op_set_n_r<3, H>; - opcode_table_cb[0xdd] = &CPU::op_set_n_r<3, L>; - opcode_table_cb[0xdf] = &CPU::op_set_n_r<3, A>; - opcode_table_cb[0xe0] = &CPU::op_set_n_r<4, B>; - opcode_table_cb[0xe1] = &CPU::op_set_n_r<4, C>; - opcode_table_cb[0xe2] = &CPU::op_set_n_r<4, D>; - opcode_table_cb[0xe3] = &CPU::op_set_n_r<4, E>; - opcode_table_cb[0xe4] = &CPU::op_set_n_r<4, H>; - opcode_table_cb[0xe5] = &CPU::op_set_n_r<4, L>; - opcode_table_cb[0xe7] = &CPU::op_set_n_r<4, A>; - opcode_table_cb[0xe8] = &CPU::op_set_n_r<5, B>; - opcode_table_cb[0xe9] = &CPU::op_set_n_r<5, C>; - opcode_table_cb[0xea] = &CPU::op_set_n_r<5, D>; - opcode_table_cb[0xeb] = &CPU::op_set_n_r<5, E>; - opcode_table_cb[0xec] = &CPU::op_set_n_r<5, H>; - opcode_table_cb[0xed] = &CPU::op_set_n_r<5, L>; - opcode_table_cb[0xef] = &CPU::op_set_n_r<5, A>; - opcode_table_cb[0xf0] = &CPU::op_set_n_r<6, B>; - opcode_table_cb[0xf1] = &CPU::op_set_n_r<6, C>; - opcode_table_cb[0xf2] = &CPU::op_set_n_r<6, D>; - opcode_table_cb[0xf3] = &CPU::op_set_n_r<6, E>; - opcode_table_cb[0xf4] = &CPU::op_set_n_r<6, H>; - opcode_table_cb[0xf5] = &CPU::op_set_n_r<6, L>; - opcode_table_cb[0xf7] = &CPU::op_set_n_r<6, A>; - opcode_table_cb[0xf8] = &CPU::op_set_n_r<7, B>; - opcode_table_cb[0xf9] = &CPU::op_set_n_r<7, C>; - opcode_table_cb[0xfa] = &CPU::op_set_n_r<7, D>; - opcode_table_cb[0xfb] = &CPU::op_set_n_r<7, E>; - opcode_table_cb[0xfc] = &CPU::op_set_n_r<7, H>; - opcode_table_cb[0xfd] = &CPU::op_set_n_r<7, L>; - opcode_table_cb[0xff] = &CPU::op_set_n_r<7, A>; - - unsigned missing = 0; - for(unsigned n = 0; n < 256; n++) { - if(opcode_table[n] == &CPU::op_unknown) missing++; - if(opcode_table_cb[n] == &CPU::op_unknown) missing++; - } - - print("CPU opcodes: ", 512 - missing, " implemented, ", missing, " remaining.\n"); -} - #endif diff --git a/gameboy/cpu/core/core.hpp b/gameboy/cpu/core/core.hpp index 82a0ed03..16444966 100755 --- a/gameboy/cpu/core/core.hpp +++ b/gameboy/cpu/core/core.hpp @@ -3,62 +3,139 @@ void (CPU::*opcode_table[256])(); void (CPU::*opcode_table_cb[256])(); void initialize_opcode_table(); -void op_unknown(); - +void op_xx(); void op_cb(); //8-bit load commands template void op_ld_r_r(); template void op_ld_r_n(); template void op_ld_r_hl(); +template void op_ld_hl_r(); void op_ld_hl_n(); +template void op_ld_a_rr(); +void op_ld_a_nn(); +template void op_ld_rr_a(); void op_ld_nn_a(); void op_ld_a_ffn(); void op_ld_ffn_a(); void op_ld_ffc_a(); +void op_ldi_hl_a(); void op_ldi_a_hl(); void op_ldd_hl_a(); +void op_ldd_a_hl(); //16-bit load commands template void op_ld_rr_nn(); +void op_ld_nn_sp(); +void op_ld_sp_hl(); template void op_push_rr(); template void op_pop_rr(); //8-bit arithmetic commands +void opi_add_a(uint8 x); template void op_add_a_r(); -template void op_and_r(); -void op_and_n(); -template void op_xor_r(); -template void op_or_r(); -void op_cp_n(); +void op_add_a_n(); +void op_add_a_hl(); + +void opi_adc_a(uint8 x); +template void op_adc_a_r(); +void op_adc_a_n(); +void op_adc_a_hl(); + +void opi_sub_a(uint8 x); +template void op_sub_a_r(); +void op_sub_a_n(); +void op_sub_a_hl(); + +void opi_sbc_a(uint8 x); +template void op_sbc_a_r(); +void op_sbc_a_n(); +void op_sbc_a_hl(); + +void opi_and_a(uint8 x); +template void op_and_a_r(); +void op_and_a_n(); +void op_and_a_hl(); + +void opi_xor_a(uint8 x); +template void op_xor_a_r(); +void op_xor_a_n(); +void op_xor_a_hl(); + +void opi_or_a(uint8 x); +template void op_or_a_r(); +void op_or_a_n(); +void op_or_a_hl(); + +void opi_cp_a(uint8 x); +template void op_cp_a_r(); +void op_cp_a_n(); +void op_cp_a_hl(); + template void op_inc_r(); +void op_inc_hl(); template void op_dec_r(); +void op_dec_hl(); +void op_daa(); void op_cpl(); //16-bit arithmetic commands template void op_add_hl_rr(); template void op_inc_rr(); template void op_dec_rr(); +void op_add_sp_n(); +void op_ld_hl_sp_n(); //rotate/shift commands +void op_rlca(); +void op_rla(); +void op_rrca(); +void op_rra(); +template void op_rlc_r(); +void op_rlc_hl(); +template void op_rl_r(); +void op_rl_hl(); +template void op_rrc_r(); +void op_rrc_hl(); +template void op_rr_r(); +void op_rr_hl(); +template void op_sla_r(); +void op_sla_hl(); template void op_swap_r(); +void op_swap_hl(); +template void op_sra_r(); +void op_sra_hl(); +template void op_srl_r(); +void op_srl_hl(); //single-bit commands template void op_bit_n_r(); +template void op_bit_n_hl(); template void op_set_n_r(); +template void op_set_n_hl(); template void op_res_n_r(); +template void op_res_n_hl(); //control commands +void op_ccf(); +void op_scf(); void op_nop(); +void op_halt(); +void op_stop(); void op_di(); void op_ei(); //jump commands void op_jp_nn(); void op_jp_hl(); +template void op_jp_f_nn(); +void op_jr_n(); template void op_jr_f_n(); void op_call_nn(); +template void op_call_f_nn(); void op_ret(); +template void op_ret_f(); +void op_reti(); template void op_rst_n(); //disassembler.cpp diff --git a/gameboy/cpu/core/disassembler.cpp b/gameboy/cpu/core/disassembler.cpp index c8c69fa9..9c67f444 100755 --- a/gameboy/cpu/core/disassembler.cpp +++ b/gameboy/cpu/core/disassembler.cpp @@ -30,36 +30,68 @@ string CPU::disassemble_opcode(uint16 pc) { switch(opcode) { case 0x00: return { "nop" }; case 0x01: return { "ld bc,$", hex<2>(p1), hex<2>(p0) }; + case 0x02: return { "ld (bc),a" }; case 0x03: return { "inc bc" }; + case 0x04: return { "inc b" }; case 0x05: return { "dec b" }; case 0x06: return { "ld b,$", hex<2>(p0) }; + case 0x07: return { "rlc a" }; + case 0x08: return { "ld ($", hex<2>(p1), hex<2>(p0), "),sp" }; case 0x09: return { "add hl,bc" }; + case 0x0a: return { "ld a,(bc)" }; case 0x0b: return { "dec bc" }; case 0x0c: return { "inc c" }; case 0x0d: return { "dec c" }; case 0x0e: return { "ld c,$", hex<2>(p0) }; + case 0x0f: return { "rrc a" }; + case 0x10: return { "stop" }; case 0x11: return { "ld de,$", hex<2>(p1), hex<2>(p0) }; + case 0x12: return { "ld (de),a" }; case 0x13: return { "inc de" }; + case 0x14: return { "inc d" }; + case 0x15: return { "dec d" }; case 0x16: return { "ld d,$", hex<2>(p0) }; + case 0x17: return { "rl a" }; + case 0x18: return { "jr $", hex<4>(r[PC] + 2 + (int8)p0) }; case 0x19: return { "add hl,de" }; + case 0x1a: return { "ld a,(de)" }; case 0x1b: return { "dec de" }; + case 0x1c: return { "inc e" }; + case 0x1d: return { "dec e" }; case 0x1e: return { "ld e,$", hex<2>(p0) }; - case 0x20: return { "jp nz,$", hex<4>(r[PC] + 2 + (int8)p0) }; + case 0x1f: return { "rr a" }; + case 0x20: return { "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) }; case 0x21: return { "ld hl,$", hex<2>(p1), hex<2>(p0) }; + case 0x22: return { "ldi (hl),a" }; case 0x23: return { "inc hl" }; + case 0x24: return { "inc h" }; + case 0x25: return { "dec h" }; case 0x26: return { "ld h,$", hex<2>(p0) }; + case 0x27: return { "daa" }; + case 0x28: return { "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) }; case 0x29: return { "add hl,hl" }; case 0x2a: return { "ldi a,(hl)" }; case 0x2b: return { "dec hl" }; + case 0x2c: return { "inc l" }; + case 0x2d: return { "dec l" }; case 0x2e: return { "ld l,$", hex<2>(p0) }; case 0x2f: return { "cpl" }; + case 0x30: return { "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) }; case 0x31: return { "ld sp,$", hex<2>(p1), hex<2>(p0) }; case 0x32: return { "ldd (hl),a" }; case 0x33: return { "inc sp" }; + case 0x34: return { "inc (hl)" }; + case 0x35: return { "dec (hl)" }; case 0x36: return { "ld (hl),$", hex<2>(p0) }; + case 0x37: return { "scf" }; + case 0x38: return { "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) }; case 0x39: return { "add hl,sp" }; + case 0x3a: return { "ldd a,(hl)" }; case 0x3b: return { "dec sp" }; + case 0x3c: return { "inc a" }; + case 0x3d: return { "dec a" }; case 0x3e: return { "ld a,$", hex<2>(p0) }; + case 0x3f: return { "ccf" }; case 0x40: return { "ld b,b" }; case 0x41: return { "ld b,c" }; case 0x42: return { "ld b,d" }; @@ -108,6 +140,14 @@ string CPU::disassemble_opcode(uint16 pc) { case 0x6d: return { "ld l,l" }; case 0x6e: return { "ld l,(hl)" }; case 0x6f: return { "ld l,a" }; + case 0x70: return { "ld (hl),b" }; + case 0x71: return { "ld (hl),c" }; + case 0x72: return { "ld (hl),d" }; + case 0x73: return { "ld (hl),e" }; + case 0x74: return { "ld (hl),h" }; + case 0x75: return { "ld (hl),l" }; + case 0x76: return { "halt" }; + case 0x77: return { "ld (hl),a" }; case 0x78: return { "ld a,b" }; case 0x79: return { "ld a,c" }; case 0x7a: return { "ld a,d" }; @@ -122,60 +162,131 @@ string CPU::disassemble_opcode(uint16 pc) { case 0x83: return { "add a,e" }; case 0x84: return { "add a,h" }; case 0x85: return { "add a,l" }; + case 0x86: return { "add a,(hl)" }; case 0x87: return { "add a,a" }; - case 0xa0: return { "and b" }; - case 0xa1: return { "and c" }; - case 0xa2: return { "and d" }; - case 0xa3: return { "and e" }; - case 0xa4: return { "and h" }; - case 0xa5: return { "and l" }; - case 0xa7: return { "and a" }; - case 0xa8: return { "xor b" }; - case 0xa9: return { "xor c" }; - case 0xaa: return { "xor d" }; - case 0xab: return { "xor e" }; - case 0xac: return { "xor h" }; - case 0xad: return { "xor l" }; - case 0xaf: return { "xor a" }; - case 0xb0: return { "or b" }; - case 0xb1: return { "or c" }; - case 0xb2: return { "or d" }; - case 0xb3: return { "or e" }; - case 0xb4: return { "or h" }; - case 0xb5: return { "or l" }; - case 0xb7: return { "or a" }; + case 0x88: return { "adc a,b" }; + case 0x89: return { "adc a,c" }; + case 0x8a: return { "adc a,d" }; + case 0x8b: return { "adc a,e" }; + case 0x8c: return { "adc a,h" }; + case 0x8d: return { "adc a,l" }; + case 0x8e: return { "adc a,(hl)" }; + case 0x8f: return { "adc a,a" }; + case 0x90: return { "sub a,b" }; + case 0x91: return { "sub a,c" }; + case 0x92: return { "sub a,d" }; + case 0x93: return { "sub a,e" }; + case 0x94: return { "sub a,h" }; + case 0x95: return { "sub a,l" }; + case 0x96: return { "sub a,(hl)" }; + case 0x97: return { "sub a,a" }; + case 0x98: return { "sbc a,b" }; + case 0x99: return { "sbc a,c" }; + case 0x9a: return { "sbc a,d" }; + case 0x9b: return { "sbc a,e" }; + case 0x9c: return { "sbc a,h" }; + case 0x9d: return { "sbc a,l" }; + case 0x9e: return { "sbc a,(hl)" }; + case 0x9f: return { "sbc a,a" }; + case 0xa0: return { "and a,b" }; + case 0xa1: return { "and a,c" }; + case 0xa2: return { "and a,d" }; + case 0xa3: return { "and a,e" }; + case 0xa4: return { "and a,h" }; + case 0xa5: return { "and a,l" }; + case 0xa6: return { "and a,(hl)" }; + case 0xa7: return { "and a,a" }; + case 0xa8: return { "xor a,b" }; + case 0xa9: return { "xor a,c" }; + case 0xaa: return { "xor a,d" }; + case 0xab: return { "xor a,e" }; + case 0xac: return { "xor a,h" }; + case 0xad: return { "xor a,l" }; + case 0xae: return { "xor a,(hl)" }; + case 0xaf: return { "xor a,a" }; + case 0xb0: return { "or a,b" }; + case 0xb1: return { "or a,c" }; + case 0xb2: return { "or a,d" }; + case 0xb3: return { "or a,e" }; + case 0xb4: return { "or a,h" }; + case 0xb5: return { "or a,l" }; + case 0xb6: return { "or a,(hl)" }; + case 0xb7: return { "or a,a" }; + case 0xb8: return { "cp a,b" }; + case 0xb9: return { "cp a,c" }; + case 0xba: return { "cp a,d" }; + case 0xbb: return { "cp a,e" }; + case 0xbc: return { "cp a,h" }; + case 0xbd: return { "cp a,l" }; + case 0xbe: return { "cp a,(hl)" }; + case 0xbf: return { "cp a,a" }; + case 0xc0: return { "ret nz" }; case 0xc1: return { "pop bc" }; + case 0xc2: return { "jp nz,$", hex<2>(p1), hex<2>(p0) }; case 0xc3: return { "jp $", hex<2>(p1), hex<2>(p0) }; + case 0xc4: return { "call nz,$", hex<2>(p1), hex<2>(p0) }; case 0xc5: return { "push bc" }; + case 0xc6: return { "add a,$", hex<2>(p0) }; case 0xc7: return { "rst $0000" }; + case 0xc8: return { "ret z" }; case 0xc9: return { "ret" }; + case 0xca: return { "jp z,$", hex<2>(p1), hex<2>(p0) }; case 0xcb: return disassemble_opcode_cb(pc + 1); + case 0xcc: return { "call z,$", hex<2>(p1), hex<2>(p0) }; case 0xcd: return { "call $", hex<2>(p1), hex<2>(p0) }; + case 0xce: return { "adc a,$", hex<2>(p0) }; case 0xcf: return { "rst $0008" }; + case 0xd0: return { "ret nc" }; case 0xd1: return { "pop de" }; + case 0xd2: return { "jp nc,$", hex<2>(p1), hex<2>(p0) }; + case 0xd3: return { "xx" }; + case 0xd4: return { "call nc,$", hex<2>(p1), hex<2>(p0) }; case 0xd5: return { "push de" }; + case 0xd6: return { "sub a,$", hex<2>(p0) }; case 0xd7: return { "rst $0010" }; + case 0xd8: return { "ret c" }; + case 0xd9: return { "reti" }; + case 0xda: return { "jp c,$", hex<2>(p1), hex<2>(p0) }; + case 0xdb: return { "xx" }; + case 0xdc: return { "call c,$", hex<2>(p1), hex<2>(p0) }; + case 0xdd: return { "xx" }; + case 0xde: return { "sbc a,$", hex<2>(p0) }; case 0xdf: return { "rst $0018" }; case 0xe0: return { "ld ($ff", hex<2>(p0), "),a" }; case 0xe1: return { "pop hl" }; case 0xe2: return { "ld ($ff00+c),a" }; + case 0xe3: return { "xx" }; + case 0xe4: return { "xx" }; case 0xe5: return { "push hl" }; - case 0xe6: return { "and $", hex<2>(p0) }; + case 0xe6: return { "and a,$", hex<2>(p0) }; case 0xe7: return { "rst $0020" }; + case 0xe8: return { "add sp,$", hex<4>((int8)p0) }; case 0xe9: return { "jp hl" }; case 0xea: return { "ld ($", hex<2>(p1), hex<2>(p0), "),a" }; + case 0xeb: return { "xx" }; + case 0xec: return { "xx" }; + case 0xed: return { "xx" }; + case 0xee: return { "xor a,$", hex<2>(p0) }; case 0xef: return { "rst $0028" }; case 0xf0: return { "ld a,($ff", hex<2>(p0), ")" }; case 0xf1: return { "pop af" }; + case 0xf2: return { "xx" }; case 0xf3: return { "di" }; + case 0xf4: return { "xx" }; case 0xf5: return { "push af" }; + case 0xf6: return { "or a,$", hex<2>(p0) }; case 0xf7: return { "rst $0030" }; + case 0xf8: return { "ld hl,sp+$", hex<4>((int8)p0) }; + case 0xf9: return { "ld sp,hl" }; + case 0xfa: return { "ld a,($", hex<2>(p1), hex<2>(p0), ")" }; case 0xfb: return { "ei" }; - case 0xfe: return { "cp $", hex<2>(p0) }; + case 0xfc: return { "xx" }; + case 0xfd: return { "xx" }; + case 0xfe: return { "cp a,$", hex<2>(p0) }; case 0xff: return { "rst $0038" }; } - return { "??? [", hex<2>(opcode), ",", hex<2>(p1), ",", hex<2>(p0), "]" }; + return ""; } string CPU::disassemble_opcode_cb(uint16 pc) { @@ -185,13 +296,77 @@ string CPU::disassemble_opcode_cb(uint16 pc) { uint8 p2 = bus.read(pc + 3); switch(opcode) { + case 0x00: return { "rlc b" }; + case 0x01: return { "rlc c" }; + case 0x02: return { "rlc d" }; + case 0x03: return { "rlc e" }; + case 0x04: return { "rlc h" }; + case 0x05: return { "rlc l" }; + case 0x06: return { "rlc (hl)" }; + case 0x07: return { "rlc a" }; + case 0x08: return { "rrc b" }; + case 0x09: return { "rrc c" }; + case 0x0a: return { "rrc d" }; + case 0x0b: return { "rrc e" }; + case 0x0c: return { "rrc h" }; + case 0x0d: return { "rrc l" }; + case 0x0e: return { "rrc (hl)" }; + case 0x0f: return { "rrc a" }; + case 0x10: return { "rl b" }; + case 0x11: return { "rl c" }; + case 0x12: return { "rl d" }; + case 0x13: return { "rl e" }; + case 0x14: return { "rl h" }; + case 0x15: return { "rl l" }; + case 0x16: return { "rl (hl)" }; + case 0x17: return { "rl a" }; + case 0x18: return { "rr b" }; + case 0x19: return { "rr c" }; + case 0x1a: return { "rr d" }; + case 0x1b: return { "rr e" }; + case 0x1c: return { "rr h" }; + case 0x1d: return { "rr l" }; + case 0x1e: return { "rr (hl)" }; + case 0x1f: return { "rr a" }; + case 0x20: return { "sla b" }; + case 0x21: return { "sla c" }; + case 0x22: return { "sla d" }; + case 0x23: return { "sla e" }; + case 0x24: return { "sla h" }; + case 0x25: return { "sla l" }; + case 0x26: return { "sla (hl)" }; + case 0x27: return { "sla a" }; + case 0x28: return { "sra b" }; + case 0x29: return { "sra c" }; + case 0x2a: return { "sra d" }; + case 0x2b: return { "sra e" }; + case 0x2c: return { "sra h" }; + case 0x2d: return { "sra l" }; + case 0x2e: return { "sra (hl)" }; + case 0x2f: return { "sra a" }; + case 0x30: return { "swap b" }; + case 0x31: return { "swap c" }; + case 0x32: return { "swap d" }; + case 0x33: return { "swap e" }; + case 0x34: return { "swap h" }; + case 0x35: return { "swap l" }; + case 0x36: return { "swap (hl)" }; case 0x37: return { "swap a" }; + case 0x38: return { "srl b" }; + case 0x39: return { "srl c" }; + case 0x3a: return { "srl d" }; + case 0x3b: return { "srl e" }; + case 0x3c: return { "srl h" }; + case 0x3d: return { "srl l" }; + case 0x3e: return { "srl (hl)" }; + case 0x3f: return { "srl a" }; case 0x40: return { "bit 0,b" }; case 0x41: return { "bit 0,c" }; case 0x42: return { "bit 0,d" }; case 0x43: return { "bit 0,e" }; case 0x44: return { "bit 0,h" }; case 0x45: return { "bit 0,l" }; + case 0x46: return { "bit 0,(hl)" }; case 0x47: return { "bit 0,a" }; case 0x48: return { "bit 1,b" }; case 0x49: return { "bit 1,c" }; @@ -199,6 +374,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x4b: return { "bit 1,e" }; case 0x4c: return { "bit 1,h" }; case 0x4d: return { "bit 1,l" }; + case 0x4e: return { "bit 1,(hl)" }; case 0x4f: return { "bit 1,a" }; case 0x50: return { "bit 2,b" }; case 0x51: return { "bit 2,c" }; @@ -206,6 +382,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x53: return { "bit 2,e" }; case 0x54: return { "bit 2,h" }; case 0x55: return { "bit 2,l" }; + case 0x56: return { "bit 2,(hl)" }; case 0x57: return { "bit 2,a" }; case 0x58: return { "bit 3,b" }; case 0x59: return { "bit 3,c" }; @@ -213,6 +390,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x5b: return { "bit 3,e" }; case 0x5c: return { "bit 3,h" }; case 0x5d: return { "bit 3,l" }; + case 0x5e: return { "bit 3,(hl)" }; case 0x5f: return { "bit 3,a" }; case 0x60: return { "bit 4,b" }; case 0x61: return { "bit 4,c" }; @@ -220,6 +398,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x63: return { "bit 4,e" }; case 0x64: return { "bit 4,h" }; case 0x65: return { "bit 4,l" }; + case 0x66: return { "bit 4,(hl)" }; case 0x67: return { "bit 4,a" }; case 0x68: return { "bit 5,b" }; case 0x69: return { "bit 5,c" }; @@ -227,6 +406,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x6b: return { "bit 5,e" }; case 0x6c: return { "bit 5,h" }; case 0x6d: return { "bit 5,l" }; + case 0x6e: return { "bit 5,(hl)" }; case 0x6f: return { "bit 5,a" }; case 0x70: return { "bit 6,b" }; case 0x71: return { "bit 6,c" }; @@ -234,6 +414,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x73: return { "bit 6,e" }; case 0x74: return { "bit 6,h" }; case 0x75: return { "bit 6,l" }; + case 0x76: return { "bit 6,(hl)" }; case 0x77: return { "bit 6,a" }; case 0x78: return { "bit 7,b" }; case 0x79: return { "bit 7,c" }; @@ -241,6 +422,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x7b: return { "bit 7,e" }; case 0x7c: return { "bit 7,h" }; case 0x7d: return { "bit 7,l" }; + case 0x7e: return { "bit 7,(hl)" }; case 0x7f: return { "bit 7,a" }; case 0x80: return { "res 0,b" }; case 0x81: return { "res 0,c" }; @@ -248,6 +430,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x83: return { "res 0,e" }; case 0x84: return { "res 0,h" }; case 0x85: return { "res 0,l" }; + case 0x86: return { "res 0,(hl)" }; case 0x87: return { "res 0,a" }; case 0x88: return { "res 1,b" }; case 0x89: return { "res 1,c" }; @@ -255,6 +438,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x8b: return { "res 1,e" }; case 0x8c: return { "res 1,h" }; case 0x8d: return { "res 1,l" }; + case 0x8e: return { "res 1,(hl)" }; case 0x8f: return { "res 1,a" }; case 0x90: return { "res 2,b" }; case 0x91: return { "res 2,c" }; @@ -262,6 +446,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x93: return { "res 2,e" }; case 0x94: return { "res 2,h" }; case 0x95: return { "res 2,l" }; + case 0x96: return { "res 2,(hl)" }; case 0x97: return { "res 2,a" }; case 0x98: return { "res 3,b" }; case 0x99: return { "res 3,c" }; @@ -269,6 +454,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0x9b: return { "res 3,e" }; case 0x9c: return { "res 3,h" }; case 0x9d: return { "res 3,l" }; + case 0x9e: return { "res 3,(hl)" }; case 0x9f: return { "res 3,a" }; case 0xa0: return { "res 4,b" }; case 0xa1: return { "res 4,c" }; @@ -276,6 +462,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xa3: return { "res 4,e" }; case 0xa4: return { "res 4,h" }; case 0xa5: return { "res 4,l" }; + case 0xa6: return { "res 4,(hl)" }; case 0xa7: return { "res 4,a" }; case 0xa8: return { "res 5,b" }; case 0xa9: return { "res 5,c" }; @@ -283,6 +470,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xab: return { "res 5,e" }; case 0xac: return { "res 5,h" }; case 0xad: return { "res 5,l" }; + case 0xae: return { "res 5,(hl)" }; case 0xaf: return { "res 5,a" }; case 0xb0: return { "res 6,b" }; case 0xb1: return { "res 6,c" }; @@ -290,6 +478,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xb3: return { "res 6,e" }; case 0xb4: return { "res 6,h" }; case 0xb5: return { "res 6,l" }; + case 0xb6: return { "res 6,(hl)" }; case 0xb7: return { "res 6,a" }; case 0xb8: return { "res 7,b" }; case 0xb9: return { "res 7,c" }; @@ -297,6 +486,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xbb: return { "res 7,e" }; case 0xbc: return { "res 7,h" }; case 0xbd: return { "res 7,l" }; + case 0xbe: return { "res 7,(hl)" }; case 0xbf: return { "res 7,a" }; case 0xc0: return { "set 0,b" }; case 0xc1: return { "set 0,c" }; @@ -304,6 +494,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xc3: return { "set 0,e" }; case 0xc4: return { "set 0,h" }; case 0xc5: return { "set 0,l" }; + case 0xc6: return { "set 0,(hl)" }; case 0xc7: return { "set 0,a" }; case 0xc8: return { "set 1,b" }; case 0xc9: return { "set 1,c" }; @@ -311,6 +502,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xcb: return { "set 1,e" }; case 0xcc: return { "set 1,h" }; case 0xcd: return { "set 1,l" }; + case 0xce: return { "set 1,(hl)" }; case 0xcf: return { "set 1,a" }; case 0xd0: return { "set 2,b" }; case 0xd1: return { "set 2,c" }; @@ -318,6 +510,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xd3: return { "set 2,e" }; case 0xd4: return { "set 2,h" }; case 0xd5: return { "set 2,l" }; + case 0xd6: return { "set 2,(hl)" }; case 0xd7: return { "set 2,a" }; case 0xd8: return { "set 3,b" }; case 0xd9: return { "set 3,c" }; @@ -325,6 +518,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xdb: return { "set 3,e" }; case 0xdc: return { "set 3,h" }; case 0xdd: return { "set 3,l" }; + case 0xde: return { "set 3,(hl)" }; case 0xdf: return { "set 3,a" }; case 0xe0: return { "set 4,b" }; case 0xe1: return { "set 4,c" }; @@ -332,6 +526,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xe3: return { "set 4,e" }; case 0xe4: return { "set 4,h" }; case 0xe5: return { "set 4,l" }; + case 0xe6: return { "set 4,(hl)" }; case 0xe7: return { "set 4,a" }; case 0xe8: return { "set 5,b" }; case 0xe9: return { "set 5,c" }; @@ -339,6 +534,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xeb: return { "set 5,e" }; case 0xec: return { "set 5,h" }; case 0xed: return { "set 5,l" }; + case 0xee: return { "set 5,(hl)" }; case 0xef: return { "set 5,a" }; case 0xf0: return { "set 6,b" }; case 0xf1: return { "set 6,c" }; @@ -346,6 +542,7 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xf3: return { "set 6,e" }; case 0xf4: return { "set 6,h" }; case 0xf5: return { "set 6,l" }; + case 0xf6: return { "set 6,(hl)" }; case 0xf7: return { "set 6,a" }; case 0xf8: return { "set 7,b" }; case 0xf9: return { "set 7,c" }; @@ -353,10 +550,11 @@ string CPU::disassemble_opcode_cb(uint16 pc) { case 0xfb: return { "set 7,e" }; case 0xfc: return { "set 7,h" }; case 0xfd: return { "set 7,l" }; + case 0xfe: return { "set 7,(hl)" }; case 0xff: return { "set 7,a" }; } - return { "cb? [", hex<2>(opcode), ",", hex<2>(p0), ",", hex<2>(p1), "]" }; + return ""; } #endif diff --git a/gameboy/cpu/core/table.cpp b/gameboy/cpu/core/table.cpp new file mode 100755 index 00000000..2c885591 --- /dev/null +++ b/gameboy/cpu/core/table.cpp @@ -0,0 +1,519 @@ +#ifdef CPU_CPP + +void CPU::initialize_opcode_table() { + opcode_table[0x00] = &CPU::op_nop; + opcode_table[0x01] = &CPU::op_ld_rr_nn; + opcode_table[0x02] = &CPU::op_ld_rr_a; + opcode_table[0x03] = &CPU::op_inc_rr; + opcode_table[0x04] = &CPU::op_inc_r; + opcode_table[0x05] = &CPU::op_dec_r; + opcode_table[0x06] = &CPU::op_ld_r_n; + opcode_table[0x07] = &CPU::op_rlca; + opcode_table[0x08] = &CPU::op_ld_nn_sp; + opcode_table[0x09] = &CPU::op_add_hl_rr; + opcode_table[0x0a] = &CPU::op_ld_a_rr; + opcode_table[0x0b] = &CPU::op_dec_rr; + opcode_table[0x0c] = &CPU::op_inc_r; + opcode_table[0x0d] = &CPU::op_dec_r; + opcode_table[0x0e] = &CPU::op_ld_r_n; + opcode_table[0x0f] = &CPU::op_rrca; + opcode_table[0x10] = &CPU::op_stop; + opcode_table[0x11] = &CPU::op_ld_rr_nn; + opcode_table[0x12] = &CPU::op_ld_rr_a; + opcode_table[0x13] = &CPU::op_inc_rr; + opcode_table[0x14] = &CPU::op_inc_r; + opcode_table[0x15] = &CPU::op_dec_r; + opcode_table[0x16] = &CPU::op_ld_r_n; + opcode_table[0x17] = &CPU::op_rla; + opcode_table[0x18] = &CPU::op_jr_n; + opcode_table[0x19] = &CPU::op_add_hl_rr; + opcode_table[0x1a] = &CPU::op_ld_a_rr; + opcode_table[0x1b] = &CPU::op_dec_rr; + opcode_table[0x1c] = &CPU::op_inc_r; + opcode_table[0x1d] = &CPU::op_dec_r; + opcode_table[0x1e] = &CPU::op_ld_r_n; + opcode_table[0x1f] = &CPU::op_rra; + opcode_table[0x20] = &CPU::op_jr_f_n; + opcode_table[0x21] = &CPU::op_ld_rr_nn; + opcode_table[0x22] = &CPU::op_ldi_hl_a; + opcode_table[0x23] = &CPU::op_inc_rr; + opcode_table[0x24] = &CPU::op_inc_r; + opcode_table[0x25] = &CPU::op_dec_r; + opcode_table[0x26] = &CPU::op_ld_r_n; + opcode_table[0x27] = &CPU::op_daa; + opcode_table[0x28] = &CPU::op_jr_f_n; + opcode_table[0x29] = &CPU::op_add_hl_rr; + opcode_table[0x2a] = &CPU::op_ldi_a_hl; + opcode_table[0x2b] = &CPU::op_dec_rr; + opcode_table[0x2c] = &CPU::op_inc_r; + opcode_table[0x2d] = &CPU::op_dec_r; + opcode_table[0x2e] = &CPU::op_ld_r_n; + opcode_table[0x2f] = &CPU::op_cpl; + opcode_table[0x30] = &CPU::op_jr_f_n; + opcode_table[0x31] = &CPU::op_ld_rr_nn; + opcode_table[0x32] = &CPU::op_ldd_hl_a; + opcode_table[0x33] = &CPU::op_inc_rr; + opcode_table[0x34] = &CPU::op_inc_hl; + opcode_table[0x35] = &CPU::op_dec_hl; + opcode_table[0x36] = &CPU::op_ld_hl_n; + opcode_table[0x37] = &CPU::op_scf; + opcode_table[0x38] = &CPU::op_jr_f_n; + opcode_table[0x39] = &CPU::op_add_hl_rr; + opcode_table[0x3a] = &CPU::op_ldd_a_hl; + opcode_table[0x3b] = &CPU::op_dec_rr; + opcode_table[0x3c] = &CPU::op_inc_r; + opcode_table[0x3d] = &CPU::op_dec_r; + opcode_table[0x3e] = &CPU::op_ld_r_n; + opcode_table[0x3f] = &CPU::op_ccf; + opcode_table[0x40] = &CPU::op_ld_r_r; + opcode_table[0x41] = &CPU::op_ld_r_r; + opcode_table[0x42] = &CPU::op_ld_r_r; + opcode_table[0x43] = &CPU::op_ld_r_r; + opcode_table[0x44] = &CPU::op_ld_r_r; + opcode_table[0x45] = &CPU::op_ld_r_r; + opcode_table[0x46] = &CPU::op_ld_r_hl; + opcode_table[0x47] = &CPU::op_ld_r_r; + opcode_table[0x48] = &CPU::op_ld_r_r; + opcode_table[0x49] = &CPU::op_ld_r_r; + opcode_table[0x4a] = &CPU::op_ld_r_r; + opcode_table[0x4b] = &CPU::op_ld_r_r; + opcode_table[0x4c] = &CPU::op_ld_r_r; + opcode_table[0x4d] = &CPU::op_ld_r_r; + opcode_table[0x4e] = &CPU::op_ld_r_hl; + opcode_table[0x4f] = &CPU::op_ld_r_r; + opcode_table[0x50] = &CPU::op_ld_r_r; + opcode_table[0x51] = &CPU::op_ld_r_r; + opcode_table[0x52] = &CPU::op_ld_r_r; + opcode_table[0x53] = &CPU::op_ld_r_r; + opcode_table[0x54] = &CPU::op_ld_r_r; + opcode_table[0x55] = &CPU::op_ld_r_r; + opcode_table[0x56] = &CPU::op_ld_r_hl; + opcode_table[0x57] = &CPU::op_ld_r_r; + opcode_table[0x58] = &CPU::op_ld_r_r; + opcode_table[0x59] = &CPU::op_ld_r_r; + opcode_table[0x5a] = &CPU::op_ld_r_r; + opcode_table[0x5b] = &CPU::op_ld_r_r; + opcode_table[0x5c] = &CPU::op_ld_r_r; + opcode_table[0x5d] = &CPU::op_ld_r_r; + opcode_table[0x5e] = &CPU::op_ld_r_hl; + opcode_table[0x5f] = &CPU::op_ld_r_r; + opcode_table[0x60] = &CPU::op_ld_r_r; + opcode_table[0x61] = &CPU::op_ld_r_r; + opcode_table[0x62] = &CPU::op_ld_r_r; + opcode_table[0x63] = &CPU::op_ld_r_r; + opcode_table[0x64] = &CPU::op_ld_r_r; + opcode_table[0x65] = &CPU::op_ld_r_r; + opcode_table[0x66] = &CPU::op_ld_r_hl; + opcode_table[0x67] = &CPU::op_ld_r_r; + opcode_table[0x68] = &CPU::op_ld_r_r; + opcode_table[0x69] = &CPU::op_ld_r_r; + opcode_table[0x6a] = &CPU::op_ld_r_r; + opcode_table[0x6b] = &CPU::op_ld_r_r; + opcode_table[0x6c] = &CPU::op_ld_r_r; + opcode_table[0x6d] = &CPU::op_ld_r_r; + opcode_table[0x6e] = &CPU::op_ld_r_hl; + opcode_table[0x6f] = &CPU::op_ld_r_r; + opcode_table[0x70] = &CPU::op_ld_hl_r; + opcode_table[0x71] = &CPU::op_ld_hl_r; + opcode_table[0x72] = &CPU::op_ld_hl_r; + opcode_table[0x73] = &CPU::op_ld_hl_r; + opcode_table[0x74] = &CPU::op_ld_hl_r; + opcode_table[0x75] = &CPU::op_ld_hl_r; + opcode_table[0x76] = &CPU::op_halt; + opcode_table[0x77] = &CPU::op_ld_hl_r; + opcode_table[0x78] = &CPU::op_ld_r_r; + opcode_table[0x79] = &CPU::op_ld_r_r; + opcode_table[0x7a] = &CPU::op_ld_r_r; + opcode_table[0x7b] = &CPU::op_ld_r_r; + opcode_table[0x7c] = &CPU::op_ld_r_r; + opcode_table[0x7d] = &CPU::op_ld_r_r; + opcode_table[0x7e] = &CPU::op_ld_r_hl; + opcode_table[0x7f] = &CPU::op_ld_r_r; + opcode_table[0x80] = &CPU::op_add_a_r; + opcode_table[0x81] = &CPU::op_add_a_r; + opcode_table[0x82] = &CPU::op_add_a_r; + opcode_table[0x83] = &CPU::op_add_a_r; + opcode_table[0x84] = &CPU::op_add_a_r; + opcode_table[0x85] = &CPU::op_add_a_r; + opcode_table[0x86] = &CPU::op_add_a_hl; + opcode_table[0x87] = &CPU::op_add_a_r; + opcode_table[0x88] = &CPU::op_adc_a_r; + opcode_table[0x89] = &CPU::op_adc_a_r; + opcode_table[0x8a] = &CPU::op_adc_a_r; + opcode_table[0x8b] = &CPU::op_adc_a_r; + opcode_table[0x8c] = &CPU::op_adc_a_r; + opcode_table[0x8d] = &CPU::op_adc_a_r; + opcode_table[0x8e] = &CPU::op_adc_a_hl; + opcode_table[0x8f] = &CPU::op_adc_a_r; + opcode_table[0x90] = &CPU::op_sub_a_r; + opcode_table[0x91] = &CPU::op_sub_a_r; + opcode_table[0x92] = &CPU::op_sub_a_r; + opcode_table[0x93] = &CPU::op_sub_a_r; + opcode_table[0x94] = &CPU::op_sub_a_r; + opcode_table[0x95] = &CPU::op_sub_a_r; + opcode_table[0x96] = &CPU::op_sub_a_hl; + opcode_table[0x97] = &CPU::op_sub_a_r; + opcode_table[0x98] = &CPU::op_sbc_a_r; + opcode_table[0x99] = &CPU::op_sbc_a_r; + opcode_table[0x9a] = &CPU::op_sbc_a_r; + opcode_table[0x9b] = &CPU::op_sbc_a_r; + opcode_table[0x9c] = &CPU::op_sbc_a_r; + opcode_table[0x9d] = &CPU::op_sbc_a_r; + opcode_table[0x9e] = &CPU::op_sbc_a_hl; + opcode_table[0x9f] = &CPU::op_sbc_a_r; + opcode_table[0xa0] = &CPU::op_and_a_r; + opcode_table[0xa1] = &CPU::op_and_a_r; + opcode_table[0xa2] = &CPU::op_and_a_r; + opcode_table[0xa3] = &CPU::op_and_a_r; + opcode_table[0xa4] = &CPU::op_and_a_r; + opcode_table[0xa5] = &CPU::op_and_a_r; + opcode_table[0xa6] = &CPU::op_and_a_hl; + opcode_table[0xa7] = &CPU::op_and_a_r; + opcode_table[0xa8] = &CPU::op_xor_a_r; + opcode_table[0xa9] = &CPU::op_xor_a_r; + opcode_table[0xaa] = &CPU::op_xor_a_r; + opcode_table[0xab] = &CPU::op_xor_a_r; + opcode_table[0xac] = &CPU::op_xor_a_r; + opcode_table[0xad] = &CPU::op_xor_a_r; + opcode_table[0xae] = &CPU::op_xor_a_hl; + opcode_table[0xaf] = &CPU::op_xor_a_r; + opcode_table[0xb0] = &CPU::op_or_a_r; + opcode_table[0xb1] = &CPU::op_or_a_r; + opcode_table[0xb2] = &CPU::op_or_a_r; + opcode_table[0xb3] = &CPU::op_or_a_r; + opcode_table[0xb4] = &CPU::op_or_a_r; + opcode_table[0xb5] = &CPU::op_or_a_r; + opcode_table[0xb6] = &CPU::op_or_a_hl; + opcode_table[0xb7] = &CPU::op_or_a_r; + opcode_table[0xb8] = &CPU::op_cp_a_r; + opcode_table[0xb9] = &CPU::op_cp_a_r; + opcode_table[0xba] = &CPU::op_cp_a_r; + opcode_table[0xbb] = &CPU::op_cp_a_r; + opcode_table[0xbc] = &CPU::op_cp_a_r; + opcode_table[0xbd] = &CPU::op_cp_a_r; + opcode_table[0xbe] = &CPU::op_cp_a_hl; + opcode_table[0xbf] = &CPU::op_cp_a_r; + opcode_table[0xc0] = &CPU::op_ret_f; + opcode_table[0xc1] = &CPU::op_pop_rr; + opcode_table[0xc2] = &CPU::op_jp_f_nn; + opcode_table[0xc3] = &CPU::op_jp_nn; + opcode_table[0xc4] = &CPU::op_call_f_nn; + opcode_table[0xc5] = &CPU::op_push_rr; + opcode_table[0xc6] = &CPU::op_add_a_n; + opcode_table[0xc7] = &CPU::op_rst_n<0x00>; + opcode_table[0xc8] = &CPU::op_ret_f; + opcode_table[0xc9] = &CPU::op_ret; + opcode_table[0xca] = &CPU::op_jp_f_nn; + opcode_table[0xcb] = &CPU::op_cb; + opcode_table[0xcc] = &CPU::op_call_f_nn; + opcode_table[0xcd] = &CPU::op_call_nn; + opcode_table[0xce] = &CPU::op_adc_a_n; + opcode_table[0xcf] = &CPU::op_rst_n<0x08>; + opcode_table[0xd0] = &CPU::op_ret_f; + opcode_table[0xd1] = &CPU::op_pop_rr; + opcode_table[0xd2] = &CPU::op_jp_f_nn; + opcode_table[0xd3] = &CPU::op_xx; + opcode_table[0xd4] = &CPU::op_call_f_nn; + opcode_table[0xd5] = &CPU::op_push_rr; + opcode_table[0xd6] = &CPU::op_sub_a_n; + opcode_table[0xd7] = &CPU::op_rst_n<0x10>; + opcode_table[0xd8] = &CPU::op_ret_f; + opcode_table[0xd9] = &CPU::op_reti; + opcode_table[0xda] = &CPU::op_jp_f_nn; + opcode_table[0xdb] = &CPU::op_xx; + opcode_table[0xdc] = &CPU::op_call_f_nn; + opcode_table[0xdd] = &CPU::op_xx; + opcode_table[0xde] = &CPU::op_sbc_a_n; + opcode_table[0xdf] = &CPU::op_rst_n<0x18>; + opcode_table[0xe0] = &CPU::op_ld_ffn_a; + opcode_table[0xe1] = &CPU::op_pop_rr; + opcode_table[0xe2] = &CPU::op_ld_ffc_a; + opcode_table[0xe3] = &CPU::op_xx; + opcode_table[0xe4] = &CPU::op_xx; + opcode_table[0xe5] = &CPU::op_push_rr; + opcode_table[0xe6] = &CPU::op_and_a_n; + opcode_table[0xe7] = &CPU::op_rst_n<0x20>; + opcode_table[0xe8] = &CPU::op_add_sp_n; + opcode_table[0xe9] = &CPU::op_jp_hl; + opcode_table[0xea] = &CPU::op_ld_nn_a; + opcode_table[0xeb] = &CPU::op_xx; + opcode_table[0xec] = &CPU::op_xx; + opcode_table[0xed] = &CPU::op_xx; + opcode_table[0xee] = &CPU::op_xor_a_n; + opcode_table[0xef] = &CPU::op_rst_n<0x28>; + opcode_table[0xf0] = &CPU::op_ld_a_ffn; + opcode_table[0xf1] = &CPU::op_pop_rr; + opcode_table[0xf2] = &CPU::op_xx; + opcode_table[0xf3] = &CPU::op_di; + opcode_table[0xf4] = &CPU::op_xx; + opcode_table[0xf5] = &CPU::op_push_rr; + opcode_table[0xf6] = &CPU::op_or_a_n; + opcode_table[0xf7] = &CPU::op_rst_n<0x30>; + opcode_table[0xf8] = &CPU::op_ld_hl_sp_n; + opcode_table[0xf9] = &CPU::op_ld_sp_hl; + opcode_table[0xfa] = &CPU::op_ld_a_nn; + opcode_table[0xfb] = &CPU::op_ei; + opcode_table[0xfc] = &CPU::op_xx; + opcode_table[0xfd] = &CPU::op_xx; + opcode_table[0xfe] = &CPU::op_cp_a_n; + opcode_table[0xff] = &CPU::op_rst_n<0x38>; + + opcode_table_cb[0x00] = &CPU::op_rlc_r; + opcode_table_cb[0x01] = &CPU::op_rlc_r; + opcode_table_cb[0x02] = &CPU::op_rlc_r; + opcode_table_cb[0x03] = &CPU::op_rlc_r; + opcode_table_cb[0x04] = &CPU::op_rlc_r; + opcode_table_cb[0x05] = &CPU::op_rlc_r; + opcode_table_cb[0x06] = &CPU::op_rlc_hl; + opcode_table_cb[0x07] = &CPU::op_rlc_r; + opcode_table_cb[0x08] = &CPU::op_rrc_r; + opcode_table_cb[0x09] = &CPU::op_rrc_r; + opcode_table_cb[0x0a] = &CPU::op_rrc_r; + opcode_table_cb[0x0b] = &CPU::op_rrc_r; + opcode_table_cb[0x0c] = &CPU::op_rrc_r; + opcode_table_cb[0x0d] = &CPU::op_rrc_r; + opcode_table_cb[0x0e] = &CPU::op_rrc_hl; + opcode_table_cb[0x0f] = &CPU::op_rrc_r; + opcode_table_cb[0x10] = &CPU::op_rl_r; + opcode_table_cb[0x11] = &CPU::op_rl_r; + opcode_table_cb[0x12] = &CPU::op_rl_r; + opcode_table_cb[0x13] = &CPU::op_rl_r; + opcode_table_cb[0x14] = &CPU::op_rl_r; + opcode_table_cb[0x15] = &CPU::op_rl_r; + opcode_table_cb[0x16] = &CPU::op_rl_hl; + opcode_table_cb[0x17] = &CPU::op_rl_r; + opcode_table_cb[0x18] = &CPU::op_rr_r; + opcode_table_cb[0x19] = &CPU::op_rr_r; + opcode_table_cb[0x1a] = &CPU::op_rr_r; + opcode_table_cb[0x1b] = &CPU::op_rr_r; + opcode_table_cb[0x1c] = &CPU::op_rr_r; + opcode_table_cb[0x1d] = &CPU::op_rr_r; + opcode_table_cb[0x1e] = &CPU::op_rr_hl; + opcode_table_cb[0x1f] = &CPU::op_rr_r; + opcode_table_cb[0x20] = &CPU::op_sla_r; + opcode_table_cb[0x21] = &CPU::op_sla_r; + opcode_table_cb[0x22] = &CPU::op_sla_r; + opcode_table_cb[0x23] = &CPU::op_sla_r; + opcode_table_cb[0x24] = &CPU::op_sla_r; + opcode_table_cb[0x25] = &CPU::op_sla_r; + opcode_table_cb[0x26] = &CPU::op_sla_hl; + opcode_table_cb[0x27] = &CPU::op_sla_r; + opcode_table_cb[0x28] = &CPU::op_sra_r; + opcode_table_cb[0x29] = &CPU::op_sra_r; + opcode_table_cb[0x2a] = &CPU::op_sra_r; + opcode_table_cb[0x2b] = &CPU::op_sra_r; + opcode_table_cb[0x2c] = &CPU::op_sra_r; + opcode_table_cb[0x2d] = &CPU::op_sra_r; + opcode_table_cb[0x2e] = &CPU::op_sra_hl; + opcode_table_cb[0x2f] = &CPU::op_sra_r; + opcode_table_cb[0x30] = &CPU::op_swap_r; + opcode_table_cb[0x31] = &CPU::op_swap_r; + opcode_table_cb[0x32] = &CPU::op_swap_r; + opcode_table_cb[0x33] = &CPU::op_swap_r; + opcode_table_cb[0x34] = &CPU::op_swap_r; + opcode_table_cb[0x35] = &CPU::op_swap_r; + opcode_table_cb[0x36] = &CPU::op_swap_hl; + opcode_table_cb[0x37] = &CPU::op_swap_r; + opcode_table_cb[0x38] = &CPU::op_srl_r; + opcode_table_cb[0x39] = &CPU::op_srl_r; + opcode_table_cb[0x3a] = &CPU::op_srl_r; + opcode_table_cb[0x3b] = &CPU::op_srl_r; + opcode_table_cb[0x3c] = &CPU::op_srl_r; + opcode_table_cb[0x3d] = &CPU::op_srl_r; + opcode_table_cb[0x3e] = &CPU::op_srl_hl; + opcode_table_cb[0x3f] = &CPU::op_srl_r; + opcode_table_cb[0x40] = &CPU::op_bit_n_r<0, B>; + opcode_table_cb[0x41] = &CPU::op_bit_n_r<0, C>; + opcode_table_cb[0x42] = &CPU::op_bit_n_r<0, D>; + opcode_table_cb[0x43] = &CPU::op_bit_n_r<0, E>; + opcode_table_cb[0x44] = &CPU::op_bit_n_r<0, H>; + opcode_table_cb[0x45] = &CPU::op_bit_n_r<0, L>; + opcode_table_cb[0x46] = &CPU::op_bit_n_hl<0>; + opcode_table_cb[0x47] = &CPU::op_bit_n_r<0, A>; + opcode_table_cb[0x48] = &CPU::op_bit_n_r<1, B>; + opcode_table_cb[0x49] = &CPU::op_bit_n_r<1, C>; + opcode_table_cb[0x4a] = &CPU::op_bit_n_r<1, D>; + opcode_table_cb[0x4b] = &CPU::op_bit_n_r<1, E>; + opcode_table_cb[0x4c] = &CPU::op_bit_n_r<1, H>; + opcode_table_cb[0x4d] = &CPU::op_bit_n_r<1, L>; + opcode_table_cb[0x4e] = &CPU::op_bit_n_hl<1>; + opcode_table_cb[0x4f] = &CPU::op_bit_n_r<1, A>; + opcode_table_cb[0x50] = &CPU::op_bit_n_r<2, B>; + opcode_table_cb[0x51] = &CPU::op_bit_n_r<2, C>; + opcode_table_cb[0x52] = &CPU::op_bit_n_r<2, D>; + opcode_table_cb[0x53] = &CPU::op_bit_n_r<2, E>; + opcode_table_cb[0x54] = &CPU::op_bit_n_r<2, H>; + opcode_table_cb[0x55] = &CPU::op_bit_n_r<2, L>; + opcode_table_cb[0x56] = &CPU::op_bit_n_hl<2>; + opcode_table_cb[0x57] = &CPU::op_bit_n_r<2, A>; + opcode_table_cb[0x58] = &CPU::op_bit_n_r<3, B>; + opcode_table_cb[0x59] = &CPU::op_bit_n_r<3, C>; + opcode_table_cb[0x5a] = &CPU::op_bit_n_r<3, D>; + opcode_table_cb[0x5b] = &CPU::op_bit_n_r<3, E>; + opcode_table_cb[0x5c] = &CPU::op_bit_n_r<3, H>; + opcode_table_cb[0x5d] = &CPU::op_bit_n_r<3, L>; + opcode_table_cb[0x5e] = &CPU::op_bit_n_hl<3>; + opcode_table_cb[0x5f] = &CPU::op_bit_n_r<3, A>; + opcode_table_cb[0x60] = &CPU::op_bit_n_r<4, B>; + opcode_table_cb[0x61] = &CPU::op_bit_n_r<4, C>; + opcode_table_cb[0x62] = &CPU::op_bit_n_r<4, D>; + opcode_table_cb[0x63] = &CPU::op_bit_n_r<4, E>; + opcode_table_cb[0x64] = &CPU::op_bit_n_r<4, H>; + opcode_table_cb[0x65] = &CPU::op_bit_n_r<4, L>; + opcode_table_cb[0x66] = &CPU::op_bit_n_hl<4>; + opcode_table_cb[0x67] = &CPU::op_bit_n_r<4, A>; + opcode_table_cb[0x68] = &CPU::op_bit_n_r<5, B>; + opcode_table_cb[0x69] = &CPU::op_bit_n_r<5, C>; + opcode_table_cb[0x6a] = &CPU::op_bit_n_r<5, D>; + opcode_table_cb[0x6b] = &CPU::op_bit_n_r<5, E>; + opcode_table_cb[0x6c] = &CPU::op_bit_n_r<5, H>; + opcode_table_cb[0x6d] = &CPU::op_bit_n_r<5, L>; + opcode_table_cb[0x6e] = &CPU::op_bit_n_hl<5>; + opcode_table_cb[0x6f] = &CPU::op_bit_n_r<5, A>; + opcode_table_cb[0x70] = &CPU::op_bit_n_r<6, B>; + opcode_table_cb[0x71] = &CPU::op_bit_n_r<6, C>; + opcode_table_cb[0x72] = &CPU::op_bit_n_r<6, D>; + opcode_table_cb[0x73] = &CPU::op_bit_n_r<6, E>; + opcode_table_cb[0x74] = &CPU::op_bit_n_r<6, H>; + opcode_table_cb[0x75] = &CPU::op_bit_n_r<6, L>; + opcode_table_cb[0x76] = &CPU::op_bit_n_hl<6>; + opcode_table_cb[0x77] = &CPU::op_bit_n_r<6, A>; + opcode_table_cb[0x78] = &CPU::op_bit_n_r<7, B>; + opcode_table_cb[0x79] = &CPU::op_bit_n_r<7, C>; + opcode_table_cb[0x7a] = &CPU::op_bit_n_r<7, D>; + opcode_table_cb[0x7b] = &CPU::op_bit_n_r<7, E>; + opcode_table_cb[0x7c] = &CPU::op_bit_n_r<7, H>; + opcode_table_cb[0x7d] = &CPU::op_bit_n_r<7, L>; + opcode_table_cb[0x7e] = &CPU::op_bit_n_hl<7>; + opcode_table_cb[0x7f] = &CPU::op_bit_n_r<7, A>; + opcode_table_cb[0x80] = &CPU::op_res_n_r<0, B>; + opcode_table_cb[0x81] = &CPU::op_res_n_r<0, C>; + opcode_table_cb[0x82] = &CPU::op_res_n_r<0, D>; + opcode_table_cb[0x83] = &CPU::op_res_n_r<0, E>; + opcode_table_cb[0x84] = &CPU::op_res_n_r<0, H>; + opcode_table_cb[0x85] = &CPU::op_res_n_r<0, L>; + opcode_table_cb[0x86] = &CPU::op_res_n_hl<0>; + opcode_table_cb[0x87] = &CPU::op_res_n_r<0, A>; + opcode_table_cb[0x88] = &CPU::op_res_n_r<1, B>; + opcode_table_cb[0x89] = &CPU::op_res_n_r<1, C>; + opcode_table_cb[0x8a] = &CPU::op_res_n_r<1, D>; + opcode_table_cb[0x8b] = &CPU::op_res_n_r<1, E>; + opcode_table_cb[0x8c] = &CPU::op_res_n_r<1, H>; + opcode_table_cb[0x8d] = &CPU::op_res_n_r<1, L>; + opcode_table_cb[0x8e] = &CPU::op_res_n_hl<1>; + opcode_table_cb[0x8f] = &CPU::op_res_n_r<1, A>; + opcode_table_cb[0x90] = &CPU::op_res_n_r<2, B>; + opcode_table_cb[0x91] = &CPU::op_res_n_r<2, C>; + opcode_table_cb[0x92] = &CPU::op_res_n_r<2, D>; + opcode_table_cb[0x93] = &CPU::op_res_n_r<2, E>; + opcode_table_cb[0x94] = &CPU::op_res_n_r<2, H>; + opcode_table_cb[0x95] = &CPU::op_res_n_r<2, L>; + opcode_table_cb[0x96] = &CPU::op_res_n_hl<2>; + opcode_table_cb[0x97] = &CPU::op_res_n_r<2, A>; + opcode_table_cb[0x98] = &CPU::op_res_n_r<3, B>; + opcode_table_cb[0x99] = &CPU::op_res_n_r<3, C>; + opcode_table_cb[0x9a] = &CPU::op_res_n_r<3, D>; + opcode_table_cb[0x9b] = &CPU::op_res_n_r<3, E>; + opcode_table_cb[0x9c] = &CPU::op_res_n_r<3, H>; + opcode_table_cb[0x9d] = &CPU::op_res_n_r<3, L>; + opcode_table_cb[0x9e] = &CPU::op_res_n_hl<3>; + opcode_table_cb[0x9f] = &CPU::op_res_n_r<3, A>; + opcode_table_cb[0xa0] = &CPU::op_res_n_r<4, B>; + opcode_table_cb[0xa1] = &CPU::op_res_n_r<4, C>; + opcode_table_cb[0xa2] = &CPU::op_res_n_r<4, D>; + opcode_table_cb[0xa3] = &CPU::op_res_n_r<4, E>; + opcode_table_cb[0xa4] = &CPU::op_res_n_r<4, H>; + opcode_table_cb[0xa5] = &CPU::op_res_n_r<4, L>; + opcode_table_cb[0xa6] = &CPU::op_res_n_hl<4>; + opcode_table_cb[0xa7] = &CPU::op_res_n_r<4, A>; + opcode_table_cb[0xa8] = &CPU::op_res_n_r<5, B>; + opcode_table_cb[0xa9] = &CPU::op_res_n_r<5, C>; + opcode_table_cb[0xaa] = &CPU::op_res_n_r<5, D>; + opcode_table_cb[0xab] = &CPU::op_res_n_r<5, E>; + opcode_table_cb[0xac] = &CPU::op_res_n_r<5, H>; + opcode_table_cb[0xad] = &CPU::op_res_n_r<5, L>; + opcode_table_cb[0xae] = &CPU::op_res_n_hl<5>; + opcode_table_cb[0xaf] = &CPU::op_res_n_r<5, A>; + opcode_table_cb[0xb0] = &CPU::op_res_n_r<6, B>; + opcode_table_cb[0xb1] = &CPU::op_res_n_r<6, C>; + opcode_table_cb[0xb2] = &CPU::op_res_n_r<6, D>; + opcode_table_cb[0xb3] = &CPU::op_res_n_r<6, E>; + opcode_table_cb[0xb4] = &CPU::op_res_n_r<6, H>; + opcode_table_cb[0xb5] = &CPU::op_res_n_r<6, L>; + opcode_table_cb[0xb6] = &CPU::op_res_n_hl<6>; + opcode_table_cb[0xb7] = &CPU::op_res_n_r<6, A>; + opcode_table_cb[0xb8] = &CPU::op_res_n_r<7, B>; + opcode_table_cb[0xb9] = &CPU::op_res_n_r<7, C>; + opcode_table_cb[0xba] = &CPU::op_res_n_r<7, D>; + opcode_table_cb[0xbb] = &CPU::op_res_n_r<7, E>; + opcode_table_cb[0xbc] = &CPU::op_res_n_r<7, H>; + opcode_table_cb[0xbd] = &CPU::op_res_n_r<7, L>; + opcode_table_cb[0xbe] = &CPU::op_res_n_hl<7>; + opcode_table_cb[0xbf] = &CPU::op_res_n_r<7, A>; + opcode_table_cb[0xc0] = &CPU::op_set_n_r<0, B>; + opcode_table_cb[0xc1] = &CPU::op_set_n_r<0, C>; + opcode_table_cb[0xc2] = &CPU::op_set_n_r<0, D>; + opcode_table_cb[0xc3] = &CPU::op_set_n_r<0, E>; + opcode_table_cb[0xc4] = &CPU::op_set_n_r<0, H>; + opcode_table_cb[0xc5] = &CPU::op_set_n_r<0, L>; + opcode_table_cb[0xc6] = &CPU::op_set_n_hl<0>; + opcode_table_cb[0xc7] = &CPU::op_set_n_r<0, A>; + opcode_table_cb[0xc8] = &CPU::op_set_n_r<1, B>; + opcode_table_cb[0xc9] = &CPU::op_set_n_r<1, C>; + opcode_table_cb[0xca] = &CPU::op_set_n_r<1, D>; + opcode_table_cb[0xcb] = &CPU::op_set_n_r<1, E>; + opcode_table_cb[0xcc] = &CPU::op_set_n_r<1, H>; + opcode_table_cb[0xcd] = &CPU::op_set_n_r<1, L>; + opcode_table_cb[0xce] = &CPU::op_set_n_hl<1>; + opcode_table_cb[0xcf] = &CPU::op_set_n_r<1, A>; + opcode_table_cb[0xd0] = &CPU::op_set_n_r<2, B>; + opcode_table_cb[0xd1] = &CPU::op_set_n_r<2, C>; + opcode_table_cb[0xd2] = &CPU::op_set_n_r<2, D>; + opcode_table_cb[0xd3] = &CPU::op_set_n_r<2, E>; + opcode_table_cb[0xd4] = &CPU::op_set_n_r<2, H>; + opcode_table_cb[0xd5] = &CPU::op_set_n_r<2, L>; + opcode_table_cb[0xd6] = &CPU::op_set_n_hl<2>; + opcode_table_cb[0xd7] = &CPU::op_set_n_r<2, A>; + opcode_table_cb[0xd8] = &CPU::op_set_n_r<3, B>; + opcode_table_cb[0xd9] = &CPU::op_set_n_r<3, C>; + opcode_table_cb[0xda] = &CPU::op_set_n_r<3, D>; + opcode_table_cb[0xdb] = &CPU::op_set_n_r<3, E>; + opcode_table_cb[0xdc] = &CPU::op_set_n_r<3, H>; + opcode_table_cb[0xdd] = &CPU::op_set_n_r<3, L>; + opcode_table_cb[0xde] = &CPU::op_set_n_hl<3>; + opcode_table_cb[0xdf] = &CPU::op_set_n_r<3, A>; + opcode_table_cb[0xe0] = &CPU::op_set_n_r<4, B>; + opcode_table_cb[0xe1] = &CPU::op_set_n_r<4, C>; + opcode_table_cb[0xe2] = &CPU::op_set_n_r<4, D>; + opcode_table_cb[0xe3] = &CPU::op_set_n_r<4, E>; + opcode_table_cb[0xe4] = &CPU::op_set_n_r<4, H>; + opcode_table_cb[0xe5] = &CPU::op_set_n_r<4, L>; + opcode_table_cb[0xe6] = &CPU::op_set_n_hl<4>; + opcode_table_cb[0xe7] = &CPU::op_set_n_r<4, A>; + opcode_table_cb[0xe8] = &CPU::op_set_n_r<5, B>; + opcode_table_cb[0xe9] = &CPU::op_set_n_r<5, C>; + opcode_table_cb[0xea] = &CPU::op_set_n_r<5, D>; + opcode_table_cb[0xeb] = &CPU::op_set_n_r<5, E>; + opcode_table_cb[0xec] = &CPU::op_set_n_r<5, H>; + opcode_table_cb[0xed] = &CPU::op_set_n_r<5, L>; + opcode_table_cb[0xee] = &CPU::op_set_n_hl<5>; + opcode_table_cb[0xef] = &CPU::op_set_n_r<5, A>; + opcode_table_cb[0xf0] = &CPU::op_set_n_r<6, B>; + opcode_table_cb[0xf1] = &CPU::op_set_n_r<6, C>; + opcode_table_cb[0xf2] = &CPU::op_set_n_r<6, D>; + opcode_table_cb[0xf3] = &CPU::op_set_n_r<6, E>; + opcode_table_cb[0xf4] = &CPU::op_set_n_r<6, H>; + opcode_table_cb[0xf5] = &CPU::op_set_n_r<6, L>; + opcode_table_cb[0xf6] = &CPU::op_set_n_hl<6>; + opcode_table_cb[0xf7] = &CPU::op_set_n_r<6, A>; + opcode_table_cb[0xf8] = &CPU::op_set_n_r<7, B>; + opcode_table_cb[0xf9] = &CPU::op_set_n_r<7, C>; + opcode_table_cb[0xfa] = &CPU::op_set_n_r<7, D>; + opcode_table_cb[0xfb] = &CPU::op_set_n_r<7, E>; + opcode_table_cb[0xfc] = &CPU::op_set_n_r<7, H>; + opcode_table_cb[0xfd] = &CPU::op_set_n_r<7, L>; + opcode_table_cb[0xfe] = &CPU::op_set_n_hl<7>; + opcode_table_cb[0xff] = &CPU::op_set_n_r<7, A>; +} + +#endif diff --git a/gameboy/cpu/cpu.cpp b/gameboy/cpu/cpu.cpp index f0c09f6e..0589f0a4 100755 --- a/gameboy/cpu/cpu.cpp +++ b/gameboy/cpu/cpu.cpp @@ -14,12 +14,9 @@ void CPU::Main() { void CPU::main() { while(true) { - print(disassemble(r[PC]), "\n"); - + //print(disassemble(r[PC]), "\n"); uint8 opcode = op_read(r[PC]++); (this->*opcode_table[opcode])(); - - opcode_counter++; } } diff --git a/gameboy/gameboy.hpp b/gameboy/gameboy.hpp index c5c229b3..e6ba73a5 100755 --- a/gameboy/gameboy.hpp +++ b/gameboy/gameboy.hpp @@ -5,7 +5,7 @@ namespace GameBoy { namespace Info { static const char Name[] = "bgameboy"; - static const char Version[] = "000.02"; + static const char Version[] = "000.03"; } } diff --git a/ui/main.cpp b/ui/main.cpp index 8aace5a4..87deb7f4 100755 --- a/ui/main.cpp +++ b/ui/main.cpp @@ -14,11 +14,22 @@ void Application::main(int argc, char **argv) { GameBoy::system.init(&interface); + unsigned frameCounter = 0; + time_t timeCounter = time(0); + while(quit == false) { OS::run(); if(GameBoy::cartridge.loaded()) { GameBoy::system.run(); + + frameCounter++; + time_t currentTime = time(0); + if(currentTime != timeCounter) { + timeCounter = currentTime; + mainWindow.setStatusText({ "FPS: ", frameCounter }); + frameCounter = 0; + } } } }