Add helper class for ARM/Thumb assembly functions (#127)

Replaces static helper functions in
    Sdk5DsiSdCardRedirectPatch.cpp
    LastWindowCrcPatch.h
    CardiTryReadCardDmaPatch.cpp
This commit is contained in:
Mow
2026-02-01 05:51:57 -05:00
committed by GitHub
parent 28bfb3b423
commit a648d4c4a9
5 changed files with 81 additions and 49 deletions

View File

@@ -1,4 +1,5 @@
#include "common.h"
#include "ArmHelper.h"
#include "sharedMemory.h"
#include "ndsHeader.h"
#include "moduleParams.h"
@@ -12,11 +13,6 @@ static const u32 sAttachFunctionPatternThumb[] = { 0xB0FFB518u, 0xB0DFB0FFu, 0x4
#define BL_TO_GET_DRIVE_STRUCT_OFFSET (-0x20)
#define BL_TO_GET_DRIVE_STRUCT_OFFSET_ALT 0x88
static bool isArmUnconditionalBl(u32 armInstruction)
{
return (armInstruction >> 24) == 0xEB;
}
bool Sdk5DsiSdCardRedirectPatch::FindPatchTarget(PatchContext& patchContext)
{
_attachFunction = patchContext.FindPattern32Twl(sAttachFunctionPattern, sizeof(sAttachFunctionPattern));
@@ -32,10 +28,10 @@ bool Sdk5DsiSdCardRedirectPatch::FindPatchTarget(PatchContext& patchContext)
{
LOG_DEBUG("Found FATFSi_sdmcRtfsAttach at %p\n", _attachFunction);
_blToGetDriveStructOffset = BL_TO_GET_DRIVE_STRUCT_OFFSET;
if (!_thumb && !isArmUnconditionalBl(*(u32*)((u8*)_attachFunction + _blToGetDriveStructOffset)))
if (!_thumb && !ArmHelper::IsArmUnconditionalBl(*(u32*)((u8*)_attachFunction + _blToGetDriveStructOffset)))
{
_blToGetDriveStructOffset = BL_TO_GET_DRIVE_STRUCT_OFFSET_ALT;
if (!isArmUnconditionalBl(*(u32*)((u8*)_attachFunction + _blToGetDriveStructOffset)))
if (!ArmHelper::IsArmUnconditionalBl(*(u32*)((u8*)_attachFunction + _blToGetDriveStructOffset)))
{
LOG_WARNING("Unsupported arm7 version for SD redirection patches\n");
_attachFunction = nullptr;
@@ -50,19 +46,6 @@ bool Sdk5DsiSdCardRedirectPatch::FindPatchTarget(PatchContext& patchContext)
return _attachFunction != nullptr;
}
static u32 getArmBlAddress(const u32* instructionPointer)
{
u32 blInstruction = *instructionPointer;
return (u32)instructionPointer + 8 + ((int)((blInstruction & 0xFFFFFF) << 8) >> 6);
}
static u32 getThumbBlAddress(const u32* instructionPointer)
{
u32 blInstruction1 = ((u16*)instructionPointer)[0];
u32 blInstruction2 = ((u16*)instructionPointer)[1];
return (u32)instructionPointer + 5 + ((int)((((blInstruction1 & 0x7FF) << 11) | (blInstruction2 & 0x7FF)) << 10) >> 9);
}
void Sdk5DsiSdCardRedirectPatch::ApplyPatch(PatchContext& patchContext)
{
if (!_attachFunction)
@@ -71,11 +54,11 @@ void Sdk5DsiSdCardRedirectPatch::ApplyPatch(PatchContext& patchContext)
u32 getDriveStructAddress;
if (_thumb)
{
getDriveStructAddress = getThumbBlAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
getDriveStructAddress = ArmHelper::GetThumbCallAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
}
else
{
getDriveStructAddress = getArmBlAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
getDriveStructAddress = ArmHelper::GetArmCallAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
}
auto arm7iAutoload = patchContext.GetAutoloadAdjusterTwl();

View File

@@ -1,4 +1,5 @@
#include "common.h"
#include "ArmHelper.h"
#include "patches/PatchContext.h"
#include "LastWindowCrcPatchCode.h"
#include "LastWindowCrcPatch.h"
@@ -13,6 +14,6 @@ void LastWindowCrcPatch::ApplyPatch(PatchContext& patchContext)
{
auto patchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<LastWindowCrcPatchCode>(patchContext.GetPatchHeap());
u32 patchAddr = (u32)patchCode->GetLastWindowCrcFunction();
*_getCrc16 = MakeBlxCall(patchAddr);
*_getCrc16 = ArmHelper::MakeArmCall((u32)_getCrc16, patchAddr);
}

View File

@@ -32,9 +32,4 @@ public:
private:
u32* _getCrc16 = nullptr;
u32 MakeBlxCall(u32 patchAddr) const
{
return 0xFA000000 | (((patchAddr - (u32)_getCrc16 - 8) >> 2) & 0xFFFFFF);
}
};

View File

@@ -1,4 +1,5 @@
#include "common.h"
#include "ArmHelper.h"
#include "patches/PatchContext.h"
#include "thumbInstructions.h"
#include "CardiSetCardDmaPatchCode.h"
@@ -169,17 +170,6 @@ bool CardiTryReadCardDmaPatch::FindPatchTarget(PatchContext& patchContext)
return true; //_cardiTryReadCardDma != nullptr;
}
static s32 getArmBlOffset(u32 blInstruction)
{
return 8 + ((int)((blInstruction & 0xFFFFFF) << 8) >> 6);
}
static u32 getArmBlAddress(const u32* instructionPointer)
{
u32 blInstruction = *instructionPointer;
return (u32)instructionPointer + 8 + ((int)((blInstruction & 0xFFFFFF) << 8) >> 6) + ((blInstruction >> 24) == 0xFA ? 1 : 0);
}
void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
if (!_cardiTryReadCardDma)
@@ -204,7 +194,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x134);
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x144);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x124));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x124));
if (*(u32*)cardiOnReadCard == 0xE92D40F0u)
{
cardiSetCardDmaDmaCopyCallOffset = 0x18;
@@ -222,7 +212,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x140);
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x150);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x130));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x130));
cardiSetCardDmaDmaCopyCallOffset = 0x18;
cardiOnReadCardOffset = 0x40;
}
@@ -230,7 +220,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x148) + 4;
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x158);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x138));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x138));
cardiSetCardDmaDmaCopyCallOffset = 0x18;
cardiOnReadCardOffset = 0x40;
}
@@ -240,11 +230,11 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x16C);
if (*(u32*)((u8*)_cardiTryReadCardDma + 0x158) == 0xE12FFF1E)
{
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x148));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x148));
}
else
{
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
}
cardiSetCardDmaDmaCopyCallOffset = 0x18;
cardiOnReadCardOffset = 0x40;
@@ -253,7 +243,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x160) + 4;
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x170);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
cardiSetCardDmaDmaCopyCallOffset = 0x18;
cardiOnReadCardOffset = 0x40;
}
@@ -261,7 +251,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x178) + 4;
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x188);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x16C));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x16C));
cardiSetCardDmaDmaCopyCallOffset = 0x1C;
cardiOnReadCardOffset = 0x48;
}
@@ -269,7 +259,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
{
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x180) + 4;
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x190);
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x174));
cardiSetCardDma = ArmHelper::GetArmCallAddress((u32*)((u8*)_cardiTryReadCardDma + 0x174));
cardiSetCardDmaDmaCopyCallOffset = 0x1C;
cardiOnReadCardOffset = 0x48;
}
@@ -291,7 +281,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
// MIi_CardDmaCopy32 is relative, but we need its final location to call it later
u32 miiCardDmaCopy32CallLocation = cardiSetCardDma + cardiSetCardDmaDmaCopyCallOffset;
s32 miiCardDmaCopy32CallOffset = getArmBlOffset(*(u32*)miiCardDmaCopy32CallLocation);
s32 miiCardDmaCopy32CallOffset = ArmHelper::GetArmCallOffset(*(u32*)miiCardDmaCopy32CallLocation);
if (autoloadAdjuster)
{
miiCardDmaCopy32CallLocation = autoloadAdjuster->AdjustInitialToFinal(miiCardDmaCopy32CallLocation);
@@ -300,7 +290,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
// same as above with OS_DisableIrqMask
u32 osDisableIrqMaskCallLocation = cardiOnReadCard + cardiOnReadCardOffset + 4;
s32 osDisableIrqMaskCallOffset = getArmBlOffset(*(u32*)osDisableIrqMaskCallLocation);
s32 osDisableIrqMaskCallOffset = ArmHelper::GetArmCallOffset(*(u32*)osDisableIrqMaskCallLocation);
if (autoloadAdjuster)
{
osDisableIrqMaskCallLocation = autoloadAdjuster->AdjustInitialToFinal(osDisableIrqMaskCallLocation);