all repos — mgba @ 00e7a5b2854b106e4b867cc40c4b539e624ea49b

mGBA Game Boy Advance Emulator

GB: Sync savedata after being written
Jeffrey Pfau jeffrey@endrift.com
Thu, 15 Sep 2016 18:11:12 -0700
commit

00e7a5b2854b106e4b867cc40c4b539e624ea49b

parent

eaf331b2499e23320b0807be90312627bdd6b817

4 files changed, 35 insertions(+), 2 deletions(-)

jump to
M src/gb/gb.csrc/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.hsrc/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.csrc/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.hsrc/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);