Merge pull request #810 from Nekotekina/master

Some code removed, CellSpursAttribute implemented
This commit is contained in:
B1ackDaemon 2014-09-15 22:13:54 +03:00
commit 29c2e84fa1
56 changed files with 650 additions and 530 deletions

View file

@ -4,12 +4,6 @@
union u128
{
struct
{
u64 hi;
u64 lo;
};
u64 _u64[2];
s64 _s64[2];
u32 _u32[4];
@ -92,31 +86,27 @@ union u128
//operator bool() const { return _u64[0] != 0 || _u64[1] != 0; }
static u128 from128(u64 hi, u64 lo)
{
u128 ret = { hi, lo };
return ret;
}
static u128 from64(u64 src)
{
u128 ret = { 0, src };
return ret;
}
static u128 from32(u32 src)
static u128 from64(u64 _0, u64 _1 = 0)
{
u128 ret;
ret._u32[0] = src;
ret._u32[1] = 0;
ret._u32[2] = 0;
ret._u32[3] = 0;
ret._u64[0] = _0;
ret._u64[1] = _1;
return ret;
}
static u128 from32(u32 _0, u32 _1 = 0, u32 _2 = 0, u32 _3 = 0)
{
u128 ret;
ret._u32[0] = _0;
ret._u32[1] = _1;
ret._u32[2] = _2;
ret._u32[3] = _3;
return ret;
}
static u128 fromBit(u32 bit)
{
u128 ret;
u128 ret = {};
ret._bit[bit] = true;
return ret;
}
@ -128,42 +118,42 @@ union u128
bool operator == (const u128& right) const
{
return (lo == right.lo) && (hi == right.hi);
return (_u64[0] == right._u64[0]) && (_u64[1] == right._u64[1]);
}
bool operator != (const u128& right) const
{
return (lo != right.lo) || (hi != right.hi);
return (_u64[0] != right._u64[0]) || (_u64[1] != right._u64[1]);
}
u128 operator | (const u128& right) const
{
return from128(hi | right.hi, lo | right.lo);
return from64(_u64[0] | right._u64[0], _u64[1] | right._u64[1]);
}
u128 operator & (const u128& right) const
{
return from128(hi & right.hi, lo & right.lo);
return from64(_u64[0] & right._u64[0], _u64[1] & right._u64[1]);
}
u128 operator ^ (const u128& right) const
{
return from128(hi ^ right.hi, lo ^ right.lo);
return from64(_u64[0] ^ right._u64[0], _u64[1] ^ right._u64[1]);
}
u128 operator ~ () const
{
return from128(~hi, ~lo);
return from64(~_u64[0], ~_u64[1]);
}
void clear()
{
hi = lo = 0;
_u64[1] = _u64[0] = 0;
}
std::string to_hex() const
{
return fmt::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]);
return fmt::Format("%16llx%16llx", _u64[1], _u64[0]);
}
std::string to_xyzw() const
@ -174,8 +164,8 @@ union u128
static __forceinline u128 byteswap(const u128 val)
{
u128 ret;
ret.lo = _byteswap_uint64(val.hi);
ret.hi = _byteswap_uint64(val.lo);
ret._u64[0] = _byteswap_uint64(val._u64[1]);
ret._u64[1] = _byteswap_uint64(val._u64[0]);
return ret;
}
};
@ -540,6 +530,24 @@ template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : pub
#define se32(x) _se<u32, decltype(x), x>::value
#define se64(x) _se<u64, decltype(x), x>::value
// template that helps to define be_t arrays in unions
template<typename T, size_t size>
class be_array_t
{
be_t<T> data[size];
public:
__forceinline be_t<T>& operator [] (size_t index)
{
return data[index];
}
__forceinline const be_t<T>& operator [] (size_t index) const
{
return data[index];
}
};
template<typename T> __forceinline static u8 Read8(T& f)
{
u8 ret;

View file

@ -20,24 +20,3 @@ void SM_Sleep()
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
thread_local size_t g_this_thread_id = 0;
size_t SM_GetCurrentThreadId()
{
return g_this_thread_id ? g_this_thread_id : g_this_thread_id = std::hash<std::thread::id>()(std::this_thread::get_id());
}
u32 SM_GetCurrentCPUThreadId()
{
if (CPUThread* t = GetCurrentCPUThread())
{
return t->GetId();
}
return 0;
}
be_t<u32> SM_GetCurrentCPUThreadIdBE()
{
return be_t<u32>::MakeFromLE(SM_GetCurrentCPUThreadId());
}

View file

@ -2,9 +2,6 @@
bool SM_IsAborted();
void SM_Sleep();
size_t SM_GetCurrentThreadId();
u32 SM_GetCurrentCPUThreadId();
be_t<u32> SM_GetCurrentCPUThreadIdBE();
enum SMutexResult
{
@ -134,44 +131,5 @@ public:
}
};
template<typename T, typename Tid, Tid (get_tid)()>
class SMutexLockerBase
{
T& sm;
public:
const Tid tid;
__forceinline SMutexLockerBase(T& _sm)
: sm(_sm)
, tid(get_tid())
{
if (!tid)
{
if (!SM_IsAborted())
{
assert(!"SMutexLockerBase: thread id == 0");
}
return;
}
sm.lock(tid);
}
__forceinline ~SMutexLockerBase()
{
if (tid) sm.unlock(tid);
}
};
typedef SMutexBase<size_t>
SMutexGeneral;
typedef SMutexBase<u32>
SMutex;
typedef SMutexBase<be_t<u32>>
SMutexBE;
typedef SMutexLockerBase<SMutexGeneral, size_t, SM_GetCurrentThreadId>
SMutexGeneralLocker;
typedef SMutexLockerBase<SMutex, u32, SM_GetCurrentCPUThreadId>
SMutexLocker;
typedef SMutexLockerBase<SMutexBE, be_t<u32>, SM_GetCurrentCPUThreadIdBE>
SMutexBELocker;

View file

@ -12,7 +12,27 @@ NamedThreadBase* GetCurrentNamedThread()
void SetCurrentNamedThread(NamedThreadBase* value)
{
g_tls_this_thread = value;
auto old_value = g_tls_this_thread;
if (old_value == value)
{
return;
}
if (value && value->m_tls_assigned.exchange(true))
{
LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", value->GetThreadName().c_str());
g_tls_this_thread = nullptr;
}
else
{
g_tls_this_thread = value;
}
if (old_value)
{
old_value->m_tls_assigned = false;
}
}
std::string NamedThreadBase::GetThreadName() const
@ -73,14 +93,15 @@ void ThreadBase::Start()
}
catch (const char* e)
{
LOG_ERROR(HLE, "%s: %s", GetThreadName().c_str(), e);
LOG_ERROR(GENERAL, "%s: %s", GetThreadName().c_str(), e);
}
catch (const std::string& e)
{
LOG_ERROR(HLE, "%s: %s", GetThreadName().c_str(), e.c_str());
LOG_ERROR(GENERAL, "%s: %s", GetThreadName().c_str(), e.c_str());
}
m_alive = false;
SetCurrentNamedThread(nullptr);
g_thread_count--;
});
}
@ -160,13 +181,14 @@ void thread::start(std::function<void()> func)
}
catch (const char* e)
{
LOG_ERROR(HLE, "%s: %s", name.c_str(), e);
LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e);
}
catch (const std::string& e)
{
LOG_ERROR(HLE, "%s: %s", name.c_str(), e.c_str());
LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e.c_str());
}
SetCurrentNamedThread(nullptr);
g_thread_count--;
});
}

View file

@ -5,16 +5,17 @@ static std::thread::id main_thread;
class NamedThreadBase
{
std::string m_name;
std::condition_variable m_signal_cv;
std::mutex m_signal_mtx;
public:
NamedThreadBase(const std::string& name) : m_name(name)
std::atomic<bool> m_tls_assigned;
NamedThreadBase(const std::string& name) : m_name(name), m_tls_assigned(false)
{
}
NamedThreadBase()
NamedThreadBase() : m_tls_assigned(false)
{
}

View file

@ -88,9 +88,9 @@ bool rMkpath(const std::string &path)
if(dir.size() == 0)
continue;
#ifdef _WIN32
if((ret = _mkdir(dir.c_str())) && errno != EEXIST){
if((ret = _mkdir(dir.c_str()) != 0) && errno != EEXIST){
#else
if((ret = mkdir(dir.c_str(), 0777)) && errno != EEXIST){
if((ret = mkdir(dir.c_str(), 0777) != 0) && errno != EEXIST){
#endif
return !ret;
}
@ -269,7 +269,7 @@ size_t rFile::Write(const void *buffer, size_t count)
bool rFile::Write(const std::string &text)
{
return reinterpret_cast<wxFile*>(handle)->Write(reinterpret_cast<const void*>(text.c_str()),text.size());
return reinterpret_cast<wxFile*>(handle)->Write(reinterpret_cast<const void*>(text.c_str()),text.size()) != 0;
}
bool rFile::Close()

View file

@ -444,7 +444,7 @@ void validate_data(const char* file_name, unsigned char *klicensee, NPD_HEADER *
int title_hash_result = 0;
int dev_hash_result = 0;
int file_name_length = strlen(file_name);
int file_name_length = (int)strlen(file_name);
unsigned char *buf = new unsigned char[0x30 + file_name_length];
unsigned char key[0x10];

View file

@ -34,7 +34,7 @@ void xor_(unsigned char *dest, unsigned char *src1, unsigned char *src2, int siz
// Hex string conversion auxiliary functions.
u64 hex_to_u64(const char* hex_str)
{
u32 length = strlen(hex_str);
u32 length = (u32)strlen(hex_str);
u64 tmp = 0;
u64 result = 0;
char c;
@ -58,7 +58,7 @@ u64 hex_to_u64(const char* hex_str)
void hex_to_bytes(unsigned char *data, const char *hex_str)
{
u32 str_length = strlen(hex_str);
u32 str_length = (u32)strlen(hex_str);
u32 data_length = str_length / 2;
char tmp_buf[3] = {0, 0, 0};

View file

@ -18,11 +18,11 @@ public:
return imm << 1;
}
virtual u8 DecodeMemory(const u64 address)
virtual u8 DecodeMemory(const u32 address)
{
using namespace ARMv7_opcodes;
const u16 code0 = vm::psv::read16((u32)address);
const u16 code1 = vm::psv::read16((u32)address + 2);
const u16 code0 = vm::psv::read16(address);
const u16 code1 = vm::psv::read16(address + 2);
switch(code0 >> 12) //15 - 12
{

View file

@ -310,7 +310,7 @@ protected:
void BL(u32 imm, u8 intstr_size)
{
CPU.LR = ((u32)CPU.PC + intstr_size) | 1;
CPU.LR = (CPU.PC + intstr_size) | 1;
CPU.SetBranch(CPU.PC + intstr_size + imm);
}

View file

@ -18,7 +18,7 @@ void ARMv7Thread::InitRegs()
memset(GPR, 0, sizeof(GPR[0]) * 15);
APSR.APSR = 0;
IPSR.IPSR = 0;
SP = (u32)m_stack_point;
SP = m_stack_addr + m_stack_size;
}
void ARMv7Thread::InitStack()
@ -26,15 +26,8 @@ void ARMv7Thread::InitStack()
if(!m_stack_addr)
{
m_stack_size = 0x10000;
m_stack_addr = Memory.Alloc(0x10000, 1);
m_stack_addr = (u32)Memory.Alloc(0x10000, 1);
}
m_stack_point = m_stack_addr + m_stack_size;
}
u64 ARMv7Thread::GetFreeStackSize() const
{
return SP - GetStackAddr();
}
void ARMv7Thread::SetArg(const uint pos, const u64 arg)

View file

@ -74,13 +74,12 @@ public:
return GPR[n];
}
return (u32)PC;
return PC;
}
public:
virtual void InitRegs();
virtual void InitStack();
virtual u64 GetFreeStackSize() const;
virtual void SetArg(const uint pos, const u64 arg);
public:

View file

@ -5,7 +5,7 @@
class CPUDecoder
{
public:
virtual u8 DecodeMemory(const u64 address)=0;
virtual u8 DecodeMemory(const u32 address)=0;
virtual ~CPUDecoder() = default;
};

View file

@ -18,7 +18,7 @@ protected:
switch(m_mode)
{
case CPUDisAsm_DumpMode:
last_opcode = fmt::Format("\t%08llx:\t%02x %02x %02x %02x\t%s\n", dump_pc,
last_opcode = fmt::Format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
offset[dump_pc],
offset[dump_pc + 1],
offset[dump_pc + 2],
@ -26,7 +26,7 @@ protected:
break;
case CPUDisAsm_InterpreterMode:
last_opcode = fmt::Format("[%08llx] %02x %02x %02x %02x: %s", dump_pc,
last_opcode = fmt::Format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
offset[dump_pc],
offset[dump_pc + 1],
offset[dump_pc + 2],
@ -41,7 +41,7 @@ protected:
public:
std::string last_opcode;
u64 dump_pc;
u32 dump_pc;
u8* offset;
protected:

View file

@ -11,7 +11,7 @@
CPUThread* GetCurrentCPUThread()
{
return (CPUThread*)GetCurrentNamedThread();
return dynamic_cast<CPUThread*>(GetCurrentNamedThread());
}
CPUThread::CPUThread(CPUThreadType type)
@ -75,7 +75,6 @@ void CPUThread::CloseStack()
}
m_stack_size = 0;
m_stack_point = 0;
}
void CPUThread::SetId(const u32 id)
@ -131,7 +130,7 @@ int CPUThread::ThreadStatus()
return CPUThread_Running;
}
void CPUThread::SetEntry(const u64 pc)
void CPUThread::SetEntry(const u32 pc)
{
entry = pc;
}
@ -150,7 +149,7 @@ void CPUThread::NextPc(u8 instr_size)
}
}
void CPUThread::SetBranch(const u64 pc, bool record_branch)
void CPUThread::SetBranch(const u32 pc, bool record_branch)
{
m_is_branch = true;
nPC = pc;
@ -159,7 +158,7 @@ void CPUThread::SetBranch(const u64 pc, bool record_branch)
CallStackBranch(pc);
}
void CPUThread::SetPc(const u64 pc)
void CPUThread::SetPc(const u32 pc)
{
PC = pc;
}
@ -288,7 +287,7 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
{
// TODO: allow recovering from a page fault
throw fmt::Format("Access violation: addr = 0x%x (is_alive=%d, last_syscall=0x%llx (%s))",
(u32)addr, t->IsAlive() ? 1 : 0, (u64)t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str());
(u32)addr, t->IsAlive() ? 1 : 0, t->m_last_syscall, SysCalls::GetHLEFuncName((u32)t->m_last_syscall).c_str());
}
else
{
@ -315,7 +314,7 @@ void CPUThread::Task()
}
}
std::vector<u64> trace;
std::vector<u32> trace;
#ifdef _WIN32
auto old_se_translator = _set_se_translator(_se_translator);
@ -377,7 +376,7 @@ void CPUThread::Task()
// TODO: linux version
#endif
for (auto& v : trace) LOG_NOTICE(PPU, "PC = 0x%llx", v);
for (auto& v : trace) LOG_NOTICE(PPU, "PC = 0x%x", v);
if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str());
}

View file

@ -30,15 +30,14 @@ protected:
u32 m_error;
u32 m_id;
u64 m_prio;
u64 m_offset;
u32 m_offset;
CPUThreadType m_type;
bool m_joinable;
bool m_joining;
bool m_is_step;
u64 m_stack_addr;
u32 m_stack_addr;
u32 m_stack_size;
u64 m_stack_point;
u64 m_exit_status;
@ -50,22 +49,19 @@ public:
virtual void InitStack()=0;
virtual void CloseStack();
u64 GetStackAddr() const { return m_stack_addr; }
u32 GetStackAddr() const { return m_stack_addr; }
u32 GetStackSize() const { return m_stack_size; }
virtual u64 GetFreeStackSize() const=0;
void SetStackAddr(u64 stack_addr) { m_stack_addr = stack_addr; }
void SetStackAddr(u32 stack_addr) { m_stack_addr = stack_addr; }
void SetStackSize(u32 stack_size) { m_stack_size = stack_size; }
virtual void SetArg(const uint pos, const u64 arg) = 0;
void SetId(const u32 id);
void SetName(const std::string& name);
void SetPrio(const u64 prio) { m_prio = prio; }
void SetOffset(const u64 offset) { m_offset = offset; }
void SetOffset(const u32 offset) { m_offset = offset; }
void SetExitStatus(const u64 status) { m_exit_status = status; }
u64 GetOffset() const { return m_offset; }
u32 GetOffset() const { return m_offset; }
u64 GetExitStatus() const { return m_exit_status; }
u64 GetPrio() const { return m_prio; }
@ -118,9 +114,9 @@ public:
}
public:
u64 entry;
u64 PC;
u64 nPC;
u32 entry;
u32 PC;
u32 nPC;
u64 cycle;
bool m_is_branch;
@ -155,9 +151,9 @@ public:
int ThreadStatus();
void NextPc(u8 instr_size);
void SetBranch(const u64 pc, bool record_branch = false);
void SetPc(const u64 pc);
void SetEntry(const u64 entry);
void SetBranch(const u32 pc, bool record_branch = false);
void SetPc(const u32 pc);
void SetEntry(const u32 entry);
void SetError(const u32 error);
@ -185,8 +181,6 @@ public:
void Resume();
void Stop();
virtual void AddArgv(const std::string& arg) {}
virtual std::string RegsToString() = 0;
virtual std::string ReadRegString(const std::string& reg) = 0;
virtual bool WriteRegString(const std::string& reg, std::string value) = 0;
@ -196,8 +190,8 @@ public:
struct CallStackItem
{
u64 pc;
u64 branch_pc;
u32 pc;
u32 branch_pc;
};
std::vector<CallStackItem> m_call_stack;
@ -208,13 +202,13 @@ public:
for(uint i=0; i<m_call_stack.size(); ++i)
{
ret += fmt::Format("0x%llx -> 0x%llx\n", m_call_stack[i].pc, m_call_stack[i].branch_pc);
ret += fmt::Format("0x%x -> 0x%x\n", m_call_stack[i].pc, m_call_stack[i].branch_pc);
}
return ret;
}
void CallStackBranch(u64 pc)
void CallStackBranch(u32 pc)
{
//look if we're jumping back and if so pop the stack back to that position
auto res = std::find_if(m_call_stack.rbegin(), m_call_stack.rend(),
@ -237,7 +231,7 @@ public:
m_call_stack.push_back(new_item);
}
virtual u64 CallStackGetNextPC(u64 pc)
virtual u32 CallStackGetNextPC(u32 pc)
{
return pc + 4;
}

View file

@ -61,5 +61,5 @@ enum
struct DMAC
{
u64 ls_offset;
u32 ls_offset;
};

View file

@ -2,7 +2,7 @@
#include "Emu/Memory/Memory.h"
#include "PPCDecoder.h"
u8 PPCDecoder::DecodeMemory(const u64 address)
u8 PPCDecoder::DecodeMemory(const u32 address)
{
u32 instr = vm::read32(address);
Decode(instr);

View file

@ -7,7 +7,7 @@ class PPCDecoder : public CPUDecoder
public:
virtual void Decode(const u32 code)=0;
virtual u8 DecodeMemory(const u64 address);
virtual u8 DecodeMemory(const u32 address);
virtual ~PPCDecoder() = default;
};

View file

@ -16,7 +16,6 @@ PPCThread* GetCurrentPPCThread()
PPCThread::PPCThread(CPUThreadType type) : CPUThread(type)
{
memset(m_args, 0, sizeof(m_args));
}
PPCThread::~PPCThread()
@ -31,9 +30,7 @@ void PPCThread::InitStack()
{
if(m_stack_addr) return;
if(m_stack_size == 0) m_stack_size = 0x10000;
m_stack_addr = Memory.StackMem.AllocAlign(m_stack_size, 0x100);
m_stack_point = m_stack_addr + m_stack_size;
m_stack_addr = (u32)Memory.StackMem.AllocAlign(m_stack_size, 0x100);
/*
m_stack_point += m_stack_size - 0x10;
m_stack_point &= -0x10;

View file

@ -3,16 +3,10 @@
class PPCThread : public CPUThread
{
protected:
u64 m_args[4];
std::vector<u64> m_argv_addr;
public:
virtual void InitRegs()=0;
virtual void InitStack();
virtual void SetArg(const uint pos, const u64 arg) { assert(pos < 4); m_args[pos] = arg; }
virtual std::string GetThreadName() const
{
return (GetFName() + fmt::Format("[0x%08llx]", PC));

View file

@ -72,11 +72,11 @@ private:
if(Ini.HLELogging.GetValue())
{
LOG_WARNING(PPU, "SysCall[0x%llx ('%s')] done with code [0x%llx]! #pc: 0x%llx",
LOG_WARNING(PPU, "SysCall[0x%llx ('%s')] done with code [0x%llx]! #pc: 0x%x",
sc, SysCalls::GetHLEFuncName((u32)sc).c_str(), CPU.GPR[3], CPU.PC);
}
#ifdef HLE_CALL_DEBUG
LOG_NOTICE(PPU, "SysCall[%lld] done with code [0x%llx]! #pc: 0x%llx", sc, CPU.GPR[3], CPU.PC);
LOG_NOTICE(PPU, "SysCall[%lld] done with code [0x%llx]! #pc: 0x%x", sc, CPU.GPR[3], CPU.PC);
#endif
CPU.m_last_syscall = old_sc;
@ -2081,7 +2081,7 @@ private:
{
if (CheckCondition(bo, bi))
{
const u64 nextLR = CPU.PC + 4;
const u32 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget((aa ? 0 : CPU.PC), bd), lk);
if(lk) CPU.LR = nextLR;
}
@ -2096,7 +2096,7 @@ private:
Emu.GetSFuncManager().StaticExecute((u32)CPU.GPR[11]);
if (Ini.HLELogging.GetValue())
{
LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%llx",
LOG_NOTICE(PPU, "'%s' done with code[0x%llx]! #pc: 0x%x",
Emu.GetSFuncManager()[CPU.GPR[11]]->name, CPU.GPR[3], CPU.PC);
}
break;
@ -2107,7 +2107,7 @@ private:
}
void B(s32 ll, u32 aa, u32 lk)
{
const u64 nextLR = CPU.PC + 4;
const u32 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget(aa ? 0 : CPU.PC, ll), lk);
if(lk) CPU.LR = nextLR;
}
@ -2119,8 +2119,8 @@ private:
{
if (CheckCondition(bo, bi))
{
const u64 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget(0, CPU.LR), true);
const u32 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget(0, (u32)CPU.LR), true);
if(lk) CPU.LR = nextLR;
}
}
@ -2172,8 +2172,8 @@ private:
{
if(bo & 0x10 || CPU.IsCR(bi) == (bo & 0x8))
{
const u64 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget(0, CPU.CTR), true);
const u32 nextLR = CPU.PC + 4;
CPU.SetBranch(branchTarget(0, (u32)CPU.CTR), true);
if(lk) CPU.LR = nextLR;
}
}
@ -2530,7 +2530,7 @@ private:
}
void LVX(u32 vd, u32 ra, u32 rb)
{
CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
CPU.VPR[vd] = vm::read128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL));
}
void NEG(u32 rd, u32 ra, u32 oe, bool rc)
{
@ -2706,7 +2706,7 @@ private:
}
void STVX(u32 vs, u32 ra, u32 rb)
{
vm::write128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL, CPU.VPR[vs]);
vm::write128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL), CPU.VPR[vs]);
}
void SUBFME(u32 rd, u32 ra, u32 oe, bool rc)
{
@ -2804,7 +2804,7 @@ private:
}
void LVXL(u32 vd, u32 ra, u32 rb)
{
CPU.VPR[vd] = vm::read128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL);
CPU.VPR[vd] = vm::read128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL));
}
void MFTB(u32 rd, u32 spr)
{
@ -2905,7 +2905,7 @@ private:
}
void STVXL(u32 vs, u32 ra, u32 rb)
{
vm::write128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL, CPU.VPR[vs]);
vm::write128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL), CPU.VPR[vs]);
}
void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{
@ -2944,10 +2944,10 @@ private:
void LVLX(u32 vd, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
const u8 eb = addr & 0xf;
const u32 eb = addr & 0xf;
CPU.VPR[vd].clear();
for (u32 i = 0; i < 16 - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(addr + i);
for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(addr + i);
}
void LDBRX(u32 rd, u32 ra, u32 rb)
{
@ -3043,9 +3043,9 @@ private:
void STVLX(u32 vs, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
const u8 eb = addr & 0xf;
const u32 eb = addr & 0xf;
for (u32 i = 0; i < 16 - eb; ++i) vm::write8(addr + i, CPU.VPR[vs]._u8[15 - i]);
for (u32 i = 0; i < 16u - eb; ++i) vm::write8(addr + i, CPU.VPR[vs]._u8[15 - i]);
}
void STSWX(u32 rs, u32 ra, u32 rb)
{
@ -3113,10 +3113,10 @@ private:
void LVLXL(u32 vd, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
const u8 eb = addr & 0xf;
const u32 eb = addr & 0xf;
CPU.VPR[vd].clear();
for (u32 i = 0; i < 16 - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(addr + i);
for (u32 i = 0; i < 16u - eb; ++i) CPU.VPR[vd]._u8[15 - i] = vm::read8(addr + i);
}
void LHBRX(u32 rd, u32 ra, u32 rb)
{
@ -3195,9 +3195,9 @@ private:
void STVLXL(u32 vs, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
const u8 eb = addr & 0xf;
const u32 eb = addr & 0xf;
for (u32 i = 0; i < 16 - eb; ++i) vm::write8(addr + i, CPU.VPR[vs]._u8[15 - i]);
for (u32 i = 0; i < 16u - eb; ++i) vm::write8(addr + i, CPU.VPR[vs]._u8[15 - i]);
}
void STHBRX(u32 rs, u32 ra, u32 rb)
{
@ -3983,7 +3983,7 @@ private:
void UNK(const std::string& err, bool pause = true)
{
LOG_ERROR(PPU, err + fmt::Format(" #pc: 0x%llx", CPU.PC));
LOG_ERROR(PPU, err + fmt::Format(" #pc: 0x%x", CPU.PC));
if(!pause) return;

View file

@ -451,7 +451,7 @@ namespace PPU_opcodes
class PPUOpcodes
{
public:
static u64 branchTarget(const u64 pc, const u64 imm)
static u32 branchTarget(const u32 pc, const u32 imm)
{
return pc + (imm & ~0x3ULL);
}

View file

@ -51,14 +51,6 @@ void PPUThread::DoReset()
cycle = 0;
}
void PPUThread::AddArgv(const std::string& arg)
{
m_stack_point -= arg.length() + 1;
m_stack_point = AlignAddr(m_stack_point, 0x10) - 0x10;
m_argv_addr.push_back(m_stack_point);
memcpy(vm::get_ptr<char>(m_stack_point), arg.c_str(), arg.size() + 1);
}
void PPUThread::InitRegs()
{
const u32 pc = entry ? vm::read32(entry) : 0;
@ -91,46 +83,9 @@ void PPUThread::InitRegs()
}
*/
m_stack_point = AlignAddr(m_stack_point, 0x200) - 0x200;
GPR[1] = m_stack_point;
GPR[1] = AlignAddr(m_stack_addr + m_stack_size, 0x200) - 0x200;
GPR[2] = rtoc;
/*
for(int i=4; i<32; ++i)
{
if(i != 6)
GPR[i] = (i+1) * 0x10000;
}
*/
if(m_argv_addr.size())
{
u64 argc = m_argv_addr.size();
m_stack_point -= 0xc + 4 * argc;
u64 argv = m_stack_point;
auto argv_list = vm::ptr<be_t<u64>>::make((u32)argv);
for(int i=0; i<argc; ++i) argv_list[i] = m_argv_addr[i];
GPR[3] = argc;
GPR[4] = argv;
GPR[5] = argv ? argv + 0xc + 4 * argc : 0; //unk
}
else
{
GPR[3] = m_args[0];
GPR[4] = m_args[1];
GPR[5] = m_args[2];
GPR[6] = m_args[3];
}
GPR[0] = pc;
GPR[8] = entry;
GPR[11] = 0x80;
GPR[12] = Emu.GetMallocPageSize();
GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060;
GPR[28] = GPR[4];
GPR[29] = GPR[3];
GPR[31] = GPR[5];
LR = Emu.GetPPUThreadExit();
CTR = PC;
@ -139,11 +94,6 @@ void PPUThread::InitRegs()
TB = 0;
}
u64 PPUThread::GetFreeStackSize() const
{
return (GetStackAddr() + GetStackSize()) - GPR[1];
}
void PPUThread::DoRun()
{
switch(Ini.CPUDecoderMode.GetValue())
@ -222,7 +172,7 @@ u64 PPUThread::GetStackArg(s32 i)
return vm::read64(GPR[1] + 0x70 + 0x8 * (i - 9));
}
u64 PPUThread::FastCall2(u64 addr, u64 rtoc)
u64 PPUThread::FastCall2(u32 addr, u32 rtoc)
{
auto old_status = m_status;
auto old_PC = PC;

View file

@ -783,13 +783,10 @@ public:
return false;
}
virtual void AddArgv(const std::string& arg) override;
public:
virtual void InitRegs();
virtual u64 GetFreeStackSize() const;
virtual void InitRegs();
u64 GetStackArg(s32 i);
u64 FastCall2(u64 addr, u64 rtoc);
u64 FastCall2(u32 addr, u32 rtoc);
void FastStop();
virtual void DoReset() override;

View file

@ -190,7 +190,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
void RawSPUThread::InitRegs()
{
dmac.ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET;
dmac.ls_offset = m_offset = (u32)GetStartAddr() + RAW_SPU_LS_OFFSET;
SPUThread::InitRegs();
}

View file

@ -257,15 +257,15 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u32[3] == 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void BINZ(u32 intr, u32 rt, u32 ra)
@ -276,15 +276,15 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u32[3] != 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void BIHZ(u32 intr, u32 rt, u32 ra)
@ -295,15 +295,15 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u16[6] == 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void BIHNZ(u32 intr, u32 rt, u32 ra)
@ -314,15 +314,15 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
if (CPU.GPR[rt]._u16[6] != 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void STOPD(u32 rc, u32 ra, u32 rb)
@ -343,8 +343,8 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
LOG5_OPCODE("branch (0x%llx)", target);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void BISL(u32 intr, u32 rt, u32 ra)
@ -355,10 +355,10 @@ private:
return;
}
u64 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
u32 target = branchTarget(CPU.GPR[ra]._u32[3], 0);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = (u32)CPU.PC + 4;
LOG5_OPCODE("branch (0x%llx)", target);
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void IRET(u32 ra)
@ -1100,15 +1100,15 @@ private:
//0 - 8
void BRZ(u32 rt, s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
u32 target = branchTarget(CPU.PC, i16);
if (CPU.GPR[rt]._u32[3] == 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void STQA(u32 rt, s32 i16)
@ -1119,41 +1119,41 @@ private:
}
void BRNZ(u32 rt, s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
u32 target = branchTarget(CPU.PC, i16);
if (CPU.GPR[rt]._u32[3] != 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void BRHZ(u32 rt, s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
u32 target = branchTarget(CPU.PC, i16);
if (CPU.GPR[rt]._u16[6] == 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void BRHNZ(u32 rt, s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
u32 target = branchTarget(CPU.PC, i16);
if (CPU.GPR[rt]._u16[6] != 0)
{
LOG5_OPCODE("taken (0x%llx)", target);
LOG5_OPCODE("taken (0x%x)", target);
CPU.SetBranch(target);
}
else
{
LOG5_OPCODE("not taken (0x%llx)", target);
LOG5_OPCODE("not taken (0x%x)", target);
}
}
void STQR(u32 rt, s32 i16)
@ -1164,8 +1164,8 @@ private:
}
void BRA(s32 i16)
{
u64 target = branchTarget(0, i16);
LOG5_OPCODE("branch (0x%llx)", target);
u32 target = branchTarget(0, i16);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void LQA(u32 rt, s32 i16)
@ -1176,16 +1176,16 @@ private:
}
void BRASL(u32 rt, s32 i16)
{
u64 target = branchTarget(0, i16);
u32 target = branchTarget(0, i16);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = (u32)CPU.PC + 4;
LOG5_OPCODE("branch (0x%llx)", target);
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void BR(s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
LOG5_OPCODE("branch (0x%llx)", target);
u32 target = branchTarget(CPU.PC, i16);
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void FSMBI(u32 rt, s32 i16)
@ -1206,10 +1206,10 @@ private:
}
void BRSL(u32 rt, s32 i16)
{
u64 target = branchTarget(CPU.PC, i16);
u32 target = branchTarget(CPU.PC, i16);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = (u32)CPU.PC + 4;
LOG5_OPCODE("branch (0x%llx)", target);
CPU.GPR[rt]._u32[3] = CPU.PC + 4;
LOG5_OPCODE("branch (0x%x)", target);
CPU.SetBranch(target);
}
void LQR(u32 rt, s32 i16)
@ -1299,7 +1299,6 @@ private:
{
const u32 lsa = (CPU.GPR[ra]._s32[3] + i10) & 0x3fff0;
//LOG_NOTICE(Log::SPU, "STQD(lsa=0x%x): GPR[%d] (0x%llx%llx)", lsa, rt, CPU.GPR[rt]._u64[1], CPU.GPR[rt]._u64[0]);
CPU.WriteLS128(lsa, CPU.GPR[rt]);
}
void LQD(u32 rt, s32 i10, u32 ra) //i10 is shifted left by 4 while decoding

View file

@ -229,7 +229,7 @@ namespace SPU_opcodes
class SPUOpcodes
{
public:
static u32 branchTarget(const u64 pc, const s32 imm)
static u32 branchTarget(const u32 pc, const s32 imm)
{
return (pc + (imm << 2)) & 0x3fffc;
}

View file

@ -3,37 +3,6 @@
#include "SPURSManager.h"
SPURSManagerAttribute::SPURSManagerAttribute(int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork)
{
this->nSpus = nSpus;
this->spuThreadGroupPriority = spuPriority;
this->ppuThreadPriority = ppuPriority;
this->exitIfNoWork = exitIfNoWork;
memset(this->namePrefix, 0, CELL_SPURS_NAME_MAX_LENGTH + 1);
this->threadGroupType = 0;
this->container = 0;
}
int SPURSManagerAttribute::_setNamePrefix(const char *name, u32 size)
{
strncpy(this->namePrefix, name, size);
this->namePrefix[0] = 0;
return 0;
}
int SPURSManagerAttribute::_setSpuThreadGroupType(int type)
{
this->threadGroupType = type;
return 0;
}
int SPURSManagerAttribute::_setMemoryContainerForSpuThread(u32 container)
{
this->container = container;
return 0;
}
SPURSManagerEventFlag::SPURSManagerEventFlag(u32 flagClearMode, u32 flagDirection)
{
this->flagClearMode = flagClearMode;
@ -46,14 +15,12 @@ SPURSManagerTasksetAttribute::SPURSManagerTasksetAttribute(u64 args, vm::ptr<con
this->maxContention = maxContention;
}
SPURSManager::SPURSManager(SPURSManagerAttribute *attr)
SPURSManager::SPURSManager()
{
this->attr = attr;
}
void SPURSManager::Finalize()
{
delete this->attr;
}
void SPURSManager::AttachLv2EventQueue(u32 queue, vm::ptr<u8> port, int isDynamic)

View file

@ -2,28 +2,6 @@
#include "Emu/SysCalls/Modules/cellSpurs.h"
// Internal class to shape a SPURS attribute.
class SPURSManagerAttribute
{
public:
SPURSManagerAttribute(int nSpus, int spuPriority, int ppuPriority, bool exitIfNoWork);
int _setNamePrefix(const char *name, u32 size);
int _setSpuThreadGroupType(int type);
int _setMemoryContainerForSpuThread(u32 container);
protected:
be_t<int> nSpus;
be_t<int> spuThreadGroupPriority;
be_t<int> ppuThreadPriority;
bool exitIfNoWork;
char namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1];
be_t<int> threadGroupType;
be_t<u32> container;
};
class SPURSManagerEventFlag
{
public:
@ -68,12 +46,9 @@ protected:
class SPURSManager
{
public:
SPURSManager(SPURSManagerAttribute *attr);
SPURSManager();
void Finalize();
void AttachLv2EventQueue(u32 queue, vm::ptr<u8> port, int isDynamic);
void DetachLv2EventQueue(u8 port);
protected:
SPURSManagerAttribute *attr;
};

View file

@ -102,7 +102,7 @@ public:
virtual void Decode(const u32 code);
virtual u8 DecodeMemory(const u64 address);
virtual u8 DecodeMemory(const u32 address);
};
#define c (*compiler)
@ -138,7 +138,7 @@ public:
{ \
static void opcode(u32 a0, u32 a1, u32 a2, u32 a3) \
{ \
SPUThread& CPU = *(SPUThread*)GetCurrentCPUThread();
SPUThread& CPU = *(SPUThread*)GetCurrentNamedThread();
#define WRAPPER_END(a0, a1, a2, a3) /*LOG2_OPCODE();*/ } \
}; \
@ -436,12 +436,12 @@ private:
{
static void STOP(u32 code)
{
SPUThread& CPU = *(SPUThread*)GetCurrentCPUThread();
SPUThread& CPU = *(SPUThread*)GetCurrentNamedThread();
CPU.StopAndSignal(code);
LOG2_OPCODE();
}
};
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
X86CallNode* call = c.call(imm_ptr(reinterpret_cast<void*>(&STOP_wrapper::STOP)), kFuncConvHost, FuncBuilder1<void, u32>());
call->setArg(0, imm_u(code));
c.mov(*pos_var, (CPU.PC >> 2) + 1);
@ -454,7 +454,7 @@ private:
}
void SYNC(u32 Cbit)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
// This instruction must be used following a store instruction that modifies the instruction stream.
c.mfence();
c.mov(*pos_var, (CPU.PC >> 2) + 1);
@ -473,7 +473,7 @@ private:
}
void RDCH(u32 rt, u32 ra)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(rt, ra, yy, zz);
CPU.ReadChannel(CPU.GPR[rt], ra);
WRAPPER_END(rt, ra, 0, 0);
@ -481,7 +481,7 @@ private:
}
void RCHCNT(u32 rt, u32 ra)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(rt, ra, yy, zz);
CPU.GPR[rt].clear();
CPU.GPR[rt]._u32[3] = CPU.GetChannelCount(ra);
@ -1089,7 +1089,7 @@ private:
}
void WRCH(u32 ra, u32 rt)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
WRAPPER_BEGIN(ra, rt, yy, zz);
CPU.WriteChannel(ra, CPU.GPR[rt]);
WRAPPER_END(ra, rt, 0, 0);
@ -1137,10 +1137,10 @@ private:
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (u32)CPU.PC + 4);
c.mov(*addr, CPU.PC + 4);
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
c.cmp(cpu_dword(GPR[rt]._u32[3]), 0);
c.cmovne(*pos_var, *addr);
@ -1155,10 +1155,10 @@ private:
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (u32)CPU.PC + 4);
c.mov(*addr, CPU.PC + 4);
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
c.cmp(cpu_dword(GPR[rt]._u32[3]), 0);
c.cmove(*pos_var, *addr);
@ -1173,10 +1173,10 @@ private:
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (u32)CPU.PC + 4);
c.mov(*addr, CPU.PC + 4);
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
c.cmp(cpu_word(GPR[rt]._u16[6]), 0);
c.cmovne(*pos_var, *addr);
@ -1191,10 +1191,10 @@ private:
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (u32)CPU.PC + 4);
c.mov(*addr, CPU.PC + 4);
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
c.cmp(cpu_word(GPR[rt]._u16[6]), 0);
c.cmove(*pos_var, *addr);
@ -1240,7 +1240,7 @@ private:
return;
}
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
@ -1257,7 +1257,7 @@ private:
XmmInvalidate(rt);
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.xor_(*pos_var, *pos_var);
@ -1265,7 +1265,7 @@ private:
c.mov(cpu_dword(GPR[rt]._u32[1]), *pos_var);
c.mov(cpu_dword(GPR[rt]._u32[2]), *pos_var);
c.mov(*pos_var, cpu_dword(GPR[ra]._u32[3]));
c.mov(cpu_dword(GPR[rt]._u32[3]), (u32)CPU.PC + 4);
c.mov(cpu_dword(GPR[rt]._u32[3]), CPU.PC + 4);
c.shr(*pos_var, 2);
LOG_OPCODE();
}
@ -2734,7 +2734,7 @@ private:
//0 - 8
void BRZ(u32 rt, s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (CPU.PC >> 2) + 1);
@ -2763,7 +2763,7 @@ private:
}
void BRNZ(u32 rt, s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (CPU.PC >> 2) + 1);
@ -2774,7 +2774,7 @@ private:
}
void BRHZ(u32 rt, s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (CPU.PC >> 2) + 1);
@ -2785,7 +2785,7 @@ private:
}
void BRHNZ(u32 rt, s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*addr, (CPU.PC >> 2) + 1);
@ -2814,7 +2814,7 @@ private:
}
void BRA(s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*pos_var, branchTarget(0, i16) >> 2);
@ -2844,20 +2844,20 @@ private:
{
XmmInvalidate(rt);
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.xor_(*addr, *addr); // zero
c.mov(cpu_dword(GPR[rt]._u32[0]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[1]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[2]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[3]), (u32)CPU.PC + 4);
c.mov(cpu_dword(GPR[rt]._u32[3]), CPU.PC + 4);
c.mov(*pos_var, branchTarget(0, i16) >> 2);
LOG_OPCODE();
}
void BR(s32 i16)
{
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.mov(*pos_var, branchTarget(CPU.PC, i16) >> 2);
@ -2884,14 +2884,14 @@ private:
{
XmmInvalidate(rt);
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
c.xor_(*addr, *addr); // zero
c.mov(cpu_dword(GPR[rt]._u32[0]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[1]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[2]), *addr);
c.mov(cpu_dword(GPR[rt]._u32[3]), (u32)CPU.PC + 4);
c.mov(cpu_dword(GPR[rt]._u32[3]), CPU.PC + 4);
c.mov(*pos_var, branchTarget(CPU.PC, i16) >> 2);
LOG_OPCODE();
}
@ -3780,7 +3780,7 @@ private:
void UNK(const std::string& err)
{
LOG_ERROR(Log::SPU, err + fmt::Format(" #pc: 0x%x", CPU.PC));
c.mov(cpu_qword(PC), (u32)CPU.PC);
c.mov(cpu_dword(PC), CPU.PC);
do_finalize = true;
Emu.Pause();
}

View file

@ -179,10 +179,10 @@ void SPURecompilerCore::Compile(u16 pos)
first = false;
}
u8 SPURecompilerCore::DecodeMemory(const u64 address)
u8 SPURecompilerCore::DecodeMemory(const u32 address)
{
assert(CPU.dmac.ls_offset == address - CPU.PC);
const u64 m_offset = CPU.dmac.ls_offset;
const u32 m_offset = CPU.dmac.ls_offset;
const u16 pos = (u16)(CPU.PC >> 2);
//ConLog.Write("DecodeMemory: pos=%d", pos);

View file

@ -69,18 +69,10 @@ void SPUThread::DoReset()
void SPUThread::InitRegs()
{
GPR[1]._u32[3] = 0x40000 - 120;
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];
cfg.Reset();
dmac.ls_offset = m_offset;
/*dmac.proxy_pos = 0;
dmac.queue_pos = 0;
dmac.proxy_lock = 0;
dmac.queue_lock = 0;*/
SPU.Status.SetValue(SPU_STATUS_STOPPED);
@ -96,11 +88,6 @@ void SPUThread::InitRegs()
m_events = 0;
}
u64 SPUThread::GetFreeStackSize() const
{
return (GetStackAddr() + GetStackSize()) - GPR[1]._u32[3];
}
void SPUThread::DoRun()
{
switch(Ini.SPUDecoderMode.GetValue())
@ -282,7 +269,7 @@ void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFC
for (u32 i = 0; i < list_size; i++)
{
auto rec = vm::ptr<list_element>::make((u32)dmac.ls_offset + list_addr + i * 8);
auto rec = vm::ptr<list_element>::make(dmac.ls_offset + list_addr + i * 8);
u32 size = rec->ts;
if (size < 16 && size != 1 && size != 2 && size != 4 && size != 8)

View file

@ -559,7 +559,6 @@ public:
public:
virtual void InitRegs();
virtual u64 GetFreeStackSize() const;
virtual void Task();
protected:

View file

@ -256,7 +256,7 @@ MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size)
#endif
if (mem != real_addr)
{
LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%llx, size=0x%llx)", addr, size);
LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%llx, size=0x%x)", addr, size);
Emu.Pause();
}
else
@ -277,7 +277,7 @@ void MemBlockInfo::Free()
if (::mprotect(mem, size, PROT_NONE))
#endif
{
LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%llx, size=0x%llx)", addr, size);
LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%llx, size=0x%x)", addr, size);
Emu.Pause();
}
}
@ -299,7 +299,7 @@ void MemoryBlock::Init()
range_start = 0;
range_size = 0;
mem = vm::get_ptr<u8>(0);
mem = vm::get_ptr<u8>(0u);
}
void MemoryBlock::InitMemory()

View file

@ -16,12 +16,12 @@ enum MemoryType
Memory_PSP,
};
enum : u64
enum : u32
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
RAW_SPU_OFFSET = 0x00100000,
RAW_SPU_BASE_ADDR = 0xE0000000,
RAW_SPU_LS_OFFSET = 0x00000000,
RAW_SPU_PROB_OFFSET = 0x00040000,
};
class MemoryBase

View file

@ -12,35 +12,67 @@ namespace vm
{
return (T*)((u8*)m_base_addr + addr);
}
template<typename T>
T* const get_ptr(u64 addr)
{
return get_ptr<T>((u32)addr);
}
template<typename T>
T& get_ref(u32 addr)
{
return *(T*)((u8*)m_base_addr + addr);
return *get_ptr<T>(addr);
}
static u8 read8(u32 addr)
template<typename T>
T& get_ref(u64 addr)
{
return *((u8*)m_base_addr + addr);
}
static void write8(u32 addr, u8 value)
{
*((u8*)m_base_addr + addr) = value;
return get_ref<T>((u32)addr);
}
namespace ps3
{
static u8 read8(u32 addr)
{
return *((u8*)m_base_addr + addr);
}
static u8 read8(u64 addr)
{
return read8((u32)addr);
}
static void write8(u32 addr, u8 value)
{
*((u8*)m_base_addr + addr) = value;
}
static void write8(u64 addr, u8 value)
{
write8((u32)addr, value);
}
static u16 read16(u32 addr)
{
return re16(*(u16*)((u8*)m_base_addr + addr));
}
static u16 read16(u64 addr)
{
return read16((u32)addr);
}
static void write16(u32 addr, u16 value)
{
*(u16*)((u8*)m_base_addr + addr) = re16(value);
}
static void write16(u64 addr, u16 value)
{
write16((u32)addr, value);
}
static u32 read32(u32 addr)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET)
@ -53,6 +85,11 @@ namespace vm
}
}
static u32 read32(u64 addr)
{
return read32((u32)addr);
}
static void write32(u32 addr, u32 value)
{
if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET)
@ -65,29 +102,64 @@ namespace vm
}
}
static void write32(u64 addr, u32 value)
{
write32((u32)addr, value);
}
static u64 read64(u32 addr)
{
return re64(*(u64*)((u8*)m_base_addr + addr));
}
static u64 read64(u64 addr)
{
return read64((u32)addr);
}
static void write64(u32 addr, u64 value)
{
*(u64*)((u8*)m_base_addr + addr) = re64(value);
}
static void write64(u64 addr, u64 value)
{
write64((u32)addr, value);
}
static u128 read128(u32 addr)
{
return re128(*(u128*)((u8*)m_base_addr + addr));
}
static u128 read128(u64 addr)
{
return read128((u32)addr);
}
static void write128(u32 addr, u128 value)
{
*(u128*)((u8*)m_base_addr + addr) = re128(value);
}
static void write128(u64 addr, u128 value)
{
write128((u32)addr, value);
}
}
namespace psv
{
static u8 read8(u32 addr)
{
return *((u8*)m_base_addr + addr);
}
static void write8(u32 addr, u8 value)
{
*((u8*)m_base_addr + addr) = value;
}
static u16 read16(u32 addr)
{
return *(u16*)((u8*)m_base_addr + addr);

View file

@ -43,7 +43,7 @@ namespace vm
{
Memory.Free(m_addr);
m_addr = 0;
m_ptr = vm::get_ptr<T>(0);
m_ptr = vm::get_ptr<T>(0u);
}
}
@ -364,7 +364,7 @@ namespace vm
{
Memory.Free(m_addr);
m_addr = 0;
m_ptr = vm::get_ptr<T>(0);
m_ptr = vm::get_ptr<T>(0u);
}
}

View file

@ -11,6 +11,11 @@ namespace cb_detail
ARG_STACK,
};
// Current implementation can handle only fixed amount of stack arguments.
// This constant can be increased if necessary.
// It's possible to calculate suitable stack frame size in template, but too complicated.
static const auto FIXED_STACK_FRAME_SIZE = 0x100;
template<typename T, _func_arg_type type, int g_count, int f_count, int v_count>
struct _func_arg;
@ -50,25 +55,29 @@ namespace cb_detail
template<typename T, int g_count, int f_count, int v_count>
struct _func_arg<T, ARG_STACK, g_count, f_count, v_count>
{
static_assert(g_count <= 8, "TODO: Unsupported stack argument type (general)");
static_assert(f_count <= 12, "TODO: Unsupported stack argument type (float)");
static_assert(v_count <= 12, "TODO: Unsupported stack argument type (vector)");
static_assert(sizeof(T) <= 8, "Invalid callback argument type for ARG_STACK");
__forceinline static void set_value(PPUThread& CPU, const T arg)
{
// TODO
const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE;
static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)");
u64 value = 0;
(T&)value = arg;
vm::write64(CPU.GPR[1] + stack_pos, value);
}
};
template<int g_count, int f_count, int v_count>
__forceinline static void _bind_func_args(PPUThread& CPU)
__forceinline static bool _bind_func_args(PPUThread& CPU)
{
// terminator
return false;
}
template<int g_count, int f_count, int v_count, typename T1, typename... T>
__forceinline static void _bind_func_args(PPUThread& CPU, T1 arg1, T... args)
__forceinline static bool _bind_func_args(PPUThread& CPU, T1 arg1, T... args)
{
static_assert(!std::is_pointer<T1>::value, "Invalid callback argument type (pointer)");
static_assert(!std::is_reference<T1>::value, "Invalid callback argument type (reference)");
@ -82,7 +91,8 @@ namespace cb_detail
const int v = v_count + (is_vector ? 1 : 0);
_func_arg<T1, t, g, f, v>::set_value(CPU, arg1);
_bind_func_args<g, f, v>(CPU, args...);
// return true if stack was used
return _bind_func_args<g, f, v>(CPU, args...) || (t == ARG_STACK);
}
template<typename RT>
@ -108,7 +118,16 @@ namespace cb_detail
template<>
struct _func_res<u128>
{
__forceinline static u128 get_value(const PPUThread& CPU)
__forceinline static const u128 get_value(const PPUThread& CPU)
{
return CPU.VPR[2];
}
};
template<>
struct _func_res<const u128>
{
__forceinline static const u128 get_value(const PPUThread& CPU)
{
return CPU.VPR[2];
}
@ -127,8 +146,10 @@ namespace cb_detail
{
__forceinline static RT call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
{
_bind_func_args<0, 0, 0>(CPU, args...);
const bool stack = _bind_func_args<0, 0, 0>(CPU, args...);
if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE;
CPU.FastCall2(pc, rtoc);
if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE;
return _func_res<RT>::get_value(CPU);
}
};

View file

@ -200,12 +200,12 @@ int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDialog,
vm::ptr<void(*)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container)
{
cellGame->Warning("cellGameDataCheckCreate2(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)",
cellGame->Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)",
version, dirName.addr(), errDialog, funcStat.addr(), container);
if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1)
{
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_PARAM");
cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_PARAM");
return CELL_GAMEDATA_ERROR_PARAM;
}
@ -215,7 +215,7 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDi
if (!Emu.GetVFS().ExistsDir(dir))
{
cellGame->Todo("cellGameDataCheckCreate2(): creating directory '%s'", dir.c_str());
cellGame->Todo("cellGameDataCheckCreate(2)(): creating directory '%s'", dir.c_str());
// TODO: create data
return CELL_GAMEDATA_RET_OK;
}
@ -223,14 +223,14 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDi
vfsFile f(dir + "/PARAM.SFO");
if (!f.IsOpened())
{
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)");
cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)");
return CELL_GAMEDATA_ERROR_BROKEN;
}
PSFLoader psf(f);
if (!psf.Load(false))
{
cellGame->Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)");
cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)");
return CELL_GAMEDATA_ERROR_BROKEN;
}
@ -269,36 +269,36 @@ int cellGameDataCheckCreate2(u32 version, vm::ptr<const char> dirName, u32 errDi
if (cbSet->setParam)
{
// TODO: write PARAM.SFO from cbSet
cellGame->Todo("cellGameDataCheckCreate2(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.addr());
cellGame->Todo("cellGameDataCheckCreate(2)(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam.addr());
}
switch ((s32)cbResult->result)
{
case CELL_GAMEDATA_CBRESULT_OK_CANCEL:
// TODO: do not process game data
cellGame->Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL");
cellGame->Warning("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL");
case CELL_GAMEDATA_CBRESULT_OK:
return CELL_GAMEDATA_RET_OK;
case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE");
cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE");
return CELL_GAMEDATA_ERROR_CBRESULT;
case CELL_GAMEDATA_CBRESULT_ERR_BROKEN:
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN");
cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN");
return CELL_GAMEDATA_ERROR_CBRESULT;
case CELL_GAMEDATA_CBRESULT_ERR_NODATA:
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA");
cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA");
return CELL_GAMEDATA_ERROR_CBRESULT;
case CELL_GAMEDATA_CBRESULT_ERR_INVALID:
cellGame->Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID");
cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID");
return CELL_GAMEDATA_ERROR_CBRESULT;
default:
cellGame->Error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x)");
cellGame->Error("cellGameDataCheckCreate(2)(): callback returned unknown error (code=0x%x)");
return CELL_GAMEDATA_ERROR_CBRESULT;
}
}

View file

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "Emu/Memory/Memory.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/Callback.h"
#include "Emu/Cell/SPURSManager.h"
#include "cellSpurs.h"
@ -12,101 +13,207 @@ extern u32 libsre;
extern u32 libsre_rtoc;
#endif
s64 cellSpursInitialize(vm::ptr<CellSpurs> spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
s64 spursInit(
vm::ptr<CellSpurs2> spurs,
u32 revision,
u32 sdkVersion,
s32 nSpus,
s32 spuPriority,
s32 ppuPriority,
u32 flags,
const char prefix[],
u32 prefixSize,
u32 container,
u32 arg11,
u32 arg12,
u32 arg13)
{
cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork);
// internal function
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc);
return cb_caller<s32,vm::ptr<CellSpurs2>, u32, u32, s32, s32, s32, u32, u32, u32, u32, u32, u32, u32>::call(GetCurrentPPUThread(), libsre + 0x74E4, libsre_rtoc,
spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, Memory.RealToVirtualAddr(prefix), prefixSize, container, arg11, arg12, arg13);
#else
SPURSManagerAttribute *attr = new SPURSManagerAttribute(nSpus, spuPriority, ppuPriority, exitIfNoWork);
spurs->spurs = new SPURSManager(attr);
//spurs->spurs = new SPURSManager(attr);
return CELL_OK;
#endif
}
s64 cellSpursFinalize(vm::ptr<CellSpurs> spurs)
s64 cellSpursInitialize(vm::ptr<CellSpurs> spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
{
cellSpurs->Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr());
cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0);
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libsre + 0x8568, libsre_rtoc);
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc);
#else
spurs->spurs->Finalize();
return CELL_OK;
return spursInit(
vm::ptr<CellSpurs2>::make(spurs.addr()),
0,
0,
nSpus,
spuPriority,
ppuPriority,
exitIfNoWork ? 1 : 0,
nullptr,
0,
0,
0,
0,
0);
#endif
}
s64 cellSpursInitializeWithAttribute(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursAttribute> attr)
{
cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.addr(), attr.addr());
cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc);
#else
spurs->spurs = new SPURSManager(attr->attr);
return CELL_OK;
if (!attr)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
if (attr->m.revision > 2)
{
return CELL_SPURS_CORE_ERROR_INVAL;
}
return spursInit(
vm::ptr<CellSpurs2>::make(spurs.addr()),
attr->m.revision,
attr->m.sdkVersion,
attr->m.nSpus,
attr->m.spuPriority,
attr->m.ppuPriority,
(u32)attr->m.flags | (attr->m.exitIfNoWork ? 1 : 0),
attr->m.prefix,
attr->m.prefixSize,
attr->m.container,
attr.addr() + 0x38,
attr->_u32[16],
attr->_u32[17]);
#endif
}
s64 cellSpursInitializeWithAttribute2(vm::ptr<CellSpurs2> spurs, vm::ptr<const CellSpursAttribute> attr)
{
cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, spurs_addr=0x%x)", spurs.addr(), attr.addr());
cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr());
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc);
#else
spurs->spurs = new SPURSManager(attr->attr);
if (!attr)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
if (attr->m.revision > 2)
{
return CELL_SPURS_CORE_ERROR_INVAL;
}
return CELL_OK;
return spursInit(
spurs,
attr->m.revision,
attr->m.sdkVersion,
attr->m.nSpus,
attr->m.spuPriority,
attr->m.ppuPriority,
(u32)attr->m.flags | (attr->m.exitIfNoWork ? 1 : 0) | 4,
attr->m.prefix,
attr->m.prefixSize,
attr->m.container,
attr.addr() + 0x38,
attr->_u32[16],
attr->_u32[17]);
#endif
}
s64 _cellSpursAttributeInitialize(vm::ptr<CellSpursAttribute> attr, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
s64 _cellSpursAttributeInitialize(vm::ptr<CellSpursAttribute> attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork)
{
cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
attr.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork);
cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)",
attr.addr(), revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0);
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x72CC, libsre_rtoc);
#else
attr->attr = new SPURSManagerAttribute(nSpus, spuPriority, ppuPriority, exitIfNoWork);
if (!attr)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
memset(attr.get_ptr(), 0, attr->size);
attr->m.revision = revision;
attr->m.sdkVersion = sdkVersion;
attr->m.nSpus = nSpus;
attr->m.spuPriority = spuPriority;
attr->m.ppuPriority = ppuPriority;
attr->m.exitIfNoWork = exitIfNoWork;
return CELL_OK;
#endif
}
s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr<CellSpursAttribute> attr, u32 container)
{
cellSpurs->Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.addr(), container);
cellSpurs->Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=%d)", attr.addr(), container);
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x6FF8, libsre_rtoc);
#else
attr->attr->_setMemoryContainerForSpuThread(container);
if (!attr)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
if ((u32)attr->m.flags & 0x20000000) // check unknown flag
{
return CELL_SPURS_CORE_ERROR_STAT;
}
attr->_u32[11] = container;
attr->m.flags |= 0x40000000; // set unknown flag
return CELL_OK;
#endif
}
s64 cellSpursAttributeSetNamePrefix(vm::ptr<CellSpursAttribute> attr, vm::ptr<const char> prefix, u32 size)
{
cellSpurs->Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=0x%x)", attr.addr(), prefix.addr(), size);
cellSpurs->Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size);
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x7234, libsre_rtoc);
#else
if (!attr || !prefix)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
if (size > CELL_SPURS_NAME_MAX_LENGTH)
{
cellSpurs->Error("cellSpursAttributeSetNamePrefix : CELL_SPURS_CORE_ERROR_INVAL");
return CELL_SPURS_CORE_ERROR_INVAL;
}
attr->attr->_setNamePrefix(prefix.get_ptr(), size);
memcpy(attr->m.prefix, prefix.get_ptr(), size);
attr->m.prefixSize = size;
return CELL_OK;
#endif
}
@ -126,12 +233,37 @@ s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr<CellSpursAttribute> attr, s3
{
cellSpurs->Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type);
#ifdef PRX_DEBUG
#ifdef PRX_DEBUG_XXX
return GetCurrentPPUThread().FastCall2(libsre + 0x70C8, libsre_rtoc);
#else
attr->attr->_setSpuThreadGroupType(type);
if (!attr)
{
return CELL_SPURS_CORE_ERROR_NULL_POINTER;
}
if (attr.addr() % 8)
{
return CELL_SPURS_CORE_ERROR_ALIGN;
}
return CELL_OK;
if (type == 0x18)
{
if (attr->m.flags & 0x40000000) // check unknown flag
{
return CELL_SPURS_CORE_ERROR_STAT;
}
attr->m.flags |= 0x20000000; // set unknown flag
return CELL_OK;
}
else if (type)
{
return CELL_SPURS_CORE_ERROR_INVAL;
}
else // if type == 0
{
attr->m.flags &= ~0x20000000; // clear unknown flag
return CELL_OK;
}
#endif
}
@ -155,6 +287,19 @@ s64 cellSpursAttributeEnableSystemWorkload(vm::ptr<CellSpursAttribute> attr, vm:
#endif
}
s64 cellSpursFinalize(vm::ptr<CellSpurs> spurs)
{
cellSpurs->Warning("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr());
#ifdef PRX_DEBUG
return GetCurrentPPUThread().FastCall2(libsre + 0x8568, libsre_rtoc);
#else
spurs->spurs->Finalize();
return CELL_OK;
#endif
}
s64 cellSpursGetSpuThreadGroupId(vm::ptr<CellSpurs> spurs, vm::ptr<be_t<u32>> group)
{
#ifdef PRX_DEBUG

View file

@ -77,7 +77,6 @@ enum TaskConstants
};
class SPURSManager;
class SPURSManagerAttribute;
class SPURSManagerEventFlag;
class SPURSManagerTaskset;
@ -94,7 +93,36 @@ struct CellSpurs2
struct CellSpursAttribute
{
SPURSManagerAttribute *attr;
static const auto align = 8;
static const auto size = 512;
union
{
// raw data
u8 _u8[size];
be_array_t<u32, size / sizeof(u32)> _u32;
// real structure
struct
{
be_t<u32> revision; // 0x0
be_t<u32> sdkVersion; // 0x4
be_t<u32> nSpus; // 0x8
be_t<s32> spuPriority; // 0xC
be_t<s32> ppuPriority; // 0x10
bool exitIfNoWork; // 0x14
char prefix[15]; // 0x15 (not a NTS)
be_t<u32> prefixSize; // 0x24
be_t<u32> flags; // 0x28
be_t<u32> container; // 0x2C
// ...
} m;
// alternative implementation
struct
{
} c;
};
};
struct CellSpursEventFlag

View file

@ -1565,7 +1565,7 @@ s32 _cellSyncLFQueuePushBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<const void>
s32 depth = (u32)queue->m_depth;
s32 size = (u32)queue->m_size;
memcpy(vm::get_ptr<void>((queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), buffer.get_ptr(), size);
memcpy(vm::get_ptr<void>((u64)(queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), buffer.get_ptr(), size);
s32 res;
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))
@ -1957,7 +1957,7 @@ s32 _cellSyncLFQueuePopBody(vm::ptr<CellSyncLFQueue> queue, vm::ptr<void> buffer
s32 depth = (u32)queue->m_depth;
s32 size = (u32)queue->m_size;
memcpy(buffer.get_ptr(), vm::get_ptr<void>((queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), size);
memcpy(buffer.get_ptr(), vm::get_ptr<void>((u64)(queue->m_buffer.addr() & ~1ull) + size * (position >= depth ? position - depth : position)), size);
s32 res;
if (queue->m_direction.ToBE() != se32(CELL_SYNC_QUEUE_ANY2ANY))

View file

@ -92,7 +92,16 @@ namespace detail
template<>
struct bind_result<u128>
{
static __forceinline void func(PPUThread& CPU, u128 result)
static __forceinline void func(PPUThread& CPU, const u128 result)
{
CPU.VPR[2] = result;
}
};
template<>
struct bind_result<const u128>
{
static __forceinline void func(PPUThread& CPU, const u128 result)
{
CPU.VPR[2] = result;
}

View file

@ -922,7 +922,7 @@ void default_syscall()
{
//tty
case 988:
LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%llx",
LOG_WARNING(HLE, "SysCall 988! r3: 0x%llx, r4: 0x%llx, pc: 0x%x",
CPU.GPR[3], CPU.GPR[4], CPU.PC);
CPU.GPR[3] = 0;
return;

View file

@ -227,7 +227,7 @@ s32 cellFsClosedir(u32 fd)
s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
{
sys_fs->Warning("cellFsStat(path=\"%s\", sb_addr: 0x%x)", path.get_ptr(), sb.addr());
sys_fs->Warning("cellFsStat(path=\"%s\", sb_addr=0x%x)", path.get_ptr(), sb.addr());
LV2_LOCK(0);
@ -270,7 +270,7 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
{
sys_fs->Warning("cellFsFstat(fd=%d, sb_addr: 0x%x)", fd, sb.addr());
sys_fs->Warning("cellFsFstat(fd=%d, sb_addr=0x%x)", fd, sb.addr());
LV2_LOCK(0);
@ -632,8 +632,8 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
*ringbuf = fs_config.m_ring_buffer;
sys_fs->Warning("*** fs stream config: block_size=0x%llx, copy=%d, ringbuf_size = 0x%llx, transfer_rate = 0x%llx",
ringbuf->block_size, ringbuf->copy,ringbuf->ringbuf_size, ringbuf->transfer_rate);
sys_fs->Warning("*** fs stream config: block_size=0x%llx, copy=%d, ringbuf_size=0x%llx, transfer_rate=0x%llx",
(u64)ringbuf->block_size, (u32)ringbuf->copy, (u64)ringbuf->ringbuf_size, (u64)ringbuf->transfer_rate);
return CELL_OK;
}
@ -716,7 +716,7 @@ s32 cellFsStRead(u32 fd, u32 buf_addr, u64 size, vm::ptr<be_t<u64>> rsize)
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<be_t<u32>> addr, vm::ptr<be_t<u64>> size)
{
sys_fs->Todo("cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr = 0x%x)", fd, addr.addr(), size.addr());
sys_fs->Todo("cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr=0x%x)", fd, addr.addr(), size.addr());
LV2_LOCK(0);
@ -728,7 +728,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<be_t<u32>> addr, vm::ptr<be_t<u64
s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size)
{
sys_fs->Todo("cellFsStReadPutCurrentAddr(fd=%d, addr_addr=0x%x, size = 0x%llx)", fd, addr_addr, size);
sys_fs->Todo("cellFsStReadPutCurrentAddr(fd=%d, addr_addr=0x%x, size=0x%llx)", fd, addr_addr, size);
LV2_LOCK(0);
@ -740,7 +740,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size)
s32 cellFsStReadWait(u32 fd, u64 size)
{
sys_fs->Todo("cellFsStReadWait(fd=%d, size = 0x%llx)", fd, size);
sys_fs->Todo("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size);
LV2_LOCK(0);
@ -752,7 +752,7 @@ s32 cellFsStReadWait(u32 fd, u64 size)
s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr<void (*)(int xfd, u64 xsize)> func)
{
sys_fs->Todo("cellFsStReadWaitCallback(fd=%d, size = 0x%llx, func_addr = 0x%x)", fd, size, func.addr());
sys_fs->Todo("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func_addr=0x%x)", fd, size, func.addr());
LV2_LOCK(0);

View file

@ -113,12 +113,13 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
EventFlag* ef;
if (!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
u32 tid = GetCurrentPPUThread().GetId();
const u32 tid = GetCurrentPPUThread().GetId();
{
SMutexLocker lock(ef->m_mutex);
ef->m_mutex.lock(tid);
if (ef->m_type == SYS_SYNC_WAITER_SINGLE && ef->waiters.size() > 0)
{
ef->m_mutex.unlock(tid);
return CELL_EPERM;
}
EventFlagWaiter rec;
@ -144,8 +145,10 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
if (result) *result = flags;
ef->m_mutex.unlock(tid);
return CELL_OK;
}
ef->m_mutex.unlock(tid);
}
u64 counter = 0;
@ -155,8 +158,7 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
{
if (ef->signal.unlock(tid, tid) == SMR_OK)
{
SMutexLocker lock(ef->m_mutex);
ef->m_mutex.lock(tid);
u64 flags = ef->flags;
for (u32 i = 0; i < ef->waiters.size(); i++)
@ -187,11 +189,13 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
if (result) *result = flags;
ef->m_mutex.unlock(tid);
return CELL_OK;
}
}
ef->signal.unlock(tid);
ef->m_mutex.unlock(tid);
return CELL_ECANCELED;
}
@ -199,7 +203,7 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
if (counter++ > max_counter)
{
SMutexLocker lock(ef->m_mutex);
ef->m_mutex.lock(tid);
for (u32 i = 0; i < ef->waiters.size(); i++)
{
@ -210,6 +214,7 @@ s32 sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>> r
}
}
ef->m_mutex.unlock(tid);
return CELL_ETIMEDOUT;
}
if (Emu.IsStopped())
@ -245,7 +250,8 @@ s32 sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>
EventFlag* ef;
if (!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
SMutexLocker lock(ef->m_mutex);
const u32 tid = GetCurrentPPUThread().GetId();
ef->m_mutex.lock(tid);
u64 flags = ef->flags;
@ -263,9 +269,11 @@ s32 sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, vm::ptr<be_t<u64>
if (result) *result = flags;
ef->m_mutex.unlock(tid);
return CELL_OK;
}
ef->m_mutex.unlock(tid);
return CELL_EBUSY;
}
@ -301,9 +309,10 @@ s32 sys_event_flag_clear(u32 eflag_id, u64 bitptn)
EventFlag* ef;
if (!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
SMutexLocker lock(ef->m_mutex);
const u32 tid = GetCurrentPPUThread().GetId();
ef->m_mutex.lock(tid);
ef->flags &= bitptn;
ef->m_mutex.unlock(tid);
return CELL_OK;
}
@ -316,14 +325,17 @@ s32 sys_event_flag_cancel(u32 eflag_id, vm::ptr<be_t<u32>> num)
std::vector<u32> tids;
const u32 tid = GetCurrentPPUThread().GetId();
{
SMutexLocker lock(ef->m_mutex);
ef->m_mutex.lock(tid);
tids.resize(ef->waiters.size());
for (u32 i = 0; i < ef->waiters.size(); i++)
{
tids[i] = ef->waiters[i].tid;
}
ef->waiters.clear();
ef->m_mutex.unlock(tid);
}
for (u32 i = 0; i < tids.size(); i++)
@ -349,8 +361,9 @@ s32 sys_event_flag_get(u32 eflag_id, vm::ptr<be_t<u64>> flags)
EventFlag* ef;
if (!sys_event_flag.CheckId(eflag_id, ef)) return CELL_ESRCH;
SMutexLocker lock(ef->m_mutex);
const u32 tid = GetCurrentPPUThread().GetId();
ef->m_mutex.lock(tid);
*flags = ef->flags;
ef->m_mutex.unlock(tid);
return CELL_OK;
}

View file

@ -178,7 +178,6 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
*thread_id = new_thread.GetId();
new_thread.SetEntry(entry);
new_thread.SetArg(0, arg);
new_thread.SetPrio(prio);
new_thread.SetStackSize(stacksize);
//new_thread.flags = flags;
@ -191,6 +190,7 @@ s32 sys_ppu_thread_create(vm::ptr<be_t<u64>> thread_id, u32 entry, u64 arg, s32
if (!is_interrupt)
{
new_thread.Run();
new_thread.GPR[3] = arg;
new_thread.Exec();
}
else

View file

@ -82,7 +82,7 @@ s32 sys_spu_thread_initialize(vm::ptr<be_t<u32>> thread, u32 group, u32 spu_num,
// Copy SPU image:
// TODO: use correct segment info
auto spu_offset = Memory.Alloc(256 * 1024, 4096);
u32 spu_offset = (u32)Memory.Alloc(256 * 1024, 4096);
memcpy(vm::get_ptr<void>(spu_offset), vm::get_ptr<void>(img->segs_addr), 256 * 1024);
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_SPU);
@ -90,15 +90,15 @@ s32 sys_spu_thread_initialize(vm::ptr<be_t<u32>> thread, u32 group, u32 spu_num,
new_thread.SetOffset(spu_offset);
new_thread.SetEntry(spu_ep);
new_thread.SetName(name);
new_thread.SetArg(0, a1);
new_thread.SetArg(1, a2);
new_thread.SetArg(2, a3);
new_thread.SetArg(3, a4);
new_thread.Run();
static_cast<SPUThread&>(new_thread).GPR[3] = u128::from64(0, a1);
static_cast<SPUThread&>(new_thread).GPR[4] = u128::from64(0, a2);
static_cast<SPUThread&>(new_thread).GPR[5] = u128::from64(0, a3);
static_cast<SPUThread&>(new_thread).GPR[6] = u128::from64(0, a4);
u32 id = new_thread.GetId();
*thread = group_info->list[spu_num] = id;
(*(SPUThread*)&new_thread).group = group_info;
static_cast<SPUThread&>(new_thread).group = group_info;
sys_spu.Warning("*** New SPU Thread [%s] (img_offset=0x%x, ls_offset=0x%x, ep=0x%x, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx): id=%d",
(attr->name ? attr->name.get_ptr() : ""), (u32)img->segs_addr, ((SPUThread&)new_thread).dmac.ls_offset, spu_ep, a1, a2, a3, a4, id);
@ -117,10 +117,12 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr<sys_spu_thread_argument> arg)
return CELL_ESRCH;
}
thr->SetArg(0, arg->arg1);
thr->SetArg(1, arg->arg2);
thr->SetArg(2, arg->arg3);
thr->SetArg(3, arg->arg4);
SPUThread& spu = *(SPUThread*)thr;
spu.GPR[3] = u128::from64(0, arg->arg1);
spu.GPR[4] = u128::from64(0, arg->arg2);
spu.GPR[5] = u128::from64(0, arg->arg3);
spu.GPR[6] = u128::from64(0, arg->arg4);
return CELL_OK;
}

View file

@ -33,6 +33,6 @@ s32 sys_tty_write(s32 ch, vm::ptr<const void> buf, u32 len, vm::ptr<u32> pwritel
LOG_ERROR(TTY, "%s", data.c_str());
}
*pwritelen = data.size();
*pwritelen = (u32)data.size();
return CELL_OK;
}

View file

@ -333,16 +333,11 @@ void Emulator::Load()
LOG_NOTICE(LOADER, "max addr = 0x%x", l.GetMaxAddr());
thread.SetOffset(Memory.MainMem.GetStartAddr());
thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr());
thread.Run();
break;
case MACHINE_PPC64:
{
thread.SetEntry(l.GetEntry());
Memory.StackMem.AllocAlign(0x1000);
thread.InitStack();
thread.AddArgv(m_elf_path); // it doesn't work
//thread.AddArgv("-emu");
m_rsx_callback = (u32)Memory.MainMem.AllocAlign(4 * 4) + 4;
vm::write32(m_rsx_callback - 4, m_rsx_callback);
@ -366,11 +361,29 @@ void Emulator::Load()
ppu_thr_stop_data[1] = BCLR(0x10 | 0x04, 0, 0, 0);
vm::write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
thread.SetEntry(l.GetEntry());
thread.SetStackSize(0x10000);
thread.SetPrio(0x50);
thread.Run();
u32 arg1 = Memory.MainMem.AllocAlign(m_elf_path.size() + 1 + 0x20, 0x10) + 0x20;
memcpy(vm::get_ptr<char>(arg1), m_elf_path.c_str(), m_elf_path.size() + 1);
u32 argv = arg1 - 0x20;
vm::write64(argv, arg1);
static_cast<PPUThread&>(thread).GPR[3] = 1; // arg count
static_cast<PPUThread&>(thread).GPR[4] = argv; // probably, args**
static_cast<PPUThread&>(thread).GPR[5] = argv + 0x10; // unknown
static_cast<PPUThread&>(thread).GPR[6] = 0; // unknown
static_cast<PPUThread&>(thread).GPR[12] = Emu.GetMallocPageSize(); // ???
//thread.AddArgv("-emu");
}
break;
default:
thread.SetEntry(l.GetEntry());
thread.Run();
break;
}
@ -381,8 +394,6 @@ void Emulator::Load()
GetAudioManager().Init();
GetEventManager().Init();
thread.Run();
SendDbgCommand(DID_READY_EMU);
}

View file

@ -91,7 +91,7 @@ void DisAsmFrame::AddLine(const wxString line)
return;
}
m_disasm_list->SetItem(count, 0, wxString::Format("%llx", CPU.PC));
m_disasm_list->SetItem(count, 0, wxString::Format("%x", CPU.PC));
m_disasm_list->SetItem(count, 1, line);
++count;
@ -480,11 +480,11 @@ void DisAsmFrame::SetPc(wxCommandEvent& WXUNUSED(event))
diag.SetSizerAndFit( s_panel );
p_pc->SetLabel(wxString::Format("%llx", CPU.PC));
p_pc->SetLabel(wxString::Format("%x", CPU.PC));
if(diag.ShowModal() == wxID_OK)
{
sscanf(fmt::ToUTF8(p_pc->GetLabel()).c_str(), "%llx", &CPU.PC);
sscanf(fmt::ToUTF8(p_pc->GetLabel()).c_str(), "%x", &CPU.PC);
Resume();
}
}

View file

@ -63,6 +63,7 @@ void GLGSFrame::Flip(void* context)
if (fps_t.GetElapsedTimeInSec() >= 0.5)
{
// can freeze on exit
SetTitle(wxString::Format("FPS: %.2f", (double)m_frames / fps_t.GetElapsedTimeInSec()));
m_frames = 0;
fps_t.Start();

View file

@ -456,7 +456,7 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
diag->SetSizerAndFit( s_panel );
if(CPU) p_pc->SetValue(wxString::Format("%llx", CPU->PC));
if(CPU) p_pc->SetValue(wxString::Format("%x", CPU->PC));
if(diag->ShowModal() == wxID_OK)
{

View file

@ -1,7 +1,7 @@
#pragma once
#include "Loader.h"
class vfsStream;
struct vfsStream;
enum ElfClass
{

View file

@ -350,7 +350,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
{
if (!Memory.MainMem.AllocFixed(offset + phdr.p_vaddr, (u32)phdr.p_memsz))
{
LOG_ERROR(LOADER, "%s(): AllocFixed(0x%llx, 0x%llx) failed", __FUNCTION__, offset + phdr.p_vaddr, phdr.p_memsz);
LOG_ERROR(LOADER, "%s(): AllocFixed(0x%llx, 0x%x) failed", __FUNCTION__, offset + phdr.p_vaddr, (u32)phdr.p_memsz);
}
else if (phdr.p_filesz)
{