From cf8ac5c09c8719db3c88b34b6d7ffc4084800f75 Mon Sep 17 00:00:00 2001 From: EmptyChaos Date: Thu, 15 Sep 2016 02:38:48 +0000 Subject: [PATCH] GeckoCode: Don't run PPC code in a CoreTiming callback Executing PPC code inside an external events callback is a bad idea. CoreTiming::Advance does not support recursion properly which will cause timing glitches. The interpreter has a slice length hack that counters this but without it this would cause a 20000 cycles time skip. It isn't clear what this was supposed to accomplish that just changing the current PC would not. Changing the PC works fine. --- Source/Core/Core/GeckoCode.cpp | 36 ++++++++++++---------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 6983eb6224..b4d896a3f2 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -156,34 +156,24 @@ static bool InstallCodeHandler() void RunCodeHandler() { - if (SConfig::GetInstance().bEnableCheats && active_codes.size() > 0) + if (!SConfig::GetInstance().bEnableCheats || active_codes.empty()) + return; + + if (!code_handler_installed || PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5) { - if (!code_handler_installed || PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS) - 0xd01f1bad > 5) - code_handler_installed = InstallCodeHandler(); + code_handler_installed = InstallCodeHandler(); + // A warning was already issued for the install failing if (!code_handler_installed) - { - // A warning was already issued. return; - } + } - if (PC == LR) - { - u32 oldLR = LR; - PowerPC::CoreMode oldMode = PowerPC::GetMode(); - - PC = INSTALLER_BASE_ADDRESS + 0xA8; - LR = 0; - - // Execute the code handler in interpreter mode to track when it exits - PowerPC::SetMode(PowerPC::MODE_INTERPRETER); - - while (PC != 0) - PowerPC::SingleStep(); - - PowerPC::SetMode(oldMode); - PC = LR = oldLR; - } + // If the last block that just executed ended with a BLR instruction then we can intercept it and + // redirect control into the Gecko Code Handler. The Code Handler will automatically BLR back to + // the original return address (which will still be in the link register) at the end. + if (PC == LR) + { + PC = NPC = INSTALLER_BASE_ADDRESS + 0xA8; } }