From 8c8f36f5c635ea70d5ef51a83feccbcdaccd554a Mon Sep 17 00:00:00 2001 From: Gericom Date: Sat, 7 Mar 2026 13:49:51 +0100 Subject: [PATCH] Preserve cheats when OS_ResetSystem is used, move temporary save buffer to main memory --- arm7/source/main.cpp | 17 ++- arm9/source/Arm7Patcher.cpp | 100 +++++++++--------- arm9/source/Arm9Patcher.cpp | 17 ++- arm9/source/Arm9Patcher.h | 10 +- arm9/source/main.cpp | 8 +- .../patches/arm7/cheats/CheatEnginePatch.h | 10 +- .../arm7/sdk2to4/CardiTaskThreadPatch.cpp | 7 +- .../arm7/sdk2to4/CardiTaskThreadPatch.h | 4 + .../arm7/sdk5/CardiDoTaskFromArm9Patch.cpp | 7 +- .../arm7/sdk5/CardiDoTaskFromArm9Patch.h | 4 + .../patches/arm9/OSResetSystemPatch.cpp | 2 + arm9/source/patches/arm9/OSResetSystemPatch.h | 6 ++ .../patches/arm9/OSResetSystemPatchCode.h | 6 ++ .../patches/arm9/OSResetSystemPatchCode.s | 51 +++++---- 14 files changed, 153 insertions(+), 96 deletions(-) diff --git a/arm7/source/main.cpp b/arm7/source/main.cpp index 7683786..96c2122 100644 --- a/arm7/source/main.cpp +++ b/arm7/source/main.cpp @@ -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) { LOG_DEBUG("Multiboot\n"); @@ -219,19 +227,10 @@ extern "C" void loaderMain() } 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); handleSavePath(); sLoader.SetArguments(gLoaderHeader.loadParams.arguments, gLoaderHeader.loadParams.argumentsLength); sLoader.SetLauncherPath(gLoaderHeader.v2.launcherPath); - sLoader.SetCheats(cheats); sLoader.Load(BootMode::Normal); } diff --git a/arm9/source/Arm7Patcher.cpp b/arm9/source/Arm7Patcher.cpp index 334559d..e96625b 100644 --- a/arm9/source/Arm7Patcher.cpp +++ b/arm9/source/Arm7Patcher.cpp @@ -18,6 +18,18 @@ #include "patches/arm7/cheats/CheatEnginePatch.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 { cheatsPtr = nullptr; @@ -63,6 +75,37 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats auto arm7ArenaPatch = new OsGetInitArenaLoPatch(); 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 { patchCollection.AddPatch(new DisableArm7WramClearPatch()); @@ -77,12 +120,16 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats if (!twlRomHeader->IsDsiWare()) { - patchCollection.AddPatch(new CardiDoTaskFromArm9Patch()); + void* saveTmpBuffer = (void*)correctAddress(mainMemoryArenaLo, romHeader); + mainMemoryArenaLo += 512; + patchCollection.AddPatch(new CardiDoTaskFromArm9Patch(saveTmpBuffer)); } } else { - patchCollection.AddPatch(new CardiTaskThreadPatch()); + void* saveTmpBuffer = (void*)correctAddress(mainMemoryArenaLo, romHeader); + mainMemoryArenaLo += 512; + patchCollection.AddPatch(new CardiTaskThreadPatch(saveTmpBuffer)); } if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") && @@ -93,54 +140,7 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, u32 cheats patchCollection.AddPatch(new PokemonDownloaderArm7Patch()); } - CheatEnginePatch* cheatEnginePatch = nullptr; - 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); - } + arm7ArenaPatch->SetMainMemoryArenaLo((void*)mainMemoryArenaLo); // 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. diff --git a/arm9/source/Arm9Patcher.cpp b/arm9/source/Arm9Patcher.cpp index 8004397..072898c 100644 --- a/arm9/source/Arm9Patcher.cpp +++ b/arm9/source/Arm9Patcher.cpp @@ -47,7 +47,7 @@ static const u32 sMiiUncompressBackwardPatternOld2[] = { 0xE3500000, 0x0A00002B, static const u32 sMiiUncompressBackwardPattern[] = { 0xE3500000, 0x0A000027, 0xE92D00F0, 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 { 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 }; PatchCollection patchCollection; + OSResetSystemPatch* osResetSystemPatch = nullptr; if (sdkVersion != 0) { if (*(vu32*)0x02FFF00C == GAMECODE("ADAJ") && @@ -217,7 +218,8 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis } patchCollection.AddPatch(new CardiReadRomIdCorePatch()); - patchCollection.AddPatch(new OSResetSystemPatch(loaderInfo)); + osResetSystemPatch = new OSResetSystemPatch(loaderInfo); + patchCollection.AddPatch(osResetSystemPatch); AddGamePatches(patchCollection, romHeader->gameCode, apListEntry); if (moduleParams && compressedEnd != 0) @@ -236,6 +238,17 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis dc_flushAll(); dc_drainWriteBuffer(); ic_invalidateAll(); + + void** softResetCheatsPointer = nullptr; + if (osResetSystemPatch != nullptr) + { + softResetCheatsPointer = osResetSystemPatch->GetCheatsPointerAtTarget(); + } + + return PatchResult + { + .softResetCheatsPointer = softResetCheatsPointer + }; } const u32* Arm9Patcher::FindMIiUncompressBackward(u32 arm9LoadAddress, SdkVersion sdkVersion) const diff --git a/arm9/source/Arm9Patcher.h b/arm9/source/Arm9Patcher.h index 316ab27..eed39e8 100644 --- a/arm9/source/Arm9Patcher.h +++ b/arm9/source/Arm9Patcher.h @@ -12,12 +12,20 @@ class OverlayHookPatch; class Arm9Patcher { 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. /// @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 isCloneBootRom \c true if the rom being loaded is a clone boot rom, or \c false otherwise. /// @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; private: diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index f8577c4..56e302d 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -47,6 +47,7 @@ static u32 sRomDirSector; static u32 sRomDirSectorOffset; static u16 sIsCloneBootRom; static loader_info_t sLoaderInfo; +static void** sSoftResetCheatsPointer = nullptr; u16 gIsDsiMode; @@ -147,11 +148,12 @@ static void handleClearMainMemCommand() static void handleApplyArm9PatchesCommand() { - Arm9Patcher().ApplyPatches( + auto result = Arm9Patcher().ApplyPatches( sLoaderPlatform, sApListEntry.GetGameCode() == 0 ? nullptr : &sApListEntry, sIsCloneBootRom, &sLoaderInfo); + sSoftResetCheatsPointer = result.softResetCheatsPointer; ipc_sendWordDirect(1); } @@ -159,6 +161,10 @@ static void handleApplyArm7PatchesCommand(u32 cheatsLength) { void* cheats = nullptr; void* patchSpaceStart = Arm7Patcher().ApplyPatches(sLoaderPlatform, cheatsLength, cheats); + if (sSoftResetCheatsPointer != nullptr) + { + *sSoftResetCheatsPointer = cheats; + } ipc_sendWordDirect((u32)patchSpaceStart); ipc_sendWordDirect((u32)cheats); } diff --git a/arm9/source/patches/arm7/cheats/CheatEnginePatch.h b/arm9/source/patches/arm7/cheats/CheatEnginePatch.h index b0d8790..35a5f58 100644 --- a/arm9/source/patches/arm7/cheats/CheatEnginePatch.h +++ b/arm9/source/patches/arm7/cheats/CheatEnginePatch.h @@ -5,16 +5,14 @@ class CheatEnginePatch : public Patch { public: + explicit CheatEnginePatch(const void* cheats) + : _cheats(cheats) { } + bool FindPatchTarget(PatchContext& patchContext) override; void ApplyPatch(PatchContext& patchContext) override; - void SetCheats(const void* cheats) - { - _cheats = cheats; - } - private: - const void* _cheats = nullptr; + const void* _cheats; u32* _vblankIrqHandler = nullptr; const u32* _foundPattern = nullptr; }; diff --git a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp index 9fc0c65..e7e917f 100644 --- a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp +++ b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp @@ -103,13 +103,12 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext) patchContext.GetPatchHeap(), (const save_file_info_t*)((u32)SHARED_SAVE_FILE_INFO - 0x02F00000 + 0x02700000) ); - void* tmpBuffer = patchContext.GetPatchHeap().Alloc(512); auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode ( patchContext.GetPatchHeap(), sectorRemapPatchCode, readPatchCode, - tmpBuffer + _saveTmpBuffer ); auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode ( @@ -117,13 +116,13 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext) sectorRemapPatchCode, readPatchCode, writePatchCode, - tmpBuffer + _saveTmpBuffer ); auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( patchContext.GetPatchHeap(), sectorRemapPatchCode, readPatchCode, - tmpBuffer + _saveTmpBuffer ); __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); diff --git a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.h b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.h index 707b35b..40f6487 100644 --- a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.h +++ b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.h @@ -22,11 +22,15 @@ public: ThumbF }; + explicit CardiTaskThreadPatch(void* saveTmpBuffer) + : _saveTmpBuffer(saveTmpBuffer) { } + bool FindPatchTarget(PatchContext& patchContext) override; void ApplyPatch(PatchContext& patchContext) override; private: u32* _cardiTaskThread = nullptr; + void* _saveTmpBuffer; PatchVariant _patchVariant = PatchVariant::None; void ApplyArmPatch(void* patch1Address) const; diff --git a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp index 5a0d0f9..baab8f7 100644 --- a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp +++ b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp @@ -68,25 +68,24 @@ void CardiDoTaskFromArm9Patch::ApplyPatch(PatchContext& patchContext) patchContext.GetPatchCodeCollection(), patchContext.GetPatchHeap()); auto sectorRemapPatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( patchContext.GetPatchHeap(), SHARED_SAVE_FILE_INFO); - void* tmpBuffer = patchContext.GetPatchHeap().Alloc(512); auto readSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( patchContext.GetPatchHeap(), sectorRemapPatchCode, readPatchCode, - tmpBuffer + _saveTmpBuffer ); auto writeSavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( patchContext.GetPatchHeap(), sectorRemapPatchCode, readPatchCode, writePatchCode, - tmpBuffer + _saveTmpBuffer ); auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( patchContext.GetPatchHeap(), sectorRemapPatchCode, readPatchCode, - tmpBuffer + _saveTmpBuffer ); __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); diff --git a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.h b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.h index b8a89db..44e7334 100644 --- a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.h +++ b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.h @@ -5,12 +5,16 @@ class CardiDoTaskFromArm9Patch : public Patch { public: + explicit CardiDoTaskFromArm9Patch(void* saveTmpBuffer) + : _saveTmpBuffer(saveTmpBuffer) { } + bool FindPatchTarget(PatchContext& patchContext) override; void ApplyPatch(PatchContext& patchContext) override; private: u32* _cardiDoTaskFromArm9 = nullptr; const u32* _foundPattern = nullptr; + void* _saveTmpBuffer; u16 _thumb = false; void TryPattern(PatchContext& patchContext, const u32* pattern); diff --git a/arm9/source/patches/arm9/OSResetSystemPatch.cpp b/arm9/source/patches/arm9/OSResetSystemPatch.cpp index 3c6a371..28c8ca8 100644 --- a/arm9/source/patches/arm9/OSResetSystemPatch.cpp +++ b/arm9/source/patches/arm9/OSResetSystemPatch.cpp @@ -126,5 +126,7 @@ void OSResetSystemPatch::ApplyPatch(PatchContext& patchContext) *(u32*)((u8*)_osResetSystem + offset) = 0xE51FF004; *(u32*)((u8*)_osResetSystem + offset + 4) = (u32)patchCode->GetOSResetSystemFunction(); + + _cheatsPointer = patchCodePart2->GetCheatsPointerAtTarget(); } diff --git a/arm9/source/patches/arm9/OSResetSystemPatch.h b/arm9/source/patches/arm9/OSResetSystemPatch.h index 5f57ce0..ab261fc 100644 --- a/arm9/source/patches/arm9/OSResetSystemPatch.h +++ b/arm9/source/patches/arm9/OSResetSystemPatch.h @@ -12,8 +12,14 @@ public: bool FindPatchTarget(PatchContext& patchContext) override; void ApplyPatch(PatchContext& patchContext) override; + void** GetCheatsPointerAtTarget() const + { + return _cheatsPointer; + } + private: u32* _osResetSystem = nullptr; u32 _hybrid = false; const loader_info_t* _loaderInfo; + void** _cheatsPointer = nullptr; }; diff --git a/arm9/source/patches/arm9/OSResetSystemPatchCode.h b/arm9/source/patches/arm9/OSResetSystemPatchCode.h index d6f0aab..179ea98 100644 --- a/arm9/source/patches/arm9/OSResetSystemPatchCode.h +++ b/arm9/source/patches/arm9/OSResetSystemPatchCode.h @@ -15,6 +15,7 @@ extern u32 patch_osresetsystem_readSdSectors_address; extern u32 patch_osresetsystem_bootPicoLoader_address; extern u16 patch_osresetsystem_entry_jump_to_twl_arm7_sync; extern u32 patch_osresetsystem_arm7Entry_address; +extern u32 patch_osresetsystem_cheats_address; class OSResetSystemPart2PatchCode : public PatchCode { @@ -28,6 +29,11 @@ public: { return GetAddressAtTarget((void*)patch_osresetsystem_bootPicoLoader); } + + void** GetCheatsPointerAtTarget() const + { + return (void**)GetAddressAtTarget(&patch_osresetsystem_cheats_address); + } }; class OSResetSystemPatchCode : public PatchCode diff --git a/arm9/source/patches/arm9/OSResetSystemPatchCode.s b/arm9/source/patches/arm9/OSResetSystemPatchCode.s index 17e79bb..6bc1a85 100644 --- a/arm9/source/patches/arm9/OSResetSystemPatchCode.s +++ b/arm9/source/patches/arm9/OSResetSystemPatchCode.s @@ -108,16 +108,24 @@ patch_osresetsystem_bootPicoLoader: ldmia r5, {r3, r5} ldrh r0, [r3, #2] // loader_info_t::picoLoaderBootDrive 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 - ldr r4, patch_osresetsystem_arm7Entry_address - str r0, [r4] + str r1, [r4] // map vram CD to arm7 - ldr r0,= 0x04000240 - ldr r7,= 0x8A82 - strh r7, [r0, #2] + strh r6, [r0, #2] adds r0, #(0x04000180 - 0x04000240) // REG_IPC_SYNC movs r1, #1 @@ -139,21 +147,17 @@ twl_arm7_sync: ldr r7,= 0x02FFFC24 movs r1, #1 strh r1, [r7, #4] - - ldrh r6, [r7, #2] - 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] + mov r11, pc + b do_sync movs r1, #3 strh r1, [r7, #4] + mov r11, pc + b do_sync + mov pc, lr + +do_sync: ldrh r6, [r7, #2] ldrh r1, [r7] 1: @@ -164,14 +168,23 @@ twl_arm7_sync: beq 1b adds r1, #1 strh r1, [r7] - - mov pc, lr + mov pc, r11 .balign 4 +regVramCntA: + .word 0x04000240 + .global patch_osresetsystem_arm7Entry_address patch_osresetsystem_arm7Entry_address: .word 0x027FFE34 +vramCDSettings: + .word 0x8A82 + +.global patch_osresetsystem_cheats_address +patch_osresetsystem_cheats_address: + .word 0 + .pool .end