diff options
author | Paul Duncan <pabs@pablotron.org> | 2018-06-16 19:49:59 -0400 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2018-06-16 19:49:59 -0400 |
commit | 67bdc96a4341b329cda87396879cfee75be4b227 (patch) | |
tree | 646dd7694f373c0adb115cedeed27f130f6bdded | |
parent | 83835b229abdee7b4e79156c4f76f854476127f5 (diff) | |
download | gb-c-67bdc96a4341b329cda87396879cfee75be4b227.tar.bz2 gb-c-67bdc96a4341b329cda87396879cfee75be4b227.zip |
add gpu_step()
-rw-r--r-- | ops.yaml | 90 |
1 files changed, 86 insertions, 4 deletions
@@ -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; @@ -7579,10 +7587,21 @@ templates: } 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; @@ -8689,6 +8709,68 @@ templates: } 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 ) { |