diff --git a/CHANGES b/CHANGES index 04e187dbb..9ef3d4b36 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Bugfixes: - GB MBC: Fix RTC initialization (fixes mgba.io/i/825) - GB MBC: Fix RTC loading when file size is off - GB Serialize: Fix deserializing video STAT + - GB, GBA Savedata: Fix savestate-related save overwriting (fixes mgba.io/i/834) Misc: - Qt: Don't rebuild library view if style hasn't changed - SDL: Fix 2.0.5 build on macOS under some circumstances diff --git a/src/gb/gb.c b/src/gb/gb.c index 4f26e08de..fcf262696 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -219,7 +219,7 @@ void GBResizeSram(struct GB* gb, size_t size) { void GBSramClean(struct GB* gb, uint32_t frameCount) { // TODO: Share with GBASavedataClean - if (!gb->sramVf || gb->sramVf != gb->sramRealVf) { + if (!gb->sramVf) { return; } if (gb->sramDirty & GB_SRAM_DIRT_NEW) { @@ -229,6 +229,9 @@ void GBSramClean(struct GB* gb, uint32_t frameCount) { gb->sramDirty |= GB_SRAM_DIRT_SEEN; } } else if ((gb->sramDirty & GB_SRAM_DIRT_SEEN) && frameCount - gb->sramDirtAge > CLEANUP_THRESHOLD) { + if (gb->sramMaskWriteback) { + GBSavedataUnmask(gb); + } if (gb->memory.mbcType == GB_MBC3_RTC) { GBMBCRTCWrite(gb); } @@ -258,7 +261,9 @@ void GBSavedataUnmask(struct GB* gb) { gb->sramVf = gb->sramRealVf; gb->memory.sram = gb->sramVf->map(gb->sramVf, gb->sramSize, MAP_WRITE); if (gb->sramMaskWriteback) { + vf->seek(vf, 0, SEEK_SET); vf->read(vf, gb->memory.sram, gb->sramSize); + gb->sramMaskWriteback = false; } vf->close(vf); } @@ -286,6 +291,7 @@ void GBUnloadROM(struct GB* gb) { gb->memory.mbcType = GB_MBC_AUTODETECT; gb->isPristine = false; + gb->sramMaskWriteback = false; GBSavedataUnmask(gb); GBSramDeinit(gb); if (gb->sramRealVf) { diff --git a/src/gba/memory.c b/src/gba/memory.c index 34e035d50..4f7b12274 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -90,6 +90,7 @@ void GBAMemoryDeinit(struct GBA* gba) { if (gba->memory.rom) { mappedMemoryFree(gba->memory.rom, gba->memory.romSize); } + gba->memory.savedata.maskWriteback = false; GBASavedataUnmask(&gba->memory.savedata); GBASavedataDeinit(&gba->memory.savedata); if (gba->memory.savedata.realVf) {