From 94094f99bffbba75e02bcd0c438c46553a3cedda Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 15 Dec 2012 18:06:55 -0800 Subject: [PATCH] Cleanup basic Mbx implementation, create func. --- Core/HLE/FunctionWrappers.h | 5 +++++ Core/HLE/sceKernel.cpp | 2 +- Core/HLE/sceKernelMbx.cpp | 42 +++++++++++++++++++++++++++++-------- Core/HLE/sceKernelMbx.h | 3 +-- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h index dd684e800..2d560cc0b 100644 --- a/Core/HLE/FunctionWrappers.h +++ b/Core/HLE/FunctionWrappers.h @@ -260,6 +260,11 @@ template void WrapI_CU() { RETURN(retval); } +template void WrapI_CUU() { + int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2)); + RETURN(retval); +} + template void WrapI_CUUU() { int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3)); diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index f73383439..2dc021550 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -435,7 +435,7 @@ const HLEFunction ThreadManForUser[] = {0x2A3D44FF,sceKernelGetCallbackCount,"sceKernelGetCallbackCount"}, {0x730ED8BC,sceKernelReferCallbackStatus,"sceKernelReferCallbackStatus"}, - {0x8125221D,&WrapU_CIUIU,"sceKernelCreateMbx"}, + {0x8125221D,&WrapI_CUU,"sceKernelCreateMbx"}, {0x86255ADA,&WrapI_I,"sceKernelDeleteMbx"}, {0xE9B3061E,&WrapV_IU,"sceKernelSendMbx"}, {0x18260574,&WrapV_IUU,"sceKernelReceiveMbx"}, diff --git a/Core/HLE/sceKernelMbx.cpp b/Core/HLE/sceKernelMbx.cpp index ee6073e6a..0bfe1e12c 100644 --- a/Core/HLE/sceKernelMbx.cpp +++ b/Core/HLE/sceKernelMbx.cpp @@ -25,6 +25,8 @@ // TODO: when a thread is being resumed (message received or cancellation), sceKernelReceiveMbx() always returns 0 +typedef std::pair MbxWaitingThread; + struct NativeMbx { SceSize size; @@ -46,7 +48,7 @@ struct Mbx : public KernelObject { if (nmb.attr & SCE_KERNEL_MBA_THPRI) { - for (std::vector >::iterator it = waitingThreads.begin(); it != waitingThreads.end(); it++) + for (std::vector::iterator it = waitingThreads.begin(); it != waitingThreads.end(); it++) { if (__KernelGetThreadPrio(id) >= __KernelGetThreadPrio((*it).first)) { @@ -63,24 +65,41 @@ struct Mbx : public KernelObject NativeMbx nmb; - std::vector > waitingThreads; + std::vector waitingThreads; std::vector messageQueue; }; -SceUID sceKernelCreateMbx(const char *name, int memoryPartition, SceUInt attr, int size, u32 optAddr) +SceUID sceKernelCreateMbx(const char *name, u32 attr, u32 optAddr) { - DEBUG_LOG(HLE, "sceKernelCreateMbx(%s, %i, %08x, %i, %08x)", name, memoryPartition, attr, size, optAddr); + if (!name) + { + WARN_LOG(HLE, "%08x=%s(): invalid name", SCE_KERNEL_ERROR_ERROR, __FUNCTION__); + return SCE_KERNEL_ERROR_ERROR; + } + if (attr >= 0x300) + { + WARN_LOG(HLE, "%08x=%s(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, __FUNCTION__, attr); + return SCE_KERNEL_ERROR_ILLEGAL_ATTR; + } Mbx *m = new Mbx(); SceUID id = kernelObjects.Create(m); m->nmb.size = sizeof(NativeMbx); - strncpy(m->nmb.name, name, sizeof(m->nmb.name)); + strncpy(m->nmb.name, name, 31); + m->nmb.name[31] = 0; m->nmb.attr = attr; m->nmb.numWaitThreads = 0; m->nmb.numMessages = 0; m->nmb.packetListHead = 0; + DEBUG_LOG(HLE, "%i=sceKernelCreateMbx(%s, %08x, %08x)", id, name, attr, optAddr); + + if (optAddr != 0) + WARN_LOG(HLE, "%s(%s) unsupported options parameter: %08x", __FUNCTION__, name, optAddr); + if ((attr & ~SCE_KERNEL_MBA_THPRI) != 0) + WARN_LOG(HLE, "%s(%s) unsupported attr parameter: %08x", __FUNCTION__, name, attr); + return id; } @@ -94,8 +113,12 @@ int sceKernelDeleteMbx(SceUID id) for (size_t i = 0; i < m->waitingThreads.size(); i++) { Memory::Write_U32(0, m->waitingThreads[i].second); - __KernelResumeThreadFromWait(m->waitingThreads[i].first); + __KernelResumeThreadFromWait(m->waitingThreads[i].first, SCE_KERNEL_ERROR_WAIT_DELETE); } + + if (!m->waitingThreads.empty()) + hleReSchedule("mbx deleted"); + m->waitingThreads.clear(); } else { @@ -184,7 +207,7 @@ void sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) DEBUG_LOG(HLE, "sceKernelReceiveMbx(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, false); // ? + __KernelWaitCurThread(WAITTYPE_MBX, id, 0, 0, false); } } @@ -211,9 +234,9 @@ void sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr) else { DEBUG_LOG(HLE, "sceKernelReceiveMbxCB(%i, %08x, %08x): no message in queue, waiting", id, packetAddrPtr, timeoutPtr); - m->AddWaitingThread(id, packetAddrPtr); + m->AddWaitingThread(__KernelGetCurThread(), packetAddrPtr); RETURN(0); - __KernelWaitCurThread(WAITTYPE_MBX, 0, 0, 0, true); // ? + __KernelWaitCurThread(WAITTYPE_MBX, id, 0, 0, true); } } @@ -281,6 +304,7 @@ int sceKernelReferMbxStatus(SceUID id, u32 infoAddr) DEBUG_LOG(HLE, "sceKernelReferMbxStatus(%i, %08x)", id, infoAddr); if (info) { + info->size = m->nmb.size; strncpy(info->name, m->nmb.name, 32); info->attr = m->nmb.attr; info->numWaitThreads = m->waitingThreads.size(); diff --git a/Core/HLE/sceKernelMbx.h b/Core/HLE/sceKernelMbx.h index e841dcb6d..05257b101 100644 --- a/Core/HLE/sceKernelMbx.h +++ b/Core/HLE/sceKernelMbx.h @@ -34,7 +34,7 @@ struct SceKernelMbxInfo u32 topPacketAddr; }; -SceUID sceKernelCreateMbx(const char *name, int memoryPartition, SceUInt attr, int size, u32 optAddr); +SceUID sceKernelCreateMbx(const char *name, u32 attr, u32 optAddr); int sceKernelDeleteMbx(SceUID id); void sceKernelSendMbx(SceUID id, u32 addPacketAddr); void sceKernelReceiveMbx(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); @@ -42,4 +42,3 @@ void sceKernelReceiveMbxCB(SceUID id, u32 packetAddrPtr, u32 timeoutPtr); int sceKernelPollMbx(SceUID id, u32 packetAddrPtr); int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr); int sceKernelReferMbxStatus(SceUID id, u32 infoAddr); -