From 67bdc96a4341b329cda87396879cfee75be4b227 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Sat, 16 Jun 2018 19:49:59 -0400 Subject: add gpu_step() --- ops.yaml | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/ops.yaml b/ops.yaml index 30451df..08c8d8c 100644 --- a/ops.yaml +++ b/ops.yaml @@ -3281,7 +3281,7 @@ ops: code: | // pop pc, enable interrupts pop_rw(ctx, RW_PC); - ctx->cpu.ei = true; + ctx->cpu.ime = true; - id: JP C, a16 hex: 0xDA cat: "jumps/calls" @@ -3604,7 +3604,7 @@ ops: c: code: | // disable interrupts - ctx->cpu.ei = false; + ctx->cpu.ime = false; - id: XX hex: 0xF4 cat: "invalid" @@ -3708,7 +3708,7 @@ ops: c: code: | // disable interrupts - ctx->cpu.ei = false; + ctx->cpu.ime = false; - id: XX hex: 0xFC cat: "invalid" @@ -7559,6 +7559,14 @@ templates: STATE_LAST, } cpu_state_t; + typedef enum { + GPU_MODE_OAM, + GPU_MODE_VRAM, + GPU_MODE_HBLANK, + GPU_MODE_VBLANK, + GPU_MODE_LAST, + } gpu_mode_t; + typedef struct { struct { bool in_bios; @@ -7578,11 +7586,22 @@ templates: uint8_t *eram; } mmu; + struct { + gpu_mode_t mode; + uint16_t clock; + uint16_t line; + uint8_t frame[3 * 160 * 144]; + } gpu; + struct { uint16_t rs[RW_LAST]; uint32_t clock; /* FIXME: uint16_t? */ cpu_state_t state; - bool ei; + + // interrupt master enable + bool ime; + uint32_t iev; + uint32_t ivs; // FIXME: uint8_t? } cpu; } gb_t; @@ -7671,6 +7690,7 @@ templates: // working ram (shadow) return ctx->mmu.ram[addr & 0x1FFF]; } + break; default: // never reached return 0; @@ -8688,6 +8708,68 @@ templates: cpu_ww(ctx, RW_PC, mmu_rw(ctx, addr)); } + void + gpu_step( + gb_t * const ctx, + const uint16_t clock + ) { + // increment clock + ctx->gpu.clock += clock; + + switch (ctx->gpu.mode) { + case GPU_MODE_OAM: + if (ctx->gpu.clock > 80) { + // clear clock, set mode + ctx->gpu.clock = 0; + ctx->gpu.mode = GPU_MODE_VRAM; + } + + break; + case GPU_MODE_VRAM: + if (ctx->gpu.clock > 172) { + // TODO: write scanline + + // clear clock, set mode + ctx->gpu.clock = 0; + ctx->gpu.mode = GPU_MODE_HBLANK; + + // TODO: trigger hblank interrupt + } + + break; + case GPU_MODE_HBLANK: + if (ctx->gpu.clock > 204) { + // clear clock, increment line + ctx->gpu.clock = 0; + ctx->gpu.line++; + + if (ctx->gpu.line < 143) { + // process next scanline + ctx->gpu.mode = GPU_MODE_OAM; + } else { + // go to vblank + ctx->gpu.mode = GPU_MODE_VBLANK; + + // TODO: trigger vblank interrupt + } + } + + break; + case GPU_MODE_VBLANK: + if (ctx->gpu.clock > 4560) { + // reset line, clear clock, set mode + ctx->gpu.line = 0; + ctx->gpu.clock = 0; + ctx->gpu.mode = GPU_MODE_OAM; + } + + break; + default: + /* do nothing, unknown gpu mode */ + break; + } + } + void gb_step( gb_t * const ctx -- cgit v1.2.3