From 00e7a5b2854b106e4b867cc40c4b539e624ea49b Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Thu, 15 Sep 2016 18:11:12 -0700 Subject: [PATCH] GB: Sync savedata after being written --- src/gb/gb.c | 25 +++++++++++++++++++++++++ src/gb/gb.h | 6 ++++-- src/gb/memory.c | 1 + src/gb/memory.h | 5 +++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index 7b18a8d84..64bd570c2 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -15,6 +15,8 @@ #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; @@ -174,6 +176,27 @@ void GBResizeSram(struct GB* gb, size_t 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!"); + } + } +} + void GBSavedataMask(struct GB* gb, struct VFile* vf) { GBSramDeinit(gb); gb->sramVf = vf; @@ -601,6 +624,8 @@ void GBGetGameCode(struct GB* gb, char* out) { } 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; diff --git a/src/gb/gb.h b/src/gb/gb.h index 764888987..a097fcaf1 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -68,6 +68,8 @@ struct GB { struct VFile* sramVf; struct VFile* sramRealVf; uint32_t sramSize; + int sramDirty; + int32_t sramDirtAge; struct mAVStream* stream; @@ -111,12 +113,13 @@ void GBHalt(struct LR35902Core* cpu); 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 diff --git a/src/gb/memory.c b/src/gb/memory.c index ce0ce67dd..69b7562de 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -220,6 +220,7 @@ void GBStore8(struct LR35902Core* cpu, uint16_t address, int8_t 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: diff --git a/src/gb/memory.h b/src/gb/memory.h index c20015165..9da54297c 100644 --- a/src/gb/memory.h +++ b/src/gb/memory.h @@ -55,6 +55,11 @@ enum { 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);