GBA Savedata: EEPROM performance fixes

This commit is contained in:
Vicki Pfau 2018-10-12 11:11:48 -07:00
parent af1d114f49
commit 50d735b99b
5 changed files with 28 additions and 13 deletions

View File

@ -1,6 +1,8 @@
0.8.0: (Future) 0.8.0: (Future)
Bugfixes: Bugfixes:
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - 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) 0.7.0: (Future)
Features: Features:

View File

@ -23,7 +23,8 @@ enum SavedataType {
SAVEDATA_SRAM = 1, SAVEDATA_SRAM = 1,
SAVEDATA_FLASH512 = 2, SAVEDATA_FLASH512 = 2,
SAVEDATA_FLASH1M = 3, SAVEDATA_FLASH1M = 3,
SAVEDATA_EEPROM = 4 SAVEDATA_EEPROM = 4,
SAVEDATA_EEPROM512 = 5
}; };
enum SavedataCommand { enum SavedataCommand {

View File

@ -266,11 +266,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
memory->dmaTransferRegister &= 0xFFFF0000; memory->dmaTransferRegister &= 0xFFFF0000;
memory->dmaTransferRegister |= memory->dmaTransferRegister >> 16; memory->dmaTransferRegister |= memory->dmaTransferRegister >> 16;
} else { } else {
if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) { if (sourceRegion == REGION_CART2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) {
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
GBASavedataInitEEPROM(&memory->savedata);
}
memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata);
} else { } else {
if (source) { if (source) {

View File

@ -558,7 +558,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
break; break;
case REGION_CART2_EX: case REGION_CART2_EX:
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; 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); value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & (SIZE_CART0 - 1)) < memory->romSize) { } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) {
LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom); LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom);

View File

@ -77,6 +77,9 @@ void GBASavedataDeinit(struct GBASavedata* savedata) {
case SAVEDATA_EEPROM: case SAVEDATA_EEPROM:
mappedMemoryFree(savedata->data, SIZE_CART_EEPROM); mappedMemoryFree(savedata->data, SIZE_CART_EEPROM);
break; break;
case SAVEDATA_EEPROM512:
mappedMemoryFree(savedata->data, SIZE_CART_EEPROM512);
break;
case SAVEDATA_FORCE_NONE: case SAVEDATA_FORCE_NONE:
case SAVEDATA_AUTODETECT: case SAVEDATA_AUTODETECT:
break; 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; return out->write(out, savedata->data, SIZE_CART_FLASH1M) == SIZE_CART_FLASH1M;
case SAVEDATA_EEPROM: case SAVEDATA_EEPROM:
return out->write(out, savedata->data, SIZE_CART_EEPROM) == SIZE_CART_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_AUTODETECT:
case SAVEDATA_FORCE_NONE: case SAVEDATA_FORCE_NONE:
return true; return true;
@ -152,7 +157,9 @@ size_t GBASavedataSize(const struct GBASavedata* savedata) {
case SAVEDATA_FLASH1M: case SAVEDATA_FLASH1M:
return SIZE_CART_FLASH1M; return SIZE_CART_FLASH1M;
case SAVEDATA_EEPROM: 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: case SAVEDATA_FORCE_NONE:
return 0; return 0;
case SAVEDATA_AUTODETECT: case SAVEDATA_AUTODETECT:
@ -218,6 +225,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type)
GBASavedataInitFlash(savedata); GBASavedataInitFlash(savedata);
break; break;
case SAVEDATA_EEPROM: case SAVEDATA_EEPROM:
case SAVEDATA_EEPROM512:
GBASavedataInitEEPROM(savedata); GBASavedataInitEEPROM(savedata);
break; break;
case SAVEDATA_SRAM: case SAVEDATA_SRAM:
@ -263,22 +271,26 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) {
void GBASavedataInitEEPROM(struct GBASavedata* savedata) { void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_EEPROM; savedata->type = SAVEDATA_EEPROM512;
} else { } else if (savedata->type != SAVEDATA_EEPROM512 && savedata->type != SAVEDATA_EEPROM) {
mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata");
return; return;
} }
int32_t eepromSize = SIZE_CART_EEPROM512; int32_t eepromSize = SIZE_CART_EEPROM512;
if (savedata->type == SAVEDATA_EEPROM) {
eepromSize = SIZE_CART_EEPROM;
}
off_t end; off_t end;
if (!savedata->vf) { if (!savedata->vf) {
end = 0; end = 0;
savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM);
} else { } else {
end = savedata->vf->size(savedata->vf); end = savedata->vf->size(savedata->vf);
if (end < SIZE_CART_EEPROM512) { if (end < eepromSize) {
savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM512); savedata->vf->truncate(savedata->vf, eepromSize);
} else if (end > SIZE_CART_EEPROM512) { } else if (end >= SIZE_CART_EEPROM) {
eepromSize = SIZE_CART_EEPROM; eepromSize = SIZE_CART_EEPROM;
savedata->type = SAVEDATA_EEPROM;
} }
savedata->data = savedata->vf->map(savedata->vf, eepromSize, savedata->mapMode); 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) { if (size < SIZE_CART_EEPROM512) {
return; return;
} }
if (savedata->type == SAVEDATA_EEPROM) {
return;
}
savedata->type = SAVEDATA_EEPROM;
if (!savedata->vf || savedata->vf->size(savedata->vf) > SIZE_CART_EEPROM512) { if (!savedata->vf || savedata->vf->size(savedata->vf) > SIZE_CART_EEPROM512) {
return; return;
} }