mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-24 15:01:16 +01:00
Merge branch 'geckoos-fix'
Fixes issue 6551.
This commit is contained in:
commit
0040e66282
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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[] =
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace HLE_Misc
|
||||
void HBReload();
|
||||
void OSBootDol();
|
||||
void OSGetResetCode();
|
||||
void HLEGeckoCodehandler();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -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!
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user