From 50d735b99b0dbb6e24eda5c40176f1519dc651ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 11:11:48 -0700 Subject: [PATCH] GBA Savedata: EEPROM performance fixes --- CHANGES | 2 ++ include/mgba/internal/gba/savedata.h | 3 ++- src/gba/dma.c | 6 +----- src/gba/memory.c | 2 +- src/gba/savedata.c | 28 ++++++++++++++++++++++------ 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index de70636d3..58af4992b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 0.8.0: (Future) Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) +Misc: + - GBA Savedata: EEPROM performance fixes 0.7.0: (Future) Features: diff --git a/include/mgba/internal/gba/savedata.h b/include/mgba/internal/gba/savedata.h index ecf17eecf..05cd65963 100644 --- a/include/mgba/internal/gba/savedata.h +++ b/include/mgba/internal/gba/savedata.h @@ -23,7 +23,8 @@ enum SavedataType { SAVEDATA_SRAM = 1, SAVEDATA_FLASH512 = 2, SAVEDATA_FLASH1M = 3, - SAVEDATA_EEPROM = 4 + SAVEDATA_EEPROM = 4, + SAVEDATA_EEPROM512 = 5 }; enum SavedataCommand { diff --git a/src/gba/dma.c b/src/gba/dma.c index cf5174fdb..2a33eae94 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -266,11 +266,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { memory->dmaTransferRegister &= 0xFFFF0000; memory->dmaTransferRegister |= memory->dmaTransferRegister >> 16; } else { - if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) { - if (memory->savedata.type == SAVEDATA_AUTODETECT) { - mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); - GBASavedataInitEEPROM(&memory->savedata); - } + if (sourceRegion == REGION_CART2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) { memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); } else { if (source) { diff --git a/src/gba/memory.c b/src/gba/memory.c index 384fd81cc..5c7efd104 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -558,7 +558,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { break; case REGION_CART2_EX: wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; - if (memory->savedata.type == SAVEDATA_EEPROM) { + if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) { value = GBASavedataReadEEPROM(&memory->savedata); } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) { LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom); diff --git a/src/gba/savedata.c b/src/gba/savedata.c index ba702e36b..08d0b1367 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -77,6 +77,9 @@ void GBASavedataDeinit(struct GBASavedata* savedata) { case SAVEDATA_EEPROM: mappedMemoryFree(savedata->data, SIZE_CART_EEPROM); break; + case SAVEDATA_EEPROM512: + mappedMemoryFree(savedata->data, SIZE_CART_EEPROM512); + break; case SAVEDATA_FORCE_NONE: case SAVEDATA_AUTODETECT: break; @@ -127,6 +130,8 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) { return out->write(out, savedata->data, SIZE_CART_FLASH1M) == SIZE_CART_FLASH1M; case SAVEDATA_EEPROM: return out->write(out, savedata->data, SIZE_CART_EEPROM) == SIZE_CART_EEPROM; + case SAVEDATA_EEPROM512: + return out->write(out, savedata->data, SIZE_CART_EEPROM512) == SIZE_CART_EEPROM512; case SAVEDATA_AUTODETECT: case SAVEDATA_FORCE_NONE: return true; @@ -152,7 +157,9 @@ size_t GBASavedataSize(const struct GBASavedata* savedata) { case SAVEDATA_FLASH1M: return SIZE_CART_FLASH1M; case SAVEDATA_EEPROM: - return (savedata->vf && savedata->vf->size(savedata->vf) == SIZE_CART_EEPROM512) ? SIZE_CART_EEPROM512 : SIZE_CART_EEPROM; + return SIZE_CART_EEPROM; + case SAVEDATA_EEPROM512: + return SIZE_CART_EEPROM512; case SAVEDATA_FORCE_NONE: return 0; case SAVEDATA_AUTODETECT: @@ -218,6 +225,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) GBASavedataInitFlash(savedata); break; case SAVEDATA_EEPROM: + case SAVEDATA_EEPROM512: GBASavedataInitEEPROM(savedata); break; case SAVEDATA_SRAM: @@ -263,22 +271,26 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { void GBASavedataInitEEPROM(struct GBASavedata* savedata) { if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_EEPROM; - } else { + savedata->type = SAVEDATA_EEPROM512; + } else if (savedata->type != SAVEDATA_EEPROM512 && savedata->type != SAVEDATA_EEPROM) { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; } int32_t eepromSize = SIZE_CART_EEPROM512; + if (savedata->type == SAVEDATA_EEPROM) { + eepromSize = SIZE_CART_EEPROM; + } off_t end; if (!savedata->vf) { end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); } else { end = savedata->vf->size(savedata->vf); - if (end < SIZE_CART_EEPROM512) { - savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM512); - } else if (end > SIZE_CART_EEPROM512) { + if (end < eepromSize) { + savedata->vf->truncate(savedata->vf, eepromSize); + } else if (end >= SIZE_CART_EEPROM) { eepromSize = SIZE_CART_EEPROM; + savedata->type = SAVEDATA_EEPROM; } savedata->data = savedata->vf->map(savedata->vf, eepromSize, savedata->mapMode); } @@ -420,6 +432,10 @@ static void _ensureEeprom(struct GBASavedata* savedata, uint32_t size) { if (size < SIZE_CART_EEPROM512) { return; } + if (savedata->type == SAVEDATA_EEPROM) { + return; + } + savedata->type = SAVEDATA_EEPROM; if (!savedata->vf || savedata->vf->size(savedata->vf) > SIZE_CART_EEPROM512) { return; }