diff --git a/Utilities/Log.h b/Utilities/Log.h index 5ff8504ce7..04d1225f2d 100644 --- a/Utilities/Log.h +++ b/Utilities/Log.h @@ -50,9 +50,9 @@ namespace Log enum LogSeverity : u32 { - Success = 0, - Notice, + Notice = 0, Warning, + Success, Error, }; diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 54f032bdbd..bb41b1e83e 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -465,7 +465,7 @@ typedef ucontext_t x64_context; #define X64REG(context, reg) (darwin_x64reg(context, reg)) #define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext->__fs.__fpu_xmm0[reg])) -#define EFLAGS(context) ((context)->uc_mcontext->__ss.__eflags) +#define EFLAGS(context) ((context)->uc_mcontext->__ss.__rflags) uint64_t* darwin_x64reg(x64_context *context, int reg) { @@ -832,7 +832,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) return false; } - memcpy(vm::get_priv_ptr(addr), XMMREG(context, reg - X64R_XMM0), 16); + memcpy(vm::priv_ptr(addr), XMMREG(context, reg - X64R_XMM0), 16); break; } @@ -842,7 +842,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) return false; } - memcpy(vm::get_priv_ptr(addr), ®_value, d_size); + memcpy(vm::priv_ptr(addr), ®_value, d_size); break; } case X64OP_MOVS: @@ -867,7 +867,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) // copy data memcpy(&value, (void*)RSI(context), d_size); - memcpy(vm::get_priv_ptr(a_addr), &value, d_size); + memcpy(vm::priv_ptr(a_addr), &value, d_size); // shift pointers if (EFLAGS(context) & 0x400 /* direction flag */) @@ -925,7 +925,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) while (a_addr >> 12 == addr >> 12) { // fill data with value - memcpy(vm::get_priv_ptr(a_addr), &value, d_size); + memcpy(vm::priv_ptr(a_addr), &value, d_size); // shift pointers if (EFLAGS(context) & 0x400 /* direction flag */) @@ -966,10 +966,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: reg_value = vm::get_priv_ref>(addr).exchange((u8)reg_value); break; - case 2: reg_value = vm::get_priv_ref>(addr).exchange((u16)reg_value); break; - case 4: reg_value = vm::get_priv_ref>(addr).exchange((u32)reg_value); break; - case 8: reg_value = vm::get_priv_ref>(addr).exchange((u64)reg_value); break; + case 1: reg_value = vm::priv_ref>(addr).exchange((u8)reg_value); break; + case 2: reg_value = vm::priv_ref>(addr).exchange((u16)reg_value); break; + case 4: reg_value = vm::priv_ref>(addr).exchange((u32)reg_value); break; + case 8: reg_value = vm::priv_ref>(addr).exchange((u64)reg_value); break; default: return false; } @@ -989,10 +989,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) switch (d_size) { - case 1: old_value = vm::get_priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; - case 2: old_value = vm::get_priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; - case 4: old_value = vm::get_priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; - case 8: old_value = vm::get_priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; + case 1: old_value = vm::priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; + case 2: old_value = vm::priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; + case 4: old_value = vm::priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; + case 8: old_value = vm::priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; default: return false; } diff --git a/rpcs3/Emu/Cell/PPCThread.cpp b/rpcs3/Emu/Cell/PPCThread.cpp deleted file mode 100644 index 4d77900d90..0000000000 --- a/rpcs3/Emu/Cell/PPCThread.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "stdafx.h" -#include "PPCThread.h" -#include "Emu/Memory/Memory.h" - -PPCThread* GetCurrentPPCThread() -{ - CPUThread* thread = GetCurrentCPUThread(); - - if(!thread || (thread->GetType() != CPU_THREAD_PPU && thread->GetType() != CPU_THREAD_SPU && thread->GetType() != CPU_THREAD_RAW_SPU)) - { - throw std::string("GetCurrentPPCThread: bad thread"); - } - - return (PPCThread*)thread; -} - -PPCThread::PPCThread(CPUThreadType type) : CPUThread(type) -{ -} - -PPCThread::~PPCThread() -{ -} - -void PPCThread::DoReset() -{ -} diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h deleted file mode 100644 index 2c3fa5c05b..0000000000 --- a/rpcs3/Emu/Cell/PPCThread.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "Emu/CPU/CPUThread.h" - -class PPCThread : public CPUThread -{ -public: - virtual std::string GetThreadName() const - { - return fmt::format("%s[0x%08x]", GetFName(), PC); - } - -protected: - PPCThread(CPUThreadType type); - -public: - virtual ~PPCThread(); - -protected: - virtual void DoReset() override; -}; - -PPCThread* GetCurrentPPCThread(); diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index 62e19e0138..4dbc1eb4cc 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -652,22 +652,53 @@ namespace PPU_instr r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31 }; + + enum + { + cr0, cr1, cr2, cr3, cr4, cr5, cr6, cr7 + }; } namespace implicts { using namespace lists; - //static auto LIS = std::bind(ADDIS, std::placeholders::_1, r0, std::placeholders::_2); - //static auto LI = std::bind(ADDI, std::placeholders::_1, r0, std::placeholders::_2); - static auto NOP = std::bind(ORI, r0, r0, 0); - static auto MR = std::bind(OR, std::placeholders::_1, std::placeholders::_2, std::placeholders::_2, false); - static auto BLR = std::bind(BCLR, 0x10 | 0x04, 0, 0, 0); - static auto BCTR = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 0); - static auto BCTRL = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 1); - static auto MTCTR = std::bind(MTSPR, (0x1 << 5) | 0x8, std::placeholders::_1); - } + inline u32 LIS(u32 reg, u32 imm) { return ADDIS(reg, r0, imm); } + inline u32 LI_(u32 reg, u32 imm) { return ADDI(reg, r0, imm); } + inline u32 NOP() { return ORI(r0, r0, 0); } + inline u32 MR(u32 x, u32 y) { return OR(x, y, y, false); } + inline u32 BLR() { return BCLR(0x10 | 0x04, 0, 0, 0); } + inline u32 BCTR() { return BCCTR(0x10 | 0x04, 0, 0, 0); } + inline u32 BCTRL() { return BCCTR(0x10 | 0x04, 0, 0, 1); } + inline u32 MFCTR(u32 reg) { return MFSPR(reg, 9 << 5); } + inline u32 MTCTR(u32 reg) { return MTSPR(9 << 5, reg); } + inline u32 MFLR(u32 reg) { return MFSPR(reg, 8 << 5); } + inline u32 MTLR(u32 reg) { return MTSPR(8 << 5, reg); } + inline u32 BNE(u32 cr, s32 imm) { return BC(4, 2 | cr << 2, imm, 0, 0); } + inline u32 BEQ(u32 cr, s32 imm) { return BC(12, 2 | cr << 2, imm, 0, 0); } + inline u32 BGT(u32 cr, s32 imm) { return BC(12, 1 | cr << 2, imm, 0, 0); } + + inline u32 BNE(s32 imm) { return BNE(cr0, imm); } + inline u32 BEQ(s32 imm) { return BEQ(cr0, imm); } + inline u32 BGT(s32 imm) { return BGT(cr0, imm); } + + inline u32 CMPDI(u32 cr, u32 reg, u32 imm) { return CMPI(cr, 1, reg, imm); } + inline u32 CMPDI(u32 reg, u32 imm) { return CMPDI(cr0, reg, imm); } + + inline u32 CMPWI(u32 cr, u32 reg, u32 imm) { return CMPI(cr, 0, reg, imm); } + inline u32 CMPWI(u32 reg, u32 imm) { return CMPWI(cr0, reg, imm); } + + inline u32 CMPLDI(u32 cr, u32 reg, u32 imm) { return CMPLI(cr, 1, reg, imm); } + inline u32 CMPLDI(u32 reg, u32 imm) { return CMPLDI(cr0, reg, imm); } + + inline u32 CMPLWI(u32 cr, u32 reg, u32 imm) { return CMPLI(cr, 0, reg, imm); } + inline u32 CMPLWI(u32 reg, u32 imm) { return CMPLWI(cr0, reg, imm); } + + inline u32 EXTRDI(u32 x, u32 y, u32 n, u32 b) { return RLDICL(x, y, b + n, 64 - b, false); } + inline u32 SRDI(u32 x, u32 y, u32 n) { return RLDICL(x, y, 64 - n, n, false); } + inline u32 CLRLDI(u32 x, u32 y, u32 n) { return RLDICL(x, y, 0, n, false); } + } using namespace lists; using namespace implicts; diff --git a/rpcs3/Emu/Cell/PPUProgramCompiler.h b/rpcs3/Emu/Cell/PPUProgramCompiler.h index 5070c34516..f7d5a00559 100644 --- a/rpcs3/Emu/Cell/PPUProgramCompiler.h +++ b/rpcs3/Emu/Cell/PPUProgramCompiler.h @@ -1,7 +1,7 @@ #pragma once -#include "PPUInstrTable.h" +/*#include "PPUInstrTable.h" #include "Loader/ELF64.h" -/* + enum ArgType { ARG_ERR = 0, diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 205dc2b4eb..9372ebe2c1 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -19,14 +19,14 @@ extern void ppu_free_tls(u32 thread); PPUThread& GetCurrentPPUThread() { - PPCThread* thread = GetCurrentPPCThread(); + CPUThread* thread = GetCurrentCPUThread(); if(!thread || thread->GetType() != CPU_THREAD_PPU) throw std::string("GetCurrentPPUThread: bad thread"); return *(PPUThread*)thread; } -PPUThread::PPUThread() : PPCThread(CPU_THREAD_PPU) +PPUThread::PPUThread() : CPUThread(CPU_THREAD_PPU) { owned_mutexes = 0; Reset(); @@ -39,8 +39,6 @@ PPUThread::~PPUThread() void PPUThread::DoReset() { - PPCThread::DoReset(); - //reset regs memset(VPR, 0, sizeof(VPR)); memset(FPR, 0, sizeof(FPR)); diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 64c11c7563..ee0254aa6a 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -1,6 +1,6 @@ #pragma once #include "Emu/Cell/Common.h" -#include "Emu/Cell/PPCThread.h" +#include "Emu/CPU/CPUThread.h" #include "Emu/Memory/vm.h" enum @@ -467,7 +467,7 @@ struct FPRdouble static int Cmp(PPCdouble a, PPCdouble b); }; -class PPUThread : public PPCThread +class PPUThread : public CPUThread { public: PPCdouble FPR[32]; //Floating Point Register diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 041ea63968..94f34c3fa0 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -47,7 +47,7 @@ bool RawSPUThread::Read32(const u32 addr, u32* value) case SPU_MBox_Status_offs: { - *value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8); + *value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8) | (SPU.Out_IntrMBox.GetCount() << 16); break; } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index b0785cfd16..0f044d4994 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -23,7 +23,7 @@ SPUThread& GetCurrentSPUThread() { - PPCThread* thread = GetCurrentPPCThread(); + CPUThread* thread = GetCurrentCPUThread(); if(!thread || (thread->GetType() != CPU_THREAD_SPU && thread->GetType() != CPU_THREAD_RAW_SPU)) { @@ -33,7 +33,7 @@ SPUThread& GetCurrentSPUThread() return *(SPUThread*)thread; } -SPUThread::SPUThread(CPUThreadType type) : PPCThread(type) +SPUThread::SPUThread(CPUThreadType type) : CPUThread(type) { assert(type == CPU_THREAD_SPU || type == CPU_THREAD_RAW_SPU); @@ -73,10 +73,8 @@ void SPUThread::Task() void SPUThread::DoReset() { - PPCThread::DoReset(); - //reset regs - memset(GPR, 0, sizeof(u128) * 128); + memset(GPR, 0, sizeof(GPR)); } void SPUThread::InitRegs() @@ -412,7 +410,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) { vm::reservation_op(vm::cast(ea), 128, [this, tag, lsa, ea]() { - memcpy(vm::get_priv_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), 128); + memcpy(vm::priv_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), 128); }); if (op == MFC_PUTLLUC_CMD) @@ -568,7 +566,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r) return; } - //if (Ini.HLELogging.GetValue()) + if (Ini.HLELogging.GetValue()) { LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index fa0dfd22d9..af3c9c8064 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -1,7 +1,7 @@ #pragma once #include "Emu/Cell/Common.h" +#include "Emu/CPU/CPUThread.h" #include "Emu/Memory/atomic_type.h" -#include "PPCThread.h" #include "Emu/SysCalls/lv2/sleep_queue_type.h" #include "Emu/SysCalls/lv2/sys_event.h" #include "Emu/Event.h" @@ -115,8 +115,6 @@ enum struct g_imm_table_struct { - //u16 cntb_table[65536]; - __m128i fsmb_table[65536]; __m128i fsmh_table[256]; __m128i fsm_table[16]; @@ -127,20 +125,8 @@ struct g_imm_table_struct g_imm_table_struct() { - /*static_assert(offsetof(g_imm_table_struct, cntb_table) == 0, "offsetof(cntb_table) != 0"); - for (u32 i = 0; i < sizeof(cntb_table) / sizeof(cntb_table[0]); i++) - { - u32 cnt_low = 0, cnt_high = 0; - for (u32 j = 0; j < 8; j++) - { - cnt_low += (i >> j) & 1; - cnt_high += (i >> (j + 8)) & 1; - } - cntb_table[i] = (cnt_high << 8) | cnt_low; - }*/ for (u32 i = 0; i < sizeof(fsm_table) / sizeof(fsm_table[0]); i++) { - for (u32 j = 0; j < 4; j++) mmToU32Ptr(fsm_table[i])[j] = (i & (1 << j)) ? ~0 : 0; } for (u32 i = 0; i < sizeof(fsmh_table) / sizeof(fsmh_table[0]); i++) @@ -287,7 +273,7 @@ union SPU_SNRConfig_hdr struct SpuGroupInfo; -class SPUThread : public PPCThread +class SPUThread : public CPUThread { public: u128 GPR[128]; // General-Purpose Registers diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 93b0482422..9939033bdc 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -264,7 +264,7 @@ namespace vm _reservation_set(addr, true); // update memory using privileged access - memcpy(vm::get_priv_ptr(addr), data, size); + memcpy(vm::priv_ptr(addr), data, size); // remove callback to not call it on successful update g_reservation_cb = nullptr; @@ -362,7 +362,7 @@ namespace vm } void* real_addr = vm::get_ptr(addr); - void* priv_addr = vm::get_priv_ptr(addr); + void* priv_addr = vm::priv_ptr(addr); #ifdef _WIN32 auto protection = flags & page_writable ? PAGE_READWRITE : (flags & page_readable ? PAGE_READONLY : PAGE_NOACCESS); @@ -464,7 +464,7 @@ namespace vm } void* real_addr = vm::get_ptr(addr); - void* priv_addr = vm::get_priv_ptr(addr); + void* priv_addr = vm::priv_ptr(addr); #ifdef _WIN32 DWORD old; diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 0df015a82e..73ae618404 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -77,15 +77,15 @@ namespace vm } template - T* const get_priv_ptr(u32 addr) + T* const priv_ptr(u32 addr) { return reinterpret_cast(static_cast(g_priv_addr) + addr); } template - T& get_priv_ref(u32 addr) + T& priv_ref(u32 addr) { - return *get_priv_ptr(addr); + return *priv_ptr(addr); } u32 get_addr(const void* real_pointer); diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 68d940ea6b..be49e8a42d 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -214,9 +214,9 @@ namespace vm return vm::get_ptr(vm::cast(m_addr)); } - T* get_priv_ptr() const + T* priv_ptr() const { - return vm::get_priv_ptr(vm::cast(m_addr)); + return vm::priv_ptr(vm::cast(m_addr)); } static const _ptr_base make(const AT& addr) @@ -248,9 +248,9 @@ namespace vm return vm::get_ptr(vm::cast(m_addr)); } - void* get_priv_ptr() const + void* priv_ptr() const { - return vm::get_priv_ptr(vm::cast(m_addr)); + return vm::priv_ptr(vm::cast(m_addr)); } explicit operator void*() const @@ -311,9 +311,9 @@ namespace vm return vm::get_ptr(vm::cast(m_addr)); } - const void* get_priv_ptr() const + const void* priv_ptr() const { - return vm::get_priv_ptr(vm::cast(m_addr)); + return vm::priv_ptr(vm::cast(m_addr)); } explicit operator const void*() const diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index 64ae948afd..02183c82e7 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -53,6 +53,7 @@ extern Module sys_fs; extern Module sys_io; extern Module sys_net; extern Module sysPrxForUser; +extern Module sys_libc; struct ModuleInfo { @@ -166,24 +167,27 @@ static const g_module_list[] = { -1, "cellSysmodule", &cellSysmodule }, { -1, "libmixer", &libmixer }, { -1, "sysPrxForUser", &sysPrxForUser }, + { -1, "sys_libc", &sys_libc }, }; void ModuleManager::Init() { - if (!initialized) + if (initialized) { - clear_ppu_functions(); - - for (auto& m : g_module_list) - { - if (m.module) - { - m.module->Init(); - } - } - - initialized = true; + Close(); } + + clear_ppu_functions(); + + for (auto& m : g_module_list) + { + if (m.module) + { + m.module->Init(); + } + } + + initialized = true; } ModuleManager::ModuleManager() diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index e6d8327f39..f01ff3dec4 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -30,21 +30,29 @@ u32 add_ppu_func_sub(StaticFunc func) return func.index; } -u32 add_ppu_func_sub(const char group[8], const u64 ops[], const char* name, Module* module, ppu_func_caller func) +u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], const size_t count, const char* name, Module* module, ppu_func_caller func) { + char group_name[9] = {}; + + if (group) + { + strcpy_trunc(group_name, group); + } + StaticFunc sf; sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, func)); sf.name = name; - sf.group = *(u64*)group; + sf.group = *(u64*)group_name; sf.found = 0; - // TODO: check for self-inclusions, use CRC - for (u32 i = 0; ops[i]; i++) + for (u32 i = 0; i < count; i++) { - SFuncOp op; - op.mask = re32((u32)(ops[i] >> 32)); - op.crc = re32((u32)(ops[i])); - if (op.mask) op.crc &= op.mask; + SearchPatternEntry op; + op.type = ops[i].type; + op.data = re32(ops[i].data); + op.mask = re32(ops[i].mask); + op.num = ops[i].num; + assert(!op.mask || (op.data & ~op.mask) == 0); sf.ops.push_back(op); } @@ -166,90 +174,155 @@ u32 get_function_id(const char* name) return (u32&)output[0]; } -void hook_ppu_funcs(u32* base, u32 size) +void hook_ppu_func(vm::ptr base, u32 pos, u32 size) { - size /= 4; + using namespace PPU_instr; + + for (auto& sub : g_ppu_func_subs) + { + bool found = true; + + for (u32 k = pos, x = 0; x + 1 <= sub.ops.size(); k++, x++) + { + if (k >= size) + { + found = false; + break; + } + + // skip NOP + if (base[k].data() == se32(0x60000000)) + { + x--; + continue; + } + + const u32 data = sub.ops[x].data; + const u32 mask = sub.ops[x].mask; + + const bool match = (base[k].data() & 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 auto addr = (base + k--).addr(); + const auto 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].data() & se32(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].data() & se32(2) ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2)); + // const auto nid = sub.ops[x].num; + // // TODO: recursive call + //} + default: + { + LOG_ERROR(LOADER, "Unknown search pattern type (%d)", sub.ops[x].type); + assert(0); + return; + } + } + + if (!found) + { + break; + } + } + + if (found) + { + LOG_SUCCESS(LOADER, "Function '%s' hooked (addr=0x%x)", sub.name, (base + pos).addr()); + 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; if (!Ini.HLEHookStFunc.GetValue()) + { return; + } // TODO: optimize search for (u32 i = 0; i < size; i++) { - for (u32 j = 0; j < g_ppu_func_subs.size(); j++) + // skip NOP + if (base[i].data() == se32(0x60000000)) { - if ((base[i] & g_ppu_func_subs[j].ops[0].mask) == g_ppu_func_subs[j].ops[0].crc) - { - bool found = true; - u32 can_skip = 0; - for (u32 k = i, x = 0; x + 1 <= g_ppu_func_subs[j].ops.size(); k++, x++) - { - if (k >= size) - { - found = false; - break; - } - - // skip NOP - if (base[k] == se32(0x60000000)) - { - x--; - continue; - } - - const u32 mask = g_ppu_func_subs[j].ops[x].mask; - const u32 crc = g_ppu_func_subs[j].ops[x].crc; - - if (!mask) - { - // TODO: define syntax - if (crc < 4) // skip various number of instructions that don't match next pattern entry - { - can_skip += crc; - k--; // process this position again - } - else if (base[k] != crc) // skippable pattern ("optional" instruction), no mask allowed - { - k--; - if (can_skip) // cannot define this behaviour properly - { - LOG_WARNING(LOADER, "hook_ppu_funcs(): can_skip = %d (unchanged)", can_skip); - } - } - else - { - if (can_skip) // cannot define this behaviour properly - { - LOG_WARNING(LOADER, "hook_ppu_funcs(): can_skip = %d (set to 0)", can_skip); - can_skip = 0; - } - } - } - else if ((base[k] & mask) != crc) // masked pattern - { - if (can_skip) - { - can_skip--; - } - else - { - found = false; - break; - } - } - else - { - can_skip = 0; - } - } - if (found) - { - LOG_NOTICE(LOADER, "Function '%s' hooked (addr=0x%x)", g_ppu_func_subs[j].name, vm::get_addr(base + i * 4)); - g_ppu_func_subs[j].found++; - base[i] = re32(0x04000000 | g_ppu_func_subs[j].index | EIF_PERFORM_BLR); // hack - } - } + continue; } + + hook_ppu_func(base, i, size); } // check function groups @@ -259,6 +332,12 @@ void hook_ppu_funcs(u32* base, u32 size) { const u64 group = g_ppu_func_subs[i].group; + if (!group) + { + // skip if group not set + continue; + } + enum GroupSearchResult : u32 { GSR_SUCCESS = 0, // every function from this group has been found once @@ -320,17 +399,17 @@ void hook_ppu_funcs(u32* base, u32 size) if (g_ppu_func_subs[j].group == group) g_ppu_func_subs[j].found = 0; } - char name[9] = "????????"; + char group_name[9] = {}; - *(u64*)name = group; + *(u64*)group_name = group; if (res == GSR_SUCCESS) { - LOG_SUCCESS(LOADER, "Function group [%s] successfully hooked", std::string(name, 9).c_str()); + LOG_SUCCESS(LOADER, "Function group [%s] successfully hooked", group_name); } else { - LOG_ERROR(LOADER, "Function group [%s] failed:%s%s", std::string(name, 9).c_str(), + LOG_ERROR(LOADER, "Function group [%s] failed:%s%s", group_name, (res & GSR_MISSING ? " missing;" : ""), (res & GSR_EXCESS ? " excess;" : "")); } @@ -338,6 +417,102 @@ void hook_ppu_funcs(u32* base, u32 size) } } +bool patch_ppu_import(u32 addr, u32 index) +{ + const auto data = vm::ptr::make(addr); + + using namespace PPU_instr; + + // 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(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR)); + 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::ptr::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(index | EIF_PERFORM_BLR)); + 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(index | EIF_PERFORM_BLR)); + 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(index | EIF_PERFORM_BLR)); + return true; + } + + return false; +} + Module::Module(const char* name, void(*init)()) : m_is_loaded(false) , m_name(name) diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index c013bae9f1..58ea0d9cf7 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -43,19 +43,31 @@ struct ModuleFunc } }; -struct SFuncOp +enum : u32 { - u32 crc; + SPET_MASKED_OPCODE, + SPET_OPTIONAL_MASKED_OPCODE, + SPET_LABEL, + SPET_BRANCH_TO_LABEL, + SPET_BRANCH_TO_FUNC, +}; + +struct SearchPatternEntry +{ + u32 type; + u32 data; u32 mask; + u32 num; // supplement info }; struct StaticFunc { u32 index; const char* name; - std::vector ops; + std::vector ops; u64 group; u32 found; + std::unordered_map labels; }; class Module : public LogBase @@ -138,17 +150,26 @@ void clear_ppu_functions(); u32 get_function_id(const char* name); u32 add_ppu_func_sub(StaticFunc sf); -u32 add_ppu_func_sub(const char group[8], const u64 ops[], const char* name, Module* module, ppu_func_caller func); +u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], size_t count, const char* name, Module* module, ppu_func_caller func); -void hook_ppu_funcs(u32* base, u32 size); +void hook_ppu_funcs(vm::ptr base, u32 size); + +bool patch_ppu_import(u32 addr, u32 index); #define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, bind_func(name))) #define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, bind_func(name))) #define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, bind_func(_nid_##nid))) -#define REG_SUB(module, group, name, ...) \ - static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \ - if (name ## _table[0]) add_ppu_func_sub(group, name ## _table, #name, &module, bind_func(name)) +#define REG_SUB(module, group, ns, name, ...) \ + const SearchPatternEntry name##_table[] = {__VA_ARGS__}; \ + add_ppu_func_sub(group, name##_table, sizeof(name##_table) / sizeof(SearchPatternEntry), #name, &module, bind_func(ns::name)) + +#define se_op_all(type, op, sup) []() { s32 XXX = 0; SearchPatternEntry res = { (type), (op), 0, (sup) }; XXX = -1; res.mask = (op) ^ ~res.data; return res; }() +#define se_op(op) se_op_all(SPET_MASKED_OPCODE, op, 0) +#define se_opt_op(op) se_op_all(SPET_OPTIONAL_MASKED_OPCODE, op, 0) +#define se_label(label) { SPET_LABEL, (label) } +#define se_br_label(op, label) se_op_all(SPET_BRANCH_TO_LABEL, op, label) +#define se_func_call(op, name) se_op_all(SPET_BRANCH_TO_FUNC, op, get_function_id(#name)) #define UNIMPLEMENTED_FUNC(module) module.Error("%s", __FUNCTION__) diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index 25c2911a8f..51a64ef198 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -168,7 +168,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) { vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { // lock the first 0x80 bytes of spurs - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); // Calculate the contention (number of SPUs used) for each workload u8 contention[CELL_SPURS_MAX_WORKLOAD]; @@ -325,7 +325,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) { vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { // lock the first 0x80 bytes of spurs - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); // Calculate the contention (number of SPUs used) for each workload u8 contention[CELL_SPURS_MAX_WORKLOAD2]; @@ -696,7 +696,7 @@ void spursSysServiceMain(SPUThread & spu, u32 pollStatus) { vm::reservation_acquire(vm::get_ptr(spu.ls_offset + 0x100), vm::cast(ctxt->spurs.addr()), 128); vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); // Halt if already initialised if (spurs->m.sysSrvOnSpu & (1 << ctxt->spuNum)) { @@ -786,7 +786,7 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt) bool terminate = false; vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); // Terminate request if (spurs->m.sysSrvMsgTerminate & (1 << ctxt->spuNum)) { @@ -853,7 +853,7 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt) } vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) { // Update workload status and runnable flag based on the workload state @@ -910,7 +910,7 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC u32 wklNotifyBitSet; u8 spuPort; vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); wklNotifyBitSet = 0; spuPort = spurs->m.spuPort;; @@ -952,7 +952,7 @@ void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32 u8 sysSrvMsgUpdateTrace; vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); sysSrvMsgUpdateTrace = spurs->m.sysSrvMsgUpdateTrace; spurs->m.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum); @@ -1006,7 +1006,7 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte bool do_return = false; vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); if (spurs->m.sysSrvWorkload[ctxt->spuNum] == 0xFF) { do_return = true; @@ -1024,7 +1024,7 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte spursSysServiceActivateWorkload(spu, ctxt); vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() { - auto spurs = ctxt->spurs.get_priv_ptr(); + auto spurs = ctxt->spurs.priv_ptr(); if (wklId >= CELL_SPURS_MAX_WORKLOAD) { spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x10; @@ -1158,7 +1158,7 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * s32 rc = CELL_OK; s32 numNewlyReadyTasks; vm::reservation_op(vm::cast(ctxt->taskset.addr()), 128, [&]() { - auto taskset = ctxt->taskset.get_priv_ptr(); + auto taskset = ctxt->taskset.priv_ptr(); // Verify taskset state is valid auto _0 = be_t::make(u128::from32(0)); @@ -1299,7 +1299,7 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 * // Increment the ready count of the workload by the number of tasks that have become ready vm::reservation_op(vm::cast(kernelCtxt->spurs.addr()), 128, [&]() { - auto spurs = kernelCtxt->spurs.get_priv_ptr(); + auto spurs = kernelCtxt->spurs.priv_ptr(); s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].read_relaxed(); readyCount += numNewlyReadyTasks; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 2e2c07b723..7c29a074b2 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -1,8 +1,10 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/CB_FUNC.h" +#include "Emu/Cell/PPUInstrTable.h" #include "Emu/CPU/CPUThreadManager.h" #include "cellAudio.h" @@ -638,569 +640,577 @@ Module libmixer("libmixer", []() ssp.clear(); }; - REG_SUB(libmixer, "surmxAAN", cellAANAddData, - 0xffffffff7c691b78, - 0xffffffff7c0802a6, - 0xfffffffff821ff91, - 0xfffffffff8010080, - 0xffffffff7c802378, - 0xffffffff7caa2b78, - 0xffffffff81690000, - 0xffffffff7c050378, - 0xffffffff7cc43378, - 0x78630020, // clrldi r3,r3,32 - 0xffffffff7d465378, - 0xffffffff812b0030, - 0xffffffff80090000, - 0xfffffffff8410028, - 0xffffffff7c0903a6, - 0xffffffff80490004, - 0xffffffff4e800421, - 0xffffffffe8410028, - 0xffffffffe8010080, - 0xffffffff7c6307b4, - 0xffffffff7c0803a6, - 0xffffffff38210070, - 0xffffffff4e800020 + using namespace PPU_instr; + + REG_SUB(libmixer, "surmxAAN", , 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, "surmxAAN", cellAANConnect, - 0xfffffffff821ff71, - 0xffffffff7c0802a6, - 0xffffffff2f830000, - 0xfffffffff80100a0, - 0xffffffff3c008031, - 0xffffffff7c691b78, - 0xffffffff7c8a2378, - 0xffffffff60000003, - 0xffffff00409e0018, // bne - 0xffffffff7c0307b4, - 0xffffffffe80100a0, - 0xffffffff38210090, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xffffffff2f850000, - 0xffffffff78630020, - 0xffffffff38810070, - 0xffffff00419effe0, // beq - 0xffffffff81690000, - 0xffffffff38000001, - 0xffffffff91210074, - 0xffffffff90a10070, - 0xffffffff90c10078, - 0xffffffff9141007c, - 0xffffffff812b0018, // difference - 0xffffffff90010080, - 0xffffffff80090000, - 0xfffffffff8410028, - 0xffffffff7c0903a6, - 0xffffffff80490004, - 0xffffffff4e800421, - 0xffffffffe8410028, - 0xffffffff7c601b78, - 0xffffffff7c0307b4, - 0xffffffffe80100a0, - 0xffffffff38210090, - 0xffffffff7c0803a6, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmxAAN", , 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 }, + se_br_label(BNE(cr7, XXX), 0x24), + se_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 }, + se_label(0x38), + { SPET_MASKED_OPCODE, 0x2f850000, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x38810070, 0xffffffff }, + se_br_label(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, "surmxAAN", cellAANDisconnect, - 0xfffffffff821ff71, - 0xffffffff7c0802a6, - 0xffffffff2f830000, - 0xfffffffff80100a0, - 0xffffffff3c008031, - 0xffffffff7c691b78, - 0xffffffff7c8a2378, - 0xffffffff60000003, - 0xffffff00409e0018, // bne - 0xffffffff7c0307b4, - 0xffffffffe80100a0, - 0xffffffff38210090, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xffffffff2f850000, - 0xffffffff78630020, - 0xffffffff38810070, - 0xffffff00419effe0, // beq - 0xffffffff81690000, - 0xffffffff38000001, - 0xffffffff91210074, - 0xffffffff90a10070, - 0xffffffff90c10078, - 0xffffffff9141007c, - 0xffffffff812b001c, // difference - 0xffffffff90010080, - 0xffffffff80090000, - 0xfffffffff8410028, - 0xffffffff7c0903a6, - 0xffffffff80490004, - 0xffffffff4e800421, - 0xffffffffe8410028, - 0xffffffff7c601b78, - 0xffffffff7c0307b4, - 0xffffffffe80100a0, - 0xffffffff38210090, - 0xffffffff7c0803a6, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmxAAN", , 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 }, + se_br_label(BNE(cr7, XXX), 0x24), + se_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 }, + se_label(0x38), + { SPET_MASKED_OPCODE, 0x2f850000, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x78630020, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x38810070, 0xffffffff }, + se_br_label(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, "surmixer", cellSurMixerCreate, - 0xffffffff2f830000, - 0xffffffff7c0802a6, - 0xfffffffff821ff51, - 0xfffffffffbc100a0, - 0xfffffffffb210078, - 0xfffffffffb410080, - 0xfffffffffb610088, - 0xfffffffffb810090, - 0xfffffffffba10098, - 0xfffffffffbe100a8, - 0xfffffffff80100c0, - 0xffffffff7c7e1b78, - 0xf000000040000000, // bne - 0xffffffff3fe08031, - 0xffffffff63ff0003, - 0xffffffffe80100c0, - 0xffffffff7fe307b4, - 0xffffffffeb210078, - 0xffffffffeb410080, - 0xffffffff7c0803a6, - 0xffffffffeb610088, - 0xffffffffeb810090, - 0xffffffffeba10098, - 0xffffffffebc100a0, - 0xffffffffebe100a8, - 0xffffffff382100b0 + REG_SUB(libmixer, "surmixer", , 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 }, + se_br_label(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 }, + se_label(0x6c), ); - REG_SUB(libmixer, "surmixer", cellSurMixerGetAANHandle, - 0xff00000081428250, // lwz - 0xffffffff3d607fce, - 0xffffffff616bfffe, - 0xffffffff812a0018, - 0xffffffff7d2afe70, - 0xffffffff91230000, - 0xffffffff7d404a78, - 0xffffffff7c005050, - 0xffffffff7c00fe70, - 0xffffffff7c035838, - 0xffffffff3c638031, - 0xffffffff38630002, - 0xffffffff7c6307b4, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmixer", , cellSurMixerGetAANHandle, + se_op(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, "surmixer", cellSurMixerChStripGetAANPortNo, - 0xff00000081228250, // lwz - 0xffffffff7c661b78, - 0xffffffff3c608031, - 0xffffffff78c60020, - 0xffffffff78840020, - 0xffffffff60630002, - 0xffffffff80090018, - 0xffffffff78a50020, - 0xffffffff2f800000, - 0xffffffff4d9e0020, - 0xffffffff78030020, - 0xf000000040000000 // b + REG_SUB(libmixer, "surmixer", , cellSurMixerChStripGetAANPortNo, + se_op(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 }, + se_op(B(XXX, 0, 0)), ); - REG_SUB(libmixer, "surmixer", cellSurMixerSetNotifyCallback, - 0xff00000081428250, // lwz - 0xffffffff7c0802a6, - 0xfffffffff821ff81, - 0xfffffffff8010090, - 0xffffffff7c6b1b78, - 0xffffffff3c608031, - 0xffffffff812a0018, - 0xffffffff7c882378, - 0xffffffff60630003, - 0xffffffff2f890000, - 0xffffffff2f0b0000, - 0xffffff00409e0020, // bne - 0xffffffff3c608031, - 0xffffffff60630002, - 0xffffffffe8010090, - 0xffffffff7c6307b4, - 0xffffffff38210080, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xffffff00419affec, // beq - 0xf0000000800a001c, // lwz - 0xffffffff79290020, - 0xffffffff38810070, - 0xffffffff2f800000, - 0xffffffff7d234b78 + REG_SUB(libmixer, "surmixer", , cellSurMixerSetNotifyCallback, + se_op(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 + se_op(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, "surmixer", cellSurMixerRemoveNotifyCallback, - 0xff00000081628250, // lwz - 0xffffffff7c0802a6, - 0xfffffffff821ff81, - 0xfffffffff8010090, - 0xffffffff7c6a1b78, - 0xffffffff3d208031, - 0xffffffff806b0018, - 0xffffffff61290002, // ori - 0xffffffff2f830000, - 0xffff0000409e0018, // bne - 0xffffffffe8010090, - 0xffffffff7d2307b4, - 0xffffffff38210080, - 0xffffffff7c0803a6, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmixer", , cellSurMixerRemoveNotifyCallback, + se_op(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, "surmixer", cellSurMixerStart, - 0xfffffffff821ff71, - 0xffffffff7c0802a6, - 0xfffffffffbc10080, - 0xf000000083c20000, // lwz - 0xfffffffff80100a0, - 0xfffffffffba10078, - 0xfffffffffbe10088, - 0xffffffff801e0018, - 0xffffffff2f800000, - 0xf0000000409e002c, // bne - 0xffffffff3fe08031, - 0xffffffff63ff0002, - 0xffffffffe80100a0, - 0xffffffff7fe307b4, - 0xffffffffeba10078, - 0xffffffffebc10080, - 0xffffffff7c0803a6, - 0xffffffffebe10088, - 0xffffffff38210090, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmixer", , cellSurMixerStart, + { SPET_MASKED_OPCODE, 0xf821ff71, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, + { SPET_MASKED_OPCODE, 0xfbc10080, 0xffffffff }, + se_op(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, "surmixer", cellSurMixerSetParameter, - 0xfffffffff821ff81, - 0xffffffff7c0802a6, - 0xfffffffffbc10070, - 0xfffffffffc000890, - 0xf000000083c28250, // lwz - 0xffffffff3d208031, - 0xfffffffff8010090, - 0xfffffffffbe10078, - 0xffffffff61290002, - 0xffffffff7c7f1b78, - 0xffffffff801e0018, - 0xffffffff2f800000, - 0xffff0000409e0020, // bne - 0xffffffffe8010090, - 0xffffffff7d2307b4, - 0xffffffffebc10070, - 0xffffffffebe10078, - 0xffffffff7c0803a6, - 0xffffffff38210080, - 0xffffffff4e800020, - 0xffffffff801e001c, - 0xffffffff2b03001f, - 0xffffffff2f800000, - 0xffff0000419cffd8, // blt - 0xffffffff2b83002b, - 0xffff000040990008, // ble - 0xffff0000409d0054 // ble + REG_SUB(libmixer, "surmixer", , cellSurMixerSetParameter, + { SPET_MASKED_OPCODE, 0xf821ff81, 0xffffffff }, + { SPET_MASKED_OPCODE, 0x7c0802a6, 0xffffffff }, + { SPET_MASKED_OPCODE, 0xfbc10070, 0xffffffff }, + { SPET_MASKED_OPCODE, 0xfc000890, 0xffffffff }, + se_op(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, "surmixer", cellSurMixerFinalize, - 0xfffffffff821ff91, - 0xffffffff7c0802a6, - 0xfffffffff8010080, - 0xffffff004bfffde1, // bl - 0xffffffffe8010080, - 0xffffffff38600000, - 0xffffffff38210070, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xfffffffff821ff71, - 0xffffffff7c0802a6, - 0xfffffffffba10078, - 0xf000000083a28250, // lwz - 0xfffffffff80100a0, - 0xffffffff817d0018, - 0xffffffff7d635b78, - 0xffffffff812b0000, - 0xffffffff81490000, - 0xffffffff800a0000, - 0xfffffffff8410028, - 0xffffffff7c0903a6, - 0xffffffff804a0004, - 0xffffffff4e800421 + REG_SUB(libmixer, "surmixer", , 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, "surmixer", cellSurMixerSurBusAddData, - 0xff00000081428250, // lwz - 0xffffffff7c0802a6, - 0xfffffffff821ff91, - 0xfffffffff8010080, - 0xffffffff7c601b78, - 0xffffffff3d208031, - 0xffffffff806a0018, - 0xffffffff7c8b2378, - 0xffffffff7cc73378, - 0xffffffff2f830000, - 0xffffffff61290002, - 0xffff0000409e0018, // bne - 0xffffffffe8010080, - 0xffffffff7d2307b4, - 0xffffffff38210070, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xffffffff78a40020, - 0xffffffff78050020, - 0xffffffff800a001c, - 0xffffffff78680020, - 0xffffffff2f800000, - 0xffffffff7d034378, - 0xffffffff79660020, - 0xffffffff78e70020, - 0xffff0000419cffcc // blt + REG_SUB(libmixer, "surmixer", , cellSurMixerSurBusAddData, + se_op(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, "surmixer", cellSurMixerChStripSetParameter, - 0xff00000081028250, // lwz - 0xffffffff7c6b1b78, - 0xffffffff3c608031, - 0xffffffff7c8a2378, - 0xffffffff7ca62b78, - 0xffffffff60630002, - 0xffffffff81280018, - 0xffffffff2f890000, - 0xffff00004d9e0020, // beqlr - 0xffffffff8008001c, - 0xffffffff79640020, - 0xffffffff79450020, - 0xffffffff2f800000, - 0xffffffff78c60020, - 0xffffffff4d9c0020, - 0xffffffff79230020, - 0xf000000048000000 // b + REG_SUB(libmixer, "surmixer", , cellSurMixerChStripSetParameter, + se_op(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, "surmixer", cellSurMixerPause, - 0xff00000081428250, // lwz - 0xffffffff7c0802a6, - 0xfffffffff821ff81, - 0xfffffffff8010090, - 0xffffffff3d208031, - 0xfffffffffbe10078, - 0xffffffff800a0018, - 0xffffffff7c7f1b78, - 0xfffffffffbc10070, - 0xffffffff2f800000, - 0xffffffff61290002, - 0xffff0000409e0020, // bne - 0xffffffffe8010090, - 0xffffffff7d2307b4, - 0xffffffffebc10070, - 0xffffffffebe10078, - 0xffffffff7c0803a6, - 0xffffffff38210080, - 0xffffffff4e800020, - 0xffffffff800a001c, - 0xffffffff2b030002, - 0xffffffff2f800000 + REG_SUB(libmixer, "surmixer", , cellSurMixerPause, + se_op(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, "surmixer", cellSurMixerGetCurrentBlockTag, - 0xff00000081628250, // lwz - 0xffffffff3d208031, - 0xffffffff61290002, - 0xffffffff880b0020, - 0xffffffff2f800000, - 0xffff0000419e0010, // beq - 0xffffffffe80b0028, - 0xffffffff39200000, - 0xfffffffff8030000, - 0xffffffff7d2307b4, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmixer", , cellSurMixerGetCurrentBlockTag, + se_op(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, "surmixer", cellSurMixerGetTimestamp, - 0xff00000081628250, // lwz - 0xffffffff7c0802a6, - 0xfffffffff821ff91, - 0xfffffffff8010080, - 0xffffffff7c852378, - 0xffffffff3d208031, - 0xffffffff880b0020, - 0xffffffff7c641b78, - 0xffffffff78a50020, - 0xffffffff2f800000, - 0xffffffff61290002, - 0xffff000040de0018, // bne- - 0xffffffffe8010080, - 0xffffffff7d2307b4, - 0xffffffff38210070, - 0xffffffff7c0803a6, - 0xffffffff4e800020, - 0xffffffff806b04d8, - 0xf000000048000001 // bl + REG_SUB(libmixer, "surmixer", , cellSurMixerGetTimestamp, + se_op(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, "surmixer", cellSurMixerBeep, - 0xff00000081228250, // lwz - 0xffffffff7c641b78, - 0xffffffff80690018, - 0xffffffff2f830000, - 0xffff00004d9e0020, // beqlr - 0xffffffff8009001c, - 0xffffffff78630020, - 0xffffffff78840020, - 0xffffffff2f800000, - 0xffffffff4d9c0020, - 0xf000000048000000 // b + REG_SUB(libmixer, "surmixer", , cellSurMixerBeep, + se_op(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, "surmxSSP", cellSSPlayerCreate, - 0xfffffffff821ff51, - 0xffffffff7c0802a6, - 0xffffffff2f840000, - 0xfffffffff80100c0, - 0xffffffff3c008031, - 0xfffffffffb210078, - 0xfffffffffb410080, - 0xfffffffffb610088, - 0xfffffffffb810090, - 0xfffffffffba10098, - 0xfffffffffbc100a0, - 0xfffffffffbe100a8, - 0xffffffff7c9a2378, - 0xffffffff7c791b78, - 0xffffffff60000003, - 0xffff0000419e0068, // beq - 0xff00000083620000, // lwz - 0xffffffff3b800000, - 0xffffffff381b0064, - 0xffffffff901b0018, - 0xffffffff5780103a, - 0xffffffff38800010, - 0xffffffff7c0007b4, - 0xffffffff38a01c70, - 0xffffffff7fc0da14, - 0xffffffff38c00000, - 0xffffffff83be0024, - 0xffffffff2f9d0000, - 0xffffffff7ba30020, - 0xffff000041de00c0, // beq- - 0xf000000048000001 // bl + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerRemove, - 0xffffffff7c641b78, - 0xffffffff7c0802a6, - 0xffffffff3c608031, - 0xffffffff2f840000, - 0xfffffffff821ff51, - 0xfffffffffb010070, - 0xfffffffffb210078, - 0xfffffffffb410080, - 0xfffffffffb610088, - 0xfffffffffb810090, - 0xfffffffffba10098, - 0xfffffffffbc100a0, - 0xfffffffffbe100a8, - 0xfffffffff80100c0, - 0xffffffff60630003, - 0xffff0000419e0074, // beq - 0xffffffff81240000, - 0xffffffff78830020, - 0xffffffff83440004, - 0xffffffff83240008, - 0xffffffff7b5b0020, - 0xffffffff81690000, - 0xffffffff800b0000, - 0xfffffffff8410028, - 0xffffffff7c0903a6, - 0xffffffff804b0004, - 0xffffffff4e800421 + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerSetWave, - 0xffffffff7c601b78, - 0xffffffff78840020, - 0xffffffff2f800000, - 0xffffffff3c608031, - 0xffffffff78a50020, - 0xffff0000419e000c, // beq - 0xffffffff78030020, - 0xf000000048000000, // b - 0xffffffff60630003, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerPlay, - 0xffffffff7c601b78, - 0xffffffff3c608031, - 0xffffffff2f800000, - 0xffffffff60630003, - 0xffffffff78840020, - 0xffffffff4d9e0020, - 0xffffffff78030020, - 0xf000000048000000, // b - 0xfffffffff821ff81, // next func - 0xffffffff7c0802a6, - 0xfffffffffbe10078, - 0xffffffff7c7f1b78, - 0xff00000081620028, // lwz - 0xfffffffff8010090, - 0xffffffff39400000, - 0xffffffff38630010 + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerStop, - 0xfffffffff821ff91, - 0xffffffff7c0802a6, - 0xffffffff2f830000, - 0xfffffffff8010080, - 0xffffffff3c008031, - 0xffffffff78630020, - 0xffffffff60000003, - 0xffff0000419e0010, // beq - 0xffffffff78840020, - 0xf000000048000001, // bl - 0xffffffff38000000, - 0xffffffff7c0307b4, - 0xffffffffe8010080, - 0xffffffff38210070, - 0xffffffff7c0803a6, - 0xffffffff4e800020 + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerSetParam, - 0xffffffff7c601b78, - 0xffffffff3c608031, - 0xffffffff2f800000, - 0xffffffff60630003, - 0xffffffff78840020, - 0xffffffff4d9e0020, - 0xffffffff78030020, - 0xf000000048000000, // b - 0xfffffffff821ff71, // next func - 0xffffffff7c0802a6, - 0xffffffff3d608031, - 0xfffffffff80100a0, - 0xffffffff80030068, - 0xffffffff616b0002, - 0xfffffffffbc10080, - 0xffffffff2f800000 + REG_SUB(libmixer, "surmxSSP", , 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, "surmxSSP", cellSSPlayerGetState, - 0xffffffff7c601b78, - 0xffffffff3c608031, - 0xffffffff2f800000, - 0xffffffff60630003, - 0xffffffff4d9e0020, - 0xffffffff78030020, - 0xf000000048000000 // b + REG_SUB(libmixer, "surmxSSP", , 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, "surmxUti", cellSurMixerUtilGetLevelFromDB, 0); - REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex, 0); - REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio, 0); + //REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDB); + //REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex); + //REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio); }); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index ee1d0e0e7c..77d3ef2fee 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -559,13 +559,12 @@ s32 _sys_printf(vm::ptr fmt) // va_args... return CELL_OK; } -s32 _nid_E75C40F2(u32 dest) +s32 sys_process_get_paramsfo(vm::ptr buffer) { - sysPrxForUser.Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest); + sysPrxForUser.Warning("sys_process_get_paramsfo(buffer=0x%x)", buffer); - // prx: load some data (0x40 bytes) previously set by sys_process_get_paramsfo - //memset(Memory + dest, 0, 0x40); - return CELL_ENOENT; + // prx: load some data (0x40 bytes) previously set by _sys_process_get_paramsfo syscall + return _sys_process_get_paramsfo(buffer); } Module sysPrxForUser("sysPrxForUser", []() @@ -674,5 +673,5 @@ Module sysPrxForUser("sysPrxForUser", []() REG_FUNC(sysPrxForUser, _sys_printf); - REG_UNNAMED(sysPrxForUser, E75C40F2); + REG_FUNC(sysPrxForUser, sys_process_get_paramsfo); }); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp b/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp new file mode 100644 index 0000000000..e59662d333 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/sys_libc.cpp @@ -0,0 +1,33 @@ +#include "stdafx.h" +#include "Emu/Memory/Memory.h" +#include "Emu/System.h" +#include "Emu/SysCalls/Modules.h" +#include "Emu/Cell/PPUInstrTable.h" + +extern Module sys_libc; + +namespace sys_libc_func +{ + void memcpy(vm::ptr dst, vm::ptr src, u32 size) + { + sys_libc.Warning("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size); + + ::memcpy(dst.get_ptr(), src.get_ptr(), size); + } +} + +Module sys_libc("sys_libc", []() +{ + using namespace PPU_instr; + + REG_SUB(sys_libc, "", sys_libc_func, memcpy, + se_op(CMPLDI(cr7, r5, 7)), + se_op(CLRLDI(r3, r3, 32)), + se_op(CLRLDI(r4, r4, 32)), + se_op(MR(r11, r3)), + se_op(BGT(cr7, XXX & 0xff)), + se_op(CMPDI(r5, 0)), + se_opt_op(MR(r9, r3)), + { SPET_MASKED_OPCODE, 0x4d820020, 0xffffffff }, + ); +}); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 2adbd38fd2..6d1d7086a9 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -80,7 +80,7 @@ const ppu_func_caller sc_table[1024] = null_func,//bind_func(), //27 (0x01B) DBG null_func,//bind_func(_sys_process_get_number_of_object)//28 (0x01C) ROOT bind_func(sys_process_get_id), //29 (0x01D) ROOT - bind_func(sys_process_get_paramsfo), //30 (0x01E) + bind_func(_sys_process_get_paramsfo), //30 (0x01E) null_func,//bind_func(sys_process_get_ppu_guid), //31 (0x01F) null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, //32-40 UNS diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index ccbe619bee..d1f7662387 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -4,6 +4,8 @@ #include "Emu/System.h" #include "Emu/SysCalls/SysCalls.h" +#include "Emu/FS/vfsFile.h" +#include "Loader/PSF.h" #include "sys_memory.h" #include "sys_process.h" @@ -286,29 +288,25 @@ s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) return process_is_spu_lock_line_reservation_address(addr, flags); } -s32 sys_process_get_paramsfo(vm::ptr buffer) +s32 _sys_process_get_paramsfo(vm::ptr buffer) { - sys_process.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.addr()); - return CELL_ENOENT; + sys_process.Warning("_sys_process_get_paramsfo(buffer=0x%x)", buffer); - /*//Before uncommenting this code, we should check if it is actually working. - MemoryAllocator> fd; - char filePath [] = "/app_home/../PARAM.SFO"; - if (!cellFsOpen(Memory.RealToVirtualAddr(filePath), 0, fd, NULL, 0)) + if (!Emu.GetTitleID().length()) + { return CELL_ENOENT; + } - MemoryAllocator> pos, nread; - cellFsLseek(fd, 0, CELL_SEEK_SET, pos); //TODO: Move to the appropriate offset (probably 0x3F7) - cellFsRead(fd, buffer.addr(), 40, nread); //WARNING: If offset==0x3F7: The file will end before the buffer (40 bytes) is filled! - cellFsClose(fd); + memset(buffer.get_ptr(), 0, 0x40); + memcpy(buffer.get_ptr() + 1, Emu.GetTitleID().c_str(), std::min(Emu.GetTitleID().length(), 9)); - return CELL_OK;*/ + return CELL_OK; } s32 process_get_sdk_version(u32 pid, s32& ver) { - // TODO: get correct SDK version for selected pid - ver = Emu.m_sdk_version; + // get correct SDK version for selected pid + ver = Emu.GetSDKVersion(); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.h b/rpcs3/Emu/SysCalls/lv2/sys_process.h index e7a1240444..376a9791fc 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.h @@ -33,7 +33,7 @@ s32 sys_process_getpid(); s32 sys_process_getppid(); s32 sys_process_get_number_of_object(u32 object, vm::ptr nump); s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size); -s32 sys_process_get_paramsfo(vm::ptr buffer); +s32 _sys_process_get_paramsfo(vm::ptr buffer); s32 sys_process_get_sdk_version(u32 pid, vm::ptr version); s32 sys_process_get_status(u64 unk); s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index cae1afd595..13cab011e9 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -38,11 +38,6 @@ static const std::string& BreakPointsDBName = "BreakPoints.dat"; static const u16 bpdb_version = 0x1000; extern std::atomic g_thread_count; -ModuleInitializer::ModuleInitializer() -{ - Emu.AddModuleInit(std::move(std::unique_ptr(this))); -} - Emulator::Emulator() : m_status(Stopped) , m_mode(DisAsm) @@ -82,11 +77,6 @@ Emulator::~Emulator() void Emulator::Init() { - while(m_modules_init.size()) - { - m_modules_init[0]->Init(); - m_modules_init.erase(m_modules_init.begin()); - } } void Emulator::SetPath(const std::string& path, const std::string& elf_path) @@ -265,24 +255,7 @@ void Emulator::Load() vm::close(); return; } - - // trying to load some info from PARAM.SFO - vfsFile f2("/app_home/../PARAM.SFO"); - if (f2.IsOpened()) - { - PSFLoader psf(f2); - if (psf.Load(false)) - { - std::string version = psf.GetString("PS3_SYSTEM_VER"); - - const size_t dot = version.find('.'); - if (dot != std::string::npos) - { - Emu.m_sdk_version = (std::stoi(version, nullptr, 16) << 20) | ((std::stoi(version.substr(dot + 1), nullptr, 16) & 0xffff) << 4) | 1; - } - } - } - + LoadPoints(BreakPointsDBName); m_status = Ready; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index d011428d0a..deeb613e67 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -61,14 +61,6 @@ public: u32 GetTLSMemsz() const { return tls_memsz; } }; -class ModuleInitializer -{ -public: - ModuleInitializer(); - - virtual void Init() = 0; -}; - class Emulator { enum Mode @@ -83,7 +75,6 @@ class Emulator u32 m_rsx_callback; u32 m_cpu_thr_stop; - std::vector> m_modules_init; std::vector m_break_points; std::vector m_marked_points; @@ -112,7 +103,6 @@ public: std::string m_emu_path; std::string m_title_id; std::string m_title; - s32 m_sdk_version; Emulator(); ~Emulator(); @@ -132,12 +122,12 @@ public: return m_emu_path; } - std::string GetTitleID() const + const std::string& GetTitleID() const { return m_title_id; } - std::string GetTitle() const + const std::string& GetTitle() const { return m_title; } @@ -164,11 +154,6 @@ public: ModuleManager& GetModuleManager() { return *m_module_manager; } SyncPrimManager& GetSyncPrimManager() { return *m_sync_prim_manager; } - void AddModuleInit(std::unique_ptr m) - { - m_modules_init.push_back(std::move(m)); - } - void SetTLSData(u32 addr, u32 filesz, u32 memsz) { m_info.SetTLSData(addr, filesz, memsz); @@ -191,6 +176,7 @@ public: u32 GetTLSMemsz() const { return m_info.GetTLSMemsz(); } u32 GetMallocPageSize() { return m_info.GetProcParam().malloc_pagesize; } + u32 GetSDKVersion() { return m_info.GetProcParam().sdk_version; } u32 GetRSXCallback() const { return m_rsx_callback; } u32 GetCPUThreadStop() const { return m_cpu_thr_stop; } diff --git a/rpcs3/Gui/CompilerELF.cpp b/rpcs3/Gui/CompilerELF.cpp index 3fc419f2f1..6528daf5de 100644 --- a/rpcs3/Gui/CompilerELF.cpp +++ b/rpcs3/Gui/CompilerELF.cpp @@ -1,8 +1,9 @@ #include "stdafx_gui.h" #include "Utilities/rMsgBox.h" -#include "Emu/Cell/PPUProgramCompiler.h" -using namespace PPU_opcodes; +//#include "Emu/Cell/PPUProgramCompiler.h" +//using namespace PPU_opcodes; + #include "CompilerELF.h" enum CompilerIDs @@ -392,8 +393,8 @@ void CompilerELF::LoadElf(wxCommandEvent& event) LoadElf(fmt::ToUTF8(ctrl.GetPath())); } -#include "Emu/Cell/PPUDisAsm.h" -#include "Emu/Cell/PPUDecoder.h" +//#include "Emu/Cell/PPUDisAsm.h" +//#include "Emu/Cell/PPUDecoder.h" void CompilerELF::LoadElf(const std::string& path) { diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index 879da2e003..55e77b7028 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -29,20 +29,22 @@ struct wxWriter : Log::LogListener wxTextAttr m_color_white; wxTextAttr m_color_yellow; wxTextAttr m_color_red; + wxTextAttr m_color_green; MTRingbuffer messages; std::atomic newLog; bool inited; - wxWriter(wxTextCtrl* p_log, wxTextCtrl* p_tty) : - m_color_white(wxColour(255, 255, 255)) , - m_color_yellow(wxColour(255, 255, 0)) , - m_color_red(wxColour(255, 0, 0)) , - m_log(p_log), - m_tty(p_tty), - newLog(false), - inited(false) + wxWriter(wxTextCtrl* p_log, wxTextCtrl* p_tty) + : m_color_white(wxColour(255, 255, 255)) + , m_color_yellow(wxColour(255, 255, 0)) + , m_color_red(wxColour(255, 0, 0)) + , m_color_green(wxColour(0, 255, 0)) + , m_log(p_log) + , m_tty(p_tty) + , newLog(false) + , inited(false) { - m_log->Bind(EVT_LOG_COMMAND, [this](wxCommandEvent &evt){this->write(evt);}); + m_log->Bind(EVT_LOG_COMMAND, [this](wxCommandEvent &evt){ this->write(evt); }); } wxWriter(wxWriter &other) = delete; @@ -83,6 +85,9 @@ struct wxWriter : Log::LogListener case Log::Error: llogcon->SetDefaultStyle(m_color_red); break; + case Log::Success: + llogcon->SetDefaultStyle(m_color_green); + break; default: break; } diff --git a/rpcs3/Gui/Debugger.cpp b/rpcs3/Gui/Debugger.cpp index 26018d0563..66f85de571 100644 --- a/rpcs3/Gui/Debugger.cpp +++ b/rpcs3/Gui/Debugger.cpp @@ -7,7 +7,7 @@ #include "Debugger.h" #include "InterpreterDisAsm.h" #include "Emu/CPU/CPUThreadManager.h" -#include "Emu/Cell/PPCThread.h" +#include "Emu/CPU/CPUThread.h" class DbgEmuPanel : public wxPanel @@ -95,7 +95,7 @@ public: break; case DID_EXIT_THR_SYSCALL: - Emu.GetCPU().RemoveThread(((PPCThread*)event.GetClientData())->GetId()); + Emu.GetCPU().RemoveThread(((CPUThread*)event.GetClientData())->GetId()); break; } diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index 0051364a08..432f88e43c 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -62,7 +62,7 @@ void GLGSFrame::Flip(void* context) canvas->SwapBuffers(); m_frames++; - const std::string sub_title = Emu.GetTitle() += Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | "; + const std::string sub_title = Emu.GetTitle() + (Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | "); if (fps_t.GetElapsedTimeInSec() >= 0.5) { diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 6ba54a475e..48c7cdc97f 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -487,8 +487,8 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) cbox_camera_type->Append("USB Video Class 1.1"); cbox_hle_loglvl->Append("All"); - cbox_hle_loglvl->Append("Success"); cbox_hle_loglvl->Append("Warnings"); + cbox_hle_loglvl->Append("Success"); cbox_hle_loglvl->Append("Errors"); cbox_hle_loglvl->Append("Nothing"); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 77cd91dbed..d4d6b6b01c 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -307,8 +307,6 @@ namespace loader return load_sprx(info); } - Emu.m_sdk_version = -1; - //store elf to memory vm::ps3::init(); @@ -467,14 +465,10 @@ namespace loader LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); } - if (!vm::check_addr(addr, 4)) + if (!patch_ppu_import(addr, index)) { LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); } - else - { - vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR)); - } } } } @@ -576,7 +570,7 @@ namespace loader { m_stream->Seek(handler::get_stream_offset() + phdr.p_offset); m_stream->Read(phdr.p_vaddr.get_ptr(), phdr.p_filesz); - hook_ppu_funcs((u32*)phdr.p_vaddr.get_ptr(), vm::cast(phdr.p_filesz)); + hook_ppu_funcs(vm::ptr::make(phdr.p_vaddr.addr()), vm::cast(phdr.p_filesz) / 4); } } break; @@ -618,7 +612,6 @@ namespace loader */ info = proc_param.info; - Emu.m_sdk_version = info.sdk_version; } } break; @@ -689,7 +682,10 @@ namespace loader LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr); } - vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR)); + if (!patch_ppu_import(addr, index)) + { + LOG_ERROR(LOADER, "Failed to inject code at address 0x%x", addr); + } //if (!func || !func->lle_func) //{ diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index a2b15df8d9..96f3b886d4 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -131,7 +131,6 @@ - true true @@ -279,6 +278,7 @@ + @@ -362,7 +362,6 @@ - diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 405e2c839b..c6b9461933 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -341,9 +341,6 @@ Emu\CPU\Cell - - Emu\CPU\Cell - Emu\CPU\Cell @@ -860,6 +857,9 @@ Emu\GPU\RSX + + Emu\SysCalls\Modules + @@ -1105,9 +1105,6 @@ Emu\CPU\Cell - - Emu\CPU\Cell - Emu\CPU\Cell