diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 38f6807aeb..e2c2a7e3a1 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -1,5 +1,9 @@ #pragma once #include "Array.h" +#include +#include +#include +#include class ThreadExec; diff --git a/rpcs3/Emu/Cell/PPCThread.cpp b/rpcs3/Emu/Cell/PPCThread.cpp index 22cfb54bab..54e5c4ef28 100644 --- a/rpcs3/Emu/Cell/PPCThread.cpp +++ b/rpcs3/Emu/Cell/PPCThread.cpp @@ -273,6 +273,7 @@ void PPCThread::Exec() { wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this); ThreadBase::Start(); + //std::thread thr(std::bind(std::mem_fn(&PPCThread::Task), this)); } void PPCThread::ExecOnce() diff --git a/rpcs3/Emu/Cell/PPCThread.h b/rpcs3/Emu/Cell/PPCThread.h index 76bd87fdb1..c16bb90c18 100644 --- a/rpcs3/Emu/Cell/PPCThread.h +++ b/rpcs3/Emu/Cell/PPCThread.h @@ -6,6 +6,7 @@ enum PPCThreadType { PPC_THREAD_PPU, PPC_THREAD_SPU, + PPC_THREAD_RAW_SPU, }; enum PPCThreadStatus @@ -77,6 +78,7 @@ public: { case PPC_THREAD_PPU: return "PPU"; case PPC_THREAD_SPU: return "SPU"; + case PPC_THREAD_RAW_SPU: return "RawSPU"; } return "Unknown"; @@ -111,6 +113,15 @@ public: void Wait(const PPCThread& thr); bool Sync(); + template + void WaitFor(T func) + { + while(func(ThreadStatus())) + { + Sleep(1); + } + } + int ThreadStatus(); void NextPc(); @@ -125,7 +136,6 @@ public: static wxArrayString ErrorToString(const u32 error); wxArrayString ErrorToString() { return ErrorToString(m_error); } - bool IsSPU() const { return m_type == PPC_THREAD_SPU; } bool IsOk() const { return m_error == 0; } bool IsRunned() const { return m_status == Runned; } bool IsPaused() const { return m_status == Paused; } @@ -138,6 +148,7 @@ public: u32 GetError() const { return m_error; } u32 GetId() const { return m_id; } + PPCThreadType GetType() const { return m_type; } void Reset(); void Close(); @@ -160,6 +171,7 @@ protected: virtual void DoResume()=0; virtual void DoStop()=0; +public: virtual void Task(); private: diff --git a/rpcs3/Emu/Cell/PPCThreadManager.cpp b/rpcs3/Emu/Cell/PPCThreadManager.cpp index 82ae53473d..eba18e18bb 100644 --- a/rpcs3/Emu/Cell/PPCThreadManager.cpp +++ b/rpcs3/Emu/Cell/PPCThreadManager.cpp @@ -2,6 +2,7 @@ #include "PPCThreadManager.h" #include "PPUThread.h" #include "SPUThread.h" +#include "RawSPUThread.h" PPCThreadManager::PPCThreadManager() { @@ -17,13 +18,19 @@ void PPCThreadManager::Close() while(m_threads.GetCount()) RemoveThread(m_threads[0].GetId()); } -PPCThread& PPCThreadManager::AddThread(bool isPPU) +PPCThread& PPCThreadManager::AddThread(PPCThreadType type) { - PPCThread* new_thread = isPPU ? (PPCThread*)new PPUThread() : (PPCThread*)new SPUThread(); - - new_thread->SetId(Emu.GetIdManager().GetNewID( - wxString::Format("%s Thread", isPPU ? "PPU" : "SPU"), new_thread, 0) - ); + PPCThread* new_thread; + char* name; + switch(type) + { + case PPC_THREAD_PPU: new_thread = new PPUThread(); name = "PPU"; break; + case PPC_THREAD_SPU: new_thread = new SPUThread(); name = "SPU"; break; + case PPC_THREAD_RAW_SPU: new_thread = new RawSPUThread(); name = "RawSPU"; break; + default: assert(0); + } + + new_thread->SetId(Emu.GetIdManager().GetNewID(wxString::Format("%s Thread", name), new_thread)); m_threads.Add(new_thread); wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread); @@ -54,14 +61,14 @@ void PPCThreadManager::RemoveThread(const u32 id) Emu.CheckStatus(); } -s32 PPCThreadManager::GetThreadNumById(bool isPPU, u32 id) +s32 PPCThreadManager::GetThreadNumById(PPCThreadType type, u32 id) { s32 num = 0; for(u32 i=0; i& GetThreads() { return m_threads; } - s32 GetThreadNumById(bool isPPU, u32 id); + s32 GetThreadNumById(PPCThreadType type, u32 id); PPCThread* GetThread(u32 id); //IdManager& GetIDs() {return m_threads_id;} diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index 75506c6510..08e110c6f4 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -593,7 +593,7 @@ namespace PPU_instr bind_instr(g3f_0_list, MTFSB1, CRBD, RC); bind_instr(g3f_0_list, MCRFS, CRFD, CRFS); bind_instr(g3f_0_list, MTFSB0, CRBD, RC); - bind_instr(g3f_0_list, MTFSFI, CRBD, I, RC); + bind_instr(g3f_0_list, MTFSFI, CRFD, I, RC); bind_instr(g3f_0_list, MFFS, FRD, RC); bind_instr(g3f_0_list, MTFSF, FM, FRB, RC); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index d234a5ea48..86d012636c 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2080,48 +2080,48 @@ private: CPU.SetBranch(branchTarget(0, CPU.LR)); if(lk) CPU.LR = CPU.PC + 4; } - void CRNOR(u32 bt, u32 ba, u32 bb) + void CRNOR(u32 crbd, u32 crba, u32 crbb) { - const u8 v = 1 ^ (CPU.IsCR(ba) | CPU.IsCR(bb)); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = 1 ^ (CPU.IsCR(crba) | CPU.IsCR(crbb)); + CPU.SetCRBit2(crbd, v & 0x1); } - void CRANDC(u32 bt, u32 ba, u32 bb) + void CRANDC(u32 crbd, u32 crba, u32 crbb) { - const u8 v = CPU.IsCR(ba) & (1 ^ CPU.IsCR(bb)); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = CPU.IsCR(crba) & (1 ^ CPU.IsCR(crbb)); + CPU.SetCRBit2(crbd, v & 0x1); } void ISYNC() { } - void CRXOR(u32 bt, u32 ba, u32 bb) + void CRXOR(u32 crbd, u32 crba, u32 crbb) { - const u8 v = CPU.IsCR(ba) ^ CPU.IsCR(bb); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = CPU.IsCR(crba) ^ CPU.IsCR(crbb); + CPU.SetCRBit2(crbd, v & 0x1); } - void CRNAND(u32 bt, u32 ba, u32 bb) + void CRNAND(u32 crbd, u32 crba, u32 crbb) { - const u8 v = 1 ^ (CPU.IsCR(ba) & CPU.IsCR(bb)); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = 1 ^ (CPU.IsCR(crba) & CPU.IsCR(crbb)); + CPU.SetCRBit2(crbd, v & 0x1); } - void CRAND(u32 bt, u32 ba, u32 bb) + void CRAND(u32 crbd, u32 crba, u32 crbb) { - const u8 v = CPU.IsCR(ba) & CPU.IsCR(bb); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = CPU.IsCR(crba) & CPU.IsCR(crbb); + CPU.SetCRBit2(crbd, v & 0x1); } - void CREQV(u32 bt, u32 ba, u32 bb) + void CREQV(u32 crbd, u32 crba, u32 crbb) { - const u8 v = 1 ^ (CPU.IsCR(ba) ^ CPU.IsCR(bb)); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = 1 ^ (CPU.IsCR(crba) ^ CPU.IsCR(crbb)); + CPU.SetCRBit2(crbd, v & 0x1); } - void CRORC(u32 bt, u32 ba, u32 bb) + void CRORC(u32 crbd, u32 crba, u32 crbb) { - const u8 v = CPU.IsCR(ba) | (1 ^ CPU.IsCR(bb)); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = CPU.IsCR(crba) | (1 ^ CPU.IsCR(crbb)); + CPU.SetCRBit2(crbd, v & 0x1); } - void CROR(u32 bt, u32 ba, u32 bb) + void CROR(u32 crbd, u32 crba, u32 crbb) { - const u8 v = CPU.IsCR(ba) | CPU.IsCR(bb); - CPU.SetCRBit2(bt, v & 0x1); + const u8 v = CPU.IsCR(crba) | CPU.IsCR(crbb); + CPU.SetCRBit2(crbd, v & 0x1); } void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { @@ -2166,7 +2166,7 @@ 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) { @@ -2934,7 +2934,7 @@ private: } void STFSX(u32 frs, u32 ra, u32 rb) { - Memory.Write32((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), PPCdouble(CPU.FPR[frs]).To32()); + Memory.Write32((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), CPU.FPR[frs].To32()); } void STVRX(u32 vs, u32 ra, u32 rb) { @@ -3147,12 +3147,12 @@ private: } void STFS(u32 frs, u32 ra, s32 d) { - Memory.Write32(ra ? CPU.GPR[ra] + d : d, PPCdouble(CPU.FPR[frs]).To32()); + Memory.Write32(ra ? CPU.GPR[ra] + d : d, CPU.FPR[frs].To32()); } void STFSU(u32 frs, u32 ra, s32 d) { const u64 addr = CPU.GPR[ra] + d; - Memory.Write32(addr, PPCdouble(CPU.FPR[frs]).To32()); + Memory.Write32(addr, CPU.FPR[frs].To32()); CPU.GPR[ra] = addr; } void STFD(u32 frs, u32 ra, s32 d) @@ -3213,32 +3213,32 @@ private: } } - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(CPU.FPR[fra] - CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fsubs.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FADDS(u32 frd, u32 fra, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(CPU.FPR[fra] + CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fadds.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FSQRTS(u32 frd, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(sqrt(CPU.FPR[frb])); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fsqrts.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FRES(u32 frd, u32 frb, bool rc) { if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX); CPU.FPR[frd] = static_cast(1.0f/CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); CPU.FPSCR.FI = 0; CPU.FPSCR.FR = 0; if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]); @@ -3248,31 +3248,31 @@ private: CPU.FPR[frd] = static_cast(CPU.FPR[fra] * CPU.FPR[frc]); CPU.FPSCR.FI = 0; CPU.FPSCR.FR = 0; - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fmuls.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fmadds.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fmsubs.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(-(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb])); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fnmsubs.");////CPU.UpdateCR1(CPU.FPR[frd]); } void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = static_cast(-(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb])); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fnmadds.");//CPU.UpdateCR1(CPU.FPR[frd]); } void STD(u32 rs, u32 ra, s32 d) @@ -3290,6 +3290,7 @@ private: { u64 mask = (1ULL << crbd); CPU.FPSCR.FPSCR |= mask; + if(rc) UNIMPLEMENTED(); } void MCRFS(u32 crbd, u32 crbs) @@ -3302,11 +3303,12 @@ private: { u64 mask = (1ULL << crbd); CPU.FPSCR.FPSCR &= ~mask; + if(rc) UNIMPLEMENTED(); } void MTFSFI(u32 crfd, u32 i, bool rc) { - u64 mask = (1ULL << crfd); + u64 mask = (0x1ULL << crfd); if(i) { @@ -3316,6 +3318,7 @@ private: { CPU.FPSCR.FPSCR &= ~mask; } + if(rc) UNIMPLEMENTED(); } void MFFS(u32 frd, bool rc) @@ -3478,25 +3481,25 @@ private: } CPU.FPR[frd] = CPU.FPR[fra] / CPU.FPR[frb]; - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fdiv.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FSUB(u32 frd, u32 fra, u32 frb, bool rc) { CPU.FPR[frd] = CPU.FPR[fra] - CPU.FPR[frb]; - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fsub.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FADD(u32 frd, u32 fra, u32 frb, bool rc) { CPU.FPR[frd] = CPU.FPR[fra] + CPU.FPR[frb]; - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fadd.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FSQRT(u32 frd, u32 frb, bool rc) { CPU.FPR[frd] = sqrt(CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fsqrt.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) @@ -3525,19 +3528,19 @@ private: void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]; - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fmadd.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = -(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fnmsub.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { CPU.FPR[frd] = -(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]); - CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType(); + CPU.FPSCR.FPRF = CPU.FPR[frd].GetType(); if(rc) UNK("fnmadd.");//CPU.UpdateCR1(CPU.FPR[frd]); } void FCMPO(u32 crfd, u32 fra, u32 frb) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index cc0b7eecfb..e3cbffe359 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3,14 +3,14 @@ #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUInterpreter.h" #include "Emu/Cell/PPUDisAsm.h" - +#include extern gcmInfo gcm_info; PPUThread& GetCurrentPPUThread() { PPCThread* thread = GetCurrentPPCThread(); - if(!thread || thread->IsSPU()) throw wxString("GetCurrentPPUThread: bad thread"); + if(!thread || thread->GetType() != PPC_THREAD_PPU) throw wxString("GetCurrentPPUThread: bad thread"); return *(PPUThread*)thread; } @@ -68,7 +68,7 @@ void PPUThread::InitRegs() SetPc(pc); - const s32 thread_num = Emu.GetCPU().GetThreadNumById(!IsSPU(), GetId()); + const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId()); if(thread_num < 0) { diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp new file mode 100644 index 0000000000..e10f97d6dc --- /dev/null +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -0,0 +1,151 @@ +#include "stdafx.h" +#include "Emu/Cell/RawSPUThread.h" + +RawSPUThread::RawSPUThread(PPCThreadType type) : SPUThread(type) +{ + Reset(); +} + +RawSPUThread::~RawSPUThread() +{ +} + +void RawSPUThread::InitRegs() +{ + GPR[3]._u64[1] = m_args[0]; + GPR[4]._u64[1] = m_args[1]; + GPR[5]._u64[1] = m_args[2]; + GPR[6]._u64[1] = m_args[3]; + + u32 num = Emu.GetCPU().GetThreadNumById(GetType(), GetId()); + + m_offset = RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * num + RAW_SPU_LS_OFFSET; + MFC_LSA.SetAddr(GetRawSPURegAddrByNum(num, MFC_LSA_offs)); + MFC_EAH.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAH_offs)); + MFC_EAL.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAL_offs)); + MFC_Size_Tag.SetAddr(GetRawSPURegAddrByNum(num, MFC_Size_Tag_offs)); + MFC_CMDStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_CMDStatus_offs)); + MFC_QStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_QStatus_offs)); + Prxy_QueryType.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryType_offs)); + Prxy_QueryMask.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryMask_offs)); + Prxy_TagStatus.SetAddr(GetRawSPURegAddrByNum(num, Prxy_TagStatus_offs)); + SPU_Out_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_Out_MBox_offs)); + SPU_In_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_In_MBox_offs)); + SPU_MBox_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_MBox_Status_offs)); + SPU_RunCntl.SetAddr(GetRawSPURegAddrByNum(num, SPU_RunCntl_offs)); + SPU_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_Status_offs)); + SPU_NPC.SetAddr(GetRawSPURegAddrByNum(num, SPU_NPC_offs)); + SPU_RdSigNotify1.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify1_offs)); + SPU_RdSigNotify2.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify2_offs)); + + SPU_RunCntl.SetValue(SPU_RUNCNTL_STOP); + SPU_Status.SetValue(SPU_STATUS_RUNNING); + Prxy_QueryType.SetValue(0); + MFC_CMDStatus.SetValue(0); + PC = SPU_NPC.GetValue(); +} + +void RawSPUThread::Task() +{ + ConLog.Write("%s enter", PPCThread::GetFName()); + + const Array& bp = Emu.GetBreakPoints(); + + try + { + for(uint i=0; i> 16; + ConLog.Warning("RawSPU DMA GET:"); + ConLog.Warning("*** lsa = 0x%x", lsa); + ConLog.Warning("*** ea = 0x%llx", ea); + ConLog.Warning("*** tag = 0x%x", tag); + ConLog.Warning("*** size = 0x%x", size); + ConLog.SkipLn(); + memcpy(Memory + m_offset + lsa, Memory + ea, size); + } + + if(Prxy_QueryType.GetValue() == 2) + { + Prxy_QueryType.SetValue(0); + u32 mask = Prxy_QueryMask.GetValue(); + // + MFC_QStatus.SetValue(mask); + } + + if(SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE) + { + if(!is_last_paused) + { + if(is_last_paused = SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE) + { + SPU_NPC.SetValue(PC); + SPU_Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL); + } + } + + Sleep(1); + continue; + } + + if(is_last_paused) + { + is_last_paused = false; + PC = SPU_NPC.GetValue(); + SPU_Status.SetValue(SPU_STATUS_RUNNING); + } + + DoCode(Memory.Read32(m_offset + PC)); + NextPc(); + + for(uint i=0; iIsSPU()) throw wxString("GetCurrentSPUThread: bad thread"); + if(!thread || thread->GetType() == PPC_THREAD_PPU) throw wxString("GetCurrentSPUThread: bad thread"); return *(SPUThread*)thread; } -SPUThread::SPUThread() : PPCThread(PPC_THREAD_SPU) +SPUThread::SPUThread(PPCThreadType type) : PPCThread(type) { Reset(); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index e713e5c8e0..c311dfef28 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -81,6 +81,22 @@ enum MFCchannels MFC_RdAtomicStat = 27, //Read completion status of last completed immediate MFC atomic update command }; +enum +{ + SPU_RUNCNTL_STOP = 0, + SPU_RUNCNTL_RUNNABLE = 1, +}; + +enum +{ + SPU_STATUS_STOPPED = 0x0, + SPU_STATUS_RUNNING = 0x1, + SPU_STATUS_STOPPED_BY_STOP = 0x2, + SPU_STATUS_STOPPED_BY_HALT = 0x4, + SPU_STATUS_WAITING_FOR_CHANNEL = 0x8, + SPU_STATUS_SINGLE_STEP = 0x10, +}; + union SPU_GPR_hdr { u128 _u128; @@ -111,10 +127,91 @@ class SPUThread : public PPCThread { public: SPU_GPR_hdr GPR[128]; //General-Purpose Register - SizedStack OutMbox; - SizedStack OutIntrMbox; - SizedStack InMbox; + template + class SPUReg + { + u64 m_addr; + u32 m_pos; + + public: + static const size_t max_count = _max_count; + static const size_t size = max_count * 4; + + SPUReg() + { + Init(); + } + + void Init() + { + m_pos = 0; + } + + void SetAddr(u64 addr) + { + m_addr = addr; + } + + u64 GetAddr() const + { + return m_addr; + } + + __forceinline bool Pop(u32& res) + { + if(!m_pos) return false; + res = Memory.Read32(m_addr + m_pos--); + return true; + } + + __forceinline bool Push(u32 value) + { + if(m_pos >= max_count) return false; + Memory.Write32(m_addr + m_pos++, value); + return true; + } + + u32 GetCount() const + { + return m_pos; + } + + u32 GetFreeCount() const + { + return max_count - m_pos; + } + + void SetValue(u32 value) + { + Memory.Write32(m_addr, value); + } + + u32 GetValue() const + { + return Memory.Read32(m_addr); + } + }; + + SPUReg<1> MFC_LSA; + SPUReg<1> MFC_EAH; + SPUReg<1> MFC_EAL; + SPUReg<1> MFC_Size_Tag; + SPUReg<1> MFC_CMDStatus; + SPUReg<1> MFC_QStatus; + SPUReg<1> Prxy_QueryType; + SPUReg<1> Prxy_QueryMask; + SPUReg<1> Prxy_TagStatus; + SPUReg<1> SPU_Out_MBox; + SPUReg<4> SPU_In_MBox; + SPUReg<1> SPU_MBox_Status; + SPUReg<1> SPU_RunCntl; + SPUReg<1> SPU_Status; + SPUReg<1> SPU_NPC; + SPUReg<1> SPU_RdSigNotify1; + SPUReg<1> SPU_RdSigNotify2; + + SizedStack SPU_OutIntr_Mbox; u32 LSA; union @@ -128,13 +225,13 @@ public: switch(ch) { case SPU_WrOutMbox: - return OutMbox.GetFreeCount(); + return SPU_Out_MBox.GetFreeCount(); case SPU_RdInMbox: - return InMbox.GetCount(); + return SPU_In_MBox.GetCount(); case SPU_WrOutIntrMbox: - return 0;//return OutIntrMbox.GetFreeCount(); + return 0;//return SPU_OutIntr_Mbox.GetFreeCount(); default: ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch); @@ -152,7 +249,7 @@ public: { case SPU_WrOutIntrMbox: ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v); - if(!OutIntrMbox.Push(v)) + if(!SPU_OutIntr_Mbox.Push(v)) { ConLog.Warning("Not enought free rooms."); } @@ -160,10 +257,11 @@ public: case SPU_WrOutMbox: ConLog.Warning("SPU_WrOutMbox = 0x%x", v); - if(!OutMbox.Push(v)) + if(!SPU_Out_MBox.Push(v)) { ConLog.Warning("Not enought free rooms."); } + SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff) | 1); break; default: @@ -180,7 +278,8 @@ public: switch(ch) { case SPU_RdInMbox: - if(!InMbox.Pop(v)) v = 0; + if(!SPU_In_MBox.Pop(v)) v = 0; + SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff00) | (SPU_In_MBox.GetCount() << 8)); break; default: @@ -203,7 +302,7 @@ public: void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); } public: - SPUThread(); + SPUThread(PPCThreadType type = PPC_THREAD_SPU); ~SPUThread(); virtual wxString RegsToString() @@ -224,7 +323,7 @@ protected: virtual void DoResume(); virtual void DoStop(); -private: +protected: virtual void DoCode(const s32 code); }; diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index c2da9042b6..a2da8e5a7b 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "GLGSRender.h" - -#define CMD_DEBUG 0 +#include "Emu/Cell/PPCInstrTable.h" +#define CMD_DEBUG 1 #define DUMP_VERTEX_DATA 1 #if CMD_DEBUG @@ -132,7 +132,9 @@ void GLRSXThread::Task() { wxCriticalSectionLocker lock(p.m_cs_main); - if(p.m_ctrl->get == p.m_ctrl->put || !Emu.IsRunned()) + const u32 get = re(p.m_ctrl->get); + const u32 put = re(p.m_ctrl->put); + if(put <= get || !Emu.IsRunned()) { SemaphorePostAndWait(p.m_sem_flush); @@ -170,23 +172,25 @@ void GLRSXThread::Task() continue; } - const u32 get = re(p.m_ctrl->get); + ConLog.Write("addr = 0x%x", p.m_ioAddress + get); const u32 cmd = Memory.Read32(p.m_ioAddress + get); const u32 count = (cmd >> 18) & 0x7ff; - + //if(cmd == 0) continue; if(cmd & CELL_GCM_METHOD_FLAG_JUMP) { u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT); - p.m_ctrl->get = re32(addr); - ConLog.Warning("rsx jump(0x%x)", addr); + addr &= ~0x1000; + //0x30101000 + 0x80bf000 = 0x80be000 + ConLog.Warning("rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", addr, p.m_ioAddress + get, cmd, get, put); + re(p.m_ctrl->get, addr); continue; } if(cmd & CELL_GCM_METHOD_FLAG_CALL) { call_stack.Push(get + 4); u32 addr = cmd & ~CELL_GCM_METHOD_FLAG_CALL; + ConLog.Warning("rsx call(0x%x) #0x%x - 0x%x", addr, cmd, get); p.m_ctrl->get = re32(addr); - ConLog.Warning("rsx call(0x%x)", addr); continue; } if(cmd & CELL_GCM_METHOD_FLAG_RETURN) @@ -606,6 +610,14 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c //Enable(args[0] ? true : false, GL_DEPTH_CLAMP); break; + case NV4097_SET_ALPHA_FUNC: + glAlphaFunc(args[0], args[1]); + break; + + case NV4097_SET_CULL_FACE: + glCullFace(args[0]); + break; + case NV4097_SET_VIEWPORT_VERTICAL: { m_set_viewport_vertical = true; @@ -1134,7 +1146,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c for(u32 i=0; i= GetStartAddr() && addr < GetEndAddr(); + return mem && addr >= GetStartAddr() && addr < GetEndAddr(); } __forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const @@ -466,24 +466,52 @@ u8* DynamicMemoryBlock::GetMem(u64 addr) const return nullptr; } +#define DEBUG_RAWSPU_MEM 1 //MemoryBase void MemoryBase::Write8(u64 addr, const u8 data) { +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Write8(addr=0x%llx,data=0x%x)", addr, data); + } +#endif GetMemByAddr(addr).Write8(addr, data); } void MemoryBase::Write16(u64 addr, const u16 data) { +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Write16(addr=0x%llx,data=0x%x)", addr, data); + } +#endif + GetMemByAddr(addr).Write16(addr, data); } void MemoryBase::Write32(u64 addr, const u32 data) { +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Write32(addr=0x%llx,data=0x%x)", addr, data); + } +#endif + GetMemByAddr(addr).Write32(addr, data); } void MemoryBase::Write64(u64 addr, const u64 data) { +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Write64(addr=0x%llx,data=0x%llx)", addr, data); + } +#endif + GetMemByAddr(addr).Write64(addr, data); } @@ -529,8 +557,13 @@ 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); +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Read8(addr=0x%llx)", addr); + } +#endif + MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -542,8 +575,13 @@ u8 MemoryBase::Read8(u64 addr) u16 MemoryBase::Read16(u64 addr) { - if(enable_log && addr >= 0xd0010a84) - ConLog.Warning("Read16 from block: [%08llx]", addr); +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Read16(addr=0x%llx)", addr); + } +#endif + MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -555,8 +593,13 @@ u16 MemoryBase::Read16(u64 addr) u32 MemoryBase::Read32(u64 addr) { - if(enable_log && addr >= 0xd0010a84) - ConLog.Warning("Read32 from block: [%08llx]", addr); +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr) && !(GetCurrentPPCThread() && GetCurrentPPCThread()->GetType() == PPC_THREAD_RAW_SPU)) + { + ConLog.Warning("Read32(addr=0x%llx)", addr); + } +#endif + MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { @@ -568,8 +611,13 @@ u32 MemoryBase::Read32(u64 addr) u64 MemoryBase::Read64(u64 addr) { - if(enable_log && addr >= 0xd0010a84) - ConLog.Warning("Read64 from block: [%08llx]", addr); +#if DEBUG_RAWSPU_MEM + if(SpuRawMem.IsMyAddress(addr)) + { + ConLog.Warning("Read64(addr=0x%llx)", addr); + } +#endif + MemoryBlock& mem = GetMemByAddr(addr); if(mem.IsNULL()) { diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 5fdcaa0b8f..0d56b45863 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -63,16 +63,16 @@ public: */ } - template static __forceinline T Reverse(T val); - template<> static __forceinline u8 Reverse(u8 val) { return val; }; - template<> static __forceinline u16 Reverse(u16 val) { return Reverse16(val); }; - template<> static __forceinline u32 Reverse(u32 val) { return Reverse32(val); }; - template<> static __forceinline u64 Reverse(u64 val) { return Reverse64(val); }; + template static __forceinline u64 ReverseData(u64 val); + template<> static __forceinline u64 ReverseData<1>(u64 val) { return val; } + template<> static __forceinline u64 ReverseData<2>(u64 val) { return Reverse16(val); } + template<> static __forceinline u64 ReverseData<4>(u64 val) { return Reverse32(val); } + template<> static __forceinline u64 ReverseData<8>(u64 val) { return Reverse64(val); } - template<> static __forceinline s8 Reverse(s8 val) { return val; }; - template<> static __forceinline s16 Reverse(s16 val) { return Reverse16(val); }; - template<> static __forceinline s32 Reverse(s32 val) { return Reverse32(val); }; - template<> static __forceinline s64 Reverse(s64 val) { return Reverse64(val); }; + template static __forceinline T Reverse(T val) + { + return (T)ReverseData(val); + }; MemoryBlock& GetMemByNum(const u8 num) { @@ -328,6 +328,31 @@ public: return PRXMem.Free(addr); } + bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) + { + if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) + { + return false; + } + + MemoryBlocks.Add((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size)); + return true; + } + + bool Unmap(const u64 addr) + { + for(uint i=0; iWait(new_thread); } Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index de9bc167af..a32b6d4ac4 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -2,10 +2,131 @@ #include "SysCalls.h" #include "SC_FUNC.h" -Module* g_modules[50]; -uint g_modules_count = 0; +Module* g_modules[3][0xff] = {0}; +uint g_max_module_id = 0; +uint g_module_2_count = 0; ArrayF g_modules_funcs_list; +struct ModuleInfo +{ + u32 id; + char* name; +} +static const g_module_list[] = +{ + {0x0000, "sys_net"}, + {0x0001, "sys_http"}, + {0x0002, "cellHttpUtil"}, + {0x0003, "cellSsl"}, + {0x0004, "cellHttps"}, + {0x0005, "cellVdec"}, + {0x0006, "cellAdec"}, + {0x0007, "cellDmux"}, + {0x0008, "cellVpost"}, + {0x0009, "cellRtc"}, + {0x000a, "cellSpurs"}, + {0x000b, "cellOvis"}, + {0x000c, "cellSheap"}, + {0x000d, "sys_sync"}, + {0x000e, "sys_fs"}, + {0x000f, "sys_jpgdec"}, + {0x0010, "cellGcmSys"}, + {0x0011, "cellAudio"}, + {0x0012, "cellPamf"}, + {0x0013, "cellAtrac"}, + {0x0014, "cellNetCtl"}, + {0x0015, "cellSysutil"}, + {0x0016, "sceNp"}, + {0x0017, "sys_io"}, + {0x0018, "cellPngDec"}, + {0x0019, "cellFont"}, + {0x001a, "cellFontFt"}, + {0x001b, "cellFreetype"}, + {0x001c, "cellUsbd"}, + {0x001d, "cellSail"}, + {0x001e, "cellL10n"}, + {0x001f, "cellResc"}, + {0x0020, "cellDaisy"}, + {0x0021, "cellKey2char"}, + {0x0022, "cellMic"}, + {0x0023, "cellCamera"}, + {0x0024, "cellVdecMpeg2"}, + {0x0025, "cellVdecAvc"}, + {0x0026, "cellAdecLpcm"}, + {0x0027, "cellAdecAc3"}, + {0x0028, "cellAdecAtx"}, + {0x0029, "cellAdecAt3"}, + {0x002a, "cellDmuxPamf"}, + {0x002e, "cellLv2dbg"}, + {0x0030, "cellUsbpspcm"}, + {0x0031, "cellAvconfExt"}, + {0x0032, "cellSysutilUserinfo"}, + {0x0033, "cellSysutilSavedata"}, + {0x0034, "cellSubdisplay"}, + {0x0035, "cellSysutilRec"}, + {0x0036, "cellVideoExport"}, + {0x0037, "cellSysutilGameExec"}, + {0x0038, "sceNp2"}, + {0x0039, "cellSysutilAp"}, + {0x003a, "cellSysutilNpClans"}, + {0x003b, "cellSysutilOskExt"}, + {0x003c, "cellVdecDivx"}, + {0x003d, "cellJpgEnc"}, + {0x003e, "cellSysutilGame"}, + {0x003f, "cellBgdl"}, + {0x0040, "cellFreetypeTT"}, + {0x0041, "cellSysutilVideoUpload"}, + {0x0042, "cellSysutilSysconfExt"}, + {0x0043, "cellFiber"}, + {0x0044, "cellSysutilNpCommerce2"}, + {0x0045, "cellSysutilNpTus"}, + {0x0046, "cellVoice"}, + {0x0047, "cellAdecCelp8"}, + {0x0048, "cellCelp8Enc"}, + {0x0049, "cellSysutilLicenseArea"}, + {0x004a, "cellSysutilMusic2"}, + {0x004e, "cellSysutilScreenshot"}, + {0x004f, "cellSysutilMusicDecode"}, + {0x0050, "cellSysutilSpursJq"}, + {0x0052, "cellPngEnc"}, + {0x0053, "cellSysutilMusicDecode2"}, + {0x0055, "cellSync2"}, + {0x0056, "cellSysutilNpUtil"}, + {0x0057, "cellRudp"}, + {0x0059, "cellSysutilNpSns"}, + {0x005a, "cellGem"}, + {0xf00a, "cellScelpEnc"}, + {0xf010, "cellGifDec"}, + {0xf019, "cellAdecCelp"}, + {0xf01b, "cellAdecM2bc"}, + {0xf01d, "cellAdecM4aac"}, + {0xf01e, "cellAdecMp3"}, + {0xf023, "cellImejp"}, + {0xf028, "cellSysutilMusic"}, + {0xf029, "cellPhotoExport"}, + {0xf02a, "cellPrint"}, + {0xf02b, "cellPhotoImport"}, + {0xf02c, "cellMusicExport"}, + {0xf02e, "cellPhotoDecode"}, + {0xf02f, "cellSysutilSearch"}, + {0xf030, "cellSysutilAvchat2"}, + {0xf034, "cellSailRec"}, + {0xf035, "sceNpTrophy"}, + {0xf053, "cellAdecAt3multi"}, + {0xf054, "cellLibatrac3multi"}, +}; + +struct _InitNullModules +{ + _InitNullModules() + { + for(auto& m : g_module_list) + { + new Module(m.id, m.name); + } + } +} InitNullModules; + bool IsLoadedFunc(u32 id) { for(u32 i=0; iSetLoaded(false); + if(g_modules[0][i]) + { + g_modules[0][i]->SetLoaded(false); + } + + if(g_modules[1][i]) + { + g_modules[1][i]->SetLoaded(false); + } + + if(g_modules[2][i]) + { + g_modules[2][i]->SetLoaded(false); + } } g_modules_funcs_list.Clear(); @@ -61,11 +195,21 @@ void UnloadModules() Module* GetModuleByName(const wxString& name) { - for(u32 i=0; iGetName().Cmp(name) == 0) + if(g_modules[0][i] && g_modules[0][i]->GetName().Cmp(name) == 0) { - return g_modules[i]; + return g_modules[0][i]; + } + + if(g_modules[1][i] && g_modules[1][i]->GetName().Cmp(name) == 0) + { + return g_modules[1][i]; + } + + if(g_modules[2][i] && g_modules[2][i]->GetName().Cmp(name) == 0) + { + return g_modules[2][i]; } } @@ -74,24 +218,92 @@ Module* GetModuleByName(const wxString& name) Module* GetModuleById(u16 id) { - for(u32 i=0; iGetID() == id) + if(g_modules[0][i] && g_modules[0][i]->GetID() == id) { - return g_modules[i]; + return g_modules[0][i]; + } + + if(g_modules[1][i] && g_modules[1][i]->GetID() == id) + { + return g_modules[1][i]; } } return nullptr; } -Module::Module(const char* name, u16 id, void (*init)()) +void SetModule(int id, Module* module, bool with_data) +{ + if(id != 0xffff) + { + if(u16((u8)id + 1) > g_max_module_id) + { + g_max_module_id = u16((u8)id + 1); + } + + int index; + switch(id >> 8) + { + case 0x00: index = 0; break; + case 0xf0: index = 1; break; + default: assert(0); return; + } + + if(g_modules[index][(u8)id]) + { + if(with_data) + { + module->SetName(g_modules[index][(u8)id]->GetName()); + delete g_modules[index][(u8)id]; + g_modules[index][(u8)id] = module; + } + else + { + g_modules[index][(u8)id]->SetName(module->GetName()); + delete module; + } + } + else + { + g_modules[index][(u8)id] = module; + } + } + else + { + g_modules[2][g_module_2_count++] = module; + + if(g_module_2_count > g_max_module_id) + { + g_max_module_id = g_module_2_count; + } + } +} + +Module::Module(u16 id, const char* name) : m_is_loaded(false) , m_name(name) , m_id(id) { - g_modules[g_modules_count++] = this; - init(); + SetModule(m_id, this, false); +} + +Module::Module(const char* name, void (*init)()) + : m_is_loaded(false) + , m_name(name) + , m_id(-1) +{ + SetModule(m_id, this, init != nullptr); + if(init) init(); +} + +Module::Module(u16 id, void (*init)()) + : m_is_loaded(false) + , m_id(id) +{ + SetModule(m_id, this, init != nullptr); + if(init) init(); } void Module::Load() @@ -154,6 +366,11 @@ wxString Module::GetName() const return m_name; } +void Module::SetName(const wxString& name) +{ + m_name = name; +} + void Module::Log(const u32 id, wxString fmt, ...) { if(enable_log) diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 38143bdd68..d3678e4ea0 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -25,14 +25,16 @@ struct ModuleFunc class Module { - const char* m_name; + wxString m_name; const u16 m_id; bool m_is_loaded; public: Array m_funcs_list; - Module(const char* name, u16 id, void (*init)()); + Module(u16 id, const char* name); + Module(const char* name, void (*init)()); + Module(u16 id, void (*init)()); void Load(); void UnLoad(); @@ -44,6 +46,7 @@ public: u16 GetID() const; wxString GetName() const; + void SetName(const wxString& name); public: void Log(const u32 id, wxString fmt, ...); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index c367afe2df..ae7eb0746e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/SC_FUNC.h" void cellGcmSys_init(); -Module cellGcmSys("cellGcmSys", 0x0010, cellGcmSys_init); +Module cellGcmSys(0x0010, cellGcmSys_init); s64 cellGcmFunc15() { diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp new file mode 100644 index 0000000000..fb7bb2e3c7 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -0,0 +1,95 @@ +#include "stdafx.h" +#include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void cellSysmodule_init(); +Module cellSysmodule("cellSysmodule", cellSysmodule_init); + +enum +{ + CELL_SYSMODULE_LOADED = CELL_OK, + CELL_SYSMODULE_ERROR_DUPLICATED = 0x80012001, + CELL_SYSMODULE_ERROR_UNKNOWN = 0x80012002, + CELL_SYSMODULE_ERROR_UNLOADED = 0x80012003, + CELL_SYSMODULE_ERROR_INVALID_MEMCONTAINER = 0x80012004, + CELL_SYSMODULE_ERROR_FATAL = 0x800120ff, +}; + +int cellSysmoduleInitialize() +{ + cellSysmodule.Log("cellSysmoduleInitialize()"); + return CELL_OK; +} + +int cellSysmoduleFinalize() +{ + cellSysmodule.Log("cellSysmoduleFinalize()"); + return CELL_OK; +} + +int cellSysmoduleSetMemcontainer(u32 ct_id) +{ + cellSysmodule.Warning("TODO: cellSysmoduleSetMemcontainer(ct_id=0x%x)", ct_id); + return CELL_OK; +} + +int cellSysmoduleLoadModule(u16 id) +{ + cellSysmodule.Warning("cellSysmoduleLoadModule(id=0x%04x)", id); + Module* m = GetModuleById(id); + + if(!m) + { + return CELL_SYSMODULE_ERROR_UNKNOWN; + } + + if(m->IsLoaded()) + { + return CELL_SYSMODULE_ERROR_DUPLICATED; + } + + m->Load(); + return CELL_OK; +} + +int cellSysmoduleUnloadModule(u16 id) +{ + cellSysmodule.Warning("cellSysmoduleUnloadModule(id=0x%04x)", id); + Module* m = GetModuleById(id); + + if(!m) + { + return CELL_SYSMODULE_ERROR_UNKNOWN; + } + + if(!m->IsLoaded()) + { + return CELL_SYSMODULE_ERROR_UNLOADED; + } + + m->UnLoad(); + return CELL_OK; +} + +int cellSysmoduleIsLoaded(u16 id) +{ + cellSysmodule.Warning("cellSysmoduleIsLoaded(id=0x%04x)", id); + Module* m = GetModuleById(id); + + if(!m) + { + return CELL_SYSMODULE_ERROR_UNKNOWN; + } + + return m->IsLoaded() ? CELL_SYSMODULE_LOADED : CELL_SYSMODULE_ERROR_UNLOADED; +} + +void cellSysmodule_init() +{ + cellSysmodule.AddFunc(0x63ff6ff9, bind_func(cellSysmoduleInitialize)); + cellSysmodule.AddFunc(0x96c07adf, bind_func(cellSysmoduleFinalize)); + cellSysmodule.AddFunc(0xa193143c, bind_func(cellSysmoduleSetMemcontainer)); + cellSysmodule.AddFunc(0x32267a31, bind_func(cellSysmoduleLoadModule)); + cellSysmodule.AddFunc(0x112a5ee9, bind_func(cellSysmoduleUnloadModule)); + cellSysmodule.AddFunc(0x5a59e258, bind_func(cellSysmoduleIsLoaded)); +} diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 512de006aa..42a0f50e17 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/SC_FUNC.h" void sysPrxForUser_init(); -Module sysPrxForUser("sysPrxForUser", -1, sysPrxForUser_init); +Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init); void sys_initialize_tls() { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index c73d87ebdd..56bd3ccc9c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/SC_FUNC.h" void sys_fs_init(); -Module sys_fs("sys_fs", 0x000e, sys_fs_init); +Module sys_fs(0x000e, sys_fs_init); void sys_fs_init() { diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index c4654036c0..f01c950d8d 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -3,7 +3,7 @@ #include "Emu/SysCalls/SC_FUNC.h" void sys_io_init(); -Module sys_io("sys_io", 0x0017, sys_io_init); +Module sys_io(0x0017, sys_io_init); void sys_io_init() { diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index bdb3078aed..6adafdddf0 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -247,7 +247,7 @@ void SysCalls::DoSyscall(u32 code) //timer case 141: case 142: - Sleep(SC_ARGS_1 / (1000 * 1000)); + std::this_thread::sleep_for(std::chrono::nanoseconds(SC_ARGS_1)); RESULT(0); return; diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 2534b5e97d..554f8992e8 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -222,7 +222,7 @@ extern int cellGcmCallback(u32 context_addr, u32 count); extern int cellGcmGetConfiguration(u32 config_addr); extern int cellGcmAddressToOffset(u32 address, u32 offset_addr); extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); -extern u32 cellGcmGetLabelAddress(u32 index); +extern u32 cellGcmGetLabelAddress(u8 index); extern u32 cellGcmGetControlRegister(); extern int cellGcmFlush(u32 ctx, u32 id); extern void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index 16a405c0b7..fe0cf1de46 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -44,14 +44,13 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) return CELL_ESRCH; } - PPCThread* thr = GetCurrentPPCThread(); - - while(true) + int result; + auto queue_receive = [&](int status) -> bool { - int status = thr->ThreadStatus(); if(status == PPCThread_Stopped) { - return CELL_ECANCELED; + result = CELL_ECANCELED; + return false; } EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data; @@ -60,11 +59,11 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) if(!equeue->ports[i]->has_data && equeue->ports[i]->thread) { SPUThread* thr = (SPUThread*)equeue->ports[i]->thread; - if(thr->OutIntrMbox.GetCount()) + if(thr->SPU_OutIntr_Mbox.GetCount()) { u32 val; - thr->OutIntrMbox.Pop(val); - if(!thr->OutMbox.Pop(val)) val = 0; + thr->SPU_OutIntr_Mbox.Pop(val); + if(!thr->SPU_Out_MBox.Pop(val)) val = 0; equeue->ports[i]->data1 = val; equeue->ports[i]->data2 = 0; equeue->ports[i]->data3 = 0; @@ -73,29 +72,28 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout) } } - 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]; + auto dst = (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); + re(dst.source, equeue->ports[i]->name); + re(dst.data1, equeue->ports[i]->data1); + re(dst.data2, equeue->ports[i]->data2); + re(dst.data3, equeue->ports[i]->data3); equeue->ports[i]->has_data = false; - break; + + result = CELL_OK; + return false; } } - if(has_data) - break; + return true; + }; - Sleep(1); - } + GetCurrentPPUThread().WaitFor(queue_receive); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 55e88107ef..ae886b8474 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -199,9 +199,14 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, u32 nwrite_addr) ID id; if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; vfsStream& file = *(vfsStream*)id.m_data; + if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) + { + MemoryBlock& block = Memory.GetMemByAddr(buf_addr); + nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); + } - Memory.Write64NN(nwrite_addr, file.Write(Memory.GetMemFromAddr(buf_addr), nbytes)); - + int count = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + Memory.Write64NN(nwrite_addr, count); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp index c6d0e5e3fc..fb2461e7c0 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp @@ -133,9 +133,9 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height return CELL_OK; } -u32 cellGcmGetLabelAddress(u32 index) +u32 cellGcmGetLabelAddress(u8 index) { - cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index); + cellGcmSys.Error("cellGcmGetLabelAddress(index=%d)", index); return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp index 44981568ac..e7e2c41fe3 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp @@ -162,15 +162,51 @@ enum SYS_MEMORY_PAGE_SIZE_64K = 0x200, }; +struct MemoryContainerInfo +{ + u64 addr; + u32 size; + + MemoryContainerInfo(u64 addr, u32 size) + : addr(addr) + , size(size) + { + } +}; + int sys_memory_container_create(u32 cid_addr, u32 yield_size) { - sc_mem.Warning("TODO: sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size); + sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size); + + if(!Memory.IsGoodAddr(cid_addr, 4)) + { + return CELL_EFAULT; + } + + u64 addr = Memory.Alloc(yield_size, 1); + + if(!addr) + { + return CELL_ENOMEM; + } + + Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size))); return CELL_OK; } int sys_memory_container_destroy(u32 cid) { - sc_mem.Warning("TODO: sys_memory_container_destroy(cid=0x%x)", cid); + sc_mem.Warning("sys_memory_container_destroy(cid=0x%x)", cid); + + MemoryContainerInfo* ct; + + if(!sc_mem.CheckId(cid, ct)) + { + return CELL_ESRCH; + } + + Memory.Free(ct->addr); + Emu.GetIdManager().RemoveID(cid); return CELL_OK; } @@ -230,7 +266,7 @@ int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a { sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr); - Memory.Write32(alloc_addr, Memory.Alloc(size, 4)); + Memory.Write32(alloc_addr, Memory.Alloc(size, alignment)); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index ccdd66c444..3601a5205f 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -21,20 +21,17 @@ int sys_ppu_thread_exit(int errorcode) int sys_ppu_thread_yield() { sysPrxForUser.Log("sys_ppu_thread_yield()"); - enable_log = !enable_log; - dump_enable = !dump_enable; - - if(!enable_log) - { - Emu.Pause(); - } return CELL_OK; } int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr) { - sysPrxForUser.Error("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr); + sysPrxForUser.Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr); + PPCThread* thr = Emu.GetCPU().GetThread(thread_id); + if(!thr) return CELL_ESRCH; + + GetCurrentPPUThread().Wait(*thr); return CELL_OK; } @@ -125,7 +122,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 return CELL_EFAULT; } - PPCThread& new_thread = Emu.GetCPU().AddThread(true); + PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU); Memory.Write32(thread_id_addr, new_thread.GetId()); new_thread.SetEntry(entry); @@ -148,7 +145,7 @@ void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry) { Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT); - PPCThread& new_thread = Emu.GetCPU().AddThread(true); + PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU); new_thread.SetEntry(entry); ((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit(); new_thread.Run(); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp index 8f0a127121..69ca0d4561 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Process.cpp @@ -37,7 +37,6 @@ int SysCalls::lv2ProcessWaitForChild(PPUThread& CPU) int SysCalls::lv2ProcessGetStatus(PPUThread& CPU) { ConLog.Warning("lv2ProcessGetStatus"); - if(CPU.IsSPU()) return CELL_UNKNOWN_ERROR; //Memory.Write32(CPU.GPR[4], GetPPUThreadStatus(CPU)); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp index 84e4470f13..81d3925fc3 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_SPU_Thread.cpp @@ -150,7 +150,7 @@ int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_a ConLog.Write("a4 = 0x%x", a4); ConLog.SkipLn(); - PPCThread& new_thread = Emu.GetCPU().AddThread(false); + PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_SPU); new_thread.SetOffset(g_spu_offset); new_thread.SetEntry(entry - g_spu_offset); new_thread.SetName(name); @@ -172,7 +172,7 @@ int sys_spu_thread_set_argument(u32 id, u32 arg_addr) sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg_addr); PPCThread* thr = Emu.GetCPU().GetThread(id); - if(!thr || !thr->IsSPU()) + if(!thr || thr->GetType() == PPC_THREAD_PPU) { return CELL_ESRCH; } @@ -268,9 +268,11 @@ 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); //Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr)); - PPCThread& new_thread = Emu.GetCPU().AddThread(false); - Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId())); - Memory.Write32(0xe0043014, 0); + PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_RAW_SPU); + Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(PPC_THREAD_RAW_SPU, new_thread.GetId())); + new_thread.Run(); + new_thread.Exec(); + return CELL_OK; } @@ -286,10 +288,7 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) if(!Memory.InitSpuRawMem(max_raw_spu)) { - //30010780; - //e0043004 - offset - //e004300c - entry - return CELL_UNKNOWN_ERROR; + return CELL_ENOMEM; } //enable_log = true; @@ -306,7 +305,7 @@ int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) PPCThread* thr = Emu.GetCPU().GetThread(id); - if(!thr || !thr->IsSPU()) + if(!thr || thr->GetType() == PPC_THREAD_PPU) { return CELL_ESRCH; } @@ -324,7 +323,7 @@ int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type) PPCThread* thr = Emu.GetCPU().GetThread(id); - if(!thr || !thr->IsSPU()) + if(!thr || thr->GetType() == PPC_THREAD_PPU) { return CELL_ESRCH; } @@ -346,12 +345,12 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value) PPCThread* thr = Emu.GetCPU().GetThread(id); - if(!thr || !thr->IsSPU()) + if(!thr || !thr->GetType() == PPC_THREAD_PPU) { return CELL_ESRCH; } - if(!(*(SPUThread*)thr).InMbox.Push(value)) + if(!(*(SPUThread*)thr).SPU_In_MBox.Push(value)) { ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items."); return CELL_EBUSY; //? diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 9bc0229754..76ad909a66 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -112,7 +112,7 @@ void Emulator::Load() } LoadPoints(BreakPointsDBName); - PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64); + PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64 ? PPC_THREAD_PPU : PPC_THREAD_SPU); if(l.GetMachine() == MACHINE_SPU) { diff --git a/rpcs3/Gui/DisAsmFrame.cpp b/rpcs3/Gui/DisAsmFrame.cpp index 5feadd3490..4fc2a446d7 100644 --- a/rpcs3/Gui/DisAsmFrame.cpp +++ b/rpcs3/Gui/DisAsmFrame.cpp @@ -135,7 +135,7 @@ public: *done = false; - if(Emu.GetCPU().GetThreads()[0].IsSPU()) + if(Emu.GetCPU().GetThreads()[0].GetType() != PPC_THREAD_PPU) { SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode); decoder = new SPU_Decoder(dis_asm); @@ -341,7 +341,7 @@ void DisAsmFrame::Dump(wxCommandEvent& WXUNUSED(event)) PPC_DisAsm* disasm; PPC_Decoder* decoder; - if(Emu.GetCPU().GetThreads()[0].IsSPU()) + if(Emu.GetCPU().GetThreads()[0].GetType() != PPC_THREAD_PPU) { SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode); decoder = new SPU_Decoder(dis_asm); diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 9b5d9d029d..d137359a70 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -108,7 +108,7 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event) if(CPU) { - if(CPU->IsSPU()) + if(CPU->GetType() != PPC_THREAD_PPU) { SPU_DisAsm& dis_asm = *new SPU_DisAsm(*CPU, InterpreterMode); decoder = new SPU_Decoder(dis_asm); diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 7dc5e4b0a9..99951b8515 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -133,18 +133,18 @@ 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 < 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 @@ -158,6 +158,40 @@ bool ELF32Loader::LoadPhdrData(u64 offset) elf32_f.Seek(phdr_arr[i].p_offset); elf32_f.Read(&Memory[phdr_arr[i].p_vaddr + offset], phdr_arr[i].p_filesz); } + else if(phdr_arr[i].p_type == 0x00000004) + { + elf32_f.Seek(phdr_arr[i].p_offset); + Elf32_Note note; + note.Load(elf32_f); + + if(note.type != 1) + { + ConLog.Error("ELF32: Bad NOTE type (%d)", note.type); + break; + } + + if(note.namesz != sizeof(note.name)) + { + ConLog.Error("ELF32: Bad NOTE namesz (%d)", note.namesz); + break; + } + + if(note.descsz < sizeof(note.desc)) + { + ConLog.Error("ELF32: Bad NOTE descsz (%d)", note.descsz); + break; + } + + //if(note.desc.flags) + //{ + // ConLog.Error("ELF32: Bad NOTE flags (0x%x)", note.desc.flags); + // break; + //} + + ConLog.Warning("name = %s", note.name); + ConLog.Warning("ls_size = %d", note.desc.ls_size); + ConLog.Warning("stack_size = %d", note.desc.stack_size); + } #ifdef LOADER_DEBUG ConLog.SkipLn(); #endif @@ -177,6 +211,11 @@ bool ELF32Loader::LoadShdrData(u64 offset) shdr.Show(); ConLog.SkipLn(); #endif + if((shdr.sh_type == SHT_RELA) || (shdr.sh_type == SHT_REL)) + { + ConLog.Error("ELF32 ERROR: Relocation"); + continue; + } if((shdr.sh_flags & SHF_ALLOC) != SHF_ALLOC) continue; if(shdr.sh_addr < min_addr) @@ -188,21 +227,6 @@ bool ELF32Loader::LoadShdrData(u64 offset) { max_addr = shdr.sh_addr + shdr.sh_size; } - - //const s64 addr = shdr.sh_addr; - //const s64 size = shdr.sh_size; - //MemoryBlock* mem = nullptr; - - /* - switch(shdr.sh_type) - { - case SHT_NOBITS: - if(size == 0) continue; - memset(&Memory[addr + offset], 0, size); - case SHT_PROGBITS: - break; - } - */ } //TODO diff --git a/rpcs3/Loader/ELF32.h b/rpcs3/Loader/ELF32.h index dc13b78ef7..5657eb7d27 100644 --- a/rpcs3/Loader/ELF32.h +++ b/rpcs3/Loader/ELF32.h @@ -75,6 +75,40 @@ struct Elf32_Ehdr u32 GetEntry() const { return e_entry; } }; +struct Elf32_Desc +{ + u32 revision; + u32 ls_size; + u32 stack_size; + u32 flags; + + void Load(vfsStream& f) + { + revision = Read32(f); + ls_size = Read32(f); + stack_size = Read32(f); + flags = Read32(f); + } +}; + +struct Elf32_Note +{ + u32 namesz; + u32 descsz; + u32 type; + u8 name[8]; + Elf32_Desc desc; + + void Load(vfsStream& f) + { + namesz = Read32(f); + descsz = Read32(f); + type = Read32(f); + f.Read(name, 8); + desc.Load(f); + } +}; + struct Elf32_Shdr { u32 sh_name; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index ef6fe0dd13..c49eb4b384 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -413,16 +413,6 @@ 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]; @@ -445,6 +435,22 @@ bool ELF64Loader::LoadShdrData(u64 offset) if(size == 0 || !Memory.IsGoodAddr(offset + addr, size)) continue; + 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((shdr.sh_type == SHT_RELA) || (shdr.sh_type == SHT_REL)) + { + ConLog.Error("ELF64 ERROR: Relocation"); + continue; + } + switch(shdr.sh_type) { case SHT_NOBITS: @@ -457,6 +463,10 @@ bool ELF64Loader::LoadShdrData(u64 offset) elf64_f.Read(&Memory[addr], shdr.sh_size); */ break; + + case SHT_RELA: + ConLog.Warning("ELF64: RELA"); + break; } } diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 74ef6e59f7..271eebaa2a 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -201,6 +201,7 @@ + @@ -243,6 +244,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index b74d4d565f..b9bee6158c 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -256,6 +256,12 @@ Emu\SysCalls + + Emu\SysCalls\Modules + + + Emu\CPU +