GBA: Add somewhat more realistic flash timings, disabled currently

This commit is contained in:
Jeffrey Pfau 2015-03-28 03:25:46 -07:00
parent c665ed78e6
commit e93240f90c
7 changed files with 39 additions and 12 deletions

View File

@ -89,6 +89,9 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
gba->lastJump = 0; gba->lastJump = 0;
gba->idleDetectionStep = 0; gba->idleDetectionStep = 0;
gba->idleDetectionFailures = 0; gba->idleDetectionFailures = 0;
gba->realisticTiming = false;
gba->performingDMA = false; gba->performingDMA = false;
} }

View File

@ -161,6 +161,8 @@ struct GBA {
int idleDetectionFailures; int idleDetectionFailures;
int32_t cachedRegisters[16]; int32_t cachedRegisters[16];
bool taintedRegisters[16]; bool taintedRegisters[16];
bool realisticTiming;
}; };
struct GBACartridge { struct GBACartridge {

View File

@ -778,7 +778,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
if (memory->savedata.type == SAVEDATA_AUTODETECT) { if (memory->savedata.type == SAVEDATA_AUTODETECT) {
if (address == SAVEDATA_FLASH_BASE) { if (address == SAVEDATA_FLASH_BASE) {
GBALog(gba, GBA_LOG_INFO, "Detected Flash savegame"); GBALog(gba, GBA_LOG_INFO, "Detected Flash savegame");
GBASavedataInitFlash(&memory->savedata); GBASavedataInitFlash(&memory->savedata, gba->realisticTiming);
} else { } else {
GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame"); GBALog(gba, GBA_LOG_INFO, "Detected SRAM savegame");
GBASavedataInitSRAM(&memory->savedata); GBASavedataInitSRAM(&memory->savedata);

View File

@ -14,6 +14,8 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#define FLASH_SETTLE_CYCLES 18000
static void _flashSwitchBank(struct GBASavedata* savedata, int bank); static void _flashSwitchBank(struct GBASavedata* savedata, int bank);
static void _flashErase(struct GBASavedata* savedata); static void _flashErase(struct GBASavedata* savedata);
static void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart); static void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart);
@ -113,7 +115,7 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
return true; 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) { if (savedata->type != SAVEDATA_AUTODETECT) {
struct VFile* vf = savedata->vf; struct VFile* vf = savedata->vf;
GBASavedataDeinit(savedata); GBASavedataDeinit(savedata);
@ -123,7 +125,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type)
case SAVEDATA_FLASH512: case SAVEDATA_FLASH512:
case SAVEDATA_FLASH1M: case SAVEDATA_FLASH1M:
savedata->type = type; savedata->type = type;
GBASavedataInitFlash(savedata); GBASavedataInitFlash(savedata, realisticTiming);
break; break;
case SAVEDATA_EEPROM: case SAVEDATA_EEPROM:
GBASavedataInitEEPROM(savedata); GBASavedataInitEEPROM(savedata);
@ -139,7 +141,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type)
} }
} }
void GBASavedataInitFlash(struct GBASavedata* savedata) { void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_FLASH512; savedata->type = SAVEDATA_FLASH512;
} }
@ -162,6 +164,8 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) {
} }
savedata->currentBank = savedata->data; savedata->currentBank = savedata->data;
savedata->dust = 0;
savedata->realisticTiming = realisticTiming;
if (end < SIZE_CART_FLASH512) { if (end < SIZE_CART_FLASH512) {
memset(&savedata->data[end], 0xFF, flashSize - end); memset(&savedata->data[end], 0xFF, flashSize - end);
} }
@ -226,6 +230,10 @@ uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address) {
} }
} }
} }
if (savedata->dust > 0 && (address >> 12) == savedata->settling) {
--savedata->dust;
return 0x5F;
}
return savedata->currentBank[address]; return savedata->currentBank[address];
} }
@ -384,6 +392,8 @@ void GBASavedataSerialize(const struct GBASavedata* savedata, struct GBASerializ
state->savedata.readBitsRemaining = savedata->readBitsRemaining; state->savedata.readBitsRemaining = savedata->readBitsRemaining;
state->savedata.readAddress = savedata->readAddress; state->savedata.readAddress = savedata->readAddress;
state->savedata.writeAddress = savedata->writeAddress; state->savedata.writeAddress = savedata->writeAddress;
state->savedata.settlingSector = savedata->settling;
state->savedata.settlingDust = savedata->dust;
UNUSED(includeData); // TODO UNUSED(includeData); // TODO
} }
@ -393,13 +403,16 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial
return; return;
} }
if (savedata->type != state->savedata.type) { if (savedata->type != state->savedata.type) {
GBASavedataForceType(savedata, state->savedata.type); GBASavedataForceType(savedata, state->savedata.type, savedata->realisticTiming);
} }
savedata->command = state->savedata.command; savedata->command = state->savedata.command;
savedata->flashState = state->savedata.flashState; savedata->flashState = state->savedata.flashState;
savedata->readBitsRemaining = state->savedata.readBitsRemaining; savedata->readBitsRemaining = state->savedata.readBitsRemaining;
savedata->readAddress = state->savedata.readAddress; savedata->readAddress = state->savedata.readAddress;
savedata->writeAddress = state->savedata.writeAddress; savedata->writeAddress = state->savedata.writeAddress;
savedata->settling = state->savedata.settlingSector;
savedata->dust = state->savedata.settlingDust;
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == SAVEDATA_FLASH1M) {
_flashSwitchBank(savedata, state->savedata.flashBank); _flashSwitchBank(savedata, state->savedata.flashBank);
} }
@ -434,5 +447,9 @@ void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart) {
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == SAVEDATA_FLASH1M) {
GBALog(0, GBA_LOG_DEBUG, "Performing unknown sector-size erase at 0x%04x", sectorStart); 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); memset(&savedata->currentBank[sectorStart & ~(size - 1)], 0xFF, size);
} }

View File

@ -73,6 +73,10 @@ struct GBASavedata {
uint8_t* currentBank; uint8_t* currentBank;
bool realisticTiming;
unsigned settling;
int dust;
enum FlashStateMachine flashState; enum FlashStateMachine flashState;
}; };
@ -82,9 +86,9 @@ void GBASavedataDeinit(struct GBASavedata* savedata);
void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf); void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf);
void GBASavedataUnmask(struct GBASavedata* savedata); void GBASavedataUnmask(struct GBASavedata* savedata);
bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out); 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 GBASavedataInitEEPROM(struct GBASavedata* savedata);
void GBASavedataInitSRAM(struct GBASavedata* savedata); void GBASavedataInitSRAM(struct GBASavedata* savedata);

View File

@ -162,8 +162,9 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
* | 0x002E3 - 0x002E3: Reserved * | 0x002E3 - 0x002E3: Reserved
* | 0x002E4 - 0x002E7: EEPROM read bits remaining * | 0x002E4 - 0x002E7: EEPROM read bits remaining
* | 0x002E8 - 0x002EB: EEPROM read address * | 0x002E8 - 0x002EB: EEPROM read address
* | 0x002EC - 0x002EBF EEPROM write address * | 0x002EC - 0x002EF: EEPROM write address
* 0x002F0 - 0x002F3: Reserved (leave zero) * | 0x002F0 - 0x002F1: Flash settling sector
* | 0x002F2 - 0x002F3: Flash settling remaining
* 0x002F4 - 0x002FF: Prefetch * 0x002F4 - 0x002FF: Prefetch
* | 0x002F4 - 0x002F7: GBA BIOS bus prefetch * | 0x002F4 - 0x002F7: GBA BIOS bus prefetch
* | 0x002F8 - 0x002FB: CPU prefecth (decode slot) * | 0x002F8 - 0x002FB: CPU prefecth (decode slot)
@ -297,10 +298,10 @@ struct GBASerializedState {
int32_t readBitsRemaining; int32_t readBitsRemaining;
uint32_t readAddress; uint32_t readAddress;
uint32_t writeAddress; uint32_t writeAddress;
uint16_t settlingSector;
uint16_t settlingDust;
} savedata; } savedata;
uint32_t reservedPadding;
uint32_t biosPrefetch; uint32_t biosPrefetch;
uint32_t cpuPrefetch[2]; uint32_t cpuPrefetch[2];

View File

@ -249,7 +249,7 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver
void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* override) { void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* override) {
if (override->savetype != SAVEDATA_AUTODETECT) { 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) { if (override->hardware != HW_NO_OVERRIDE) {