diff --git a/BootLoader/source/common.h b/BootLoader/source/common.h index 2005e4d..b8c7ed4 100755 --- a/BootLoader/source/common.h +++ b/BootLoader/source/common.h @@ -34,12 +34,13 @@ enum { ERR_NONE=0x00, ERR_STS_CLR_MEM=0x01, ERR_STS_LOAD_BIN=0x02, ERR_STS_HOOK_ enum {ARM9_BOOT, ARM9_START, ARM9_MEMCLR, ARM9_READY, ARM9_BOOTBIN, ARM9_DISPERR, ARM9_SETSCFG} ARM9_STATE; extern tNDSHeader* ndsHeader; -extern bool dsiModeConfirmed; + extern bool arm9_dsiModeConfirmed; extern bool arm9_boostVram; extern bool arm9_scfgUnlock; extern bool arm9_TWLClockSpeeds; extern bool arm9_ExtendRam; +extern bool arm9_DebugMode; extern volatile int arm9_stateFlag; extern volatile u32 arm9_errorCode; diff --git a/BootLoader/source/find.h b/BootLoader/source/find.h index 6d4d897..5dfcedc 100644 --- a/BootLoader/source/find.h +++ b/BootLoader/source/find.h @@ -29,3 +29,4 @@ u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, u32* findMpuInitCacheOffset(const u32* mpuStartOffset); #endif // FIND_H + diff --git a/BootLoader/source/find_arm9.c b/BootLoader/source/find_arm9.c index 253ec43..9741db0 100644 --- a/BootLoader/source/find_arm9.c +++ b/BootLoader/source/find_arm9.c @@ -138,3 +138,4 @@ u32* findMpuInitCacheOffset(const u32* mpuStartOffset) { // dbg_printf("\n"); return mpuInitCacheOffset; } + diff --git a/BootLoader/source/launch_ds_crt0.s b/BootLoader/source/launch_ds_crt0.s index f5ca8bb..1449220 100755 --- a/BootLoader/source/launch_ds_crt0.s +++ b/BootLoader/source/launch_ds_crt0.s @@ -10,6 +10,7 @@ .global boostVram .global soundFreq .global extendRam + .global debugMode @--------------------------------------------------------------------------------- .align 4 .arm @@ -36,6 +37,8 @@ soundFreq: .word 0x00000000 extendRam: .word 0x00000000 +debugMode: + .word 0x00000000 startUp: mov r0, #0x04000000 @ IME = 0; diff --git a/BootLoader/source/main.arm7.c b/BootLoader/source/main.arm7.c index af8b5d3..8665e07 100755 --- a/BootLoader/source/main.arm7.c +++ b/BootLoader/source/main.arm7.c @@ -66,11 +66,12 @@ extern u32 twlClock; extern u32 boostVram; extern u32 soundFreq; extern u32 extendRam; +extern u32 debugMode; bool useTwlCfg = false; int twlCfgLang = 0; -bool gameSoftReset = false; +// bool gameSoftReset = false; void arm7_clearmem (void* loc, size_t len); extern void ensureBinaryDecompressed(const tNDSHeader* ndsHeader, module_params_t* moduleParams); @@ -107,8 +108,7 @@ u32* findModuleParamsOffset(const tNDSHeader* ndsHeader) { //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Used for debugging purposes -/* Disabled for now. Re-enable to debug problems -static void errorOutput (u32 code) { +/*static void errorOutput (u32 code) { // Wait until the ARM9 is ready while (arm9_stateFlag != ARM9_READY); // Set the error code, then tell ARM9 to display it @@ -117,17 +117,17 @@ static void errorOutput (u32 code) { arm9_stateFlag = ARM9_DISPERR; // Stop while(1); -} -*/ +}*/ + static void debugOutput (u32 code) { // Wait until the ARM9 is ready while (arm9_stateFlag != ARM9_READY); // Set the error code, then tell ARM9 to display it - arm9_errorCode = code; - arm9_errorClearBG = false; + arm9_errorCode = code; + arm9_errorClearBG = debugMode; arm9_stateFlag = ARM9_DISPERR; - // Wait for completion + // Wait for completion while (arm9_stateFlag != ARM9_READY); } @@ -190,6 +190,8 @@ static void my_readUserSettings(tNDSHeader* ndsHeader) { } } +void memset_addrs_arm7(u32 start, u32 end) { toncset((u32*)start, 0, ((int)end - (int)start)); } + /*------------------------------------------------------------------------- arm7_resetMemory Clears all of the NDS's RAM that is visible to the ARM7 @@ -198,7 +200,7 @@ Modified by Chishm: * Added STMIA clear mem loop --------------------------------------------------------------------------*/ void arm7_resetMemory (void) { - int i; + int i, reg; REG_IME = 0; @@ -217,6 +219,7 @@ void arm7_resetMemory (void) { DMA_DEST(i) = 0; TIMER_CR(i) = 0; TIMER_DATA(i) = 0; + for(reg=0; reg<0x1c; reg+=4)*((u32*)(0x04004104 + ((i*0x1c)+reg))) = 0; //Reset NDMA. } // Clear out FIFO @@ -228,6 +231,9 @@ void arm7_resetMemory (void) { toncset ((void*)0x037F8000, 0, 96*1024); // arm7_clearmem ((void*)0x037F8000, 96*1024); + memset_addrs_arm7(0x03000000, 0x0380FFC0); + memset_addrs_arm7(0x0380FFD0, 0x03800000 + 0x10000); + // clear most of EXRAM - except before 0x023F0000, which has the cheat data toncset ((void*)0x02004000, 0, 0x3EC000); @@ -242,33 +248,100 @@ void arm7_resetMemory (void) { REG_IE = 0; REG_IF = ~0; + REG_AUXIE = 0; + REG_AUXIF = ~0; (*(vu32*)(0x04000000-4)) = 0; //IRQ_HANDLER ARM7 version (*(vu32*)(0x04000000-8)) = ~0; //VBLANK_INTR_WAIT_FLAGS, ARM7 version REG_POWERCNT = 1; //turn off power to stuffs - useTwlCfg = (dsiMode && (*(u8*)0x02000400 & 0x0F) && (*(u8*)0x02000404 == 0)); + // useTwlCfg = (dsiMode && (*(u8*)0x02000400 & 0x0F) && (*(u8*)0x02000404 == 0)); + useTwlCfg = (dsiMode && (*(u8*)0x02000400 & 0x0F) && (*(u8*)0x02000401 == 0) && (*(u8*)0x02000402 == 0) && (*(u8*)0x02000404 == 0)); twlCfgLang = *(u8*)0x02000406; // Load FW header //arm7_readFirmware((u32)0x000000, (u8*)0x027FF830, 0x20); + //readFirmware((u32)0x000000, (u8*)0x027FF830, 0x20); } static void NDSTouchscreenMode(void) { - //unsigned char * *(unsigned char*)0x40001C0= (unsigned char*)0x40001C0; - //unsigned char * *(unsigned char*)0x40001C0byte2=(unsigned char*)0x40001C1; - //unsigned char * *(unsigned char*)0x40001C2= (unsigned char*)0x40001C2; - //unsigned char * I2C_DATA= (unsigned char*)0x4004500; - //unsigned char * I2C_CNT= (unsigned char*)0x4004501; + bool specialSetting = false; u8 volLevel; - //if (fifoCheckValue32(FIFO_MAXMOD)) { - // // special setting (when found special gamecode) - // volLevel = 0xAC; - // } else { + static const char list[][4] = { + "ABX", // NTR-ABXE Bomberman Land Touch! + "YO9", // NTR-YO9J Bokura no TV Game Kentei - Pikotto! Udedameshi + "ALH", // NTR-ALHE Flushed Away + "ACC", // NTR-ACCE Cooking Mama + "YCQ", // NTR-YCQE Cooking Mama 2 - Dinner with Friends + "YYK", // NTR-YYKE Trauma Center - Under the Knife 2 + "AZW", // NTR-AZWE WarioWare - Touched! + "AKA", // NTR-AKAE Rub Rabbits!, The + "AN9", // NTR-AN9E Little Mermaid - Ariel's Undersea Adventure, The + "AKE", // NTR-AKEJ Keroro Gunsou - Enshuu da Yo! Zenin Shuugou Part 2 + "YFS", // NTR-YFSJ Frogman Show - DS Datte, Shouganaijanai, The + "YG8", // NTR-YG8E Yu-Gi-Oh! World Championship 2008 + "AY7", // NTR-AY7E Yu-Gi-Oh! World Championship 2007 + "YON", // NTR-YONJ Minna no DS Seminar - Kantan Ongakuryoku + "A5H", // NTR-A5HE Interactive Storybook DS - Series 2 + "A5I", // NTR-A5IE Interactive Storybook DS - Series 3 + "AMH", // NTR-AMHE Metroid Prime Hunters + "A3T", // NTR-A3TE Tak - The Great Juju Challenge + "YBO", // NTR-YBOE Boogie + "ADA", // NTR-ADAE PKMN Diamond + "APA", // NTR-APAE PKMN Pearl + "CPU", // NTR-CPUE PKMN Platinum + "APY", // NTR-APYE Puyo Pop Fever + "AWH", // NTR-AWHE Bubble Bobble Double Shot + "AXB", // NTR-AXBJ Daigassou! Band Brothers DX + "A4U", // NTR-A4UJ Wi-Fi Taiou - Morita Shogi + "A8N", // NTR-A8NE Planet Puzzle League + "ABJ", // NTR-ABJE Harvest Moon DS - Island of Happiness + "ABN", // NTR-ABNE Bomberman Story DS + "ACL", // NTR-ACLE Custom Robo Arena + "ART", // NTR-ARTJ Shin Lucky Star Moe Drill - Tabidachi + "AVT", // NTR-AVTJ Kou Rate Ura Mahjong Retsuden Mukoubuchi - Goburei, Shuuryou desu ne + "AWY", // NTR-AWYJ Wi-Fi Taiou - Gensen Table Game DS + "AXJ", // NTR-AXJE Dungeon Explorer - Warriors of Ancient Arts + "AYK", // NTR-AYKJ Wi-Fi Taiou - Yakuman DS + "YB2", // NTR-YB2E Bomberman Land Touch! 2 + "YB3", // NTR-YB3E Harvest Moon DS - Sunshine Islands + "YCH", // NTR-YCHJ Kousoku Card Battle - Card Hero + "YFE", // NTR-YFEE Fire Emblem - Shadow Dragon + "YGD", // NTR-YGDE Diary Girl + "YKR", // NTR-YKRJ Culdcept DS + "YRM", // NTR-YRME My Secret World by Imagine + "YW2", // NTR-YW2E Advance Wars - Days of Ruin + "AJU", // NTR-AJUJ Jump! Ultimate Stars + "ACZ", // NTR-ACZE Cars + "AHD", // NTR-AHDE Jam Sessions + "ANR", // NTR-ANRE Naruto - Saikyou Ninja Daikesshu 3 + "YT3", // NTR-YT3E Tamagotchi Connection - Corner Shop 3 + "AVI", // NTR-AVIJ Kodomo no Tame no Yomi Kikase - Ehon de Asobou 1-Kan + "AV2", // NTR-AV2J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 2-Kan + "AV3", // NTR-AV3J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 3-Kan + "AV4", // NTR-AV4J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 4-Kan + "AV5", // NTR-AV5J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 5-Kan + "AV6", // NTR-AV6J Kodomo no Tame no Yomi Kikase - Ehon de Asobou 6-Kan + "YNZ", // NTR-YNZE Petz - Dogz Fashion + }; + + for (unsigned int i = 0; i < sizeof(list) / sizeof(list[0]); i++) { + if (memcmp(ndsHeader->gameCode, list[i], 3) == 0) { + // Found a match. + specialSetting = true; // Special setting (when found special gamecode) + break; + } + } + + if (specialSetting) { + // special setting (when found special gamecode) + volLevel = 0xAC; + } else { // normal setting (for any other gamecodes) - volLevel = 0xA7; - // } + volLevel = 0xA7; + } + // Touchscreen cdcReadReg (0x63, 0x00); @@ -466,7 +539,7 @@ static tNDSHeader* loadHeader(tDSiHeader* dsiHeaderTemp) { *ndsHeader = dsiHeaderTemp->ndshdr; - if (dsiModeConfirmed) { + if (twlMode) { tDSiHeader* dsiHeader = (tDSiHeader*)(isSdk5(moduleParams) ? DSI_HEADER_SDK5 : DSI_HEADER); // __DSiHeader *dsiHeader = *dsiHeaderTemp; } @@ -481,9 +554,6 @@ Written by Darkain, modified by Chishm. --------------------------------------------------------------------------*/ void arm7_startBinary (void) { REG_IME = 0; - - while(REG_VCOUNT!=191); - while(REG_VCOUNT==191); // Get the ARM9 to boot arm9_stateFlag = ARM9_BOOTBIN; @@ -494,46 +564,54 @@ void arm7_startBinary (void) { // Start ARM7 VoidFn arm7code = (VoidFn)ndsHeader->arm7executeAddress; - if (!dsiModeConfirmed) { - REG_SCFG_EXT = 0x92A03000; - if (!scfgUnlock) { REG_SCFG_EXT &= ~(1UL << 31); } - - while(REG_VCOUNT!=191); - while(REG_VCOUNT==191); - } - arm7code(); } void initMBK() { - if (dsiModeConfirmed) { + if (twlMode) { // give all DSI WRAM to arm7 at boot // this function have no effect with ARM7 SCFG locked // arm7 is master of WRAM-A, arm9 of WRAM-B & C - REG_MBK9=0x3000000F; + // REG_MBK9=0x0300000F; // Disabled. This write is redundent. Already set as result of MBK settings in DSi Extended header of NTR_Launcher's SRL // WRAM-A fully mapped to arm7 - *((vu32*)REG_MBK1)=0x8185898D; // same as dsiware + // *((vu32*)REG_MBK1)=0x8185898D; // same as dsiware // WRAM-B fully mapped to arm7 // inverted order - *((vu32*)REG_MBK2)=0x9195999D; - *((vu32*)REG_MBK3)=0x8185898D; + // *((vu32*)REG_MBK2)=0x9195999D; + // *((vu32*)REG_MBK3)=0x8185898D; // WRAM-C fully mapped to arm7 // inverted order - *((vu32*)REG_MBK4)=0x9195999D; - *((vu32*)REG_MBK5)=0x8185898D; + // *((vu32*)REG_MBK4)=0x9195999D; + // *((vu32*)REG_MBK5)=0x8185898D; // WRAM mapped to the 0x3700000 - 0x37FFFFF area // WRAM-A mapped to the 0x37C0000 - 0x37FFFFF area : 256k - REG_MBK6=0x080037C0; // same as dsiware + // REG_MBK6=0x080037C0; // same as dsiware // WRAM-B mapped to the 0x3740000 - 0x37BFFFF area : 512k // why? only 256k real memory is there - REG_MBK7=0x07C03740; // same as dsiware + // REG_MBK7=0x07C03740; // same as dsiware // WRAM-C mapped to the 0x3700000 - 0x373FFFF area : 256k - REG_MBK8=0x07403700; // same as dsiware + // REG_MBK8=0x07403700; // same as dsiware + + *((vu32*)REG_MBK1)=0x8D898581; + *((vu32*)REG_MBK2)=0x8C888480; + *((vu32*)REG_MBK3)=0x9C989490; + *((vu32*)REG_MBK4)=0x8C888480; + *((vu32*)REG_MBK5)=0x9C989490; + + REG_MBK6=0x080037C0; + REG_MBK7=0x07C03740; + REG_MBK8=0x07403700; } else { + *((vu32*)REG_MBK1)=0x8D898581; + *((vu32*)REG_MBK2)=0x8C888480; + *((vu32*)REG_MBK3)=0x9C989490; + *((vu32*)REG_MBK4)=0x8C888480; + *((vu32*)REG_MBK5)=0x9C989490; + REG_MBK6=0x09403900; REG_MBK7=0x09803940; REG_MBK8=0x09C03980; @@ -553,7 +631,9 @@ void initMBK() { void fixDSBrowser(void) { extern void patchMpu(const tNDSHeader* ndsHeader, const module_params_t* moduleParams); - patchMpu(ndsHeader, moduleParams); + // patchMpu(ndsHeader, moduleParams); + + patchMpu((tNDSHeader*)NDS_HEADER, moduleParams); toncset((char*)0x02400000, 0xFF, 0xC0); *(u8*)0x024000B2 = 0; @@ -593,6 +673,7 @@ void fixDSBrowser(void) { static void setMemoryAddress(const tNDSHeader* ndsHeader) { + if (ROMsupportsDSiMode(ndsHeader)) { // u8* deviceListAddr = (u8*)((u8*)0x02FFE1D4); // tonccpy(deviceListAddr, deviceList_bin, deviceList_bin_len); @@ -632,9 +713,11 @@ static void setMemoryAddress(const tNDSHeader* ndsHeader) { // Main function void arm7_main (void) { - + initMBK(); + arm9_DebugMode = debugMode; + int errorCode; // Wait for ARM9 to at least start @@ -647,6 +730,8 @@ void arm7_main (void) { debugOutput (ERR_STS_LOAD_BIN); + if (!twlMode) { REG_SCFG_ROM = 0x703; } + tDSiHeader* dsiHeaderTemp = (tDSiHeader*)0x02FFC000; // Load the NDS file @@ -657,85 +742,90 @@ void arm7_main (void) { if (ROMisDSiEnhanced(&dsiHeaderTemp->ndshdr)) { extendRam = true; } // Required for TWL carts to boot properly. Disabled by default for NTR carts to allow WoodR4 to operate correctly. if (ROMisDSiExclusive(&dsiHeaderTemp->ndshdr)) { + twlMode = true; + dsiMode = true; + // dsiModeConfirmed = true; twlClock = true; extendRam = true; boostVram = true; - dsiMode = true; } - if (dsiMode) { + /*if (dsiMode) { if (twlMode == 2) { dsiModeConfirmed = twlMode; } else { dsiModeConfirmed = twlMode && ROMsupportsDSiMode(&dsiHeaderTemp->ndshdr); } - } + }*/ - if (dsiModeConfirmed) { - if (dsiHeaderTemp->arm9ibinarySize > 0) { - cardRead(dsiHeaderTemp->arm9iromOffset, (u32*)dsiHeaderTemp->arm9idestination, dsiHeaderTemp->arm9ibinarySize); + if (twlMode) { + if (dsiHeaderTemp->arm9ibinarySize > 0) { + cardRead((u32)dsiHeaderTemp->arm9iromOffset, (u32*)dsiHeaderTemp->arm9idestination, dsiHeaderTemp->arm9ibinarySize); } if (dsiHeaderTemp->arm7ibinarySize > 0) { - cardRead(dsiHeaderTemp->arm7iromOffset, (u32*)dsiHeaderTemp->arm7idestination, dsiHeaderTemp->arm7ibinarySize); + cardRead((u32)dsiHeaderTemp->arm7iromOffset, (u32*)dsiHeaderTemp->arm7idestination, dsiHeaderTemp->arm7ibinarySize); } - } else { - REG_SCFG_ROM = 0x703; } ndsHeader = loadHeader(dsiHeaderTemp); + // if (*(u32*)(NDS_HEADER+0xC) == 0x50524255) { fixDSBrowser(); } + bool isDSBrowser = (memcmp(ndsHeader->gameCode, "UBRP", 4) == 0); + + bool arm9_extendedMemory = (twlMode || isDSBrowser); + + if (isDSBrowser) { arm9_ExtendRam = true; } + + if (!arm9_extendedMemory) { tonccpy((u32*)0x023FF000, (u32*)(isSdk5(moduleParams) ? 0x02FFF000 : 0x027FF000), 0x1000); } + my_readUserSettings(ndsHeader); // Header has to be loaded first - if (dsiMode && !dsiModeConfirmed) { + if (!twlMode) { NDSTouchscreenMode(); *(u16*)0x4000500 = 0x807F; - - if (twlClock) { - // REG_SCFG_CLK = 0x0181; - REG_SCFG_CLK = 0x0187; - } else { - REG_SCFG_CLK = 0x0180; - } - if (!sdAccess) { REG_SCFG_EXT = 0x93FBFB06; } } - - if (*(u32*)(NDS_HEADER+0xC) == 0x50524255) { fixDSBrowser(); } - - if ((*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x52544E // Download Play ROMs + + if (isDSBrowser) { fixDSBrowser(); } + /*if ((*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x52544E // Download Play ROMs || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x4D5341 // Super Mario 64 DS || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x434D41 // Mario Kart DS || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x443241 // New Super Mario Bros. || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x5A5241 // Rockman ZX/MegaMan ZX || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x574B41 // Kirby Squeak Squad/Mouse Attack || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x585A59 // Rockman ZX Advent/MegaMan ZX Advent - || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x5A3642) // Rockman Zero Collection/MegaMan Zero Collection + || (*(u32*)(NDS_HEADER+0xC) & 0x00FFFFFF) == 0x5A3642) // Rockman Zero Collection/MegaMan Zero Collection { gameSoftReset = true; - } + }*/ toncset ((void*)0x023F0000, 0, 0x8000); // Clear cheat data from main memory - + debugOutput (ERR_STS_START); + arm9_dsiModeConfirmed = twlMode; arm9_TWLClockSpeeds = twlClock; arm9_boostVram = boostVram; - arm9_scfgUnlock = scfgUnlock; - arm9_dsiModeConfirmed = dsiModeConfirmed; - arm9_ExtendRam = extendRam; - //arm9_isSdk5 = isSdk5(moduleParams); + arm9_scfgUnlock = scfgUnlock; + arm9_ExtendRam = extendRam; - - if (dsiModeConfirmed) { - REG_SCFG_EXT = 0x93FBFB06; - if (!scfgUnlock) { REG_SCFG_EXT &= ~(1UL << 31); } + if (twlClock) { + if (!sdAccess) { REG_SCFG_CLK = 0x0186; } else { REG_SCFG_CLK = 0x0187; } + } else { + if (!sdAccess) { REG_SCFG_CLK = 0x0180; } else { REG_SCFG_CLK = 0x0181; } } - + + if (twlMode) { REG_SCFG_EXT = 0x92FBFB06; } else { REG_SCFG_EXT = 0x92A00000; } + + if (sdAccess) { REG_SCFG_EXT |= BIT(18); } + + if (!scfgUnlock) { REG_SCFG_EXT &= ~(1UL << 31); } + while (arm9_stateFlag != ARM9_READY); arm9_stateFlag = ARM9_SETSCFG; while (arm9_stateFlag != ARM9_READY); - + setMemoryAddress(ndsHeader); - + arm7_startBinary(); while (1); diff --git a/BootLoader/source/main.arm9.c b/BootLoader/source/main.arm9.c index 0bfb474..86ad0e5 100755 --- a/BootLoader/source/main.arm9.c +++ b/BootLoader/source/main.arm9.c @@ -45,13 +45,13 @@ tNDSHeader* ndsHeader = NULL; -bool arm9_runCardEngine = false; +// bool dsiModeConfirmed = false; bool arm9_dsiModeConfirmed = false; -bool dsiModeConfirmed = false; bool arm9_boostVram = false; bool arm9_scfgUnlock = false; bool arm9_TWLClockSpeeds = false; bool arm9_ExtendRam = false; +bool arm9_DebugMode = false; volatile int arm9_stateFlag = ARM9_BOOT; volatile u32 arm9_errorCode = 0xFFFFFFFF; @@ -63,37 +63,49 @@ External functions --------------------------------------------------------------------------*/ extern void arm9_clearCache (void); - void initMBKARM9() { if (arm9_dsiModeConfirmed) { // default dsiware settings // WRAM-B fully mapped to arm7 // inverted order - *((vu32*)REG_MBK2)=0x9195999D; - *((vu32*)REG_MBK3)=0x8185898D; + // *((vu32*)REG_MBK2)=0x9195999D; + // *((vu32*)REG_MBK3)=0x8185898D; // WRAM-C fully mapped to arm7 // inverted order - *((vu32*)REG_MBK4)=0x9195999D; - *((vu32*)REG_MBK5)=0x8185898D; + // *((vu32*)REG_MBK4)=0x9195999D; + // *((vu32*)REG_MBK5)=0x8185898D; // WRAM-A not mapped (reserved to arm7) - REG_MBK6=0x00000000; + // REG_MBK6=0x00000000; // WRAM-B mapped to the 0x3740000 - 0x37BFFFF area : 512k // why? only 256k real memory is there - REG_MBK7=0x07C03740; // same as dsiware + // REG_MBK7=0x07C03740; // same as dsiware // WRAM-C mapped to the 0x3700000 - 0x373FFFF area : 256k - REG_MBK8=0x07403700; // same as dsiware + // REG_MBK8=0x07403700; // same as dsiware + + // This gets set on arm7 + // *((vu32*)REG_MBK1)=0x8D898581; + // *((vu32*)REG_MBK2)=0x8C888480; + // *((vu32*)REG_MBK3)=0x9C989490; + // *((vu32*)REG_MBK4)=0x8C888480; + // *((vu32*)REG_MBK5)=0x9C989490; + + REG_MBK6=0x00000000; + REG_MBK7=0x07C03740; + REG_MBK8=0x07403700; + REG_MBK9=0x0300000F; } else { // MBK settings for NTR mode games - *((vu32*)REG_MBK1)=0x8D898581; - *((vu32*)REG_MBK2)=0x91898581; - *((vu32*)REG_MBK3)=0x91999591; - *((vu32*)REG_MBK4)=0x91898581; - *((vu32*)REG_MBK5)=0x91999591; + // *((vu32*)REG_MBK1)=0x8D898581; + // *((vu32*)REG_MBK2)=0x91898581; + // *((vu32*)REG_MBK3)=0x91999591; + // *((vu32*)REG_MBK4)=0x91898581; + // *((vu32*)REG_MBK5)=0x91999591; REG_MBK6=0x00003000; REG_MBK7=0x00003000; REG_MBK8=0x00003000; + REG_MBK9=0xFCFFFF0F; } } @@ -116,8 +128,7 @@ arm9_errorOutput Displays an error code on screen. Written by Chishm --------------------------------------------------------------------------*/ -/*static void arm9_errorOutput (u32 code, bool clearBG) { -// Re-enable for debugging +static void arm9_errorOutput (u32 code, bool clearBG) { int i, j, k; u16 colour; @@ -127,9 +138,8 @@ Written by Chishm if (clearBG) { // Clear display - for (i = 0; i < 256*192; i++) { - VRAM_A[i] = 0x0000; - } + // for (i = 0; i < 256*192; i++) { VRAM_A[i] = 0x0000; } + for (i = 0; i < 256*192; i++) { VRAM_A[i] = 0xFFFF; } } // Draw boxes of colour, signifying error codes @@ -192,7 +202,6 @@ Written by Chishm } } } -*/ /*------------------------------------------------------------------------- arm9_main @@ -202,14 +211,15 @@ Jumps to the ARM9 NDS binary in sync with the display and ARM7 Written by Darkain, modified by Chishm --------------------------------------------------------------------------*/ void __attribute__((target("arm"))) arm9_main (void) { + + initMBKARM9(); + register int i; - + //set shared ram to ARM7 WRAM_CR = 0x03; REG_EXMEMCNT = 0xE880; - initMBKARM9(); - arm9_stateFlag = ARM9_START; REG_IME = 0; @@ -249,8 +259,8 @@ void __attribute__((target("arm"))) arm9_main (void) { VRAM_A_CR = 0x80; VRAM_B_CR = 0x80; VRAM_C_CR = 0x80; -// Don't mess with the VRAM used for execution -// VRAM_D_CR = 0x80; + // Don't mess with the VRAM used for execution + // VRAM_D_CR = 0x80; VRAM_E_CR = 0x80; VRAM_F_CR = 0x80; VRAM_G_CR = 0x80; @@ -283,35 +293,34 @@ void __attribute__((target("arm"))) arm9_main (void) { *(u16*)0x0400006C &= BIT(15); SetBrightness(0, 0); SetBrightness(1, 0); - + // set ARM9 state to ready and wait for it to change again arm9_stateFlag = ARM9_READY; - while ( arm9_stateFlag != ARM9_BOOTBIN ) { + while (arm9_stateFlag != ARM9_BOOTBIN) { if (arm9_stateFlag == ARM9_DISPERR) { // Re-enable for debugging - // arm9_errorOutput (arm9_errorCode, arm9_errorClearBG); - if ( arm9_stateFlag == ARM9_DISPERR) { arm9_stateFlag = ARM9_READY; } + if (arm9_DebugMode) { arm9_errorOutput(arm9_errorCode, arm9_errorClearBG); } + if (arm9_stateFlag == ARM9_DISPERR) { arm9_stateFlag = ARM9_READY; } } - // I don't set SCFG_EXT here anymore. The required changes to make WoodR4 work would crash Bootloader if set here. if (arm9_stateFlag == ARM9_SETSCFG) { arm9_stateFlag = ARM9_READY; } } VoidFn arm9code = (VoidFn)ndsHeader->arm9executeAddress; - - // wait for vblank then boot + while(REG_VCOUNT!=191); while(REG_VCOUNT==191); - // arm9_errorOutput (*(u32*)(first), true); - if (arm9_dsiModeConfirmed) { - REG_SCFG_EXT = 0x8307F100; - REG_SCFG_CLK = 0x84; + REG_SCFG_EXT = 0x8207F100; + REG_SCFG_CLK = 0x0084; if (arm9_TWLClockSpeeds) { REG_SCFG_CLK |= BIT(0); } + REG_SCFG_RST = 1; } else { - // REG_SCFG_EXT = 0x8300C000; - REG_SCFG_EXT=0x83000000; + // REG_SCFG_EXT = 0x8200C000; + REG_SCFG_EXT=0x82000000; + REG_SCFG_CLK = 0x80; + if (arm9_TWLClockSpeeds) { REG_SCFG_CLK |= BIT(0); } if (arm9_ExtendRam) { REG_SCFG_EXT |= BIT(14); @@ -319,11 +328,11 @@ void __attribute__((target("arm"))) arm9_main (void) { } // Extended VRAM Access if (arm9_boostVram) { REG_SCFG_EXT |= BIT(13); } - // lock SCFG if (!arm9_scfgUnlock) { REG_SCFG_EXT &= ~(1UL << 31); } } + // wait for vblank then boot while(REG_VCOUNT!=191); while(REG_VCOUNT==191); diff --git a/BootLoader/source/module_params.h b/BootLoader/source/module_params.h index 6b10d39..74d38ce 100644 --- a/BootLoader/source/module_params.h +++ b/BootLoader/source/module_params.h @@ -20,3 +20,4 @@ inline bool isSdk5(const module_params_t* moduleParams) { } #endif // MODULE_PARAMS_H + diff --git a/BootLoader/source/ndsheaderbanner.h b/BootLoader/source/ndsheaderbanner.h index 7d0c42f..627185a 100644 --- a/BootLoader/source/ndsheaderbanner.h +++ b/BootLoader/source/ndsheaderbanner.h @@ -136,3 +136,4 @@ typedef struct { //static_assert(sizeof(sNDSHeaderExt) == 0x3B4, "sizeof(sNDSHeaderExt) is not 0x3B4 bytes"); #endif // NDS_HEADER2 + diff --git a/BootLoader/source/read_card.c b/BootLoader/source/read_card.c index 784a0be..f08991e 100755 --- a/BootLoader/source/read_card.c +++ b/BootLoader/source/read_card.c @@ -235,7 +235,7 @@ static void switchToTwlBlowfish(sNDSHeaderExt* ndsHeader) { cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); // The 0x800 bytes are modcrypted, so this function isn't ran - //decryptSecureArea (gameCode->key, secureArea, 1); + // decryptSecureArea (gameCode->key, secureArea, 1); twlBlowfish = true; } @@ -289,9 +289,8 @@ int cardInit (sNDSHeaderExt* ndsHeader, u32* chipID) { // Adjust card transfer method depending on the most significant bit of the chip ID normalChip = ((*chipID) & 0x80000000) != 0; // ROM chip ID MSB - if (!normalChip) { - portFlagsKey1 |= CARD_SEC_LARGE; - } + + if (!normalChip) { portFlagsKey1 |= CARD_SEC_LARGE; } // 3Ciiijjj xkkkkkxx - Activate KEY1 Encryption Mode initKey1Encryption (cmdData, 0); @@ -356,11 +355,10 @@ int cardInit (sNDSHeaderExt* ndsHeader, u32* chipID) { } cardPolledTransfer(portFlagsKey1, NULL, 0, cmdData); - //CycloDS doesn't like the dsi secure area being decrypted - if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1]) { - decryptSecureArea (gameCode->key, secureArea, 0); - } - + // CycloDS doesn't like the dsi secure area being decrypted + if((ndsHeader->arm9romOffset != 0x4000) || secureArea[0] || secureArea[1]) { decryptSecureArea (gameCode->key, secureArea, 0); } + // decryptSecureArea (gameCode->key, secureArea, 0); + if (secureArea[0] == 0x72636e65 /*'encr'*/ && secureArea[1] == 0x6a624f79 /*'yObj'*/) { // Secure area exists, so just clear the tag secureArea[0] = 0xe7ffdeff; @@ -382,7 +380,7 @@ void cardRead (u32 src, u32* dest, size_t size) { size_t readSize; - if (src > ndsHeader->romSize) { switchToTwlBlowfish(ndsHeader); } + if (src > ndsHeader->romSize) { switchToTwlBlowfish(ndsHeader); } if (src < CARD_SECURE_AREA_OFFSET) { return; diff --git a/BootLoader/source/tonccpy.c b/BootLoader/source/tonccpy.c index 5f0816b..e474f5e 100644 --- a/BootLoader/source/tonccpy.c +++ b/BootLoader/source/tonccpy.c @@ -12,18 +12,16 @@ \param size Fill-length in bytes. \note The pointers and size need not be word-aligned. */ -void tonccpy(void *dst, const void *src, uint size) -{ - if(size==0 || dst==NULL || src==NULL) - return; +void tonccpy(void *dst, const void *src, uint size) { + + if(size==0 || dst==NULL || src==NULL) { return; } uint count; u16 *dst16; // hword destination u8 *src8; // byte source // Ideal case: copy by 4x words. Leaves tail for later. - if( ((u32)src|(u32)dst)%4==0 && size>=4) - { + if( ((u32)src|(u32)dst)%4==0 && size>=4) { u32 *src32= (u32*)src, *dst32= (u32*)dst; count= size/4; @@ -33,47 +31,40 @@ void tonccpy(void *dst, const void *src, uint size) // Duff's Device, good friend! switch(tmp) { do { *dst32++ = *src32++; - case 3: *dst32++ = *src32++; - case 2: *dst32++ = *src32++; - case 1: *dst32++ = *src32++; - case 0: ; } while(count--); + case 3: *dst32++ = *src32++; + case 2: *dst32++ = *src32++; + case 1: *dst32++ = *src32++; + case 0: ; } while(count--); } // Check for tail size &= 3; - if(size == 0) - return; - + if(size == 0) { return; } src8= (u8*)src32; dst16= (u16*)dst32; - } - else // Unaligned. - { + } else { + // Unaligned. uint dstOfs= (u32)dst&1; src8= (u8*)src; dst16= (u16*)(dst-dstOfs); // Head: 1 byte. - if(dstOfs != 0) - { + if(dstOfs != 0) { *dst16= (*dst16 & 0xFF) | *src8++<<8; dst16++; - if(--size==0) - return; + if(--size==0) { return; } } } // Unaligned main: copy by 2x byte. count= size/2; - while(count--) - { + while(count--) { *dst16++ = src8[0] | src8[1]<<8; src8 += 2; } // Tail: 1 byte. - if(size&1) - *dst16= (*dst16 &~ 0xFF) | *src8; + if(size&1) { *dst16= (*dst16 &~ 0xFF) | *src8; } } //# toncset.c @@ -88,21 +79,17 @@ void tonccpy(void *dst, const void *src, uint size) word-aligned. In the case of unaligned fills, \a fill will be masked off to match the situation. */ -void __toncset(void *dst, u32 fill, uint size) -{ - if(size==0 || dst==NULL) - return; +void __toncset(void *dst, u32 fill, uint size) { + if(size==0 || dst==NULL) { return; } uint left= (u32)dst&3; u32 *dst32= (u32*)(dst-left); u32 count, mask; // Unaligned head. - if(left != 0) - { + if(left != 0) { // Adjust for very small stint. - if(left+size<4) - { + if(left+size<4) { mask= BIT_MASK(size*8)<<(left*8); *dst32= (*dst32 &~ mask) | (fill & mask); return; @@ -121,17 +108,17 @@ void __toncset(void *dst, u32 fill, uint size) switch(tmp) { do { *dst32++ = fill; - case 3: *dst32++ = fill; - case 2: *dst32++ = fill; - case 1: *dst32++ = fill; - case 0: ; } while(count--); + case 3: *dst32++ = fill; + case 2: *dst32++ = fill; + case 1: *dst32++ = fill; + case 0: ; } while(count--); } // Tail size &= 3; - if(size) - { + if(size) { mask= BIT_MASK(size*8); *dst32= (*dst32 &~ mask) | (fill & mask); } -} \ No newline at end of file +} + diff --git a/Makefile b/Makefile index b4d9c0c..e21c35a 100755 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ export TARGET := NTR_Launcher export TOPDIR := $(CURDIR) export VERSION_MAJOR := 2 -export VERSION_MINOR := 2 +export VERSION_MINOR := 4 export VERSTRING := $(VERSION_MAJOR).$(VERSION_MINOR) #--------------------------------------------------------------------------------- @@ -29,7 +29,7 @@ all: $(TARGET).nds $(TARGET).nds : $(TARGET).arm7 $(TARGET).arm9 ndstool -c $(TARGET).nds -7 arm7/$(TARGET).arm7.elf -9 arm9/$(TARGET).arm9.elf \ -b $(CURDIR)/icon.bmp "NTR Launcher;NitroHax provided by Chishm;Modified by Apache Thunder" \ - -g KKGP 01 "NTR LAUNCHER" -z 80040000 -u 00030004 -a 00000038 -p 0000 + -g KKGP 01 "NTR LAUNCHER" -z 80040000 -u 00030004 -a 00000038 -p 0001 #--------------------------------------------------------------------------------- $(TARGET).arm7 : arm7/$(TARGET).elf diff --git a/NTR_Launcher.ini b/NTR_Launcher.ini index bbe993a..df216c1 100644 --- a/NTR_Launcher.ini +++ b/NTR_Launcher.ini @@ -1,12 +1,14 @@ [NTRLAUNCHER] -ANIMATEDSPLASH = 0 -NTRSPLASH = 0 -HEALTHSAFETYSPLASH = 1 -TWLMODE = 0 TWLCLOCK = 0 TWLVRAM = 0 TWLEXTRAM = 0 -SCFGUNLOCK = 0 +TWLMODE = 0 SOUNDFREQ = 0 +SCFGUNLOCK = 0 +RESETSLOT1 = 0 +ANIMATEDSPLASH = 0 +NTRSPLASH = 0 +HEALTHSAFETYSPLASH = 1 +DEBUGMODE = 0 LANGUAGE = -1 -RESETSLOT1 = 0 \ No newline at end of file + diff --git a/README.md b/README.md index 0c287c9..d96a3b7 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -NTR Launcher - DSi Branch for RocketLauncher - Apache Thunder +NTR Launcher - Apache Thunder Original code from NitroHax but with cheat engine/menu stripped out. Launcher side of NitroHax without the cheat engine. Nothing much else to say about it. :P diff --git a/arm9/source/launch_engine.c b/arm9/source/launch_engine.c index ebbe143..7ffba8d 100644 --- a/arm9/source/launch_engine.c +++ b/arm9/source/launch_engine.c @@ -33,24 +33,21 @@ #define BOOSTVRAM_OFFSET 28 #define SOUNDFREQ_OFFSET 32 #define EXTENDRAM_OFFSET 36 +#define DEBUGMODE_OFFSET 40 typedef signed int addr_t; typedef unsigned char data_t; -static void writeAddr (data_t *mem, addr_t offset, addr_t value) { - ((addr_t*)mem)[offset/sizeof(addr_t)] = value; -} +static void writeAddr (data_t *mem, addr_t offset, addr_t value) { ((addr_t*)mem)[offset/sizeof(addr_t)] = value; } void vramcpy (void* dst, const void* src, int len) { u16* dst16 = (u16*)dst; u16* src16 = (u16*)src; - for ( ; len > 0; len -= 2) { - *dst16++ = *src16++; - } + for ( ; len > 0; len -= 2) { *dst16++ = *src16++; } } -void runLaunchEngine (bool EnableSD, int language, bool scfgUnlock, bool TWLMODE, bool TWLCLK, bool TWLVRAM, bool soundFreq, bool extendRam) { +void runLaunchEngine (bool EnableSD, int language, bool scfgUnlock, bool TWLMODE, bool TWLCLK, bool TWLVRAM, bool soundFreq, bool extendRam, bool debugMode) { // nocashMessage("runLaunchEngine"); irqDisable(IRQ_ALL); @@ -74,6 +71,7 @@ void runLaunchEngine (bool EnableSD, int language, bool scfgUnlock, bool TWLMODE writeAddr ((data_t*) LCDC_BANK_D, BOOSTVRAM_OFFSET, TWLVRAM); writeAddr ((data_t*) LCDC_BANK_D, SOUNDFREQ_OFFSET, soundFreq); writeAddr ((data_t*) LCDC_BANK_D, EXTENDRAM_OFFSET, extendRam); + writeAddr ((data_t*) LCDC_BANK_D, DEBUGMODE_OFFSET, debugMode); // nocashMessage("irqDisable(IRQ_ALL);"); irqDisable(IRQ_ALL); diff --git a/arm9/source/launch_engine.h b/arm9/source/launch_engine.h index a65a56c..bf79578 100644 --- a/arm9/source/launch_engine.h +++ b/arm9/source/launch_engine.h @@ -25,7 +25,7 @@ extern "C" { #endif -void runLaunchEngine (bool EnableSD, int language, bool scfgUnlock, bool TWLMODE, bool TWLCLK, bool TWLVRAM, bool soundFreq, bool extendRam); +void runLaunchEngine (bool EnableSD, int language, bool scfgUnlock, bool TWLMODE, bool TWLCLK, bool TWLVRAM, bool soundFreq, bool extendRam, bool debugMode); #ifdef __cplusplus } diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 40501d0..06f3fda 100755 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -59,7 +59,7 @@ int main() { bool TWLVRAM = false; bool soundFreq = false; bool EnableSD = false; - bool slot1Init = false; + bool slot1Init = false; bool UseAnimatedSplash = false; bool UseNTRSplash = true; @@ -67,24 +67,30 @@ int main() { int language = -1; + bool DebugMode = false; + u32 ndsHeader[0x80]; if (fatInitDefault()) { - CIniFile ntrlauncher_config( "sd:/nds/NTR_Launcher.ini" ); + CIniFile ntrlauncher_config( "sd:/NDS/NTR_Launcher.ini" ); TWLCLK = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLCLOCK",0); TWLVRAM = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLVRAM",0); TWLEXTRAM = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLEXTRAM",0); TWLMODE = ntrlauncher_config.GetInt("NTRLAUNCHER","TWLMODE",0); soundFreq = ntrlauncher_config.GetInt("NTRLAUNCHER","SOUNDFREQ",0); + // EnableSD = ntrlauncher_config.GetInt("NTRLAUNCHER","SDACCESS",0); scfgUnlock = ntrlauncher_config.GetInt("NTRLAUNCHER","SCFGUNLOCK",0); - language = ntrlauncher_config.GetInt("NTRLAUNCHER", "LANGUAGE", -1); - slot1Init = ntrlauncher_config.GetInt("NTRLAUNCHER","RESETSLOT1",0); - + slot1Init = ntrlauncher_config.GetInt("NTRLAUNCHER","RESETSLOT1",0); UseAnimatedSplash = ntrlauncher_config.GetInt("NTRLAUNCHER","ANIMATEDSPLASH",0); UseNTRSplash = ntrlauncher_config.GetInt("NTRLAUNCHER","NTRSPLASH",0); HealthAndSafety_MSG = ntrlauncher_config.GetInt("NTRLAUNCHER","HEALTHSAFETYSPLASH",0); - + + DebugMode = ntrlauncher_config.GetInt("NTRLAUNCHER","DEBUGMODE",0); + + language = ntrlauncher_config.GetInt("NTRLAUNCHER", "LANGUAGE", -1); + + if(slot1Init) { fifoSendValue32(FIFO_USER_04, 1); for (int i = 0; i < 25; i++) { swiWaitForVBlank(); } @@ -122,11 +128,6 @@ int main() { // inserted. if(REG_SCFG_MC == 0x10) { fifoSendValue32(FIFO_USER_02, 1); } - if( TWLCLK == false ) { - REG_SCFG_CLK = 0x80; - swiWaitForVBlank(); - } - fifoSendValue32(FIFO_USER_01, 1); fifoWaitValue32(FIFO_USER_03); @@ -149,7 +150,7 @@ int main() { } break; } else { - runLaunchEngine (EnableSD, language, scfgUnlock, TWLMODE, TWLCLK, TWLVRAM, soundFreq, TWLEXTRAM); + runLaunchEngine (EnableSD, language, scfgUnlock, TWLMODE, TWLCLK, TWLVRAM, soundFreq, TWLEXTRAM, DebugMode); } } return 0; diff --git a/arm9/source/nds_card.c b/arm9/source/nds_card.c deleted file mode 100755 index bf21207..0000000 --- a/arm9/source/nds_card.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - NitroHax -- Cheat tool for the Nintendo DS - Copyright (C) 2008 Michael "Chishm" Chisholm - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include -#include "nds_card.h" - -void getHeader (u32* ndsHeader) { - cardParamCommand (CARD_CMD_DUMMY, 0, - CARD_ACTIVATE | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), - NULL, 0); - - cardParamCommand(CARD_CMD_HEADER_READ, 0, - CARD_ACTIVATE | CARD_nRESET | CARD_CLK_SLOW | CARD_BLK_SIZE(1) | CARD_DELAY1(0x1FFF) | CARD_DELAY2(0x3F), - ndsHeader, 512); - -} - diff --git a/arm9/source/nds_card.h b/arm9/source/nds_card.h deleted file mode 100755 index 0d49105..0000000 --- a/arm9/source/nds_card.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - NitroHax -- Cheat tool for the Nintendo DS - Copyright (C) 2008 Michael "Chishm" Chisholm - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef NDS_CARD_H -#define NDS_CARD_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -void getHeader (u32* ndsHeader); - -void SwitchToNTRCARD(); - -void SwitchToTWLCARD(); - - -#ifdef __cplusplus -} -#endif - -#endif // NDS_CARD_H diff --git a/icon.bmp b/icon.bmp index 1f215ec..8c649ea 100755 Binary files a/icon.bmp and b/icon.bmp differ