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;
|
typedef std::deque<u32> ipc_msg_queue;
|
||||||
static ipc_msg_queue request_queue; // ppc -> arm
|
static ipc_msg_queue request_queue; // ppc -> arm
|
||||||
static ipc_msg_queue reply_queue; // arm -> ppc
|
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_reply;
|
||||||
static int event_enqueue_request;
|
static int event_enqueue_request;
|
||||||
|
|
||||||
static u64 last_reply_time;
|
static u64 last_reply_time;
|
||||||
|
|
||||||
|
static const u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x100000000ULL;
|
||||||
static void EnqueueReplyCallback(u64 userdata, int)
|
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);
|
reply_queue.push_back((u32)userdata);
|
||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
@ -576,6 +584,12 @@ void EnqueueReply_Threadsafe(u32 address, int cycles_in_future)
|
||||||
CoreTiming::ScheduleEvent_Threadsafe(cycles_in_future, event_enqueue_reply, address);
|
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
|
// This is called every IPC_HLE_PERIOD from SystemTimers.cpp
|
||||||
// Takes care of routing ipc <-> ipc HLE
|
// Takes care of routing ipc <-> ipc HLE
|
||||||
void Update()
|
void Update()
|
||||||
|
@ -600,6 +614,14 @@ void Update()
|
||||||
reply_queue.pop_front();
|
reply_queue.pop_front();
|
||||||
return;
|
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()
|
void UpdateDevices()
|
||||||
|
|
|
@ -65,5 +65,6 @@ void ExecuteCommand(u32 _Address);
|
||||||
void EnqueueRequest(u32 address);
|
void EnqueueRequest(u32 address);
|
||||||
void EnqueueReply(u32 address, int cycles_in_future = 0);
|
void EnqueueReply(u32 address, int cycles_in_future = 0);
|
||||||
void EnqueueReply_Threadsafe(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
|
} // end of namespace WII_IPC_HLE_Interface
|
||||||
|
|
|
@ -394,8 +394,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||||
}
|
}
|
||||||
SContentAccess& rContent = itr->second;
|
SContentAccess& rContent = itr->second;
|
||||||
|
|
||||||
_dbg_assert_(WII_IPC_ES, rContent.m_pContent->m_pData != nullptr);
|
|
||||||
|
|
||||||
u8* pDest = Memory::GetPointer(Addr);
|
u8* pDest = Memory::GetPointer(Addr);
|
||||||
|
|
||||||
if (rContent.m_Position + Size > rContent.m_pContent->m_Size)
|
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);
|
u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16);
|
||||||
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
|
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
|
||||||
|
|
||||||
|
std::string tContentFile;
|
||||||
if ((u32)(TitleID>>32) != 0x00000001 || TitleID == TITLEID_SYSMENU)
|
if ((u32)(TitleID>>32) != 0x00000001 || TitleID == TITLEID_SYSMENU)
|
||||||
{
|
{
|
||||||
const DiscIO::INANDContentLoader& ContentLoader = AccessContentDevice(TitleID);
|
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);
|
const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(bootInd);
|
||||||
if (pContent)
|
if (pContent)
|
||||||
{
|
{
|
||||||
LoadWAD(Common::GetTitleContentPath(TitleID));
|
tContentFile = Common::GetTitleContentPath(TitleID);
|
||||||
std::unique_ptr<CDolLoader> pDolLoader;
|
std::unique_ptr<CDolLoader> pDolLoader;
|
||||||
if (pContent->m_pData)
|
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++)
|
for (unsigned int i = 0; i < size; i++)
|
||||||
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
|
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
|
||||||
|
|
||||||
std::string tContentFile(m_ContentFile);
|
|
||||||
|
|
||||||
WII_IPC_HLE_Interface::Reset(true);
|
WII_IPC_HLE_Interface::Reset(true);
|
||||||
WII_IPC_HLE_Interface::Init();
|
WII_IPC_HLE_Interface::Init();
|
||||||
s_Usb = GetUsbPointer();
|
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.
|
// IOS also seems to write back the command that was responded to in the FD field.
|
||||||
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
|
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
|
||||||
|
|
||||||
// Generate a reply to the IPC command
|
// Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(_CommandAddress, 0);
|
// involves restarting IOS; IOS generates two acknowledgements in a row.
|
||||||
|
WII_IPC_HLE_Interface::EnqueueCommandAcknowledgement(_CommandAddress, 0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue