diff --git a/include/cpu.h b/include/cpu.h index 678944e..984ebce 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -47,6 +47,10 @@ u16 cpu_read_reg(reg_type rt); void cpu_set_reg(reg_type rt, u16 val); +u8 cpu_read_reg8(reg_type rt); + +void cpu_set_reg8(reg_type rt, u8 val); + void fetch_data(); u8 cpu_get_ie_register(); diff --git a/lib/bus.c b/lib/bus.c index f7cd79b..a290bc7 100644 --- a/lib/bus.c +++ b/lib/bus.c @@ -108,5 +108,5 @@ u16 bus_read16(u16 address) { void bus_write16(u16 address, u16 value) { bus_write(address+1, (value >> 8) & 0xFF); - bus_write(address, value * 0xFF); + bus_write(address, value & 0xFF); } \ No newline at end of file diff --git a/lib/cart.c b/lib/cart.c index 11f95d1..f6c0247 100644 --- a/lib/cart.c +++ b/lib/cart.c @@ -183,6 +183,6 @@ u8 cart_read(u16 address){ } void cart_write(u16 address, u8 value){ - printf("UNSUPPORTED cart_write(%04X)\n"); + printf("UNSUPPORTED cart_write(%04X)\n", address); //NO_IMPL } \ No newline at end of file diff --git a/lib/cpu.c b/lib/cpu.c index d3326f8..f5768cd 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -1,6 +1,7 @@ #include #include #include +#include cpu_context ctx = {0}; @@ -29,12 +30,19 @@ bool cpu_step() { if(!ctx.halted) { u16 pc = ctx.regs.pc; fetch_instruction(); - printf("%04X: %-7s (%02X %02X %02X) AF: %02X%02X BC: %02X%02X DE: %02X%02X HL: %02X%02X SP: %04X PC: %04X\n", pc, inst_name(ctx.cur_inst->type), ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, ctx.regs.f, ctx.regs.b, ctx.regs.c, ctx.regs.d, ctx.regs.e, ctx.regs.h, ctx.regs.l, ctx.regs.sp, ctx.regs.pc); + fetch_data(); + char flags[16]; + sprintf(flags, "%c%c%c%c", + ctx.regs.f & (1 << 7) ? 'Z' : '-', + ctx.regs.f & (1 << 6) ? 'N' : '-', + ctx.regs.f & (1 << 5) ? 'H' : '-', + ctx.regs.f & (1 << 4) ? 'C' : '-' + ); + printf("%08lX - %04X: %-7s (%02X %02X %02X) A: %02X F: %s BC: %02X%02X DE: %02X%02X HL: %02X%02X SP: %04X PC: %04X\n", emu_get_context()->ticks, pc, inst_name(ctx.cur_inst->type), ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, flags, ctx.regs.b, ctx.regs.c, ctx.regs.d, ctx.regs.e, ctx.regs.h, ctx.regs.l, ctx.regs.sp, ctx.regs.pc); if(ctx.cur_inst == NULL){ printf("Unknown Instruction! %02X\n", ctx.cur_opcode); exit(-7); } - fetch_data(); execute(); } diff --git a/lib/cpu_proc.c b/lib/cpu_proc.c index f866754..92e2dae 100644 --- a/lib/cpu_proc.c +++ b/lib/cpu_proc.c @@ -20,6 +20,10 @@ void cpu_set_flags(cpu_context *ctx, u8 z, u8 n, u8 h, u8 c){ } } +static bool is_16_bit(reg_type rt){ + return rt >= RT_AF; +} + static void proc_none(cpu_context *ctx) { printf("INVALID INSTRUCTION!\n"); exit(-7); @@ -29,8 +33,304 @@ static void proc_nop(cpu_context *ctx) { } +static void proc_rlca(cpu_context *ctx) { + u8 u = ctx->regs.a; + bool c = (u >> 7) & 1; + u = (u << 1) | c; + ctx->regs.a = u; + + cpu_set_flags(ctx, 0, 0, 0, c); +} + +static void proc_rrca(cpu_context *ctx) { + u8 b = ctx->regs.a & 1; + ctx->regs.a >>= 1; + ctx->regs.a |= (b << 7); + + cpu_set_flags(ctx, 0, 0, 0, b); +} + +static void proc_rla(cpu_context *ctx) { + +} + +static void proc_rra(cpu_context *ctx) { + +} + +static void proc_cb(cpu_context *ctx) { + u8 op = ctx->fetched_data; + reg_type reg = decode_reg(op & 0b111); + u8 bit = (op >> 3) & 0xb111; + u8 bit_op = (op >> 6) & 0b11; + u8 reg_val = cpu_read_reg8(reg); + emu_cycles(1); + + if(reg == RT_HL) { + emu_cycles(2); + } + + switch(bit_op) { + case 1: + //BIT + cpu_set_flags(ctx, !(reg_val & (1 << bit)), 0, 1, -1); + return; + + case 2: + //RST + reg_val &= ~(1 << bit); + cpu_set_reg8(reg, reg_val); + return; + + case 3: + //set + reg_val |= (1 << bit); + cpu_set_reg8(reg, reg_val); + return; + } + + bool flagC = CPU_FLAG_C; + + switch(bit) { + case 0: { + //RLC + bool setC = false; + u8 result = (reg_val << 1) & 0xFF; + + if(reg_val & (1 << 7) != 0) { + result |= 1; + setC = true; + } + + cpu_set_reg8(reg, result); + cpu_set_flags(ctx, result == 0, 0, 0, setC); + } return; + + case 1: { + //RRC + u8 old = reg_val; + reg_val >>= 1; + reg_val |= (old << 7); + + cpu_set_reg8(reg, reg_val); + cpu_set_flags(ctx, !reg_val, 0, 0, old & 1); + } return; + + case 2: { + //RL + u8 old = reg_val; + reg_val <<= 1; + reg_val |= flagC; + + cpu_set_reg8(reg, reg_val); + cpu_set_flags(ctx, !reg_val, 0, 0, !!(old & 0x80)); + } return; + + case 3: { + //RR + u8 old = reg_val; + reg_val >>= 1; + + reg_val |= (flagC << 7); + cpu_set_reg8(reg, reg_val); + cpu_set_flags(ctx, !reg_val, 0, 0, old & 1); + } return; + + case 4: { + //SLA + u8 old = reg_val; + reg_val <<= 1; + + cpu_set_reg8(reg, reg_val); + cpu_set_flags(ctx, !reg_val, 0, 0, old & 0x80); + } return; + + case 5: { + //SRA + u8 u = (int8_t)reg_val >> 1; + cpu_set_reg8(reg, u); + cpu_set_flags(ctx, !u, 0, 0, reg_val & 1); + } return; + + case 6: { + //SWAP + reg_val = ((reg_val & 0xF0) >> 4) | ((reg_val & 0xF) << 4); + cpu_set_reg8(reg, reg_val); + cpu_set_flags(ctx, reg_val == 0, 0, 0, 0); + } return; + + case 7: { + //SRL + u8 u = reg_val >> 1; + cpu_set_reg8(reg, u); + cpu_set_flags(ctx, !u, 0, 0, reg_val & 1); + } return; + } + + fprintf(stderr, "ERROR: INVALID CB: %02X\n", op); + NO_IMPL +} + +reg_type rt_lookup[] = { + RT_B, + RT_C, + RT_D, + RT_E, + RT_H, + RT_L, + RT_HL, + RT_A +}; + +reg_type decode_reg(u8 reg) { + if (reg > 0b111) { + return RT_NONE; + } + return rt_lookup[reg]; +} + +static void proc_and(cpu_context *ctx) { + ctx->regs.a &= ctx->fetched_data; + cpu_set_flags(ctx, ctx->regs.a == 0, 0, 1, 0); +} + +static void proc_xor(cpu_context *ctx) { + ctx->regs.a ^= ctx->fetched_data & 0xFF; + cpu_set_flags(ctx, ctx->regs.a == 0, 0, 0, 0); +} + +static void proc_or(cpu_context *ctx) { + ctx->regs.a |= ctx->fetched_data & 0xFF; + cpu_set_flags(ctx, ctx->regs.a == 0, 0, 0, 0); +} + +static void proc_cp(cpu_context *ctx) { + int n = (int)ctx->regs.a - (int)ctx->fetched_data; + + cpu_set_flags(ctx, n == 0, 1, ((int)ctx->regs.a & 0x0F) - ((int)ctx->fetched_data & 0x0f) < 0, n < 0); +} + +static void proc_sub(cpu_context *ctx) { + u16 val = cpu_read_reg(ctx->cur_inst->reg_1) - ctx->fetched_data; + + int z = val == 0; + int h = ((int)cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) - ((int)ctx->fetched_data & 0xF) < 0; + int c = ((int)cpu_read_reg(ctx->cur_inst->reg_1)) - ((int)ctx->fetched_data) < 0; + + cpu_set_reg(ctx->cur_inst->reg_1, val); + cpu_set_flags(ctx, z, 1, h, c); +} + +static void proc_sbc(cpu_context *ctx) { + u8 val = ctx->fetched_data + CPU_FLAG_C; + + int z = cpu_read_reg(ctx->cur_inst->reg_1) - val == 0; + int h = ((int)cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) + - ((int)ctx->fetched_data & 0xF) - ((int)CPU_FLAG_C) < 0; + int c = ((int)cpu_read_reg(ctx->cur_inst->reg_1)) + - ((int)ctx->fetched_data) - ((int)CPU_FLAG_C) < 0; + + cpu_set_reg(ctx->cur_inst->reg_1, cpu_read_reg(ctx->cur_inst->reg_1) - val); + cpu_set_flags(ctx, z, 1, h, c); +} + +static void proc_adc(cpu_context *ctx) { + u16 u = ctx->fetched_data; + u16 a = ctx->regs.a; + u16 c = CPU_FLAG_C; + + ctx->regs.a = (a + u + c) & 0xFF; + + cpu_set_flags(ctx, ctx->regs.a == 0, 0, (a & 0xF) + (u & 0xF) + c > 0xF, a + u + c > 0xFF); +} + +static void proc_add(cpu_context *ctx) { + u32 val = cpu_read_reg(ctx->cur_inst->reg_1) + ctx->fetched_data; + + bool is_16bit = is_16_bit(ctx->cur_inst->reg_1); + + if(is_16bit) { + emu_cycles(1); + } + + if(ctx->cur_inst->reg_1 == RT_SP) { + val = cpu_read_reg(ctx->cur_inst->reg_1) + (char)ctx->fetched_data; + } + + int z = (val & 0xFF) == 0; + int h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) + (ctx->fetched_data & 0xF) >= 0x10; + int c = (int)(cpu_read_reg(ctx->cur_inst->reg_1) & 0xFF) + (int)(ctx->fetched_data & 0xFF) >= 0x100; + + if (is_16bit) { + z = -1; + h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xFFF) + (ctx->fetched_data & 0xFFF) >= 0x1000; + u32 n = ((u32)cpu_read_reg(ctx->cur_inst->reg_1)) + ((u32)ctx->fetched_data); + c = n >= 0x10000; + } + + if(ctx->cur_inst->reg_1 == RT_SP) { + z = 0; + h = (cpu_read_reg(ctx->cur_inst->reg_1) & 0xF) + (ctx->fetched_data & 0xF) >= 0x10; + c = (int)(cpu_read_reg(ctx->cur_inst->reg_1) & 0xFF) + (int)(ctx->fetched_data & 0xFF) > 0x100; + } + + cpu_set_reg(ctx->cur_inst->reg_1, val & 0xFFFF); + cpu_set_flags(ctx, z, 0, h, c); +} + +static void proc_inc(cpu_context *ctx) { + u16 val = cpu_read_reg(ctx->cur_inst->reg_1) + 1; + + if(is_16_bit(ctx->cur_inst->reg_1)) { + emu_cycles(1); + } + + if (ctx->cur_inst->reg_1 == RT_HL && ctx->dest_is_mem) { + val = bus_read(cpu_read_reg(RT_HL)) + 1; + val &= 0xFF; + bus_write(cpu_read_reg(RT_HL), val); + } else { + cpu_set_reg(ctx->cur_inst->reg_1, val); + val = cpu_read_reg(ctx->cur_inst->reg_1); + } + + if((ctx->cur_opcode & 0x03) == 0x03) { + return; + } + + cpu_set_flags(ctx, val == 0, 0, (val & 0x0F), -1); +} + +static void proc_dec(cpu_context *ctx) { + u16 val = cpu_read_reg(ctx->cur_inst->reg_1) - 1; + + if(is_16_bit(ctx->cur_inst->reg_1)) { + emu_cycles(1); + } + + if (ctx->cur_inst->reg_1 == RT_HL && ctx->dest_is_mem) { + val = bus_read(cpu_read_reg(RT_HL)) - 1; + val &= 0xFF; + bus_write(cpu_read_reg(RT_HL), val); + } else { + cpu_set_reg(ctx->cur_inst->reg_1, val); + val = cpu_read_reg(ctx->cur_inst->reg_1); + } + + if((ctx->cur_opcode & 0x0B) == 0x0B) { + return; + } + + cpu_set_flags(ctx, val == 0, 1, (val & 0x0F) == 0x0F, -1); +} + static void proc_pop(cpu_context *ctx) { - u16 n = stack_pop16(); + u16 lo = stack_pop(); + emu_cycles(1); + u16 hi = stack_pop(); + emu_cycles(1); + + u16 n = (hi << 8) | lo; cpu_set_reg(ctx->cur_inst->reg_1, n); emu_cycles(2); @@ -40,8 +340,11 @@ static void proc_pop(cpu_context *ctx) { } static void proc_push(cpu_context *ctx) { - stack_push16(cpu_read_reg(ctx->cur_inst->reg_1)); - emu_cycles(2); + u16 val = cpu_read_reg(ctx->cur_inst->reg_1); + stack_push((val >> 8) & 0xFF); + emu_cycles(1); + stack_push((val & 0xFF)); + emu_cycles(1); } static void proc_ldh(cpu_context *ctx) { @@ -53,18 +356,13 @@ static void proc_ldh(cpu_context *ctx) { emu_cycles(1); } -static void proc_xor(cpu_context *ctx) { - ctx->regs.a ^= ctx->fetched_data & 0XFF; - cpu_set_flags(ctx, ctx->regs.a == 0, 0, 0, 0); -} - static void proc_di(cpu_context *ctx) { ctx->int_master_enabled = false; } static void proc_ld(cpu_context *ctx) { if(ctx->dest_is_mem) { - if(ctx->cur_inst->reg_2 >= RT_AF) { + if(is_16_bit(ctx->cur_inst->reg_2)) { bus_write16(ctx->mem_dest, ctx->fetched_data); emu_cycles(1); } else { @@ -144,7 +442,7 @@ static void proc_reti(cpu_context *ctx) { } static void proc_jr(cpu_context *ctx) { - char rel = (char)(ctx->fetched_data & 0XFF); + int8_t rel = (int8_t)(ctx->fetched_data & 0XFF); u16 addr = ctx->regs.pc + rel; goto_addr(ctx, addr, false); } @@ -155,7 +453,6 @@ IN_PROC processors[] = { [IN_LD] = proc_ld, [IN_JP] = proc_jp, [IN_DI] = proc_di, - [IN_XOR] = proc_xor, [IN_LDH] = proc_ldh, [IN_POP] = proc_pop, [IN_PUSH] = proc_push, @@ -163,7 +460,18 @@ IN_PROC processors[] = { [IN_JR] = proc_jr, [IN_RET] = proc_ret, [IN_RETI] = proc_reti, - [IN_RST] = proc_rst + [IN_RST] = proc_rst, + [IN_INC] = proc_inc, + [IN_DEC] = proc_dec, + [IN_ADD] = proc_add, + [IN_ADC] = proc_adc, + [IN_SBC] = proc_sbc, + [IN_SUB] = proc_sub, + [IN_AND] = proc_and, + [IN_XOR] = proc_xor, + [IN_OR] = proc_or, + [IN_CP] = proc_cp, + [IN_CB] = proc_cb }; IN_PROC inst_get_processor(in_type type) { diff --git a/lib/cpu_util.c b/lib/cpu_util.c index 4084d30..f3ae0fc 100644 --- a/lib/cpu_util.c +++ b/lib/cpu_util.c @@ -1,4 +1,5 @@ #include +#include extern cpu_context ctx; @@ -50,6 +51,45 @@ void cpu_set_reg(reg_type rt, u16 val) { } } +u8 cpu_read_reg8(reg_type rt) { + switch(rt) { + case RT_A: return ctx.regs.a; + case RT_F: return ctx.regs.f; + case RT_B: return ctx.regs.b; + case RT_C: return ctx.regs.c; + case RT_D: return ctx.regs.d; + case RT_E: return ctx.regs.e; + case RT_H: return ctx.regs.h; + case RT_L: return ctx.regs.l; + + case RT_HL: { + return bus_read(cpu_read_reg(RT_HL)); + } + default: + printf("**ERR INVALID REG8: %d\n", rt); + NO_IMPL + } +} + +void cpu_set_reg8(reg_type rt, u8 val) { + switch(rt) { + case RT_A: ctx.regs.a = val & 0XFF; break; + case RT_F: ctx.regs.f = val & 0XFF; break; + case RT_B: ctx.regs.b = val & 0XFF; break; + case RT_C: ctx.regs.c = val & 0XFF; break; + case RT_D: ctx.regs.d = val & 0XFF; break; + case RT_E: ctx.regs.e = val & 0XFF; break; + case RT_H: ctx.regs.h = val & 0XFF; break; + case RT_L: ctx.regs.l = val & 0XFF; break; + + case RT_HL: bus_write(cpu_read_reg(RT_HL), val); break; + + default: + printf("**ERR INVALID REG8: %d\n", rt); + NO_IMPL + } +} + cpu_registers *cpu_get_regs() { return &ctx.regs; } \ No newline at end of file diff --git a/lib/instructions.c b/lib/instructions.c index 41cd7ed..af10498 100644 --- a/lib/instructions.c +++ b/lib/instructions.c @@ -6,37 +6,70 @@ instruction instructions[0x100] = { [0x00] = {IN_NOP, AM_IMP}, [0x01] = {IN_LD, AM_R_D16, RT_BC}, [0x02] = {IN_LD, AM_MR_R, RT_BC, RT_A}, + [0x03] = {IN_INC, AM_R, RT_BC}, + [0x04] = {IN_INC, AM_R, RT_B}, [0x05] = {IN_DEC, AM_R, RT_B}, [0x06] = {IN_LD, AM_R_D8, RT_B}, + [0x07] = {IN_RLCA}, [0x08] = {IN_LD, AM_A16_R, RT_NONE, RT_SP}, + [0x09] = {IN_ADD, AM_R_R, RT_HL, RT_BC}, [0x0A] = {IN_LD, AM_R_MR, RT_A, RT_BC}, + [0x0B] = {IN_DEC, AM_R, RT_BC}, + [0x0C] = {IN_INC, AM_R, RT_C}, + [0x0D] = {IN_DEC, AM_R, RT_C}, [0x0E] = {IN_LD, AM_R_D8, RT_C}, + [0x0F] = {IN_RRA}, //0x1X + [0x10] = {IN_STOP}, [0x11] = {IN_LD, AM_R_D16, RT_DE}, [0x12] = {IN_LD, AM_MR_R, RT_DE, RT_A}, + [0x13] = {IN_INC, AM_R, RT_DE}, + [0x14] = {IN_INC, AM_R, RT_D}, [0x15] = {IN_DEC, AM_R, RT_D}, [0x16] = {IN_LD, AM_R_D8, RT_D}, + [0x17] = {IN_RLA}, [0x18] = {IN_JR, AM_D8}, + [0x19] = {IN_ADD, AM_R_R, RT_HL, RT_DE}, [0x1A] = {IN_LD, AM_R_MR, RT_A, RT_DE}, + [0x1B] = {IN_DEC, AM_R, RT_DE}, + [0x1C] = {IN_INC, AM_R, RT_E}, + [0x1D] = {IN_DEC, AM_R, RT_E}, [0x1E] = {IN_LD, AM_R_D8, RT_E}, + [0x1F] = {IN_RRA}, //0x2X [0x20] = {IN_JR, AM_D8, RT_NONE, RT_NONE, CT_NZ}, [0x21] = {IN_LD, AM_R_D16, RT_HL}, [0x22] = {IN_LD, AM_HLI_R, RT_HL, RT_A}, + [0x23] = {IN_INC, AM_R, RT_HL}, + [0x24] = {IN_INC, AM_R, RT_H}, [0x25] = {IN_DEC, AM_R, RT_H}, [0x26] = {IN_LD, AM_R_D8, RT_H}, + [0x27] = {IN_DAA}, [0x28] = {IN_JR, AM_D8, RT_NONE, RT_NONE, CT_Z}, + [0x29] = {IN_ADD, AM_R_R, RT_HL, RT_HL}, [0x2A] = {IN_LD, AM_R_HLI, RT_A, RT_HL}, + [0x2B] = {IN_DEC, AM_R, RT_HL}, + [0x2C] = {IN_INC, AM_R, RT_L}, + [0x2D] = {IN_DEC, AM_R, RT_L}, [0x2E] = {IN_LD, AM_R_D8, RT_L}, + [0x2F] = {IN_CPL}, //0x3X [0x30] = {IN_JR, AM_D8, RT_NONE, RT_NONE, CT_NC}, [0x31] = {IN_LD, AM_R_D16, RT_SP}, [0x32] = {IN_LD, AM_HLD_R, RT_HL, RT_A}, + [0x33] = {IN_INC, AM_R, RT_SP}, + [0x34] = {IN_INC, AM_MR, RT_HL}, [0x35] = {IN_DEC, AM_MR, RT_HL}, [0x36] = {IN_LD, AM_MR_D8, RT_HL}, + [0x37] = {IN_SCF}, [0x38] = {IN_JR, AM_D8, RT_NONE, RT_NONE, CT_C}, + [0x39] = {IN_ADD, AM_R_R, RT_HL, RT_SP}, [0x3A] = {IN_LD, AM_R_HLD, RT_A, RT_HL}, + [0x3B] = {IN_DEC, AM_R, RT_SP}, + [0x3C] = {IN_INC, AM_R, RT_A}, + [0x3D] = {IN_DEC, AM_R, RT_A}, [0x3E] = {IN_LD, AM_R_D8, RT_A}, + [0x3F] = {IN_CCF}, //0x4X [0x40] = {IN_LD, AM_R_R, RT_B, RT_B}, [0x41] = {IN_LD, AM_R_R, RT_B, RT_C}, @@ -106,10 +139,73 @@ instruction instructions[0x100] = { [0x7E] = {IN_LD, AM_R_MR, RT_A, RT_HL}, [0x7F] = {IN_LD, AM_R_R, RT_A, RT_A}, //0x8X + [0x80] = {IN_ADD, AM_R_R, RT_A, RT_B}, + [0x81] = {IN_ADD, AM_R_R, RT_A, RT_C}, + [0x82] = {IN_ADD, AM_R_R, RT_A, RT_D}, + [0x83] = {IN_ADD, AM_R_R, RT_A, RT_E}, + [0x84] = {IN_ADD, AM_R_R, RT_A, RT_H}, + [0x85] = {IN_ADD, AM_R_R, RT_A, RT_L}, + [0x86] = {IN_ADD, AM_R_MR, RT_A, RT_HL}, + [0x87] = {IN_ADD, AM_R_R, RT_A, RT_A}, + [0x88] = {IN_ADC, AM_R_R, RT_A, RT_B}, + [0x89] = {IN_ADC, AM_R_R, RT_A, RT_C}, + [0x8A] = {IN_ADC, AM_R_R, RT_A, RT_D}, + [0x8B] = {IN_ADC, AM_R_R, RT_A, RT_E}, + [0x8C] = {IN_ADC, AM_R_R, RT_A, RT_H}, + [0x8D] = {IN_ADC, AM_R_R, RT_A, RT_L}, + [0x8E] = {IN_ADC, AM_R_MR, RT_A, RT_HL}, + [0x8F] = {IN_ADC, AM_R_R, RT_A, RT_A}, //0x9X + [0x90] = {IN_SUB, AM_R_R, RT_A, RT_B}, + [0x91] = {IN_SUB, AM_R_R, RT_A, RT_C}, + [0x92] = {IN_SUB, AM_R_R, RT_A, RT_D}, + [0x93] = {IN_SUB, AM_R_R, RT_A, RT_E}, + [0x94] = {IN_SUB, AM_R_R, RT_A, RT_H}, + [0x95] = {IN_SUB, AM_R_R, RT_A, RT_L}, + [0x96] = {IN_SUB, AM_R_MR, RT_A, RT_HL}, + [0x97] = {IN_SUB, AM_R_R, RT_A, RT_A}, + [0x98] = {IN_SBC, AM_R_R, RT_A, RT_B}, + [0x99] = {IN_SBC, AM_R_R, RT_A, RT_C}, + [0x9A] = {IN_SBC, AM_R_R, RT_A, RT_D}, + [0x9B] = {IN_SBC, AM_R_R, RT_A, RT_E}, + [0x9C] = {IN_SBC, AM_R_R, RT_A, RT_H}, + [0x9D] = {IN_SBC, AM_R_R, RT_A, RT_L}, + [0x9E] = {IN_SBC, AM_R_MR, RT_A, RT_HL}, + [0x9F] = {IN_SBC, AM_R_R, RT_A, RT_A}, //0xAX - [0xAF] = {IN_XOR, AM_R, RT_A}, + [0xA0] = {IN_AND, AM_R_R, RT_A, RT_B}, + [0xA1] = {IN_AND, AM_R_R, RT_A, RT_C}, + [0xA2] = {IN_AND, AM_R_R, RT_A, RT_D}, + [0xA3] = {IN_AND, AM_R_R, RT_A, RT_E}, + [0xA4] = {IN_AND, AM_R_R, RT_A, RT_H}, + [0xA5] = {IN_AND, AM_R_R, RT_A, RT_L}, + [0xA6] = {IN_AND, AM_R_MR, RT_A, RT_HL}, + [0xA7] = {IN_AND, AM_R_R, RT_A, RT_A}, + [0xA8] = {IN_XOR, AM_R_R, RT_A, RT_B}, + [0xA9] = {IN_XOR, AM_R_R, RT_A, RT_C}, + [0xAA] = {IN_XOR, AM_R_R, RT_A, RT_D}, + [0xAB] = {IN_XOR, AM_R_R, RT_A, RT_E}, + [0xAC] = {IN_XOR, AM_R_R, RT_A, RT_H}, + [0xAD] = {IN_XOR, AM_R_R, RT_A, RT_L}, + [0xAE] = {IN_XOR, AM_R_MR, RT_A, RT_HL}, + [0xAF] = {IN_XOR, AM_R_R, RT_A, RT_A}, //0xBX + [0xB0] = {IN_OR, AM_R_R, RT_A, RT_B}, + [0xB1] = {IN_OR, AM_R_R, RT_A, RT_C}, + [0xB2] = {IN_OR, AM_R_R, RT_A, RT_D}, + [0xB3] = {IN_OR, AM_R_R, RT_A, RT_E}, + [0xB4] = {IN_OR, AM_R_R, RT_A, RT_H}, + [0xB5] = {IN_OR, AM_R_R, RT_A, RT_L}, + [0xB6] = {IN_OR, AM_R_MR, RT_A, RT_HL}, + [0xB7] = {IN_OR, AM_R_R, RT_A, RT_A}, + [0xB8] = {IN_CP, AM_R_R, RT_A, RT_B}, + [0xB9] = {IN_CP, AM_R_R, RT_A, RT_C}, + [0xBA] = {IN_CP, AM_R_R, RT_A, RT_D}, + [0xBB] = {IN_CP, AM_R_R, RT_A, RT_E}, + [0xBC] = {IN_CP, AM_R_R, RT_A, RT_H}, + [0xBD] = {IN_CP, AM_R_R, RT_A, RT_L}, + [0xBE] = {IN_CP, AM_R_MR, RT_A, RT_HL}, + [0xBF] = {IN_CP, AM_R_R, RT_A, RT_A}, //0xCX [0xC0] = {IN_RET, AM_IMP, RT_NONE, RT_NONE, CT_NZ}, [0xC1] = {IN_POP, AM_IMP, RT_BC}, @@ -117,12 +213,15 @@ instruction instructions[0x100] = { [0xC3] = {IN_JP, AM_D16}, [0xC4] = {IN_CALL, AM_D16, RT_NONE, RT_NONE, CT_NZ}, [0xC5] = {IN_PUSH, AM_IMP, RT_BC}, + [0xC6] = {IN_ADD, AM_R_D8, RT_A}, [0xC7] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x00}, [0xC8] = {IN_RET, AM_IMP, RT_NONE, RT_NONE, CT_Z}, [0xC9] = {IN_RET}, [0xCA] = {IN_JP, AM_D16, RT_NONE, RT_NONE, CT_Z}, + [0xCB] = {IN_CB, AM_D8}, [0xCC] = {IN_CALL, AM_D16, RT_NONE, RT_NONE, CT_Z}, [0xCD] = {IN_CALL, AM_D16}, + [0xCE] = {IN_ADC, AM_R_D8, RT_A}, [0xCF] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x08}, //0xDX [0xD0] = {IN_RET, AM_IMP, RT_NONE, RT_NONE, CT_NC}, @@ -130,20 +229,25 @@ instruction instructions[0x100] = { [0xD2] = {IN_JP, AM_D16, RT_NONE, RT_NONE, CT_NC}, [0xD4] = {IN_CALL, AM_D16, RT_NONE, RT_NONE, CT_NC}, [0xD5] = {IN_PUSH, AM_IMP, RT_DE}, + [0xD6] = {IN_SUB, AM_R_D8, RT_A}, [0xD7] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x10}, [0xD8] = {IN_RET, AM_IMP, RT_NONE, RT_NONE, CT_C}, [0xD9] = {IN_RETI}, [0xDA] = {IN_JP, AM_D16, RT_NONE, RT_NONE, CT_C}, [0xDC] = {IN_CALL, AM_D16, RT_NONE, RT_NONE, CT_C}, + [0xDE] = {IN_SBC, AM_R_D8, RT_A}, [0xDF] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x18}, //0xEX [0xE0] = {IN_LDH, AM_A8_R, RT_NONE, RT_A}, [0xE1] = {IN_POP, AM_IMP, RT_HL}, [0xE2] = {IN_LD, AM_MR_R, RT_C, RT_A}, [0xE5] = {IN_PUSH, AM_IMP, RT_HL}, + [0xE6] = {IN_AND, AM_D8}, [0xE7] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x20}, + [0xE8] = {IN_ADD, AM_R_D8, RT_SP}, [0xE9] = {IN_JP, AM_MR, RT_HL}, [0xEA] = {IN_LD, AM_A16_R, RT_NONE, RT_A}, + [0xEE] = {IN_XOR, AM_D8}, [0xEF] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x28}, //0xFX [0xF0] = {IN_LDH, AM_R_A8, RT_A}, @@ -151,8 +255,13 @@ instruction instructions[0x100] = { [0xF2] = {IN_LD, AM_R_MR, RT_A, RT_C}, [0xF3] = {IN_DI}, [0xF5] = {IN_PUSH, AM_IMP, RT_AF}, + [0xF6] = {IN_OR, AM_D8}, [0xF7] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x30}, + [0xF8] = {IN_LD, AM_HL_SPR, RT_HL, RT_SP}, + [0xF9] = {IN_LD, AM_R_R, RT_HL, RT_SP}, [0xFA] = {IN_LD, AM_R_A16, RT_A}, + [0xFB] = {IN_EI}, + [0xFE] = {IN_CP, AM_D8}, [0xFF] = {IN_RST, AM_IMP, RT_NONE, RT_NONE, CT_NONE, 0x38} }; diff --git a/lib/stack.c b/lib/stack.c index c602823..68536d8 100644 --- a/lib/stack.c +++ b/lib/stack.c @@ -19,5 +19,5 @@ u8 stack_pop(){ u16 stack_pop16(){ u16 lo = stack_pop(); u16 hi = stack_pop(); - return (hi << 8) || lo; + return (hi << 8) | lo; }