Changed the Gecko code handling to the native code handler. This provides full compatibility with all Gecko codes.
To use the native code handler, place the kenobiwii.bin file into the Sys directory. Dolphin will silently fall-back to the emulated code handler if the file is not there. Fixes issue 4561.
This commit is contained in:
parent
f575c2c3be
commit
69b2d4ddc1
|
@ -126,6 +126,8 @@
|
|||
#define WII_USA_SETTING "setting-usa.txt"
|
||||
#define WII_JAP_SETTING "setting-jpn.txt"
|
||||
|
||||
#define GECKO_CODE_HANDLER "kenobiwii.bin"
|
||||
|
||||
// Subdirs in Sys
|
||||
#define GC_SYS_DIR "GC"
|
||||
#define WII_SYS_DIR "Wii"
|
||||
|
|
|
@ -195,10 +195,13 @@ bool CBoot::BootUp()
|
|||
|
||||
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
|
||||
|
||||
// HLE jump to loader (homebrew)
|
||||
HLE::Patch(0x80001800, "HBReload");
|
||||
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
|
||||
Memory::WriteBigEData(stubstr, 0x80001804, 8);
|
||||
// HLE jump to loader (homebrew). Disabled when Gecko is active as it interferes with the code handler
|
||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||
{
|
||||
HLE::Patch(0x80001800, "HBReload");
|
||||
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
|
||||
Memory::WriteBigEData(stubstr, 0x80001804, 8);
|
||||
}
|
||||
|
||||
g_symbolDB.Clear();
|
||||
VideoInterface::Preset(_StartupPara.bNTSC);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "ConfigManager.h"
|
||||
|
||||
#include "vector"
|
||||
#include "PowerPC/PowerPC.h"
|
||||
#include "CommonPaths.h"
|
||||
|
||||
namespace Gecko
|
||||
{
|
||||
|
@ -40,6 +42,9 @@ static struct
|
|||
// codes execute when counter is 0
|
||||
static int code_execution_counter = 0;
|
||||
|
||||
// Track whether the code handler has been installed
|
||||
static bool code_handler_installed = false;
|
||||
|
||||
// the currently active codes
|
||||
std::vector<GeckoCode> active_codes;
|
||||
|
||||
|
@ -93,6 +98,64 @@ void SetActiveCodes(const std::vector<GeckoCode>& gcodes)
|
|||
}
|
||||
|
||||
inserted_asm_codes.clear();
|
||||
|
||||
code_handler_installed = false;
|
||||
}
|
||||
|
||||
bool InstallCodeHandler()
|
||||
{
|
||||
std::string data;
|
||||
std::string _rCodeHandlerFilename = File::GetSysDirectory() + GECKO_CODE_HANDLER;
|
||||
if (!File::ReadFileToString(false, _rCodeHandlerFilename.c_str(), data))
|
||||
return false;
|
||||
|
||||
// Install code handler
|
||||
Memory::WriteBigEData((const u8*)data.data(), 0x80001800, data.length());
|
||||
|
||||
// Turn off Pause on start
|
||||
Memory::Write_U32(0, 0x80001808);
|
||||
|
||||
// Write the Game ID into the location expected by WiiRD
|
||||
Memory::WriteBigEData(Memory::GetPointer(0x80000000), 0x80001800, 6);
|
||||
|
||||
// Create GCT in memory
|
||||
Memory::Write_U32(0x00d0c0de, 0x800027d0);
|
||||
Memory::Write_U32(0x00d0c0de, 0x800027d4);
|
||||
|
||||
std::lock_guard<std::mutex> lk(active_codes_lock);
|
||||
|
||||
int i = 0;
|
||||
std::vector<GeckoCode>::iterator
|
||||
gcodes_iter = active_codes.begin(),
|
||||
gcodes_end = active_codes.end();
|
||||
for (; gcodes_iter!=gcodes_end; ++gcodes_iter)
|
||||
{
|
||||
if (gcodes_iter->enabled)
|
||||
{
|
||||
current_code = codes_start = &*gcodes_iter->codes.begin();
|
||||
codes_end = &*gcodes_iter->codes.end();
|
||||
for (; current_code < codes_end; ++current_code)
|
||||
{
|
||||
const GeckoCode::Code& code = *current_code;
|
||||
Memory::Write_U32(code.address, 0x800027d8 + i);
|
||||
Memory::Write_U32(code.data, 0x800027d8 + i + 4);
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory::Write_U32(0xff000000, 0x800027d8 + i);
|
||||
Memory::Write_U32(0x00000000, 0x800027d8 + i + 4);
|
||||
|
||||
// Turn on codes
|
||||
Memory::Write_U8(1, 0x80001807);
|
||||
|
||||
// Invalidate the icache
|
||||
for (int i = 0; i < data.length(); i += 32)
|
||||
{
|
||||
PowerPC::ppcState.iCache.Invalidate(0x80001800 + i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunGeckoCode(GeckoCode& gecko_code)
|
||||
|
@ -168,6 +231,41 @@ bool RunActiveCodes()
|
|||
return true;
|
||||
}
|
||||
|
||||
void RunCodeHandler()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||
{
|
||||
if (!code_handler_installed)
|
||||
code_handler_installed = InstallCodeHandler();
|
||||
|
||||
if (code_handler_installed)
|
||||
{
|
||||
if (PC == LR)
|
||||
{
|
||||
u32 oldLR = LR;
|
||||
PowerPC::CoreMode oldMode = PowerPC::GetMode();
|
||||
|
||||
PC = 0x800018A8;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the emulated code handler
|
||||
Gecko::RunActiveCodes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes() {
|
||||
return inserted_asm_codes;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace Gecko
|
|||
|
||||
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
|
||||
bool RunActiveCodes();
|
||||
void RunCodeHandler();
|
||||
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes();
|
||||
|
||||
} // namespace Gecko
|
||||
|
|
|
@ -210,13 +210,14 @@ void ApplyPatches(const std::vector<Patch> &patches)
|
|||
void ApplyFramePatches()
|
||||
{
|
||||
ApplyPatches(onFrame);
|
||||
|
||||
// Run the Gecko code handler
|
||||
Gecko::RunCodeHandler();
|
||||
}
|
||||
|
||||
void ApplyARPatches()
|
||||
{
|
||||
ActionReplay::RunAllActive();
|
||||
// w/e this can be changed later
|
||||
Gecko::RunActiveCodes();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -213,6 +213,11 @@ void Shutdown()
|
|||
state = CPU_POWERDOWN;
|
||||
}
|
||||
|
||||
CoreMode GetMode()
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
void SetMode(CoreMode new_mode)
|
||||
{
|
||||
if (new_mode == mode)
|
||||
|
@ -223,7 +228,6 @@ void SetMode(CoreMode new_mode)
|
|||
switch (mode)
|
||||
{
|
||||
case MODE_INTERPRETER: // Switching from JIT to interpreter
|
||||
jit->ClearCache(); // Remove all those nasty JIT patches.
|
||||
cpu_core_base = interpreter;
|
||||
break;
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ void Init(int cpu_core);
|
|||
void Shutdown();
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
CoreMode GetMode();
|
||||
void SetMode(CoreMode _coreType);
|
||||
|
||||
void SingleStep();
|
||||
|
|
Loading…
Reference in New Issue