GB MBC: Fix MBC2 saves (fixes #954)
Vicki Pfau vi@endrift.com
Mon, 08 Jan 2018 18:24:29 -0800
3 files changed,
19 insertions(+),
3 deletions(-)
M
CHANGES
→
CHANGES
@@ -13,6 +13,7 @@ - LR35902: Fix watchpoints not reporting new value
- GBA Audio: Increase PSG volume (fixes mgba.io/i/932) - GBA BIOS: Fix incorrect exit condition in LZ77 - 3DS: Fix opening files in directory names with trailing slashes + - GB MBC: Fix MBC2 saves (fixes mgba.io/i/954) Misc: - GBA: Improve multiboot image detection - GB MBC: Remove erroneous bank 0 wrapping
M
src/gb/mbc.c
→
src/gb/mbc.c
@@ -30,6 +30,7 @@ static void _GBMBC7(struct GB*, uint16_t address, uint8_t value);
static void _GBHuC3(struct GB*, uint16_t address, uint8_t value); static void _GBPocketCam(struct GB* gb, uint16_t address, uint8_t value); +static uint8_t _GBMBC2Read(struct GBMemory*, uint16_t address); static uint8_t _GBMBC7Read(struct GBMemory*, uint16_t address); static uint8_t _GBPocketCamRead(struct GBMemory*, uint16_t address);@@ -183,7 +184,8 @@ gb->memory.mbcWrite = _GBMBC1;
break; case GB_MBC2: gb->memory.mbcWrite = _GBMBC2; - gb->sramSize = 0x200; + gb->memory.mbcRead = _GBMBC2Read; + gb->sramSize = 0x100; break; case GB_MBC3: gb->memory.mbcWrite = _GBMBC3;@@ -355,6 +357,7 @@ }
void _GBMBC2(struct GB* gb, uint16_t address, uint8_t value) { struct GBMemory* memory = &gb->memory; + int shift = (address & 1) * 4; int bank = value & 0xF; switch (address >> 13) { case 0x0:@@ -364,7 +367,6 @@ memory->sramAccess = false;
break; case 0xA: memory->sramAccess = true; - GBMBCSwitchSramBank(gb, memory->sramCurrentBank); break; default: // TODO@@ -378,11 +380,24 @@ ++bank;
} GBMBCSwitchBank(gb, bank); break; + case 0x5: + if (!memory->sramAccess) { + return; + } + address &= 0x1FF; + memory->sramBank[(address >> 1)] &= 0xF0 >> shift; + memory->sramBank[(address >> 1)] |= (value & 0xF) << shift; default: // TODO mLOG(GB_MBC, STUB, "MBC2 unknown address: %04X:%02X", address, value); break; } +} + +static uint8_t _GBMBC2Read(struct GBMemory* memory, uint16_t address) { + address &= 0x1FF; + int shift = (address & 1) * 4; + return (memory->sramBank[(address >> 1)] >> shift) | 0xF0; } void _GBMBC3(struct GB* gb, uint16_t address, uint8_t value) {
M
src/gb/memory.c
→
src/gb/memory.c
@@ -289,7 +289,7 @@ case GB_REGION_EXTERNAL_RAM:
case GB_REGION_EXTERNAL_RAM + 1: if (memory->rtcAccess) { memory->rtcRegs[memory->activeRtcReg] = value; - } else if (memory->sramAccess && memory->sram) { + } else if (memory->sramAccess && memory->sram && memory->mbcType != GB_MBC2) { memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value; } else if (memory->mbcType == GB_MBC7) { GBMBC7Write(memory, address, value);