From e9dab48f48d00b3b91e4eea9853e454b05d6941a Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 26 Jun 2018 22:42:37 -0400 Subject: add cpu_irq() and clean up interrupts --- ops.yaml | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/ops.yaml b/ops.yaml index 6bf9870..29fe351 100644 --- a/ops.yaml +++ b/ops.yaml @@ -8095,6 +8095,12 @@ templates: #define F_H (1 << 5) #define F_C (1 << 4) + #define IRQ_VBLANK (1) + #define IRQ_LCDC (1 << 1) + #define IRQ_TIMER (1 << 2) + #define IRQ_SERIAL (1 << 3) + #define IRQ_P1 (1 << 4) + typedef enum { RB_A, RB_F, @@ -9195,6 +9201,15 @@ templates: )); } + static void + cpu_irq( + gb_t * const ctx, + const uint8_t mask + ) { + // trigger interrupt mask + mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) | mask); + } + static void cpu_set_state( gb_t * const ctx, @@ -10112,7 +10127,7 @@ templates: if (ctx->gpu.stat & (1 << 6) && (line == ctx->gpu.lyc)) { // lyc interrupt is enabled, trigger LCDC interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 1)); + cpu_irq(ctx, IRQ_LCDC); } } @@ -10134,11 +10149,11 @@ templates: ctx->config->on_gpu_set_mode(ctx, mode); } - switch (gpu_get_mode(ctx)) { + switch (mode & 0x03) { case GPU_MODE_OAM: if (ctx->gpu.stat & (1 << 5)) { - // lcd status interrupt is enabled, trigger LCDC interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 1)); + // trigger LCDC interrupt + cpu_irq(ctx, IRQ_LCDC); } break; @@ -10147,20 +10162,25 @@ templates: break; case GPU_MODE_HBLANK: if (ctx->gpu.stat & (1 << 3)) { - // lcd status interrupt is enabled, trigger LCDC interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 1)); + // trigger LCDC interrupt + cpu_irq(ctx, IRQ_LCDC); + } - if (ctx->config && ctx->config->on_hblank) { - ctx->config->on_hblank(ctx); - } + if (ctx->config && ctx->config->on_hblank) { + ctx->config->on_hblank(ctx); } break; case GPU_MODE_VBLANK: if (ctx->gpu.stat & (1 << 4)) { - // vblank interrupt is enabled, trigger vblank interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & 1); + // trigger LCDC interrupt + cpu_irq(ctx, IRQ_LCDC); + } + + // trigger vblank interrupt + cpu_irq(ctx, IRQ_VBLANK); + if (ctx->cpu.ime && (mmu_rb(ctx, PORT_IE) & 1)) { if (ctx->config && ctx->config->on_vblank) { ctx->config->on_vblank(ctx); } @@ -10357,7 +10377,7 @@ templates: ctx->timer.tima = (ctx->timer.tma << shift); // trigger timer interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 2)); + cpu_irq(ctx, IRQ_TIMER); if (ctx->config && ctx->config->on_timer) { // notify callback @@ -10560,7 +10580,7 @@ templates: ctx->mmu.btns = btns; // trigger p1 interrupt - mmu_wb(ctx, PORT_IF, mmu_rb(ctx, PORT_IF) & (1 << 4)); + cpu_irq(ctx, IRQ_P1); } } @@ -10606,8 +10626,8 @@ templates: gpu_init( gb_t * const ctx ) { - gpu_set_mode(ctx, GPU_MODE_OAM); - gpu_set_line(ctx, 0); + ctx->gpu.mode = GPU_MODE_VBLANK; + ctx->gpu.line = 0; ctx->gpu.lcdc = 0x91; ctx->gpu.bgp = 0xFC; ctx->gpu.obp0 = 0xFF; -- cgit v1.2.3