From 022c24dd35a42532d53d7899200e36c01aa29160 Mon Sep 17 00:00:00 2001 From: Samuel Walker Date: Thu, 30 Jan 2025 21:59:05 -0700 Subject: [PATCH] LD, LDH, WRAM, and HRAM --- include/bus.h | 5 +- include/cpu.h | 10 +++- include/ram.h | 9 +++ lib/bus.c | 86 +++++++++++++++++++++++++++- lib/cart.c | 5 +- lib/cpu.c | 47 ++++------------ lib/cpu_fetch.c | 137 +++++++++++++++++++++++++++++++++++++++++++++ lib/cpu_proc.c | 51 +++++++++++++---- lib/cpu_util.c | 22 ++++++++ lib/instructions.c | 114 +++++++++++++++++++++++++++++++++++-- lib/ram.c | 30 ++++++++++ 11 files changed, 458 insertions(+), 58 deletions(-) create mode 100644 include/ram.h create mode 100644 lib/cpu_fetch.c create mode 100644 lib/ram.c diff --git a/include/bus.h b/include/bus.h index 4a5bfc6..be1211b 100644 --- a/include/bus.h +++ b/include/bus.h @@ -3,4 +3,7 @@ #include u8 bus_read(u16 address); -void bus_write(u16 address, u8 value); \ No newline at end of file +void bus_write(u16 address, u8 value); + +u16 bus_read16(u16 address); +void bus_write16(u16 address, u16 value); \ No newline at end of file diff --git a/include/cpu.h b/include/cpu.h index 512342b..1c2d43b 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -30,6 +30,7 @@ typedef struct { bool stepping; bool int_master_enabled; + u8 ie_register; } cpu_context; void cpu_init(); @@ -42,4 +43,11 @@ IN_PROC inst_get_processor(in_type type); #define CPU_FLAG_Z BIT(ctx->regs.f, 7) #define CPU_FLAG_C BIT(ctx->regs.f, 4) -u16 cpu_read_reg(reg_type rt); \ No newline at end of file +u16 cpu_read_reg(reg_type rt); + +void cpu_set_reg(reg_type rt, u16 val); + +void fetch_data(); + +u8 cpu_get_ie_register(); +void cpu_set_ie_register(u8 ie); \ No newline at end of file diff --git a/include/ram.h b/include/ram.h new file mode 100644 index 0000000..87ef08f --- /dev/null +++ b/include/ram.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +u8 wram_read(u16 address); +void wram_write(u16 address, u8 value); + +u8 hram_read(u16 address); +void hram_write(u16 address, u8 value); \ No newline at end of file diff --git a/lib/bus.c b/lib/bus.c index a116bed..f7cd79b 100644 --- a/lib/bus.c +++ b/lib/bus.c @@ -1,4 +1,8 @@ #include +#include +#include +#include +#include // 0x0000 - 0x3FFF : ROM Bank 0 // 0x4000 - 0x7FFF : ROM Bank 1 - Switchable @@ -17,16 +21,92 @@ u8 bus_read(u16 address) { if(address < 0x8000) { return cart_read(address); + } else if (address < 0xA000) { + //Char/Map Data + //TODO + printf("UNSUPPORTED bus_read(%04X)\n", address); + NO_IMPL + } else if (address < 0xC000) { + //Cartridge RAM + return cart_read(address); + } else if (address < 0xE000) { + //WRAM (Working RAM) + return wram_read(address); + } else if (address < 0xFE00) { + //reserved echo ram... + return 0; + } else if (address < 0xFEA0) { + //OAM + //TODO + printf("UNSUPPORTED bus_read(%04X)\n", address); + NO_IMPL + } else if (address < 0xFF00) { + //reserved unusable + return 0; + } else if (address < 0xFF80) { + //IO registers + //TODO + printf("UNSUPPORTED bus_read(%04X)\n", address); + //NO_IMPL + } else if (address == 0xFFFF) { + //CPU ENABLE REGISTER + //TODO + return cpu_get_ie_register(); } - NO_IMPL + return hram_read(address); } void bus_write(u16 address, u8 value) { if(address < 0x8000) { - cart_write(address); + cart_write(address, value); + return; + } else if (address < 0xA000) { + //Char/Map Data + //TODO + printf("UNSUPPORTED bus_write(%04X)\n", address); + NO_IMPL + } else if (address < 0xC000) { + //Cartridge RAM + cart_write(address, value); + return; + } else if (address < 0xE000) { + //WRAM (Working RAM) + wram_write(address, value); + return; + } else if (address < 0xFE00) { + //reserved echo ram... + return; + } else if (address < 0xFEA0) { + //OAM + //TODO + printf("UNSUPPORTED bus_write(%04X)\n", address); + NO_IMPL + } else if (address < 0xFF00) { + //reserved unusable + return; + } else if (address < 0xFF80) { + //IO registers + //TODO + printf("UNSUPPORTED bus_write(%04X)\n", address); + //NO_IMPL + return; + } else if (address == 0xFFFF) { + //CPU ENABLE REGISTER + cpu_set_ie_register(value); return; } - NO_IMPL + hram_write(address, value); +} + +u16 bus_read16(u16 address) { + u16 lo = bus_read(address); + u16 hi = bus_read(address+1); + return lo | (hi << 8); +} + +void bus_write16(u16 address, u16 value) { + bus_write(address+1, (value >> 8) & 0xFF); + bus_write(address, value * 0xFF); } \ No newline at end of file diff --git a/lib/cart.c b/lib/cart.c index 5cc5fdc..11f95d1 100644 --- a/lib/cart.c +++ b/lib/cart.c @@ -1,4 +1,5 @@ #include +#include typedef struct { char filename[1024]; @@ -182,6 +183,6 @@ u8 cart_read(u16 address){ } void cart_write(u16 address, u8 value){ - - NO_IMPL + printf("UNSUPPORTED cart_write(%04X)\n"); + //NO_IMPL } \ No newline at end of file diff --git a/lib/cpu.c b/lib/cpu.c index e23577c..d3326f8 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -1,11 +1,11 @@ #include #include +#include cpu_context ctx = {0}; void cpu_init() { ctx.regs.pc = 0x100; - ctx.regs.a = 0x01; } static void fetch_instruction() { @@ -13,42 +13,11 @@ static void fetch_instruction() { ctx.cur_inst = instruction_by_opcode(ctx.cur_opcode); } -static void fetch_data() { - ctx.mem_dest = 0; - ctx.dest_is_mem = false; - - if(ctx.cur_inst == NULL) return; - - switch(ctx.cur_inst->mode) { - case AM_IMP: return; - case AM_R: - ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_1); - return; - case AM_R_D8: - ctx.fetched_data = bus_read(ctx.regs.pc); - emu_cycles(1); - ctx.regs.pc++; - return; - case AM_D16: { - u16 lo = bus_read(ctx.regs.pc); - emu_cycles(1); - u16 hi = bus_read(ctx.regs.pc+1); - emu_cycles(1); - ctx.fetched_data = lo | (hi << 8); - ctx.regs.pc += 2; - return; - } - default: - printf("Unknown Addressing Mode! %d (%02X)\n", ctx.cur_inst->mode, ctx.cur_opcode); - exit(-7); - return; - } -} - static void execute() { IN_PROC proc = inst_get_processor(ctx.cur_inst->type); if (!proc) { + printf("no implementation(%02X)\n", ctx.cur_opcode); NO_IMPL } @@ -60,14 +29,22 @@ bool cpu_step() { if(!ctx.halted) { u16 pc = ctx.regs.pc; fetch_instruction(); - fetch_data(); - printf("%04X: %-7s (%02X %02X %02X) A: %02X B: %02X C: %02X\n", pc, inst_name(ctx.cur_inst->type), ctx.cur_opcode, bus_read(pc+1), bus_read(pc+2), ctx.regs.a, ctx.regs.b, ctx.regs.c); + 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); if(ctx.cur_inst == NULL){ printf("Unknown Instruction! %02X\n", ctx.cur_opcode); exit(-7); } + fetch_data(); execute(); } return true; +} + +u8 cpu_get_ie_register(){ + return ctx.ie_register; +} + +void cpu_set_ie_register(u8 ie){ + ctx.ie_register = ie; } \ No newline at end of file diff --git a/lib/cpu_fetch.c b/lib/cpu_fetch.c new file mode 100644 index 0000000..291dcf1 --- /dev/null +++ b/lib/cpu_fetch.c @@ -0,0 +1,137 @@ +#include +#include +#include + +extern cpu_context ctx; + +void fetch_data() { + ctx.mem_dest = 0; + ctx.dest_is_mem = false; + + if(ctx.cur_inst == NULL) return; + + switch(ctx.cur_inst->mode) { + case AM_IMP: return; + case AM_R: + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_1); + return; + case AM_R_R: + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_2); + case AM_R_D8: + ctx.fetched_data = bus_read(ctx.regs.pc); + emu_cycles(1); + ctx.regs.pc++; + return; + case AM_R_D16: + case AM_D16: { + u16 lo = bus_read(ctx.regs.pc); + emu_cycles(1); + u16 hi = bus_read(ctx.regs.pc+1); + emu_cycles(1); + ctx.fetched_data = lo | (hi << 8); + ctx.regs.pc += 2; + return; + } + case AM_MR_R: + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_2); + ctx.mem_dest = cpu_read_reg(ctx.cur_inst->reg_1); + ctx.dest_is_mem = true; + + if (ctx.cur_inst->reg_1 == RT_C) { + ctx.mem_dest |= 0xFF00; + } + return; + case AM_R_MR: { + u16 addr = cpu_read_reg(ctx.cur_inst->reg_2); + if(ctx.cur_inst->reg_1 == RT_C) { + addr |= 0xFF00; + } + ctx.fetched_data = bus_read(addr); + emu_cycles(1); + return; + } + case AM_R_HLI: + ctx.fetched_data = bus_read(cpu_read_reg(ctx.cur_inst->reg_2)); + emu_cycles(1); + cpu_set_reg(RT_HL, cpu_read_reg(RT_HL)+1); + return; + case AM_R_HLD: + ctx.fetched_data = bus_read(cpu_read_reg(ctx.cur_inst->reg_2)); + emu_cycles(1); + cpu_set_reg(RT_HL, cpu_read_reg(RT_HL)-1); + return; + case AM_HLI_R: + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_2); + ctx.mem_dest = bus_read(cpu_read_reg(ctx.cur_inst->reg_1)); + ctx.dest_is_mem = true; + cpu_set_reg(RT_HL, cpu_read_reg(RT_HL)+1); + return; + case AM_HLD_R: + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_2); + ctx.mem_dest = cpu_read_reg(ctx.cur_inst->reg_1); + ctx.dest_is_mem = true; + cpu_set_reg(RT_HL, cpu_read_reg(RT_HL)-1); + return; + case AM_R_A8: + ctx.fetched_data = bus_read(bus_read(ctx.regs.pc)); + emu_cycles(2); + ctx.regs.pc++; + return; + case AM_A8_R: + ctx.mem_dest = bus_read(ctx.regs.pc) | 0xFF00; + emu_cycles(1); + ctx.dest_is_mem = true; + ctx.regs.pc++; + return; + case AM_HL_SPR: + ctx.fetched_data = bus_read(ctx.regs.pc); + emu_cycles(1); + ctx.regs.pc++; + return; + case AM_D8: + ctx.fetched_data = bus_read(ctx.regs.pc); + emu_cycles(1); + ctx.regs.pc++; + return; + case AM_A16_R: + case AM_D16_R: { + u16 lo = bus_read(ctx.regs.pc); + emu_cycles(1); + u16 hi = bus_read(ctx.regs.pc+1); + emu_cycles(1); + ctx.mem_dest = lo | (hi << 8); + ctx.dest_is_mem = true; + ctx.regs.pc += 2; + ctx.fetched_data = cpu_read_reg(ctx.cur_inst->reg_2); + } return; + + case AM_MR_D8: + ctx.fetched_data = bus_read(ctx.regs.pc); + emu_cycles(1); + ctx.regs.pc++; + ctx.mem_dest = cpu_read_reg(ctx.cur_inst->reg_1); + ctx.dest_is_mem = true; + return; + + case AM_MR: + ctx.mem_dest = cpu_read_reg(ctx.cur_inst->reg_1); + ctx.dest_is_mem = true; + ctx.fetched_data = bus_read(cpu_read_reg(ctx.cur_inst->reg_1)); + emu_cycles(1); + return; + + case AM_R_A16: { + u16 lo = bus_read(ctx.regs.pc); + emu_cycles(1); + u16 hi = bus_read(ctx.regs.pc+1); + emu_cycles(1); + ctx.fetched_data = bus_read(lo | (hi << 8)); + emu_cycles(1); + ctx.regs.pc += 2; + } return; + default: + printf("Unknown Addressing Mode! %d (%02X)\n", ctx.cur_inst->mode, ctx.cur_opcode); + exit(-7); + return; + } +} \ No newline at end of file diff --git a/lib/cpu_proc.c b/lib/cpu_proc.c index ff7c3fe..c8bdc07 100644 --- a/lib/cpu_proc.c +++ b/lib/cpu_proc.c @@ -1,17 +1,9 @@ #include #include +#include //process CPU instructions... -static void proc_none(cpu_context *ctx) { - printf("INVALID INSTRUCTION!\n"); - exit(-7); -} - -static void proc_nop(cpu_context *ctx) { - -} - void cpu_set_flags(cpu_context *ctx, u8 z, u8 n, u8 h, u8 c){ if (z != -1){ BIT_SET(ctx->regs.f, 7, z) @@ -27,6 +19,24 @@ void cpu_set_flags(cpu_context *ctx, u8 z, u8 n, u8 h, u8 c){ } } +static void proc_none(cpu_context *ctx) { + printf("INVALID INSTRUCTION!\n"); + exit(-7); +} + +static void proc_nop(cpu_context *ctx) { + +} + +static void proc_ldh(cpu_context *ctx) { + if (!ctx->dest_is_mem) { + cpu_set_reg(ctx->cur_inst->reg_1, bus_read(0XFF00 | ctx->fetched_data)); + } else { + bus_write(0xFF00 | ctx->mem_dest, ctx->cur_inst->reg_2); + } + 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); @@ -37,7 +47,25 @@ static void proc_di(cpu_context *ctx) { } static void proc_ld(cpu_context *ctx) { - //TODO + if(ctx->dest_is_mem) { + if(ctx->cur_inst->reg_2 >= RT_AF) { + bus_write16(ctx->mem_dest, ctx->fetched_data); + emu_cycles(1); + } else { + bus_write(ctx->mem_dest, ctx->fetched_data); + emu_cycles(1); + } + return; + } + + if (ctx->cur_inst->mode == AM_HL_SPR) { + u8 hflag = (cpu_read_reg(ctx->cur_inst->reg_2) & 0xF) + (ctx->fetched_data & 0xF) >= 0x10; + u8 cflag = (cpu_read_reg(ctx->cur_inst->reg_2) & 0xFF) + (ctx->fetched_data & 0xFF) >= 0x100; + cpu_set_flags(ctx, 0, 0, hflag, cflag); + cpu_set_reg(ctx->cur_inst->reg_1, cpu_read_reg(ctx->cur_inst->reg_2) + (char)ctx->fetched_data); + } + + cpu_set_reg(ctx->cur_inst->reg_1, ctx->fetched_data); } static bool check_condition(cpu_context *ctx) { @@ -68,7 +96,8 @@ IN_PROC processors[] = { [IN_LD] = proc_ld, [IN_JP] = proc_jp, [IN_DI] = proc_di, - [IN_XOR] = proc_xor + [IN_XOR] = proc_xor, + [IN_LDH] = proc_ldh }; IN_PROC inst_get_processor(in_type type) { diff --git a/lib/cpu_util.c b/lib/cpu_util.c index 8cce035..81ffeb6 100644 --- a/lib/cpu_util.c +++ b/lib/cpu_util.c @@ -26,4 +26,26 @@ u16 cpu_read_reg(reg_type rt) { case RT_SP: return ctx.regs.sp; default: return 0; } +} + +void cpu_set_reg(reg_type rt, u16 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_AF: *((u16 *)&ctx.regs.a) = reverse(val); break; + case RT_BC: *((u16 *)&ctx.regs.b) = reverse(val); break; + case RT_DE: *((u16 *)&ctx.regs.d) = reverse(val); break; + case RT_HL: *((u16 *)&ctx.regs.h) = reverse(val); break; + + case RT_PC: ctx.regs.pc = val; break; + case RT_SP: ctx.regs.sp = val; break; + case RT_NONE: break; + } } \ No newline at end of file diff --git a/lib/instructions.c b/lib/instructions.c index a4432bd..ba13aca 100644 --- a/lib/instructions.c +++ b/lib/instructions.c @@ -2,17 +2,121 @@ #include instruction instructions[0x100] = { + //0x0X [0x00] = {IN_NOP, AM_IMP}, - + [0x01] = {IN_LD, AM_R_D16, RT_BC}, + [0x02] = {IN_LD, AM_MR_R, RT_BC, RT_A}, [0x05] = {IN_DEC, AM_R, RT_B}, - + [0x06] = {IN_LD, AM_R_D8, RT_B}, + [0x08] = {IN_LD, AM_A16_R, RT_NONE, RT_SP}, + [0x0A] = {IN_LD, AM_R_MR, RT_A, RT_BC}, [0x0E] = {IN_LD, AM_R_D8, RT_C}, - + //0x1X + [0x11] = {IN_LD, AM_R_D16, RT_DE}, + [0x12] = {IN_LD, AM_MR_R, RT_DE, RT_A}, + [0x15] = {IN_DEC, AM_R, RT_D}, + [0x16] = {IN_LD, AM_R_D8, RT_D}, + [0x1A] = {IN_LD, AM_R_MR, RT_A, RT_DE}, + [0x1E] = {IN_LD, AM_R_D8, RT_E}, + //0x2X + [0x21] = {IN_LD, AM_R_D16, RT_HL}, + [0x22] = {IN_LD, AM_HLI_R, RT_HL, RT_A}, + [0x25] = {IN_DEC, AM_R, RT_H}, + [0x26] = {IN_LD, AM_R_D8, RT_H}, + [0x2A] = {IN_LD, AM_R_HLI, RT_A, RT_HL}, + [0x2E] = {IN_LD, AM_R_D8, RT_L}, + //0x3X + [0x31] = {IN_LD, AM_R_D16, RT_SP}, + [0x32] = {IN_LD, AM_HLD_R, RT_HL, RT_A}, + [0x35] = {IN_DEC, AM_MR, RT_HL}, + [0x36] = {IN_LD, AM_MR_D8, RT_HL}, + [0x3A] = {IN_LD, AM_R_HLD, RT_A, RT_HL}, + [0x3E] = {IN_LD, AM_R_D8, RT_A}, + //0x4X + [0x40] = {IN_LD, AM_R_R, RT_B, RT_B}, + [0x41] = {IN_LD, AM_R_R, RT_B, RT_C}, + [0x42] = {IN_LD, AM_R_R, RT_B, RT_D}, + [0x43] = {IN_LD, AM_R_R, RT_B, RT_E}, + [0x44] = {IN_LD, AM_R_R, RT_B, RT_H}, + [0x45] = {IN_LD, AM_R_R, RT_B, RT_L}, + [0x46] = {IN_LD, AM_R_MR, RT_B, RT_HL}, + [0x47] = {IN_LD, AM_R_R, RT_B, RT_A}, + [0x48] = {IN_LD, AM_R_R, RT_C, RT_B}, + [0x49] = {IN_LD, AM_R_R, RT_C, RT_C}, + [0x4A] = {IN_LD, AM_R_R, RT_C, RT_D}, + [0x4B] = {IN_LD, AM_R_R, RT_C, RT_E}, + [0x4C] = {IN_LD, AM_R_R, RT_C, RT_H}, + [0x4D] = {IN_LD, AM_R_R, RT_C, RT_L}, + [0x4E] = {IN_LD, AM_R_MR, RT_C, RT_HL}, + [0x4F] = {IN_LD, AM_R_R, RT_C, RT_A}, + //0x5X + [0x50] = {IN_LD, AM_R_R, RT_D, RT_B}, + [0x51] = {IN_LD, AM_R_R, RT_D, RT_C}, + [0x52] = {IN_LD, AM_R_R, RT_D, RT_D}, + [0x53] = {IN_LD, AM_R_R, RT_D, RT_E}, + [0x54] = {IN_LD, AM_R_R, RT_D, RT_H}, + [0x55] = {IN_LD, AM_R_R, RT_D, RT_L}, + [0x56] = {IN_LD, AM_R_MR, RT_D, RT_HL}, + [0x57] = {IN_LD, AM_R_R, RT_D, RT_A}, + [0x58] = {IN_LD, AM_R_R, RT_E, RT_B}, + [0x59] = {IN_LD, AM_R_R, RT_E, RT_C}, + [0x5A] = {IN_LD, AM_R_R, RT_E, RT_D}, + [0x5B] = {IN_LD, AM_R_R, RT_E, RT_E}, + [0x5C] = {IN_LD, AM_R_R, RT_E, RT_H}, + [0x5D] = {IN_LD, AM_R_R, RT_E, RT_L}, + [0x5E] = {IN_LD, AM_R_MR, RT_E, RT_HL}, + [0x5F] = {IN_LD, AM_R_R, RT_E, RT_A}, + //0x6X + [0x60] = {IN_LD, AM_R_R, RT_H, RT_B}, + [0x61] = {IN_LD, AM_R_R, RT_H, RT_C}, + [0x62] = {IN_LD, AM_R_R, RT_H, RT_D}, + [0x63] = {IN_LD, AM_R_R, RT_H, RT_E}, + [0x64] = {IN_LD, AM_R_R, RT_H, RT_H}, + [0x65] = {IN_LD, AM_R_R, RT_H, RT_L}, + [0x66] = {IN_LD, AM_R_MR, RT_H, RT_HL}, + [0x67] = {IN_LD, AM_R_R, RT_H, RT_A}, + [0x68] = {IN_LD, AM_R_R, RT_L, RT_B}, + [0x69] = {IN_LD, AM_R_R, RT_L, RT_C}, + [0x6A] = {IN_LD, AM_R_R, RT_L, RT_D}, + [0x6B] = {IN_LD, AM_R_R, RT_L, RT_E}, + [0x6C] = {IN_LD, AM_R_R, RT_L, RT_H}, + [0x6D] = {IN_LD, AM_R_R, RT_L, RT_L}, + [0x6E] = {IN_LD, AM_R_MR, RT_L, RT_HL}, + [0x6F] = {IN_LD, AM_R_R, RT_L, RT_A}, + //0x7X + [0x70] = {IN_LD, AM_MR_R, RT_HL, RT_B}, + [0x71] = {IN_LD, AM_MR_R, RT_HL, RT_C}, + [0x72] = {IN_LD, AM_MR_R, RT_HL, RT_D}, + [0x73] = {IN_LD, AM_MR_R, RT_HL, RT_E}, + [0x74] = {IN_LD, AM_MR_R, RT_HL, RT_H}, + [0x75] = {IN_LD, AM_MR_R, RT_HL, RT_L}, + [0x76] = {IN_HALT}, + [0x77] = {IN_LD, AM_MR_R, RT_HL, RT_A}, + [0x78] = {IN_LD, AM_R_R, RT_A, RT_B}, + [0x79] = {IN_LD, AM_R_R, RT_A, RT_C}, + [0x7A] = {IN_LD, AM_R_R, RT_A, RT_D}, + [0x7B] = {IN_LD, AM_R_R, RT_A, RT_E}, + [0x7C] = {IN_LD, AM_R_R, RT_A, RT_H}, + [0x7D] = {IN_LD, AM_R_R, RT_A, RT_L}, + [0x7E] = {IN_LD, AM_R_MR, RT_A, RT_HL}, + [0x7F] = {IN_LD, AM_R_R, RT_A, RT_A}, + //0x8X + //0x9X + //0xAX [0xAF] = {IN_XOR, AM_R, RT_A}, - + //0xBX + //0xCX [0xC3] = {IN_JP, AM_D16}, - + //0xDX + //0xEX + [0xE0] = {IN_LDH, AM_A8_R, RT_NONE, RT_A}, + [0xE2] = {IN_LD, AM_MR_R, RT_C, RT_A}, + [0xEA] = {IN_LD, AM_A16_R, RT_NONE, RT_A}, + //0xFX + [0xF0] = {IN_LDH, AM_R_A8, RT_A}, + [0xF2] = {IN_LD, AM_R_MR, RT_A, RT_C}, [0xF3] = {IN_DI}, + [0xFA] = {IN_LD, AM_R_A16, RT_A}, }; instruction *instruction_by_opcode(u8 opcode) { diff --git a/lib/ram.c b/lib/ram.c new file mode 100644 index 0000000..2cf815d --- /dev/null +++ b/lib/ram.c @@ -0,0 +1,30 @@ +#include + +typedef struct { + u8 wram[0x2000]; + u8 hram[0x80]; +} ram_context; + +static ram_context ctx; + +u8 wram_read(u16 address) { + address -= 0xC000; + + return ctx.wram[address]; +} + +void wram_write(u16 address, u8 value){ + address -= 0xC000; + ctx.wram[address] = value; +} + +u8 hram_read(u16 address){ + address -= 0xFF80; + + return ctx.hram[address]; +} + +void hram_write(u16 address, u8 value){ + address -= 0xFF80; + ctx.hram[address] = value; +} \ No newline at end of file