mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
- Implemented RAW SPU.
- Implemented memory mapping.
This commit is contained in:
parent
027a31bd84
commit
559852a8fc
@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Array.h"
|
#include "Array.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
class ThreadExec;
|
class ThreadExec;
|
||||||
|
|
||||||
|
@ -273,6 +273,7 @@ void PPCThread::Exec()
|
|||||||
{
|
{
|
||||||
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
|
||||||
ThreadBase::Start();
|
ThreadBase::Start();
|
||||||
|
//std::thread thr(std::bind(std::mem_fn(&PPCThread::Task), this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCThread::ExecOnce()
|
void PPCThread::ExecOnce()
|
||||||
|
@ -6,6 +6,7 @@ enum PPCThreadType
|
|||||||
{
|
{
|
||||||
PPC_THREAD_PPU,
|
PPC_THREAD_PPU,
|
||||||
PPC_THREAD_SPU,
|
PPC_THREAD_SPU,
|
||||||
|
PPC_THREAD_RAW_SPU,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PPCThreadStatus
|
enum PPCThreadStatus
|
||||||
@ -77,6 +78,7 @@ public:
|
|||||||
{
|
{
|
||||||
case PPC_THREAD_PPU: return "PPU";
|
case PPC_THREAD_PPU: return "PPU";
|
||||||
case PPC_THREAD_SPU: return "SPU";
|
case PPC_THREAD_SPU: return "SPU";
|
||||||
|
case PPC_THREAD_RAW_SPU: return "RawSPU";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
@ -111,6 +113,15 @@ public:
|
|||||||
void Wait(const PPCThread& thr);
|
void Wait(const PPCThread& thr);
|
||||||
bool Sync();
|
bool Sync();
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void WaitFor(T func)
|
||||||
|
{
|
||||||
|
while(func(ThreadStatus()))
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ThreadStatus();
|
int ThreadStatus();
|
||||||
|
|
||||||
void NextPc();
|
void NextPc();
|
||||||
@ -125,7 +136,6 @@ public:
|
|||||||
static wxArrayString ErrorToString(const u32 error);
|
static wxArrayString ErrorToString(const u32 error);
|
||||||
wxArrayString ErrorToString() { return ErrorToString(m_error); }
|
wxArrayString ErrorToString() { return ErrorToString(m_error); }
|
||||||
|
|
||||||
bool IsSPU() const { return m_type == PPC_THREAD_SPU; }
|
|
||||||
bool IsOk() const { return m_error == 0; }
|
bool IsOk() const { return m_error == 0; }
|
||||||
bool IsRunned() const { return m_status == Runned; }
|
bool IsRunned() const { return m_status == Runned; }
|
||||||
bool IsPaused() const { return m_status == Paused; }
|
bool IsPaused() const { return m_status == Paused; }
|
||||||
@ -138,6 +148,7 @@ public:
|
|||||||
|
|
||||||
u32 GetError() const { return m_error; }
|
u32 GetError() const { return m_error; }
|
||||||
u32 GetId() const { return m_id; }
|
u32 GetId() const { return m_id; }
|
||||||
|
PPCThreadType GetType() const { return m_type; }
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
void Close();
|
void Close();
|
||||||
@ -160,6 +171,7 @@ protected:
|
|||||||
virtual void DoResume()=0;
|
virtual void DoResume()=0;
|
||||||
virtual void DoStop()=0;
|
virtual void DoStop()=0;
|
||||||
|
|
||||||
|
public:
|
||||||
virtual void Task();
|
virtual void Task();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "PPCThreadManager.h"
|
#include "PPCThreadManager.h"
|
||||||
#include "PPUThread.h"
|
#include "PPUThread.h"
|
||||||
#include "SPUThread.h"
|
#include "SPUThread.h"
|
||||||
|
#include "RawSPUThread.h"
|
||||||
|
|
||||||
PPCThreadManager::PPCThreadManager()
|
PPCThreadManager::PPCThreadManager()
|
||||||
{
|
{
|
||||||
@ -17,13 +18,19 @@ void PPCThreadManager::Close()
|
|||||||
while(m_threads.GetCount()) RemoveThread(m_threads[0].GetId());
|
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();
|
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(
|
new_thread->SetId(Emu.GetIdManager().GetNewID(wxString::Format("%s Thread", name), new_thread));
|
||||||
wxString::Format("%s Thread", isPPU ? "PPU" : "SPU"), new_thread, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
m_threads.Add(new_thread);
|
m_threads.Add(new_thread);
|
||||||
wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread);
|
wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread);
|
||||||
@ -54,14 +61,14 @@ void PPCThreadManager::RemoveThread(const u32 id)
|
|||||||
Emu.CheckStatus();
|
Emu.CheckStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PPCThreadManager::GetThreadNumById(bool isPPU, u32 id)
|
s32 PPCThreadManager::GetThreadNumById(PPCThreadType type, u32 id)
|
||||||
{
|
{
|
||||||
s32 num = 0;
|
s32 num = 0;
|
||||||
|
|
||||||
for(u32 i=0; i<m_threads.GetCount(); ++i)
|
for(u32 i=0; i<m_threads.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
if(m_threads[i].GetId() == id) return num;
|
if(m_threads[i].GetId() == id) return num;
|
||||||
if(m_threads[i].IsSPU() == !isPPU) num++;
|
if(m_threads[i].GetType() == type) num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -14,11 +14,11 @@ public:
|
|||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
PPCThread& AddThread(bool isPPU);
|
PPCThread& AddThread(PPCThreadType type);
|
||||||
void RemoveThread(const u32 id);
|
void RemoveThread(const u32 id);
|
||||||
|
|
||||||
ArrayF<PPCThread>& GetThreads() { return m_threads; }
|
ArrayF<PPCThread>& GetThreads() { return m_threads; }
|
||||||
s32 GetThreadNumById(bool isPPU, u32 id);
|
s32 GetThreadNumById(PPCThreadType type, u32 id);
|
||||||
PPCThread* GetThread(u32 id);
|
PPCThread* GetThread(u32 id);
|
||||||
//IdManager& GetIDs() {return m_threads_id;}
|
//IdManager& GetIDs() {return m_threads_id;}
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ namespace PPU_instr
|
|||||||
bind_instr(g3f_0_list, MTFSB1, CRBD, RC);
|
bind_instr(g3f_0_list, MTFSB1, CRBD, RC);
|
||||||
bind_instr(g3f_0_list, MCRFS, CRFD, CRFS);
|
bind_instr(g3f_0_list, MCRFS, CRFD, CRFS);
|
||||||
bind_instr(g3f_0_list, MTFSB0, CRBD, RC);
|
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, MFFS, FRD, RC);
|
||||||
bind_instr(g3f_0_list, MTFSF, FM, FRB, RC);
|
bind_instr(g3f_0_list, MTFSF, FM, FRB, RC);
|
||||||
|
|
||||||
|
@ -2080,48 +2080,48 @@ private:
|
|||||||
CPU.SetBranch(branchTarget(0, CPU.LR));
|
CPU.SetBranch(branchTarget(0, CPU.LR));
|
||||||
if(lk) CPU.LR = CPU.PC + 4;
|
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));
|
const u8 v = 1 ^ (CPU.IsCR(crba) | CPU.IsCR(crbb));
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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));
|
const u8 v = CPU.IsCR(crba) & (1 ^ CPU.IsCR(crbb));
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
CPU.SetCRBit2(crbd, v & 0x1);
|
||||||
}
|
}
|
||||||
void ISYNC()
|
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);
|
const u8 v = CPU.IsCR(crba) ^ CPU.IsCR(crbb);
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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));
|
const u8 v = 1 ^ (CPU.IsCR(crba) & CPU.IsCR(crbb));
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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);
|
const u8 v = CPU.IsCR(crba) & CPU.IsCR(crbb);
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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));
|
const u8 v = 1 ^ (CPU.IsCR(crba) ^ CPU.IsCR(crbb));
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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));
|
const u8 v = CPU.IsCR(crba) | (1 ^ CPU.IsCR(crbb));
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
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);
|
const u8 v = CPU.IsCR(crba) | CPU.IsCR(crbb);
|
||||||
CPU.SetCRBit2(bt, v & 0x1);
|
CPU.SetCRBit2(crbd, v & 0x1);
|
||||||
}
|
}
|
||||||
void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk)
|
void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk)
|
||||||
{
|
{
|
||||||
@ -2166,7 +2166,7 @@ private:
|
|||||||
void ANDI_(u32 ra, u32 rs, u32 uimm16)
|
void ANDI_(u32 ra, u32 rs, u32 uimm16)
|
||||||
{
|
{
|
||||||
CPU.GPR[ra] = CPU.GPR[rs] & uimm16;
|
CPU.GPR[ra] = CPU.GPR[rs] & uimm16;
|
||||||
CPU.UpdateCR0<s32>(CPU.GPR[ra]);
|
CPU.UpdateCR0<s16>(CPU.GPR[ra]);
|
||||||
}
|
}
|
||||||
void ANDIS_(u32 ra, u32 rs, u32 uimm16)
|
void ANDIS_(u32 ra, u32 rs, u32 uimm16)
|
||||||
{
|
{
|
||||||
@ -2934,7 +2934,7 @@ private:
|
|||||||
}
|
}
|
||||||
void STFSX(u32 frs, u32 ra, u32 rb)
|
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)
|
void STVRX(u32 vs, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -3147,12 +3147,12 @@ private:
|
|||||||
}
|
}
|
||||||
void STFS(u32 frs, u32 ra, s32 d)
|
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)
|
void STFSU(u32 frs, u32 ra, s32 d)
|
||||||
{
|
{
|
||||||
const u64 addr = CPU.GPR[ra] + 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;
|
CPU.GPR[ra] = addr;
|
||||||
}
|
}
|
||||||
void STFD(u32 frs, u32 ra, s32 d)
|
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]);
|
if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FSUBS(u32 frd, u32 fra, u32 frb, bool rc)
|
void FSUBS(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] - CPU.FPR[frb]);
|
CPU.FPR[frd] = static_cast<float>(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]);
|
if(rc) UNK("fsubs.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FADDS(u32 frd, u32 fra, u32 frb, bool rc)
|
void FADDS(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] + CPU.FPR[frb]);
|
CPU.FPR[frd] = static_cast<float>(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]);
|
if(rc) UNK("fadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FSQRTS(u32 frd, u32 frb, bool rc)
|
void FSQRTS(u32 frd, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(sqrt(CPU.FPR[frb]));
|
CPU.FPR[frd] = static_cast<float>(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]);
|
if(rc) UNK("fsqrts.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FRES(u32 frd, u32 frb, bool rc)
|
void FRES(u32 frd, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
|
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
|
||||||
CPU.FPR[frd] = static_cast<float>(1.0f/CPU.FPR[frb]);
|
CPU.FPR[frd] = static_cast<float>(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.FI = 0;
|
||||||
CPU.FPSCR.FR = 0;
|
CPU.FPSCR.FR = 0;
|
||||||
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
@ -3248,31 +3248,31 @@ private:
|
|||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc]);
|
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc]);
|
||||||
CPU.FPSCR.FI = 0;
|
CPU.FPSCR.FI = 0;
|
||||||
CPU.FPSCR.FR = 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]);
|
if(rc) UNK("fmuls.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]);
|
CPU.FPR[frd] = static_cast<float>(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]);
|
if(rc) UNK("fmadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]);
|
CPU.FPR[frd] = static_cast<float>(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]);
|
if(rc) UNK("fmsubs.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(-(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]));
|
CPU.FPR[frd] = static_cast<float>(-(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]);
|
if(rc) UNK("fnmsubs.");////CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = static_cast<float>(-(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]));
|
CPU.FPR[frd] = static_cast<float>(-(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]);
|
if(rc) UNK("fnmadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void STD(u32 rs, u32 ra, s32 d)
|
void STD(u32 rs, u32 ra, s32 d)
|
||||||
@ -3290,6 +3290,7 @@ private:
|
|||||||
{
|
{
|
||||||
u64 mask = (1ULL << crbd);
|
u64 mask = (1ULL << crbd);
|
||||||
CPU.FPSCR.FPSCR |= mask;
|
CPU.FPSCR.FPSCR |= mask;
|
||||||
|
|
||||||
if(rc) UNIMPLEMENTED();
|
if(rc) UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
void MCRFS(u32 crbd, u32 crbs)
|
void MCRFS(u32 crbd, u32 crbs)
|
||||||
@ -3302,11 +3303,12 @@ private:
|
|||||||
{
|
{
|
||||||
u64 mask = (1ULL << crbd);
|
u64 mask = (1ULL << crbd);
|
||||||
CPU.FPSCR.FPSCR &= ~mask;
|
CPU.FPSCR.FPSCR &= ~mask;
|
||||||
|
|
||||||
if(rc) UNIMPLEMENTED();
|
if(rc) UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
void MTFSFI(u32 crfd, u32 i, bool rc)
|
void MTFSFI(u32 crfd, u32 i, bool rc)
|
||||||
{
|
{
|
||||||
u64 mask = (1ULL << crfd);
|
u64 mask = (0x1ULL << crfd);
|
||||||
|
|
||||||
if(i)
|
if(i)
|
||||||
{
|
{
|
||||||
@ -3316,6 +3318,7 @@ private:
|
|||||||
{
|
{
|
||||||
CPU.FPSCR.FPSCR &= ~mask;
|
CPU.FPSCR.FPSCR &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rc) UNIMPLEMENTED();
|
if(rc) UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
void MFFS(u32 frd, bool rc)
|
void MFFS(u32 frd, bool rc)
|
||||||
@ -3478,25 +3481,25 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU.FPR[frd] = CPU.FPR[fra] / CPU.FPR[frb];
|
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]);
|
if(rc) UNK("fdiv.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FSUB(u32 frd, u32 fra, u32 frb, bool rc)
|
void FSUB(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = CPU.FPR[fra] - CPU.FPR[frb];
|
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]);
|
if(rc) UNK("fsub.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FADD(u32 frd, u32 fra, u32 frb, bool rc)
|
void FADD(u32 frd, u32 fra, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = CPU.FPR[fra] + CPU.FPR[frb];
|
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]);
|
if(rc) UNK("fadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FSQRT(u32 frd, u32 frb, bool rc)
|
void FSQRT(u32 frd, u32 frb, bool rc)
|
||||||
{
|
{
|
||||||
CPU.FPR[frd] = sqrt(CPU.FPR[frb]);
|
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]);
|
if(rc) UNK("fsqrt.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
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)
|
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.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]);
|
if(rc) UNK("fmadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
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.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]);
|
if(rc) UNK("fnmsub.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
|
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.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]);
|
if(rc) UNK("fnmadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
|
||||||
}
|
}
|
||||||
void FCMPO(u32 crfd, u32 fra, u32 frb)
|
void FCMPO(u32 crfd, u32 fra, u32 frb)
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
#include "Emu/Cell/PPUDecoder.h"
|
#include "Emu/Cell/PPUDecoder.h"
|
||||||
#include "Emu/Cell/PPUInterpreter.h"
|
#include "Emu/Cell/PPUInterpreter.h"
|
||||||
#include "Emu/Cell/PPUDisAsm.h"
|
#include "Emu/Cell/PPUDisAsm.h"
|
||||||
|
#include <thread>
|
||||||
extern gcmInfo gcm_info;
|
extern gcmInfo gcm_info;
|
||||||
|
|
||||||
PPUThread& GetCurrentPPUThread()
|
PPUThread& GetCurrentPPUThread()
|
||||||
{
|
{
|
||||||
PPCThread* thread = GetCurrentPPCThread();
|
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;
|
return *(PPUThread*)thread;
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ void PPUThread::InitRegs()
|
|||||||
|
|
||||||
SetPc(pc);
|
SetPc(pc);
|
||||||
|
|
||||||
const s32 thread_num = Emu.GetCPU().GetThreadNumById(!IsSPU(), GetId());
|
const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId());
|
||||||
|
|
||||||
if(thread_num < 0)
|
if(thread_num < 0)
|
||||||
{
|
{
|
||||||
|
151
rpcs3/Emu/Cell/RawSPUThread.cpp
Normal file
151
rpcs3/Emu/Cell/RawSPUThread.cpp
Normal file
@ -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<u64>& bp = Emu.GetBreakPoints();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for(uint i=0; i<bp.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(bp[i] == m_offset + PC)
|
||||||
|
{
|
||||||
|
Emu.Pause();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_last_paused = false;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
int status = ThreadStatus();
|
||||||
|
|
||||||
|
if(status == PPCThread_Stopped || status == PPCThread_Break)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(status == PPCThread_Sleeping)
|
||||||
|
{
|
||||||
|
Sleep(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(MFC_CMDStatus.GetValue() == 0x40)
|
||||||
|
{
|
||||||
|
MFC_CMDStatus.SetValue(0);
|
||||||
|
u32 lsa = MFC_LSA.GetValue();
|
||||||
|
u64 ea = (u64)MFC_EAL.GetValue() | ((u64)MFC_EAH.GetValue() << 32);
|
||||||
|
u32 size_tag = MFC_Size_Tag.GetValue();
|
||||||
|
u16 tag = (u16)size_tag;
|
||||||
|
u16 size = size_tag >> 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; i<bp.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(bp[i] == m_offset + PC)
|
||||||
|
{
|
||||||
|
Emu.Pause();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const wxString& e)
|
||||||
|
{
|
||||||
|
ConLog.Error("Exception: %s", e);
|
||||||
|
}
|
||||||
|
catch(const char* e)
|
||||||
|
{
|
||||||
|
ConLog.Error("Exception: %s", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConLog.Write("%s leave", PPCThread::GetFName());
|
||||||
|
}
|
66
rpcs3/Emu/Cell/RawSPUThread.h
Normal file
66
rpcs3/Emu/Cell/RawSPUThread.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "SPUThread.h"
|
||||||
|
#include "Emu/event.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MFC_LSA_offs = 0x3004,
|
||||||
|
MFC_EAH_offs = 0x3008,
|
||||||
|
MFC_EAL_offs = 0x300C,
|
||||||
|
MFC_Size_Tag_offs = 0x3010,
|
||||||
|
MFC_Class_CMD_offs = 0x3014,
|
||||||
|
MFC_CMDStatus_offs = 0x3014,
|
||||||
|
MFC_QStatus_offs = 0x3104,
|
||||||
|
Prxy_QueryType_offs = 0x3204,
|
||||||
|
Prxy_QueryMask_offs = 0x321C,
|
||||||
|
Prxy_TagStatus_offs = 0x322C,
|
||||||
|
SPU_Out_MBox_offs = 0x4004,
|
||||||
|
SPU_In_MBox_offs = 0x400C,
|
||||||
|
SPU_MBox_Status_offs = 0x4014,
|
||||||
|
SPU_RunCntl_offs = 0x401C,
|
||||||
|
SPU_Status_offs = 0x4024,
|
||||||
|
SPU_NPC_offs = 0x4034,
|
||||||
|
SPU_RdSigNotify1_offs = 0x1400C,
|
||||||
|
SPU_RdSigNotify2_offs = 0x1C00C,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum : u64
|
||||||
|
{
|
||||||
|
RAW_SPU_OFFSET = 0x0000000000100000,
|
||||||
|
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
|
||||||
|
RAW_SPU_LS_OFFSET = 0x0000000000000000,
|
||||||
|
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
|
||||||
|
};
|
||||||
|
|
||||||
|
__forceinline static u32 GetRawSPURegAddrByNum(int num, int offset)
|
||||||
|
{
|
||||||
|
return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
__forceinline static u32 GetRawSPURegAddrById(int id, int offset)
|
||||||
|
{
|
||||||
|
return GetRawSPURegAddrByNum(Emu.GetCPU().GetThreadNumById(PPC_THREAD_RAW_SPU, id), offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RawSPUThread : public SPUThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RawSPUThread(PPCThreadType type = PPC_THREAD_RAW_SPU);
|
||||||
|
~RawSPUThread();
|
||||||
|
|
||||||
|
virtual wxString RegsToString()
|
||||||
|
{
|
||||||
|
wxString ret = PPCThread::RegsToString();
|
||||||
|
for(uint i=0; i<128; ++i) ret += wxString::Format("GPR[%d] = 0x%s\n", i, GPR[i].ToString());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void InitRegs();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void Task();
|
||||||
|
};
|
||||||
|
|
||||||
|
SPUThread& GetCurrentSPUThread();
|
@ -27,7 +27,11 @@ private:
|
|||||||
//0 - 10
|
//0 - 10
|
||||||
void STOP(u32 code)
|
void STOP(u32 code)
|
||||||
{
|
{
|
||||||
CPU.Pause();
|
if(code & 0x2000)
|
||||||
|
{
|
||||||
|
CPU.SetExitStatus(code & 0xfff);
|
||||||
|
CPU.Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void LNOP()
|
void LNOP()
|
||||||
{
|
{
|
||||||
|
@ -8,12 +8,12 @@ SPUThread& GetCurrentSPUThread()
|
|||||||
{
|
{
|
||||||
PPCThread* thread = GetCurrentPPCThread();
|
PPCThread* thread = GetCurrentPPCThread();
|
||||||
|
|
||||||
if(!thread || !thread->IsSPU()) throw wxString("GetCurrentSPUThread: bad thread");
|
if(!thread || thread->GetType() == PPC_THREAD_PPU) throw wxString("GetCurrentSPUThread: bad thread");
|
||||||
|
|
||||||
return *(SPUThread*)thread;
|
return *(SPUThread*)thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPUThread::SPUThread() : PPCThread(PPC_THREAD_SPU)
|
SPUThread::SPUThread(PPCThreadType type) : PPCThread(type)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,22 @@ enum MFCchannels
|
|||||||
MFC_RdAtomicStat = 27, //Read completion status of last completed immediate MFC atomic update command
|
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
|
union SPU_GPR_hdr
|
||||||
{
|
{
|
||||||
u128 _u128;
|
u128 _u128;
|
||||||
@ -111,10 +127,91 @@ class SPUThread : public PPCThread
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
||||||
SizedStack<u32, 1> OutMbox;
|
|
||||||
SizedStack<u32, 1> OutIntrMbox;
|
|
||||||
SizedStack<u32, 4> InMbox;
|
|
||||||
|
|
||||||
|
template<size_t _max_count>
|
||||||
|
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<u32, 1> SPU_OutIntr_Mbox;
|
||||||
u32 LSA;
|
u32 LSA;
|
||||||
|
|
||||||
union
|
union
|
||||||
@ -128,13 +225,13 @@ public:
|
|||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_WrOutMbox:
|
case SPU_WrOutMbox:
|
||||||
return OutMbox.GetFreeCount();
|
return SPU_Out_MBox.GetFreeCount();
|
||||||
|
|
||||||
case SPU_RdInMbox:
|
case SPU_RdInMbox:
|
||||||
return InMbox.GetCount();
|
return SPU_In_MBox.GetCount();
|
||||||
|
|
||||||
case SPU_WrOutIntrMbox:
|
case SPU_WrOutIntrMbox:
|
||||||
return 0;//return OutIntrMbox.GetFreeCount();
|
return 0;//return SPU_OutIntr_Mbox.GetFreeCount();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
|
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
|
||||||
@ -152,7 +249,7 @@ public:
|
|||||||
{
|
{
|
||||||
case SPU_WrOutIntrMbox:
|
case SPU_WrOutIntrMbox:
|
||||||
ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v);
|
ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v);
|
||||||
if(!OutIntrMbox.Push(v))
|
if(!SPU_OutIntr_Mbox.Push(v))
|
||||||
{
|
{
|
||||||
ConLog.Warning("Not enought free rooms.");
|
ConLog.Warning("Not enought free rooms.");
|
||||||
}
|
}
|
||||||
@ -160,10 +257,11 @@ public:
|
|||||||
|
|
||||||
case SPU_WrOutMbox:
|
case SPU_WrOutMbox:
|
||||||
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
|
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
|
||||||
if(!OutMbox.Push(v))
|
if(!SPU_Out_MBox.Push(v))
|
||||||
{
|
{
|
||||||
ConLog.Warning("Not enought free rooms.");
|
ConLog.Warning("Not enought free rooms.");
|
||||||
}
|
}
|
||||||
|
SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff) | 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -180,7 +278,8 @@ public:
|
|||||||
switch(ch)
|
switch(ch)
|
||||||
{
|
{
|
||||||
case SPU_RdInMbox:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -203,7 +302,7 @@ public:
|
|||||||
void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
|
void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SPUThread();
|
SPUThread(PPCThreadType type = PPC_THREAD_SPU);
|
||||||
~SPUThread();
|
~SPUThread();
|
||||||
|
|
||||||
virtual wxString RegsToString()
|
virtual wxString RegsToString()
|
||||||
@ -224,7 +323,7 @@ protected:
|
|||||||
virtual void DoResume();
|
virtual void DoResume();
|
||||||
virtual void DoStop();
|
virtual void DoStop();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
virtual void DoCode(const s32 code);
|
virtual void DoCode(const s32 code);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "GLGSRender.h"
|
#include "GLGSRender.h"
|
||||||
|
#include "Emu/Cell/PPCInstrTable.h"
|
||||||
#define CMD_DEBUG 0
|
#define CMD_DEBUG 1
|
||||||
#define DUMP_VERTEX_DATA 1
|
#define DUMP_VERTEX_DATA 1
|
||||||
|
|
||||||
#if CMD_DEBUG
|
#if CMD_DEBUG
|
||||||
@ -132,7 +132,9 @@ void GLRSXThread::Task()
|
|||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(p.m_cs_main);
|
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);
|
SemaphorePostAndWait(p.m_sem_flush);
|
||||||
|
|
||||||
@ -170,23 +172,25 @@ void GLRSXThread::Task()
|
|||||||
continue;
|
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 cmd = Memory.Read32(p.m_ioAddress + get);
|
||||||
const u32 count = (cmd >> 18) & 0x7ff;
|
const u32 count = (cmd >> 18) & 0x7ff;
|
||||||
|
//if(cmd == 0) continue;
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
|
||||||
{
|
{
|
||||||
u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
|
u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
|
||||||
p.m_ctrl->get = re32(addr);
|
addr &= ~0x1000;
|
||||||
ConLog.Warning("rsx jump(0x%x)", addr);
|
//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;
|
continue;
|
||||||
}
|
}
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
|
||||||
{
|
{
|
||||||
call_stack.Push(get + 4);
|
call_stack.Push(get + 4);
|
||||||
u32 addr = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
|
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);
|
p.m_ctrl->get = re32(addr);
|
||||||
ConLog.Warning("rsx call(0x%x)", addr);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(cmd & CELL_GCM_METHOD_FLAG_RETURN)
|
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);
|
//Enable(args[0] ? true : false, GL_DEPTH_CLAMP);
|
||||||
break;
|
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:
|
case NV4097_SET_VIEWPORT_VERTICAL:
|
||||||
{
|
{
|
||||||
m_set_viewport_vertical = true;
|
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<count; ++i) log += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
|
for(u32 i=0; i<count; ++i) log += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
|
||||||
log += ")";
|
log += ")";
|
||||||
ConLog.Error("TODO: " + log);
|
ConLog.Error("TODO: " + log);
|
||||||
Emu.Pause();
|
//Emu.Pause();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -43,3 +43,4 @@ OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f);
|
|||||||
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
|
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
|
||||||
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
|
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
|
||||||
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);
|
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);
|
||||||
|
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT);
|
@ -88,7 +88,7 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
|
|||||||
|
|
||||||
bool MemoryBlock::IsMyAddress(const u64 addr)
|
bool MemoryBlock::IsMyAddress(const u64 addr)
|
||||||
{
|
{
|
||||||
return addr >= GetStartAddr() && addr < GetEndAddr();
|
return mem && addr >= GetStartAddr() && addr < GetEndAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const
|
__forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const
|
||||||
@ -466,24 +466,52 @@ u8* DynamicMemoryBlock::GetMem(u64 addr) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEBUG_RAWSPU_MEM 1
|
||||||
//MemoryBase
|
//MemoryBase
|
||||||
void MemoryBase::Write8(u64 addr, const u8 data)
|
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);
|
GetMemByAddr(addr).Write8(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBase::Write16(u64 addr, const u16 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);
|
GetMemByAddr(addr).Write16(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBase::Write32(u64 addr, const u32 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);
|
GetMemByAddr(addr).Write32(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryBase::Write64(u64 addr, const u64 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);
|
GetMemByAddr(addr).Write64(addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,8 +557,13 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data)
|
|||||||
|
|
||||||
u8 MemoryBase::Read8(u64 addr)
|
u8 MemoryBase::Read8(u64 addr)
|
||||||
{
|
{
|
||||||
if(enable_log && addr >= 0xd0010a84)
|
#if DEBUG_RAWSPU_MEM
|
||||||
ConLog.Warning("Read8 from block: [%08llx]", addr);
|
if(SpuRawMem.IsMyAddress(addr))
|
||||||
|
{
|
||||||
|
ConLog.Warning("Read8(addr=0x%llx)", addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemoryBlock& mem = GetMemByAddr(addr);
|
MemoryBlock& mem = GetMemByAddr(addr);
|
||||||
if(mem.IsNULL())
|
if(mem.IsNULL())
|
||||||
{
|
{
|
||||||
@ -542,8 +575,13 @@ u8 MemoryBase::Read8(u64 addr)
|
|||||||
|
|
||||||
u16 MemoryBase::Read16(u64 addr)
|
u16 MemoryBase::Read16(u64 addr)
|
||||||
{
|
{
|
||||||
if(enable_log && addr >= 0xd0010a84)
|
#if DEBUG_RAWSPU_MEM
|
||||||
ConLog.Warning("Read16 from block: [%08llx]", addr);
|
if(SpuRawMem.IsMyAddress(addr))
|
||||||
|
{
|
||||||
|
ConLog.Warning("Read16(addr=0x%llx)", addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemoryBlock& mem = GetMemByAddr(addr);
|
MemoryBlock& mem = GetMemByAddr(addr);
|
||||||
if(mem.IsNULL())
|
if(mem.IsNULL())
|
||||||
{
|
{
|
||||||
@ -555,8 +593,13 @@ u16 MemoryBase::Read16(u64 addr)
|
|||||||
|
|
||||||
u32 MemoryBase::Read32(u64 addr)
|
u32 MemoryBase::Read32(u64 addr)
|
||||||
{
|
{
|
||||||
if(enable_log && addr >= 0xd0010a84)
|
#if DEBUG_RAWSPU_MEM
|
||||||
ConLog.Warning("Read32 from block: [%08llx]", addr);
|
if(SpuRawMem.IsMyAddress(addr) && !(GetCurrentPPCThread() && GetCurrentPPCThread()->GetType() == PPC_THREAD_RAW_SPU))
|
||||||
|
{
|
||||||
|
ConLog.Warning("Read32(addr=0x%llx)", addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemoryBlock& mem = GetMemByAddr(addr);
|
MemoryBlock& mem = GetMemByAddr(addr);
|
||||||
if(mem.IsNULL())
|
if(mem.IsNULL())
|
||||||
{
|
{
|
||||||
@ -568,8 +611,13 @@ u32 MemoryBase::Read32(u64 addr)
|
|||||||
|
|
||||||
u64 MemoryBase::Read64(u64 addr)
|
u64 MemoryBase::Read64(u64 addr)
|
||||||
{
|
{
|
||||||
if(enable_log && addr >= 0xd0010a84)
|
#if DEBUG_RAWSPU_MEM
|
||||||
ConLog.Warning("Read64 from block: [%08llx]", addr);
|
if(SpuRawMem.IsMyAddress(addr))
|
||||||
|
{
|
||||||
|
ConLog.Warning("Read64(addr=0x%llx)", addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
MemoryBlock& mem = GetMemByAddr(addr);
|
MemoryBlock& mem = GetMemByAddr(addr);
|
||||||
if(mem.IsNULL())
|
if(mem.IsNULL())
|
||||||
{
|
{
|
||||||
|
@ -63,16 +63,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> static __forceinline T Reverse(T val);
|
template<int size> static __forceinline u64 ReverseData(u64 val);
|
||||||
template<> static __forceinline u8 Reverse(u8 val) { return val; };
|
template<> static __forceinline u64 ReverseData<1>(u64 val) { return val; }
|
||||||
template<> static __forceinline u16 Reverse(u16 val) { return Reverse16(val); };
|
template<> static __forceinline u64 ReverseData<2>(u64 val) { return Reverse16(val); }
|
||||||
template<> static __forceinline u32 Reverse(u32 val) { return Reverse32(val); };
|
template<> static __forceinline u64 ReverseData<4>(u64 val) { return Reverse32(val); }
|
||||||
template<> static __forceinline u64 Reverse(u64 val) { return Reverse64(val); };
|
template<> static __forceinline u64 ReverseData<8>(u64 val) { return Reverse64(val); }
|
||||||
|
|
||||||
template<> static __forceinline s8 Reverse(s8 val) { return val; };
|
template<typename T> static __forceinline T Reverse(T val)
|
||||||
template<> static __forceinline s16 Reverse(s16 val) { return Reverse16(val); };
|
{
|
||||||
template<> static __forceinline s32 Reverse(s32 val) { return Reverse32(val); };
|
return (T)ReverseData<sizeof(T)>(val);
|
||||||
template<> static __forceinline s64 Reverse(s64 val) { return Reverse64(val); };
|
};
|
||||||
|
|
||||||
MemoryBlock& GetMemByNum(const u8 num)
|
MemoryBlock& GetMemByNum(const u8 num)
|
||||||
{
|
{
|
||||||
@ -328,6 +328,31 @@ public:
|
|||||||
return PRXMem.Free(addr);
|
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; i<MemoryBlocks.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
if(MemoryBlocks[i].IsMirror())
|
||||||
|
{
|
||||||
|
if(MemoryBlocks[i].GetStartAddr() == addr)
|
||||||
|
{
|
||||||
|
MemoryBlocks.RemoveFAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u8* operator + (const u64 vaddr)
|
u8* operator + (const u64 vaddr)
|
||||||
{
|
{
|
||||||
u8* ret = GetMemFromAddr(vaddr);
|
u8* ret = GetMemFromAddr(vaddr);
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
virtual void Delete();
|
virtual void Delete();
|
||||||
|
|
||||||
virtual bool IsNULL() { return false; }
|
virtual bool IsNULL() { return false; }
|
||||||
|
virtual bool IsMirror() { return false; }
|
||||||
|
|
||||||
u64 FixAddr(const u64 addr) const;
|
u64 FixAddr(const u64 addr) const;
|
||||||
|
|
||||||
@ -88,6 +89,31 @@ public:
|
|||||||
virtual u8* GetMem(u64 addr) const { return mem + addr; }
|
virtual u8* GetMem(u64 addr) const { return mem + addr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MemoryMirror : public MemoryBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool IsMirror() { return true; }
|
||||||
|
|
||||||
|
virtual MemoryBlock* SetRange(const u64 start, const u32 size)
|
||||||
|
{
|
||||||
|
range_start = start;
|
||||||
|
range_size = size;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMemory(u8* memory)
|
||||||
|
{
|
||||||
|
mem = memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryBlock* SetRange(u8* memory, const u64 start, const u32 size)
|
||||||
|
{
|
||||||
|
SetMemory(memory);
|
||||||
|
return SetRange(start, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class NullMemoryBlock : public MemoryBlock
|
class NullMemoryBlock : public MemoryBlock
|
||||||
{
|
{
|
||||||
virtual bool IsNULL() { return true; }
|
virtual bool IsNULL() { return true; }
|
||||||
|
@ -25,24 +25,22 @@ void Callback::Branch()
|
|||||||
{
|
{
|
||||||
m_has_data = false;
|
m_has_data = false;
|
||||||
|
|
||||||
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
|
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU);
|
||||||
|
|
||||||
new_thread.SetPc(m_addr);
|
new_thread.SetPc(m_addr);
|
||||||
new_thread.SetPrio(0x1001);
|
new_thread.SetPrio(1001);
|
||||||
new_thread.stack_size = 0x10000;
|
new_thread.stack_size = 0x10000;
|
||||||
new_thread.SetName("Callback");
|
new_thread.SetName("Callback");
|
||||||
|
|
||||||
|
new_thread.SetArg(0, a1);
|
||||||
|
new_thread.SetArg(1, a2);
|
||||||
|
new_thread.SetArg(2, a3);
|
||||||
|
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
|
||||||
new_thread.Run();
|
new_thread.Run();
|
||||||
|
|
||||||
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
|
|
||||||
((PPUThread&)new_thread).GPR[3] = a1;
|
|
||||||
((PPUThread&)new_thread).GPR[4] = a2;
|
|
||||||
((PPUThread&)new_thread).GPR[5] = a3;
|
|
||||||
new_thread.Exec();
|
new_thread.Exec();
|
||||||
|
|
||||||
while(new_thread.IsAlive()) Sleep(1);
|
GetCurrentPPCThread()->Wait(new_thread);
|
||||||
Emu.GetCPU().RemoveThread(new_thread.GetId());
|
|
||||||
|
|
||||||
ConLog.Write("Callback EXIT!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
|
Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)
|
||||||
|
@ -2,10 +2,131 @@
|
|||||||
#include "SysCalls.h"
|
#include "SysCalls.h"
|
||||||
#include "SC_FUNC.h"
|
#include "SC_FUNC.h"
|
||||||
|
|
||||||
Module* g_modules[50];
|
Module* g_modules[3][0xff] = {0};
|
||||||
uint g_modules_count = 0;
|
uint g_max_module_id = 0;
|
||||||
|
uint g_module_2_count = 0;
|
||||||
ArrayF<ModuleFunc> g_modules_funcs_list;
|
ArrayF<ModuleFunc> 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)
|
bool IsLoadedFunc(u32 id)
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||||
@ -51,9 +172,22 @@ bool UnloadFunc(u32 id)
|
|||||||
|
|
||||||
void UnloadModules()
|
void UnloadModules()
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<g_modules_count; ++i)
|
for(u32 i=0; i<g_max_module_id; ++i)
|
||||||
{
|
{
|
||||||
g_modules[i]->SetLoaded(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();
|
g_modules_funcs_list.Clear();
|
||||||
@ -61,11 +195,21 @@ void UnloadModules()
|
|||||||
|
|
||||||
Module* GetModuleByName(const wxString& name)
|
Module* GetModuleByName(const wxString& name)
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<g_modules_count; ++i)
|
for(u32 i=0; i<g_max_module_id; ++i)
|
||||||
{
|
{
|
||||||
if(g_modules[i]->GetName().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)
|
Module* GetModuleById(u16 id)
|
||||||
{
|
{
|
||||||
for(u32 i=0; i<g_modules_count; ++i)
|
for(u32 i=0; i<g_max_module_id; ++i)
|
||||||
{
|
{
|
||||||
if(g_modules[i]->GetID() == 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;
|
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_is_loaded(false)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
, m_id(id)
|
, m_id(id)
|
||||||
{
|
{
|
||||||
g_modules[g_modules_count++] = this;
|
SetModule(m_id, this, false);
|
||||||
init();
|
}
|
||||||
|
|
||||||
|
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()
|
void Module::Load()
|
||||||
@ -154,6 +366,11 @@ wxString Module::GetName() const
|
|||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::SetName(const wxString& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
void Module::Log(const u32 id, wxString fmt, ...)
|
void Module::Log(const u32 id, wxString fmt, ...)
|
||||||
{
|
{
|
||||||
if(enable_log)
|
if(enable_log)
|
||||||
|
@ -25,14 +25,16 @@ struct ModuleFunc
|
|||||||
|
|
||||||
class Module
|
class Module
|
||||||
{
|
{
|
||||||
const char* m_name;
|
wxString m_name;
|
||||||
const u16 m_id;
|
const u16 m_id;
|
||||||
bool m_is_loaded;
|
bool m_is_loaded;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Array<ModuleFunc> m_funcs_list;
|
Array<ModuleFunc> 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 Load();
|
||||||
void UnLoad();
|
void UnLoad();
|
||||||
@ -44,6 +46,7 @@ public:
|
|||||||
|
|
||||||
u16 GetID() const;
|
u16 GetID() const;
|
||||||
wxString GetName() const;
|
wxString GetName() const;
|
||||||
|
void SetName(const wxString& name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Log(const u32 id, wxString fmt, ...);
|
void Log(const u32 id, wxString fmt, ...);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
|
||||||
void cellGcmSys_init();
|
void cellGcmSys_init();
|
||||||
Module cellGcmSys("cellGcmSys", 0x0010, cellGcmSys_init);
|
Module cellGcmSys(0x0010, cellGcmSys_init);
|
||||||
|
|
||||||
s64 cellGcmFunc15()
|
s64 cellGcmFunc15()
|
||||||
{
|
{
|
||||||
|
95
rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp
Normal file
95
rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp
Normal file
@ -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));
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
|
||||||
void sysPrxForUser_init();
|
void sysPrxForUser_init();
|
||||||
Module sysPrxForUser("sysPrxForUser", -1, sysPrxForUser_init);
|
Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init);
|
||||||
|
|
||||||
void sys_initialize_tls()
|
void sys_initialize_tls()
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
|
||||||
void sys_fs_init();
|
void sys_fs_init();
|
||||||
Module sys_fs("sys_fs", 0x000e, sys_fs_init);
|
Module sys_fs(0x000e, sys_fs_init);
|
||||||
|
|
||||||
void sys_fs_init()
|
void sys_fs_init()
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "Emu/SysCalls/SC_FUNC.h"
|
#include "Emu/SysCalls/SC_FUNC.h"
|
||||||
|
|
||||||
void sys_io_init();
|
void sys_io_init();
|
||||||
Module sys_io("sys_io", 0x0017, sys_io_init);
|
Module sys_io(0x0017, sys_io_init);
|
||||||
|
|
||||||
void sys_io_init()
|
void sys_io_init()
|
||||||
{
|
{
|
||||||
|
@ -247,7 +247,7 @@ void SysCalls::DoSyscall(u32 code)
|
|||||||
//timer
|
//timer
|
||||||
case 141:
|
case 141:
|
||||||
case 142:
|
case 142:
|
||||||
Sleep(SC_ARGS_1 / (1000 * 1000));
|
std::this_thread::sleep_for(std::chrono::nanoseconds(SC_ARGS_1));
|
||||||
RESULT(0);
|
RESULT(0);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ extern int cellGcmCallback(u32 context_addr, u32 count);
|
|||||||
extern int cellGcmGetConfiguration(u32 config_addr);
|
extern int cellGcmGetConfiguration(u32 config_addr);
|
||||||
extern int cellGcmAddressToOffset(u32 address, u32 offset_addr);
|
extern int cellGcmAddressToOffset(u32 address, u32 offset_addr);
|
||||||
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
|
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 u32 cellGcmGetControlRegister();
|
||||||
extern int cellGcmFlush(u32 ctx, u32 id);
|
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);
|
extern void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank);
|
||||||
|
@ -44,14 +44,13 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
|||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCThread* thr = GetCurrentPPCThread();
|
int result;
|
||||||
|
auto queue_receive = [&](int status) -> bool
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
int status = thr->ThreadStatus();
|
|
||||||
if(status == PPCThread_Stopped)
|
if(status == PPCThread_Stopped)
|
||||||
{
|
{
|
||||||
return CELL_ECANCELED;
|
result = CELL_ECANCELED;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data;
|
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)
|
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
|
||||||
{
|
{
|
||||||
SPUThread* thr = (SPUThread*)equeue->ports[i]->thread;
|
SPUThread* thr = (SPUThread*)equeue->ports[i]->thread;
|
||||||
if(thr->OutIntrMbox.GetCount())
|
if(thr->SPU_OutIntr_Mbox.GetCount())
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
thr->OutIntrMbox.Pop(val);
|
thr->SPU_OutIntr_Mbox.Pop(val);
|
||||||
if(!thr->OutMbox.Pop(val)) val = 0;
|
if(!thr->SPU_Out_MBox.Pop(val)) val = 0;
|
||||||
equeue->ports[i]->data1 = val;
|
equeue->ports[i]->data1 = val;
|
||||||
equeue->ports[i]->data2 = 0;
|
equeue->ports[i]->data2 = 0;
|
||||||
equeue->ports[i]->data3 = 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; i<equeue->pos; i++)
|
for(int i=0; i<equeue->pos; i++)
|
||||||
{
|
{
|
||||||
if(equeue->ports[i]->has_data)
|
if(equeue->ports[i]->has_data)
|
||||||
{
|
{
|
||||||
has_data = true;
|
auto dst = (sys_event_data&)Memory[event_addr];
|
||||||
auto res = (sys_event_data&)Memory[event_addr];
|
|
||||||
|
|
||||||
re(res.source, equeue->ports[i]->name);
|
re(dst.source, equeue->ports[i]->name);
|
||||||
re(res.data1, equeue->ports[i]->data1);
|
re(dst.data1, equeue->ports[i]->data1);
|
||||||
re(res.data2, equeue->ports[i]->data2);
|
re(dst.data2, equeue->ports[i]->data2);
|
||||||
re(res.data3, equeue->ports[i]->data3);
|
re(dst.data3, equeue->ports[i]->data3);
|
||||||
|
|
||||||
equeue->ports[i]->has_data = false;
|
equeue->ports[i]->has_data = false;
|
||||||
break;
|
|
||||||
|
result = CELL_OK;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(has_data)
|
return true;
|
||||||
break;
|
};
|
||||||
|
|
||||||
Sleep(1);
|
GetCurrentPPUThread().WaitFor(queue_receive);
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -199,9 +199,14 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, u32 nwrite_addr)
|
|||||||
ID id;
|
ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,9 +133,9 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height
|
|||||||
return CELL_OK;
|
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;
|
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,15 +162,51 @@ enum
|
|||||||
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
|
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)
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_memory_container_destroy(u32 cid)
|
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;
|
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);
|
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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,17 @@ int sys_ppu_thread_exit(int errorcode)
|
|||||||
int sys_ppu_thread_yield()
|
int sys_ppu_thread_yield()
|
||||||
{
|
{
|
||||||
sysPrxForUser.Log("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;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr)
|
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;
|
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;
|
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());
|
Memory.Write32(thread_id_addr, new_thread.GetId());
|
||||||
new_thread.SetEntry(entry);
|
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);
|
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);
|
new_thread.SetEntry(entry);
|
||||||
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
|
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
|
||||||
new_thread.Run();
|
new_thread.Run();
|
||||||
|
@ -37,7 +37,6 @@ int SysCalls::lv2ProcessWaitForChild(PPUThread& CPU)
|
|||||||
int SysCalls::lv2ProcessGetStatus(PPUThread& CPU)
|
int SysCalls::lv2ProcessGetStatus(PPUThread& CPU)
|
||||||
{
|
{
|
||||||
ConLog.Warning("lv2ProcessGetStatus");
|
ConLog.Warning("lv2ProcessGetStatus");
|
||||||
if(CPU.IsSPU()) return CELL_UNKNOWN_ERROR;
|
|
||||||
//Memory.Write32(CPU.GPR[4], GetPPUThreadStatus(CPU));
|
//Memory.Write32(CPU.GPR[4], GetPPUThreadStatus(CPU));
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -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.Write("a4 = 0x%x", a4);
|
||||||
ConLog.SkipLn();
|
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.SetOffset(g_spu_offset);
|
||||||
new_thread.SetEntry(entry - g_spu_offset);
|
new_thread.SetEntry(entry - g_spu_offset);
|
||||||
new_thread.SetName(name);
|
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);
|
sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg_addr);
|
||||||
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||||
|
|
||||||
if(!thr || !thr->IsSPU())
|
if(!thr || thr->GetType() == PPC_THREAD_PPU)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
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);
|
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));
|
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
|
||||||
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
|
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_RAW_SPU);
|
||||||
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
|
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(PPC_THREAD_RAW_SPU, new_thread.GetId()));
|
||||||
Memory.Write32(0xe0043014, 0);
|
new_thread.Run();
|
||||||
|
new_thread.Exec();
|
||||||
|
|
||||||
return CELL_OK;
|
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))
|
if(!Memory.InitSpuRawMem(max_raw_spu))
|
||||||
{
|
{
|
||||||
//30010780;
|
return CELL_ENOMEM;
|
||||||
//e0043004 - offset
|
|
||||||
//e004300c - entry
|
|
||||||
return CELL_UNKNOWN_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//enable_log = true;
|
//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);
|
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||||
|
|
||||||
if(!thr || !thr->IsSPU())
|
if(!thr || thr->GetType() == PPC_THREAD_PPU)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
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);
|
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||||
|
|
||||||
if(!thr || !thr->IsSPU())
|
if(!thr || thr->GetType() == PPC_THREAD_PPU)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
return CELL_ESRCH;
|
||||||
}
|
}
|
||||||
@ -346,12 +345,12 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
|||||||
|
|
||||||
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||||
|
|
||||||
if(!thr || !thr->IsSPU())
|
if(!thr || !thr->GetType() == PPC_THREAD_PPU)
|
||||||
{
|
{
|
||||||
return CELL_ESRCH;
|
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.");
|
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
|
||||||
return CELL_EBUSY; //?
|
return CELL_EBUSY; //?
|
||||||
|
@ -112,7 +112,7 @@ void Emulator::Load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
LoadPoints(BreakPointsDBName);
|
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)
|
if(l.GetMachine() == MACHINE_SPU)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ public:
|
|||||||
|
|
||||||
*done = false;
|
*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);
|
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode);
|
||||||
decoder = new SPU_Decoder(dis_asm);
|
decoder = new SPU_Decoder(dis_asm);
|
||||||
@ -341,7 +341,7 @@ void DisAsmFrame::Dump(wxCommandEvent& WXUNUSED(event))
|
|||||||
PPC_DisAsm* disasm;
|
PPC_DisAsm* disasm;
|
||||||
PPC_Decoder* decoder;
|
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);
|
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode);
|
||||||
decoder = new SPU_Decoder(dis_asm);
|
decoder = new SPU_Decoder(dis_asm);
|
||||||
|
@ -108,7 +108,7 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
|
|||||||
|
|
||||||
if(CPU)
|
if(CPU)
|
||||||
{
|
{
|
||||||
if(CPU->IsSPU())
|
if(CPU->GetType() != PPC_THREAD_PPU)
|
||||||
{
|
{
|
||||||
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*CPU, InterpreterMode);
|
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*CPU, InterpreterMode);
|
||||||
decoder = new SPU_Decoder(dis_asm);
|
decoder = new SPU_Decoder(dis_asm);
|
||||||
|
@ -133,18 +133,18 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
|
|||||||
{
|
{
|
||||||
phdr_arr[i].Show();
|
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_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)
|
if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr)
|
||||||
{
|
{
|
||||||
ConLog.Warning
|
ConLog.Warning
|
||||||
@ -158,6 +158,40 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
|
|||||||
elf32_f.Seek(phdr_arr[i].p_offset);
|
elf32_f.Seek(phdr_arr[i].p_offset);
|
||||||
elf32_f.Read(&Memory[phdr_arr[i].p_vaddr + offset], phdr_arr[i].p_filesz);
|
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
|
#ifdef LOADER_DEBUG
|
||||||
ConLog.SkipLn();
|
ConLog.SkipLn();
|
||||||
#endif
|
#endif
|
||||||
@ -177,6 +211,11 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
|||||||
shdr.Show();
|
shdr.Show();
|
||||||
ConLog.SkipLn();
|
ConLog.SkipLn();
|
||||||
#endif
|
#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_flags & SHF_ALLOC) != SHF_ALLOC) continue;
|
||||||
|
|
||||||
if(shdr.sh_addr < min_addr)
|
if(shdr.sh_addr < min_addr)
|
||||||
@ -188,21 +227,6 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
|||||||
{
|
{
|
||||||
max_addr = shdr.sh_addr + shdr.sh_size;
|
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
|
//TODO
|
||||||
|
@ -75,6 +75,40 @@ struct Elf32_Ehdr
|
|||||||
u32 GetEntry() const { return e_entry; }
|
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
|
struct Elf32_Shdr
|
||||||
{
|
{
|
||||||
u32 sh_name;
|
u32 sh_name;
|
||||||
|
@ -413,16 +413,6 @@ bool ELF64Loader::LoadShdrData(u64 offset)
|
|||||||
{
|
{
|
||||||
Elf64_Shdr& shdr = shdr_arr[i];
|
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())
|
if(i < shdr_name_arr.GetCount())
|
||||||
{
|
{
|
||||||
const wxString& name = shdr_name_arr[i];
|
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(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)
|
switch(shdr.sh_type)
|
||||||
{
|
{
|
||||||
case SHT_NOBITS:
|
case SHT_NOBITS:
|
||||||
@ -457,6 +463,10 @@ bool ELF64Loader::LoadShdrData(u64 offset)
|
|||||||
elf64_f.Read(&Memory[addr], shdr.sh_size);
|
elf64_f.Read(&Memory[addr], shdr.sh_size);
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SHT_RELA:
|
||||||
|
ConLog.Warning("ELF64: RELA");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +201,7 @@
|
|||||||
<ClCompile Include="Emu\Cell\PPCThreadManager.cpp" />
|
<ClCompile Include="Emu\Cell\PPCThreadManager.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
|
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\PPUThread.cpp" />
|
<ClCompile Include="Emu\Cell\PPUThread.cpp" />
|
||||||
|
<ClCompile Include="Emu\Cell\RawSPUThread.cpp" />
|
||||||
<ClCompile Include="Emu\Cell\SPUThread.cpp" />
|
<ClCompile Include="Emu\Cell\SPUThread.cpp" />
|
||||||
<ClCompile Include="Emu\DbgConsole.cpp" />
|
<ClCompile Include="Emu\DbgConsole.cpp" />
|
||||||
<ClCompile Include="Emu\FS\VFS.cpp" />
|
<ClCompile Include="Emu\FS\VFS.cpp" />
|
||||||
@ -243,6 +244,7 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
|
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\cellGcmSys.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\cellGcmSys.cpp" />
|
||||||
|
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\sys_fs.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\sys_fs.cpp" />
|
||||||
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />
|
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />
|
||||||
|
@ -256,6 +256,12 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\Modules.cpp">
|
<ClCompile Include="Emu\SysCalls\Modules.cpp">
|
||||||
<Filter>Emu\SysCalls</Filter>
|
<Filter>Emu\SysCalls</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp">
|
||||||
|
<Filter>Emu\SysCalls\Modules</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\Cell\RawSPUThread.cpp">
|
||||||
|
<Filter>Emu\CPU</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
|
Loading…
Reference in New Issue
Block a user