mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
GeckoCode: Use named constants in ICache flush hack
Turns out one of the magic numbers was very magic. The gameid is an ad-hoc comm protocol with HLE_Misc to control the number of times the ICache is reset.
This commit is contained in:
@ -17,6 +17,7 @@
|
|||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||||
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
#include "Core/HW/DVDInterface.h"
|
#include "Core/HW/DVDInterface.h"
|
||||||
#include "Core/HW/EXI_DeviceIPL.h"
|
#include "Core/HW/EXI_DeviceIPL.h"
|
||||||
@ -481,6 +482,6 @@ bool CBoot::BootUp()
|
|||||||
|
|
||||||
// Not part of the binary itself, but either we or Gecko OS might insert
|
// Not part of the binary itself, but either we or Gecko OS might insert
|
||||||
// this, and it doesn't clear the icache properly.
|
// this, and it doesn't clear the icache properly.
|
||||||
HLE::Patch(0x800018a8, "GeckoCodehandler");
|
HLE::Patch(Gecko::ENTRY_POINT, "GeckoCodehandler");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
|
|
||||||
namespace Gecko
|
namespace Gecko
|
||||||
{
|
{
|
||||||
static constexpr u32 INSTALLER_BASE_ADDRESS = 0x80001800;
|
|
||||||
static constexpr u32 INSTALLER_END_ADDRESS = 0x80003000;
|
static constexpr u32 INSTALLER_END_ADDRESS = 0x80003000;
|
||||||
static constexpr u32 CODE_SIZE = 8;
|
static constexpr u32 CODE_SIZE = 8;
|
||||||
static constexpr u32 MAGIC_GAMEID = 0xD01F1BAD;
|
|
||||||
|
|
||||||
// return true if a code exists
|
// return true if a code exists
|
||||||
bool GeckoCode::Exist(u32 address, u32 data) const
|
bool GeckoCode::Exist(u32 address, u32 data) const
|
||||||
@ -102,6 +100,7 @@ static bool InstallCodeHandlerLocked()
|
|||||||
const u32 codelist_end_address = INSTALLER_END_ADDRESS;
|
const u32 codelist_end_address = INSTALLER_END_ADDRESS;
|
||||||
|
|
||||||
// Write a magic value to 'gameid' (codehandleronly does not actually read this).
|
// Write a magic value to 'gameid' (codehandleronly does not actually read this).
|
||||||
|
// This value will be read back and modified over time by HLE_Misc::HLEGeckoCodehandler.
|
||||||
PowerPC::HostWrite_U32(MAGIC_GAMEID, INSTALLER_BASE_ADDRESS);
|
PowerPC::HostWrite_U32(MAGIC_GAMEID, INSTALLER_BASE_ADDRESS);
|
||||||
|
|
||||||
// Create GCT in memory
|
// Create GCT in memory
|
||||||
@ -161,7 +160,7 @@ void RunCodeHandler()
|
|||||||
if (s_active_codes.empty())
|
if (s_active_codes.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!s_code_handler_installed || PowerPC::HostRead_U32(INSTALLER_BASE_ADDRESS) - MAGIC_GAMEID > 5)
|
if (!s_code_handler_installed)
|
||||||
{
|
{
|
||||||
s_code_handler_installed = InstallCodeHandlerLocked();
|
s_code_handler_installed = InstallCodeHandlerLocked();
|
||||||
|
|
||||||
@ -175,7 +174,7 @@ void RunCodeHandler()
|
|||||||
// the original return address (which will still be in the link register) at the end.
|
// the original return address (which will still be in the link register) at the end.
|
||||||
if (PC == LR)
|
if (PC == LR)
|
||||||
{
|
{
|
||||||
PC = NPC = INSTALLER_BASE_ADDRESS + 0xA8;
|
PC = NPC = ENTRY_POINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,20 @@ public:
|
|||||||
bool Exist(u32 address, u32 data) const;
|
bool Exist(u32 address, u32 data) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Installation address for codehandler.bin in the Game's RAM
|
||||||
|
constexpr u32 INSTALLER_BASE_ADDRESS = 0x80001800;
|
||||||
|
constexpr u32 ENTRY_POINT = 0x800018A8;
|
||||||
|
|
||||||
|
// This forms part of a communication protocol with HLE_Misc::HLEGeckoCodehandler.
|
||||||
|
// Basically, codehandleronly.s doesn't use ICBI like it's supposed to when patching the
|
||||||
|
// game's code. This results in the JIT happily ignoring all code patches for blocks that
|
||||||
|
// are already compiled. The hack for getting around that is that the first 5 frames after
|
||||||
|
// the handler is installed (0xD01F1BAD -> +5 -> 0xD01F1BB2) cause full ICache resets.
|
||||||
|
//
|
||||||
|
// HLEGeckoCodehandler will increment this value 5 times then cease flushing the ICache to
|
||||||
|
// preserve the emulation performance.
|
||||||
|
constexpr u32 MAGIC_GAMEID = 0xD01F1BAD;
|
||||||
|
|
||||||
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
|
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
|
||||||
void RunCodeHandler();
|
void RunCodeHandler();
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/HLE/HLE_Misc.h"
|
#include "Core/HLE/HLE_Misc.h"
|
||||||
#include "Core/HW/CPU.h"
|
#include "Core/HW/CPU.h"
|
||||||
#include "Core/Host.h"
|
#include "Core/Host.h"
|
||||||
@ -47,17 +48,17 @@ void HLEGeckoCodehandler()
|
|||||||
// been read into memory, or such, so we do the first 5 frames. More
|
// been read into memory, or such, so we do the first 5 frames. More
|
||||||
// robust alternative would be to actually detect memory writes, but that
|
// robust alternative would be to actually detect memory writes, but that
|
||||||
// would be even uglier.)
|
// would be even uglier.)
|
||||||
u32 magic = 0xd01f1bad;
|
u32 gch_gameid = PowerPC::HostRead_U32(Gecko::INSTALLER_BASE_ADDRESS);
|
||||||
u32 existing = PowerPC::HostRead_U32(0x80001800);
|
if (gch_gameid - Gecko::MAGIC_GAMEID == 5)
|
||||||
if (existing - magic == 5)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (existing - magic > 5)
|
else if (gch_gameid - Gecko::MAGIC_GAMEID > 5)
|
||||||
{
|
{
|
||||||
existing = magic;
|
gch_gameid = Gecko::MAGIC_GAMEID;
|
||||||
}
|
}
|
||||||
PowerPC::HostWrite_U32(existing + 1, 0x80001800);
|
PowerPC::HostWrite_U32(gch_gameid + 1, Gecko::INSTALLER_BASE_ADDRESS);
|
||||||
|
|
||||||
PowerPC::ppcState.iCache.Reset();
|
PowerPC::ppcState.iCache.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user