diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index bae99599e2..6ccfc574be 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -969,10 +969,10 @@ public: } else { - u8 code = v >> 24; + const u8 code = v >> 24; if (code < 64) { - /* ===== sys_spu_thread_send_event ===== */ + /* ===== sys_spu_thread_send_event (used by spu_printf) ===== */ u8 spup = code & 63; @@ -1001,13 +1001,12 @@ public: if (!port.eq) { - // spu_printf fails there LOG_WARNING(Log::SPU, "sys_spu_thread_send_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, (v & 0x00ffffff), data); SPU.In_MBox.PushUncond(CELL_ENOTCONN); // TODO: check error passing return; } - if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)code << 32) | (v & 0x00ffffff), data)) + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) { SPU.In_MBox.PushUncond(CELL_EBUSY); return; @@ -1016,6 +1015,43 @@ public: SPU.In_MBox.PushUncond(CELL_OK); return; } + else if (code < 128) + { + /* ===== sys_spu_thread_throw_event ===== */ + + const u8 spup = code & 63; + + u32 data; + if (!SPU.Out_MBox.Pop(data)) + { + LOG_ERROR(Log::SPU, "sys_spu_thread_throw_event(v=0x%x, spup=%d): Out_MBox is empty", v, spup); + return; + } + + //if (Ini.HLELogging.GetValue()) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data); + } + + EventPort& port = SPUPs[spup]; + + std::lock_guard lock(port.m_mutex); + + if (!port.eq) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x): event queue not connected", spup, (v & 0x00ffffff), data); + return; + } + + // TODO: check passing spup value + if (!port.eq->events.push(SYS_SPU_THREAD_EVENT_USER_KEY, GetCurrentCPUThread()->GetId(), ((u64)spup << 32) | (v & 0x00ffffff), data)) + { + LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x) failed (queue is full)", spup, (v & 0x00ffffff), data); + return; + } + + return; + } else if (code == 128) { /* ===== sys_event_flag_set_bit ===== */ diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 86adba31be..57ddfa1626 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -302,6 +302,15 @@ s32 _sys_printf(u32 arg1) return CELL_OK; } +s32 _unnamed_E75C40F2(u32 dest) +{ + sysPrxForUser->Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest); + + // prx: load some data (0x40 bytes) previously set by sys_process_get_paramsfo + //memset(Memory + dest, 0, 0x40); + return CELL_ENOENT; +} + void sysPrxForUser_init() { REG_FUNC(sysPrxForUser, sys_initialize_tls); @@ -380,6 +389,7 @@ void sysPrxForUser_init() REG_FUNC(sysPrxForUser, _sys_strncat); REG_FUNC(sysPrxForUser, _sys_strcpy); REG_FUNC(sysPrxForUser, _sys_strncpy); + sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown spu_printf_agcb = 0; spu_printf_dgcb = 0; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 0baa1449d1..7fe220130b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -842,6 +842,7 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, m eq->ports.add(&(t->SPUPs[i])); t->SPUPs[i].eq = eq; } + LOG_NOTICE(HLE, "*** spup -> %d", i); spup = (u8)i; }