diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 8f2e11ba1d..b6dd47706a 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -71,10 +71,16 @@ private: if(Ini.HLELogging.GetValue()) { - ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); + ConLog.Warning("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); if(CPU.GPR[11] > 1024) SysCalls::DoFunc(CPU.GPR[11]); } + /*else if ((s64)CPU.GPR[3] < 0) // probably, error code + { + ConLog.Error("SysCall[0x%llx] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); + if(CPU.GPR[11] > 1024) + SysCalls::DoFunc(CPU.GPR[11]); + }*/ #ifdef HLE_CALL_DEBUG ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC); #endif @@ -2088,6 +2094,11 @@ private: { case 0x1: UNK(wxString::Format("HyperCall %d", CPU.GPR[0])); break; case 0x2: SysCall(); break; + case 0x3: + StaticExecute(CPU.GPR[11]); + ConLog.Write("'%s' done with code[0x%llx]! #pc: 0x%llx", + wxString(g_static_funcs_list[CPU.GPR[11]].name).wx_str(), CPU.GPR[3], CPU.PC); + break; case 0x22: UNK("HyperCall LV1"); break; default: UNK(wxString::Format("Unknown sc: %x", sc_code)); } diff --git a/rpcs3/Emu/SysCalls/Callback.cpp b/rpcs3/Emu/SysCalls/Callback.cpp index f64851b6c3..73e7896744 100644 --- a/rpcs3/Emu/SysCalls/Callback.cpp +++ b/rpcs3/Emu/SysCalls/Callback.cpp @@ -53,7 +53,7 @@ void Callback::Branch(bool wait) { m_has_data = false; - static SMutexGeneral cb_mutex; + static std::mutex cb_mutex; CPUThread& thr = Emu.GetCallbackThread(); @@ -69,7 +69,7 @@ again: Sleep(1); } - SMutexGeneralLocker lock(cb_mutex); + std::lock_guard lock(cb_mutex); if (thr.IsAlive()) { diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index bdecfc62b8..07404f49ad 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -8,6 +8,7 @@ uint g_max_module_id = 0; uint g_module_2_count = 0; ArrayF g_modules_funcs_list; std::mutex g_funcs_lock; +ArrayF g_static_funcs_list; struct ModuleInfo { diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index faef27d9b7..165f59a49d 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -25,6 +25,21 @@ struct ModuleFunc } }; +struct SFuncOp +{ + u32 crc; + u32 mask; +}; + +struct SFunc +{ + func_caller* func; + char* name; + Array ops; +}; + +extern ArrayF g_static_funcs_list; + class Module { std::string m_name; @@ -94,6 +109,8 @@ public: } template __forceinline void AddFunc(u32 id, T func); + + template __forceinline void AddFuncSub(const u64 ops[], char* name, T func); }; template @@ -102,6 +119,29 @@ __forceinline void Module::AddFunc(u32 id, T func) m_funcs_list.Move(new ModuleFunc(id, bind_func(func))); } +template +__forceinline void Module::AddFuncSub(const u64 ops[], char* name, T func) +{ + if (!ops[0]) return; + + SFunc* sf = new SFunc; + sf->func = bind_func(func); + sf->name = name; + + // TODO: check for self-inclusions, use CRC + + for (u32 i = 0; ops[i]; i++) + { + SFuncOp op; + op.mask = ops[i] >> 32; + op.crc = ops[i] & op.mask; + op.mask = re(op.mask); + op.crc = re(op.crc); + sf->ops.AddCpy(op); + } + g_static_funcs_list.Add(sf); +} + bool IsLoadedFunc(u32 id); bool CallFunc(u32 num); bool UnloadFunc(u32 id); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 8c5915d6ff..dc2f7789d5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -4,9 +4,8 @@ #include "Emu/Audio/cellAudio.h" void cellAudio_init(); -void cellAudio_load(); void cellAudio_unload(); -Module cellAudio(0x0011, cellAudio_init, cellAudio_load, cellAudio_unload); +Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload); extern u64 get_system_time(); @@ -135,7 +134,7 @@ struct CellAudioPortConfig struct AudioPortConfig { - SMutex m_mutex; + SMutexGeneral m_mutex; bool m_is_audio_port_opened; bool m_is_audio_port_started; u8 channel; @@ -179,64 +178,6 @@ struct AudioConfig //custom structure } } m_config; -//libmixer datatypes -typedef void * CellAANHandle; - -struct CellSSPlayerConfig -{ - be_t channels; - be_t outputMode; -}; - -struct CellSSPlayerWaveParam -{ - void *addr; - be_t format; - be_t samples; - be_t loopStartOffset; - be_t startOffset; -}; - -struct CellSSPlayerCommonParam -{ - be_t loopMode; - be_t attackMode; -}; - -struct CellSurMixerPosition -{ - be_t x; - be_t y; - be_t z; -}; - -struct CellSSPlayerRuntimeInfo -{ - be_t level; - be_t speed; - CellSurMixerPosition position; -}; - -struct CellSurMixerConfig -{ - be_t priority; - be_t chStrips1; - be_t chStrips2; - be_t chStrips6; - be_t chStrips8; -}; - -struct CellSurMixerChStripParam -{ - be_t param; - void *attribute; - be_t dBSwitch; - be_t floatVal; - be_t intVal; -}; - -CellSSPlayerWaveParam current_SSPlayerWaveParam; - //libsnd3 datatypes struct CellSnd3DataCtx { @@ -368,7 +309,7 @@ int cellAudioInit() memset(Memory + buf_addr, 0, block_size * sizeof(float)); { - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); port.counter = m_config.counter; port.tag++; // absolute index of block that will be read index = (position + 1) % port.block; // write new value @@ -621,7 +562,7 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) AudioPortConfig& port = m_config.m_ports[portNum]; - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); stamp = m_config.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000; @@ -655,7 +596,7 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag) return CELL_AUDIO_ERROR_PARAM; } - SMutexLocker lock(port.m_mutex); + SMutexGeneralLocker lock(port.m_mutex); u64 tag_base = port.tag; if (tag_base % port.block > blockNo) @@ -796,168 +737,6 @@ int cellAudioUnsetPersonalDevice(int iPersonalStream) return CELL_OK; } - -//Callback Functions -typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. - -// libmixer Functions, NOT active in this moment -int cellAANConnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellAANDisconnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellAANAddData(CellAANHandle handle, u32 port, u32 offset, float *addr, u32 samples) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerRemove(CellAANHandle handle) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerStop() //CellAANHandle handle, u32 mode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSSPlayerGetState() //CellAANHandle handle -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerCreate() //const CellSurMixerConfig *config -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetAANHandle() //CellAANHandle *handle -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerChStripGetAANPortNo() //u32 *port, u32 type, u32 index -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSetNotifyCallback() //CellSurMixerNotifyCallbackFunction callback, void *arg -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerRemoveNotifyCallback() //CellSurMixerNotifyCallbackFunction callback -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerStart() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerSetParameter() //u32 param, float value -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerPause() //u32 switch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetCurrentBlockTag() //u64 *tag -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSurMixerBeep(); //void *arg - -float cellSurMixerUtilGetLevelFromDB() //float dB -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO; -} - -float cellSurMixerUtilGetLevelFromDBIndex() //int index -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO; -} - -float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -int cellSurMixerFinalize(); //Currently unused. Returns 0 (in the current release). - //*libsnd3 Functions, NOT active in this moment s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue { @@ -1399,14 +1178,7 @@ void cellAudio_init() //TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions } -void cellAudio_load() -{ - m_config.m_is_audio_initialized = false; - m_config.Clear(); -} - void cellAudio_unload() { - m_config.m_is_audio_initialized = false; - m_config.Clear(); + //StaticFinalize(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 29f3d83424..a664683a29 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -52,6 +52,9 @@ u32 dmuxOpen(Demuxer* data) u32 cb_add = 0; + u32 updates_count = 0; + u32 updates_signaled = 0; + while (true) { if (Emu.IsStopped()) @@ -68,9 +71,17 @@ u32 dmuxOpen(Demuxer* data) if (!stream.peek(code)) { + dmux.is_running = false; // demuxing finished - task.type = dmuxResetStream; - goto task; + mem_ptr_t dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16)); + dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; + dmuxMsg->supplementalInfo = stream.userdata; + /*Callback cb; + cb.SetAddr(dmux.cbFunc); + cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ + dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, true, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; } else switch (code.ToLE()) { @@ -125,11 +136,14 @@ u32 dmuxOpen(Demuxer* data) if (esATX[ch]) { ElementaryStream& es = *esATX[ch]; - if (es.isfull()) + while (es.isfull()) { - stream = backup; + if (Emu.IsStopped()) + { + ConLog.Warning("esATX[%d] was full, waiting aborted", ch); + return; + } Sleep(1); - continue; } //ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts); @@ -163,10 +177,14 @@ u32 dmuxOpen(Demuxer* data) if (esAVC[ch]) { ElementaryStream& es = *esAVC[ch]; - if (es.isfull()) + while (es.isfull()) { + if (Emu.IsStopped()) + { + ConLog.Warning("esAVC[%d] was full, waiting aborted", ch); + return; + } Sleep(1); - continue; } DemuxerStream backup = stream; @@ -177,11 +195,11 @@ u32 dmuxOpen(Demuxer* data) if (pes.new_au && es.hasdata()) // new AU detected { - if (es.hasunseen()) // hack, probably useless + /*if (es.hasunseen()) // hack, probably useless { stream = backup; continue; - } + }*/ es.finish(stream); // callback mem_ptr_t esMsg(a128(dmux.memAddr) + (cb_add ^= 16)); @@ -257,24 +275,11 @@ u32 dmuxOpen(Demuxer* data) { break; // Emu is stopped } -task: + switch (task.type) { case dmuxSetStream: { - bool do_wait = false; - for (u32 i = 0; i < 192; i++) - { - if (esALL[i]) - { - if (esALL[i]->hasunseen()) // hack, probably useless - { - do_wait = true; - break; - } - } - } - if (do_wait) continue; stream = task.stream; ConLog.Write("*** stream updated(addr=0x%x, size=0x%x, discont=%d, userdata=0x%llx)", stream.addr, stream.size, stream.discontinuity, stream.userdata); @@ -285,6 +290,7 @@ task: esALL[i]->reset(); } } + updates_count++; dmux.is_running = true; } break; @@ -292,7 +298,6 @@ task: case dmuxResetStream: case dmuxResetStreamAndWaitDone: { - // TODO: send CELL_DMUX_MSG_TYPE_DEMUX_DONE callback and provide waiting condition mem_ptr_t dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16)); dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE; dmuxMsg->supplementalInfo = stream.userdata; @@ -302,6 +307,7 @@ task: cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; dmux.is_running = false; } break; @@ -578,10 +584,15 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize return CELL_DMUX_ERROR_FATAL; } - if (dmux->is_running) + while (dmux->is_running) // hack { - Sleep(1); // performance hack - return CELL_DMUX_ERROR_BUSY; + if (Emu.IsStopped()) + { + ConLog.Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle); + break; + } + Sleep(1); + //return CELL_DMUX_ERROR_BUSY; } DemuxerTask task(dmuxSetStream); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp new file mode 100644 index 0000000000..81ed26a5a8 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -0,0 +1,404 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" +#include "libmixer.h" + +void libmixer_init(); +Module libmixer("libmixer", libmixer_init); + +int cellAANAddData(u32 handle, u32 port, u32 offset, u32 addr, u32 samples) +{ + libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", + handle, port, offset, addr, samples); + return CELL_OK; +} + +// libmixer Functions, NOT active in this moment +/*int cellAANConnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellAANDisconnect(CellAANHandle receive, u32 receivePortNo, CellAANHandle source, u32 sourcePortNo) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerRemove(CellAANHandle handle) +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerStop() //CellAANHandle handle, u32 mode +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +s32 cellSSPlayerGetState() //CellAANHandle handle +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +}*/ + +int cellSurMixerCreate(const mem_ptr_t config) +{ + libmixer.Error("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr()); + return CELL_OK; +} + +int cellSurMixerGetAANHandle(mem32_t handle) +{ + libmixer.Error("cellSurMixerGetAANHandle(handle_addr=0x%x)", handle.GetAddr()); + return CELL_OK; +} + +int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index) +{ + libmixer.Error("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x)", port.GetAddr(), type, index); + return CELL_OK; +} + +int cellSurMixerSetNotifyCallback(u32 func, u32 arg) +{ + libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg); + return CELL_OK; +} + +int cellSurMixerRemoveNotifyCallback(u32 func) +{ + libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func); + return CELL_OK; +} + +int cellSurMixerStart() +{ + libmixer.Error("cellSurMixerStart()"); + return CELL_OK; +} + +int cellSurMixerSetParameter(u32 param, float value) +{ + libmixer.Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + return CELL_OK; +} + +int cellSurMixerFinalize() +{ + libmixer.Error("cellSurMixerFinalize()"); + return CELL_OK; +} + +/*int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerPause() //u32 switch +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerGetCurrentBlockTag() //u64 *tag +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp +{ + UNIMPLEMENTED_FUNC(libmixer); + return 0; +} + +void cellSurMixerBeep(); //void *arg + +float cellSurMixerUtilGetLevelFromDB() //float dB +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO; +} + +float cellSurMixerUtilGetLevelFromDBIndex() //int index +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO; +} + +float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note +{ + UNIMPLEMENTED_FUNC(libmixer); + return CELL_OK; //it's NOT real value + //TODO +}*/ + +void libmixer_init() +{ + static const u64 cellAANAddData_table[] = { + // TODO + 0xffffffff7c691b78, + 0xffffffff7c0802a6, + 0xfffffffff821ff91, + 0xfffffffff8010080, + 0xffffffff7c802378, + 0xffffffff7caa2b78, + 0xffffffff81690000, + 0xffffffff7c050378, + 0xffffffff7cc43378, + // 78 63 00 20 clrldi r3,r3,32 # 20 // may be included + 0xffffffff7d465378, + 0xffffffff812b0030, + 0xffffffff80090000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff80490004, + 0xffffffff4e800421, + 0xffffffffe8410028, + 0xffffffffe8010080, + 0xffffffff7c6307b4, + 0xffffffff7c0803a6, + 0xffffffff38210070, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellAANAddData_table, "cellAANAddData", cellAANAddData); + + static const u64 cellSurMixerCreate_table[] = { + 0xffffffff2f830000, + 0xffffffff7c0802a6, + 0xfffffffff821ff51, + 0xfffffffffbc100a0, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbe100a8, + 0xfffffffff80100c0, + 0xffffffff7c7e1b78, + 0xf000000040000000, // bne + 0xffffffff3fe08031, + 0xffffffff63ff0003, + 0xffffffffe80100c0, + 0xffffffff7fe307b4, + 0xffffffffeb210078, + 0xffffffffeb410080, + 0xffffffff7c0803a6, + 0xffffffffeb610088, + 0xffffffffeb810090, + 0xffffffffeba10098, + 0xffffffffebc100a0, + 0xffffffffebe100a8, + 0xffffffff382100b0, + 0 + }; + libmixer.AddFuncSub(cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + + static const u64 cellSurMixerGetAANHandle_table[] = { + // first instruction ignored + 0xffffffff3d607fce, + 0xffffffff616bfffe, + 0xffffffff812a0018, + 0xffffffff7d2afe70, + 0xffffffff91230000, + 0xffffffff7d404a78, + 0xffffffff7c005050, + 0xffffffff7c00fe70, + 0xffffffff7c035838, + 0xffffffff3c638031, + 0xffffffff38630002, + 0xffffffff7c6307b4, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + + static const u64 cellSurMixerChStripGetAANPortNo_table[] = { + // first instruction ignored + 0xffffffff7c661b78, + 0xffffffff3c608031, + 0xffffffff78c60020, + 0xffffffff78840020, + 0xffffffff60630002, + 0xffffffff80090018, + 0xffffffff78a50020, + 0xffffffff2f800000, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000040000000, // b + 0 + }; + libmixer.AddFuncSub(cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + + static const u64 cellSurMixerSetNotifyCallback_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff81, + 0xfffffffff8010090, + 0xffffffff7c6b1b78, + 0xffffffff3c608031, + 0xffffffff812a0018, + 0xffffffff7c882378, + 0xffffffff60630003, + 0xffffffff2f890000, + 0xffffffff2f0b0000, + 0xffffff00409e0020, // bne + 0xffffffff3c608031, + 0xffffffff60630002, + 0xffffffffe8010090, + 0xffffffff7c6307b4, + 0xffffffff38210080, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffff00419affec, // beq + 0xf0000000800a001c, // lwz + 0xffffffff79290020, + 0xffffffff38810070, + 0xffffffff2f800000, + 0xffffffff7d234b78, + 0 + }; + libmixer.AddFuncSub(cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + + static const u64 cellSurMixerRemoveNotifyCallback_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff81, + 0xfffffffff8010090, + 0xffffffff7c6a1b78, + 0xffffffff3d208031, + 0xffffffff806b0018, + 0xffffffff61290002, + 0xffffffff2f830000, + 0xf0000000409e0018, // bne + 0xffffffffe8010090, + 0xffffffff7d2307b4, + 0xffffffff38210080, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + + static const u64 cellSurMixerStart_table[] = { + 0xfffffffff821ff71, + 0xffffffff7c0802a6, + 0xfffffffffbc10080, + 0xf000000083c20000, // lwz + 0xfffffffff80100a0, + 0xfffffffffba10078, + 0xfffffffffbe10088, + 0xffffffff801e0018, + 0xffffffff2f800000, + 0xf0000000409e002c, // bne + 0xffffffff3fe08031, + 0xffffffff63ff0002, + 0xffffffffe80100a0, + 0xffffffff7fe307b4, + 0xffffffffeba10078, + 0xffffffffebc10080, + 0xffffffff7c0803a6, + 0xffffffffebe10088, + 0xffffffff38210090, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub(cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + + static const u64 cellSurMixerSetParameter_table[] = { + 0xfffffffff821ff81, + 0xffffffff7c0802a6, + 0xfffffffffbc10070, + 0xfffffffffc000890, + 0xf000000083c28250, // lwz + 0xffffffff3d208031, + 0xfffffffff8010090, + 0xfffffffffbe10078, + 0xffffffff61290002, + 0xffffffff7c7f1b78, + 0xffffffff801e0018, + 0xffffffff2f800000, + 0xffff0000409e0020, // bne + 0xffffffffe8010090, + 0xffffffff7d2307b4, + 0xffffffffebc10070, + 0xffffffffebe10078, + 0xffffffff7c0803a6, + 0xffffffff38210080, + 0xffffffff4e800020, + 0xffffffff801e001c, + 0xffffffff2b03001f, + 0xffffffff2f800000, + 0xffff0000419cffd8, // blt + 0xffffffff2b83002b, + 0xffff000040990008, // ble + 0xffff0000409d0054, // ble + 0 + }; + libmixer.AddFuncSub(cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + + static const u64 cellSurMixerFinalize_table[] = { + 0xfffffffff821ff91, + 0xffffffff7c0802a6, + 0xfffffffff8010080, + 0xffffff004bfffde1, // bl + 0xffffffffe8010080, + 0xffffffff38600000, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xfffffffff821ff71, + 0xffffffff7c0802a6, + 0xfffffffffba10078, + 0xf000000083a28250, // lwz + 0xfffffffff80100a0, + 0xffffffff817d0018, + 0xffffffff7d635b78, + 0xffffffff812b0000, + 0xffffffff81490000, + 0xffffffff800a0000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff804a0004, + 0xffffffff4e800421, + 0 + }; + libmixer.AddFuncSub(cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h new file mode 100644 index 0000000000..24c30c7b70 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -0,0 +1,63 @@ +#pragma once + + +//Callback Functions +typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. + +//libmixer datatypes +typedef void * CellAANHandle; + +struct CellSSPlayerConfig +{ + be_t channels; + be_t outputMode; +}; + +struct CellSSPlayerWaveParam +{ + void *addr; + be_t format; + be_t samples; + be_t loopStartOffset; + be_t startOffset; +}; + +struct CellSSPlayerCommonParam +{ + be_t loopMode; + be_t attackMode; +}; + +struct CellSurMixerPosition +{ + be_t x; + be_t y; + be_t z; +}; + +struct CellSSPlayerRuntimeInfo +{ + be_t level; + be_t speed; + CellSurMixerPosition position; +}; + +struct CellSurMixerConfig +{ + be_t priority; + be_t chStrips1; + be_t chStrips2; + be_t chStrips6; + be_t chStrips8; +}; + +struct CellSurMixerChStripParam +{ + be_t param; + void *attribute; + be_t dBSwitch; + be_t floatVal; + be_t intVal; +}; + +CellSSPlayerWaveParam current_SSPlayerWaveParam; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp new file mode 100644 index 0000000000..6d653a7b1c --- /dev/null +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" +#include "Modules.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +extern ArrayF g_static_funcs_list; + +void StaticAnalyse(void* ptr, u32 size) +{ + u32* data = (u32*)ptr; size /= 4; + + // TODO: optimize search + for (u32 i = 0; i < size; i++) + { + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) + { + if ((data[i] & g_static_funcs_list[j].ops[0].mask) == g_static_funcs_list[j].ops[0].crc && (i + g_static_funcs_list[j].ops.GetCount()) < size) + { + bool found = true; + for (u32 k = i + 1, x = 1; x < g_static_funcs_list[j].ops.GetCount(); k++, x++) + { + // skip NOP + if (data[k] == se32(0x60000000)) + { + k++; + continue; + } + + if ((data[k] & g_static_funcs_list[j].ops[x].mask) != g_static_funcs_list[j].ops[x].crc) + { + found = false; + break; + } + } + if (found) + { + ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str()); + data[i] = re(0x39600000 | j); // li r11, j + data[i+1] = se32(0x44000003); // sc 3 + data[i+2] = se32(0x4e800020); // blr + i += g_static_funcs_list[j].ops.GetCount(); // ??? + } + } + } + } +} + +void StaticExecute(u32 code) +{ + if (code < g_static_funcs_list.GetCount()) + { + (*g_static_funcs_list[code].func)(); + } + else + { + ConLog.Error("StaticExecute(%d): unknown function or illegal opcode", code); + } +} + +void StaticFinalize() +{ + g_static_funcs_list.Clear(); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 51242b9b30..988c1391e3 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -433,3 +433,7 @@ public: }; //extern SysCalls SysCallsManager; + +void StaticAnalyse(void* ptr, u32 size); +void StaticExecute(u32 code); +void StaticFinalize(); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 2a42841c31..76a0cf4ebc 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -57,7 +57,7 @@ int sys_lwmutex_destroy(mem_ptr_t lwmutex) { case CELL_OK: lwmutex->all_info() = 0; - lwmutex->attribute = 0; + lwmutex->attribute = 0xDEADBEEF; lwmutex->sleep_queue = 0; Emu.GetIdManager().RemoveID(sq_id); default: return res; @@ -205,7 +205,17 @@ bool SleepQueue::finalize() int sys_lwmutex_t::trylock(be_t tid) { - if (!attribute.ToBE()) return CELL_EINVAL; + if (attribute.ToBE() == se32(0xDEADBEEF)) return CELL_EINVAL; + + while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0) + { + if (Emu.IsStopped()) + { + ConLog.Warning("(hack) sys_lwmutex_t::trylock aborted (waiting for recursive attribute, attr=0x%x)", (u32)attribute); + return CELL_ESRCH; + } + Sleep(1); + } if (tid == mutex.GetOwner()) { diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp index 04e2c958d3..5c4f5b9761 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp @@ -52,12 +52,12 @@ int sys_memory_allocate(u32 size, u32 flags, u32 alloc_addr_addr) { case SYS_MEMORY_PAGE_SIZE_1M: if(size & 0xfffff) return CELL_EALIGN; - addr = Memory.Alloc(size, 1); + addr = Memory.Alloc(size, 0x100000); break; case SYS_MEMORY_PAGE_SIZE_64K: if(size & 0xffff) return CELL_EALIGN; - addr = Memory.Alloc(size, 1); + addr = Memory.Alloc(size, 0x10000); break; default: return CELL_EINVAL; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp index 4ae474631b..d3921cbcc0 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Mutex.cpp @@ -37,7 +37,12 @@ int sys_mutex_create(mem32_t mutex_id, mem_ptr_t attr) return CELL_EINVAL; } - mutex_id = sys_mtx.GetNewId(new Mutex((u32)attr->protocol, is_recursive, attr->name_u64)); + u32 tid = GetCurrentPPUThread().GetId(); + Mutex* mutex = new Mutex((u32)attr->protocol, is_recursive, attr->name_u64); + u32 id = sys_mtx.GetNewId(mutex); + mutex->m_mutex.lock(tid); + mutex_id = id; + mutex->m_mutex.unlock(tid); sys_mtx.Warning("*** mutex created [%s] (protocol=0x%x, recursive=%s): id = %d", wxString(attr->name, 8).wx_str(), (u32)attr->protocol, wxString(is_recursive ? "true" : "false").wx_str(), mutex_id.GetValue()); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 0abf3866ea..6604d86d64 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -246,6 +246,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset) { elf64_f.Seek(phdr_arr[i].p_offset); elf64_f.Read(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); + StaticAnalyse(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); } } break; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 9e53606cac..c6395389c0 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -301,11 +301,13 @@ + + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 28561ebfcf..3eb2bd8980 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -436,6 +436,12 @@ Crypto + + Emu\SysCalls + + + Emu\SysCalls\Modules +