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_USA_SETTING "setting-usa.txt"
|
||||||
#define WII_JAP_SETTING "setting-jpn.txt"
|
#define WII_JAP_SETTING "setting-jpn.txt"
|
||||||
|
|
||||||
|
#define GECKO_CODE_HANDLER "kenobiwii.bin"
|
||||||
|
|
||||||
// Subdirs in Sys
|
// Subdirs in Sys
|
||||||
#define GC_SYS_DIR "GC"
|
#define GC_SYS_DIR "GC"
|
||||||
#define WII_SYS_DIR "Wii"
|
#define WII_SYS_DIR "Wii"
|
||||||
|
|
|
@ -195,10 +195,13 @@ bool CBoot::BootUp()
|
||||||
|
|
||||||
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
|
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
|
||||||
|
|
||||||
// HLE jump to loader (homebrew)
|
// HLE jump to loader (homebrew). Disabled when Gecko is active as it interferes with the code handler
|
||||||
HLE::Patch(0x80001800, "HBReload");
|
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||||
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
|
{
|
||||||
Memory::WriteBigEData(stubstr, 0x80001804, 8);
|
HLE::Patch(0x80001800, "HBReload");
|
||||||
|
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
|
||||||
|
Memory::WriteBigEData(stubstr, 0x80001804, 8);
|
||||||
|
}
|
||||||
|
|
||||||
g_symbolDB.Clear();
|
g_symbolDB.Clear();
|
||||||
VideoInterface::Preset(_StartupPara.bNTSC);
|
VideoInterface::Preset(_StartupPara.bNTSC);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "ConfigManager.h"
|
#include "ConfigManager.h"
|
||||||
|
|
||||||
#include "vector"
|
#include "vector"
|
||||||
|
#include "PowerPC/PowerPC.h"
|
||||||
|
#include "CommonPaths.h"
|
||||||
|
|
||||||
namespace Gecko
|
namespace Gecko
|
||||||
{
|
{
|
||||||
|
@ -40,6 +42,9 @@ static struct
|
||||||
// codes execute when counter is 0
|
// codes execute when counter is 0
|
||||||
static int code_execution_counter = 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
|
// the currently active codes
|
||||||
std::vector<GeckoCode> active_codes;
|
std::vector<GeckoCode> active_codes;
|
||||||
|
|
||||||
|
@ -93,6 +98,64 @@ void SetActiveCodes(const std::vector<GeckoCode>& gcodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
inserted_asm_codes.clear();
|
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)
|
bool RunGeckoCode(GeckoCode& gecko_code)
|
||||||
|
@ -168,6 +231,41 @@ bool RunActiveCodes()
|
||||||
return true;
|
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() {
|
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes() {
|
||||||
return inserted_asm_codes;
|
return inserted_asm_codes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ namespace Gecko
|
||||||
|
|
||||||
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
|
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
|
||||||
bool RunActiveCodes();
|
bool RunActiveCodes();
|
||||||
|
void RunCodeHandler();
|
||||||
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes();
|
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes();
|
||||||
|
|
||||||
} // namespace Gecko
|
} // namespace Gecko
|
||||||
|
|
|
@ -210,13 +210,14 @@ void ApplyPatches(const std::vector<Patch> &patches)
|
||||||
void ApplyFramePatches()
|
void ApplyFramePatches()
|
||||||
{
|
{
|
||||||
ApplyPatches(onFrame);
|
ApplyPatches(onFrame);
|
||||||
|
|
||||||
|
// Run the Gecko code handler
|
||||||
|
Gecko::RunCodeHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyARPatches()
|
void ApplyARPatches()
|
||||||
{
|
{
|
||||||
ActionReplay::RunAllActive();
|
ActionReplay::RunAllActive();
|
||||||
// w/e this can be changed later
|
|
||||||
Gecko::RunActiveCodes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -213,6 +213,11 @@ void Shutdown()
|
||||||
state = CPU_POWERDOWN;
|
state = CPU_POWERDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreMode GetMode()
|
||||||
|
{
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
void SetMode(CoreMode new_mode)
|
void SetMode(CoreMode new_mode)
|
||||||
{
|
{
|
||||||
if (new_mode == mode)
|
if (new_mode == mode)
|
||||||
|
@ -223,7 +228,6 @@ void SetMode(CoreMode new_mode)
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case MODE_INTERPRETER: // Switching from JIT to interpreter
|
case MODE_INTERPRETER: // Switching from JIT to interpreter
|
||||||
jit->ClearCache(); // Remove all those nasty JIT patches.
|
|
||||||
cpu_core_base = interpreter;
|
cpu_core_base = interpreter;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ void Init(int cpu_core);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
|
|
||||||
|
CoreMode GetMode();
|
||||||
void SetMode(CoreMode _coreType);
|
void SetMode(CoreMode _coreType);
|
||||||
|
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
|
|
Loading…
Reference in New Issue