diff options
-rw-r--r-- | gb.h | 2 | ||||
-rw-r--r-- | ops.yaml | 66 | ||||
-rw-r--r-- | test.c | 24 |
3 files changed, 64 insertions, 28 deletions
@@ -40,6 +40,8 @@ typedef struct { void (*on_gpu_step)(const gb_t *); void (*on_gpu_set_mode)(const gb_t *, const uint8_t); void (*on_rst)(const gb_t *, const uint16_t); + void (*on_mmu_rb)(const gb_t *, const uint16_t, const uint8_t); + void (*on_mmu_wb)(const gb_t *, const uint16_t, const uint8_t); void *cb_data; } gb_config_t; @@ -965,7 +965,7 @@ ops: h: c: code: | - cpu_ww(ctx, RW_HL, cpu_rw(ctx, RW_HL) - 1); + cpu_ww(ctx, RW_SP, cpu_rw(ctx, RW_SP) - 1); - id: INC A hex: 0x3C cat: "8-bit math" @@ -8557,6 +8557,11 @@ templates: #define PORT_WY 0xFF4A #define PORT_WX 0xFF4B + // forward references for mmu_rp()/mmu_wp() + static void gpu_set_line(gb_t * const ctx, const uint8_t line); + static void gpu_set_mode(gb_t * const ctx, const uint8_t mode); + static bool gpu_is_active(const gb_t * const ctx); + static uint8_t mmu_rp( const gb_t * const ctx, @@ -8606,7 +8611,8 @@ templates: case PORT_STAT: return (ctx->gpu.stat & 0xF8) | ((ctx->gpu.line == ctx->gpu.lyc) ? (1 << 3) : 0) | - (ctx->gpu.mode & 0x3); + // always return mode 1 if lcd is disabled + (gpu_is_active(ctx) ? (ctx->gpu.mode & 0x3) : 1); break; case PORT_SCY: @@ -8618,7 +8624,8 @@ templates: break; case PORT_LY: - return ctx->gpu.line; + // FIXME: is this correct? + return gpu_is_active(ctx) ? ctx->gpu.line : 144; break; case PORT_LYC: @@ -8656,9 +8663,6 @@ templates: } } - // forward reference for mmu_wp() - static void gpu_set_line(gb_t * const ctx, const uint8_t line); - static void mmu_wp( gb_t * const ctx, @@ -8712,6 +8716,13 @@ templates: case PORT_LCDC: ctx->gpu.lcdc = val; + if (gpu_is_active(ctx)) { + // reset line, mode, and clock + gpu_set_line(ctx, 0); + gpu_set_mode(ctx, GPU_MODE_OAM); + ctx->gpu.clock = 0; + } + break; case PORT_STAT: ctx->gpu.stat = (val & 0xF8); @@ -8883,29 +8894,13 @@ templates: gb_t * const ctx, const uint16_t addr ) { - switch (addr & 0xF000) { - case 0x0000: - case 0x1000: - case 0x2000: - case 0x3000: - case 0x4000: - case 0x5000: - case 0x6000: - case 0x7000: - return rom_rb(ctx, addr); - case 0x8000: - case 0x9000: - case 0xA000: - case 0xB000: - case 0xC000: - case 0xD000: - case 0xE000: - case 0xF000: - return ram_rb(ctx, addr); - default: - // never reached - return 0; + const uint8_t val = (addr & 0x8000) ? ram_rb(ctx, addr) : rom_rb(ctx, addr); + + if (ctx->config && ctx->config->on_mmu_rb) { + ctx->config->on_mmu_rb(ctx, addr, val); } + + return val; } static void @@ -9049,6 +9044,10 @@ templates: const uint16_t addr, const uint8_t val ) { + if (ctx->config && ctx->config->on_mmu_wb) { + ctx->config->on_mmu_wb(ctx, addr, val); + } + switch (addr & 0xF000) { case 0x0000: case 0x1000: @@ -10092,6 +10091,13 @@ templates: // TODO: implement DAA } + static bool + gpu_is_active( + const gb_t * const ctx + ) { + return ctx->gpu.lcdc & (1 << 7); + } + static void gpu_set_line( gb_t * const ctx, @@ -10250,6 +10256,10 @@ templates: gb_t * const ctx, const uint16_t clock ) { + if (!gpu_is_active(ctx)) { + return; + } + // increment clock ctx->gpu.clock += clock; @@ -135,6 +135,28 @@ on_rst( printf("rst: addr = %04x\n", addr); } +/* + * static void + * on_mmu_rb( + * const gb_t * const ctx, + * const uint16_t addr, + * const uint8_t val + * ) { + * UNUSED(ctx); + * printf("mmu_rb: addr = 0x%04X, val = 0x%02X\n", addr, val); + * } + */ + +static void +on_mmu_wb( + const gb_t * const ctx, + const uint16_t addr, + const uint8_t val +) { + UNUSED(ctx); + printf("mmu_wb: addr = 0x%04X, val = 0x%02X\n", addr, val); +} + static const gb_config_t EXECUTE_CONFIG = { .on_set_rom_bank = on_set_rom_bank, @@ -146,6 +168,8 @@ EXECUTE_CONFIG = { .on_gpu_set_mode = on_gpu_set_mode, .on_set_cpu_state = on_set_cpu_state, .on_rst = on_rst, + // .on_mmu_rb = on_mmu_rb, + .on_mmu_wb = on_mmu_wb, }; static void |