From 6d7d3acb43d4808575e359ff86a04fe647814daa Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 6 Jul 2013 02:49:38 +0300 Subject: [PATCH] - Fixed loading modules in debug mode. - Improved Lwmutex. - Implemented events syscalls. - Fixed SPU local storage. --- Utilities/Array.h | 55 +++ rpcs3/Emu/Cell/PPCDisAsm.h | 19 +- rpcs3/Emu/Cell/PPCThread.cpp | 50 +- rpcs3/Emu/Cell/PPCThread.h | 21 + rpcs3/Emu/Cell/PPCThreadManager.cpp | 9 +- rpcs3/Emu/Cell/PPUDisAsm.h | 4 +- rpcs3/Emu/Cell/PPUInstrTable.h | 2 +- rpcs3/Emu/Cell/PPUInterpreter.h | 114 +++-- rpcs3/Emu/Cell/PPUThread.cpp | 14 +- rpcs3/Emu/Cell/PPUThread.h | 24 + rpcs3/Emu/Cell/SPUDecoder.h | 6 - rpcs3/Emu/Cell/SPUDisAsm.h | 451 ++++++++++--------- rpcs3/Emu/Cell/SPUInterpreter.h | 74 +-- rpcs3/Emu/Cell/SPUOpcodes.h | 4 +- rpcs3/Emu/Cell/SPUThread.cpp | 2 - rpcs3/Emu/Cell/SPUThread.h | 130 +++--- rpcs3/Emu/Memory/Memory.cpp | 8 + rpcs3/Emu/SysCalls/FuncList.cpp | 4 +- rpcs3/Emu/SysCalls/Modules.cpp | 235 ++++++++++ rpcs3/Emu/SysCalls/Modules.h | 76 ++++ rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 42 +- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 59 +-- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 38 +- rpcs3/Emu/SysCalls/Modules/sys_io.cpp | 26 +- rpcs3/Emu/SysCalls/SysCalls.cpp | 198 ++------ rpcs3/Emu/SysCalls/SysCalls.h | 212 +-------- rpcs3/Emu/SysCalls/lv2/SC_Event.cpp | 137 ++++++ rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 65 +-- rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp | 46 +- rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp | 282 +++++++++++- rpcs3/Emu/System.cpp | 24 +- rpcs3/Emu/System.h | 15 + rpcs3/Emu/event.h | 35 ++ rpcs3/Gui/InterpreterDisAsm.cpp | 5 +- rpcs3/Loader/ELF32.cpp | 21 + rpcs3/Loader/ELF64.cpp | 20 + rpcs3/Loader/Loader.h | 6 + rpcs3/rpcs3.vcxproj | 2 + rpcs3/rpcs3.vcxproj.filters | 6 + 39 files changed, 1639 insertions(+), 902 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules.cpp create mode 100644 rpcs3/Emu/SysCalls/Modules.h create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_Event.cpp create mode 100644 rpcs3/Emu/event.h diff --git a/Utilities/Array.h b/Utilities/Array.h index 45961bd7cd..c672ef4fe6 100644 --- a/Utilities/Array.h +++ b/Utilities/Array.h @@ -209,6 +209,61 @@ template struct Stack : public Array } }; +template class SizedStack +{ + T m_ptr[size]; + uint m_count; + +public: + SizedStack() + { + Clear(); + } + + ~SizedStack() + { + Clear(); + } + + void Clear() + { + m_count = 0; + } + + bool Pop(T& dst) + { + if(!m_count) + return false; + + dst = m_ptr[--m_count]; + return true; + } + + bool Push(const T& src) + { + if(m_count + 1 > size) + return false; + + m_ptr[m_count++] = src; + return true; + } + + size_t GetFreeCount() const + { + return size - m_count; + } + + size_t GetCount() const + { + return m_count; + } + + size_t GetMaxCount() const + { + return size; + } +}; + template class ArrayF { u32 m_count; diff --git a/rpcs3/Emu/Cell/PPCDisAsm.h b/rpcs3/Emu/Cell/PPCDisAsm.h index 0c8ee7eb3b..c3ca64fa25 100644 --- a/rpcs3/Emu/Cell/PPCDisAsm.h +++ b/rpcs3/Emu/Cell/PPCDisAsm.h @@ -23,7 +23,7 @@ protected: { case DumpMode: { - wxString mem = wxString::Format("\t%x:\t", dump_pc); + wxString mem = wxString::Format("\t%08llx:\t", dump_pc); for(u8 i=0; i < 4; ++i) { mem += wxString::Format("%02x", Memory.Read8(dump_pc + i)); @@ -36,14 +36,11 @@ protected: case InterpreterMode: { - wxString mem = wxString::Format("[%x] ", dump_pc); - for(u8 i=0; i < 4; ++i) - { - mem += wxString::Format("%02x", Memory.Read8(dump_pc + i)); - if(i < 3) mem += " "; - } - - last_opcode = mem + ": " + value; + last_opcode = wxString::Format("[%08llx] %02x %02x %02x %02x: %s", dump_pc, + Memory.Read8(offset + dump_pc), + Memory.Read8(offset + dump_pc + 1), + Memory.Read8(offset + dump_pc + 2), + Memory.Read8(offset + dump_pc + 3), value); } break; @@ -55,12 +52,14 @@ protected: public: wxString last_opcode; - uint dump_pc; + u64 dump_pc; + u64 offset; protected: PPC_DisAsm(PPCThread& cpu, DisAsmModes mode = NormalMode) : m_mode(mode) , disasm_frame(NULL) + , offset(0) { if(m_mode != NormalMode) return; diff --git a/rpcs3/Emu/Cell/PPCThread.cpp b/rpcs3/Emu/Cell/PPCThread.cpp index 8124a58115..e58f5a7d41 100644 --- a/rpcs3/Emu/Cell/PPCThread.cpp +++ b/rpcs3/Emu/Cell/PPCThread.cpp @@ -17,6 +17,8 @@ PPCThread::PPCThread(PPCThreadType type) , stack_addr(0) , m_prio(0) , m_offset(0) + , m_sync_wait(false) + , m_wait_thread_id(-1) { } @@ -39,6 +41,9 @@ void PPCThread::Reset() { CloseStack(); + m_sync_wait = 0; + m_wait_thread_id = -1; + SetPc(0); cycle = 0; @@ -92,6 +97,36 @@ void PPCThread::SetName(const wxString& name) m_name = name; } +void PPCThread::Wait(bool wait) +{ + wxCriticalSectionLocker lock(m_cs_sync); + m_sync_wait = wait; +} + +void PPCThread::Wait(const PPCThread& thr) +{ + wxCriticalSectionLocker lock(m_cs_sync); + m_wait_thread_id = thr.GetId(); + m_sync_wait = true; +} + +bool PPCThread::Sync() +{ + wxCriticalSectionLocker lock(m_cs_sync); + + return m_sync_wait; +} + +int PPCThread::ThreadStatus() +{ + if(Emu.IsStopped()) return PPCThread_Stopped; + if(TestDestroy()) return PPCThread_Break; + if(Emu.IsPaused() || Sync()) + return PPCThread_Sleeping; + + return PPCThread_Running; +} + void PPCThread::NextBranchPc() { SetPc(nPC); @@ -127,9 +162,9 @@ void PPCThread::SetEntry(const u64 pc) void PPCThread::SetBranch(const u64 pc) { - if(!Memory.IsGoodAddr(pc)) + if(!Memory.IsGoodAddr(m_offset + pc)) { - ConLog.Error("%s branch error: bad address 0x%llx #pc: 0x%llx", GetFName(), pc, PC); + ConLog.Error("%s branch error: bad address 0x%llx #pc: 0x%llx", GetFName(), m_offset+ pc, m_offset + PC); Emu.Pause(); } nPC = pc; @@ -255,9 +290,16 @@ void PPCThread::Task() } } - while(!Emu.IsStopped() && !TestDestroy()) + while(true) { - if(Emu.IsPaused()) + int status = ThreadStatus(); + + if(status == PPCThread_Stopped || status == PPCThread_Break) + { + break; + } + + if(status == PPCThread_Sleeping) { Sleep(1); continue; diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h index 14abf1f17b..edcfcd43cf 100644 --- a/rpcs3/Emu/Cell/PPCThread.h +++ b/rpcs3/Emu/Cell/PPCThread.h @@ -8,6 +8,16 @@ enum PPCThreadType PPC_THREAD_SPU, }; +enum PPCThreadStatus +{ + PPCThread_Ready, + PPCThread_Running, + PPCThread_Paused, + PPCThread_Stopped, + PPCThread_Sleeping, + PPCThread_Break, +}; + class PPCThread : public ThreadBase { protected: @@ -43,6 +53,7 @@ public: void SetName(const wxString& name); void SetPrio(const u64 prio) { m_prio = prio; } void SetOffset(const u64 offset) { m_offset = offset; } + u64 GetOffset() { return m_offset; } u64 GetPrio() const { return m_prio; } wxString GetName() const { return m_name; } @@ -88,6 +99,16 @@ protected: public: ~PPCThread(); + u32 m_wait_thread_id; + + wxCriticalSection m_cs_sync; + bool m_sync_wait; + void Wait(bool wait); + void Wait(const PPCThread& thr); + bool Sync(); + + int ThreadStatus(); + void NextPc(); void NextBranchPc(); void PrevPc(); diff --git a/rpcs3/Emu/Cell/PPCThreadManager.cpp b/rpcs3/Emu/Cell/PPCThreadManager.cpp index dde13c534f..82ae53473d 100644 --- a/rpcs3/Emu/Cell/PPCThreadManager.cpp +++ b/rpcs3/Emu/Cell/PPCThreadManager.cpp @@ -35,14 +35,19 @@ void PPCThreadManager::RemoveThread(const u32 id) { for(u32 i=0; i(crfd, l ? CPU.GPR[ra] : (u32)CPU.GPR[ra], uimm16); + CPU.UpdateCRnU(l, crfd, CPU.GPR[ra], uimm16); } void CMPI(u32 crfd, u32 l, u32 ra, s32 simm16) { - CPU.UpdateCRn(crfd, l ? CPU.GPR[ra] : (s32)CPU.GPR[ra], simm16); + CPU.UpdateCRnS(l, crfd, CPU.GPR[ra], simm16); } void ADDIC(u32 rd, u32 ra, s32 simm16) { @@ -2172,12 +2172,12 @@ private: void ANDI_(u32 ra, u32 rs, u32 uimm16) { CPU.GPR[ra] = CPU.GPR[rs] & uimm16; - CPU.UpdateCR0(CPU.GPR[ra]); + CPU.UpdateCR0(CPU.GPR[ra]); } void ANDIS_(u32 ra, u32 rs, u32 uimm16) { CPU.GPR[ra] = CPU.GPR[rs] & (uimm16 << 16); - CPU.UpdateCR0(CPU.GPR[ra]); + CPU.UpdateCR0(CPU.GPR[ra]); } void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { @@ -2202,7 +2202,7 @@ private: } void CMP(u32 crfd, u32 l, u32 ra, u32 rb) { - CPU.UpdateCRn(crfd, l ? CPU.GPR[ra] : (s32)CPU.GPR[ra], l ? CPU.GPR[rb] : (s32)CPU.GPR[rb]); + CPU.UpdateCRnS(l, crfd, CPU.GPR[ra], CPU.GPR[rb]); } void TW(u32 to, u32 ra, u32 rb) { @@ -2256,7 +2256,7 @@ private: { const s64 RA = CPU.GPR[ra]; const s64 RB = CPU.GPR[rb]; - CPU.GPR[rd] = RB - RA; + CPU.GPR[rd] = ~RA + RB + 1; CPU.XER.CA = CPU.IsCarry(RA, RB); if(oe) UNK("subfco"); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); @@ -2334,9 +2334,9 @@ private: CPU.reserve = true; CPU.GPR[rd] = Memory.Read32(addr); } - void LDX(u32 ra, u32 rs, u32 rb) + void LDX(u32 rd, u32 ra, u32 rb) { - CPU.GPR[ra] = Memory.Read64(rs ? CPU.GPR[rs] + CPU.GPR[rb] : CPU.GPR[rb]); + CPU.GPR[rd] = Memory.Read64(ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]); } void LWZX(u32 rd, u32 ra, u32 rb) { @@ -2362,11 +2362,16 @@ private: CPU.GPR[ra] = i; - if(rc) CPU.UpdateCR0(CPU.GPR[ra]); + if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void SLD(u32 ra, u32 rs, u32 rb, bool rc) { - CPU.GPR[ra] = CPU.GPR[rb] & 0x40 ? 0 : CPU.GPR[rs] << (CPU.GPR[rb] & 0x3f); + const u32 n = CPU.GPR[rb] & 0x3f; + const u64 r = rotl64(CPU.GPR[rs], n); + const u64 m = (CPU.GPR[rb] & 0x30) ? 0 : rotate_mask[0][63 - n]; + + CPU.GPR[ra] = r & m; + if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void AND(u32 ra, u32 rs, u32 rb, bool rc) @@ -2376,7 +2381,7 @@ private: } void CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { - CPU.UpdateCRn(crfd, l ? CPU.GPR[ra] : (u32)CPU.GPR[ra], l ? CPU.GPR[rb] : (u32)CPU.GPR[rb]); + CPU.UpdateCRnU(l, crfd, CPU.GPR[ra], CPU.GPR[rb]); } void LVSR(u32 vd, u32 ra, u32 rb) { @@ -2570,21 +2575,23 @@ private: void STWCX_(u32 rs, u32 ra, u32 rb) { CPU.SetCR(0, CPU.XER.SO ? CR_SO : 0); - if(!CPU.reserve) return; - - const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - - if(addr == CPU.reserve_addr) + + if(CPU.reserve) { - Memory.Write32(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, true); - } - else - { - static const bool u = 0; - if(u) Memory.Write32(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, u); - CPU.reserve = false; + const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; + + if(addr == CPU.reserve_addr) + { + Memory.Write32(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, true); + } + else + { + static const bool u = 0; + if(u) Memory.Write32(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, u); + CPU.reserve = false; + } } } void STWX(u32 rs, u32 ra, u32 rb) @@ -2621,21 +2628,22 @@ private: void STDCX_(u32 rs, u32 ra, u32 rb) { CPU.SetCR(0, CPU.XER.SO ? CR_SO : 0); - if(!CPU.reserve) return; - - const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; - - if(addr == CPU.reserve_addr) + if(!CPU.reserve) { - Memory.Write64(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, true); - } - else - { - static const bool u = 0; - if(u) Memory.Write64(addr, CPU.GPR[rs]); - CPU.SetCR_EQ(0, u); - CPU.reserve = false; + const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; + + if(addr == CPU.reserve_addr) + { + Memory.Write64(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, true); + } + else + { + static const bool u = 0; + if(u) Memory.Write64(addr, CPU.GPR[rs]); + CPU.SetCR_EQ(0, u); + CPU.reserve = false; + } } } void STBX(u32 rs, u32 ra, u32 rb) @@ -2824,10 +2832,10 @@ private: const s64 RA = CPU.GPR[ra]; const s64 RB = CPU.GPR[rb]; - if (RB == 0 || ((u64)RA == 0x8000000000000000 && RB == -1)) + if (RB == 0 || ((u64)RA == (1ULL << 63) && RB == -1)) { if(oe) UNK("divdo"); - CPU.GPR[rd] = (((u64)RA & 0x8000000000000000) && RB == 0) ? -1 : 0; + CPU.GPR[rd] = (((u64)RA & (1ULL << 63)) && RB == 0) ? -1 : 0; } else { @@ -2841,10 +2849,10 @@ private: const s32 RA = CPU.GPR[ra]; const s32 RB = CPU.GPR[rb]; - if (RB == 0 || ((u32)RA == 0x80000000 && RB == -1)) + if (RB == 0 || ((u32)RA == (1 << 31) && RB == -1)) { if(oe) UNK("divwo"); - CPU.GPR[rd] = (((u32)RA & 0x80000000) && RB == 0) ? -1 : 0; + CPU.GPR[rd] = (((u32)RA & (1 << 31)) && RB == 0) ? -1 : 0; } else { @@ -2871,12 +2879,20 @@ private: } void SRW(u32 ra, u32 rs, u32 rb, bool rc) { - CPU.GPR[ra] = CPU.GPR[rb] & 0x20 ? 0 : (u32)CPU.GPR[rs] >> (CPU.GPR[rb] & 0x1f); + u32 n = CPU.GPR[rb] & 0x1f; + u64 r = rotl32((u32)CPU.GPR[rs], 64 - n); + u64 m = CPU.GPR[rb] & 0x20 ? 0 : rotate_mask[32 + n][63]; + CPU.GPR[ra] = r & m; + if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void SRD(u32 ra, u32 rs, u32 rb, bool rc) { - CPU.GPR[ra] = CPU.GPR[rb] & 0x40 ? 0 : CPU.GPR[rs] >> (CPU.GPR[rb] & 0x3f); + u32 n = CPU.GPR[rb] & 0x3f; + u64 r = rotl64(CPU.GPR[rs], 64 - n); + u64 m = CPU.GPR[rb] & 0x40 ? 0 : rotate_mask[n][63]; + CPU.GPR[ra] = r & m; + if(rc) CPU.UpdateCR0(CPU.GPR[ra]); } void LVRX(u32 vd, u32 ra, u32 rb) @@ -2940,7 +2956,7 @@ private: CPU.GPR[rd] = (u16&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]]; } void SRAW(u32 ra, u32 rs, u32 rb, bool rc) - { + { s32 RS = CPU.GPR[rs]; s32 RB = CPU.GPR[rb]; CPU.GPR[ra] = RS >> RB; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 0b8eb74234..0bb661060f 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -60,13 +60,13 @@ void PPUThread::AddArgv(const wxString& arg) void PPUThread::InitRegs() { - const u32 entry = Memory.Read32(PC); - const u32 rtoc = Memory.Read32(PC + 4); + const u32 pc = Memory.Read32(entry); + const u32 rtoc = Memory.Read32(entry + 4); ConLog.Write("entry = 0x%x", entry); ConLog.Write("rtoc = 0x%x", rtoc); - SetPc(entry); + SetPc(pc); u64 argc = m_arg; u64 argv = 0; @@ -110,20 +110,18 @@ void PPUThread::InitRegs() { GPR[3] = argc; GPR[4] = argv; - GPR[5] = argv ? argv - 0xc - 4 * argc : 0; //unk + GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk } else { GPR[3] = m_arg; } - GPR[0] = entry; - //GPR[7] = 0x80d90; + GPR[0] = pc; GPR[8] = entry; - //GPR[10] = 0x131700; GPR[11] = 0x80; GPR[12] = Emu.GetMallocPageSize(); - GPR[13] = Memory.MainMem.Alloc(0x10000) + 0x7060; + GPR[13] = Memory.PRXMem.Alloc(0x10000) + 0x7060 - 8; GPR[28] = GPR[4]; GPR[29] = GPR[3]; GPR[31] = GPR[5]; diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 7e1c150632..dc543f0a9e 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -652,6 +652,30 @@ public: SetCR_SO(n, XER.SO); } + void UpdateCRnU(const u8 l, const u8 n, const u64 a, const u64 b) + { + if(l) + { + UpdateCRn(n, a, b); + } + else + { + UpdateCRn(n, a, b); + } + } + + void UpdateCRnS(const u8 l, const u8 n, const u64 a, const u64 b) + { + if(l) + { + UpdateCRn(n, a, b); + } + else + { + UpdateCRn(n, a, b); + } + } + template void UpdateCR0(const T val) { UpdateCRn(0, val, 0); diff --git a/rpcs3/Emu/Cell/SPUDecoder.h b/rpcs3/Emu/Cell/SPUDecoder.h index eac3dae07a..97af2abb3a 100644 --- a/rpcs3/Emu/Cell/SPUDecoder.h +++ b/rpcs3/Emu/Cell/SPUDecoder.h @@ -24,9 +24,3 @@ public: (*SPU_instr::rrr_list)(m_op, code); } }; - -#undef START_OPCODES_GROUP_ -#undef START_OPCODES_GROUP -#undef ADD_OPCODE -#undef ADD_NULL_OPCODE -#undef END_OPCODES_GROUP \ No newline at end of file diff --git a/rpcs3/Emu/Cell/SPUDisAsm.h b/rpcs3/Emu/Cell/SPUDisAsm.h index d8a94307b5..c82b9d7a2e 100644 --- a/rpcs3/Emu/Cell/SPUDisAsm.h +++ b/rpcs3/Emu/Cell/SPUDisAsm.h @@ -46,813 +46,861 @@ private: } private: + wxString& FixOp(wxString& op) + { + op.Append(' ', max(10 - (int)op.Len(), 0)); + return op; + } + void DisAsm(const char* op) + { + Write(op); + } + void DisAsm(wxString op, u32 a1) + { + Write(wxString::Format("%s 0x%x", FixOp(op), a1)); + } + void DisAsm(wxString op, const char* a1) + { + Write(wxString::Format("%s %s", FixOp(op), a1)); + } + void DisAsm(wxString op, const char* a1, const char* a2) + { + Write(wxString::Format("%s %s,%s", FixOp(op), a1, a2)); + } + void DisAsm(wxString op, int a1, const char* a2) + { + Write(wxString::Format("%s 0x%x,%s", FixOp(op), a1, a2)); + } + void DisAsm(wxString op, const char* a1, int a2) + { + Write(wxString::Format("%s %s,0x%x", FixOp(op), a1, a2)); + } + void DisAsm(wxString op, int a1, int a2) + { + Write(wxString::Format("%s 0x%x,0x%x", FixOp(op), a1, a2)); + } + void DisAsm(wxString op, const char* a1, const char* a2, const char* a3) + { + Write(wxString::Format("%s %s,%s,%s", FixOp(op), a1, a2, a3)); + } + void DisAsm(wxString op, const char* a1, int a2, const char* a3) + { + Write(wxString::Format("%s %s,0x%x(%s)", FixOp(op), a1, a2, a3)); + } + void DisAsm(wxString op, const char* a1, const char* a2, int a3) + { + Write(wxString::Format("%s %s,%s,0x%x", FixOp(op), a1, a2, a3)); + } + void DisAsm(wxString op, const char* a1, const char* a2, const char* a3, const char* a4) + { + Write(wxString::Format("%s %s,%s,%s,%s", FixOp(op), a1, a2, a3, a4)); + } //0 - 10 void STOP(u32 code) { - Write(wxString::Format("stop 0x%x", code)); + DisAsm("stop", code); } void LNOP() { - Write("lnop"); + DisAsm("lnop"); } void SYNC(u32 Cbit) { - Write(wxString::Format("sync %d", Cbit)); + DisAsm("sync", Cbit); } void DSYNC() { - Write("dsync"); + DisAsm("dsync"); } void MFSPR(u32 rt, u32 sa) { - Write(wxString::Format("mfspr %s,%s", spu_reg_name[rt], spu_reg_name[sa])); // Are SPR mapped on the GPR or are there 128 additional registers ? + DisAsm("mfspr", spu_reg_name[rt], spu_reg_name[sa]); // Are SPR mapped on the GPR or are there 128 additional registers ? } void RDCH(u32 rt, u32 ra) { - Write(wxString::Format("rdch %s,%s", spu_reg_name[rt], spu_ch_name[ra])); + DisAsm("rdch", spu_reg_name[rt], spu_ch_name[ra]); } void RCHCNT(u32 rt, u32 ra) { - Write(wxString::Format("rchcnt %s,%s", spu_reg_name[rt], spu_ch_name[ra])); + DisAsm("rchcnt", spu_reg_name[rt], spu_ch_name[ra]); } void SF(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("sf %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("sf", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void OR(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("or %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("or", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void BG(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("bg %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("bg", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SFH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("sfh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("sfh", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void NOR(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("nor %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("nor", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ABSDB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("absdb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("absdb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rot %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rot", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTM(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotm", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTMA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotma", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SHL(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("shl %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("shl", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("roth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("roth", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTHM(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rothm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rothm", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTMAH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotmah %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotmah", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SHLH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("shlh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("shlh", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("roti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("roti", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTMI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotmi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotmi", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTMAI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotmai %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotmai", spu_reg_name[rt], spu_reg_name[ra], i7); } void SHLI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("shli %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("shli", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTHI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rothi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rothi", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTHMI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rothmi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rothmi", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTMAHI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotmahi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotmahi", spu_reg_name[rt], spu_reg_name[ra], i7); } void SHLHI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("shlhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("shlhi", spu_reg_name[rt], spu_reg_name[ra], i7); } void A(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("a %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("a", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void AND(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("and %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("and", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CG(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cg %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cg", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void AH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("ah %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("ah", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void NAND(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("nand %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("nand", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void AVGB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("avgb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("avgb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MTSPR(u32 rt, u32 sa) { - Write(wxString::Format("mtspr %s,%s", spu_reg_name[rt], spu_reg_name[sa])); + DisAsm("mtspr", spu_reg_name[rt], spu_reg_name[sa]); } void WRCH(u32 ra, u32 rt) { - Write(wxString::Format("wrch %s,%s", spu_ch_name[ra], spu_reg_name[rt])); + DisAsm("wrch", spu_ch_name[ra], spu_reg_name[rt]); } void BIZ(u32 rt, u32 ra) { - Write(wxString::Format("biz %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("biz", spu_reg_name[rt], spu_reg_name[ra]); } void BINZ(u32 rt, u32 ra) { - Write(wxString::Format("binz %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("binz", spu_reg_name[rt], spu_reg_name[ra]); } void BIHZ(u32 rt, u32 ra) { - Write(wxString::Format("bihz %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("bihz", spu_reg_name[rt], spu_reg_name[ra]); } void BIHNZ(u32 rt, u32 ra) { - Write(wxString::Format("bihnz %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("bihnz", spu_reg_name[rt], spu_reg_name[ra]); } void STOPD(u32 rc, u32 ra, u32 rb) { - Write(wxString::Format("bihnz %s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("bihnz", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb]); } void STQX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("stqx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("stqx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void BI(u32 ra) { - Write(wxString::Format("bi %s", spu_reg_name[ra])); + DisAsm("bi", spu_reg_name[ra]); } void BISL(u32 rt, u32 ra) { - Write(wxString::Format("bisl %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("bisl", spu_reg_name[rt], spu_reg_name[ra]); } void IRET(u32 ra) { - Write(wxString::Format("iret %s", spu_reg_name[ra])); + DisAsm("iret", spu_reg_name[ra]); } void BISLED(u32 rt, u32 ra) { - Write(wxString::Format("bisled %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("bisled", spu_reg_name[rt], spu_reg_name[ra]); } void HBR(u32 p, u32 ro, u32 ra) { - Write(wxString::Format("hbr 0x%x,%s", DisAsmBranchTarget(ro), spu_reg_name[ra])); + DisAsm("hbr", DisAsmBranchTarget(ro), spu_reg_name[ra]); } void GB(u32 rt, u32 ra) { - Write(wxString::Format("gb %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("gb", spu_reg_name[rt], spu_reg_name[ra]); } void GBH(u32 rt, u32 ra) { - Write(wxString::Format("gbh %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("gbh", spu_reg_name[rt], spu_reg_name[ra]); } void GBB(u32 rt, u32 ra) { - Write(wxString::Format("gbb %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("gbb", spu_reg_name[rt], spu_reg_name[ra]); } void FSM(u32 rt, u32 ra) { - Write(wxString::Format("fsm %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("fsm", spu_reg_name[rt], spu_reg_name[ra]); } void FSMH(u32 rt, u32 ra) { - Write(wxString::Format("fsmh %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("fsmh", spu_reg_name[rt], spu_reg_name[ra]); } void FSMB(u32 rt, u32 ra) { - Write(wxString::Format("fsmb %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("fsmb", spu_reg_name[rt], spu_reg_name[ra]); } void FREST(u32 rt, u32 ra) { - Write(wxString::Format("frest %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("frest", spu_reg_name[rt], spu_reg_name[ra]); } void FRSQEST(u32 rt, u32 ra) { - Write(wxString::Format("frsqest %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("frsqest", spu_reg_name[rt], spu_reg_name[ra]); } void LQX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("lqx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("lqx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQBYBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqbybi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQMBYBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqmbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqmbybi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SHLQBYBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("shlqbybi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("shlqbybi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CBX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cbx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cbx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CHX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("chx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("chx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CWX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cwx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cwx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CDX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cdx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cdx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqbi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQMBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqmbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqmbi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SHLQBI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("shlqbi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("shlqbi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQBY(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqby", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ROTQMBY(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("rotqmby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("rotqmby", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SHLQBY(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("shlqby %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("shlqby", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ORX(u32 rt, u32 ra) { - Write(wxString::Format("orx %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("orx", spu_reg_name[rt], spu_reg_name[ra]); } void CBD(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("cbd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("cbd", spu_reg_name[rt], spu_reg_name[ra], i7); } void CHD(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("chd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("chd", spu_reg_name[rt], spu_reg_name[ra], i7); } void CWD(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("cwd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("cwd", spu_reg_name[rt], spu_reg_name[ra], i7); } void CDD(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("cdd %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("cdd", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTQBII(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotqbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotqbii", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTQMBII(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotqmbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotqmbii", spu_reg_name[rt], spu_reg_name[ra], i7); } void SHLQBII(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("shlqbii %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("shlqbii", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTQBYI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotqbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotqbyi", spu_reg_name[rt], spu_reg_name[ra], i7); } void ROTQMBYI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("rotqmbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("rotqmbyi", spu_reg_name[rt], spu_reg_name[ra], i7); } void SHLQBYI(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("shlqbyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("shlqbyi", spu_reg_name[rt], spu_reg_name[ra], i7); } void NOP(u32 rt) { - Write(wxString::Format("nop %s", spu_reg_name[rt])); + DisAsm("nop", spu_reg_name[rt]); } void CGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void XOR(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("xor %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("xor", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CGTH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cgth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cgth", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void EQV(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("eqv %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("eqv", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CGTB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cgtb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cgtb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SUMB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("sumb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("sumb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void HGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("hgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("hgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CLZ(u32 rt, u32 ra) { - Write(wxString::Format("clz %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("clz", spu_reg_name[rt], spu_reg_name[ra]); } void XSWD(u32 rt, u32 ra) { - Write(wxString::Format("xswd %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("xswd", spu_reg_name[rt], spu_reg_name[ra]); } void XSHW(u32 rt, u32 ra) { - Write(wxString::Format("xshw %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("xshw", spu_reg_name[rt], spu_reg_name[ra]); } void CNTB(u32 rt, u32 ra) { - Write(wxString::Format("cntb %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("cntb", spu_reg_name[rt], spu_reg_name[ra]); } void XSBH(u32 rt, u32 ra) { - Write(wxString::Format("xsbh %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("xsbh", spu_reg_name[rt], spu_reg_name[ra]); } void CLGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("clgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("clgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ANDC(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("andc %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("andc", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FCGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fcgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fcgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFCGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfcgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfcgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fa %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fa", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FS(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fs %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fs", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FM(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fm", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CLGTH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("clgth %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("clgth", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ORC(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("orc %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("orc", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FCMGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fcmgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fcmgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFCMGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfcmgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfcmgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfa %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfa", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFS(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfs %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfs", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFM(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfm %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfm", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CLGTB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("clgtb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("clgtb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void HLGT(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("hlgt %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("hlgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFMA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfma", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFMS(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfms %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfms", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFNMS(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfnms %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfnms", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFNMA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfnma %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfnma", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("ceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("ceq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYHHU(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyhhu %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyhhu", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void ADDX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("addx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("addx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void SFX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("sfx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("sfx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CGX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("cgx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("cgx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void BGX(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("bgx %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("bgx", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYHHA(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyhha %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyhha", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYHHAU(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyhhau %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyhhau", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FSCRRD(u32 rt) { - Write(wxString::Format("fscrrd %s", spu_reg_name[rt])); + DisAsm("fscrrd", spu_reg_name[rt]); } void FESD(u32 rt, u32 ra) { - Write(wxString::Format("fesd %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("fesd", spu_reg_name[rt], spu_reg_name[ra]); } void FRDS(u32 rt, u32 ra) { - Write(wxString::Format("frds %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("frds", spu_reg_name[rt], spu_reg_name[ra]); } void FSCRWR(u32 rt, u32 ra) { - Write(wxString::Format("fscrwr %s,%s", spu_reg_name[rt], spu_reg_name[ra])); + DisAsm("fscrwr", spu_reg_name[rt], spu_reg_name[ra]); } void DFTSV(u32 rt, u32 ra, s32 i7) { - Write(wxString::Format("dftsv %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i7)); + DisAsm("dftsv", spu_reg_name[rt], spu_reg_name[ra], i7); } void FCEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fceq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFCEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfceq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfceq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPY(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpy %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpy", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyh", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYHH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyhh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyhh", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYS(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpys %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpys", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CEQH(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("ceqh %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("ceqh", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FCMEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fcmeq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fcmeq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void DFCMEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("dfcmeq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("dfcmeq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void MPYU(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("mpyu %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("mpyu", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void CEQB(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("ceqb %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("ceqb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void FI(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("fi %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("fi", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } void HEQ(u32 rt, u32 ra, u32 rb) { - Write(wxString::Format("heq %s,%s,%s", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb])); + DisAsm("heq", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]); } //0 - 9 void CFLTS(u32 rt, u32 ra, s32 i8) { - Write(wxString::Format("cflts %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8)); + DisAsm("cflts", spu_reg_name[rt], spu_reg_name[ra], i8); } void CFLTU(u32 rt, u32 ra, s32 i8) { - Write(wxString::Format("cfltu %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8)); + DisAsm("cfltu", spu_reg_name[rt], spu_reg_name[ra], i8); } void CSFLT(u32 rt, u32 ra, s32 i8) { - Write(wxString::Format("csflt %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8)); + DisAsm("csflt", spu_reg_name[rt], spu_reg_name[ra], i8); } void CUFLT(u32 rt, u32 ra, s32 i8) { - Write(wxString::Format("cuflt %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i8)); + DisAsm("cuflt", spu_reg_name[rt], spu_reg_name[ra], i8); } //0 - 8 void BRZ(u32 rt, s32 i16) { - Write(wxString::Format("brz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brz", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void STQA(u32 rt, s32 i16) { - Write(wxString::Format("stqa %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("stqa", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BRNZ(u32 rt, s32 i16) { - Write(wxString::Format("brnz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brnz", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BRHZ(u32 rt, s32 i16) { - Write(wxString::Format("brhz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brhz", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BRHNZ(u32 rt, s32 i16) { - Write(wxString::Format("brhnz %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brhnz", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void STQR(u32 rt, s32 i16) { - Write(wxString::Format("stqr %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("stqr", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BRA(s32 i16) { - Write(wxString::Format("bra 0x%x", DisAsmBranchTarget(i16))); + DisAsm("bra", DisAsmBranchTarget(i16)); } void LQA(u32 rt, s32 i16) { - Write(wxString::Format("lqa %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("lqa", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BRASL(u32 rt, s32 i16) { - Write(wxString::Format("brasl %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brasl", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void BR(s32 i16) { - Write(wxString::Format("br 0x%x", DisAsmBranchTarget(i16))); + DisAsm("br", DisAsmBranchTarget(i16)); } void FSMBI(u32 rt, s32 i16) { - Write(wxString::Format("fsmbi %s,%d", spu_reg_name[rt], i16)); + DisAsm("fsmbi", spu_reg_name[rt], i16); } void BRSL(u32 rt, s32 i16) { - Write(wxString::Format("brsl %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("brsl", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void LQR(u32 rt, s32 i16) { - Write(wxString::Format("lqr %s,0x%x", spu_reg_name[rt], DisAsmBranchTarget(i16))); + DisAsm("lqr", spu_reg_name[rt], DisAsmBranchTarget(i16)); } void IL(u32 rt, s32 i16) { - Write(wxString::Format("il %s,%d", spu_reg_name[rt], i16)); + DisAsm("il", spu_reg_name[rt], i16); } void ILHU(u32 rt, s32 i16) { - Write(wxString::Format("ilhu %s,%d", spu_reg_name[rt], i16)); + DisAsm("ilhu", spu_reg_name[rt], i16); } void ILH(u32 rt, s32 i16) { - Write(wxString::Format("ilh %s,%d", spu_reg_name[rt], i16)); + DisAsm("ilh", spu_reg_name[rt], i16); } void IOHL(u32 rt, s32 i16) { - Write(wxString::Format("iolh %s,%d", spu_reg_name[rt], i16)); + DisAsm("iolh", spu_reg_name[rt], i16); } - //0 - 7 void ORI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ori %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ori", spu_reg_name[rt], spu_reg_name[ra], i10); } void ORHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("orhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("orhi", spu_reg_name[rt], spu_reg_name[ra], i10); } void ORBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("orbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("orbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void SFI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("sfi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("sfi", spu_reg_name[rt], spu_reg_name[ra], i10); } void SFHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("sfhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("sfhi", spu_reg_name[rt], spu_reg_name[ra], i10); } void ANDI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("andi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("andi", spu_reg_name[rt], spu_reg_name[ra], i10); } void ANDHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("andhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("andhi", spu_reg_name[rt], spu_reg_name[ra], i10); } void ANDBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("andbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("andbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void AI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ai %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ai", spu_reg_name[rt], spu_reg_name[ra], i10); } void AHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ahi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ahi", spu_reg_name[rt], spu_reg_name[ra], i10); } void STQD(u32 rt, s32 i10, u32 ra) { - Write(wxString::Format("stqd %s,%d(%s)", spu_reg_name[rt], i10, spu_reg_name[ra])); + DisAsm("stqd", spu_reg_name[rt], i10, spu_reg_name[ra]); } void LQD(u32 rt, s32 i10, u32 ra) { - Write(wxString::Format("lqd %s,%d(%s)", spu_reg_name[rt], i10, spu_reg_name[ra])); + DisAsm("lqd", spu_reg_name[rt], i10, spu_reg_name[ra]); } void XORI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("xori %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("xori", spu_reg_name[rt], spu_reg_name[ra], i10); } void XORHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("xorhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("xorhi", spu_reg_name[rt], spu_reg_name[ra], i10); } void XORBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("xorbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("xorbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void CGTI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("cgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("cgti", spu_reg_name[rt], spu_reg_name[ra], i10); } void CGTHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("cgthi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("cgthi", spu_reg_name[rt], spu_reg_name[ra], i10); } void CGTBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("cgtbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("cgtbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void HGTI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("hgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("hgti", spu_reg_name[rt], spu_reg_name[ra], i10); } void CLGTI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("clgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("clgti", spu_reg_name[rt], spu_reg_name[ra], i10); } void CLGTHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("clgthi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("clgthi", spu_reg_name[rt], spu_reg_name[ra], i10); } void CLGTBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("clgtbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("clgtbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void HLGTI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("hlgti %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("hlgti", spu_reg_name[rt], spu_reg_name[ra], i10); } void MPYI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("mpyi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("mpyi", spu_reg_name[rt], spu_reg_name[ra], i10); } void MPYUI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("mpyui %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("mpyui", spu_reg_name[rt], spu_reg_name[ra], i10); } void CEQI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ceqi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ceqi", spu_reg_name[rt], spu_reg_name[ra], i10); } void CEQHI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ceqhi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ceqhi", spu_reg_name[rt], spu_reg_name[ra], i10); } void CEQBI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("ceqbi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("ceqbi", spu_reg_name[rt], spu_reg_name[ra], i10); } void HEQI(u32 rt, u32 ra, s32 i10) { - Write(wxString::Format("heqi %s,%s,%d", spu_reg_name[rt], spu_reg_name[ra], i10)); + DisAsm("heqi", spu_reg_name[rt], spu_reg_name[ra], i10); } //0 - 6 void HBRA(s32 ro, s32 i16) { - Write(wxString::Format("hbra 0x%x,0x%x", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16))); + DisAsm("hbra", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16)); } void HBRR(s32 ro, s32 i16) { - Write(wxString::Format("hbrr 0x%x,0x%x", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16))); + DisAsm("hbrr", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16)); } void ILA(u32 rt, s32 i18) { - Write(wxString::Format("ila %s,%d", spu_reg_name[rt], i18)); + DisAsm("ila", spu_reg_name[rt], i18); } //0 - 3 void SELB(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("selb %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("selb", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void SHUFB(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("shufb %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("shufb", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void MPYA(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("mpya %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("mpya", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void FNMS(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("fnms %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("fnms", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void FMA(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("fma %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("fma", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void FMS(u32 rc, u32 ra, u32 rb, u32 rt) { - Write(wxString::Format("fms %s,%s,%s,%s", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt])); + DisAsm("fms", spu_reg_name[rc], spu_reg_name[ra], spu_reg_name[rb], spu_reg_name[rt]); } void UNK(u32 code, u32 opcode, u32 gcode) @@ -860,6 +908,3 @@ private: Write(wxString::Format("Unknown/Illegal opcode! (0x%08x, 0x%x, 0x%x)", code, opcode, gcode)); } }; - -#undef START_OPCODES_GROUP -#undef END_OPCODES_GROUP \ No newline at end of file diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 39952916ee..dcbc7fba8d 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -27,18 +27,18 @@ private: //0 - 10 void STOP(u32 code) { - Emu.Pause(); + CPU.Pause(); } void LNOP() { } void SYNC(u32 Cbit) { - UNIMPLEMENTED(); + //UNIMPLEMENTED(); } void DSYNC() { - UNIMPLEMENTED(); + //UNIMPLEMENTED(); } void MFSPR(u32 rt, u32 sa) { @@ -51,7 +51,7 @@ private: void RCHCNT(u32 rt, u32 ra) { CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[0] = CPU.GetChannelCount(ra); + CPU.GPR[rt]._u32[3] = CPU.GetChannelCount(ra); } void SF(u32 rt, u32 ra, u32 rb) { @@ -280,16 +280,15 @@ private: } void STQX(u32 rt, u32 ra, u32 rb) { - CPU.LSA = CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0]; - CPU.WriteLSA128(CPU.GPR[rt]._u128); + CPU.WriteLS128(CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0], CPU.GPR[rt]._u128); } void BI(u32 ra) { - CPU.SetBranch(CPU.GPR[ra]._u32[0] & 0xfffffffc); + CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); } void BISL(u32 rt, u32 ra) { - CPU.SetBranch(CPU.GPR[ra]._u32[0] & 0xfffffffc); + CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[0] = CPU.PC + 4; } @@ -353,8 +352,7 @@ private: } void LQX(u32 rt, u32 ra, u32 rb) { - CPU.LSA = CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0]; - CPU.GPR[rt]._u128 = CPU.ReadLSA128(); + CPU.GPR[rt]._u128 = CPU.ReadLS128(CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0]); } void ROTQBYBI(u32 rt, u32 ra, u32 rb) { @@ -870,8 +868,6 @@ private: UNIMPLEMENTED(); } - - //0 - 9 void CFLTS(u32 rt, u32 ra, s32 i8) { @@ -890,35 +886,31 @@ private: UNIMPLEMENTED(); } - - //0 - 8 void BRZ(u32 rt, s32 i16) { - if(!CPU.GPR[rt]._u32[0]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if(!CPU.GPR[rt]._u32[3]) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void STQA(u32 rt, s32 i16) { - CPU.LSA = i16 << 2; - CPU.WriteLSA128(CPU.GPR[rt]._u128); + CPU.WriteLS128(i16 << 2, CPU.GPR[rt]._u128); } void BRNZ(u32 rt, s32 i16) { - if(CPU.GPR[rt]._u32[0] != 0) + if(CPU.GPR[rt]._u32[3] != 0) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void BRHZ(u32 rt, s32 i16) { - if(!CPU.GPR[rt]._u16[0]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if(!CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void BRHNZ(u32 rt, s32 i16) { - if(CPU.GPR[rt]._u16[0]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if(CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void STQR(u32 rt, s32 i16) { - CPU.LSA = branchTarget(CPU.PC, i16); - CPU.WriteLSA128(CPU.GPR[rt]._u128); + CPU.WriteLS128(branchTarget(CPU.PC, i16), CPU.GPR[rt]._u128); } void BRA(s32 i16) { @@ -926,14 +918,7 @@ private: } void LQA(u32 rt, s32 i16) { - CPU.LSA = i16 << 2; - if(!Memory.IsGoodAddr(CPU.LSA)) - { - ConLog.Warning("LQA: Bad addr: 0x%x", CPU.LSA); - return; - } - - CPU.GPR[rt]._u128 = CPU.ReadLSA128(); + CPU.GPR[rt]._u128 = CPU.ReadLS128(i16 << 2); } void BRASL(u32 rt, s32 i16) { @@ -964,19 +949,12 @@ private: void BRSL(u32 rt, s32 i16) { CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[0] = CPU.PC + 4; + CPU.GPR[rt]._u32[3] = CPU.PC + 4; CPU.SetBranch(branchTarget(CPU.PC, i16)); } void LQR(u32 rt, s32 i16) { - CPU.LSA = branchTarget(CPU.PC, i16); - if(!Memory.IsGoodAddr(CPU.LSA)) - { - ConLog.Warning("LQR: Bad addr: 0x%x", CPU.LSA); - return; - } - - CPU.GPR[rt]._u128 = CPU.ReadLSA128(); + CPU.GPR[rt]._u128 = CPU.ReadLS128(branchTarget(CPU.PC, i16)); } void IL(u32 rt, s32 i16) { @@ -988,7 +966,7 @@ private: void ILHU(u32 rt, s32 i16) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u16[w*2] = i16; + CPU.GPR[rt]._u16[w*2 + 1] = i16; } void ILH(u32 rt, s32 i16) { @@ -1061,13 +1039,11 @@ private: } void STQD(u32 rt, s32 i10, u32 ra) { - CPU.LSA = branchTarget(0, i10 + CPU.GPR[ra]._u32[0]); - CPU.WriteLSA128(CPU.GPR[rt]._u128); + CPU.WriteLS128(CPU.GPR[ra]._u32[3] + i10, CPU.GPR[rt]._u128); } void LQD(u32 rt, s32 i10, u32 ra) { - CPU.LSA = branchTarget(0, i10 + CPU.GPR[ra]._u32[0]); - CPU.GPR[rt]._u128 = CPU.ReadLSA128(); + CPU.GPR[rt]._u128 = CPU.ReadLS128(CPU.GPR[ra]._u32[3] + i10); } void XORI(u32 rt, u32 ra, s32 i10) { @@ -1167,10 +1143,6 @@ private: } void HBRR(s32 ro, s32 i16) { - UNIMPLEMENTED(); - //CHECK ME - //CPU.GPR[0]._u64[0] = branchTarget(CPU.PC, i16); - //CPU.SetBranch(branchTarget(CPU.PC, ro)); } void ILA(u32 rt, s32 i18) { @@ -1189,12 +1161,6 @@ private: ( CPU.GPR[rc]._u32[i] & CPU.GPR[rb]._u32[i]) | (~CPU.GPR[rc]._u32[i] & CPU.GPR[ra]._u32[i]); } - /* - CPU.GPR[rt] = _mm_or_si128( - _mm_and_si128(CPU.GPR[rc], CPU.GPR[rb]), - _mm_andnot_si128(CPU.GPR[rc], CPU.GPR[ra]) - ); - */ } void SHUFB(u32 rc, u32 ra, u32 rb, u32 rt) { diff --git a/rpcs3/Emu/Cell/SPUOpcodes.h b/rpcs3/Emu/Cell/SPUOpcodes.h index 1b56e9281b..e3bff38d3e 100644 --- a/rpcs3/Emu/Cell/SPUOpcodes.h +++ b/rpcs3/Emu/Cell/SPUOpcodes.h @@ -231,8 +231,8 @@ class SPU_Opcodes public: static u32 branchTarget(const u64 pc, const s32 imm) { - return (pc + ((imm << 2) & ~0x3)) & 0x3fff0; - } + return (pc + (imm << 2)) & 0x3fffc; + } virtual void Exit()=0; diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index fcac328f20..ad636cacb3 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -26,8 +26,6 @@ void SPUThread::DoReset() { //reset regs for(u32 i=0; i<128; ++i) GPR[i].Reset(); - - LSA = 0; } void SPUThread::InitRegs() diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 54e46e85f6..e713e5c8e0 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -1,29 +1,30 @@ #pragma once #include "PPCThread.h" +#include "Emu/event.h" static const wxString spu_reg_name[128] = { - "$LR", "$SP", "$3", "$4", "$5", "$6", "$7", "$8", - "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16", - "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", - "$25", "$26", "$27", "$28", "$29", "$30", "$31", "$32", - "$33", "$34", "$35", "$36", "$37", "$38", "$39", "$40", - "$41", "$42", "$43", "$44", "$45", "$46", "$47", "$48", - "$49", "$50", "$51", "$52", "$53", "$54", "$55", "$56", - "$57", "$58", "$59", "$60", "$61", "$62", "$63", "$64", - "$65", "$66", "$67", "$68", "$69", "$70", "$71", "$72", - "$73", "$74", "$75", "$76", "$77", "$78", "$79", "$80", - "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", - "$89", "$90", "$91", "$92", "$93", "$94", "$95", "$96", - "$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104", - "$105", "$106", "$107", "$108", "$109", "$110", "$111", "$112", - "$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120", - "$121", "$122", "$123", "$124", "$125", "$126", "$127", + "$LR", "$SP", "$2", "$3", "$4", "$5", "$6", "$7", + "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", + "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", + "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", + "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", + "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", + "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", + "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", + "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", + "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", + "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", + "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", + "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", + "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", + "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", + "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", }; static const wxString spu_ch_name[128] = { - "$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_RdSigNotify1", + "$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_WrEventAck", "$SPU_RdSigNotify1", "$SPU_RdSigNotify2", "$ch5", "$ch6", "$SPU_WrDec", "$SPU_RdDec", "$MFC_WrMSSyncReq", "$ch10", "$SPU_RdEventMask", "$MFC_RdTagMask", "$SPU_RdMachStat", "$SPU_WrSRR0", "$SPU_RdSRR0", "$MFC_LSA", "$MFC_EAH", "$MFC_EAL", "$MFC_Size", @@ -82,8 +83,6 @@ enum MFCchannels union SPU_GPR_hdr { - //__m128i _m128i; - u128 _u128; s128 _i128; u64 _u64[2]; @@ -96,19 +95,6 @@ union SPU_GPR_hdr s8 _i8[16]; SPU_GPR_hdr() {} - /* - SPU_GPR_hdr(const __m128i val){_u128._u64[0] = val.m128i_u64[0]; _u128._u64[1] = val.m128i_u64[1];} - SPU_GPR_hdr(const u128 val) { _u128 = val; } - SPU_GPR_hdr(const u64 val) { Reset(); _u64[0] = val; } - SPU_GPR_hdr(const u32 val) { Reset(); _u32[0] = val; } - SPU_GPR_hdr(const u16 val) { Reset(); _u16[0] = val; } - SPU_GPR_hdr(const u8 val) { Reset(); _u8[0] = val; } - SPU_GPR_hdr(const s128 val) { _i128 = val; } - SPU_GPR_hdr(const s64 val) { Reset(); _i64[0] = val; } - SPU_GPR_hdr(const s32 val) { Reset(); _i32[0] = val; } - SPU_GPR_hdr(const s16 val) { Reset(); _i16[0] = val; } - SPU_GPR_hdr(const s8 val) { Reset(); _i8[0] = val; } - */ wxString ToString() const { @@ -119,41 +105,17 @@ union SPU_GPR_hdr { memset(this, 0, sizeof(*this)); } - - //operator __m128i() { __m128i ret; ret.m128i_u64[0]=_u128._u64[0]; ret.m128i_u64[1]=_u128._u64[1]; return ret; } - /* - SPU_GPR_hdr operator ^ (__m128i right) { return _mm_xor_si128(*this, right); } - SPU_GPR_hdr operator | (__m128i right) { return _mm_or_si128 (*this, right); } - SPU_GPR_hdr operator & (__m128i right) { return _mm_and_si128(*this, right); } - SPU_GPR_hdr operator << (int right) { return _mm_slli_epi32(*this, right); } - SPU_GPR_hdr operator << (__m128i right) { return _mm_sll_epi32(*this, right); } - SPU_GPR_hdr operator >> (int right) { return _mm_srai_epi32(*this, right); } - SPU_GPR_hdr operator >> (__m128i right) { return _mm_sra_epi32(*this, right); } - - SPU_GPR_hdr operator | (__m128i right) { return _mm_or_si128 (*this, right); } - SPU_GPR_hdr operator & (__m128i right) { return _mm_and_si128(*this, right); } - SPU_GPR_hdr operator << (int right) { return _mm_slli_epi32(*this, right); } - SPU_GPR_hdr operator << (__m128i right) { return _mm_sll_epi32(*this, right); } - SPU_GPR_hdr operator >> (int right) { return _mm_srai_epi32(*this, right); } - SPU_GPR_hdr operator >> (__m128i right) { return _mm_sra_epi32(*this, right); } - - SPU_GPR_hdr operator ^= (__m128i right) { return *this = *this ^ right; } - SPU_GPR_hdr operator |= (__m128i right) { return *this = *this | right; } - SPU_GPR_hdr operator &= (__m128i right) { return *this = *this & right; } - SPU_GPR_hdr operator <<= (int right) { return *this = *this << right; } - SPU_GPR_hdr operator <<= (__m128i right){ return *this = *this << right; } - SPU_GPR_hdr operator >>= (int right) { return *this = *this >> right; } - SPU_GPR_hdr operator >>= (__m128i right){ return *this = *this >> right; } - */ }; class SPUThread : public PPCThread { public: SPU_GPR_hdr GPR[128]; //General-Purpose Register - Stack Mbox; + SizedStack OutMbox; + SizedStack OutIntrMbox; + SizedStack InMbox; - u32 LSA; //local storage address + u32 LSA; union { @@ -165,11 +127,14 @@ public: { switch(ch) { + case SPU_WrOutMbox: + return OutMbox.GetFreeCount(); + case SPU_RdInMbox: - return 1; + return InMbox.GetCount(); case SPU_WrOutIntrMbox: - return 0; + return 0;//return OutIntrMbox.GetFreeCount(); default: ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch); @@ -181,12 +146,24 @@ public: void WriteChannel(u32 ch, const SPU_GPR_hdr& r) { - const u32 v = r._u32[0]; + const u32 v = r._u32[3]; switch(ch) { case SPU_WrOutIntrMbox: - Mbox.Push(v); + ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v); + if(!OutIntrMbox.Push(v)) + { + ConLog.Warning("Not enought free rooms."); + } + break; + + case SPU_WrOutMbox: + ConLog.Warning("SPU_WrOutMbox = 0x%x", v); + if(!OutMbox.Push(v)) + { + ConLog.Warning("Not enought free rooms."); + } break; default: @@ -198,12 +175,12 @@ public: void ReadChannel(SPU_GPR_hdr& r, u32 ch) { r.Reset(); - u32& v = r._u32[0]; + u32& v = r._u32[3]; switch(ch) { case SPU_RdInMbox: - v = Mbox.Pop(); + if(!InMbox.Pop(v)) v = 0; break; default: @@ -212,17 +189,18 @@ public: } } - u8 ReadLSA8 () { return Memory.Read8 (LSA + m_offset); } - u16 ReadLSA16 () { return Memory.Read16 (LSA + m_offset); } - u32 ReadLSA32 () { return Memory.Read32 (LSA + m_offset); } - u64 ReadLSA64 () { return Memory.Read64 (LSA + m_offset); } - u128 ReadLSA128() { return Memory.Read128(LSA + m_offset); } + bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa); } + u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + (m_offset & 0x3fffc)); } + u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); } + u32 ReadLS32 (const u32 lsa) const { return Memory.Read32 (lsa + m_offset); } + u64 ReadLS64 (const u32 lsa) const { return Memory.Read64 (lsa + m_offset); } + u128 ReadLS128(const u32 lsa) const { return Memory.Read128(lsa + m_offset); } - void WriteLSA8 (const u8& data) { Memory.Write8 (LSA + m_offset, data); } - void WriteLSA16 (const u16& data) { Memory.Write16 (LSA + m_offset, data); } - void WriteLSA32 (const u32& data) { Memory.Write32 (LSA + m_offset, data); } - void WriteLSA64 (const u64& data) { Memory.Write64 (LSA + m_offset, data); } - void WriteLSA128(const u128& data) { Memory.Write128(LSA + m_offset, data); } + void WriteLS8 (const u32 lsa, const u8& data) const { Memory.Write8 (lsa + m_offset, data); } + void WriteLS16 (const u32 lsa, const u16& data) const { Memory.Write16 (lsa + m_offset, data); } + void WriteLS32 (const u32 lsa, const u32& data) const { Memory.Write32 (lsa + m_offset, data); } + void WriteLS64 (const u32 lsa, const u64& data) const { Memory.Write64 (lsa + m_offset, data); } + void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); } public: SPUThread(); diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 0c08be11b7..466566c921 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -529,6 +529,8 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data) u8 MemoryBase::Read8(u64 addr) { + if(enable_log && addr >= 0xd0010a84) + ConLog.Warning("Read8 from block: [%08llx]", addr); MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -540,6 +542,8 @@ u8 MemoryBase::Read8(u64 addr) u16 MemoryBase::Read16(u64 addr) { + if(enable_log && addr >= 0xd0010a84) + ConLog.Warning("Read16 from block: [%08llx]", addr); MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -551,6 +555,8 @@ u16 MemoryBase::Read16(u64 addr) u32 MemoryBase::Read32(u64 addr) { + if(enable_log && addr >= 0xd0010a84) + ConLog.Warning("Read32 from block: [%08llx]", addr); MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -562,6 +568,8 @@ u32 MemoryBase::Read32(u64 addr) u64 MemoryBase::Read64(u64 addr) { + if(enable_log && addr >= 0xd0010a84) + ConLog.Warning("Read64 from block: [%08llx]", addr); MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index 5103b69c45..1fe792894f 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -3583,7 +3583,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0x2f85c0ef: return sys_lwmutex_create(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: sys_lwmutex_create"); case 0x3172759d: FUNC_LOG_ERROR("TODO: sys_game_get_temperature"); case 0x318f17e1: FUNC_LOG_ERROR("TODO: _sys_memalign"); - case 0x350d454e: return sys_ppu_thread_get_id();//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id"); + case 0x350d454e: return sys_ppu_thread_get_id(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id"); case 0x35168520: return sys_heap_malloc(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: _sys_heap_malloc"); case 0x3bd53c7b: FUNC_LOG_ERROR("TODO: _sys_memchr"); case 0x3dd4a957: FUNC_LOG_ERROR("TODO: sys_ppu_thread_register_atexit"); @@ -3647,7 +3647,7 @@ s64 SysCalls::DoFunc(const u32 id) case 0xa285139d: FUNC_LOG_ERROR("TODO: sys_spinlock_lock"); case 0xa2c7ba64: FUNC_LOG_ERROR("TODO: sys_prx_exitspawn_with_level"); case 0xa330ad84: FUNC_LOG_ERROR("TODO: sys_prx_load_module_on_memcontainer_by_fd"); - case 0xa3e3be68: FUNC_LOG_ERROR("TODO: sys_ppu_thread_once"); + case 0xa3e3be68: sys_ppu_thread_once(SC_ARGS_2); return SC_ARGS_1;//FUNC_LOG_ERROR("TODO: sys_ppu_thread_once"); case 0xa5d06bf0: FUNC_LOG_ERROR("TODO: sys_prx_get_module_list"); case 0xaa6d9bff: FUNC_LOG_ERROR("TODO: sys_prx_load_module_on_memcontainer"); case 0xac6fc404: FUNC_LOG_ERROR("TODO: sys_ppu_thread_unregister_atexit"); diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp new file mode 100644 index 0000000000..de9bc167af --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -0,0 +1,235 @@ +#include "stdafx.h" +#include "SysCalls.h" +#include "SC_FUNC.h" + +Module* g_modules[50]; +uint g_modules_count = 0; +ArrayF g_modules_funcs_list; + +bool IsLoadedFunc(u32 id) +{ + for(u32 i=0; iSetLoaded(false); + } + + g_modules_funcs_list.Clear(); +} + +Module* GetModuleByName(const wxString& name) +{ + for(u32 i=0; iGetName().Cmp(name) == 0) + { + return g_modules[i]; + } + } + + return nullptr; +} + +Module* GetModuleById(u16 id) +{ + for(u32 i=0; iGetID() == id) + { + return g_modules[i]; + } + } + + return nullptr; +} + +Module::Module(const char* name, u16 id, void (*init)()) + : m_is_loaded(false) + , m_name(name) + , m_id(id) +{ + g_modules[g_modules_count++] = this; + init(); +} + +void Module::Load() +{ + for(u32 i=0; i bool Module::CheckId(u32 id, T*& data) +{ + ID id_data; + + if(!CheckId(id, id_data)) return false; + + data = (T*)id_data.m_data; + + return true; +} + +u32 Module::GetNewId(void* data, u8 flags) +{ + return Emu.GetIdManager().GetNewID(GetName(), data, flags); +} diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h new file mode 100644 index 0000000000..38143bdd68 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -0,0 +1,76 @@ +#pragma once + +#define declCPU PPUThread& CPU = GetCurrentPPUThread + +class func_caller +{ +public: + virtual void operator()() = 0; +}; + +static func_caller *null_func = nullptr; + +//TODO +struct ModuleFunc +{ + u32 id; + func_caller* func; + + ModuleFunc(u32 id, func_caller* func) + : id(id) + , func(func) + { + } +}; + +class Module +{ + const char* m_name; + const u16 m_id; + bool m_is_loaded; + +public: + Array m_funcs_list; + + Module(const char* name, u16 id, void (*init)()); + + void Load(); + void UnLoad(); + bool Load(u32 id); + bool UnLoad(u32 id); + + void SetLoaded(bool loaded = true); + bool IsLoaded() const; + + u16 GetID() const; + wxString GetName() const; + +public: + void Log(const u32 id, wxString fmt, ...); + void Log(wxString fmt, ...); + + void Warning(const u32 id, wxString fmt, ...); + void Warning(wxString fmt, ...); + + void Error(const u32 id, wxString fmt, ...); + void Error(wxString fmt, ...); + + bool CheckId(u32 id) const; + + bool CheckId(u32 id, ID& _id) const; + + template bool CheckId(u32 id, T*& data); + + u32 GetNewId(void* data = nullptr, u8 flags = 0); + __forceinline void Module::AddFunc(u32 id, func_caller* func) + { + m_funcs_list.Move(new ModuleFunc(id, func)); + } +}; + +bool IsLoadedFunc(u32 id); +bool CallFunc(u32 id); +bool UnloadFunc(u32 id); +void UnloadModules(); +Module* GetModuleByName(const wxString& name); +Module* GetModuleById(u16 id); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index ac33410632..c367afe2df 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -2,7 +2,8 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" -Module cellGcmSys("cellGcmSys", 0x0010); +void cellGcmSys_init(); +Module cellGcmSys("cellGcmSys", 0x0010, cellGcmSys_init); s64 cellGcmFunc15() { @@ -16,25 +17,22 @@ s64 cellGcmSetFlipCommandWithWaitLabel() return 0; } -struct _cellGcmSys_init +void cellGcmSys_init() { - _cellGcmSys_init() - { - cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize)); - cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit)); - cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush)); - cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset)); - cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15)); - cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode)); - cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize)); - cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus)); - cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize)); - cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize)); - cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer)); - cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister)); - cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus)); - cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel)); - cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration)); - cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull)); - } -} _cellGcmSys_init; + cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize)); + cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit)); + cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush)); + cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset)); + cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15)); + cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode)); + cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize)); + cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus)); + cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize)); + cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize)); + cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer)); + cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister)); + cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus)); + cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel)); + cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration)); + cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull)); +} diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 2d8102dda6..512de006aa 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -2,7 +2,8 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" -Module sysPrxForUser("sysPrxForUser", -1); +void sysPrxForUser_init(); +Module sysPrxForUser("sysPrxForUser", -1, sysPrxForUser_init); void sys_initialize_tls() { @@ -21,6 +22,12 @@ s64 sys_process_at_Exitspawn() return 0; } +int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) +{ + sysPrxForUser.Warning("sys_spu_printf_initialize(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", a1, a2, a3, a4, a5); + return 0; +} + s64 sys_prx_register_library() { sysPrxForUser.Error("sys_prx_register_library()"); @@ -40,36 +47,36 @@ s64 sys_strlen(u32 addr) return str.Len(); } -struct _sysPrxForUser_init +void sysPrxForUser_init() { - _sysPrxForUser_init() - { - sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls)); + sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls)); + + sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create)); + sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy)); + sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock)); + sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock)); + sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock)); - sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create)); - sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy)); - sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock)); - sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock)); - sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock)); + sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time)); - sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time)); + sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit)); + sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn)); + sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn)); - sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit)); - sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn)); - sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn)); + sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create)); + sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id)); + sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit)); + sysPrxForUser.AddFunc(0xa3e3be68, bind_func(sys_ppu_thread_once)); - sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create)); - sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id)); - sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit)); + sysPrxForUser.AddFunc(0x45fe2fce, bind_func(sys_spu_printf_initialize)); - sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library)); - sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level)); + sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library)); + sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level)); - sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen)); + sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen)); - sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc)); - //sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free>); - //sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap>); - sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap)); - } -} sysPrxForUser_init; \ No newline at end of file + sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc)); + //sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free)); + //sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap)); + sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap)); +} diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 6c0c9f0633..c73d87ebdd 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -2,25 +2,23 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" -Module sys_fs("sys_fs", 0x000e); +void sys_fs_init(); +Module sys_fs("sys_fs", 0x000e, sys_fs_init); -struct _sys_fs_init +void sys_fs_init() { - _sys_fs_init() - { - sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen)); - sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead)); - sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite)); - sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose)); - sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir)); - sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir)); - sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir)); - sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat)); - sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat)); - sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir)); - sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename)); - sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir)); - sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink)); - sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek)); - } -} sys_fs_init; \ No newline at end of file + sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen)); + sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead)); + sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite)); + sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose)); + sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir)); + sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir)); + sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir)); + sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat)); + sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat)); + sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir)); + sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename)); + sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir)); + sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink)); + sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek)); +} diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index 7bea344fdb..c4654036c0 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -2,19 +2,17 @@ #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" -Module sys_io("sys_io", 0x0017); +void sys_io_init(); +Module sys_io("sys_io", 0x0017, sys_io_init); -struct _sys_io_init +void sys_io_init() { - _sys_io_init() - { - sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit)); - sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd)); - sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf)); - sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData)); - sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra)); - sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect)); - sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2)); - sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting)); - } -} sys_io_init; \ No newline at end of file + sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit)); + sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd)); + sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf)); + sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData)); + sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra)); + sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect)); + sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2)); + sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting)); +} diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index b81c86d8c2..b3250416d5 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -1,137 +1,7 @@ #include "stdafx.h" #include "SysCalls.h" +#include "Modules.h" #include "SC_FUNC.h" -#include - -ArrayF g_modules_funcs_list; -ArrayF g_modules_list; - -bool IsLoadedFunc(u32 id) -{ - for(u32 i=0; i m_funcs_list; - - Module(const char* name, u16 id); - - void Load(); - void UnLoad(); - bool Load(u32 id); - bool UnLoad(u32 id); - - void SetLoaded(bool loaded = true) - { - m_is_loaded = loaded; - } - - bool IsLoaded() const - { - return m_is_loaded; - } - - u16 GetID() const - { - return m_id; - } - - wxString GetName() const - { - return m_name; - } - -public: - void Log(const u32 id, wxString fmt, ...) - { -#ifdef SYSCALLS_DEBUG - va_list list; - va_start(list, fmt); - ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list)); - va_end(list); -#endif - } - - void Log(wxString fmt, ...) - { -#ifdef SYSCALLS_DEBUG - va_list list; - va_start(list, fmt); - ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list)); - va_end(list); -#endif - } - - void Warning(const u32 id, wxString fmt, ...) - { -//#ifdef SYSCALLS_DEBUG - va_list list; - va_start(list, fmt); - ConLog.Warning(GetName() + wxString::Format("[%d] warning: ", id) + wxString::FormatV(fmt, list)); - va_end(list); -//#endif - } - - void Warning(wxString fmt, ...) - { -//#ifdef SYSCALLS_DEBUG - va_list list; - va_start(list, fmt); - ConLog.Warning(GetName() + " warning: " + wxString::FormatV(fmt, list)); - va_end(list); -//#endif - } - - void Error(const u32 id, wxString fmt, ...) - { - va_list list; - va_start(list, fmt); - ConLog.Error(GetName() + wxString::Format("[%d] error: ", id) + wxString::FormatV(fmt, list)); - va_end(list); - } - - void Error(wxString fmt, ...) - { - va_list list; - va_start(list, fmt); - ConLog.Error(GetName() + " error: " + wxString::FormatV(fmt, list)); - va_end(list); - } - - bool CheckId(u32 id) const - { - return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName()); - } - - bool CheckId(u32 id, ID& _id) const - { - return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName()); - } - - template bool CheckId(u32 id, T*& data) - { - ID id_data; - - if(!CheckId(id, id_data)) return false; - - data = (T*)id_data.m_data; - - return true; - } - - u32 GetNewId(void* data = nullptr, u8 flags = 0) - { - return Emu.GetIdManager().GetNewID(GetName(), data, flags); - } - -//protected: - __forceinline void AddFunc(u32 id, func_caller* func) - { - m_funcs_list.Move(new ModuleFunc(id, func)); - } -}; - -static s64 null_function() { return 0; } - -bool IsLoadedFunc(u32 id); -bool CallFunc(u32 id); -bool UnloadFunc(u32 id); -void UnloadModules(); -Module* GetModuleByName(const wxString& name); -Module* GetModuleById(u16 id); +extern bool enable_log; class SysCallBase //Module { @@ -178,22 +24,24 @@ public: void Log(const u32 id, wxString fmt, ...) { -#ifdef SYSCALLS_DEBUG + if(enable_log) + { va_list list; va_start(list, fmt); ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list)); va_end(list); -#endif + } } void Log(wxString fmt, ...) { -#ifdef SYSCALLS_DEBUG + if(enable_log) + { va_list list; va_start(list, fmt); ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list)); va_end(list); -#endif + } } void Warning(const u32 id, wxString fmt, ...) @@ -259,40 +107,18 @@ public: } }; -/* -static bool CmpPath(const wxString& path1, const wxString& path2) -{ - return path1.Len() >= path2.Len() && path1(0, path2.Len()).CmpNoCase(path2) == 0; -} - -static wxString GetWinPath(const wxString& path) -{ - if(!CmpPath(path, "/") && CmpPath(path(1, 1), ":")) return path; - - wxString ppath = wxFileName(Emu.m_path).GetPath() + '/' + wxFileName(path).GetFullName(); - if(wxFileExists(ppath)) return ppath; - - if (CmpPath(path, "/dev_hdd0/") || - CmpPath(path, "/dev_hdd1/") || - CmpPath(path, "/dev_bdvd/") || - CmpPath(path, "/dev_usb001/") || - CmpPath(path, "/ps3_home/") || - CmpPath(path, "/app_home/") || - CmpPath(path, "/dev_flash/") || - CmpPath(path, "/dev_flash2/") || - CmpPath(path, "/dev_flash3/") - ) return wxGetCwd() + path; - - return wxFileName(Emu.m_path).GetPath() + (path[0] == '/' ? path : "/" + path); -} -*/ - //process extern int sys_process_getpid(); extern int sys_process_exit(int errorcode); extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr, u32 data, u32 data_size, int prio, u64 flags ); +//sys_event +extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size); +extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout); +extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name); +extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id); + //sys_semaphore extern int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_val, int max_val); extern int sys_semaphore_destroy(u32 sem); @@ -333,7 +159,9 @@ extern int sys_ppu_thread_get_stack_information(u32 info_addr); extern int sys_ppu_thread_stop(u32 thread_id); extern int sys_ppu_thread_restart(u32 thread_id); extern int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr); -extern int sys_ppu_thread_get_id(); +extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry); +extern int sys_ppu_thread_get_id(const u32 id_addr); +extern int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr); //memory extern int sys_memory_container_create(u32 cid_addr, u32 yield_size); @@ -421,10 +249,16 @@ extern int sys_heap_create_heap(const u32 heap_addr, const u32 start_addr, const extern int sys_heap_malloc(const u32 heap_addr, const u32 size); //sys_spu +extern int sys_spu_image_open(u32 img_addr, u32 path_addr); +extern int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_addr, u32 attr_addr, u32 arg_addr); +extern int sys_spu_thread_group_start(u32 id); extern int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr); extern int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg, int prio, u32 stacksize, u64 flags, u64 threadname_addr); extern int sys_raw_spu_create(u32 id_addr, u32 attr_addr); extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu); +extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type); +extern int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type); +extern int sys_spu_thread_write_spu_mb(u32 id, u32 value); //sys_time extern int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr); @@ -469,7 +303,7 @@ protected: ~SysCalls(); public: - s64 DoSyscall(u32 code); + void DoSyscall(u32 code); s64 DoFunc(const u32 id); }; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp new file mode 100644 index 0000000000..16a405c0b7 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -0,0 +1,137 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/Cell/SPUThread.h" +#include "Emu/event.h" + +SysCallBase sys_event("sys_event"); + +//128 +int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size) +{ + sys_event.Warning("sys_event_queue_create(equeue_id_addr=0x%x, attr_addr=0x%x, event_queue_key=0x%llx, size=%d)", + equeue_id_addr, attr_addr, event_queue_key, size); + + if(size <= 0 || size > 127) + { + return CELL_EINVAL; + } + + if(!Memory.IsGoodAddr(equeue_id_addr, 4) || !Memory.IsGoodAddr(attr_addr, sizeof(sys_event_queue_attr))) + { + return CELL_EFAULT; + } + + auto& attr = (sys_event_queue_attr&)Memory[attr_addr]; + sys_event.Warning("name = %s", attr.name); + sys_event.Warning("type = %d", re(attr.type)); + EventQueue* equeue = new EventQueue(); + equeue->size = size; + equeue->pos = 0; + equeue->type = re(attr.type); + strncpy(equeue->name, attr.name, 8); + Memory.Write32(equeue_id_addr, sys_event.GetNewId(equeue)); + + return CELL_OK; +} + +int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) +{ + sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x, event_addr=0x%x, timeout=0x%x)", + equeue_id, event_addr, timeout); + + if(!sys_event.CheckId(equeue_id)) + { + return CELL_ESRCH; + } + + PPCThread* thr = GetCurrentPPCThread(); + + while(true) + { + int status = thr->ThreadStatus(); + if(status == PPCThread_Stopped) + { + return CELL_ECANCELED; + } + + EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data; + for(int i=0; ipos; ++i) + { + if(!equeue->ports[i]->has_data && equeue->ports[i]->thread) + { + SPUThread* thr = (SPUThread*)equeue->ports[i]->thread; + if(thr->OutIntrMbox.GetCount()) + { + u32 val; + thr->OutIntrMbox.Pop(val); + if(!thr->OutMbox.Pop(val)) val = 0; + equeue->ports[i]->data1 = val; + equeue->ports[i]->data2 = 0; + equeue->ports[i]->data3 = 0; + equeue->ports[i]->has_data = true; + } + } + } + + bool has_data = false; + for(int i=0; ipos; i++) + { + if(equeue->ports[i]->has_data) + { + has_data = true; + auto res = (sys_event_data&)Memory[event_addr]; + + re(res.source, equeue->ports[i]->name); + re(res.data1, equeue->ports[i]->data1); + re(res.data2, equeue->ports[i]->data2); + re(res.data3, equeue->ports[i]->data3); + + equeue->ports[i]->has_data = false; + break; + } + } + + if(has_data) + break; + + Sleep(1); + } + + return CELL_OK; +} + +int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name) +{ + sys_event.Warning("sys_event_port_create(eport_id_addr=0x%x, port_type=0x%x, name=0x%llx)", + eport_id_addr, port_type, name); + + if(!Memory.IsGoodAddr(eport_id_addr, 4)) + { + return CELL_EFAULT; + } + + EventPort* eport = new EventPort(); + u32 id = sys_event.GetNewId(eport); + eport->has_data = false; + eport->name = name ? name : id; + Memory.Write32(eport_id_addr, id); + + return CELL_OK; +} + +int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id) +{ + sys_event.Warning("sys_event_port_connect_local(event_port_id=0x%x, event_queue_id=0x%x)", + event_port_id, event_queue_id); + + if(!sys_event.CheckId(event_port_id) || !sys_event.CheckId(event_queue_id)) + { + return CELL_ESRCH; + } + + EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data; + EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(event_queue_id).m_data; + equeue->ports[equeue->pos++] = eport; + + return CELL_OK; +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 99dba6cfca..8177530f34 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -33,26 +33,15 @@ SysCallBase sc_lwmutex("sys_wmutex"); int sys_lwmutex_create(u64 lwmutex_addr, u64 lwmutex_attr_addr) { + if(!Memory.IsGoodAddr(lwmutex_addr, 4) || !Memory.IsGoodAddr(lwmutex_attr_addr)) + { + return CELL_EFAULT; + } + lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; + lmtx.lock_var.all_info = 0; lwmutex_attr& lmtx_attr = (lwmutex_attr&)Memory[lwmutex_attr_addr]; - //sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr = 0x%llx, lwmutex_attr_addr = 0x%llx)", lwmutex_addr, lwmutex_attr_addr); - - lmtx.lock_var.info.owner = 0; - lmtx.lock_var.info.waiter = 0; - - lmtx.attribute = Emu.GetIdManager().GetNewID(wxString::Format("lwmutex[%s]", lmtx_attr.name), nullptr, lwmutex_addr); - /* - ConLog.Write("r3:"); - ConLog.Write("*** lock_var[owner: 0x%x, waiter: 0x%x]", re(lmtx.lock_var.info.owner), re(lmtx.lock_var.info.waiter)); - ConLog.Write("*** attribute: 0x%x", re(lmtx.attribute)); - ConLog.Write("*** recursive_count: 0x%x", re(lmtx.recursive_count)); - ConLog.Write("*** sleep_queue: 0x%x", re(lmtx.sleep_queue)); - ConLog.Write("r4:"); - ConLog.Write("*** attr_protocol: 0x%x", re(lmtx_attr.attr_protocol)); - ConLog.Write("*** attr_recursive: 0x%x", re(lmtx_attr.attr_recursive)); - ConLog.Write("*** name: %s", lmtx_attr.name); - */ return CELL_OK; } @@ -60,39 +49,46 @@ int sys_lwmutex_destroy(u64 lwmutex_addr) { //sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr = 0x%llx)", lwmutex_addr); - lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; - Emu.GetIdManager().RemoveID(lmtx.attribute); + //lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; + //Emu.GetIdManager().RemoveID(lmtx.attribute); return CELL_OK; } int sys_lwmutex_lock(u64 lwmutex_addr, u64 timeout) { - //sc_lwmutex.Warning("sys_lwmutex_lock(lwmutex_addr = 0x%llx, timeout = 0x%llx)", lwmutex_addr, timeout); - lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; + PPCThread& thr = GetCurrentPPUThread(); + + if(thr.GetId() == re(lmtx.lock_var.info.owner)) + { + re(lmtx.recursive_count, re(lmtx.recursive_count) + 1); + return CELL_OK; + } + if(!lmtx.lock_var.info.owner) { re(lmtx.lock_var.info.owner, GetCurrentPPUThread().GetId()); + re(lmtx.recursive_count, 1); } else if(!lmtx.lock_var.info.waiter) { - re(lmtx.lock_var.info.waiter, GetCurrentPPUThread().GetId()); - while(re(lmtx.lock_var.info.owner) != GetCurrentPPUThread().GetId()) Sleep(1); + thr.Wait(true); + re(lmtx.lock_var.info.waiter, thr.GetId()); } else { - return -1; + ConLog.Warning("lwmutex has waiter!"); + return CELL_EBUSY; } - + return CELL_OK; } int sys_lwmutex_trylock(u64 lwmutex_addr) { //sc_lwmutex.Warning("sys_lwmutex_trylock(lwmutex_addr = 0x%llx)", lwmutex_addr); - lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; if(lmtx.lock_var.info.owner) return CELL_EBUSY; @@ -105,8 +101,21 @@ int sys_lwmutex_unlock(u64 lwmutex_addr) //sc_lwmutex.Warning("sys_lwmutex_unlock(lwmutex_addr = 0x%llx)", lwmutex_addr); lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr]; - lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter; - lmtx.lock_var.info.waiter = 0; + + re(lmtx.recursive_count, re(lmtx.recursive_count) - 1); + + if(!lmtx.recursive_count) + { + if(lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter) + { + lmtx.lock_var.info.waiter = 0; + PPCThread* thr = Emu.GetCPU().GetThread(lmtx.lock_var.info.owner); + if(thr) + { + thr->Wait(false); + } + } + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index eddf0ec52e..f9f39c4bbd 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -3,7 +3,12 @@ extern Module sysPrxForUser; -#define PPU_THREAD_ID_INVALID 0xFFFFFFFFU +static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU; +enum +{ + SYS_PPU_THREAD_ONCE_INIT, + SYS_PPU_THREAD_DONE_INIT, +}; int sys_ppu_thread_exit(int errorcode) { @@ -15,9 +20,14 @@ int sys_ppu_thread_exit(int errorcode) int sys_ppu_thread_yield() { - sysPrxForUser.Log("sys_ppu_thread_yield()"); - wxThread::Yield(); + sysPrxForUser.Log("sys_ppu_thread_yield()"); + enable_log = !enable_log; + dump_enable = !dump_enable; + if(!enable_log) + { + Emu.Pause(); + } return CELL_OK; } @@ -110,7 +120,10 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 sysPrxForUser.Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))", thread_id_addr, entry, arg, prio, stacksize, flags, threadname_addr, Memory.ReadString(threadname_addr)); - if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr) || !Memory.IsGoodAddr(threadname_addr)) return CELL_EFAULT; + if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr) || !Memory.IsGoodAddr(threadname_addr)) + { + return CELL_EFAULT; + } PPCThread& new_thread = Emu.GetCPU().AddThread(true); @@ -127,9 +140,28 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 return CELL_OK; } -int sys_ppu_thread_get_id() +void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry) { - sysPrxForUser.Log("sys_ppu_thread_get_id()"); + sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl_addr, entry); - return GetCurrentPPUThread().GetId(); + if(Memory.IsGoodAddr(once_ctrl_addr, 4) && Memory.Read32(once_ctrl_addr) == SYS_PPU_THREAD_ONCE_INIT) + { + Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT); + + PPCThread& new_thread = Emu.GetCPU().AddThread(true); + new_thread.SetEntry(entry); + ((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit(); + new_thread.Run(); + new_thread.Exec(); + + GetCurrentPPUThread().Wait(new_thread); + } +} + +int sys_ppu_thread_get_id(const u32 id_addr) +{ + sysPrxForUser.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr); + + Memory.Write32(id_addr, GetCurrentPPUThread().GetId()); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 7e3ba1b5d5..241aaddcc8 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Loader/ELF.h" +#include "Emu/Cell/SPUThread.h" SysCallBase sc_spu("sys_spu"); @@ -12,6 +13,21 @@ struct sys_spu_thread_group_attribute union{u32 ct;} option; }; +struct sys_spu_thread_attribute +{ + u32 name_addr; + u32 name_len; + u32 option; +}; + +struct sys_spu_thread_argument +{ + u64 arg1; + u64 arg2; + u64 arg3; + u64 arg4; +}; + struct sys_spu_image { u32 type; @@ -20,25 +36,149 @@ struct sys_spu_image int nsegs; }; -u32 LoadImage(vfsStream& stream) +struct SpuGroupInfo +{ + PPCThread* threads[10]; + sys_spu_thread_group_attribute& attr; + + SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr) + { + memset(threads, 0, sizeof(PPCThread*) * 10); + } +}; + +u64 g_spu_offset = 0; + +u32 LoadSpuImage(vfsStream& stream) { ELFLoader l(stream); l.LoadInfo(); - l.LoadData(Memory.MainMem.Alloc(stream.GetSize())); + g_spu_offset = Memory.MainMem.Alloc(0xFFFFED - stream.GetSize()); + l.LoadData(g_spu_offset); - return l.GetEntry(); + return g_spu_offset + l.GetEntry(); } - int sys_spu_image_open(u32 img_addr, u32 path_addr) - { +//156 +int sys_spu_image_open(u32 img_addr, u32 path_addr) +{ const wxString& path = Memory.ReadString(path_addr); sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img_addr, path_addr, path); - vfsLocalFile stream(path); - LoadImage(stream); + if(!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) || !Memory.IsGoodAddr(path_addr)) + { + return CELL_EFAULT; + } + + vfsStream* stream = Emu.GetVFS().Open(path, vfsRead); + + if(!stream || !stream->IsOpened()) + { + sc_spu.Error("'%s' not found!", path); + delete stream; + + return CELL_ENOENT; + } + + u32 entry = LoadSpuImage(*stream); + delete stream; + + sys_spu_image& ret = (sys_spu_image&)Memory[img_addr]; + re(ret.type, 1); + re(ret.entry_point, entry); + re(ret.segs_addr, 0x0); + re(ret.nsegs, 0); return CELL_OK; - } +} + +//172 +int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_addr, u32 attr_addr, u32 arg_addr) +{ + sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)", + thread_addr, group, spu_num, img_addr, attr_addr, arg_addr); + + if(!Emu.GetIdManager().CheckID(group)) + { + return CELL_ESRCH; + } + + if( + !Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) || + !Memory.IsGoodAddr(attr_addr, sizeof(sys_spu_thread_attribute)) || + !Memory.IsGoodAddr(arg_addr, sizeof(sys_spu_thread_argument))) + { + return CELL_EFAULT; + } + + sys_spu_image& img = (sys_spu_image&)Memory[img_addr]; + sys_spu_thread_attribute& attr = (sys_spu_thread_attribute&)Memory[attr_addr]; + sys_spu_thread_argument& arg = (sys_spu_thread_argument&)Memory[arg_addr]; + + if(!Memory.IsGoodAddr(re(attr.name_addr), re(attr.name_len))) + { + return CELL_EFAULT; + } + + u32 entry = re(img.entry_point); + wxString name = Memory.ReadString(re(attr.name_addr), re(attr.name_len)); + u64 a1 = re(arg.arg1); + u64 a2 = re(arg.arg2); + u64 a3 = re(arg.arg3); + u64 a4 = re(arg.arg4); + + ConLog.Write("New SPU Thread:"); + ConLog.Write("entry = 0x%x", entry); + ConLog.Write("name = %s", name); + ConLog.Write("a1 = 0x%x", a1); + ConLog.Write("a2 = 0x%x", a2); + ConLog.Write("a3 = 0x%x", a3); + ConLog.Write("a4 = 0x%x", a4); + ConLog.SkipLn(); + + PPCThread& new_thread = Emu.GetCPU().AddThread(false); + new_thread.SetOffset(g_spu_offset); + new_thread.SetEntry(entry - g_spu_offset); + new_thread.SetName(name); + SPU_GPR_hdr* GPR = ((SPUThread&)new_thread).GPR; + new_thread.Run(); + new_thread.Pause(); + GPR[3]._u64[1] = a1; + GPR[4]._u64[1] = a2; + GPR[5]._u64[1] = a3; + GPR[6]._u64[1] = a4; + + ID& id = Emu.GetIdManager().GetIDData(group); + SpuGroupInfo& group_info = *(SpuGroupInfo*)id.m_data; + group_info.threads[spu_num] = &new_thread; + + return CELL_OK; +} + +//173 +int sys_spu_thread_group_start(u32 id) +{ + sc_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id); + + if(!Emu.GetIdManager().CheckID(id)) + { + return CELL_ESRCH; + } + + ID& id_data = Emu.GetIdManager().GetIDData(id); + SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data; + + Emu.Pause(); + for(int i=0; i<10; i++) + { + if(group_info.threads[i]) + { + group_info.threads[i]->Exec(); + } + } + + return CELL_OK; +} //170 int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr) @@ -49,7 +189,7 @@ int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr) ConLog.Write("*** prio=%d", prio); ConLog.Write("*** attr_addr=0x%llx", attr_addr); - sys_spu_thread_group_attribute& attr = *new sys_spu_thread_group_attribute(*(sys_spu_thread_group_attribute*)&Memory[attr_addr]); + sys_spu_thread_group_attribute& attr = (sys_spu_thread_group_attribute&)Memory[attr_addr]; ConLog.Write("*** attr.name_len=%d", re(attr.name_len)); ConLog.Write("*** attr.name_addr=0x%x", re(attr.name_addr)); @@ -60,7 +200,7 @@ int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr) ConLog.Write("*** name='%s'", name); Memory.Write32(id_addr, - Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group %s", name), &attr, 0)); + Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(attr))); return CELL_OK; } @@ -76,10 +216,10 @@ int sys_raw_spu_create(u32 id_addr, u32 attr_addr) { sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id_addr, attr_addr); - //PPCThread& new_thread = Emu.GetCPU().AddThread(false); //Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr)); - //Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId())); - + PPCThread& new_thread = Emu.GetCPU().AddThread(false); + Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId())); + Memory.Write32(0xe0043014, 0); return CELL_OK; } @@ -88,10 +228,126 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) { sc_spu.Warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu); + if(max_raw_spu > 5) + { + return CELL_EINVAL; + } + if(!Memory.InitSpuRawMem(max_raw_spu)) { + //30010780; + //e0043004 - offset + //e004300c - entry return CELL_UNKNOWN_ERROR; } + //enable_log = true; + //dump_enable = true; + + return CELL_OK; +} + +//181 +int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) +{ + sc_spu.Warning("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=0x%x)", + id, address, value, type); + + PPCThread* thr = Emu.GetCPU().GetThread(id); + + if(!thr || !thr->IsSPU()) + { + return CELL_ESRCH; + } + + (*(SPUThread*)thr).WriteLS64(address, value); + + return CELL_OK; +} + +//182 +int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type) +{ + sc_spu.Warning("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value_addr=0x%x, type=0x%x)", + id, address, value_addr, type); + + PPCThread* thr = Emu.GetCPU().GetThread(id); + + if(!thr || !thr->IsSPU()) + { + return CELL_ESRCH; + } + + if(!(*(SPUThread*)thr).IsGoodLSA(address)) + { + return CELL_EFAULT; + } + + Memory.Write64(value_addr, (*(SPUThread*)thr).ReadLS64(address)); + + return CELL_OK; +} + +//190 +int sys_spu_thread_write_spu_mb(u32 id, u32 value) +{ + sc_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value); + + PPCThread* thr = Emu.GetCPU().GetThread(id); + + if(!thr || !thr->IsSPU()) + { + return CELL_ESRCH; + } + + if(!(*(SPUThread*)thr).InMbox.Push(value)) + { + ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items."); + return CELL_EBUSY; //? + } + + return CELL_OK; +} + +extern SysCallBase sys_event; + +int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr) +{ + sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=0x%x, eq=0x%x, req=0x%llx, spup_addr=0x%x)", + id, eq, req, spup_addr); + + if(!Emu.GetIdManager().CheckID(id) || !sys_event.CheckId(eq)) + { + return CELL_ESRCH; + } + + if(!req) + { + return CELL_EINVAL; + } + + SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data; + EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(eq).m_data; + + for(int i=0; i<10; ++i) + { + if(group->threads[i]) + { + bool finded_port = false; + for(int j=0; jpos; ++j) + { + if(!equeue->ports[j]->thread) + { + finded_port = true; + equeue->ports[j]->thread = group->threads[i]; + } + } + + if(!finded_port) + { + return CELL_EISCONN; + } + } + } return CELL_OK; } \ No newline at end of file diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 812e50e05c..9d62bfeef7 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -12,7 +12,10 @@ using namespace PPU_instr; static const wxString& BreakPointsDBName = "BreakPoints.dat"; static const u16 bpdb_version = 0x1000; -//SysCalls SysCallsManager; +ModuleInitializer::ModuleInitializer() +{ + Emu.AddModuleInit(this); +} Emulator::Emulator() : m_status(Stopped) @@ -24,6 +27,11 @@ Emulator::Emulator() void Emulator::Init() { + while(m_modules_init.GetCount()) + { + m_modules_init[0].Init(); + m_modules_init.RemoveAt(0); + } //if(m_memory_viewer) m_memory_viewer->Close(); //m_memory_viewer = new MemoryViewerPanel(wxGetApp().m_MainFrame); } @@ -108,7 +116,19 @@ void Emulator::Load() LoadPoints(BreakPointsDBName); PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64); - thread.SetEntry(l.GetEntry()); + if(l.GetMachine() == MACHINE_SPU) + { + ConLog.Write("offset = 0x%llx", Memory.MainMem.GetStartAddr()); + ConLog.Write("max addr = 0x%x", l.GetMaxAddr()); + thread.SetOffset(Memory.MainMem.GetStartAddr()); + Memory.MainMem.Alloc(Memory.MainMem.GetStartAddr() + l.GetMaxAddr(), 0xFFFFED - l.GetMaxAddr()); + thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); + } + else + { + thread.SetEntry(l.GetEntry()); + } + thread.SetArg(thread.GetId()); Memory.StackMem.Alloc(0x1000); thread.InitStack(); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 837fe2322f..8719e5fa73 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -8,6 +8,7 @@ #include "Emu/DbgConsole.h" #include "Loader/Loader.h" #include "SysCalls/Callback.h" +#include "SysCalls/Modules.h" struct EmuInfo { @@ -45,6 +46,14 @@ public: u64 GetTLSMemsz() const { return tls_memsz; } }; +class ModuleInitializer +{ +public: + ModuleInitializer(); + + virtual void Init() = 0; +}; + class Emulator { enum Mode @@ -62,6 +71,7 @@ class Emulator u32 m_ppu_thr_exit; MemoryViewerPanel* m_memory_viewer; //ArrayF m_cpu_threads; + ArrayF m_modules_init; Array m_break_points; Array m_marked_points; @@ -93,6 +103,11 @@ public: VFS& GetVFS() { return m_vfs; } Array& GetBreakPoints() { return m_break_points; } Array& GetMarkedPoints() { return m_marked_points; } + + void AddModuleInit(ModuleInitializer* m) + { + m_modules_init.Add(m); + } void SetTLSData(const u64 addr, const u64 filesz, const u64 memsz) { diff --git a/rpcs3/Emu/event.h b/rpcs3/Emu/event.h new file mode 100644 index 0000000000..57580c9975 --- /dev/null +++ b/rpcs3/Emu/event.h @@ -0,0 +1,35 @@ +#pragma once + +struct sys_event_queue_attr +{ + u32 attr_protocol; + int type; + char name[8]; +}; + +struct sys_event_data +{ + u64 source; + u64 data1; + u64 data2; + u64 data3; +}; + +struct EventPort +{ + u64 name; + u64 data1; + u64 data2; + u64 data3; + bool has_data; + PPCThread* thread; +}; + +struct EventQueue +{ + EventPort* ports[127]; + int size; + int pos; + int type; + char name[8]; +}; \ No newline at end of file diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index bdf9a1e4de..a0126bdb66 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -164,16 +164,17 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) { PC = addr; m_list->Freeze(); + disasm->offset = CPU.GetOffset(); for(uint i=0; iSetItem(i, 0, wxString::Format("[%08llx] illegal address", PC)); continue; } disasm->dump_pc = PC; - decoder->Decode(Memory.Read32(PC)); + decoder->Decode(Memory.Read32(CPU.GetOffset() + PC)); if(IsBreakPoint(PC)) { diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 514ed3df17..7dc5e4b0a9 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -133,6 +133,16 @@ bool ELF32Loader::LoadPhdrData(u64 offset) { phdr_arr[i].Show(); + if(phdr_arr[i].p_vaddr < min_addr) + { + min_addr = phdr_arr[i].p_vaddr; + } + + if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr) + { + max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz; + } + if(phdr_arr[i].p_type == 0x00000001) //LOAD { if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr) @@ -161,6 +171,7 @@ bool ELF32Loader::LoadShdrData(u64 offset) for(u32 i=0; i max_addr) + { + max_addr = shdr.sh_addr + shdr.sh_size; + } + //const s64 addr = shdr.sh_addr; //const s64 size = shdr.sh_size; //MemoryBlock* mem = nullptr; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index e12b58f923..ef6fe0dd13 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -207,6 +207,16 @@ bool ELF64Loader::LoadPhdrData(u64 offset) { phdr_arr[i].Show(); + if(phdr_arr[i].p_vaddr < min_addr) + { + min_addr = phdr_arr[i].p_vaddr; + } + + if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr) + { + max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz; + } + if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr) { ConLog.Warning @@ -403,6 +413,16 @@ bool ELF64Loader::LoadShdrData(u64 offset) { Elf64_Shdr& shdr = shdr_arr[i]; + if(shdr.sh_addr < min_addr) + { + min_addr = shdr.sh_addr; + } + + if(shdr.sh_addr + shdr.sh_size > max_addr) + { + max_addr = shdr.sh_addr + shdr.sh_size; + } + if(i < shdr_name_arr.GetCount()) { const wxString& name = shdr_name_arr[i]; diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index d96d5b15b6..febec7c85c 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -144,11 +144,15 @@ class LoaderBase { protected: u32 entry; + u32 min_addr; + u32 max_addr; Elf_Machine machine; LoaderBase() : machine(MACHINE_Unknown) , entry(0) + , min_addr(0) + , max_addr(0) { } @@ -157,6 +161,8 @@ public: virtual bool LoadData(u64 offset = 0) { return false; } Elf_Machine GetMachine() { return machine; } u32 GetEntry() { return entry; } + u32 GetMinAddr() { return min_addr; } + u32 GetMaxAddr() { return min_addr; } }; class Loader : public LoaderBase diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 50c21ec9bf..74ef6e59f7 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -224,6 +224,7 @@ + @@ -240,6 +241,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index df23b4814f..b74d4d565f 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -250,6 +250,12 @@ Emu\CPU + + Emu\SysCalls\lv2 + + + Emu\SysCalls +