mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-10 21:40:43 +00:00
Fixed conflicts
This commit is contained in:
commit
e2de06da63
4
bin/dev_usb000/.gitignore
vendored
Normal file
4
bin/dev_usb000/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
59
rpcs3/Emu/SysCalls/lv2/SC_Memory.h
Normal file
59
rpcs3/Emu/SysCalls/lv2/SC_Memory.h
Normal 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;
|
||||
};
|
@ -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);
|
||||
|
286
rpcs3/Emu/SysCalls/lv2/SC_VM.cpp
Normal file
286
rpcs3/Emu/SysCalls/lv2/SC_VM.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
};
|
@ -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" />
|
||||
|
@ -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>
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define NOCOMPILE
|
||||
#include "types.h"
|
||||
#include "elf.h"
|
||||
|
||||
|
@ -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
5
scetool/scetool.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
bool scetool_decrypt(scetool::s8 *_file_in, scetool::s8 *_file_out);
|
Loading…
x
Reference in New Issue
Block a user