summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gb.h2
-rw-r--r--ops.yaml66
-rw-r--r--test.c24
3 files changed, 64 insertions, 28 deletions
diff --git a/gb.h b/gb.h
index ea092a2..15bd75e 100644
--- a/gb.h
+++ b/gb.h
@@ -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;
diff --git a/ops.yaml b/ops.yaml
index 199b61d..e3e7979 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -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;
diff --git a/test.c b/test.c
index 824458d..5900cf7 100644
--- a/test.c
+++ b/test.c
@@ -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