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:
skidau 2011-12-31 15:18:48 +11:00 committed by calc84maniac
parent f575c2c3be
commit 69b2d4ddc1
7 changed files with 117 additions and 7 deletions

View File

@ -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"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();