From 6cdf5046ac1b62c41cfd69fdffa44884dd46a4ed Mon Sep 17 00:00:00 2001 From: RocketRobz Date: Thu, 30 Jan 2020 00:34:03 -0700 Subject: [PATCH] Full DS(i) ROM with arm9i/7i bins now dumpable --- arm9/source/driveMenu.cpp | 15 +- arm9/source/ndsheaderbanner.h | 138 +++++++++++++++++ arm9/source/read_card.c | 283 ++++++++++++++++++++++++---------- arm9/source/read_card.h | 4 +- 4 files changed, 349 insertions(+), 91 deletions(-) create mode 100644 arm9/source/ndsheaderbanner.h diff --git a/arm9/source/driveMenu.cpp b/arm9/source/driveMenu.cpp index e2567de..c5e9131 100644 --- a/arm9/source/driveMenu.cpp +++ b/arm9/source/driveMenu.cpp @@ -31,6 +31,7 @@ #include "screenshot.h" #include "driveOperations.h" #include "fileOperations.h" +#include "ndsheaderbanner.h" #include "read_card.h" #include "tonccpy.h" @@ -73,15 +74,6 @@ void ndsCardDump(void) { if ((pressed & KEY_A) || (pressed & KEY_Y)) { consoleClear(); - sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart - if (!flashcardMounted && isDSiMode()) { - // Reset card slot - disableSlot1(); - for(int i = 0; i < 25; i++) { swiWaitForVBlank(); } - enableSlot1(); - for(int i = 0; i < 15; i++) { swiWaitForVBlank(); } - } - char folderPath[2][256]; sprintf(folderPath[0], "%s:/gm9i", (sdMounted ? "sd" : "fat")); sprintf(folderPath[1], "%s:/gm9i/out", (sdMounted ? "sd" : "fat")); @@ -96,7 +88,7 @@ void ndsCardDump(void) { } consoleClear(); // Read header - tNDSHeader* ndsCardHeader = (tNDSHeader*)malloc(0x1000); + sNDSHeaderExt* ndsCardHeader = (sNDSHeaderExt*)malloc(0x1000); if (cardInit (ndsCardHeader) == 0) { printf("Dumping...\n"); printf("Do not remove the NDS card.\n"); @@ -121,7 +113,8 @@ void ndsCardDump(void) { // Determine ROM size u32 romSize = 0; if (trimRom) { - romSize = ndsCardHeader->romSize; + romSize = ((ndsCardHeader->unitCode != 0) && (ndsCardHeader->twlRomSize > 0)) + ? ndsCardHeader->twlRomSize : ndsCardHeader->romSize; } else switch (ndsCardHeader->deviceSize) { case 0x00: romSize = 0x20000; diff --git a/arm9/source/ndsheaderbanner.h b/arm9/source/ndsheaderbanner.h new file mode 100644 index 0000000..88f5546 --- /dev/null +++ b/arm9/source/ndsheaderbanner.h @@ -0,0 +1,138 @@ +/*--------------------------------------------------------------------------------- + + memory.h -- Declaration of memory regions + + + Copyright (C) 2005 Michael Noland (joat) and Jason Rogers (dovoto) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any + damages arising from the use of this software. + + Permission is granted to anyone to use this software for any + purpose, including commercial applications, and to alter it and + redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +---------------------------------------------------------------------------------*/ +/*! \file ndsheaderbanner.h +\brief Defines the Nintendo DS file header and icon/title structs. +*/ + +#ifndef NDS_HEADER2 +#define NDS_HEADER2 + +#include + +/*! + \brief the NDS file header format + See gbatek for more info. +*/ +typedef struct { + char gameTitle[12]; //!< 12 characters for the game title. + char gameCode[4]; //!< 4 characters for the game code. + char makercode[2]; //!< identifies the (commercial) developer. + u8 unitCode; //!< identifies the required hardware. + u8 deviceType; //!< type of device in the game card + u8 deviceSize; //!< capacity of the device (1 << n Mbit) + u8 reserved1[9]; + u8 romversion; //!< version of the ROM. + u8 flags; //!< bit 2: auto-boot flag. + + u32 arm9romOffset; //!< offset of the arm9 binary in the nds file. + u32 arm9executeAddress; //!< adress that should be executed after the binary has been copied. + u32 arm9destination; //!< destination address to where the arm9 binary should be copied. + u32 arm9binarySize; //!< size of the arm9 binary. + + u32 arm7romOffset; //!< offset of the arm7 binary in the nds file. + u32 arm7executeAddress; //!< adress that should be executed after the binary has been copied. + u32 arm7destination; //!< destination address to where the arm7 binary should be copied. + u32 arm7binarySize; //!< size of the arm7 binary. + + u32 filenameOffset; //!< File Name Table (FNT) offset. + u32 filenameSize; //!< File Name Table (FNT) size. + u32 fatOffset; //!< File Allocation Table (FAT) offset. + u32 fatSize; //!< File Allocation Table (FAT) size. + + u32 arm9overlaySource; //!< File arm9 overlay offset. + u32 arm9overlaySize; //!< File arm9 overlay size. + u32 arm7overlaySource; //!< File arm7 overlay offset. + u32 arm7overlaySize; //!< File arm7 overlay size. + + u32 cardControl13; //!< Port 40001A4h setting for normal commands (used in modes 1 and 3) + u32 cardControlBF; //!< Port 40001A4h setting for KEY1 commands (used in mode 2) + u32 bannerOffset; //!< offset to the banner with icon and titles etc. + + u16 secureCRC16; //!< Secure Area Checksum, CRC-16. + + u16 readTimeout; //!< Secure Area Loading Timeout. + + u32 unknownRAM1; //!< ARM9 Auto Load List RAM Address (?) + u32 unknownRAM2; //!< ARM7 Auto Load List RAM Address (?) + + u32 bfPrime1; //!< Secure Area Disable part 1. + u32 bfPrime2; //!< Secure Area Disable part 2. + u32 romSize; //!< total size of the ROM. + + u32 headerSize; //!< ROM header size. + u32 zeros88[14]; + u8 gbaLogo[156]; //!< Nintendo logo needed for booting the game. + u16 logoCRC16; //!< Nintendo Logo Checksum, CRC-16. + u16 headerCRC16; //!< header checksum, CRC-16. + + u32 debugRomSource; //!< debug ROM offset. + u32 debugRomSize; //!< debug size. + u32 debugRomDestination; //!< debug RAM destination. + u32 offset_0x16C; //reserved? + + u8 zero[0x40]; + u32 region; + u32 accessControl; + u32 arm7SCFGSettings; + u16 dsi_unk1; + u8 dsi_unk2; + u8 dsi_flags; + + u32 arm9iromOffset; //!< offset of the arm9 binary in the nds file. + u32 arm9iexecuteAddress; + u32 arm9idestination; //!< destination address to where the arm9 binary should be copied. + u32 arm9ibinarySize; //!< size of the arm9 binary. + + u32 arm7iromOffset; //!< offset of the arm7 binary in the nds file. + u32 deviceListDestination; + u32 arm7idestination; //!< destination address to where the arm7 binary should be copied. + u32 arm7ibinarySize; //!< size of the arm7 binary. + + u8 zero2[0x20]; + + // 0x200 + // TODO: More DSi-specific fields. + u8 dsi1[0x10]; + u32 twlRomSize; + u32 dsi_unk3; + u32 dsi_unk4; + u32 dsi_unk5; + u8 dsi2[0x10]; + u32 dsi_tid; + u32 dsi_tid2; + u32 pubSavSize; + u32 prvSavSize; + u8 dsi3[0x174]; +} sNDSHeaderExt; + +//#define __NDSHeader ((tNDSHeader *)0x02FFFE00) + +// Make sure the header size is correct. +//static_assert(sizeof(sNDSHeaderExt) == 0x3B4, "sizeof(sNDSHeaderExt) is not 0x3B4 bytes"); + +#endif // NDS_HEADER2 diff --git a/arm9/source/read_card.c b/arm9/source/read_card.c index 273c2fe..b62d76f 100644 --- a/arm9/source/read_card.c +++ b/arm9/source/read_card.c @@ -48,9 +48,12 @@ typedef union u32 key; } GameCode; +static bool twlBlowfish = false; + +static bool normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000 static u32 portFlags = 0; static u32 headerData[0x1000/sizeof(u32)] = {0}; -static u32 secureAreaData[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0}; +static u32 secureArea[CARD_SECURE_AREA_SIZE/sizeof(u32)] = {0}; static const u8 cardSeedBytes[] = {0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5}; @@ -151,67 +154,37 @@ static void cardDelay (u16 readTimeout) { TIMER_DATA(0) = 0; } +static void switchToTwlBlowfish(sNDSHeaderExt* ndsHeader) { + if (twlBlowfish || ndsHeader->unitCode == 0) return; + + // Used for dumping the DSi arm9i/7i binaries -int cardInit (tNDSHeader* ndsHeader) -{ 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 - u32* secureArea; int secureBlockNumber; int i; u8 cmdData[8] __attribute__ ((aligned)); GameCode* gameCode; if (isDSiMode()) { - cardReset(); - } else { + // Reset card slot + disableSlot1(); + for(int i = 0; i < 25; i++) { swiWaitForVBlank(); } + enableSlot1(); + for(int i = 0; i < 15; i++) { swiWaitForVBlank(); } + // Dummy command sent after card reset cardParamCommand (CARD_CMD_DUMMY, 0, CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), NULL, 0); + } else { + cardReset(); } - u32 iCardId=cardReadID(CARD_CLK_SLOW); - u32 iCheapCard=iCardId&0x80000000; - - // Read the header - if(iCheapCard) - { - //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 - if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) { - return ERR_HEAD_CRC; - } - - tonccpy(headerData, ndsHeader, 0x1000); - - u32 nds9Offset = *(u32*)(headerData+0x20); - - int iCardDevice = ((*(u8*)(headerData+0x12) != 0) ? 1 : 0); - - /* - // Check logo CRC - if (ndsHeader->logoCRC16 != 0xCF56) { - return ERR_LOGO_CRC; - } - */ + //int iCardDevice = 1; // Initialise blowfish encryption for KEY1 commands and decrypting the secure area gameCode = (GameCode*)ndsHeader->gameCode; - init_keycode (gameCode->key, iCardDevice?1:2, 8, iCardDevice); + init_keycode (gameCode->key, 1, 8, 1); // Port 40001A4h setting for normal reads (command B7) portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7); @@ -220,13 +193,12 @@ int cardInit (tNDSHeader* ndsHeader) ((ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF))) + ((ndsHeader->cardControlBF & CARD_DELAY2(0x3F)) >> 16)); // Adjust card transfer method depending on the most significant bit of the chip ID - normalChip = (iCardId & 0x80000000) != 0; // ROM chip ID MSB if (!normalChip) { portFlagsKey1 |= CARD_SEC_LARGE; } // 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode - initKey1Encryption (cmdData, iCardDevice); + initKey1Encryption (cmdData, 1); cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData); // 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode @@ -259,10 +231,10 @@ int cardInit (tNDSHeader* ndsHeader) cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData); // 2bbbbiii jjjkkkkk - Get Secure Area Block - secureArea = secureAreaData; portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F))) | CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT; + int secureAreaOffset = 0; for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) { createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber); @@ -270,12 +242,158 @@ int cardInit (tNDSHeader* ndsHeader) cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData); cardDelay(ndsHeader->readTimeout); for (i = 8; i > 0; i--) { - cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea, 0x200, cmdData); - secureArea += 0x200/sizeof(u32); + cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData); + secureAreaOffset += 0x200/sizeof(u32); } } else { - cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea, 0x1000, cmdData); - secureArea += 0x1000/sizeof(u32); + cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData); + secureAreaOffset += 0x1000/sizeof(u32); + } + } + + // Alllliii jjjkkkkk - Enter Main Data Mode + createEncryptedCommand (CARD_CMD_DATA_MODE, cmdData, 0); + + if (normalChip) { + cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); + cardDelay(ndsHeader->readTimeout); + } + cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); + + decryptSecureArea (gameCode->key, secureArea, 1); + + twlBlowfish = true; +} + + +int cardInit (sNDSHeaderExt* ndsHeader) +{ + u32 portFlagsKey1, portFlagsSecRead; + normalChip = false; // As defined by GBAtek, normal chip secure area is accessed in blocks of 0x200, other chip in blocks of 0x1000 + int secureBlockNumber; + int i; + u8 cmdData[8] __attribute__ ((aligned)); + GameCode* gameCode; + + twlBlowfish = false; + + if (isDSiMode()) { + sysSetCardOwner (BUS_OWNER_ARM9); // Allow arm9 to access NDS cart + // Reset card slot + disableSlot1(); + for(int i = 0; i < 25; i++) { swiWaitForVBlank(); } + enableSlot1(); + for(int i = 0; i < 15; i++) { swiWaitForVBlank(); } + + // Dummy command sent after card reset + cardParamCommand (CARD_CMD_DUMMY, 0, + CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), + NULL, 0); + } else { + cardReset(); + } + + u32 iCardId=cardReadID(CARD_CLK_SLOW); + u32 iCheapCard=iCardId&0x80000000; + + // Read the header + if(iCheapCard) + { + //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 + if (ndsHeader->headerCRC16 != swiCRC16(0xFFFF, (void*)ndsHeader, 0x15E)) { + return ERR_HEAD_CRC; + } + + tonccpy(headerData, ndsHeader, 0x1000); + + /* + // Check logo CRC + if (ndsHeader->logoCRC16 != 0xCF56) { + return ERR_LOGO_CRC; + } + */ + + // Initialise blowfish encryption for KEY1 commands and decrypting the secure area + gameCode = (GameCode*)ndsHeader->gameCode; + init_keycode (gameCode->key, 2, 8, 0); + + // Port 40001A4h setting for normal reads (command B7) + portFlags = ndsHeader->cardControl13 & ~CARD_BLK_SIZE(7); + // Port 40001A4h setting for KEY1 commands (usually 001808F8h) + 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)); + + // Adjust card transfer method depending on the most significant bit of the chip ID + normalChip = (iCardId & 0x80000000) != 0; // ROM chip ID MSB + if (!normalChip) { + portFlagsKey1 |= CARD_SEC_LARGE; + } + + // 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode + initKey1Encryption (cmdData, 0); + cardPolledTransfer((ndsHeader->cardControl13 & (CARD_WR|CARD_nRESET|CARD_CLK_SLOW)) | CARD_ACTIVATE, NULL, 0, cmdData); + + // 4llllmmm nnnkkkkk - Activate KEY2 Encryption Mode + createEncryptedCommand (CARD_CMD_ACTIVATE_SEC, cmdData, 0); + + if (normalChip) { + cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); + cardDelay(ndsHeader->readTimeout); + } + cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); + + // Set the KEY2 encryption registers + REG_ROMCTRL = 0; + REG_CARD_1B0 = cardSeedBytes[ndsHeader->deviceType & 0x07] | (key1data.nnn << 15) | (key1data.mmm << 27) | 0x6000; + REG_CARD_1B4 = 0x879b9b05; + REG_CARD_1B8 = key1data.mmm >> 5; + REG_CARD_1BA = 0x5c; + REG_ROMCTRL = CARD_nRESET | CARD_SEC_SEED | CARD_SEC_EN | CARD_SEC_DAT; + + // Update the DS card flags to suit KEY2 encryption + portFlagsKey1 |= CARD_SEC_EN | CARD_SEC_DAT; + + // 1lllliii jjjkkkkk - 2nd Get ROM Chip ID / Get KEY2 Stream + createEncryptedCommand (CARD_CMD_SECURE_CHIPID, cmdData, 0); + + if (normalChip) { + cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); + cardDelay(ndsHeader->readTimeout); + } + cardPolledTransfer(portFlagsKey1 | CARD_BLK_SIZE(7), NULL, 0, cmdData); + + // 2bbbbiii jjjkkkkk - Get Secure Area Block + portFlagsSecRead = (ndsHeader->cardControlBF & (CARD_CLK_SLOW|CARD_DELAY1(0x1FFF)|CARD_DELAY2(0x3F))) + | CARD_ACTIVATE | CARD_nRESET | CARD_SEC_EN | CARD_SEC_DAT; + + int secureAreaOffset = 0; + for (secureBlockNumber = 4; secureBlockNumber < 8; secureBlockNumber++) { + createEncryptedCommand (CARD_CMD_SECURE_READ, cmdData, secureBlockNumber); + + if (normalChip) { + cardPolledTransfer(portFlagsSecRead, NULL, 0, cmdData); + cardDelay(ndsHeader->readTimeout); + for (i = 8; i > 0; i--) { + cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(1), secureArea + secureAreaOffset, 0x200, cmdData); + secureAreaOffset += 0x200/sizeof(u32); + } + } else { + cardPolledTransfer(portFlagsSecRead | CARD_BLK_SIZE(4) | CARD_SEC_LARGE, secureArea + secureAreaOffset, 0x1000, cmdData); + secureAreaOffset += 0x1000/sizeof(u32); } } @@ -289,12 +407,11 @@ int cardInit (tNDSHeader* ndsHeader) cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); //CycloDS doesn't like the dsi secure area being decrypted - if(!iCardDevice && ((nds9Offset != 0x4000) || secureAreaData[0] || secureAreaData[1])) + if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1]) { - decryptSecureArea (gameCode->key, secureAreaData, iCardDevice); + decryptSecureArea (gameCode->key, secureArea, 0); } - secureArea = secureAreaData; if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) { // Secure area exists, so just clear the tag secureArea[0] = 0xe7ffdeff; @@ -308,6 +425,8 @@ int cardInit (tNDSHeader* ndsHeader) void cardRead (u32 src, void* dest) { + sNDSHeaderExt* ndsHeader = (sNDSHeaderExt*)headerData; + if (src >= 0 && src < 0x1000) { // Read header tonccpy (dest, (u8*)headerData + src, 0x200); @@ -317,7 +436,11 @@ void cardRead (u32 src, void* dest) return; } else if (src < CARD_DATA_OFFSET) { // Read data from secure area - tonccpy (dest, (u8*)secureAreaData + src - CARD_SECURE_AREA_OFFSET, 0x200); + tonccpy (dest, (u8*)secureArea + src - CARD_SECURE_AREA_OFFSET, 0x200); + return; + } else if ((ndsHeader->unitCode != 0) && (src >= ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset+MODC_AREA_SIZE)) { + // Read data from secure area + tonccpy (dest, (u8*)secureArea + src - ndsHeader->arm9iromOffset, 0x200); return; } @@ -325,30 +448,32 @@ void cardRead (u32 src, void* dest) portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1), dest, 0x200); - /*int iCardDevice = ((*(u8*)(headerData+0x12) != 0) ? 1 : 0); - u32 arm9i_rom_offset = *(u32*)(headerData + 0x1C0); + if (src > ndsHeader->romSize) { + switchToTwlBlowfish(ndsHeader); - if (iCardDevice && (src > arm9i_rom_offset) && - (src < arm9i_rom_offset + MODC_AREA_SIZE)) - { - u8* buffer8 = (u8*) dest; - u8* buff = buffer8; + /* + if ((ndsHeader->unitCode != 0) + && (src > ndsHeader->arm9iromOffset) && (src < ndsHeader->arm9iromOffset + MODC_AREA_SIZE)) + { + u8* buffer8 = (u8*) dest; + //u8* buff = buffer8; - // modcrypt area handling - u8* buffer_arm9i = buffer8; - u32 offset_i = 0; - u32 size_i = MODC_AREA_SIZE; - if (arm9i_rom_offset < (src)) - offset_i = (src) - arm9i_rom_offset; - else buffer_arm9i = buffer8 + (arm9i_rom_offset - (src)); - size_i = MODC_AREA_SIZE - offset_i; - if (size_i > (0x4000) - (buffer_arm9i - buffer8)) - size_i = (0x4000) - (buffer_arm9i - buffer8); - if (size_i) { - cardParamCommand (CARD_CMD_DATA_READ, (0x4000 + offset_i), - portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1), - buffer_arm9i, size_i); - } - }*/ + // modcrypt area handling + u8* buffer_arm9i = buffer8; + u32 offset_i = 0; + u32 size_i = MODC_AREA_SIZE; + if (arm9i_rom_offset < (src)) + offset_i = (src) - arm9i_rom_offset; + else buffer_arm9i = buffer8 + (arm9i_rom_offset - (src)); + size_i = MODC_AREA_SIZE - offset_i; + if (size_i > (0x4000) - (buffer_arm9i - buffer8)) + size_i = (0x4000) - (buffer_arm9i - buffer8); + if (size_i) { + cardParamCommand (CARD_CMD_DATA_READ, (0x4000 + offset_i), + portFlags | CARD_ACTIVATE | CARD_nRESET | CARD_BLK_SIZE(1), + buffer_arm9i, size_i); + } + }*/ + } } diff --git a/arm9/source/read_card.h b/arm9/source/read_card.h index e1c1301..e54d37a 100644 --- a/arm9/source/read_card.h +++ b/arm9/source/read_card.h @@ -23,6 +23,8 @@ #include #include +#include "ndsheaderbanner.h" + #define CARD_NDS_HEADER_SIZE (0x200) #define CARD_SECURE_AREA_OFFSET (0x4000) #define CARD_SECURE_AREA_SIZE (0x4000) @@ -34,7 +36,7 @@ extern "C" { #endif -int cardInit (tNDSHeader* ndsHeader); +int cardInit (sNDSHeaderExt* ndsHeader); void cardRead (u32 src, void* dest);