GB: Sync savedata after being written
Jeffrey Pfau jeffrey@endrift.com
Thu, 15 Sep 2016 18:11:12 -0700
4 files changed,
35 insertions(+),
2 deletions(-)
M
src/gb/gb.c
→
src/gb/gb.c
@@ -15,6 +15,8 @@ #include "util/math.h"
#include "util/patch.h" #include "util/vfs.h" +#define CLEANUP_THRESHOLD 15 + const uint32_t CGB_LR35902_FREQUENCY = 0x800000; const uint32_t SGB_LR35902_FREQUENCY = 0x418B1E;@@ -171,6 +173,27 @@ gb->memory.sram = newSram;
} if (gb->sramSize < size) { gb->sramSize = size; + } +} + +void GBSramClean(struct GB* gb, uint32_t frameCount) { + // TODO: Share with GBASavedataClean + if (!gb->sramVf) { + return; + } + if (gb->sramDirty & GB_SRAM_DIRT_NEW) { + gb->sramDirtAge = frameCount; + gb->sramDirty &= ~GB_SRAM_DIRT_NEW; + if (!(gb->sramDirty & GB_SRAM_DIRT_SEEN)) { + gb->sramDirty |= GB_SRAM_DIRT_SEEN; + } + } else if ((gb->sramDirty & GB_SRAM_DIRT_SEEN) && frameCount - gb->sramDirtAge > CLEANUP_THRESHOLD) { + gb->sramDirty = 0; + if (gb->memory.sram && gb->sramVf->sync(gb->sramVf, gb->memory.sram, gb->sramSize)) { + mLOG(GB_MEM, INFO, "Savedata synced"); + } else { + mLOG(GB_MEM, INFO, "Savedata failed to sync!"); + } } }@@ -601,6 +624,8 @@ }
} void GBFrameEnded(struct GB* gb) { + GBSramClean(gb, gb->video.frameCounter); + if (gb->cpu->components && gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]) { struct mCheatDevice* device = (struct mCheatDevice*) gb->cpu->components[CPU_COMPONENT_CHEAT_DEVICE]; size_t i;
M
src/gb/gb.h
→
src/gb/gb.h
@@ -68,6 +68,8 @@ struct VFile* biosVf;
struct VFile* sramVf; struct VFile* sramRealVf; uint32_t sramSize; + int sramDirty; + int32_t sramDirtAge; struct mAVStream* stream;@@ -111,12 +113,13 @@
struct VFile; bool GBLoadROM(struct GB* gb, struct VFile* vf); bool GBLoadSave(struct GB* gb, struct VFile* vf); -void GBResizeSram(struct GB* gb, size_t size); void GBYankROM(struct GB* gb); void GBUnloadROM(struct GB* gb); void GBLoadBIOS(struct GB* gb, struct VFile* vf); +void GBSramClean(struct GB* gb, uint32_t frameCount); +void GBResizeSram(struct GB* gb, size_t size); void GBSavedataMask(struct GB* gb, struct VFile* vf); void GBSavedataUnmask(struct GB* gb);@@ -127,7 +130,6 @@ bool GBIsROM(struct VFile* vf);
void GBGetGameTitle(struct GB* gba, char* out); void GBGetGameCode(struct GB* gba, char* out); -void GBFrameStarted(struct GB* gb); void GBFrameEnded(struct GB* gb); #endif
M
src/gb/memory.c
→
src/gb/memory.c
@@ -220,6 +220,7 @@ memory->sramBank[address & (GB_SIZE_EXTERNAL_RAM - 1)] = value;
} else if (memory->mbcType == GB_MBC7) { GBMBC7Write(memory, address, value); } + gb->sramDirty |= GB_SRAM_DIRT_NEW; return; case GB_REGION_WORKING_RAM_BANK0: case GB_REGION_WORKING_RAM_BANK0 + 2:
M
src/gb/memory.h
→
src/gb/memory.h
@@ -55,6 +55,11 @@ GB_SIZE_IO = 0x80,
GB_SIZE_HRAM = 0x7F, }; +enum { + GB_SRAM_DIRT_NEW = 1, + GB_SRAM_DIRT_SEEN = 2 +}; + struct GBMemory; typedef void (*GBMemoryBankController)(struct GB*, uint16_t address, uint8_t value);