From 1d18f06b4cd65d17a076543377f4d41516835c2b Mon Sep 17 00:00:00 2001 From: Gericom Date: Sat, 10 Jan 2026 14:04:30 +0100 Subject: [PATCH] =?UTF-8?q?Added=20support=20for=20SDK=20variant=20with=20?= =?UTF-8?q?a=20lot=20of=20inlining.=20Fixes=20#53.=20Fixes=20Tropix!=20...?= =?UTF-8?q?Your=20Island=20Getaway=20and=20Think=20-=20Training=20f=C3=BCr?= =?UTF-8?q?=20den=20Kopf=20-=20Kids=20-=20Spiel=20Dich=20Schlau!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arm9/sdk2to4/CardiReadCardPatch.cpp | 33 +++++++++++++------ .../arm9/sdk2to4/CardiReadCardPatchAsm.s | 4 +-- .../arm9/sdk2to4/CardiTryReadCardDmaPatch.cpp | 5 +++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatch.cpp b/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatch.cpp index 3f3c215..783e084 100644 --- a/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatch.cpp +++ b/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatch.cpp @@ -20,6 +20,7 @@ static const u32 sCARDiReadCardPatternSdk3027530Thumb[] = { 0xB082B5F8u, 0x90019 static const u32 sCARDiReadCardPatternSdk4002774[] = { 0xE92D4070u, 0xE59F40D0u, 0xE1A06000u, 0xE3A00C02u }; static const u32 sCARDiReadCardPatternSdk4017530[] = { 0xE92D4070u, 0xE59F40D8u, 0xE1A06000u, 0xE3A00C02u }; static const u32 sCARDiReadCardPatternSdk4017530Thumb[] = { 0xB082B5F8u, 0x90019000u, 0x90013020u, 0x69C24827u }; +static const u32 sCARDiReadCardPatternSdk4027531ThumbInlined[] = { 0xB082B5F8u, 0x90019000u, 0x90013020u, 0x69C14841u }; static const u32 sCARDiReadCardPatternSdk4027539SpiritTracks[] = { 0xE92D4070u, 0xE59F40D4u, 0xE1A06000u, 0xE3A00C02u }; void CardiReadCardPatch::TryPattern(PatchContext& patchContext, const u32* pattern, u32 byteLength) @@ -90,6 +91,8 @@ bool CardiReadCardPatch::FindPatchTarget(PatchContext& patchContext) TryPattern(patchContext, sCARDiReadCardPatternSdk3027530Thumb, sizeof(sCARDiReadCardPatternSdk3027530Thumb)); if (!_cardiReadCard) TryPattern(patchContext, sCARDiReadCardPatternSdk2027533ThumbChouSoujuu, sizeof(sCARDiReadCardPatternSdk2027533ThumbChouSoujuu)); + if (!_cardiReadCard) + TryPattern(patchContext, sCARDiReadCardPatternSdk4027531ThumbInlined, sizeof(sCARDiReadCardPatternSdk4027531ThumbInlined)); if (_cardiReadCard) _thumb = true; @@ -153,42 +156,53 @@ void CardiReadCardPatch::ApplyPatch(PatchContext& patchContext) if (_thumb) { u32 patchOffset; - u32 cardiCommonOffset; if (_foundPattern == sCARDiReadCardPatternSdk4017530Thumb) { patchOffset = 0x36; - cardiCommonOffset = 0x74; patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x3C); patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R4); // dst - patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0); + patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r3 from the stack patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP; - patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4); + patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 0xC); // copy to r4 on the stack + *(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R3, 0x74); // ldr r3,= cardi_common } else if (_foundPattern == sCARDiReadCardPatternSdk3027530Thumb) { patchOffset = 0x36; - cardiCommonOffset = 0x6C; patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x36); patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R4); // dst - patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0); + patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r3 from the stack patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP; - patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4); + patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 0xC); // copy to r4 on the stack + *(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R3, 0x6C); // ldr r3,= cardi_common } else if (_foundPattern == sCARDiReadCardPatternSdk2004F4CThumb) { patchOffset = 0x36; - cardiCommonOffset = 0; patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x2E); patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R5); // dst - patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r6 from stack + patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0x10); // r6 from stack if (patchContext.GetSdkVersion().GetMajor() <= SDK_VERSION_MAJOR_NITRO_2) patch_cardireadcard_adjust_cardicommon_offset = THUMB_SUBS_IMM(THUMB_R6, THUMB_R6, 4); else patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP; patch_cardireadcard_mov_r3_to_dst = THUMB_MOVS_REG(THUMB_R5, THUMB_R3); + *(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_NOP; + } + else if (_foundPattern == sCARDiReadCardPatternSdk4027531ThumbInlined) + { + // This variant has a lot of inlining + patchOffset = 0x36; + patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x64); + patch_cardireadcard_mov_src_to_r0 = THUMB_LDR_SP_IMM(THUMB_R0, 8); // src, r3 from the stack + patch_cardireadcard_mov_dst_to_r1 = THUMB_LDR_SP_IMM(THUMB_R1, 4); // dst, r2 from the stack + patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0); // r1 from the stack + patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP; + patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4); // copy to r2 on the stack + *(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R1, 0xDC); // ldr r1,= cardi_common } else { @@ -196,7 +210,6 @@ void CardiReadCardPatch::ApplyPatch(PatchContext& patchContext) while (1); } - *(u16*)((u8*)_cardiReadCard + patchOffset + 0) = cardiCommonOffset == 0 ? THUMB_NOP : THUMB_LDR_PC_IMM(THUMB_R3, cardiCommonOffset); // ldr r0,= cardi_common *(u16*)((u8*)_cardiReadCard + patchOffset + 2) = THUMB_LDR_PC_IMM(THUMB_R0, 0); // ldr r0,= entryAddress *(u16*)((u8*)_cardiReadCard + patchOffset + 4) = THUMB_BLX(THUMB_R0); *(u32*)((u8*)_cardiReadCard + patchOffset + 6) = entryAddress; diff --git a/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatchAsm.s b/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatchAsm.s index b344ceb..7e3a04e 100644 --- a/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatchAsm.s +++ b/arm9/source/patches/arm9/sdk2to4/CardiReadCardPatchAsm.s @@ -11,7 +11,7 @@ patch_cardireadcard_entry: patch_cardireadcard_return_offset: movs r0, #0x38 add lr, r0 - push {r3,r4,r6,lr} + push {r1,r2,r3,r4,r6,lr} ldr r3, __patch_cardireadcard_fix_cp15_asm_address blx r3 .global patch_cardireadcard_mov_src_to_r0 @@ -59,7 +59,7 @@ patch_cardireadcard_mov_r3_to_dst: do_read: ldr r3, __patch_cardireadcard_sdread_asm_address blx r3 - pop {r3,r4,r6,pc} + pop {r1,r2,r3,r4,r6,pc} .balign 4 diff --git a/arm9/source/patches/arm9/sdk2to4/CardiTryReadCardDmaPatch.cpp b/arm9/source/patches/arm9/sdk2to4/CardiTryReadCardDmaPatch.cpp index 15502ba..eeb8840 100644 --- a/arm9/source/patches/arm9/sdk2to4/CardiTryReadCardDmaPatch.cpp +++ b/arm9/source/patches/arm9/sdk2to4/CardiTryReadCardDmaPatch.cpp @@ -36,6 +36,7 @@ static const u32 sCARDiTryReadCardDmaPatternSdkThumb[] = { 0xB084B5F8u, 0x483D90 static const u32 sCARDiTryReadCardDmaPatternSdk4007531Thumb[] = { 0xB084B5F8u, 0x483E9000u, 0x6A446A05u, 0x90032000u }; static const u32 sCARDiTryReadCardDmaPatternSdk4017530Thumb[] = { 0xB084B5F8u, 0x48479000u, 0x6A446A05u, 0x90032000u }; static const u32 sCARDiTryReadCardDmaPatternSdk4027530Thumb[] = { 0xB084B5F8u, 0x48479000u, 0x6A446A05u, 0x90032000u }; +static const u32 sCARDiTryReadCardDmaPatternSdk4027531ThumbInlined[] = { 0xB083B5F0u, 0x485D9000u, 0x6A062500u, 0x1C286A44u }; static const u16 sReturnFalsePatchThumb[] = { THUMB_MOVS_IMM(0, 0), THUMB_BX_LR }; static const u32 sReturnFalsePatchArm[] = { 0xE3A00000, 0xE12FFF1E }; // mov r0, #0; bx lr @@ -141,6 +142,10 @@ bool CardiTryReadCardDmaPatch::FindPatchTarget(PatchContext& patchContext) if (!_cardiTryReadCardDma) TryPattern(patchContext, sCARDiTryReadCardDmaPatternThumbChouSoujuu); } + if (!_cardiTryReadCardDma && patchContext.GetSdkVersion() == 0x4027531) + { + TryPattern(patchContext, sCARDiTryReadCardDmaPatternSdk4027531ThumbInlined); + } if (_cardiTryReadCardDma) _thumb = true;