Fixed conflicts

This commit is contained in:
Alexandro Sánchez Bach 2013-12-09 18:07:13 +01:00
commit e2de06da63
42 changed files with 2258 additions and 1395 deletions

4
bin/dev_usb000/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -67,10 +67,10 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); *value = Prxy.QueryMask.GetValue(); break;
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); *value = Prxy.TagStatus.GetValue(); break;
case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_Out_MBox)", m_index); while(!SPU.Out_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break;
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); *value = SPU.In_MBox.GetValue(); break;
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); while(!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) Sleep(1); break;
case SPU_MBox_Status_offs: //ConLog.Warning("RawSPUThread[%d]: Read32(SPU_MBox_Status)", m_index);
SPU.MBox_Status.SetValue(SPU.Out_MBox.GetCount() ? SPU.MBox_Status.GetValue() | 1 : SPU.MBox_Status.GetValue() & ~1);
SPU.MBox_Status.SetValue((SPU.MBox_Status.GetValue() & ~0xff00) | (SPU.In_MBox.GetCount() << 8));
//SPU.MBox_Status.SetValue(SPU.Out_MBox.GetCount() ? SPU.MBox_Status.GetValue() | 1 : SPU.MBox_Status.GetValue() & ~1);
SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8));
*value = SPU.MBox_Status.GetValue();
break;
case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = SPU.RunCntl.GetValue(); break;
@ -156,38 +156,9 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
case MFC_EAL_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_EAL, 0x%x)", m_index, value); MFC.EAL.SetValue(value); break;
case MFC_Size_Tag_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_Size_Tag, 0x%x)", m_index, value); MFC.Size_Tag.SetValue(value); break;
case MFC_CMDStatus_offs:
{
ConLog.Warning("RawSPUThread[%d]: Write32(MFC_CMDStatus, 0x%x)", m_index, value);
MFC.CMDStatus.SetValue(value);
u16 op = value & MFC_MASK_CMD;
switch(op)
{
case MFC_PUT_CMD:
case MFC_GET_CMD:
{
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("RawSPUThread[%d]: DMA %s:", m_index, op == MFC_PUT_CMD ? "PUT" : "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();
MFC.CMDStatus.SetValue(dmac.Cmd(value, tag, lsa, ea, size));
}
break;
default:
ConLog.Error("RawSPUThread[%d]: Unknown MFC cmd. (opcode=0x%x, cmd=0x%x)", m_index, op, value);
break;
}
}
DoMfcCmd();
break;
case MFC_QStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); MFC.QStatus.SetValue(value); break;
case Prxy_QueryType_offs:
@ -213,7 +184,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
case Prxy_QueryMask_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); Prxy.QueryMask.SetValue(value); break;
case Prxy_TagStatus_offs: ConLog.Warning("RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); Prxy.TagStatus.SetValue(value); break;
case SPU_Out_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); while(!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break;
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value); SPU.In_MBox.SetValue(value); break;
case SPU_In_MBox_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_In_MBox, 0x%x)", m_index, value); while(!SPU.In_MBox.Push(value) && !Emu.IsStopped()) Sleep(1); break;
case SPU_MBox_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break;
case SPU_RunCntl_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_RunCntl, 0x%x)", m_index, value); SPU.RunCntl.SetValue(value); break;
case SPU_Status_offs: ConLog.Warning("RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); SPU.Status.SetValue(value); break;
@ -284,7 +255,8 @@ void RawSPUThread::Task()
}
}
bool is_last_paused = SPU.RunCntl.GetValue() == SPU_RUNCNTL_STOP;
bool is_last_paused = true;
while(true)
{
int status = ThreadStatus();
@ -306,11 +278,9 @@ void RawSPUThread::Task()
{
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);
}
is_last_paused = true;
SPU.NPC.SetValue(PC);
SPU.Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL);
}
Sleep(1);
@ -322,6 +292,7 @@ void RawSPUThread::Task()
is_last_paused = false;
PC = SPU.NPC.GetValue();
SPU.Status.SetValue(SPU_STATUS_RUNNING);
ConLog.Warning("Starting RawSPU...");
}
Step();
@ -330,7 +301,7 @@ void RawSPUThread::Task()
if(status == CPUThread_Step)
{
m_is_step = false;
break;
continue;
}
for(uint i=0; i<bp.GetCount(); ++i)
@ -338,7 +309,7 @@ void RawSPUThread::Task()
if(bp[i] == PC)
{
Emu.Pause();
break;
continue;
}
}
}

View File

@ -852,7 +852,7 @@ private:
{
DisAsm("hbrr", DisAsmBranchTarget(ro), DisAsmBranchTarget(i16));
}
void ILA(u32 rt, s32 i18)
void ILA(u32 rt, u32 i18)
{
DisAsm("ila", spu_reg_name[rt], i18);
}

File diff suppressed because it is too large Load Diff

View File

@ -435,7 +435,7 @@ public:
//0 - 6
virtual void HBRA(s32 ro, s32 i16) = 0;
virtual void HBRR(s32 ro, s32 i16) = 0;
virtual void ILA(u32 rt, s32 i18) = 0;
virtual void ILA(u32 rt, u32 i18) = 0;
//0 - 3
virtual void SELB(u32 rc, u32 ra, u32 rb, u32 rt) = 0;

View File

@ -51,7 +51,7 @@ void SPUThread::InitRegs()
SPU.Status.SetValue(SPU_STATUS_RUNNING);
Prxy.QueryType.SetValue(0);
MFC.CMDStatus.SetValue(0);
PC = SPU.NPC.GetValue();
//PC = SPU.NPC.GetValue();
}
u64 SPUThread::GetFreeStackSize() const

View File

@ -3,7 +3,7 @@
#include "Emu/event.h"
#include "MFC.h"
static const wxString spu_reg_name[128] =
static const char* spu_reg_name[128] =
{
"$LR", "$SP", "$2", "$3", "$4", "$5", "$6", "$7",
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
@ -23,7 +23,7 @@ static const wxString spu_reg_name[128] =
"$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127",
};
//SPU reg $0 is a dummy reg, and is used for certain instructions.
static const wxString spu_specialreg_name[128] = {
static const char* spu_specialreg_name[128] = {
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
@ -42,7 +42,7 @@ static const wxString spu_specialreg_name[128] = {
"$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127",
};
static const wxString spu_ch_name[128] =
static const char* spu_ch_name[128] =
{
"$SPU_RdEventStat", "$SPU_WrEventMask", "$SPU_WrEventAck", "$SPU_RdSigNotify1",
"$SPU_RdSigNotify2", "$ch5", "$ch6", "$SPU_WrDec", "$SPU_RdDec",
@ -204,6 +204,8 @@ union SPU_GPR_hdr
{
u128 _u128;
s128 _i128;
__m128 _m128;
__m128i _m128i;
u64 _u64[2];
s64 _i64[2];
u32 _u32[4];
@ -232,13 +234,13 @@ union SPU_SPR_hdr
{
u128 _u128;
s128 _i128;
u32 _u32[4];
SPU_SPR_hdr() {}
wxString ToString() const
{
return wxString::Format("%16%16", _u128.hi, _u128.lo);
return wxString::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]);
}
void Reset()
@ -351,10 +353,72 @@ public:
DMAC dmac;
void DoMfcCmd()
{
u32 cmd = MFC.CMDStatus.GetValue();
u16 op = cmd & MFC_MASK_CMD;
switch(op & (MFC_PUT_CMD | MFC_GET_CMD))
{
case MFC_PUT_CMD:
case MFC_GET_CMD:
{
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("DMA %s:", op & MFC_PUT_CMD ? "PUT" : "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.Warning("*** cmd = 0x%x", cmd);
ConLog.SkipLn();
MFC.CMDStatus.SetValue(dmac.Cmd(cmd, tag, lsa, ea, size));
}
break;
default:
ConLog.Error("Unknown MFC cmd. (opcode=0x%x, cmd=0x%x)", op, cmd);
break;
}
}
u32 GetChannelCount(u32 ch)
{
switch(ch)
{
case SPU_RdEventStat: //Read event status with mask applied
case SPU_WrEventMask: //Write event mask
case SPU_WrEventAck: //Write end of event processing
case SPU_RdSigNotify1: //Signal notification 1
case SPU_RdSigNotify2: //Signal notification 2
case SPU_WrDec: //Write decrementer count
case SPU_RdDec: //Read decrementer count
case SPU_RdEventMask: //Read event mask
case SPU_RdMachStat: //Read SPU run status
case SPU_WrSRR0: //Write SPU machine state save/restore register 0 (SRR0)
case SPU_RdSRR0: //Read SPU machine state save/restore register 0 (SRR0)
case MFC_WrMSSyncReq: //Write multisource synchronization request
case MFC_RdTagMask: //Read tag mask
case MFC_LSA: //Write local memory address command parameter
case MFC_EAH: //Write high order DMA effective address command parameter
case MFC_EAL: //Write low order DMA effective address command parameter
case MFC_Size: //Write DMA transfer size command parameter
case MFC_TagID: //Write tag identifier command parameter
case MFC_Cmd: //Write and enqueue DMA command with associated class ID
case MFC_WrTagMask: //Write tag mask
case MFC_WrTagUpdate: //Write request for conditional or unconditional tag status update
case MFC_RdTagStat: //Read tag status with mask applied
case MFC_RdListStallStat: //Read DMA list stall-and-notify status
case MFC_WrListStallAck: //Write DMA list stall-and-notify acknowledge
case MFC_RdAtomicStat: //Read completion status of last completed immediate MFC atomic update command
ConLog.Error("%s error: unimplemented channel (%s).", __FUNCTION__, spu_ch_name[ch]);
break;
case SPU_WrOutMbox:
return SPU.Out_MBox.GetFreeCount();
@ -365,7 +429,7 @@ public:
return 0;//return SPU.OutIntr_Mbox.GetFreeCount();
default:
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break;
}
@ -376,11 +440,11 @@ public:
{
const u32 v = r._u32[3];
ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v);
switch(ch)
{
case SPU_WrOutIntrMbox:
ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v);
while(!SPU.OutIntr_Mbox.Push(v) && !Emu.IsStopped())
{
Sleep(1);
@ -388,16 +452,47 @@ public:
break;
case SPU_WrOutMbox:
ConLog.Warning("SPU_WrOutMbox = 0x%x", v);
while(!SPU.Out_MBox.Push(v) && !Emu.IsStopped())
{
Sleep(1);
}
break;
case MFC_WrTagMask:
Prxy.QueryMask.SetValue(v);
break;
case MFC_WrTagUpdate:
Prxy.TagStatus.SetValue(Prxy.QueryMask.GetValue());
break;
case MFC_LSA:
MFC.LSA.SetValue(v);
break;
case MFC_EAH:
MFC.EAH.SetValue(v);
break;
case MFC_EAL:
MFC.EAL.SetValue(v);
break;
case MFC_Size:
MFC.Size_Tag.SetValue((MFC.Size_Tag.GetValue() & 0xffff) | (v << 16));
break;
case MFC_TagID:
MFC.Size_Tag.SetValue((MFC.Size_Tag.GetValue() & ~0xffff) | (v & 0xffff));
break;
case MFC_Cmd:
MFC.CMDStatus.SetValue(v);
DoMfcCmd();
break;
default:
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break;
}
}
@ -411,13 +506,18 @@ public:
{
case SPU_RdInMbox:
if(!SPU.In_MBox.Pop(v)) v = 0;
ConLog.Warning("%s: SPU_RdInMbox(0x%x).", __FUNCTION__, v);
break;
case MFC_RdTagStat:
v = Prxy.TagStatus.GetValue();
break;
default:
ConLog.Error("%s error: unknown/illegal channel (%d).", __FUNCTION__, ch);
ConLog.Error("%s error: unknown/illegal channel (%d [%s]).", __FUNCTION__, ch, spu_ch_name[ch]);
break;
}
ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]);
}
bool IsGoodLSA(const u32 lsa) const { return Memory.IsGoodAddr(lsa + m_offset) && lsa < 0x40000; }

View File

@ -175,17 +175,16 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
res[idx].path = "$(EmulatorDir)\\dev_hdd1\\";
res[idx].mount = "/dev_hdd1/";
res[idx].device = vfsDevice_LocalFile;
/*
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "";
res[idx].path = "$(EmulatorDir)\\dev_usb000\\";
res[idx].mount = "/dev_usb000/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "/";
res[idx].path = "$(EmulatorDir)\\dev_usb000\\";
res[idx].mount = "/dev_usb/";
res[idx].device = vfsDevice_LocalFile;
*/
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
@ -196,6 +195,12 @@ void VFS::SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load)
res[idx].path = "";
res[idx].mount = "/host_root/";
res[idx].device = vfsDevice_LocalFile;
idx = res.Move(new VFSManagerEntry());
res[idx].path = "$(GameDir)";
res[idx].mount = "/";
res[idx].device = vfsDevice_LocalFile;
return;
}

View File

@ -1051,7 +1051,30 @@ void GLGSRender::ExecCMD()
void GLGSRender::Flip()
{
if(m_fbo.IsCreated())
if(m_read_buffer)
{
gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr);
u32 width = re(buffers[m_gcm_current_buffer].width);
u32 height = re(buffers[m_gcm_current_buffer].height);
u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL);
if(Memory.IsGoodAddr(addr))
{
//TODO
//buffer rotating
static Array<u8> pixels;
pixels.SetCount(width * height * 4);
u8* src = (u8*)Memory.VirtualToRealAddr(addr);
for(u32 y=0; y<height; ++y)
{
memcpy(pixels + (height - y - 1) * width * 4, src + y * width * 4, width * 4);
}
glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels.GetPtr());
}
}
else if(m_fbo.IsCreated())
{
m_fbo.Bind(GL_READ_FRAMEBUFFER);
GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0);

View File

@ -126,16 +126,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
Flip();
m_gcm_current_buffer = args[0];
m_read_buffer = true;
m_flip_status = 0;
if(m_flip_handler)
{
m_flip_handler.Handle(1, 0, 0);
m_flip_handler.Branch(false);
}
SemaphorePostAndWait(m_sem_flip);
//Emu.Pause();
}
break;
@ -612,6 +611,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
//ConLog.Warning("NV4097_SET_BEGIN_END: %x", a0);
m_read_buffer = false;
if(a0)
{
Begin(a0);
@ -1396,7 +1397,12 @@ void RSXThread::Task()
if(put == get || !Emu.IsRunning())
{
if(put == get)
{
if(m_flip_status == 0)
SemaphorePostAndWait(m_sem_flip);
SemaphorePostAndWait(m_sem_flush);
}
Sleep(1);
continue;

View File

@ -516,6 +516,7 @@ public:
u32 m_surface_colour_target;
u8 m_begin_end;
bool m_read_buffer;
protected:
RSXThread()
@ -530,6 +531,8 @@ protected:
, m_draw_mode(0)
, m_draw_array_count(0)
, m_draw_array_first(~0)
, m_gcm_current_buffer(0)
, m_read_buffer(true)
{
m_set_alpha_test = false;
m_set_blend = false;

View File

@ -133,6 +133,7 @@ bool DynamicMemoryBlockBase<PT>::Free(u64 addr)
{
if(addr == m_used_mem[i].addr)
{
if(IsLocked(m_used_mem[i].addr)) return false;
m_used_mem.RemoveAt(i);
return true;
}
@ -158,3 +159,68 @@ u8* DynamicMemoryBlockBase<PT>::GetMem(u64 addr) const
assert(0);
return nullptr;
}
template<typename PT>
bool DynamicMemoryBlockBase<PT>::IsLocked(const u64 addr)
{
for(u32 i=0; i<m_locked_mem.GetCount(); ++i)
{
if(addr == m_locked_mem[i].addr)
{
return true;
}
}
return false;
}
template<typename PT>
void DynamicMemoryBlockBase<PT>::AppendLockedMem(u64 addr, u32 size)
{
m_locked_mem.Move(new MemBlockInfo(addr, size));
}
template<typename PT>
bool DynamicMemoryBlockBase<PT>::Lock(u64 addr, u32 size)
{
if(!IsInMyRange(addr, size))
{
assert(0);
return false;
}
if(IsMyAddress(addr) || IsMyAddress(addr + size - 1))
{
return false;
}
AppendLockedMem(addr, size);
return true;
}
template<typename PT>
bool DynamicMemoryBlockBase<PT>::Unlock(u64 addr , u32 size)
{
for(u32 i=0; i<m_locked_mem.GetCount(); ++i)
{
if(addr == m_locked_mem[i].addr)
{
if(m_locked_mem.Get(i).size > size)
{
m_locked_mem.Get(i).size -= size;
}
else if(m_locked_mem.Get(i).size == size)
{
m_locked_mem.RemoveAt(i);
}
else
{
return false;
}
return true;
}
}
return false;
}

View File

@ -210,7 +210,7 @@ __forceinline void MemoryBlock::FastWrite128(const u64 addr, const u128 value)
bool MemoryBlock::Write8(const u64 addr, const u8 value)
{
if(!IsMyAddress(addr)) return false;
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
FastWrite8(FixAddr(addr), value);
return true;
@ -218,7 +218,7 @@ bool MemoryBlock::Write8(const u64 addr, const u8 value)
bool MemoryBlock::Write16(const u64 addr, const u16 value)
{
if(!IsMyAddress(addr)) return false;
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
FastWrite16(FixAddr(addr), value);
return true;
@ -226,7 +226,7 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value)
bool MemoryBlock::Write32(const u64 addr, const u32 value)
{
if(!IsMyAddress(addr)) return false;
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
FastWrite32(FixAddr(addr), value);
return true;
@ -234,7 +234,7 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value)
bool MemoryBlock::Write64(const u64 addr, const u64 value)
{
if(!IsMyAddress(addr)) return false;
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
FastWrite64(FixAddr(addr), value);
return true;
@ -242,7 +242,7 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value)
bool MemoryBlock::Write128(const u64 addr, const u128 value)
{
if(!IsMyAddress(addr)) return false;
if(!IsMyAddress(addr) || IsLocked(addr)) return false;
FastWrite128(FixAddr(addr), value);
return true;

View File

@ -356,6 +356,16 @@ public:
return UserMemory->Free(addr);
}
bool Lock(const u64 addr, const u32 size)
{
return UserMemory->Lock(addr, size);
}
bool Unlock(const u64 addr, const u32 size)
{
return UserMemory->Unlock(addr, size);
}
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
{
if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr))

View File

@ -70,6 +70,7 @@ public:
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
virtual bool IsMyAddress(const u64 addr);
virtual bool IsLocked(const u64 addr) { return false; }
__forceinline const u8 FastRead8(const u64 addr) const;
__forceinline const u16 FastRead16(const u64 addr) const;
@ -106,6 +107,8 @@ public:
virtual u64 Alloc(u32 size) { return 0; }
virtual bool Alloc() { return false; }
virtual bool Free(u64 addr) { return false; }
virtual bool Lock(u64 addr, u32 size) { return false; }
virtual bool Unlock(u64 addr, u32 size) { return false; }
};
class MemoryBlockLE : public MemoryBlock
@ -171,6 +174,7 @@ template<typename PT>
class DynamicMemoryBlockBase : public PT
{
Array<MemBlockInfo> m_used_mem;
Array<MemBlockInfo> m_locked_mem;
u32 m_max_size;
public:
@ -182,6 +186,7 @@ public:
virtual bool IsInMyRange(const u64 addr);
virtual bool IsInMyRange(const u64 addr, const u32 size);
virtual bool IsMyAddress(const u64 addr);
virtual bool IsLocked(const u64 addr);
virtual MemoryBlock* SetRange(const u64 start, const u32 size);
@ -191,11 +196,14 @@ public:
virtual u64 Alloc(u32 size);
virtual bool Alloc();
virtual bool Free(u64 addr);
virtual bool Lock(u64 addr, u32 size);
virtual bool Unlock(u64 addr, u32 size);
virtual u8* GetMem(u64 addr) const;
private:
void AppendUsedMem(u64 addr, u32 size);
void AppendLockedMem(u64 addr, u32 size);
};
#include "DynamicMemoryBlockBase.inl"

View File

@ -107,12 +107,14 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_t<CellGameConten
if (!type.IsGood() || !attributes.IsGood() || !size.IsGood() || !dirName.IsGood())
return CELL_GAME_ERROR_PARAM;
wxString dir ("/dev_hdd0/game/" + Emu.m_title_id + "/USRDIR");
type = CELL_GAME_GAMETYPE_DISC;
attributes = 0;
size->hddFreeSizeKB = 40000000; //40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run.
size->sizeKB = CELL_GAME_SIZEKB_NOTCALC;
size->sysSizeKB = 0;
//TODO: dirName
Memory.WriteString(dirName.GetAddr(), dir);
return CELL_OK;
}
@ -129,9 +131,14 @@ int cellGameDataCheck()
return CELL_OK;
}
int cellGameContentPermit()
int cellGameContentPermit(mem_list_ptr_t<u8> contentInfoPath, mem_list_ptr_t<u8> usrdirPath)
{
UNIMPLEMENTED_FUNC(cellGame);
cellGame.Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)",
contentInfoPath.GetAddr(), usrdirPath.GetAddr());
if (!contentInfoPath.IsGood() || !usrdirPath.IsGood())
return CELL_GAME_ERROR_PARAM;
return CELL_OK;
}

View File

@ -39,13 +39,24 @@ int cellGcmMapMainMemory(u32 address, u32 size, mem32_t offset)
return CELL_OK;
}
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
{
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
//Memory.Map(io, ea, size);
//Emu.GetGSManager().GetRender().m_ioAddress = io;
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
return CELL_OK;
}
int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
{
cellGcmSys.Log("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
cellGcmSys.Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress);
const u32 local_size = 0xf900000; //TODO
const u32 local_addr = Memory.RSXFBMem.GetStartAddr();
cellGcmSys.Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size);
map_offset_addr = 0;
map_offset_pos = 0;
current_config.ioSize = re32(ioSize);
@ -144,6 +155,7 @@ int cellGcmAddressToOffset(u32 address, mem32_t offset)
}
offset = address - sa;
//ConLog.Warning("Address To Offset: 0x%x -> 0x%x", address, address - sa);
//Memory.Write16(map_offset_addr + map_offset_pos + 0, ea);
//Memory.Write16(map_offset_addr + map_offset_pos + 2, offset);
//map_offset_pos += 4;
@ -153,7 +165,7 @@ int cellGcmAddressToOffset(u32 address, mem32_t offset)
int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height)
{
cellGcmSys.Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
cellGcmSys.Warning("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)",
id, offset, width ? pitch/width : pitch, width, height);
if(id > 7) return CELL_EINVAL;
@ -284,6 +296,12 @@ u32 cellGcmGetTiledPitchSize(u32 size)
return size;
}
u32 cellGcmSetUserHandler(u32 handler)
{
cellGcmSys.Warning("cellGcmSetUserHandler(handler=0x%x)", handler);
return handler;
}
u32 cellGcmGetDefaultCommandWordSize()
{
cellGcmSys.Warning("cellGcmGetDefaultCommandWordSize()");
@ -302,14 +320,6 @@ int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize)
return CELL_OK;
}
int cellGcmMapEaIoAddress(const u32 ea, const u32 io, const u32 size)
{
cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size);
Memory.Map(io, ea, size);
Emu.GetGSManager().GetRender().m_report_main_addr = ea;
return CELL_OK;
}
int cellGcmUnbindZcull(u8 index)
{
cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index);
@ -347,7 +357,23 @@ int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 lab
{
int res = cellGcmSetPrepareFlip(ctx, id);
Memory.Write32(Memory.RSXCMDMem.GetStartAddr() + 0x10 * label_index, label_value);
return res == CELL_GCM_ERROR_FAILURE ? CELL_GCM_ERROR_FAILURE : CELL_OK;
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
}
int cellGcmSetFlip(mem_ptr_t<CellGcmContextData> ctxt, u32 id)
{
cellGcmSys.Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.GetAddr(), id);
int res = cellGcmSetPrepareFlip(ctxt, id);
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
}
int cellGcmSetWaitFlip(mem_ptr_t<CellGcmContextData> ctxt)
{
cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr());
GSLockCurrent lock(GS_LOCK_WAIT_FLIP);
return CELL_OK;
}
int cellGcmInitCursor()
@ -525,6 +551,8 @@ int cellGcmSetDebugOutputLevel (int level)
default: return CELL_EINVAL;
}
return CELL_OK;
}
int cellGcmSetSecondVFrequency (u32 freq)
@ -541,11 +569,14 @@ int cellGcmSetSecondVFrequency (u32 freq)
default: return CELL_EINVAL;
}
return CELL_OK;
}
void cellGcmSys_init()
{
cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize);
cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler);
cellGcmSys.AddFunc(0x15bae46b, cellGcmInit);
cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand);
cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset);
@ -589,4 +620,6 @@ void cellGcmSys_init()
cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation);
cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel);
cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency);
cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip);
cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip);
}

View File

@ -600,6 +600,7 @@ int cellRescGetBufferSize(mem32_t colorBuffers, mem32_t vertexArray, mem32_t fra
colorBuffersSize = s_rescInternalInstance->m_dstBufInterval * GetNumColorBuffers();
vertexArraySize = 0x180; //sizeof(RescVertex_t) * VERTEX_NUMBER_RESERVED;
//fragmentUcodeSize = m_pCFragmentShader->GetUcodeSize();
fragmentUcodeSize = 0x300;
}
else //CELL_RESC_CONSTANT_VRAM
{

View File

@ -386,17 +386,32 @@ int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 option_addr)
int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, mem_ptr_t<CellVideoOutDeviceInfo> info)
{
cellSysutil.Error("Unimplemented function: cellVideoOutGetDeviceInfo(videoOut=%u, deviceIndex=%u, info_addr=0x%x)",
cellSysutil.Warning("cellVideoOutGetDeviceInfo(videoOut=%u, deviceIndex=%u, info_addr=0x%x)",
videoOut, deviceIndex, info.GetAddr());
if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND;
// Use standard dummy values for now.
info->portType = CELL_VIDEO_OUT_PORT_HDMI;
info->colorSpace = Emu.GetGSManager().GetColorSpace();
//info->latency = ;
//info->availableModeCount = ;
info->latency = 1000;
info->availableModeCount = 1;
info->state = CELL_VIDEO_OUT_DEVICE_STATE_AVAILABLE;
//info->rgbOutputRange = ;
info->rgbOutputRange = 1;
info->colorInfo.blueX = 0xFFFF;
info->colorInfo.blueY = 0xFFFF;
info->colorInfo.greenX = 0xFFFF;
info->colorInfo.greenY = 0xFFFF;
info->colorInfo.redX = 0xFFFF;
info->colorInfo.redY = 0xFFFF;
info->colorInfo.whiteX = 0xFFFF;
info->colorInfo.whiteY = 0xFFFF;
info->colorInfo.gamma = 100;
info->availableModes[0].aspect = 0;
info->availableModes[0].conversion = 0;
info->availableModes[0].refreshRates = 0xF;
info->availableModes[0].resolutionId = 1;
info->availableModes[0].scanMode = 0;
return CELL_OK;
}

View File

@ -28,9 +28,9 @@ int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5)
return 0;
}
s64 sys_prx_register_library()
s64 sys_prx_register_library(u32 lib_addr)
{
sysPrxForUser.Error("sys_prx_register_library()");
sysPrxForUser.Error("sys_prx_register_library(lib_addr=0x%x)", lib_addr);
return 0;
}
@ -79,4 +79,7 @@ void sysPrxForUser_init()
//sysPrxForUser.AddFunc(0xaede4b03, sys_heap_free);
//sysPrxForUser.AddFunc(0x8a561d92, sys_heap_delete_heap);
sysPrxForUser.AddFunc(0xb2fcf2c8, sys_heap_create_heap);
sysPrxForUser.AddFunc(0xb257540b, sys_mmapper_allocate_memory);
sysPrxForUser.AddFunc(0xdc578057, sys_mmapper_map_memory);
}

View File

@ -13,6 +13,7 @@ void sys_io_init()
sys_io.AddFunc(0x8b72cda1, cellPadGetData);
sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra);
sys_io.AddFunc(0xf65544ee, cellPadSetActDirect);
sys_io.AddFunc(0x3aaad464, cellPadGetInfo);
sys_io.AddFunc(0xa703a51d, cellPadGetInfo2);
sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting);

View File

@ -52,8 +52,8 @@ static func_caller* sc_table[1024] =
null_func, //77 (0x04D)
null_func, //78 (0x04E)
null_func, //79 (0x04F)
null_func, null_func, null_func, null_func, null_func, //84
null_func, null_func, null_func, null_func, null_func, //89
null_func, null_func, bind_func(sys_event_flag_create), bind_func(sys_event_flag_destroy), null_func, //84
bind_func(sys_event_flag_wait), bind_func(sys_event_flag_trywait), bind_func(sys_event_flag_set), null_func, null_func, //89
bind_func(sys_semaphore_create), //90 (0x05A)
bind_func(sys_semaphore_destroy), //91 (0x05B)
bind_func(sys_semaphore_wait), //92 (0x05C)
@ -76,7 +76,7 @@ static func_caller* sc_table[1024] =
bind_func(sys_cond_signal_all), //109 (0x06D)
null_func, null_func, null_func, null_func, //113 (0x071)
bind_func(sys_semaphore_get_value), //114 (0x072)
null_func, null_func, null_func, null_func, null_func, //119 (0x077)
null_func, null_func, null_func, bind_func(sys_event_flag_clear), null_func, //119 (0x077)
bind_func(sys_rwlock_create), //120 (0x078)
bind_func(sys_rwlock_destroy), //121 (0x079)
bind_func(sys_rwlock_rlock), //122 (0x07A)
@ -87,8 +87,8 @@ static func_caller* sc_table[1024] =
bind_func(sys_rwlock_wunlock), //127 (0x07F)
bind_func(sys_event_queue_create), //128 (0x080)
null_func, //129 (0x081)
bind_func(sys_event_queue_receive), null_func, null_func, null_func, bind_func(sys_event_port_create), //134
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), null_func, //139
bind_func(sys_event_queue_receive), null_func, bind_func(sys_event_flag_cancel), null_func, bind_func(sys_event_port_create), //134
null_func, bind_func(sys_event_port_connect_local), null_func, bind_func(sys_event_port_send), bind_func(sys_event_flag_get), //139
null_func, bind_func(sys_timer_usleep), bind_func(sys_timer_sleep), null_func, bind_func(sys_time_get_timezone), //144
bind_func(sys_time_get_current_time), bind_func(sys_time_get_system_time), bind_func(sys_time_get_timebase_frequency), null_func, null_func, //149
null_func, null_func, null_func, null_func, null_func, //154
@ -121,15 +121,15 @@ static func_caller* sc_table[1024] =
null_func, null_func, null_func, null_func, null_func, //289
null_func, null_func, null_func, null_func, null_func, //294
null_func, null_func, null_func, null_func, null_func, //299
null_func, null_func, null_func, null_func, null_func, //304
null_func, null_func, null_func, null_func, null_func, //309
null_func, null_func, null_func, null_func, null_func, //314
bind_func(sys_vm_memory_map), bind_func(sys_vm_unmap), bind_func(sys_vm_append_memory), bind_func(sys_vm_return_memory), bind_func(sys_vm_lock), //304
bind_func(sys_vm_unlock), bind_func(sys_vm_touch), bind_func(sys_vm_flush), bind_func(sys_vm_invalidate), bind_func(sys_vm_store), //309
bind_func(sys_vm_sync), bind_func(sys_vm_test), bind_func(sys_vm_get_statistics), null_func, null_func, //314
null_func, null_func, null_func, null_func, null_func, //319
null_func, null_func, null_func, null_func, bind_func(sys_memory_container_create), //324
bind_func(sys_memory_container_destroy), null_func, null_func, null_func, null_func, //329
bind_func(sys_mmapper_allocate_address), null_func, null_func, null_func, null_func, //334
null_func, null_func, null_func, null_func, null_func, //339
null_func, null_func, null_func, null_func, null_func, //344
null_func, bind_func(sys_memory_container_create), bind_func(sys_memory_container_destroy), null_func, null_func, //344
null_func, null_func, null_func, bind_func(sys_memory_allocate), bind_func(sys_memory_free), //349
null_func, null_func, bind_func(sys_memory_get_user_memory_size), null_func, null_func, //354
null_func, null_func, null_func, null_func, null_func, //359

View File

@ -122,6 +122,14 @@ extern int sys_game_process_exitspawn(u32 path_addr, u32 argv_addr, u32 envp_add
u32 data, u32 data_size, int prio, u64 flags );
//sys_event
extern int sys_event_flag_create(u32 eflag_id_addr, u32 attr_addr, u64 init);
extern int sys_event_flag_destroy(u32 eflag_id);
extern int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr, u32 timeout);
extern int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr);
extern int sys_event_flag_set(u32 eflag_id, u64 bitptn);
extern int sys_event_flag_clear(u32 eflag_id, u64 bitptn);
extern int sys_event_flag_cancel(u32 eflag_id, u32 num_addr);
extern int sys_event_flag_get(u32 eflag_id, u32 flag_addr);
extern int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size);
extern int sys_event_queue_receive(u32 equeue_id, u32 event_addr, u32 timeout);
extern int sys_event_port_create(u32 eport_id_addr, int port_type, u64 name);
@ -183,6 +191,21 @@ extern int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32
extern int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr);
extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
//vm
extern int sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr);
extern int sys_vm_unmap(u32 addr);
extern int sys_vm_append_memory(u32 addr, u32 size);
extern int sys_vm_return_memory(u32 addr, u32 size);
extern int sys_vm_lock(u32 addr, u32 size);
extern int sys_vm_unlock(u32 addr, u32 size);
extern int sys_vm_touch(u32 addr, u32 size);
extern int sys_vm_flush(u32 addr, u32 size);
extern int sys_vm_invalidate(u32 addr, u32 size);
extern int sys_vm_store(u32 addr, u32 size);
extern int sys_vm_sync(u32 addr, u32 size);
extern int sys_vm_test(u32 addr, u32 size, u32 result_addr);
extern int sys_vm_get_statistics(u32 addr, u32 stat_addr);
//cellFs
extern int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size);
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread);
@ -210,9 +233,6 @@ extern int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 optio
extern int cellVideoOutGetNumberOfDevice(u32 videoOut);
extern int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option);
//cellMsgDialog
extern int cellMsgDialogOpen2(u32 type, u32 msgString_addr, u32 callback_addr, u32 userData, u32 extParam);
//cellPad
extern int cellPadInit(u32 max_connect);
extern int cellPadEnd();
@ -220,6 +240,7 @@ extern int cellPadClearBuf(u32 port_no);
extern int cellPadGetData(u32 port_no, u32 data_addr);
extern int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr);
extern int cellPadSetActDirect(u32 port_no, u32 param_addr);
extern int cellPadGetInfo(u32 info_addr);
extern int cellPadGetInfo2(u32 info_addr);
extern int cellPadSetPortSetting(u32 port_no, u32 port_setting);

View File

@ -5,6 +5,103 @@
SysCallBase sys_event("sys_event");
int sys_event_flag_create(u32 eflag_id_addr, u32 attr_addr, u64 init)
{
sys_event.Warning("sys_event_flag_create(eflag_id_addr=0x%x, attr_addr=0x%x, init=0x%llx)", eflag_id_addr, attr_addr, init);
if(!Memory.IsGoodAddr(eflag_id_addr, 4) || !Memory.IsGoodAddr(attr_addr, sizeof(sys_event_flag_attr)))
{
return CELL_EFAULT;
}
sys_event_flag_attr attr = (sys_event_flag_attr&)Memory[attr_addr];
attr.protocol = re(attr.protocol);
attr.pshared = re(attr.pshared);
attr.ipc_key = re(attr.ipc_key);
attr.flags = re(attr.flags);
attr.type = re(attr.type);
sys_event.Warning("name = %s", attr.name);
sys_event.Warning("type = %d", attr.type);
Memory.Write32(eflag_id_addr, sys_event.GetNewId(new event_flag(init, attr)));
return CELL_OK;
}
int sys_event_flag_destroy(u32 eflag_id)
{
sys_event.Warning("sys_event_flag_destroy(eflag_id=0x%x)", eflag_id);
if(!sys_event.CheckId(eflag_id)) return CELL_ESRCH;
Emu.GetIdManager().RemoveID(eflag_id);
return CELL_OK;
}
int sys_event_flag_wait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr, u32 timeout)
{
sys_event.Warning("Unimplemented function: sys_event_flag_wait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x, timeout=0x%x)"
, eflag_id, bitptn, mode, result_addr, timeout);
return CELL_OK;
}
int sys_event_flag_trywait(u32 eflag_id, u64 bitptn, u32 mode, u32 result_addr)
{
sys_event.Warning("Unimplemented function: sys_event_flag_trywait(eflag_id=0x%x, bitptn=0x%llx, mode=0x%x, result_addr=0x%x)"
, eflag_id, bitptn, mode, result_addr);
return CELL_OK;
}
int sys_event_flag_set(u32 eflag_id, u64 bitptn)
{
sys_event.Warning("sys_event_flag_set(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
event_flag* event_flag_data = nullptr;
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
event_flag_data->pattern |= bitptn;
return CELL_OK;
}
int sys_event_flag_clear(u32 eflag_id, u64 bitptn)
{
sys_event.Warning("sys_event_flag_clear(eflag_id=0x%x, bitptn=0x%llx)", eflag_id, bitptn);
event_flag* event_flag_data = nullptr;
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
event_flag_data->pattern &= bitptn;
return CELL_OK;
}
int sys_event_flag_cancel(u32 eflag_id, u32 num_addr)
{
sys_event.Warning("Unimplemented function: sys_event_flag_cancel(eflag_id=0x%x, num_addr=0x%x)"
, eflag_id, num_addr);
return CELL_OK;
}
int sys_event_flag_get(u32 eflag_id, u32 flag_addr)
{
sys_event.Warning("sys_event_flag_get(eflag_id=0x%x, flag_addr=0x%x)", eflag_id, flag_addr);
if(!Memory.IsGoodAddr(flag_addr, 4))
{
return CELL_EFAULT;
}
event_flag* event_flag_data = nullptr;
if(!sys_event.CheckId(eflag_id, event_flag_data)) return CELL_ESRCH;
Memory.Write64(flag_addr, event_flag_data->pattern);
return CELL_OK;
}
//128
int sys_event_queue_create(u32 equeue_id_addr, u32 attr_addr, u64 event_queue_key, int size)
{

View File

@ -1,26 +1,9 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "SC_Memory.h"
SysCallBase sc_mem("memory");
enum
{
SYS_MEMORY_PAGE_SIZE_1M = 0x400,
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("sys_memory_container_create(cid_addr=0x%x,yield_size=0x%x)", cid_addr, yield_size);
@ -93,29 +76,32 @@ int sys_memory_free(u32 start_addr)
return CELL_OK;
}
struct mmapper_info
{
u64 addr;
u32 size;
u32 flags;
mmapper_info(u64 _addr, u32 _size, u32 _flags)
: addr(_addr)
, size(_size)
, flags(_flags)
{
}
mmapper_info()
{
}
};
int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_addr)
{
sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr);
Memory.Write32(alloc_addr, Memory.Alloc(size, 4));
if(!Memory.IsGoodAddr(alloc_addr)) return CELL_EFAULT;
if(!alignment)
alignment = 1;
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
default:
case SYS_MEMORY_PAGE_SIZE_1M:
if(Memory.AlignAddr(size, alignment) & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(Memory.AlignAddr(size, alignment) & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
}
Memory.Write32(alloc_addr, addr);
return CELL_OK;
}
@ -126,7 +112,22 @@ int sys_mmapper_allocate_memory(u32 size, u64 flags, u32 mem_id_addr)
if(!Memory.IsGoodAddr(mem_id_addr)) return CELL_EFAULT;
u64 addr = Memory.Alloc(size, 1);
u32 addr;
switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K))
{
case SYS_MEMORY_PAGE_SIZE_1M:
if(size & 0xfffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
if(size & 0xffff) return CELL_EALIGN;
addr = Memory.Alloc(size, 0x10000);
break;
default:
return CELL_EINVAL;
}
if(!addr)
return CELL_ENOMEM;
@ -147,17 +148,10 @@ int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags)
{
sc_mem.Error("sys_mmapper_map_memory failed!");
}
//Memory.MemoryBlocks.Add((new MemoryBlock())->SetRange(start_addr, info->size));
return CELL_OK;
}
struct sys_memory_info
{
u32 total_user_memory;
u32 available_user_memory;
};
int sys_memory_get_user_memory_size(u32 mem_info_addr)
{
sys_memory_info info;

View File

@ -0,0 +1,59 @@
#pragma once
#define SYS_MEMORY_CONTAINER_ID_INVALID 0xFFFFFFFF
#define SYS_VM_TEST_INVALID 0x0000ULL
#define SYS_VM_TEST_UNUSED 0x0001ULL
#define SYS_VM_TEST_ALLOCATED 0x0002ULL
#define SYS_VM_TEST_STORED 0x0004ULL
enum
{
SYS_MEMORY_PAGE_SIZE_1M = 0x400,
SYS_MEMORY_PAGE_SIZE_64K = 0x200,
};
struct MemoryContainerInfo
{
u64 addr;
u32 size;
MemoryContainerInfo(u64 addr, u32 size)
: addr(addr)
, size(size)
{
}
};
struct mmapper_info
{
u64 addr;
u32 size;
u32 flags;
mmapper_info(u64 _addr, u32 _size, u32 _flags)
: addr(_addr)
, size(_size)
, flags(_flags)
{
}
mmapper_info()
{
}
};
struct sys_memory_info
{
u32 total_user_memory;
u32 available_user_memory;
};
struct sys_vm_statistics {
u64 vm_crash_ppu;
u64 vm_crash_spu;
u64 vm_read;
u64 vm_write;
u32 physical_mem_size;
u32 physical_mem_used;
u64 timestamp;
};

View File

@ -24,6 +24,16 @@ struct CellPadData
u16 button[CELL_PAD_MAX_CODES];
};
struct CellPadInfo
{
u32 max_connect;
u32 now_connect;
u32 system_info;
u16 vendor_id[CELL_MAX_PADS];
u16 product_id[CELL_MAX_PADS];
u8 status[CELL_MAX_PADS];
};
struct CellPadInfo2
{
u32 max_connect;
@ -142,6 +152,35 @@ int cellPadSetActDirect(u32 port_no, u32 param_addr)
return CELL_OK;
}
int cellPadGetInfo(u32 info_addr)
{
sys_io.Log("cellPadGetInfo(info_addr=0x%x)", info_addr);
if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED;
CellPadInfo info;
memset(&info, 0, sizeof(CellPadInfo));
const PadInfo& rinfo = Emu.GetPadManager().GetInfo();
info.max_connect = re(rinfo.max_connect);
info.now_connect = re(rinfo.now_connect);
info.system_info = re(rinfo.system_info);
const Array<Pad>& pads = Emu.GetPadManager().GetPads();
for(u32 i=0; i<CELL_MAX_PADS; ++i)
{
if(i >= pads.GetCount()) break;
info.status[i] = re(pads[i].m_port_status);
info.product_id[i] = const_se_t<u16, 0x0268>::value;
info.vendor_id[i] = const_se_t<u16, 0x054C>::value;
}
Memory.WriteData(info_addr, info);
return CELL_OK;
}
int cellPadGetInfo2(u32 info_addr)
{
sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr);

View File

@ -0,0 +1,286 @@
#include "stdafx.h"
#include "Emu/SysCalls/SysCalls.h"
#include "SC_Memory.h"
SysCallBase sc_vm("vm");
MemoryContainerInfo* current_ct;
int sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr)
{
sc_vm.Warning("sys_vm_memory_map(vsize=0x%x,psize=0x%x,cidr=0x%x,flags=0x%llx,policy=0x%llx,addr=0x%x)",
vsize, psize, cid, flag, policy, addr);
// Check output address.
if(!Memory.IsGoodAddr(addr, 4))
{
return CELL_EFAULT;
}
// Check virtual size.
if((vsize < (0x100000 * 32)) || (vsize > (0x100000 * 256)))
{
return CELL_EINVAL;
}
// Check physical size.
if(psize > (0x100000 * 256))
{
return CELL_ENOMEM;
}
// If container ID is SYS_MEMORY_CONTAINER_ID_INVALID, allocate directly.
if(cid == SYS_MEMORY_CONTAINER_ID_INVALID)
{
u32 new_addr;
switch(flag)
{
case SYS_MEMORY_PAGE_SIZE_1M:
new_addr = Memory.Alloc(psize, 0x100000);
break;
case SYS_MEMORY_PAGE_SIZE_64K:
new_addr = Memory.Alloc(psize, 0x10000);
break;
default: return CELL_EINVAL;
}
if(!new_addr) return CELL_ENOMEM;
// Create a new MemoryContainerInfo to act as default container with vsize.
current_ct = new MemoryContainerInfo(new_addr, vsize);
}
else
{
// Check memory container.
MemoryContainerInfo* ct;
if(!sc_vm.CheckId(cid, ct)) return CELL_ESRCH;
current_ct = ct;
}
// Write a pointer for the allocated memory.
Memory.Write32(addr, current_ct->addr);
return CELL_OK;
}
int sys_vm_unmap(u32 addr)
{
sc_vm.Warning("sys_vm_unmap(addr=0x%x)", addr);
// Simply free the memory to unmap.
if(!Memory.Free(addr)) return CELL_EINVAL;
return CELL_OK;
}
int sys_vm_append_memory(u32 addr, u32 size)
{
sc_vm.Warning("sys_vm_append_memory(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (size <= 0))
{
return CELL_EINVAL;
}
// Total memory size must not be superior to 256MB.
if((current_ct->size + size) > (0x100000 * 256))
{
return CELL_ENOMEM;
}
// The size is added to the virtual size, which should be inferior to the physical size allocated.
current_ct->size += size;
return CELL_OK;
}
int sys_vm_return_memory(u32 addr, u32 size)
{
sc_vm.Warning("sys_vm_return_memory(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (size <= 0))
{
return CELL_EINVAL;
}
// The memory size to return should not be superior to the virtual size in use minus 1MB.
if((current_ct->size - size - 0x100000) < 0)
{
return CELL_EBUSY;
}
// The size is returned to physical memory and is subtracted to the virtual size.
current_ct->size -= size;
return CELL_OK;
}
int sys_vm_lock(u32 addr, u32 size)
{
sc_vm.Warning("sys_vm_lock(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// The memory size to return should not be superior to the virtual size to lock minus 1MB.
if((current_ct->size - size - 0x100000) < 0)
{
return CELL_EBUSY;
}
// The locked memory area keeps allocated and unchanged until sys_vm_unlocked is called.
Memory.Lock(addr, size);
return CELL_OK;
}
int sys_vm_unlock(u32 addr, u32 size)
{
sc_vm.Warning("sys_vm_unlock(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
Memory.Unlock(addr, size);
return CELL_OK;
}
int sys_vm_touch(u32 addr, u32 size)
{
sc_vm.Warning("Unimplemented function: sys_vm_touch(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_touch allocates physical memory for a virtual memory address.
// This function is asynchronous, so it may not complete immediately.
return CELL_OK;
}
int sys_vm_flush(u32 addr, u32 size)
{
sc_vm.Warning("Unimplemented function: sys_vm_flush(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_flush frees physical memory for a virtual memory address and creates a backup if the memory area is dirty.
// This function is asynchronous, so it may not complete immediately.
return CELL_OK;
}
int sys_vm_invalidate(u32 addr, u32 size)
{
sc_vm.Warning("Unimplemented function: sys_vm_invalidate(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_invalidate frees physical memory for a virtual memory address.
// This function is asynchronous, so it may not complete immediately.
return CELL_OK;
}
int sys_vm_store(u32 addr, u32 size)
{
sc_vm.Warning("Unimplemented function: sys_vm_store(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_store creates a backup for a dirty virtual memory area and marks it as clean.
// This function is asynchronous, so it may not complete immediately.
return CELL_OK;
}
int sys_vm_sync(u32 addr, u32 size)
{
sc_vm.Warning("Unimplemented function: sys_vm_sync(addr=0x%x,size=0x%x)", addr, size);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_sync stalls execution until all asynchronous vm calls finish.
return CELL_OK;
}
int sys_vm_test(u32 addr, u32 size, u32 result_addr)
{
sc_vm.Warning("Unimplemented function: sys_vm_test(addr=0x%x,size=0x%x,result_addr=0x%x)", addr, size, result_addr);
// Check address and size.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr) || (current_ct->size < size) || (size <= 0))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_test checks the state of a portion of the virtual memory area.
// Faking.
Memory.Write64(result_addr, SYS_VM_TEST_ALLOCATED);
return CELL_OK;
}
int sys_vm_get_statistics(u32 addr, u32 stat_addr)
{
sc_vm.Warning("Unimplemented function: sys_vm_get_statistics(addr=0x%x,stat_addr=0x%x)", addr, stat_addr);
// Check address.
if(!Memory.IsGoodAddr(addr, 4) || (current_ct->addr != addr))
{
return CELL_EINVAL;
}
// TODO
// sys_vm_get_statistics collects virtual memory management stats.
sys_vm_statistics stats;
stats.physical_mem_size = current_ct->size; // Total physical memory allocated for the virtual memory area.
stats.physical_mem_used = 0; // Physical memory in use by the virtual memory area.
stats.timestamp = 0; // Current time.
stats.vm_crash_ppu = 0; // Number of bad virtual memory accesses from a PPU thread.
stats.vm_crash_spu = 0; // Number of bad virtual memory accesses from a SPU thread.
stats.vm_read = 0; // Number of virtual memory backup reading operations.
stats.vm_write = 0; // Number of virtual memory backup writing operations.
Memory.WriteData(stat_addr, stats); // Faking.
return CELL_OK;
}

View File

@ -6,6 +6,10 @@
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Cell/PPUInstrTable.h"
#include "scetool/scetool.h"
#include "Loader/SELF.h"
#include <cstdlib>
#include <fstream>
using namespace PPU_instr;
@ -21,7 +25,7 @@ ModuleInitializer::ModuleInitializer()
Emulator::Emulator()
: m_status(Stopped)
, m_mode(DisAsm)
, m_dbg_console(NULL)
, m_dbg_console(nullptr)
, m_rsx_callback(0)
{
}
@ -43,6 +47,11 @@ void Emulator::SetPath(const wxString& path, const wxString& elf_path)
m_elf_path = elf_path;
}
void Emulator::SetTitleID(const wxString& id)
{
m_title_id = id;
}
void Emulator::CheckStatus()
{
ArrayF<CPUThread>& threads = GetCPU().GetThreads();
@ -80,16 +89,126 @@ void Emulator::CheckStatus()
}
}
bool Emulator::IsSelf(const std::string& path)
{
vfsLocalFile f(path);
if(!f.IsOpened())
return false;
SceHeader hdr;
hdr.Load(f);
return hdr.CheckMagic();
}
bool Emulator::DecryptSelf(const std::string& elf, const std::string& self)
{
// Check if the data really needs to be decrypted.
wxFile f(self.c_str());
if(!f.IsOpened())
{
ConLog.Error("Could not open SELF file! (%s)", self.c_str());
return false;
}
// Get the key version.
f.Seek(0x08);
be_t<u16> key_version;
f.Read(&key_version, sizeof(key_version));
if(key_version.ToBE() == const_se_t<u16, 0x8000>::value)
{
ConLog.Warning("Debug SELF detected! Removing fake header...");
// Get the real elf offset.
f.Seek(0x10);
be_t<u64> elf_offset;
f.Read(&elf_offset, sizeof(elf_offset));
// Start at the real elf offset.
f.Seek(elf_offset);
wxFile out(elf.c_str(), wxFile::write);
if(!out.IsOpened())
{
ConLog.Error("Could not create ELF file! (%s)", elf.c_str());
return false;
}
// Copy the data.
char buf[2048];
while (ssize_t size = f.Read(buf, 2048))
out.Write(buf, size);
}
else
{
if (!scetool_decrypt((scetool::s8 *)self.c_str(), (scetool::s8 *)elf.c_str()))
{
ConLog.Write("SELF: Could not decrypt file");
return false;
}
}
return true;
}
bool Emulator::BootGame(const std::string& path)
{
static const char* elf_path[6] =
{
"\\PS3_GAME\\USRDIR\\BOOT.BIN",
"\\USRDIR\\BOOT.BIN",
"\\BOOT.BIN",
"\\PS3_GAME\\USRDIR\\EBOOT.BIN",
"\\USRDIR\\EBOOT.BIN",
"\\EBOOT.BIN",
};
for(int i=0; i<sizeof(elf_path) / sizeof(*elf_path);i++)
{
const wxString& curpath = path + elf_path[i];
if(wxFile::Access(curpath, wxFile::read))
{
SetPath(curpath);
Load();
return true;
}
}
return false;
}
void Emulator::Load()
{
if(!wxFileExists(m_path)) return;
if(IsSelf(m_path.c_str()))
{
std::string self_path = m_path;
std::string elf_path = wxFileName(m_path).GetPath().c_str();
if(wxFileName(m_path).GetFullName().CmpNoCase("EBOOT.BIN") == 0)
{
elf_path += "\\BOOT.BIN";
}
else
{
elf_path += "\\" + wxFileName(m_path).GetName() + ".elf";
}
DecryptSelf(elf_path, self_path);
m_path = elf_path;
}
ConLog.Write("Loading '%s'...", m_path.mb_str());
GetInfo().Reset();
m_vfs.Init(m_path);
//m_vfs.Mount("/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
//m_vfs.Mount("/dev_hdd0/", wxGetCwd() + "\\dev_hdd0\\", new vfsLocalFile());
//m_vfs.Mount("/app_home/", vfsDevice::GetRoot(m_path), new vfsLocalFile());
//m_vfs.Mount(vfsDevice::GetRootPs3(m_path), vfsDevice::GetRoot(m_path), new vfsLocalFile());
ConLog.SkipLn();
ConLog.Write("Mount info:");
@ -377,7 +496,7 @@ void Emulator::LoadPoints(const std::string& path)
if (!f.is_open())
return;
f.seekg(0, std::ios::end);
int length = f.tellg();
int length = f.tellg();
f.seekg(0, std::ios::beg);
u32 break_count, marked_count;
u16 version;

View File

@ -93,11 +93,13 @@ class Emulator
public:
wxString m_path;
wxString m_elf_path;
wxString m_title_id;
Emulator();
void Init();
void SetPath(const wxString& path, const wxString& elf_path = wxEmptyString);
void SetTitleID(const wxString& id);
std::shared_ptr<vfsFileBase> OpenFile(const wxString& path, vfsOpenMode mode = vfsRead)
{
@ -144,6 +146,10 @@ public:
void CheckStatus();
bool IsSelf(const std::string& path);
bool DecryptSelf(const std::string& elf, const std::string& self);
bool BootGame(const std::string& path);
void Load();
void Run();
void Pause();

View File

@ -1,5 +1,27 @@
#pragma once
struct sys_event_flag_attr
{
u32 protocol;
u32 pshared;
u64 ipc_key;
int flags;
int type;
char name[8];
};
struct event_flag
{
sys_event_flag_attr attr;
u64 pattern;
event_flag(u64 pattern, sys_event_flag_attr attr)
: pattern(pattern)
, attr(attr)
{
}
};
struct sys_event_queue_attr
{
u32 attr_protocol;

View File

@ -8,7 +8,7 @@ GameViewer::GameViewer(wxWindow* parent) : wxListView(parent)
LoadSettings();
m_columns.Show(this);
m_path = wxGetCwd(); //TODO
m_path = wxGetCwd() + "\\dev_hdd0\\game\\"; //TODO
Connect(GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(GameViewer::DClick));
@ -34,16 +34,13 @@ void GameViewer::LoadGames()
if(!dir.HasSubDirs()) return;
wxString buf;
if(!dir.GetFirst(&buf)) return;
if(wxDirExists(buf)) m_games.Add(buf);
for(;;)
for(bool ok = dir.GetFirst(&buf); ok; ok = dir.GetNext(&buf))
{
if(!dir.GetNext(&buf)) break;
if(wxDirExists(buf)) m_games.Add(buf);
if(wxDirExists(m_path + buf))
m_games.Add(buf);
}
//ConLog.Write("path: %s", m_path);
//ConLog.Write("path: %s", m_path.c_str());
//ConLog.Write("folders count: %d", m_games.GetCount());
}
@ -52,7 +49,7 @@ void GameViewer::LoadPSF()
m_game_data.Clear();
for(uint i=0; i<m_games.GetCount(); ++i)
{
const wxString& path = m_games[i] + "\\" + "PARAM.SFO";
const wxString& path = m_path + m_games[i] + "\\PARAM.SFO";
if(!wxFileExists(path)) continue;
vfsLocalFile f(path);
PSFLoader psf(f);
@ -91,14 +88,13 @@ void GameViewer::DClick(wxListEvent& event)
long i = GetFirstSelected();
if(i < 0) return;
const wxString& path = m_path + "\\" + m_game_data[i].root + "\\" + "USRDIR" + "\\" + "BOOT.BIN";
if(!wxFileExists(path))
const wxString& path = m_path + m_game_data[i].root;
Emu.Stop();
if(!Emu.BootGame(path.c_str()))
{
ConLog.Error("Boot error: elf not found! [%s]", path.mb_str());
return;
}
Emu.Stop();
Emu.SetPath(path);
Emu.Run();
}

File diff suppressed because it is too large Load Diff

View File

@ -20,9 +20,8 @@ private:
void OnQuit(wxCloseEvent& event);
void BootGame(wxCommandEvent& event);
void BootPkg(wxCommandEvent& event);
void InstallPkg(wxCommandEvent& event);
void BootElf(wxCommandEvent& event);
void BootSelf(wxCommandEvent& event);
void Pause(wxCommandEvent& event);
void Stop(wxCommandEvent& event);
void SendExit(wxCommandEvent& event);

View File

@ -371,6 +371,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset)
if(!module->Load(nid))
{
ConLog.Warning("Unknown function 0x%08x in '%s' module", nid, module_name.mb_str());
SysCalls::DoFunc(nid);
}
}
#ifdef LOADER_DEBUG

View File

@ -5,6 +5,17 @@ PSFLoader::PSFLoader(vfsStream& f) : psf_f(f)
{
}
PsfEntry* PSFLoader::SearchEntry(const std::string& key)
{
for(uint i=0; i<m_entries.GetCount(); ++i)
{
if(m_entries[i].name == key)
return &m_entries[i];
}
return nullptr;
}
bool PSFLoader::Load(bool show)
{
if(!psf_f.IsOpened()) return false;
@ -13,17 +24,7 @@ bool PSFLoader::Load(bool show)
if(!LoadHdr()) return false;
if(!LoadKeyTable()) return false;
if(!LoadValuesTable()) return false;
if(show)
{
ConLog.SkipLn();
for(uint i=0; i<m_table.GetCount(); ++i)
{
ConLog.Write("%s", m_table[i].mb_str());
}
ConLog.SkipLn();
}
if(!LoadDataTable()) return false;
return true;
}
@ -35,198 +36,71 @@ bool PSFLoader::Close()
bool PSFLoader::LoadHdr()
{
psf_f.Read(&psfhdr, sizeof(PsfHeader));
if(psf_f.Read(&psfhdr, sizeof(PsfHeader)) != sizeof(PsfHeader))
return false;
if(!psfhdr.CheckMagic()) return false;
if(m_show_log) ConLog.Write("PSF version: %x", psfhdr.psf_version);
m_psfindxs.Clear();
m_entries.Clear();
m_psfindxs.SetCount(psfhdr.psf_entries_num);
m_entries.SetCount(psfhdr.psf_entries_num);
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
{
if(psf_f.Read(&m_psfindxs[i], sizeof(PsfDefTbl)) != sizeof(PsfDefTbl))
return false;
m_entries[i].fmt = m_psfindxs[i].psf_param_fmt;
}
return true;
}
bool PSFLoader::LoadKeyTable()
{
psf_f.Seek(psfhdr.psf_offset_key_table);
m_table.Clear();
m_table.Add(wxEmptyString);
while(!psf_f.Eof())
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
{
char c;
psf_f.Read(&c, 1);
if(c == 0)
psf_f.Seek(psfhdr.psf_offset_key_table + m_psfindxs[i].psf_key_table_offset);
int c_pos = 0;
while(!psf_f.Eof())
{
char c;
psf_f.Read(&c, 1);
if(c == 0) break;
m_entries[i].name[c_pos++] = c;
m_table.Add(wxEmptyString);
if(c_pos >= sizeof(m_entries[i].name) || c == '\0')
break;
}
m_table[m_table.GetCount() - 1].Append(c);
}
if(m_table.GetCount() != psfhdr.psf_entries_num)
{
if(m_show_log) ConLog.Error("PSF error: Entries loaded with error! [%d - %d]", m_table.GetCount(), psfhdr.psf_entries_num);
m_table.Clear();
return false;
}
return true;
}
struct PsfHelper
bool PSFLoader::LoadDataTable()
{
static wxString ReadString(vfsStream& f, const u32 size)
for(u32 i=0; i<psfhdr.psf_entries_num; ++i)
{
wxString ret = wxEmptyString;
for(uint i=0; i<size && !f.Eof(); ++i)
{
ret += ReadChar(f);
}
return ret;
psf_f.Seek(psfhdr.psf_offset_data_table + m_psfindxs[i].psf_data_tbl_offset);
psf_f.Read(m_entries[i].param, m_psfindxs[i].psf_param_len);
memset(m_entries[i].param + m_psfindxs[i].psf_param_len, 0, m_psfindxs[i].psf_param_max_len - m_psfindxs[i].psf_param_len);
}
static wxString ReadString(vfsStream& f)
{
wxString ret = wxEmptyString;
while(!f.Eof())
{
const char c = ReadChar(f);
if(c == 0) break;
ret += c;
}
return ret;
}
static char ReadChar(vfsStream& f)
{
char c;
f.Read(&c, 1);
return c;
}
static char ReadCharNN(vfsStream& f)
{
char c;
while(!f.Eof())
{
f.Read(&c, 1);
if(c != 0) break;
}
return c;
}
static void GoToNN(vfsStream& f)
{
while(!f.Eof())
{
char c;
f.Read(&c, 1);
if(c != 0)
{
f.Seek(f.Tell() - 1);
break;
}
}
}
static wxString FixName(const wxString& name)
{
wxString ret = wxEmptyString;
for(uint i=0; i<name.Length(); ++i)
{
switch((u8)name[i])
{
case 0xE2: case 0xA2: case 0x84: continue;
default: ret += name[i]; break;
};
}
return ret;
}
};
bool PSFLoader::LoadValuesTable()
{
psf_f.Seek(psfhdr.psf_offset_values_table);
m_info.Reset();
for(uint i=0;i<m_table.GetCount(); i++)
{
if(!m_table[i].Cmp("TITLE_ID"))
{
m_info.serial = PsfHelper::ReadString(psf_f);
m_table[i].Append(wxString::Format(": %s", m_info.serial.mb_str()));
PsfHelper::GoToNN(psf_f);
}
else if(!m_table[i](0, 5).Cmp("TITLE"))
{
m_info.name = PsfHelper::FixName(PsfHelper::ReadString(psf_f));
m_table[i].Append(wxString::Format(": %s", m_info.name.mb_str()));
PsfHelper::GoToNN(psf_f);
}
else if(!m_table[i].Cmp("APP_VER"))
{
m_info.app_ver = PsfHelper::ReadString(psf_f, sizeof(u64));
m_table[i].Append(wxString::Format(": %s", m_info.app_ver.mb_str()));
}
else if(!m_table[i].Cmp("ATTRIBUTE"))
{
psf_f.Read(&m_info.attr, sizeof(m_info.attr));
m_table[i].Append(wxString::Format(": 0x%x", m_info.attr));
}
else if(!m_table[i].Cmp("CATEGORY"))
{
m_info.category = PsfHelper::ReadString(psf_f, sizeof(u32));
m_table[i].Append(wxString::Format(": %s", m_info.category.mb_str()));
}
else if(!m_table[i].Cmp("BOOTABLE"))
{
psf_f.Read(&m_info.bootable, sizeof(m_info.bootable));
m_table[i].Append(wxString::Format(": %d", m_info.bootable));
}
else if(!m_table[i].Cmp("LICENSE"))
{
m_table[i].Append(wxString::Format(": %s", PsfHelper::ReadString(psf_f).mb_str()));
psf_f.Seek(psf_f.Tell() + (sizeof(u64) * 7 * 2) - 1);
}
else if(!m_table[i](0, 14).Cmp("PARENTAL_LEVEL"))
{
u32 buf;
psf_f.Read(&buf, sizeof(buf));
if(!m_table[i].Cmp("PARENTAL_LEVEL"))
{
m_info.parental_lvl = buf;
}
m_table[i].Append(wxString::Format(": %d", buf));
}
else if(!m_table[i].Cmp("PS3_SYSTEM_VER"))
{
m_info.fw = PsfHelper::ReadString(psf_f, sizeof(u64));
m_table[i].Append(wxString::Format(": %s", m_info.fw.mb_str()));
}
else if(!m_table[i].Cmp("SOUND_FORMAT"))
{
m_info.sound_format = Read32(psf_f);
m_table[i].Append(wxString::Format(": 0x%x", m_info.sound_format));
}
else if(!m_table[i].Cmp("RESOLUTION"))
{
m_info.resolution = Read32(psf_f);
m_table[i].Append(wxString::Format(": 0x%x", m_info.resolution));
}
else
{
m_table[i].Append(wxString::Format(": %s", PsfHelper::ReadString(psf_f).mb_str()));
PsfHelper::GoToNN(psf_f);
}
}
if(PsfEntry* entry = SearchEntry("TITLE_ID")) m_info.serial = entry->Format();
if(PsfEntry* entry = SearchEntry("TITLE")) m_info.name = entry->Format();
if(PsfEntry* entry = SearchEntry("APP_VER")) m_info.app_ver = entry->Format();
if(PsfEntry* entry = SearchEntry("CATEGORY")) m_info.category = entry->Format();
if(PsfEntry* entry = SearchEntry("PS3_SYSTEM_VER")) m_info.fw = entry->Format();
if(PsfEntry* entry = SearchEntry("SOUND_FORMAT")) m_info.sound_format = entry->FormatInteger();
if(PsfEntry* entry = SearchEntry("RESOLUTION")) m_info.resolution = entry->FormatInteger();
if(PsfEntry* entry = SearchEntry("PARENTAL_LEVEL")) m_info.parental_lvl = entry->FormatInteger();
if(m_info.serial.Length() == 9)
{

View File

@ -6,7 +6,7 @@ struct PsfHeader
u32 psf_magic;
u32 psf_version;
u32 psf_offset_key_table;
u32 psf_offset_values_table;
u32 psf_offset_data_table;
u32 psf_entries_num;
bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; }
@ -14,13 +14,44 @@ struct PsfHeader
struct PsfDefTbl
{
u16 psf_name_tbl_offset;
u16 psf_data_type;
u32 psf_data_size;
u32 psf_data_fsize;
u16 psf_key_table_offset;
u16 psf_param_fmt;
u32 psf_param_len;
u32 psf_param_max_len;
u32 psf_data_tbl_offset;
};
struct PsfEntry
{
char name[128];
u16 fmt;
char param[4096];
std::string Format() const
{
switch(fmt)
{
default:
case 0x0400:
case 0x0402:
return FormatString();
case 0x0404:
return wxString::Format("0x%x", FormatInteger()).c_str();
}
}
u32 FormatInteger() const
{
return *(u32*)param;
}
char* FormatString() const
{
return (char*)param;
}
};
class PSFLoader
{
vfsStream& psf_f;
@ -29,14 +60,19 @@ class PSFLoader
public:
PSFLoader(vfsStream& f);
wxArrayString m_table;
Array<PsfEntry> m_entries;
PsfEntry* SearchEntry(const std::string& key);
//wxArrayString m_table;
GameInfo m_info;
PsfHeader psfhdr;
Array<PsfDefTbl> m_psfindxs;
virtual bool Load(bool show = true);
virtual bool Close();
private:
bool LoadHdr();
bool LoadKeyTable();
bool LoadValuesTable();
bool LoadDataTable();
};

View File

@ -199,6 +199,12 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\scetool\scetool.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\Utilities\Thread.cpp" />
<ClCompile Include="AppConnector.cpp" />
<ClCompile Include="Emu\ARMv7\ARMv7Thread.cpp" />
@ -257,6 +263,7 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_Timer.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_Trace.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_TTY.cpp" />
<ClCompile Include="Emu\SysCalls\lv2\SC_VM.cpp" />
<ClCompile Include="Emu\SysCalls\Modules.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellAudio.cpp" />
<ClCompile Include="Emu\SysCalls\Modules\cellFont.cpp" />
@ -323,6 +330,7 @@
<ClInclude Include="Emu\Cell\PPUOpcodes.h" />
<ClInclude Include="Emu\Cell\PPUProgramCompiler.h" />
<ClInclude Include="Emu\Cell\PPUThread.h" />
<ClInclude Include="Emu\Cell\RawSPUThread.h" />
<ClInclude Include="Emu\Cell\SPUDecoder.h" />
<ClInclude Include="Emu\Cell\SPUDisAsm.h" />
<ClInclude Include="Emu\Cell\SPUInterpreter.h" />

View File

@ -53,6 +53,9 @@
<Filter Include="Emu\ARMv7">
<UniqueIdentifier>{bee6a4b4-6371-4c1b-8558-fc7888b1574e}</UniqueIdentifier>
</Filter>
<Filter Include="Utilities\scetool">
<UniqueIdentifier>{52b11fe8-a967-4d52-bf88-a3210d4ffb27}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="rpcs3.cpp">
@ -340,6 +343,12 @@
<ClCompile Include="Emu\SysCalls\Modules\cellGame.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\lv2\SC_VM.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
<ClCompile Include="..\scetool\scetool.cpp">
<Filter>Utilities\scetool</Filter>
</ClCompile>
<ClCompile Include="Emu\SysCalls\Modules\cellFontFT.cpp">
<Filter>Emu\SysCalls\Modules</Filter>
</ClCompile>
@ -513,5 +522,8 @@
<ClInclude Include="..\Utilities\BEType.h">
<Filter>Utilities</Filter>
</ClInclude>
<ClInclude Include="Emu\Cell\RawSPUThread.h">
<Filter>Include</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -8,6 +8,7 @@
#include <string.h>
#define NOCOMPILE
#include "types.h"
#include "elf.h"

View File

@ -3,6 +3,8 @@
* This file is released under the GPLv2.
*/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

5
scetool/scetool.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include "types.h"
bool scetool_decrypt(scetool::s8 *_file_in, scetool::s8 *_file_out);