mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
- Fixed loading modules in debug mode.
- Improved Lwmutex. - Implemented events syscalls. - Fixed SPU local storage.
This commit is contained in:
parent
991f281bbd
commit
6d7d3acb43
@ -209,6 +209,61 @@ template<typename T> struct Stack : public Array<T>
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, size_t size> class SizedStack
|
||||
{
|
||||
T m_ptr[size];
|
||||
uint m_count;
|
||||
|
||||
public:
|
||||
SizedStack()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
~SizedStack()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
bool Pop(T& dst)
|
||||
{
|
||||
if(!m_count)
|
||||
return false;
|
||||
|
||||
dst = m_ptr[--m_count];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Push(const T& src)
|
||||
{
|
||||
if(m_count + 1 > size)
|
||||
return false;
|
||||
|
||||
m_ptr[m_count++] = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t GetFreeCount() const
|
||||
{
|
||||
return size - m_count;
|
||||
}
|
||||
|
||||
size_t GetCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
size_t GetMaxCount() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> class ArrayF
|
||||
{
|
||||
u32 m_count;
|
||||
|
@ -23,7 +23,7 @@ protected:
|
||||
{
|
||||
case DumpMode:
|
||||
{
|
||||
wxString mem = wxString::Format("\t%x:\t", dump_pc);
|
||||
wxString mem = wxString::Format("\t%08llx:\t", dump_pc);
|
||||
for(u8 i=0; i < 4; ++i)
|
||||
{
|
||||
mem += wxString::Format("%02x", Memory.Read8(dump_pc + i));
|
||||
@ -36,14 +36,11 @@ protected:
|
||||
|
||||
case InterpreterMode:
|
||||
{
|
||||
wxString mem = wxString::Format("[%x] ", dump_pc);
|
||||
for(u8 i=0; i < 4; ++i)
|
||||
{
|
||||
mem += wxString::Format("%02x", Memory.Read8(dump_pc + i));
|
||||
if(i < 3) mem += " ";
|
||||
}
|
||||
|
||||
last_opcode = mem + ": " + value;
|
||||
last_opcode = wxString::Format("[%08llx] %02x %02x %02x %02x: %s", dump_pc,
|
||||
Memory.Read8(offset + dump_pc),
|
||||
Memory.Read8(offset + dump_pc + 1),
|
||||
Memory.Read8(offset + dump_pc + 2),
|
||||
Memory.Read8(offset + dump_pc + 3), value);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -55,12 +52,14 @@ protected:
|
||||
|
||||
public:
|
||||
wxString last_opcode;
|
||||
uint dump_pc;
|
||||
u64 dump_pc;
|
||||
u64 offset;
|
||||
|
||||
protected:
|
||||
PPC_DisAsm(PPCThread& cpu, DisAsmModes mode = NormalMode)
|
||||
: m_mode(mode)
|
||||
, disasm_frame(NULL)
|
||||
, offset(0)
|
||||
{
|
||||
if(m_mode != NormalMode) return;
|
||||
|
||||
|
@ -17,6 +17,8 @@ PPCThread::PPCThread(PPCThreadType type)
|
||||
, stack_addr(0)
|
||||
, m_prio(0)
|
||||
, m_offset(0)
|
||||
, m_sync_wait(false)
|
||||
, m_wait_thread_id(-1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,6 +41,9 @@ void PPCThread::Reset()
|
||||
{
|
||||
CloseStack();
|
||||
|
||||
m_sync_wait = 0;
|
||||
m_wait_thread_id = -1;
|
||||
|
||||
SetPc(0);
|
||||
cycle = 0;
|
||||
|
||||
@ -92,6 +97,36 @@ void PPCThread::SetName(const wxString& name)
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void PPCThread::Wait(bool wait)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_cs_sync);
|
||||
m_sync_wait = wait;
|
||||
}
|
||||
|
||||
void PPCThread::Wait(const PPCThread& thr)
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_cs_sync);
|
||||
m_wait_thread_id = thr.GetId();
|
||||
m_sync_wait = true;
|
||||
}
|
||||
|
||||
bool PPCThread::Sync()
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_cs_sync);
|
||||
|
||||
return m_sync_wait;
|
||||
}
|
||||
|
||||
int PPCThread::ThreadStatus()
|
||||
{
|
||||
if(Emu.IsStopped()) return PPCThread_Stopped;
|
||||
if(TestDestroy()) return PPCThread_Break;
|
||||
if(Emu.IsPaused() || Sync())
|
||||
return PPCThread_Sleeping;
|
||||
|
||||
return PPCThread_Running;
|
||||
}
|
||||
|
||||
void PPCThread::NextBranchPc()
|
||||
{
|
||||
SetPc(nPC);
|
||||
@ -127,9 +162,9 @@ void PPCThread::SetEntry(const u64 pc)
|
||||
|
||||
void PPCThread::SetBranch(const u64 pc)
|
||||
{
|
||||
if(!Memory.IsGoodAddr(pc))
|
||||
if(!Memory.IsGoodAddr(m_offset + pc))
|
||||
{
|
||||
ConLog.Error("%s branch error: bad address 0x%llx #pc: 0x%llx", GetFName(), pc, PC);
|
||||
ConLog.Error("%s branch error: bad address 0x%llx #pc: 0x%llx", GetFName(), m_offset+ pc, m_offset + PC);
|
||||
Emu.Pause();
|
||||
}
|
||||
nPC = pc;
|
||||
@ -255,9 +290,16 @@ void PPCThread::Task()
|
||||
}
|
||||
}
|
||||
|
||||
while(!Emu.IsStopped() && !TestDestroy())
|
||||
while(true)
|
||||
{
|
||||
if(Emu.IsPaused())
|
||||
int status = ThreadStatus();
|
||||
|
||||
if(status == PPCThread_Stopped || status == PPCThread_Break)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(status == PPCThread_Sleeping)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
|
@ -8,6 +8,16 @@ enum PPCThreadType
|
||||
PPC_THREAD_SPU,
|
||||
};
|
||||
|
||||
enum PPCThreadStatus
|
||||
{
|
||||
PPCThread_Ready,
|
||||
PPCThread_Running,
|
||||
PPCThread_Paused,
|
||||
PPCThread_Stopped,
|
||||
PPCThread_Sleeping,
|
||||
PPCThread_Break,
|
||||
};
|
||||
|
||||
class PPCThread : public ThreadBase
|
||||
{
|
||||
protected:
|
||||
@ -43,6 +53,7 @@ public:
|
||||
void SetName(const wxString& name);
|
||||
void SetPrio(const u64 prio) { m_prio = prio; }
|
||||
void SetOffset(const u64 offset) { m_offset = offset; }
|
||||
u64 GetOffset() { return m_offset; }
|
||||
|
||||
u64 GetPrio() const { return m_prio; }
|
||||
wxString GetName() const { return m_name; }
|
||||
@ -88,6 +99,16 @@ protected:
|
||||
public:
|
||||
~PPCThread();
|
||||
|
||||
u32 m_wait_thread_id;
|
||||
|
||||
wxCriticalSection m_cs_sync;
|
||||
bool m_sync_wait;
|
||||
void Wait(bool wait);
|
||||
void Wait(const PPCThread& thr);
|
||||
bool Sync();
|
||||
|
||||
int ThreadStatus();
|
||||
|
||||
void NextPc();
|
||||
void NextBranchPc();
|
||||
void PrevPc();
|
||||
|
@ -35,14 +35,19 @@ void PPCThreadManager::RemoveThread(const u32 id)
|
||||
{
|
||||
for(u32 i=0; i<m_threads.GetCount(); ++i)
|
||||
{
|
||||
if(m_threads[i].m_wait_thread_id == id)
|
||||
{
|
||||
m_threads[i].Wait(false);
|
||||
m_threads[i].m_wait_thread_id = -1;
|
||||
}
|
||||
|
||||
if(m_threads[i].GetId() != id) continue;
|
||||
|
||||
wxGetApp().SendDbgCommand(DID_REMOVE_THREAD, &m_threads[i]);
|
||||
m_threads[i].Close();
|
||||
delete &m_threads[i];
|
||||
m_threads.RemoveFAt(i);
|
||||
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID(id, false);
|
||||
|
@ -1051,9 +1051,9 @@ private:
|
||||
{
|
||||
DisAsm_R3("lwarx", rd, ra, rb);
|
||||
}
|
||||
void LDX(u32 ra, u32 rs, u32 rb)
|
||||
void LDX(u32 rd, u32 ra, u32 rb)
|
||||
{
|
||||
DisAsm_R3("ldx", ra, rs, rb);
|
||||
DisAsm_R3("ldx", rd, ra, rb);
|
||||
}
|
||||
void LWZX(u32 rd, u32 ra, u32 rb)
|
||||
{
|
||||
|
@ -489,7 +489,7 @@ namespace PPU_instr
|
||||
/*0x00b*/bind_instr(g1f_list, MULHWU, RD, RA, RB, RC);
|
||||
/*0x013*/bind_instr(g1f_list, MFOCRF, L_11, RD, CRM);
|
||||
/*0x014*/bind_instr(g1f_list, LWARX, RD, RA, RB);
|
||||
/*0x015*/bind_instr(g1f_list, LDX, RA, RS, RB);
|
||||
/*0x015*/bind_instr(g1f_list, LDX, RD, RA, RB);
|
||||
/*0x017*/bind_instr(g1f_list, LWZX, RD, RA, RB);
|
||||
/*0x018*/bind_instr(g1f_list, SLW, RA, RS, RB, RC);
|
||||
/*0x01a*/bind_instr(g1f_list, CNTLZW, RA, RS, RC);
|
||||
|
@ -61,10 +61,10 @@ private:
|
||||
|
||||
void SysCall()
|
||||
{
|
||||
CPU.GPR[3] = CPU.DoSyscall(CPU.GPR[11]);
|
||||
CPU.DoSyscall(CPU.GPR[11]);
|
||||
|
||||
//if((s32)CPU.GPR[3] < 0)
|
||||
//ConLog.Warning("SysCall[%lld] done with code [0x%x]! #pc: 0x%llx", CPU.GPR[11], (u32)CPU.GPR[3], CPU.PC);
|
||||
if(enable_log)
|
||||
ConLog.Warning("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
|
||||
#ifdef HLE_CALL_DEBUG
|
||||
ConLog.Write("SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", CPU.GPR[11], CPU.GPR[3], CPU.PC);
|
||||
#endif
|
||||
@ -2028,11 +2028,11 @@ private:
|
||||
}
|
||||
void CMPLI(u32 crfd, u32 l, u32 ra, u32 uimm16)
|
||||
{
|
||||
CPU.UpdateCRn<u64>(crfd, l ? CPU.GPR[ra] : (u32)CPU.GPR[ra], uimm16);
|
||||
CPU.UpdateCRnU(l, crfd, CPU.GPR[ra], uimm16);
|
||||
}
|
||||
void CMPI(u32 crfd, u32 l, u32 ra, s32 simm16)
|
||||
{
|
||||
CPU.UpdateCRn<s64>(crfd, l ? CPU.GPR[ra] : (s32)CPU.GPR[ra], simm16);
|
||||
CPU.UpdateCRnS(l, crfd, CPU.GPR[ra], simm16);
|
||||
}
|
||||
void ADDIC(u32 rd, u32 ra, s32 simm16)
|
||||
{
|
||||
@ -2172,12 +2172,12 @@ private:
|
||||
void ANDI_(u32 ra, u32 rs, u32 uimm16)
|
||||
{
|
||||
CPU.GPR[ra] = CPU.GPR[rs] & uimm16;
|
||||
CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||
CPU.UpdateCR0<s32>(CPU.GPR[ra]);
|
||||
}
|
||||
void ANDIS_(u32 ra, u32 rs, u32 uimm16)
|
||||
{
|
||||
CPU.GPR[ra] = CPU.GPR[rs] & (uimm16 << 16);
|
||||
CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||
CPU.UpdateCR0<s32>(CPU.GPR[ra]);
|
||||
}
|
||||
void RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc)
|
||||
{
|
||||
@ -2202,7 +2202,7 @@ private:
|
||||
}
|
||||
void CMP(u32 crfd, u32 l, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.UpdateCRn<s64>(crfd, l ? CPU.GPR[ra] : (s32)CPU.GPR[ra], l ? CPU.GPR[rb] : (s32)CPU.GPR[rb]);
|
||||
CPU.UpdateCRnS(l, crfd, CPU.GPR[ra], CPU.GPR[rb]);
|
||||
}
|
||||
void TW(u32 to, u32 ra, u32 rb)
|
||||
{
|
||||
@ -2256,7 +2256,7 @@ private:
|
||||
{
|
||||
const s64 RA = CPU.GPR[ra];
|
||||
const s64 RB = CPU.GPR[rb];
|
||||
CPU.GPR[rd] = RB - RA;
|
||||
CPU.GPR[rd] = ~RA + RB + 1;
|
||||
CPU.XER.CA = CPU.IsCarry(RA, RB);
|
||||
if(oe) UNK("subfco");
|
||||
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
|
||||
@ -2334,9 +2334,9 @@ private:
|
||||
CPU.reserve = true;
|
||||
CPU.GPR[rd] = Memory.Read32(addr);
|
||||
}
|
||||
void LDX(u32 ra, u32 rs, u32 rb)
|
||||
void LDX(u32 rd, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.GPR[ra] = Memory.Read64(rs ? CPU.GPR[rs] + CPU.GPR[rb] : CPU.GPR[rb]);
|
||||
CPU.GPR[rd] = Memory.Read64(ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]);
|
||||
}
|
||||
void LWZX(u32 rd, u32 ra, u32 rb)
|
||||
{
|
||||
@ -2362,11 +2362,16 @@ private:
|
||||
|
||||
CPU.GPR[ra] = i;
|
||||
|
||||
if(rc) CPU.UpdateCR0<u32>(CPU.GPR[ra]);
|
||||
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[ra]);
|
||||
}
|
||||
void SLD(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
{
|
||||
CPU.GPR[ra] = CPU.GPR[rb] & 0x40 ? 0 : CPU.GPR[rs] << (CPU.GPR[rb] & 0x3f);
|
||||
const u32 n = CPU.GPR[rb] & 0x3f;
|
||||
const u64 r = rotl64(CPU.GPR[rs], n);
|
||||
const u64 m = (CPU.GPR[rb] & 0x30) ? 0 : rotate_mask[0][63 - n];
|
||||
|
||||
CPU.GPR[ra] = r & m;
|
||||
|
||||
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||
}
|
||||
void AND(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
@ -2376,7 +2381,7 @@ private:
|
||||
}
|
||||
void CMPL(u32 crfd, u32 l, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.UpdateCRn<u64>(crfd, l ? CPU.GPR[ra] : (u32)CPU.GPR[ra], l ? CPU.GPR[rb] : (u32)CPU.GPR[rb]);
|
||||
CPU.UpdateCRnU(l, crfd, CPU.GPR[ra], CPU.GPR[rb]);
|
||||
}
|
||||
void LVSR(u32 vd, u32 ra, u32 rb)
|
||||
{
|
||||
@ -2570,21 +2575,23 @@ private:
|
||||
void STWCX_(u32 rs, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.SetCR(0, CPU.XER.SO ? CR_SO : 0);
|
||||
if(!CPU.reserve) return;
|
||||
|
||||
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
|
||||
if(addr == CPU.reserve_addr)
|
||||
|
||||
if(CPU.reserve)
|
||||
{
|
||||
Memory.Write32(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const bool u = 0;
|
||||
if(u) Memory.Write32(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, u);
|
||||
CPU.reserve = false;
|
||||
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
|
||||
if(addr == CPU.reserve_addr)
|
||||
{
|
||||
Memory.Write32(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const bool u = 0;
|
||||
if(u) Memory.Write32(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, u);
|
||||
CPU.reserve = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
void STWX(u32 rs, u32 ra, u32 rb)
|
||||
@ -2621,21 +2628,22 @@ private:
|
||||
void STDCX_(u32 rs, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.SetCR(0, CPU.XER.SO ? CR_SO : 0);
|
||||
if(!CPU.reserve) return;
|
||||
|
||||
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
|
||||
if(addr == CPU.reserve_addr)
|
||||
if(!CPU.reserve)
|
||||
{
|
||||
Memory.Write64(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const bool u = 0;
|
||||
if(u) Memory.Write64(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, u);
|
||||
CPU.reserve = false;
|
||||
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
|
||||
|
||||
if(addr == CPU.reserve_addr)
|
||||
{
|
||||
Memory.Write64(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const bool u = 0;
|
||||
if(u) Memory.Write64(addr, CPU.GPR[rs]);
|
||||
CPU.SetCR_EQ(0, u);
|
||||
CPU.reserve = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
void STBX(u32 rs, u32 ra, u32 rb)
|
||||
@ -2824,10 +2832,10 @@ private:
|
||||
const s64 RA = CPU.GPR[ra];
|
||||
const s64 RB = CPU.GPR[rb];
|
||||
|
||||
if (RB == 0 || ((u64)RA == 0x8000000000000000 && RB == -1))
|
||||
if (RB == 0 || ((u64)RA == (1ULL << 63) && RB == -1))
|
||||
{
|
||||
if(oe) UNK("divdo");
|
||||
CPU.GPR[rd] = (((u64)RA & 0x8000000000000000) && RB == 0) ? -1 : 0;
|
||||
CPU.GPR[rd] = (((u64)RA & (1ULL << 63)) && RB == 0) ? -1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2841,10 +2849,10 @@ private:
|
||||
const s32 RA = CPU.GPR[ra];
|
||||
const s32 RB = CPU.GPR[rb];
|
||||
|
||||
if (RB == 0 || ((u32)RA == 0x80000000 && RB == -1))
|
||||
if (RB == 0 || ((u32)RA == (1 << 31) && RB == -1))
|
||||
{
|
||||
if(oe) UNK("divwo");
|
||||
CPU.GPR[rd] = (((u32)RA & 0x80000000) && RB == 0) ? -1 : 0;
|
||||
CPU.GPR[rd] = (((u32)RA & (1 << 31)) && RB == 0) ? -1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2871,12 +2879,20 @@ private:
|
||||
}
|
||||
void SRW(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
{
|
||||
CPU.GPR[ra] = CPU.GPR[rb] & 0x20 ? 0 : (u32)CPU.GPR[rs] >> (CPU.GPR[rb] & 0x1f);
|
||||
u32 n = CPU.GPR[rb] & 0x1f;
|
||||
u64 r = rotl32((u32)CPU.GPR[rs], 64 - n);
|
||||
u64 m = CPU.GPR[rb] & 0x20 ? 0 : rotate_mask[32 + n][63];
|
||||
CPU.GPR[ra] = r & m;
|
||||
|
||||
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[ra]);
|
||||
}
|
||||
void SRD(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
{
|
||||
CPU.GPR[ra] = CPU.GPR[rb] & 0x40 ? 0 : CPU.GPR[rs] >> (CPU.GPR[rb] & 0x3f);
|
||||
u32 n = CPU.GPR[rb] & 0x3f;
|
||||
u64 r = rotl64(CPU.GPR[rs], 64 - n);
|
||||
u64 m = CPU.GPR[rb] & 0x40 ? 0 : rotate_mask[n][63];
|
||||
CPU.GPR[ra] = r & m;
|
||||
|
||||
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||
}
|
||||
void LVRX(u32 vd, u32 ra, u32 rb)
|
||||
@ -2940,7 +2956,7 @@ private:
|
||||
CPU.GPR[rd] = (u16&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]];
|
||||
}
|
||||
void SRAW(u32 ra, u32 rs, u32 rb, bool rc)
|
||||
{
|
||||
{
|
||||
s32 RS = CPU.GPR[rs];
|
||||
s32 RB = CPU.GPR[rb];
|
||||
CPU.GPR[ra] = RS >> RB;
|
||||
|
@ -60,13 +60,13 @@ void PPUThread::AddArgv(const wxString& arg)
|
||||
|
||||
void PPUThread::InitRegs()
|
||||
{
|
||||
const u32 entry = Memory.Read32(PC);
|
||||
const u32 rtoc = Memory.Read32(PC + 4);
|
||||
const u32 pc = Memory.Read32(entry);
|
||||
const u32 rtoc = Memory.Read32(entry + 4);
|
||||
|
||||
ConLog.Write("entry = 0x%x", entry);
|
||||
ConLog.Write("rtoc = 0x%x", rtoc);
|
||||
|
||||
SetPc(entry);
|
||||
SetPc(pc);
|
||||
|
||||
u64 argc = m_arg;
|
||||
u64 argv = 0;
|
||||
@ -110,20 +110,18 @@ void PPUThread::InitRegs()
|
||||
{
|
||||
GPR[3] = argc;
|
||||
GPR[4] = argv;
|
||||
GPR[5] = argv ? argv - 0xc - 4 * argc : 0; //unk
|
||||
GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk
|
||||
}
|
||||
else
|
||||
{
|
||||
GPR[3] = m_arg;
|
||||
}
|
||||
|
||||
GPR[0] = entry;
|
||||
//GPR[7] = 0x80d90;
|
||||
GPR[0] = pc;
|
||||
GPR[8] = entry;
|
||||
//GPR[10] = 0x131700;
|
||||
GPR[11] = 0x80;
|
||||
GPR[12] = Emu.GetMallocPageSize();
|
||||
GPR[13] = Memory.MainMem.Alloc(0x10000) + 0x7060;
|
||||
GPR[13] = Memory.PRXMem.Alloc(0x10000) + 0x7060 - 8;
|
||||
GPR[28] = GPR[4];
|
||||
GPR[29] = GPR[3];
|
||||
GPR[31] = GPR[5];
|
||||
|
@ -652,6 +652,30 @@ public:
|
||||
SetCR_SO(n, XER.SO);
|
||||
}
|
||||
|
||||
void UpdateCRnU(const u8 l, const u8 n, const u64 a, const u64 b)
|
||||
{
|
||||
if(l)
|
||||
{
|
||||
UpdateCRn<u64>(n, a, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCRn<u32>(n, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCRnS(const u8 l, const u8 n, const u64 a, const u64 b)
|
||||
{
|
||||
if(l)
|
||||
{
|
||||
UpdateCRn<s64>(n, a, b);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCRn<s32>(n, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> void UpdateCR0(const T val)
|
||||
{
|
||||
UpdateCRn<T>(0, val, 0);
|
||||
|
@ -24,9 +24,3 @@ public:
|
||||
(*SPU_instr::rrr_list)(m_op, code);
|
||||
}
|
||||
};
|
||||
|
||||
#undef START_OPCODES_GROUP_
|
||||
#undef START_OPCODES_GROUP
|
||||
#undef ADD_OPCODE
|
||||
#undef ADD_NULL_OPCODE
|
||||
#undef END_OPCODES_GROUP
|
File diff suppressed because it is too large
Load Diff
@ -27,18 +27,18 @@ private:
|
||||
//0 - 10
|
||||
void STOP(u32 code)
|
||||
{
|
||||
Emu.Pause();
|
||||
CPU.Pause();
|
||||
}
|
||||
void LNOP()
|
||||
{
|
||||
}
|
||||
void SYNC(u32 Cbit)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//UNIMPLEMENTED();
|
||||
}
|
||||
void DSYNC()
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//UNIMPLEMENTED();
|
||||
}
|
||||
void MFSPR(u32 rt, u32 sa)
|
||||
{
|
||||
@ -51,7 +51,7 @@ private:
|
||||
void RCHCNT(u32 rt, u32 ra)
|
||||
{
|
||||
CPU.GPR[rt].Reset();
|
||||
CPU.GPR[rt]._u32[0] = CPU.GetChannelCount(ra);
|
||||
CPU.GPR[rt]._u32[3] = CPU.GetChannelCount(ra);
|
||||
}
|
||||
void SF(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
@ -280,16 +280,15 @@ private:
|
||||
}
|
||||
void STQX(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.LSA = CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0];
|
||||
CPU.WriteLSA128(CPU.GPR[rt]._u128);
|
||||
CPU.WriteLS128(CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0], CPU.GPR[rt]._u128);
|
||||
}
|
||||
void BI(u32 ra)
|
||||
{
|
||||
CPU.SetBranch(CPU.GPR[ra]._u32[0] & 0xfffffffc);
|
||||
CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc);
|
||||
}
|
||||
void BISL(u32 rt, u32 ra)
|
||||
{
|
||||
CPU.SetBranch(CPU.GPR[ra]._u32[0] & 0xfffffffc);
|
||||
CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc);
|
||||
CPU.GPR[rt].Reset();
|
||||
CPU.GPR[rt]._u32[0] = CPU.PC + 4;
|
||||
}
|
||||
@ -353,8 +352,7 @@ private:
|
||||
}
|
||||
void LQX(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
CPU.LSA = CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0];
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLSA128();
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLS128(CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0]);
|
||||
}
|
||||
void ROTQBYBI(u32 rt, u32 ra, u32 rb)
|
||||
{
|
||||
@ -870,8 +868,6 @@ private:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//0 - 9
|
||||
void CFLTS(u32 rt, u32 ra, s32 i8)
|
||||
{
|
||||
@ -890,35 +886,31 @@ private:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//0 - 8
|
||||
void BRZ(u32 rt, s32 i16)
|
||||
{
|
||||
if(!CPU.GPR[rt]._u32[0]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
if(!CPU.GPR[rt]._u32[3]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void STQA(u32 rt, s32 i16)
|
||||
{
|
||||
CPU.LSA = i16 << 2;
|
||||
CPU.WriteLSA128(CPU.GPR[rt]._u128);
|
||||
CPU.WriteLS128(i16 << 2, CPU.GPR[rt]._u128);
|
||||
}
|
||||
void BRNZ(u32 rt, s32 i16)
|
||||
{
|
||||
if(CPU.GPR[rt]._u32[0] != 0)
|
||||
if(CPU.GPR[rt]._u32[3] != 0)
|
||||
CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void BRHZ(u32 rt, s32 i16)
|
||||
{
|
||||
if(!CPU.GPR[rt]._u16[0]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
if(!CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void BRHNZ(u32 rt, s32 i16)
|
||||
{
|
||||
if(CPU.GPR[rt]._u16[0]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
if(CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void STQR(u32 rt, s32 i16)
|
||||
{
|
||||
CPU.LSA = branchTarget(CPU.PC, i16);
|
||||
CPU.WriteLSA128(CPU.GPR[rt]._u128);
|
||||
CPU.WriteLS128(branchTarget(CPU.PC, i16), CPU.GPR[rt]._u128);
|
||||
}
|
||||
void BRA(s32 i16)
|
||||
{
|
||||
@ -926,14 +918,7 @@ private:
|
||||
}
|
||||
void LQA(u32 rt, s32 i16)
|
||||
{
|
||||
CPU.LSA = i16 << 2;
|
||||
if(!Memory.IsGoodAddr(CPU.LSA))
|
||||
{
|
||||
ConLog.Warning("LQA: Bad addr: 0x%x", CPU.LSA);
|
||||
return;
|
||||
}
|
||||
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLSA128();
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLS128(i16 << 2);
|
||||
}
|
||||
void BRASL(u32 rt, s32 i16)
|
||||
{
|
||||
@ -964,19 +949,12 @@ private:
|
||||
void BRSL(u32 rt, s32 i16)
|
||||
{
|
||||
CPU.GPR[rt].Reset();
|
||||
CPU.GPR[rt]._u32[0] = CPU.PC + 4;
|
||||
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
|
||||
CPU.SetBranch(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void LQR(u32 rt, s32 i16)
|
||||
{
|
||||
CPU.LSA = branchTarget(CPU.PC, i16);
|
||||
if(!Memory.IsGoodAddr(CPU.LSA))
|
||||
{
|
||||
ConLog.Warning("LQR: Bad addr: 0x%x", CPU.LSA);
|
||||
return;
|
||||
}
|
||||
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLSA128();
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLS128(branchTarget(CPU.PC, i16));
|
||||
}
|
||||
void IL(u32 rt, s32 i16)
|
||||
{
|
||||
@ -988,7 +966,7 @@ private:
|
||||
void ILHU(u32 rt, s32 i16)
|
||||
{
|
||||
for (int w = 0; w < 4; w++)
|
||||
CPU.GPR[rt]._u16[w*2] = i16;
|
||||
CPU.GPR[rt]._u16[w*2 + 1] = i16;
|
||||
}
|
||||
void ILH(u32 rt, s32 i16)
|
||||
{
|
||||
@ -1061,13 +1039,11 @@ private:
|
||||
}
|
||||
void STQD(u32 rt, s32 i10, u32 ra)
|
||||
{
|
||||
CPU.LSA = branchTarget(0, i10 + CPU.GPR[ra]._u32[0]);
|
||||
CPU.WriteLSA128(CPU.GPR[rt]._u128);
|
||||
CPU.WriteLS128(CPU.GPR[ra]._u32[3] + i10, CPU.GPR[rt]._u128);
|
||||
}
|
||||
void LQD(u32 rt, s32 i10, u32 ra)
|
||||
{
|
||||
CPU.LSA = branchTarget(0, i10 + CPU.GPR[ra]._u32[0]);
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLSA128();
|
||||
CPU.GPR[rt]._u128 = CPU.ReadLS128(CPU.GPR[ra]._u32[3] + i10);
|
||||
}
|
||||
void XORI(u32 rt, u32 ra, s32 i10)
|
||||
{
|
||||
@ -1167,10 +1143,6 @@ private:
|
||||
}
|
||||
void HBRR(s32 ro, s32 i16)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
//CHECK ME
|
||||
//CPU.GPR[0]._u64[0] = branchTarget(CPU.PC, i16);
|
||||
//CPU.SetBranch(branchTarget(CPU.PC, ro));
|
||||
}
|
||||
void ILA(u32 rt, s32 i18)
|
||||
{
|
||||
@ -1189,12 +1161,6 @@ private:
|
||||
( CPU.GPR[rc]._u32[i] & CPU.GPR[rb]._u32[i]) |
|
||||
(~CPU.GPR[rc]._u32[i] & CPU.GPR[ra]._u32[i]);
|
||||
}
|
||||
/*
|
||||
CPU.GPR[rt] = _mm_or_si128(
|
||||
_mm_and_si128(CPU.GPR[rc], CPU.GPR[rb]),
|
||||
_mm_andnot_si128(CPU.GPR[rc], CPU.GPR[ra])
|
||||
);
|
||||
*/
|
||||
}
|
||||
void SHUFB(u32 rc, u32 ra, u32 rb, u32 rt)
|
||||
{
|
||||
|
@ -231,8 +231,8 @@ class SPU_Opcodes
|
||||
public:
|
||||
static u32 branchTarget(const u64 pc, const s32 imm)
|
||||
{
|
||||
return (pc + ((imm << 2) & ~0x3)) & 0x3fff0;
|
||||
}
|
||||
return (pc + (imm << 2)) & 0x3fffc;
|
||||
}
|
||||
|
||||
virtual void Exit()=0;
|
||||
|
||||
|
@ -26,8 +26,6 @@ void SPUThread::DoReset()
|
||||
{
|
||||
//reset regs
|
||||
for(u32 i=0; i<128; ++i) GPR[i].Reset();
|
||||
|
||||
LSA = 0;
|
||||
}
|
||||
|
||||
void SPUThread::InitRegs()
|
||||
|
@ -1,29 +1,30 @@
|
||||
#pragma once
|
||||
#include "PPCThread.h"
|
||||
#include "Emu/event.h"
|
||||
|
||||
static const wxString spu_reg_name[128] =
|
||||
{
|
||||
"$LR", "$SP", "$3", "$4", "$5", "$6", "$7", "$8",
|
||||
"$9", "$10", "$11", "$12", "$13", "$14", "$15", "$16",
|
||||
"$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24",
|
||||
"$25", "$26", "$27", "$28", "$29", "$30", "$31", "$32",
|
||||
"$33", "$34", "$35", "$36", "$37", "$38", "$39", "$40",
|
||||
"$41", "$42", "$43", "$44", "$45", "$46", "$47", "$48",
|
||||
"$49", "$50", "$51", "$52", "$53", "$54", "$55", "$56",
|
||||
"$57", "$58", "$59", "$60", "$61", "$62", "$63", "$64",
|
||||
"$65", "$66", "$67", "$68", "$69", "$70", "$71", "$72",
|
||||
"$73", "$74", "$75", "$76", "$77", "$78", "$79", "$80",
|
||||
"$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88",
|
||||
"$89", "$90", "$91", "$92", "$93", "$94", "$95", "$96",
|
||||
"$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104",
|
||||
"$105", "$106", "$107", "$108", "$109", "$110", "$111", "$112",
|
||||
"$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120",
|
||||
"$121", "$122", "$123", "$124", "$125", "$126", "$127",
|
||||
"$LR", "$SP", "$2", "$3", "$4", "$5", "$6", "$7",
|
||||
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
||||
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
||||
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
|
||||
"$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39",
|
||||
"$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47",
|
||||
"$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55",
|
||||
"$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63",
|
||||
"$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71",
|
||||
"$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79",
|
||||
"$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87",
|
||||
"$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95",
|
||||
"$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103",
|
||||
"$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111",
|
||||
"$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119",
|
||||
"$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127",
|
||||
};
|
||||
|
||||
static const wxString spu_ch_name[128] =
|
||||
{
|
||||
"$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_RdSigNotify1",
|
||||
"$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_WrEventAck", "$SPU_RdSigNotify1",
|
||||
"$SPU_RdSigNotify2", "$ch5", "$ch6", "$SPU_WrDec", "$SPU_RdDec",
|
||||
"$MFC_WrMSSyncReq", "$ch10", "$SPU_RdEventMask", "$MFC_RdTagMask", "$SPU_RdMachStat",
|
||||
"$SPU_WrSRR0", "$SPU_RdSRR0", "$MFC_LSA", "$MFC_EAH", "$MFC_EAL", "$MFC_Size",
|
||||
@ -82,8 +83,6 @@ enum MFCchannels
|
||||
|
||||
union SPU_GPR_hdr
|
||||
{
|
||||
//__m128i _m128i;
|
||||
|
||||
u128 _u128;
|
||||
s128 _i128;
|
||||
u64 _u64[2];
|
||||
@ -96,19 +95,6 @@ union SPU_GPR_hdr
|
||||
s8 _i8[16];
|
||||
|
||||
SPU_GPR_hdr() {}
|
||||
/*
|
||||
SPU_GPR_hdr(const __m128i val){_u128._u64[0] = val.m128i_u64[0]; _u128._u64[1] = val.m128i_u64[1];}
|
||||
SPU_GPR_hdr(const u128 val) { _u128 = val; }
|
||||
SPU_GPR_hdr(const u64 val) { Reset(); _u64[0] = val; }
|
||||
SPU_GPR_hdr(const u32 val) { Reset(); _u32[0] = val; }
|
||||
SPU_GPR_hdr(const u16 val) { Reset(); _u16[0] = val; }
|
||||
SPU_GPR_hdr(const u8 val) { Reset(); _u8[0] = val; }
|
||||
SPU_GPR_hdr(const s128 val) { _i128 = val; }
|
||||
SPU_GPR_hdr(const s64 val) { Reset(); _i64[0] = val; }
|
||||
SPU_GPR_hdr(const s32 val) { Reset(); _i32[0] = val; }
|
||||
SPU_GPR_hdr(const s16 val) { Reset(); _i16[0] = val; }
|
||||
SPU_GPR_hdr(const s8 val) { Reset(); _i8[0] = val; }
|
||||
*/
|
||||
|
||||
wxString ToString() const
|
||||
{
|
||||
@ -119,41 +105,17 @@ union SPU_GPR_hdr
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
//operator __m128i() { __m128i ret; ret.m128i_u64[0]=_u128._u64[0]; ret.m128i_u64[1]=_u128._u64[1]; return ret; }
|
||||
/*
|
||||
SPU_GPR_hdr operator ^ (__m128i right) { return _mm_xor_si128(*this, right); }
|
||||
SPU_GPR_hdr operator | (__m128i right) { return _mm_or_si128 (*this, right); }
|
||||
SPU_GPR_hdr operator & (__m128i right) { return _mm_and_si128(*this, right); }
|
||||
SPU_GPR_hdr operator << (int right) { return _mm_slli_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator << (__m128i right) { return _mm_sll_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator >> (int right) { return _mm_srai_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator >> (__m128i right) { return _mm_sra_epi32(*this, right); }
|
||||
|
||||
SPU_GPR_hdr operator | (__m128i right) { return _mm_or_si128 (*this, right); }
|
||||
SPU_GPR_hdr operator & (__m128i right) { return _mm_and_si128(*this, right); }
|
||||
SPU_GPR_hdr operator << (int right) { return _mm_slli_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator << (__m128i right) { return _mm_sll_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator >> (int right) { return _mm_srai_epi32(*this, right); }
|
||||
SPU_GPR_hdr operator >> (__m128i right) { return _mm_sra_epi32(*this, right); }
|
||||
|
||||
SPU_GPR_hdr operator ^= (__m128i right) { return *this = *this ^ right; }
|
||||
SPU_GPR_hdr operator |= (__m128i right) { return *this = *this | right; }
|
||||
SPU_GPR_hdr operator &= (__m128i right) { return *this = *this & right; }
|
||||
SPU_GPR_hdr operator <<= (int right) { return *this = *this << right; }
|
||||
SPU_GPR_hdr operator <<= (__m128i right){ return *this = *this << right; }
|
||||
SPU_GPR_hdr operator >>= (int right) { return *this = *this >> right; }
|
||||
SPU_GPR_hdr operator >>= (__m128i right){ return *this = *this >> right; }
|
||||
*/
|
||||
};
|
||||
|
||||
class SPUThread : public PPCThread
|
||||
{
|
||||
public:
|
||||
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
||||
Stack<u32> Mbox;
|
||||
SizedStack<u32, 1> OutMbox;
|
||||
SizedStack<u32, 1> OutIntrMbox;
|
||||
SizedStack<u32, 4> InMbox;
|
||||
|
||||
u32 LSA; //local storage address
|
||||
u32 LSA;
|
||||
|
||||
union
|
||||
{
|
||||
@ -165,11 +127,14 @@ public:
|
||||
{
|
||||
switch(ch)
|
||||
{
|
||||
case SPU_WrOutMbox:
|
||||
return OutMbox.GetFreeCount();
|
||||
|
||||
case SPU_RdInMbox:
|
||||
return 1;
|
||||
return InMbox.GetCount();
|
||||
|
||||
case SPU_WrOutIntrMbox:
|
||||
return 0;
|
||||
return 0;//return OutIntrMbox.GetFreeCount();
|
||||
|
||||
default:
|
||||
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
|
||||
@ -181,12 +146,24 @@ public:
|
||||
|
||||
void WriteChannel(u32 ch, const SPU_GPR_hdr& r)
|
||||
{
|
||||
const u32 v = r._u32[0];
|
||||
const u32 v = r._u32[3];
|
||||
|
||||
switch(ch)
|
||||
{
|
||||
case SPU_WrOutIntrMbox:
|
||||
Mbox.Push(v);
|
||||
ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v);
|
||||
if(!OutIntrMbox.Push(v))
|
||||
{
|
||||
ConLog.Warning("Not enought free rooms.");
|
||||
}
|
||||
break;
|
||||
|
||||
case SPU_WrOutMbox:
|
||||
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
|
||||
if(!OutMbox.Push(v))
|
||||
{
|
||||
ConLog.Warning("Not enought free rooms.");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -198,12 +175,12 @@ public:
|
||||
void ReadChannel(SPU_GPR_hdr& r, u32 ch)
|
||||
{
|
||||
r.Reset();
|
||||
u32& v = r._u32[0];
|
||||
u32& v = r._u32[3];
|
||||
|
||||
switch(ch)
|
||||
{
|
||||
case SPU_RdInMbox:
|
||||
v = Mbox.Pop();
|
||||
if(!InMbox.Pop(v)) v = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -212,17 +189,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
u8 ReadLSA8 () { return Memory.Read8 (LSA + m_offset); }
|
||||
u16 ReadLSA16 () { return Memory.Read16 (LSA + m_offset); }
|
||||
u32 ReadLSA32 () { return Memory.Read32 (LSA + m_offset); }
|
||||
u64 ReadLSA64 () { return Memory.Read64 (LSA + m_offset); }
|
||||
u128 ReadLSA128() { return Memory.Read128(LSA + m_offset); }
|
||||
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa); }
|
||||
u8 ReadLS8 (const u32 lsa) const { return Memory.Read8 (lsa + (m_offset & 0x3fffc)); }
|
||||
u16 ReadLS16 (const u32 lsa) const { return Memory.Read16 (lsa + m_offset); }
|
||||
u32 ReadLS32 (const u32 lsa) const { return Memory.Read32 (lsa + m_offset); }
|
||||
u64 ReadLS64 (const u32 lsa) const { return Memory.Read64 (lsa + m_offset); }
|
||||
u128 ReadLS128(const u32 lsa) const { return Memory.Read128(lsa + m_offset); }
|
||||
|
||||
void WriteLSA8 (const u8& data) { Memory.Write8 (LSA + m_offset, data); }
|
||||
void WriteLSA16 (const u16& data) { Memory.Write16 (LSA + m_offset, data); }
|
||||
void WriteLSA32 (const u32& data) { Memory.Write32 (LSA + m_offset, data); }
|
||||
void WriteLSA64 (const u64& data) { Memory.Write64 (LSA + m_offset, data); }
|
||||
void WriteLSA128(const u128& data) { Memory.Write128(LSA + m_offset, data); }
|
||||
void WriteLS8 (const u32 lsa, const u8& data) const { Memory.Write8 (lsa + m_offset, data); }
|
||||
void WriteLS16 (const u32 lsa, const u16& data) const { Memory.Write16 (lsa + m_offset, data); }
|
||||
void WriteLS32 (const u32 lsa, const u32& data) const { Memory.Write32 (lsa + m_offset, data); }
|
||||
void WriteLS64 (const u32 lsa, const u64& data) const { Memory.Write64 (lsa + m_offset, data); }
|
||||
void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
|
||||
|
||||
public:
|
||||
SPUThread();
|
||||
|
@ -529,6 +529,8 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data)
|
||||
|
||||
u8 MemoryBase::Read8(u64 addr)
|
||||
{
|
||||
if(enable_log && addr >= 0xd0010a84)
|
||||
ConLog.Warning("Read8 from block: [%08llx]", addr);
|
||||
MemoryBlock& mem = GetMemByAddr(addr);
|
||||
if(mem.IsNULL())
|
||||
{
|
||||
@ -540,6 +542,8 @@ u8 MemoryBase::Read8(u64 addr)
|
||||
|
||||
u16 MemoryBase::Read16(u64 addr)
|
||||
{
|
||||
if(enable_log && addr >= 0xd0010a84)
|
||||
ConLog.Warning("Read16 from block: [%08llx]", addr);
|
||||
MemoryBlock& mem = GetMemByAddr(addr);
|
||||
if(mem.IsNULL())
|
||||
{
|
||||
@ -551,6 +555,8 @@ u16 MemoryBase::Read16(u64 addr)
|
||||
|
||||
u32 MemoryBase::Read32(u64 addr)
|
||||
{
|
||||
if(enable_log && addr >= 0xd0010a84)
|
||||
ConLog.Warning("Read32 from block: [%08llx]", addr);
|
||||
MemoryBlock& mem = GetMemByAddr(addr);
|
||||
if(mem.IsNULL())
|
||||
{
|
||||
@ -562,6 +568,8 @@ u32 MemoryBase::Read32(u64 addr)
|
||||
|
||||
u64 MemoryBase::Read64(u64 addr)
|
||||
{
|
||||
if(enable_log && addr >= 0xd0010a84)
|
||||
ConLog.Warning("Read64 from block: [%08llx]", addr);
|
||||
MemoryBlock& mem = GetMemByAddr(addr);
|
||||
if(mem.IsNULL())
|
||||
{
|
||||
|
@ -3583,7 +3583,7 @@ s64 SysCalls::DoFunc(const u32 id)
|
||||
case 0x2f85c0ef: return sys_lwmutex_create(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: sys_lwmutex_create");
|
||||
case 0x3172759d: FUNC_LOG_ERROR("TODO: sys_game_get_temperature");
|
||||
case 0x318f17e1: FUNC_LOG_ERROR("TODO: _sys_memalign");
|
||||
case 0x350d454e: return sys_ppu_thread_get_id();//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id");
|
||||
case 0x350d454e: return sys_ppu_thread_get_id(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: sys_ppu_thread_get_id");
|
||||
case 0x35168520: return sys_heap_malloc(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: _sys_heap_malloc");
|
||||
case 0x3bd53c7b: FUNC_LOG_ERROR("TODO: _sys_memchr");
|
||||
case 0x3dd4a957: FUNC_LOG_ERROR("TODO: sys_ppu_thread_register_atexit");
|
||||
@ -3647,7 +3647,7 @@ s64 SysCalls::DoFunc(const u32 id)
|
||||
case 0xa285139d: FUNC_LOG_ERROR("TODO: sys_spinlock_lock");
|
||||
case 0xa2c7ba64: FUNC_LOG_ERROR("TODO: sys_prx_exitspawn_with_level");
|
||||
case 0xa330ad84: FUNC_LOG_ERROR("TODO: sys_prx_load_module_on_memcontainer_by_fd");
|
||||
case 0xa3e3be68: FUNC_LOG_ERROR("TODO: sys_ppu_thread_once");
|
||||
case 0xa3e3be68: sys_ppu_thread_once(SC_ARGS_2); return SC_ARGS_1;//FUNC_LOG_ERROR("TODO: sys_ppu_thread_once");
|
||||
case 0xa5d06bf0: FUNC_LOG_ERROR("TODO: sys_prx_get_module_list");
|
||||
case 0xaa6d9bff: FUNC_LOG_ERROR("TODO: sys_prx_load_module_on_memcontainer");
|
||||
case 0xac6fc404: FUNC_LOG_ERROR("TODO: sys_ppu_thread_unregister_atexit");
|
||||
|
235
rpcs3/Emu/SysCalls/Modules.cpp
Normal file
235
rpcs3/Emu/SysCalls/Modules.cpp
Normal file
@ -0,0 +1,235 @@
|
||||
#include "stdafx.h"
|
||||
#include "SysCalls.h"
|
||||
#include "SC_FUNC.h"
|
||||
|
||||
Module* g_modules[50];
|
||||
uint g_modules_count = 0;
|
||||
ArrayF<ModuleFunc> g_modules_funcs_list;
|
||||
|
||||
bool IsLoadedFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CallFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
(*g_modules_funcs_list[i].func)();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnloadFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
g_modules_funcs_list.RemoveAt(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UnloadModules()
|
||||
{
|
||||
for(u32 i=0; i<g_modules_count; ++i)
|
||||
{
|
||||
g_modules[i]->SetLoaded(false);
|
||||
}
|
||||
|
||||
g_modules_funcs_list.Clear();
|
||||
}
|
||||
|
||||
Module* GetModuleByName(const wxString& name)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_count; ++i)
|
||||
{
|
||||
if(g_modules[i]->GetName().Cmp(name) == 0)
|
||||
{
|
||||
return g_modules[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Module* GetModuleById(u16 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_count; ++i)
|
||||
{
|
||||
if(g_modules[i]->GetID() == id)
|
||||
{
|
||||
return g_modules[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Module::Module(const char* name, u16 id, void (*init)())
|
||||
: m_is_loaded(false)
|
||||
, m_name(name)
|
||||
, m_id(id)
|
||||
{
|
||||
g_modules[g_modules_count++] = this;
|
||||
init();
|
||||
}
|
||||
|
||||
void Module::Load()
|
||||
{
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(IsLoadedFunc(m_funcs_list[i].id)) continue;
|
||||
|
||||
g_modules_funcs_list.Add(m_funcs_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Module::UnLoad()
|
||||
{
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
UnloadFunc(m_funcs_list[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::Load(u32 id)
|
||||
{
|
||||
if(IsLoadedFunc(id)) return false;
|
||||
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(m_funcs_list[i].id == id)
|
||||
{
|
||||
g_modules_funcs_list.Add(m_funcs_list[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Module::UnLoad(u32 id)
|
||||
{
|
||||
return UnloadFunc(id);
|
||||
}
|
||||
|
||||
void Module::SetLoaded(bool loaded)
|
||||
{
|
||||
m_is_loaded = loaded;
|
||||
}
|
||||
|
||||
bool Module::IsLoaded() const
|
||||
{
|
||||
return m_is_loaded;
|
||||
}
|
||||
|
||||
u16 Module::GetID() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
wxString Module::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Module::Log(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
if(enable_log)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
}
|
||||
|
||||
void Module::Log(wxString fmt, ...)
|
||||
{
|
||||
if(enable_log)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
}
|
||||
|
||||
void Module::Warning(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Warning(GetName() + wxString::Format("[%d] warning: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
void Module::Warning(wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Warning(GetName() + " warning: " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
void Module::Error(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Error(GetName() + wxString::Format("[%d] error: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
void Module::Error(wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Error(GetName() + " error: " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
bool Module::CheckId(u32 id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
bool Module::CheckId(u32 id, ID& _id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
template<typename T> bool Module::CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID id_data;
|
||||
|
||||
if(!CheckId(id, id_data)) return false;
|
||||
|
||||
data = (T*)id_data.m_data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 Module::GetNewId(void* data, u8 flags)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
|
||||
}
|
76
rpcs3/Emu/SysCalls/Modules.h
Normal file
76
rpcs3/Emu/SysCalls/Modules.h
Normal file
@ -0,0 +1,76 @@
|
||||
#pragma once
|
||||
|
||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||
|
||||
class func_caller
|
||||
{
|
||||
public:
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
static func_caller *null_func = nullptr;
|
||||
|
||||
//TODO
|
||||
struct ModuleFunc
|
||||
{
|
||||
u32 id;
|
||||
func_caller* func;
|
||||
|
||||
ModuleFunc(u32 id, func_caller* func)
|
||||
: id(id)
|
||||
, func(func)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Module
|
||||
{
|
||||
const char* m_name;
|
||||
const u16 m_id;
|
||||
bool m_is_loaded;
|
||||
|
||||
public:
|
||||
Array<ModuleFunc> m_funcs_list;
|
||||
|
||||
Module(const char* name, u16 id, void (*init)());
|
||||
|
||||
void Load();
|
||||
void UnLoad();
|
||||
bool Load(u32 id);
|
||||
bool UnLoad(u32 id);
|
||||
|
||||
void SetLoaded(bool loaded = true);
|
||||
bool IsLoaded() const;
|
||||
|
||||
u16 GetID() const;
|
||||
wxString GetName() const;
|
||||
|
||||
public:
|
||||
void Log(const u32 id, wxString fmt, ...);
|
||||
void Log(wxString fmt, ...);
|
||||
|
||||
void Warning(const u32 id, wxString fmt, ...);
|
||||
void Warning(wxString fmt, ...);
|
||||
|
||||
void Error(const u32 id, wxString fmt, ...);
|
||||
void Error(wxString fmt, ...);
|
||||
|
||||
bool CheckId(u32 id) const;
|
||||
|
||||
bool CheckId(u32 id, ID& _id) const;
|
||||
|
||||
template<typename T> bool CheckId(u32 id, T*& data);
|
||||
|
||||
u32 GetNewId(void* data = nullptr, u8 flags = 0);
|
||||
__forceinline void Module::AddFunc(u32 id, func_caller* func)
|
||||
{
|
||||
m_funcs_list.Move(new ModuleFunc(id, func));
|
||||
}
|
||||
};
|
||||
|
||||
bool IsLoadedFunc(u32 id);
|
||||
bool CallFunc(u32 id);
|
||||
bool UnloadFunc(u32 id);
|
||||
void UnloadModules();
|
||||
Module* GetModuleByName(const wxString& name);
|
||||
Module* GetModuleById(u16 id);
|
@ -2,7 +2,8 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
Module cellGcmSys("cellGcmSys", 0x0010);
|
||||
void cellGcmSys_init();
|
||||
Module cellGcmSys("cellGcmSys", 0x0010, cellGcmSys_init);
|
||||
|
||||
s64 cellGcmFunc15()
|
||||
{
|
||||
@ -16,25 +17,22 @@ s64 cellGcmSetFlipCommandWithWaitLabel()
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct _cellGcmSys_init
|
||||
void cellGcmSys_init()
|
||||
{
|
||||
_cellGcmSys_init()
|
||||
{
|
||||
cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize));
|
||||
cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit));
|
||||
cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush));
|
||||
cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset));
|
||||
cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15));
|
||||
cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode));
|
||||
cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize));
|
||||
cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus));
|
||||
cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize));
|
||||
cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize));
|
||||
cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer));
|
||||
cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister));
|
||||
cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus));
|
||||
cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel));
|
||||
cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration));
|
||||
cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull));
|
||||
}
|
||||
} _cellGcmSys_init;
|
||||
cellGcmSys.AddFunc(0x055bd74d, bind_func(cellGcmGetTiledPitchSize));
|
||||
cellGcmSys.AddFunc(0x15bae46b, bind_func(cellGcmInit));
|
||||
cellGcmSys.AddFunc(0x21397818, bind_func(cellGcmFlush));
|
||||
cellGcmSys.AddFunc(0x21ac3697, bind_func(cellGcmAddressToOffset));
|
||||
cellGcmSys.AddFunc(0x3a33c1fd, bind_func(cellGcmFunc15));
|
||||
cellGcmSys.AddFunc(0x4ae8d215, bind_func(cellGcmSetFlipMode));
|
||||
cellGcmSys.AddFunc(0x5e2ee0f0, bind_func(cellGcmGetDefaultCommandWordSize));
|
||||
cellGcmSys.AddFunc(0x72a577ce, bind_func(cellGcmGetFlipStatus));
|
||||
cellGcmSys.AddFunc(0x8cdf8c70, bind_func(cellGcmGetDefaultSegmentWordSize));
|
||||
cellGcmSys.AddFunc(0x9ba451e4, bind_func(cellGcmSetDefaultFifoSize));
|
||||
cellGcmSys.AddFunc(0xa53d12ae, bind_func(cellGcmSetDisplayBuffer));
|
||||
cellGcmSys.AddFunc(0xa547adde, bind_func(cellGcmGetControlRegister));
|
||||
cellGcmSys.AddFunc(0xb2e761d4, bind_func(cellGcmResetFlipStatus));
|
||||
cellGcmSys.AddFunc(0xd8f88e1a, bind_func(cellGcmSetFlipCommandWithWaitLabel));
|
||||
cellGcmSys.AddFunc(0xe315a0b2, bind_func(cellGcmGetConfiguration));
|
||||
cellGcmSys.AddFunc(0x9dc04436, bind_func(cellGcmBindZcull));
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
Module sysPrxForUser("sysPrxForUser", -1);
|
||||
void sysPrxForUser_init();
|
||||
Module sysPrxForUser("sysPrxForUser", -1, sysPrxForUser_init);
|
||||
|
||||
void sys_initialize_tls()
|
||||
{
|
||||
@ -21,6 +22,12 @@ s64 sys_process_at_Exitspawn()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5)
|
||||
{
|
||||
sysPrxForUser.Warning("sys_spu_printf_initialize(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)", a1, a2, a3, a4, a5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s64 sys_prx_register_library()
|
||||
{
|
||||
sysPrxForUser.Error("sys_prx_register_library()");
|
||||
@ -40,36 +47,36 @@ s64 sys_strlen(u32 addr)
|
||||
return str.Len();
|
||||
}
|
||||
|
||||
struct _sysPrxForUser_init
|
||||
void sysPrxForUser_init()
|
||||
{
|
||||
_sysPrxForUser_init()
|
||||
{
|
||||
sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls));
|
||||
sysPrxForUser.AddFunc(0x744680a2, bind_func(sys_initialize_tls));
|
||||
|
||||
sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create));
|
||||
sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy));
|
||||
sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock));
|
||||
sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock));
|
||||
sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock));
|
||||
|
||||
sysPrxForUser.AddFunc(0x2f85c0ef, bind_func(sys_lwmutex_create));
|
||||
sysPrxForUser.AddFunc(0xc3476d0c, bind_func(sys_lwmutex_destroy));
|
||||
sysPrxForUser.AddFunc(0x1573dc3f, bind_func(sys_lwmutex_lock));
|
||||
sysPrxForUser.AddFunc(0xaeb78725, bind_func(sys_lwmutex_trylock));
|
||||
sysPrxForUser.AddFunc(0x1bc200f4, bind_func(sys_lwmutex_unlock));
|
||||
sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time));
|
||||
|
||||
sysPrxForUser.AddFunc(0x8461e528, bind_func(sys_time_get_system_time));
|
||||
sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit));
|
||||
sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn));
|
||||
sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn));
|
||||
|
||||
sysPrxForUser.AddFunc(0xe6f2c1e7, bind_func(sys_process_exit));
|
||||
sysPrxForUser.AddFunc(0x2c847572, bind_func(sys_process_atexitspawn));
|
||||
sysPrxForUser.AddFunc(0x96328741, bind_func(sys_process_at_Exitspawn));
|
||||
sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create));
|
||||
sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id));
|
||||
sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit));
|
||||
sysPrxForUser.AddFunc(0xa3e3be68, bind_func(sys_ppu_thread_once));
|
||||
|
||||
sysPrxForUser.AddFunc(0x24a1ea07, bind_func(sys_ppu_thread_create));
|
||||
sysPrxForUser.AddFunc(0x350d454e, bind_func(sys_ppu_thread_get_id));
|
||||
sysPrxForUser.AddFunc(0xaff080a4, bind_func(sys_ppu_thread_exit));
|
||||
sysPrxForUser.AddFunc(0x45fe2fce, bind_func(sys_spu_printf_initialize));
|
||||
|
||||
sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library));
|
||||
sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level));
|
||||
sysPrxForUser.AddFunc(0x42b23552, bind_func(sys_prx_register_library));
|
||||
sysPrxForUser.AddFunc(0xa2c7ba64, bind_func(sys_prx_exitspawn_with_level));
|
||||
|
||||
sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen));
|
||||
sysPrxForUser.AddFunc(0x2d36462b, bind_func(sys_strlen));
|
||||
|
||||
sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc));
|
||||
//sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free>);
|
||||
//sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap>);
|
||||
sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap));
|
||||
}
|
||||
} sysPrxForUser_init;
|
||||
sysPrxForUser.AddFunc(0x35168520, bind_func(sys_heap_malloc));
|
||||
//sysPrxForUser.AddFunc(0xaede4b03, bind_func(sys_heap_free));
|
||||
//sysPrxForUser.AddFunc(0x8a561d92, bind_func(sys_heap_delete_heap));
|
||||
sysPrxForUser.AddFunc(0xb2fcf2c8, bind_func(sys_heap_create_heap));
|
||||
}
|
||||
|
@ -2,25 +2,23 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
Module sys_fs("sys_fs", 0x000e);
|
||||
void sys_fs_init();
|
||||
Module sys_fs("sys_fs", 0x000e, sys_fs_init);
|
||||
|
||||
struct _sys_fs_init
|
||||
void sys_fs_init()
|
||||
{
|
||||
_sys_fs_init()
|
||||
{
|
||||
sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen));
|
||||
sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead));
|
||||
sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite));
|
||||
sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose));
|
||||
sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir));
|
||||
sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir));
|
||||
sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir));
|
||||
sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat));
|
||||
sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat));
|
||||
sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir));
|
||||
sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename));
|
||||
sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir));
|
||||
sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink));
|
||||
sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek));
|
||||
}
|
||||
} sys_fs_init;
|
||||
sys_fs.AddFunc(0x718bf5f8, bind_func(cellFsOpen));
|
||||
sys_fs.AddFunc(0x4d5ff8e2, bind_func(cellFsRead));
|
||||
sys_fs.AddFunc(0xecdcf2ab, bind_func(cellFsWrite));
|
||||
sys_fs.AddFunc(0x2cb51f0d, bind_func(cellFsClose));
|
||||
sys_fs.AddFunc(0x3f61245c, bind_func(cellFsOpendir));
|
||||
sys_fs.AddFunc(0x5c74903d, bind_func(cellFsReaddir));
|
||||
sys_fs.AddFunc(0xff42dcc3, bind_func(cellFsClosedir));
|
||||
sys_fs.AddFunc(0x7de6dced, bind_func(cellFsStat));
|
||||
sys_fs.AddFunc(0xef3efa34, bind_func(cellFsFstat));
|
||||
sys_fs.AddFunc(0xba901fe6, bind_func(cellFsMkdir));
|
||||
sys_fs.AddFunc(0xf12eecc8, bind_func(cellFsRename));
|
||||
sys_fs.AddFunc(0x2796fdf3, bind_func(cellFsRmdir));
|
||||
sys_fs.AddFunc(0x7f4677a8, bind_func(cellFsUnlink));
|
||||
sys_fs.AddFunc(0xa397d042, bind_func(cellFsLseek));
|
||||
}
|
||||
|
@ -2,19 +2,17 @@
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/SysCalls/SC_FUNC.h"
|
||||
|
||||
Module sys_io("sys_io", 0x0017);
|
||||
void sys_io_init();
|
||||
Module sys_io("sys_io", 0x0017, sys_io_init);
|
||||
|
||||
struct _sys_io_init
|
||||
void sys_io_init()
|
||||
{
|
||||
_sys_io_init()
|
||||
{
|
||||
sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit));
|
||||
sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd));
|
||||
sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf));
|
||||
sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData));
|
||||
sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra));
|
||||
sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect));
|
||||
sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2));
|
||||
sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting));
|
||||
}
|
||||
} sys_io_init;
|
||||
sys_io.AddFunc(0x1cf98800, bind_func(cellPadInit));
|
||||
sys_io.AddFunc(0x4d9b75d5, bind_func(cellPadEnd));
|
||||
sys_io.AddFunc(0x0d5f2c14, bind_func(cellPadClearBuf));
|
||||
sys_io.AddFunc(0x8b72cda1, bind_func(cellPadGetData));
|
||||
sys_io.AddFunc(0x6bc09c61, bind_func(cellPadGetDataExtra));
|
||||
sys_io.AddFunc(0xf65544ee, bind_func(cellPadSetActDirect));
|
||||
sys_io.AddFunc(0xa703a51d, bind_func(cellPadGetInfo2));
|
||||
sys_io.AddFunc(0x578e3c98, bind_func(cellPadSetPortSetting));
|
||||
}
|
||||
|
@ -1,137 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "SysCalls.h"
|
||||
#include "Modules.h"
|
||||
#include "SC_FUNC.h"
|
||||
#include <vector>
|
||||
|
||||
ArrayF<ModuleFunc> g_modules_funcs_list;
|
||||
ArrayF<Module> g_modules_list;
|
||||
|
||||
bool IsLoadedFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CallFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
(*g_modules_funcs_list[i].func)();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UnloadFunc(u32 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_funcs_list[i].id == id)
|
||||
{
|
||||
g_modules_funcs_list.RemoveAt(i);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UnloadModules()
|
||||
{
|
||||
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
|
||||
{
|
||||
g_modules_list[i].SetLoaded(false);
|
||||
}
|
||||
|
||||
g_modules_funcs_list.Clear();
|
||||
}
|
||||
|
||||
Module* GetModuleByName(const wxString& name)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_list[i].GetName().Cmp(name) == 0)
|
||||
{
|
||||
return &g_modules_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Module* GetModuleById(u16 id)
|
||||
{
|
||||
for(u32 i=0; i<g_modules_list.GetCount(); ++i)
|
||||
{
|
||||
if(g_modules_list[i].GetID() == id)
|
||||
{
|
||||
return &g_modules_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Module::Module(const char* name, u16 id)
|
||||
: m_is_loaded(false)
|
||||
, m_name(name)
|
||||
, m_id(id)
|
||||
{
|
||||
g_modules_list.Add(this);
|
||||
}
|
||||
|
||||
void Module::Load()
|
||||
{
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(IsLoadedFunc(m_funcs_list[i].id)) continue;
|
||||
|
||||
g_modules_funcs_list.Add(m_funcs_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Module::UnLoad()
|
||||
{
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
UnloadFunc(m_funcs_list[i].id);
|
||||
}
|
||||
}
|
||||
|
||||
bool Module::Load(u32 id)
|
||||
{
|
||||
if(IsLoadedFunc(id)) return false;
|
||||
|
||||
for(u32 i=0; i<m_funcs_list.GetCount(); ++i)
|
||||
{
|
||||
if(m_funcs_list[i].id == id)
|
||||
{
|
||||
g_modules_funcs_list.Add(m_funcs_list[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Module::UnLoad(u32 id)
|
||||
{
|
||||
return UnloadFunc(id);
|
||||
}
|
||||
|
||||
static func_caller* sc_table[1024] =
|
||||
{
|
||||
@ -160,20 +30,20 @@ static func_caller* sc_table[1024] =
|
||||
null_func, null_func, null_func, null_func, null_func, //114
|
||||
null_func, null_func, null_func, null_func, null_func, //119
|
||||
null_func, null_func, null_func, null_func, null_func, //124
|
||||
null_func, null_func, null_func, null_func, null_func, //129
|
||||
null_func, null_func, null_func, null_func, null_func, //134
|
||||
null_func, null_func, null_func, null_func, null_func, //139
|
||||
null_func, null_func, null_func, bind_func(sys_event_queue_create), null_func, //129
|
||||
bind_func(sys_event_queue_receive), null_func, null_func, null_func, bind_func(sys_event_port_create), //134
|
||||
null_func, bind_func(sys_event_port_connect_local), null_func, null_func, null_func, //139
|
||||
null_func, null_func, null_func, null_func, null_func, //144
|
||||
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
|
||||
null_func, null_func, null_func, null_func, null_func, //154
|
||||
null_func, null_func, null_func, null_func, null_func, //159
|
||||
null_func, bind_func(sys_spu_image_open), null_func, null_func, null_func, //159
|
||||
bind_func(sys_raw_spu_create), null_func, null_func, null_func, null_func, //164
|
||||
null_func, null_func, null_func, null_func, bind_func(sys_spu_initialize), //169
|
||||
bind_func(sys_spu_thread_group_create), null_func, null_func, null_func, null_func, //174
|
||||
bind_func(sys_spu_thread_group_create), null_func, bind_func(sys_spu_thread_initialize), bind_func(sys_spu_thread_group_start), null_func, //174
|
||||
null_func, null_func, null_func, null_func, null_func, //179
|
||||
null_func, null_func, null_func, null_func, null_func, //184
|
||||
null_func, bind_func(sys_spu_thread_write_ls), bind_func(sys_spu_thread_read_ls), null_func, null_func, //184
|
||||
null_func, null_func, null_func, null_func, null_func, //189
|
||||
null_func, null_func, null_func, null_func, null_func, //194
|
||||
bind_func(sys_spu_thread_write_spu_mb), null_func, null_func, null_func, null_func, //194
|
||||
null_func, null_func, null_func, null_func, null_func, //199
|
||||
null_func, null_func, null_func, null_func, null_func, //204
|
||||
null_func, null_func, null_func, null_func, null_func, //209
|
||||
@ -185,7 +55,7 @@ static func_caller* sc_table[1024] =
|
||||
null_func, null_func, null_func, null_func, null_func, //239
|
||||
null_func, null_func, null_func, null_func, null_func, //244
|
||||
null_func, null_func, null_func, null_func, null_func, //249
|
||||
null_func, null_func, null_func, null_func, null_func, //254
|
||||
null_func, bind_func(sys_spu_thread_group_connect_event_all_threads), null_func, null_func, null_func, //254
|
||||
null_func, null_func, null_func, null_func, null_func, //259
|
||||
null_func, null_func, null_func, null_func, null_func, //264
|
||||
null_func, null_func, null_func, null_func, null_func, //269
|
||||
@ -350,55 +220,67 @@ SysCalls::~SysCalls()
|
||||
{
|
||||
}
|
||||
|
||||
s64 SysCalls::DoSyscall(u32 code)
|
||||
bool enable_log = false;
|
||||
|
||||
void SysCalls::DoSyscall(u32 code)
|
||||
{
|
||||
if(code < 0x400)
|
||||
{
|
||||
if(sc_table[code])
|
||||
{
|
||||
(*sc_table[code])();
|
||||
return SC_ARGS_1;
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: remove this
|
||||
switch(code)
|
||||
{
|
||||
//process
|
||||
case 2: return lv2ProcessWaitForChild(CPU);
|
||||
case 4: return lv2ProcessGetStatus(CPU);
|
||||
case 5: return lv2ProcessDetachChild(CPU);
|
||||
case 12: return lv2ProcessGetNumberOfObject(CPU);
|
||||
case 13: return lv2ProcessGetId(CPU);
|
||||
case 18: return lv2ProcessGetPpid(CPU);
|
||||
case 19: return lv2ProcessKill(CPU);
|
||||
case 23: return lv2ProcessWaitForChild2(CPU);
|
||||
case 25: return lv2ProcessGetSdkVersion(CPU);
|
||||
case 2: RESULT(lv2ProcessWaitForChild(CPU)); return;
|
||||
case 4: RESULT(lv2ProcessGetStatus(CPU)); return;
|
||||
case 5: RESULT(lv2ProcessDetachChild(CPU)); return;
|
||||
case 12: RESULT(lv2ProcessGetNumberOfObject(CPU)); return;
|
||||
case 13: RESULT(lv2ProcessGetId(CPU)); return;
|
||||
case 18: RESULT(lv2ProcessGetPpid(CPU)); return;
|
||||
case 19: RESULT(lv2ProcessKill(CPU)); return;
|
||||
case 23: RESULT(lv2ProcessWaitForChild2(CPU)); return;
|
||||
case 25: RESULT(lv2ProcessGetSdkVersion(CPU)); return;
|
||||
//timer
|
||||
case 141:
|
||||
case 142:
|
||||
Sleep(SC_ARGS_1 / (1000 * 1000));
|
||||
return 0;
|
||||
RESULT(0);
|
||||
return;
|
||||
|
||||
//tty
|
||||
case 988:
|
||||
ConLog.Warning("SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",
|
||||
CPU.GPR[3], CPU.GPR[4], CPU.PC);
|
||||
return 0;
|
||||
RESULT(0);
|
||||
return;
|
||||
|
||||
case 999:
|
||||
dump_enable = !dump_enable;
|
||||
ConLog.Warning("Dump %s", dump_enable ? "enabled" : "disabled");
|
||||
return 0;
|
||||
return;
|
||||
|
||||
case 1000:
|
||||
enable_log = !enable_log;
|
||||
ConLog.Warning("Log %s", enable_log ? "enabled" : "disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
ConLog.Error("Unknown syscall: %d - %08x", code, code);
|
||||
return 0;
|
||||
RESULT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(CallFunc(code)) return SC_ARGS_1;
|
||||
|
||||
if(CallFunc(code))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//ConLog.Error("Unknown function 0x%08x", code);
|
||||
//return 0;
|
||||
|
||||
//TODO: remove this
|
||||
return DoFunc(code);
|
||||
RESULT(DoFunc(code));
|
||||
}
|
@ -5,161 +5,7 @@
|
||||
|
||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||
|
||||
class func_caller
|
||||
{
|
||||
public:
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
static func_caller *null_func = nullptr;
|
||||
|
||||
//TODO
|
||||
struct ModuleFunc
|
||||
{
|
||||
u32 id;
|
||||
func_caller* func;
|
||||
|
||||
ModuleFunc(u32 id, func_caller* func)
|
||||
: id(id)
|
||||
, func(func)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Module
|
||||
{
|
||||
const char* m_name;
|
||||
const u16 m_id;
|
||||
bool m_is_loaded;
|
||||
|
||||
public:
|
||||
Array<ModuleFunc> m_funcs_list;
|
||||
|
||||
Module(const char* name, u16 id);
|
||||
|
||||
void Load();
|
||||
void UnLoad();
|
||||
bool Load(u32 id);
|
||||
bool UnLoad(u32 id);
|
||||
|
||||
void SetLoaded(bool loaded = true)
|
||||
{
|
||||
m_is_loaded = loaded;
|
||||
}
|
||||
|
||||
bool IsLoaded() const
|
||||
{
|
||||
return m_is_loaded;
|
||||
}
|
||||
|
||||
u16 GetID() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
wxString GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public:
|
||||
void Log(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
#ifdef SYSCALLS_DEBUG
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Log(wxString fmt, ...)
|
||||
{
|
||||
#ifdef SYSCALLS_DEBUG
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Warning(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
//#ifdef SYSCALLS_DEBUG
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Warning(GetName() + wxString::Format("[%d] warning: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
//#endif
|
||||
}
|
||||
|
||||
void Warning(wxString fmt, ...)
|
||||
{
|
||||
//#ifdef SYSCALLS_DEBUG
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Warning(GetName() + " warning: " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
//#endif
|
||||
}
|
||||
|
||||
void Error(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Error(GetName() + wxString::Format("[%d] error: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
void Error(wxString fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Error(GetName() + " error: " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
bool CheckId(u32 id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !Emu.GetIdManager().GetIDData(id).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
bool CheckId(u32 id, ID& _id) const
|
||||
{
|
||||
return Emu.GetIdManager().CheckID(id) && !(_id = Emu.GetIdManager().GetIDData(id)).m_name.Cmp(GetName());
|
||||
}
|
||||
|
||||
template<typename T> bool CheckId(u32 id, T*& data)
|
||||
{
|
||||
ID id_data;
|
||||
|
||||
if(!CheckId(id, id_data)) return false;
|
||||
|
||||
data = (T*)id_data.m_data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 GetNewId(void* data = nullptr, u8 flags = 0)
|
||||
{
|
||||
return Emu.GetIdManager().GetNewID(GetName(), data, flags);
|
||||
}
|
||||
|
||||
//protected:
|
||||
__forceinline void AddFunc(u32 id, func_caller* func)
|
||||
{
|
||||
m_funcs_list.Move(new ModuleFunc(id, func));
|
||||
}
|
||||
};
|
||||
|
||||
static s64 null_function() { return 0; }
|
||||
|
||||
bool IsLoadedFunc(u32 id);
|
||||
bool CallFunc(u32 id);
|
||||
bool UnloadFunc(u32 id);
|
||||
void UnloadModules();
|
||||
Module* GetModuleByName(const wxString& name);
|
||||
Module* GetModuleById(u16 id);
|
||||
extern bool enable_log;
|
||||
|
||||
class SysCallBase //Module
|
||||
{
|
||||
@ -178,22 +24,24 @@ public:
|
||||
|
||||
void Log(const u32 id, wxString fmt, ...)
|
||||
{
|
||||
#ifdef SYSCALLS_DEBUG
|
||||
if(enable_log)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + wxString::Format("[%d]: ", id) + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Log(wxString fmt, ...)
|
||||
{
|
||||
#ifdef SYSCALLS_DEBUG
|
||||
if(enable_log)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, fmt);
|
||||
ConLog.Write(GetName() + ": " + wxString::FormatV(fmt, list));
|
||||
va_end(list);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Warning(const u32 id, wxString fmt, ...)
|
||||
@ -259,40 +107,18 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
static bool CmpPath(const wxString& path1, const wxString& path2)
|
||||
{
|
||||
return path1.Len() >= path2.Len() && path1(0, path2.Len()).CmpNoCase(path2) == 0;
|
||||
}
|
||||
|
||||
static wxString GetWinPath(const wxString& path)
|
||||
{
|
||||
if(!CmpPath(path, "/") && CmpPath(path(1, 1), ":")) return path;
|
||||
|
||||
wxString ppath = wxFileName(Emu.m_path).GetPath() + '/' + wxFileName(path).GetFullName();
|
||||
if(wxFileExists(ppath)) return ppath;
|
||||
|
||||
if (CmpPath(path, "/dev_hdd0/") ||
|
||||
CmpPath(path, "/dev_hdd1/") ||
|
||||
CmpPath(path, "/dev_bdvd/") ||
|
||||
CmpPath(path, "/dev_usb001/") ||
|
||||
CmpPath(path, "/ps3_home/") ||
|
||||
CmpPath(path, "/app_home/") ||
|
||||
CmpPath(path, "/dev_flash/") ||
|
||||
CmpPath(path, "/dev_flash2/") ||
|
||||
CmpPath(path, "/dev_flash3/")
|
||||
) return wxGetCwd() + path;
|
||||
|
||||
return wxFileName(Emu.m_path).GetPath() + (path[0] == '/' ? path : "/" + path);
|
||||
}
|
||||
*/
|
||||
|
||||
//process
|
||||
extern int sys_process_getpid();
|
||||
extern int sys_process_exit(int errorcode);
|
||||
extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_addr,
|
||||
u32 data, u32 data_size, int prio, u64 flags );
|
||||
|
||||
//sys_event
|
||||
extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size);
|
||||
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
|
||||
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
|
||||
extern int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
|
||||
|
||||
//sys_semaphore
|
||||
extern int sys_semaphore_create(u32 sem_addr, u32 attr_addr, int initial_val, int max_val);
|
||||
extern int sys_semaphore_destroy(u32 sem);
|
||||
@ -333,7 +159,9 @@ extern int sys_ppu_thread_get_stack_information(u32 info_addr);
|
||||
extern int sys_ppu_thread_stop(u32 thread_id);
|
||||
extern int sys_ppu_thread_restart(u32 thread_id);
|
||||
extern int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32 stacksize, u64 flags, u32 threadname_addr);
|
||||
extern int sys_ppu_thread_get_id();
|
||||
extern void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry);
|
||||
extern int sys_ppu_thread_get_id(const u32 id_addr);
|
||||
extern int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr);
|
||||
|
||||
//memory
|
||||
extern int sys_memory_container_create(u32 cid_addr, u32 yield_size);
|
||||
@ -421,10 +249,16 @@ extern int sys_heap_create_heap(const u32 heap_addr, const u32 start_addr, const
|
||||
extern int sys_heap_malloc(const u32 heap_addr, const u32 size);
|
||||
|
||||
//sys_spu
|
||||
extern int sys_spu_image_open(u32 img_addr, u32 path_addr);
|
||||
extern int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_addr, u32 attr_addr, u32 arg_addr);
|
||||
extern int sys_spu_thread_group_start(u32 id);
|
||||
extern int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr);
|
||||
extern int sys_spu_thread_create(u64 thread_id_addr, u64 entry_addr, u64 arg, int prio, u32 stacksize, u64 flags, u64 threadname_addr);
|
||||
extern int sys_raw_spu_create(u32 id_addr, u32 attr_addr);
|
||||
extern int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
||||
extern int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
|
||||
extern int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type);
|
||||
extern int sys_spu_thread_write_spu_mb(u32 id, u32 value);
|
||||
|
||||
//sys_time
|
||||
extern int sys_time_get_current_time(u32 sec_addr, u32 nsec_addr);
|
||||
@ -469,7 +303,7 @@ protected:
|
||||
~SysCalls();
|
||||
|
||||
public:
|
||||
s64 DoSyscall(u32 code);
|
||||
void DoSyscall(u32 code);
|
||||
s64 DoFunc(const u32 id);
|
||||
};
|
||||
|
||||
|
137
rpcs3/Emu/SysCalls/lv2/SC_Event.cpp
Normal file
137
rpcs3/Emu/SysCalls/lv2/SC_Event.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/event.h"
|
||||
|
||||
SysCallBase sys_event("sys_event");
|
||||
|
||||
//128
|
||||
int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size)
|
||||
{
|
||||
sys_event.Warning("sys_event_queue_create(equeue_id_addr=0x%x, attr_addr=0x%x, event_queue_key=0x%llx, size=%d)",
|
||||
equeue_id_addr, attr_addr, event_queue_key, size);
|
||||
|
||||
if(size <= 0 || size > 127)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if(!Memory.IsGoodAddr(equeue_id_addr, 4) || !Memory.IsGoodAddr(attr_addr, sizeof(sys_event_queue_attr)))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
auto& attr = (sys_event_queue_attr&)Memory[attr_addr];
|
||||
sys_event.Warning("name = %s", attr.name);
|
||||
sys_event.Warning("type = %d", re(attr.type));
|
||||
EventQueue* equeue = new EventQueue();
|
||||
equeue->size = size;
|
||||
equeue->pos = 0;
|
||||
equeue->type = re(attr.type);
|
||||
strncpy(equeue->name, attr.name, 8);
|
||||
Memory.Write32(equeue_id_addr, sys_event.GetNewId(equeue));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
|
||||
{
|
||||
sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x, event_addr=0x%x, timeout=0x%x)",
|
||||
equeue_id, event_addr, timeout);
|
||||
|
||||
if(!sys_event.CheckId(equeue_id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
PPCThread* thr = GetCurrentPPCThread();
|
||||
|
||||
while(true)
|
||||
{
|
||||
int status = thr->ThreadStatus();
|
||||
if(status == PPCThread_Stopped)
|
||||
{
|
||||
return CELL_ECANCELED;
|
||||
}
|
||||
|
||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data;
|
||||
for(int i=0; i<equeue->pos; ++i)
|
||||
{
|
||||
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
|
||||
{
|
||||
SPUThread* thr = (SPUThread*)equeue->ports[i]->thread;
|
||||
if(thr->OutIntrMbox.GetCount())
|
||||
{
|
||||
u32 val;
|
||||
thr->OutIntrMbox.Pop(val);
|
||||
if(!thr->OutMbox.Pop(val)) val = 0;
|
||||
equeue->ports[i]->data1 = val;
|
||||
equeue->ports[i]->data2 = 0;
|
||||
equeue->ports[i]->data3 = 0;
|
||||
equeue->ports[i]->has_data = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool has_data = false;
|
||||
for(int i=0; i<equeue->pos; i++)
|
||||
{
|
||||
if(equeue->ports[i]->has_data)
|
||||
{
|
||||
has_data = true;
|
||||
auto res = (sys_event_data&)Memory[event_addr];
|
||||
|
||||
re(res.source, equeue->ports[i]->name);
|
||||
re(res.data1, equeue->ports[i]->data1);
|
||||
re(res.data2, equeue->ports[i]->data2);
|
||||
re(res.data3, equeue->ports[i]->data3);
|
||||
|
||||
equeue->ports[i]->has_data = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_data)
|
||||
break;
|
||||
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_create(eport_id_addr=0x%x, port_type=0x%x, name=0x%llx)",
|
||||
eport_id_addr, port_type, name);
|
||||
|
||||
if(!Memory.IsGoodAddr(eport_id_addr, 4))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
EventPort* eport = new EventPort();
|
||||
u32 id = sys_event.GetNewId(eport);
|
||||
eport->has_data = false;
|
||||
eport->name = name ? name : id;
|
||||
Memory.Write32(eport_id_addr, id);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id)
|
||||
{
|
||||
sys_event.Warning("sys_event_port_connect_local(event_port_id=0x%x, event_queue_id=0x%x)",
|
||||
event_port_id, event_queue_id);
|
||||
|
||||
if(!sys_event.CheckId(event_port_id) || !sys_event.CheckId(event_queue_id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
EventPort* eport = (EventPort*)Emu.GetIdManager().GetIDData(event_port_id).m_data;
|
||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(event_queue_id).m_data;
|
||||
equeue->ports[equeue->pos++] = eport;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
@ -33,26 +33,15 @@ SysCallBase sc_lwmutex("sys_wmutex");
|
||||
|
||||
int sys_lwmutex_create(u64 lwmutex_addr, u64 lwmutex_attr_addr)
|
||||
{
|
||||
if(!Memory.IsGoodAddr(lwmutex_addr, 4) || !Memory.IsGoodAddr(lwmutex_attr_addr))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
lmtx.lock_var.all_info = 0;
|
||||
lwmutex_attr& lmtx_attr = (lwmutex_attr&)Memory[lwmutex_attr_addr];
|
||||
|
||||
//sc_lwmutex.Warning("sys_lwmutex_create(lwmutex_addr = 0x%llx, lwmutex_attr_addr = 0x%llx)", lwmutex_addr, lwmutex_attr_addr);
|
||||
|
||||
lmtx.lock_var.info.owner = 0;
|
||||
lmtx.lock_var.info.waiter = 0;
|
||||
|
||||
lmtx.attribute = Emu.GetIdManager().GetNewID(wxString::Format("lwmutex[%s]", lmtx_attr.name), nullptr, lwmutex_addr);
|
||||
/*
|
||||
ConLog.Write("r3:");
|
||||
ConLog.Write("*** lock_var[owner: 0x%x, waiter: 0x%x]", re(lmtx.lock_var.info.owner), re(lmtx.lock_var.info.waiter));
|
||||
ConLog.Write("*** attribute: 0x%x", re(lmtx.attribute));
|
||||
ConLog.Write("*** recursive_count: 0x%x", re(lmtx.recursive_count));
|
||||
ConLog.Write("*** sleep_queue: 0x%x", re(lmtx.sleep_queue));
|
||||
ConLog.Write("r4:");
|
||||
ConLog.Write("*** attr_protocol: 0x%x", re(lmtx_attr.attr_protocol));
|
||||
ConLog.Write("*** attr_recursive: 0x%x", re(lmtx_attr.attr_recursive));
|
||||
ConLog.Write("*** name: %s", lmtx_attr.name);
|
||||
*/
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -60,39 +49,46 @@ int sys_lwmutex_destroy(u64 lwmutex_addr)
|
||||
{
|
||||
//sc_lwmutex.Warning("sys_lwmutex_destroy(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
||||
|
||||
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
Emu.GetIdManager().RemoveID(lmtx.attribute);
|
||||
//lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
//Emu.GetIdManager().RemoveID(lmtx.attribute);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_lwmutex_lock(u64 lwmutex_addr, u64 timeout)
|
||||
{
|
||||
//sc_lwmutex.Warning("sys_lwmutex_lock(lwmutex_addr = 0x%llx, timeout = 0x%llx)", lwmutex_addr, timeout);
|
||||
|
||||
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
|
||||
PPCThread& thr = GetCurrentPPUThread();
|
||||
|
||||
if(thr.GetId() == re(lmtx.lock_var.info.owner))
|
||||
{
|
||||
re(lmtx.recursive_count, re(lmtx.recursive_count) + 1);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if(!lmtx.lock_var.info.owner)
|
||||
{
|
||||
re(lmtx.lock_var.info.owner, GetCurrentPPUThread().GetId());
|
||||
re(lmtx.recursive_count, 1);
|
||||
}
|
||||
else if(!lmtx.lock_var.info.waiter)
|
||||
{
|
||||
re(lmtx.lock_var.info.waiter, GetCurrentPPUThread().GetId());
|
||||
while(re(lmtx.lock_var.info.owner) != GetCurrentPPUThread().GetId()) Sleep(1);
|
||||
thr.Wait(true);
|
||||
re(lmtx.lock_var.info.waiter, thr.GetId());
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
ConLog.Warning("lwmutex has waiter!");
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_lwmutex_trylock(u64 lwmutex_addr)
|
||||
{
|
||||
//sc_lwmutex.Warning("sys_lwmutex_trylock(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
||||
|
||||
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
|
||||
if(lmtx.lock_var.info.owner) return CELL_EBUSY;
|
||||
@ -105,8 +101,21 @@ int sys_lwmutex_unlock(u64 lwmutex_addr)
|
||||
//sc_lwmutex.Warning("sys_lwmutex_unlock(lwmutex_addr = 0x%llx)", lwmutex_addr);
|
||||
|
||||
lwmutex& lmtx = (lwmutex&)Memory[lwmutex_addr];
|
||||
lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter;
|
||||
lmtx.lock_var.info.waiter = 0;
|
||||
|
||||
re(lmtx.recursive_count, re(lmtx.recursive_count) - 1);
|
||||
|
||||
if(!lmtx.recursive_count)
|
||||
{
|
||||
if(lmtx.lock_var.info.owner = lmtx.lock_var.info.waiter)
|
||||
{
|
||||
lmtx.lock_var.info.waiter = 0;
|
||||
PPCThread* thr = Emu.GetCPU().GetThread(lmtx.lock_var.info.owner);
|
||||
if(thr)
|
||||
{
|
||||
thr->Wait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -3,7 +3,12 @@
|
||||
|
||||
extern Module sysPrxForUser;
|
||||
|
||||
#define PPU_THREAD_ID_INVALID 0xFFFFFFFFU
|
||||
static const u32 PPU_THREAD_ID_INVALID = 0xFFFFFFFFU;
|
||||
enum
|
||||
{
|
||||
SYS_PPU_THREAD_ONCE_INIT,
|
||||
SYS_PPU_THREAD_DONE_INIT,
|
||||
};
|
||||
|
||||
int sys_ppu_thread_exit(int errorcode)
|
||||
{
|
||||
@ -15,9 +20,14 @@ int sys_ppu_thread_exit(int errorcode)
|
||||
|
||||
int sys_ppu_thread_yield()
|
||||
{
|
||||
sysPrxForUser.Log("sys_ppu_thread_yield()");
|
||||
wxThread::Yield();
|
||||
sysPrxForUser.Log("sys_ppu_thread_yield()");
|
||||
enable_log = !enable_log;
|
||||
dump_enable = !dump_enable;
|
||||
|
||||
if(!enable_log)
|
||||
{
|
||||
Emu.Pause();
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -110,7 +120,10 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32
|
||||
sysPrxForUser.Log("sys_ppu_thread_create(thread_id_addr=0x%x, entry=0x%x, arg=0x%x, prio=%d, stacksize=0x%x, flags=0x%llx, threadname_addr=0x%x('%s'))",
|
||||
thread_id_addr, entry, arg, prio, stacksize, flags, threadname_addr, Memory.ReadString(threadname_addr));
|
||||
|
||||
if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr) || !Memory.IsGoodAddr(threadname_addr)) return CELL_EFAULT;
|
||||
if(!Memory.IsGoodAddr(entry) || !Memory.IsGoodAddr(thread_id_addr) || !Memory.IsGoodAddr(threadname_addr))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
|
||||
|
||||
@ -127,9 +140,28 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sys_ppu_thread_get_id()
|
||||
void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry)
|
||||
{
|
||||
sysPrxForUser.Log("sys_ppu_thread_get_id()");
|
||||
sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, entry=0x%x)", once_ctrl_addr, entry);
|
||||
|
||||
return GetCurrentPPUThread().GetId();
|
||||
if(Memory.IsGoodAddr(once_ctrl_addr, 4) && Memory.Read32(once_ctrl_addr) == SYS_PPU_THREAD_ONCE_INIT)
|
||||
{
|
||||
Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT);
|
||||
|
||||
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
|
||||
new_thread.SetEntry(entry);
|
||||
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
|
||||
new_thread.Run();
|
||||
new_thread.Exec();
|
||||
|
||||
GetCurrentPPUThread().Wait(new_thread);
|
||||
}
|
||||
}
|
||||
|
||||
int sys_ppu_thread_get_id(const u32 id_addr)
|
||||
{
|
||||
sysPrxForUser.Log("sys_ppu_thread_get_id(id_addr=0x%x)", id_addr);
|
||||
|
||||
Memory.Write32(id_addr, GetCurrentPPUThread().GetId());
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
#include "Loader/ELF.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
|
||||
SysCallBase sc_spu("sys_spu");
|
||||
|
||||
@ -12,6 +13,21 @@ struct sys_spu_thread_group_attribute
|
||||
union{u32 ct;} option;
|
||||
};
|
||||
|
||||
struct sys_spu_thread_attribute
|
||||
{
|
||||
u32 name_addr;
|
||||
u32 name_len;
|
||||
u32 option;
|
||||
};
|
||||
|
||||
struct sys_spu_thread_argument
|
||||
{
|
||||
u64 arg1;
|
||||
u64 arg2;
|
||||
u64 arg3;
|
||||
u64 arg4;
|
||||
};
|
||||
|
||||
struct sys_spu_image
|
||||
{
|
||||
u32 type;
|
||||
@ -20,25 +36,149 @@ struct sys_spu_image
|
||||
int nsegs;
|
||||
};
|
||||
|
||||
u32 LoadImage(vfsStream& stream)
|
||||
struct SpuGroupInfo
|
||||
{
|
||||
PPCThread* threads[10];
|
||||
sys_spu_thread_group_attribute& attr;
|
||||
|
||||
SpuGroupInfo(sys_spu_thread_group_attribute& attr) : attr(attr)
|
||||
{
|
||||
memset(threads, 0, sizeof(PPCThread*) * 10);
|
||||
}
|
||||
};
|
||||
|
||||
u64 g_spu_offset = 0;
|
||||
|
||||
u32 LoadSpuImage(vfsStream& stream)
|
||||
{
|
||||
ELFLoader l(stream);
|
||||
l.LoadInfo();
|
||||
l.LoadData(Memory.MainMem.Alloc(stream.GetSize()));
|
||||
g_spu_offset = Memory.MainMem.Alloc(0xFFFFED - stream.GetSize());
|
||||
l.LoadData(g_spu_offset);
|
||||
|
||||
return l.GetEntry();
|
||||
return g_spu_offset + l.GetEntry();
|
||||
}
|
||||
|
||||
int sys_spu_image_open(u32 img_addr, u32 path_addr)
|
||||
{
|
||||
//156
|
||||
int sys_spu_image_open(u32 img_addr, u32 path_addr)
|
||||
{
|
||||
const wxString& path = Memory.ReadString(path_addr);
|
||||
sc_spu.Warning("sys_spu_image_open(img_addr=0x%x, path_addr=0x%x [%s])", img_addr, path_addr, path);
|
||||
|
||||
vfsLocalFile stream(path);
|
||||
LoadImage(stream);
|
||||
if(!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) || !Memory.IsGoodAddr(path_addr))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
vfsStream* stream = Emu.GetVFS().Open(path, vfsRead);
|
||||
|
||||
if(!stream || !stream->IsOpened())
|
||||
{
|
||||
sc_spu.Error("'%s' not found!", path);
|
||||
delete stream;
|
||||
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
u32 entry = LoadSpuImage(*stream);
|
||||
delete stream;
|
||||
|
||||
sys_spu_image& ret = (sys_spu_image&)Memory[img_addr];
|
||||
re(ret.type, 1);
|
||||
re(ret.entry_point, entry);
|
||||
re(ret.segs_addr, 0x0);
|
||||
re(ret.nsegs, 0);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
//172
|
||||
int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_addr, u32 attr_addr, u32 arg_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_initialize(thread_addr=0x%x, group=0x%x, spu_num=%d, img_addr=0x%x, attr_addr=0x%x, arg_addr=0x%x)",
|
||||
thread_addr, group, spu_num, img_addr, attr_addr, arg_addr);
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(group))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(
|
||||
!Memory.IsGoodAddr(img_addr, sizeof(sys_spu_image)) ||
|
||||
!Memory.IsGoodAddr(attr_addr, sizeof(sys_spu_thread_attribute)) ||
|
||||
!Memory.IsGoodAddr(arg_addr, sizeof(sys_spu_thread_argument)))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
sys_spu_image& img = (sys_spu_image&)Memory[img_addr];
|
||||
sys_spu_thread_attribute& attr = (sys_spu_thread_attribute&)Memory[attr_addr];
|
||||
sys_spu_thread_argument& arg = (sys_spu_thread_argument&)Memory[arg_addr];
|
||||
|
||||
if(!Memory.IsGoodAddr(re(attr.name_addr), re(attr.name_len)))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
u32 entry = re(img.entry_point);
|
||||
wxString name = Memory.ReadString(re(attr.name_addr), re(attr.name_len));
|
||||
u64 a1 = re(arg.arg1);
|
||||
u64 a2 = re(arg.arg2);
|
||||
u64 a3 = re(arg.arg3);
|
||||
u64 a4 = re(arg.arg4);
|
||||
|
||||
ConLog.Write("New SPU Thread:");
|
||||
ConLog.Write("entry = 0x%x", entry);
|
||||
ConLog.Write("name = %s", name);
|
||||
ConLog.Write("a1 = 0x%x", a1);
|
||||
ConLog.Write("a2 = 0x%x", a2);
|
||||
ConLog.Write("a3 = 0x%x", a3);
|
||||
ConLog.Write("a4 = 0x%x", a4);
|
||||
ConLog.SkipLn();
|
||||
|
||||
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
|
||||
new_thread.SetOffset(g_spu_offset);
|
||||
new_thread.SetEntry(entry - g_spu_offset);
|
||||
new_thread.SetName(name);
|
||||
SPU_GPR_hdr* GPR = ((SPUThread&)new_thread).GPR;
|
||||
new_thread.Run();
|
||||
new_thread.Pause();
|
||||
GPR[3]._u64[1] = a1;
|
||||
GPR[4]._u64[1] = a2;
|
||||
GPR[5]._u64[1] = a3;
|
||||
GPR[6]._u64[1] = a4;
|
||||
|
||||
ID& id = Emu.GetIdManager().GetIDData(group);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id.m_data;
|
||||
group_info.threads[spu_num] = &new_thread;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//173
|
||||
int sys_spu_thread_group_start(u32 id)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id);
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
ID& id_data = Emu.GetIdManager().GetIDData(id);
|
||||
SpuGroupInfo& group_info = *(SpuGroupInfo*)id_data.m_data;
|
||||
|
||||
Emu.Pause();
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
if(group_info.threads[i])
|
||||
{
|
||||
group_info.threads[i]->Exec();
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//170
|
||||
int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr)
|
||||
@ -49,7 +189,7 @@ int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr)
|
||||
ConLog.Write("*** prio=%d", prio);
|
||||
ConLog.Write("*** attr_addr=0x%llx", attr_addr);
|
||||
|
||||
sys_spu_thread_group_attribute& attr = *new sys_spu_thread_group_attribute(*(sys_spu_thread_group_attribute*)&Memory[attr_addr]);
|
||||
sys_spu_thread_group_attribute& attr = (sys_spu_thread_group_attribute&)Memory[attr_addr];
|
||||
|
||||
ConLog.Write("*** attr.name_len=%d", re(attr.name_len));
|
||||
ConLog.Write("*** attr.name_addr=0x%x", re(attr.name_addr));
|
||||
@ -60,7 +200,7 @@ int sys_spu_thread_group_create(u64 id_addr, u32 num, int prio, u64 attr_addr)
|
||||
ConLog.Write("*** name='%s'", name);
|
||||
|
||||
Memory.Write32(id_addr,
|
||||
Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group %s", name), &attr, 0));
|
||||
Emu.GetIdManager().GetNewID(wxString::Format("sys_spu_thread_group '%s'", name), new SpuGroupInfo(attr)));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -76,10 +216,10 @@ int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id_addr, attr_addr);
|
||||
|
||||
//PPCThread& new_thread = Emu.GetCPU().AddThread(false);
|
||||
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
|
||||
//Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
|
||||
|
||||
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
|
||||
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
|
||||
Memory.Write32(0xe0043014, 0);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -88,10 +228,126 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu);
|
||||
|
||||
if(max_raw_spu > 5)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if(!Memory.InitSpuRawMem(max_raw_spu))
|
||||
{
|
||||
//30010780;
|
||||
//e0043004 - offset
|
||||
//e004300c - entry
|
||||
return CELL_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
//enable_log = true;
|
||||
//dump_enable = true;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//181
|
||||
int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=0x%x)",
|
||||
id, address, value, type);
|
||||
|
||||
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || !thr->IsSPU())
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
(*(SPUThread*)thr).WriteLS64(address, value);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//182
|
||||
int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value_addr=0x%x, type=0x%x)",
|
||||
id, address, value_addr, type);
|
||||
|
||||
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || !thr->IsSPU())
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(!(*(SPUThread*)thr).IsGoodLSA(address))
|
||||
{
|
||||
return CELL_EFAULT;
|
||||
}
|
||||
|
||||
Memory.Write64(value_addr, (*(SPUThread*)thr).ReadLS64(address));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
//190
|
||||
int sys_spu_thread_write_spu_mb(u32 id, u32 value)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value);
|
||||
|
||||
PPCThread* thr = Emu.GetCPU().GetThread(id);
|
||||
|
||||
if(!thr || !thr->IsSPU())
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(!(*(SPUThread*)thr).InMbox.Push(value))
|
||||
{
|
||||
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
|
||||
return CELL_EBUSY; //?
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
extern SysCallBase sys_event;
|
||||
|
||||
int sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, u32 spup_addr)
|
||||
{
|
||||
sc_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=0x%x, eq=0x%x, req=0x%llx, spup_addr=0x%x)",
|
||||
id, eq, req, spup_addr);
|
||||
|
||||
if(!Emu.GetIdManager().CheckID(id) || !sys_event.CheckId(eq))
|
||||
{
|
||||
return CELL_ESRCH;
|
||||
}
|
||||
|
||||
if(!req)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
SpuGroupInfo* group = (SpuGroupInfo*)Emu.GetIdManager().GetIDData(id).m_data;
|
||||
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(eq).m_data;
|
||||
|
||||
for(int i=0; i<10; ++i)
|
||||
{
|
||||
if(group->threads[i])
|
||||
{
|
||||
bool finded_port = false;
|
||||
for(int j=0; j<equeue->pos; ++j)
|
||||
{
|
||||
if(!equeue->ports[j]->thread)
|
||||
{
|
||||
finded_port = true;
|
||||
equeue->ports[j]->thread = group->threads[i];
|
||||
}
|
||||
}
|
||||
|
||||
if(!finded_port)
|
||||
{
|
||||
return CELL_EISCONN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
@ -12,7 +12,10 @@ using namespace PPU_instr;
|
||||
static const wxString& BreakPointsDBName = "BreakPoints.dat";
|
||||
static const u16 bpdb_version = 0x1000;
|
||||
|
||||
//SysCalls SysCallsManager;
|
||||
ModuleInitializer::ModuleInitializer()
|
||||
{
|
||||
Emu.AddModuleInit(this);
|
||||
}
|
||||
|
||||
Emulator::Emulator()
|
||||
: m_status(Stopped)
|
||||
@ -24,6 +27,11 @@ Emulator::Emulator()
|
||||
|
||||
void Emulator::Init()
|
||||
{
|
||||
while(m_modules_init.GetCount())
|
||||
{
|
||||
m_modules_init[0].Init();
|
||||
m_modules_init.RemoveAt(0);
|
||||
}
|
||||
//if(m_memory_viewer) m_memory_viewer->Close();
|
||||
//m_memory_viewer = new MemoryViewerPanel(wxGetApp().m_MainFrame);
|
||||
}
|
||||
@ -108,7 +116,19 @@ void Emulator::Load()
|
||||
LoadPoints(BreakPointsDBName);
|
||||
PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64);
|
||||
|
||||
thread.SetEntry(l.GetEntry());
|
||||
if(l.GetMachine() == MACHINE_SPU)
|
||||
{
|
||||
ConLog.Write("offset = 0x%llx", Memory.MainMem.GetStartAddr());
|
||||
ConLog.Write("max addr = 0x%x", l.GetMaxAddr());
|
||||
thread.SetOffset(Memory.MainMem.GetStartAddr());
|
||||
Memory.MainMem.Alloc(Memory.MainMem.GetStartAddr() + l.GetMaxAddr(), 0xFFFFED - l.GetMaxAddr());
|
||||
thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr());
|
||||
}
|
||||
else
|
||||
{
|
||||
thread.SetEntry(l.GetEntry());
|
||||
}
|
||||
|
||||
thread.SetArg(thread.GetId());
|
||||
Memory.StackMem.Alloc(0x1000);
|
||||
thread.InitStack();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Emu/DbgConsole.h"
|
||||
#include "Loader/Loader.h"
|
||||
#include "SysCalls/Callback.h"
|
||||
#include "SysCalls/Modules.h"
|
||||
|
||||
struct EmuInfo
|
||||
{
|
||||
@ -45,6 +46,14 @@ public:
|
||||
u64 GetTLSMemsz() const { return tls_memsz; }
|
||||
};
|
||||
|
||||
class ModuleInitializer
|
||||
{
|
||||
public:
|
||||
ModuleInitializer();
|
||||
|
||||
virtual void Init() = 0;
|
||||
};
|
||||
|
||||
class Emulator
|
||||
{
|
||||
enum Mode
|
||||
@ -62,6 +71,7 @@ class Emulator
|
||||
u32 m_ppu_thr_exit;
|
||||
MemoryViewerPanel* m_memory_viewer;
|
||||
//ArrayF<CPUThread> m_cpu_threads;
|
||||
ArrayF<ModuleInitializer> m_modules_init;
|
||||
|
||||
Array<u64> m_break_points;
|
||||
Array<u64> m_marked_points;
|
||||
@ -93,6 +103,11 @@ public:
|
||||
VFS& GetVFS() { return m_vfs; }
|
||||
Array<u64>& GetBreakPoints() { return m_break_points; }
|
||||
Array<u64>& GetMarkedPoints() { return m_marked_points; }
|
||||
|
||||
void AddModuleInit(ModuleInitializer* m)
|
||||
{
|
||||
m_modules_init.Add(m);
|
||||
}
|
||||
|
||||
void SetTLSData(const u64 addr, const u64 filesz, const u64 memsz)
|
||||
{
|
||||
|
35
rpcs3/Emu/event.h
Normal file
35
rpcs3/Emu/event.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
struct sys_event_queue_attr
|
||||
{
|
||||
u32 attr_protocol;
|
||||
int type;
|
||||
char name[8];
|
||||
};
|
||||
|
||||
struct sys_event_data
|
||||
{
|
||||
u64 source;
|
||||
u64 data1;
|
||||
u64 data2;
|
||||
u64 data3;
|
||||
};
|
||||
|
||||
struct EventPort
|
||||
{
|
||||
u64 name;
|
||||
u64 data1;
|
||||
u64 data2;
|
||||
u64 data3;
|
||||
bool has_data;
|
||||
PPCThread* thread;
|
||||
};
|
||||
|
||||
struct EventQueue
|
||||
{
|
||||
EventPort* ports[127];
|
||||
int size;
|
||||
int pos;
|
||||
int type;
|
||||
char name[8];
|
||||
};
|
@ -164,16 +164,17 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr)
|
||||
{
|
||||
PC = addr;
|
||||
m_list->Freeze();
|
||||
disasm->offset = CPU.GetOffset();
|
||||
for(uint i=0; i<m_item_count; ++i, PC += 4)
|
||||
{
|
||||
if(!Memory.IsGoodAddr(PC, 4))
|
||||
if(!Memory.IsGoodAddr(CPU.GetOffset() + PC, 4))
|
||||
{
|
||||
m_list->SetItem(i, 0, wxString::Format("[%08llx] illegal address", PC));
|
||||
continue;
|
||||
}
|
||||
|
||||
disasm->dump_pc = PC;
|
||||
decoder->Decode(Memory.Read32(PC));
|
||||
decoder->Decode(Memory.Read32(CPU.GetOffset() + PC));
|
||||
|
||||
if(IsBreakPoint(PC))
|
||||
{
|
||||
|
@ -133,6 +133,16 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
|
||||
{
|
||||
phdr_arr[i].Show();
|
||||
|
||||
if(phdr_arr[i].p_vaddr < min_addr)
|
||||
{
|
||||
min_addr = phdr_arr[i].p_vaddr;
|
||||
}
|
||||
|
||||
if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr)
|
||||
{
|
||||
max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz;
|
||||
}
|
||||
|
||||
if(phdr_arr[i].p_type == 0x00000001) //LOAD
|
||||
{
|
||||
if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr)
|
||||
@ -161,6 +171,7 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
||||
for(u32 i=0; i<shdr_arr.GetCount(); ++i)
|
||||
{
|
||||
Elf32_Shdr& shdr = shdr_arr[i];
|
||||
|
||||
#ifdef LOADER_DEBUG
|
||||
if(i < shdr_name_arr.GetCount()) ConLog.Write("Name: %s", shdr_name_arr[i]);
|
||||
shdr.Show();
|
||||
@ -168,6 +179,16 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
||||
#endif
|
||||
if((shdr.sh_flags & SHF_ALLOC) != SHF_ALLOC) 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;
|
||||
}
|
||||
|
||||
//const s64 addr = shdr.sh_addr;
|
||||
//const s64 size = shdr.sh_size;
|
||||
//MemoryBlock* mem = nullptr;
|
||||
|
@ -207,6 +207,16 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
|
||||
{
|
||||
phdr_arr[i].Show();
|
||||
|
||||
if(phdr_arr[i].p_vaddr < min_addr)
|
||||
{
|
||||
min_addr = phdr_arr[i].p_vaddr;
|
||||
}
|
||||
|
||||
if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr)
|
||||
{
|
||||
max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz;
|
||||
}
|
||||
|
||||
if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr)
|
||||
{
|
||||
ConLog.Warning
|
||||
@ -403,6 +413,16 @@ bool ELF64Loader::LoadShdrData(u64 offset)
|
||||
{
|
||||
Elf64_Shdr& shdr = shdr_arr[i];
|
||||
|
||||
if(shdr.sh_addr < min_addr)
|
||||
{
|
||||
min_addr = shdr.sh_addr;
|
||||
}
|
||||
|
||||
if(shdr.sh_addr + shdr.sh_size > max_addr)
|
||||
{
|
||||
max_addr = shdr.sh_addr + shdr.sh_size;
|
||||
}
|
||||
|
||||
if(i < shdr_name_arr.GetCount())
|
||||
{
|
||||
const wxString& name = shdr_name_arr[i];
|
||||
|
@ -144,11 +144,15 @@ class LoaderBase
|
||||
{
|
||||
protected:
|
||||
u32 entry;
|
||||
u32 min_addr;
|
||||
u32 max_addr;
|
||||
Elf_Machine machine;
|
||||
|
||||
LoaderBase()
|
||||
: machine(MACHINE_Unknown)
|
||||
, entry(0)
|
||||
, min_addr(0)
|
||||
, max_addr(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -157,6 +161,8 @@ public:
|
||||
virtual bool LoadData(u64 offset = 0) { return false; }
|
||||
Elf_Machine GetMachine() { return machine; }
|
||||
u32 GetEntry() { return entry; }
|
||||
u32 GetMinAddr() { return min_addr; }
|
||||
u32 GetMaxAddr() { return min_addr; }
|
||||
};
|
||||
|
||||
class Loader : public LoaderBase
|
||||
|
@ -224,6 +224,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\Callback.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\FuncList.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Condition.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Event.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_FileSystem.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_GCM.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Heap.cpp" />
|
||||
@ -240,6 +241,7 @@
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_SysUtil_MsgDialog.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Time.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellGcmSys.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_fs.cpp" />
|
||||
|
@ -250,6 +250,12 @@
|
||||
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp">
|
||||
<Filter>Emu\CPU</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Event.cpp">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules.cpp">
|
||||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
Loading…
Reference in New Issue
Block a user