summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-06-16 19:49:59 -0400
committerPaul Duncan <pabs@pablotron.org>2018-06-16 19:49:59 -0400
commit67bdc96a4341b329cda87396879cfee75be4b227 (patch)
tree646dd7694f373c0adb115cedeed27f130f6bdded
parent83835b229abdee7b4e79156c4f76f854476127f5 (diff)
downloadgb-c-67bdc96a4341b329cda87396879cfee75be4b227.tar.bz2
gb-c-67bdc96a4341b329cda87396879cfee75be4b227.zip
add gpu_step()
-rw-r--r--ops.yaml90
1 files 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;
@@ -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
) {