all repos — mgba @ a74fe13506d1f7adfc3b4d2074830417b5b3e750

mGBA Game Boy Advance Emulator

GB MBC: Fix MBC2 saves (fixes #954)
Vicki Pfau vi@endrift.com
Mon, 08 Jan 2018 18:24:29 -0800
commit

a74fe13506d1f7adfc3b4d2074830417b5b3e750

parent

52be25028e8ddd3dec7e78c3e35e3a1c21f7f9a4

3 files changed, 19 insertions(+), 3 deletions(-)

jump to
M CHANGESCHANGES

@@ -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.csrc/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.csrc/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);