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.
This commit is contained in:
EmptyChaos 2016-09-15 02:38:48 +00:00
parent 07f672f81b
commit cf8ac5c09c

View File

@ -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;
}
}