all repos — mgba @ e93240f90c75a5f174efaf1647a18a8102ce95e5

mGBA Game Boy Advance Emulator

GBA: Add somewhat more realistic flash timings, disabled currently
Jeffrey Pfau jeffrey@endrift.com
Sat, 28 Mar 2015 03:25:46 -0700
commit

e93240f90c75a5f174efaf1647a18a8102ce95e5

parent

c665ed78e6df97c0f45fc1bc18c3ab0f63964c05

M src/gba/gba.csrc/gba/gba.c

@@ -89,6 +89,9 @@ gba->idleLoop = IDLE_LOOP_NONE;

gba->lastJump = 0; gba->idleDetectionStep = 0; gba->idleDetectionFailures = 0; + + gba->realisticTiming = false; + gba->performingDMA = false; }
M src/gba/gba.hsrc/gba/gba.h

@@ -161,6 +161,8 @@ int idleDetectionStep;

int idleDetectionFailures; int32_t cachedRegisters[16]; bool taintedRegisters[16]; + + bool realisticTiming; }; struct GBACartridge {
M src/gba/memory.csrc/gba/memory.c

@@ -778,7 +778,7 @@ case REGION_CART_SRAM_MIRROR:

if (memory->savedata.type == SAVEDATA_AUTODETECT) { if (address == SAVEDATA_FLASH_BASE) { GBALog(gba, GBA_LOG_INFO, "Detected Flash savegame"); - GBASavedataInitFlash(&memory->savedata); + GBASavedataInitFlash(&memory->savedata, gba->realisticTiming); } else { GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame"); GBASavedataInitSRAM(&memory->savedata);
M src/gba/savedata.csrc/gba/savedata.c

@@ -14,6 +14,8 @@

#include <errno.h> #include <fcntl.h> +#define FLASH_SETTLE_CYCLES 18000 + static void _flashSwitchBank(struct GBASavedata* savedata, int bank); static void _flashErase(struct GBASavedata* savedata); static void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart);

@@ -113,7 +115,7 @@ }

return true; } -void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) { +void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type, bool realisticTiming) { if (savedata->type != SAVEDATA_AUTODETECT) { struct VFile* vf = savedata->vf; GBASavedataDeinit(savedata);

@@ -123,7 +125,7 @@ switch (type) {

case SAVEDATA_FLASH512: case SAVEDATA_FLASH1M: savedata->type = type; - GBASavedataInitFlash(savedata); + GBASavedataInitFlash(savedata, realisticTiming); break; case SAVEDATA_EEPROM: GBASavedataInitEEPROM(savedata);

@@ -139,7 +141,7 @@ break;

} } -void GBASavedataInitFlash(struct GBASavedata* savedata) { +void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming) { if (savedata->type == SAVEDATA_AUTODETECT) { savedata->type = SAVEDATA_FLASH512; }

@@ -162,6 +164,8 @@ savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_FLASH1M, savedata->mapMode);

} savedata->currentBank = savedata->data; + savedata->dust = 0; + savedata->realisticTiming = realisticTiming; if (end < SIZE_CART_FLASH512) { memset(&savedata->data[end], 0xFF, flashSize - end); }

@@ -226,6 +230,10 @@ return FLASH_MFG_SANYO >> (address * 8);

} } } + if (savedata->dust > 0 && (address >> 12) == savedata->settling) { + --savedata->dust; + return 0x5F; + } return savedata->currentBank[address]; }

@@ -384,6 +392,8 @@ state->savedata.flashBank = savedata->currentBank == &savedata->data[0x10000];

state->savedata.readBitsRemaining = savedata->readBitsRemaining; state->savedata.readAddress = savedata->readAddress; state->savedata.writeAddress = savedata->writeAddress; + state->savedata.settlingSector = savedata->settling; + state->savedata.settlingDust = savedata->dust; UNUSED(includeData); // TODO }

@@ -393,13 +403,16 @@ if (state->savedata.type == SAVEDATA_FORCE_NONE) {

return; } if (savedata->type != state->savedata.type) { - GBASavedataForceType(savedata, state->savedata.type); + GBASavedataForceType(savedata, state->savedata.type, savedata->realisticTiming); } savedata->command = state->savedata.command; savedata->flashState = state->savedata.flashState; savedata->readBitsRemaining = state->savedata.readBitsRemaining; savedata->readAddress = state->savedata.readAddress; savedata->writeAddress = state->savedata.writeAddress; + savedata->settling = state->savedata.settlingSector; + savedata->dust = state->savedata.settlingDust; + if (savedata->type == SAVEDATA_FLASH1M) { _flashSwitchBank(savedata, state->savedata.flashBank); }

@@ -433,6 +446,10 @@ GBALog(0, GBA_LOG_DEBUG, "Performing flash sector erase at 0x%04x", sectorStart);

size_t size = 0x1000; if (savedata->type == SAVEDATA_FLASH1M) { GBALog(0, GBA_LOG_DEBUG, "Performing unknown sector-size erase at 0x%04x", sectorStart); + } + savedata->settling = sectorStart >> 12; + if (savedata->realisticTiming) { + savedata->dust = FLASH_SETTLE_CYCLES; } memset(&savedata->currentBank[sectorStart & ~(size - 1)], 0xFF, size); }
M src/gba/savedata.hsrc/gba/savedata.h

@@ -73,6 +73,10 @@ uint32_t writeAddress;

uint8_t* currentBank; + bool realisticTiming; + unsigned settling; + int dust; + enum FlashStateMachine flashState; };

@@ -82,9 +86,9 @@

void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf); void GBASavedataUnmask(struct GBASavedata* savedata); bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out); -void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type); +void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type, bool realisticTiming); -void GBASavedataInitFlash(struct GBASavedata* savedata); +void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming); void GBASavedataInitEEPROM(struct GBASavedata* savedata); void GBASavedataInitSRAM(struct GBASavedata* savedata);
M src/gba/serialize.hsrc/gba/serialize.h

@@ -162,8 +162,9 @@ * | bits 5 - 7: Reserved

* | 0x002E3 - 0x002E3: Reserved * | 0x002E4 - 0x002E7: EEPROM read bits remaining * | 0x002E8 - 0x002EB: EEPROM read address - * | 0x002EC - 0x002EBF EEPROM write address - * 0x002F0 - 0x002F3: Reserved (leave zero) + * | 0x002EC - 0x002EF: EEPROM write address + * | 0x002F0 - 0x002F1: Flash settling sector + * | 0x002F2 - 0x002F3: Flash settling remaining * 0x002F4 - 0x002FF: Prefetch * | 0x002F4 - 0x002F7: GBA BIOS bus prefetch * | 0x002F8 - 0x002FB: CPU prefecth (decode slot)

@@ -297,9 +298,9 @@ unsigned : 8;

int32_t readBitsRemaining; uint32_t readAddress; uint32_t writeAddress; + uint16_t settlingSector; + uint16_t settlingDust; } savedata; - - uint32_t reservedPadding; uint32_t biosPrefetch; uint32_t cpuPrefetch[2];
M src/gba/supervisor/overrides.csrc/gba/supervisor/overrides.c

@@ -249,7 +249,7 @@ }

void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* override) { if (override->savetype != SAVEDATA_AUTODETECT) { - GBASavedataForceType(&gba->memory.savedata, override->savetype); + GBASavedataForceType(&gba->memory.savedata, override->savetype, gba->realisticTiming); } if (override->hardware != HW_NO_OVERRIDE) {