From 7b0a101f1347d1963fcca53bf8f6a68cc09b982f Mon Sep 17 00:00:00 2001 From: Balint Kovacs Date: Fri, 12 Jul 2019 14:49:50 +0200 Subject: [PATCH] Add read support for CTR cartridge saves I have done nothing, however, to decrypt them. There is also no write support. --- arm9/source/gamecart/spi.c | 19 ++++++++++++++----- arm9/source/gamecart/spi.h | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/arm9/source/gamecart/spi.c b/arm9/source/gamecart/spi.c index 697993e..99954a3 100644 --- a/arm9/source/gamecart/spi.c +++ b/arm9/source/gamecart/spi.c @@ -95,11 +95,12 @@ u32 SPIGetPageSize(CardType type) { u32 EEPROMSizes[] = { 16, 32, 128, 256 }; if(type == NO_CHIP || type > CHIP_LAST) return 0; else if(type < FLASH_256KB_1) return EEPROMSizes[(int) type]; - else return 256; + else if(type < FLASH_64KB_CTR ) return 256; + else return 0; // TODO } u32 SPIGetCapacity(CardType type) { - u32 sz[] = { 9, 13, 16, 17, 18, 18, 19, 19, 20, 23, 19, 19 }; + u32 sz[] = { 9, 13, 16, 17, 18, 18, 19, 19, 20, 23, 16, 17, 18, 19, 20, 21, 22, 23, 19, 18 }; if(type == NO_CHIP || type > CHIP_LAST) return 0; else return 1 << sz[(int) type]; @@ -251,6 +252,14 @@ int SPIReadSaveData(CardType type, u32 offset, void* data, u32 size) { case FLASH_8MB: case FLASH_512KB_INFRARED: case FLASH_256KB_INFRARED: + case FLASH_64KB_CTR: + case FLASH_128KB_CTR: + case FLASH_256KB_CTR: + case FLASH_512KB_CTR: + case FLASH_1MB_CTR: + case FLASH_2MB_CTR: + case FLASH_4MB_CTR: + case FLASH_8MB_CTR: cmdSize = 4; cmd[1] = (u8)(pos >> 16); cmd[2] = (u8)(pos >> 8); @@ -346,7 +355,7 @@ int SPIGetCardType(CardType* type, int infrared) { u32 tries = 0; CardType t = (infrared == 1) ? FLASH_INFRARED_DUMMY : FLASH_STD_DUMMY; int res; - u32 jedecOrderedList[] = { 0x204012, 0x621600, 0x204013, 0x621100, 0x204014, 0x202017}; + u32 jedecOrderedList[] = { 0x204012, 0x621600, 0x204013, 0x621100, 0x204014, 0x202017, 0xC22210, 0xC22211, 0xC22212, 0xC22213, 0xC22214, 0xC22215, 0xC22216, 0xC22217 }; u32 maxTries = (infrared == -1) ? 2 : 1; // note: infrared = -1 fails 1/3 of the time while(tries < maxTries){ @@ -390,9 +399,9 @@ int SPIGetCardType(CardType* type, int infrared) { if(infrared == 1) *type = NO_CHIP; // did anything go wrong? if(jedec == 0x204017) { *type = FLASH_8MB; return 0; } // 8MB. savegame-manager: which one? (more work is required to unlock this save chip!) - int i; + size_t i; - for(i = 0; i < 6; ++i) { + for(i = 0; i < sizeof(jedecOrderedList) / sizeof(int); ++i) { if(jedec == jedecOrderedList[i]) { *type = (CardType)((int) FLASH_256KB_1 + i); return 0; } } diff --git a/arm9/source/gamecart/spi.h b/arm9/source/gamecart/spi.h index a6b06cd..be9f5c6 100644 --- a/arm9/source/gamecart/spi.h +++ b/arm9/source/gamecart/spi.h @@ -63,11 +63,22 @@ typedef enum { FLASH_8MB = 9, // <- can't restore savegames, and maybe not read them atm FLASH_STD_DUMMY = 4, - FLASH_512KB_INFRARED = 10, - FLASH_256KB_INFRARED = 11, // AFAIK, only "Active Health with Carol Vorderman" has such a flash save memory - FLASH_INFRARED_DUMMY = 9, + FLASH_64KB_CTR = 10, // I am extrapolating from the dataheets, only a few of these have been observed in the wild + FLASH_128KB_CTR = 11, // Most common, including Ocarina of time 3D + FLASH_256KB_CTR = 12, + FLASH_512KB_CTR = 13, // Also common, including Detective Pikachu + FLASH_1MB_CTR = 14, // For example Pokemon Ultra Sun + FLASH_2MB_CTR = 15, + FLASH_4MB_CTR = 16, + FLASH_8MB_CTR = 17, + // Animal crossing: New leaf??? + // (What is that? 3dbrew states 10M, but Macronix only makes powers of 2) + + FLASH_512KB_INFRARED = 18, + FLASH_256KB_INFRARED = 19, // AFAIK, only "Active Health with Carol Vorderman" has such a flash save memory + FLASH_INFRARED_DUMMY = 17, - CHIP_LAST = 11, + CHIP_LAST = 19, } CardType; int SPIWriteRead(CardType type, void* cmd, u32 cmdSize, void* answer, u32 answerSize, void* data, u32 dataSize);