summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ops.yaml250
1 files changed, 171 insertions, 79 deletions
diff --git a/ops.yaml b/ops.yaml
index 58afc61..b1f744e 100644
--- a/ops.yaml
+++ b/ops.yaml
@@ -8208,6 +8208,52 @@ templates:
}
static uint8_t
+ eram_rb(
+ const gb_t * const ctx,
+ const uint16_t addr
+ ) {
+ // switchable external ram bank (8k, banked, optional)
+ switch (rom_get_mbc_type(ctx)) {
+ case MBC_TYPE_MBC1:
+ return mbc1_eram_rb(ctx, addr);
+ case MBC_TYPE_MBC2:
+ return mbc2_eram_rb(ctx, addr);
+ case MBC_TYPE_NONE:
+ default:
+ return 0;
+ }
+ }
+
+ static uint8_t
+ vram_rb(
+ const gb_t * const ctx,
+ const uint16_t addr
+ ) {
+ switch (ctx->gpu.mode) {
+ case GPU_MODE_VRAM:
+ return 0xFF;
+ default:
+ // return vram (8k)
+ return ctx->mmu.vram[addr & 0x1FFF];
+ }
+ }
+
+ static uint8_t
+ oam_rb(
+ const gb_t * const ctx,
+ const uint16_t addr
+ ) {
+ switch (ctx->gpu.mode) {
+ case GPU_MODE_HBLANK:
+ case GPU_MODE_VBLANK:
+ // oam memory (160 bytes):
+ return ctx->mmu.oam[addr & 0xFF];
+ default:
+ return 0;
+ }
+ }
+
+ static uint8_t
ram_rb(
gb_t * const ctx,
const uint16_t addr
@@ -8216,24 +8262,36 @@ templates:
case 0x8000:
case 0x9000:
// return vram (8k)
- return ctx->mmu.vram[addr & 0x1FFF];
+ return vram_rb(ctx, addr);
case 0xA000:
case 0xB000:
// switchable external ram bank (8k, banked, optional)
- switch (rom_get_mbc_type(ctx)) {
- case MBC_TYPE_MBC1:
- return mbc1_eram_rb(ctx, addr);
- case MBC_TYPE_MBC2:
- return mbc2_eram_rb(ctx, addr);
- case MBC_TYPE_NONE:
- default:
- return 0;
- }
+ return eram_rb(ctx, addr);
case 0xC000: // working ram (8k)
case 0xD000:
case 0xE000: // working ram (shadow)
- case 0xF000:
return ctx->mmu.ram[addr & 0x1FFF];
+ case 0xF000:
+ switch (addr & 0x0F00) {
+ case 0x0E00:
+ if (addr < 0xFEA0) {
+ return oam_rb(ctx, addr);
+ } else {
+ // rest of page reads as zero
+ return 0;
+ }
+ case 0x0F00:
+ if (addr == PORT_IE || addr < 0xFF80) {
+ // io port
+ return mmu_rp(ctx, addr);
+ } else {
+ // zero page
+ return ctx->mmu.zram[addr & 0x7F];
+ }
+ default:
+ // working ram (<0xFE00, 8k, shadow)
+ return ctx->mmu.ram[addr & 0x1FFF];
+ }
default:
// never reached
return 0;
@@ -8262,29 +8320,8 @@ templates:
case 0xC000:
case 0xD000:
case 0xE000:
- return ram_rb(ctx, addr);
case 0xF000:
- switch (addr & 0x0F00) {
- case 0x0E00:
- if (addr < 0xFEA0) {
- // oam memory (160 bytes):
- return ctx->mmu.oam[addr & 0xFF];
- } else {
- // rest of page reads as zero
- return 0;
- }
- case 0x0F00:
- if (addr == PORT_IE || addr < 0xFF80) {
- // io port
- return mmu_rp(ctx, addr);
- } else {
- // zero page
- return ctx->mmu.zram[addr & 0x7F];
- }
- default:
- // working ram (<0xFE00, 8k, shadow)
- return ram_rb(ctx, addr);
- }
+ return ram_rb(ctx, addr);
default:
// never reached
return 0;
@@ -8311,6 +8348,72 @@ templates:
}
static void
+ eram_wb(
+ gb_t * const ctx,
+ const uint16_t addr,
+ const uint8_t val
+ ) {
+ switch (rom_get_mbc_type(ctx)) {
+ case MBC_TYPE_MBC1:
+ mbc1_eram_wb(ctx, addr, val);
+ break;
+ case MBC_TYPE_MBC2:
+ mbc2_eram_wb(ctx, addr, val);
+ break;
+ case MBC_TYPE_NONE:
+ // TODO: implement remaining mbcs
+ if (ctx->mmu.eram) {
+ // external ram (8k, optional)
+ ctx->mmu.eram[addr & 0x1FFF] = val;
+ }
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+
+ static void
+ vram_wb(
+ gb_t * const ctx,
+ const uint16_t addr,
+ const uint8_t val
+ ) {
+ switch (ctx->gpu.mode) {
+ case GPU_MODE_HBLANK:
+ case GPU_MODE_VBLANK:
+ case GPU_MODE_OAM:
+ // vram (8k)
+ ctx->mmu.vram[addr & 0x1FFF] = val;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+
+ static void
+ oam_wb(
+ gb_t * const ctx,
+ const uint16_t addr,
+ const uint8_t val
+ ) {
+ switch (ctx->gpu.mode) {
+ case GPU_MODE_HBLANK:
+ case GPU_MODE_VBLANK:
+ // oam memory (160 bytes):
+ ctx->mmu.oam[addr & 0xFF] = val;
+
+ // TODO: invalidate OAM cache
+
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+
+ static void
ram_wb(
gb_t * const ctx,
const uint16_t addr,
@@ -8319,38 +8422,41 @@ templates:
switch (addr & 0xF000) {
case 0x8000:
case 0x9000:
- // vram (8k)
- // (FIXME: can we write directly to vram?)
- ctx->mmu.vram[addr & 0x1FFF] = val;
+ vram_wb(ctx, addr, val);
break;
case 0xA000:
case 0xB000:
- switch (rom_get_mbc_type(ctx)) {
- case MBC_TYPE_MBC1:
- mbc1_eram_wb(ctx, addr, val);
- break;
- case MBC_TYPE_MBC2:
- mbc2_eram_wb(ctx, addr, val);
- break;
- case MBC_TYPE_NONE:
- // TODO: implement remaining mbcs
- if (ctx->mmu.eram) {
- // external ram (8k, optional)
- ctx->mmu.eram[addr & 0x1FFF] = val;
- }
- break;
- default:
- // do nothing
- break;
- }
-
+ eram_wb(ctx, addr, val);
break;
case 0xC000: // working ram (8k)
case 0xD000:
case 0xE000: // working ram (8k, shadow)
- case 0xF000:
ctx->mmu.ram[addr & 0x1FFF] = val;
break;
+ case 0xF000:
+ switch (addr & 0x0F00) {
+ case 0x0E00:
+ if (addr < 0xFEA0) {
+ // oam memory (160 bytes):
+ oam_wb(ctx, addr, val);
+ }
+
+ break;
+ case 0x0F00:
+ if (addr == PORT_IE || addr < 0xFF80) {
+ // io ports
+ mmu_wp(ctx, addr, val);
+ } else {
+ // zero page
+ ctx->mmu.zram[addr & 0x7F] = val;
+ }
+
+ break;
+ default:
+ // working ram (<0xFE00, 8k, shadow)
+ ctx->mmu.ram[addr & 0x1FFF] = val;
+ break;
+ }
default:
// never reached
break;
@@ -8381,31 +8487,9 @@ templates:
case 0xC000:
case 0xD000:
case 0xE000:
+ case 0xF000:
ram_wb(ctx, addr, val);
break;
- case 0xF000:
- switch (addr & 0x0F00) {
- case 0x0E00:
- if (addr < 0xFEA0) {
- // oam memory (160 bytes):
- ctx->mmu.oam[addr & 0xFF] = val;
- }
-
- break;
- case 0x0F00:
- if (addr == PORT_IE || addr < 0xFF80) {
- // io ports
- mmu_wp(ctx, addr, val);
- } else {
- // zero page
- ctx->mmu.zram[addr & 0x7F] = val;
- }
-
- break;
- default:
- // working ram (<0xFE00, 8k, shadow)
- ram_wb(ctx, addr, val);
- }
}
}
@@ -9710,8 +9794,10 @@ templates:
gb_frame(
gb_t * const ctx
) {
+ // get current frame
const uint32_t frame = ctx->gpu.frame;
+ // run until next frame
while (ctx->gpu.frame == frame) {
gb_step(ctx);
}
@@ -9733,6 +9819,7 @@ templates:
// init cpu registers
// (src: TCAGBD.pdf, 3.2)
+ // TODO: this varies by model (DGB/CGB/SGB/GBA/etc)
ctx->cpu.rs[RW_AF] = 0x01B0;
ctx->cpu.rs[RW_BC] = 0x0013;
ctx->cpu.rs[RW_DE] = 0x00D8;
@@ -9749,9 +9836,14 @@ templates:
// clear context
memset(ctx, 0, sizeof(gb_t));
+ // init cpu
cpu_init(ctx);
// init mmu
ctx->mmu.rom = rom;
ctx->mmu.rom_size = rom_size;
+
+ // init gpu
+ ctx->gpu.mode = GPU_MODE_OAM;
+ ctx->gpu.line = 0;
}