Added check to CardiTaskThreadPatch that the required slot is actually mapped to arm7. Fixes #60

This commit is contained in:
Gericom
2025-12-27 12:44:00 +01:00
parent 8036004e5a
commit 64e020182a
18 changed files with 95 additions and 42 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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
};

View File

@@ -34,5 +34,7 @@ public:
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
bool HasDmaSdReads() const override { return true; }
};

View File

@@ -11,6 +11,8 @@ public:
explicit IoRPGLoaderPlatform(u8 ioRpgCmdSdioByte)
: _ioRpgCmdSdioByte(ioRpgCmdSdioByte) { }
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
bool InitializeSdCard() override;
protected:

View File

@@ -43,5 +43,7 @@ public:
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
bool HasDmaSdReads() const override { return true; }
};

View File

@@ -34,5 +34,7 @@ public:
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
bool InitializeSdCard() override;
};

View File

@@ -30,4 +30,6 @@ public:
return new EZPWriteSectorsPatchCode(patchHeap);
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
};

View File

@@ -34,5 +34,7 @@ public:
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
bool HasDmaSdReads() const override { return true; }
};

View File

@@ -27,6 +27,8 @@ public:
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot2; }
private:
u32 GetAgbRamPtr() const
{

View File

@@ -33,4 +33,6 @@ public:
}));
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
};

View File

@@ -25,4 +25,6 @@ public:
return new MelonDSWriteSdPatchCode(patchHeap);
});
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot1; }
};

View File

@@ -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;

View File

@@ -99,6 +99,8 @@ public:
}
}
LoaderPlatformType GetPlatformType() const override { return LoaderPlatformType::Slot2; }
bool InitializeSdCard() override;
private: