From 5f572ffb6238881b6fda7e7531e5fd7c68c0ef6b Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Tue, 28 Jul 2015 13:15:37 -0700 Subject: [PATCH] GBA Video: Callback for VRAM writes --- src/gba/memory.c | 10 ++++++++-- src/gba/renderers/video-software.c | 7 +++++++ src/gba/video.c | 8 ++++++++ src/gba/video.h | 1 + 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 9e7a478bb..a69b5fd5a 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -634,8 +634,12 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { #define STORE_VRAM \ if ((address & 0x0001FFFF) < SIZE_VRAM) { \ STORE_32(value, address & 0x0001FFFC, gba->video.renderer->vram); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \ } else { \ STORE_32(value, address & 0x00017FFC, gba->video.renderer->vram); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC) + 2); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC)); \ } \ wait += waitstatesRegion[REGION_VRAM]; @@ -728,8 +732,10 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle case REGION_VRAM: if ((address & 0x0001FFFF) < SIZE_VRAM) { STORE_16(value, address & 0x0001FFFE, gba->video.renderer->vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } else { STORE_16(value, address & 0x00017FFE, gba->video.renderer->vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE); } break; case REGION_OAM: @@ -794,8 +800,8 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address); break; } - ((int8_t*) gba->video.renderer->vram)[address & 0x1FFFE] = value; - ((int8_t*) gba->video.renderer->vram)[(address & 0x1FFFE) | 1] = value; + gba->video.renderer->vram[(address & 0x1FFFE) >> 1] = ((uint8_t) value) | (value << 8); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); break; case REGION_OAM: GBALog(gba, GBA_LOG_GAME_ERROR, "Cannot Store8 to OAM: 0x%08X", address); diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index f2b7d842c..7dae88af6 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -13,6 +13,7 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer); +static void GBAVideoSoftwareRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -46,6 +47,7 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.reset = GBAVideoSoftwareRendererReset; renderer->d.deinit = GBAVideoSoftwareRendererDeinit; renderer->d.writeVideoRegister = GBAVideoSoftwareRendererWriteVideoRegister; + renderer->d.writeVRAM = GBAVideoSoftwareRendererWriteVRAM; renderer->d.writeOAM = GBAVideoSoftwareRendererWriteOAM; renderer->d.writePalette = GBAVideoSoftwareRendererWritePalette; renderer->d.drawScanline = GBAVideoSoftwareRendererDrawScanline; @@ -327,6 +329,11 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender return value; } +static void GBAVideoSoftwareRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { + UNUSED(renderer); + UNUSED(address); +} + static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; softwareRenderer->oamDirty = 1; diff --git a/src/gba/video.c b/src/gba/video.c index 66ebedd34..39856c2a9 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -17,6 +17,7 @@ static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoDummyRendererReset(struct GBAVideoRenderer* renderer); static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer); static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); +static void GBAVideoDummyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoDummyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static void GBAVideoDummyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); @@ -47,6 +48,7 @@ static struct GBAVideoRenderer dummyRenderer = { .reset = GBAVideoDummyRendererReset, .deinit = GBAVideoDummyRendererDeinit, .writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister, + .writeVRAM = GBAVideoDummyRendererWriteVRAM, .writePalette = GBAVideoDummyRendererWritePalette, .writeOAM = GBAVideoDummyRendererWriteOAM, .drawScanline = GBAVideoDummyRendererDrawScanline, @@ -222,6 +224,12 @@ static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* return value; } +static void GBAVideoDummyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { + UNUSED(renderer); + UNUSED(address); + // Nothing to do +} + static void GBAVideoDummyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { UNUSED(renderer); UNUSED(address); diff --git a/src/gba/video.h b/src/gba/video.h index 8d22545f3..13451ce51 100644 --- a/src/gba/video.h +++ b/src/gba/video.h @@ -162,6 +162,7 @@ struct GBAVideoRenderer { void (*deinit)(struct GBAVideoRenderer* renderer); uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); + void (*writeVRAM)(struct GBAVideoRenderer* renderer, uint32_t address); void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); void (*writeOAM)(struct GBAVideoRenderer* renderer, uint32_t oam); void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);