mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 01:06:50 +02:00
Preserve cheats when OS_ResetSystem is used, move temporary save buffer to main memory
This commit is contained in:
@@ -205,6 +205,14 @@ extern "C" void loaderMain()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gLoaderHeader.v3.cheats != nullptr && gLoaderHeader.v3.cheats->numberOfCheats != 0)
|
||||||
|
{
|
||||||
|
// Copy cheats to vram
|
||||||
|
auto cheats = (pload_cheats_t*)malloc(gLoaderHeader.v3.cheats->length);
|
||||||
|
memcpy(cheats, gLoaderHeader.v3.cheats, gLoaderHeader.v3.cheats->length);
|
||||||
|
sLoader.SetCheats(cheats);
|
||||||
|
}
|
||||||
|
|
||||||
if (multiboot)
|
if (multiboot)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("Multiboot\n");
|
LOG_DEBUG("Multiboot\n");
|
||||||
@@ -219,19 +227,10 @@ extern "C" void loaderMain()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pload_cheats_t* cheats = nullptr;
|
|
||||||
if (gLoaderHeader.v3.cheats != nullptr && gLoaderHeader.v3.cheats->numberOfCheats != 0)
|
|
||||||
{
|
|
||||||
// Copy cheats to vram
|
|
||||||
cheats = (pload_cheats_t*)malloc(gLoaderHeader.v3.cheats->length);
|
|
||||||
memcpy(cheats, gLoaderHeader.v3.cheats, gLoaderHeader.v3.cheats->length);
|
|
||||||
}
|
|
||||||
|
|
||||||
sLoader.SetRomPath(gLoaderHeader.loadParams.romPath);
|
sLoader.SetRomPath(gLoaderHeader.loadParams.romPath);
|
||||||
handleSavePath();
|
handleSavePath();
|
||||||
sLoader.SetArguments(gLoaderHeader.loadParams.arguments, gLoaderHeader.loadParams.argumentsLength);
|
sLoader.SetArguments(gLoaderHeader.loadParams.arguments, gLoaderHeader.loadParams.argumentsLength);
|
||||||
sLoader.SetLauncherPath(gLoaderHeader.v2.launcherPath);
|
sLoader.SetLauncherPath(gLoaderHeader.v2.launcherPath);
|
||||||
sLoader.SetCheats(cheats);
|
|
||||||
sLoader.Load(BootMode::Normal);
|
sLoader.Load(BootMode::Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,18 @@
|
|||||||
#include "patches/arm7/cheats/CheatEnginePatch.h"
|
#include "patches/arm7/cheats/CheatEnginePatch.h"
|
||||||
#include "Arm7Patcher.h"
|
#include "Arm7Patcher.h"
|
||||||
|
|
||||||
|
static u32 correctAddress(u32 address, const nds_header_ntr_t* romHeader)
|
||||||
|
{
|
||||||
|
if (gIsDsiMode && romHeader->unitCode == 0)
|
||||||
|
{
|
||||||
|
return address & ~0xC00000; // 0x023...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return address | 0x800000; // make sure it ends up in the right place while in 16MB mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheatsLength, void*& cheatsPtr) const
|
void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheatsLength, void*& cheatsPtr) const
|
||||||
{
|
{
|
||||||
cheatsPtr = nullptr;
|
cheatsPtr = nullptr;
|
||||||
@@ -63,6 +75,37 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats
|
|||||||
auto arm7ArenaPatch = new OsGetInitArenaLoPatch();
|
auto arm7ArenaPatch = new OsGetInitArenaLoPatch();
|
||||||
patchCollection.AddPatch(arm7ArenaPatch);
|
patchCollection.AddPatch(arm7ArenaPatch);
|
||||||
|
|
||||||
|
if (!arm7ArenaPatch->FindPatchTarget(patchContext))
|
||||||
|
{
|
||||||
|
ErrorDisplay().PrintError("Failed to apply arm7 patches.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 arm7PatchSpaceSize = 0x800;
|
||||||
|
void* privateWramHeapStart = arm7ArenaPatch->GetArm7PrivateWramArenaLo();
|
||||||
|
u32 mainMemoryArenaLo = (u32)arm7ArenaPatch->GetMainMemoryArenaLo();
|
||||||
|
if (0x0380F780 - (u32)privateWramHeapStart - 0x2100 >= arm7PatchSpaceSize)
|
||||||
|
{
|
||||||
|
patchSpaceStart = privateWramHeapStart;
|
||||||
|
arm7ArenaPatch->SetArm7PrivateWramArenaLo((u8*)patchSpaceStart + arm7PatchSpaceSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Arm 7 patches placed in main memory\n");
|
||||||
|
patchSpaceStart = (void*)correctAddress(mainMemoryArenaLo, romHeader);
|
||||||
|
mainMemoryArenaLo += arm7PatchSpaceSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
patchContext.GetPatchHeap().AddFreeSpace(patchSpaceStart, arm7PatchSpaceSize);
|
||||||
|
|
||||||
|
if (cheatsLength > 0)
|
||||||
|
{
|
||||||
|
void* cheats = (void*)correctAddress(mainMemoryArenaLo, romHeader);
|
||||||
|
LOG_DEBUG("Cheats placed at 0x%p\n", cheats);
|
||||||
|
cheatsPtr = cheats;
|
||||||
|
patchCollection.AddPatch(new CheatEnginePatch(cheats));
|
||||||
|
mainMemoryArenaLo += cheatsLength;
|
||||||
|
}
|
||||||
|
|
||||||
if (romHeader->unitCode == 0) // seems only present on NITRO, not on HYBRID or LIMITED
|
if (romHeader->unitCode == 0) // seems only present on NITRO, not on HYBRID or LIMITED
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new DisableArm7WramClearPatch());
|
patchCollection.AddPatch(new DisableArm7WramClearPatch());
|
||||||
@@ -77,12 +120,16 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats
|
|||||||
|
|
||||||
if (!twlRomHeader->IsDsiWare())
|
if (!twlRomHeader->IsDsiWare())
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new CardiDoTaskFromArm9Patch());
|
void* saveTmpBuffer = (void*)correctAddress(mainMemoryArenaLo, romHeader);
|
||||||
|
mainMemoryArenaLo += 512;
|
||||||
|
patchCollection.AddPatch(new CardiDoTaskFromArm9Patch(saveTmpBuffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
patchCollection.AddPatch(new CardiTaskThreadPatch());
|
void* saveTmpBuffer = (void*)correctAddress(mainMemoryArenaLo, romHeader);
|
||||||
|
mainMemoryArenaLo += 512;
|
||||||
|
patchCollection.AddPatch(new CardiTaskThreadPatch(saveTmpBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") &&
|
if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") &&
|
||||||
@@ -93,54 +140,7 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats
|
|||||||
patchCollection.AddPatch(new PokemonDownloaderArm7Patch());
|
patchCollection.AddPatch(new PokemonDownloaderArm7Patch());
|
||||||
}
|
}
|
||||||
|
|
||||||
CheatEnginePatch* cheatEnginePatch = nullptr;
|
arm7ArenaPatch->SetMainMemoryArenaLo((void*)mainMemoryArenaLo);
|
||||||
if (cheatsLength > 0)
|
|
||||||
{
|
|
||||||
cheatEnginePatch = new CheatEnginePatch();
|
|
||||||
patchCollection.AddPatch(cheatEnginePatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arm7ArenaPatch->FindPatchTarget(patchContext))
|
|
||||||
{
|
|
||||||
const u32 arm7PatchSpaceSize = 0x800;
|
|
||||||
void* privateWramHeapStart = arm7ArenaPatch->GetArm7PrivateWramArenaLo();
|
|
||||||
u32 mainMemoryArenaLo = (u32)arm7ArenaPatch->GetMainMemoryArenaLo();
|
|
||||||
if (0x0380F780 - (u32)privateWramHeapStart - 0x2100 >= arm7PatchSpaceSize)
|
|
||||||
{
|
|
||||||
patchSpaceStart = privateWramHeapStart;
|
|
||||||
arm7ArenaPatch->SetArm7PrivateWramArenaLo((u8*)patchSpaceStart + arm7PatchSpaceSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_DEBUG("Arm 7 patches placed in main memory\n");
|
|
||||||
if (gIsDsiMode && romHeader->unitCode == 0)
|
|
||||||
{
|
|
||||||
patchSpaceStart = (void*)(mainMemoryArenaLo & ~0xC00000); // 0x023...
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
patchSpaceStart = (void*)(mainMemoryArenaLo | 0x800000); // make sure it ends up in the right place while in 16MB mode
|
|
||||||
}
|
|
||||||
mainMemoryArenaLo += arm7PatchSpaceSize;
|
|
||||||
}
|
|
||||||
if (cheatsLength > 0)
|
|
||||||
{
|
|
||||||
void* cheats;
|
|
||||||
if (gIsDsiMode && romHeader->unitCode == 0)
|
|
||||||
{
|
|
||||||
cheats = (void*)(mainMemoryArenaLo & ~0xC00000); // 0x023...
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cheats = (void*)(mainMemoryArenaLo | 0x800000); // make sure it ends up in the right place while in 16MB mode
|
|
||||||
}
|
|
||||||
cheatsPtr = cheats;
|
|
||||||
cheatEnginePatch->SetCheats(cheats);
|
|
||||||
mainMemoryArenaLo += cheatsLength;
|
|
||||||
}
|
|
||||||
arm7ArenaPatch->SetMainMemoryArenaLo((void*)mainMemoryArenaLo);
|
|
||||||
patchContext.GetPatchHeap().AddFreeSpace(patchSpaceStart, arm7PatchSpaceSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The arm7 patcher uses the fact that the ntr wram is mirrored over the entire 03 region.
|
// The arm7 patcher uses the fact that the ntr wram is mirrored over the entire 03 region.
|
||||||
// Since the reserved patch space is smaller than the ntr wram, it will never overlap.
|
// Since the reserved patch space is smaller than the ntr wram, it will never overlap.
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ static const u32 sMiiUncompressBackwardPatternOld2[] = { 0xE3500000, 0x0A00002B,
|
|||||||
static const u32 sMiiUncompressBackwardPattern[] = { 0xE3500000, 0x0A000027, 0xE92D00F0, 0xE9100006 };
|
static const u32 sMiiUncompressBackwardPattern[] = { 0xE3500000, 0x0A000027, 0xE92D00F0, 0xE9100006 };
|
||||||
static const u32 sMiiUncompressBackwardPatternHybrid[] = { 0xE3500000, 0x0A000029, 0xE92D01F0, 0xE9100006 };
|
static const u32 sMiiUncompressBackwardPatternHybrid[] = { 0xE3500000, 0x0A000029, 0xE92D01F0, 0xE9100006 };
|
||||||
|
|
||||||
void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApListEntry* apListEntry,
|
Arm9Patcher::PatchResult Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApListEntry* apListEntry,
|
||||||
bool isCloneBootRom, const loader_info_t* loaderInfo) const
|
bool isCloneBootRom, const loader_info_t* loaderInfo) const
|
||||||
{
|
{
|
||||||
auto romHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader;
|
auto romHeader = (const nds_header_ntr_t*)TWL_SHARED_MEMORY->ntrSharedMem.romHeader;
|
||||||
@@ -165,6 +165,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
loaderPlatform
|
loaderPlatform
|
||||||
};
|
};
|
||||||
PatchCollection patchCollection;
|
PatchCollection patchCollection;
|
||||||
|
OSResetSystemPatch* osResetSystemPatch = nullptr;
|
||||||
if (sdkVersion != 0)
|
if (sdkVersion != 0)
|
||||||
{
|
{
|
||||||
if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") &&
|
if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") &&
|
||||||
@@ -217,7 +218,8 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
patchCollection.AddPatch(new CardiReadRomIdCorePatch());
|
patchCollection.AddPatch(new CardiReadRomIdCorePatch());
|
||||||
patchCollection.AddPatch(new OSResetSystemPatch(loaderInfo));
|
osResetSystemPatch = new OSResetSystemPatch(loaderInfo);
|
||||||
|
patchCollection.AddPatch(osResetSystemPatch);
|
||||||
AddGamePatches(patchCollection, romHeader->gameCode, apListEntry);
|
AddGamePatches(patchCollection, romHeader->gameCode, apListEntry);
|
||||||
|
|
||||||
if (moduleParams && compressedEnd != 0)
|
if (moduleParams && compressedEnd != 0)
|
||||||
@@ -236,6 +238,17 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis
|
|||||||
dc_flushAll();
|
dc_flushAll();
|
||||||
dc_drainWriteBuffer();
|
dc_drainWriteBuffer();
|
||||||
ic_invalidateAll();
|
ic_invalidateAll();
|
||||||
|
|
||||||
|
void** softResetCheatsPointer = nullptr;
|
||||||
|
if (osResetSystemPatch != nullptr)
|
||||||
|
{
|
||||||
|
softResetCheatsPointer = osResetSystemPatch->GetCheatsPointerAtTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResult
|
||||||
|
{
|
||||||
|
.softResetCheatsPointer = softResetCheatsPointer
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32* Arm9Patcher::FindMIiUncompressBackward(u32 arm9LoadAddress, SdkVersion sdkVersion) const
|
const u32* Arm9Patcher::FindMIiUncompressBackward(u32 arm9LoadAddress, SdkVersion sdkVersion) const
|
||||||
|
|||||||
@@ -12,12 +12,20 @@ class OverlayHookPatch;
|
|||||||
class Arm9Patcher
|
class Arm9Patcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct PatchResult
|
||||||
|
{
|
||||||
|
/// @brief Pointer to the cheats pointer used for soft reset.
|
||||||
|
/// This pointer must be set to keep cheats over soft resets.
|
||||||
|
void** softResetCheatsPointer;
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Applies arm9 patches using the given \p loaderPlatform.
|
/// @brief Applies arm9 patches using the given \p loaderPlatform.
|
||||||
/// @param loaderPlatform The loader platform to use.
|
/// @param loaderPlatform The loader platform to use.
|
||||||
/// @param apListEntry The AP list entry for the rom being loaded, or \c nullptr if there is none.
|
/// @param apListEntry The AP list entry for the rom being loaded, or \c nullptr if there is none.
|
||||||
/// @param isCloneBootRom \c true if the rom being loaded is a clone boot rom, or \c false otherwise.
|
/// @param isCloneBootRom \c true if the rom being loaded is a clone boot rom, or \c false otherwise.
|
||||||
/// @param loaderInfo The loader info to use.
|
/// @param loaderInfo The loader info to use.
|
||||||
void ApplyPatches(const LoaderPlatform* loaderPlatform, const ApListEntry* apListEntry,
|
/// @return Some information resulting from the patching.
|
||||||
|
PatchResult ApplyPatches(const LoaderPlatform* loaderPlatform, const ApListEntry* apListEntry,
|
||||||
bool isCloneBootRom, const loader_info_t* loaderInfo) const;
|
bool isCloneBootRom, const loader_info_t* loaderInfo) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ static u32 sRomDirSector;
|
|||||||
static u32 sRomDirSectorOffset;
|
static u32 sRomDirSectorOffset;
|
||||||
static u16 sIsCloneBootRom;
|
static u16 sIsCloneBootRom;
|
||||||
static loader_info_t sLoaderInfo;
|
static loader_info_t sLoaderInfo;
|
||||||
|
static void** sSoftResetCheatsPointer = nullptr;
|
||||||
|
|
||||||
u16 gIsDsiMode;
|
u16 gIsDsiMode;
|
||||||
|
|
||||||
@@ -147,11 +148,12 @@ static void handleClearMainMemCommand()
|
|||||||
|
|
||||||
static void handleApplyArm9PatchesCommand()
|
static void handleApplyArm9PatchesCommand()
|
||||||
{
|
{
|
||||||
Arm9Patcher().ApplyPatches(
|
auto result = Arm9Patcher().ApplyPatches(
|
||||||
sLoaderPlatform,
|
sLoaderPlatform,
|
||||||
sApListEntry.GetGameCode() == 0 ? nullptr : &sApListEntry,
|
sApListEntry.GetGameCode() == 0 ? nullptr : &sApListEntry,
|
||||||
sIsCloneBootRom,
|
sIsCloneBootRom,
|
||||||
&sLoaderInfo);
|
&sLoaderInfo);
|
||||||
|
sSoftResetCheatsPointer = result.softResetCheatsPointer;
|
||||||
ipc_sendWordDirect(1);
|
ipc_sendWordDirect(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +161,10 @@ static void handleApplyArm7PatchesCommand(u32 cheatsLength)
|
|||||||
{
|
{
|
||||||
void* cheats = nullptr;
|
void* cheats = nullptr;
|
||||||
void* patchSpaceStart = Arm7Patcher().ApplyPatches(sLoaderPlatform, cheatsLength, cheats);
|
void* patchSpaceStart = Arm7Patcher().ApplyPatches(sLoaderPlatform, cheatsLength, cheats);
|
||||||
|
if (sSoftResetCheatsPointer != nullptr)
|
||||||
|
{
|
||||||
|
*sSoftResetCheatsPointer = cheats;
|
||||||
|
}
|
||||||
ipc_sendWordDirect((u32)patchSpaceStart);
|
ipc_sendWordDirect((u32)patchSpaceStart);
|
||||||
ipc_sendWordDirect((u32)cheats);
|
ipc_sendWordDirect((u32)cheats);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,14 @@
|
|||||||
class CheatEnginePatch : public Patch
|
class CheatEnginePatch : public Patch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit CheatEnginePatch(const void* cheats)
|
||||||
|
: _cheats(cheats) { }
|
||||||
|
|
||||||
bool FindPatchTarget(PatchContext& patchContext) override;
|
bool FindPatchTarget(PatchContext& patchContext) override;
|
||||||
void ApplyPatch(PatchContext& patchContext) override;
|
void ApplyPatch(PatchContext& patchContext) override;
|
||||||
|
|
||||||
void SetCheats(const void* cheats)
|
|
||||||
{
|
|
||||||
_cheats = cheats;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const void* _cheats = nullptr;
|
const void* _cheats;
|
||||||
u32* _vblankIrqHandler = nullptr;
|
u32* _vblankIrqHandler = nullptr;
|
||||||
const u32* _foundPattern = nullptr;
|
const u32* _foundPattern = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -103,13 +103,12 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
(const save_file_info_t*)((u32)SHARED_SAVE_FILE_INFO - 0x02F00000 + 0x02700000)
|
(const save_file_info_t*)((u32)SHARED_SAVE_FILE_INFO - 0x02F00000 + 0x02700000)
|
||||||
);
|
);
|
||||||
void* tmpBuffer = patchContext.GetPatchHeap().Alloc(512);
|
|
||||||
auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<ReadSavePatchCode>
|
auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<ReadSavePatchCode>
|
||||||
(
|
(
|
||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<WriteSavePatchCode>
|
auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<WriteSavePatchCode>
|
||||||
(
|
(
|
||||||
@@ -117,13 +116,13 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
writePatchCode,
|
writePatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<VerifySavePatchCode>(
|
auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<VerifySavePatchCode>(
|
||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
__patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction();
|
__patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction();
|
||||||
|
|||||||
@@ -22,11 +22,15 @@ public:
|
|||||||
ThumbF
|
ThumbF
|
||||||
};
|
};
|
||||||
|
|
||||||
|
explicit CardiTaskThreadPatch(void* saveTmpBuffer)
|
||||||
|
: _saveTmpBuffer(saveTmpBuffer) { }
|
||||||
|
|
||||||
bool FindPatchTarget(PatchContext& patchContext) override;
|
bool FindPatchTarget(PatchContext& patchContext) override;
|
||||||
void ApplyPatch(PatchContext& patchContext) override;
|
void ApplyPatch(PatchContext& patchContext) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32* _cardiTaskThread = nullptr;
|
u32* _cardiTaskThread = nullptr;
|
||||||
|
void* _saveTmpBuffer;
|
||||||
PatchVariant _patchVariant = PatchVariant::None;
|
PatchVariant _patchVariant = PatchVariant::None;
|
||||||
|
|
||||||
void ApplyArmPatch(void* patch1Address) const;
|
void ApplyArmPatch(void* patch1Address) const;
|
||||||
|
|||||||
@@ -68,25 +68,24 @@ void CardiDoTaskFromArm9Patch::ApplyPatch(PatchContext& patchContext)
|
|||||||
patchContext.GetPatchCodeCollection(), patchContext.GetPatchHeap());
|
patchContext.GetPatchCodeCollection(), patchContext.GetPatchHeap());
|
||||||
auto sectorRemapPatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<SaveOffsetToSdSectorPatchCode>(
|
auto sectorRemapPatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<SaveOffsetToSdSectorPatchCode>(
|
||||||
patchContext.GetPatchHeap(), SHARED_SAVE_FILE_INFO);
|
patchContext.GetPatchHeap(), SHARED_SAVE_FILE_INFO);
|
||||||
void* tmpBuffer = patchContext.GetPatchHeap().Alloc(512);
|
|
||||||
auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<ReadSavePatchCode>(
|
auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<ReadSavePatchCode>(
|
||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<WriteSavePatchCode>(
|
auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<WriteSavePatchCode>(
|
||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
writePatchCode,
|
writePatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<VerifySavePatchCode>(
|
auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode<VerifySavePatchCode>(
|
||||||
patchContext.GetPatchHeap(),
|
patchContext.GetPatchHeap(),
|
||||||
sectorRemapPatchCode,
|
sectorRemapPatchCode,
|
||||||
readPatchCode,
|
readPatchCode,
|
||||||
tmpBuffer
|
_saveTmpBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
__patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction();
|
__patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction();
|
||||||
|
|||||||
@@ -5,12 +5,16 @@
|
|||||||
class CardiDoTaskFromArm9Patch : public Patch
|
class CardiDoTaskFromArm9Patch : public Patch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit CardiDoTaskFromArm9Patch(void* saveTmpBuffer)
|
||||||
|
: _saveTmpBuffer(saveTmpBuffer) { }
|
||||||
|
|
||||||
bool FindPatchTarget(PatchContext& patchContext) override;
|
bool FindPatchTarget(PatchContext& patchContext) override;
|
||||||
void ApplyPatch(PatchContext& patchContext) override;
|
void ApplyPatch(PatchContext& patchContext) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32* _cardiDoTaskFromArm9 = nullptr;
|
u32* _cardiDoTaskFromArm9 = nullptr;
|
||||||
const u32* _foundPattern = nullptr;
|
const u32* _foundPattern = nullptr;
|
||||||
|
void* _saveTmpBuffer;
|
||||||
u16 _thumb = false;
|
u16 _thumb = false;
|
||||||
|
|
||||||
void TryPattern(PatchContext& patchContext, const u32* pattern);
|
void TryPattern(PatchContext& patchContext, const u32* pattern);
|
||||||
|
|||||||
@@ -126,5 +126,7 @@ void OSResetSystemPatch::ApplyPatch(PatchContext& patchContext)
|
|||||||
|
|
||||||
*(u32*)((u8*)_osResetSystem + offset) = 0xE51FF004;
|
*(u32*)((u8*)_osResetSystem + offset) = 0xE51FF004;
|
||||||
*(u32*)((u8*)_osResetSystem + offset + 4) = (u32)patchCode->GetOSResetSystemFunction();
|
*(u32*)((u8*)_osResetSystem + offset + 4) = (u32)patchCode->GetOSResetSystemFunction();
|
||||||
|
|
||||||
|
_cheatsPointer = patchCodePart2->GetCheatsPointerAtTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,14 @@ public:
|
|||||||
bool FindPatchTarget(PatchContext& patchContext) override;
|
bool FindPatchTarget(PatchContext& patchContext) override;
|
||||||
void ApplyPatch(PatchContext& patchContext) override;
|
void ApplyPatch(PatchContext& patchContext) override;
|
||||||
|
|
||||||
|
void** GetCheatsPointerAtTarget() const
|
||||||
|
{
|
||||||
|
return _cheatsPointer;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32* _osResetSystem = nullptr;
|
u32* _osResetSystem = nullptr;
|
||||||
u32 _hybrid = false;
|
u32 _hybrid = false;
|
||||||
const loader_info_t* _loaderInfo;
|
const loader_info_t* _loaderInfo;
|
||||||
|
void** _cheatsPointer = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ extern u32 patch_osresetsystem_readSdSectors_address;
|
|||||||
extern u32 patch_osresetsystem_bootPicoLoader_address;
|
extern u32 patch_osresetsystem_bootPicoLoader_address;
|
||||||
extern u16 patch_osresetsystem_entry_jump_to_twl_arm7_sync;
|
extern u16 patch_osresetsystem_entry_jump_to_twl_arm7_sync;
|
||||||
extern u32 patch_osresetsystem_arm7Entry_address;
|
extern u32 patch_osresetsystem_arm7Entry_address;
|
||||||
|
extern u32 patch_osresetsystem_cheats_address;
|
||||||
|
|
||||||
class OSResetSystemPart2PatchCode : public PatchCode
|
class OSResetSystemPart2PatchCode : public PatchCode
|
||||||
{
|
{
|
||||||
@@ -28,6 +29,11 @@ public:
|
|||||||
{
|
{
|
||||||
return GetAddressAtTarget((void*)patch_osresetsystem_bootPicoLoader);
|
return GetAddressAtTarget((void*)patch_osresetsystem_bootPicoLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void** GetCheatsPointerAtTarget() const
|
||||||
|
{
|
||||||
|
return (void**)GetAddressAtTarget(&patch_osresetsystem_cheats_address);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class OSResetSystemPatchCode : public PatchCode
|
class OSResetSystemPatchCode : public PatchCode
|
||||||
|
|||||||
@@ -108,16 +108,24 @@ patch_osresetsystem_bootPicoLoader:
|
|||||||
ldmia r5, {r3, r5}
|
ldmia r5, {r3, r5}
|
||||||
ldrh r0, [r3, #2] // loader_info_t::picoLoaderBootDrive
|
ldrh r0, [r3, #2] // loader_info_t::picoLoaderBootDrive
|
||||||
strh r0, [r5, #8] // pload_header7_t::bootDrive
|
strh r0, [r5, #8] // pload_header7_t::bootDrive
|
||||||
ldr r0, [r5] // pload_header7_t::entryPoint
|
|
||||||
|
adr r0, regVramCntA
|
||||||
|
ldmia r0, {r0, r4, r6, r7}
|
||||||
|
// r0 = regVramCntA
|
||||||
|
// r4 = patch_osresetsystem_arm7Entry_address
|
||||||
|
// r6 = vramCDSettings
|
||||||
|
// r7 = patch_osresetsystem_cheats_address
|
||||||
|
|
||||||
|
movs r2, #0x41
|
||||||
|
lsls r2, r2, #4 // 0x410
|
||||||
|
str r7, [r5, r2] // pload_header7_t::v3.cheats
|
||||||
|
ldr r1, [r5] // pload_header7_t::entryPoint
|
||||||
|
|
||||||
// set NTR_SHARED_MEMORY->romHeader.arm7EntryAddress
|
// set NTR_SHARED_MEMORY->romHeader.arm7EntryAddress
|
||||||
ldr r4, patch_osresetsystem_arm7Entry_address
|
str r1, [r4]
|
||||||
str r0, [r4]
|
|
||||||
|
|
||||||
// map vram CD to arm7
|
// map vram CD to arm7
|
||||||
ldr r0,= 0x04000240
|
strh r6, [r0, #2]
|
||||||
ldr r7,= 0x8A82
|
|
||||||
strh r7, [r0, #2]
|
|
||||||
|
|
||||||
adds r0, #(0x04000180 - 0x04000240) // REG_IPC_SYNC
|
adds r0, #(0x04000180 - 0x04000240) // REG_IPC_SYNC
|
||||||
movs r1, #1
|
movs r1, #1
|
||||||
@@ -139,21 +147,17 @@ twl_arm7_sync:
|
|||||||
ldr r7,= 0x02FFFC24
|
ldr r7,= 0x02FFFC24
|
||||||
movs r1, #1
|
movs r1, #1
|
||||||
strh r1, [r7, #4]
|
strh r1, [r7, #4]
|
||||||
|
mov r11, pc
|
||||||
ldrh r6, [r7, #2]
|
b do_sync
|
||||||
ldrh r1, [r7]
|
|
||||||
1:
|
|
||||||
adds r1, #1
|
|
||||||
strh r1, [r7]
|
|
||||||
ldrh r4, [r7, #2]
|
|
||||||
cmp r6, r4
|
|
||||||
beq 1b
|
|
||||||
adds r1, #1
|
|
||||||
strh r1, [r7]
|
|
||||||
|
|
||||||
movs r1, #3
|
movs r1, #3
|
||||||
strh r1, [r7, #4]
|
strh r1, [r7, #4]
|
||||||
|
mov r11, pc
|
||||||
|
b do_sync
|
||||||
|
|
||||||
|
mov pc, lr
|
||||||
|
|
||||||
|
do_sync:
|
||||||
ldrh r6, [r7, #2]
|
ldrh r6, [r7, #2]
|
||||||
ldrh r1, [r7]
|
ldrh r1, [r7]
|
||||||
1:
|
1:
|
||||||
@@ -164,14 +168,23 @@ twl_arm7_sync:
|
|||||||
beq 1b
|
beq 1b
|
||||||
adds r1, #1
|
adds r1, #1
|
||||||
strh r1, [r7]
|
strh r1, [r7]
|
||||||
|
mov pc, r11
|
||||||
mov pc, lr
|
|
||||||
|
|
||||||
.balign 4
|
.balign 4
|
||||||
|
|
||||||
|
regVramCntA:
|
||||||
|
.word 0x04000240
|
||||||
|
|
||||||
.global patch_osresetsystem_arm7Entry_address
|
.global patch_osresetsystem_arm7Entry_address
|
||||||
patch_osresetsystem_arm7Entry_address:
|
patch_osresetsystem_arm7Entry_address:
|
||||||
.word 0x027FFE34
|
.word 0x027FFE34
|
||||||
|
|
||||||
|
vramCDSettings:
|
||||||
|
.word 0x8A82
|
||||||
|
|
||||||
|
.global patch_osresetsystem_cheats_address
|
||||||
|
patch_osresetsystem_cheats_address:
|
||||||
|
.word 0
|
||||||
|
|
||||||
.pool
|
.pool
|
||||||
.end
|
.end
|
||||||
|
|||||||
Reference in New Issue
Block a user