mirror of https://github.com/mgba-emu/mgba.git
GBA: Add somewhat more realistic flash timings, disabled currently
This commit is contained in:
parent
c665ed78e6
commit
e93240f90c
|
@ -89,6 +89,9 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) {
|
|||
gba->lastJump = 0;
|
||||
gba->idleDetectionStep = 0;
|
||||
gba->idleDetectionFailures = 0;
|
||||
|
||||
gba->realisticTiming = false;
|
||||
|
||||
gba->performingDMA = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,8 @@ struct GBA {
|
|||
int idleDetectionFailures;
|
||||
int32_t cachedRegisters[16];
|
||||
bool taintedRegisters[16];
|
||||
|
||||
bool realisticTiming;
|
||||
};
|
||||
|
||||
struct GBACartridge {
|
||||
|
|
|
@ -778,7 +778,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
|
|||
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);
|
||||
|
|
|
@ -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 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
|
|||
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 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType 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 @@ 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) {
|
||||
savedata->type = SAVEDATA_FLASH512;
|
||||
}
|
||||
|
@ -162,6 +164,8 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) {
|
|||
}
|
||||
|
||||
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 @@ 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];
|
||||
}
|
||||
|
||||
|
@ -384,6 +392,8 @@ void GBASavedataSerialize(const struct GBASavedata* savedata, struct GBASerializ
|
|||
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 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial
|
|||
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);
|
||||
}
|
||||
|
@ -434,5 +447,9 @@ void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart) {
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,10 @@ struct GBASavedata {
|
|||
|
||||
uint8_t* currentBank;
|
||||
|
||||
bool realisticTiming;
|
||||
unsigned settling;
|
||||
int dust;
|
||||
|
||||
enum FlashStateMachine flashState;
|
||||
};
|
||||
|
||||
|
@ -82,9 +86,9 @@ void GBASavedataDeinit(struct GBASavedata* savedata);
|
|||
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);
|
||||
|
||||
|
|
|
@ -162,8 +162,9 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
|
|||
* | 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,10 +298,10 @@ struct GBASerializedState {
|
|||
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];
|
||||
|
||||
|
|
|
@ -249,7 +249,7 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver
|
|||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue