GBA Savedata: Prefix SavedataType constants and type name

This commit is contained in:
Vicki Pfau 2024-03-24 22:57:51 -07:00
parent 6940b424df
commit ea5339304a
13 changed files with 270 additions and 270 deletions

View File

@ -16,7 +16,7 @@ CXX_GUARD_START
struct GBACartridgeOverride { struct GBACartridgeOverride {
char id[4]; char id[4];
enum SavedataType savetype; enum GBASavedataType savetype;
int hardware; int hardware;
uint32_t idleLoop; uint32_t idleLoop;
bool mirroring; bool mirroring;

View File

@ -17,15 +17,15 @@ mLOG_DECLARE_CATEGORY(GBA_SAVE);
struct VFile; struct VFile;
enum SavedataType { enum GBASavedataType {
SAVEDATA_AUTODETECT = -1, GBA_SAVEDATA_AUTODETECT = -1,
SAVEDATA_FORCE_NONE = 0, GBA_SAVEDATA_FORCE_NONE = 0,
SAVEDATA_SRAM = 1, GBA_SAVEDATA_SRAM = 1,
SAVEDATA_FLASH512 = 2, GBA_SAVEDATA_FLASH512 = 2,
SAVEDATA_FLASH1M = 3, GBA_SAVEDATA_FLASH1M = 3,
SAVEDATA_EEPROM = 4, GBA_SAVEDATA_EEPROM = 4,
SAVEDATA_EEPROM512 = 5, GBA_SAVEDATA_EEPROM512 = 5,
SAVEDATA_SRAM512 = 6, GBA_SAVEDATA_SRAM512 = 6,
}; };
enum SavedataCommand { enum SavedataCommand {
@ -68,7 +68,7 @@ enum {
}; };
struct GBASavedata { struct GBASavedata {
enum SavedataType type; enum GBASavedataType type;
uint8_t* data; uint8_t* data;
enum SavedataCommand command; enum SavedataCommand command;
struct VFile* vf; struct VFile* vf;
@ -108,7 +108,7 @@ void GBASavedataUnmask(struct GBASavedata* savedata);
size_t GBASavedataSize(const struct GBASavedata* savedata); size_t GBASavedataSize(const struct GBASavedata* savedata);
bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out); bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out);
bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in); bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in);
void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type); void GBASavedataForceType(struct GBASavedata* savedata, enum GBASavedataType type);
void GBASavedataInitFlash(struct GBASavedata* savedata); void GBASavedataInitFlash(struct GBASavedata* savedata);
void GBASavedataInitEEPROM(struct GBASavedata* savedata); void GBASavedataInitEEPROM(struct GBASavedata* savedata);

View File

@ -1004,27 +1004,27 @@ size_t _GBACoreListMemoryBlocks(const struct mCore* core, const struct mCoreMemo
if (gbacore->memoryBlockType != gba->memory.savedata.type) { if (gbacore->memoryBlockType != gba->memory.savedata.type) {
switch (gba->memory.savedata.type) { switch (gba->memory.savedata.type) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM, sizeof(_GBAMemoryBlocksSRAM)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM, sizeof(_GBAMemoryBlocksSRAM));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM) / sizeof(*_GBAMemoryBlocksSRAM);
break; break;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM512, sizeof(_GBAMemoryBlocksSRAM512)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksSRAM512, sizeof(_GBAMemoryBlocksSRAM512));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM512) / sizeof(*_GBAMemoryBlocksSRAM512); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksSRAM512) / sizeof(*_GBAMemoryBlocksSRAM512);
break; break;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash512, sizeof(_GBAMemoryBlocksFlash512)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash512, sizeof(_GBAMemoryBlocksFlash512));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash512) / sizeof(*_GBAMemoryBlocksFlash512);
break; break;
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash1M, sizeof(_GBAMemoryBlocksFlash1M)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksFlash1M, sizeof(_GBAMemoryBlocksFlash1M));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksFlash1M) / sizeof(*_GBAMemoryBlocksFlash1M);
break; break;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM, sizeof(_GBAMemoryBlocksEEPROM)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM, sizeof(_GBAMemoryBlocksEEPROM));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM) / sizeof(*_GBAMemoryBlocksEEPROM);
break; break;
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM512, sizeof(_GBAMemoryBlocksEEPROM512)); memcpy(gbacore->memoryBlocks, _GBAMemoryBlocksEEPROM512, sizeof(_GBAMemoryBlocksEEPROM512));
gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM512) / sizeof(*_GBAMemoryBlocksEEPROM512); gbacore->nMemoryBlocks = sizeof(_GBAMemoryBlocksEEPROM512) / sizeof(*_GBAMemoryBlocksEEPROM512);
break; break;
@ -1076,7 +1076,7 @@ void* _GBACoreGetMemoryBlock(struct mCore* core, size_t id, size_t* sizeOut) {
*sizeOut = gba->memory.romSize; *sizeOut = gba->memory.romSize;
return gba->memory.rom; return gba->memory.rom;
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
if (gba->memory.savedata.type == SAVEDATA_FLASH1M) { if (gba->memory.savedata.type == GBA_SAVEDATA_FLASH1M) {
*sizeOut = GBA_SIZE_FLASH1M; *sizeOut = GBA_SIZE_FLASH1M;
return gba->memory.savedata.currentBank; return gba->memory.savedata.currentBank;
} }

View File

@ -274,7 +274,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
} }
cpu->memory.store32(cpu, dest, memory->dmaTransferRegister, 0); cpu->memory.store32(cpu, dest, memory->dmaTransferRegister, 0);
} else { } else {
if (sourceRegion == GBA_REGION_ROM2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) { if (sourceRegion == GBA_REGION_ROM2_EX && (memory->savedata.type == GBA_SAVEDATA_EEPROM || memory->savedata.type == GBA_SAVEDATA_EEPROM512)) {
memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata);
memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; memory->dmaTransferRegister |= memory->dmaTransferRegister << 16;
} else if (source) { } else if (source) {
@ -282,11 +282,11 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; memory->dmaTransferRegister |= memory->dmaTransferRegister << 16;
} }
if (destRegion == GBA_REGION_ROM2_EX) { if (destRegion == GBA_REGION_ROM2_EX) {
if (memory->savedata.type == SAVEDATA_AUTODETECT) { if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) {
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
GBASavedataInitEEPROM(&memory->savedata); GBASavedataInitEEPROM(&memory->savedata);
} }
if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { if (memory->savedata.type == GBA_SAVEDATA_EEPROM512 || memory->savedata.type == GBA_SAVEDATA_EEPROM) {
GBASavedataWriteEEPROM(&memory->savedata, memory->dmaTransferRegister, info->nextCount); GBASavedataWriteEEPROM(&memory->savedata, memory->dmaTransferRegister, info->nextCount);
} }
} else { } else {

View File

@ -469,10 +469,10 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) {
} }
bool GBALoadSave(struct GBA* gba, struct VFile* sav) { bool GBALoadSave(struct GBA* gba, struct VFile* sav) {
enum SavedataType type = gba->memory.savedata.type; enum GBASavedataType type = gba->memory.savedata.type;
GBASavedataDeinit(&gba->memory.savedata); GBASavedataDeinit(&gba->memory.savedata);
GBASavedataInit(&gba->memory.savedata, sav); GBASavedataInit(&gba->memory.savedata, sav);
if (type != SAVEDATA_AUTODETECT) { if (type != GBA_SAVEDATA_AUTODETECT) {
GBASavedataForceType(&gba->memory.savedata, type); GBASavedataForceType(&gba->memory.savedata, type);
} }
return sav; return sav;

View File

@ -595,7 +595,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
break; break;
case GBA_REGION_ROM2_EX: case GBA_REGION_ROM2_EX:
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) { if (memory->savedata.type == GBA_SAVEDATA_EEPROM || memory->savedata.type == GBA_SAVEDATA_EEPROM512) {
value = GBASavedataReadEEPROM(&memory->savedata); value = GBASavedataReadEEPROM(&memory->savedata);
} else if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) { } else if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
value = GBACartEReaderRead(&memory->ereader, address); value = GBACartEReaderRead(&memory->ereader, address);
@ -702,7 +702,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
case GBA_REGION_SRAM_MIRROR: case GBA_REGION_SRAM_MIRROR:
wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; wait = memory->waitstatesNonseq16[address >> BASE_OFFSET];
if (memory->savedata.type == SAVEDATA_AUTODETECT) { if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) {
mLOG(GBA_MEM, INFO, "Detected SRAM savegame"); mLOG(GBA_MEM, INFO, "Detected SRAM savegame");
GBASavedataInitSRAM(&memory->savedata); GBASavedataInitSRAM(&memory->savedata);
} }
@ -711,13 +711,13 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
} }
if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) { if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
value = GBACartEReaderReadFlash(&memory->ereader, address); value = GBACartEReaderReadFlash(&memory->ereader, address);
} else if (memory->savedata.type == SAVEDATA_SRAM) { } else if (memory->savedata.type == GBA_SAVEDATA_SRAM) {
value = memory->savedata.data[address & (GBA_SIZE_SRAM - 1)]; value = memory->savedata.data[address & (GBA_SIZE_SRAM - 1)];
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) { } else if (memory->savedata.type == GBA_SAVEDATA_FLASH512 || memory->savedata.type == GBA_SAVEDATA_FLASH1M) {
value = GBASavedataReadFlash(&memory->savedata, address); value = GBASavedataReadFlash(&memory->savedata, address);
} else if (memory->hw.devices & HW_TILT) { } else if (memory->hw.devices & HW_TILT) {
value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK); value = GBAHardwareTiltRead(&memory->hw, address & OFFSET_MASK);
} else if (memory->savedata.type == SAVEDATA_SRAM512) { } else if (memory->savedata.type == GBA_SAVEDATA_SRAM512) {
value = memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)]; value = memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)];
} else { } else {
mLOG(GBA_MEM, GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address); mLOG(GBA_MEM, GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
@ -975,11 +975,11 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle
if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) { if ((address & 0x0DFC0000) >= 0x0DF80000 && memory->hw.devices & HW_EREADER) {
GBACartEReaderWrite(&memory->ereader, address, value); GBACartEReaderWrite(&memory->ereader, address, value);
break; break;
} else if (memory->savedata.type == SAVEDATA_AUTODETECT) { } else if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) {
mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); mLOG(GBA_MEM, INFO, "Detected EEPROM savegame");
GBASavedataInitEEPROM(&memory->savedata); GBASavedataInitEEPROM(&memory->savedata);
} }
if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { if (memory->savedata.type == GBA_SAVEDATA_EEPROM512 || memory->savedata.type == GBA_SAVEDATA_EEPROM) {
GBASavedataWriteEEPROM(&memory->savedata, value, 1); GBASavedataWriteEEPROM(&memory->savedata, value, 1);
break; break;
} }
@ -1050,7 +1050,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
break; break;
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
case GBA_REGION_SRAM_MIRROR: case GBA_REGION_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_AUTODETECT) { if (memory->savedata.type == GBA_SAVEDATA_AUTODETECT) {
if (address == SAVEDATA_FLASH_BASE) { if (address == SAVEDATA_FLASH_BASE) {
mLOG(GBA_MEM, INFO, "Detected Flash savegame"); mLOG(GBA_MEM, INFO, "Detected Flash savegame");
GBASavedataInitFlash(&memory->savedata); GBASavedataInitFlash(&memory->savedata);
@ -1061,9 +1061,9 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
} }
if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) { if (memory->hw.devices & HW_EREADER && (address & 0xE00FF80) >= 0xE00FF80) {
GBACartEReaderWriteFlash(&memory->ereader, address, value); GBACartEReaderWriteFlash(&memory->ereader, address, value);
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) { } else if (memory->savedata.type == GBA_SAVEDATA_FLASH512 || memory->savedata.type == GBA_SAVEDATA_FLASH1M) {
GBASavedataWriteFlash(&memory->savedata, address, value); GBASavedataWriteFlash(&memory->savedata, address, value);
} else if (memory->savedata.type == SAVEDATA_SRAM) { } else if (memory->savedata.type == GBA_SAVEDATA_SRAM) {
if (memory->vfame.cartType) { if (memory->vfame.cartType) {
GBAVFameSramWrite(&memory->vfame, address, value, memory->savedata.data); GBAVFameSramWrite(&memory->vfame, address, value, memory->savedata.data);
} else { } else {
@ -1072,7 +1072,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
memory->savedata.dirty |= mSAVEDATA_DIRT_NEW; memory->savedata.dirty |= mSAVEDATA_DIRT_NEW;
} else if (memory->hw.devices & HW_TILT) { } else if (memory->hw.devices & HW_TILT) {
GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value); GBAHardwareTiltWrite(&memory->hw, address & OFFSET_MASK, value);
} else if (memory->savedata.type == SAVEDATA_SRAM512) { } else if (memory->savedata.type == GBA_SAVEDATA_SRAM512) {
memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)] = value; memory->savedata.data[address & (GBA_SIZE_SRAM512 - 1)] = value;
memory->savedata.dirty |= mSAVEDATA_DIRT_NEW; memory->savedata.dirty |= mSAVEDATA_DIRT_NEW;
} else { } else {
@ -1263,7 +1263,7 @@ void GBAPatch32(struct ARMCore* cpu, uint32_t address, int32_t value, int32_t* o
break; break;
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
case GBA_REGION_SRAM_MIRROR: case GBA_REGION_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) { if (memory->savedata.type == GBA_SAVEDATA_SRAM) {
LOAD_32(oldValue, address & (GBA_SIZE_SRAM - 4), memory->savedata.data); LOAD_32(oldValue, address & (GBA_SIZE_SRAM - 4), memory->savedata.data);
STORE_32(value, address & (GBA_SIZE_SRAM - 4), memory->savedata.data); STORE_32(value, address & (GBA_SIZE_SRAM - 4), memory->savedata.data);
} else { } else {
@ -1333,7 +1333,7 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o
break; break;
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
case GBA_REGION_SRAM_MIRROR: case GBA_REGION_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) { if (memory->savedata.type == GBA_SAVEDATA_SRAM) {
LOAD_16(oldValue, address & (GBA_SIZE_SRAM - 2), memory->savedata.data); LOAD_16(oldValue, address & (GBA_SIZE_SRAM - 2), memory->savedata.data);
STORE_16(value, address & (GBA_SIZE_SRAM - 2), memory->savedata.data); STORE_16(value, address & (GBA_SIZE_SRAM - 2), memory->savedata.data);
} else { } else {
@ -1391,7 +1391,7 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old)
break; break;
case GBA_REGION_SRAM: case GBA_REGION_SRAM:
case GBA_REGION_SRAM_MIRROR: case GBA_REGION_SRAM_MIRROR:
if (memory->savedata.type == SAVEDATA_SRAM) { if (memory->savedata.type == GBA_SAVEDATA_SRAM) {
oldValue = ((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)]; oldValue = ((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)];
((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)] = value; ((int8_t*) memory->savedata.data)[address & (GBA_SIZE_SRAM - 1)] = value;
} else { } else {

View File

@ -13,210 +13,210 @@
static const struct GBACartridgeOverride _overrides[] = { static const struct GBACartridgeOverride _overrides[] = {
// Advance Wars // Advance Wars
{ "AWRE", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, { "AWRE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false },
{ "AWRP", SAVEDATA_FLASH512, HW_NONE, 0x8038810, false }, { "AWRP", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8038810, false },
// Advance Wars 2: Black Hole Rising // Advance Wars 2: Black Hole Rising
{ "AW2E", SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false }, { "AW2E", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8036E08, false },
{ "AW2P", SAVEDATA_FLASH512, HW_NONE, 0x803719C, false }, { "AW2P", GBA_SAVEDATA_FLASH512, HW_NONE, 0x803719C, false },
// Boktai: The Sun is in Your Hand // Boktai: The Sun is in Your Hand
{ "U3IJ", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U3IJ", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U3IE", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U3IE", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U3IP", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U3IP", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Boktai 2: Solar Boy Django // Boktai 2: Solar Boy Django
{ "U32J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U32J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U32E", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U32E", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
{ "U32P", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U32P", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Crash Bandicoot 2 - N-Tranced // Crash Bandicoot 2 - N-Tranced
{ "AC8J", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "AC8J", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "AC8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "AC8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "AC8P", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "AC8P", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// DigiCommunication Nyo - Datou! Black Gemagema Dan // DigiCommunication Nyo - Datou! Black Gemagema Dan
{ "BDKJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "BDKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Dragon Ball Z - The Legacy of Goku // Dragon Ball Z - The Legacy of Goku
{ "ALGP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALGP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Dragon Ball Z - The Legacy of Goku II // Dragon Ball Z - The Legacy of Goku II
{ "ALFJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALFJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "ALFE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALFE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "ALFP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALFP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Dragon Ball Z - Taiketsu // Dragon Ball Z - Taiketsu
{ "BDBE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "BDBE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "BDBP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "BDBP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Drill Dozer // Drill Dozer
{ "V49J", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, { "V49J", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
{ "V49E", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, { "V49E", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
{ "V49P", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, { "V49P", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
// e-Reader // e-Reader
{ "PEAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, { "PEAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
{ "PSAJ", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, { "PSAJ", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
{ "PSAE", SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE }, { "PSAE", GBA_SAVEDATA_FLASH1M, HW_EREADER, IDLE_LOOP_NONE },
// Final Fantasy Tactics Advance // Final Fantasy Tactics Advance
{ "AFXE", SAVEDATA_FLASH512, HW_NONE, 0x8000428, false }, { "AFXE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x8000428, false },
// F-Zero - Climax // F-Zero - Climax
{ "BFTJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BFTJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Goodboy Galaxy // Goodboy Galaxy
{ "2GBP", SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false }, { "2GBP", GBA_SAVEDATA_SRAM, HW_RUMBLE, IDLE_LOOP_NONE, false },
// Iridion II // Iridion II
{ "AI2E", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "AI2E", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
{ "AI2P", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "AI2P", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
// Game Boy Wars Advance 1+2 // Game Boy Wars Advance 1+2
{ "BGWJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BGWJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Golden Sun: The Lost Age // Golden Sun: The Lost Age
{ "AGFE", SAVEDATA_FLASH512, HW_NONE, 0x801353A, false }, { "AGFE", GBA_SAVEDATA_FLASH512, HW_NONE, 0x801353A, false },
// Koro Koro Puzzle - Happy Panechu! // Koro Koro Puzzle - Happy Panechu!
{ "KHPJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, { "KHPJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
// Legendz - Yomigaeru Shiren no Shima // Legendz - Yomigaeru Shiren no Shima
{ "BLJJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, { "BLJJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
{ "BLJK", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, { "BLJK", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
// Legendz - Sign of Nekuromu // Legendz - Sign of Nekuromu
{ "BLVJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, { "BLVJ", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
// Mega Man Battle Network // Mega Man Battle Network
{ "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E, false }, { "AREE", GBA_SAVEDATA_SRAM, HW_NONE, 0x800032E, false },
// Mega Man Zero // Mega Man Zero
{ "AZCE", SAVEDATA_SRAM, HW_NONE, 0x80004E8, false }, { "AZCE", GBA_SAVEDATA_SRAM, HW_NONE, 0x80004E8, false },
// Metal Slug Advance // Metal Slug Advance
{ "BSME", SAVEDATA_EEPROM, HW_NONE, 0x8000290, false }, { "BSME", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8000290, false },
// Pokemon Ruby // Pokemon Ruby
{ "AXVJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXVF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXVF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Pokemon Sapphire // Pokemon Sapphire
{ "AXPJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPE", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPE", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPP", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPP", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPI", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPI", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPS", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPS", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPD", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPD", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
{ "AXPF", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "AXPF", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Pokemon Emerald // Pokemon Emerald
{ "BPEJ", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPEJ", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEE", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPEE", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEP", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPEP", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEI", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPEI", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPES", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPES", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPED", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPED", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
{ "BPEF", SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false }, { "BPEF", GBA_SAVEDATA_FLASH1M, HW_RTC, 0x80008C6, false },
// Pokemon Mystery Dungeon // Pokemon Mystery Dungeon
{ "B24E", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "B24E", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "B24P", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "B24P", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Pokemon FireRed // Pokemon FireRed
{ "BPRJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPRF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPRF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// Pokemon LeafGreen // Pokemon LeafGreen
{ "BPGJ", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGJ", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGE", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGE", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGP", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGP", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGI", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGI", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGS", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGS", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGD", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGD", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
{ "BPGF", SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false }, { "BPGF", GBA_SAVEDATA_FLASH1M, HW_NONE, IDLE_LOOP_NONE, false },
// RockMan EXE 4.5 - Real Operation // RockMan EXE 4.5 - Real Operation
{ "BR4J", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false }, { "BR4J", GBA_SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
// Rocky // Rocky
{ "AR8E", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "AR8E", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "AROP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "AROP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Sennen Kazoku // Sennen Kazoku
{ "BKAJ", SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false }, { "BKAJ", GBA_SAVEDATA_FLASH1M, HW_RTC, IDLE_LOOP_NONE, false },
// Shin Bokura no Taiyou: Gyakushuu no Sabata // Shin Bokura no Taiyou: Gyakushuu no Sabata
{ "U33J", SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false }, { "U33J", GBA_SAVEDATA_EEPROM, HW_RTC | HW_LIGHT_SENSOR, IDLE_LOOP_NONE, false },
// Stuart Little 2 // Stuart Little 2
{ "ASLE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "ASLE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
{ "ASLF", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "ASLF", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
// Super Mario Advance 2 // Super Mario Advance 2
{ "AA2J", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, { "AA2J", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false },
{ "AA2E", SAVEDATA_EEPROM, HW_NONE, 0x800052E, false }, { "AA2E", GBA_SAVEDATA_EEPROM, HW_NONE, 0x800052E, false },
{ "AA2P", SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false }, { "AA2P", GBA_SAVEDATA_AUTODETECT, HW_NONE, 0x800052E, false },
// Super Mario Advance 3 // Super Mario Advance 3
{ "A3AJ", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, { "A3AJ", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
{ "A3AE", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, { "A3AE", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
{ "A3AP", SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false }, { "A3AP", GBA_SAVEDATA_EEPROM, HW_NONE, 0x8002B9C, false },
// Super Mario Advance 4 // Super Mario Advance 4
{ "AX4J", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, { "AX4J", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
{ "AX4E", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, { "AX4E", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
{ "AX4P", SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false }, { "AX4P", GBA_SAVEDATA_FLASH1M, HW_NONE, 0x800072A, false },
// Super Monkey Ball Jr. // Super Monkey Ball Jr.
{ "ALUE", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALUE", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "ALUP", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "ALUP", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Top Gun - Combat Zones // Top Gun - Combat Zones
{ "A2YE", SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false }, { "A2YE", GBA_SAVEDATA_FORCE_NONE, HW_NONE, IDLE_LOOP_NONE, false },
// Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle // Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle
{ "BUHJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "BUHJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Wario Ware Twisted // Wario Ware Twisted
{ "RZWJ", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, { "RZWJ", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
{ "RZWE", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, { "RZWE", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
{ "RZWP", SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false }, { "RZWP", GBA_SAVEDATA_SRAM, HW_RUMBLE | HW_GYRO, IDLE_LOOP_NONE, false },
// Yoshi's Universal Gravitation // Yoshi's Universal Gravitation
{ "KYGJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, { "KYGJ", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
{ "KYGE", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, { "KYGE", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
{ "KYGP", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false }, { "KYGP", GBA_SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
// Aging cartridge // Aging cartridge
{ "TCHK", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "TCHK", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
// Famicom Mini series 3 (FDS), some aren't mirrored (22 - 28) // Famicom Mini series 3 (FDS), some aren't mirrored (22 - 28)
// See https://forum.no-intro.org/viewtopic.php?f=2&t=4221 for discussion // See https://forum.no-intro.org/viewtopic.php?f=2&t=4221 for discussion
{ "FNMJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FNMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FMRJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FMRJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FPTJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FPTJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FLBJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FLBJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FFMJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FFMJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FTKJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FTKJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ "FTUJ", SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false }, { "FTUJ", GBA_SAVEDATA_EEPROM, HW_NONE, IDLE_LOOP_NONE, false },
{ { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE, false } { { 0, 0, 0, 0 }, 0, 0, IDLE_LOOP_NONE, false }
}; };
bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) { bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOverride* override) {
override->savetype = SAVEDATA_AUTODETECT; override->savetype = GBA_SAVEDATA_AUTODETECT;
override->hardware = HW_NONE; override->hardware = HW_NONE;
override->idleLoop = IDLE_LOOP_NONE; override->idleLoop = IDLE_LOOP_NONE;
override->mirroring = false; override->mirroring = false;
@ -233,7 +233,7 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver
} }
if (!found && override->id[0] == 'F') { if (!found && override->id[0] == 'F') {
// Classic NES Series // Classic NES Series
override->savetype = SAVEDATA_EEPROM; override->savetype = GBA_SAVEDATA_EEPROM;
found = true; found = true;
} }
@ -247,25 +247,25 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver
if (savetype) { if (savetype) {
if (strcasecmp(savetype, "SRAM") == 0) { if (strcasecmp(savetype, "SRAM") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_SRAM; override->savetype = GBA_SAVEDATA_SRAM;
} else if (strcasecmp(savetype, "SRAM512") == 0) { } else if (strcasecmp(savetype, "SRAM512") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_SRAM512; override->savetype = GBA_SAVEDATA_SRAM512;
} else if (strcasecmp(savetype, "EEPROM") == 0) { } else if (strcasecmp(savetype, "EEPROM") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_EEPROM; override->savetype = GBA_SAVEDATA_EEPROM;
} else if (strcasecmp(savetype, "EEPROM512") == 0) { } else if (strcasecmp(savetype, "EEPROM512") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_EEPROM512; override->savetype = GBA_SAVEDATA_EEPROM512;
} else if (strcasecmp(savetype, "FLASH512") == 0) { } else if (strcasecmp(savetype, "FLASH512") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_FLASH512; override->savetype = GBA_SAVEDATA_FLASH512;
} else if (strcasecmp(savetype, "FLASH1M") == 0) { } else if (strcasecmp(savetype, "FLASH1M") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_FLASH1M; override->savetype = GBA_SAVEDATA_FLASH1M;
} else if (strcasecmp(savetype, "NONE") == 0) { } else if (strcasecmp(savetype, "NONE") == 0) {
found = true; found = true;
override->savetype = SAVEDATA_FORCE_NONE; override->savetype = GBA_SAVEDATA_FORCE_NONE;
} }
} }
@ -295,28 +295,28 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver
snprintf(sectionName, sizeof(sectionName), "override.%c%c%c%c", override->id[0], override->id[1], override->id[2], override->id[3]); snprintf(sectionName, sizeof(sectionName), "override.%c%c%c%c", override->id[0], override->id[1], override->id[2], override->id[3]);
const char* savetype = 0; const char* savetype = 0;
switch (override->savetype) { switch (override->savetype) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
savetype = "SRAM"; savetype = "SRAM";
break; break;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
savetype = "SRAM512"; savetype = "SRAM512";
break; break;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
savetype = "EEPROM"; savetype = "EEPROM";
break; break;
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
savetype = "EEPROM512"; savetype = "EEPROM512";
break; break;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
savetype = "FLASH512"; savetype = "FLASH512";
break; break;
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
savetype = "FLASH1M"; savetype = "FLASH1M";
break; break;
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
savetype = "NONE"; savetype = "NONE";
break; break;
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
break; break;
} }
ConfigurationSetValue(config, sectionName, "savetype", savetype); ConfigurationSetValue(config, sectionName, "savetype", savetype);
@ -335,7 +335,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 != GBA_SAVEDATA_AUTODETECT) {
GBASavedataForceType(&gba->memory.savedata, override->savetype); GBASavedataForceType(&gba->memory.savedata, override->savetype);
} }
@ -429,7 +429,7 @@ void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overr
if (isPokemon && !isKnownPokemon) { if (isPokemon && !isKnownPokemon) {
// Enable FLASH1M and RTC on Pokémon ROM hacks // Enable FLASH1M and RTC on Pokémon ROM hacks
override.savetype = SAVEDATA_FLASH1M; override.savetype = GBA_SAVEDATA_FLASH1M;
override.hardware = HW_RTC; override.hardware = HW_RTC;
override.vbaBugCompat = true; override.vbaBugCompat = true;
GBAOverrideApply(gba, &override); GBAOverrideApply(gba, &override);

View File

@ -44,7 +44,7 @@ static void _ashesToAshes(struct mTiming* timing, void* user, uint32_t cyclesLat
} }
void GBASavedataInit(struct GBASavedata* savedata, struct VFile* vf) { void GBASavedataInit(struct GBASavedata* savedata, struct VFile* vf) {
savedata->type = SAVEDATA_AUTODETECT; savedata->type = GBA_SAVEDATA_AUTODETECT;
savedata->data = 0; savedata->data = 0;
savedata->command = EEPROM_COMMAND_NULL; savedata->command = EEPROM_COMMAND_NULL;
savedata->flashState = FLASH_STATE_RAW; savedata->flashState = FLASH_STATE_RAW;
@ -72,35 +72,35 @@ void GBASavedataDeinit(struct GBASavedata* savedata) {
savedata->vf = NULL; savedata->vf = NULL;
} else { } else {
switch (savedata->type) { switch (savedata->type) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
mappedMemoryFree(savedata->data, GBA_SIZE_SRAM); mappedMemoryFree(savedata->data, GBA_SIZE_SRAM);
break; break;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
mappedMemoryFree(savedata->data, GBA_SIZE_SRAM512); mappedMemoryFree(savedata->data, GBA_SIZE_SRAM512);
break; break;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
mappedMemoryFree(savedata->data, GBA_SIZE_FLASH512); mappedMemoryFree(savedata->data, GBA_SIZE_FLASH512);
break; break;
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
mappedMemoryFree(savedata->data, GBA_SIZE_FLASH1M); mappedMemoryFree(savedata->data, GBA_SIZE_FLASH1M);
break; break;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM); mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM);
break; break;
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM512); mappedMemoryFree(savedata->data, GBA_SIZE_EEPROM512);
break; break;
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
break; break;
} }
} }
savedata->data = 0; savedata->data = 0;
savedata->type = SAVEDATA_AUTODETECT; savedata->type = GBA_SAVEDATA_AUTODETECT;
} }
void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf, bool writeback) { void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf, bool writeback) {
enum SavedataType type = savedata->type; enum GBASavedataType type = savedata->type;
struct VFile* oldVf = savedata->vf; struct VFile* oldVf = savedata->vf;
GBASavedataDeinit(savedata); GBASavedataDeinit(savedata);
if (oldVf && oldVf != savedata->realVf) { if (oldVf && oldVf != savedata->realVf) {
@ -116,7 +116,7 @@ void GBASavedataUnmask(struct GBASavedata* savedata) {
if (!savedata->realVf || savedata->vf == savedata->realVf) { if (!savedata->realVf || savedata->vf == savedata->realVf) {
return; return;
} }
enum SavedataType type = savedata->type; enum GBASavedataType type = savedata->type;
struct VFile* vf = savedata->vf; struct VFile* vf = savedata->vf;
GBASavedataDeinit(savedata); GBASavedataDeinit(savedata);
savedata->vf = savedata->realVf; savedata->vf = savedata->realVf;
@ -132,20 +132,20 @@ void GBASavedataUnmask(struct GBASavedata* savedata) {
bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) { bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
if (savedata->data) { if (savedata->data) {
switch (savedata->type) { switch (savedata->type) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
return out->write(out, savedata->data, GBA_SIZE_SRAM) == GBA_SIZE_SRAM; return out->write(out, savedata->data, GBA_SIZE_SRAM) == GBA_SIZE_SRAM;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
return out->write(out, savedata->data, GBA_SIZE_SRAM512) == GBA_SIZE_SRAM512; return out->write(out, savedata->data, GBA_SIZE_SRAM512) == GBA_SIZE_SRAM512;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
return out->write(out, savedata->data, GBA_SIZE_FLASH512) == GBA_SIZE_FLASH512; return out->write(out, savedata->data, GBA_SIZE_FLASH512) == GBA_SIZE_FLASH512;
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
return out->write(out, savedata->data, GBA_SIZE_FLASH1M) == GBA_SIZE_FLASH1M; return out->write(out, savedata->data, GBA_SIZE_FLASH1M) == GBA_SIZE_FLASH1M;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
return out->write(out, savedata->data, GBA_SIZE_EEPROM) == GBA_SIZE_EEPROM; return out->write(out, savedata->data, GBA_SIZE_EEPROM) == GBA_SIZE_EEPROM;
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
return out->write(out, savedata->data, GBA_SIZE_EEPROM512) == GBA_SIZE_EEPROM512; return out->write(out, savedata->data, GBA_SIZE_EEPROM512) == GBA_SIZE_EEPROM512;
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
return true; return true;
} }
} else if (savedata->vf) { } else if (savedata->vf) {
@ -163,21 +163,21 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
size_t GBASavedataSize(const struct GBASavedata* savedata) { size_t GBASavedataSize(const struct GBASavedata* savedata) {
switch (savedata->type) { switch (savedata->type) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
return GBA_SIZE_SRAM; return GBA_SIZE_SRAM;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
return GBA_SIZE_SRAM512; return GBA_SIZE_SRAM512;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
return GBA_SIZE_FLASH512; return GBA_SIZE_FLASH512;
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
return GBA_SIZE_FLASH1M; return GBA_SIZE_FLASH1M;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
return GBA_SIZE_EEPROM; return GBA_SIZE_EEPROM;
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
return GBA_SIZE_EEPROM512; return GBA_SIZE_EEPROM512;
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
return 0; return 0;
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
default: default:
if (savedata->vf) { if (savedata->vf) {
return savedata->vf->size(savedata->vf); return savedata->vf->size(savedata->vf);
@ -188,7 +188,7 @@ size_t GBASavedataSize(const struct GBASavedata* savedata) {
bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) { bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) {
if (savedata->data) { if (savedata->data) {
if (!in || savedata->type == SAVEDATA_FORCE_NONE) { if (!in || savedata->type == GBA_SAVEDATA_FORCE_NONE) {
return false; return false;
} }
ssize_t size = GBASavedataSize(savedata); ssize_t size = GBASavedataSize(savedata);
@ -220,11 +220,11 @@ bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) {
return true; return true;
} }
void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) { void GBASavedataForceType(struct GBASavedata* savedata, enum GBASavedataType type) {
if (savedata->type == type) { if (savedata->type == type) {
return; return;
} }
if (savedata->type != SAVEDATA_AUTODETECT) { if (savedata->type != GBA_SAVEDATA_AUTODETECT) {
struct VFile* vf = savedata->vf; struct VFile* vf = savedata->vf;
int mapMode = savedata->mapMode; int mapMode = savedata->mapMode;
bool maskWriteback = savedata->maskWriteback; bool maskWriteback = savedata->maskWriteback;
@ -234,40 +234,40 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type)
savedata->maskWriteback = maskWriteback; savedata->maskWriteback = maskWriteback;
} }
switch (type) { switch (type) {
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
savedata->type = type; savedata->type = type;
GBASavedataInitFlash(savedata); GBASavedataInitFlash(savedata);
break; break;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
savedata->type = type; savedata->type = type;
GBASavedataInitEEPROM(savedata); GBASavedataInitEEPROM(savedata);
break; break;
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
GBASavedataInitSRAM(savedata); GBASavedataInitSRAM(savedata);
break; break;
case SAVEDATA_SRAM512: case GBA_SAVEDATA_SRAM512:
GBASavedataInitSRAM512(savedata); GBASavedataInitSRAM512(savedata);
break; break;
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
savedata->type = SAVEDATA_FORCE_NONE; savedata->type = GBA_SAVEDATA_FORCE_NONE;
break; break;
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
break; break;
} }
} }
void GBASavedataInitFlash(struct GBASavedata* savedata) { void GBASavedataInitFlash(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == GBA_SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_FLASH512; savedata->type = GBA_SAVEDATA_FLASH512;
} }
if (savedata->type != SAVEDATA_FLASH512 && savedata->type != SAVEDATA_FLASH1M) { if (savedata->type != GBA_SAVEDATA_FLASH512 && savedata->type != GBA_SAVEDATA_FLASH1M) {
mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata");
return; return;
} }
int32_t flashSize = GBA_SIZE_FLASH512; int32_t flashSize = GBA_SIZE_FLASH512;
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
flashSize = GBA_SIZE_FLASH1M; flashSize = GBA_SIZE_FLASH1M;
} }
off_t end; off_t end;
@ -289,14 +289,14 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) {
} }
void GBASavedataInitEEPROM(struct GBASavedata* savedata) { void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == GBA_SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_EEPROM512; savedata->type = GBA_SAVEDATA_EEPROM512;
} else if (savedata->type != SAVEDATA_EEPROM512 && savedata->type != SAVEDATA_EEPROM) { } else if (savedata->type != GBA_SAVEDATA_EEPROM512 && savedata->type != GBA_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 = GBA_SIZE_EEPROM512; int32_t eepromSize = GBA_SIZE_EEPROM512;
if (savedata->type == SAVEDATA_EEPROM) { if (savedata->type == GBA_SAVEDATA_EEPROM) {
eepromSize = GBA_SIZE_EEPROM; eepromSize = GBA_SIZE_EEPROM;
} }
off_t end; off_t end;
@ -316,8 +316,8 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
} }
void GBASavedataInitSRAM(struct GBASavedata* savedata) { void GBASavedataInitSRAM(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == GBA_SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_SRAM; savedata->type = GBA_SAVEDATA_SRAM;
} else { } else {
mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata");
return; return;
@ -340,8 +340,8 @@ void GBASavedataInitSRAM(struct GBASavedata* savedata) {
} }
void GBASavedataInitSRAM512(struct GBASavedata* savedata) { void GBASavedataInitSRAM512(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_AUTODETECT) { if (savedata->type == GBA_SAVEDATA_AUTODETECT) {
savedata->type = SAVEDATA_SRAM512; savedata->type = GBA_SAVEDATA_SRAM512;
} else { } else {
mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata");
return; return;
@ -365,11 +365,11 @@ void GBASavedataInitSRAM512(struct GBASavedata* savedata) {
uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address) { uint8_t GBASavedataReadFlash(struct GBASavedata* savedata, uint16_t address) {
if (savedata->command == FLASH_COMMAND_ID) { if (savedata->command == FLASH_COMMAND_ID) {
if (savedata->type == SAVEDATA_FLASH512) { if (savedata->type == GBA_SAVEDATA_FLASH512) {
if (address < 2) { if (address < 2) {
return FLASH_MFG_PANASONIC >> (address * 8); return FLASH_MFG_PANASONIC >> (address * 8);
} }
} else if (savedata->type == SAVEDATA_FLASH1M) { } else if (savedata->type == GBA_SAVEDATA_FLASH1M) {
if (address < 2) { if (address < 2) {
return FLASH_MFG_SANYO >> (address * 8); return FLASH_MFG_SANYO >> (address * 8);
} }
@ -472,10 +472,10 @@ static void _ensureEeprom(struct GBASavedata* savedata, uint32_t size) {
if (size < GBA_SIZE_EEPROM512) { if (size < GBA_SIZE_EEPROM512) {
return; return;
} }
if (savedata->type == SAVEDATA_EEPROM) { if (savedata->type == GBA_SAVEDATA_EEPROM) {
return; return;
} }
savedata->type = SAVEDATA_EEPROM; savedata->type = GBA_SAVEDATA_EEPROM;
if (!savedata->vf) { if (!savedata->vf) {
return; return;
} }
@ -605,7 +605,7 @@ void GBASavedataRTCWrite(struct GBASavedata* savedata) {
int bank = 0; int bank = 0;
if ((savedata->vf->size(savedata->vf) & 0xFF) != sizeof(buffer)) { if ((savedata->vf->size(savedata->vf) & 0xFF) != sizeof(buffer)) {
// Writing past the end of the file can invalidate the file mapping // Writing past the end of the file can invalidate the file mapping
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
bank = savedata->currentBank == &savedata->data[0x10000]; bank = savedata->currentBank == &savedata->data[0x10000];
} }
savedata->vf->unmap(savedata->vf, savedata->data, size); savedata->vf->unmap(savedata->vf, savedata->data, size);
@ -614,9 +614,9 @@ void GBASavedataRTCWrite(struct GBASavedata* savedata) {
savedata->vf->write(savedata->vf, &buffer, sizeof(buffer)); savedata->vf->write(savedata->vf, &buffer, sizeof(buffer));
if (!savedata->data) { if (!savedata->data) {
savedata->data = savedata->vf->map(savedata->vf, size, MAP_WRITE); savedata->data = savedata->vf->map(savedata->vf, size, MAP_WRITE);
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
savedata->currentBank = &savedata->data[bank << 16]; savedata->currentBank = &savedata->data[bank << 16];
} else if (savedata->type == SAVEDATA_FLASH512) { } else if (savedata->type == GBA_SAVEDATA_FLASH512) {
savedata->currentBank = savedata->data; savedata->currentBank = savedata->data;
} }
} }
@ -730,7 +730,7 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial
LOAD_32(savedata->writeAddress, 0, &state->savedata.writeAddress); LOAD_32(savedata->writeAddress, 0, &state->savedata.writeAddress);
LOAD_16(savedata->settling, 0, &state->savedata.settlingSector); LOAD_16(savedata->settling, 0, &state->savedata.settlingSector);
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
_flashSwitchBank(savedata, GBASerializedSavedataFlagsGetFlashBank(flags)); _flashSwitchBank(savedata, GBASerializedSavedataFlagsGetFlashBank(flags));
} }
@ -743,9 +743,9 @@ void GBASavedataDeserialize(struct GBASavedata* savedata, const struct GBASerial
void _flashSwitchBank(struct GBASavedata* savedata, int bank) { void _flashSwitchBank(struct GBASavedata* savedata, int bank) {
mLOG(GBA_SAVE, DEBUG, "Performing flash bank switch to bank %i", bank); mLOG(GBA_SAVE, DEBUG, "Performing flash bank switch to bank %i", bank);
if (bank > 0 && savedata->type == SAVEDATA_FLASH512) { if (bank > 0 && savedata->type == GBA_SAVEDATA_FLASH512) {
mLOG(GBA_SAVE, INFO, "Updating flash chip from 512kb to 1Mb"); mLOG(GBA_SAVE, INFO, "Updating flash chip from 512kb to 1Mb");
savedata->type = SAVEDATA_FLASH1M; savedata->type = GBA_SAVEDATA_FLASH1M;
if (savedata->vf) { if (savedata->vf) {
savedata->vf->unmap(savedata->vf, savedata->data, GBA_SIZE_FLASH512); savedata->vf->unmap(savedata->vf, savedata->data, GBA_SIZE_FLASH512);
if (savedata->vf->size(savedata->vf) < GBA_SIZE_FLASH1M) { if (savedata->vf->size(savedata->vf) < GBA_SIZE_FLASH1M) {
@ -764,7 +764,7 @@ void _flashErase(struct GBASavedata* savedata) {
mLOG(GBA_SAVE, DEBUG, "Performing flash chip erase"); mLOG(GBA_SAVE, DEBUG, "Performing flash chip erase");
savedata->dirty |= mSAVEDATA_DIRT_NEW; savedata->dirty |= mSAVEDATA_DIRT_NEW;
size_t size = GBA_SIZE_FLASH512; size_t size = GBA_SIZE_FLASH512;
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
size = GBA_SIZE_FLASH1M; size = GBA_SIZE_FLASH1M;
} }
memset(savedata->data, 0xFF, size); memset(savedata->data, 0xFF, size);
@ -774,7 +774,7 @@ void _flashEraseSector(struct GBASavedata* savedata, uint16_t sectorStart) {
mLOG(GBA_SAVE, DEBUG, "Performing flash sector erase at 0x%04x", sectorStart); mLOG(GBA_SAVE, DEBUG, "Performing flash sector erase at 0x%04x", sectorStart);
savedata->dirty |= mSAVEDATA_DIRT_NEW; savedata->dirty |= mSAVEDATA_DIRT_NEW;
size_t size = 0x1000; size_t size = 0x1000;
if (savedata->type == SAVEDATA_FLASH1M) { if (savedata->type == GBA_SAVEDATA_FLASH1M) {
mLOG(GBA_SAVE, DEBUG, "Performing unknown sector-size erase at 0x%04x", sectorStart); mLOG(GBA_SAVE, DEBUG, "Performing unknown sector-size erase at 0x%04x", sectorStart);
} }
savedata->settling = sectorStart >> 12; savedata->settling = sectorStart >> 12;

View File

@ -18,9 +18,9 @@ static const int GSV_PAYLOAD_OFFSET = 0x430;
static bool _importSavedata(struct GBA* gba, void* payload, size_t size) { static bool _importSavedata(struct GBA* gba, void* payload, size_t size) {
bool success = false; bool success = false;
switch (gba->memory.savedata.type) { switch (gba->memory.savedata.type) {
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
if (size > GBA_SIZE_FLASH512) { if (size > GBA_SIZE_FLASH512) {
GBASavedataForceType(&gba->memory.savedata, SAVEDATA_FLASH1M); GBASavedataForceType(&gba->memory.savedata, GBA_SAVEDATA_FLASH1M);
} }
// Fall through // Fall through
default: default:
@ -28,8 +28,8 @@ static bool _importSavedata(struct GBA* gba, void* payload, size_t size) {
size = GBASavedataSize(&gba->memory.savedata); size = GBASavedataSize(&gba->memory.savedata);
} }
break; break;
case SAVEDATA_FORCE_NONE: case GBA_SAVEDATA_FORCE_NONE:
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
goto cleanup; goto cleanup;
} }
@ -276,7 +276,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) {
checksum += buffer.c[i] << (checksum % 24); checksum += buffer.c[i] << (checksum % 24);
} }
if (gba->memory.savedata.type == SAVEDATA_EEPROM) { if (gba->memory.savedata.type == GBA_SAVEDATA_EEPROM) {
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
char byte = gba->memory.savedata.data[i ^ 7]; char byte = gba->memory.savedata.data[i ^ 7];
checksum += byte << (checksum % 24); checksum += byte << (checksum % 24);

View File

@ -1156,7 +1156,7 @@ size_t retro_get_memory_size(unsigned id) {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: case mPLATFORM_GBA:
switch (((struct GBA*) core->board)->memory.savedata.type) { switch (((struct GBA*) core->board)->memory.savedata.type) {
case SAVEDATA_AUTODETECT: case GBA_SAVEDATA_AUTODETECT:
return GBA_SIZE_FLASH1M; return GBA_SIZE_FLASH1M;
default: default:
return GBASavedataSize(&((struct GBA*) core->board)->memory.savedata); return GBASavedataSize(&((struct GBA*) core->board)->memory.savedata);

View File

@ -153,14 +153,14 @@ void OverrideView::updateOverrides() {
if (m_ui.tabWidget->currentWidget() == m_ui.tabGBA) { if (m_ui.tabWidget->currentWidget() == m_ui.tabGBA) {
auto gba = std::make_unique<GBAOverride>(); auto gba = std::make_unique<GBAOverride>();
memset(gba->override.id, 0, 4); memset(gba->override.id, 0, 4);
gba->override.savetype = static_cast<SavedataType>(m_ui.savetype->currentIndex() - 1); gba->override.savetype = static_cast<GBASavedataType>(m_ui.savetype->currentIndex() - 1);
gba->override.hardware = HW_NO_OVERRIDE; gba->override.hardware = HW_NO_OVERRIDE;
gba->override.idleLoop = IDLE_LOOP_NONE; gba->override.idleLoop = IDLE_LOOP_NONE;
gba->override.mirroring = false; gba->override.mirroring = false;
gba->override.vbaBugCompat = false; gba->override.vbaBugCompat = false;
gba->vbaBugCompatSet = false; gba->vbaBugCompatSet = false;
if (gba->override.savetype != SAVEDATA_AUTODETECT) { if (gba->override.savetype != GBA_SAVEDATA_AUTODETECT) {
hasOverride = true; hasOverride = true;
} }
if (!m_ui.hwAutodetect->isChecked()) { if (!m_ui.hwAutodetect->isChecked()) {

View File

@ -170,8 +170,8 @@ void SaveConverter::detectFromSavestate(VFile* vf) {
switch (platform) { switch (platform) {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: case mPLATFORM_GBA:
save.gba.type = static_cast<SavedataType>(state.at(offsetof(GBASerializedState, savedata.type))); save.gba.type = static_cast<GBASavedataType>(state.at(offsetof(GBASerializedState, savedata.type)));
if (save.gba.type == SAVEDATA_EEPROM || save.gba.type == SAVEDATA_EEPROM512) { if (save.gba.type == GBA_SAVEDATA_EEPROM || save.gba.type == GBA_SAVEDATA_EEPROM512) {
save.endianness = Endian::LITTLE; save.endianness = Endian::LITTLE;
} }
break; break;
@ -198,25 +198,25 @@ void SaveConverter::detectFromSize(std::shared_ptr<VFileDevice> vf) {
switch (vf->size()) { switch (vf->size()) {
case GBA_SIZE_SRAM: case GBA_SIZE_SRAM:
case GBA_SIZE_SRAM + 16: case GBA_SIZE_SRAM + 16:
m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, vf}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, vf});
break; break;
case GBA_SIZE_FLASH512: case GBA_SIZE_FLASH512:
case GBA_SIZE_FLASH512 + 16: case GBA_SIZE_FLASH512 + 16:
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, vf}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, vf});
break; break;
case GBA_SIZE_FLASH1M: case GBA_SIZE_FLASH1M:
case GBA_SIZE_FLASH1M + 16: case GBA_SIZE_FLASH1M + 16:
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, vf}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, vf});
break; break;
case GBA_SIZE_EEPROM: case GBA_SIZE_EEPROM:
case GBA_SIZE_EEPROM + 16: case GBA_SIZE_EEPROM + 16:
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, vf, Endian::LITTLE}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, vf, Endian::LITTLE});
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, vf, Endian::BIG}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, vf, Endian::BIG});
break; break;
case GBA_SIZE_EEPROM512: case GBA_SIZE_EEPROM512:
case GBA_SIZE_EEPROM512 + 16: case GBA_SIZE_EEPROM512 + 16:
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, vf, Endian::LITTLE}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, vf, Endian::LITTLE});
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, vf, Endian::BIG}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, vf, Endian::BIG});
break; break;
} }
#endif #endif
@ -272,12 +272,12 @@ void SaveConverter::detectFromHeaders(std::shared_ptr<VFileDevice> vf) {
QByteArray bytes = QByteArray::fromRawData(static_cast<const char*>(data), size); QByteArray bytes = QByteArray::fromRawData(static_cast<const char*>(data), size);
bytes.data(); // Trigger a deep copy before we delete the backing bytes.data(); // Trigger a deep copy before we delete the backing
if (size == GBA_SIZE_FLASH1M) { if (size == GBA_SIZE_FLASH1M) {
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::SHARKPORT}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::SHARKPORT});
} else { } else {
m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::SHARKPORT}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::SHARKPORT});
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_FLASH512)), Endian::NONE, Container::SHARKPORT}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_FLASH512)), Endian::NONE, Container::SHARKPORT});
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::SHARKPORT}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::SHARKPORT});
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::SHARKPORT}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::SHARKPORT});
} }
free(data); free(data);
} }
@ -289,20 +289,20 @@ void SaveConverter::detectFromHeaders(std::shared_ptr<VFileDevice> vf) {
bytes.data(); // Trigger a deep copy before we delete the backing bytes.data(); // Trigger a deep copy before we delete the backing
switch (size) { switch (size) {
case GBA_SIZE_FLASH1M: case GBA_SIZE_FLASH1M:
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV});
break; break;
case GBA_SIZE_FLASH512: case GBA_SIZE_FLASH512:
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH512, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH512, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV});
m_validSaves.append(AnnotatedSave{SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_FLASH1M, std::make_shared<VFileDevice>(bytes), Endian::NONE, Container::GSV});
break; break;
case GBA_SIZE_SRAM: case GBA_SIZE_SRAM:
m_validSaves.append(AnnotatedSave{SAVEDATA_SRAM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_SRAM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_SRAM)), Endian::NONE, Container::GSV});
break; break;
case GBA_SIZE_EEPROM: case GBA_SIZE_EEPROM:
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM)), Endian::BIG, Container::GSV});
break; break;
case GBA_SIZE_EEPROM512: case GBA_SIZE_EEPROM512:
m_validSaves.append(AnnotatedSave{SAVEDATA_EEPROM512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::GSV}); m_validSaves.append(AnnotatedSave{GBA_SAVEDATA_EEPROM512, std::make_shared<VFileDevice>(bytes.left(GBA_SIZE_EEPROM512)), Endian::BIG, Container::GSV});
break; break;
} }
free(data); free(data);
@ -401,7 +401,7 @@ SaveConverter::AnnotatedSave::AnnotatedSave(mPlatform platform, std::shared_ptr<
} }
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
SaveConverter::AnnotatedSave::AnnotatedSave(SavedataType type, std::shared_ptr<VFileDevice> vf, Endian endianness, Container container) SaveConverter::AnnotatedSave::AnnotatedSave(GBASavedataType type, std::shared_ptr<VFileDevice> vf, Endian endianness, Container container)
: container(container) : container(container)
, platform(mPLATFORM_GBA) , platform(mPLATFORM_GBA)
, size(vf->size()) , size(vf->size())
@ -468,15 +468,15 @@ SaveConverter::AnnotatedSave::operator QString() const {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: case mPLATFORM_GBA:
switch (gba.type) { switch (gba.type) {
case SAVEDATA_SRAM: case GBA_SAVEDATA_SRAM:
typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "SRAM"); typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "SRAM");
break; break;
case SAVEDATA_FLASH512: case GBA_SAVEDATA_FLASH512:
case SAVEDATA_FLASH1M: case GBA_SAVEDATA_FLASH1M:
typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 flash"); typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 flash");
break; break;
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 EEPROM"); typeFormat = QCoreApplication::translate("QGBA::SaveConverter", "%1 EEPROM");
break; break;
default: default:
@ -664,8 +664,8 @@ QByteArray SaveConverter::AnnotatedSave::convertTo(const SaveConverter::Annotate
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
case mPLATFORM_GBA: case mPLATFORM_GBA:
switch (gba.type) { switch (gba.type) {
case SAVEDATA_EEPROM: case GBA_SAVEDATA_EEPROM:
case SAVEDATA_EEPROM512: case GBA_SAVEDATA_EEPROM512:
if (endianness == target.endianness) { if (endianness == target.endianness) {
break; break;
} }

View File

@ -48,7 +48,7 @@ private slots:
private: private:
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
struct GBASave { struct GBASave {
SavedataType type; GBASavedataType type;
}; };
#endif #endif
#ifdef M_CORE_GB #ifdef M_CORE_GB
@ -66,7 +66,7 @@ private:
AnnotatedSave(); AnnotatedSave();
AnnotatedSave(mPlatform, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE); AnnotatedSave(mPlatform, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE);
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
AnnotatedSave(SavedataType, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE); AnnotatedSave(GBASavedataType, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE);
#endif #endif
#ifdef M_CORE_GB #ifdef M_CORE_GB
AnnotatedSave(GBMemoryBankControllerType, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE); AnnotatedSave(GBMemoryBankControllerType, std::shared_ptr<VFileDevice>, Endian = Endian::NONE, Container = Container::NONE);