GB MBC: Fix SRAM dangling pointer with RTC games
Jeffrey Pfau jeffrey@endrift.com
Thu, 13 Oct 2016 00:17:30 -0700
3 files changed,
12 insertions(+),
2 deletions(-)
M
src/gb/gb.c
→
src/gb/gb.c
@@ -120,7 +120,7 @@
static void GBSramDeinit(struct GB* gb) { if (gb->sramVf) { gb->sramVf->unmap(gb->sramVf, gb->memory.sram, gb->sramSize); - if (gb->memory.mbcType == GB_MBC3_RTC) { + if (gb->memory.mbcType == GB_MBC3_RTC && gb->sramVf == gb->sramRealVf) { GBMBCRTCWrite(gb); } gb->sramVf = NULL;@@ -192,7 +192,7 @@ }
void GBSramClean(struct GB* gb, uint32_t frameCount) { // TODO: Share with GBASavedataClean - if (!gb->sramVf) { + if (!gb->sramVf || gb->sramVf != gb->sramRealVf) { return; } if (gb->sramDirty & GB_SRAM_DIRT_NEW) {
M
src/gb/mbc.c
→
src/gb/mbc.c
@@ -671,6 +671,15 @@ STORE_32LE(gb->memory.rtcRegs[3], 0, &rtcBuffer.latchedDays);
STORE_32LE(gb->memory.rtcRegs[4], 0, &rtcBuffer.latchedDaysHi); STORE_64LE(rtcLastLatch, 0, &rtcBuffer.unixTime); + if (vf->size(vf) == gb->sramSize) { + // Writing past the end of the file can invalidate the file mapping + vf->unmap(vf, gb->memory.sram, gb->sramSize); + gb->memory.sram = NULL; + } vf->seek(vf, gb->sramSize, SEEK_SET); vf->write(vf, &rtcBuffer, sizeof(rtcBuffer)); + if (!gb->memory.sram) { + gb->memory.sram = vf->map(vf, gb->sramSize, MAP_WRITE); + GBMBCSwitchSramBank(gb, gb->memory.sramCurrentBank); + } }