mirror of https://github.com/mgba-emu/mgba.git
GBA Savedata: Add realistic timing for EEPROM
This commit is contained in:
parent
ac11542226
commit
b1618cbed3
1
CHANGES
1
CHANGES
|
@ -54,6 +54,7 @@ Misc:
|
||||||
- GBA Video: Optimize sprite drawing
|
- GBA Video: Optimize sprite drawing
|
||||||
- GBA BIOS: Use custom ArcTan, not relying on OS
|
- GBA BIOS: Use custom ArcTan, not relying on OS
|
||||||
- PSP2: Sync files per descriptor
|
- PSP2: Sync files per descriptor
|
||||||
|
- GBA Savedata: Add realistic timing for EEPROM
|
||||||
|
|
||||||
0.4.1: (2016-07-11)
|
0.4.1: (2016-07-11)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -811,7 +811,7 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
|
||||||
case REGION_CART2_EX:
|
case REGION_CART2_EX:
|
||||||
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
|
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
|
||||||
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
|
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
|
||||||
GBASavedataInitEEPROM(&memory->savedata);
|
GBASavedataInitEEPROM(&memory->savedata, gba->realisticTiming);
|
||||||
}
|
}
|
||||||
GBASavedataWriteEEPROM(&memory->savedata, value, 1);
|
GBASavedataWriteEEPROM(&memory->savedata, value, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -1690,7 +1690,7 @@ void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info) {
|
||||||
} else if (destRegion == REGION_CART2_EX) {
|
} else if (destRegion == REGION_CART2_EX) {
|
||||||
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
|
if (memory->savedata.type == SAVEDATA_AUTODETECT) {
|
||||||
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
|
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
|
||||||
GBASavedataInitEEPROM(&memory->savedata);
|
GBASavedataInitEEPROM(&memory->savedata, gba->realisticTiming);
|
||||||
}
|
}
|
||||||
word = cpu->memory.load16(cpu, source, 0);
|
word = cpu->memory.load16(cpu, source, 0);
|
||||||
gba->bus = word | (word << 16);
|
gba->bus = word | (word << 16);
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
// Other games vary from very little, with a fairly solid 20500 cycle count. (Observed on a SST (D4BF) chip).
|
// Other games vary from very little, with a fairly solid 20500 cycle count. (Observed on a SST (D4BF) chip).
|
||||||
// An average estimation is as follows.
|
// An average estimation is as follows.
|
||||||
#define FLASH_SETTLE_CYCLES 18000
|
#define FLASH_SETTLE_CYCLES 18000
|
||||||
|
// This needs real testing, and is only an estimation currently
|
||||||
|
#define EEPROM_SETTLE_CYCLES 14500
|
||||||
#define CLEANUP_THRESHOLD 15
|
#define CLEANUP_THRESHOLD 15
|
||||||
|
|
||||||
mLOG_DEFINE_CATEGORY(GBA_SAVE, "GBA Savedata");
|
mLOG_DEFINE_CATEGORY(GBA_SAVE, "GBA Savedata");
|
||||||
|
@ -201,7 +203,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type,
|
||||||
GBASavedataInitFlash(savedata, realisticTiming);
|
GBASavedataInitFlash(savedata, realisticTiming);
|
||||||
break;
|
break;
|
||||||
case SAVEDATA_EEPROM:
|
case SAVEDATA_EEPROM:
|
||||||
GBASavedataInitEEPROM(savedata);
|
GBASavedataInitEEPROM(savedata, realisticTiming);
|
||||||
break;
|
break;
|
||||||
case SAVEDATA_SRAM:
|
case SAVEDATA_SRAM:
|
||||||
GBASavedataInitSRAM(savedata);
|
GBASavedataInitSRAM(savedata);
|
||||||
|
@ -247,7 +249,7 @@ void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
|
void GBASavedataInitEEPROM(struct GBASavedata* savedata, bool realisticTiming) {
|
||||||
if (savedata->type == SAVEDATA_AUTODETECT) {
|
if (savedata->type == SAVEDATA_AUTODETECT) {
|
||||||
savedata->type = SAVEDATA_EEPROM;
|
savedata->type = SAVEDATA_EEPROM;
|
||||||
} else {
|
} else {
|
||||||
|
@ -265,6 +267,8 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
|
||||||
}
|
}
|
||||||
savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, savedata->mapMode);
|
savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, savedata->mapMode);
|
||||||
}
|
}
|
||||||
|
savedata->dust = 0;
|
||||||
|
savedata->realisticTiming = realisticTiming;
|
||||||
if (end < SIZE_CART_EEPROM) {
|
if (end < SIZE_CART_EEPROM) {
|
||||||
memset(&savedata->data[end], 0xFF, SIZE_CART_EEPROM - end);
|
memset(&savedata->data[end], 0xFF, SIZE_CART_EEPROM - end);
|
||||||
}
|
}
|
||||||
|
@ -430,6 +434,9 @@ void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value, uint32
|
||||||
current |= (value & 0x1) << (0x7 - (savedata->writeAddress & 0x7));
|
current |= (value & 0x1) << (0x7 - (savedata->writeAddress & 0x7));
|
||||||
savedata->dirty |= SAVEDATA_DIRT_NEW;
|
savedata->dirty |= SAVEDATA_DIRT_NEW;
|
||||||
savedata->data[savedata->writeAddress >> 3] = current;
|
savedata->data[savedata->writeAddress >> 3] = current;
|
||||||
|
if (savedata->realisticTiming) {
|
||||||
|
savedata->dust = EEPROM_SETTLE_CYCLES;
|
||||||
|
}
|
||||||
++savedata->writeAddress;
|
++savedata->writeAddress;
|
||||||
} else {
|
} else {
|
||||||
mLOG(GBA_SAVE, GAME_ERROR, "Writing beyond end of EEPROM: %08X", (savedata->writeAddress >> 3));
|
mLOG(GBA_SAVE, GAME_ERROR, "Writing beyond end of EEPROM: %08X", (savedata->writeAddress >> 3));
|
||||||
|
@ -452,7 +459,14 @@ void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value, uint32
|
||||||
|
|
||||||
uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata) {
|
uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata) {
|
||||||
if (savedata->command != EEPROM_COMMAND_READ) {
|
if (savedata->command != EEPROM_COMMAND_READ) {
|
||||||
|
if (!savedata->realisticTiming || savedata->dust <= 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
// Give some overhead for waitstates and the comparison
|
||||||
|
// This estimation can probably be improved
|
||||||
|
savedata->dust -= 10;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
--savedata->readBitsRemaining;
|
--savedata->readBitsRemaining;
|
||||||
if (savedata->readBitsRemaining < 64) {
|
if (savedata->readBitsRemaining < 64) {
|
||||||
|
|
|
@ -103,7 +103,7 @@ bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in);
|
||||||
void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type, bool realisticTiming);
|
void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type, bool realisticTiming);
|
||||||
|
|
||||||
void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming);
|
void GBASavedataInitFlash(struct GBASavedata* savedata, bool realisticTiming);
|
||||||
void GBASavedataInitEEPROM(struct GBASavedata* savedata);
|
void GBASavedataInitEEPROM(struct GBASavedata* savedata, bool realisticTiming);
|
||||||
void GBASavedataInitSRAM(struct GBASavedata* savedata);
|
void GBASavedataInitSRAM(struct GBASavedata* savedata);
|
||||||
|
|
||||||
uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address);
|
uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address);
|
||||||
|
|
Loading…
Reference in New Issue