summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorcomex <comexk@gmail.com>2013-09-13 18:18:51 -0400
committercomex <comexk@gmail.com>2013-09-13 18:18:51 -0400
commit0040e662823ec2b7ae97d0e8ea2fff715d30283f (patch)
tree06b4803b77d256c67cd3410a7cc9a39157d83585 /Source
parent7a15159c3479724bef43d8dc43e47c21392c2df7 (diff)
parente15e30602c5c30c4f667278ca114e37747473f6c (diff)
Merge branch 'geckoos-fix'
Fixes issue 6551.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/Src/Boot/Boot.cpp21
-rw-r--r--Source/Core/Core/Src/GeckoCode.cpp10
-rw-r--r--Source/Core/Core/Src/HLE/HLE.cpp1
-rw-r--r--Source/Core/Core/Src/HLE/HLE_Misc.cpp23
-rw-r--r--Source/Core/Core/Src/HLE/HLE_Misc.h1
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp17
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp30
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp12
8 files changed, 83 insertions, 32 deletions
diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp
index 6f8f67bf11..f35c24c594 100644
--- a/Source/Core/Core/Src/Boot/Boot.cpp
+++ b/Source/Core/Core/Src/Boot/Boot.cpp
@@ -184,14 +184,6 @@ bool CBoot::BootUp()
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
- // 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);
switch (_StartupPara.m_BootType)
@@ -415,6 +407,19 @@ bool CBoot::BootUp()
return false;
}
}
+
+ // 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);
+ }
+
+ // Not part of the binary itself, but either we or Gecko OS might insert
+ // this, and it doesn't clear the icache properly.
+ HLE::Patch(0x800018a8, "GeckoCodehandler");
+
Host_UpdateLogDisplay();
return true;
}
diff --git a/Source/Core/Core/Src/GeckoCode.cpp b/Source/Core/Core/Src/GeckoCode.cpp
index 252e758746..f8359e1bc5 100644
--- a/Source/Core/Core/Src/GeckoCode.cpp
+++ b/Source/Core/Core/Src/GeckoCode.cpp
@@ -154,8 +154,9 @@ bool InstallCodeHandler()
// Turn off Pause on start
Memory::Write_U32(0, 0x80002774);
- // Write the Game ID into the location expected by WiiRD
- Memory::WriteBigEData(Memory::GetPointer(0x80000000), 0x80001800, 6);
+ // Write a magic value to 'gameid' (codehandleronly does not actually read this).
+ // For the purpose of this, see HLEGeckoCodehandler.
+ Memory::Write_U32(0xd01f1bad, 0x80001800);
// Create GCT in memory
Memory::Write_U32(0x00d0c0de, codelist_location);
@@ -279,10 +280,7 @@ void RunCodeHandler()
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats && active_codes.size() > 0)
{
- u8 *gameId = Memory::GetPointer(0x80000000);
- u8 *wiirdId = Memory::GetPointer(0x80001800);
-
- if (!code_handler_installed || memcmp(gameId, wiirdId, 6))
+ if (!code_handler_installed || Memory::Read_U32(0x80001800) - 0xd01f1bad > 5)
code_handler_installed = InstallCodeHandler();
if (code_handler_installed)
diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp
index 6469359a31..3d3d8d6052 100644
--- a/Source/Core/Core/Src/HLE/HLE.cpp
+++ b/Source/Core/Core/Src/HLE/HLE.cpp
@@ -63,6 +63,7 @@ static const SPatch OSPatches[] =
{ "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used for early init things (normally)
{ "___blank", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "__write_console", HLE_OS::HLE_write_console, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used by sysmenu (+more?)
+ { "GeckoCodehandler", HLE_Misc::HLEGeckoCodehandler, HLE_HOOK_START, HLE_TYPE_GENERIC },
};
static const SPatch OSBreakPoints[] =
diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp
index 0b5db4f17f..fa5f8c7d61 100644
--- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp
+++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp
@@ -17,6 +17,7 @@
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "HLE.h"
#include "PowerPC/PPCAnalyst.h"
+#include "PowerPC/PPCCache.h"
#include "PowerPC/SignatureDB.h"
#include "PowerPC/PPCSymbolDB.h"
#include "CommonPaths.h"
@@ -242,4 +243,26 @@ void OSBootDol()
NPC = PC;
}
+void HLEGeckoCodehandler()
+{
+ // Work around the codehandler not properly invalidating the icache, but
+ // only the first few frames.
+ // (Project M uses a conditional to only apply patches after something has
+ // 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
+ // would be even uglier.)
+ u32 magic = 0xd01f1bad;
+ u32 existing = Memory::Read_U32(0x80001800);
+ if (existing - magic == 5)
+ {
+ return;
+ }
+ else if(existing - magic > 5)
+ {
+ existing = magic;
+ }
+ Memory::Write_U32(existing + 1, 0x80001800);
+ PowerPC::ppcState.iCache.Reset();
+}
+
}
diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.h b/Source/Core/Core/Src/HLE/HLE_Misc.h
index 43924a4dcf..bc3acd143f 100644
--- a/Source/Core/Core/Src/HLE/HLE_Misc.h
+++ b/Source/Core/Core/Src/HLE/HLE_Misc.h
@@ -12,6 +12,7 @@ namespace HLE_Misc
void HBReload();
void OSBootDol();
void OSGetResetCode();
+ void HLEGeckoCodehandler();
}
#endif
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
index 9e52b70e5a..31baf28abb 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -150,6 +150,12 @@ void Reset(bool _bHard)
g_FdMap[i] = NULL;
}
+ u32 j;
+ for (j=0; j<ES_MAX_COUNT; j++)
+ {
+ es_inuse[j] = false;
+ }
+
TDeviceMap::iterator itr = g_DeviceMap.begin();
while (itr != g_DeviceMap.end())
{
@@ -548,17 +554,6 @@ void ExecuteCommand(u32 _Address)
// Generate a reply to the IPC command
EnqReply(_Address, reply_delay);
}
- else
- {
- if (pDevice)
- {
- INFO_LOG(WII_IPC_HLE, "<<-- Reply Failed to %s IPC Request %i @ 0x%08x ", pDevice->GetDeviceName().c_str(), Command, _Address);
- }
- else
- {
- INFO_LOG(WII_IPC_HLE, "<<-- Reply Failed to Unknown (%08x) IPC Request %i @ 0x%08x ", DeviceID, Command, _Address);
- }
- }
}
// Happens AS SOON AS IPC gets a new pointer!
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp
index 754b930053..98e77c7695 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp
@@ -594,13 +594,18 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
ViewCount = FileSize / DiscIO::INANDContentLoader::TICKET_SIZE;
_dbg_assert_msg_(WII_IPC_ES, (ViewCount>0) && (ViewCount<=4), "IOCTL_ES_GETVIEWCNT ticket count seems to be wrong");
}
+ else if (TitleID >> 32 == 0x00000001)
+ {
+ // Fake a ticket view to make IOS reload work.
+ ViewCount = 1;
+ }
else
{
+ ViewCount = 0;
if (TitleID == TITLEID_SYSMENU)
{
PanicAlertT("There must be a ticket for 00000001/00000002. Your NAND dump is probably incomplete.");
}
- ViewCount = 0;
//retVal = ES_NO_TICKET_INSTALLED;
}
}
@@ -651,6 +656,19 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
}
}
}
+ else if (TitleID >> 32 == 0x00000001)
+ {
+ // For IOS titles, the ticket view isn't normally parsed by either the
+ // SDK or libogc, just passed to LaunchTitle, so this
+ // shouldn't matter at all. Just fill out some fields just
+ // to be on the safe side.
+ u32 Address = Buffer.PayloadBuffer[0].m_Address;
+ memset(Memory::GetPointer(Address), 0, 0xD8);
+ Memory::Write_U64(TitleID, Address + 4 + (0x1dc - 0x1d0)); // title ID
+ Memory::Write_U16(0xffff, Address + 4 + (0x1e4 - 0x1d0)); // unnnown
+ Memory::Write_U32(0xff00, Address + 4 + (0x1ec - 0x1d0)); // access mask
+ memset(Memory::GetPointer(Address + 4 + (0x222 - 0x1d0)), 0xff, 0x20); // content permissions
+ }
else
{
//retVal = ES_NO_TICKET_INSTALLED;
@@ -916,10 +934,11 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
// Lie to mem about loading a different IOS
// someone with an affected game should test
IOSv = TitleID & 0xffff;
+ bSuccess = true;
}
- if (!bSuccess && IOSv >= 30 && IOSv != 0xffff)
+ if (!bSuccess)
{
- PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload an IOS or a title that is not available in your NAND dump\n"
+ PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload a title that is not available in your NAND dump\n"
"TitleID %016llx.\n Dolphin will likely hang now.", TitleID);
}
else
@@ -966,14 +985,13 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_LAUNCH %016llx %08x %016llx %08x %016llx %04x", TitleID,view,ticketid,devicetype,titleid,access);
// IOCTL_ES_LAUNCH 0001000248414341 00000001 0001c0fef3df2cfa 00000000 0001000248414341 ffff
- //We have to handle the reply ourselves as this handle is not valid anymore
-
+ // This is necessary because Reset(true) above deleted this object. Ew.
// It seems that the original hardware overwrites the command after it has been
// executed. We write 8 which is not any valid command, and what IOS does
Memory::Write_U32(8, _CommandAddress);
// IOS seems to write back the command that was responded to
- Memory::Write_U32(6, _CommandAddress + 8);
+ Memory::Write_U32(7, _CommandAddress + 8);
// Generate a reply to the IPC command
WII_IPC_HLE_Interface::EnqReply(_CommandAddress, 0);
diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp
index ca98489fd3..a99eab7cea 100644
--- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp
+++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp
@@ -106,10 +106,20 @@ int Interpreter::SingleStepInner(void)
if (HLE::IsEnabled(flags))
{
HLEFunction(function);
+ if (type == HLE::HLE_HOOK_START)
+ {
+ // Run the original.
+ function = 0;
+ }
+ }
+ else
+ {
+ function = 0;
}
}
}
- else
+
+ if (function == 0)
{
#ifdef USE_GDBSTUB
if (gdb_active() && gdb_bp_x(PC)) {