IPCHLE: Fix ES_LAUNCH so it works for disk titles.
Among other things, this makes the Disk Channel fully functional.
This commit is contained in:
parent
7416b9cdb4
commit
f9b72d0891
|
@ -76,14 +76,22 @@ IWII_IPC_HLE_Device* es_handles[ES_MAX_COUNT];
|
|||
typedef std::deque<u32> ipc_msg_queue;
|
||||
static ipc_msg_queue request_queue; // ppc -> arm
|
||||
static ipc_msg_queue reply_queue; // arm -> ppc
|
||||
static ipc_msg_queue ack_queue; // arm -> ppc
|
||||
|
||||
static int event_enqueue_reply;
|
||||
static int event_enqueue_request;
|
||||
|
||||
static u64 last_reply_time;
|
||||
|
||||
static const u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x100000000ULL;
|
||||
static void EnqueueReplyCallback(u64 userdata, int)
|
||||
{
|
||||
if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG)
|
||||
{
|
||||
ack_queue.push_back((u32)userdata);
|
||||
Update();
|
||||
return;
|
||||
}
|
||||
reply_queue.push_back((u32)userdata);
|
||||
Update();
|
||||
}
|
||||
|
@ -576,6 +584,12 @@ void EnqueueReply_Threadsafe(u32 address, int cycles_in_future)
|
|||
CoreTiming::ScheduleEvent_Threadsafe(cycles_in_future, event_enqueue_reply, address);
|
||||
}
|
||||
|
||||
void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future)
|
||||
{
|
||||
CoreTiming::ScheduleEvent(cycles_in_future, event_enqueue_reply,
|
||||
address | ENQUEUE_ACKNOWLEDGEMENT_FLAG);
|
||||
}
|
||||
|
||||
// This is called every IPC_HLE_PERIOD from SystemTimers.cpp
|
||||
// Takes care of routing ipc <-> ipc HLE
|
||||
void Update()
|
||||
|
@ -600,6 +614,14 @@ void Update()
|
|||
reply_queue.pop_front();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ack_queue.size())
|
||||
{
|
||||
WII_IPCInterface::GenerateAck(ack_queue.front());
|
||||
WARN_LOG(WII_IPC_HLE, "<<-- Double-ack to IPC Request @ 0x%08x", ack_queue.front());
|
||||
ack_queue.pop_front();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateDevices()
|
||||
|
|
|
@ -65,5 +65,6 @@ void ExecuteCommand(u32 _Address);
|
|||
void EnqueueRequest(u32 address);
|
||||
void EnqueueReply(u32 address, int cycles_in_future = 0);
|
||||
void EnqueueReply_Threadsafe(u32 address, int cycles_in_future = 0);
|
||||
void EnqueueCommandAcknowledgement(u32 _Address, int cycles_in_future = 0);
|
||||
|
||||
} // end of namespace WII_IPC_HLE_Interface
|
||||
|
|
|
@ -394,8 +394,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
}
|
||||
SContentAccess& rContent = itr->second;
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, rContent.m_pContent->m_pData != nullptr);
|
||||
|
||||
u8* pDest = Memory::GetPointer(Addr);
|
||||
|
||||
if (rContent.m_Position + Size > rContent.m_pContent->m_Size)
|
||||
|
@ -905,7 +903,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16);
|
||||
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
|
||||
|
||||
|
||||
std::string tContentFile;
|
||||
if ((u32)(TitleID>>32) != 0x00000001 || TitleID == TITLEID_SYSMENU)
|
||||
{
|
||||
const DiscIO::INANDContentLoader& ContentLoader = AccessContentDevice(TitleID);
|
||||
|
@ -915,7 +913,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(bootInd);
|
||||
if (pContent)
|
||||
{
|
||||
LoadWAD(Common::GetTitleContentPath(TitleID));
|
||||
tContentFile = Common::GetTitleContentPath(TitleID);
|
||||
std::unique_ptr<CDolLoader> pDolLoader;
|
||||
if (pContent->m_pData)
|
||||
{
|
||||
|
@ -954,8 +952,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
|||
for (unsigned int i = 0; i < size; i++)
|
||||
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
|
||||
|
||||
std::string tContentFile(m_ContentFile);
|
||||
|
||||
WII_IPC_HLE_Interface::Reset(true);
|
||||
WII_IPC_HLE_Interface::Init();
|
||||
s_Usb = GetUsbPointer();
|
||||
|
@ -997,9 +993,9 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _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
|
||||
WII_IPC_HLE_Interface::EnqueueReply(_CommandAddress, 0);
|
||||
|
||||
// Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
|
||||
// involves restarting IOS; IOS generates two acknowledgements in a row.
|
||||
WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(_CommandAddress, 0);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue