GB: Clean up cartridge removal codepath (fixes #398)
Vicki Pfau vi@endrift.com
Wed, 24 Feb 2021 20:18:13 -0800
4 files changed,
33 insertions(+),
34 deletions(-)
M
include/mgba/internal/gb/mbc.h
→
include/mgba/internal/gb/mbc.h
@@ -17,6 +17,7 @@
struct GB; struct GBMemory; void GBMBCInit(struct GB* gb); +void GBMBCReset(struct GB* gb); void GBMBCSwitchBank(struct GB* gb, int bank); void GBMBCSwitchBank0(struct GB* gb, int bank); void GBMBCSwitchHalfBank(struct GB* gb, int half, int bank);
M
src/gb/gb.c
→
src/gb/gb.c
@@ -116,10 +116,10 @@ gb->yankedRomSize = 0;
gb->memory.romBase = gb->memory.rom; gb->memory.romSize = gb->pristineRomSize; gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize); - GBMBCInit(gb); + memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); + GBMBCReset(gb); if (gb->cpu) { - GBMBCSwitchBank(gb, 0); struct SM83Core* cpu = gb->cpu; cpu->memory.setActiveRegion(cpu, cpu->pc); }@@ -133,7 +133,7 @@ gb->yankedRomSize = gb->memory.romSize;
gb->yankedMbc = gb->memory.mbcType; gb->memory.romSize = 0; gb->memory.mbcType = GB_MBC_NONE; - gb->memory.sramAccess = false; + GBMBCReset(gb); if (gb->cpu) { struct SM83Core* cpu = gb->cpu;
M
src/gb/mbc.c
→
src/gb/mbc.c
@@ -224,7 +224,7 @@ }
void GBMBCInit(struct GB* gb) { const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; - if (gb->memory.rom) { + if (gb->memory.rom && gb->memory.romSize) { if (gb->memory.romSize >= 0x8000) { const struct GBCartridge* cartFooter = (const struct GBCartridge*) &gb->memory.rom[gb->memory.romSize - 0x7F00]; if (doCrc32(cartFooter->logo, sizeof(cartFooter->logo)) == GB_LOGO_HASH && cartFooter->type >= 0x0B && cartFooter->type <= 0x0D) {@@ -433,6 +433,33 @@
if (gb->memory.mbcType == GB_MBC3_RTC) { GBMBCRTCRead(gb); } +} + +void GBMBCReset(struct GB* gb) { + gb->memory.romBank = &gb->memory.rom[GB_SIZE_CART_BANK0]; + + memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); + GBMBCInit(gb); + switch (gb->memory.mbcType) { + case GB_MBC1: + gb->memory.mbcState.mbc1.mode = 0; + gb->memory.mbcState.mbc1.bankLo = 1; + break; + case GB_MBC6: + GBMBCSwitchHalfBank(gb, 0, 2); + GBMBCSwitchHalfBank(gb, 1, 3); + gb->memory.mbcState.mbc6.sramAccess = false; + GBMBCSwitchSramHalfBank(gb, 0, 0); + GBMBCSwitchSramHalfBank(gb, 0, 1); + break; + case GB_MMM01: + GBMBCSwitchBank0(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 2); + GBMBCSwitchBank(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 1); + break; + default: + break; + } + gb->memory.sramBank = gb->memory.sram; } static void _latchRtc(struct mRTCSource* rtc, uint8_t* rtcRegs, time_t* rtcLastLatch) {
M
src/gb/memory.c
→
src/gb/memory.c
@@ -183,10 +183,6 @@ base[i + 3] = ~pattern;
} } GBMemorySwitchWramBank(&gb->memory, 1); - gb->memory.romBank = &gb->memory.rom[GB_SIZE_CART_BANK0]; - gb->memory.currentBank = 1; - gb->memory.sramCurrentBank = 0; - gb->memory.ime = false; gb->memory.ie = 0;@@ -210,32 +206,7 @@ gb->memory.hdmaEvent.priority = 0x41;
memset(&gb->memory.hram, 0, sizeof(gb->memory.hram)); - memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); - GBMBCInit(gb); - switch (gb->memory.mbcType) { - case GB_MBC1: - gb->memory.mbcState.mbc1.mode = 0; - gb->memory.mbcState.mbc1.bankLo = 1; - break; - case GB_MBC6: - GBMBCSwitchHalfBank(gb, 0, 2); - GBMBCSwitchHalfBank(gb, 1, 3); - gb->memory.mbcState.mbc6.sramAccess = false; - GBMBCSwitchSramHalfBank(gb, 0, 0); - GBMBCSwitchSramHalfBank(gb, 0, 1); - break; - case GB_MMM01: - GBMBCSwitchBank0(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 2); - GBMBCSwitchBank(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 1); - break; - default: - break; - } - gb->memory.sramBank = gb->memory.sram; - - if (!gb->memory.wram) { - GBMemoryDeinit(gb); - } + GBMBCReset(gb); } void GBMemorySwitchWramBank(struct GBMemory* memory, int bank) {