Merge pull request #4468 from marcan/master
Make the neutered version of HBC work in Dolphin
This commit is contained in:
commit
a3d2dead76
|
@ -381,6 +381,8 @@ bool CBoot::BootUp()
|
|||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
if (dolLoader.IsWii())
|
||||
HID4.SBE = 1;
|
||||
PowerPC::DBATUpdated();
|
||||
PowerPC::IBATUpdated();
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ bool CBoot::IsElfWii(const std::string& filename)
|
|||
u32 HID4_mask = Common::swap32(0xfc1fffff);
|
||||
ElfReader reader(elf.get());
|
||||
|
||||
for (int i = 0; i < reader.GetNumSections(); ++i)
|
||||
for (int i = 0; i < reader.GetNumSegments(); ++i)
|
||||
{
|
||||
if (reader.IsCodeSection(i))
|
||||
if (reader.IsCodeSegment(i))
|
||||
{
|
||||
u32* code = (u32*)reader.GetSectionDataPtr(i);
|
||||
for (u32 j = 0; j < reader.GetSectionSize(i) / sizeof(u32); ++j)
|
||||
u32* code = (u32*)reader.GetSegmentPtr(i);
|
||||
for (u32 j = 0; j < reader.GetSegmentSize(i) / sizeof(u32); ++j)
|
||||
{
|
||||
if ((code[j] & HID4_mask) == HID4_pattern)
|
||||
return true;
|
||||
|
@ -85,6 +85,8 @@ bool CBoot::Boot_ELF(const std::string& filename)
|
|||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
if (IsElfWii(filename))
|
||||
HID4.SBE = 1;
|
||||
PowerPC::DBATUpdated();
|
||||
PowerPC::IBATUpdated();
|
||||
|
||||
|
|
|
@ -109,7 +109,11 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
|||
return false;
|
||||
|
||||
pDolLoader->Load();
|
||||
PC = pDolLoader->GetEntryPoint();
|
||||
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
|
||||
// The state of other CPU registers (like the BAT registers) doesn't matter much
|
||||
// because the realmode code at 0x3400 initializes everything itself anyway.
|
||||
MSR = 0;
|
||||
PC = 0x3400;
|
||||
|
||||
// Pass the "#002 check"
|
||||
// Apploader should write the IOS version and revision to 0x3140, and compare it
|
||||
|
|
|
@ -55,8 +55,9 @@ public:
|
|||
else
|
||||
return nullptr;
|
||||
}
|
||||
bool IsCodeSection(int section) const { return sections[section].sh_type == SHT_PROGBITS; }
|
||||
bool IsCodeSegment(int segment) const { return segments[segment].p_flags & PF_X; }
|
||||
const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); }
|
||||
int GetSegmentSize(int segment) const { return segments[segment].p_filesz; }
|
||||
u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
|
||||
int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
|
||||
SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found
|
||||
|
|
|
@ -533,6 +533,11 @@ void ExecuteCommand(u32 address)
|
|||
{
|
||||
result = device->IOCtl(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(FS_EINVAL, address + 4);
|
||||
result = IWII_IPC_HLE_Device::GetDefaultReply();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IPC_CMD_IOCTLV:
|
||||
|
@ -541,6 +546,11 @@ void ExecuteCommand(u32 address)
|
|||
{
|
||||
result = device->IOCtlV(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
Memory::Write_U32(FS_EINVAL, address + 4);
|
||||
result = IWII_IPC_HLE_Device::GetDefaultReply();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -937,6 +937,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
{
|
||||
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2);
|
||||
bool bSuccess = false;
|
||||
bool bReset = false;
|
||||
u16 IOSv = 0xffff;
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
|
@ -968,13 +969,14 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
if (pDolLoader->IsValid())
|
||||
{
|
||||
pDolLoader->Load(); // TODO: Check why sysmenu does not load the DOL correctly
|
||||
// WADs start with address translation off at the given entry point.
|
||||
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
|
||||
//
|
||||
// The state of other CPU registers (like the BAT registers) doesn't matter much
|
||||
// because the WAD initializes everything itself anyway.
|
||||
// because the realmode code at 0x3400 initializes everything itself anyway.
|
||||
MSR = 0;
|
||||
PC = pDolLoader->GetEntryPoint();
|
||||
PC = 0x3400;
|
||||
bSuccess = true;
|
||||
bReset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1045,7 +1047,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188);
|
||||
|
||||
// TODO: provide correct return code when bSuccess= false
|
||||
// Note: If we just reset the PPC, don't write anything to the command buffer. This
|
||||
// could clobber the DOL we just loaded.
|
||||
if (!bReset)
|
||||
{
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
}
|
||||
|
||||
ERROR_LOG(WII_IPC_ES,
|
||||
"IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x",
|
||||
|
@ -1055,10 +1062,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
|
||||
// This is necessary because Reset(true) above deleted this object. Ew.
|
||||
|
||||
if (!bReset)
|
||||
{
|
||||
// The original hardware overwrites the command type with the async reply type.
|
||||
Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress);
|
||||
// IOS also seems to write back the command that was responded to in the FD field.
|
||||
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
|
||||
}
|
||||
|
||||
// Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
|
||||
// involves restarting IOS; IOS generates two acknowledgements in a row.
|
||||
|
|
|
@ -50,7 +50,7 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtlV(u32 command_address)
|
|||
|
||||
IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 command_address)
|
||||
{
|
||||
IPCCommandResult reply = GetNoReply();
|
||||
IPCCommandResult reply = GetDefaultReply();
|
||||
u32 command = Memory::Read_U32(command_address + 0x0c);
|
||||
u32 buffer_in = Memory::Read_U32(command_address + 0x10);
|
||||
u32 buffer_in_size = Memory::Read_U32(command_address + 0x14);
|
||||
|
|
Loading…
Reference in New Issue