diff --git a/retail/Makefile b/retail/Makefile index 8ea669720..96cb5cd76 100644 --- a/retail/Makefile +++ b/retail/Makefile @@ -128,7 +128,7 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) export GAME_ICON := $(CURDIR)/$(ASSETS)/icon.bmp #.PHONY: cardengine_arm7 cardengine_arm9 bootloader BootStrap clean -.PHONY: all dist release nightly bootloader bootloader2 bootloaderi bootloaderi2 cardengine_arm7 cardengine_arm9_igm cardengine_arm9_igm_extmem cardengine_arm9 cardengine_arm9_start cardengine_arm9_alt cardengine_arm9_alt2 cardengine_arm9_extmem cardenginei_arm7 cardenginei_arm7_alt cardenginei_arm7_twlsdk cardenginei_arm7_twlsdk3 cardenginei_arm7_dsiware cardenginei_arm7_dsiware3 cardenginei_arm7_cheat cardenginei_arm9_igm cardenginei_arm9 cardenginei_arm9_alt cardenginei_arm9_alt2 cardenginei_arm9_gsdd cardenginei_arm9_gsdd_alt cardenginei_arm9_dldi cardenginei_arm9_gsdd_dldi cardenginei_arm9_twlsdk cardenginei_arm9_twlsdk3 cardenginei_arm9_twlsdk_dldi cardenginei_arm9_twlsdk3_dldi cardenginei_arm9_dsiware cardenginei_arm9_dsiware3 arm7/$(TARGET).elf arm9/$(TARGET).elf clean +.PHONY: all dist release nightly bootloader bootloader2 bootloaderi bootloaderi2 cardengine_arm7 cardengine_arm9_igm cardengine_arm9_igm_extmem cardengine_arm9 cardengine_arm9_start cardengine_arm9_alt cardengine_arm9_alt2 cardengine_arm9_extmem cardenginei_arm7 cardenginei_arm7_alt cardenginei_arm7_twlsdk cardenginei_arm7_twlsdk3 cardenginei_arm7_dsiware cardenginei_arm7_dsiware3 cardenginei_arm7_cheat cardenginei_arm9_igm cardenginei_arm9 cardenginei_arm9_alt cardenginei_arm9_alt2 cardenginei_arm9_dlp cardenginei_arm9_gsdd cardenginei_arm9_gsdd_alt cardenginei_arm9_dldi cardenginei_arm9_gsdd_dldi cardenginei_arm9_twlsdk cardenginei_arm9_twlsdk3 cardenginei_arm9_twlsdk_dldi cardenginei_arm9_twlsdk3_dldi cardenginei_arm9_dsiware cardenginei_arm9_dsiware3 arm7/$(TARGET).elf arm9/$(TARGET).elf clean all: $(OUTPUT) @@ -169,7 +169,7 @@ bootloader2: $(DATA) @$(MAKE) -C bootloader2 #--------------------------------------------------------------------------------- -bootloaderi: $(DATA) cardenginei_arm7 cardenginei_arm7_alt cardenginei_arm7_twlsdk cardenginei_arm7_twlsdk3 cardenginei_arm7_dsiware cardenginei_arm7_dsiware3 cardenginei_arm7_cheat cardenginei_arm9_igm cardenginei_arm9 cardenginei_arm9_alt cardenginei_arm9_alt2 cardenginei_arm9_gsdd cardenginei_arm9_gsdd_alt cardenginei_arm9_dldi cardenginei_arm9_gsdd_dldi cardenginei_arm9_twlsdk cardenginei_arm9_twlsdk3 cardenginei_arm9_twlsdk_dldi cardenginei_arm9_twlsdk3_dldi cardenginei_arm9_dsiware cardenginei_arm9_dsiware3 +bootloaderi: $(DATA) cardenginei_arm7 cardenginei_arm7_alt cardenginei_arm7_twlsdk cardenginei_arm7_twlsdk3 cardenginei_arm7_dsiware cardenginei_arm7_dsiware3 cardenginei_arm7_cheat cardenginei_arm9_igm cardenginei_arm9 cardenginei_arm9_alt cardenginei_arm9_alt2 cardenginei_arm9_dlp cardenginei_arm9_gsdd cardenginei_arm9_gsdd_alt cardenginei_arm9_dldi cardenginei_arm9_gsdd_dldi cardenginei_arm9_twlsdk cardenginei_arm9_twlsdk3 cardenginei_arm9_twlsdk_dldi cardenginei_arm9_twlsdk3_dldi cardenginei_arm9_dsiware cardenginei_arm9_dsiware3 @$(MAKE) -C bootloaderi #--------------------------------------------------------------------------------- @@ -252,6 +252,10 @@ cardenginei_arm9_alt: $(DATA) cardenginei_arm9_alt2: $(DATA) @$(MAKE) -C cardenginei/arm9_alt2 +#--------------------------------------------------------------------------------- +cardenginei_arm9_dlp: $(DATA) + @$(MAKE) -C cardenginei/arm9_dlp + #--------------------------------------------------------------------------------- cardenginei_arm9_gsdd: $(DATA) @$(MAKE) -C cardenginei/arm9_gsdd @@ -323,6 +327,7 @@ clean: @$(MAKE) -C cardenginei/arm9 clean @$(MAKE) -C cardenginei/arm9_alt clean @$(MAKE) -C cardenginei/arm9_alt2 clean + @$(MAKE) -C cardenginei/arm9_dlp clean @$(MAKE) -C cardenginei/arm9_gsdd clean @$(MAKE) -C cardenginei/arm9_gsdd_alt clean @$(MAKE) -C cardenginei/arm9_dldi clean diff --git a/retail/arm9/source/conf_sd.cpp b/retail/arm9/source/conf_sd.cpp index e0c1514a9..fdf533d24 100644 --- a/retail/arm9/source/conf_sd.cpp +++ b/retail/arm9/source/conf_sd.cpp @@ -1166,7 +1166,8 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { conf->dsiWramAccess = true; } if (conf->dsiWramAccess) { - if (strncmp(romTid, "ADA", 3) == 0 // Diamond + if (strncmp(romTid, "HND", 3) == 0 // DS Download Play + || strncmp(romTid, "ADA", 3) == 0 // Diamond || strncmp(romTid, "APA", 3) == 0 // Pearl || strncmp(romTid, "Y3E", 3) == 0 // 2006-Nen 10-Gatsu Taikenban Soft || strncmp(romTid, "CPU", 3) == 0 // Platinum @@ -1235,6 +1236,7 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { } fclose(cebin); + const bool dlp = (memcmp(romTid, "HND", 3) == 0); const bool gsdd = (memcmp(romTid, "BO5", 3) == 0); if (conf->gameOnFlashcard) { @@ -1252,7 +1254,9 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { fclose(cebin); } else { const char* ce9Path = conf->dsiWramAccess ? "nitro:/cardenginei_arm9.lz77" : "nitro:/cardenginei_arm9_alt.lz77"; - if (gsdd) { + if (dlp) { + ce9Path = "nitro:/cardenginei_arm9_dlp.lz77"; + } else if (gsdd) { ce9Path = conf->dsiWramAccess ? "nitro:/cardenginei_arm9_gsdd.lz77" : "nitro:/cardenginei_arm9_gsdd_alt.lz77"; } @@ -1264,7 +1268,7 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) { } fclose(cebin); - if (!conf->dsiWramAccess && !gsdd) { + if (!conf->dsiWramAccess && !dlp && !gsdd) { // Load ce9 binary (alt 2) cebin = fopen("nitro:/cardenginei_arm9_alt2.lz77", "rb"); if (cebin) { diff --git a/retail/bootloaderi/source/arm7/find_arm9.c b/retail/bootloaderi/source/arm7/find_arm9.c index 67b47e26f..6d8563228 100644 --- a/retail/bootloaderi/source/arm7/find_arm9.c +++ b/retail/bootloaderi/source/arm7/find_arm9.c @@ -2602,7 +2602,7 @@ u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* modu if (moduleParams->sdk_version > 0x5000000) { return findCardEndReadDmaSdk5(ndsHeader,moduleParams,usesThumb); - } + } const u32* offsetDmaHandler = NULL; if (moduleParams->sdk_version < 0x4000000) { @@ -2736,11 +2736,11 @@ u32* findCardSetDmaSdk5(const tNDSHeader* ndsHeader, const module_params_t* modu u32* findCardSetDma(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { dbg_printf("findCardSetDma\n"); - + if (moduleParams->sdk_version > 0x5000000) { return findCardSetDmaSdk5(ndsHeader,moduleParams,usesThumb); - } - + } + //const u16* cardSetDmaSignatureStartThumb = cardSetDmaSignatureStartThumb4; const u32* cardSetDmaSignatureStart = cardSetDmaSignatureStart4; int cardSetDmaSignatureStartLen = 3; diff --git a/retail/bootloaderi/source/arm7/hook_arm7.c b/retail/bootloaderi/source/arm7/hook_arm7.c index a5ae47bb9..8836c4a39 100644 --- a/retail/bootloaderi/source/arm7/hook_arm7.c +++ b/retail/bootloaderi/source/arm7/hook_arm7.c @@ -54,6 +54,7 @@ #define b_dsiBios BIT(18) #define b_bootstrapOnFlashcard BIT(19) #define b_ndmaDisabled BIT(20) +#define b_isDlp BIT(21) #define b_scfgLocked BIT(31) extern u32 newArm7binarySize; @@ -399,6 +400,9 @@ int hookNdsRetailArm7( if (ndmaDisabled) { ce7->valueBits |= b_ndmaDisabled; } + if (strncmp(romTid, "HND", 3) == 0) { + ce7->valueBits |= b_isDlp; + } if (REG_SCFG_EXT == 0) { ce7->valueBits |= b_scfgLocked; } diff --git a/retail/bootloaderi/source/arm7/hook_arm9.c b/retail/bootloaderi/source/arm7/hook_arm9.c index 8239d50d3..20d6c397a 100644 --- a/retail/bootloaderi/source/arm7/hook_arm9.c +++ b/retail/bootloaderi/source/arm7/hook_arm9.c @@ -26,6 +26,7 @@ #define b_asyncCardRead BIT(12) #define b_softResetMb BIT(13) #define b_cloneboot BIT(14) +#define b_isDlp BIT(15) static const int MAX_HANDLER_LEN = 50; @@ -329,6 +330,9 @@ int hookNdsRetailArm9( if (usesCloneboot) { ce9->valueBits |= b_cloneboot; } + if (strncmp(romTid, "HND", 3) == 0) { + ce9->valueBits |= b_isDlp; + } ce9->mainScreen = mainScreen; ce9->overlaysSize = overlaysSize; ce9->romPaddingSize = romPaddingSize; diff --git a/retail/bootloaderi/source/arm7/main.arm7.c b/retail/bootloaderi/source/arm7/main.arm7.c index 0602f0aea..83542643f 100644 --- a/retail/bootloaderi/source/arm7/main.arm7.c +++ b/retail/bootloaderi/source/arm7/main.arm7.c @@ -1588,6 +1588,9 @@ int arm7_main(void) { extern u32 clusterCache; u32 add = (moduleParams->sdk_version >= 0x2008000 || moduleParams->sdk_version == 0x20029A8) ? 0xC8000 : 0xE8000; // 0x027C8000 : 0x027E8000 + if (memcmp(romTid, "HND", 3) == 0) { + add = 0x108000; // 0x02808000 + } tonccpy((char*)0x02700000+add, (char*)0x02700000, 0x10000); // Move FAT table cache elsewhere romFile->fatTableCache = (u32*)((u32)romFile->fatTableCache+add); savFile->fatTableCache = (u32*)((u32)savFile->fatTableCache+add); @@ -2011,6 +2014,9 @@ int arm7_main(void) { } else { const bool laterSdk = (moduleParams->sdk_version >= 0x2008000 || moduleParams->sdk_version == 0x20029A8); ce9Location = dsiWramAccess ? CARDENGINEI_ARM9_LOCATION_DSI_WRAM : (!laterSdk ? CARDENGINEI_ARM9_LOCATION2 : CARDENGINEI_ARM9_LOCATION); + if (memcmp(romTid, "HND", 3) == 0) { + ce9Location = CARDENGINEI_ARM9_LOCATION_DLP; + } ce9size = 0x5000; tonccpy((u32*)ce9Location, (u32*)((!dsiWramAccess && !laterSdk) ? CARDENGINEI_ARM9_BUFFERED_LOCATION2 : CARDENGINEI_ARM9_BUFFERED_LOCATION), ce9size); } diff --git a/retail/bootloaderi/source/arm7/patch_arm9.c b/retail/bootloaderi/source/arm7/patch_arm9.c index ffc56bb15..903bdb0d6 100644 --- a/retail/bootloaderi/source/arm7/patch_arm9.c +++ b/retail/bootloaderi/source/arm7/patch_arm9.c @@ -2518,9 +2518,9 @@ u32 patchCardNdsArm9(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const mod if (strncmp(romTid, "UOR", 3) == 0) { // Start at 0x2003800 for "WarioWare: DIY" startOffset = (u32)ndsHeader->arm9destination + 0x3800; } else if (strncmp(romTid, "UXB", 3) == 0) { // Start at 0x2080000 for "Jam with the Band" - startOffset = (u32)ndsHeader->arm9destination + 0x80000; + startOffset = (u32)ndsHeader->arm9destination + 0x80000; } else if (strncmp(romTid, "USK", 3) == 0) { // Start at 0x20E8000 for "Face Training" - startOffset = (u32)ndsHeader->arm9destination + 0xE4000; + startOffset = (u32)ndsHeader->arm9destination + 0xE4000; } dbg_printf("startOffset : "); diff --git a/retail/cardenginei/arm7/include/patcher/find.h b/retail/cardenginei/arm7/include/patcher/find.h index c1cb7d051..c9c91ba5e 100644 --- a/retail/cardenginei/arm7/include/patcher/find.h +++ b/retail/cardenginei/arm7/include/patcher/find.h @@ -11,7 +11,10 @@ // COMMON //u8* memsearch(const u8* start, u32 dataSize, const u8* find, u32 findSize); u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, bool forward); +u32* memsearch32_2(const u32* start, u32 dataSize, const u32* find, const u32* find2, u32 findSize, bool forward); +u32* memsearch32_3(const u32* start, u32 dataSize, const u32* find, const u32* find2, const u32* find3, u32 findSize, bool forward); u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward); +u16* memsearch16_4(const u16* start, u32 dataSize, const u16* find, const u16* find2, const u16* find3, const u16* find4, u32 findSize, bool forward); inline u32* findOffset(const u32* start, u32 dataSize, const u32* find, u32 findLen) { return memsearch32(start, dataSize, find, findLen*sizeof(u32), true); @@ -19,12 +22,21 @@ inline u32* findOffset(const u32* start, u32 dataSize, const u32* find, u32 find inline u32* findOffsetBackwards(const u32* start, u32 dataSize, const u32* find, u32 findLen) { return memsearch32(start, dataSize, find, findLen*sizeof(u32), false); } +inline u32* findOffsetBackwards2(const u32* start, u32 dataSize, const u32* find, const u32* find2, u32 findLen) { + return memsearch32_2(start, dataSize, find, find2, findLen*sizeof(u32), false); +} +inline u32* findOffsetBackwards3(const u32* start, u32 dataSize, const u32* find, const u32* find2, const u32* find3, u32 findLen) { + return memsearch32_3(start, dataSize, find, find2, find3, findLen*sizeof(u32), false); +} inline u16* findOffsetThumb(const u16* start, u32 dataSize, const u16* find, u32 findLen) { return memsearch16(start, dataSize, find, findLen*sizeof(u16), true); } inline u16* findOffsetBackwardsThumb(const u16* start, u32 dataSize, const u16* find, u32 findLen) { return memsearch16(start, dataSize, find, findLen*sizeof(u16), false); } +inline u16* findOffsetBackwardsThumb4(const u16* start, u32 dataSize, const u16* find, const u16* find2, const u16* find3, const u16* find4, u32 findLen) { + return memsearch16_4(start, dataSize, find, find2, find3, find4, findLen*sizeof(u16), false); +} // ARM9 u32* a9_findSwi12Offset(const tNDSHeader* ndsHeader); @@ -32,13 +44,21 @@ u32* findModuleParamsOffset(const tNDSHeader* ndsHeader); u32* findCardReadEndOffsetType0(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 startOffset); u32* findCardReadEndOffsetType1(const tNDSHeader* ndsHeader, u32 startOffset); u16* findCardReadEndOffsetThumb(const tNDSHeader* ndsHeader, u32 startOffset); +u16* findCardReadEndOffsetThumb5Type0(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 startOffset); // SDK 5 +u16* findCardReadEndOffsetThumb5Type1(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 startOffset); // SDK 5 u32* findCardReadStartOffsetType0(const module_params_t* moduleParams, const u32* cardReadEndOffset); u32* findCardReadStartOffsetType1(const u32* cardReadEndOffset); +u32* findCardReadStartOffset5(const module_params_t* moduleParams, const u32* cardReadEndOffset); // SDK 5 +u32* findCardReadCheckOffsetMvDK4(u32 startOffset); u16* findCardReadStartOffsetThumb(const u16* cardReadEndOffset); +u16* findCardReadStartOffsetThumb5Type0(const module_params_t* moduleParams, const u16* cardReadEndOffset); // SDK 5 +u16* findCardReadStartOffsetThumb5Type1(const module_params_t* moduleParams, const u16* cardReadEndOffset); // SDK 5 u32* findCardReadCachedEndOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams); u32* findCardReadCachedStartOffset(const module_params_t* moduleParams, const u32* cardReadCachedEndOffset); u32* findCardPullOutOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams); u16* findCardPullOutOffsetThumb(const tNDSHeader* ndsHeader); +u16* findCardPullOutOffsetThumb5Type0(const tNDSHeader* ndsHeader, const module_params_t* moduleParams); // SDK 5 +u16* findCardPullOutOffsetThumb5Type1(const tNDSHeader* ndsHeader, const module_params_t* moduleParams); // SDK 5 u32* findCardIdEndOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, const u32* cardReadEndOffset); u16* findCardIdEndOffsetThumb(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, const u16* cardReadEndOffset); u32* findCardIdStartOffset(const module_params_t* moduleParams, const u32* cardIdEndOffset); @@ -52,9 +72,11 @@ const u32* getMpuInitRegionSignature(u32 patchMpuRegion); u32* findMpuStartOffset(const tNDSHeader* ndsHeader, u32 patchMpuRegion); u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, const u32* mpuStartOffset); u32* findMpuDataOffsetAlt(const tNDSHeader* ndsHeader); +u32* findMpuChange(const tNDSHeader* ndsHeader); u32* findHeapPointerOffset(const module_params_t* moduleParams, const tNDSHeader* ndsHeader); u32* findHeapPointer2Offset(const module_params_t* moduleParams, const tNDSHeader* ndsHeader); u32* findRandomPatchOffset(const tNDSHeader* ndsHeader); +u32* findRandomPatchOffset5Second(const tNDSHeader* ndsHeader); // SDK 5 u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, bool* usesThumbPtr); u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, const u32* cardReadDmaEndOffset, u32* offsetDmaHandler); u32* findCardSetDma(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb); diff --git a/retail/cardenginei/arm7/source/cardengine.c b/retail/cardenginei/arm7/source/cardengine.c index 908fdbaf7..139876c24 100644 --- a/retail/cardenginei/arm7/source/cardengine.c +++ b/retail/cardenginei/arm7/source/cardengine.c @@ -75,6 +75,7 @@ #define dsiBios BIT(18) #define bootstrapOnFlashcard BIT(19) #define ndmaDisabled BIT(20) +#define isDlp BIT(21) #define scfgLocked BIT(31) #define REG_EXTKEYINPUT (*(vuint16*)0x04000136) @@ -367,6 +368,10 @@ static void initialize(void) { sharedAddr = (vu32*)CARDENGINE_SHARED_ADDRESS_SDK5; ndsHeader = (tNDSHeader*)NDS_HEADER_SDK5; personalData = (PERSONAL_DATA*)((u8*)NDS_HEADER_SDK5-0x180); + } else { + sharedAddr = (vu32*)CARDENGINE_SHARED_ADDRESS_SDK1; + ndsHeader = (tNDSHeader*)NDS_HEADER; + personalData = (PERSONAL_DATA*)((u8*)NDS_HEADER-0x180); } #endif @@ -451,9 +456,11 @@ static void cardReadRAM(u8* dst, u32 src, u32 len/*, int romPartNo*/) { } void reset(void) { + register int i, reg; + #ifndef TWLSDK u32 resetParam = ((valueBits & isSdk5) ? RESET_PARAM_SDK5 : RESET_PARAM); - if ((valueBits & slowSoftReset) || (*(u32*)(resetParam+0xC) > 0 && (*(u32*)CARDENGINEI_ARM9_LOCATION == 0 || (valueBits & isSdk5)))) { + if (((valueBits & isDlp) && *(u32*)(NDS_HEADER_SDK5+0xC) == 0) || (valueBits & slowSoftReset) || (*(u32*)(resetParam+0xC) > 0 && (*(u32*)CARDENGINEI_ARM9_LOCATION == 0 || (valueBits & isSdk5)))) { REG_MASTER_VOLUME = 0; int oldIME = enterCriticalSection(); //driveInitialize(); @@ -480,10 +487,10 @@ void reset(void) { leaveCriticalSection(oldIME); while (1); } + + if (!(valueBits & isDlp)) { #endif - register int i, reg; - REG_IME = 0; for (i = 0; i < 16; i++) { @@ -522,37 +529,52 @@ void reset(void) { *(vu32*)0x0380FFF8 = 0; // VBLANK_INTR_WAIT_FLAGS, ARM7 version REG_POWERCNT = 1; // Turn off power to stuff - initialized = false; funcsUnpatched = false; + +#ifndef TWLSDK + } +#endif + + initialized = false; //ipcSyncHooked = false; languageTimer = 0; #ifndef TWLSDK - if (currentSrlAddr != *(u32*)(resetParam+0xC) || *(u32*)(resetParam+8) == 0x44414F4C) { + if ((valueBits & isDlp) || currentSrlAddr != *(u32*)(resetParam+0xC) || *(u32*)(resetParam+8) == 0x44414F4C) { currentSrlAddr = *(u32*)(resetParam+0xC); - if (*(u32*)(resetParam+8) == 0x44414F4C) { + if (valueBits & isDlp) { ndmaCopyWordsAsynch(1, (u32*)0x022C0000, ndsHeader->arm7destination, ndsHeader->arm7binarySize); - *((u16*)(/*isSdk5(moduleParams) ? 0x02fffc40 :*/ 0x027ffc40)) = 2; // Boot Indicator (Cloneboot/Multiboot) - // tonccpy((u32*)0x027FFC40, (u32*)0x02344820, 0x40); // Multiboot info? - } else if (valueBits & ROMinRAM) { - cardReadRAM((u8*)ndsHeader, currentSrlAddr, 0x160); - cardReadRAM((u8*)ndsHeader->arm9destination, currentSrlAddr+ndsHeader->arm9romOffset, ndsHeader->arm9binarySize); - cardReadRAM((u8*)ndsHeader->arm7destination, currentSrlAddr+ndsHeader->arm7romOffset, ndsHeader->arm7binarySize); + *(u16*)0x02fffc40 = 2; // Boot Indicator (Cloneboot/Multiboot) } else { - fileRead((char*)ndsHeader, romFile, currentSrlAddr, 0x160); - fileRead((char*)ndsHeader->arm9destination, romFile, currentSrlAddr+ndsHeader->arm9romOffset, ndsHeader->arm9binarySize); - fileRead((char*)ndsHeader->arm7destination, romFile, currentSrlAddr+ndsHeader->arm7romOffset, ndsHeader->arm7binarySize); + if (*(u32*)(resetParam+8) == 0x44414F4C) { + ndmaCopyWordsAsynch(1, (u32*)0x022C0000, ndsHeader->arm7destination, ndsHeader->arm7binarySize); + *((u16*)(/*isSdk5(moduleParams) ? 0x02fffc40 :*/ 0x027ffc40)) = 2; // Boot Indicator (Cloneboot/Multiboot) + // tonccpy((u32*)0x027FFC40, (u32*)0x02344820, 0x40); // Multiboot info? + } else if (valueBits & ROMinRAM) { + cardReadRAM((u8*)ndsHeader, currentSrlAddr, 0x160); + cardReadRAM((u8*)ndsHeader->arm9destination, currentSrlAddr+ndsHeader->arm9romOffset, ndsHeader->arm9binarySize); + cardReadRAM((u8*)ndsHeader->arm7destination, currentSrlAddr+ndsHeader->arm7romOffset, ndsHeader->arm7binarySize); + } else { + fileRead((char*)ndsHeader, romFile, currentSrlAddr, 0x160); + fileRead((char*)ndsHeader->arm9destination, romFile, currentSrlAddr+ndsHeader->arm9romOffset, ndsHeader->arm9binarySize); + fileRead((char*)ndsHeader->arm7destination, romFile, currentSrlAddr+ndsHeader->arm7romOffset, ndsHeader->arm7binarySize); + } } moduleParams = getModuleParams(ndsHeader); /*dbg_printf("sdk_version: "); dbg_hexa(moduleParams->sdk_version); dbg_printf("\n");*/ + if (moduleParams->sdk_version > 0x5000000) { + valueBits |= isSdk5; + } else { + valueBits &= ~isSdk5; + } - ensureBinaryDecompressed(ndsHeader, moduleParams, resetParam); + ensureBinaryDecompressed(ndsHeader, moduleParams, (valueBits & isDlp) ? 0x44414F4 : resetParam); patchCardNdsArm9( - (cardengineArm9*)CARDENGINEI_ARM9_LOCATION, + (cardengineArm9*)((valueBits & isDlp) ? CARDENGINEI_ARM9_LOCATION_DLP : CARDENGINEI_ARM9_LOCATION), ndsHeader, moduleParams, 1 @@ -582,7 +604,15 @@ void reset(void) { ndmaCopyWordsAsynch(1, ndsHeader->arm7destination, (char*)DONOR_ROM_ARM7_LOCATION, ndsHeader->arm7binarySize); while (ndmaBusy(0) || ndmaBusy(1)); } */ - *(u32*)(resetParam+8) = 0; + if (valueBits & isDlp) { + toncset((u32*)0x022C0000, 0, ndsHeader->arm7binarySize); + if (!(valueBits & isSdk5)) { + tonccpy((u8*)0x027FF000, (u8*)0x02FFF000, 0x1000); + } + } else { + *(u32*)(resetParam+8) = 0; + } + valueBits &= ~isDlp; } else { //driveInitialize(); @@ -1574,6 +1604,15 @@ void myIrqHandlerVBlank(void) { i2cWriteRegister(0x4A, 0x11, 0x01); // Reboot into error screen if SD card is removed } +#ifndef TWLSDK + if (valueBits & isDlp) { + if (!(REG_EXTKEYINPUT & KEY_A) && *(u32*)(NDS_HEADER_SDK5+0xC) != 0 && !wifiIrq) { + IPC_SendSync(0x5); + reset(); + } + } +#endif + if ((0 == (REG_KEYINPUT & igmHotkey) && 0 == (REG_EXTKEYINPUT & (((igmHotkey >> 10) & 3) | ((igmHotkey >> 6) & 0xC0))) && (valueBits & igmAccessible) && !wifiIrq) || returnToMenu || sharedAddr[5] == 0x4C4D4749 /* IGML */) { #ifdef TWLSDK igmText = (struct IgmText *)INGAME_MENU_LOCATION; diff --git a/retail/cardenginei/arm7/source/patcher/find_arm7.c b/retail/cardenginei/arm7/source/patcher/find_arm7.c index 7ffcfc624..2b87314c0 100644 --- a/retail/cardenginei/arm7/source/patcher/find_arm7.c +++ b/retail/cardenginei/arm7/source/patcher/find_arm7.c @@ -8,9 +8,11 @@ // static const u32 relocateStartSignature[1] = {0x027FFFFA}; +static const u32 relocateStartSignature5[1] = {0x3381C0DE}; // 33 81 C0 DE DE C0 81 33 00 00 00 00 is the marker for the beggining of the relocated area :-) +static const u32 relocateStartSignature5Alt[1] = {0x2106C0DE}; static const u32 nextFunctiontSignature[1] = {0xE92D4000}; -// static const u32 relocateValidateSignature[1] = {0x400010C}; +static const u32 relocateValidateSignature[1] = {0x400010C}; static const u32 swi12Signature[1] = {0x4770DF12}; // LZ77UnCompReadByCallbackWrite16bit @@ -30,6 +32,8 @@ static const u32 swiGetPitchTableSignature1Alt10[3] = {0xE59FC000, 0xE12FFF1C, 0 static const u32 swiGetPitchTableSignature1Alt11[3] = {0xE59FC000, 0xE12FFF1C, 0x03804189}; static const u32 swiGetPitchTableSignature1Alt12[3] = {0xE59FC000, 0xE12FFF1C, 0x038049D5}; static const u32 swiGetPitchTableSignature1Alt13[3] = {0xE59FC000, 0xE12FFF1C, 0x03804BE9}; +static const u32 swiGetPitchTableSignature1Alt14[3] = {0xE59FC000, 0xE12FFF1C, 0x03804E35}; +static const u32 swiGetPitchTableSignature1Alt15[3] = {0xE59FC000, 0xE12FFF1C, 0x03800D89}; static const u32 swiGetPitchTableSignature3[3] = {0xE59FC000, 0xE12FFF1C, 0x03800FD5}; static const u32 swiGetPitchTableSignature3Alt1[3] = {0xE59FC000, 0xE12FFF1C, 0x03801149}; static const u32 swiGetPitchTableSignature3Alt2[3] = {0xE59FC000, 0xE12FFF1C, 0x03801215}; @@ -53,6 +57,7 @@ static const u32 swiGetPitchTableSignature4Alt6[3] = {0xE59FC000, 0xE12FFF1C, 0 static const u32 swiGetPitchTableSignature4Alt7[3] = {0xE59FC000, 0xE12FFF1C, 0x03803829}; static const u32 swiGetPitchTableSignature4Alt8[3] = {0xE59FC000, 0xE12FFF1C, 0x03803ED5}; static const u32 swiGetPitchTableSignature4Alt9[3] = {0xE59FC000, 0xE12FFF1C, 0x03803F15}; +static const u32 swiGetPitchTableSignature5[4] = {0x781A4B06, 0xD3030791, 0xD20106D1, 0x1A404904}; // Sleep patch static const u32 sleepPatch[2] = {0x0A000001, 0xE3A00601}; @@ -67,11 +72,68 @@ static const u32 cardCheckPullOutSignature3[4] = {0xE92D4000, 0xE24DD004, 0xE59F // irq enable static const u32 irqEnableStartSignature1[4] = {0xE59FC028, 0xE1DC30B0, 0xE3A01000, 0xE1CC10B0}; // SDK <= 3 static const u32 irqEnableStartSignature4[4] = {0xE92D4010, 0xE1A04000, 0xEBFFFFF6, 0xE59FC020}; // SDK >= 4 +static const u32 irqEnableStartSignature4Alt[4] = {0xE92D4010, 0xE1A04000, 0xEBFFFFE9, 0xE59FC020}; // SDK 5 +static const u16 irqEnableStartSignatureThumb[5] = {0xB530, 0xB081, 0x4D07, 0x882C, 0x2100}; +static const u16 irqEnableStartSignatureThumb3[5] = {0xB510, 0x1C04, 0xF7FF, 0xFFF4, 0x4B05}; // SDK 3 +static const u16 irqEnableStartSignatureThumb5[5] = {0xB510, 0x1C04, 0xF7FF, 0xFFE4, 0x4B05}; // SDK 5 +u32 relocationStart = 0; bool a7GetReloc(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { extern u32 vAddrOfRelocSrc; extern u32 relocDestAtSharedMem; + if (moduleParams->sdk_version > 0x5000000) { + // Find the relocation signature + relocationStart = (u32)findOffset( + (u32*)ndsHeader->arm7destination, 0x800, + relocateStartSignature5, 1 + ); + if (!relocationStart) { + // dbg_printf("Relocation start not found. Trying alt\n"); + relocationStart = (u32)findOffset( + (u32*)ndsHeader->arm7destination, 0x800, + relocateStartSignature5Alt, 1 + ); + if (relocationStart>0) relocationStart += 0x28; + } + if (!relocationStart) { + // dbg_printf("Relocation start alt not found\n"); + return false; + } + + // Validate the relocation signature + vAddrOfRelocSrc = relocationStart + 0x8; + // sanity checks + u32 relocationCheck = (u32)findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + relocateValidateSignature, 1 + ); + u32 relocationCheck2 = + *(u32*)(relocationCheck - 0x4); + + relocDestAtSharedMem = 0x37F8000; + if (relocationCheck + 0xC - vAddrOfRelocSrc + relocDestAtSharedMem > relocationCheck2) { + relocationCheck -= 4; + } + if (relocationCheck + 0xC - vAddrOfRelocSrc + relocDestAtSharedMem > relocationCheck2) { + relocationCheck += 4; + /* dbg_printf("Error in relocation checking\n"); + dbg_hexa(relocationCheck + 0xC - vAddrOfRelocSrc + relocDestAtSharedMem); + dbg_printf(" "); + dbg_hexa(relocationCheck2); + dbg_printf("\n"); */ + + vAddrOfRelocSrc = relocationCheck + 0xC - relocationCheck2 + relocDestAtSharedMem; + // dbg_printf("vAddrOfRelocSrc: "); + } /* else { + dbg_printf("Relocation src: "); + } + dbg_hexa(vAddrOfRelocSrc); + dbg_printf("\n"); */ + + return true; + } + // Find the relocation signature u32 relocationStart = (u32)findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, @@ -187,402 +249,440 @@ u16* findSwiGetPitchTableThumbBranchOffset(const tNDSHeader* ndsHeader) { } u32* findSwiGetPitchTableOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { - //dbg_printf("findSwiGetPitchTableOffset:\n"); + // dbg_printf("findSwiGetPitchTableOffset:\n"); - u32* swiGetPitchTableOffset = findOffset( - (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, - swiGetPitchTableSignature1, 4 - ); - /*if (swiGetPitchTableOffset) { - dbg_printf("swiGetPitchTable SDK <= 2 call found\n"); - } else { - dbg_printf("swiGetPitchTable SDK <= 2 call not found\n"); - }*/ + u32* swiGetPitchTableOffset = NULL; + + if (moduleParams->sdk_version > 0x5000000) { + swiGetPitchTableOffset = findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, + swiGetPitchTableSignature5, 4 + ); + /* if (swiGetPitchTableOffset) { + dbg_printf("swiGetPitchTable call SDK 5 found\n"); + } else { + dbg_printf("swiGetPitchTable call SDK 5 not found\n"); + } */ + } + + if (!swiGetPitchTableOffset) { + swiGetPitchTableOffset = findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, + swiGetPitchTableSignature1, 4 + ); + /* if (swiGetPitchTableOffset) { + dbg_printf("swiGetPitchTable SDK <= 2 call found\n"); + } else { + dbg_printf("swiGetPitchTable SDK <= 2 call not found\n"); + } */ + } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt1, 4 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 1 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 1 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt2, 4 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 2 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 2 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt3, 4 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 3 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 3 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt4, 4 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 4 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 4 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt5, 4 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 5 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 5 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt6, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 6 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 6 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt7, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 7 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 7 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt8, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 8 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 8 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt9, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 9 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 9 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt10, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 10 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 10 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt11, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 11 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 11 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt12, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 12 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 12 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature1Alt13, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK <= 2 call alt 13 found\n"); } else { dbg_printf("swiGetPitchTable SDK <= 2 call alt 13 not found\n"); - }*/ + } */ + } + if (!swiGetPitchTableOffset) { + swiGetPitchTableOffset = findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, + swiGetPitchTableSignature1Alt14, 3 + ); + /* if (swiGetPitchTableOffset) { + dbg_printf("swiGetPitchTable SDK <= 2 call alt 14 found\n"); + } else { + dbg_printf("swiGetPitchTable SDK <= 2 call alt 14 not found\n"); + } */ + } + if (!swiGetPitchTableOffset) { + swiGetPitchTableOffset = findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, + swiGetPitchTableSignature1Alt15, 3 + ); + /* if (swiGetPitchTableOffset) { + dbg_printf("swiGetPitchTable SDK <= 2 call alt 15 found\n"); + } else { + dbg_printf("swiGetPitchTable SDK <= 2 call alt 15 not found\n"); + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt1, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 1 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 1 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt2, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 2 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 2 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt3, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 3 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 3 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt4, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 4 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 4 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt5, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 5 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 5 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt6, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 6 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 6 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt7, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 7 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 7 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt8, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 8 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 8 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt9, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 9 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 9 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt10, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 10 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 10 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt11, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 11 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 11 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature3Alt12, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 3 call alt 12 found\n"); } else { dbg_printf("swiGetPitchTable SDK 3 call alt 12 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt1, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 1 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 1 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt2, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 2 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 2 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt3, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 3 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 3 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt4, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 4 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 4 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt5, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 5 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 5 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt6, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 6 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 6 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt7, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 7 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 7 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { swiGetPitchTableOffset = findOffset( (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt8, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 8 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 8 not found\n"); - }*/ + } */ } if (!swiGetPitchTableOffset) { @@ -590,14 +690,14 @@ u32* findSwiGetPitchTableOffset(const tNDSHeader* ndsHeader, const module_params (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize > 0x10000 ? 0x10000 : ndsHeader->arm7binarySize, swiGetPitchTableSignature4Alt9, 3 ); - /*if (swiGetPitchTableOffset) { + /* if (swiGetPitchTableOffset) { dbg_printf("swiGetPitchTable SDK 4 call alt 9 found\n"); } else { dbg_printf("swiGetPitchTable SDK 4 call alt 9 not found\n"); - }*/ + } */ } - //dbg_printf("\n"); + // dbg_printf("\n"); return swiGetPitchTableOffset; } @@ -687,10 +787,10 @@ u32* findCardCheckPullOutOffset(const tNDSHeader* ndsHeader, const module_params } u32* findCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { - //dbg_printf("findCardIrqEnableOffset:\n"); + // dbg_printf("findCardIrqEnableOffset:\n"); const u32* irqEnableStartSignature = irqEnableStartSignature1; - if (moduleParams->sdk_version > 0x4000000) { + if (ndsHeader->arm7binarySize != 0x289C0 && moduleParams->sdk_version > 0x4000000) { irqEnableStartSignature = irqEnableStartSignature4; } @@ -698,11 +798,11 @@ u32* findCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_t* (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, irqEnableStartSignature, 4 ); - /*if (cardIrqEnableOffset) { + /* if (cardIrqEnableOffset) { dbg_printf("irq enable found\n"); } else { dbg_printf("irq enable not found\n"); - }*/ + } */ if (!cardIrqEnableOffset && moduleParams->sdk_version < 0x4000000) { // SDK 4 @@ -710,11 +810,69 @@ u32* findCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_t* (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, irqEnableStartSignature4, 4 ); - /*if (cardIrqEnableOffset) { + /* if (cardIrqEnableOffset) { dbg_printf("irq enable SDK 4 found\n"); } else { dbg_printf("irq enable SDK 4 not found\n"); - }*/ + } */ + } + + if (!cardIrqEnableOffset) { + // SDK 5 + cardIrqEnableOffset = findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + irqEnableStartSignature4Alt, 4 + ); + /* if (cardIrqEnableOffset) { + dbg_printf("irq enable alt found\n"); + } else { + dbg_printf("irq enable alt not found\n"); + } */ + } + + if (!cardIrqEnableOffset) { + cardIrqEnableOffset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + irqEnableStartSignatureThumb, 5 + ); + if (cardIrqEnableOffset) { + // Find again + cardIrqEnableOffset = (u32*)findOffsetThumb( + (u16*)cardIrqEnableOffset+4, ndsHeader->arm7binarySize, + irqEnableStartSignatureThumb, 5 + ); + } + /* if (cardIrqEnableOffset) { + dbg_printf("irq enable thumb found\n"); + } else { + dbg_printf("irq enable thumb not found\n"); + } */ + } + + if (!cardIrqEnableOffset) { + // SDK 3 + cardIrqEnableOffset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + irqEnableStartSignatureThumb3, 5 + ); + /* if (cardIrqEnableOffset) { + dbg_printf("irq enable thumb SDK 3 found\n"); + } else { + dbg_printf("irq enable thumb SDK 3 not found\n"); + } */ + } + + if (!cardIrqEnableOffset && moduleParams->sdk_version > 0x5000000) { + // SDK 5 + cardIrqEnableOffset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + irqEnableStartSignatureThumb5, 5 + ); + /* if (cardIrqEnableOffset) { + dbg_printf("irq enable thumb SDK 5 found\n"); + } else { + dbg_printf("irq enable thumb SDK 5 not found\n"); + } */ } //dbg_printf("\n"); diff --git a/retail/cardenginei/arm7/source/patcher/find_arm9.c b/retail/cardenginei/arm7/source/patcher/find_arm9.c index 1ed36afa2..156a14d9c 100644 --- a/retail/cardenginei/arm7/source/patcher/find_arm9.c +++ b/retail/cardenginei/arm7/source/patcher/find_arm9.c @@ -22,28 +22,44 @@ static const u32 cardReadEndSignatureAlt[2] = {0x040001A4, 0x04100010}; static const u32 cardReadEndSignatureSdk2Alt[3] = {0x040001A4, 0x04100010, 0xE92D000F}; // SDK 2 static const u32 cardReadEndSignatureAlt2[3] = {0x040001A4, 0x040001A1, 0x04100010}; static const u16 cardReadEndSignatureThumb[4] = {0x01A4, 0x0400, 0x0200, 0x0000}; +static const u16 cardReadEndSignatureThumb5[4] = {0x01A4, 0x0400, 0xFE00, 0xFFFF}; // SDK 5 +static const u16 cardReadEndSignatureThumb5Alt1[5] = {0x01A4, 0x0400, 0x0010, 0x0410, 0xB510}; // SDK 5 static const u32 cardReadStartSignature[1] = {0xE92D4FF0}; static const u32 cardReadStartSignatureAlt[1] = {0xE92D47F0}; static const u32 cardReadStartSignatureAlt2[1] = {0xE92D4070}; +static const u32 cardReadStartSignature5[1] = {0xE92D4FF8}; // SDK 5 +static const u32 cardReadStartSignature5Alt[4] = {0xE92D4010}; // SDK 5.5 +static const u32 cardReadCheckSignatureMvDK4[3] = {0xE5C02289, 0xE5C02288, 0xE5D0028A}; static const u16 cardReadStartSignatureThumb[2] = {0xB5F8, 0xB082}; static const u16 cardReadStartSignatureThumbAlt[2] = {0xB5F0, 0xB083}; +static const u16 cardReadStartSignatureThumb5[1] = {0xB5F0}; // SDK 5 +static const u16 cardReadStartSignatureThumb5Alt[1] = {0xB5F8}; // SDK 5 // Card pull out static const u32 cardPullOutSignature1[4] = {0xE92D4000, 0xE24DD004, 0xE201003F, 0xE3500011}; // SDK <= 3 static const u32 cardPullOutSignature1Elab[5] = {0xE92D4000, 0xE24DD004, 0xE201003F, 0xE3500011, 0x1A00000F}; // SDK 2 static const u32 cardPullOutSignature2Alt[4] = {0xE92D000F, 0xE92D4030, 0xE24DD004, 0xE59D0014}; // SDK 2 static const u32 cardPullOutSignature4[4] = {0xE92D4008, 0xE201003F, 0xE3500011, 0x1A00000D}; // SDK >= 4 +static const u32 cardPullOutSignature5[4] = {0xE92D4010, 0xE201003F, 0xE3500011, 0x1A000012}; // SDK 5 +static const u32 cardPullOutSignature5Alt[4] = {0xE92D4038, 0xE201003F, 0xE3500011, 0x1A000011}; // SDK 5 static const u16 cardPullOutSignatureThumb[5] = {0xB508, 0x203F, 0x4008, 0x2811, 0xD10E}; static const u16 cardPullOutSignatureThumbAlt[4] = {0xB500, 0xB081, 0x203F, 0x4001}; static const u16 cardPullOutSignatureThumbAlt2[4] = {0xB5F8, 0x203F, 0x4008, 0x2811}; +static const u16 cardPullOutSignatureThumb5[4] = {0xB510, 0x203F, 0x4008, 0x2811}; // SDK 5 +static const u16 cardPullOutSignatureThumb5Alt[4] = {0xB538, 0x203F, 0x4008, 0x2811}; // SDK 5 // Card id static const u32 cardIdEndSignature[2] = {0x040001A4, 0x04100010}; +static const u32 cardIdEndSignature5[4] = {0xE8BD8010, 0x02FFFAE0, 0x040001A4, 0x04100010}; // SDK 5 +static const u32 cardIdEndSignature5Alt[3] = {0x02FFFAE0, 0x040001A4, 0x04100010}; // SDK 5 static const u16 cardIdEndSignatureThumb[6] = {0xFFFF, 0xF8FF, 0x01A4, 0x0400, 0x0010, 0x0410}; static const u16 cardIdEndSignatureThumbAlt[6] = {0xFFFF, 0xF8FF, 0x0000, 0xA700, 0xE000, 0xFFFF}; +static const u16 cardIdEndSignatureThumb5[8] = {0xFAE0, 0x02FF, 0xFFFF, 0xF8FF, 0x01A4, 0x0400, 0x0010, 0x0410}; // SDK 5 static const u32 cardIdStartSignature[1] = {0xE92D4000}; static const u32 cardIdStartSignatureAlt1[1] = {0xE92D4008}; static const u32 cardIdStartSignatureAlt2[1] = {0xE92D4010}; +static const u32 cardIdStartSignature5[2] = {0xE92D4010, 0xE3A050B8}; // SDK 5 +static const u32 cardIdStartSignature5Alt[2] = {0xE92D4038, 0xE3A050B8}; // SDK 5 static const u16 cardIdStartSignatureThumb[2] = {0xB500, 0xB081}; static const u16 cardIdStartSignatureThumbAlt1[2] = {0xB508, 0x202E}; static const u16 cardIdStartSignatureThumbAlt2[2] = {0xB508, 0x20B8}; @@ -57,13 +73,17 @@ static const u32 cardReadDmaStartSignature[1] = {0xE92D4FF8}; static const u32 cardReadDmaStartSignatureSdk2Alt[1] = {0xE92D4070}; static const u32 cardReadDmaStartSignatureAlt1[1] = {0xE92D47F0}; static const u32 cardReadDmaStartSignatureAlt2[1] = {0xE92D4FF0}; +static const u32 cardReadDmaStartSignature5[1] = {0xE92D43F8}; // SDK 5 static const u16 cardReadDmaStartSignatureThumb1[1] = {0xB5F0}; // SDK <= 2 static const u16 cardReadDmaStartSignatureThumb3[1] = {0xB5F8}; // SDK >= 3 // Card end read DMA static const u16 cardEndReadDmaSignatureThumb3[1] = {0x481E}; -static const u32 cardEndReadDmaSignature4[1] = {0xE3A00702}; +static const u32 cardEndReadDmaSignature4[1] = {0xE3A00702}; +static const u32 cardEndReadDmaSignature4Alt[1] = {0xE3A04702}; static const u16 cardEndReadDmaSignatureThumb4[2] = {0x2002, 0x0480}; +static const u32 cardEndReadDmaSignature5[4] = {0xE59F0010, 0xE3A02000, 0xE5901000, 0xE5812000}; +static const u16 cardEndReadDmaSignatureThumb5[4] = {0x4803, 0x2200, 0x6801, 0x600A}; // Card set DMA static const u32 cardSetDmaSignatureValue1[1] = {0x4100010}; @@ -74,14 +94,20 @@ static const u32 cardSetDmaSignatureStart2Early[4] = {0xE92D4000, 0xE24DD004, 0 static const u32 cardSetDmaSignatureStart2[3] = {0xE92D4010, 0xE59F403C, 0xE59F103C}; static const u32 cardSetDmaSignatureStart3[3] = {0xE92D4010, 0xE59F4038, 0xE59F1038}; static const u32 cardSetDmaSignatureStart4[3] = {0xE92D4038, 0xE59F4038, 0xE59F1038}; +static const u32 cardSetDmaSignatureStart4Alt[3] = {0xE92D4038, 0xE59F5038, 0xE59F1038}; +static const u32 cardSetDmaSignatureStart5[2] = {0xE92D4070, 0xE1A06000}; +static const u32 cardSetDmaSignatureStart5Alt[2] = {0xE92D4038, 0xE1A05000}; +static const u16 cardSetDmaSignatureStartThumb5[2] = {0xB570, 0x1C05}; // Random patch static const u32 randomPatchSignature[4] = {0xE3500000, 0x1597002C, 0x10406004, 0x03E06000}; +static const u32 randomPatchSignature5Second[3] = {0xE59F003C, 0xE590001C, 0xE3500000}; // SDK 5 // irq enable static const u32 irqEnableStartSignature1[4] = {0xE59FC028, 0xE3A01000, 0xE1DC30B0, 0xE59F2020}; // SDK <= 3 static const u32 irqEnableStartSignature2Alt[4] = {0xE92D000F, 0xE92D4030, 0xE24DD004, 0xEBFFFFDB}; // SDK 2 static const u32 irqEnableStartSignature4[4] = {0xE59F3024, 0xE3A01000, 0xE1D320B0, 0xE1C310B0}; // SDK >= 4 +static const u32 irqEnableStartSignature5Debug[4] = {0xE92D000F, 0xE92D4038, 0xEBFFFFE5, 0xE1A05000}; // IS-TWL-DEBUGGER SDK 5 static const u32 irqEnableStartSignatureThumb[5] = {0x4D07B430, 0x2100882C, 0x4B068029, 0x1C11681A, 0x60194301}; // SDK <= 3 static const u32 irqEnableStartSignatureThumbAlt[4] = {0x4C07B418, 0x88232100, 0x32081C22, 0x68118021}; // SDK >= 3 @@ -91,11 +117,20 @@ static const u32 mpuInitRegion0Data[1] = {0x4000033}; static const u32 mpuInitRegion1Signature[1] = {0xEE060F11}; static const u32 mpuInitRegion1Data1[1] = {0x200002D}; // SDK <= 4 static const u32 mpuInitRegion1DataAlt[1] = {0x200002B}; +static const u32 mpuInitRegion1Data5[1] = {0x2000031}; // SDK 5 static const u32 mpuInitRegion2Signature[1] = {0xEE060F12}; +// static const u32 mpuInitRegion2SignatureElab[2] = {0xEE060F12, 0xE59F00B4}; static const u32 mpuInitRegion2Data1[1] = {0x27C0023}; // SDK <= 2 static const u32 mpuInitRegion2Data3[1] = {0x27E0021}; // SDK >= 2 (Late) +static const u32 mpuInitRegion2Data5[1] = {0x2F80025}; // SDK 5 (TWL) static const u32 mpuInitRegion3Signature[1] = {0xEE060F13}; static const u32 mpuInitRegion3Data[1] = {0x8000035}; +static const u32 mpuChangeRegion1Signature[3] = {0xE3A00001, 0xE3A01402, 0xE3A0202A}; +static const u32 mpuChangeRegion1SignatureAlt[3] = {0x03A0202C, 0xE3A00001, 0xE3A01402}; +static const u16 mpuChangeRegion1SignatureThumb[3] = {0x2001, 0x0609, 0x222A}; +static const u16 mpuChangeRegion1SignatureThumbAlt[3] = {0x2001, 0x0621, 0x222A}; +static const u32 mpuInitRegion3TwlEndSignature[4] = {0xE1A00100, 0xE280062F, 0xE2800AFF, 0xE5900DC4}; +static const u32 mpuInitRegion3TwlEndSignatureThumb[3] = {0x48010081, 0x47705808, 0x02FFFDC4}; //static const u32 operaRamSignature[2] = {0x097FFFFE, 0x09000000}; @@ -105,11 +140,14 @@ static const u16 sleepSignatureThumb2[4] = {0x4010, 0xE92D, 0xD030, 0xE24 static const u32 sleepSignature4[4] = {0xE92D4030, 0xE24DD034, 0xE1A04000, 0xE28D0008}; // sdk4 static const u32 sleepSignature4Alt[4] = {0xE92D4030, 0xE24DD034, 0xE1A05000, 0xE28D0008}; // sdk4 static const u16 sleepSignatureThumb4[4] = {0xB530, 0xB08D, 0x1C04, 0xA802}; // sdk4 +static const u32 sleepSignature5[4] = {0xE92D4030, 0xE24DD034, 0xE28D4008, 0xE1A05000}; // sdk5 +static const u16 sleepSignatureThumb5[4] = {0xB578, 0xB08D, 0xAE02, 0x1C05}; // sdk5 static const u16 sleepConstantValue[1] = {0x82EA}; // Init Heap static const u32 initHeapEndSignature1[2] = {0x27FF000, 0x37F8000}; +static const u32 initHeapEndSignature5[2] = {0x2FFF000, 0x37F8000}; static const u32 initHeapEndFuncSignature[1] = {0xE12FFF1E}; static const u32 initHeapEndFunc2Signature[2] = {0xE12FFF1E, 0x023E0000}; static const u32 initHeapEndFuncSignatureAlt[1] = {0xE8BD8008}; @@ -131,10 +169,15 @@ static const u32 resetSignature3Alt[4] = {0xE92D4010, 0xE59F1068, 0xE1A04000, 0 static const u32 resetSignature3Mb[1] = {0xE92D4008}; // sdk3 static const u32 resetSignature4[4] = {0xE92D4070, 0xE59F10A0, 0xE1A04000, 0xE1D100B0}; // sdk4 static const u32 resetSignature4Alt[4] = {0xE92D4010, 0xE59F1084, 0xE1A04000, 0xE1D100B0}; // sdk4 +static const u32 resetSignature5[4] = {0xE92D4038, 0xE59F1054, 0xE1A05000, 0xE1D100B0}; // sdk5 static const u32 resetSignature5Alt1[4] = {0xE92D4010, 0xE59F104C, 0xE1A04000, 0xE1D100B0}; // sdk2 and sdk5 +static const u32 resetSignature5Alt2[4] = {0xE92D4010, 0xE59F1088, 0xE1A04000, 0xE1D100B0}; // sdk5 +static const u32 resetSignature5Alt3[4] = {0xE92D4038, 0xE59F106C, 0xE1A05000, 0xE1D100B0}; // sdk5 +static const u32 resetSignature5Alt4[4] = {0xE92D4038, 0xE59F1090, 0xE1A05000, 0xE1D100B0}; // sdk5 static const u32 resetConstant[1] = {RESET_PARAM}; static const u32 resetConstantMb[1] = {0x027FFE34}; +static const u32 resetConstant5[1] = {RESET_PARAM_SDK5}; // Panic // TODO : could be a good idea to catch the call to Panic function and store the message somewhere @@ -142,6 +185,8 @@ static const u32 resetConstantMb[1] = {0x027FFE34}; extern u32 iUncompressedSize; +extern bool isPawsAndClaws(const tNDSHeader* ndsHeader); + u32* a9_findSwi12Offset(const tNDSHeader* ndsHeader) { //dbg_printf("findSwi12Offset:\n"); @@ -168,7 +213,6 @@ u32* findModuleParamsOffset(const tNDSHeader* ndsHeader) { ); /*if (moduleParamsOffset) { dbg_printf("Module params offset found: "); - patchOffsetCache.moduleParamsOffset = moduleParamsOffset; } else { dbg_printf("Module params offset not found\n"); } @@ -187,7 +231,7 @@ u32* findCardReadEndOffsetType0(const tNDSHeader* ndsHeader, const module_params const char* romTid = getRomTid(ndsHeader); u32* cardReadEndOffset = NULL; - if (moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4008000) { + if ((moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4008000) || isPawsAndClaws(ndsHeader)) { cardReadEndOffset = findOffset( (u32*)startOffset, iUncompressedSize-(startOffset-0x02000000),//ndsHeader->arm9binarySize, cardReadEndSignature3Elab, 3 @@ -287,6 +331,60 @@ u16* findCardReadEndOffsetThumb(const tNDSHeader* ndsHeader, u32 startOffset) { return cardReadEndOffset; } +// SDK 5 +u16* findCardReadEndOffsetThumb5Type1(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 startOffset) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + // dbg_printf("findCardReadEndOffsetThumb5Type1:\n"); + + u16* cardReadEndOffset = findOffsetThumb( + (u16*)startOffset, iUncompressedSize-(startOffset-0x02000000),//ndsHeader->arm9binarySize, + cardReadEndSignatureThumb5, 4 + ); + /* if (cardReadEndOffset) { + dbg_printf("ARM9 Card read end SDK 5 thumb (type 1) found: "); + } else { + dbg_printf("ARM9 Card read end SDK 5 thumb (type 1) not found\n"); + } + + if (cardReadEndOffset) { + dbg_hexa((u32)cardReadEndOffset); + dbg_printf("\n"); + } + + dbg_printf("\n"); */ + return cardReadEndOffset; +} + +// SDK 5 +u16* findCardReadEndOffsetThumb5Type0(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 startOffset) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + // dbg_printf("findCardReadEndOffsetThumb5Type0:\n"); + + u16* cardReadEndOffset = findOffsetThumb( + (u16*)startOffset, iUncompressedSize-(startOffset-0x02000000),//ndsHeader->arm9binarySize, + cardReadEndSignatureThumb5Alt1, 5 + ); + /* if (cardReadEndOffset) { + dbg_printf("ARM9 Card read end SDK 5 thumb alt 1 (type 0) found: "); + } else { + dbg_printf("ARM9 Card read end SDK 5 thumb alt 1 (type 0) not found\n"); + } + + if (cardReadEndOffset) { + dbg_hexa((u32)cardReadEndOffset); + dbg_printf("\n"); + } + + dbg_printf("\n"); */ + return cardReadEndOffset; +} + u32* findCardReadStartOffsetType0(const module_params_t* moduleParams, const u32* cardReadEndOffset) { if (!cardReadEndOffset) { return NULL; @@ -341,6 +439,61 @@ u32* findCardReadStartOffsetType1(const u32* cardReadEndOffset) { return cardReadStartOffset; } +// SDK 5 +u32* findCardReadStartOffset5(const module_params_t* moduleParams, const u32* cardReadEndOffset) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + if (!cardReadEndOffset) { + return NULL; + } + + // dbg_printf("findCardReadStartOffset5:\n"); + + u32* cardReadStartOffset = findOffsetBackwards( + (u32*)cardReadEndOffset, 0x120, + cardReadStartSignature5, 1 + ); + /* if (cardReadStartOffset) { + dbg_printf("ARM9 Card read start SDK 5 found\n"); + } else { + dbg_printf("ARM9 Card read start SDK 5 not found\n"); + } */ + + if (!cardReadStartOffset) { + cardReadStartOffset = findOffsetBackwards( + (u32*)cardReadEndOffset, 0x120, + cardReadStartSignature5Alt, 1 + ); + /* if (cardReadStartOffset) { + dbg_printf("ARM9 Card read start SDK 5.5 found\n"); + } else { + dbg_printf("ARM9 Card read start SDK 5.5 not found\n"); + } */ + } + + // dbg_printf("\n"); + return cardReadStartOffset; +} + +u32* findCardReadCheckOffsetMvDK4(u32 startOffset) { + // dbg_printf("findCardReadCheckOffsetMvDK4:\n"); + + u32* cardReadStartOffset = findOffset( + (u32*)startOffset, 0x20000, + cardReadCheckSignatureMvDK4, 3 + ); + /* if (cardReadStartOffset) { + dbg_printf("ARM9 Card read check (MvDK4) found\n"); + } else { + dbg_printf("ARM9 Card read check (MvDK4) not found\n"); + } + + dbg_printf("\n"); */ + return cardReadStartOffset; +} + u16* findCardReadStartOffsetThumb(const u16* cardReadEndOffset) { if (!cardReadEndOffset) { return NULL; @@ -374,64 +527,154 @@ u16* findCardReadStartOffsetThumb(const u16* cardReadEndOffset) { return cardReadStartOffset; } +// SDK 5 +u16* findCardReadStartOffsetThumb5Type0(const module_params_t* moduleParams, const u16* cardReadEndOffset) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + if (!cardReadEndOffset) { + return NULL; + } + + // dbg_printf("findCardReadStartOffsetThumb5Type0:\n"); + + u16* cardReadStartOffset = findOffsetBackwardsThumb( + cardReadEndOffset, 0xD0, + cardReadStartSignatureThumb5, 1 + ); + /* if (cardReadStartOffset) { + dbg_printf("ARM9 Card read start SDK 5 thumb (type 0) found\n"); + } else { + dbg_printf("ARM9 Card read start SDK 5 thumb (type 0) not found\n"); + } + + dbg_printf("\n"); */ + return cardReadStartOffset; +} + +// SDK 5 +u16* findCardReadStartOffsetThumb5Type1(const module_params_t* moduleParams, const u16* cardReadEndOffset) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + if (!cardReadEndOffset) { + return NULL; + } + + // dbg_printf("findCardReadStartOffsetThumb5Type1:\n"); + + u16* cardReadStartOffset = findOffsetBackwardsThumb( + (u16*)cardReadEndOffset, 0xD0, + cardReadStartSignatureThumb5Alt, 1 + ); + /* if (cardReadStartOffset) { + dbg_printf("ARM9 Card read start SDK 5 thumb alt (type 0) found\n"); + } else { + dbg_printf("ARM9 Card read start SDK 5 thumb alt (type 0) not found\n"); + } + + dbg_printf("\n"); */ + return cardReadStartOffset; +} + u32* findCardPullOutOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { //dbg_printf("findCardPullOutOffset:\n"); //if (!usesThumb) { u32* cardPullOutOffset = 0; - if (moduleParams->sdk_version > 0x2008000 && moduleParams->sdk_version < 0x3000000) { - // SDK 2 + if (moduleParams->sdk_version > 0x5000000) { + // SDK 5 cardPullOutOffset = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, - cardPullOutSignature1Elab, 5 + cardPullOutSignature5, 4 ); - /*if (cardPullOutOffset) { - dbg_printf("Card pull out handler SDK 2 elaborate found\n"); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 5 found\n"); } else { - dbg_printf("Card pull out handler SDK 2 elaborate not found\n"); - }*/ - } + dbg_printf("Card pull out handler SDK 5 not found\n"); + } */ - if (!cardPullOutOffset && moduleParams->sdk_version < 0x4000000) { - cardPullOutOffset = findOffset( - (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, - cardPullOutSignature1, 4 - ); - /*if (cardPullOutOffset) { - dbg_printf("Card pull out handler found\n"); - } else { - dbg_printf("Card pull out handler not found\n"); - }*/ - } + if (!cardPullOutOffset) { + // SDK 5 + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature5Alt, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 5 alt found\n"); + } else { + dbg_printf("Card pull out handler SDK 5 alt not found\n"); + } */ + } + } else { + if (moduleParams->sdk_version > 0x2008000 && moduleParams->sdk_version < 0x3000000) { + // SDK 2 + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature1Elab, 5 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 2 elaborate found\n"); + } else { + dbg_printf("Card pull out handler SDK 2 elaborate not found\n"); + } */ + } - if (!cardPullOutOffset && moduleParams->sdk_version < 0x2008000) { - // SDK 2 - cardPullOutOffset = findOffset( - (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, - cardPullOutSignature2Alt, 4 - ); - /*if (cardPullOutOffset) { - dbg_printf("Card pull out handler SDK 2 alt found\n"); - } else { - dbg_printf("Card pull out handler SDK 2 alt not found\n"); - }*/ - } + if (!cardPullOutOffset && moduleParams->sdk_version < 0x4000000) { + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature1, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler found\n"); + } else { + dbg_printf("Card pull out handler not found\n"); + } */ + } - if (!cardPullOutOffset) { - // SDK 4 - cardPullOutOffset = findOffset( - (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, - cardPullOutSignature4, 4 - ); - /*if (cardPullOutOffset) { - dbg_printf("Card pull out handler SDK 4 found\n"); - } else { - dbg_printf("Card pull out handler SDK 4 not found\n"); - }*/ + if (!cardPullOutOffset && moduleParams->sdk_version < 0x2008000) { + // SDK 2 + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature2Alt, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 2 alt found\n"); + } else { + dbg_printf("Card pull out handler SDK 2 alt not found\n"); + } */ + } + + if (!cardPullOutOffset) { + // SDK 4 + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature4, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 4 found\n"); + } else { + dbg_printf("Card pull out handler SDK 4 not found\n"); + } */ + } + + if (!cardPullOutOffset && moduleParams->sdk_version > 0x4000000) { + cardPullOutOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardPullOutSignature1, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler found\n"); + } else { + dbg_printf("Card pull out handler not found\n"); + } */ + } } - //dbg_printf("\n"); + // dbg_printf("\n"); return cardPullOutOffset; } @@ -476,35 +719,117 @@ u16* findCardPullOutOffsetThumb(const tNDSHeader* ndsHeader) { return cardPullOutOffset; } -u32* findCardIdEndOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, const u32* cardReadEndOffset) { - if (!cardReadEndOffset) { +// SDK 5 +u16* findCardPullOutOffsetThumb5Type0(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { + if (moduleParams->sdk_version < 0x5000000) { return NULL; } - //dbg_printf("findCardIdEndOffset:\n"); + // dbg_printf("findCardPullOutOffsetThumbType0:\n"); + + u16* cardPullOutOffset = findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, + cardPullOutSignatureThumb5, 4 + ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 5 thumb (type 0) found\n"); + } else { + dbg_printf("Card pull out handler SDK 5 thumb (type 0) not found\n"); + } - u32* cardIdEndOffset = findOffset( - (u32*)cardReadEndOffset + 0x10, iUncompressedSize, - cardIdEndSignature, 2 + dbg_printf("\n"); */ + return cardPullOutOffset; +} + +// SDK 5 +u16* findCardPullOutOffsetThumb5Type1(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { + if (moduleParams->sdk_version < 0x5000000) { + return NULL; + } + + // dbg_printf("findCardPullOutOffsetThumbType1:\n"); + + u16* cardPullOutOffset = findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, + cardPullOutSignatureThumb5Alt, 4 ); - if (!cardIdEndOffset) { - cardIdEndOffset = findOffset( - (u32*)ndsHeader->arm9destination, iUncompressedSize, - cardIdEndSignature, 2 - ); + /* if (cardPullOutOffset) { + dbg_printf("Card pull out handler SDK 5 thumb alt (type 1) found\n"); + } else { + dbg_printf("Card pull out handler SDK 5 thumb alt (type 1) not found\n"); + } + + dbg_printf("\n"); */ + return cardPullOutOffset; +} + +u32* findCardIdEndOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, const u32* cardReadEndOffset) { + if (!isPawsAndClaws(ndsHeader) && !cardReadEndOffset) { + return NULL; } - /*if (cardIdEndOffset) { - dbg_printf("Card ID end found: "); + + // dbg_printf("findCardIdEndOffset:\n"); + + u32* cardIdEndOffset = NULL; + + if (moduleParams->sdk_version > 0x5000000) { + // SDK 5 + if (cardReadEndOffset) { + cardIdEndOffset = findOffsetBackwards( + (u32*)cardReadEndOffset, 0x800, + cardIdEndSignature5, 4 + ); + } else { + cardIdEndOffset = findOffsetBackwards( + (u32*)ndsHeader->arm9destination, iUncompressedSize, + cardIdEndSignature5, 4 + ); + } + /* if (cardIdEndOffset) { + dbg_printf("Card ID end SDK 5 found: "); + } else { + dbg_printf("Card ID end SDK 5 not found\n"); + } */ + + if (!cardIdEndOffset) { + // SDK 5 + cardIdEndOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize, + cardIdEndSignature5Alt, 3 + ); + /* if (cardIdEndOffset) { + dbg_printf("Card ID end SDK 5 alt found: "); + } else { + dbg_printf("Card ID end SDK 5 alt not found\n"); + } */ + } } else { - dbg_printf("Card ID end not found\n"); - }*/ + if (cardReadEndOffset) { + cardIdEndOffset = findOffset( + (u32*)cardReadEndOffset + 0x10, iUncompressedSize, + cardIdEndSignature, 2 + ); + } + if (!cardIdEndOffset) { + cardIdEndOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize, + cardIdEndSignature, 2 + ); + } + if (cardIdEndOffset) { + cardIdEndOffset[0] = 0; // Prevent being searched again + // dbg_printf("Card ID end found: "); + } /* else { + dbg_printf("Card ID end not found\n"); + } */ + } - /*if (cardIdEndOffset) { + /* if (cardIdEndOffset) { dbg_hexa((u32)cardIdEndOffset); dbg_printf("\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return cardIdEndOffset; } @@ -513,37 +838,50 @@ u16* findCardIdEndOffsetThumb(const tNDSHeader* ndsHeader, const module_params_t return NULL; } - //dbg_printf("findCardIdEndOffsetThumb:\n"); + // dbg_printf("findCardIdEndOffsetThumb:\n"); u16* cardIdEndOffset = findOffsetThumb( (u16*)ndsHeader->arm9destination, iUncompressedSize, cardIdEndSignatureThumb, 6 ); - /*if (cardIdEndOffset) { + /* if (cardIdEndOffset) { dbg_printf("Card ID end thumb found: "); } else { dbg_printf("Card ID end thumb not found\n"); - }*/ + } */ - if (!cardIdEndOffset /*&& moduleParams->sdk_version < 0x5000000*/) { + if (!cardIdEndOffset && moduleParams->sdk_version < 0x5000000) { // SDK <= 4 cardIdEndOffset = findOffsetThumb( (u16*)ndsHeader->arm9destination, iUncompressedSize, cardIdEndSignatureThumbAlt, 6 ); - /*if (cardIdEndOffset) { + /* if (cardIdEndOffset) { dbg_printf("Card ID end thumb alt found: "); } else { dbg_printf("Card ID end thumb alt not found\n"); - }*/ + } */ } - /*if (cardIdEndOffset) { + if (!cardIdEndOffset && moduleParams->sdk_version > 0x5000000) { + // SDK 5 + cardIdEndOffset = findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize, + cardIdEndSignatureThumb5, 8 + ); + /* if (cardIdEndOffset) { + dbg_printf("Card ID end SDK 5 thumb found: "); + } else { + dbg_printf("Card ID end SDK 5 thumb not found\n"); + } */ + } + + /* if (cardIdEndOffset) { dbg_hexa((u32)cardIdEndOffset); dbg_printf("\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return cardIdEndOffset; } @@ -552,43 +890,46 @@ u32* findCardIdStartOffset(const module_params_t* moduleParams, const u32* cardI return NULL; } - //dbg_printf("findCardIdStartOffset:\n"); + // dbg_printf("findCardIdStartOffset:\n"); - u32* cardIdStartOffset = findOffsetBackwards( - (u32*)cardIdEndOffset, 0x100, - cardIdStartSignature, 1 - ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start found\n"); - } else { - dbg_printf("Card ID start not found\n"); - }*/ + u32* cardIdStartOffset = NULL; - if (!cardIdStartOffset) { - cardIdStartOffset = findOffsetBackwards( - (u32*)cardIdEndOffset, 0x100, - cardIdStartSignatureAlt1, 1 + if (isSdk5(moduleParams)) { + // SDK 5 + cardIdStartOffset = findOffsetBackwards2( + (u32*)cardIdEndOffset, 0x200, + cardIdStartSignature5, cardIdStartSignature5Alt, 2 ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start alt 1 found\n"); + /* if (cardIdStartOffset) { + dbg_printf("Card ID start SDK 5 found\n"); } else { - dbg_printf("Card ID start alt 1 not found\n"); - }*/ - } + dbg_printf("Card ID start SDK 5 not found\n"); + } */ - if (!cardIdStartOffset) { - cardIdStartOffset = findOffsetBackwards( + if (!cardIdStartOffset) { + cardIdStartOffset = findOffsetBackwards2( + (u32*)cardIdEndOffset, 0x100, + cardIdStartSignatureAlt1, cardIdStartSignatureAlt2, 1 + ); + /* if (cardIdStartOffset) { + dbg_printf("Card ID start alt found\n"); + } else { + dbg_printf("Card ID start alt not found\n"); + } */ + } + } else { + cardIdStartOffset = findOffsetBackwards3( (u32*)cardIdEndOffset, 0x100, - cardIdStartSignatureAlt2, 1 + cardIdStartSignature, cardIdStartSignatureAlt1, cardIdStartSignatureAlt2, 1 ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start alt 2 found\n"); + /* if (cardIdStartOffset) { + dbg_printf("Card ID start found\n"); } else { - dbg_printf("Card ID start alt 2 not found\n"); - }*/ + dbg_printf("Card ID start not found\n"); + } */ } - //dbg_printf("\n"); + // dbg_printf("\n"); return cardIdStartOffset; } @@ -597,53 +938,19 @@ u16* findCardIdStartOffsetThumb(const module_params_t* moduleParams, const u16* return NULL; } - //dbg_printf("findCardIdStartOffsetThumb:\n"); + // dbg_printf("findCardIdStartOffsetThumb:\n"); - u16* cardIdStartOffset = findOffsetBackwardsThumb( + u16* cardIdStartOffset = findOffsetBackwardsThumb4( (u16*)cardIdEndOffset, 0x50, - cardIdStartSignatureThumb, 2 + cardIdStartSignatureThumb, cardIdStartSignatureThumbAlt1, cardIdStartSignatureThumbAlt2, cardIdStartSignatureThumbAlt3, 2 ); - /*if (cardIdStartOffset) { + /* if (cardIdStartOffset) { dbg_printf("Card ID start thumb found\n"); } else { dbg_printf("Card ID start thumb not found\n"); - }*/ - - if (!cardIdStartOffset) { - cardIdStartOffset = findOffsetBackwardsThumb( - (u16*)cardIdEndOffset, 0x50, - cardIdStartSignatureThumbAlt1, 2 - ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start thumb alt 1 found\n"); - } else { - dbg_printf("Card ID start thumb alt 1 not found\n"); - }*/ - } - if (!cardIdStartOffset) { - cardIdStartOffset = findOffsetBackwardsThumb( - (u16*)cardIdEndOffset, 0x50, - cardIdStartSignatureThumbAlt2, 2 - ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start thumb alt 2 found\n"); - } else { - dbg_printf("Card ID start thumb alt 2 not found\n"); - }*/ - } - if (!cardIdStartOffset) { - cardIdStartOffset = findOffsetBackwardsThumb( - (u16*)cardIdEndOffset, 0x50, - cardIdStartSignatureThumbAlt3, 2 - ); - /*if (cardIdStartOffset) { - dbg_printf("Card ID start thumb alt 3 found\n"); - } else { - dbg_printf("Card ID start thumb alt 3 not found\n"); - }*/ } - //dbg_printf("\n"); + dbg_printf("\n"); */ return cardIdStartOffset; } @@ -708,54 +1015,68 @@ u32* findCardReadDmaStartOffset(const module_params_t* moduleParams, const u32* return NULL; } - //dbg_printf("findCardReadDmaStartOffset:\n"); + // dbg_printf("findCardReadDmaStartOffset:\n"); - u32* cardReadDmaStartOffset = findOffsetBackwards( - (u32*)cardReadDmaEndOffset, 0x200, - cardReadDmaStartSignature, 1 - ); - /*if (cardReadDmaStartOffset) { - dbg_printf("Card read DMA start found\n"); - } else { - dbg_printf("Card read DMA start not found\n"); - }*/ + u32* cardReadDmaStartOffset = NULL; - if (!cardReadDmaStartOffset && moduleParams->sdk_version < 0x2008000) { + if (moduleParams->sdk_version > 0x5000000) { cardReadDmaStartOffset = findOffsetBackwards( (u32*)cardReadDmaEndOffset, 0x200, - cardReadDmaStartSignatureSdk2Alt, 1 + cardReadDmaStartSignature5, 1 ); - /*if (cardReadDmaStartOffset) { - dbg_printf("Card read DMA start SDK 2 alt found\n"); + /* if (cardReadDmaStartOffset) { + dbg_printf("Card read DMA start SDK 5 found\n"); } else { - dbg_printf("Card read DMA start SDK 2 alt not found\n"); - }*/ - } - - if (!cardReadDmaStartOffset) { - cardReadDmaStartOffset = findOffsetBackwards( - (u32*)cardReadDmaEndOffset, 0x200, - cardReadDmaStartSignatureAlt1, 1 - ); - /*if (cardReadDmaStartOffset) { - dbg_printf("Card read DMA start alt 1 found\n"); - } else { - dbg_printf("Card read DMA start alt 1 not found\n"); - }*/ - } - if (!cardReadDmaStartOffset) { + dbg_printf("Card read DMA start SDK 5 not found\n"); + } */ + } else { cardReadDmaStartOffset = findOffsetBackwards( (u32*)cardReadDmaEndOffset, 0x200, - cardReadDmaStartSignatureAlt2, 1 + cardReadDmaStartSignature, 1 ); - /*if (cardReadDmaStartOffset) { - dbg_printf("Card read DMA start alt 2 found\n"); + /* if (cardReadDmaStartOffset) { + dbg_printf("Card read DMA start found\n"); } else { - dbg_printf("Card read DMA start alt 2 not found\n"); - }*/ + dbg_printf("Card read DMA start not found\n"); + } */ + + if (!cardReadDmaStartOffset && moduleParams->sdk_version < 0x2008000) { + cardReadDmaStartOffset = findOffsetBackwards( + (u32*)cardReadDmaEndOffset, 0x200, + cardReadDmaStartSignatureSdk2Alt, 1 + ); + /* if (cardReadDmaStartOffset) { + dbg_printf("Card read DMA start SDK 2 alt found\n"); + } else { + dbg_printf("Card read DMA start SDK 2 alt not found\n"); + } */ + } + + if (!cardReadDmaStartOffset) { + cardReadDmaStartOffset = findOffsetBackwards( + (u32*)cardReadDmaEndOffset, 0x200, + cardReadDmaStartSignatureAlt1, 1 + ); + /* if (cardReadDmaStartOffset) { + dbg_printf("Card read DMA start alt 1 found\n"); + } else { + dbg_printf("Card read DMA start alt 1 not found\n"); + } */ + } + if (!cardReadDmaStartOffset) { + cardReadDmaStartOffset = findOffsetBackwards( + (u32*)cardReadDmaEndOffset, 0x200, + cardReadDmaStartSignatureAlt2, 1 + ); + /* if (cardReadDmaStartOffset) { + dbg_printf("Card read DMA start alt 2 found\n"); + } else { + dbg_printf("Card read DMA start alt 2 not found\n"); + } */ + } } - //dbg_printf("\n"); + // dbg_printf("\n"); return cardReadDmaStartOffset; } @@ -793,7 +1114,7 @@ u16* findCardReadDmaStartOffsetThumb(const u16* cardReadDmaEndOffset) { } u32* a9FindCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool* usesThumb) { - //dbg_printf("findCardIrqEnableOffset:\n"); + // dbg_printf("findCardIrqEnableOffset:\n"); const u32* irqEnableStartSignature = irqEnableStartSignature1; if (moduleParams->sdk_version > 0x4008000) { @@ -804,22 +1125,22 @@ u32* a9FindCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_ (u32*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, irqEnableStartSignature, 4 ); - /*if (cardIrqEnableOffset) { + /* if (cardIrqEnableOffset) { dbg_printf("irq enable found\n"); } else { dbg_printf("irq enable not found\n"); - }*/ + } */ if (!cardIrqEnableOffset && moduleParams->sdk_version < 0x2008000) { cardIrqEnableOffset = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, irqEnableStartSignature2Alt, 4 ); - /*if (cardIrqEnableOffset) { + /* if (cardIrqEnableOffset) { dbg_printf("irq enable SDK 2 alt found\n"); } else { dbg_printf("irq enable SDK 2 alt not found\n"); - }*/ + } */ } if (!cardIrqEnableOffset && moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4008000) { @@ -827,11 +1148,23 @@ u32* a9FindCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_ (u32*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, irqEnableStartSignature4, 4 ); - /*if (cardIrqEnableOffset) { + /* if (cardIrqEnableOffset) { dbg_printf("irq enable SDK 4 found\n"); } else { dbg_printf("irq enable SDK 4 not found\n"); - }*/ + } */ + } + + if (!cardIrqEnableOffset && moduleParams->sdk_version > 0x5000000) { + cardIrqEnableOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//, ndsHeader->arm9binarySize, + irqEnableStartSignature5Debug, 4 + ); + /* if (cardIrqEnableOffset) { + dbg_printf("irq enable SDK 5 debugger found: "); + } else { + dbg_printf("irq enable SDK 5 debugger not found\n"); + } */ } if (!cardIrqEnableOffset && moduleParams->sdk_version < 0x4008000) { @@ -841,10 +1174,10 @@ u32* a9FindCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_ ); if (cardIrqEnableOffset) { *usesThumb = true; - //dbg_printf("irq enable thumb found\n"); - } /*else { + // dbg_printf("irq enable thumb found\n"); + } /* else { dbg_printf("irq enable thumb not found\n"); - }*/ + } */ } if (!cardIrqEnableOffset) { @@ -854,13 +1187,13 @@ u32* a9FindCardIrqEnableOffset(const tNDSHeader* ndsHeader, const module_params_ ); if (cardIrqEnableOffset) { *usesThumb = true; - //dbg_printf("irq enable thumb alt found\n"); - } /*else { + // dbg_printf("irq enable thumb alt found\n"); + } /* else { dbg_printf("irq enable thumb alt not found\n"); - }*/ + } */ } - //dbg_printf("\n"); + // dbg_printf("\n"); return cardIrqEnableOffset; } @@ -875,30 +1208,36 @@ const u32* getMpuInitRegionSignature(u32 patchMpuRegion) { } u32* findMpuStartOffset(const tNDSHeader* ndsHeader, u32 patchMpuRegion) { - //dbg_printf("findMpuStartOffset:\n"); + // dbg_printf("findMpuStartOffset:\n"); const u32* mpuInitRegionSignature = getMpuInitRegionSignature(patchMpuRegion); u32* mpuStartOffset = NULL; - /*if (patchMpuRegion == 2 && ndsHeader->unitCode == 3) { + /* if (patchMpuRegion == 2 && ndsHeader->unitCode == 3) { mpuStartOffset = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize, mpuInitRegion2SignatureElab, 2 ); - }*/ + } */ + if (((u32)ndsHeader->arm9executeAddress - (u32)ndsHeader->arm9destination) >= 0x1000) { + mpuStartOffset = findOffset( + (u32*)ndsHeader->arm9executeAddress, 0x400, + mpuInitRegionSignature, 1 + ); + } if (!mpuStartOffset) { mpuStartOffset = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize, mpuInitRegionSignature, 1 ); } - /*if (mpuStartOffset) { + /* if (mpuStartOffset) { dbg_printf("Mpu init found\n"); } else { dbg_printf("Mpu init not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return mpuStartOffset; } @@ -907,22 +1246,23 @@ u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, return NULL; } - //dbg_printf("findMpuDataOffset:\n"); + // dbg_printf("findMpuDataOffset:\n"); const u32* mpuInitRegion1Data = mpuInitRegion1Data1; const u32* mpuInitRegion2Data = mpuInitRegion2Data1; - if (moduleParams->sdk_version >= 0x2008000) { + if (moduleParams->sdk_version > 0x4000000) { mpuInitRegion2Data = mpuInitRegion2Data3; } + if (moduleParams->sdk_version > 0x5000000) { + mpuInitRegion1Data = mpuInitRegion1Data5; + mpuInitRegion2Data = mpuInitRegion2Data5; + } const u32* mpuInitRegionData = mpuInitRegion1Data; switch (patchMpuRegion) { case 0: mpuInitRegionData = mpuInitRegion0Data; break; - case 1: - mpuInitRegionData = mpuInitRegion1Data; - break; case 2: mpuInitRegionData = mpuInitRegion2Data; break; @@ -935,6 +1275,18 @@ u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, mpuStartOffset, 0x100, mpuInitRegionData, 1 ); + if (!mpuDataOffset && patchMpuRegion == 1 && moduleParams->sdk_version < 0x4000000) { + mpuDataOffset = findOffset( + mpuStartOffset, 0x100, + mpuInitRegion1DataAlt, 1 + ); + } + if (!mpuDataOffset && patchMpuRegion == 2 && moduleParams->sdk_version < 0x4000000) { + mpuDataOffset = findOffset( + mpuStartOffset, 0x100, + mpuInitRegion2Data3, 1 + ); + } if (!mpuDataOffset) { // Try to find it for (int i = 0; i < 0x100; i++) { @@ -944,55 +1296,137 @@ u32* findMpuDataOffset(const module_params_t* moduleParams, u32 patchMpuRegion, } } } - /*if (mpuDataOffset) { + /* if (mpuDataOffset) { dbg_printf("Mpu data found\n"); } else { dbg_printf("Mpu data not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return mpuDataOffset; } u32* findMpuDataOffsetAlt(const tNDSHeader* ndsHeader) { - //dbg_printf("findMpuDataOffsetAlt:\n"); + // dbg_printf("findMpuDataOffsetAlt:\n"); u32* mpuDataOffset = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize, mpuInitRegion1DataAlt, 1 ); - /*if (mpuDataOffset) { + /* if (mpuDataOffset) { dbg_printf("Mpu data found\n"); } else { dbg_printf("Mpu data not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return mpuDataOffset; } +u32* findMpuChange(const tNDSHeader* ndsHeader) { + // dbg_printf("findMpuChange:\n"); + + u32* offset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize, + mpuChangeRegion1Signature, 3 + ); + /* if (offset) { + dbg_printf("Mpu change found\n"); + } else { + dbg_printf("Mpu change not found\n"); + } */ + + if (!offset) { + offset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize, + mpuChangeRegion1SignatureAlt, 3 + ); + /* if (offset) { + dbg_printf("Mpu change alt found\n"); + } else { + dbg_printf("Mpu change alt not found\n"); + } */ + } + + if (!offset) { + offset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize, + mpuChangeRegion1SignatureThumb, 3 + ); + /* if (offset) { + dbg_printf("Mpu change thumb found\n"); + } else { + dbg_printf("Mpu change thumb not found\n"); + } */ + } + + if (!offset) { + offset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize, + mpuChangeRegion1SignatureThumbAlt, 3 + ); + /* if (offset) { + dbg_printf("Mpu change thumb alt found\n"); + } else { + dbg_printf("Mpu change thumb alt not found\n"); + } */ + } + + // dbg_printf("\n"); + return offset; +} + +u32* findMpuInitTwlEnd(const u32* heapPointer2Offset) { + // dbg_printf("findMpuInitTwlEnd:\n"); + + u32* offset = findOffsetBackwards( + heapPointer2Offset, 0x80, + mpuInitRegion3TwlEndSignature, 4 + ); + /* if (offset) { + dbg_printf("Mpu init TWL end found\n"); + } else { + dbg_printf("Mpu init TWL end not found\n"); + } */ + + if (!offset) { + offset = findOffsetBackwards( + heapPointer2Offset, 0x60, + mpuInitRegion3TwlEndSignatureThumb, 3 + ); + /* if (offset) { + dbg_printf("Mpu init TWL end thumb found\n"); + } else { + dbg_printf("Mpu init TWL end thumb not found\n"); + } */ + } + + // dbg_printf("\n"); + return offset; +} + u32* findHeapPointerOffset(const module_params_t* moduleParams, const tNDSHeader* ndsHeader) { - //dbg_printf("findHeapPointerOffset:\n"); + // dbg_printf("findHeapPointerOffset:\n"); const u32* initHeapEndSignature = initHeapEndSignature1; - /*if (moduleParams->sdk_version > 0x5000000) { + if (moduleParams->sdk_version > 0x5000000) { initHeapEndSignature = initHeapEndSignature5; - }*/ + } u32* initHeapEnd = findOffset( (u32*)ndsHeader->arm9destination, iUncompressedSize, initHeapEndSignature, 2 ); if (initHeapEnd) { - //dbg_printf("Init Heap End found: "); + // dbg_printf("Init Heap End found: "); } else { - //dbg_printf("Init Heap End not found\n\n"); + // dbg_printf("Init Heap End not found\n\n"); return 0; } - /*dbg_hexa((u32)initHeapEnd); + /* dbg_hexa((u32)initHeapEnd); dbg_printf("\n"); - dbg_printf("heapPointer: ");*/ + dbg_printf("heapPointer: "); */ u32* initEndFunc = findOffsetBackwards( (u32*)initHeapEnd, 0x40, @@ -1020,8 +1454,8 @@ u32* findHeapPointerOffset(const module_params_t* moduleParams, const tNDSHeader heapPointer = (u32*)((u16*)initEndFuncThumb+1); } - /*dbg_hexa((u32)heapPointer); - dbg_printf("\n");*/ + /* dbg_hexa((u32)heapPointer); + dbg_printf("\n"); */ return heapPointer; } @@ -1075,8 +1509,8 @@ u32* findHeapPointer2Offset(const module_params_t* moduleParams, const tNDSHeade u32* heapPointer = initEndFunc + 1; - /*dbg_hexa((u32)heapPointer); - dbg_printf("\n");*/ + /* dbg_hexa((u32)heapPointer); + dbg_printf("\n"); */ return heapPointer; } @@ -1103,8 +1537,31 @@ u32* findRandomPatchOffset(const tNDSHeader* ndsHeader) { return randomPatchOffset; } +// SDK 5 +u32* findRandomPatchOffset5Second(const tNDSHeader* ndsHeader) { + // dbg_printf("findRandomPatchOffset5Second:\n"); + + u32* randomPatchOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + randomPatchSignature5Second, 3 + ); + /* if (randomPatchOffset) { + dbg_printf("Random patch SDK 5 second found: "); + } else { + dbg_printf("Random patch SDK 5 second not found\n"); + } + + if (randomPatchOffset) { + dbg_hexa((u32)randomPatchOffset); + dbg_printf("\n"); + } + + dbg_printf("\n"); */ + return randomPatchOffset; +} + u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, bool* usesThumbPtr) { - //dbg_printf("findSleepOffset\n"); + // dbg_printf("findSleepOffset\n"); const u32* sleepSignature = sleepSignature2; const u16* sleepSignatureThumb = sleepSignatureThumb2; @@ -1112,6 +1569,10 @@ u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP sleepSignature = sleepSignature4; sleepSignatureThumb = sleepSignatureThumb4; } + if (moduleParams->sdk_version > 0x5000000) { + sleepSignature = sleepSignature5; + sleepSignatureThumb = sleepSignatureThumb5; + } u32 * sleepOffset = NULL; @@ -1137,6 +1598,16 @@ u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP ); } + if (!sleepOffset && usesThumb && moduleParams->sdk_version > 0x5000000) { + sleepOffset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + sleepSignatureThumb4, 4 + ); + if (sleepOffset) { + *usesThumbPtr = true; + } + } + if (!sleepOffset && usesThumb) { // Try search for ARM signature, as some THUMB games have the function in ARM sleepOffset = findOffset( @@ -1151,9 +1622,9 @@ u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP sleepConstantValue, 1 ); if (sleepEndOffset) { - /*dbg_printf("Sleep constant found: "); + /* dbg_printf("Sleep constant found: "); dbg_hexa((u32)sleepEndOffset); - dbg_printf("\n");*/ + dbg_printf("\n"); */ break; } @@ -1170,18 +1641,52 @@ u32* findSleepOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP } } - /*if (sleepOffset) { + /* if (sleepOffset) { dbg_printf("Sleep found\n"); } else { dbg_printf("Sleep not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return sleepOffset; } +u32* findCardEndReadDmaSdk5(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { + // dbg_printf("findCardEndReadDmaSdk5\n"); + + const u16* cardEndReadDmaSignatureThumb = cardEndReadDmaSignatureThumb5; + const u32* cardEndReadDmaSignature = cardEndReadDmaSignature5; + + u32 * offset = NULL; + + if(usesThumb) { + offset = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardEndReadDmaSignatureThumb, 4 + ); + } else { + offset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + cardEndReadDmaSignature, 4 + ); + } + + /* if (offset) { + dbg_printf("cardEndReadDma found\n"); + } else { + dbg_printf("cardEndReadDma not found\n"); + } + + dbg_printf("\n"); */ + return offset; +} + u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, const u32* cardReadDmaEndOffset, u32* dmaHandlerOffset) { - //dbg_printf("findCardEndReadDma\n"); + // dbg_printf("findCardEndReadDma\n"); + + if (moduleParams->sdk_version > 0x5000000) { + return findCardEndReadDmaSdk5(ndsHeader,moduleParams,usesThumb); + } const u32* offsetDmaHandler = NULL; if (moduleParams->sdk_version < 0x4000000) { @@ -1197,15 +1702,15 @@ u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* modu } if(*offsetDmaHandler<0x2000000 || *offsetDmaHandler>0x2400000) { - //dbg_printf("offsetDmaHandler not found\n"); + // dbg_printf("offsetDmaHandler not found\n"); return 0; } - /*dbg_printf("\noffsetDmaHandler found\n"); + /* dbg_printf("\noffsetDmaHandler found\n"); dbg_hexa((u32)offsetDmaHandler); dbg_printf(" : "); dbg_hexa(*offsetDmaHandler); - dbg_printf("\n");*/ + dbg_printf("\n"); */ u32 * offset = NULL; @@ -1218,7 +1723,13 @@ u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* modu offset = findOffset( (u32*)*offsetDmaHandler, 0x200,//ndsHeader->arm9binarySize, cardEndReadDmaSignature4, 1 - ); + ); + if (!offset) { + offset = findOffset( + (u32*)*offsetDmaHandler, 0x200,//ndsHeader->arm9binarySize, + cardEndReadDmaSignature4Alt, 1 + ); + } } if (!offset) { @@ -1233,29 +1744,88 @@ u32* findCardEndReadDma(const tNDSHeader* ndsHeader, const module_params_t* modu offsetDmaHandler+1, 0x200,//ndsHeader->arm9binarySize, cardEndReadDmaSignature4, 1 ); - /*if (offset) { + /* if (offset) { *dmaHandlerOffset = *offsetDmaHandler; dbg_printf("Offset before relocation: "); dbg_hexa((u32)offsetDmaHandler+4); dbg_printf("\n"); - }*/ + } */ } } - /*if (offset) { + /* if (offset) { dbg_printf("cardEndReadDma found\n"); } else { dbg_printf("cardEndReadDma not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return offset; } +u32* findCardSetDmaSdk5(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { + // dbg_printf("findCardSetDmaSdk5\n"); + + u32* currentOffset = (u32*)ndsHeader->arm9destination; + u32* startOffset = NULL; + while (startOffset==NULL) { + u32* cardSetDmaEndOffset = findOffset( + currentOffset+1, iUncompressedSize, + cardSetDmaSignatureValue1, 1 + ); + if (cardSetDmaEndOffset==NULL) { + // dbg_printf("cardSetDmaEnd not found\n"); + return NULL; + } else { + /* dbg_printf("cardSetDmaSignatureValue1 found\n"); + dbg_hexa((u32)cardSetDmaEndOffset); + dbg_printf(" : "); + dbg_hexa(*cardSetDmaEndOffset); + dbg_printf("\n"); */ + + currentOffset = cardSetDmaEndOffset+2; + if(usesThumb) { + // dbg_printf("cardSetDmaSignatureStartThumb used: "); + startOffset = (u32*)findOffsetBackwardsThumb( + (u16*)cardSetDmaEndOffset, 0x90, + cardSetDmaSignatureStartThumb5, 2 + ); + } else { + // dbg_printf("cardSetDmaSignatureStart used: "); + startOffset = findOffsetBackwards( + cardSetDmaEndOffset, 0x90, + cardSetDmaSignatureStart5, 2 + ); + } + if (!startOffset && !usesThumb) { + startOffset = findOffsetBackwards( + cardSetDmaEndOffset, 0x90, + cardSetDmaSignatureStart5Alt, 2 + ); + } + if (startOffset!=NULL) { + // dbg_printf("cardSetDmaSignatureStart found\n"); + /*dbg_hexa((u32)startOffset); + dbg_printf(" : "); + dbg_hexa(*startOffset); + dbg_printf("\n");*/ + + return startOffset; + } + } + } + + return NULL; +} + u32* findCardSetDma(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { - //dbg_printf("findCardSetDma\n"); + // dbg_printf("findCardSetDma\n"); - //u16* cardSetDmaSignatureStartThumb = cardSetDmaSignatureStartThumb4; + if (moduleParams->sdk_version > 0x5000000) { + return findCardSetDmaSdk5(ndsHeader,moduleParams,usesThumb); + } + + // const u16* cardSetDmaSignatureStartThumb = cardSetDmaSignatureStartThumb4; const u32* cardSetDmaSignatureStart = cardSetDmaSignatureStart4; int cardSetDmaSignatureStartLen = 3; @@ -1309,13 +1879,13 @@ u32* findCardSetDma(const tNDSHeader* ndsHeader, const module_params_t* modulePa u32 * offset = NULL; if(usesThumb) { - //dbg_printf("cardSetDmaSignatureStartThumb used: "); + // dbg_printf("cardSetDmaSignatureStartThumb used: "); offset = (u32*)findOffsetBackwardsThumb( (u16*)cardSetDmaEndOffset, 0x60, cardSetDmaSignatureStartThumb4, 4 ); } else { - //dbg_printf("cardSetDmaSignatureStart used: "); + // dbg_printf("cardSetDmaSignatureStart used: "); offset = findOffsetBackwards( cardSetDmaEndOffset, 0x80, cardSetDmaSignatureStart, cardSetDmaSignatureStartLen @@ -1328,30 +1898,40 @@ u32* findCardSetDma(const tNDSHeader* ndsHeader, const module_params_t* modulePa cardSetDmaSignatureStartThumb3, 4 ); } - if (!offset && !usesThumb && moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4000000) { - offset = findOffsetBackwards( - cardSetDmaEndOffset, 0x60, - cardSetDmaSignatureStart3, 3 - ); + if (!offset && !usesThumb) { + if (moduleParams->sdk_version > 0x3000000 && moduleParams->sdk_version < 0x4000000) { + offset = findOffsetBackwards( + cardSetDmaEndOffset, 0x60, + cardSetDmaSignatureStart3, 3 + ); + } else if (moduleParams->sdk_version > 0x4000000) { + offset = findOffsetBackwards( + cardSetDmaEndOffset, 0x60, + cardSetDmaSignatureStart4Alt, 3 + ); + } } - /*if (offset) { + /* if (offset) { dbg_printf("cardSetDma found\n"); } else { dbg_printf("cardSetDma not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return offset; } u32* findResetOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool* softResetMb) { - //dbg_printf("findResetOffset\n"); + // dbg_printf("findResetOffset\n"); const u32* resetSignature = resetSignature2; if (moduleParams->sdk_version > 0x4008000 && moduleParams->sdk_version < 0x5000000) { resetSignature = resetSignature4; } + if (moduleParams->sdk_version > 0x5000000) { + resetSignature = resetSignature5; + } u32 * resetOffset = NULL; @@ -1374,13 +1954,13 @@ u32* findResetOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP } if (resetOffset) { - /*dbg_printf("Reset found\n"); + /* dbg_printf("Reset found\n"); dbg_printf("\n");*/ *softResetMb = true; return resetOffset; - } /*else { + } /* else { dbg_printf("Reset not found\n"); - }*/ + } */ } } @@ -1427,10 +2007,33 @@ u32* findResetOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, resetSignature4Alt, 4 ); + } else if (moduleParams->sdk_version > 0x5000000) { + resetOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + resetSignature5Alt1, 4 + ); + if (!resetOffset) { + resetOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + resetSignature5Alt2, 4 + ); + } + if (!resetOffset) { + resetOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + resetSignature5Alt3, 4 + ); + } + if (!resetOffset) { + resetOffset = findOffset( + (u32*)ndsHeader->arm9destination, iUncompressedSize,//ndsHeader->arm9binarySize, + resetSignature5Alt4, 4 + ); + } } } - /*if (resetOffset) { + /* if (resetOffset) { dbg_printf("Reset found: "); dbg_hexa((u32)resetOffset); dbg_printf("\n"); @@ -1439,12 +2042,12 @@ u32* findResetOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP while(resetOffset!=NULL) { u32* resetEndOffset = findOffset( resetOffset, 0x200, - resetConstant, 1 + ((moduleParams->sdk_version > 0x5000000) ? resetConstant5 : resetConstant), 1 ); if (resetEndOffset) { - /*dbg_printf("Reset constant found: "); + /* dbg_printf("Reset constant found: "); dbg_hexa((u32)resetEndOffset); - dbg_printf("\n");*/ + dbg_printf("\n"); */ break; } @@ -1452,19 +2055,19 @@ u32* findResetOffset(const tNDSHeader* ndsHeader, const module_params_t* moduleP resetOffset+1, iUncompressedSize,//ndsHeader->arm9binarySize, resetSignature, 4 ); - /*if (resetOffset) { + /* if (resetOffset) { dbg_printf("Reset found: "); dbg_hexa((u32)resetOffset); dbg_printf("\n"); - }*/ + } */ } - /*if (resetOffset) { + /* if (resetOffset) { dbg_printf("Reset found\n"); } else { dbg_printf("Reset not found\n"); } - dbg_printf("\n");*/ + dbg_printf("\n"); */ return resetOffset; } diff --git a/retail/cardenginei/arm7/source/patcher/find_common.c b/retail/cardenginei/arm7/source/patcher/find_common.c index 8f02d7633..2163e3643 100644 --- a/retail/cardenginei/arm7/source/patcher/find_common.c +++ b/retail/cardenginei/arm7/source/patcher/find_common.c @@ -37,6 +37,44 @@ u32* memsearch32(const u32* start, u32 dataSize, const u32* find, u32 findSize, } return NULL; } +u32* memsearch32_2(const u32* start, u32 dataSize, const u32* find, const u32* find2, u32 findSize, bool forward) { + u32 dataLen = dataSize/sizeof(u32); + u32 findLen = findSize/sizeof(u32); + + const u32* end = forward ? (start + dataLen) : (start - dataLen); + for (u32* addr = (u32*)start; addr != end; forward ? ++addr : --addr) { + bool found = true; + for (u32 j = 0; j < findLen; ++j) { + if (addr[j] != find[j] && addr[j] != find2[j]) { + found = false; + break; + } + } + if (found) { + return (u32*)addr; + } + } + return NULL; +} +u32* memsearch32_3(const u32* start, u32 dataSize, const u32* find, const u32* find2, const u32* find3, u32 findSize, bool forward) { + u32 dataLen = dataSize/sizeof(u32); + u32 findLen = findSize/sizeof(u32); + + const u32* end = forward ? (start + dataLen) : (start - dataLen); + for (u32* addr = (u32*)start; addr != end; forward ? ++addr : --addr) { + bool found = true; + for (u32 j = 0; j < findLen; ++j) { + if (addr[j] != find[j] && addr[j] != find2[j] && addr[j] != find3[j]) { + found = false; + break; + } + } + if (found) { + return (u32*)addr; + } + } + return NULL; +} u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, bool forward) { u32 dataLen = dataSize/sizeof(u16); u32 findLen = findSize/sizeof(u16); @@ -56,6 +94,25 @@ u16* memsearch16(const u16* start, u32 dataSize, const u16* find, u32 findSize, } return NULL; } +u16* memsearch16_4(const u16* start, u32 dataSize, const u16* find, const u16* find2, const u16* find3, const u16* find4, u32 findSize, bool forward) { + u32 dataLen = dataSize/sizeof(u16); + u32 findLen = findSize/sizeof(u16); + + const u16* end = forward ? (start + dataLen) : (start - dataLen); + for (u16* addr = (u16*)start; addr != end; forward ? ++addr : --addr) { + bool found = true; + for (u32 j = 0; j < findLen; ++j) { + if (addr[j] != find[j] && addr[j] != find2[j] && addr[j] != find3[j] && addr[j] != find4[j]) { + found = false; + break; + } + } + if (found) { + return (u16*)addr; + } + } + return NULL; +} /* * Boyer-Moore Horspool algorithm diff --git a/retail/cardenginei/arm7/source/patcher/hook_arm9.c b/retail/cardenginei/arm7/source/patcher/hook_arm9.c index 613cc214f..6d725bb4e 100644 --- a/retail/cardenginei/arm7/source/patcher/hook_arm9.c +++ b/retail/cardenginei/arm7/source/patcher/hook_arm9.c @@ -9,8 +9,12 @@ #include "nds_header.h" #include "cardengine_header_arm9.h" +#define isSdk5_9 BIT(5) +#define isSdk5_7 BIT(13) #define b_softResetMb BIT(13) +#define b_isDlp BIT(15) +extern u32 valueBits; extern vu32* volatile sharedAddr; @@ -122,11 +126,17 @@ int hookNdsRetailArm9( extern u32 iUncompressedSize; extern bool softResetMb; + if (valueBits & isSdk5_7) { + sharedAddr[1] |= isSdk5_9; + } else { + sharedAddr[1] &= ~isSdk5_9; + } if (softResetMb) { sharedAddr[1] |= b_softResetMb; } else { sharedAddr[1] &= ~b_softResetMb; } + sharedAddr[1] &= ~b_isDlp; u32* tableAddr = hookInterruptHandler((u32*)ndsHeader->arm9destination, iUncompressedSize); diff --git a/retail/cardenginei/arm7/source/patcher/patch_arm7.c b/retail/cardenginei/arm7/source/patcher/patch_arm7.c index 29c2e1411..d14e3c512 100644 --- a/retail/cardenginei/arm7/source/patcher/patch_arm7.c +++ b/retail/cardenginei/arm7/source/patcher/patch_arm7.c @@ -13,6 +13,7 @@ #define gameOnFlashcard BIT(0) #define ROMinRAM BIT(3) +#define dsiMode BIT(4) extern u32 valueBits; extern u16 scfgRomBak; @@ -23,6 +24,8 @@ extern bool sdRead; u32 savePatchV1(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, const module_params_t* moduleParams); u32 savePatchV2(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, const module_params_t* moduleParams); u32 savePatchUniversal(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, const module_params_t* moduleParams); +u32 savePatchInvertedThumb(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, const module_params_t* moduleParams); +u32 savePatchV5(const cardengineArm7* ce7, const tNDSHeader* ndsHeader); // SDK 5 u32 generateA7Instr(int arg1, int arg2) { return (((u32)(arg2 - arg1 - 8) >> 2) & 0xFFFFFF) | 0xEB000000; @@ -97,6 +100,35 @@ static void fixForDifferentBios(const cardengineArm7* ce7, const tNDSHeader* nds dbg_printf("\n\n");*/ } +static void patchMirrorCheck(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { + if (moduleParams->sdk_version > 0x5000000) { + return; + } + + extern u32 relocationStart; + u32* offset = (u32*)relocationStart; + offset--; + offset--; + offset--; + offset--; + for (int i = 0; i < 0xA0/sizeof(u32); i++) { + if (offset[-1] == 0xE12FFF1E) { + break; + } + offset--; + } + + offset[0] = (valueBits & dsiMode) ? 0xE3A01002 : 0xE3A01001; // mov r1, #dsiModeConfirmed ? 2 : 1 + offset[1] = 0xE59F2004; // ldr r2, =0x027FFFFA + offset[2] = 0xE1C210B0; // strh r1, [r2] + offset[3] = 0xE12FFF1E; // bx lr + offset[4] = 0x027FFFFA; + + /* dbg_printf("RAM mirror check location : "); + dbg_hexa((u32)offset); + dbg_printf("\n\n"); */ +} + static void patchSleepMode(const tNDSHeader* ndsHeader) { // Sleep u32* sleepPatchOffset = findSleepPatchOffset(ndsHeader); @@ -160,12 +192,22 @@ u32 patchCardNdsArm7( } if (a7GetReloc(ndsHeader, moduleParams)) { - u32 saveResult = savePatchV1(ce7, ndsHeader, moduleParams); - if (!saveResult) { - saveResult = savePatchV2(ce7, ndsHeader, moduleParams); - } - if (!saveResult) { - saveResult = savePatchUniversal(ce7, ndsHeader, moduleParams); + patchMirrorCheck(ndsHeader, moduleParams); + u32 saveResult = 0; + + if (ndsHeader->arm7binarySize==0x2352C || ndsHeader->arm7binarySize==0x235DC || ndsHeader->arm7binarySize==0x23CAC || ndsHeader->arm7binarySize==0x245C0 || ndsHeader->arm7binarySize==0x245C4) { + saveResult = savePatchInvertedThumb(ce7, ndsHeader, moduleParams); + } else if (moduleParams->sdk_version > 0x5000000) { + // SDK 5 + saveResult = savePatchV5(ce7, ndsHeader); + } else { + saveResult = savePatchV1(ce7, ndsHeader, moduleParams); + if (!saveResult) { + saveResult = savePatchV2(ce7, ndsHeader, moduleParams); + } + if (!saveResult) { + saveResult = savePatchUniversal(ce7, ndsHeader, moduleParams); + } } } diff --git a/retail/cardenginei/arm7/source/patcher/patch_arm9.c b/retail/cardenginei/arm7/source/patcher/patch_arm9.c index 465e66748..8c6454738 100644 --- a/retail/cardenginei/arm7/source/patcher/patch_arm9.c +++ b/retail/cardenginei/arm7/source/patcher/patch_arm9.c @@ -20,6 +20,18 @@ extern u16 scfgRomBak; extern vu32* volatile sharedAddr; +bool isPawsAndClaws(const tNDSHeader* ndsHeader) { + const char* romTid = getRomTid(ndsHeader); + + if (strncmp(romTid, "AQ2", 3) == 0 // Paws & Claws: Pet Resort + || strncmp(romTid, "YMU", 3) == 0 // Paws & Claws: Pet Vet 2 + ) { + return true; + } + + return false; +} + static void fixForDifferentBios(const cardengineArm9* ce9, const tNDSHeader* ndsHeader, bool usesThumb) { if (scfgRomBak & BIT(1)) { return; @@ -38,15 +50,34 @@ static void fixForDifferentBios(const cardengineArm9* ce9, const tNDSHeader* nds dbg_printf("\n\n");*/ } -static bool patchCardRead(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool* usesThumbPtr, int* readTypePtr, u32** cardReadEndOffsetPtr, u32 startOffset) { +static bool patchCardRead(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool* usesThumbPtr, int* readTypePtr, int* sdk5ReadTypePtr, u32** cardReadEndOffsetPtr, u32 startOffset) { bool usesThumb = false; int readType = 0; + int sdk5ReadType = 0; // SDK 5 // Card read - u32* cardReadEndOffset = (u32*)findCardReadEndOffsetThumb(ndsHeader, startOffset); + // SDK 5 + //dbg_printf("Trying SDK 5 thumb...\n"); + u32* cardReadEndOffset = (u32*)findCardReadEndOffsetThumb5Type1(ndsHeader, moduleParams, startOffset); if (cardReadEndOffset) { + sdk5ReadType = 1; usesThumb = true; } + if (!cardReadEndOffset) { + // SDK 5 + cardReadEndOffset = (u32*)findCardReadEndOffsetThumb5Type0(ndsHeader, moduleParams, startOffset); + if (cardReadEndOffset) { + sdk5ReadType = 0; + usesThumb = true; + } + } + if (!cardReadEndOffset) { + //dbg_printf("Trying thumb...\n"); + cardReadEndOffset = (u32*)findCardReadEndOffsetThumb(ndsHeader, startOffset); + if (cardReadEndOffset) { + usesThumb = true; + } + } if (!cardReadEndOffset) { cardReadEndOffset = findCardReadEndOffsetType0(ndsHeader, moduleParams, startOffset); } @@ -56,7 +87,7 @@ static bool patchCardRead(cardengineArm9* ce9, const tNDSHeader* ndsHeader, cons if (cardReadEndOffset) { readType = 1; if (*(cardReadEndOffset - 1) == 0xFFFFFE00) { - //dbg_printf("Found thumb\n\n"); + // dbg_printf("Found thumb\n\n"); --cardReadEndOffset; usesThumb = true; } @@ -64,11 +95,27 @@ static bool patchCardRead(cardengineArm9* ce9, const tNDSHeader* ndsHeader, cons } *usesThumbPtr = usesThumb; *readTypePtr = readType; + *sdk5ReadTypePtr = sdk5ReadType; // SDK 5 *cardReadEndOffsetPtr = cardReadEndOffset; if (!cardReadEndOffset) { // Not necessarily needed return false; } - u32* cardReadStartOffset = (u32*)findCardReadStartOffsetThumb((u16*)cardReadEndOffset); + u32* cardReadStartOffset = NULL; + // SDK 5 + //dbg_printf("Trying SDK 5 thumb...\n"); + if (sdk5ReadType == 0) { + cardReadStartOffset = (u32*)findCardReadStartOffsetThumb5Type0(moduleParams, (u16*)cardReadEndOffset); + } else { + cardReadStartOffset = (u32*)findCardReadStartOffsetThumb5Type1(moduleParams, (u16*)cardReadEndOffset); + } + if (!cardReadStartOffset) { + //dbg_printf("Trying thumb...\n"); + cardReadStartOffset = (u32*)findCardReadStartOffsetThumb((u16*)cardReadEndOffset); + } + if (!cardReadStartOffset) { + //dbg_printf("Trying SDK 5...\n"); + cardReadStartOffset = (u32*)findCardReadStartOffset5(moduleParams, cardReadEndOffset); + } if (!cardReadStartOffset) { if (readType == 0) { cardReadStartOffset = findCardReadStartOffsetType0(moduleParams, cardReadEndOffset); @@ -83,33 +130,54 @@ static bool patchCardRead(cardengineArm9* ce9, const tNDSHeader* ndsHeader, cons // Card struct u32** cardStruct = (u32**)(cardReadEndOffset - 1); - //u32* cardStructPatch = (usesThumb ? ce9->thumbPatches->cardStructArm9 : ce9->patches->cardStructArm9); + u32* cardStructPatch = (usesThumb ? ce9->thumbPatches->cardStructArm9 : ce9->patches->cardStructArm9); if (moduleParams->sdk_version > 0x3000000) { // Save card struct - sharedAddr[4] = (u32)(*cardStruct + 7); - //*cardStructPatch = (u32)(*cardStruct + 7); // Cache management alternative + ce9->cardStruct0 = (u32)(*cardStruct + 7); + *cardStructPatch = (u32)(*cardStruct + 7); // Cache management alternative } else { // Save card struct - sharedAddr[4] = (u32)(*cardStruct + 6); - //*cardStructPatch = (u32)(*cardStruct + 6); // Cache management alternative + ce9->cardStruct0 = (u32)(*cardStruct + 6); + *cardStructPatch = (u32)(*cardStruct + 6); // Cache management alternative } // Patch u32* cardReadPatch = (usesThumb ? ce9->thumbPatches->card_read_arm9 : ce9->patches->card_read_arm9); - tonccpy(cardReadStartOffset, cardReadPatch, usesThumb ? 0xA0 : 0xE0); // 0xE0 = 0xF0 - 0x08 - /*dbg_printf("cardRead location : "); + tonccpy(cardReadStartOffset, cardReadPatch, usesThumb ? ((moduleParams->sdk_version > 0x5000000) ? 0xB0 : 0xA0) : 0xE0); // 0xE0 = 0xF0 - 0x08 + /* dbg_printf("cardRead location : "); dbg_hexa((u32)cardReadStartOffset); dbg_printf("\n"); dbg_hexa((u32)ce9); - dbg_printf("\n\n");*/ + dbg_printf("\n\n"); */ + return true; +} + +static bool patchCardReadMvDK4(u32 startOffset) { + u32* offset = findCardReadCheckOffsetMvDK4(startOffset); + if (!offset) { + return false; + } + + //offset[2] = 0xE3A00001; // mov r0, #1 + offset[3] = 0xE1A00000; // nop + offset[4] += 0xD0000000; // bne to b + + /* dbg_printf("cardReadMvDK4 location : "); + dbg_hexa((u32)offset); + dbg_printf("\n\n"); */ return true; } -static bool patchCardPullOut(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, u32** cardPullOutOffsetPtr) { +static void patchCardPullOut(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, int sdk5ReadType, u32** cardPullOutOffsetPtr) { // Card pull out u32* cardPullOutOffset = NULL; if (usesThumb) { //dbg_printf("Trying SDK 5 thumb...\n"); + if (sdk5ReadType == 0) { + cardPullOutOffset = (u32*)findCardPullOutOffsetThumb5Type0(ndsHeader, moduleParams); + } else { + cardPullOutOffset = (u32*)findCardPullOutOffsetThumb5Type1(ndsHeader, moduleParams); + } if (!cardPullOutOffset) { //dbg_printf("Trying thumb...\n"); cardPullOutOffset = (u32*)findCardPullOutOffsetThumb(ndsHeader); @@ -119,16 +187,15 @@ static bool patchCardPullOut(cardengineArm9* ce9, const tNDSHeader* ndsHeader, c } *cardPullOutOffsetPtr = cardPullOutOffset; if (!cardPullOutOffset) { - return false; + return; } // Patch u32* cardPullOutPatch = (usesThumb ? ce9->thumbPatches->card_pull_out_arm9 : ce9->patches->card_pull_out_arm9); tonccpy(cardPullOutOffset, cardPullOutPatch, usesThumb ? 0x2 : 0x30); - /*dbg_printf("cardPullOut location : "); + /* dbg_printf("cardPullOut location : "); dbg_hexa((u32)cardPullOutOffset); - dbg_printf("\n\n");*/ - return true; + dbg_printf("\n\n"); */ } /*static void patchCacheFlush(cardengineArm9* ce9, bool usesThumb, u32* cardPullOutOffset) { @@ -142,7 +209,7 @@ static bool patchCardPullOut(cardengineArm9* ce9, const tNDSHeader* ndsHeader, c }*/ static void patchCardId(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb, u32* cardReadEndOffset) { - if (!cardReadEndOffset) { + if (!isPawsAndClaws(ndsHeader) && !cardReadEndOffset) { return; } @@ -161,9 +228,9 @@ static void patchCardId(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const // Patch u32* cardIdPatch = (usesThumb ? ce9->thumbPatches->card_id_arm9 : ce9->patches->card_id_arm9); tonccpy(cardIdStartOffset, cardIdPatch, usesThumb ? 0x8 : 0xC); - /*dbg_printf("cardId location : "); + /* dbg_printf("cardId location : "); dbg_hexa((u32)cardIdStartOffset); - dbg_printf("\n\n");*/ + dbg_printf("\n\n"); */ } } @@ -191,7 +258,7 @@ static void patchCardReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, c } static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { - /*const char* romTid = getRomTid(ndsHeader); + const char* romTid = getRomTid(ndsHeader); if (strncmp(romTid, "AJS", 3) == 0 // Jump Super Stars || strncmp(romTid, "AJU", 3) == 0 // Jump Ultimate Stars @@ -201,7 +268,8 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader || strncmp(romTid, "Y8L", 3) == 0 // Golden Sun: Dark Dawn (Demo Version) || strncmp(romTid, "B8I", 3) == 0 // Spider-Man: Edge of Time || strncmp(romTid, "TAM", 3) == 0 // The Amazing Spider-Man - || !cardReadDMA) return false;*/ + || strncmp(romTid, "V2G", 3) == 0 // Mario vs. Donkey Kong: Mini-Land Mayhem (DS mode) + /* || !cardReadDMA*/) return false; u32* offset = NULL; u32 offsetDmaHandler = 0; @@ -211,10 +279,11 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader } offset = findCardEndReadDma(ndsHeader,moduleParams,usesThumb,cardReadDmaEndOffset,&offsetDmaHandler); if(offset) { - /*dbg_printf("\nNDMA CARD READ METHOD ACTIVE\n"); + /* dbg_printf("\nNDMA CARD READ METHOD ACTIVE\n"); dbg_printf("cardEndReadDma location : "); dbg_hexa((u32)offset); - dbg_printf("\n\n");*/ + dbg_printf("\n\n"); */ + if(moduleParams->sdk_version < 0x5000000) { // SDK1-4 if(usesThumb) { u16* thumbOffset = (u16*)offset; @@ -264,6 +333,25 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader } ce9->patches->cardEndReadDmaRef = offsetDmaHandler==0 ? armOffset : (u32*)offsetDmaHandler; } + } else { + // SDK5 + if(usesThumb) { + u16* thumbOffset = (u16*)offset; + while(*thumbOffset!=0xB508) { // push {r3, lr} + thumbOffset--; + } + ce9->thumbPatches->cardEndReadDmaRef = (u32*)thumbOffset; + thumbOffset[1] = 0x46C0; // NOP + thumbOffset[2] = 0x46C0; // NOP + thumbOffset[3] = 0x46C0; // NOP + thumbOffset[4] = 0x46C0; // NOP + } else { + u32* armOffset = (u32*)offset; + armOffset--; + *armOffset = 0xE92D4008; // STMFD SP!, {R3,LR} + ce9->patches->cardEndReadDmaRef = armOffset; + } + } return true; } return false; @@ -271,7 +359,7 @@ static bool patchCardEndReadDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader bool setDmaPatched = false; static bool patchCardSetDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams, bool usesThumb) { - /*const char* romTid = getRomTid(ndsHeader); + const char* romTid = getRomTid(ndsHeader); if (strncmp(romTid, "AJS", 3) == 0 // Jump Super Stars || strncmp(romTid, "AJU", 3) == 0 // Jump Ultimate Stars @@ -281,7 +369,8 @@ static bool patchCardSetDma(cardengineArm9* ce9, const tNDSHeader* ndsHeader, co || strncmp(romTid, "Y8L", 3) == 0 // Golden Sun: Dark Dawn (Demo Version) || strncmp(romTid, "B8I", 3) == 0 // Spider-Man: Edge of Time || strncmp(romTid, "TAM", 3) == 0 // The Amazing Spider-Man - || !cardReadDMA) return false;*/ + || strncmp(romTid, "V2G", 3) == 0 // Mario vs. Donkey Kong: Mini-Land Mayhem (DS mode) + /* || !cardReadDMA*/) return false; //dbg_printf("\npatchCardSetDma\n"); @@ -352,17 +441,17 @@ static bool getSleep(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const mod } bool a9PatchCardIrqEnable(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { - /*const char* romTid = getRomTid(ndsHeader); + const char* romTid = getRomTid(ndsHeader); if (strncmp(romTid, "AJS", 3) == 0 // Jump Super Stars - Fix white screen on boot || strncmp(romTid, "AJU", 3) == 0 // Jump Ultimate Stars - Fix white screen on boot || strncmp(romTid, "AWD", 3) == 0 // Diddy Kong Racing - Fix corrupted 3D model bug || strncmp(romTid, "CP3", 3) == 0 // Viva Pinata - Fix touch and model rendering bug - || strncmp(romTid, "BO5", 3) == 0 // Golden Sun: Dark Dawn + || strncmp(romTid, "BO5", 3) == 0 // Golden Sun: Dark Dawn - Fix black screen on boot || strncmp(romTid, "Y8L", 3) == 0 // Golden Sun: Dark Dawn (Demo Version) - Fix black screen on boot || strncmp(romTid, "B8I", 3) == 0 // Spider-Man: Edge of Time - Fix white screen on boot || strncmp(romTid, "TAM", 3) == 0 // The Amazing Spider-Man - Fix white screen on boot - ) return true;*/ + ) return true; bool usesThumb = false; @@ -372,7 +461,7 @@ bool a9PatchCardIrqEnable(cardengineArm9* ce9, const tNDSHeader* ndsHeader, cons return false; } u32* cardIrqEnablePatch = (usesThumb ? ce9->thumbPatches->card_irq_enable : ce9->patches->card_irq_enable); - tonccpy(cardIrqEnableOffset, cardIrqEnablePatch, usesThumb ? 0x20 : 0x30); + tonccpy(cardIrqEnableOffset, cardIrqEnablePatch, usesThumb ? 0x18 : 0x30); /*dbg_printf("cardIrqEnable location : "); dbg_hexa((u32)cardIrqEnableOffset); dbg_printf("\n\n");*/ @@ -380,7 +469,7 @@ bool a9PatchCardIrqEnable(cardengineArm9* ce9, const tNDSHeader* ndsHeader, cons } static void patchMpu(const tNDSHeader* ndsHeader, const module_params_t* moduleParams, u32 patchMpuRegion) { - //if (patchMpuRegion == 2 || isSdk5(moduleParams)) return; + if (patchMpuRegion == 2) return; unpatchedFunctions* unpatchedFuncs = (unpatchedFunctions*)UNPATCHED_FUNCTION_LOCATION; @@ -463,7 +552,7 @@ static void patchMpu(const tNDSHeader* ndsHeader, const module_params_t* moduleP }*/ } - //if (!isSdk5(moduleParams)) { + if (moduleParams->sdk_version < 0x5000000 && unpatchedFuncs->mpuInitRegionOldData != 0x200002B) { u32* mpuDataOffsetAlt = findMpuDataOffsetAlt(ndsHeader); if (mpuDataOffsetAlt) { unpatchedFuncs->mpuDataOffsetAlt = mpuDataOffsetAlt; @@ -471,15 +560,15 @@ static void patchMpu(const tNDSHeader* ndsHeader, const module_params_t* moduleP *mpuDataOffsetAlt = PAGE_32M | 0x02000000 | 1; - /*dbg_printf("Mpu data alt: "); + /* dbg_printf("Mpu data alt: "); dbg_hexa((u32)mpuDataOffsetAlt); - dbg_printf("\n\n");*/ + dbg_printf("\n\n"); */ } - //} + } } static void patchMpu2(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { - if (moduleParams->sdk_version < 0x2008000 || moduleParams->sdk_version > 0x5000000) { + if (moduleParams->sdk_version > 0x5000000) { return; } @@ -522,7 +611,7 @@ static void patchMpu2(const tNDSHeader* ndsHeader, const module_params_t* module //Original code made loading slow, so new code is used unpatchedFuncs->mpuDataOffset2 = mpuDataOffset; unpatchedFuncs->mpuInitRegionOldData2 = *mpuDataOffset; - *mpuDataOffset = PAGE_128K | 0x027E0000 | 1; + *mpuDataOffset = 0; //} /*u32 mpuInitRegionNewData = PAGE_32M | 0x02000000 | 1; @@ -561,6 +650,12 @@ static void patchMpu2(const tNDSHeader* ndsHeader, const module_params_t* module dbg_hexa((u32)mpuInitOffset); dbg_printf("\n\n");*/ + u32 mpuInitOffsetInSrl = (u32)mpuInitOffset; + mpuInitOffsetInSrl -= (u32)ndsHeader->arm9destination; + + if (mpuInitOffsetInSrl >= 0 && mpuInitOffsetInSrl < 0x4000) { + unpatchedFuncs->mpuInitOffset2 = mpuInitOffset; + } *mpuInitOffset = 0xE1A00000; // nop // Try to find it @@ -577,15 +672,39 @@ static void patchMpu2(const tNDSHeader* ndsHeader, const module_params_t* module } } +void patchMpuChange(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { + if (moduleParams->sdk_version < 0x5000000) { + return; + } + + u32* offset = findMpuChange(ndsHeader); + + if (!offset) { + return; + } + + if (offset[0] == 0xE3A00001 || offset[0] == 0x03A0202C) { + offset[3] = 0xE1A00000; // nop + } else { + u16* thumbOffset = (u16*)offset; + thumbOffset[3] = 0x46C0; // nop + thumbOffset[4] = 0x46C0; // nop + } + + /* dbg_printf("Mpu change: "); + dbg_hexa((u32)offset); + dbg_printf("\n\n"); */ +} + static void randomPatch(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { - //const char* romTid = getRomTid(ndsHeader); + const char* romTid = getRomTid(ndsHeader); // Random patch if (moduleParams->sdk_version > 0x3000000 - /*&& strncmp(romTid, "AKT", 3) != 0 // Doctor Tendo + && strncmp(romTid, "AKT", 3) != 0 // Doctor Tendo && strncmp(romTid, "ACZ", 3) != 0 // Cars && strncmp(romTid, "ABC", 3) != 0 // Harvest Moon DS - && strncmp(romTid, "AWL", 3) != 0*/) // TWEWY + && strncmp(romTid, "AWL", 3) != 0) // TWEWY { u32* randomPatchOffset = findRandomPatchOffset(ndsHeader); if (randomPatchOffset) { @@ -596,6 +715,23 @@ static void randomPatch(const tNDSHeader* ndsHeader, const module_params_t* modu } } +// SDK 5 +static void randomPatch5Second(const tNDSHeader* ndsHeader, const module_params_t* moduleParams) { + if (moduleParams->sdk_version < 0x5000000) { + return; + } + + // Random patch SDK 5 second + u32* randomPatchOffset5Second = findRandomPatchOffset5Second(ndsHeader); + if (!randomPatchOffset5Second) { + return; + } + // Patch + *randomPatchOffset5Second = 0xE3A00000; + //*(u32*)((u32)randomPatchOffset5Second + 4) = 0xE12FFF1E; + *(randomPatchOffset5Second + 1) = 0xE12FFF1E; +} + /*static void setFlushCache(cardengineArm9* ce9, u32 patchMpuRegion, bool usesThumb) { ce9->patches->needFlushDCCache = (patchMpuRegion == 1); }*/ @@ -605,32 +741,59 @@ u32 patchCardNdsArm9(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const mod bool usesThumb; //bool slot2usesThumb = false; int readType; + int sdk5ReadType; // SDK 5 u32* cardReadEndOffset; u32* cardPullOutOffset; a9PatchCardIrqEnable(ce9, ndsHeader, moduleParams); + const char* romTid = getRomTid(ndsHeader); + u32 startOffset = (u32)ndsHeader->arm9destination; + if (strncmp(romTid, "UOR", 3) == 0) { // Start at 0x2003800 for "WarioWare: DIY" + startOffset = (u32)ndsHeader->arm9destination + 0x3800; + } else if (strncmp(romTid, "UXB", 3) == 0) { // Start at 0x2080000 for "Jam with the Band" + startOffset = (u32)ndsHeader->arm9destination + 0x80000; + } else if (strncmp(romTid, "USK", 3) == 0) { // Start at 0x20E8000 for "Face Training" + startOffset = (u32)ndsHeader->arm9destination + 0xE4000; + } /*dbg_printf("startOffset : "); dbg_hexa(startOffset); dbg_printf("\n\n");*/ patchMpu(ndsHeader, moduleParams, patchMpuRegion); + patchMpuChange(ndsHeader, moduleParams); patchMpu2(ndsHeader, moduleParams); - if (!patchCardRead(ce9, ndsHeader, moduleParams, &usesThumb, &readType, &cardReadEndOffset, startOffset)) { + if (isPawsAndClaws(ndsHeader)) { + patchCardId(ce9, ndsHeader, moduleParams, false, NULL); // Patch card ID first + } + + if (!patchCardRead(ce9, ndsHeader, moduleParams, &usesThumb, &readType, &sdk5ReadType, &cardReadEndOffset, startOffset)) { //dbg_printf("ERR_LOAD_OTHR\n\n"); return ERR_LOAD_OTHR; } fixForDifferentBios(ce9, ndsHeader, usesThumb); - patchCardPullOut(ce9, ndsHeader, moduleParams, usesThumb, &cardPullOutOffset); + if (strncmp(romTid, "V2G", 3) == 0) { + // try to patch card read a second time + // dbg_printf("patch card read a second time\n"); + // dbg_printf("startOffset : 0x02030000\n\n"); + if (!patchCardReadMvDK4(0x02030000)) { + // dbg_printf("ERR_LOAD_OTHR\n\n"); + return ERR_LOAD_OTHR; + } + } + + patchCardPullOut(ce9, ndsHeader, moduleParams, usesThumb, sdk5ReadType, &cardPullOutOffset); //patchCacheFlush(ce9, usesThumb, cardPullOutOffset); - patchCardId(ce9, ndsHeader, moduleParams, usesThumb, cardReadEndOffset); + if (!isPawsAndClaws(ndsHeader)) { + patchCardId(ce9, ndsHeader, moduleParams, usesThumb, cardReadEndOffset); + } if (getSleep(ce9, ndsHeader, moduleParams, usesThumb)) { patchCardReadDma(ce9, ndsHeader, moduleParams, usesThumb); @@ -640,6 +803,7 @@ u32 patchCardNdsArm9(cardengineArm9* ce9, const tNDSHeader* ndsHeader, const mod } if (!patchCardEndReadDma(ce9, ndsHeader, moduleParams, usesThumb)) { randomPatch(ndsHeader, moduleParams); + randomPatch5Second(ndsHeader, moduleParams); } } diff --git a/retail/cardenginei/arm7/source/patcher/save_patch_universal.c b/retail/cardenginei/arm7/source/patcher/save_patch_universal.c index 1da1722c5..02ef8c85b 100644 --- a/retail/cardenginei/arm7/source/patcher/save_patch_universal.c +++ b/retail/cardenginei/arm7/source/patcher/save_patch_universal.c @@ -8,7 +8,6 @@ extern u32 vAddrOfRelocSrc; extern u32 relocDestAtSharedMem; -//extern u32 newSwiHaltAddr; // // Subroutine function signatures ARM7 @@ -35,6 +34,7 @@ static const u16 a7JumpTableSignatureUniversalThumb_pt2[3] = {0x6910, 0x68D static const u16 a7JumpTableSignatureUniversalThumb_pt3[2] = {0x6908, 0x6949}; static const u16 a7JumpTableSignatureUniversalThumb_pt3_alt[2] = {0x6910, 0x6951}; static const u16 a7JumpTableSignatureUniversalThumb_pt3_alt2[2] = {0x6800, 0x6900}; +static const u16 a7JumpTableSignatureUniversalThumb_pt3_alt3[2] = {0x6800, 0x6900}; u32 savePatchUniversal(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, module_params_t* moduleParams) { @@ -175,6 +175,12 @@ u32 savePatchUniversal(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, m a7JumpTableSignatureUniversalThumb_pt3_alt, 2 ); } + if (!EepromEraseJump) { + EepromEraseJump = (u32*)findOffsetThumb( + (u16*)EepromVerifyJump + 2, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb_pt3_alt2, 2 + ); + } } else JumpTableFuncType++; } if (JumpTableFuncType == 1) { @@ -193,7 +199,7 @@ u32 savePatchUniversal(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, m ); EepromEraseJump = (u32*)findOffsetThumb( (u16*)EepromVerifyJump - 2, ndsHeader->arm7binarySize, - a7JumpTableSignatureUniversalThumb_pt3_alt2, 2 + a7JumpTableSignatureUniversalThumb_pt3_alt3, 2 ); } } @@ -334,3 +340,115 @@ u32 savePatchUniversal(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, m return 1; } + +u32 savePatchInvertedThumb(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, module_params_t* moduleParams) { + // dbg_printf("\nArm7 (patch kirby specific)\n"); + + //u32* JumpTableFunc; + u32* EepromReadJump; + u32* EepromWriteJump; + u32* EepromProgJump; + u32* EepromVerifyJump; + u32* EepromEraseJump; + + // inverted order + EepromEraseJump = (u32*)findOffsetThumb( + (u16*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb_pt3_alt3, 2 + ); + + EepromVerifyJump = (u32*)findOffsetThumb( + (u16*)EepromEraseJump + 2, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb_pt2, 3 + ); + + EepromProgJump = (u32*)findOffsetThumb( + (u16*)EepromVerifyJump + 2, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb_pt2, 3 + ); + + EepromWriteJump = (u32*)findOffsetThumb( + (u16*)EepromProgJump + 2, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb_pt2, 3 + ); + + EepromReadJump = (u32*)findOffsetThumb( + (u16*)EepromWriteJump, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb, 3 + ); + + /* dbg_printf("usesThumb\n"); + dbg_printf("inverted order\n"); + dbg_printf("EepromEraseJump\n"); + dbg_hexa((u32)EepromEraseJump); + dbg_printf("\n"); */ + + //u32 srcAddr; + + u32* eepromRead = (u32*)((u32)EepromReadJump + 0xA); + /* dbg_printf("Eeprom read :\t"); + dbg_hexa((u32)eepromRead); + dbg_printf("\t:\t"); + dbg_hexa(*eepromRead); + dbg_printf("\n"); */ + *eepromRead = ce7->patches->arm7FunctionsDirect->eepromRead; + /* dbg_printf("Eeprom read after:\t"); + dbg_hexa((u32)eepromRead); + dbg_printf("\t:\t"); + dbg_hexa(*eepromRead); + dbg_printf("\n"); */ + + u32* eepromPageWrite = (u32*)((u32)EepromWriteJump + 0xA); + /* dbg_printf("Eeprom page write:\t"); + dbg_hexa((u32)eepromPageWrite); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageWrite); + dbg_printf("\n"); */ + *eepromPageWrite = ce7->patches->arm7FunctionsDirect->eepromPageWrite; + /* dbg_printf("Eeprom page write after:\t"); + dbg_hexa((u32)eepromPageWrite); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageWrite); + dbg_printf("\n"); */ + + u32* eepromPageProg = (u32*)((u32)EepromProgJump + 0xA); + /* dbg_printf("Eeprom page prog:\t"); + dbg_hexa((u32)eepromPageProg); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageProg); + dbg_printf("\n"); */ + *eepromPageProg = ce7->patches->arm7FunctionsDirect->eepromPageProg; + /* dbg_printf("Eeprom page prog after:\t"); + dbg_hexa((u32)eepromPageProg); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageProg); + dbg_printf("\n"); */ + + u32* eepromPageVerify = (u32*)((u32)EepromVerifyJump + 0xA); + /* dbg_printf("Eeprom verify:\t"); + dbg_hexa((u32)eepromPageVerify); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageVerify); + dbg_printf("\n"); */ + *eepromPageVerify = ce7->patches->arm7FunctionsDirect->eepromPageVerify; + /* dbg_printf("Eeprom verify after:\t"); + dbg_hexa((u32)eepromPageVerify); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageVerify); + dbg_printf("\n"); */ + + u32* eepromPageErase = (u32*)((u32)EepromEraseJump + 0x8); + /* dbg_printf("Eeprom page erase:\t"); + dbg_hexa((u32)eepromPageErase); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageErase); + dbg_printf("\n"); */ + *eepromPageErase = ce7->patches->arm7FunctionsDirect->eepromPageErase; + /* dbg_printf("Eeprom page erase after:\t"); + dbg_hexa((u32)eepromPageErase); + dbg_printf("\t:\t"); + dbg_hexa(*eepromPageErase); + dbg_printf("\n"); */ + + return 1; +} diff --git a/retail/cardenginei/arm7/source/patcher/save_patch_v5.c b/retail/cardenginei/arm7/source/patcher/save_patch_v5.c new file mode 100644 index 000000000..76b001746 --- /dev/null +++ b/retail/cardenginei/arm7/source/patcher/save_patch_v5.c @@ -0,0 +1,193 @@ +#include +#include "module_params.h" +#include "patch.h" +#include "find.h" +#include "cardengine_header_arm7.h" +#include "debug_file.h" +#include "tonccpy.h" + +extern u32 vAddrOfRelocSrc; +extern u32 relocDestAtSharedMem; + +// +// Subroutine function signatures ARM7 +// + +static const u32 a7JumpTableSignatureUniversal[3] = {0xE592000C, 0xE5921010, 0xE5922014}; +static const u32 a7JumpTableSignatureUniversal_2[3] = {0xE593000C, 0xE5931010, 0xE5932014}; +static const u16 a7JumpTableSignatureUniversalThumb[4] = {0x6822, 0x68D0, 0x6911, 0x6952}; + +u32 savePatchV5(const cardengineArm7* ce7, const tNDSHeader* ndsHeader, const u32 saveFileCluster, const u32 saveSize) { + // dbg_printf("\nArm7 (patch v5)\n"); + + bool usesThumb = false; + + u32 JumpTableFunc = (u32)findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversal, 3 + ); + + if(!JumpTableFunc){ + JumpTableFunc = (u32)findOffset( + (u32*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversal_2, 3 + ); + } + + if(!JumpTableFunc){ + usesThumb = true; + JumpTableFunc = (u32)findOffsetThumb( + (u16*)ndsHeader->arm7destination, ndsHeader->arm7binarySize, + a7JumpTableSignatureUniversalThumb, 4 + ); + } + + if(!JumpTableFunc){ + return 0; + } + + /* dbg_printf("JumpTableFunc: "); + dbg_hexa(JumpTableFunc); + dbg_printf("\n"); */ + + + u32 srcAddr; + + if (usesThumb) { + /* u32* cardId = (u32*) (JumpTableFunc - 0xE); + dbg_printf("card id:\t"); + dbg_hexa((u32)cardId); + dbg_printf("\n"); + srcAddr = JumpTableFunc - 0xE - vAddrOfRelocSrc + relocDestAtSharedMem ; + const u16* patchCardId = generateA7InstrThumb(srcAddr, ce7->patches->arm7FunctionsThumb->cardId); + cardId[0] = patchCardId[0]; + cardId[1] = patchCardId[1]; */ + + u16* eepromReadBranch = (u16*)(JumpTableFunc + 0x8); + /* dbg_printf("Eeprom read branch:\t"); + dbg_hexa((u32)eepromReadBranch); + dbg_printf("\n"); */ + u16* eepromRead = getOffsetFromBLThumb(eepromReadBranch); + /* dbg_printf("Eeprom read:\t"); + dbg_hexa((u32)eepromRead); + dbg_printf("\n"); */ + tonccpy(eepromRead, (u16*)ce7->patches->arm7FunctionsThumb->eepromRead, 0x14); + + u16* eepromPageWriteBranch = (u16*)(JumpTableFunc + 0x16); + /* dbg_printf("Eeprom page write branch:\t"); + dbg_hexa((u32)eepromPageWriteBranch); + dbg_printf("\n"); */ + u16* eepromPageWrite = getOffsetFromBLThumb(eepromPageWriteBranch); + /* dbg_printf("Eeprom page write:\t"); + dbg_hexa((u32)eepromPageWrite); + dbg_printf("\n"); */ + tonccpy(eepromPageWrite, (u16*)ce7->patches->arm7FunctionsThumb->eepromPageWrite, 0x14); + + u16* eepromPageProgBranch = (u16*)(JumpTableFunc + 0x24); + /* dbg_printf("Eeprom page prog branch:\t"); + dbg_hexa((u32)eepromPageProgBranch); + dbg_printf("\n"); */ + u16* eepromPageProg = getOffsetFromBLThumb(eepromPageProgBranch); + /* dbg_printf("Eeprom page prog:\t"); + dbg_hexa((u32)eepromPageProg); + dbg_printf("\n"); */ + tonccpy(eepromPageProg, (u16*)ce7->patches->arm7FunctionsThumb->eepromPageProg, 0x14); + + u16* eepromPageVerifyBranch = (u16*)(JumpTableFunc + 0x32); + /* dbg_printf("Eeprom verify branch:\t"); + dbg_hexa((u32)eepromPageVerifyBranch); + dbg_printf("\n"); */ + u16* eepromPageVerify = getOffsetFromBLThumb(eepromPageVerifyBranch); + /* dbg_printf("Eeprom verify:\t"); + dbg_hexa((u32)eepromPageVerify); + dbg_printf("\n"); */ + tonccpy(eepromPageVerify, (u16*)ce7->patches->arm7FunctionsThumb->eepromPageVerify, 0x14); + + u16* eepromPageEraseBranch = (u16*)(JumpTableFunc + 0x3E); + /* dbg_printf("Eeprom page erase branch:\t"); + dbg_hexa((u32)eepromPageEraseBranch); + dbg_printf("\n"); */ + u16* eepromPageErase = getOffsetFromBLThumb(eepromPageEraseBranch); + /* dbg_printf("Eeprom page erase:\t"); + dbg_hexa((u32)eepromPageErase); + dbg_printf("\n"); */ + tonccpy(eepromPageErase, (u16*)ce7->patches->arm7FunctionsThumb->eepromPageErase, 0x14); + } else { + if (*(u32*)(JumpTableFunc - 0x24) == 0xEBFFFFB3) { + u32* cardId = (u32*) (JumpTableFunc - 0x24); + /* dbg_printf("card id:\t"); + dbg_hexa((u32)cardId); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc - 0x24 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchCardId = generateA7Instr(srcAddr, ce7->patches->arm7Functions->cardId); + *cardId=patchCardId; + + u32* cardRead = (u32*) (JumpTableFunc - 0x14); + /* dbg_printf("card read:\t"); + dbg_hexa((u32)cardRead); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc - 0x14 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchCardRead = generateA7Instr(srcAddr, ce7->patches->arm7Functions->cardRead); + *cardRead=patchCardRead; + } else { + u32* cardId = (u32*) (JumpTableFunc - 0x18); + /* dbg_printf("card id:\t"); + dbg_hexa((u32)cardId); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc - 0x18 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchCardId = generateA7Instr(srcAddr, ce7->patches->arm7Functions->cardId); + *cardId=patchCardId; + + u32* cardRead = (u32*) (JumpTableFunc - 0x8); + /* dbg_printf("card read:\t"); + dbg_hexa((u32)cardRead); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc - 0x8 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchCardRead = generateA7Instr(srcAddr, ce7->patches->arm7Functions->cardRead); + *cardRead=patchCardRead; + } + + u32* eepromRead = (u32*) (JumpTableFunc + 0xC); + /* dbg_printf("Eeprom read:\t"); + dbg_hexa((u32)eepromRead); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc + 0xC - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchRead = generateA7Instr(srcAddr, ce7->patches->arm7Functions->eepromRead); + *eepromRead=patchRead; + + u32* eepromPageWrite = (u32*) (JumpTableFunc + 0x24); + /* dbg_printf("Eeprom page write:\t"); + dbg_hexa((u32)eepromPageWrite); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc + 0x24 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchWrite = generateA7Instr(srcAddr, ce7->patches->arm7Functions->eepromPageWrite); + *eepromPageWrite=patchWrite; + + u32* eepromPageProg = (u32*) (JumpTableFunc + 0x3C); + /* dbg_printf("Eeprom page prog:\t"); + dbg_hexa((u32)eepromPageProg); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc + 0x3C - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchProg = generateA7Instr(srcAddr, ce7->patches->arm7Functions->eepromPageProg); + *eepromPageProg=patchProg; + + u32* eepromPageVerify = (u32*) (JumpTableFunc + 0x54); + /* dbg_printf("Eeprom verify:\t"); + dbg_hexa((u32)eepromPageVerify); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc + 0x54 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchVerify = generateA7Instr(srcAddr, ce7->patches->arm7Functions->eepromPageVerify); + *eepromPageVerify=patchVerify; + + + u32* eepromPageErase = (u32*) (JumpTableFunc + 0x68); + /* dbg_printf("Eeprom page erase:\t"); + dbg_hexa((u32)eepromPageErase); + dbg_printf("\n"); */ + srcAddr = JumpTableFunc + 0x68 - vAddrOfRelocSrc + relocDestAtSharedMem ; + u32 patchErase = generateA7Instr(srcAddr, ce7->patches->arm7Functions->eepromPageErase); + *eepromPageErase=patchErase; + } + + return 1; +} diff --git a/retail/cardenginei/arm9/source/misc.c b/retail/cardenginei/arm9/source/misc.c index 3fc2a88a7..2af4a9d49 100644 --- a/retail/cardenginei/arm9/source/misc.c +++ b/retail/cardenginei/arm9/source/misc.c @@ -40,6 +40,7 @@ #define slowSoftReset BIT(10) #define softResetMb BIT(13) #define cloneboot BIT(14) +#define isDlp BIT(15) #include "my_fat.h" @@ -131,9 +132,9 @@ void enableIPC_SYNC(void) { } #ifndef TWLSDK -void initialize(void) { - static bool initialized = false; +static bool initialized = false; +void initialize(void) { if (initialized) { return; } @@ -150,6 +151,9 @@ void initialize(void) { cacheAddressTable = (u32*)CACHE_ADDRESS_TABLE_LOCATION_TWLSDK; #endif } + } else { + sharedAddr = (vu32*)CARDENGINE_SHARED_ADDRESS_SDK1; + ndsHeader = (tNDSHeader*)NDS_HEADER; } #endif initialized = true; @@ -335,12 +339,13 @@ void reset(u32 param, u32 tid2) { while (REG_VCOUNT == 191); } - if (*(u32*)(RESET_PARAM+0xC) > 0) { + if ((ce9->valueBits & isDlp) || *(u32*)(RESET_PARAM+0xC) > 0) { u32 newIrqTable = sharedAddr[2]; ce9->valueBits = sharedAddr[1]; ce9->irqTable = (u32*)newIrqTable; ce9->cardStruct0 = sharedAddr[4]; sharedAddr[4] = 0; + initialized = false; } #endif diff --git a/retail/cardenginei/arm9_dlp/Makefile b/retail/cardenginei/arm9_dlp/Makefile new file mode 100644 index 000000000..eceea2570 --- /dev/null +++ b/retail/cardenginei/arm9_dlp/Makefile @@ -0,0 +1,144 @@ +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITARM)),) +$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") +endif + +include $(DEVKITARM)/ds_rules + +ifeq ($(OS),Windows_NT) +LZSS ?= ../../../lzss.exe + +else + +LZSS ?= lzss + +endif +#--------------------------------------------------------------------------------- +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +# DATA is a list of directories containing binary files +# all directories are relative to this makefile +#--------------------------------------------------------------------------------- +BUILD := build +SOURCES := ../arm9/source ../arm9/source_ext ../../common/source_general +INCLUDES := ../arm9/include ../arm9/include_ext ../../common/include +DATA := data + + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -march=armv5te -mtune=arm946e-s + +CFLAGS := -g -Wall -O2\ + -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\ + -ffast-math \ + $(ARCH) + +# ADD -DDEBUG here for logging/debug +CFLAGS += $(INCLUDE) -DARM9 -DNO_CARDID +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions + +ASFLAGS := -g $(ARCH) $(INCLUDE) + +LDFLAGS = -nostartfiles -T cardengine.ld -g $(ARCH) -Wl,-Map,$(notdir $*.map) + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project (order is important) +#--------------------------------------------------------------------------------- +LIBS := + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBNDS) + + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export TARGET := cardenginei_arm9_dlp +export OUTPUT := $(CURDIR)/../../nitrofiles_dec/$(TARGET) +export OUTPUT_CMP := $(CURDIR)/../../nitrofiles/$(TARGET) +export DEPSDIR := $(CURDIR)/$(BUILD) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + @cp $(OUTPUT).bin $(OUTPUT_CMP).lz77 + @$(LZSS) -ewf $(OUTPUT_CMP).lz77 + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf + + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).bin: $(DEPSDIR)/$(TARGET).elf +$(DEPSDIR)/$(TARGET).elf: cardengine.ld $(OFILES) +# @echo linking $(notdir $@) +# @$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@ + +cardengine.ld: $(CURDIR)/../cardengine.ld.in + $(CPP) -P $(INCLUDE) $< $@ + + +#--------------------------------------------------------------------------------- +%.bin : %.elf +#--------------------------------------------------------------------------------- + @$(OBJCOPY) -O binary $< $@ + @echo built ... $(notdir $@) + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/retail/cardenginei/arm9_dlp/cardengine.ld.in b/retail/cardenginei/arm9_dlp/cardengine.ld.in new file mode 100644 index 000000000..419864840 --- /dev/null +++ b/retail/cardenginei/arm9_dlp/cardengine.ld.in @@ -0,0 +1,201 @@ +#include "locations.h" + +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +/*ENTRY(_start)*/ + +MEMORY { + + vram : ORIGIN = CARDENGINEI_ARM9_LOCATION_DLP, LENGTH = 29K /* Main RAM */ +} + +__vram_start = ORIGIN(vram); +__vram_top = ORIGIN(vram)+ LENGTH(vram); +__sp_irq = __vram_top - 0x60; +__sp_svc = __sp_irq - 0x100; +__sp_usr = __sp_svc - 0x100; + +__irq_flags = __vram_top - 8; +__irq_flagsaux = __vram_top - 0x40; /*__irq_flagsaux = 0x04000000 - 0x40;*/ +__irq_vector = __vram_top - 4; + +SECTIONS +{ + .init : + { + __text_start = . ; + KEEP (*(.init)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .plt : + { + *(.plt) + } >vram = 0xff + + .text : /* ALIGN (4): */ + { + + *(.text*) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .fini : + { + KEEP (*(.fini)) + } >vram =0xff + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + SORT(CONSTRUCTORS) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >vram + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >vram + __exidx_end = .; + +/* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { KEEP (*(.preinit_array)) } >vram = 0xff + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } >vram = 0xff + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } >vram = 0xff + PROVIDE (__fini_array_end = .); + + .ctors : + { + /* gcc uses crtbegin.o to find the start of the constructors, so + we make sure it is first. Because this is a wildcard, it + doesn't matter if the user does not actually link against + crtbegin.o; the linker won't look for a file to match a + wildcard. The wildcard also means that it doesn't matter which + directory crtbegin.o is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .eh_frame : + { + KEEP (*(.eh_frame)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + + .gcc_except_table : + { + *(.gcc_except_table) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram = 0xff + .jcr : { KEEP (*(.jcr)) } >vram = 0 + .got : { *(.got.plt) *(.got) } >vram = 0 + + + .vram ALIGN(4) : + { + __vram_start = ABSOLUTE(.) ; + *(.vram) + *vram.*(.text) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + __vram_end = ABSOLUTE(.) ; + } >vram = 0xff + + + .data ALIGN(4) : { + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + CONSTRUCTORS + . = ALIGN(4); + __data_end = ABSOLUTE(.) ; + } >vram = 0xff + + + + .bss ALIGN(4) : + { + __bss_start = ABSOLUTE(.); + __bss_start__ = ABSOLUTE(.); + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(COMMON) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >vram + + __bss_end = . ; + __bss_end__ = . ; + + _end = . ; + __end__ = . ; + PROVIDE (end = _end); + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack 0x80000 : { _stack = .; *(.stack) } + /* These must appear regardless of . */ +} diff --git a/retail/common/include/cardengine_header_arm7.h b/retail/common/include/cardengine_header_arm7.h index 4b32917aa..4c94a2bfa 100644 --- a/retail/common/include/cardengine_header_arm7.h +++ b/retail/common/include/cardengine_header_arm7.h @@ -101,6 +101,7 @@ typedef struct cardengineArm7 { 18: dsiBios 19: bootstrapOnFlashcard 20: ndmaDisabled + 21: isDlp 31: scfgLocked */ s32 mainScreen; diff --git a/retail/common/include/cardengine_header_arm9.h b/retail/common/include/cardengine_header_arm9.h index 68e843c0a..9f9961e01 100644 --- a/retail/common/include/cardengine_header_arm9.h +++ b/retail/common/include/cardengine_header_arm9.h @@ -100,6 +100,7 @@ typedef struct cardengineArm9 { 12: asyncCardRead 13: softResetMb 14: cloneboot + 15: isDlp */ s32 mainScreen; u32 overlaysSize; diff --git a/retail/common/include/locations.h b/retail/common/include/locations.h index 0b6a1c3e3..5f7c51416 100644 --- a/retail/common/include/locations.h +++ b/retail/common/include/locations.h @@ -86,6 +86,7 @@ #define CARDENGINEI_ARM7_DSIWARE_LOCATION3 0x03807400 #define CARDENGINEI_ARM9_LOCATION 0x027D8000 #define CARDENGINEI_ARM9_LOCATION2 0x027E0000 +#define CARDENGINEI_ARM9_LOCATION_DLP 0x02800000 #define CARDENGINEI_ARM9_LOCATION_DSI_WRAM 0x03700000 #define CARDENGINEI_ARM9_TWLSDK_LOCATION 0x02FD6C00 // Used for DSi-Enhanced games in DSi mode #define CARDENGINEI_ARM9_TWLSDK_LOCATION3 0x02F80000 // Used for DSi-Exclusive games