- Implemented RAW SPU.

- Implemented memory mapping.
This commit is contained in:
DH 2013-07-12 15:42:17 +03:00
parent 027a31bd84
commit 559852a8fc
43 changed files with 1106 additions and 224 deletions

View File

@ -1,5 +1,9 @@
#pragma once
#include "Array.h"
#include <functional>
#include <thread>
#include <mutex>
#include <condition_variable>
class ThreadExec;

View File

@ -273,6 +273,7 @@ void PPCThread::Exec()
{
wxGetApp().SendDbgCommand(DID_EXEC_THREAD, this);
ThreadBase::Start();
//std::thread thr(std::bind(std::mem_fn(&PPCThread::Task), this));
}
void PPCThread::ExecOnce()

View File

@ -6,6 +6,7 @@ enum PPCThreadType
{
PPC_THREAD_PPU,
PPC_THREAD_SPU,
PPC_THREAD_RAW_SPU,
};
enum PPCThreadStatus
@ -77,6 +78,7 @@ public:
{
case PPC_THREAD_PPU: return "PPU";
case PPC_THREAD_SPU: return "SPU";
case PPC_THREAD_RAW_SPU: return "RawSPU";
}
return "Unknown";
@ -111,6 +113,15 @@ public:
void Wait(const PPCThread& thr);
bool Sync();
template<typename T>
void WaitFor(T func)
{
while(func(ThreadStatus()))
{
Sleep(1);
}
}
int ThreadStatus();
void NextPc();
@ -125,7 +136,6 @@ public:
static wxArrayString ErrorToString(const u32 error);
wxArrayString ErrorToString() { return ErrorToString(m_error); }
bool IsSPU() const { return m_type == PPC_THREAD_SPU; }
bool IsOk() const { return m_error == 0; }
bool IsRunned() const { return m_status == Runned; }
bool IsPaused() const { return m_status == Paused; }
@ -138,6 +148,7 @@ public:
u32 GetError() const { return m_error; }
u32 GetId() const { return m_id; }
PPCThreadType GetType() const { return m_type; }
void Reset();
void Close();
@ -160,6 +171,7 @@ protected:
virtual void DoResume()=0;
virtual void DoStop()=0;
public:
virtual void Task();
private:

View File

@ -2,6 +2,7 @@
#include "PPCThreadManager.h"
#include "PPUThread.h"
#include "SPUThread.h"
#include "RawSPUThread.h"
PPCThreadManager::PPCThreadManager()
{
@ -17,13 +18,19 @@ void PPCThreadManager::Close()
while(m_threads.GetCount()) RemoveThread(m_threads[0].GetId());
}
PPCThread& PPCThreadManager::AddThread(bool isPPU)
PPCThread& PPCThreadManager::AddThread(PPCThreadType type)
{
PPCThread* new_thread = isPPU ? (PPCThread*)new PPUThread() : (PPCThread*)new SPUThread();
new_thread->SetId(Emu.GetIdManager().GetNewID(
wxString::Format("%s Thread", isPPU ? "PPU" : "SPU"), new_thread, 0)
);
PPCThread* new_thread;
char* name;
switch(type)
{
case PPC_THREAD_PPU: new_thread = new PPUThread(); name = "PPU"; break;
case PPC_THREAD_SPU: new_thread = new SPUThread(); name = "SPU"; break;
case PPC_THREAD_RAW_SPU: new_thread = new RawSPUThread(); name = "RawSPU"; break;
default: assert(0);
}
new_thread->SetId(Emu.GetIdManager().GetNewID(wxString::Format("%s Thread", name), new_thread));
m_threads.Add(new_thread);
wxGetApp().SendDbgCommand(DID_CREATE_THREAD, new_thread);
@ -54,14 +61,14 @@ void PPCThreadManager::RemoveThread(const u32 id)
Emu.CheckStatus();
}
s32 PPCThreadManager::GetThreadNumById(bool isPPU, u32 id)
s32 PPCThreadManager::GetThreadNumById(PPCThreadType type, u32 id)
{
s32 num = 0;
for(u32 i=0; i<m_threads.GetCount(); ++i)
{
if(m_threads[i].GetId() == id) return num;
if(m_threads[i].IsSPU() == !isPPU) num++;
if(m_threads[i].GetType() == type) num++;
}
return -1;

View File

@ -14,11 +14,11 @@ public:
void Close();
PPCThread& AddThread(bool isPPU);
PPCThread& AddThread(PPCThreadType type);
void RemoveThread(const u32 id);
ArrayF<PPCThread>& GetThreads() { return m_threads; }
s32 GetThreadNumById(bool isPPU, u32 id);
s32 GetThreadNumById(PPCThreadType type, u32 id);
PPCThread* GetThread(u32 id);
//IdManager& GetIDs() {return m_threads_id;}

View File

@ -593,7 +593,7 @@ namespace PPU_instr
bind_instr(g3f_0_list, MTFSB1, CRBD, RC);
bind_instr(g3f_0_list, MCRFS, CRFD, CRFS);
bind_instr(g3f_0_list, MTFSB0, CRBD, RC);
bind_instr(g3f_0_list, MTFSFI, CRBD, I, RC);
bind_instr(g3f_0_list, MTFSFI, CRFD, I, RC);
bind_instr(g3f_0_list, MFFS, FRD, RC);
bind_instr(g3f_0_list, MTFSF, FM, FRB, RC);

View File

@ -2080,48 +2080,48 @@ private:
CPU.SetBranch(branchTarget(0, CPU.LR));
if(lk) CPU.LR = CPU.PC + 4;
}
void CRNOR(u32 bt, u32 ba, u32 bb)
void CRNOR(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = 1 ^ (CPU.IsCR(ba) | CPU.IsCR(bb));
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = 1 ^ (CPU.IsCR(crba) | CPU.IsCR(crbb));
CPU.SetCRBit2(crbd, v & 0x1);
}
void CRANDC(u32 bt, u32 ba, u32 bb)
void CRANDC(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = CPU.IsCR(ba) & (1 ^ CPU.IsCR(bb));
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = CPU.IsCR(crba) & (1 ^ CPU.IsCR(crbb));
CPU.SetCRBit2(crbd, v & 0x1);
}
void ISYNC()
{
}
void CRXOR(u32 bt, u32 ba, u32 bb)
void CRXOR(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = CPU.IsCR(ba) ^ CPU.IsCR(bb);
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = CPU.IsCR(crba) ^ CPU.IsCR(crbb);
CPU.SetCRBit2(crbd, v & 0x1);
}
void CRNAND(u32 bt, u32 ba, u32 bb)
void CRNAND(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = 1 ^ (CPU.IsCR(ba) & CPU.IsCR(bb));
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = 1 ^ (CPU.IsCR(crba) & CPU.IsCR(crbb));
CPU.SetCRBit2(crbd, v & 0x1);
}
void CRAND(u32 bt, u32 ba, u32 bb)
void CRAND(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = CPU.IsCR(ba) & CPU.IsCR(bb);
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = CPU.IsCR(crba) & CPU.IsCR(crbb);
CPU.SetCRBit2(crbd, v & 0x1);
}
void CREQV(u32 bt, u32 ba, u32 bb)
void CREQV(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = 1 ^ (CPU.IsCR(ba) ^ CPU.IsCR(bb));
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = 1 ^ (CPU.IsCR(crba) ^ CPU.IsCR(crbb));
CPU.SetCRBit2(crbd, v & 0x1);
}
void CRORC(u32 bt, u32 ba, u32 bb)
void CRORC(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = CPU.IsCR(ba) | (1 ^ CPU.IsCR(bb));
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = CPU.IsCR(crba) | (1 ^ CPU.IsCR(crbb));
CPU.SetCRBit2(crbd, v & 0x1);
}
void CROR(u32 bt, u32 ba, u32 bb)
void CROR(u32 crbd, u32 crba, u32 crbb)
{
const u8 v = CPU.IsCR(ba) | CPU.IsCR(bb);
CPU.SetCRBit2(bt, v & 0x1);
const u8 v = CPU.IsCR(crba) | CPU.IsCR(crbb);
CPU.SetCRBit2(crbd, v & 0x1);
}
void BCCTR(u32 bo, u32 bi, u32 bh, u32 lk)
{
@ -2166,7 +2166,7 @@ private:
void ANDI_(u32 ra, u32 rs, u32 uimm16)
{
CPU.GPR[ra] = CPU.GPR[rs] & uimm16;
CPU.UpdateCR0<s32>(CPU.GPR[ra]);
CPU.UpdateCR0<s16>(CPU.GPR[ra]);
}
void ANDIS_(u32 ra, u32 rs, u32 uimm16)
{
@ -2934,7 +2934,7 @@ private:
}
void STFSX(u32 frs, u32 ra, u32 rb)
{
Memory.Write32((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), PPCdouble(CPU.FPR[frs]).To32());
Memory.Write32((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), CPU.FPR[frs].To32());
}
void STVRX(u32 vs, u32 ra, u32 rb)
{
@ -3147,12 +3147,12 @@ private:
}
void STFS(u32 frs, u32 ra, s32 d)
{
Memory.Write32(ra ? CPU.GPR[ra] + d : d, PPCdouble(CPU.FPR[frs]).To32());
Memory.Write32(ra ? CPU.GPR[ra] + d : d, CPU.FPR[frs].To32());
}
void STFSU(u32 frs, u32 ra, s32 d)
{
const u64 addr = CPU.GPR[ra] + d;
Memory.Write32(addr, PPCdouble(CPU.FPR[frs]).To32());
Memory.Write32(addr, CPU.FPR[frs].To32());
CPU.GPR[ra] = addr;
}
void STFD(u32 frs, u32 ra, s32 d)
@ -3213,32 +3213,32 @@ private:
}
}
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fdivs.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FSUBS(u32 frd, u32 fra, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] - CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fsubs.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FADDS(u32 frd, u32 fra, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] + CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FSQRTS(u32 frd, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(sqrt(CPU.FPR[frb]));
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fsqrts.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FRES(u32 frd, u32 frb, bool rc)
{
if(CPU.FPR[frb] == 0.0) CPU.SetFPSCRException(FPSCR_ZX);
CPU.FPR[frd] = static_cast<float>(1.0f/CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
CPU.FPSCR.FI = 0;
CPU.FPSCR.FR = 0;
if(rc) UNK("fres.");//CPU.UpdateCR1(CPU.FPR[frd]);
@ -3248,31 +3248,31 @@ private:
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc]);
CPU.FPSCR.FI = 0;
CPU.FPSCR.FR = 0;
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fmuls.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fmadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fmsubs.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(-(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]));
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fnmsubs.");////CPU.UpdateCR1(CPU.FPR[frd]);
}
void FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = static_cast<float>(-(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]));
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fnmadds.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void STD(u32 rs, u32 ra, s32 d)
@ -3290,6 +3290,7 @@ private:
{
u64 mask = (1ULL << crbd);
CPU.FPSCR.FPSCR |= mask;
if(rc) UNIMPLEMENTED();
}
void MCRFS(u32 crbd, u32 crbs)
@ -3302,11 +3303,12 @@ private:
{
u64 mask = (1ULL << crbd);
CPU.FPSCR.FPSCR &= ~mask;
if(rc) UNIMPLEMENTED();
}
void MTFSFI(u32 crfd, u32 i, bool rc)
{
u64 mask = (1ULL << crfd);
u64 mask = (0x1ULL << crfd);
if(i)
{
@ -3316,6 +3318,7 @@ private:
{
CPU.FPSCR.FPSCR &= ~mask;
}
if(rc) UNIMPLEMENTED();
}
void MFFS(u32 frd, bool rc)
@ -3478,25 +3481,25 @@ private:
}
CPU.FPR[frd] = CPU.FPR[fra] / CPU.FPR[frb];
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fdiv.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FSUB(u32 frd, u32 fra, u32 frb, bool rc)
{
CPU.FPR[frd] = CPU.FPR[fra] - CPU.FPR[frb];
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fsub.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FADD(u32 frd, u32 fra, u32 frb, bool rc)
{
CPU.FPR[frd] = CPU.FPR[fra] + CPU.FPR[frb];
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FSQRT(u32 frd, u32 frb, bool rc)
{
CPU.FPR[frd] = sqrt(CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fsqrt.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
@ -3525,19 +3528,19 @@ private:
void FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb];
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fmadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = -(CPU.FPR[fra] * CPU.FPR[frc] - CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fnmsub.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
CPU.FPR[frd] = -(CPU.FPR[fra] * CPU.FPR[frc] + CPU.FPR[frb]);
CPU.FPSCR.FPRF = PPCdouble(CPU.FPR[frd]).GetType();
CPU.FPSCR.FPRF = CPU.FPR[frd].GetType();
if(rc) UNK("fnmadd.");//CPU.UpdateCR1(CPU.FPR[frd]);
}
void FCMPO(u32 crfd, u32 fra, u32 frb)

View File

@ -3,14 +3,14 @@
#include "Emu/Cell/PPUDecoder.h"
#include "Emu/Cell/PPUInterpreter.h"
#include "Emu/Cell/PPUDisAsm.h"
#include <thread>
extern gcmInfo gcm_info;
PPUThread& GetCurrentPPUThread()
{
PPCThread* thread = GetCurrentPPCThread();
if(!thread || thread->IsSPU()) throw wxString("GetCurrentPPUThread: bad thread");
if(!thread || thread->GetType() != PPC_THREAD_PPU) throw wxString("GetCurrentPPUThread: bad thread");
return *(PPUThread*)thread;
}
@ -68,7 +68,7 @@ void PPUThread::InitRegs()
SetPc(pc);
const s32 thread_num = Emu.GetCPU().GetThreadNumById(!IsSPU(), GetId());
const s32 thread_num = Emu.GetCPU().GetThreadNumById(GetType(), GetId());
if(thread_num < 0)
{

View File

@ -0,0 +1,151 @@
#include "stdafx.h"
#include "Emu/Cell/RawSPUThread.h"
RawSPUThread::RawSPUThread(PPCThreadType type) : SPUThread(type)
{
Reset();
}
RawSPUThread::~RawSPUThread()
{
}
void RawSPUThread::InitRegs()
{
GPR[3]._u64[1] = m_args[0];
GPR[4]._u64[1] = m_args[1];
GPR[5]._u64[1] = m_args[2];
GPR[6]._u64[1] = m_args[3];
u32 num = Emu.GetCPU().GetThreadNumById(GetType(), GetId());
m_offset = RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * num + RAW_SPU_LS_OFFSET;
MFC_LSA.SetAddr(GetRawSPURegAddrByNum(num, MFC_LSA_offs));
MFC_EAH.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAH_offs));
MFC_EAL.SetAddr(GetRawSPURegAddrByNum(num, MFC_EAL_offs));
MFC_Size_Tag.SetAddr(GetRawSPURegAddrByNum(num, MFC_Size_Tag_offs));
MFC_CMDStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_CMDStatus_offs));
MFC_QStatus.SetAddr(GetRawSPURegAddrByNum(num, MFC_QStatus_offs));
Prxy_QueryType.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryType_offs));
Prxy_QueryMask.SetAddr(GetRawSPURegAddrByNum(num, Prxy_QueryMask_offs));
Prxy_TagStatus.SetAddr(GetRawSPURegAddrByNum(num, Prxy_TagStatus_offs));
SPU_Out_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_Out_MBox_offs));
SPU_In_MBox.SetAddr(GetRawSPURegAddrByNum(num, SPU_In_MBox_offs));
SPU_MBox_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_MBox_Status_offs));
SPU_RunCntl.SetAddr(GetRawSPURegAddrByNum(num, SPU_RunCntl_offs));
SPU_Status.SetAddr(GetRawSPURegAddrByNum(num, SPU_Status_offs));
SPU_NPC.SetAddr(GetRawSPURegAddrByNum(num, SPU_NPC_offs));
SPU_RdSigNotify1.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify1_offs));
SPU_RdSigNotify2.SetAddr(GetRawSPURegAddrByNum(num, SPU_RdSigNotify2_offs));
SPU_RunCntl.SetValue(SPU_RUNCNTL_STOP);
SPU_Status.SetValue(SPU_STATUS_RUNNING);
Prxy_QueryType.SetValue(0);
MFC_CMDStatus.SetValue(0);
PC = SPU_NPC.GetValue();
}
void RawSPUThread::Task()
{
ConLog.Write("%s enter", PPCThread::GetFName());
const Array<u64>& bp = Emu.GetBreakPoints();
try
{
for(uint i=0; i<bp.GetCount(); ++i)
{
if(bp[i] == m_offset + PC)
{
Emu.Pause();
break;
}
}
bool is_last_paused = false;
while(true)
{
int status = ThreadStatus();
if(status == PPCThread_Stopped || status == PPCThread_Break)
{
break;
}
if(status == PPCThread_Sleeping)
{
Sleep(1);
continue;
}
if(MFC_CMDStatus.GetValue() == 0x40)
{
MFC_CMDStatus.SetValue(0);
u32 lsa = MFC_LSA.GetValue();
u64 ea = (u64)MFC_EAL.GetValue() | ((u64)MFC_EAH.GetValue() << 32);
u32 size_tag = MFC_Size_Tag.GetValue();
u16 tag = (u16)size_tag;
u16 size = size_tag >> 16;
ConLog.Warning("RawSPU DMA GET:");
ConLog.Warning("*** lsa = 0x%x", lsa);
ConLog.Warning("*** ea = 0x%llx", ea);
ConLog.Warning("*** tag = 0x%x", tag);
ConLog.Warning("*** size = 0x%x", size);
ConLog.SkipLn();
memcpy(Memory + m_offset + lsa, Memory + ea, size);
}
if(Prxy_QueryType.GetValue() == 2)
{
Prxy_QueryType.SetValue(0);
u32 mask = Prxy_QueryMask.GetValue();
//
MFC_QStatus.SetValue(mask);
}
if(SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
{
if(!is_last_paused)
{
if(is_last_paused = SPU_RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
{
SPU_NPC.SetValue(PC);
SPU_Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL);
}
}
Sleep(1);
continue;
}
if(is_last_paused)
{
is_last_paused = false;
PC = SPU_NPC.GetValue();
SPU_Status.SetValue(SPU_STATUS_RUNNING);
}
DoCode(Memory.Read32(m_offset + PC));
NextPc();
for(uint i=0; i<bp.GetCount(); ++i)
{
if(bp[i] == m_offset + PC)
{
Emu.Pause();
break;
}
}
}
}
catch(const wxString& e)
{
ConLog.Error("Exception: %s", e);
}
catch(const char* e)
{
ConLog.Error("Exception: %s", e);
}
ConLog.Write("%s leave", PPCThread::GetFName());
}

View File

@ -0,0 +1,66 @@
#pragma once
#include "SPUThread.h"
#include "Emu/event.h"
enum
{
MFC_LSA_offs = 0x3004,
MFC_EAH_offs = 0x3008,
MFC_EAL_offs = 0x300C,
MFC_Size_Tag_offs = 0x3010,
MFC_Class_CMD_offs = 0x3014,
MFC_CMDStatus_offs = 0x3014,
MFC_QStatus_offs = 0x3104,
Prxy_QueryType_offs = 0x3204,
Prxy_QueryMask_offs = 0x321C,
Prxy_TagStatus_offs = 0x322C,
SPU_Out_MBox_offs = 0x4004,
SPU_In_MBox_offs = 0x400C,
SPU_MBox_Status_offs = 0x4014,
SPU_RunCntl_offs = 0x401C,
SPU_Status_offs = 0x4024,
SPU_NPC_offs = 0x4034,
SPU_RdSigNotify1_offs = 0x1400C,
SPU_RdSigNotify2_offs = 0x1C00C,
};
enum : u64
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
};
__forceinline static u32 GetRawSPURegAddrByNum(int num, int offset)
{
return RAW_SPU_OFFSET * num + RAW_SPU_BASE_ADDR + RAW_SPU_PROB_OFFSET + offset;
}
__forceinline static u32 GetRawSPURegAddrById(int id, int offset)
{
return GetRawSPURegAddrByNum(Emu.GetCPU().GetThreadNumById(PPC_THREAD_RAW_SPU, id), offset);
}
class RawSPUThread : public SPUThread
{
public:
RawSPUThread(PPCThreadType type = PPC_THREAD_RAW_SPU);
~RawSPUThread();
virtual wxString RegsToString()
{
wxString ret = PPCThread::RegsToString();
for(uint i=0; i<128; ++i) ret += wxString::Format("GPR[%d] = 0x%s\n", i, GPR[i].ToString());
return ret;
}
public:
virtual void InitRegs();
private:
virtual void Task();
};
SPUThread& GetCurrentSPUThread();

View File

@ -27,7 +27,11 @@ private:
//0 - 10
void STOP(u32 code)
{
CPU.Pause();
if(code & 0x2000)
{
CPU.SetExitStatus(code & 0xfff);
CPU.Stop();
}
}
void LNOP()
{

View File

@ -8,12 +8,12 @@ SPUThread& GetCurrentSPUThread()
{
PPCThread* thread = GetCurrentPPCThread();
if(!thread || !thread->IsSPU()) throw wxString("GetCurrentSPUThread: bad thread");
if(!thread || thread->GetType() == PPC_THREAD_PPU) throw wxString("GetCurrentSPUThread: bad thread");
return *(SPUThread*)thread;
}
SPUThread::SPUThread() : PPCThread(PPC_THREAD_SPU)
SPUThread::SPUThread(PPCThreadType type) : PPCThread(type)
{
Reset();
}

View File

@ -81,6 +81,22 @@ enum MFCchannels
MFC_RdAtomicStat = 27, //Read completion status of last completed immediate MFC atomic update command
};
enum
{
SPU_RUNCNTL_STOP = 0,
SPU_RUNCNTL_RUNNABLE = 1,
};
enum
{
SPU_STATUS_STOPPED = 0x0,
SPU_STATUS_RUNNING = 0x1,
SPU_STATUS_STOPPED_BY_STOP = 0x2,
SPU_STATUS_STOPPED_BY_HALT = 0x4,
SPU_STATUS_WAITING_FOR_CHANNEL = 0x8,
SPU_STATUS_SINGLE_STEP = 0x10,
};
union SPU_GPR_hdr
{
u128 _u128;
@ -111,10 +127,91 @@ class SPUThread : public PPCThread
{
public:
SPU_GPR_hdr GPR[128]; //General-Purpose Register
SizedStack<u32, 1> OutMbox;
SizedStack<u32, 1> OutIntrMbox;
SizedStack<u32, 4> InMbox;
template<size_t _max_count>
class SPUReg
{
u64 m_addr;
u32 m_pos;
public:
static const size_t max_count = _max_count;
static const size_t size = max_count * 4;
SPUReg()
{
Init();
}
void Init()
{
m_pos = 0;
}
void SetAddr(u64 addr)
{
m_addr = addr;
}
u64 GetAddr() const
{
return m_addr;
}
__forceinline bool Pop(u32& res)
{
if(!m_pos) return false;
res = Memory.Read32(m_addr + m_pos--);
return true;
}
__forceinline bool Push(u32 value)
{
if(m_pos >= max_count) return false;
Memory.Write32(m_addr + m_pos++, value);
return true;
}
u32 GetCount() const
{
return m_pos;
}
u32 GetFreeCount() const
{
return max_count - m_pos;
}
void SetValue(u32 value)
{
Memory.Write32(m_addr, value);
}
u32 GetValue() const
{
return Memory.Read32(m_addr);
}
};
SPUReg<1> MFC_LSA;
SPUReg<1> MFC_EAH;
SPUReg<1> MFC_EAL;
SPUReg<1> MFC_Size_Tag;
SPUReg<1> MFC_CMDStatus;
SPUReg<1> MFC_QStatus;
SPUReg<1> Prxy_QueryType;
SPUReg<1> Prxy_QueryMask;
SPUReg<1> Prxy_TagStatus;
SPUReg<1> SPU_Out_MBox;
SPUReg<4> SPU_In_MBox;
SPUReg<1> SPU_MBox_Status;
SPUReg<1> SPU_RunCntl;
SPUReg<1> SPU_Status;
SPUReg<1> SPU_NPC;
SPUReg<1> SPU_RdSigNotify1;
SPUReg<1> SPU_RdSigNotify2;
SizedStack<u32, 1> SPU_OutIntr_Mbox;
u32 LSA;
union
@ -128,13 +225,13 @@ public:
switch(ch)
{
case SPU_WrOutMbox:
return OutMbox.GetFreeCount();
return SPU_Out_MBox.GetFreeCount();
case SPU_RdInMbox:
return InMbox.GetCount();
return SPU_In_MBox.GetCount();
case SPU_WrOutIntrMbox:
return 0;//return OutIntrMbox.GetFreeCount();
return 0;//return SPU_OutIntr_Mbox.GetFreeCount();
default:
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
@ -152,7 +249,7 @@ public:
{
case SPU_WrOutIntrMbox:
ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v);
if(!OutIntrMbox.Push(v))
if(!SPU_OutIntr_Mbox.Push(v))
{
ConLog.Warning("Not enought free rooms.");
}
@ -160,10 +257,11 @@ public:
case SPU_WrOutMbox:
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
if(!OutMbox.Push(v))
if(!SPU_Out_MBox.Push(v))
{
ConLog.Warning("Not enought free rooms.");
}
SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff) | 1);
break;
default:
@ -180,7 +278,8 @@ public:
switch(ch)
{
case SPU_RdInMbox:
if(!InMbox.Pop(v)) v = 0;
if(!SPU_In_MBox.Pop(v)) v = 0;
SPU_Status.SetValue((SPU_Status.GetValue() & ~0xff00) | (SPU_In_MBox.GetCount() << 8));
break;
default:
@ -203,7 +302,7 @@ public:
void WriteLS128(const u32 lsa, const u128& data) const { Memory.Write128(lsa + m_offset, data); }
public:
SPUThread();
SPUThread(PPCThreadType type = PPC_THREAD_SPU);
~SPUThread();
virtual wxString RegsToString()
@ -224,7 +323,7 @@ protected:
virtual void DoResume();
virtual void DoStop();
private:
protected:
virtual void DoCode(const s32 code);
};

View File

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "GLGSRender.h"
#define CMD_DEBUG 0
#include "Emu/Cell/PPCInstrTable.h"
#define CMD_DEBUG 1
#define DUMP_VERTEX_DATA 1
#if CMD_DEBUG
@ -132,7 +132,9 @@ void GLRSXThread::Task()
{
wxCriticalSectionLocker lock(p.m_cs_main);
if(p.m_ctrl->get == p.m_ctrl->put || !Emu.IsRunned())
const u32 get = re(p.m_ctrl->get);
const u32 put = re(p.m_ctrl->put);
if(put <= get || !Emu.IsRunned())
{
SemaphorePostAndWait(p.m_sem_flush);
@ -170,23 +172,25 @@ void GLRSXThread::Task()
continue;
}
const u32 get = re(p.m_ctrl->get);
ConLog.Write("addr = 0x%x", p.m_ioAddress + get);
const u32 cmd = Memory.Read32(p.m_ioAddress + get);
const u32 count = (cmd >> 18) & 0x7ff;
//if(cmd == 0) continue;
if(cmd & CELL_GCM_METHOD_FLAG_JUMP)
{
u32 addr = cmd & ~(CELL_GCM_METHOD_FLAG_JUMP | CELL_GCM_METHOD_FLAG_NON_INCREMENT);
p.m_ctrl->get = re32(addr);
ConLog.Warning("rsx jump(0x%x)", addr);
addr &= ~0x1000;
//0x30101000 + 0x80bf000 = 0x80be000
ConLog.Warning("rsx jump(0x%x) #addr=0x%x, cmd=0x%x, get=0x%x, put=0x%x", addr, p.m_ioAddress + get, cmd, get, put);
re(p.m_ctrl->get, addr);
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_CALL)
{
call_stack.Push(get + 4);
u32 addr = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
ConLog.Warning("rsx call(0x%x) #0x%x - 0x%x", addr, cmd, get);
p.m_ctrl->get = re32(addr);
ConLog.Warning("rsx call(0x%x)", addr);
continue;
}
if(cmd & CELL_GCM_METHOD_FLAG_RETURN)
@ -606,6 +610,14 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
//Enable(args[0] ? true : false, GL_DEPTH_CLAMP);
break;
case NV4097_SET_ALPHA_FUNC:
glAlphaFunc(args[0], args[1]);
break;
case NV4097_SET_CULL_FACE:
glCullFace(args[0]);
break;
case NV4097_SET_VIEWPORT_VERTICAL:
{
m_set_viewport_vertical = true;
@ -1134,7 +1146,7 @@ void GLGSRender::DoCmd(const u32 fcmd, const u32 cmd, mem32_t& args, const u32 c
for(u32 i=0; i<count; ++i) log += (i ? ", " : "") + wxString::Format("0x%x", args[i]);
log += ")";
ConLog.Error("TODO: " + log);
Emu.Pause();
//Emu.Pause();
}
break;
}

View File

@ -42,4 +42,5 @@ OPENGL_PROC(PFNGLUNIFORM1FPROC, Uniform1f);
OPENGL_PROC(PFNGLUNIFORM4FPROC, Uniform4f);
OPENGL_PROC(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv);
OPENGL_PROC(PFNGLUSEPROGRAMPROC, UseProgram);
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);
OPENGL_PROC2(PFNWGLSWAPINTERVALEXTPROC, SwapInterval, wglSwapIntervalEXT);
OPENGL_PROC2(PFNGLDEPTHBOUNDSEXTPROC, DepthBounds, glDepthBoundsEXT);

View File

@ -88,7 +88,7 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size)
bool MemoryBlock::IsMyAddress(const u64 addr)
{
return addr >= GetStartAddr() && addr < GetEndAddr();
return mem && addr >= GetStartAddr() && addr < GetEndAddr();
}
__forceinline const u8 MemoryBlock::FastRead8(const u64 addr) const
@ -466,24 +466,52 @@ u8* DynamicMemoryBlock::GetMem(u64 addr) const
return nullptr;
}
#define DEBUG_RAWSPU_MEM 1
//MemoryBase
void MemoryBase::Write8(u64 addr, const u8 data)
{
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Write8(addr=0x%llx,data=0x%x)", addr, data);
}
#endif
GetMemByAddr(addr).Write8(addr, data);
}
void MemoryBase::Write16(u64 addr, const u16 data)
{
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Write16(addr=0x%llx,data=0x%x)", addr, data);
}
#endif
GetMemByAddr(addr).Write16(addr, data);
}
void MemoryBase::Write32(u64 addr, const u32 data)
{
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Write32(addr=0x%llx,data=0x%x)", addr, data);
}
#endif
GetMemByAddr(addr).Write32(addr, data);
}
void MemoryBase::Write64(u64 addr, const u64 data)
{
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Write64(addr=0x%llx,data=0x%llx)", addr, data);
}
#endif
GetMemByAddr(addr).Write64(addr, data);
}
@ -529,8 +557,13 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data)
u8 MemoryBase::Read8(u64 addr)
{
if(enable_log && addr >= 0xd0010a84)
ConLog.Warning("Read8 from block: [%08llx]", addr);
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Read8(addr=0x%llx)", addr);
}
#endif
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
@ -542,8 +575,13 @@ u8 MemoryBase::Read8(u64 addr)
u16 MemoryBase::Read16(u64 addr)
{
if(enable_log && addr >= 0xd0010a84)
ConLog.Warning("Read16 from block: [%08llx]", addr);
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Read16(addr=0x%llx)", addr);
}
#endif
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
@ -555,8 +593,13 @@ u16 MemoryBase::Read16(u64 addr)
u32 MemoryBase::Read32(u64 addr)
{
if(enable_log && addr >= 0xd0010a84)
ConLog.Warning("Read32 from block: [%08llx]", addr);
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr) && !(GetCurrentPPCThread() && GetCurrentPPCThread()->GetType() == PPC_THREAD_RAW_SPU))
{
ConLog.Warning("Read32(addr=0x%llx)", addr);
}
#endif
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{
@ -568,8 +611,13 @@ u32 MemoryBase::Read32(u64 addr)
u64 MemoryBase::Read64(u64 addr)
{
if(enable_log && addr >= 0xd0010a84)
ConLog.Warning("Read64 from block: [%08llx]", addr);
#if DEBUG_RAWSPU_MEM
if(SpuRawMem.IsMyAddress(addr))
{
ConLog.Warning("Read64(addr=0x%llx)", addr);
}
#endif
MemoryBlock& mem = GetMemByAddr(addr);
if(mem.IsNULL())
{

View File

@ -63,16 +63,16 @@ public:
*/
}
template<typename T> static __forceinline T Reverse(T val);
template<> static __forceinline u8 Reverse(u8 val) { return val; };
template<> static __forceinline u16 Reverse(u16 val) { return Reverse16(val); };
template<> static __forceinline u32 Reverse(u32 val) { return Reverse32(val); };
template<> static __forceinline u64 Reverse(u64 val) { return Reverse64(val); };
template<int size> static __forceinline u64 ReverseData(u64 val);
template<> static __forceinline u64 ReverseData<1>(u64 val) { return val; }
template<> static __forceinline u64 ReverseData<2>(u64 val) { return Reverse16(val); }
template<> static __forceinline u64 ReverseData<4>(u64 val) { return Reverse32(val); }
template<> static __forceinline u64 ReverseData<8>(u64 val) { return Reverse64(val); }
template<> static __forceinline s8 Reverse(s8 val) { return val; };
template<> static __forceinline s16 Reverse(s16 val) { return Reverse16(val); };
template<> static __forceinline s32 Reverse(s32 val) { return Reverse32(val); };
template<> static __forceinline s64 Reverse(s64 val) { return Reverse64(val); };
template<typename T> static __forceinline T Reverse(T val)
{
return (T)ReverseData<sizeof(T)>(val);
};
MemoryBlock& GetMemByNum(const u8 num)
{
@ -328,6 +328,31 @@ public:
return PRXMem.Free(addr);
}
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
{
if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr))
{
return false;
}
MemoryBlocks.Add((new MemoryMirror())->SetRange(GetMemFromAddr(src_addr), dst_addr, size));
return true;
}
bool Unmap(const u64 addr)
{
for(uint i=0; i<MemoryBlocks.GetCount(); ++i)
{
if(MemoryBlocks[i].IsMirror())
{
if(MemoryBlocks[i].GetStartAddr() == addr)
{
MemoryBlocks.RemoveFAt(i);
}
}
}
}
u8* operator + (const u64 vaddr)
{
u8* ret = GetMemFromAddr(vaddr);

View File

@ -46,6 +46,7 @@ public:
virtual void Delete();
virtual bool IsNULL() { return false; }
virtual bool IsMirror() { return false; }
u64 FixAddr(const u64 addr) const;
@ -88,6 +89,31 @@ public:
virtual u8* GetMem(u64 addr) const { return mem + addr; }
};
class MemoryMirror : public MemoryBlock
{
public:
virtual bool IsMirror() { return true; }
virtual MemoryBlock* SetRange(const u64 start, const u32 size)
{
range_start = start;
range_size = size;
return this;
}
void SetMemory(u8* memory)
{
mem = memory;
}
MemoryBlock* SetRange(u8* memory, const u64 start, const u32 size)
{
SetMemory(memory);
return SetRange(start, size);
}
};
class NullMemoryBlock : public MemoryBlock
{
virtual bool IsNULL() { return true; }

View File

@ -25,24 +25,22 @@ void Callback::Branch()
{
m_has_data = false;
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU);
new_thread.SetPc(m_addr);
new_thread.SetPrio(0x1001);
new_thread.SetPrio(1001);
new_thread.stack_size = 0x10000;
new_thread.SetName("Callback");
new_thread.SetArg(0, a1);
new_thread.SetArg(1, a2);
new_thread.SetArg(2, a3);
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
new_thread.Run();
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
((PPUThread&)new_thread).GPR[3] = a1;
((PPUThread&)new_thread).GPR[4] = a2;
((PPUThread&)new_thread).GPR[5] = a3;
new_thread.Exec();
while(new_thread.IsAlive()) Sleep(1);
Emu.GetCPU().RemoveThread(new_thread.GetId());
ConLog.Write("Callback EXIT!");
GetCurrentPPCThread()->Wait(new_thread);
}
Callback2::Callback2(u32 slot, u64 addr, u64 userdata) : Callback(slot, addr)

View File

@ -2,10 +2,131 @@
#include "SysCalls.h"
#include "SC_FUNC.h"
Module* g_modules[50];
uint g_modules_count = 0;
Module* g_modules[3][0xff] = {0};
uint g_max_module_id = 0;
uint g_module_2_count = 0;
ArrayF<ModuleFunc> g_modules_funcs_list;
struct ModuleInfo
{
u32 id;
char* name;
}
static const g_module_list[] =
{
{0x0000, "sys_net"},
{0x0001, "sys_http"},
{0x0002, "cellHttpUtil"},
{0x0003, "cellSsl"},
{0x0004, "cellHttps"},
{0x0005, "cellVdec"},
{0x0006, "cellAdec"},
{0x0007, "cellDmux"},
{0x0008, "cellVpost"},
{0x0009, "cellRtc"},
{0x000a, "cellSpurs"},
{0x000b, "cellOvis"},
{0x000c, "cellSheap"},
{0x000d, "sys_sync"},
{0x000e, "sys_fs"},
{0x000f, "sys_jpgdec"},
{0x0010, "cellGcmSys"},
{0x0011, "cellAudio"},
{0x0012, "cellPamf"},
{0x0013, "cellAtrac"},
{0x0014, "cellNetCtl"},
{0x0015, "cellSysutil"},
{0x0016, "sceNp"},
{0x0017, "sys_io"},
{0x0018, "cellPngDec"},
{0x0019, "cellFont"},
{0x001a, "cellFontFt"},
{0x001b, "cellFreetype"},
{0x001c, "cellUsbd"},
{0x001d, "cellSail"},
{0x001e, "cellL10n"},
{0x001f, "cellResc"},
{0x0020, "cellDaisy"},
{0x0021, "cellKey2char"},
{0x0022, "cellMic"},
{0x0023, "cellCamera"},
{0x0024, "cellVdecMpeg2"},
{0x0025, "cellVdecAvc"},
{0x0026, "cellAdecLpcm"},
{0x0027, "cellAdecAc3"},
{0x0028, "cellAdecAtx"},
{0x0029, "cellAdecAt3"},
{0x002a, "cellDmuxPamf"},
{0x002e, "cellLv2dbg"},
{0x0030, "cellUsbpspcm"},
{0x0031, "cellAvconfExt"},
{0x0032, "cellSysutilUserinfo"},
{0x0033, "cellSysutilSavedata"},
{0x0034, "cellSubdisplay"},
{0x0035, "cellSysutilRec"},
{0x0036, "cellVideoExport"},
{0x0037, "cellSysutilGameExec"},
{0x0038, "sceNp2"},
{0x0039, "cellSysutilAp"},
{0x003a, "cellSysutilNpClans"},
{0x003b, "cellSysutilOskExt"},
{0x003c, "cellVdecDivx"},
{0x003d, "cellJpgEnc"},
{0x003e, "cellSysutilGame"},
{0x003f, "cellBgdl"},
{0x0040, "cellFreetypeTT"},
{0x0041, "cellSysutilVideoUpload"},
{0x0042, "cellSysutilSysconfExt"},
{0x0043, "cellFiber"},
{0x0044, "cellSysutilNpCommerce2"},
{0x0045, "cellSysutilNpTus"},
{0x0046, "cellVoice"},
{0x0047, "cellAdecCelp8"},
{0x0048, "cellCelp8Enc"},
{0x0049, "cellSysutilLicenseArea"},
{0x004a, "cellSysutilMusic2"},
{0x004e, "cellSysutilScreenshot"},
{0x004f, "cellSysutilMusicDecode"},
{0x0050, "cellSysutilSpursJq"},
{0x0052, "cellPngEnc"},
{0x0053, "cellSysutilMusicDecode2"},
{0x0055, "cellSync2"},
{0x0056, "cellSysutilNpUtil"},
{0x0057, "cellRudp"},
{0x0059, "cellSysutilNpSns"},
{0x005a, "cellGem"},
{0xf00a, "cellScelpEnc"},
{0xf010, "cellGifDec"},
{0xf019, "cellAdecCelp"},
{0xf01b, "cellAdecM2bc"},
{0xf01d, "cellAdecM4aac"},
{0xf01e, "cellAdecMp3"},
{0xf023, "cellImejp"},
{0xf028, "cellSysutilMusic"},
{0xf029, "cellPhotoExport"},
{0xf02a, "cellPrint"},
{0xf02b, "cellPhotoImport"},
{0xf02c, "cellMusicExport"},
{0xf02e, "cellPhotoDecode"},
{0xf02f, "cellSysutilSearch"},
{0xf030, "cellSysutilAvchat2"},
{0xf034, "cellSailRec"},
{0xf035, "sceNpTrophy"},
{0xf053, "cellAdecAt3multi"},
{0xf054, "cellLibatrac3multi"},
};
struct _InitNullModules
{
_InitNullModules()
{
for(auto& m : g_module_list)
{
new Module(m.id, m.name);
}
}
} InitNullModules;
bool IsLoadedFunc(u32 id)
{
for(u32 i=0; i<g_modules_funcs_list.GetCount(); ++i)
@ -51,9 +172,22 @@ bool UnloadFunc(u32 id)
void UnloadModules()
{
for(u32 i=0; i<g_modules_count; ++i)
for(u32 i=0; i<g_max_module_id; ++i)
{
g_modules[i]->SetLoaded(false);
if(g_modules[0][i])
{
g_modules[0][i]->SetLoaded(false);
}
if(g_modules[1][i])
{
g_modules[1][i]->SetLoaded(false);
}
if(g_modules[2][i])
{
g_modules[2][i]->SetLoaded(false);
}
}
g_modules_funcs_list.Clear();
@ -61,11 +195,21 @@ void UnloadModules()
Module* GetModuleByName(const wxString& name)
{
for(u32 i=0; i<g_modules_count; ++i)
for(u32 i=0; i<g_max_module_id; ++i)
{
if(g_modules[i]->GetName().Cmp(name) == 0)
if(g_modules[0][i] && g_modules[0][i]->GetName().Cmp(name) == 0)
{
return g_modules[i];
return g_modules[0][i];
}
if(g_modules[1][i] && g_modules[1][i]->GetName().Cmp(name) == 0)
{
return g_modules[1][i];
}
if(g_modules[2][i] && g_modules[2][i]->GetName().Cmp(name) == 0)
{
return g_modules[2][i];
}
}
@ -74,24 +218,92 @@ Module* GetModuleByName(const wxString& name)
Module* GetModuleById(u16 id)
{
for(u32 i=0; i<g_modules_count; ++i)
for(u32 i=0; i<g_max_module_id; ++i)
{
if(g_modules[i]->GetID() == id)
if(g_modules[0][i] && g_modules[0][i]->GetID() == id)
{
return g_modules[i];
return g_modules[0][i];
}
if(g_modules[1][i] && g_modules[1][i]->GetID() == id)
{
return g_modules[1][i];
}
}
return nullptr;
}
Module::Module(const char* name, u16 id, void (*init)())
void SetModule(int id, Module* module, bool with_data)
{
if(id != 0xffff)
{
if(u16((u8)id + 1) > g_max_module_id)
{
g_max_module_id = u16((u8)id + 1);
}
int index;
switch(id >> 8)
{
case 0x00: index = 0; break;
case 0xf0: index = 1; break;
default: assert(0); return;
}
if(g_modules[index][(u8)id])
{
if(with_data)
{
module->SetName(g_modules[index][(u8)id]->GetName());
delete g_modules[index][(u8)id];
g_modules[index][(u8)id] = module;
}
else
{
g_modules[index][(u8)id]->SetName(module->GetName());
delete module;
}
}
else
{
g_modules[index][(u8)id] = module;
}
}
else
{
g_modules[2][g_module_2_count++] = module;
if(g_module_2_count > g_max_module_id)
{
g_max_module_id = g_module_2_count;
}
}
}
Module::Module(u16 id, const char* name)
: m_is_loaded(false)
, m_name(name)
, m_id(id)
{
g_modules[g_modules_count++] = this;
init();
SetModule(m_id, this, false);
}
Module::Module(const char* name, void (*init)())
: m_is_loaded(false)
, m_name(name)
, m_id(-1)
{
SetModule(m_id, this, init != nullptr);
if(init) init();
}
Module::Module(u16 id, void (*init)())
: m_is_loaded(false)
, m_id(id)
{
SetModule(m_id, this, init != nullptr);
if(init) init();
}
void Module::Load()
@ -154,6 +366,11 @@ wxString Module::GetName() const
return m_name;
}
void Module::SetName(const wxString& name)
{
m_name = name;
}
void Module::Log(const u32 id, wxString fmt, ...)
{
if(enable_log)

View File

@ -25,14 +25,16 @@ struct ModuleFunc
class Module
{
const char* m_name;
wxString m_name;
const u16 m_id;
bool m_is_loaded;
public:
Array<ModuleFunc> m_funcs_list;
Module(const char* name, u16 id, void (*init)());
Module(u16 id, const char* name);
Module(const char* name, void (*init)());
Module(u16 id, void (*init)());
void Load();
void UnLoad();
@ -44,6 +46,7 @@ public:
u16 GetID() const;
wxString GetName() const;
void SetName(const wxString& name);
public:
void Log(const u32 id, wxString fmt, ...);

View File

@ -3,7 +3,7 @@
#include "Emu/SysCalls/SC_FUNC.h"
void cellGcmSys_init();
Module cellGcmSys("cellGcmSys", 0x0010, cellGcmSys_init);
Module cellGcmSys(0x0010, cellGcmSys_init);
s64 cellGcmFunc15()
{

View File

@ -0,0 +1,95 @@
#include "stdafx.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/SC_FUNC.h"
void cellSysmodule_init();
Module cellSysmodule("cellSysmodule", cellSysmodule_init);
enum
{
CELL_SYSMODULE_LOADED = CELL_OK,
CELL_SYSMODULE_ERROR_DUPLICATED = 0x80012001,
CELL_SYSMODULE_ERROR_UNKNOWN = 0x80012002,
CELL_SYSMODULE_ERROR_UNLOADED = 0x80012003,
CELL_SYSMODULE_ERROR_INVALID_MEMCONTAINER = 0x80012004,
CELL_SYSMODULE_ERROR_FATAL = 0x800120ff,
};
int cellSysmoduleInitialize()
{
cellSysmodule.Log("cellSysmoduleInitialize()");
return CELL_OK;
}
int cellSysmoduleFinalize()
{
cellSysmodule.Log("cellSysmoduleFinalize()");
return CELL_OK;
}
int cellSysmoduleSetMemcontainer(u32 ct_id)
{
cellSysmodule.Warning("TODO: cellSysmoduleSetMemcontainer(ct_id=0x%x)", ct_id);
return CELL_OK;
}
int cellSysmoduleLoadModule(u16 id)
{
cellSysmodule.Warning("cellSysmoduleLoadModule(id=0x%04x)", id);
Module* m = GetModuleById(id);
if(!m)
{
return CELL_SYSMODULE_ERROR_UNKNOWN;
}
if(m->IsLoaded())
{
return CELL_SYSMODULE_ERROR_DUPLICATED;
}
m->Load();
return CELL_OK;
}
int cellSysmoduleUnloadModule(u16 id)
{
cellSysmodule.Warning("cellSysmoduleUnloadModule(id=0x%04x)", id);
Module* m = GetModuleById(id);
if(!m)
{
return CELL_SYSMODULE_ERROR_UNKNOWN;
}
if(!m->IsLoaded())
{
return CELL_SYSMODULE_ERROR_UNLOADED;
}
m->UnLoad();
return CELL_OK;
}
int cellSysmoduleIsLoaded(u16 id)
{
cellSysmodule.Warning("cellSysmoduleIsLoaded(id=0x%04x)", id);
Module* m = GetModuleById(id);
if(!m)
{
return CELL_SYSMODULE_ERROR_UNKNOWN;
}
return m->IsLoaded() ? CELL_SYSMODULE_LOADED : CELL_SYSMODULE_ERROR_UNLOADED;
}
void cellSysmodule_init()
{
cellSysmodule.AddFunc(0x63ff6ff9, bind_func(cellSysmoduleInitialize));
cellSysmodule.AddFunc(0x96c07adf, bind_func(cellSysmoduleFinalize));
cellSysmodule.AddFunc(0xa193143c, bind_func(cellSysmoduleSetMemcontainer));
cellSysmodule.AddFunc(0x32267a31, bind_func(cellSysmoduleLoadModule));
cellSysmodule.AddFunc(0x112a5ee9, bind_func(cellSysmoduleUnloadModule));
cellSysmodule.AddFunc(0x5a59e258, bind_func(cellSysmoduleIsLoaded));
}

View File

@ -3,7 +3,7 @@
#include "Emu/SysCalls/SC_FUNC.h"
void sysPrxForUser_init();
Module sysPrxForUser("sysPrxForUser", -1, sysPrxForUser_init);
Module sysPrxForUser("sysPrxForUser", sysPrxForUser_init);
void sys_initialize_tls()
{

View File

@ -3,7 +3,7 @@
#include "Emu/SysCalls/SC_FUNC.h"
void sys_fs_init();
Module sys_fs("sys_fs", 0x000e, sys_fs_init);
Module sys_fs(0x000e, sys_fs_init);
void sys_fs_init()
{

View File

@ -3,7 +3,7 @@
#include "Emu/SysCalls/SC_FUNC.h"
void sys_io_init();
Module sys_io("sys_io", 0x0017, sys_io_init);
Module sys_io(0x0017, sys_io_init);
void sys_io_init()
{

View File

@ -247,7 +247,7 @@ void SysCalls::DoSyscall(u32 code)
//timer
case 141:
case 142:
Sleep(SC_ARGS_1 / (1000 * 1000));
std::this_thread::sleep_for(std::chrono::nanoseconds(SC_ARGS_1));
RESULT(0);
return;

View File

@ -222,7 +222,7 @@ extern int cellGcmCallback(u32 context_addr, u32 count);
extern int cellGcmGetConfiguration(u32 config_addr);
extern int cellGcmAddressToOffset(u32 address, u32 offset_addr);
extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height);
extern u32 cellGcmGetLabelAddress(u32 index);
extern u32 cellGcmGetLabelAddress(u8 index);
extern u32 cellGcmGetControlRegister();
extern int cellGcmFlush(u32 ctx, u32 id);
extern void cellGcmSetTile(u32 index, u32 location, u32 offset, u32 size, u32 pitch, u32 comp, u32 base, u32 bank);

View File

@ -44,14 +44,13 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
return CELL_ESRCH;
}
PPCThread* thr = GetCurrentPPCThread();
while(true)
int result;
auto queue_receive = [&](int status) -> bool
{
int status = thr->ThreadStatus();
if(status == PPCThread_Stopped)
{
return CELL_ECANCELED;
result = CELL_ECANCELED;
return false;
}
EventQueue* equeue = (EventQueue*)Emu.GetIdManager().GetIDData(equeue_id).m_data;
@ -60,11 +59,11 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
if(!equeue->ports[i]->has_data && equeue->ports[i]->thread)
{
SPUThread* thr = (SPUThread*)equeue->ports[i]->thread;
if(thr->OutIntrMbox.GetCount())
if(thr->SPU_OutIntr_Mbox.GetCount())
{
u32 val;
thr->OutIntrMbox.Pop(val);
if(!thr->OutMbox.Pop(val)) val = 0;
thr->SPU_OutIntr_Mbox.Pop(val);
if(!thr->SPU_Out_MBox.Pop(val)) val = 0;
equeue->ports[i]->data1 = val;
equeue->ports[i]->data2 = 0;
equeue->ports[i]->data3 = 0;
@ -73,29 +72,28 @@ int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout)
}
}
bool has_data = false;
for(int i=0; i<equeue->pos; i++)
{
if(equeue->ports[i]->has_data)
{
has_data = true;
auto res = (sys_event_data&)Memory[event_addr];
auto dst = (sys_event_data&)Memory[event_addr];
re(res.source, equeue->ports[i]->name);
re(res.data1, equeue->ports[i]->data1);
re(res.data2, equeue->ports[i]->data2);
re(res.data3, equeue->ports[i]->data3);
re(dst.source, equeue->ports[i]->name);
re(dst.data1, equeue->ports[i]->data1);
re(dst.data2, equeue->ports[i]->data2);
re(dst.data3, equeue->ports[i]->data3);
equeue->ports[i]->has_data = false;
break;
result = CELL_OK;
return false;
}
}
if(has_data)
break;
return true;
};
Sleep(1);
}
GetCurrentPPUThread().WaitFor(queue_receive);
return CELL_OK;
}

View File

@ -199,9 +199,14 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, u32 nwrite_addr)
ID id;
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
vfsStream& file = *(vfsStream*)id.m_data;
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes))
{
MemoryBlock& block = Memory.GetMemByAddr(buf_addr);
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
}
Memory.Write64NN(nwrite_addr, file.Write(Memory.GetMemFromAddr(buf_addr), nbytes));
int count = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
Memory.Write64NN(nwrite_addr, count);
return CELL_OK;
}

View File

@ -133,9 +133,9 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height
return CELL_OK;
}
u32 cellGcmGetLabelAddress(u32 index)
u32 cellGcmGetLabelAddress(u8 index)
{
cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index);
cellGcmSys.Error("cellGcmGetLabelAddress(index=%d)", index);
return Memory.RSXCMDMem.GetStartAddr() + 0x10 * index;
}

View File

@ -162,15 +162,51 @@ enum
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
};
struct MemoryContainerInfo
{
u64 addr;
u32 size;
MemoryContainerInfo(u64 addr, u32 size)
: addr(addr)
, size(size)
{
}
};
int sys_memory_container_create(u32 cid_addr, u32 yield_size)
{
sc_mem.Warning("TODO: sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
sc_mem.Warning("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
if(!Memory.IsGoodAddr(cid_addr, 4))
{
return CELL_EFAULT;
}
u64 addr = Memory.Alloc(yield_size, 1);
if(!addr)
{
return CELL_ENOMEM;
}
Memory.Write32(cid_addr, sc_mem.GetNewId(new MemoryContainerInfo(addr, yield_size)));
return CELL_OK;
}
int sys_memory_container_destroy(u32 cid)
{
sc_mem.Warning("TODO: sys_memory_container_destroy(cid=0x%x)", cid);
sc_mem.Warning("sys_memory_container_destroy(cid=0x%x)", cid);
MemoryContainerInfo* ct;
if(!sc_mem.CheckId(cid, ct))
{
return CELL_ESRCH;
}
Memory.Free(ct->addr);
Emu.GetIdManager().RemoveID(cid);
return CELL_OK;
}
@ -230,7 +266,7 @@ int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
Memory.Write32(alloc_addr, Memory.Alloc(size, 4));
Memory.Write32(alloc_addr, Memory.Alloc(size, alignment));
return CELL_OK;
}

View File

@ -21,20 +21,17 @@ int sys_ppu_thread_exit(int errorcode)
int sys_ppu_thread_yield()
{
sysPrxForUser.Log("sys_ppu_thread_yield()");
enable_log = !enable_log;
dump_enable = !dump_enable;
if(!enable_log)
{
Emu.Pause();
}
return CELL_OK;
}
int sys_ppu_thread_join(u32 thread_id, u32 vptr_addr)
{
sysPrxForUser.Error("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr);
sysPrxForUser.Warning("sys_ppu_thread_join(thread_id=%d, vptr_addr=0x%x)", thread_id, vptr_addr);
PPCThread* thr = Emu.GetCPU().GetThread(thread_id);
if(!thr) return CELL_ESRCH;
GetCurrentPPUThread().Wait(*thr);
return CELL_OK;
}
@ -125,7 +122,7 @@ int sys_ppu_thread_create(u32 thread_id_addr, u32 entry, u32 arg, int prio, u32
return CELL_EFAULT;
}
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU);
Memory.Write32(thread_id_addr, new_thread.GetId());
new_thread.SetEntry(entry);
@ -148,7 +145,7 @@ void sys_ppu_thread_once(u32 once_ctrl_addr, u32 entry)
{
Memory.Write32(once_ctrl_addr, SYS_PPU_THREAD_DONE_INIT);
PPCThread& new_thread = Emu.GetCPU().AddThread(true);
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_PPU);
new_thread.SetEntry(entry);
((PPUThread&)new_thread).LR = Emu.GetPPUThreadExit();
new_thread.Run();

View File

@ -37,7 +37,6 @@ int SysCalls::lv2ProcessWaitForChild(PPUThread& CPU)
int SysCalls::lv2ProcessGetStatus(PPUThread& CPU)
{
ConLog.Warning("lv2ProcessGetStatus");
if(CPU.IsSPU()) return CELL_UNKNOWN_ERROR;
//Memory.Write32(CPU.GPR[4], GetPPUThreadStatus(CPU));
return CELL_OK;
}

View File

@ -150,7 +150,7 @@ int sys_spu_thread_initialize(u32 thread_addr, u32 group, u32 spu_num, u32 img_a
ConLog.Write("a4 = 0x%x", a4);
ConLog.SkipLn();
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_SPU);
new_thread.SetOffset(g_spu_offset);
new_thread.SetEntry(entry - g_spu_offset);
new_thread.SetName(name);
@ -172,7 +172,7 @@ int sys_spu_thread_set_argument(u32 id, u32 arg_addr)
sc_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg_addr=0x%x)", id, arg_addr);
PPCThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || !thr->IsSPU())
if(!thr || thr->GetType() == PPC_THREAD_PPU)
{
return CELL_ESRCH;
}
@ -268,9 +268,11 @@ int sys_raw_spu_create(u32 id_addr, u32 attr_addr)
sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id_addr, attr_addr);
//Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr));
PPCThread& new_thread = Emu.GetCPU().AddThread(false);
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(false, new_thread.GetId()));
Memory.Write32(0xe0043014, 0);
PPCThread& new_thread = Emu.GetCPU().AddThread(PPC_THREAD_RAW_SPU);
Memory.Write32(id_addr, Emu.GetCPU().GetThreadNumById(PPC_THREAD_RAW_SPU, new_thread.GetId()));
new_thread.Run();
new_thread.Exec();
return CELL_OK;
}
@ -286,10 +288,7 @@ int sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
if(!Memory.InitSpuRawMem(max_raw_spu))
{
//30010780;
//e0043004 - offset
//e004300c - entry
return CELL_UNKNOWN_ERROR;
return CELL_ENOMEM;
}
//enable_log = true;
@ -306,7 +305,7 @@ int sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type)
PPCThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || !thr->IsSPU())
if(!thr || thr->GetType() == PPC_THREAD_PPU)
{
return CELL_ESRCH;
}
@ -324,7 +323,7 @@ int sys_spu_thread_read_ls(u32 id, u32 address, u32 value_addr, u32 type)
PPCThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || !thr->IsSPU())
if(!thr || thr->GetType() == PPC_THREAD_PPU)
{
return CELL_ESRCH;
}
@ -346,12 +345,12 @@ int sys_spu_thread_write_spu_mb(u32 id, u32 value)
PPCThread* thr = Emu.GetCPU().GetThread(id);
if(!thr || !thr->IsSPU())
if(!thr || !thr->GetType() == PPC_THREAD_PPU)
{
return CELL_ESRCH;
}
if(!(*(SPUThread*)thr).InMbox.Push(value))
if(!(*(SPUThread*)thr).SPU_In_MBox.Push(value))
{
ConLog.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x): used all mbox items.");
return CELL_EBUSY; //?

View File

@ -112,7 +112,7 @@ void Emulator::Load()
}
LoadPoints(BreakPointsDBName);
PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64);
PPCThread& thread = GetCPU().AddThread(l.GetMachine() == MACHINE_PPC64 ? PPC_THREAD_PPU : PPC_THREAD_SPU);
if(l.GetMachine() == MACHINE_SPU)
{

View File

@ -135,7 +135,7 @@ public:
*done = false;
if(Emu.GetCPU().GetThreads()[0].IsSPU())
if(Emu.GetCPU().GetThreads()[0].GetType() != PPC_THREAD_PPU)
{
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode);
decoder = new SPU_Decoder(dis_asm);
@ -341,7 +341,7 @@ void DisAsmFrame::Dump(wxCommandEvent& WXUNUSED(event))
PPC_DisAsm* disasm;
PPC_Decoder* decoder;
if(Emu.GetCPU().GetThreads()[0].IsSPU())
if(Emu.GetCPU().GetThreads()[0].GetType() != PPC_THREAD_PPU)
{
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*(PPCThread*)NULL, DumpMode);
decoder = new SPU_Decoder(dis_asm);

View File

@ -108,7 +108,7 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
if(CPU)
{
if(CPU->IsSPU())
if(CPU->GetType() != PPC_THREAD_PPU)
{
SPU_DisAsm& dis_asm = *new SPU_DisAsm(*CPU, InterpreterMode);
decoder = new SPU_Decoder(dis_asm);

View File

@ -133,18 +133,18 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
{
phdr_arr[i].Show();
if(phdr_arr[i].p_vaddr < min_addr)
{
min_addr = phdr_arr[i].p_vaddr;
}
if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr)
{
max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz;
}
if(phdr_arr[i].p_type == 0x00000001) //LOAD
{
if(phdr_arr[i].p_vaddr < min_addr)
{
min_addr = phdr_arr[i].p_vaddr;
}
if(phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz > max_addr)
{
max_addr = phdr_arr[i].p_vaddr + phdr_arr[i].p_memsz;
}
if(phdr_arr[i].p_vaddr != phdr_arr[i].p_paddr)
{
ConLog.Warning
@ -158,6 +158,40 @@ bool ELF32Loader::LoadPhdrData(u64 offset)
elf32_f.Seek(phdr_arr[i].p_offset);
elf32_f.Read(&Memory[phdr_arr[i].p_vaddr + offset], phdr_arr[i].p_filesz);
}
else if(phdr_arr[i].p_type == 0x00000004)
{
elf32_f.Seek(phdr_arr[i].p_offset);
Elf32_Note note;
note.Load(elf32_f);
if(note.type != 1)
{
ConLog.Error("ELF32: Bad NOTE type (%d)", note.type);
break;
}
if(note.namesz != sizeof(note.name))
{
ConLog.Error("ELF32: Bad NOTE namesz (%d)", note.namesz);
break;
}
if(note.descsz < sizeof(note.desc))
{
ConLog.Error("ELF32: Bad NOTE descsz (%d)", note.descsz);
break;
}
//if(note.desc.flags)
//{
// ConLog.Error("ELF32: Bad NOTE flags (0x%x)", note.desc.flags);
// break;
//}
ConLog.Warning("name = %s", note.name);
ConLog.Warning("ls_size = %d", note.desc.ls_size);
ConLog.Warning("stack_size = %d", note.desc.stack_size);
}
#ifdef LOADER_DEBUG
ConLog.SkipLn();
#endif
@ -177,6 +211,11 @@ bool ELF32Loader::LoadShdrData(u64 offset)
shdr.Show();
ConLog.SkipLn();
#endif
if((shdr.sh_type == SHT_RELA) || (shdr.sh_type == SHT_REL))
{
ConLog.Error("ELF32 ERROR: Relocation");
continue;
}
if((shdr.sh_flags & SHF_ALLOC) != SHF_ALLOC) continue;
if(shdr.sh_addr < min_addr)
@ -188,21 +227,6 @@ bool ELF32Loader::LoadShdrData(u64 offset)
{
max_addr = shdr.sh_addr + shdr.sh_size;
}
//const s64 addr = shdr.sh_addr;
//const s64 size = shdr.sh_size;
//MemoryBlock* mem = nullptr;
/*
switch(shdr.sh_type)
{
case SHT_NOBITS:
if(size == 0) continue;
memset(&Memory[addr + offset], 0, size);
case SHT_PROGBITS:
break;
}
*/
}
//TODO

View File

@ -75,6 +75,40 @@ struct Elf32_Ehdr
u32 GetEntry() const { return e_entry; }
};
struct Elf32_Desc
{
u32 revision;
u32 ls_size;
u32 stack_size;
u32 flags;
void Load(vfsStream& f)
{
revision = Read32(f);
ls_size = Read32(f);
stack_size = Read32(f);
flags = Read32(f);
}
};
struct Elf32_Note
{
u32 namesz;
u32 descsz;
u32 type;
u8 name[8];
Elf32_Desc desc;
void Load(vfsStream& f)
{
namesz = Read32(f);
descsz = Read32(f);
type = Read32(f);
f.Read(name, 8);
desc.Load(f);
}
};
struct Elf32_Shdr
{
u32 sh_name;

View File

@ -413,16 +413,6 @@ bool ELF64Loader::LoadShdrData(u64 offset)
{
Elf64_Shdr& shdr = shdr_arr[i];
if(shdr.sh_addr < min_addr)
{
min_addr = shdr.sh_addr;
}
if(shdr.sh_addr + shdr.sh_size > max_addr)
{
max_addr = shdr.sh_addr + shdr.sh_size;
}
if(i < shdr_name_arr.GetCount())
{
const wxString& name = shdr_name_arr[i];
@ -445,6 +435,22 @@ bool ELF64Loader::LoadShdrData(u64 offset)
if(size == 0 || !Memory.IsGoodAddr(offset + addr, size)) continue;
if(shdr.sh_addr < min_addr)
{
min_addr = shdr.sh_addr;
}
if(shdr.sh_addr + shdr.sh_size > max_addr)
{
max_addr = shdr.sh_addr + shdr.sh_size;
}
if((shdr.sh_type == SHT_RELA) || (shdr.sh_type == SHT_REL))
{
ConLog.Error("ELF64 ERROR: Relocation");
continue;
}
switch(shdr.sh_type)
{
case SHT_NOBITS:
@ -457,6 +463,10 @@ bool ELF64Loader::LoadShdrData(u64 offset)
elf64_f.Read(&Memory[addr], shdr.sh_size);
*/
break;
case SHT_RELA:
ConLog.Warning("ELF64: RELA");
break;
}
}

View File

@ -201,6 +201,7 @@
<ClCompile Include="Emu\Cell\PPCThreadManager.cpp" />
<ClCompile Include="Emu\Cell\PPUProgramCompiler.cpp" />
<ClCompile Include="Emu\Cell\PPUThread.cpp" />
<ClCompile Include="Emu\Cell\RawSPUThread.cpp" />
<ClCompile Include="Emu\Cell\SPUThread.cpp" />
<ClCompile Include="Emu\DbgConsole.cpp" />
<ClCompile Include="Emu\FS\VFS.cpp" />
@ -243,6 +244,7 @@
<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\cellSysmodule.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sys_fs.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />

View File

@ -256,6 +256,12 @@
<ClCompile Include="Emu\SysCalls\Modules.cpp">
<Filter>Emu\SysCalls</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\cellSysmodule.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\Cell\RawSPUThread.cpp">
<Filter>Emu\CPU</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />