Cut back on card definitions

Saves 400 - 440 bytes of .data
This commit is contained in:
Balint Kovacs 2019-07-28 00:45:57 +02:00 committed by d0k3
parent bef427dfdb
commit aea79aa634
3 changed files with 89 additions and 143 deletions

View File

@ -57,73 +57,47 @@ int CardSPIWriteSaveData_24bit_erase_program(CardSPIType type, u32 offset, const
int CardSPIEraseSector_emulated(CardSPIType type, u32 offset);
int CardSPIEraseSector_real(CardSPIType type, u32 offset);
const CardSPITypeData EEPROM_512B_ = { CardSPIEnableWriting_512B, CardSPIReadSaveData_9bit, CardSPIWriteSaveData_9bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 9, 16, 16, 16, false, 0, 0, 0 };
const CardSPITypeData EEPROM_512B_ = { CardSPIEnableWriting_512B, CardSPIReadSaveData_9bit, CardSPIWriteSaveData_9bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 9, 16, 16, 16, 0, 0, 0 };
const CardSPITypeData EEPROM_STD_DUMMY = { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, UINT32_MAX, 1, 1, 1, false, SPI_EEPROM_CMD_WRITE, 0, 0 };
const CardSPITypeData EEPROM_DUMMY = { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, UINT32_MAX, 1, 1, 1, SPI_EEPROM_CMD_WRITE, 0, 0 };
const CardSPITypeData EEPROMTypes[] = {
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 13, 32, 32, 32, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 8 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 16, 128, 128, 128, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 64 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_emulated, 0xffffff, 1 << 17, 256, 256, 256, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 128 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 13, 32, 32, 32, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 8 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 16, 128, 128, 128, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 64 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_emulated, 0xffffff, 1 << 17, 256, 256, 256, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 128 KB
};
const CardSPITypeData FLASH_STD_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, false, 0, 0, 0 };
const CardSPITypeData FlashStdTypes[] = {
const CardSPITypeData FLASH_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, 0, 0, 0 };
const CardSPITypeData flashTypes[] = {
// NTR/TWL
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204014, 1 << 20, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204014, 1 << 20, 65536, 256, 256, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
// Untested (but pretty safe bet), for Art Academy
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x202017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x204017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x202017, 1 << 23, 65536, 32, 65536, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
// CTR
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22210, 1 << 16, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22211, 1 << 17, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22212, 1 << 18, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22213, 1 << 19, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22214, 1 << 20, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22215, 1 << 21, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22216, 1 << 22, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22217, 1 << 23, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22211, 1 << 17, 4096, 32, 4096, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22213, 1 << 19, 4096, 32, 4096, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22214, 1 << 20, 4096, 32, 4096, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
};
const CardSPITypeData FLASH_INFRARED_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, true, 0, 0, 0 };
const CardSPITypeData FlashInfraredTypes[] = {
// NTR/TWL
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
};
const CardSPITypeData * const EEPROM_512B = &EEPROM_512B_;
const CardSPIType EEPROM_512B = &EEPROM_512B_;
const CardSPITypeData * const EEPROM_8KB = EEPROMTypes + 0;
const CardSPITypeData * const EEPROM_64KB = EEPROMTypes + 1;
const CardSPITypeData * const EEPROM_128KB = EEPROMTypes + 2;
const CardSPIType EEPROM_8KB = EEPROMTypes + 0;
const CardSPIType EEPROM_64KB = EEPROMTypes + 1;
const CardSPIType EEPROM_128KB = EEPROMTypes + 2;
const CardSPITypeData * const FLASH_256KB_1 = flashTypes + 0;
const CardSPITypeData * const FLASH_256KB_2 = flashTypes + 1;
const CardSPITypeData * const FLASH_512KB_1 = flashTypes + 2;
const CardSPITypeData * const FLASH_512KB_2 = flashTypes + 3;
const CardSPITypeData * const FLASH_1MB = flashTypes + 4;
const CardSPITypeData * const FLASH_8MB = flashTypes + 5;
const CardSPIType FLASH_256KB_1 = FlashStdTypes + 0;
const CardSPIType FLASH_256KB_2 = FlashStdTypes + 1;
const CardSPIType FLASH_512KB_1 = FlashStdTypes + 2;
const CardSPIType FLASH_512KB_2 = FlashStdTypes + 3;
const CardSPIType FLASH_1MB = FlashStdTypes + 4;
const CardSPIType FLASH_8MB_1 = FlashStdTypes + 5;
const CardSPIType FLASH_8MB_2 = FlashStdTypes + 6;
const CardSPIType FLASH_64KB_CTR = FlashStdTypes + 7;
const CardSPIType FLASH_128KB_CTR = FlashStdTypes + 8;
const CardSPIType FLASH_256KB_CTR = FlashStdTypes + 9;
const CardSPIType FLASH_512KB_CTR = FlashStdTypes + 10;
const CardSPIType FLASH_1MB_CTR = FlashStdTypes + 11;
const CardSPIType FLASH_2MB_CTR = FlashStdTypes + 12;
const CardSPIType FLASH_4MB_CTR = FlashStdTypes + 13;
const CardSPIType FLASH_8MB_CTR = FlashStdTypes + 14;
const CardSPIType FLASH_256KB_1_INFRARED = FlashInfraredTypes + 0;
const CardSPIType FLASH_256KB_2_INFRARED = FlashInfraredTypes + 1;
const CardSPIType FLASH_512KB_1_INFRARED = FlashInfraredTypes + 2;
const CardSPIType FLASH_512KB_2_INFRARED = FlashInfraredTypes + 3;
const CardSPITypeData * const FLASH_128KB_CTR = flashTypes + 6;
const CardSPITypeData * const FLASH_512KB_CTR = flashTypes + 7;
const CardSPITypeData * const FLASH_1MB_CTR = flashTypes + 8;
#define REG_CFG9_CARDCTL *((vu16*)0x1000000C)
#define CARDCTL_SPICARD (1u<<8)
@ -133,7 +107,7 @@ int CardSPIWriteRead(CardSPIType type, const void* cmd, u32 cmdSize, void* answe
REG_CFG9_CARDCTL |= CARDCTL_SPICARD;
if (type->infrared) {
if (type.infrared) {
SPI_XferInfo irXfer = { &headerFooterVal, 1, false };
SPI_DoXfer(SPI_DEV_CART_IR, &irXfer, 1, false);
}
@ -185,8 +159,8 @@ int CardSPIEnableWriting_regular(CardSPIType type) {
}
int CardSPIEnableWriting(CardSPIType type) {
if (type == NO_CHIP) return 1;
return type->enableWriting(type);
if (type.chip == NO_CHIP) return 1;
return type.chip->enableWriting(type);
}
int _SPIWriteTransaction(CardSPIType type, void* cmd, u32 cmdSize, const void* data, u32 dataSize) {
@ -218,18 +192,18 @@ int CardSPIReadJEDECIDAndStatusReg(CardSPIType type, u32* id, u8* statusReg) {
}
u32 CardSPIGetPageSize(CardSPIType type) {
if (type == NO_CHIP) return 0;
return type->pageSize;
if (type.chip == NO_CHIP) return 0;
return type.chip->pageSize;
}
u32 CardSPIGetEraseSize(CardSPIType type) {
if (type == NO_CHIP) return 0;
return type->eraseSize;
if (type.chip == NO_CHIP) return 0;
return type.chip->eraseSize;
}
u32 CardSPIGetCapacity(CardSPIType type) {
if (type == NO_CHIP) return 0;
return type->capacity;
if (type.chip == NO_CHIP) return 0;
return type.chip->capacity;
}
int CardSPIWriteSaveData_9bit(CardSPIType type, u32 offset, const void* data, u32 size) {
@ -239,19 +213,19 @@ int CardSPIWriteSaveData_9bit(CardSPIType type, u32 offset, const void* data, u3
}
int CardSPIWriteSaveData_16bit(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[3] = { type->writeCommand, (u8)(offset >> 8), (u8) offset };
u8 cmd[3] = { type.chip->writeCommand, (u8)(offset >> 8), (u8) offset };
return _SPIWriteTransaction(type, cmd, 3, (void*) ((u8*) data), size);
}
int CardSPIWriteSaveData_24bit_write(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[4] = { type->writeCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
u8 cmd[4] = { type.chip->writeCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
return _SPIWriteTransaction(type, cmd, 4, (void*) ((u8*) data), size);
}
int CardSPIWriteSaveData_24bit_erase_program(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[4] = { type->programCommand };
u8 cmd[4] = { type.chip->programCommand };
const u32 pageSize = CardSPIGetPageSize(type);
const u32 eraseSize = CardSPIGetEraseSize(type);
int res;
@ -290,13 +264,13 @@ int CardSPIWriteSaveData_24bit_erase_program(CardSPIType type, u32 offset, const
}
int CardSPIWriteSaveData(CardSPIType type, u32 offset, const void* data, u32 size) {
if (type == NO_CHIP) return 1;
if (type.chip == NO_CHIP) return 1;
if (size == 0) return 0;
size = min(size, CardSPIGetCapacity(type) - offset);
u32 end = offset + size;
u32 pos = offset;
u32 writeSize = type->writeSize;
u32 writeSize = type.chip->writeSize;
if (writeSize == 0) return 0xC8E13404;
int res = CardSPIWaitWriteEnd(type);
@ -308,7 +282,7 @@ int CardSPIWriteSaveData(CardSPIType type, u32 offset, const void* data, u32 siz
u32 dataSize = (remaining < nb) ? remaining : nb;
if ((res = type->writeSaveData(type, pos, (void*) ((u8*) data - offset + pos), dataSize))) return res;
if ((res = type.chip->writeSaveData(type, pos, (void*) ((u8*) data - offset + pos), dataSize))) return res;
pos = ((pos / writeSize) + 1) * writeSize; // truncate
}
@ -361,7 +335,7 @@ int CardSPIReadSaveData_24bit(CardSPIType type, u32 offset, void* data, u32 size
}
int CardSPIReadSaveData(CardSPIType type, u32 offset, void* data, u32 size) {
if (type == NO_CHIP) return 1;
if (type.chip == NO_CHIP) return 1;
if (size == 0) return 0;
@ -370,7 +344,7 @@ int CardSPIReadSaveData(CardSPIType type, u32 offset, void* data, u32 size) {
size = (size <= CardSPIGetCapacity(type) - offset) ? size : CardSPIGetCapacity(type) - offset;
return type->readSaveData(type, offset, data, size);
return type.chip->readSaveData(type, offset, data, size);
}
int CardSPIEraseSector_emulated(CardSPIType type, u32 offset) {
@ -386,7 +360,7 @@ int CardSPIEraseSector_emulated(CardSPIType type, u32 offset) {
}
int CardSPIEraseSector_real(CardSPIType type, u32 offset) {
u8 cmd[4] = { type->eraseCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
u8 cmd[4] = { type.chip->eraseCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
int res = CardSPIWaitWriteEnd(type);
if (res) return res;
@ -396,8 +370,8 @@ int CardSPIEraseSector_real(CardSPIType type, u32 offset) {
int CardSPIEraseSector(CardSPIType type, u32 offset) {
if (type == NO_CHIP) return 1;
return type->eraseSector(type, offset);
if (type.chip == NO_CHIP) return 1;
return type.chip->eraseSector(type, offset);
}
@ -456,7 +430,7 @@ int CardSPIGetCardSPIType(CardSPIType* type, int infrared) {
u8 sr = 0;
u32 jedec = 0;
u32 tries = 0;
CardSPIType t = (infrared == 1) ? &FLASH_INFRARED_DUMMY : &FLASH_STD_DUMMY;
CardSPIType t = { &FLASH_DUMMY, infrared == 1 };
int res;
u32 maxTries = (infrared == -1) ? 2 : 1; // note: infrared = -1 fails 1/3 of the time
@ -465,58 +439,39 @@ int CardSPIGetCardSPIType(CardSPIType* type, int infrared) {
if (res) return res;
if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) { break; }
if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) { t = EEPROM_512B; break; }
if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) { t = &EEPROM_STD_DUMMY; break; }
if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) { *type = (CardSPIType) { EEPROM_512B, false }; return 0; }
if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) { t = (CardSPIType) { &EEPROM_DUMMY, false }; break; }
++tries;
t = &FLASH_INFRARED_DUMMY;
t.infrared = true;
}
if (t == EEPROM_512B) { *type = t; return 0; }
else if (t == &EEPROM_STD_DUMMY) {
if (t.chip == &EEPROM_DUMMY) {
bool mirrored = false;
size_t i;
for(i = 0; i < sizeof(EEPROMTypes) / sizeof(CardSPITypeData) - 1; i++) {
if ((res = _SPIIsDataMirrored(t, CardSPIGetCapacity(EEPROMTypes + i), &mirrored))) return res;
if ((res = _SPIIsDataMirrored(t, CardSPIGetCapacity((CardSPIType) {EEPROMTypes + i, false}), &mirrored))) return res;
if (mirrored) {
*type = EEPROMTypes + i;
*type = (CardSPIType) {EEPROMTypes + i, false};
return 0;
}
}
*type = EEPROMTypes + i;
*type = (CardSPIType) { EEPROMTypes + i, false };
return 0;
}
else if (t == &FLASH_INFRARED_DUMMY) {
size_t i;
if (infrared == 0) *type = NO_CHIP; // did anything go wrong?
for(i = 0; i < sizeof(FlashInfraredTypes) / sizeof(CardSPITypeData); i++) {
if (FlashInfraredTypes[i].jedecId == jedec) {
*type = FlashInfraredTypes + i;
return 0;
}
if (infrared == 0 && t.infrared) *type = (CardSPIType) { NO_CHIP, false }; // did anything go wrong?
if (infrared == 1 && !t.infrared) *type = (CardSPIType) { NO_CHIP, true };
for(size_t i = 0; i < sizeof(flashTypes) / sizeof(CardSPITypeData); i++) {
if (flashTypes[i].jedecId == jedec) {
*type = (CardSPIType) { flashTypes + i, t.infrared };
return 0;
}
*type = NO_CHIP;
return 0;
}
else {
size_t i;
if (infrared == 1) *type = NO_CHIP; // did anything go wrong?
for(i = 0; i < sizeof(FlashStdTypes) / sizeof(CardSPITypeData); i++) {
if (FlashStdTypes[i].jedecId == jedec) {
*type = FlashStdTypes + i;
return 0;
}
}
*type = NO_CHIP;
return 0;
}
*type = (CardSPIType) { NO_CHIP, t.infrared };
return 0;
}

View File

@ -27,7 +27,10 @@ extern "C" {
typedef struct CardSPITypeData CardSPITypeData;
typedef const CardSPITypeData * CardSPIType;
typedef struct {
const CardSPITypeData *chip;
bool infrared;
} CardSPIType;
struct CardSPITypeData {
int (*enableWriting) (CardSPIType type);
@ -39,7 +42,6 @@ struct CardSPITypeData {
u32 eraseSize;
u32 pageSize;
u32 writeSize;
bool infrared;
u8 writeCommand;
u8 programCommand;
u8 eraseCommand;
@ -47,33 +49,22 @@ struct CardSPITypeData {
#define NO_CHIP NULL
const CardSPIType EEPROM_512B;
const CardSPITypeData * const EEPROM_512B;
const CardSPIType EEPROM_8KB;
const CardSPIType EEPROM_64KB;
const CardSPIType EEPROM_128KB;
const CardSPITypeData * const EEPROM_8KB;
const CardSPITypeData * const EEPROM_64KB;
const CardSPITypeData * const EEPROM_128KB;
const CardSPIType FLASH_256KB_1;
const CardSPIType FLASH_256KB_2;
const CardSPIType FLASH_512KB_1;
const CardSPIType FLASH_512KB_2;
const CardSPIType FLASH_1MB;
const CardSPIType FLASH_8MB_1; // <- can't restore savegames, and maybe not read them atm
const CardSPIType FLASH_8MB_2; // we are also unsure about the ID for this
const CardSPITypeData * const FLASH_256KB_1;
const CardSPITypeData * const FLASH_256KB_2;
const CardSPITypeData * const FLASH_512KB_1;
const CardSPITypeData * const FLASH_512KB_2;
const CardSPITypeData * const FLASH_1MB;
const CardSPITypeData * const FLASH_8MB; // <- can't restore savegames, and maybe not read them atm
const CardSPIType FLASH_64KB_CTR; // I am extrapolating from the dataheets, only a few of these have been observed in the wild
const CardSPIType FLASH_128KB_CTR; // Most common, including Ocarina of time 3D
const CardSPIType FLASH_256KB_CTR;
const CardSPIType FLASH_512KB_CTR; // Also common, including Detective Pikachu
const CardSPIType FLASH_1MB_CTR; // For example Pokemon Ultra Sun
const CardSPIType FLASH_2MB_CTR;
const CardSPIType FLASH_4MB_CTR;
const CardSPIType FLASH_8MB_CTR;
const CardSPIType FLASH_256KB_1_INFRARED; // AFAIK, only "Active Health with Carol Vorderman" has such a flash save memory
const CardSPIType FLASH_256KB_2_INFRARED;
const CardSPIType FLASH_512KB_1_INFRARED;
const CardSPIType FLASH_512KB_2_INFRARED;
const CardSPITypeData * const FLASH_128KB_CTR; // Most common, including Ocarina of time 3D
const CardSPITypeData * const FLASH_512KB_CTR; // Also common, including Detective Pikachu
const CardSPITypeData * const FLASH_1MB_CTR; // For example Pokemon Ultra Sun
int CardSPIWriteRead(CardSPIType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize);
int CardSPIWaitWriteEnd(CardSPIType type);

View File

@ -101,7 +101,7 @@ u32 InitCartRead(CartData* cdata) {
// save data
u32 card2_offset = getle32(cdata->header + 0x200);
if ((card2_offset != 0xFFFFFFFF) || (CardSPIGetCardSPIType(&(cdata->save_type), 0) != 0)) {
cdata->save_type = NO_CHIP;
cdata->save_type = (CardSPIType) { NO_CHIP, false };
}
cdata->save_size = CardSPIGetCapacity(cdata->save_type);
} else { // NTR/TWL cartridges
@ -136,7 +136,7 @@ u32 InitCartRead(CartData* cdata) {
// save data
u32 infrared = (*(nds_header->game_code) == 'I') ? 1 : 0;
if (CardSPIGetCardSPIType(&(cdata->save_type), infrared) != 0) {
cdata->save_type = NO_CHIP;
cdata->save_type = (CardSPIType) { NO_CHIP, false };
}
cdata->save_size = CardSPIGetCapacity(cdata->save_type);
}
@ -243,13 +243,13 @@ u32 ReadCartPrivateHeader(void* buffer, u64 offset, u64 count, CartData* cdata)
u32 ReadCartSave(u8* buffer, u64 offset, u64 count, CartData* cdata) {
if (offset >= cdata->save_size) return 1;
if (offset + count > cdata->save_size) count = cdata->save_size - offset;
return (CardSPIReadSaveData((CardSPIType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
return (CardSPIReadSaveData(cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
}
u32 WriteCartSave(const u8* buffer, u64 offset, u64 count, CartData* cdata) {
if (offset >= cdata->save_size) return 1;
if (offset + count > cdata->save_size) count = cdata->save_size - offset;
return (CardSPIWriteSaveData((CardSPIType) cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
return (CardSPIWriteSaveData(cdata->save_type, offset, buffer, count) == 0) ? 0 : 1;
}
u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata) {
@ -258,7 +258,7 @@ u32 ReadCartSaveJedecId(u8* buffer, u64 offset, u64 count, CartData* cdata) {
u8 sReg;
if (offset >= JEDECID_AND_SREG_SIZE) return 1;
if (offset + count > JEDECID_AND_SREG_SIZE) count = JEDECID_AND_SREG_SIZE - offset;
CardSPIReadJEDECIDAndStatusReg((CardSPIType) cdata->save_type, &id, &sReg);
CardSPIReadJEDECIDAndStatusReg(cdata->save_type, &id, &sReg);
ownBuf[0] = (id >> 16) & 0xff;
ownBuf[1] = (id >> 8) & 0xff;
ownBuf[2] = id & 0xff;