mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-21 18:39:57 +00:00
General improvements:
- Added drafts for event flag emulation; - Implemented memory locking/unlocking; - Refactored common SC_Memory objects; - Implemented VM (virtual memory) syscalls; - Improved cellGameBootCheck; - Added more dummy values to cellVideoOutGetDeviceInfo; - Mapped functions sys_mmapper_allocate_memory and sys_mmapper_map_memory to sysPrxForUser; - Mapped syscalls 341 and 342 (duplicates of 324 and 325) to sys_memory_container_create and sys_memory_container_destroy; Improved PKG installation routine: - Allow immediate game booting; - Fixed and improved game folder path handling.
This commit is contained in:
parent
ff4fcdd5fd
commit
a9a246a866
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)");
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,11 @@ 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));
|
||||
Memory.Write32(alloc_addr, Memory.Alloc(size, alignment));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@ -126,7 +91,7 @@ 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);
|
||||
u64 addr = Memory.Alloc(size, 4);
|
||||
|
||||
if(!addr)
|
||||
return CELL_ENOMEM;
|
||||
@ -147,17 +112,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;
|
||||
};
|
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;
|
||||
}
|
@ -43,6 +43,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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -45,6 +45,47 @@ wxString GetPaneName()
|
||||
return wxString::Format("Pane_%d", pane_num++);
|
||||
}
|
||||
|
||||
bool wxMoveDir(wxString sFrom, wxString sTo)
|
||||
{
|
||||
if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH;
|
||||
if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH;
|
||||
|
||||
if (!::wxDirExists(sFrom)) {
|
||||
::wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str());
|
||||
return false;
|
||||
}
|
||||
if (!wxDirExists(sTo)) {
|
||||
if (!wxFileName::Mkdir(sTo, 0777, wxPATH_MKDIR_FULL)) {
|
||||
::wxLogError(wxT("%s could not be created!"), sTo.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
wxDir fDir(sFrom);
|
||||
wxString sNext = wxEmptyString;
|
||||
bool bIsFile = fDir.GetFirst(&sNext);
|
||||
while (bIsFile) {
|
||||
const wxString sFileFrom = sFrom + sNext;
|
||||
const wxString sFileTo = sTo + sNext;
|
||||
if (::wxDirExists(sFileFrom)) {
|
||||
wxMoveDir(sFileFrom, sFileTo);
|
||||
::wxRmdir(sFileFrom);
|
||||
}
|
||||
else {
|
||||
if (!::wxFileExists(sFileTo)) {
|
||||
if (!::wxCopyFile(sFileFrom, sFileTo)) {
|
||||
::wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
::wxRemoveFile(sFileFrom);
|
||||
}
|
||||
bIsFile = fDir.GetNext(&sNext);
|
||||
}
|
||||
::wxRmdir(sFrom);
|
||||
return true;
|
||||
}
|
||||
|
||||
MainFrame::MainFrame()
|
||||
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600))
|
||||
, m_aui_mgr(this)
|
||||
@ -276,7 +317,109 @@ void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event))
|
||||
if (!wxRemoveFile(ctrl.GetPath()+".dec"))
|
||||
ConLog.Warning("Could not delete the decoded DEC file");
|
||||
|
||||
// Copy the PKG to dev_hdd0 and format the path to be identical to the PS3.
|
||||
wxString gamePath = "\\dev_hdd0\\game\\";
|
||||
pkg_header *header;
|
||||
pkg_info((const char *)fileName.mb_str(), &header);
|
||||
|
||||
// Get the PKG title ID from the header and format it (should match TITLE ID from PARAM.SFO).
|
||||
wxString titleID_full (header->title_id);
|
||||
wxString titleID = titleID_full.SubString(7, 15);
|
||||
|
||||
// Travel to bin folder.
|
||||
wxSetWorkingDirectory(wxGetCwd() + "\\..\\");
|
||||
|
||||
// Save the main dir.
|
||||
wxString mainDir = wxGetCwd();
|
||||
|
||||
// Set PKG dir.
|
||||
wxString oldPkgDir = wxT(wxGetCwd() + "\\" + titleID_full);
|
||||
wxString newPkgDir = wxT(wxGetCwd() + gamePath + titleID);
|
||||
|
||||
// Move the final folder.
|
||||
wxMoveDir(oldPkgDir, newPkgDir);
|
||||
|
||||
// Save the title ID.
|
||||
Emu.SetTitleID(titleID);
|
||||
|
||||
ConLog.Write("PKG: extract done.");
|
||||
|
||||
// Travel to the installed PKG.
|
||||
wxSetWorkingDirectory(newPkgDir);
|
||||
|
||||
wxString elf[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<6;i++)
|
||||
{
|
||||
if(wxFile::Access(wxGetCwd() + elf[i], wxFile::read))
|
||||
{
|
||||
ConLog.Write("SELF: booting...");
|
||||
|
||||
wxString fileIn = wxGetCwd()+elf[i];
|
||||
wxString fileOut = (wxGetCwd()+elf[i])+".elf";
|
||||
|
||||
// Check if the data really needs to be decrypted.
|
||||
if(!wxFileExists(fileIn))
|
||||
{
|
||||
ConLog.Error("Could not open game boot file!");
|
||||
return;
|
||||
}
|
||||
|
||||
wxFile f(fileIn);
|
||||
// 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(fileOut, wxFile::write);
|
||||
|
||||
// Copy the data.
|
||||
char buf[2048];
|
||||
while (ssize_t size = f.Read(buf, 2048))
|
||||
out.Write(buf, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!scetool_decrypt((scetool::s8 *)fileIn.mb_str(), (scetool::s8 *)fileOut.mb_str()))
|
||||
{
|
||||
ConLog.Write("Could not decrypt game boot file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
f.Close();
|
||||
|
||||
// Set the working directory back.
|
||||
wxSetWorkingDirectory(mainDir);
|
||||
|
||||
Emu.SetPath(fileOut);
|
||||
Emu.Load();
|
||||
if (!wxRemoveFile(fileOut))
|
||||
ConLog.Warning("Could not delete the decrypted ELF file");
|
||||
|
||||
ConLog.Write("Game: boot done.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event))
|
||||
|
@ -257,6 +257,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" />
|
||||
|
@ -340,6 +340,9 @@
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="rpcs3.rc" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user