diff --git a/rpcs3/Emu/Cell/Modules/libmixer.cpp b/rpcs3/Emu/Cell/Modules/libmixer.cpp new file mode 100644 index 0000000000..ac5b0ed831 --- /dev/null +++ b/rpcs3/Emu/Cell/Modules/libmixer.cpp @@ -0,0 +1,654 @@ +#include "stdafx.h" +#include "Emu/System.h" +#include "Emu/IdManager.h" +#include "Emu/Cell/PPUModule.h" + +#include "cellAudio.h" +#include "libmixer.h" + +LOG_CHANNEL(libmixer); + +// TODO: use fxm +SurMixerConfig g_surmx; + +std::vector g_ssp; + +s32 cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) +{ + libmixer.trace("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d)", aan_handle, aan_port, offset, addr, samples); + + u32 type = aan_port >> 16; + u32 port = aan_port & 0xffff; + + switch (type) + { + case CELL_SURMIXER_CHSTRIP_TYPE1A: + if (port >= g_surmx.ch_strips_1) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE2A: + if (port >= g_surmx.ch_strips_2) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE6A: + if (port >= g_surmx.ch_strips_6) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE8A: + if (port >= g_surmx.ch_strips_8) type = 0; break; + default: + type = 0; break; + } + + if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0) + { + libmixer.error("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr, samples); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + std::lock_guard lock(g_surmx.mutex); + + if (type == CELL_SURMIXER_CHSTRIP_TYPE1A) + { + // mono upmixing + for (u32 i = 0; i < samples; i++) + { + const float center = addr[i]; + g_surmx.mixdata[i * 8 + 0] += center; + g_surmx.mixdata[i * 8 + 1] += center; + } + } + else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) + { + // stereo upmixing + for (u32 i = 0; i < samples; i++) + { + const float left = addr[i * 2 + 0]; + const float right = addr[i * 2 + 1]; + g_surmx.mixdata[i * 8 + 0] += left; + g_surmx.mixdata[i * 8 + 1] += right; + } + } + else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) + { + // 5.1 upmixing + for (u32 i = 0; i < samples; i++) + { + const float left = addr[i * 6 + 0]; + const float right = addr[i * 6 + 1]; + const float center = addr[i * 6 + 2]; + const float low_freq = addr[i * 6 + 3]; + const float rear_left = addr[i * 6 + 4]; + const float rear_right = addr[i * 6 + 5]; + g_surmx.mixdata[i * 8 + 0] += left; + g_surmx.mixdata[i * 8 + 1] += right; + g_surmx.mixdata[i * 8 + 2] += center; + g_surmx.mixdata[i * 8 + 3] += low_freq; + g_surmx.mixdata[i * 8 + 4] += rear_left; + g_surmx.mixdata[i * 8 + 5] += rear_right; + } + } + else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A) + { + // 7.1 + for (u32 i = 0; i < samples * 8; i++) + { + g_surmx.mixdata[i] += addr[i]; + } + } + + return CELL_OK; +} + +s32 cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +{ + libmixer.warning("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", + receive, receivePortNo, source, sourcePortNo); + + std::lock_guard lock(g_surmx.mutex); + + if (source >= g_ssp.size() || !g_ssp[source].m_created) + { + libmixer.error("cellAANConnect(): invalid source (%d)", source); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + g_ssp[source].m_connected = true; + + return CELL_OK; +} + +s32 cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) +{ + libmixer.warning("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", + receive, receivePortNo, source, sourcePortNo); + + std::lock_guard lock(g_surmx.mutex); + + if (source >= g_ssp.size() || !g_ssp[source].m_created) + { + libmixer.error("cellAANDisconnect(): invalid source (%d)", source); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + g_ssp[source].m_connected = false; + + return CELL_OK; +} + +s32 cellSSPlayerCreate(vm::ptr handle, vm::ptr config) +{ + libmixer.warning("cellSSPlayerCreate(handle=*0x%x, config=*0x%x)", handle, config); + + if (config->outputMode != 0 || config->channels - 1 >= 2) + { + libmixer.error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", config->outputMode, config->channels); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + std::lock_guard lock(g_surmx.mutex); + + SSPlayer p; + p.m_created = true; + p.m_connected = false; + p.m_active = false; + p.m_channels = config->channels; + + g_ssp.push_back(p); + *handle = (u32)g_ssp.size() - 1; + return CELL_OK; +} + +s32 cellSSPlayerRemove(u32 handle) +{ + libmixer.warning("cellSSPlayerRemove(handle=0x%x)", handle); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.error("cellSSPlayerRemove(): SSPlayer not found (%d)", handle); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + g_ssp[handle].m_active = false; + g_ssp[handle].m_created = false; + g_ssp[handle].m_connected = false; + + return CELL_OK; +} + +s32 cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) +{ + libmixer.warning("cellSSPlayerSetWave(handle=0x%x, waveInfo=*0x%x, commonInfo=*0x%x)", handle, waveInfo, commonInfo); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.error("cellSSPlayerSetWave(): SSPlayer not found (%d)", handle); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + // TODO: check parameters + + g_ssp[handle].m_addr = waveInfo->addr; + g_ssp[handle].m_samples = waveInfo->samples; + g_ssp[handle].m_loop_start = waveInfo->loopStartOffset - 1; + g_ssp[handle].m_loop_mode = commonInfo ? (u32)commonInfo->loopMode : CELL_SSPLAYER_ONESHOT; + g_ssp[handle].m_position = waveInfo->startOffset - 1; + + return CELL_OK; +} + +s32 cellSSPlayerPlay(u32 handle, vm::ptr info) +{ + libmixer.warning("cellSSPlayerPlay(handle=0x%x, info=*0x%x)", handle, info); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.error("cellSSPlayerPlay(): SSPlayer not found (%d)", handle); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + // TODO: check parameters + + g_ssp[handle].m_active = true; + g_ssp[handle].m_level = info->level; + g_ssp[handle].m_speed = info->speed; + g_ssp[handle].m_x = info->position.x; + g_ssp[handle].m_y = info->position.y; + g_ssp[handle].m_z = info->position.z; + + return CELL_OK; +} + +s32 cellSSPlayerStop(u32 handle, u32 mode) +{ + libmixer.warning("cellSSPlayerStop(handle=0x%x, mode=0x%x)", handle, mode); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.error("cellSSPlayerStop(): SSPlayer not found (%d)", handle); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + // TODO: transition to stop state + + g_ssp[handle].m_active = false; + + return CELL_OK; +} + +s32 cellSSPlayerSetParam(u32 handle, vm::ptr info) +{ + libmixer.warning("cellSSPlayerSetParam(handle=0x%x, info=*0x%x)", handle, info); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.error("cellSSPlayerSetParam(): SSPlayer not found (%d)", handle); + return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; + } + + // TODO: check parameters + + g_ssp[handle].m_level = info->level; + g_ssp[handle].m_speed = info->speed; + g_ssp[handle].m_x = info->position.x; + g_ssp[handle].m_y = info->position.y; + g_ssp[handle].m_z = info->position.z; + + return CELL_OK; +} + +s32 cellSSPlayerGetState(u32 handle) +{ + libmixer.warning("cellSSPlayerGetState(handle=0x%x)", handle); + + std::lock_guard lock(g_surmx.mutex); + + if (handle >= g_ssp.size() || !g_ssp[handle].m_created) + { + libmixer.warning("cellSSPlayerGetState(): SSPlayer not found (%d)", handle); + return CELL_SSPLAYER_STATE_ERROR; + } + + if (g_ssp[handle].m_active) + { + return CELL_SSPLAYER_STATE_ON; + } + + return CELL_SSPLAYER_STATE_OFF; +} + +s32 cellSurMixerCreate(vm::cptr config) +{ + libmixer.warning("cellSurMixerCreate(config=*0x%x)", config); + + const auto g_audio = fxm::get(); + + const auto port = g_audio->open_port(); + + if (!port) + { + return CELL_LIBMIXER_ERROR_FULL; + } + + g_surmx.audio_port = port->number; + g_surmx.priority = config->priority; + g_surmx.ch_strips_1 = config->chStrips1; + g_surmx.ch_strips_2 = config->chStrips2; + g_surmx.ch_strips_6 = config->chStrips6; + g_surmx.ch_strips_8 = config->chStrips8; + + port->channel = 8; + port->block = 16; + port->attr = 0; + port->size = port->channel * port->block * AUDIO_SAMPLES * sizeof(float); + port->tag = 0; + port->level = 1.0f; + port->level_set.store({ 1.0f, 0.0f }); + + libmixer.warning("*** audio port opened (port=%d)", g_surmx.audio_port); + + g_surmx.mixcount = 0; + g_surmx.cb = vm::null; + + g_ssp.clear(); + + libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); + + const auto ppu = idm::make_ptr("Surmixer Thread"); + ppu->prio = 1001; + ppu->stack_size = 0x10000; + ppu->custom_task = [g_audio](PPUThread& ppu) + { + audio_port& port = g_audio->ports[g_surmx.audio_port]; + + while (port.state != audio_port_state::closed) + { + CHECK_EMU_STATUS; + + if (g_surmx.mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; + } + + if (port.state == audio_port_state::started) + { + //u64 stamp0 = get_system_time(); + + memset(g_surmx.mixdata, 0, sizeof(g_surmx.mixdata)); + if (g_surmx.cb) + { + g_surmx.cb(ppu, g_surmx.cb_arg, (u32)g_surmx.mixcount, 256); + } + + //u64 stamp1 = get_system_time(); + + { + std::lock_guard lock(g_surmx.mutex); + + for (auto& p : g_ssp) if (p.m_active && p.m_created) + { + auto v = vm::ptrl::make(p.m_addr); // 16-bit LE audio data + float left = 0.0f; + float right = 0.0f; + float speed = fabs(p.m_speed); + float fpos = 0.0f; + for (s32 i = 0; i < 256; i++) if (p.m_active) + { + u32 pos = p.m_position; + s32 pos_inc = 0; + if (p.m_speed > 0.0f) // select direction + { + pos_inc = 1; + } + else if (p.m_speed < 0.0f) + { + pos_inc = -1; + } + s32 shift = i - (int)fpos; // change playback speed (simple and rough) + if (shift > 0) + { + // slow playback + pos_inc = 0; // duplicate one sample at this time + fpos += 1.0f; + fpos += speed; + } + else if (shift < 0) + { + // fast playback + i--; // mix two sample into one at this time + fpos -= 1.0f; + } + else + { + fpos += speed; + } + p.m_position += (u32)pos_inc; + if (p.m_channels == 1) // get mono data + { + left = right = (float)v[pos] / 0x8000 * p.m_level; + } + else if (p.m_channels == 2) // get stereo data + { + left = (float)v[pos * 2 + 0] / 0x8000 * p.m_level; + right = (float)v[pos * 2 + 1] / 0x8000 * p.m_level; + } + if (p.m_connected) // mix + { + // TODO: m_x, m_y, m_z ignored + g_surmx.mixdata[i * 8 + 0] += left; + g_surmx.mixdata[i * 8 + 1] += right; + } + if ((p.m_position == p.m_samples && p.m_speed > 0.0f) || + (p.m_position == ~0 && p.m_speed < 0.0f)) // loop or stop + { + if (p.m_loop_mode == CELL_SSPLAYER_LOOP_ON) + { + p.m_position = p.m_loop_start; + } + else if (p.m_loop_mode == CELL_SSPLAYER_ONESHOT_CONT) + { + p.m_position -= (u32)pos_inc; // restore position + } + else // oneshot + { + p.m_active = false; + p.m_position = p.m_loop_start; // TODO: check value + } + } + } + } + } + + //u64 stamp2 = get_system_time(); + + auto buf = vm::_ptr(port.addr.addr() + (g_surmx.mixcount % port.block) * port.channel * AUDIO_SAMPLES * sizeof(float)); + + for (auto& mixdata : g_surmx.mixdata) + { + // reverse byte order + *buf++ = mixdata; + } + + //u64 stamp3 = get_system_time(); + + //ConLog.Write("Libmixer perf: start=%lld (cb=%lld, ssp=%lld, finalize=%lld)", stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2); + } + + g_surmx.mixcount++; + } + + idm::remove(ppu.id); + }; + + ppu->cpu_init(); + ppu->state -= cpu_state::stop; + ppu->safe_notify(); + + return CELL_OK; +} + +s32 cellSurMixerGetAANHandle(vm::ptr handle) +{ + libmixer.warning("cellSurMixerGetAANHandle(handle=*0x%x) -> %d", handle, 0x11111111); + *handle = 0x11111111; + return CELL_OK; +} + +s32 cellSurMixerChStripGetAANPortNo(vm::ptr port, u32 type, u32 index) +{ + libmixer.warning("cellSurMixerChStripGetAANPortNo(port=*0x%x, type=0x%x, index=0x%x) -> 0x%x", port, type, index, (type << 16) | index); + *port = (type << 16) | index; + return CELL_OK; +} + +s32 cellSurMixerSetNotifyCallback(vm::ptr func, vm::ptr arg) +{ + libmixer.warning("cellSurMixerSetNotifyCallback(func=*0x%x, arg=*0x%x)", func, arg); + + if (g_surmx.cb) + { + throw EXCEPTION("Callback already set"); + } + + g_surmx.cb = func; + g_surmx.cb_arg = arg; + + return CELL_OK; +} + +s32 cellSurMixerRemoveNotifyCallback(vm::ptr func) +{ + libmixer.warning("cellSurMixerRemoveNotifyCallback(func=*0x%x)", func); + + if (g_surmx.cb != func) + { + throw EXCEPTION("Callback not set"); + } + + g_surmx.cb = vm::null; + + return CELL_OK; +} + +s32 cellSurMixerStart() +{ + libmixer.warning("cellSurMixerStart()"); + + const auto g_audio = fxm::get(); + + if (g_surmx.audio_port >= AUDIO_PORT_COUNT) + { + return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; + } + + g_audio->ports[g_surmx.audio_port].state.compare_and_swap(audio_port_state::opened, audio_port_state::started); + + return CELL_OK; +} + +s32 cellSurMixerSetParameter(u32 param, float value) +{ + libmixer.todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + return CELL_OK; +} + +s32 cellSurMixerFinalize() +{ + libmixer.warning("cellSurMixerFinalize()"); + + const auto g_audio = fxm::get(); + + if (g_surmx.audio_port >= AUDIO_PORT_COUNT) + { + return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; + } + + g_audio->ports[g_surmx.audio_port].state.compare_and_swap(audio_port_state::opened, audio_port_state::closed); + + return CELL_OK; +} + +s32 cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 samples) +{ + if (busNo < 8 && samples == 256 && offset == 0) + { + libmixer.trace("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + } + else + { + libmixer.todo("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + return CELL_OK; + } + + std::lock_guard lock(g_surmx.mutex); + + for (u32 i = 0; i < samples; i++) + { + // reverse byte order and mix + g_surmx.mixdata[i * 8 + busNo] += addr[i]; + } + + return CELL_OK; +} + +s32 cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr param) +{ + libmixer.todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param=*0x%x)", type, index, param); + return CELL_OK; +} + +s32 cellSurMixerPause(u32 type) +{ + libmixer.warning("cellSurMixerPause(type=%d)", type); + + const auto g_audio = fxm::get(); + + if (g_surmx.audio_port >= AUDIO_PORT_COUNT) + { + return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; + } + + g_audio->ports[g_surmx.audio_port].state.compare_and_swap(audio_port_state::started, audio_port_state::opened); + + return CELL_OK; +} + +s32 cellSurMixerGetCurrentBlockTag(vm::ptr tag) +{ + libmixer.trace("cellSurMixerGetCurrentBlockTag(tag=*0x%x)", tag); + + *tag = g_surmx.mixcount; + return CELL_OK; +} + +s32 cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) +{ + libmixer.trace("cellSurMixerGetTimestamp(tag=0x%llx, stamp=*0x%x)", tag, stamp); + + const auto g_audio = fxm::get(); + *stamp = g_audio->start_time + (tag) * 256000000 / 48000; // ??? + return CELL_OK; +} + +void cellSurMixerBeep(u32 arg) +{ + libmixer.todo("cellSurMixerBeep(arg=%d)", arg); + return; +} + +f32 cellSurMixerUtilGetLevelFromDB(f32 dB) +{ + libmixer.todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); + throw EXCEPTION("TODO"); +} + +f32 cellSurMixerUtilGetLevelFromDBIndex(s32 index) +{ + libmixer.todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); + throw EXCEPTION("TODO"); +} + +f32 cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) +{ + libmixer.todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); + throw EXCEPTION("TODO"); +} + +DECLARE(ppu_module_manager::libmixer)("libmixer", []() +{ + REG_FUNC(libmixer, cellAANAddData); + REG_FUNC(libmixer, cellAANConnect); + REG_FUNC(libmixer, cellAANDisconnect); + + REG_FUNC(libmixer, cellSurMixerCreate); + REG_FUNC(libmixer, cellSurMixerGetAANHandle); + REG_FUNC(libmixer, cellSurMixerChStripGetAANPortNo); + REG_FUNC(libmixer, cellSurMixerSetNotifyCallback); + REG_FUNC(libmixer, cellSurMixerRemoveNotifyCallback); + REG_FUNC(libmixer, cellSurMixerStart); + REG_FUNC(libmixer, cellSurMixerSetParameter); + REG_FUNC(libmixer, cellSurMixerFinalize); + REG_FUNC(libmixer, cellSurMixerSurBusAddData); + REG_FUNC(libmixer, cellSurMixerChStripSetParameter); + REG_FUNC(libmixer, cellSurMixerPause); + REG_FUNC(libmixer, cellSurMixerGetCurrentBlockTag); + REG_FUNC(libmixer, cellSurMixerGetTimestamp); + REG_FUNC(libmixer, cellSurMixerBeep); + + REG_FUNC(libmixer, cellSSPlayerCreate); + REG_FUNC(libmixer, cellSSPlayerRemove); + REG_FUNC(libmixer, cellSSPlayerSetWave); + REG_FUNC(libmixer, cellSSPlayerPlay); + REG_FUNC(libmixer, cellSSPlayerStop); + REG_FUNC(libmixer, cellSSPlayerSetParam); + REG_FUNC(libmixer, cellSSPlayerGetState); + + REG_FUNC(libmixer, cellSurMixerUtilGetLevelFromDB); + REG_FUNC(libmixer, cellSurMixerUtilGetLevelFromDBIndex); + REG_FUNC(libmixer, cellSurMixerUtilNoteToRatio); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/Cell/Modules/libmixer.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/libmixer.h rename to rpcs3/Emu/Cell/Modules/libmixer.h diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp b/rpcs3/Emu/Cell/Modules/libsnd3.cpp similarity index 71% rename from rpcs3/Emu/SysCalls/Modules/libsnd3.cpp rename to rpcs3/Emu/Cell/Modules/libsnd3.cpp index 74e5f84fbe..861039754d 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp +++ b/rpcs3/Emu/Cell/Modules/libsnd3.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "libsnd3.h" +LOG_CHANNEL(libsnd3); + s32 cellSnd3Init(u32 maxVoice, u32 samples, vm::ptr queue) { UNIMPLEMENTED_FUNC(libsnd3); @@ -290,56 +291,56 @@ s32 cellSnd3SMFGetKeyOnID(u32 smfID, u32 midiChannel, vm::ptr keyOnID) } -Module<> libsnd3("libsnd3", []() +DECLARE(ppu_module_manager::libsnd3)("libsnd3", []() { - REG_SUB(libsnd3,, cellSnd3Init); - REG_SUB(libsnd3,, cellSnd3Exit); - REG_SUB(libsnd3,, cellSnd3Note2Pitch); - REG_SUB(libsnd3,, cellSnd3Pitch2Note); - REG_SUB(libsnd3,, cellSnd3SetOutputMode); - REG_SUB(libsnd3,, cellSnd3Synthesis); - REG_SUB(libsnd3,, cellSnd3SynthesisEx); - REG_SUB(libsnd3,, cellSnd3BindSoundData); - REG_SUB(libsnd3,, cellSnd3UnbindSoundData); - REG_SUB(libsnd3,, cellSnd3NoteOnByTone); - REG_SUB(libsnd3,, cellSnd3KeyOnByTone); - REG_SUB(libsnd3,, cellSnd3VoiceNoteOnByTone); - REG_SUB(libsnd3,, cellSnd3VoiceKeyOnByTone); - REG_SUB(libsnd3,, cellSnd3VoiceSetReserveMode); - REG_SUB(libsnd3,, cellSnd3VoiceSetSustainHold); - REG_SUB(libsnd3,, cellSnd3VoiceKeyOff); - REG_SUB(libsnd3,, cellSnd3VoiceSetPitch); - REG_SUB(libsnd3,, cellSnd3VoiceSetVelocity); - REG_SUB(libsnd3,, cellSnd3VoiceSetPanpot); - REG_SUB(libsnd3,, cellSnd3VoiceSetPanpotEx); - REG_SUB(libsnd3,, cellSnd3VoiceSetPitchBend); - REG_SUB(libsnd3,, cellSnd3VoiceAllKeyOff); - REG_SUB(libsnd3,, cellSnd3VoiceGetEnvelope); - REG_SUB(libsnd3,, cellSnd3VoiceGetStatus); - REG_SUB(libsnd3,, cellSnd3KeyOffByID); - REG_SUB(libsnd3,, cellSnd3GetVoice); - REG_SUB(libsnd3,, cellSnd3GetVoiceByID); - REG_SUB(libsnd3,, cellSnd3NoteOn); - REG_SUB(libsnd3,, cellSnd3NoteOff); - REG_SUB(libsnd3,, cellSnd3SetSustainHold); - REG_SUB(libsnd3,, cellSnd3SetEffectType); - REG_SUB(libsnd3,, cellSnd3SMFBind); - REG_SUB(libsnd3,, cellSnd3SMFUnbind); - REG_SUB(libsnd3,, cellSnd3SMFPlay); - REG_SUB(libsnd3,, cellSnd3SMFPlayEx); - REG_SUB(libsnd3,, cellSnd3SMFPause); - REG_SUB(libsnd3,, cellSnd3SMFResume); - REG_SUB(libsnd3,, cellSnd3SMFStop); - REG_SUB(libsnd3,, cellSnd3SMFAddTempo); - REG_SUB(libsnd3,, cellSnd3SMFGetTempo); - REG_SUB(libsnd3,, cellSnd3SMFSetPlayVelocity); - REG_SUB(libsnd3,, cellSnd3SMFGetPlayVelocity); - REG_SUB(libsnd3,, cellSnd3SMFSetPlayPanpot); - REG_SUB(libsnd3,, cellSnd3SMFSetPlayPanpotEx); - REG_SUB(libsnd3,, cellSnd3SMFGetPlayPanpot); - REG_SUB(libsnd3,, cellSnd3SMFGetPlayPanpotEx); - REG_SUB(libsnd3,, cellSnd3SMFGetPlayStatus); - REG_SUB(libsnd3,, cellSnd3SMFSetPlayChannel); - REG_SUB(libsnd3,, cellSnd3SMFGetPlayChannel); - REG_SUB(libsnd3,, cellSnd3SMFGetKeyOnID); + REG_FUNC(libsnd3, cellSnd3Init); + REG_FUNC(libsnd3, cellSnd3Exit); + REG_FUNC(libsnd3, cellSnd3Note2Pitch); + REG_FUNC(libsnd3, cellSnd3Pitch2Note); + REG_FUNC(libsnd3, cellSnd3SetOutputMode); + REG_FUNC(libsnd3, cellSnd3Synthesis); + REG_FUNC(libsnd3, cellSnd3SynthesisEx); + REG_FUNC(libsnd3, cellSnd3BindSoundData); + REG_FUNC(libsnd3, cellSnd3UnbindSoundData); + REG_FUNC(libsnd3, cellSnd3NoteOnByTone); + REG_FUNC(libsnd3, cellSnd3KeyOnByTone); + REG_FUNC(libsnd3, cellSnd3VoiceNoteOnByTone); + REG_FUNC(libsnd3, cellSnd3VoiceKeyOnByTone); + REG_FUNC(libsnd3, cellSnd3VoiceSetReserveMode); + REG_FUNC(libsnd3, cellSnd3VoiceSetSustainHold); + REG_FUNC(libsnd3, cellSnd3VoiceKeyOff); + REG_FUNC(libsnd3, cellSnd3VoiceSetPitch); + REG_FUNC(libsnd3, cellSnd3VoiceSetVelocity); + REG_FUNC(libsnd3, cellSnd3VoiceSetPanpot); + REG_FUNC(libsnd3, cellSnd3VoiceSetPanpotEx); + REG_FUNC(libsnd3, cellSnd3VoiceSetPitchBend); + REG_FUNC(libsnd3, cellSnd3VoiceAllKeyOff); + REG_FUNC(libsnd3, cellSnd3VoiceGetEnvelope); + REG_FUNC(libsnd3, cellSnd3VoiceGetStatus); + REG_FUNC(libsnd3, cellSnd3KeyOffByID); + REG_FUNC(libsnd3, cellSnd3GetVoice); + REG_FUNC(libsnd3, cellSnd3GetVoiceByID); + REG_FUNC(libsnd3, cellSnd3NoteOn); + REG_FUNC(libsnd3, cellSnd3NoteOff); + REG_FUNC(libsnd3, cellSnd3SetSustainHold); + REG_FUNC(libsnd3, cellSnd3SetEffectType); + REG_FUNC(libsnd3, cellSnd3SMFBind); + REG_FUNC(libsnd3, cellSnd3SMFUnbind); + REG_FUNC(libsnd3, cellSnd3SMFPlay); + REG_FUNC(libsnd3, cellSnd3SMFPlayEx); + REG_FUNC(libsnd3, cellSnd3SMFPause); + REG_FUNC(libsnd3, cellSnd3SMFResume); + REG_FUNC(libsnd3, cellSnd3SMFStop); + REG_FUNC(libsnd3, cellSnd3SMFAddTempo); + REG_FUNC(libsnd3, cellSnd3SMFGetTempo); + REG_FUNC(libsnd3, cellSnd3SMFSetPlayVelocity); + REG_FUNC(libsnd3, cellSnd3SMFGetPlayVelocity); + REG_FUNC(libsnd3, cellSnd3SMFSetPlayPanpot); + REG_FUNC(libsnd3, cellSnd3SMFSetPlayPanpotEx); + REG_FUNC(libsnd3, cellSnd3SMFGetPlayPanpot); + REG_FUNC(libsnd3, cellSnd3SMFGetPlayPanpotEx); + REG_FUNC(libsnd3, cellSnd3SMFGetPlayStatus); + REG_FUNC(libsnd3, cellSnd3SMFSetPlayChannel); + REG_FUNC(libsnd3, cellSnd3SMFGetPlayChannel); + REG_FUNC(libsnd3, cellSnd3SMFGetKeyOnID); }); diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.h b/rpcs3/Emu/Cell/Modules/libsnd3.h similarity index 97% rename from rpcs3/Emu/SysCalls/Modules/libsnd3.h rename to rpcs3/Emu/Cell/Modules/libsnd3.h index 978d8b9a77..5afd3024b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsnd3.h +++ b/rpcs3/Emu/Cell/Modules/libsnd3.h @@ -51,5 +51,3 @@ struct CellSnd3RequestQueueCtx vm::bptr rearQueue; be_t rearQueueSize; }; - -extern Module<> libsnd3; diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp b/rpcs3/Emu/Cell/Modules/libsynth2.cpp similarity index 75% rename from rpcs3/Emu/SysCalls/Modules/libsynth2.cpp rename to rpcs3/Emu/Cell/Modules/libsynth2.cpp index ad341c25c9..532932a2d7 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp +++ b/rpcs3/Emu/Cell/Modules/libsynth2.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "libsynth2.h" +LOG_CHANNEL(libsynth2); + s32 cellSoundSynth2Config(s16 param, s32 value) { libsynth2.todo("cellSoundSynth2Config(param=%d, value=%d)", param, value); @@ -104,23 +105,23 @@ u16 cellSoundSynth2Pitch2Note(u16 center_note, u16 center_fine, u16 pitch) } -Module<> libsynth2("libsynth2", []() +DECLARE(ppu_module_manager::libsynth2)("libsynth2", []() { - REG_SUB(libsynth2,, cellSoundSynth2Config); - REG_SUB(libsynth2,, cellSoundSynth2Init); - REG_SUB(libsynth2,, cellSoundSynth2Exit); - REG_SUB(libsynth2,, cellSoundSynth2SetParam); - REG_SUB(libsynth2,, cellSoundSynth2GetParam); - REG_SUB(libsynth2,, cellSoundSynth2SetSwitch); - REG_SUB(libsynth2,, cellSoundSynth2GetSwitch); - REG_SUB(libsynth2,, cellSoundSynth2SetAddr); - REG_SUB(libsynth2,, cellSoundSynth2GetAddr); - REG_SUB(libsynth2,, cellSoundSynth2SetEffectAttr); - REG_SUB(libsynth2,, cellSoundSynth2SetEffectMode); - REG_SUB(libsynth2,, cellSoundSynth2SetCoreAttr); - REG_SUB(libsynth2,, cellSoundSynth2Generate); - REG_SUB(libsynth2,, cellSoundSynth2VoiceTrans); - REG_SUB(libsynth2,, cellSoundSynth2VoiceTransStatus); - REG_SUB(libsynth2,, cellSoundSynth2Note2Pitch); - REG_SUB(libsynth2,, cellSoundSynth2Pitch2Note); + REG_FUNC(libsynth2, cellSoundSynth2Config); + REG_FUNC(libsynth2, cellSoundSynth2Init); + REG_FUNC(libsynth2, cellSoundSynth2Exit); + REG_FUNC(libsynth2, cellSoundSynth2SetParam); + REG_FUNC(libsynth2, cellSoundSynth2GetParam); + REG_FUNC(libsynth2, cellSoundSynth2SetSwitch); + REG_FUNC(libsynth2, cellSoundSynth2GetSwitch); + REG_FUNC(libsynth2, cellSoundSynth2SetAddr); + REG_FUNC(libsynth2, cellSoundSynth2GetAddr); + REG_FUNC(libsynth2, cellSoundSynth2SetEffectAttr); + REG_FUNC(libsynth2, cellSoundSynth2SetEffectMode); + REG_FUNC(libsynth2, cellSoundSynth2SetCoreAttr); + REG_FUNC(libsynth2, cellSoundSynth2Generate); + REG_FUNC(libsynth2, cellSoundSynth2VoiceTrans); + REG_FUNC(libsynth2, cellSoundSynth2VoiceTransStatus); + REG_FUNC(libsynth2, cellSoundSynth2Note2Pitch); + REG_FUNC(libsynth2, cellSoundSynth2Pitch2Note); }); diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.h b/rpcs3/Emu/Cell/Modules/libsynth2.h similarity index 92% rename from rpcs3/Emu/SysCalls/Modules/libsynth2.h rename to rpcs3/Emu/Cell/Modules/libsynth2.h index 6b972ad7cf..cd2ce07f89 100644 --- a/rpcs3/Emu/SysCalls/Modules/libsynth2.h +++ b/rpcs3/Emu/Cell/Modules/libsynth2.h @@ -17,5 +17,3 @@ struct CellSoundSynth2EffectAttr be_t delay; be_t feedback; }; - -extern Module<> libsynth2; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp similarity index 95% rename from rpcs3/Emu/SysCalls/Modules/sceNp.cpp rename to rpcs3/Emu/Cell/Modules/sceNp.cpp index d3204c22f3..80c682eeed 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -1,16 +1,12 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/state.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/lv2/sys_process.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsDir.h" +#include "Emu/Cell/lv2/sys_process.h" #include "Crypto/unedat.h" #include "sceNp.h" -extern Module<> sceNp; +LOG_CHANNEL(sceNp); s32 sceNpInit(u32 poolsize, vm::ptr poolptr) { @@ -42,9 +38,11 @@ s32 sceNpTerm() s32 npDrmIsAvailable(u32 k_licensee_addr, vm::cptr drm_path) { - if (!Emu.GetVFS().ExistsFile(drm_path.get_ptr())) + const std::string& enc_drm_path = drm_path.get_ptr(); + + if (!fs::is_file(vfs::get(enc_drm_path))) { - sceNp.warning("npDrmIsAvailable(): '%s' not found", drm_path.get_ptr()); + sceNp.warning("npDrmIsAvailable(): '%s' not found", enc_drm_path); return CELL_ENOENT; } @@ -60,49 +58,40 @@ s32 npDrmIsAvailable(u32 k_licensee_addr, vm::cptr drm_path) } } - sceNp.warning("npDrmIsAvailable(): Found DRM license file at %s", drm_path.get_ptr()); - sceNp.warning("npDrmIsAvailable(): Using k_licensee 0x%s", k_licensee_str.c_str()); + sceNp.warning("npDrmIsAvailable(): Found DRM license file at %s", enc_drm_path); + sceNp.warning("npDrmIsAvailable(): Using k_licensee 0x%s", k_licensee_str); // Set the necessary file paths. - std::string drm_file_name = fmt::AfterLast(drm_path.get_ptr(), '/'); + const std::string& drm_file_name = enc_drm_path.substr(enc_drm_path.find_last_of('/') + 1); // TODO: Make more explicit what this actually does (currently it copies "XXXXXXXX" from drm_path (== "/dev_hdd0/game/XXXXXXXXX/*" assumed) - std::string titleID(&drm_path[15], 9); + const std::string& drm_file_dir = enc_drm_path.substr(15); + const std::string& title_id = drm_file_dir.substr(0, drm_file_dir.find_first_of('/')); - // TODO: These shouldn't use current dir - std::string enc_drm_path = drm_path.get_ptr(); - std::string dec_drm_path = "/dev_hdd1/cache/" + drm_file_name; - std::string pf_str("00000001"); // TODO: Allow multiple profiles. Use default for now. - std::string rap_path("/dev_hdd0/home/" + pf_str + "/exdata/"); + const std::string& dec_drm_path = "/dev_hdd1/cache/" + drm_file_name; + + std::string rap_lpath = vfs::get("/dev_hdd0/home/00000001/exdata/"); // TODO: Allow multiple profiles. Use default for now. // Search for a compatible RAP file. - for (const auto entry : vfsDir(rap_path)) + for (const auto& entry : fs::dir(rap_lpath)) { - if (entry->name.find(titleID) != std::string::npos) + if (entry.name.find(title_id) != -1) { - rap_path += entry->name; + rap_lpath += entry.name; break; } } - if (rap_path.back() == '/') + if (rap_lpath.back() == '/') { - sceNp.warning("npDrmIsAvailable(): Can't find RAP file for '%s' (titleID='%s')", drm_path.get_ptr(), titleID); - rap_path.clear(); + sceNp.warning("npDrmIsAvailable(): Can't find RAP file for %s", enc_drm_path); + rap_lpath.clear(); } - // Decrypt this EDAT using the supplied k_licensee and matching RAP file. - std::string enc_drm_path_local, dec_drm_path_local, rap_path_local; + const std::string& enc_drm_path_local = vfs::get(enc_drm_path); + const std::string& dec_drm_path_local = vfs::get(dec_drm_path); - Emu.GetVFS().GetDevice(enc_drm_path, enc_drm_path_local); - Emu.GetVFS().GetDevice(dec_drm_path, dec_drm_path_local); - - if (rap_path.size()) - { - Emu.GetVFS().GetDevice(rap_path, rap_path_local); - } - - if (DecryptEDAT(enc_drm_path_local, dec_drm_path_local, 8, rap_path_local, k_licensee, false) >= 0) + if (DecryptEDAT(enc_drm_path_local, dec_drm_path_local, 8, rap_lpath, k_licensee, false) >= 0) { // If decryption succeeds, replace the encrypted file with it. fs::remove_file(enc_drm_path_local); @@ -1526,7 +1515,7 @@ s32 _Z32_sce_np_sysutil_cxml_prepare_docPN16sysutil_cxmlutil11FixedMemoryERN4cxm } -Module<> sceNp("sceNp", []() +DECLARE(ppu_module_manager::sceNp)("sceNp", []() { REG_FUNC(sceNp, sceNpInit); REG_FUNC(sceNp, sceNpTerm); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNp.h rename to rpcs3/Emu/Cell/Modules/sceNp.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp2.cpp b/rpcs3/Emu/Cell/Modules/sceNp2.cpp similarity index 98% rename from rpcs3/Emu/SysCalls/Modules/sceNp2.cpp rename to rpcs3/Emu/Cell/Modules/sceNp2.cpp index 0c6cf5260b..c424aaf877 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp2.cpp @@ -1,11 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNp.h" #include "sceNp2.h" -extern Module<> sceNp2; +LOG_CHANNEL(sceNp2); s32 sceNp2Init(u32 poolsize, vm::ptr poolptr) { @@ -384,7 +383,7 @@ s32 sceNpMatching2RegisterRoomMessageCallback() } -Module<> sceNp2("sceNp2", []() +DECLARE(ppu_module_manager::sceNp2)("sceNp2", []() { REG_FUNC(sceNp2, sceNpMatching2DestroyContext); REG_FUNC(sceNp2, sceNpMatching2LeaveLobby); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp2.h b/rpcs3/Emu/Cell/Modules/sceNp2.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNp2.h rename to rpcs3/Emu/Cell/Modules/sceNp2.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp similarity index 98% rename from rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp rename to rpcs3/Emu/Cell/Modules/sceNpClans.cpp index 2bf714ad12..e3d7daca27 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNp.h" #include "sceNpClans.h" -extern Module<> sceNpClans; +LOG_CHANNEL(sceNpClans); s32 sceNpClansInit(vm::ptr commId, vm::ptr passphrase, vm::ptr pool, vm::ptr poolSize, u32 flags) { @@ -255,7 +254,7 @@ s32 sceNpClansRemoveChallenge() return CELL_OK; } -Module<> sceNpClans("sceNpClans", []() +DECLARE(ppu_module_manager::sceNpClans)("sceNpClans", []() { REG_FUNC(sceNpClans, sceNpClansInit); REG_FUNC(sceNpClans, sceNpClansTerm); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.h b/rpcs3/Emu/Cell/Modules/sceNpClans.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpClans.h rename to rpcs3/Emu/Cell/Modules/sceNpClans.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp similarity index 98% rename from rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp rename to rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp index c1bdbf23d9..ba8f47ce7e 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp @@ -1,10 +1,9 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNpCommerce2.h" -extern Module<> sceNpCommerce2; +LOG_CHANNEL(sceNpCommerce2); s32 sceNpCommerce2ExecuteStoreBrowse() { @@ -315,7 +314,7 @@ s32 sceNpCommerce2DoServiceListFinishAsync() throw EXCEPTION(""); } -Module<> sceNpCommerce2("sceNpCommerce2", []() +DECLARE(ppu_module_manager::sceNpCommerce2)("sceNpCommerce2", []() { REG_FUNC(sceNpCommerce2, sceNpCommerce2ExecuteStoreBrowse); REG_FUNC(sceNpCommerce2, sceNpCommerce2GetStoreBrowseUserdata); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.h rename to rpcs3/Emu/Cell/Modules/sceNpCommerce2.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp similarity index 92% rename from rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp rename to rpcs3/Emu/Cell/Modules/sceNpSns.cpp index 26b61aed15..15dc2c7153 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp @@ -1,9 +1,9 @@ #include "stdafx.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNpSns.h" -extern Module<> sceNpSns; +LOG_CHANNEL(sceNpSns); s32 sceNpSnsFbInit(vm::ptr params) { @@ -66,7 +66,7 @@ s32 sceNpSnsFbLoadThrottle() } -Module<> sceNpSns("sceNpSns", []() +DECLARE(ppu_module_manager::sceNpSns)("sceNpSns", []() { REG_FUNC(sceNpSns, sceNpSnsFbInit); REG_FUNC(sceNpSns, sceNpSnsFbTerm); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpSns.h b/rpcs3/Emu/Cell/Modules/sceNpSns.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpSns.h rename to rpcs3/Emu/Cell/Modules/sceNpSns.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp similarity index 92% rename from rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp rename to rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 98756e976c..a0848e2621 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -1,33 +1,29 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/IdManager.h" #include "Emu/System.h" -#include "Emu/state.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/IdManager.h" +#include "Emu/Cell/PPUModule.h" #include "Utilities/rXml.h" #include "Loader/TRP.h" #include "Loader/TROPUSR.h" -#include "Emu/FS/VFS.h" -#include "Emu/FS/vfsDir.h" -#include "Emu/FS/vfsFileBase.h" + #include "sceNp.h" #include "sceNpTrophy.h" -extern Module<> sceNpTrophy; +LOG_CHANNEL(sceNpTrophy); struct trophy_context_t { - const u32 id = idm::get_last_id(); + const u32 id{}; std::string trp_name; - std::unique_ptr trp_stream; + fs::file trp_stream; std::unique_ptr tropusr; }; struct trophy_handle_t { - const u32 id = idm::get_last_id(); + const u32 id{}; }; // Functions @@ -103,10 +99,10 @@ s32 sceNpTrophyCreateContext(vm::ptr context, vm::cptrdata, commId->num); // open trophy pack file - std::unique_ptr stream(Emu.GetVFS().OpenFile("/app_home/../TROPDIR/" + name + "/TROPHY.TRP", fom::read)); + fs::file stream(vfs::get("/app_home/../TROPDIR/" + name + "/TROPHY.TRP")); // check if exists and opened - if (!stream || !stream->IsOpened()) + if (!stream) { return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST; } @@ -158,7 +154,7 @@ s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr< return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE; } - TRPLoader trp(*ctxt->trp_stream); + TRPLoader trp(ctxt->trp_stream); if (!trp.LoadHeader()) { sceNpTrophy.error("sceNpTrophyRegisterContext(): SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE"); @@ -169,7 +165,7 @@ s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr< const size_t kTargetBufferLength = 31; char target[kTargetBufferLength + 1]; target[kTargetBufferLength] = 0; - strcpy_trunc(target, fmt::format("TROP_%02d.SFM", rpcs3::config.system.language.value())); + strcpy_trunc(target, fmt::format("TROP_%02d.SFM", /*rpcs3::config.system.language.value()*/0)); if (trp.ContainsEntry(target)) { @@ -191,7 +187,7 @@ s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr< for (s32 i = 0; i <= 18; i++) { strcpy_trunc(target, fmt::format("TROP_%02d.SFM", i)); - if (i != rpcs3::config.system.language.value()) + if (i != /*rpcs3::config.system.language.value()*/0) { trp.RemoveEntry(target); } @@ -237,7 +233,7 @@ s32 sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspa } // TODO: This is not accurate. It's just an approximation of the real value - *reqspace = ctxt->trp_stream->GetSize(); + *reqspace = ctxt->trp_stream.size(); return CELL_OK; } @@ -267,9 +263,12 @@ s32 sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptrtrp_name + "/TROPCONF.SFM"); + + // TODO: rXmlDocument can open only real file + ASSERT(!fs::get_virtual_device(path)); rXmlDocument doc; - Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user doc.Load(path); std::string titleName; @@ -394,9 +393,12 @@ s32 sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptrtrp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user + // TODO: Get the path of the current user + const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"); + + // TODO: rXmlDocument can open only real file + ASSERT(!fs::get_virtual_device(path)); + rXmlDocument doc; doc.Load(path); std::string name; @@ -455,7 +457,7 @@ s32 sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::ptr sceNpTrophy("sceNpTrophy", []() +DECLARE(ppu_module_manager::sceNpTrophy)("sceNpTrophy", []() { REG_FUNC(sceNpTrophy, sceNpTrophyGetGameProgress); REG_FUNC(sceNpTrophy, sceNpTrophyRegisterContext); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h b/rpcs3/Emu/Cell/Modules/sceNpTrophy.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpTrophy.h rename to rpcs3/Emu/Cell/Modules/sceNpTrophy.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp similarity index 98% rename from rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp rename to rpcs3/Emu/Cell/Modules/sceNpTus.cpp index 4eb33b0cee..1ee55bf9f6 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp @@ -1,11 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNp.h" #include "sceNpTus.h" -extern Module<> sceNpTus; +LOG_CHANNEL(sceNpTus); s32 sceNpTusInit() { @@ -333,7 +332,7 @@ s32 sceNpTusDeleteMultiSlotDataVUserAsync() return CELL_OK; } -Module<> sceNpTus("sceNpTus", []() +DECLARE(ppu_module_manager::sceNpTus)("sceNpTus", []() { REG_FUNC(sceNpTus, sceNpTusInit); REG_FUNC(sceNpTus, sceNpTusTerm); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTus.h b/rpcs3/Emu/Cell/Modules/sceNpTus.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpTus.h rename to rpcs3/Emu/Cell/Modules/sceNpTus.h diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpUtil.cpp b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp similarity index 83% rename from rpcs3/Emu/SysCalls/Modules/sceNpUtil.cpp rename to rpcs3/Emu/Cell/Modules/sceNpUtil.cpp index a0ad31b011..0dc924f80a 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp @@ -1,11 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sceNp.h" #include "sceNpUtil.h" -extern Module<> sceNpUtil; +LOG_CHANNEL(sceNpUtil); s32 sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) { @@ -31,7 +30,7 @@ s32 sceNpUtilBandwidthTestAbort() return CELL_OK; } -Module<> sceNpUtil("sceNpUtil", []() +DECLARE(ppu_module_manager::sceNpUtil)("sceNpUtil", []() { REG_FUNC(sceNpUtil, sceNpUtilBandwidthTestInitStart); REG_FUNC(sceNpUtil, sceNpUtilBandwidthTestShutdown); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpUtil.h b/rpcs3/Emu/Cell/Modules/sceNpUtil.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sceNpUtil.h rename to rpcs3/Emu/Cell/Modules/sceNpUtil.h diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp similarity index 51% rename from rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp rename to rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp index ca24e0bd8a..7140e8b37e 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp @@ -1,80 +1,84 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_interrupt.h" -#include "Emu/SysCalls/lv2/sys_process.h" +#include "Emu/Cell/lv2/sys_interrupt.h" +#include "Emu/Cell/lv2/sys_process.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +LOG_CHANNEL(sysPrxForUser); extern u64 get_system_time(); -#define TLS_MAX 128 +vm::gvar sys_prx_version; // ??? + #define TLS_SYS 0x30 -u32 g_tls_start; // start of TLS memory area -u32 g_tls_size; +u32 g_tls_size = 0; // Size of TLS area per thread +u32 g_tls_addr = 0; // Start of TLS memory area +u32 g_tls_max = 0; // Max number of threads -std::array, TLS_MAX> g_tls_owners; +std::unique_ptr[]> g_tls_map; // I'd like to make it std::vector but it won't work -void sys_initialize_tls() +u32 ppu_alloc_tls() { - sysPrxForUser.trace("sys_initialize_tls()"); -} - -u32 ppu_get_tls(u32 thread) -{ - if (!g_tls_start) + for (u32 i = 0; i < g_tls_max; i++) { - g_tls_size = Emu.GetTLSMemsz() + TLS_SYS; - g_tls_start = vm::alloc(g_tls_size * TLS_MAX, vm::main); // memory for up to TLS_MAX threads - LOG_NOTICE(MEMORY, "Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", - g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz()); - } - - if (!thread) - { - return 0; - } - - for (u32 i = 0; i < TLS_MAX; i++) - { - if (g_tls_owners[i] == thread) + if (g_tls_map[i].exchange(true) == false) { - return g_tls_start + i * g_tls_size + TLS_SYS; // if already initialized, return TLS address - } - } - - for (u32 i = 0; i < TLS_MAX; i++) - { - u32 old = 0; - if (g_tls_owners[i].compare_exchange_strong(old, thread)) - { - const u32 addr = g_tls_start + i * g_tls_size + TLS_SYS; // get TLS address - std::memset(vm::base(addr - TLS_SYS), 0, TLS_SYS); // initialize system area with zeros - std::memcpy(vm::base(addr), vm::base(Emu.GetTLSAddr()), Emu.GetTLSFilesz()); // initialize from TLS image - std::memset(vm::base(addr + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // fill the rest with zeros + const u32 addr = g_tls_addr + i * g_tls_size; // Calculate TLS address + std::memset(vm::base(addr), 0, TLS_SYS); // Clear system area (TODO) + std::memcpy(vm::base(addr + TLS_SYS), vm::base(Emu.GetTLSAddr()), Emu.GetTLSFilesz()); // Copy TLS image + std::memset(vm::base(addr + TLS_SYS + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // Clear the rest return addr; } } - throw EXCEPTION("Out of TLS memory"); + sysPrxForUser.error("ppu_alloc_tls(): out of TLS memory (max=%zu)", g_tls_max); + return 0; } -void ppu_free_tls(u32 thread) +void ppu_free_tls(u32 addr) { - for (auto& v : g_tls_owners) + // Calculate TLS position + const u32 i = (addr - g_tls_addr) / g_tls_size; + + if (addr < g_tls_addr || i >= g_tls_max || (addr - g_tls_addr) % g_tls_size) { - u32 old = thread; - if (v.compare_exchange_strong(old, 0)) - { - return; - } + sysPrxForUser.error("ppu_free_tls(0x%x): invalid address", addr); + return; } - LOG_ERROR(MEMORY, "TLS deallocation failed (thread=0x%x)", thread); + if (g_tls_map[i].exchange(false) == false) + { + sysPrxForUser.error("ppu_free_tls(0x%x): deallocation failed", addr); + return; + } +} + +void sys_initialize_tls(PPUThread& ppu, u64 main_thread_id, u32 tls_seg_addr, u32 tls_seg_size, u32 tls_mem_size) +{ + sysPrxForUser.notice("sys_initialize_tls(thread_id=0x%llx, addr=*0x%x, size=0x%x, mem_size=0x%x)", main_thread_id, tls_seg_addr, tls_seg_size, tls_mem_size); + + // Uninitialized TLS expected. + if (ppu.GPR[13] != 0) return; + + // Initialize TLS memory + g_tls_size = Emu.GetTLSMemsz() + TLS_SYS; + g_tls_addr = vm::alloc(0x20000, vm::main) + 0x30; + g_tls_max = (0xffd0 / g_tls_size) + (0x10000 / g_tls_size); + g_tls_map = std::make_unique[]>(g_tls_max); + + // Allocate TLS for main thread + ppu.GPR[13] = ppu_alloc_tls() + 0x7000 + TLS_SYS; + + sysPrxForUser.notice("TLS initialized (addr=0x%x, size=0x%x, max=0x%zu)", g_tls_addr - 0x30, g_tls_size, g_tls_max); + + // TODO + g_spu_printf_agcb = vm::null; + g_spu_printf_dgcb = vm::null; + g_spu_printf_atcb = vm::null; + g_spu_printf_dtcb = vm::null; } s64 sys_time_get_system_time() @@ -86,21 +90,32 @@ s64 sys_time_get_system_time() s64 _sys_process_atexitspawn() { - sysPrxForUser.trace("_sys_process_atexitspawn()"); + sysPrxForUser.todo("_sys_process_atexitspawn()"); return CELL_OK; } s64 _sys_process_at_Exitspawn() { - sysPrxForUser.trace("_sys_process_at_Exitspawn"); + sysPrxForUser.todo("_sys_process_at_Exitspawn"); return CELL_OK; } s32 sys_interrupt_thread_disestablish(PPUThread& ppu, u32 ih) { - sysPrxForUser.todo("sys_interrupt_thread_disestablish(ih=0x%x)", ih); + sysPrxForUser.notice("sys_interrupt_thread_disestablish(ih=0x%x)", ih); - return _sys_interrupt_thread_disestablish(ppu, ih, vm::var{}); + vm::var r13; + + // Call the syscall + if (s32 res = _sys_interrupt_thread_disestablish(ppu, ih, r13)) + { + return res; + } + + // Deallocate TLS + ppu_free_tls(vm::cast(*r13, HERE) - 0x7030); + + return CELL_OK; } s32 sys_process_is_stack(u32 p) @@ -166,20 +181,8 @@ extern void sysPrxForUser_sys_spu_init(); extern void sysPrxForUser_sys_game_init(); extern void sysPrxForUser_sys_libc_init(); -Module<> sysPrxForUser("sysPrxForUser", []() +DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []() { - g_tls_start = 0; - - for (auto& v : g_tls_owners) - { - v = 0; - } - - // Setup random number generator - srand(time(NULL)); - - //REG_VARIABLE(sysPrxForUser, sys_prx_version); // 0x7df066cf - sysPrxForUser_sys_lwmutex_init(); sysPrxForUser_sys_lwcond_init(); sysPrxForUser_sys_ppu_thread_init(); @@ -192,6 +195,8 @@ Module<> sysPrxForUser("sysPrxForUser", []() sysPrxForUser_sys_game_init(); sysPrxForUser_sys_libc_init(); + REG_VAR(sysPrxForUser, sys_prx_version); // 0x7df066cf + REG_FUNC(sysPrxForUser, sys_initialize_tls); REG_FUNC(sysPrxForUser, sys_time_get_system_time); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h b/rpcs3/Emu/Cell/Modules/sysPrxForUser.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sysPrxForUser.h rename to rpcs3/Emu/Cell/Modules/sysPrxForUser.h diff --git a/rpcs3/Emu/SysCalls/Modules/sys_game.cpp b/rpcs3/Emu/Cell/Modules/sys_game.cpp similarity index 91% rename from rpcs3/Emu/SysCalls/Modules/sys_game.cpp rename to rpcs3/Emu/Cell/Modules/sys_game.cpp index 413cd98b5c..1c2d47b368 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_game.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_game.cpp @@ -1,12 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/FS/VFS.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { @@ -70,18 +68,11 @@ void sys_game_process_exitspawn(vm::cptr path, u32 argv_addr, u32 envp_add Emu.Pause(); sysPrxForUser.success("Process finished"); - Emu.CallAfter([=]() + Emu.CallAfter([=, path = vfs::get(_path)]() { Emu.Stop(); - - std::string real_path; - - Emu.GetVFS().GetDevice(_path.c_str(), real_path); - - Emu.BootGame(real_path, true); + Emu.BootGame(path, true); }); - - return; } void sys_game_process_exitspawn2(vm::cptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) @@ -146,15 +137,10 @@ void sys_game_process_exitspawn2(vm::cptr path, u32 argv_addr, u32 envp_ad Emu.Pause(); sysPrxForUser.success("Process finished"); - Emu.CallAfter([=]() + Emu.CallAfter([=, path = vfs::get(_path)]() { Emu.Stop(); - - std::string real_path; - - Emu.GetVFS().GetDevice(_path.c_str(), real_path); - - Emu.BootGame(real_path, true); + Emu.BootGame(path, true); }); return; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_heap.cpp b/rpcs3/Emu/Cell/Modules/sys_heap.cpp similarity index 95% rename from rpcs3/Emu/SysCalls/Modules/sys_heap.cpp rename to rpcs3/Emu/Cell/Modules/sys_heap.cpp index cec953fdf1..13b344fd2f 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_heap.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_heap.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/IdManager.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/IdManager.h" +#include "Emu/Cell/PPUModule.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; struct HeapInfo { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/Cell/Modules/sys_io.cpp similarity index 88% rename from rpcs3/Emu/SysCalls/Modules/sys_io.cpp rename to rpcs3/Emu/Cell/Modules/sys_io.cpp index eb7888f151..11d2202e5d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_io.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -extern Module<> sys_io; +LOG_CHANNEL(sys_io); extern void cellPad_init(); extern void cellKb_init(); @@ -39,7 +39,7 @@ s32 sys_config_unregister_service() } -Module<> sys_io("sys_io", []() +DECLARE(ppu_module_manager::sys_io)("sys_io", []() { cellPad_init(); cellKb_init(); diff --git a/rpcs3/Emu/Cell/Modules/sys_libc.cpp b/rpcs3/Emu/Cell/Modules/sys_libc.cpp new file mode 100644 index 0000000000..74fabd32b0 --- /dev/null +++ b/rpcs3/Emu/Cell/Modules/sys_libc.cpp @@ -0,0 +1,24 @@ +#include "stdafx.h" +#include "Emu/System.h" +#include "Emu/Cell/PPUModule.h" +#include "Emu/Cell/PPUOpcodes.h" + +LOG_CHANNEL(sys_libc); + +namespace sys_libc_func +{ + void memcpy(vm::ptr dst, vm::cptr src, u32 size) + { + sys_libc.trace("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); + + ::memcpy(dst.get_ptr(), src.get_ptr(), size); + } +} + +// Define macro for namespace +#define REG_FUNC_(name) REG_FNID(sys_libc, ppu_generate_id(#name), sys_libc_func::name) + +DECLARE(ppu_module_manager::sys_libc)("sys_libc", []() +{ + REG_FUNC_(memcpy); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp similarity index 83% rename from rpcs3/Emu/SysCalls/Modules/sys_libc.cpp rename to rpcs3/Emu/Cell/Modules/sys_libc_.cpp index 0045cdf423..61f91faee2 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp @@ -1,12 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/Cell/PPUInstrTable.h" +#include "Emu/Cell/PPUModule.h" -extern Module<> sys_libc; +extern _log::channel sysPrxForUser; -std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_count, u32 v_count) +// TODO +static std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count) { std::string result; @@ -33,7 +31,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c if (*fmt == '*') { fmt++; - return context.get_next_gpr_arg(g_count, f_count, v_count); + return context.get_next_arg(g_count); } while (*fmt - '0' < 10) @@ -57,7 +55,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c if (*++fmt == '*') { fmt++; - return context.get_next_gpr_arg(g_count, f_count, v_count); + return context.get_next_arg(g_count); } while (*fmt - '0' < 10) @@ -81,7 +79,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c case 'i': { // signed decimal - const s64 value = context.get_next_gpr_arg(g_count, f_count, v_count); + const s64 value = context.get_next_arg(g_count); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -92,7 +90,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c case 'X': { // hexadecimal - const u64 value = context.get_next_gpr_arg(g_count, f_count, v_count); + const u64 value = context.get_next_arg(g_count); if (plus_sign || minus_sign || space_sign || prec) break; @@ -101,7 +99,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c result += cf == 'x' ? "0x" : "0X"; } - const std::string& hex = cf == 'x' ? fmt::to_hex(value) : fmt::toupper(fmt::to_hex(value)); + const std::string& hex = cf == 'x' ? fmt::to_hex(value) : fmt::to_upper(fmt::to_hex(value)); if (hex.length() >= width) { @@ -120,7 +118,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c case 's': { // string - auto string = vm::cptr::make(context.get_next_gpr_arg(g_count, f_count, v_count)); + auto string = vm::cptr::make(context.get_next_arg(g_count)); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -130,7 +128,7 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c case 'u': { // unsigned decimal - const u64 value = context.get_next_gpr_arg(g_count, f_count, v_count); + const u64 value = context.get_next_arg(g_count); if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break; @@ -149,18 +147,6 @@ std::string ps3_fmt(PPUThread& context, vm::cptr fmt, u32 g_count, u32 f_c return result; } -namespace sys_libc_func -{ - void memcpy(vm::ptr dst, vm::cptr src, u32 size) - { - sys_libc.trace("memcpy(dst=*0x%x, src=*0x%x, size=0x%x)", dst, src, size); - - ::memcpy(dst.get_ptr(), src.get_ptr(), size); - } -} - -extern Module<> sysPrxForUser; - vm::ptr _sys_memset(vm::ptr dst, s32 value, u32 size) { sysPrxForUser.trace("_sys_memset(dst=*0x%x, value=%d, size=0x%x)", dst, value, size); @@ -328,7 +314,7 @@ s32 _sys_snprintf(PPUThread& ppu, vm::ptr dst, u32 count, vm::cptr f { sysPrxForUser.warning("_sys_snprintf(dst=*0x%x, count=%d, fmt=*0x%x, ...)", dst, count, fmt); - std::string result = ps3_fmt(ppu, fmt, va_args.g_count, va_args.f_count, va_args.v_count); + std::string result = ps3_fmt(ppu, fmt, va_args.count); sysPrxForUser.warning("*** '%s' -> '%s'", fmt.get_ptr(), result); @@ -350,7 +336,7 @@ s32 _sys_printf(PPUThread& ppu, vm::cptr fmt, ppu_va_args_t va_args) { sysPrxForUser.warning("_sys_printf(fmt=*0x%x, ...)", fmt); - _log::g_tty_file.log(ps3_fmt(ppu, fmt, va_args.g_count, va_args.f_count, va_args.v_count)); + _log::g_tty_file.log(ps3_fmt(ppu, fmt, va_args.count)); return CELL_OK; } @@ -414,19 +400,3 @@ void sysPrxForUser_sys_libc_init() REG_FUNC(sysPrxForUser, _sys_qsort); } - -Module<> sys_libc("sys_libc", []() -{ - using namespace PPU_instr; - - REG_SUB(sys_libc, sys_libc_func, memcpy, - SP_I(CMPLDI(cr7, r5, 7)), - SP_I(CLRLDI(r3, r3, 32)), - SP_I(CLRLDI(r4, r4, 32)), - SP_I(MR(r11, r3)), - SP_I(BGT(cr7, XXX & 0xff)), - SP_I(CMPDI(r5, 0)), - OPT_SP_I(MR(r9, r3)), - { SPET_MASKED_OPCODE, 0x4d820020, 0xffffffff }, - ); -}); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp rename to rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp index c2c0fbf4bf..791e29ceed 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sys_lv2dbg.h" -extern Module<> sys_lv2dbg; +LOG_CHANNEL(sys_lv2dbg); s32 sys_dbg_read_ppu_thread_context(u64 id, vm::ptr ppu_context) { @@ -190,7 +189,7 @@ s32 sys_dbg_set_mask_to_ppu_exception_handler(u64 mask, u64 flags) throw EXCEPTION(""); } -Module<> sys_lv2dbg("sys_lv2dbg", [] +DECLARE(ppu_module_manager::sys_lv2dbg)("sys_lv2dbg", [] { REG_FUNC(sys_lv2dbg, sys_dbg_read_ppu_thread_context); REG_FUNC(sys_lv2dbg, sys_dbg_read_spu_thread_context); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.h similarity index 95% rename from rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h rename to rpcs3/Emu/Cell/Modules/sys_lv2dbg.h index 5661690945..e9a30c19fd 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lv2dbg.h +++ b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.h @@ -1,13 +1,13 @@ #pragma once -#include "Emu/SysCalls/lv2/sys_mutex.h" -#include "Emu/SysCalls/lv2/sys_cond.h" -#include "Emu/SysCalls/lv2/sys_rwlock.h" -#include "Emu/SysCalls/lv2/sys_event.h" -#include "Emu/SysCalls/lv2/sys_semaphore.h" -#include "Emu/SysCalls/lv2/sys_lwmutex.h" -#include "Emu/SysCalls/lv2/sys_lwcond.h" -#include "Emu/SysCalls/lv2/sys_event_flag.h" +#include "Emu/Cell/lv2/sys_mutex.h" +#include "Emu/Cell/lv2/sys_cond.h" +#include "Emu/Cell/lv2/sys_rwlock.h" +#include "Emu/Cell/lv2/sys_event.h" +#include "Emu/Cell/lv2/sys_semaphore.h" +#include "Emu/Cell/lv2/sys_lwmutex.h" +#include "Emu/Cell/lv2/sys_lwcond.h" +#include "Emu/Cell/lv2/sys_event_flag.h" namespace vm { using namespace ps3; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp similarity index 94% rename from rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp rename to rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index 8f6577dec7..d3bf78062c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -1,15 +1,13 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/IdManager.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_sync.h" -#include "Emu/SysCalls/lv2/sys_lwmutex.h" -#include "Emu/SysCalls/lv2/sys_lwcond.h" +#include "Emu/Cell/lv2/sys_lwmutex.h" +#include "Emu/Cell/lv2/sys_lwcond.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; s32 sys_lwcond_create(vm::ptr lwcond, vm::ptr lwmutex, vm::ptr attr) { @@ -47,7 +45,7 @@ s32 sys_lwcond_signal(PPUThread& ppu, vm::ptr lwcond) //return _sys_lwcond_signal(lwcond->lwcond_queue, 0, -1, 2); } - if (lwmutex->vars.owner.load() == ppu.get_id()) + if (lwmutex->vars.owner.load() == ppu.id) { // if owns the mutex lwmutex->all_info++; @@ -105,7 +103,7 @@ s32 sys_lwcond_signal_all(PPUThread& ppu, vm::ptr lwcond) //return _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 2); } - if (lwmutex->vars.owner.load() == ppu.get_id()) + if (lwmutex->vars.owner.load() == ppu.id) { // if owns the mutex, call the syscall const s32 res = _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 1); @@ -162,7 +160,7 @@ s32 sys_lwcond_signal_to(PPUThread& ppu, vm::ptr lwcond, u32 ppu_t //return _sys_lwcond_signal(lwcond->lwcond_queue, 0, ppu_thread_id, 2); } - if (lwmutex->vars.owner.load() == ppu.get_id()) + if (lwmutex->vars.owner.load() == ppu.id) { // if owns the mutex lwmutex->all_info++; @@ -212,7 +210,7 @@ s32 sys_lwcond_wait(PPUThread& ppu, vm::ptr lwcond, u64 timeout) { sysPrxForUser.trace("sys_lwcond_wait(lwcond=*0x%x, timeout=0x%llx)", lwcond, timeout); - const be_t tid = ppu.get_id(); + const be_t tid = ppu.id; const vm::ptr lwmutex = lwcond->lwmutex; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp similarity index 94% rename from rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp rename to rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 347c180077..7e2e9fad4c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -2,13 +2,12 @@ #include "Emu/Memory/Memory.h" #include "Emu/IdManager.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_sync.h" -#include "Emu/SysCalls/lv2/sys_lwmutex.h" +#include "Emu/Cell/lv2/sys_lwmutex.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptr attr) { @@ -45,7 +44,7 @@ s32 sys_lwmutex_destroy(PPUThread& ppu, vm::ptr lwmutex) sysPrxForUser.trace("sys_lwmutex_destroy(lwmutex=*0x%x)", lwmutex); // check to prevent recursive locking in the next call - if (lwmutex->vars.owner.load() == ppu.get_id()) + if (lwmutex->vars.owner.load() == ppu.id) { return CELL_EBUSY; } @@ -75,7 +74,7 @@ s32 sys_lwmutex_lock(PPUThread& ppu, vm::ptr lwmutex, u64 timeout { sysPrxForUser.trace("sys_lwmutex_lock(lwmutex=*0x%x, timeout=0x%llx)", lwmutex, timeout); - const be_t tid = ppu.get_id(); + const be_t tid = ppu.id; // try to lock lightweight mutex const be_t old_owner = lwmutex->vars.owner.compare_and_swap(lwmutex_free, tid); @@ -169,7 +168,7 @@ s32 sys_lwmutex_trylock(PPUThread& ppu, vm::ptr lwmutex) { sysPrxForUser.trace("sys_lwmutex_trylock(lwmutex=*0x%x)", lwmutex); - const be_t tid = ppu.get_id(); + const be_t tid = ppu.id; // try to lock lightweight mutex const be_t old_owner = lwmutex->vars.owner.compare_and_swap(lwmutex_free, tid); @@ -236,7 +235,7 @@ s32 sys_lwmutex_unlock(PPUThread& ppu, vm::ptr lwmutex) { sysPrxForUser.trace("sys_lwmutex_unlock(lwmutex=*0x%x)", lwmutex); - const be_t tid = ppu.get_id(); + const be_t tid = ppu.id; // check owner if (lwmutex->vars.owner.load() != tid) diff --git a/rpcs3/Emu/SysCalls/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/Modules/sys_mempool.cpp rename to rpcs3/Emu/Cell/Modules/sys_mempool.cpp index 60851eacb8..99763b4b1f 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; using sys_mempool_t = u32; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_mmapper_.cpp b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp similarity index 76% rename from rpcs3/Emu/SysCalls/Modules/sys_mmapper_.cpp rename to rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp index 5a2c59c300..37830aea71 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_mmapper_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_mmapper.h" +#include "Emu/Cell/lv2/sys_mmapper.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; void sysPrxForUser_sys_mmapper_init() { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/Cell/Modules/sys_net.cpp similarity index 97% rename from rpcs3/Emu/SysCalls/Modules/sys_net.cpp rename to rpcs3/Emu/Cell/Modules/sys_net.cpp index 35456c6a65..9ebd8d7e4b 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_net.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sys_net.h" @@ -9,7 +8,6 @@ #define _WIN32_WINNT 0x0601 #include #include -#pragma comment(lib, "ws2_32.lib") #else #include #include @@ -18,7 +16,7 @@ #include #endif -extern Module<> libnet; +LOG_CHANNEL(libnet); // We map host sockets to sequential IDs to return as FDs because syscalls using // socketselect(), etc. expect socket FDs to be under 1024. @@ -622,10 +620,10 @@ namespace sys_net } } -// define additional macro for specific namespace -#define REG_FUNC_(name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &libnet, #name, BIND_FUNC(sys_net::name))) +// Define macro for namespace +#define REG_FUNC_(name) REG_FNID(sys_net, ppu_generate_id(#name), sys_net::name) -Module<> libnet("sys_net", []() +DECLARE(ppu_module_manager::libnet)("sys_net", []() { REG_FUNC_(accept); REG_FUNC_(bind); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.h b/rpcs3/Emu/Cell/Modules/sys_net.h similarity index 100% rename from rpcs3/Emu/SysCalls/Modules/sys_net.h rename to rpcs3/Emu/Cell/Modules/sys_net.h diff --git a/rpcs3/Emu/SysCalls/Modules/sys_ppu_thread_.cpp b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp similarity index 72% rename from rpcs3/Emu/SysCalls/Modules/sys_ppu_thread_.cpp rename to rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp index a22edcc521..f339fa8407 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_ppu_thread_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp @@ -1,28 +1,35 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_ppu_thread.h" +#include "Emu/Cell/lv2/sys_ppu_thread.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; + +extern u32 ppu_alloc_tls(); +extern void ppu_free_tls(u32 addr); s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::cptr threadname) { - sysPrxForUser.warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); + sysPrxForUser.warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", + thread_id, entry, arg, prio, stacksize, flags, threadname); - // (allocate TLS) - // (return CELL_ENOMEM if failed) - // ... + // Allocate TLS + const u32 tls_addr = ppu_alloc_tls(); - // call the syscall - if (s32 res = _sys_ppu_thread_create(thread_id, vm::make_var(ppu_thread_param_t{ entry, 0 }), arg, 0, prio, stacksize, flags, threadname)) + if (!tls_addr) + { + return CELL_ENOMEM; + } + + // Call the syscall + if (s32 res = _sys_ppu_thread_create(thread_id, vm::make_var(ppu_thread_param_t{ entry, tls_addr + 0x7030 }), arg, 0, prio, stacksize, flags, threadname)) { return res; } - // run the thread + // Run the thread return flags & SYS_PPU_THREAD_CREATE_INTERRUPT ? CELL_OK : sys_ppu_thread_start(static_cast(*thread_id)); } @@ -30,7 +37,7 @@ s32 sys_ppu_thread_get_id(PPUThread& ppu, vm::ptr thread_id) { sysPrxForUser.trace("sys_ppu_thread_get_id(thread_id=*0x%x)", thread_id); - *thread_id = ppu.get_id(); + *thread_id = ppu.id; return CELL_OK; } @@ -40,13 +47,15 @@ void sys_ppu_thread_exit(PPUThread& ppu, u64 val) sysPrxForUser.trace("sys_ppu_thread_exit(val=0x%llx)", val); // (call registered atexit functions) - // (deallocate TLS) // ... + + // Deallocate TLS + ppu_free_tls(vm::cast(ppu.GPR[13], HERE) - 0x7030); - if (ppu.hle_code == 0xaff080a4) + if (ppu.GPR[3] == val && !ppu.custom_task) { - // Change sys_ppu_thread_exit code to the syscall code - ppu.hle_code = ~41; + // Change sys_ppu_thread_exit code to the syscall code (hack) + ppu.GPR[11] = 41; } // Call the syscall diff --git a/rpcs3/Emu/SysCalls/Modules/sys_prx_.cpp b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp similarity index 90% rename from rpcs3/Emu/SysCalls/Modules/sys_prx_.cpp rename to rpcs3/Emu/Cell/Modules/sys_prx_.cpp index 0ad64dc4ad..1b2fac8523 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_prx_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" -#include "Emu/SysCalls/lv2/sys_prx.h" +#include "Emu/Cell/lv2/sys_prx.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; s64 sys_prx_exitspawn_with_level() { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_spinlock.cpp b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp similarity index 92% rename from rpcs3/Emu/SysCalls/Modules/sys_spinlock.cpp rename to rpcs3/Emu/Cell/Modules/sys_spinlock.cpp index 50bc095695..42397477b7 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_spinlock.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp @@ -1,11 +1,10 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; void sys_spinlock_initialize(vm::ptr> lock) { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp similarity index 78% rename from rpcs3/Emu/SysCalls/Modules/sys_spu_.cpp rename to rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 4d859a9739..3d2c0e6863 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -1,15 +1,13 @@ #include "stdafx.h" -#include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUModule.h" #include "Emu/Cell/RawSPUThread.h" -#include "Emu/SysCalls/lv2/sys_spu.h" -#include "Emu/FS/vfsFile.h" +#include "Emu/Cell/lv2/sys_spu.h" #include "Crypto/unself.h" #include "sysPrxForUser.h" -extern Module<> sysPrxForUser; +extern _log::channel sysPrxForUser; extern u64 get_system_time(); @@ -30,17 +28,38 @@ s32 sys_spu_elf_get_segments(u32 elf_img, vm::ptr segments, s32 return CELL_OK; } -s32 sys_spu_image_import(vm::ptr img, u32 src, u32 type) +s32 sys_spu_image_import(vm::ptr img, u32 src, u32 type) { sysPrxForUser.warning("sys_spu_image_import(img=*0x%x, src=0x%x, type=%d)", img, src, type); - return spu_image_import(*img, src, type); + u32 entry, offset = LoadSpuImage(fs::file(vm::base(src), 0 - src), entry); + + img->type = SYS_SPU_IMAGE_TYPE_USER; + img->entry_point = entry; + img->segs.set(offset); // TODO: writing actual segment info + img->nsegs = 1; // wrong value + + return CELL_OK; } -s32 sys_spu_image_close(vm::ptr img) +s32 sys_spu_image_close(vm::ptr img) { - sysPrxForUser.todo("sys_spu_image_close(img=*0x%x)", img); + sysPrxForUser.warning("sys_spu_image_close(img=*0x%x)", img); + if (img->type == SYS_SPU_IMAGE_TYPE_USER) + { + //_sys_free(img->segs.addr()); + } + else if (img->type == SYS_SPU_IMAGE_TYPE_KERNEL) + { + //return syscall_158(img); + } + else + { + return CELL_EINVAL; + } + + ASSERT(vm::dealloc(img->segs.addr(), vm::main)); // Current rough implementation return CELL_OK; } @@ -49,10 +68,10 @@ s32 sys_raw_spu_load(s32 id, vm::cptr path, vm::ptr entry) sysPrxForUser.warning("sys_raw_spu_load(id=%d, path=*0x%x, entry=*0x%x)", id, path, entry); sysPrxForUser.warning("*** path = '%s'", path.get_ptr()); - vfsFile f(path.get_ptr()); - if (!f.IsOpened()) + const fs::file f(vfs::get(path.get_ptr())); + if (!f) { - sysPrxForUser.error("sys_raw_spu_load error: '%s' not found!", path.get_ptr()); + sysPrxForUser.error("sys_raw_spu_load() error: '%s' not found!", path.get_ptr()); return CELL_ENOENT; } @@ -61,12 +80,10 @@ s32 sys_raw_spu_load(s32 id, vm::cptr path, vm::ptr entry) if (hdr.CheckMagic()) { - sysPrxForUser.error("sys_raw_spu_load error: '%s' is encrypted! Decrypt SELF and try again.", path.get_ptr()); - Emu.Pause(); - return CELL_ENOENT; + throw fmt::exception("sys_raw_spu_load() error: '%s' is encrypted! Try to decrypt it manually and try again.", path.get_ptr()); } - f.Seek(0); + f.seek(0); u32 _entry; LoadSpuImage(f, _entry, RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id); @@ -76,7 +93,7 @@ s32 sys_raw_spu_load(s32 id, vm::cptr path, vm::ptr entry) return CELL_OK; } -s32 sys_raw_spu_image_load(PPUThread& ppu, s32 id, vm::ptr img) +s32 sys_raw_spu_image_load(PPUThread& ppu, s32 id, vm::ptr img) { sysPrxForUser.warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img); @@ -84,7 +101,7 @@ s32 sys_raw_spu_image_load(PPUThread& ppu, s32 id, vm::ptr img) const auto stamp0 = get_system_time(); - std::memcpy(vm::base(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), vm::base(img->addr), 256 * 1024); + std::memcpy(vm::base(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), img->segs.get_ptr(), 256 * 1024); const auto stamp1 = get_system_time(); @@ -173,11 +190,6 @@ s32 _sys_spu_printf_detach_thread(PPUThread& ppu, u32 thread) void sysPrxForUser_sys_spu_init() { - g_spu_printf_agcb = vm::null; - g_spu_printf_dgcb = vm::null; - g_spu_printf_atcb = vm::null; - g_spu_printf_dtcb = vm::null; - REG_FUNC(sysPrxForUser, sys_spu_elf_get_information); REG_FUNC(sysPrxForUser, sys_spu_elf_get_segments); REG_FUNC(sysPrxForUser, sys_spu_image_import); diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp deleted file mode 100644 index 06b3a66917..0000000000 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ /dev/null @@ -1,343 +0,0 @@ -#include "stdafx.h" -#include "Modules.h" -#include "ModuleManager.h" - -extern Module<> cellAdec; -extern Module<> cellAtrac; -extern Module<> cellAtracMulti; -extern Module<> cellAudio; -extern Module<> cellAvconfExt; -extern Module<> cellBGDL; -extern Module<> cellCamera; -extern Module<> cellCelp8Enc; -extern Module<> cellCelpEnc; -extern Module<> cellDaisy; -extern Module<> cellDmux; -extern Module<> cellFiber; -extern Module<> cellFont; -extern Module<> cellFontFT; -extern Module<> cellFs; -extern Module<> cellGame; -extern Module<> cellGameExec; -extern Module<> cellGcmSys; -extern Module<> cellGem; -extern Module<> cellGifDec; -extern Module<> cellHttp; -extern Module<> cellHttps; -extern Module<> cellHttpUtil; -extern Module<> cellImeJp; -extern Module<> cellJpgDec; -extern Module<> cellJpgEnc; -extern Module<> cellKey2char; -extern Module<> cellL10n; -extern Module<> cellMic; -extern Module<> cellMusic; -extern Module<> cellMusicDecode; -extern Module<> cellMusicExport; -extern Module<> cellNetCtl; -extern Module<> cellOskDialog; -extern Module<> cellOvis; -extern Module<> cellPamf; -extern Module<> cellPhotoDecode; -extern Module<> cellPhotoExport; -extern Module<> cellPhotoImportUtil; -extern Module<> cellPngDec; -extern Module<> cellPngEnc; -extern Module<> cellPrint; -extern Module<> cellRec; -extern Module<> cellRemotePlay; -extern Module<> cellResc; -extern Module<> cellRtc; -extern Module<> cellRudp; -extern Module<> cellSail; -extern Module<> cellSailRec; -extern Module<> cellSaveData; -extern Module<> cellMinisSaveData; -extern Module<> cellScreenshot; -extern Module<> cellSearch; -extern Module<> cellSheap; -extern Module<> cellSpudll; -extern Module<> cellSpurs; -extern Module<> cellSpursJq; -extern Module<> cellSsl; -extern Module<> cellSubdisplay; -extern Module<> cellSync; -extern Module cellSync2; -extern Module<> cellSysconf; -extern Module<> cellSysmodule; -extern Module<> cellSysutil; -extern Module<> cellSysutilAp; -extern Module<> cellSysutilAvc; -extern Module<> cellSysutilAvc2; -extern Module<> cellSysutilMisc; -extern Module<> cellUsbd; -extern Module<> cellUsbPspcm; -extern Module<> cellUserInfo; -extern Module<> cellVdec; -extern Module<> cellVideoExport; -extern Module<> cellVideoUpload; -extern Module<> cellVoice; -extern Module<> cellVpost; -extern Module<> libmixer; -extern Module<> libsnd3; -extern Module<> libsynth2; -extern Module<> sceNp; -extern Module<> sceNp2; -extern Module<> sceNpClans; -extern Module<> sceNpCommerce2; -extern Module<> sceNpSns; -extern Module<> sceNpTrophy; -extern Module<> sceNpTus; -extern Module<> sceNpUtil; -extern Module<> sys_io; -extern Module<> libnet; -extern Module<> sysPrxForUser; -extern Module<> sys_libc; -extern Module<> sys_lv2dbg; - -struct ModuleInfo -{ - const s32 id; // -1 if the module doesn't have corresponding CELL_SYSMODULE_* id - const char* const name; - Module<>* const module; - - explicit operator bool() const - { - return module != nullptr; - } - - operator Module<>*() const - { - return module; - } - - Module<>* operator ->() const - { - return module; - } -} -const g_module_list[] = -{ - { 0x0000, "sys_net", &libnet }, - { 0x0001, "cellHttp", &cellHttp }, - { 0x0002, "cellHttpUtil", &cellHttpUtil }, - { 0x0003, "cellSsl", &cellSsl }, - { 0x0004, "cellHttps", &cellHttps }, - { 0x0005, "libvdec", &cellVdec }, - { 0x0006, "cellAdec", &cellAdec }, - { 0x0007, "cellDmux", &cellDmux }, - { 0x0008, "cellVpost", &cellVpost }, - { 0x0009, "cellRtc", &cellRtc }, - { 0x000a, "cellSpurs", &cellSpurs }, - { 0x000b, "cellOvis", &cellOvis }, - { 0x000c, "cellSheap", &cellSheap }, - { 0x000d, "cellSync", &cellSync }, - { 0x000e, "sys_fs", &cellFs }, - { 0x000f, "cellJpgDec", &cellJpgDec }, - { 0x0010, "cellGcmSys", &cellGcmSys }, - { 0x0011, "cellAudio", &cellAudio }, - { 0x0012, "cellPamf", &cellPamf }, - { 0x0013, "cellAtrac", &cellAtrac }, - { 0x0014, "cellNetCtl", &cellNetCtl }, - { 0x0015, "cellSysutil", &cellSysutil }, - { 0x0016, "sceNp", &sceNp }, - { 0x0017, "sys_io", &sys_io }, - { 0x0018, "cellPngDec", &cellPngDec }, - { 0x0019, "cellFont", &cellFont }, - { 0x001a, "cellFontFT", &cellFontFT }, - { 0x001b, "cell_FreeType2", nullptr }, - { 0x001c, "cellUsbd", &cellUsbd }, - { 0x001d, "cellSail", &cellSail }, - { 0x001e, "cellL10n", &cellL10n }, - { 0x001f, "cellResc", &cellResc }, - { 0x0020, "cellDaisy", &cellDaisy }, - { 0x0021, "cellKey2char", &cellKey2char }, - { 0x0022, "cellMic", &cellMic }, - { 0x0023, "cellCamera", &cellCamera }, - { 0x0024, "cellVdecMpeg2", nullptr }, - { 0x0025, "cellVdecAvc", nullptr }, - { 0x0026, "cellAdecLpcm", nullptr }, - { 0x0027, "cellAdecAc3", nullptr }, - { 0x0028, "cellAdecAtx", nullptr }, - { 0x0029, "cellAdecAt3", nullptr }, - { 0x002a, "cellDmuxPamf", nullptr }, - { 0x002b, "?", nullptr }, - { 0x002c, "?", nullptr }, - { 0x002d, "?", nullptr }, - { 0x002e, "sys_lv2dbg", &sys_lv2dbg }, - { 0x002f, "cellSysutilAvcExt", &cellSysutilAvc }, - { 0x0030, "cellUsbPspcm", &cellUsbPspcm }, - { 0x0031, "cellSysutilAvconfExt", &cellAvconfExt }, - { 0x0032, "cellUserInfo", &cellUserInfo }, - { 0x0033, "cellSaveData", &cellSaveData }, - { 0x0034, "cellSubDisplay", &cellSubdisplay }, - { 0x0035, "cellRec", &cellRec }, - { 0x0036, "cellVideoExportUtility", &cellVideoExport }, - { 0x0037, "cellGameExec", &cellGameExec }, - { 0x0038, "sceNp2", &sceNp2 }, - { 0x0039, "cellSysutilAp", &cellSysutilAp }, - { 0x003a, "sceNpClans", &sceNpClans }, - { 0x003b, "cellOskExtUtility", &cellOskDialog }, - { 0x003c, "cellVdecDivx", nullptr }, - { 0x003d, "cellJpgEnc", &cellJpgEnc }, - { 0x003e, "cellGame", &cellGame }, - { 0x003f, "cellBGDLUtility", &cellBGDL }, - { 0x0040, "cell_FreeType2", nullptr }, - { 0x0041, "cellVideoUpload", &cellVideoUpload }, - { 0x0042, "cellSysconfExtUtility", &cellSysconf }, - { 0x0043, "cellFiber", &cellFiber }, - { 0x0044, "sceNpCommerce2", &sceNpCommerce2 }, - { 0x0045, "sceNpTus", &sceNpTus }, - { 0x0046, "cellVoice", &cellVoice }, - { 0x0047, "cellAdecCelp8", nullptr }, - { 0x0048, "cellCelp8Enc", &cellCelp8Enc }, - { 0x0049, "cellSysutilMisc", &cellSysutilMisc }, - { 0x004a, "cellMusicUtility", &cellMusic }, // 2 - { 0x004e, "cellScreenShotUtility", &cellScreenshot }, - { 0x004f, "cellMusicDecodeUtility", &cellMusicDecode }, - { 0x0050, "cellSpursJq", &cellSpursJq }, - { 0x0052, "cellPngEnc", &cellPngEnc }, - { 0x0053, "cellMusicDecodeUtility", &cellMusicDecode }, // 2 - { 0x0055, "cellSync2", &cellSync2 }, - { 0x0056, "sceNpUtil", &sceNpUtil }, - { 0x0057, "cellRudp", &cellRudp }, - { 0x0059, "sceNpSns", &sceNpSns }, - { 0x005a, "libgem", &cellGem }, - { 0xf00a, "cellCelpEnc", &cellCelpEnc }, - { 0xf010, "cellGifDec", &cellGifDec }, - { 0xf019, "cellAdecCelp", nullptr }, - { 0xf01b, "cellAdecM2bc", nullptr }, - { 0xf01d, "cellAdecM4aac", nullptr }, - { 0xf01e, "cellAdecMp3", nullptr }, - { 0xf023, "cellImeJpUtility", &cellImeJp }, - { 0xf028, "cellMusicUtility", &cellMusic }, - { 0xf029, "cellPhotoUtility", &cellPhotoExport }, - { 0xf02a, "cellPrintUtility", &cellPrint }, - { 0xf02b, "cellPhotoImportUtil", &cellPhotoImportUtil }, - { 0xf02c, "cellMusicExportUtility", &cellMusicExport }, - { 0xf02e, "cellPhotoDecodeUtil", &cellPhotoDecode }, - { 0xf02f, "cellSearchUtility", &cellSearch }, - { 0xf030, "cellSysutilAvc2", &cellSysutilAvc2 }, - { 0xf034, "cellSailRec", &cellSailRec }, - { 0xf035, "sceNpTrophy", &sceNpTrophy }, - { 0xf053, "cellAdecAt3multi", nullptr }, - { 0xf054, "cellAtracMulti", &cellAtracMulti }, - - { -1, "cellSysmodule", &cellSysmodule }, - { -1, "libmixer", &libmixer }, - { -1, "sysPrxForUser", &sysPrxForUser }, - { -1, "sys_libc", &sys_libc }, - { -1, "cellMinisSaveData", &cellMinisSaveData }, - { -1, "cellSpudll", &cellSpudll }, - { -1, "cellRemotePlay", &cellRemotePlay }, - { -1, "libsnd3", &libsnd3 }, - { -1, "libsynth2", &libsynth2 }, -}; - -void ModuleManager::Init() -{ - if (m_init) - { - Close(); - } - - clear_ppu_functions(); - - std::unordered_set*> processed; - - for (auto& module : g_module_list) - { - if (module && processed.emplace(module).second) - { - module->Init(); - } - } - - m_init = true; -} - -ModuleManager::ModuleManager() -{ -} - -ModuleManager::~ModuleManager() -{ - Close(); -} - -void ModuleManager::Close() -{ - if (!m_init) - { - return; - } - - std::unordered_set*> processed; - - for (auto& module : g_module_list) - { - if (module && module->on_stop && processed.emplace(module).second) - { - module->on_stop(); - } - } - - m_init = false; -} - -void ModuleManager::Alloc() -{ - if (!m_init) - { - return; - } - - std::unordered_set*> processed; - - for (auto& module : g_module_list) - { - if (module && module->on_alloc && processed.emplace(module).second) - { - module->on_alloc(); - } - } -} - -Module<>* ModuleManager::GetModuleByName(const char* name) -{ - for (auto& module : g_module_list) - { - if (!strcmp(name, module.name)) - { - return module; - } - } - - return nullptr; -} - -Module<>* ModuleManager::GetModuleById(u16 id) -{ - for (auto& module : g_module_list) - { - if (module.id == id) - { - return module; - } - } - - return nullptr; -} - -bool ModuleManager::CheckModuleId(u16 id) -{ - for (auto& module : g_module_list) - { - if (module.id == id) - { - return true; - } - } - - return false; -} diff --git a/rpcs3/Emu/SysCalls/ModuleManager.h b/rpcs3/Emu/SysCalls/ModuleManager.h deleted file mode 100644 index 593f278b3a..0000000000 --- a/rpcs3/Emu/SysCalls/ModuleManager.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -template class Module; - -class ModuleManager -{ - bool m_init = false; - -public: - ModuleManager(); - ~ModuleManager(); - - void Init(); - void Close(); - void Alloc(); - - static Module* GetModuleByName(const char* name); - static Module* GetModuleById(u16 id); - static bool CheckModuleId(u16 id); -}; diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp deleted file mode 100644 index 744dfc95bb..0000000000 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ /dev/null @@ -1,576 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/state.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/SysCalls/SysCalls.h" -#include "Crypto/sha1.h" -#include "ModuleManager.h" -#include "Emu/Cell/PPUInstrTable.h" - -std::vector g_ppu_func_list; -std::vector g_ppu_func_subs; -std::vector g_ps3_var_list; - -u32 add_ppu_func(ModuleFunc func) -{ - if (g_ppu_func_list.empty()) - { - // prevent relocations if the array growths, must be sizeof(ModuleFunc) * 0x8000 ~~ about 1 MB of memory - g_ppu_func_list.reserve(0x8000); - } - - for (auto& f : g_ppu_func_list) - { - if (f.id == func.id) - { - // if NIDs overlap or if the same function is added twice - throw EXCEPTION("FNID already exists: 0x%08x (%s)", f.id, f.name); - } - } - - g_ppu_func_list.emplace_back(std::move(func)); - return (u32)g_ppu_func_list.size() - 1; -} - -void add_variable(u32 nid, Module<>* module, const char* name, u32(*addr)()) -{ - if (g_ps3_var_list.empty()) - { - g_ps3_var_list.reserve(0x4000); // as g_ppu_func_list - } - - for (auto& v : g_ps3_var_list) - { - if (v.id == nid) - { - throw EXCEPTION("VNID already exists: 0x%08x (%s)", nid, name); - } - } - - g_ps3_var_list.emplace_back(ModuleVariable{ nid, module, name, addr }); -} - -ModuleVariable* get_variable_by_nid(u32 nid) -{ - for (auto& v : g_ps3_var_list) - { - if (v.id == nid) - { - return &v; - } - } - - return nullptr; -} - -u32 add_ppu_func_sub(StaticFunc func) -{ - g_ppu_func_subs.emplace_back(func); - return func.index; -} - -u32 add_ppu_func_sub(const std::initializer_list& ops, const char* name, Module<>* module, ppu_func_caller func) -{ - StaticFunc sf; - sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, name, func)); - sf.name = name; - sf.found = 0; - sf.ops = ops; - - return add_ppu_func_sub(std::move(sf)); -} - -ModuleFunc* get_ppu_func_by_nid(u32 nid, u32* out_index) -{ - for (auto& f : g_ppu_func_list) - { - if (f.id == nid) - { - if (out_index) - { - *out_index = (u32)(&f - g_ppu_func_list.data()); - } - - return &f; - } - } - - return nullptr; -} - -ModuleFunc* get_ppu_func_by_index(u32 index) -{ - index &= ~EIF_FLAGS; - - if (index >= g_ppu_func_list.size()) - { - return nullptr; - } - - return &g_ppu_func_list[index]; -} - -void execute_ppu_func_by_index(PPUThread& ppu, u32 index) -{ - if (auto func = get_ppu_func_by_index(index)) - { - // save RTOC if necessary - if (index & EIF_SAVE_RTOC) - { - vm::write64(VM_CAST(ppu.GPR[1] + 0x28), ppu.GPR[2]); - } - - // save old syscall/NID value - const auto last_code = ppu.hle_code; - - // branch directly to the LLE function - if (index & EIF_USE_BRANCH) - { - // for example, FastCall2 can't work with functions which do user level context switch - - if (last_code) - { - throw EXCEPTION("This function cannot be called from the callback: %s (0x%llx)", get_ps3_function_name(func->id), func->id); - } - - if (!func->lle_func) - { - throw EXCEPTION("LLE function not set: %s (0x%llx)", get_ps3_function_name(func->id), func->id); - } - - if (func->flags & MFF_FORCED_HLE) - { - throw EXCEPTION("Forced HLE enabled: %s (0x%llx)", get_ps3_function_name(func->id), func->id); - } - - LOG_TRACE(HLE, "Branch to LLE function: %s (0x%llx)", get_ps3_function_name(func->id), func->id); - - if (index & EIF_PERFORM_BLR) - { - throw EXCEPTION("TODO: Branch with link: %s (0x%llx)", get_ps3_function_name(func->id), func->id); - // CPU.LR = CPU.PC + 4; - } - - const auto data = vm::_ptr(func->lle_func.addr()); - ppu.PC = data[0] - 4; - ppu.GPR[2] = data[1]; // set rtoc - - return; - } - - // change current syscall/NID value - ppu.hle_code = func->id; - - if (func->lle_func && !(func->flags & MFF_FORCED_HLE)) - { - // call LLE function if available - - const auto data = vm::_ptr(func->lle_func.addr()); - const u32 pc = data[0]; - const u32 rtoc = data[1]; - - LOG_TRACE(HLE, "LLE function called: %s", get_ps3_function_name(func->id)); - - ppu.fast_call(pc, rtoc); - - LOG_TRACE(HLE, "LLE function finished: %s -> 0x%llx", get_ps3_function_name(func->id), ppu.GPR[3]); - } - else if (func->func) - { - LOG_TRACE(HLE, "HLE function called: %s", get_ps3_function_name(func->id)); - - func->func(ppu); - - LOG_TRACE(HLE, "HLE function finished: %s -> 0x%llx", get_ps3_function_name(func->id), ppu.GPR[3]); - } - else - { - LOG_TODO(HLE, "Unimplemented function: %s -> CELL_OK", get_ps3_function_name(func->id)); - ppu.GPR[3] = 0; - } - - if (index & EIF_PERFORM_BLR) - { - // return if necessary - ppu.PC = VM_CAST(ppu.LR & ~3) - 4; - } - - // execute module-specific error check - if ((s64)ppu.GPR[3] < 0 && func->module && func->module->on_error) - { - func->module->on_error(ppu.GPR[3], func); - } - - ppu.hle_code = last_code; - } - else - { - throw EXCEPTION("Invalid function index (0x%x)", index); - } -} - -void clear_ppu_functions() -{ - g_ppu_func_list.clear(); - g_ppu_func_subs.clear(); - g_ps3_var_list.clear(); -} - -u32 get_function_id(const char* name) -{ - const char* suffix = "\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A"; // Symbol name suffix - u8 output[20]; - - // Compute SHA-1 hash - sha1_context ctx; - - sha1_starts(&ctx); - sha1_update(&ctx, (const u8*)name, strlen(name)); - sha1_update(&ctx, (const u8*)suffix, strlen(suffix)); - sha1_finish(&ctx, output); - - return (u32&)output[0]; -} - -void hook_ppu_func(vm::ptr base, u32 pos, u32 size) -{ - using namespace PPU_instr; - - for (auto& sub : g_ppu_func_subs) - { - bool found = sub.ops.size() != 0; - - for (u32 k = pos, x = 0; x + 1 <= sub.ops.size(); k++, x++) - { - if (k >= size) - { - found = false; - break; - } - - // skip NOP - if (base[k] == 0x60000000) - { - x--; - continue; - } - - const be_t data = sub.ops[x].data; - const be_t mask = sub.ops[x].mask; - - const bool match = (base[k] & mask) == data; - - switch (sub.ops[x].type) - { - case SPET_MASKED_OPCODE: - { - // masked pattern - if (!match) - { - found = false; - } - - break; - } - case SPET_OPTIONAL_MASKED_OPCODE: - { - // optional masked pattern - if (!match) - { - k--; - } - - break; - } - case SPET_LABEL: - { - const u32 addr = (base + k--).addr(); - const u32 lnum = data; - const auto label = sub.labels.find(lnum); - - if (label == sub.labels.end()) // register the label - { - sub.labels[lnum] = addr; - } - else if (label->second != addr) // or check registered label - { - found = false; - } - - break; - } - case SPET_BRANCH_TO_LABEL: - { - if (!match) - { - found = false; - break; - } - - const auto addr = (base[k] & 2 ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); - const auto lnum = sub.ops[x].num; - const auto label = sub.labels.find(lnum); - - if (label == sub.labels.end()) // register the label - { - sub.labels[lnum] = addr; - } - else if (label->second != addr) // or check registered label - { - found = false; - } - - break; - } - //case SPET_BRANCH_TO_FUNC: - //{ - // if (!match) - // { - // found = false; - // break; - // } - - // const auto addr = (base[k] & 2 ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); - // const auto nid = sub.ops[x].num; - // // TODO: recursive call - //} - default: - { - throw EXCEPTION("Unknown search pattern type (%d)", sub.ops[x].type); - } - } - - if (!found) - { - break; - } - } - - if (found) - { - LOG_SUCCESS(LOADER, "Function '%s' hooked (addr=*0x%x)", sub.name, base + pos); - sub.found++; - base[pos] = HACK(sub.index | EIF_PERFORM_BLR); - } - - if (sub.labels.size()) - { - sub.labels.clear(); - } - } -} - -void hook_ppu_funcs(vm::ptr base, u32 size) -{ - using namespace PPU_instr; - - // TODO: optimize search - for (u32 i = 0; i < size; i++) - { - // skip NOP - if (base[i] == 0x60000000) - { - continue; - } - - hook_ppu_func(base, i, size); - } - - // check functions - for (u32 i = 0; i < g_ppu_func_subs.size(); i++) - { - if (g_ppu_func_subs[i].found > 1) - { - LOG_ERROR(LOADER, "Function '%s' hooked %u times", g_ppu_func_subs[i].found); - } - } -} - -bool patch_ppu_import(u32 addr, u32 index) -{ - const auto data = vm::cptr::make(addr); - - using namespace PPU_instr; - - if (index >= g_ppu_func_list.size()) - { - return false; - } - - const u32 imm = (g_ppu_func_list[index].flags & MFF_NO_RETURN) && !(g_ppu_func_list[index].flags & MFF_FORCED_HLE) - ? index | EIF_USE_BRANCH - : index | EIF_PERFORM_BLR; - - // check different patterns: - - if (vm::check_addr(addr, 32) && - (data[0] & 0xffff0000) == LI_(r12, 0) && - (data[1] & 0xffff0000) == ORIS(r12, r12, 0) && - (data[2] & 0xffff0000) == LWZ(r12, r12, 0) && - data[3] == STD(r2, r1, 0x28) && - data[4] == LWZ(r0, r12, 0) && - data[5] == LWZ(r2, r12, 4) && - data[6] == MTCTR(r0) && - data[7] == BCTR()) - { - vm::write32(addr, HACK(imm | EIF_SAVE_RTOC)); - return true; - } - - if (vm::check_addr(addr, 12) && - (data[0] & 0xffff0000) == LI_(r0, 0) && - (data[1] & 0xffff0000) == ORIS(r0, r0, 0) && - (data[2] & 0xfc000003) == B(0, 0, 0)) - { - const auto sub = vm::cptr::make(addr + 8 + ((s32)data[2] << 6 >> 8 << 2)); - - if (vm::check_addr(sub.addr(), 60) && - sub[0x0] == STDU(r1, r1, -0x80) && - sub[0x1] == STD(r2, r1, 0x70) && - sub[0x2] == MR(r2, r0) && - sub[0x3] == MFLR(r0) && - sub[0x4] == STD(r0, r1, 0x90) && - sub[0x5] == LWZ(r2, r2, 0) && - sub[0x6] == LWZ(r0, r2, 0) && - sub[0x7] == LWZ(r2, r2, 4) && - sub[0x8] == MTCTR(r0) && - sub[0x9] == BCTRL() && - sub[0xa] == LD(r2, r1, 0x70) && - sub[0xb] == ADDI(r1, r1, 0x80) && - sub[0xc] == LD(r0, r1, 0x10) && - sub[0xd] == MTLR(r0) && - sub[0xe] == BLR()) - { - vm::write32(addr, HACK(imm)); - return true; - } - } - - if (vm::check_addr(addr, 64) && - data[0x0] == MFLR(r0) && - data[0x1] == STD(r0, r1, 0x10) && - data[0x2] == STDU(r1, r1, -0x80) && - data[0x3] == STD(r2, r1, 0x70) && - (data[0x4] & 0xffff0000) == LI_(r2, 0) && - (data[0x5] & 0xffff0000) == ORIS(r2, r2, 0) && - data[0x6] == LWZ(r2, r2, 0) && - data[0x7] == LWZ(r0, r2, 0) && - data[0x8] == LWZ(r2, r2, 4) && - data[0x9] == MTCTR(r0) && - data[0xa] == BCTRL() && - data[0xb] == LD(r2, r1, 0x70) && - data[0xc] == ADDI(r1, r1, 0x80) && - data[0xd] == LD(r0, r1, 0x10) && - data[0xe] == MTLR(r0) && - data[0xf] == BLR()) - { - vm::write32(addr, HACK(imm)); - return true; - } - - if (vm::check_addr(addr, 64) && - data[0x0] == MFLR(r0) && - data[0x1] == STD(r0, r1, 0x10) && - data[0x2] == STDU(r1, r1, -0x80) && - data[0x3] == STD(r2, r1, 0x70) && - (data[0x4] & 0xffff0000) == LIS(r12, 0) && - (data[0x5] & 0xffff0000) == LWZ(r12, r12, 0) && - data[0x6] == LWZ(r0, r12, 0) && - data[0x7] == LWZ(r2, r12, 4) && - data[0x8] == MTCTR(r0) && - data[0x9] == BCTRL() && - data[0xa] == LD(r2, r1, 0x70) && - data[0xb] == ADDI(r1, r1, 0x80) && - data[0xc] == LD(r0, r1, 0x10) && - data[0xd] == MTLR(r0) && - data[0xe] == BLR()) - { - vm::write32(addr, HACK(imm)); - return true; - } - - if (vm::check_addr(addr, 56) && - (data[0x0] & 0xffff0000) == LI_(r12, 0) && - (data[0x1] & 0xffff0000) == ORIS(r12, r12, 0) && - (data[0x2] & 0xffff0000) == LWZ(r12, r12, 0) && - data[0x3] == STD(r2, r1, 0x28) && - data[0x4] == MFLR(r0) && - data[0x5] == STD(r0, r1, 0x20) && - data[0x6] == LWZ(r0, r12, 0) && - data[0x7] == LWZ(r2, r12, 4) && - data[0x8] == MTCTR(r0) && - data[0x9] == BCTRL() && - data[0xa] == LD(r0, r1, 0x20) && - data[0xb] == MTLR(r0) && - data[0xc] == LD(r2, r1, 0x28) && - data[0xd] == BLR()) - { - vm::write32(addr, HACK(imm)); - return true; - } - - //vm::write32(addr, HACK(imm)); - return false; -} - -Module<>::Module(const std::string& name, void(*init)()) - : _log::channel(name, _log::level::notice) - , m_is_loaded(false) - , m_init(init) -{ -} - -Module<>::~Module() -{ -} - -void Module<>::Init() -{ - on_load = nullptr; - on_unload = nullptr; - on_stop = nullptr; - on_error = nullptr; - - m_init(); -} - -void Module<>::Load() -{ - if (IsLoaded()) - { - return; - } - - if (on_load) - { - on_load(); - } - - SetLoaded(true); -} - -void Module<>::Unload() -{ - if (!IsLoaded()) - { - return; - } - - if (on_unload) - { - on_unload(); - } - - SetLoaded(false); -} - -void Module<>::SetLoaded(bool loaded) -{ - m_is_loaded = loaded; -} - -bool Module<>::IsLoaded() const -{ - return m_is_loaded; -} diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h deleted file mode 100644 index 656ea1a0f3..0000000000 --- a/rpcs3/Emu/SysCalls/Modules.h +++ /dev/null @@ -1,185 +0,0 @@ -#pragma once - -#include "Emu/SysCalls/SC_FUNC.h" -#include "Emu/SysCalls/CB_FUNC.h" -#include "ErrorCodes.h" - -namespace vm { using namespace ps3; } - -template class Module; - -struct ModuleFunc -{ - u32 id; - u32 flags; - Module<>* module; - const char* name; - ppu_func_caller func; - vm::ptr lle_func; - - ModuleFunc() - { - } - - ModuleFunc(u32 id, u32 flags, Module<>* module, const char* name, ppu_func_caller func, vm::ptr lle_func = vm::null) - : id(id) - , flags(flags) - , module(module) - , name(name) - , func(func) - , lle_func(lle_func) - { - } -}; - -struct ModuleVariable -{ - u32 id; - Module<>* module; - const char* name; - u32(*retrieve_addr)(); -}; - -enum : u32 -{ - SPET_MASKED_OPCODE, - SPET_OPTIONAL_MASKED_OPCODE, - SPET_LABEL, - SPET_BRANCH_TO_LABEL, - SPET_BRANCH_TO_FUNC, -}; - -struct SearchPatternEntry -{ - u32 type; - be_t data; - be_t mask; - u32 num; // supplement info -}; - -struct StaticFunc -{ - u32 index; - const char* name; - std::vector ops; - u32 found; - std::unordered_map labels; -}; - -template<> class Module : public _log::channel -{ - friend class ModuleManager; - - bool m_is_loaded; - void(*m_init)(); - -protected: - std::function on_alloc; - -public: - Module(const std::string& name, void(*init)()); - - Module(const Module&) = delete; // Delete copy/move constructors and copy/move operators - - ~Module(); - - std::function on_load; - std::function on_unload; - std::function on_stop; - std::function on_error; - - void Init(); - void Load(); - void Unload(); - - void SetLoaded(bool loaded = true); - bool IsLoaded() const; -}; - -// Module<> with an instance of specified type in PS3 memory -template class Module : public Module -{ - u32 m_addr; - -public: - Module(const char* name, void(*init)()) - : Module(name, init) - { - on_alloc = [this] - { - static_assert(std::is_trivially_destructible::value, "Module<> instance must be trivially destructible"); - //static_assert(std::is_trivially_copy_assignable::value, "Module<> instance must be trivially copy-assignable"); - - // Allocate module instance and call the default constructor -#include "restore_new.h" - new(vm::base(m_addr = vm::alloc(sizeof(T), vm::main))) T(); -#include "define_new_memleakdetect.h" - }; - } - - T* operator ->() const - { - return vm::_ptr(m_addr); - } -}; - -u32 add_ppu_func(ModuleFunc func); -void add_variable(u32 nid, Module<>* module, const char* name, u32(*addr)()); -ModuleFunc* get_ppu_func_by_nid(u32 nid, u32* out_index = nullptr); -ModuleFunc* get_ppu_func_by_index(u32 index); -ModuleVariable* get_variable_by_nid(u32 nid); -void execute_ppu_func_by_index(PPUThread& ppu, u32 id); -extern std::string get_ps3_function_name(u64 fid); -void clear_ppu_functions(); -u32 get_function_id(const char* name); - -u32 add_ppu_func_sub(StaticFunc sf); -u32 add_ppu_func_sub(const std::initializer_list& ops, const char* name, Module<>* module, ppu_func_caller func); - -void hook_ppu_funcs(vm::ptr base, u32 size); - -bool patch_ppu_import(u32 addr, u32 index); - -// Variable associated with registered HLE function -template struct ppu_func_by_func { static u32 index; }; - -template u32 ppu_func_by_func::index = 0xffffffffu; - -template> inline RT call_ppu_func(PPUThread& ppu, Args&&... args) -{ - const auto mfunc = get_ppu_func_by_index(ppu_func_by_func::index); - - if (mfunc && mfunc->lle_func && (mfunc->flags & MFF_FORCED_HLE) == 0 && (mfunc->flags & MFF_NO_RETURN) == 0) - { - const u32 pc = vm::read32(mfunc->lle_func.addr()); - const u32 rtoc = vm::read32(mfunc->lle_func.addr() + 4); - - return cb_call(ppu, pc, rtoc, std::forward(args)...); - } - else - { - return Func(std::forward(args)...); - } -} - -// Call specified function directly if LLE is not available, call LLE equivalent in callback style otherwise -#define CALL_FUNC(ppu, func, ...) call_ppu_func(ppu, __VA_ARGS__) - -#define REG_FNID(module, nid, func, ...) (ppu_func_by_func::index = add_ppu_func(ModuleFunc(nid, { __VA_ARGS__ }, &module, #func, BIND_FUNC(func)))) - -#define REG_FUNC(module, func, ...) REG_FNID(module, get_function_id(#func), func, __VA_ARGS__) - -#define REG_VNID(module, nid, var) add_variable(nid, &module, #var, []{ return vm::get_addr(&module->var); }) - -#define REG_VARIABLE(module, var) REG_VNID(module, get_function_id(#var), var) - -#define REG_SUB(module, ns, name, ...) add_ppu_func_sub({ __VA_ARGS__ }, #name, &module, BIND_FUNC(ns::name)) - -#define SP_OP(type, op, sup) []() { s32 XXX = 0; SearchPatternEntry res = { (type), (op), 0, (sup) }; XXX = -1; res.mask = (op) ^ ~res.data; return res; }() -#define SP_I(op) SP_OP(SPET_MASKED_OPCODE, op, 0) -#define OPT_SP_I(op) SP_OP(SPET_OPTIONAL_MASKED_OPCODE, op, 0) -#define SET_LABEL(label) { SPET_LABEL, (label) } -#define SP_LABEL_BR(op, label) SP_OP(SPET_BRANCH_TO_LABEL, op, label) -#define SP_CALL(op, name) SP_OP(SPET_BRANCH_TO_FUNC, op, get_function_id(#name)) - -#define UNIMPLEMENTED_FUNC(module) module.todo("%s", __FUNCTION__) diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp deleted file mode 100644 index 47e482aff5..0000000000 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -#include "stdafx.h" -#include "Emu/Memory/Memory.h" -#include "Emu/System.h" -#include "Emu/IdManager.h" -#include "Emu/SysCalls/Modules.h" -#include "Emu/Cell/PPUInstrTable.h" - -#include "cellAudio.h" -#include "libmixer.h" - -extern Module<> libmixer; - -SurMixerConfig g_surmx; - -std::vector g_ssp; - -s32 cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) -{ - libmixer.trace("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d)", aan_handle, aan_port, offset, addr, samples); - - u32 type = aan_port >> 16; - u32 port = aan_port & 0xffff; - - switch (type) - { - case CELL_SURMIXER_CHSTRIP_TYPE1A: - if (port >= g_surmx.ch_strips_1) type = 0; break; - case CELL_SURMIXER_CHSTRIP_TYPE2A: - if (port >= g_surmx.ch_strips_2) type = 0; break; - case CELL_SURMIXER_CHSTRIP_TYPE6A: - if (port >= g_surmx.ch_strips_6) type = 0; break; - case CELL_SURMIXER_CHSTRIP_TYPE8A: - if (port >= g_surmx.ch_strips_8) type = 0; break; - default: - type = 0; break; - } - - if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0) - { - libmixer.error("cellAANAddData(aan_handle=0x%x, aan_port=0x%x, offset=0x%x, addr=*0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr, samples); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - std::lock_guard lock(g_surmx.mutex); - - if (type == CELL_SURMIXER_CHSTRIP_TYPE1A) - { - // mono upmixing - for (u32 i = 0; i < samples; i++) - { - const float center = addr[i]; - g_surmx.mixdata[i * 8 + 0] += center; - g_surmx.mixdata[i * 8 + 1] += center; - } - } - else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) - { - // stereo upmixing - for (u32 i = 0; i < samples; i++) - { - const float left = addr[i * 2 + 0]; - const float right = addr[i * 2 + 1]; - g_surmx.mixdata[i * 8 + 0] += left; - g_surmx.mixdata[i * 8 + 1] += right; - } - } - else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) - { - // 5.1 upmixing - for (u32 i = 0; i < samples; i++) - { - const float left = addr[i * 6 + 0]; - const float right = addr[i * 6 + 1]; - const float center = addr[i * 6 + 2]; - const float low_freq = addr[i * 6 + 3]; - const float rear_left = addr[i * 6 + 4]; - const float rear_right = addr[i * 6 + 5]; - g_surmx.mixdata[i * 8 + 0] += left; - g_surmx.mixdata[i * 8 + 1] += right; - g_surmx.mixdata[i * 8 + 2] += center; - g_surmx.mixdata[i * 8 + 3] += low_freq; - g_surmx.mixdata[i * 8 + 4] += rear_left; - g_surmx.mixdata[i * 8 + 5] += rear_right; - } - } - else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A) - { - // 7.1 - for (u32 i = 0; i < samples * 8; i++) - { - g_surmx.mixdata[i] += addr[i]; - } - } - - return CELL_OK; -} - -s32 cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) -{ - libmixer.warning("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", - receive, receivePortNo, source, sourcePortNo); - - std::lock_guard lock(g_surmx.mutex); - - if (source >= g_ssp.size() || !g_ssp[source].m_created) - { - libmixer.error("cellAANConnect(): invalid source (%d)", source); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - g_ssp[source].m_connected = true; - - return CELL_OK; -} - -s32 cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) -{ - libmixer.warning("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", - receive, receivePortNo, source, sourcePortNo); - - std::lock_guard lock(g_surmx.mutex); - - if (source >= g_ssp.size() || !g_ssp[source].m_created) - { - libmixer.error("cellAANDisconnect(): invalid source (%d)", source); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - g_ssp[source].m_connected = false; - - return CELL_OK; -} - -s32 cellSSPlayerCreate(vm::ptr handle, vm::ptr config) -{ - libmixer.warning("cellSSPlayerCreate(handle=*0x%x, config=*0x%x)", handle, config); - - if (config->outputMode != 0 || config->channels - 1 >= 2) - { - libmixer.error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", config->outputMode, config->channels); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - std::lock_guard lock(g_surmx.mutex); - - SSPlayer p; - p.m_created = true; - p.m_connected = false; - p.m_active = false; - p.m_channels = config->channels; - - g_ssp.push_back(p); - *handle = (u32)g_ssp.size() - 1; - return CELL_OK; -} - -s32 cellSSPlayerRemove(u32 handle) -{ - libmixer.warning("cellSSPlayerRemove(handle=0x%x)", handle); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.error("cellSSPlayerRemove(): SSPlayer not found (%d)", handle); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - g_ssp[handle].m_active = false; - g_ssp[handle].m_created = false; - g_ssp[handle].m_connected = false; - - return CELL_OK; -} - -s32 cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) -{ - libmixer.warning("cellSSPlayerSetWave(handle=0x%x, waveInfo=*0x%x, commonInfo=*0x%x)", handle, waveInfo, commonInfo); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.error("cellSSPlayerSetWave(): SSPlayer not found (%d)", handle); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - // TODO: check parameters - - g_ssp[handle].m_addr = waveInfo->addr; - g_ssp[handle].m_samples = waveInfo->samples; - g_ssp[handle].m_loop_start = waveInfo->loopStartOffset - 1; - g_ssp[handle].m_loop_mode = commonInfo ? (u32)commonInfo->loopMode : CELL_SSPLAYER_ONESHOT; - g_ssp[handle].m_position = waveInfo->startOffset - 1; - - return CELL_OK; -} - -s32 cellSSPlayerPlay(u32 handle, vm::ptr info) -{ - libmixer.warning("cellSSPlayerPlay(handle=0x%x, info=*0x%x)", handle, info); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.error("cellSSPlayerPlay(): SSPlayer not found (%d)", handle); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - // TODO: check parameters - - g_ssp[handle].m_active = true; - g_ssp[handle].m_level = info->level; - g_ssp[handle].m_speed = info->speed; - g_ssp[handle].m_x = info->position.x; - g_ssp[handle].m_y = info->position.y; - g_ssp[handle].m_z = info->position.z; - - return CELL_OK; -} - -s32 cellSSPlayerStop(u32 handle, u32 mode) -{ - libmixer.warning("cellSSPlayerStop(handle=0x%x, mode=0x%x)", handle, mode); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.error("cellSSPlayerStop(): SSPlayer not found (%d)", handle); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - // TODO: transition to stop state - - g_ssp[handle].m_active = false; - - return CELL_OK; -} - -s32 cellSSPlayerSetParam(u32 handle, vm::ptr info) -{ - libmixer.warning("cellSSPlayerSetParam(handle=0x%x, info=*0x%x)", handle, info); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.error("cellSSPlayerSetParam(): SSPlayer not found (%d)", handle); - return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; - } - - // TODO: check parameters - - g_ssp[handle].m_level = info->level; - g_ssp[handle].m_speed = info->speed; - g_ssp[handle].m_x = info->position.x; - g_ssp[handle].m_y = info->position.y; - g_ssp[handle].m_z = info->position.z; - - return CELL_OK; -} - -s32 cellSSPlayerGetState(u32 handle) -{ - libmixer.warning("cellSSPlayerGetState(handle=0x%x)", handle); - - std::lock_guard lock(g_surmx.mutex); - - if (handle >= g_ssp.size() || !g_ssp[handle].m_created) - { - libmixer.warning("cellSSPlayerGetState(): SSPlayer not found (%d)", handle); - return CELL_SSPLAYER_STATE_ERROR; - } - - if (g_ssp[handle].m_active) - { - return CELL_SSPLAYER_STATE_ON; - } - - return CELL_SSPLAYER_STATE_OFF; -} - -s32 cellSurMixerCreate(vm::cptr config) -{ - libmixer.warning("cellSurMixerCreate(config=*0x%x)", config); - - g_surmx.audio_port = g_audio.open_port(); - - if (!~g_surmx.audio_port) - { - return CELL_LIBMIXER_ERROR_FULL; - } - - g_surmx.priority = config->priority; - g_surmx.ch_strips_1 = config->chStrips1; - g_surmx.ch_strips_2 = config->chStrips2; - g_surmx.ch_strips_6 = config->chStrips6; - g_surmx.ch_strips_8 = config->chStrips8; - - AudioPortConfig& port = g_audio.ports[g_surmx.audio_port]; - - port.channel = 8; - port.block = 16; - port.attr = 0; - port.addr = g_audio.buffer + AUDIO_PORT_OFFSET * g_surmx.audio_port; - port.read_index_addr = g_audio.indexes + sizeof(u64) * g_surmx.audio_port; - port.size = port.channel * port.block * AUDIO_SAMPLES * sizeof(float); - port.tag = 0; - port.level = 1.0f; - port.level_set.store({ 1.0f, 0.0f }); - - libmixer.warning("*** audio port opened (port=%d)", g_surmx.audio_port); - - g_surmx.mixcount = 0; - g_surmx.cb = vm::null; - - g_ssp.clear(); - - libmixer.warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); - - const auto ppu = idm::make_ptr("Surmixer Thread"); - ppu->prio = 1001; - ppu->stack_size = 0x10000; - ppu->custom_task = [](PPUThread& ppu) - { - AudioPortConfig& port = g_audio.ports[g_surmx.audio_port]; - - while (port.state != AUDIO_PORT_STATE_CLOSED) - { - CHECK_EMU_STATUS; - - if (g_surmx.mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - continue; - } - - if (port.state == AUDIO_PORT_STATE_STARTED) - { - //u64 stamp0 = get_system_time(); - - memset(g_surmx.mixdata, 0, sizeof(g_surmx.mixdata)); - if (g_surmx.cb) - { - g_surmx.cb(ppu, g_surmx.cb_arg, (u32)g_surmx.mixcount, 256); - } - - //u64 stamp1 = get_system_time(); - - { - std::lock_guard lock(g_surmx.mutex); - - for (auto& p : g_ssp) if (p.m_active && p.m_created) - { - auto v = vm::ptrl::make(p.m_addr); // 16-bit LE audio data - float left = 0.0f; - float right = 0.0f; - float speed = fabs(p.m_speed); - float fpos = 0.0f; - for (s32 i = 0; i < 256; i++) if (p.m_active) - { - u32 pos = p.m_position; - s32 pos_inc = 0; - if (p.m_speed > 0.0f) // select direction - { - pos_inc = 1; - } - else if (p.m_speed < 0.0f) - { - pos_inc = -1; - } - s32 shift = i - (int)fpos; // change playback speed (simple and rough) - if (shift > 0) - { - // slow playback - pos_inc = 0; // duplicate one sample at this time - fpos += 1.0f; - fpos += speed; - } - else if (shift < 0) - { - // fast playback - i--; // mix two sample into one at this time - fpos -= 1.0f; - } - else - { - fpos += speed; - } - p.m_position += (u32)pos_inc; - if (p.m_channels == 1) // get mono data - { - left = right = (float)v[pos] / 0x8000 * p.m_level; - } - else if (p.m_channels == 2) // get stereo data - { - left = (float)v[pos * 2 + 0] / 0x8000 * p.m_level; - right = (float)v[pos * 2 + 1] / 0x8000 * p.m_level; - } - if (p.m_connected) // mix - { - // TODO: m_x, m_y, m_z ignored - g_surmx.mixdata[i * 8 + 0] += left; - g_surmx.mixdata[i * 8 + 1] += right; - } - if ((p.m_position == p.m_samples && p.m_speed > 0.0f) || - (p.m_position == ~0 && p.m_speed < 0.0f)) // loop or stop - { - if (p.m_loop_mode == CELL_SSPLAYER_LOOP_ON) - { - p.m_position = p.m_loop_start; - } - else if (p.m_loop_mode == CELL_SSPLAYER_ONESHOT_CONT) - { - p.m_position -= (u32)pos_inc; // restore position - } - else // oneshot - { - p.m_active = false; - p.m_position = p.m_loop_start; // TODO: check value - } - } - } - } - } - - //u64 stamp2 = get_system_time(); - - auto buf = vm::_ptr(port.addr + (g_surmx.mixcount % port.block) * port.channel * AUDIO_SAMPLES * sizeof(float)); - - for (auto& mixdata : g_surmx.mixdata) - { - // reverse byte order - *buf++ = mixdata; - } - - //u64 stamp3 = get_system_time(); - - //ConLog.Write("Libmixer perf: start=%lld (cb=%lld, ssp=%lld, finalize=%lld)", stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2); - } - - g_surmx.mixcount++; - } - - idm::remove(ppu.get_id()); - }; - - ppu->run(); - ppu->exec(); - - return CELL_OK; -} - -s32 cellSurMixerGetAANHandle(vm::ptr handle) -{ - libmixer.warning("cellSurMixerGetAANHandle(handle=*0x%x) -> %d", handle, 0x11111111); - *handle = 0x11111111; - return CELL_OK; -} - -s32 cellSurMixerChStripGetAANPortNo(vm::ptr port, u32 type, u32 index) -{ - libmixer.warning("cellSurMixerChStripGetAANPortNo(port=*0x%x, type=0x%x, index=0x%x) -> 0x%x", port, type, index, (type << 16) | index); - *port = (type << 16) | index; - return CELL_OK; -} - -s32 cellSurMixerSetNotifyCallback(vm::ptr func, vm::ptr arg) -{ - libmixer.warning("cellSurMixerSetNotifyCallback(func=*0x%x, arg=*0x%x)", func, arg); - - if (g_surmx.cb) - { - throw EXCEPTION("Callback already set"); - } - - g_surmx.cb = func; - g_surmx.cb_arg = arg; - - return CELL_OK; -} - -s32 cellSurMixerRemoveNotifyCallback(vm::ptr func) -{ - libmixer.warning("cellSurMixerRemoveNotifyCallback(func=*0x%x)", func); - - if (g_surmx.cb != func) - { - throw EXCEPTION("Callback not set"); - } - - g_surmx.cb = vm::null; - - return CELL_OK; -} - -s32 cellSurMixerStart() -{ - libmixer.warning("cellSurMixerStart()"); - - if (g_surmx.audio_port >= AUDIO_PORT_COUNT) - { - return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; - } - - g_audio.ports[g_surmx.audio_port].state.compare_and_swap(AUDIO_PORT_STATE_OPENED, AUDIO_PORT_STATE_STARTED); - - return CELL_OK; -} - -s32 cellSurMixerSetParameter(u32 param, float value) -{ - libmixer.todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); - return CELL_OK; -} - -s32 cellSurMixerFinalize() -{ - libmixer.warning("cellSurMixerFinalize()"); - - if (g_surmx.audio_port >= AUDIO_PORT_COUNT) - { - return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; - } - - g_audio.ports[g_surmx.audio_port].state.compare_and_swap(AUDIO_PORT_STATE_OPENED, AUDIO_PORT_STATE_CLOSED); - - return CELL_OK; -} - -s32 cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 samples) -{ - if (busNo < 8 && samples == 256 && offset == 0) - { - libmixer.trace("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); - } - else - { - libmixer.todo("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); - return CELL_OK; - } - - std::lock_guard lock(g_surmx.mutex); - - for (u32 i = 0; i < samples; i++) - { - // reverse byte order and mix - g_surmx.mixdata[i * 8 + busNo] += addr[i]; - } - - return CELL_OK; -} - -s32 cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr param) -{ - libmixer.todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param=*0x%x)", type, index, param); - return CELL_OK; -} - -s32 cellSurMixerPause(u32 type) -{ - libmixer.warning("cellSurMixerPause(type=%d)", type); - - if (g_surmx.audio_port >= AUDIO_PORT_COUNT) - { - return CELL_LIBMIXER_ERROR_NOT_INITIALIZED; - } - - g_audio.ports[g_surmx.audio_port].state.compare_and_swap(AUDIO_PORT_STATE_STARTED, AUDIO_PORT_STATE_OPENED); - - return CELL_OK; -} - -s32 cellSurMixerGetCurrentBlockTag(vm::ptr tag) -{ - libmixer.trace("cellSurMixerGetCurrentBlockTag(tag=*0x%x)", tag); - - *tag = g_surmx.mixcount; - return CELL_OK; -} - -s32 cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) -{ - libmixer.trace("cellSurMixerGetTimestamp(tag=0x%llx, stamp=*0x%x)", tag, stamp); - - *stamp = g_audio.start_time + (tag) * 256000000 / 48000; // ??? - return CELL_OK; -} - -void cellSurMixerBeep(u32 arg) -{ - libmixer.todo("cellSurMixerBeep(arg=%d)", arg); - return; -} - -float cellSurMixerUtilGetLevelFromDB(float dB) -{ - libmixer.todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); - throw EXCEPTION(""); -} - -float cellSurMixerUtilGetLevelFromDBIndex(s32 index) -{ - libmixer.todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); - throw EXCEPTION(""); -} - -float cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) -{ - libmixer.todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); - throw EXCEPTION(""); -} - -Module<> libmixer("libmixer", []() -{ - g_surmx.audio_port = ~0; - - libmixer.on_stop = []() - { - g_ssp.clear(); - }; - - using namespace PPU_instr; - - REG_SUB(libmixer,, cellAANAddData, - { SPET_MASKED_OPCODE, 0x7c691b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff91, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c802378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7caa2b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x81690000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c050378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7cc43378, 0xffffffff }, - { SPET_OPTIONAL_MASKED_OPCODE, 0x78630020, 0xffffffff }, // clrldi r3,r3,32 - { SPET_MASKED_OPCODE, 0x7d465378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812b0030, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80090000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0903a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80490004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800421, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c6307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - ); - - REG_SUB(libmixer,, cellAANConnect, - { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c008031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c691b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c8a2378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60000003, 0xffffffff }, - SP_LABEL_BR(BNE(cr7, XXX), 0x24), - SET_LABEL(0x24), - { SPET_MASKED_OPCODE, 0x7c0307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - SET_LABEL(0x38), - { SPET_MASKED_OPCODE, 0x2f850000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38810070, 0xffffffff }, - SP_LABEL_BR(BEQ(cr7, XXX), 0x38), - { SPET_MASKED_OPCODE, 0x81690000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38000001, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x91210074, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x90a10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x90c10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x9141007c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812b0018, 0xffffffff }, // - { SPET_MASKED_OPCODE, 0x90010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80090000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0903a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80490004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800421, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - ); - - REG_SUB(libmixer,, cellAANDisconnect, - { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c008031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c691b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c8a2378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60000003, 0xffffffff }, - SP_LABEL_BR(BNE(cr7, XXX), 0x24), - SET_LABEL(0x24), - { SPET_MASKED_OPCODE, 0x7c0307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - SET_LABEL(0x38), - { SPET_MASKED_OPCODE, 0x2f850000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38810070, 0xffffffff }, - SP_LABEL_BR(BEQ(cr7, XXX), 0x38), - { SPET_MASKED_OPCODE, 0x81690000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38000001, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x91210074, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x90a10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x90c10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x9141007c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812b001c, 0xffffffff }, // - { SPET_MASKED_OPCODE, 0x90010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80090000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0903a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80490004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800421, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - ); - - REG_SUB(libmixer,, cellSurMixerCreate, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff51, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb210078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb410080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb610088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb810090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfba10098, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe100a8, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100c0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c7e1b78, 0xffffffff }, - SP_LABEL_BR(BNE(cr7, XXX), 0x6c), - { SPET_MASKED_OPCODE, 0x3fe08031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x63ff0003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100c0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7fe307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeb210078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeb410080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeb610088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeb810090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeba10098, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebc100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebe100a8, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x382100b0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - SET_LABEL(0x6c), - ); - - REG_SUB(libmixer,, cellSurMixerGetAANHandle, - SP_I(LWZ(r10, r2, XXX)), - { SPET_MASKED_OPCODE, 0x3d607fce, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x616bfffe, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812a0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2afe70, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x91230000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d404a78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c005050, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c00fe70, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c035838, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c638031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38630002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c6307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - ); - - REG_SUB(libmixer,, cellSurMixerChStripGetAANPortNo, - SP_I(LWZ(r9, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c661b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78c60020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80090018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78a50020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78030020, 0xffffffff }, - SP_I(B(XXX, 0, 0)), - ); - - REG_SUB(libmixer,, cellSurMixerSetNotifyCallback, - SP_I(LWZ(r10, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c6b1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812a0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c882378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f890000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f0b0000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x409e0000, 0xffffff00 }, // bne - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c6307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419aff00, 0xffffff00 }, // beq - SP_I(LWZ(r0, r10, XXX)), - { SPET_MASKED_OPCODE, 0x79290020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38810070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d234b78, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerRemoveNotifyCallback, - SP_I(LWZ(r11, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c6a1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x806b0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, // ori - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x409e0000, 0xffff0000 }, // bne - { SPET_MASKED_OPCODE, 0xe8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerStart, - { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc10080, 0xffffffff }, - SP_I(LWZ(r30, r2, XXX)), - { SPET_MASKED_OPCODE, 0xf80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfba10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe10088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x801e0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // bne - { SPET_MASKED_OPCODE, 0x3fe08031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x63ff0002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7fe307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xeba10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebc10080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebe10088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerSetParameter, - { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfc000890, 0xffffffff }, - SP_I(LWZ(r30, r2, XXX)), - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c7f1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x801e0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x409e0000, 0xffff0000 }, // bne - { SPET_MASKED_OPCODE, 0xe8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebc10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebe10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x801e001c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2b03001f, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419c0000, 0xffff0000 }, // blt - { SPET_MASKED_OPCODE, 0x2b83002b, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40990000, 0xffff0000 }, // ble - { SPET_MASKED_OPCODE, 0x409d0000, 0xffff0000 }, // ble - ); - - REG_SUB(libmixer,, cellSurMixerFinalize, - { SPET_MASKED_OPCODE, 0xf821ff91, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4bfffd00, 0xffffff00 }, // bl - { SPET_MASKED_OPCODE, 0xe8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38600000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfba10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80000000, 0xf0000000 }, // lwz - { SPET_MASKED_OPCODE, 0xf80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x817d0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d635b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x812b0000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x81490000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x800a0000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0903a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x804a0004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800421, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerSurBusAddData, - SP_I(LWZ(r10, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff91, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x806a0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c8b2378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7cc73378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x409e0000, 0xffff0000 }, // bne - { SPET_MASKED_OPCODE, 0xe8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78a40020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78050020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x800a001c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78680020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d034378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x79660020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78e70020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419c0000, 0xffff0000 } // blt - ); - - REG_SUB(libmixer,, cellSurMixerChStripSetParameter, - SP_I(LWZ(r8, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c6b1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c8a2378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7ca62b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x81280018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f890000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0000, 0xffff0000 }, // beqlr - { SPET_MASKED_OPCODE, 0x8008001c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x79640020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x79450020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78c60020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9c0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x79230020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 } // b - ); - - REG_SUB(libmixer,, cellSurMixerPause, - SP_I(LWZ(r10, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x800a0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c7f1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x409e0000, 0xffff0000 }, // bne - { SPET_MASKED_OPCODE, 0xe8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebc10070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xebe10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x800a001c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2b030002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerGetCurrentBlockTag, - SP_I(LWZ(r11, r2, XXX)), - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x880b0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419e0000, 0xffff0000 }, // beq - { SPET_MASKED_OPCODE, 0xe80b0028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x39200000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8030000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSurMixerGetTimestamp, - SP_I(LWZ(r11, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff91, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c852378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3d208031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x880b0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c641b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78a50020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x61290002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40de0000, 0xffff0000 }, // bne- - { SPET_MASKED_OPCODE, 0xe8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7d2307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x806b04d8, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 } // bl - ); - - REG_SUB(libmixer,, cellSurMixerBeep, - SP_I(LWZ(r9, r2, XXX)), - { SPET_MASKED_OPCODE, 0x7c641b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80690018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0000, 0xffff0000 }, // beqlr - { SPET_MASKED_OPCODE, 0x8009001c, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9c0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 } // b - ); - - REG_SUB(libmixer,, cellSSPlayerCreate, - { SPET_MASKED_OPCODE, 0xf821ff51, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f840000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100c0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c008031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb210078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb410080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb610088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb810090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfba10098, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe100a8, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c9a2378, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c791b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60000003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419e0000, 0xffff0000 }, // beq - { SPET_MASKED_OPCODE, 0x83000000, 0xff000000 }, // lwz - { SPET_MASKED_OPCODE, 0x3b800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x381b0064, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x901b0018, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x5780103a, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38800010, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0007b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38a01c70, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7fc0da14, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38c00000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x83be0024, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f9d0000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7ba30020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x41de0000, 0xffff0000 }, // beq- - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 } // bl - ); - - REG_SUB(libmixer,, cellSSPlayerRemove, - { SPET_MASKED_OPCODE, 0x7c641b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f840000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf821ff51, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb010070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb210078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb410080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb610088, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfb810090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfba10098, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe100a8, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100c0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419e0000, 0xffff0000 }, // beq - { SPET_MASKED_OPCODE, 0x81240000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78830020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x83440004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x83240008, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7b5b0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x81690000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x800b0000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8410028, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0903a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x804b0004, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800421, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSSPlayerSetWave, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78a50020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419e0000, 0xffff0000 }, // beq - { SPET_MASKED_OPCODE, 0x78030020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // b - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSSPlayerPlay, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78030020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // b - { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, // next func - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbe10078, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c7f1b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x81000000, 0xff000000 }, // lwz - { SPET_MASKED_OPCODE, 0xf8010090, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x39400000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38630010, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSSPlayerStop, - { SPET_MASKED_OPCODE, 0xf821ff91, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f830000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c008031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60000003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x419e0000, 0xffff0000 }, // beq - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // bl - { SPET_MASKED_OPCODE, 0x38000000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0307b4, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xe8010080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x38210070, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x7c0803a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4e800020, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSSPlayerSetParam, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78840020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78030020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // b - { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, // next func - { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3d608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xf80100a0, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x80030068, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x616b0002, 0xffffffff }, - { SPET_MASKED_OPCODE, 0xfbc10080, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff } - ); - - REG_SUB(libmixer,, cellSSPlayerGetState, - { SPET_MASKED_OPCODE, 0x7c601b78, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x3c608031, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x2f800000, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x60630003, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x4d9e0020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x78030020, 0xffffffff }, - { SPET_MASKED_OPCODE, 0x40000000, 0xf0000000 }, // b - ); - - REG_SUB(libmixer,, cellSurMixerUtilGetLevelFromDB); - REG_SUB(libmixer,, cellSurMixerUtilGetLevelFromDBIndex); - REG_SUB(libmixer,, cellSurMixerUtilNoteToRatio); -});