mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 09:16:49 +02:00
@@ -29,14 +29,26 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const
|
|||||||
// Spider-Man 2 (USA) is probably the only game without module params
|
// Spider-Man 2 (USA) is probably the only game without module params
|
||||||
sdkVersion = 0x02004F50;
|
sdkVersion = 0x02004F50;
|
||||||
}
|
}
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> arm7Autoload; // TODO unused
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> arm7iAutoload;
|
||||||
|
if (gIsDsiMode && romHeader->SupportsDsiMode())
|
||||||
|
{
|
||||||
|
auto arm7iModuleParams = (const module_params_twl_t*)(twlRomHeader->arm7LoadAddress + twlRomHeader->arm7iModuleParamsAddress);
|
||||||
|
arm7iAutoload = std::make_unique<AutoloadAdjuster<autoload_list_entry_sdk5_t>>(
|
||||||
|
(autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListStart,
|
||||||
|
(autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListEnd,
|
||||||
|
arm7iModuleParams->autoloadStart);
|
||||||
|
}
|
||||||
PatchCollection patchCollection;
|
PatchCollection patchCollection;
|
||||||
LOG_DEBUG("Arm7 region: 0x%x - 0x%x\n", romHeader->arm7LoadAddress, romHeader->arm7LoadAddress + romHeader->arm7Size);
|
LOG_DEBUG("Arm7 region: 0x%x - 0x%x\n", romHeader->arm7LoadAddress, romHeader->arm7LoadAddress + romHeader->arm7Size);
|
||||||
PatchContext patchContext
|
PatchContext patchContext
|
||||||
{
|
{
|
||||||
(void*)romHeader->arm7LoadAddress,
|
(void*)romHeader->arm7LoadAddress,
|
||||||
romHeader->arm7Size,
|
romHeader->arm7Size,
|
||||||
|
std::move(arm7Autoload),
|
||||||
(romHeader->SupportsDsiMode()) ? (void*)twlRomHeader->arm7iLoadAddress : nullptr,
|
(romHeader->SupportsDsiMode()) ? (void*)twlRomHeader->arm7iLoadAddress : nullptr,
|
||||||
(romHeader->SupportsDsiMode()) ? twlRomHeader->arm7iSize : 0,
|
(romHeader->SupportsDsiMode()) ? twlRomHeader->arm7iSize : 0,
|
||||||
|
std::move(arm7iAutoload),
|
||||||
sdkVersion,
|
sdkVersion,
|
||||||
romHeader->gameCode,
|
romHeader->gameCode,
|
||||||
romHeader->softwareVersion,
|
romHeader->softwareVersion,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "ModuleParamsLocator.h"
|
#include "ModuleParamsLocator.h"
|
||||||
|
#include "AutoloadAdjuster.h"
|
||||||
#include "SdkVersion.h"
|
#include "SdkVersion.h"
|
||||||
#include "patches/PatchCollection.h"
|
#include "patches/PatchCollection.h"
|
||||||
#include "patches/PatchContext.h"
|
#include "patches/PatchContext.h"
|
||||||
@@ -54,6 +55,8 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
u32 arm9Size = romHeader->arm9Size;
|
u32 arm9Size = romHeader->arm9Size;
|
||||||
u32 arm9iSize = romHeader->SupportsDsiMode() ? twlRomHeader->arm9iSize : 0;
|
u32 arm9iSize = romHeader->SupportsDsiMode() ? twlRomHeader->arm9iSize : 0;
|
||||||
u32 compressedEnd = 0;
|
u32 compressedEnd = 0;
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> arm9Autoload;
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> arm9iAutoload;
|
||||||
auto moduleParams = ModuleParamsLocator().FindModuleParams(romHeader);
|
auto moduleParams = ModuleParamsLocator().FindModuleParams(romHeader);
|
||||||
SdkVersion sdkVersion = moduleParams ? moduleParams->sdkVersion : 0u;
|
SdkVersion sdkVersion = moduleParams ? moduleParams->sdkVersion : 0u;
|
||||||
if (moduleParams)
|
if (moduleParams)
|
||||||
@@ -77,12 +80,28 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sdkVersion.IsTwlSdk())
|
||||||
|
{
|
||||||
|
arm9Autoload = std::make_unique<AutoloadAdjuster<autoload_list_entry_sdk5_t>>(
|
||||||
|
(autoload_list_entry_sdk5_t*)moduleParams->autoloadListStart,
|
||||||
|
(autoload_list_entry_sdk5_t*)moduleParams->autoloadListEnd,
|
||||||
|
moduleParams->autoloadStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm9Autoload = std::make_unique<AutoloadAdjuster<autoload_list_entry_t>>(
|
||||||
|
(autoload_list_entry_t*)moduleParams->autoloadListStart,
|
||||||
|
(autoload_list_entry_t*)moduleParams->autoloadListEnd,
|
||||||
|
moduleParams->autoloadStart);
|
||||||
|
}
|
||||||
|
|
||||||
if (gIsDsiMode && romHeader->SupportsDsiMode())
|
if (gIsDsiMode && romHeader->SupportsDsiMode())
|
||||||
{
|
{
|
||||||
auto arm9iModuleParams = (module_params_twl_t*)(romHeader->arm9LoadAddress + twlRomHeader->arm9iModuleParamsAddress);
|
auto arm9iModuleParams = (module_params_twl_t*)(romHeader->arm9LoadAddress + twlRomHeader->arm9iModuleParamsAddress);
|
||||||
if (arm9iModuleParams->magicBigEndian == MODULE_PARAMS_TWL_MAGIC_BE &&
|
if (arm9iModuleParams->magicBigEndian == MODULE_PARAMS_TWL_MAGIC_BE &&
|
||||||
arm9iModuleParams->magicLittleEndian == MODULE_PARAMS_TWL_MAGIC_LE &&
|
arm9iModuleParams->magicLittleEndian == MODULE_PARAMS_TWL_MAGIC_LE)
|
||||||
arm9iModuleParams->compressedEnd != 0)
|
{
|
||||||
|
if (arm9iModuleParams->compressedEnd != 0)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Compressed arm9i found\n");
|
LOG_DEBUG("Compressed arm9i found\n");
|
||||||
if (miiUncompressBackward)
|
if (miiUncompressBackward)
|
||||||
@@ -97,6 +116,11 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
LOG_DEBUG("Could not decompress arm9i\n");
|
LOG_DEBUG("Could not decompress arm9i\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
arm9iAutoload = std::make_unique<AutoloadAdjuster<autoload_list_entry_sdk5_t>>(
|
||||||
|
(autoload_list_entry_sdk5_t*)arm9iModuleParams->autoloadListStart,
|
||||||
|
(autoload_list_entry_sdk5_t*)arm9iModuleParams->autoloadListEnd,
|
||||||
|
arm9iModuleParams->autoloadStart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -106,6 +130,10 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
{
|
{
|
||||||
// Spider-Man 2 (USA) is probably the only game without module params
|
// Spider-Man 2 (USA) is probably the only game without module params
|
||||||
sdkVersion = 0x02004F50;
|
sdkVersion = 0x02004F50;
|
||||||
|
arm9Autoload = std::make_unique<AutoloadAdjuster<autoload_list_entry_t>>(
|
||||||
|
(autoload_list_entry_t*)0x0215DBA0,
|
||||||
|
(autoload_list_entry_t*)0x0215DBB8,
|
||||||
|
0x02157CC0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("Arm9 region: 0x%x - 0x%x\n", romHeader->arm9LoadAddress, romHeader->arm9LoadAddress + arm9Size);
|
LOG_DEBUG("Arm9 region: 0x%x - 0x%x\n", romHeader->arm9LoadAddress, romHeader->arm9LoadAddress + arm9Size);
|
||||||
@@ -113,8 +141,10 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
{
|
{
|
||||||
(void*)romHeader->arm9LoadAddress,
|
(void*)romHeader->arm9LoadAddress,
|
||||||
arm9Size,
|
arm9Size,
|
||||||
|
std::move(arm9Autoload),
|
||||||
romHeader->SupportsDsiMode() ? (void*)twlRomHeader->arm9iLoadAddress : nullptr,
|
romHeader->SupportsDsiMode() ? (void*)twlRomHeader->arm9iLoadAddress : nullptr,
|
||||||
arm9iSize,
|
arm9iSize,
|
||||||
|
std::move(arm9iAutoload),
|
||||||
sdkVersion,
|
sdkVersion,
|
||||||
romHeader->gameCode,
|
romHeader->gameCode,
|
||||||
romHeader->softwareVersion,
|
romHeader->softwareVersion,
|
||||||
|
|||||||
59
arm9/source/AutoloadAdjuster.h
Normal file
59
arm9/source/AutoloadAdjuster.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include "moduleParams.h"
|
||||||
|
#include "IAutoloadAdjuster.h"
|
||||||
|
|
||||||
|
/// @brief Class for adjusting addresses for autoload from autoload list entries.
|
||||||
|
/// @tparam T The type of autoload list entry.
|
||||||
|
template<typename T>
|
||||||
|
class AutoloadAdjuster : public IAutoloadAdjuster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoloadAdjuster(const T* autoloadListStart, const T* autoloadListEnd, u32 autoloadStartAddress)
|
||||||
|
: _autoloadListStart(autoloadListStart), _autoloadListEnd(autoloadListEnd), _autoloadStartAddress(autoloadStartAddress) { }
|
||||||
|
|
||||||
|
u32 AdjustInitialToFinal(u32 initialAddress) const override
|
||||||
|
{
|
||||||
|
u32 finalAddress = initialAddress;
|
||||||
|
u32 currentAddress = _autoloadStartAddress;
|
||||||
|
for (auto autoloadListCurr = _autoloadListStart; autoloadListCurr != _autoloadListEnd; autoloadListCurr++)
|
||||||
|
{
|
||||||
|
if (initialAddress >= currentAddress && initialAddress < currentAddress + autoloadListCurr->size)
|
||||||
|
{
|
||||||
|
finalAddress -= currentAddress;
|
||||||
|
finalAddress += autoloadListCurr->targetAddress;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentAddress += autoloadListCurr->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AdjustFinalToInitial(u32 finalAddress) const override
|
||||||
|
{
|
||||||
|
u32 initialAddress = finalAddress;
|
||||||
|
u32 currentAddress = _autoloadStartAddress;
|
||||||
|
for (auto autoloadListCurr = _autoloadListStart; autoloadListCurr != _autoloadListEnd; autoloadListCurr++)
|
||||||
|
{
|
||||||
|
if (finalAddress >= autoloadListCurr->targetAddress && finalAddress < autoloadListCurr->targetAddress + autoloadListCurr->size)
|
||||||
|
{
|
||||||
|
initialAddress -= autoloadListCurr->targetAddress;
|
||||||
|
initialAddress += currentAddress;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentAddress += autoloadListCurr->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initialAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T* _autoloadListStart;
|
||||||
|
const T* _autoloadListEnd;
|
||||||
|
u32 _autoloadStartAddress;
|
||||||
|
};
|
||||||
21
arm9/source/IAutoloadAdjuster.h
Normal file
21
arm9/source/IAutoloadAdjuster.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// @brief Interface for an autoload address adjuster.
|
||||||
|
class IAutoloadAdjuster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IAutoloadAdjuster() { }
|
||||||
|
|
||||||
|
/// @brief Adjust an initial address (pre-autoload) to its final location after autoload.
|
||||||
|
/// @param initialAddress The address to adjust for autoloading.
|
||||||
|
/// @return The final location of the address.
|
||||||
|
virtual u32 AdjustInitialToFinal(u32 initialAddress) const = 0;
|
||||||
|
|
||||||
|
/// @brief Adjust a final address (post-autoload) to its initial location before autoload.
|
||||||
|
/// @param finalAddress The address to adjust for autoloading.
|
||||||
|
/// @return The initial location of the address.
|
||||||
|
virtual u32 AdjustFinalToInitial(u32 finalAddress) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IAutoloadAdjuster() { }
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "SdkVersion.h"
|
#include "SdkVersion.h"
|
||||||
|
#include "AutoloadAdjuster.h"
|
||||||
#include "PatchHeap.h"
|
#include "PatchHeap.h"
|
||||||
#include "PatchCodeCollection.h"
|
#include "PatchCodeCollection.h"
|
||||||
|
|
||||||
@@ -10,9 +11,11 @@ class LoaderPlatform;
|
|||||||
class PatchContext
|
class PatchContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PatchContext(void* data, u32 dataSize, void* twlData, u32 twlDataSize,
|
PatchContext(void* data, u32 dataSize, std::unique_ptr<IAutoloadAdjuster> autoloadAdjuster,
|
||||||
|
void* twlData, u32 twlDataSize, std::unique_ptr<IAutoloadAdjuster> twlAutoloadAdjuster,
|
||||||
SdkVersion sdkVersion, u32 gameCode, u8 gameRevision, const LoaderPlatform* loaderPlatform)
|
SdkVersion sdkVersion, u32 gameCode, u8 gameRevision, const LoaderPlatform* loaderPlatform)
|
||||||
: _data(data), _dataSize(dataSize), _twlData(twlData), _twlDataSize(twlDataSize)
|
: _data(data), _dataSize(dataSize), _autoloadAdjuster(std::move(autoloadAdjuster))
|
||||||
|
, _twlData(twlData), _twlDataSize(twlDataSize), _twlAutoloadAdjuster(std::move(twlAutoloadAdjuster))
|
||||||
, _sdkVersion(sdkVersion), _gameCode(gameCode), _gameRevision(gameRevision), _loaderPlatform(loaderPlatform) { }
|
, _sdkVersion(sdkVersion), _gameCode(gameCode), _gameRevision(gameRevision), _loaderPlatform(loaderPlatform) { }
|
||||||
|
|
||||||
/// @brief Tries to find the given \p pattern of the given \p byteLength in the ntr region.
|
/// @brief Tries to find the given \p pattern of the given \p byteLength in the ntr region.
|
||||||
@@ -27,6 +30,14 @@ public:
|
|||||||
/// @return A pointer to the first location where the pattern was found, or \c nullptr if the pattern was not found.
|
/// @return A pointer to the first location where the pattern was found, or \c nullptr if the pattern was not found.
|
||||||
u32* FindPattern32Twl(const u32* pattern, u32 byteLength) const;
|
u32* FindPattern32Twl(const u32* pattern, u32 byteLength) const;
|
||||||
|
|
||||||
|
/// @brief Returns the ntr autoload adjuster of this context.
|
||||||
|
/// @return The ntr autoload adjuster of this context.
|
||||||
|
constexpr const IAutoloadAdjuster* GetAutoloadAdjuster() const { return _autoloadAdjuster.get(); }
|
||||||
|
|
||||||
|
/// @brief Returns the twl autoload adjuster of this context.
|
||||||
|
/// @return The twl autoload adjuster of this context.
|
||||||
|
constexpr const IAutoloadAdjuster* GetAutoloadAdjusterTwl() const { return _twlAutoloadAdjuster.get(); }
|
||||||
|
|
||||||
/// @brief Returns the patch heap of this context.
|
/// @brief Returns the patch heap of this context.
|
||||||
/// @return The patch heap of this context.
|
/// @return The patch heap of this context.
|
||||||
constexpr PatchHeap& GetPatchHeap() { return _patchHeap; }
|
constexpr PatchHeap& GetPatchHeap() { return _patchHeap; }
|
||||||
@@ -54,8 +65,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
void* _data;
|
void* _data;
|
||||||
u32 _dataSize;
|
u32 _dataSize;
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> _autoloadAdjuster;
|
||||||
void* _twlData;
|
void* _twlData;
|
||||||
u32 _twlDataSize;
|
u32 _twlDataSize;
|
||||||
|
std::unique_ptr<IAutoloadAdjuster> _twlAutoloadAdjuster;
|
||||||
SdkVersion _sdkVersion;
|
SdkVersion _sdkVersion;
|
||||||
u32 _gameCode;
|
u32 _gameCode;
|
||||||
u8 _gameRevision;
|
u8 _gameRevision;
|
||||||
|
|||||||
@@ -63,29 +63,6 @@ static u32 getThumbBlAddress(const u32* instructionPointer)
|
|||||||
return (u32)instructionPointer + 5 + ((int)((((blInstruction1 & 0x7FF) << 11) | (blInstruction2 & 0x7FF)) << 10) >> 9);
|
return (u32)instructionPointer + 5 + ((int)((((blInstruction1 & 0x7FF) << 11) | (blInstruction2 & 0x7FF)) << 10) >> 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 correctAddressForArm7iAutoLoad(u32 address)
|
|
||||||
{
|
|
||||||
auto romHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader;
|
|
||||||
auto arm7iModuleParams = (const module_params_twl_t*)(
|
|
||||||
romHeader->arm7LoadAddress + romHeader->arm7iModuleParamsAddress);
|
|
||||||
|
|
||||||
auto autoLoadListEntry = (autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListStart;
|
|
||||||
u32 currentAddress = arm7iModuleParams->autoloadStart;
|
|
||||||
while (autoLoadListEntry != (autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListEnd)
|
|
||||||
{
|
|
||||||
if (address >= currentAddress && address < currentAddress + autoLoadListEntry->size)
|
|
||||||
{
|
|
||||||
address -= currentAddress;
|
|
||||||
address += autoLoadListEntry->targetAddress;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
currentAddress += autoLoadListEntry->size;
|
|
||||||
autoLoadListEntry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sdk5DsiSdCardRedirectPatch::ApplyPatch(PatchContext& patchContext)
|
void Sdk5DsiSdCardRedirectPatch::ApplyPatch(PatchContext& patchContext)
|
||||||
{
|
{
|
||||||
if (!_attachFunction)
|
if (!_attachFunction)
|
||||||
@@ -101,7 +78,8 @@ void Sdk5DsiSdCardRedirectPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
getDriveStructAddress = getArmBlAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
|
getDriveStructAddress = getArmBlAddress((u32*)((u8*)_attachFunction + _blToGetDriveStructOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
getDriveStructAddress = correctAddressForArm7iAutoLoad(getDriveStructAddress);
|
auto arm7iAutoload = patchContext.GetAutoloadAdjusterTwl();
|
||||||
|
getDriveStructAddress = arm7iAutoload->AdjustInitialToFinal(getDriveStructAddress);
|
||||||
|
|
||||||
auto sdRead = patchContext.GetLoaderPlatform()->CreateSdReadPatchCode(
|
auto sdRead = patchContext.GetLoaderPlatform()->CreateSdReadPatchCode(
|
||||||
patchContext.GetPatchCodeCollection(), patchContext.GetPatchHeap());
|
patchContext.GetPatchCodeCollection(), patchContext.GetPatchHeap());
|
||||||
|
|||||||
@@ -169,6 +169,11 @@ bool CardiTryReadCardDmaPatch::FindPatchTarget(PatchContext& patchContext)
|
|||||||
return true; //_cardiTryReadCardDma != nullptr;
|
return true; //_cardiTryReadCardDma != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s32 getArmBlOffset(u32 blInstruction)
|
||||||
|
{
|
||||||
|
return 8 + ((int)((blInstruction & 0xFFFFFF) << 8) >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
static u32 getArmBlAddress(const u32* instructionPointer)
|
static u32 getArmBlAddress(const u32* instructionPointer)
|
||||||
{
|
{
|
||||||
u32 blInstruction = *instructionPointer;
|
u32 blInstruction = *instructionPointer;
|
||||||
@@ -193,7 +198,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
u32 cardiCommon;
|
u32 cardiCommon;
|
||||||
u32 cardiOnReadCard;
|
u32 cardiOnReadCard;
|
||||||
u32 cardiSetCardDma;
|
u32 cardiSetCardDma;
|
||||||
u32 miiCardDmaCopy32;
|
u32 cardiSetCardDmaDmaCopyCallOffset;
|
||||||
u32 cardiOnReadCardOffset;
|
u32 cardiOnReadCardOffset;
|
||||||
if (_foundPattern == sCARDiTryReadCardDmaPattern20029A7)
|
if (_foundPattern == sCARDiTryReadCardDmaPattern20029A7)
|
||||||
{
|
{
|
||||||
@@ -202,7 +207,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x124));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x124));
|
||||||
if (*(u32*)cardiOnReadCard == 0xE92D40F0u)
|
if (*(u32*)cardiOnReadCard == 0xE92D40F0u)
|
||||||
{
|
{
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x18));
|
cardiSetCardDmaDmaCopyCallOffset = 0x18;
|
||||||
cardiOnReadCardOffset = 0x40;
|
cardiOnReadCardOffset = 0x40;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -218,7 +223,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x140);
|
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x140);
|
||||||
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x150);
|
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x150);
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x130));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x130));
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x18));
|
cardiSetCardDmaDmaCopyCallOffset = 0x18;
|
||||||
cardiOnReadCardOffset = 0x40;
|
cardiOnReadCardOffset = 0x40;
|
||||||
}
|
}
|
||||||
else if (_foundPattern == sCARDiTryReadCardDmaPattern)
|
else if (_foundPattern == sCARDiTryReadCardDmaPattern)
|
||||||
@@ -226,7 +231,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x148) + 4;
|
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x148) + 4;
|
||||||
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x158);
|
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x158);
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x138));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x138));
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x18));
|
cardiSetCardDmaDmaCopyCallOffset = 0x18;
|
||||||
cardiOnReadCardOffset = 0x40;
|
cardiOnReadCardOffset = 0x40;
|
||||||
}
|
}
|
||||||
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk3017530)
|
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk3017530)
|
||||||
@@ -241,7 +246,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
{
|
{
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
|
||||||
}
|
}
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x18));
|
cardiSetCardDmaDmaCopyCallOffset = 0x18;
|
||||||
cardiOnReadCardOffset = 0x40;
|
cardiOnReadCardOffset = 0x40;
|
||||||
}
|
}
|
||||||
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk3027530)
|
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk3027530)
|
||||||
@@ -249,7 +254,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x160) + 4;
|
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x160) + 4;
|
||||||
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x170);
|
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x170);
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x14C));
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x18));
|
cardiSetCardDmaDmaCopyCallOffset = 0x18;
|
||||||
cardiOnReadCardOffset = 0x40;
|
cardiOnReadCardOffset = 0x40;
|
||||||
}
|
}
|
||||||
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk4007532)
|
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk4007532)
|
||||||
@@ -257,7 +262,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x178) + 4;
|
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x178) + 4;
|
||||||
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x188);
|
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x188);
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x16C));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x16C));
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x1C));
|
cardiSetCardDmaDmaCopyCallOffset = 0x1C;
|
||||||
cardiOnReadCardOffset = 0x48;
|
cardiOnReadCardOffset = 0x48;
|
||||||
}
|
}
|
||||||
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk4027539SpiritTracks)
|
else if (_foundPattern == sCARDiTryReadCardDmaPatternSdk4027539SpiritTracks)
|
||||||
@@ -265,7 +270,7 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x180) + 4;
|
cardiCommon = *(u32*)((u8*)_cardiTryReadCardDma + 0x180) + 4;
|
||||||
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x190);
|
cardiOnReadCard = *(u32*)((u8*)_cardiTryReadCardDma + 0x190);
|
||||||
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x174));
|
cardiSetCardDma = getArmBlAddress((u32*)((u8*)_cardiTryReadCardDma + 0x174));
|
||||||
miiCardDmaCopy32 = getArmBlAddress((u32*)(cardiSetCardDma + 0x1C));
|
cardiSetCardDmaDmaCopyCallOffset = 0x1C;
|
||||||
cardiOnReadCardOffset = 0x48;
|
cardiOnReadCardOffset = 0x48;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -275,7 +280,32 @@ void CardiTryReadCardDmaPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 osDisableIrqMask = getArmBlAddress((u32*)(cardiOnReadCard + cardiOnReadCardOffset + 4));
|
// correct all addresses for autoload, if libcard is in an autoload block (New Super Mario Bros.)
|
||||||
|
auto autoloadAdjuster = patchContext.GetAutoloadAdjuster();
|
||||||
|
|
||||||
|
// CARDi_OnReadCard address is the final location, but we need its initial location to patch it now
|
||||||
|
if (autoloadAdjuster)
|
||||||
|
{
|
||||||
|
cardiOnReadCard = autoloadAdjuster->AdjustFinalToInitial(cardiOnReadCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIi_CardDmaCopy32 is relative, but we need its final location to call it later
|
||||||
|
u32 miiCardDmaCopy32CallLocation = cardiSetCardDma + cardiSetCardDmaDmaCopyCallOffset;
|
||||||
|
s32 miiCardDmaCopy32CallOffset = getArmBlOffset(*(u32*)miiCardDmaCopy32CallLocation);
|
||||||
|
if (autoloadAdjuster)
|
||||||
|
{
|
||||||
|
miiCardDmaCopy32CallLocation = autoloadAdjuster->AdjustInitialToFinal(miiCardDmaCopy32CallLocation);
|
||||||
|
}
|
||||||
|
u32 miiCardDmaCopy32 = miiCardDmaCopy32CallLocation + miiCardDmaCopy32CallOffset;
|
||||||
|
|
||||||
|
// same as above with OS_DisableIrqMask
|
||||||
|
u32 osDisableIrqMaskCallLocation = cardiOnReadCard + cardiOnReadCardOffset + 4;
|
||||||
|
s32 osDisableIrqMaskCallOffset = getArmBlOffset(*(u32*)osDisableIrqMaskCallLocation);
|
||||||
|
if (autoloadAdjuster)
|
||||||
|
{
|
||||||
|
osDisableIrqMaskCallLocation = autoloadAdjuster->AdjustInitialToFinal(osDisableIrqMaskCallLocation);
|
||||||
|
}
|
||||||
|
u32 osDisableIrqMask = osDisableIrqMaskCallLocation + osDisableIrqMaskCallOffset;
|
||||||
|
|
||||||
// patch CARDi_SetCardDma
|
// patch CARDi_SetCardDma
|
||||||
auto sdReadDmaPatchCode = patchContext.GetLoaderPlatform()->CreateSdReadDmaPatchCode(
|
auto sdReadDmaPatchCode = patchContext.GetLoaderPlatform()->CreateSdReadDmaPatchCode(
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ struct build_params_t
|
|||||||
u32 magicLittleEndian; //0x3381C0DE
|
u32 magicLittleEndian; //0x3381C0DE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct autoload_list_entry_t
|
||||||
|
{
|
||||||
|
u32 targetAddress;
|
||||||
|
u32 size;
|
||||||
|
u32 bssSize;
|
||||||
|
};
|
||||||
|
|
||||||
struct autoload_list_entry_sdk5_t
|
struct autoload_list_entry_sdk5_t
|
||||||
{
|
{
|
||||||
u32 targetAddress;
|
u32 targetAddress;
|
||||||
|
|||||||
Reference in New Issue
Block a user