diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 148a6b15eb..7bab6af57a 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -191,6 +191,11 @@ void VFS::SaveLoadDevices(Array& res, bool is_load) res[idx].mount = "/app_home/"; res[idx].device = vfsDevice_LocalFile; + idx = res.Move(new VFSManagerEntry()); + res[idx].path = "$(GameDir)\\..\\"; + res[idx].mount = "/dev_bdvd/"; + res[idx].device = vfsDevice_LocalFile; + idx = res.Move(new VFSManagerEntry()); res[idx].path = ""; res[idx].mount = "/host_root/"; diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index dbd9749677..4e83d11cc7 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -141,10 +141,10 @@ struct Pad , m_device_capability(device_capability) , m_device_type(device_type) - , m_analog_left_x(0) - , m_analog_left_y(0) - , m_analog_right_x(0) - , m_analog_right_y(0) + , m_analog_left_x(128) + , m_analog_left_y(128) + , m_analog_right_x(128) + , m_analog_right_y(128) , m_press_right(0) , m_press_left(0) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 68fb88c772..313b91676f 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -90,6 +90,7 @@ static const g_module_list[] = {0x0050, "cellSpursJq"}, {0x0052, "cellPngEnc"}, {0x0053, "cellMusicDecode2"}, + {0x0054, "cellSync"}, {0x0055, "cellSync2"}, {0x0056, "cellNpUtil"}, {0x0057, "cellRudp"}, diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp new file mode 100644 index 0000000000..60ef2d3249 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -0,0 +1,98 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void cellSync_init(); +Module cellSync(0x0054, cellSync_init); + +// Return Codes +enum +{ + CELL_SYNC_ERROR_AGAIN = 0x80410101, + CELL_SYNC_ERROR_INVAL = 0x80410102, + CELL_SYNC_ERROR_NOMEM = 0x80410104, + CELL_SYNC_ERROR_DEADLK = 0x80410108, + CELL_SYNC_ERROR_PERM = 0x80410109, + CELL_SYNC_ERROR_BUSY = 0x8041010A, + CELL_SYNC_ERROR_STAT = 0x8041010F, + CELL_SYNC_ERROR_ALIGN = 0x80410110, + CELL_SYNC_ERROR_NULL_POINTER = 0x80410111, + CELL_SYNC_ERROR_NOT_SUPPORTED_THREAD = 0x80410112, + CELL_SYNC_ERROR_NO_NOTIFIER = 0x80410113, + CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114, +}; + +int cellSyncMutexInitialize(mem32_t mutex) +{ + const u32 mutex_addr = mutex.GetAddr(); + if (!mutex_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (mutex_addr % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + mutex = 0; + return CELL_OK; +} + +int cellSyncMutexLock(mem32_t mutex) +{ + const u32 mutex_addr = mutex.GetAddr(); + if (!mutex_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (mutex_addr % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + //aggressive spin-wait + while (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)); + _mm_lfence(); + return CELL_OK; +} + +int cellSyncMutexTryLock(mem32_t mutex) +{ + const u32 mutex_addr = mutex.GetAddr(); + if (!mutex_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (mutex_addr % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + if (_InterlockedExchange((volatile long*)(Memory + mutex_addr), 1)) + { + return CELL_SYNC_ERROR_BUSY; + } + _mm_lfence(); + return CELL_OK; +} + +int cellSyncMutexUnlock(mem32_t mutex) +{ + const u32 mutex_addr = mutex.GetAddr(); + if (!mutex_addr) + { + return CELL_SYNC_ERROR_NULL_POINTER; + } + if (mutex_addr % 4) + { + return CELL_SYNC_ERROR_ALIGN; + } + _mm_sfence(); + mutex = 0; + return CELL_OK; +} + +void cellSync_init() +{ + cellSync.AddFunc(0xa9072dee, cellSyncMutexInitialize); + cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock); + cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock); + cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index e015d46fda..8973d05665 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -91,6 +91,12 @@ int sys_spu_image_import(mem_ptr_t img, u32 src, u32 type) return CELL_OK; } +int sys_spu_image_close(mem_ptr_t img) +{ + sysPrxForUser.Warning("sys_spu_image_close(img=0x%x)", img.GetAddr()); + return CELL_OK; +} + int sys_raw_spu_load(int id, u32 path_addr, mem32_t entry) { const wxString path = Memory.ReadString(path_addr).mb_str(); @@ -166,6 +172,7 @@ void sysPrxForUser_init() sysPrxForUser.AddFunc(0x1ed454ce, sys_spu_elf_get_information); sysPrxForUser.AddFunc(0xdb6b3250, sys_spu_elf_get_segments); sysPrxForUser.AddFunc(0xebe5f72f, sys_spu_image_import); + sysPrxForUser.AddFunc(0xe0da8efd, sys_spu_image_close); sysPrxForUser.AddFunc(0x893305fa, sys_raw_spu_load); sysPrxForUser.AddFunc(0xb995662e, sys_raw_spu_image_load); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 959fd93dd1..611d5be4ff 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -95,8 +95,9 @@ static func_caller* sc_table[1024] = null_func, bind_func(sys_spu_image_open), null_func, null_func, null_func, //159 bind_func(sys_raw_spu_create), null_func, null_func, null_func, null_func, //164 null_func, null_func, null_func, null_func, bind_func(sys_spu_initialize), //169 - bind_func(sys_spu_thread_group_create), bind_func(sys_spu_thread_set_argument), bind_func(sys_spu_thread_initialize), bind_func(sys_spu_thread_group_start), null_func, //174 - null_func, null_func, null_func, null_func, null_func, //179 + bind_func(sys_spu_thread_group_create), bind_func(sys_spu_thread_set_argument), bind_func(sys_spu_thread_initialize), //172 + bind_func(sys_spu_thread_group_start), bind_func(sys_spu_thread_group_suspend), //174 + null_func, null_func, null_func, bind_func(sys_spu_thread_group_join), null_func, //179 null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, bind_func(sys_spu_thread_write_snr), //184 null_func, null_func, bind_func(sys_spu_thread_set_spu_cfg), bind_func(sys_spu_thread_get_spu_cfg), null_func, //189 bind_func(sys_spu_thread_write_spu_mb), bind_func(sys_spu_thread_connect_event), null_func, null_func, null_func, //194 diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index f802f7a4b7..8fded44273 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -283,9 +283,11 @@ extern int sys_spu_image_open(mem_ptr_t img, u32 path_addr); extern int sys_spu_thread_initialize(mem32_t thread, u32 group, u32 spu_num, mem_ptr_t img, mem_ptr_t attr, mem_ptr_t arg); extern int sys_spu_thread_set_argument(u32 id, mem_ptr_t arg); extern int sys_spu_thread_group_start(u32 id); +extern int sys_spu_thread_group_suspend(u32 id); extern int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t attr); extern int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr); extern int sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup); +extern int sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status); extern int sys_raw_spu_create(mem32_t id, u32 attr_addr); extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu); extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index a7fb066862..a74f7cfe69 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -4,6 +4,7 @@ #include "Emu/SysCalls/SC_FUNC.h" #include "Loader/ELF.h" #include "Emu/Cell/RawSPUThread.h" +#include static SysCallBase sc_spu("sys_spu"); extern SysCallBase sys_event; @@ -14,8 +15,9 @@ struct SpuGroupInfo { CPUThread* threads[g_spu_group_thr_count]; sys_spu_thread_group_attribute& attr; + volatile long lock; - SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr) + SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr), lock(0) { memset(threads, 0, sizeof(CPUThread*) * g_spu_group_thr_count); } @@ -45,7 +47,7 @@ int sys_spu_image_open(mem_ptr_t img, u32 path_addr) return CELL_EFAULT; } - vfsFile f(path.c_str()); + vfsFile f(path); if(!f.IsOpened()) { sc_spu.Error("sys_spu_image_open error: '%s' not found!", path); @@ -182,6 +184,31 @@ int sys_spu_thread_group_start(u32 id) return CELL_OK; } +//174 +int sys_spu_thread_group_suspend(u32 id) +{ + sc_spu.Warning("sys_spu_thread_group_suspend(id=0x%x)", id); + + if(!Emu.GetIdManager().CheckID(id)) + { + return CELL_ESRCH; + } + + ID& id_data = Emu.GetIdManager().GetIDData(id); + SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data; + + //Emu.Pause(); + for(int i=0; iPause(); + } + } + + return CELL_OK; +} + //170 int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_t attr) { @@ -204,6 +231,39 @@ int sys_spu_thread_group_create(mem32_t id, u32 num, int prio, mem_ptr_tIsStopped()) Sleep(1); + } + } + + _InterlockedExchange(&group_info.lock, 0); //release lock + return CELL_OK; +} + int sys_spu_thread_create(mem32_t thread_id, mem32_t entry, u64 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr) { UNIMPLEMENTED_FUNC(sc_spu); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h index c4f670c28a..9c82c6aee9 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.h @@ -2,6 +2,13 @@ u32 LoadSpuImage(vfsStream& stream); +enum +{ + SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001, + SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT = 0x0002, + SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004 +}; + struct sys_spu_thread_group_attribute { be_t name_len; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 64533cf4a3..9acda133d6 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -1,4 +1,4 @@ - + @@ -276,6 +276,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index d9cf039b7b..69730fd7dc 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -358,6 +358,9 @@ Emu\Audio + + Emu\SysCalls\Modules +