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:
parent
07f672f81b
commit
cf8ac5c09c
|
@ -156,34 +156,24 @@ static bool InstallCodeHandler()
|
||||||
|
|
||||||
void RunCodeHandler()
|
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)
|
if (!code_handler_installed)
|
||||||
{
|
|
||||||
// A warning was already issued.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PC == LR)
|
// 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
|
||||||
u32 oldLR = LR;
|
// the original return address (which will still be in the link register) at the end.
|
||||||
PowerPC::CoreMode oldMode = PowerPC::GetMode();
|
if (PC == LR)
|
||||||
|
{
|
||||||
PC = INSTALLER_BASE_ADDRESS + 0xA8;
|
PC = NPC = 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue