From fac10eae96d38c4a4f78b4d06eb23022263fff75 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 21 Mar 2018 09:11:24 -0700 Subject: [PATCH] GB Memory: Fix OAM DMA blocking regions (fixes #1013) --- CHANGES | 1 + include/mgba/internal/gb/video.h | 1 - src/gb/memory.c | 58 +++++++++++++++++--------------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index 6313f9097..547e9dcd3 100644 --- a/CHANGES +++ b/CHANGES @@ -53,6 +53,7 @@ Bugfixes: - GBA: Fix SharkPort saves for EEPROM games - Qt: Fix opening in fullscreen (fixes mgba.io/i/993) - Python: Fix package directory + - GB Memory: Fix OAM DMA blocking regions (fixes mgba.io/i/1013) Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index 90cfd7bbb..7fd731be6 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -26,7 +26,6 @@ enum { GB_VIDEO_HORIZONTAL_LENGTH = 456, - GB_VIDEO_MODE_1_LENGTH = 65664, GB_VIDEO_TOTAL_LENGTH = 70224, GB_BASE_MAP = 0x1800, diff --git a/src/gb/memory.c b/src/gb/memory.c index 1dae0b988..089558011 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -16,31 +16,33 @@ mLOG_DEFINE_CATEGORY(GB_MEM, "GB Memory", "gb.memory"); -struct OAMBlock { - uint16_t low; - uint16_t high; +enum GBBus { + GB_BUS_CPU, + GB_BUS_MAIN, + GB_BUS_VRAM, + GB_BUS_RAM }; -static const struct OAMBlock _oamBlockDMG[] = { - { 0xA000, 0xFE00 }, - { 0xA000, 0xFE00 }, - { 0xA000, 0xFE00 }, - { 0xA000, 0xFE00 }, - { 0x8000, 0xA000 }, - { 0xA000, 0xFE00 }, - { 0xA000, 0xFE00 }, - { 0xA000, 0xFE00 }, +static const enum GBBus _oamBlockDMG[] = { + GB_BUS_MAIN, // 0x0000 + GB_BUS_MAIN, // 0x2000 + GB_BUS_MAIN, // 0x4000 + GB_BUS_MAIN, // 0x6000 + GB_BUS_VRAM, // 0x8000 + GB_BUS_MAIN, // 0xA000 + GB_BUS_MAIN, // 0xC000 + GB_BUS_CPU, // 0xE000 }; -static const struct OAMBlock _oamBlockCGB[] = { - { 0xA000, 0xC000 }, - { 0xA000, 0xC000 }, - { 0xA000, 0xC000 }, - { 0xA000, 0xC000 }, - { 0x8000, 0xA000 }, - { 0xA000, 0xC000 }, - { 0xC000, 0xFE00 }, - { 0xA000, 0xC000 }, +static const enum GBBus _oamBlockCGB[] = { + GB_BUS_MAIN, // 0x0000 + GB_BUS_MAIN, // 0x2000 + GB_BUS_MAIN, // 0x4000 + GB_BUS_MAIN, // 0x6000 + GB_BUS_VRAM, // 0x8000 + GB_BUS_MAIN, // 0xA000 + GB_BUS_RAM, // 0xC000 + GB_BUS_CPU // 0xE000 }; static void _pristineCow(struct GB* gba); @@ -192,9 +194,10 @@ uint8_t GBLoad8(struct LR35902Core* cpu, uint16_t address) { struct GB* gb = (struct GB*) cpu->master; struct GBMemory* memory = &gb->memory; if (gb->memory.dmaRemaining) { - const struct OAMBlock* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB; - block = &block[memory->dmaSource >> 13]; - if (address >= block->low && address < block->high) { + const enum GBBus* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB; + enum GBBus dmaBus = block[memory->dmaSource >> 13]; + enum GBBus accessBus = block[address >> 13]; + if (dmaBus != GB_BUS_CPU && dmaBus == accessBus) { return 0xFF; } if (address >= GB_BASE_OAM && address < GB_BASE_UNUSABLE) { @@ -264,9 +267,10 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t value) { struct GB* gb = (struct GB*) cpu->master; struct GBMemory* memory = &gb->memory; if (gb->memory.dmaRemaining) { - const struct OAMBlock* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB; - block = &block[memory->dmaSource >> 13]; - if (address >= block->low && address < block->high) { + const enum GBBus* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB; + enum GBBus dmaBus = block[memory->dmaSource >> 13]; + enum GBBus accessBus = block[address >> 13]; + if (dmaBus != GB_BUS_CPU && dmaBus == accessBus) { return; } if (address >= GB_BASE_OAM && address < GB_BASE_UNUSABLE) {