diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index c104585ebe..13bf6af807 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -25,6 +25,11 @@ public: void Init() { + on_load = nullptr; + on_unload = nullptr; + on_stop = nullptr; + on_error = nullptr; + m_init(); } diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index cde8a38972..9108cbac2e 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -198,6 +198,12 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) CPU.PC = VM_CAST(CPU.LR & ~3) - 4; } + // execute module-specific error check + if ((s64)CPU.GPR[3] < 0 && func->module && func->module->on_error) + { + func->module->on_error(CPU.GPR[3], func); + } + CPU.hle_code = last_code; } else @@ -610,6 +616,11 @@ Module::~Module() void Module::Init() { + on_load = nullptr; + on_unload = nullptr; + on_stop = nullptr; + on_error = nullptr; + m_init(); } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 10203a49bc..4cc7fb4e7c 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -99,6 +99,7 @@ public: std::function on_load; std::function on_unload; std::function on_stop; + std::function on_error; void Init(); void Load(); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 27a6000acc..65146445ce 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1596,6 +1596,41 @@ s32 _cellSyncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr const char* + { + switch (code) + { + case CELL_SYNC_ERROR_AGAIN: return "CELL_SYNC_ERROR_AGAIN"; + case CELL_SYNC_ERROR_INVAL: return "CELL_SYNC_ERROR_INVAL"; + case CELL_SYNC_ERROR_NOSYS: return "CELL_SYNC_ERROR_NOSYS"; + case CELL_SYNC_ERROR_NOMEM: return "CELL_SYNC_ERROR_NOMEM"; + case CELL_SYNC_ERROR_SRCH: return "CELL_SYNC_ERROR_SRCH"; + case CELL_SYNC_ERROR_NOENT: return "CELL_SYNC_ERROR_NOENT"; + case CELL_SYNC_ERROR_NOEXEC: return "CELL_SYNC_ERROR_NOEXEC"; + case CELL_SYNC_ERROR_DEADLK: return "CELL_SYNC_ERROR_DEADLK"; + case CELL_SYNC_ERROR_PERM: return "CELL_SYNC_ERROR_PERM"; + case CELL_SYNC_ERROR_BUSY: return "CELL_SYNC_ERROR_BUSY"; + case CELL_SYNC_ERROR_ABORT: return "CELL_SYNC_ERROR_ABORT"; + case CELL_SYNC_ERROR_FAULT: return "CELL_SYNC_ERROR_FAULT"; + case CELL_SYNC_ERROR_CHILD: return "CELL_SYNC_ERROR_CHILD"; + case CELL_SYNC_ERROR_STAT: return "CELL_SYNC_ERROR_STAT"; + case CELL_SYNC_ERROR_ALIGN: return "CELL_SYNC_ERROR_ALIGN"; + } + + return "???"; + }; + + // analyse error code + if (s32 code = (value & 0xffffff00) == 0x80410100 ? static_cast(value) : 0) + { + cellSync.Error("%s() -> %s (0x%x)", func->name, get_error(code), code); + } + }; + REG_FUNC(cellSync, cellSyncMutexInitialize); REG_FUNC(cellSync, cellSyncMutexLock); REG_FUNC(cellSync, cellSyncMutexTryLock);