From 64e020182a84740fd1aa90b717f578920143f535 Mon Sep 17 00:00:00 2001 From: Gericom Date: Sat, 27 Dec 2025 12:44:00 +0100 Subject: [PATCH] Added check to CardiTaskThreadPatch that the required slot is actually mapped to arm7. Fixes #60 --- .../patches/arm7/CardiTaskThreadPatchAsm.h | 1 + .../patches/arm7/CardiTaskThreadPatchAsm.s | 70 +++++++++---------- arm9/source/patches/arm7/VerifySaveAsm.s | 8 +-- .../arm7/sdk2to4/CardiTaskThreadPatch.cpp | 10 +++ .../arm7/sdk5/CardiDoTaskFromArm9Patch.cpp | 10 +++ arm9/source/patches/platform/LoaderPlatform.h | 5 ++ .../patches/platform/LoaderPlatformType.h | 11 +++ .../platform/ace3ds/Ace3DSLoaderPlatform.h | 2 + .../acekard-common/IoRPGLoaderPlatform.h | 2 + .../platform/dspico/DSPicoLoaderPlatform.h | 2 + .../platform/dstt/DSTTLoaderPlatform.h | 2 + .../patches/platform/ezp/EZPLoaderPlatform.h | 2 + .../platform/g003/G003LoaderPlatform.h | 2 + .../platform/isnitro/IsNitroLoaderPlatform.h | 2 + .../platform/m3ds/M3DSLoaderPlatform.h | 2 + .../platform/melonds/MelonDSLoaderPlatform.h | 2 + .../patches/platform/r4/R4LoaderPlatform.h | 2 + .../supercard/SuperCardLoaderPlatform.h | 2 + 18 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 arm9/source/patches/platform/LoaderPlatformType.h diff --git a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h index 29ac1b7..b67be3c 100644 --- a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h +++ b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h @@ -8,6 +8,7 @@ extern "C" void __patch_carditaskthread_entry_sdk4(); extern u16 __patch_carditaskthread_mov_cardicommon_to_r4; extern u16 __patch_carditaskthread_mov_command_to_r0; +extern u16 __patch_carditaskthread_lsls_exmemstat_bit_to_r1; extern u32 __patch_carditaskthread_failoffset; extern u32 __patch_carditaskthread_successoffset; diff --git a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s index 22de3ba..64a7c03 100644 --- a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s +++ b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s @@ -21,30 +21,34 @@ __patch_carditaskthread_mov_cardicommon_to_r4: __patch_carditaskthread_mov_command_to_r0: ldr r0, [r4, #4] // r0 = command + ldr r1,= 0x04000204 + ldrh r1, [r1] +.global __patch_carditaskthread_lsls_exmemstat_bit_to_r1 +__patch_carditaskthread_lsls_exmemstat_bit_to_r1: + lsls r1, r1, #20 + mvns r1, r1 + lsrs r1, r1, #31 // r1 = 0 when slot mapped to arm7, 1 when slot not mapped to arm7 + cmp r0, #2 - beq identify_backup - + beq end_success // identify cmp r0, #6 - beq read_backup - + beq read_backup cmp r0, #7 - beq write_backup - + beq write_backup cmp r0, #8 - beq write_backup - + beq write_backup cmp r0, #9 - beq verify_backup + beq verify_backup // erase cmp r0, #10 - beq end_success + beq end_success cmp r0, #11 - beq end_success + beq end_success cmp r0, #12 - beq end_success + beq end_success cmp r0, #15 - beq end_success + beq end_success end_fail: ldr r0, __patch_carditaskthread_failoffset @@ -58,18 +62,8 @@ end: adds r3, r0 bx r3 -identify_backup: - b end_success - read_backup: - ldr r0, [r4] - movs r1, #0 - str r1, [r0] // result - ldr r1, [r0, #0xC] // src - ldr r2, [r0, #0x10] // dst - ldr r3, [r0, #0x14] // len - cmp r3, #0 - beq end_success + bl read_write_verify_backup_common ldr r0, __patch_carditaskthread_readsave_asm_address bl blx_r0 @@ -77,14 +71,7 @@ read_backup: b end_success write_backup: - ldr r0, [r4] - movs r1, #0 - str r1, [r0] // result - ldr r1, [r0, #0xC] // src - ldr r2, [r0, #0x10] // dst - ldr r3, [r0, #0x14] // len - cmp r3, #0 - beq end_success + bl read_write_verify_backup_common ldr r0, __patch_carditaskthread_writesave_asm_address bl blx_r0 @@ -92,12 +79,7 @@ write_backup: b end_success verify_backup: - ldr r0, [r4] - ldr r2, [r0, #0xC] // src - ldr r1, [r0, #0x10] // dst - ldr r3, [r0, #0x14] // len - cmp r3, #0 - beq end_success + bl read_write_verify_backup_common push {r0} ldr r0, __patch_carditaskthread_verifysave_asm_address @@ -106,6 +88,18 @@ verify_backup: str r0, [r1] // result b end_success +read_write_verify_backup_common: + ldr r0, [r4] + str r1, [r0] // result + cmp r1, #0 + bne end_success + ldr r1, [r0, #0xC] // src + ldr r2, [r0, #0x10] // dst + ldr r3, [r0, #0x14] // len + cmp r3, #0 + beq end_success + bx lr + blx_r0: bx r0 diff --git a/arm9/source/patches/arm7/VerifySaveAsm.s b/arm9/source/patches/arm7/VerifySaveAsm.s index 6f01f54..2a8468a 100644 --- a/arm9/source/patches/arm7/VerifySaveAsm.s +++ b/arm9/source/patches/arm7/VerifySaveAsm.s @@ -3,16 +3,16 @@ .syntax unified .thumb -// r1 = save src -// r2 = memory src +// r1 = memory src +// r2 = save src // r3 = byte length .global verifysave_asm .type verifysave_asm, %function verifysave_asm: push {r4,r5,r6,r7,lr} movs r4, r3 // remaining bytes - movs r5, r1 - movs r6, r2 + movs r5, r2 + movs r6, r1 1: movs r0, r5 // will be rounded down by function ldr r3, verifysave_save_offset_to_sd_sector_asm_address diff --git a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp index 31efa1f..6b9a136 100644 --- a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp +++ b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp @@ -133,6 +133,16 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext) __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); __patch_carditaskthread_writesave_asm_address = (u32)writeSavePatchCode->GetWriteSaveFunction(); __patch_carditaskthread_verifysave_asm_address = (u32)verifySavePatchCode->GetVerifySaveFunction(); + if (loaderPlatform->GetPlatformType() == LoaderPlatformType::Slot1) + { + // Test REG_EXMEMSTAT bit 11 + __patch_carditaskthread_lsls_exmemstat_bit_to_r1 = THUMB_LSLS_IMM(THUMB_R1, THUMB_R1, 31 - 11); + } + else + { + // Test REG_EXMEMSTAT bit 7 + __patch_carditaskthread_lsls_exmemstat_bit_to_r1 = THUMB_LSLS_IMM(THUMB_R1, THUMB_R1, 31 - 7); + } if (_patchVariant >= PatchVariant::ThumbA) { diff --git a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp index 7f32292..9f9fcf2 100644 --- a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp +++ b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp @@ -93,6 +93,16 @@ void CardiDoTaskFromArm9Patch::ApplyPatch(PatchContext& patchContext) __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); __patch_carditaskthread_writesave_asm_address = (u32)writeSavePatchCode->GetWriteSaveFunction(); __patch_carditaskthread_verifysave_asm_address = (u32)verifySavePatchCode->GetVerifySaveFunction(); + if (loaderPlatform->GetPlatformType() == LoaderPlatformType::Slot1) + { + // Test REG_EXMEMSTAT bit 11 + __patch_carditaskthread_lsls_exmemstat_bit_to_r1 = THUMB_LSLS_IMM(THUMB_R1, THUMB_R1, 31 - 11); + } + else + { + // Test REG_EXMEMSTAT bit 7 + __patch_carditaskthread_lsls_exmemstat_bit_to_r1 = THUMB_LSLS_IMM(THUMB_R1, THUMB_R1, 31 - 7); + } u32 patchOffset; diff --git a/arm9/source/patches/platform/LoaderPlatform.h b/arm9/source/patches/platform/LoaderPlatform.h index 8e843b0..cf0e2ef 100644 --- a/arm9/source/patches/platform/LoaderPlatform.h +++ b/arm9/source/patches/platform/LoaderPlatform.h @@ -5,6 +5,7 @@ #include "SdWritePatchCode.h" #include "../PatchHeap.h" #include "../PatchCodeCollection.h" +#include "LoaderPlatformType.h" /// @brief Abstract class for platform (flashcard or other sd access method) specific parts of the loader. class LoaderPlatform @@ -38,6 +39,10 @@ public: virtual const SdReadPatchCode* CreateRomReadPatchCode( PatchCodeCollection& patchCodeCollection, PatchHeap& patchHeap) const { return nullptr; } + /// @brief Returns the type of this loader platform. + /// @return The type of this loader platform. + virtual LoaderPlatformType GetPlatformType() const = 0; + /// @brief Checks if the platform supports rom reads directly. /// @return True if the platform supports rom reads, or false otherwise. virtual bool HasRomReads() const { return false; } diff --git a/arm9/source/patches/platform/LoaderPlatformType.h b/arm9/source/patches/platform/LoaderPlatformType.h new file mode 100644 index 0000000..bf0ca44 --- /dev/null +++ b/arm9/source/patches/platform/LoaderPlatformType.h @@ -0,0 +1,11 @@ +#pragma once + +/// @brief Enum representing the type of loader platform. +enum class LoaderPlatformType +{ + /// @brief Slot 1 (DS) cartridge. + Slot1, + + /// @brief Slot 2 (GBA) cartridge. + Slot2 +}; diff --git a/arm9/source/patches/platform/ace3ds/Ace3DSLoaderPlatform.h b/arm9/source/patches/platform/ace3ds/Ace3DSLoaderPlatform.h index 27f525f..fe3772f 100644 --- a/arm9/source/patches/platform/ace3ds/Ace3DSLoaderPlatform.h +++ b/arm9/source/patches/platform/ace3ds/Ace3DSLoaderPlatform.h @@ -34,5 +34,7 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool HasDmaSdReads() const override { return true; } }; diff --git a/arm9/source/patches/platform/acekard-common/IoRPGLoaderPlatform.h b/arm9/source/patches/platform/acekard-common/IoRPGLoaderPlatform.h index c35c4df..3ff5c7f 100644 --- a/arm9/source/patches/platform/acekard-common/IoRPGLoaderPlatform.h +++ b/arm9/source/patches/platform/acekard-common/IoRPGLoaderPlatform.h @@ -11,6 +11,8 @@ public: explicit IoRPGLoaderPlatform(u8 ioRpgCmdSdioByte) : _ioRpgCmdSdioByte(ioRpgCmdSdioByte) { } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool InitializeSdCard() override; protected: diff --git a/arm9/source/patches/platform/dspico/DSPicoLoaderPlatform.h b/arm9/source/patches/platform/dspico/DSPicoLoaderPlatform.h index a5099b2..1ccf414 100644 --- a/arm9/source/patches/platform/dspico/DSPicoLoaderPlatform.h +++ b/arm9/source/patches/platform/dspico/DSPicoLoaderPlatform.h @@ -43,5 +43,7 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool HasDmaSdReads() const override { return true; } }; diff --git a/arm9/source/patches/platform/dstt/DSTTLoaderPlatform.h b/arm9/source/patches/platform/dstt/DSTTLoaderPlatform.h index 8e60432..da6eafb 100644 --- a/arm9/source/patches/platform/dstt/DSTTLoaderPlatform.h +++ b/arm9/source/patches/platform/dstt/DSTTLoaderPlatform.h @@ -34,5 +34,7 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool InitializeSdCard() override; }; diff --git a/arm9/source/patches/platform/ezp/EZPLoaderPlatform.h b/arm9/source/patches/platform/ezp/EZPLoaderPlatform.h index 86bb8d6..dfbc3ed 100644 --- a/arm9/source/patches/platform/ezp/EZPLoaderPlatform.h +++ b/arm9/source/patches/platform/ezp/EZPLoaderPlatform.h @@ -30,4 +30,6 @@ public: return new EZPWriteSectorsPatchCode(patchHeap); }); } + + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } }; diff --git a/arm9/source/patches/platform/g003/G003LoaderPlatform.h b/arm9/source/patches/platform/g003/G003LoaderPlatform.h index 9c6c3f5..484cde8 100644 --- a/arm9/source/patches/platform/g003/G003LoaderPlatform.h +++ b/arm9/source/patches/platform/g003/G003LoaderPlatform.h @@ -34,5 +34,7 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool HasDmaSdReads() const override { return true; } }; diff --git a/arm9/source/patches/platform/isnitro/IsNitroLoaderPlatform.h b/arm9/source/patches/platform/isnitro/IsNitroLoaderPlatform.h index 43b40e0..818f580 100644 --- a/arm9/source/patches/platform/isnitro/IsNitroLoaderPlatform.h +++ b/arm9/source/patches/platform/isnitro/IsNitroLoaderPlatform.h @@ -27,6 +27,8 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot2; } + private: u32 GetAgbRamPtr() const { diff --git a/arm9/source/patches/platform/m3ds/M3DSLoaderPlatform.h b/arm9/source/patches/platform/m3ds/M3DSLoaderPlatform.h index bba8676..08eddf4 100644 --- a/arm9/source/patches/platform/m3ds/M3DSLoaderPlatform.h +++ b/arm9/source/patches/platform/m3ds/M3DSLoaderPlatform.h @@ -33,4 +33,6 @@ public: })); }); } + + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } }; diff --git a/arm9/source/patches/platform/melonds/MelonDSLoaderPlatform.h b/arm9/source/patches/platform/melonds/MelonDSLoaderPlatform.h index b9667e1..bbc4ac6 100644 --- a/arm9/source/patches/platform/melonds/MelonDSLoaderPlatform.h +++ b/arm9/source/patches/platform/melonds/MelonDSLoaderPlatform.h @@ -25,4 +25,6 @@ public: return new MelonDSWriteSdPatchCode(patchHeap); }); } + + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } }; diff --git a/arm9/source/patches/platform/r4/R4LoaderPlatform.h b/arm9/source/patches/platform/r4/R4LoaderPlatform.h index 4d5b110..106a90e 100644 --- a/arm9/source/patches/platform/r4/R4LoaderPlatform.h +++ b/arm9/source/patches/platform/r4/R4LoaderPlatform.h @@ -37,6 +37,8 @@ public: }); } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; } + bool HasRomReads() const override { return true; } void PrepareRomBoot(u32 romDirSector, u32 romDirSectorOffset) const override; diff --git a/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h b/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h index daa24e5..cffc383 100644 --- a/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h +++ b/arm9/source/patches/platform/supercard/SuperCardLoaderPlatform.h @@ -99,6 +99,8 @@ public: } } + LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot2; } + bool InitializeSdCard() override; private: