Properly dump DS(i) ROM header

Code ported from GM9
This commit is contained in:
RocketRobz 2020-01-29 19:38:16 -07:00
parent 81dfdef103
commit e53ddc5ecc
3 changed files with 29 additions and 18 deletions

View File

@ -52,8 +52,6 @@ static int dmMaxCursors = -1;
static u8 gbaFixedValue = 0; static u8 gbaFixedValue = 0;
static tNDSHeader* ndsCardHeader = (tNDSHeader*)0x02000000;
void ndsCardDump(void) { void ndsCardDump(void) {
int pressed = 0; int pressed = 0;
@ -98,8 +96,8 @@ void ndsCardDump(void) {
} }
consoleClear(); consoleClear();
// Read header // Read header
u32 cardID = 0; tNDSHeader* ndsCardHeader = (tNDSHeader*)malloc(0x1000);
if (cardInit (ndsCardHeader, &cardID) == 0) { if (cardInit (ndsCardHeader) == 0) {
printf("Dumping...\n"); printf("Dumping...\n");
printf("Do not remove the NDS card.\n"); printf("Do not remove the NDS card.\n");
} else { } else {
@ -107,6 +105,8 @@ void ndsCardDump(void) {
for (int i = 0; i < 60*2; i++) { for (int i = 0; i < 60*2; i++) {
swiWaitForVBlank(); swiWaitForVBlank();
} }
free(ndsCardHeader);
return;
} }
char gameTitle[13] = {0}; char gameTitle[13] = {0};
tonccpy(gameTitle, ndsCardHeader->gameTitle, 12); tonccpy(gameTitle, ndsCardHeader->gameTitle, 12);
@ -171,6 +171,7 @@ void ndsCardDump(void) {
fwrite(romBuffer, 1, 0x200, destinationFile); fwrite(romBuffer, 1, 0x200, destinationFile);
} }
fclose(destinationFile); fclose(destinationFile);
free(ndsCardHeader);
break; break;
} }
if (pressed & KEY_B) { if (pressed & KEY_B) {

View File

@ -49,7 +49,7 @@ typedef union
} GameCode; } GameCode;
static u32 portFlags = 0; static u32 portFlags = 0;
static u32 headerData[CARD_NDS_HEADER_SIZE/sizeof(u32)] = {0}; static u32 headerData[0x1000/sizeof(u32)] = {0};
static u32 secureAreaData[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0}; static u32 secureAreaData[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0};
static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5}; static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5};
@ -148,7 +148,7 @@ static void cardDelay (u16 readTimeout) {
} }
int cardInit (tNDSHeader* ndsHeader, u32* chipID) int cardInit (tNDSHeader* ndsHeader)
{ {
u32 portFlagsKey1, portFlagsSecRead; u32 portFlagsKey1, portFlagsSecRead;
bool normalChip; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000 bool normalChip; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000
@ -163,17 +163,32 @@ int cardInit (tNDSHeader* ndsHeader, u32* chipID)
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
NULL, 0); NULL, 0);
u32 iCardId=cardReadID(CARD_CLK_SLOW);
u32 iCheapCard=iCardId&0x80000000;
// Read the header // Read the header
cardParamCommand (CARD_CMD_HEADER_READ, 0, if(iCheapCard)
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), {
(uint32*)ndsHeader, sizeof(tNDSHeader)); //this is magic of wood goblins
for(size_t ii=0;ii<8;++ii) {
cardParamCommand (CARD_CMD_HEADER_READ, ii*0x200,
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
(u32*)(void*)(ndsHeader+ii*0x200), 0x200);
}
}
else
{
cardParamCommand (CARD_CMD_HEADER_READ, 0,
CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(4) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F),
(u32*)(void*)ndsHeader, 0x1000);
}
// Check header CRC // Check header CRC
if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) { if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) {
return ERR_HEAD_CRC; return ERR_HEAD_CRC;
} }
tonccpy(headerData, ndsHeader, CARD_NDS_HEADER_SIZE); tonccpy(headerData, ndsHeader, 0x1000);
/* /*
// Check logo CRC // Check logo CRC
@ -192,13 +207,8 @@ int cardInit (tNDSHeader* ndsHeader, u32* chipID)
portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) | portFlagsKey1 = CARD_ACTIVATE | CARD_nRESET | (ndsHeader->cardControl13 & (CARD_WR|CARD_CLK_SLOW)) |
((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16)); ((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16));
// 1st Get ROM Chip ID
cardParamCommand (CARD_CMD_HEADER_CHIPID, 0,
(ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE | CARD_BLK_SIZE(7),
chipID, sizeof(u32));
// Adjust card transfer method depending on the most significant bit of the chip ID // Adjust card transfer method depending on the most significant bit of the chip ID
normalChip = ((*chipID) & 0x80000000) != 0; // ROM chip ID MSB normalChip = (iCardId & 0x80000000) != 0; // ROM chip ID MSB
if (!normalChip) { if (!normalChip) {
portFlagsKey1 |= CARD_SEC_LARGE; portFlagsKey1 |= CARD_SEC_LARGE;
} }
@ -295,7 +305,7 @@ void cardRead (u32 src, u32* dest, size_t size)
{ {
size_t readSize; size_t readSize;
if (src >= 0 && src < 0x200) { if (src >= 0 && src < 0x1000) {
// Read header // Read header
readSize = size < CARD_DATA_BLOCK_SIZE ? size : CARD_DATA_BLOCK_SIZE; readSize = size < CARD_DATA_BLOCK_SIZE ? size : CARD_DATA_BLOCK_SIZE;
tonccpy (dest, (u8*)headerData + src, readSize); tonccpy (dest, (u8*)headerData + src, readSize);

View File

@ -33,7 +33,7 @@
extern "C" { extern "C" {
#endif #endif
int cardInit (tNDSHeader* ndsHeader, u32* chipID); int cardInit (tNDSHeader* ndsHeader);
void cardRead (u32 src, u32* dest, size_t size); void cardRead (u32 src, u32* dest, size_t size);