From 794cd4cf89be0e360b0b369b84a3bb13974a3723 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 28 Nov 2013 02:15:45 +0400 Subject: [PATCH 01/16] cellGcmSetUserHandler (empty), SPU.SF syntax Test commit --- rpcs3/Emu/Cell/SPUInterpreter.h | 8 ++++---- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 234329da47..f12b7185ea 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -72,10 +72,10 @@ private: } void SF(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._u32[0] = CPU.GPR[rb]._u32[0] + ~CPU.GPR[ra]._u32[0] + 1; - CPU.GPR[rt]._u32[1] = CPU.GPR[rb]._u32[1] + ~CPU.GPR[ra]._u32[1] + 1; - CPU.GPR[rt]._u32[2] = CPU.GPR[rb]._u32[2] + ~CPU.GPR[ra]._u32[2] + 1; - CPU.GPR[rt]._u32[3] = CPU.GPR[rb]._u32[3] + ~CPU.GPR[ra]._u32[3] + 1; + CPU.GPR[rt]._u32[0] = CPU.GPR[rb]._u32[0] - CPU.GPR[ra]._u32[0]; + CPU.GPR[rt]._u32[1] = CPU.GPR[rb]._u32[1] - CPU.GPR[ra]._u32[1]; + CPU.GPR[rt]._u32[2] = CPU.GPR[rb]._u32[2] - CPU.GPR[ra]._u32[2]; + CPU.GPR[rt]._u32[3] = CPU.GPR[rb]._u32[3] - CPU.GPR[ra]._u32[3]; } void OR(u32 rt, u32 ra, u32 rb) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 9c7e503c2c..bfef39781b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -284,6 +284,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()"); @@ -546,6 +552,7 @@ int cellGcmSetSecondVFrequency (u32 freq) void cellGcmSys_init() { cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); + cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); cellGcmSys.AddFunc(0x15bae46b, cellGcmInit); cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); From c48168ffc7c4653b7d681df28a6e6b775684026e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 29 Nov 2013 19:27:10 +0400 Subject: [PATCH 02/16] SPU ELF loading I'm not sure that it's correct way to get entry point --- rpcs3/Emu/Cell/SPUThread.cpp | 2 +- rpcs3/Emu/System.cpp | 3 ++- rpcs3/Loader/ELF.cpp | 1 + rpcs3/Loader/ELF32.cpp | 2 ++ rpcs3/Loader/ELF64.cpp | 3 +++ rpcs3/Loader/Loader.cpp | 1 + rpcs3/Loader/Loader.h | 3 +++ 7 files changed, 13 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 8bc5a30dbc..2faacb49bd 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -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 diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index d81b93dcae..3a0fb8b4e8 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -185,7 +185,8 @@ void Emulator::Load() ConLog.Write("max addr = 0x%x", l.GetMaxAddr()); thread.SetOffset(Memory.MainMem.GetStartAddr()); Memory.MainMem.Alloc(Memory.MainMem.GetStartAddr() + l.GetMaxAddr(), 0xFFFFED - l.GetMaxAddr()); - thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); + //thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); + thread.SetEntry(l.GetTextEntry()); break; case MACHINE_PPC64: diff --git a/rpcs3/Loader/ELF.cpp b/rpcs3/Loader/ELF.cpp index d967e4583e..fd1526e665 100644 --- a/rpcs3/Loader/ELF.cpp +++ b/rpcs3/Loader/ELF.cpp @@ -27,6 +27,7 @@ bool ELFLoader::LoadInfo() entry = loader->GetEntry(); machine = loader->GetMachine(); + _text_section_offset = loader->GetTextEntry(); return true; } diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 6684a4f584..c022de7d58 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -135,6 +135,8 @@ bool ELF32Loader::LoadShdrInfo() name += c; } shdr_name_arr.Add(name); + if(name == ".text") //temporary solution for SPU ELF loading + _text_section_offset = shdr_arr[i].sh_offset; } return true; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index e03ac6cadd..be47e93813 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -186,6 +186,8 @@ bool ELF64Loader::LoadShdrInfo(s64 offset) } shdr_name_arr.Add(name); + if(name == ".text") + _text_section_offset = shdr_arr[i].sh_offset; } return true; @@ -371,6 +373,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 diff --git a/rpcs3/Loader/Loader.cpp b/rpcs3/Loader/Loader.cpp index 86f8ebd326..5725ef0dd2 100644 --- a/rpcs3/Loader/Loader.cpp +++ b/rpcs3/Loader/Loader.cpp @@ -147,6 +147,7 @@ bool Loader::Analyze() machine = m_loader->GetMachine(); entry = m_loader->GetMachine() == MACHINE_SPU ? m_loader->GetEntry() + g_spu_offset : m_loader->GetEntry(); + _text_section_offset = m_loader->GetTextEntry(); return true; } diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index ab5c974c20..ee04d50911 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -181,12 +181,14 @@ protected: u32 min_addr; u32 max_addr; Elf_Machine machine; + u32 _text_section_offset; LoaderBase() : machine(MACHINE_Unknown) , entry(0) , min_addr(0) , max_addr(0) + , _text_section_offset(0) { } @@ -196,6 +198,7 @@ public: Elf_Machine GetMachine() { return machine; } u32 GetEntry() { return entry; } + u32 GetTextEntry() { return _text_section_offset; } u32 GetMinAddr() { return min_addr; } u32 GetMaxAddr() { return min_addr; } }; From 384e20acf023b5d8ca26efd89e4d2e4c89ca3167 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 30 Nov 2013 03:40:31 +0400 Subject: [PATCH 03/16] SPU fixes Partially tested and fixed --- rpcs3/Emu/Cell/SPUInterpreter.h | 65 +++++++++++++++++++++------------ rpcs3/Emu/Cell/SPUThread.cpp | 2 +- rpcs3/Loader/ELF64.cpp | 1 + 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index f12b7185ea..e61416980f 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -555,10 +555,10 @@ private: } void CDD(u32 rt, u32 ra, s32 i7) { - const int t = ((CPU.GPR[ra]._u32[0] + i7) & 0xf) >> 3; + const int t = (((CPU.GPR[ra]._u32[0] + i7) & 0xf) >> 3) ^ 1; - for (int i=0; i<16; ++i) - CPU.GPR[rt]._u8[i] = 0x10 + i; + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; CPU.GPR[rt]._u64[t] = (u64)0x0001020304050607; } @@ -1163,9 +1163,9 @@ private: CPU.GPR[rt]._u16[i] = CPU.GPR[ra]._u16[i] + i10; } } - void STQD(u32 rt, s32 i10, u32 ra) + void STQD(u32 rt, s32 i10, u32 ra) //hello_world addr=0x178, value won't be saved { - u32 lsa = CPU.GPR[ra]._u32[3] + i10; + const u32 lsa = (CPU.GPR[ra]._u32[3] + (i10 << 4)) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQD: bad lsa (0x%x)", lsa); @@ -1176,7 +1176,7 @@ private: } void LQD(u32 rt, s32 i10, u32 ra) { - u32 lsa = CPU.GPR[ra]._u32[3] + i10; + const u32 lsa = (CPU.GPR[ra]._u32[3] + (i10 << 4)) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQD: bad lsa (0x%x)", lsa); @@ -1224,14 +1224,14 @@ private: { for(u32 i = 0; i < 4; ++i) { - CPU.GPR[rt]._u32[i] = (CPU.GPR[rt]._u32[i] > (u32)i10) ? 0xffffffff : 0x00000000; + CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._u32[i] > (u32)i10) ? 0xffffffff : 0x00000000; } } void CLGTHI(u32 rt, u32 ra, s32 i10) { for(u32 i = 0; i < 8; ++i) { - CPU.GPR[rt]._u16[i] = (CPU.GPR[rt]._u16[i] > (u16)i10) ? 0xffff : 0x0000; + CPU.GPR[rt]._u16[i] = (CPU.GPR[ra]._u16[i] > (u16)i10) ? 0xffff : 0x0000; } } void CLGTBI(u32 rt, u32 ra, s32 i10) @@ -1246,18 +1246,18 @@ private: void MPYI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = CPU.GPR[rt]._i16[w*2 + 1] * i10; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2 + 1] * i10; } void MPYUI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = CPU.GPR[rt]._u16[w*2 + 1] * (u16)(i10 & 0xffff); + CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u16[w*2 + 1] * (u16)(i10 & 0xffff); } void CEQI(u32 rt, u32 ra, s32 i10) { for(u32 i = 0; i < 4; ++i) { - CPU.GPR[rt]._u32[i] = (CPU.GPR[rt]._u32[i] == (u32)i10) ? 0xffffffff : 0x00000000; + CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._u32[i] == (u32)i10) ? 0xffffffff : 0x00000000; } } void CEQHI(u32 rt, u32 ra, s32 i10) @@ -1304,7 +1304,24 @@ private: } void SHUFB(u32 rt, u32 ra, u32 rb, u32 rc) { - //ConLog.Warning("SHUFB"); + for (int i = 0; i < 16; i++) + { + u8 b = CPU.GPR[rc]._u8[i]; + if(b & 0x80) { + if(b & 0x40) { + if(b & 0x20) + CPU.GPR[rt]._u8[i] = 0x80; + else + CPU.GPR[rt]._u8[i] = 0xFF; + } else + CPU.GPR[rt]._u8[i] = 0x00; + } else { + if(b & 0x10) + CPU.GPR[rt]._u8[i] = CPU.GPR[rb]._u8[15 - (b & 0x0F)]; + else + CPU.GPR[rt]._u8[i] = CPU.GPR[ra]._u8[15 - (b & 0x0F)]; + } + } } void MPYA(u32 rc, u32 ra, u32 rb, u32 rt) { @@ -1313,24 +1330,24 @@ private: } void FNMS(u32 rt, u32 ra, u32 rb, u32 rc) { - CPU.GPR[rt]._f[0] -= CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0]; - CPU.GPR[rt]._f[1] -= CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1]; - CPU.GPR[rt]._f[2] -= CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2]; - CPU.GPR[rt]._f[3] -= CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3]; + CPU.GPR[rt]._f[0] = CPU.GPR[rc]._f[0] - CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0]; + CPU.GPR[rt]._f[1] = CPU.GPR[rc]._f[1] - CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1]; + CPU.GPR[rt]._f[2] = CPU.GPR[rc]._f[2] - CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2]; + CPU.GPR[rt]._f[3] = CPU.GPR[rc]._f[3] - CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3]; } void FMA(u32 rc, u32 ra, u32 rb, u32 rt) { - CPU.GPR[rt]._f[0] += CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0]; - CPU.GPR[rt]._f[1] += CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1]; - CPU.GPR[rt]._f[2] += CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2]; - CPU.GPR[rt]._f[3] += CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3]; + CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0] + CPU.GPR[rc]._f[0]; + CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1] + CPU.GPR[rc]._f[1]; + CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2] + CPU.GPR[rc]._f[2]; + CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3] + CPU.GPR[rc]._f[3]; } void FMS(u32 rc, u32 ra, u32 rb, u32 rt) { - CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0] - CPU.GPR[rt]._f[0]; - CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1] - CPU.GPR[rt]._f[1]; - CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2] - CPU.GPR[rt]._f[2]; - CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3] - CPU.GPR[rt]._f[3]; + CPU.GPR[rt]._f[0] = CPU.GPR[ra]._f[0] * CPU.GPR[rb]._f[0] - CPU.GPR[rc]._f[0]; + CPU.GPR[rt]._f[1] = CPU.GPR[ra]._f[1] * CPU.GPR[rb]._f[1] - CPU.GPR[rc]._f[1]; + CPU.GPR[rt]._f[2] = CPU.GPR[ra]._f[2] * CPU.GPR[rb]._f[2] - CPU.GPR[rc]._f[2]; + CPU.GPR[rt]._f[3] = CPU.GPR[ra]._f[3] * CPU.GPR[rb]._f[3] - CPU.GPR[rc]._f[3]; } void UNK(u32 code, u32 opcode, u32 gcode) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 8bc5a30dbc..2faacb49bd 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -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 diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index e03ac6cadd..f0406e0aea 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -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 From b217742c7b177a01926d755742adabbb9a200a6f Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 30 Nov 2013 03:50:43 +0400 Subject: [PATCH 04/16] Merge fix --- rpcs3/Emu/System.cpp | 3 +-- rpcs3/Loader/ELF.cpp | 1 - rpcs3/Loader/ELF32.cpp | 2 -- rpcs3/Loader/ELF64.cpp | 2 -- rpcs3/Loader/Loader.cpp | 1 - rpcs3/Loader/Loader.h | 3 --- 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 3a0fb8b4e8..d81b93dcae 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -185,8 +185,7 @@ void Emulator::Load() ConLog.Write("max addr = 0x%x", l.GetMaxAddr()); thread.SetOffset(Memory.MainMem.GetStartAddr()); Memory.MainMem.Alloc(Memory.MainMem.GetStartAddr() + l.GetMaxAddr(), 0xFFFFED - l.GetMaxAddr()); - //thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); - thread.SetEntry(l.GetTextEntry()); + thread.SetEntry(l.GetEntry() - Memory.MainMem.GetStartAddr()); break; case MACHINE_PPC64: diff --git a/rpcs3/Loader/ELF.cpp b/rpcs3/Loader/ELF.cpp index fd1526e665..d967e4583e 100644 --- a/rpcs3/Loader/ELF.cpp +++ b/rpcs3/Loader/ELF.cpp @@ -27,7 +27,6 @@ bool ELFLoader::LoadInfo() entry = loader->GetEntry(); machine = loader->GetMachine(); - _text_section_offset = loader->GetTextEntry(); return true; } diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index c022de7d58..6684a4f584 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -135,8 +135,6 @@ bool ELF32Loader::LoadShdrInfo() name += c; } shdr_name_arr.Add(name); - if(name == ".text") //temporary solution for SPU ELF loading - _text_section_offset = shdr_arr[i].sh_offset; } return true; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index be47e93813..f0406e0aea 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -186,8 +186,6 @@ bool ELF64Loader::LoadShdrInfo(s64 offset) } shdr_name_arr.Add(name); - if(name == ".text") - _text_section_offset = shdr_arr[i].sh_offset; } return true; diff --git a/rpcs3/Loader/Loader.cpp b/rpcs3/Loader/Loader.cpp index 5725ef0dd2..86f8ebd326 100644 --- a/rpcs3/Loader/Loader.cpp +++ b/rpcs3/Loader/Loader.cpp @@ -147,7 +147,6 @@ bool Loader::Analyze() machine = m_loader->GetMachine(); entry = m_loader->GetMachine() == MACHINE_SPU ? m_loader->GetEntry() + g_spu_offset : m_loader->GetEntry(); - _text_section_offset = m_loader->GetTextEntry(); return true; } diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index ee04d50911..ab5c974c20 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -181,14 +181,12 @@ protected: u32 min_addr; u32 max_addr; Elf_Machine machine; - u32 _text_section_offset; LoaderBase() : machine(MACHINE_Unknown) , entry(0) , min_addr(0) , max_addr(0) - , _text_section_offset(0) { } @@ -198,7 +196,6 @@ public: Elf_Machine GetMachine() { return machine; } u32 GetEntry() { return entry; } - u32 GetTextEntry() { return _text_section_offset; } u32 GetMinAddr() { return min_addr; } u32 GetMaxAddr() { return min_addr; } }; From ae39d3802f2193479c6878a471a6c0c74097d9db Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 1 Dec 2013 04:36:55 +0400 Subject: [PATCH 05/16] SPU Fixes 2 It's almost finished --- rpcs3/Emu/Cell/SPUInterpreter.h | 494 ++++++++++++++++---------------- rpcs3/Emu/Cell/SPUThread.h | 1 + 2 files changed, 247 insertions(+), 248 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index e61416980f..07cb71baf6 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -278,22 +278,22 @@ private: void BIZ(u32 rt, u32 ra) { if(CPU.GPR[rt]._u32[3] == 0) - CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); + CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void BINZ(u32 rt, u32 ra) { if(CPU.GPR[rt]._u32[3] != 0) - CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); + CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void BIHZ(u32 rt, u32 ra) { if(CPU.GPR[rt]._u16[7] == 0) - CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); + CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void BIHNZ(u32 rt, u32 ra) { if(CPU.GPR[rt]._u16[7] != 0) - CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); + CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void STOPD(u32 rc, u32 ra, u32 rb) { @@ -301,7 +301,7 @@ private: } void STQX(u32 rt, u32 ra, u32 rb) { - u32 lsa = CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]; + u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQX: bad lsa (0x%x)", lsa); @@ -313,7 +313,7 @@ private: } void BI(u32 ra) { - CPU.SetBranch(CPU.GPR[ra]._u32[3] & 0xfffffffc); + CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void BISL(u32 rt, u32 ra) { @@ -332,12 +332,11 @@ private: } void HBR(u32 p, u32 ro, u32 ra) { - CPU.SetBranch(CPU.GPR[ra]._u32[0]); } void GB(u32 rt, u32 ra) { CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] & 1) | + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[0] & 1) | ((CPU.GPR[ra]._u32[1] & 1) << 1) | ((CPU.GPR[ra]._u32[2] & 1) << 2) | ((CPU.GPR[ra]._u32[3] & 1) << 3); @@ -347,41 +346,47 @@ private: CPU.GPR[rt].Reset(); for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u32[0] |= (CPU.GPR[ra]._u16[h] & 1) << h; + CPU.GPR[rt]._u32[3] |= (CPU.GPR[ra]._u16[h] & 1) << h; } void GBB(u32 rt, u32 ra) { CPU.GPR[rt].Reset(); for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u32[0] |= (CPU.GPR[ra]._u8[b] & 1) << b; + CPU.GPR[rt]._u32[3] |= (CPU.GPR[ra]._u8[b] & 1) << b; } void FSM(u32 rt, u32 ra) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = (CPU.GPR[ra]._u32[0] & (8 >> w)) ? ~0 : 0; + CPU.GPR[rt]._u32[w] = (CPU.GPR[ra]._u32[3] & (1 << w)) ? ~0 : 0; } void FSMH(u32 rt, u32 ra) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = (CPU.GPR[ra]._u32[0] & (128 >> h)) ? ~0 : 0; + CPU.GPR[rt]._u16[h] = (CPU.GPR[ra]._u32[3] & (1 << h)) ? ~0 : 0; } void FSMB(u32 rt, u32 ra) { for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = (CPU.GPR[ra]._u32[0] & (32768 >> b)) ? ~0 : 0; + CPU.GPR[rt]._u8[b] = (CPU.GPR[ra]._u32[3] & (1 << b)) ? ~0 : 0; } void FREST(u32 rt, u32 ra) { - UNIMPLEMENTED(); + //(SSE) RCPPS - Compute Reciprocals of Packed Single-Precision Floating-Point Values + //rt = approximate(1/ra) + CPU.GPR[rt]._m128 = _mm_rcp_ps(CPU.GPR[ra]._m128); } void FRSQEST(u32 rt, u32 ra) { - UNIMPLEMENTED(); + //(SSE) RSQRTPS - Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values + //rt = approximate(1/sqrt(abs(ra))) + //abs(ra) === ra & FloatAbsMask + const __m128 FloatAbsMask = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; + CPU.GPR[rt]._m128 = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[ra]._m128, FloatAbsMask)); } void LQX(u32 rt, u32 ra, u32 rb) { - u32 lsa = CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]; + u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQX: bad lsa (0x%x)", lsa); @@ -393,238 +398,195 @@ private: } void ROTQBYBI(u32 rt, u32 ra, u32 rb) { - const int s = (CPU.GPR[rb]._u32[0] >> 3) & 0xf; + const int s = (CPU.GPR[rb]._u32[3] >> 3) & 0xf; - for (int b = 0; b < 8; b++) - { - if(b + s < 16) - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; - } - else - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s - 16]; - } - } + for (int b = 0; b < 16; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; } void ROTQMBYBI(u32 rt, u32 ra, u32 rb) { - const int nShift = ((0 - CPU.GPR[rb]._u32[0]) >> 3) & 0x1f; + const int s = (0 - (CPU.GPR[rb]._u32[3] >> 3)) & 0x1f; - for (int b = 0; b < 16; b++) - { - if (b >= nShift) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - nShift]; - else - CPU.GPR[rt]._u8[b] = 0; - } + CPU.GPR[rt].Reset(); + for (int b = 0; b < 16 - s; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; } void SHLQBYBI(u32 rt, u32 ra, u32 rb) { - const int nShift = (CPU.GPR[rb]._u32[0] >> 3) & 0x1f; + const int s = (CPU.GPR[rb]._u32[3] >> 3) & 0x1f; - for (int b = 0; b < 16; b++) - { - if ((b + nShift) < 16) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + nShift]; - else - CPU.GPR[rt]._u8[b] = 0; - } + CPU.GPR[rt].Reset(); + for (int b = s; b < 16; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; } void CBX(u32 rt, u32 ra, u32 rb) { - int n = (CPU.GPR[rb]._u32[0] + CPU.GPR[ra]._u32[0]) & 0xf; + const u32 t = (CPU.GPR[rb]._u32[3] + CPU.GPR[ra]._u32[3]) & 0xF; - for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = b == n ? 3 : b | 0x10; + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u8[15 - t] = 0x03; } void CHX(u32 rt, u32 ra, u32 rb) { - int n = ((CPU.GPR[rb]._u32[0] + CPU.GPR[ra]._u32[0]) & 0xf) >> 1; + const u32 t = (CPU.GPR[rb]._u32[3] + CPU.GPR[ra]._u32[3]) & 0xE; - for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = h == n ? 0x0203 : (h * 2 * 0x0101 + 0x1011); + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u16[7 - (t >> 1)] = 0x0203; } void CWX(u32 rt, u32 ra, u32 rb) { - const u32 t = ((CPU.GPR[ra]._u32[0] + CPU.GPR[rb]._u32[0]) & 0xc) / 4; - for(u32 i=0; i<16; ++i) CPU.GPR[rt]._i8[i] = 0x10 + i; - CPU.GPR[rt]._u32[t] = 0x10203; + const u32 t = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0xC; + + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u32[3 - (t >> 2)] = 0x00010203; } void CDX(u32 rt, u32 ra, u32 rb) { - int n = ((CPU.GPR[rb]._u32[0] + CPU.GPR[ra]._u32[0]) & 0x8) >> 2; + const u32 t = (CPU.GPR[rb]._u32[3] + CPU.GPR[ra]._u32[3]) & 0x8; - for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = (w == n) ? 0x00010203 : (w == (n + 1)) ? 0x04050607 : (0x01010101 * (w * 4) + 0x10111213); + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u64[1 - (t >> 3)] = (u64)0x0001020304050607; } void ROTQBI(u32 rt, u32 ra, u32 rb) { - int nShift = CPU.GPR[rb]._u32[0] & 0x7; + const int t = CPU.GPR[rb]._u32[3] & 0x7; - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << nShift) | (CPU.GPR[ra]._u32[1] >> (32 - nShift)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << nShift) | (CPU.GPR[ra]._u32[2] >> (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << nShift) | (CPU.GPR[ra]._u32[3] >> (32 - nShift)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << nShift) | (CPU.GPR[ra]._u32[0] >> (32 - nShift)); + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << t) | (CPU.GPR[ra]._u32[3] >> (32 - t)); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << t) | (CPU.GPR[ra]._u32[0] >> (32 - t)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << t) | (CPU.GPR[ra]._u32[1] >> (32 - t)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << t) | (CPU.GPR[ra]._u32[2] >> (32 - t)); } void ROTQMBI(u32 rt, u32 ra, u32 rb) { - int nShift = (0 - CPU.GPR[rb]._u32[0]) % 8; + const int t = (0 - CPU.GPR[rb]._u32[3]) & 0x7; - CPU.GPR[rt]._u32[0] = CPU.GPR[ra]._u32[0] >> nShift; - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> nShift) | (CPU.GPR[ra]._u32[0] << (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> nShift) | (CPU.GPR[ra]._u32[1] << (32 - nShift)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> nShift) | (CPU.GPR[ra]._u32[2] << (32 - nShift)); + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] >> t) | (CPU.GPR[ra]._u32[1] << (32 - t)); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> t) | (CPU.GPR[ra]._u32[2] << (32 - t)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> t) | (CPU.GPR[ra]._u32[3] << (32 - t)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> t); } void SHLQBI(u32 rt, u32 ra, u32 rb) { - const int nShift = CPU.GPR[rb]._u32[0] & 0x7; + const int t = CPU.GPR[rb]._u32[3] & 0x7; - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << nShift) | (CPU.GPR[ra]._u32[1] >> (32 - nShift)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << nShift) | (CPU.GPR[ra]._u32[2] >> (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << nShift) | (CPU.GPR[ra]._u32[3] >> (32 - nShift)); - CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._u32[3] << nShift; + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << t); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << t) | (CPU.GPR[ra]._u32[0] >> (32 - t)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << t) | (CPU.GPR[ra]._u32[1] >> (32 - t)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << t) | (CPU.GPR[ra]._u32[2] >> (32 - t)); } void ROTQBY(u32 rt, u32 ra, u32 rb) { - const s32 s = CPU.GPR[rb]._u8[0] & 0xf; + const int s = CPU.GPR[rb]._u32[3] & 0xf; - for(u32 b = 0; b < 16; ++b) - { - if(b + s < 16) - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; - } - else - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s - 16]; - } - } + for (int b = 0; b < 16; ++b) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; } void ROTQMBY(u32 rt, u32 ra, u32 rb) { - const int nShift = (0 - CPU.GPR[rb]._u32[0]) % 32; + const int s = (0 - CPU.GPR[rb]._u32[3]) & 0x1f; - for (int b = 0; b < 16; b++) - if (b >= nShift) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - nShift]; - else - CPU.GPR[rt]._u8[b] = 0; + CPU.GPR[rt].Reset(); + for (int b = 0; b < 16 - s; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; } void SHLQBY(u32 rt, u32 ra, u32 rb) { - const int nShift = CPU.GPR[rb]._u32[0] & 0x1f; + const int s = CPU.GPR[rb]._u32[3] & 0x1f; - for (int b = 0; b < 16; b++) - if (b + nShift < 16) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + nShift]; - else - CPU.GPR[rt]._u8[b] = 0; + CPU.GPR[rt].Reset(); + for (int b = s; b < 16; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; } void ORX(u32 rt, u32 ra) { CPU.GPR[rt].Reset(); - - CPU.GPR[rt]._u32[0] = CPU.GPR[ra]._u32[0] | CPU.GPR[ra]._u32[1] | CPU.GPR[ra]._u32[2] | CPU.GPR[ra]._u32[3]; + CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._u32[0] | CPU.GPR[ra]._u32[1] | CPU.GPR[ra]._u32[2] | CPU.GPR[ra]._u32[3]; } void CBD(u32 rt, u32 ra, s32 i7) { - const int n = (CPU.GPR[ra]._u32[0] + i7) & 0xf; - - for (int b = 0; b < 16; b++) - if (b == n) - CPU.GPR[rt]._u8[b] = 0x3; - else - CPU.GPR[rt]._u8[b] = b | 0x10; - } - void CHD(u32 rt, u32 ra, s32 i7) - { - int n = ((CPU.GPR[ra]._u32[0] + i7) & 0xf) >> 1; - - for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = h == n ? 0x0203 : (h * 2 * 0x0101 + 0x1011); - } - void CWD(u32 rt, u32 ra, s32 i7) - { - const int t = ((CPU.GPR[ra]._u32[0] + i7) & 0xf) >> 2; - - for (int i=0; i<16; ++i) - CPU.GPR[rt]._u8[i] = 0x10 + i; - - CPU.GPR[rt]._u32[t] = 0x10203; - } - void CDD(u32 rt, u32 ra, s32 i7) - { - const int t = (((CPU.GPR[ra]._u32[0] + i7) & 0xf) >> 3) ^ 1; + const int t = (CPU.GPR[ra]._u32[3] + i7) & 0xF; CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u8[15 - t] = 0x03; + } + void CHD(u32 rt, u32 ra, s32 i7) + { + const int t = (CPU.GPR[ra]._u32[3] + i7) & 0xE; - CPU.GPR[rt]._u64[t] = (u64)0x0001020304050607; + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u16[7 - (t >> 1)] = 0x0203; + } + void CWD(u32 rt, u32 ra, s32 i7) + { + const int t = (CPU.GPR[ra]._u32[3] + i7) & 0xC; + + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u32[3 - (t >> 2)] = 0x00010203; + } + void CDD(u32 rt, u32 ra, s32 i7) + { + const int t = (CPU.GPR[ra]._u32[3] + i7) & 0x8; + + CPU.GPR[rt]._u64[0] = (u64)0x18191A1B1C1D1E1F; + CPU.GPR[rt]._u64[1] = (u64)0x1011121314151617; + CPU.GPR[rt]._u64[1 - (t >> 3)] = (u64)0x0001020304050607; } void ROTQBII(u32 rt, u32 ra, s32 i7) { - int nShift = i7 & 0x7; + const int s = i7 & 0x7; - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << nShift) | (CPU.GPR[ra]._u32[1] >> (32 - nShift)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << nShift) | (CPU.GPR[ra]._u32[2] >> (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << nShift) | (CPU.GPR[ra]._u32[3] >> (32 - nShift)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << nShift) | (CPU.GPR[ra]._u32[0] >> (32 - nShift)); + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << s) | (CPU.GPR[ra]._u32[3] >> (32 - s)); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << s) | (CPU.GPR[ra]._u32[0] >> (32 - s)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << s) | (CPU.GPR[ra]._u32[1] >> (32 - s)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << s) | (CPU.GPR[ra]._u32[2] >> (32 - s)); } void ROTQMBII(u32 rt, u32 ra, s32 i7) { - int nShift = (0 - i7) % 8; + const int s = (0 - i7) & 0x7; - CPU.GPR[rt]._u32[0] = CPU.GPR[ra]._u32[0] >> nShift; - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> nShift) | (CPU.GPR[ra]._u32[0] << (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> nShift) | (CPU.GPR[ra]._u32[1] << (32 - nShift)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> nShift) | (CPU.GPR[ra]._u32[2] << (32 - nShift)); + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] >> s) | (CPU.GPR[ra]._u32[1] << (32 - s)); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> s) | (CPU.GPR[ra]._u32[2] << (32 - s)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> s) | (CPU.GPR[ra]._u32[3] << (32 - s)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> s); } void SHLQBII(u32 rt, u32 ra, s32 i7) { - const int nShift = i7 & 0x7; + const int s = i7 & 0x7; - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << nShift) | (CPU.GPR[ra]._u32[1] >> (32 - nShift)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << nShift) | (CPU.GPR[ra]._u32[2] >> (32 - nShift)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << nShift) | (CPU.GPR[ra]._u32[3] >> (32 - nShift)); - CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._u32[3] << nShift; + CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << s); + CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << s) | (CPU.GPR[ra]._u32[0] >> (32 - s)); + CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << s) | (CPU.GPR[ra]._u32[1] >> (32 - s)); + CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << s) | (CPU.GPR[ra]._u32[2] >> (32 - s)); } void ROTQBYI(u32 rt, u32 ra, s32 i7) { - const u16 s = i7 & 0xf; + const int s = i7 & 0xf; - for(u32 b = 0; b < 16; ++b) - { - if(b + s < 16) - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; - } - else - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s - 16]; - } - } + for (int b = 0; b < 16; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; } void ROTQMBYI(u32 rt, u32 ra, s32 i7) { - const int nShift = (0 - i7) % 32; + const int s = (0 - i7) & 0x1f; - for (int b = 0; b < 16; b++) - if (b >= nShift) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - nShift]; - else - CPU.GPR[rt]._u8[b] = 0; + CPU.GPR[rt].Reset(); + for (int b = 0; b < 16 - s; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; } void SHLQBYI(u32 rt, u32 ra, s32 i7) { - const u16 s = i7 & 0x1f; + const int s = i7 & 0x1f; CPU.GPR[rt].Reset(); - - for(u32 b = 0; b + s < 16; ++b) - { - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; - } + for (int b = s; b < 16; b++) + CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; } void NOP(u32 rt) { @@ -647,7 +609,7 @@ private: void EQV(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = (CPU.GPR[ra]._u32[w] & CPU.GPR[rb]._u32[w]) | ~(CPU.GPR[ra]._u32[w] | CPU.GPR[rb]._u32[w]); + CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u32[w] ^ (~CPU.GPR[rb]._u32[w]); } void CGTB(u32 rt, u32 ra, u32 rb) { @@ -665,10 +627,7 @@ private: //HGT uses signed values. HLGT uses unsigned values void HGT(u32 rt, s32 ra, s32 rb) { - if(CPU.GPR[ra]._i32[0] > CPU.GPR[rb]._i32[0]) - { - CPU.Stop(); - } + if(CPU.GPR[ra]._i32[3] > CPU.GPR[rb]._i32[3]) CPU.Stop(); } void CLZ(u32 rt, u32 ra) { @@ -685,13 +644,13 @@ private: } void XSWD(u32 rt, u32 ra) { - CPU.GPR[rt]._i64[0] = (s64)CPU.GPR[ra]._i32[1]; - CPU.GPR[rt]._i64[1] = (s64)CPU.GPR[ra]._i32[3]; + CPU.GPR[rt]._i64[0] = (s64)CPU.GPR[ra]._i32[0]; + CPU.GPR[rt]._i64[1] = (s64)CPU.GPR[ra]._i32[2]; } void XSHW(u32 rt, u32 ra) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = (s32)CPU.GPR[ra]._i16[w*2 + 1]; + CPU.GPR[rt]._i32[w] = (s32)CPU.GPR[ra]._i16[w*2]; } void CNTB(u32 rt, u32 ra) { @@ -704,7 +663,7 @@ private: void XSBH(u32 rt, u32 ra) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._i16[h] = (s16)CPU.GPR[ra]._i8[h*2 + 1]; + CPU.GPR[rt]._i16[h] = (s16)CPU.GPR[ra]._i8[h*2]; } void CLGT(u32 rt, u32 ra, u32 rb) { @@ -795,10 +754,7 @@ private: } void HLGT(u32 rt, u32 ra, u32 rb) { - if(CPU.GPR[ra]._u32[0] > CPU.GPR[rb]._u32[0]) - { - CPU.Stop(); - } + if(CPU.GPR[ra]._u32[3] > CPU.GPR[rb]._u32[3]) CPU.Stop(); } void DFMA(u32 rt, u32 ra, u32 rb) { @@ -817,8 +773,8 @@ private: } void DFNMA(u32 rt, u32 ra, u32 rb) { - CPU.GPR[rt]._d[0] = - CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0] - CPU.GPR[rt]._d[0] ; - CPU.GPR[rt]._d[1] = - CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1] - CPU.GPR[rt]._d[1] ; + CPU.GPR[rt]._d[0] = -(CPU.GPR[ra]._d[0] * CPU.GPR[rb]._d[0] + CPU.GPR[rt]._d[0]); + CPU.GPR[rt]._d[1] = -(CPU.GPR[ra]._d[1] * CPU.GPR[rb]._d[1] + CPU.GPR[rt]._d[1]); } void CEQ(u32 rt, u32 ra, u32 rb) { @@ -828,7 +784,7 @@ private: void MPYHHU(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u16[w*2] * CPU.GPR[rb]._u16[w*2]; + CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u16[w*2+1] * CPU.GPR[rb]._u16[w*2+1]; } void ADDX(u32 rt, u32 ra, u32 rb) { @@ -843,7 +799,7 @@ private: void CGX(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = (CPU.GPR[ra]._u32[w] + CPU.GPR[rb]._u32[w] + (CPU.GPR[rt]._u32[w] & 1)) < CPU.GPR[ra]._u32[w] ? 1 : 0; + CPU.GPR[rt]._u32[w] = ((u64)CPU.GPR[ra]._u32[w] + (u64)CPU.GPR[rb]._u32[w] + (u64)(CPU.GPR[rt]._u32[w] & 1)) >> 32; } void BGX(u32 rt, u32 ra, u32 rb) { @@ -851,19 +807,19 @@ private: for (int w = 0; w < 4; w++) { - nResult = (u64)CPU.GPR[rb]._u32[w] - (u64)CPU.GPR[ra]._u32[w] - (1 - (CPU.GPR[rt]._u32[w] & 1)); + nResult = (u64)CPU.GPR[rb]._u32[w] - (u64)CPU.GPR[ra]._u32[w] - (u64)(1 - (CPU.GPR[rt]._u32[w] & 1)); CPU.GPR[rt]._u32[w] = nResult < 0 ? 0 : 1; } } void MPYHHA(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] += CPU.GPR[ra]._i16[w*2] * CPU.GPR[rb]._i16[w*2]; + CPU.GPR[rt]._i32[w] += CPU.GPR[ra]._i16[w*2+1] * CPU.GPR[rb]._i16[w*2+1]; } void MPYHHAU(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] += CPU.GPR[ra]._u16[w*2] * CPU.GPR[rb]._u16[w*2]; + CPU.GPR[rt]._u32[w] += CPU.GPR[ra]._u16[w*2+1] * CPU.GPR[rb]._u16[w*2+1]; } //Forced bits to 0, hence the shift: @@ -876,15 +832,15 @@ private: } void FESD(u32 rt, u32 ra) { - CPU.GPR[rt]._d[0] = (double)CPU.GPR[ra]._f[0]; - CPU.GPR[rt]._d[1] = (double)CPU.GPR[ra]._f[2]; + CPU.GPR[rt]._d[0] = (double)CPU.GPR[ra]._f[1]; + CPU.GPR[rt]._d[1] = (double)CPU.GPR[ra]._f[3]; } void FRDS(u32 rt, u32 ra) { - CPU.GPR[rt]._f[0] = (float)CPU.GPR[ra]._d[0]; - CPU.GPR[rt]._f[1] = 0x00000000; - CPU.GPR[rt]._f[2] = (float)CPU.GPR[ra]._d[1]; - CPU.GPR[rt]._f[3] = 0x00000000; + CPU.GPR[rt]._f[1] = (float)CPU.GPR[ra]._d[0]; + CPU.GPR[rt]._u32[0] = 0x00000000; + CPU.GPR[rt]._f[3] = (float)CPU.GPR[ra]._d[1]; + CPU.GPR[rt]._u32[1] = 0x00000000; } void FSCRWR(u32 rt, u32 ra) { @@ -892,7 +848,55 @@ private: } void DFTSV(u32 rt, u32 ra, s32 i7) { - UNIMPLEMENTED(); + const u64 DoubleExpMask = 0x7ff0000000000000; + const u64 DoubleFracMask = 0x000fffffffffffff; + const u64 DoubleSignMask = 0x8000000000000000; + CPU.GPR[rt].Reset(); + if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] & DoubleFracMask) + if (CPU.GPR[ra]._u64[i] & DoubleSignMask & DoubleExpMask == DoubleSignMask) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] & DoubleFracMask) + if (CPU.GPR[ra]._u64[i] & DoubleSignMask & DoubleExpMask == 0) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] == DoubleSignMask) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] == 0) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] == DoubleSignMask & DoubleExpMask) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] == DoubleExpMask) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } + if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero) + for (int i = 0; i < 2; i++) + { + if (CPU.GPR[ra]._u64[i] & DoubleFracMask) + if (CPU.GPR[ra]._u64[i] & DoubleExpMask == DoubleExpMask) + CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; + } } void FCEQ(u32 rt, u32 ra, u32 rb) { @@ -909,22 +913,22 @@ private: void MPY(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2 + 1] * CPU.GPR[rb]._i16[w*2 + 1]; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2] * CPU.GPR[rb]._i16[w*2]; } void MPYH(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = ((CPU.GPR[ra]._i32[w] >> 16) * (CPU.GPR[rb]._i32[w] & 0xffff)) << 16; + CPU.GPR[rt]._i32[w] = (CPU.GPR[ra]._i16[w*2+1] * CPU.GPR[rb]._i16[w*2]) << 16; } void MPYHH(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2] * CPU.GPR[rb]._i16[w*2]; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2+1] * CPU.GPR[rb]._i16[w*2+1]; } void MPYS(u32 rt, u32 ra, u32 rb) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = (CPU.GPR[ra]._i16[w*2 + 1] * CPU.GPR[rb]._i16[w*2 + 1]) >> 16; + CPU.GPR[rt]._i32[w] = (CPU.GPR[ra]._i16[w*2] * CPU.GPR[rb]._i16[w*2]) >> 16; } void CEQH(u32 rt, u32 ra, u32 rb) { @@ -959,7 +963,7 @@ private: } void HEQ(u32 rt, u32 ra, u32 rb) { - UNIMPLEMENTED(); + if(CPU.GPR[ra]._i32[3] == CPU.GPR[rb]._i32[3]) CPU.Stop(); } //0 - 9 @@ -983,11 +987,12 @@ private: //0 - 8 void BRZ(u32 rt, s32 i16) { - if(!CPU.GPR[rt]._u32[3]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if (CPU.GPR[rt]._u32[3] == 0) + CPU.SetBranch(branchTarget(CPU.PC, i16)); } void STQA(u32 rt, s32 i16) { - u32 lsa = i16 << 2; + u32 lsa = (i16 << 2) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQA: bad lsa (0x%x)", lsa); @@ -999,20 +1004,22 @@ private: } void BRNZ(u32 rt, s32 i16) { - if(CPU.GPR[rt]._u32[3] != 0) + if (CPU.GPR[rt]._u32[3] != 0) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void BRHZ(u32 rt, s32 i16) { - if(!CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if (CPU.GPR[rt]._u16[7] == 0) + CPU.SetBranch(branchTarget(CPU.PC, i16)); } void BRHNZ(u32 rt, s32 i16) { - if(CPU.GPR[rt]._u16[7]) CPU.SetBranch(branchTarget(CPU.PC, i16)); + if (CPU.GPR[rt]._u16[7] != 0) + CPU.SetBranch(branchTarget(CPU.PC, i16)); } void STQR(u32 rt, s32 i16) { - u32 lsa = branchTarget(CPU.PC, i16); + u32 lsa = branchTarget(CPU.PC, (i16 << 2) & 0xFFFFFFF0); if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQR: bad lsa (0x%x)", lsa); @@ -1024,11 +1031,11 @@ private: } void BRA(s32 i16) { - CPU.SetBranch(i16 << 2); + CPU.SetBranch(branchTarget(0, i16)); } void LQA(u32 rt, s32 i16) { - u32 lsa = i16 << 2; + u32 lsa = (i16 << 2) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQA: bad lsa (0x%x)", lsa); @@ -1040,9 +1047,9 @@ private: } void BRASL(u32 rt, s32 i16) { + CPU.SetBranch(branchTarget(0, i16)); CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[0] = CPU.PC + 4; - CPU.SetBranch(i16 << 2); + CPU.GPR[rt]._u32[3] = CPU.PC + 4; } void BR(s32 i16) { @@ -1066,9 +1073,9 @@ private: } void BRSL(u32 rt, s32 i16) { + CPU.SetBranch(branchTarget(CPU.PC, i16)); CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[3] = CPU.PC + 4; - CPU.SetBranch(branchTarget(CPU.PC, i16)); } void LQR(u32 rt, s32 i16) { @@ -1084,25 +1091,25 @@ private: } void IL(u32 rt, s32 i16) { - CPU.GPR[rt]._u32[0] = i16; - CPU.GPR[rt]._u32[1] = i16; - CPU.GPR[rt]._u32[2] = i16; - CPU.GPR[rt]._u32[3] = i16; + CPU.GPR[rt]._i32[0] = + CPU.GPR[rt]._i32[1] = + CPU.GPR[rt]._i32[2] = + CPU.GPR[rt]._i32[3] = i16; } void ILHU(u32 rt, s32 i16) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u16[w*2 + 1] = i16; + CPU.GPR[rt]._i32[w] = i16 << 16; } void ILH(u32 rt, s32 i16) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = i16; + CPU.GPR[rt]._i16[h] = i16; } void IOHL(u32 rt, s32 i16) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] |= i16; + CPU.GPR[rt]._i32[w] |= (i16 & 0xFFFF); } @@ -1110,19 +1117,17 @@ private: void ORI(u32 rt, u32 ra, s32 i10) { for(u32 i = 0; i < 4; ++i) - { - CPU.GPR[rt]._u32[i] = CPU.GPR[ra]._u32[i] | i10; - } + CPU.GPR[rt]._i32[i] = CPU.GPR[ra]._i32[i] | i10; } void ORHI(u32 rt, u32 ra, s32 i10) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = CPU.GPR[ra]._u16[h] | i10; + CPU.GPR[rt]._i16[h] = CPU.GPR[ra]._i16[h] | i10; } void ORBI(u32 rt, u32 ra, s32 i10) { for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b] | (i10 & 0xff); + CPU.GPR[rt]._i8[b] = CPU.GPR[ra]._i8[b] | i10; } void SFI(u32 rt, u32 ra, s32 i10) { @@ -1137,31 +1142,27 @@ private: void ANDI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u32[w] & i10; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i32[w] & i10; } void ANDHI(u32 rt, u32 ra, s32 i10) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = CPU.GPR[ra]._u16[h] & i10; + CPU.GPR[rt]._i16[h] = CPU.GPR[ra]._i16[h] & i10; } void ANDBI(u32 rt, u32 ra, s32 i10) { for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b] & (i10 & 0xff); + CPU.GPR[rt]._i8[b] = CPU.GPR[ra]._i8[b] & i10; } void AI(u32 rt, u32 ra, s32 i10) { for(u32 i = 0; i < 4; ++i) - { - CPU.GPR[rt]._u32[i] = CPU.GPR[ra]._u32[i] + i10; - } + CPU.GPR[rt]._i32[i] = CPU.GPR[ra]._i32[i] + i10; } void AHI(u32 rt, u32 ra, s32 i10) { - for(u32 i = 0; i < 8; ++i) - { - CPU.GPR[rt]._u16[i] = CPU.GPR[ra]._u16[i] + i10; - } + for(u32 h = 0; h < 8; ++h) + CPU.GPR[rt]._i16[h] = CPU.GPR[ra]._i16[h] + i10; } void STQD(u32 rt, s32 i10, u32 ra) //hello_world addr=0x178, value won't be saved { @@ -1189,17 +1190,17 @@ private: void XORI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u32[w] ^ i10; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i32[w] ^ i10; } void XORHI(u32 rt, u32 ra, s32 i10) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = CPU.GPR[ra]._u16[h] ^ i10; + CPU.GPR[rt]._i16[h] = CPU.GPR[ra]._i16[h] ^ i10; } void XORBI(u32 rt, u32 ra, s32 i10) { for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b] ^ (i10 & 0xff); + CPU.GPR[rt]._i8[b] = CPU.GPR[ra]._i8[b] ^ i10; } void CGTI(u32 rt, u32 ra, s32 i10) { @@ -1218,7 +1219,7 @@ private: } void HGTI(u32 rt, u32 ra, s32 i10) { - UNIMPLEMENTED(); + if(CPU.GPR[ra]._i32[3] > i10) CPU.Stop(); } void CLGTI(u32 rt, u32 ra, s32 i10) { @@ -1241,55 +1242,52 @@ private: } void HLGTI(u32 rt, u32 ra, s32 i10) { - UNIMPLEMENTED(); + if(CPU.GPR[ra]._u32[3] > (u32)i10) CPU.Stop(); } void MPYI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2 + 1] * i10; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2] * i10; } void MPYUI(u32 rt, u32 ra, s32 i10) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u16[w*2 + 1] * (u16)(i10 & 0xffff); + CPU.GPR[rt]._u32[w] = CPU.GPR[ra]._u16[w*2] * (u16)(i10 & 0xffff); } void CEQI(u32 rt, u32 ra, s32 i10) { for(u32 i = 0; i < 4; ++i) - { - CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._u32[i] == (u32)i10) ? 0xffffffff : 0x00000000; - } + CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._i32[i] == i10) ? 0xffffffff : 0x00000000; } void CEQHI(u32 rt, u32 ra, s32 i10) { for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = CPU.GPR[ra]._i16[h] == (s16)i10 ? 0xffff : 0; + CPU.GPR[rt]._u16[h] = (CPU.GPR[ra]._i16[h] == (s16)i10) ? 0xffff : 0; } void CEQBI(u32 rt, u32 ra, s32 i10) { for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b] == (u8)(i10 & 0xff) ? 0xff : 0; + CPU.GPR[rt]._i8[b] = (CPU.GPR[ra]._i8[b] == (s8)(i10 & 0xff)) ? 0xff : 0; } void HEQI(u32 rt, u32 ra, s32 i10) { - UNIMPLEMENTED(); + if(CPU.GPR[ra]._i32[3] == i10) CPU.Stop(); } //0 - 6 void HBRA(s32 ro, s32 i16) { - UNIMPLEMENTED(); } void HBRR(s32 ro, s32 i16) { } void ILA(u32 rt, s32 i18) { - CPU.GPR[rt]._u32[0] = i18; - CPU.GPR[rt]._u32[1] = i18; - CPU.GPR[rt]._u32[2] = i18; - CPU.GPR[rt]._u32[3] = i18; + CPU.GPR[rt]._u32[0] = + CPU.GPR[rt]._u32[1] = + CPU.GPR[rt]._u32[2] = + CPU.GPR[rt]._u32[3] = i18 & 0x3FFFF; } //0 - 3 @@ -1326,7 +1324,7 @@ private: void MPYA(u32 rc, u32 ra, u32 rb, u32 rt) { for (int w = 0; w < 4; w++) - CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2 + 1] * CPU.GPR[rb]._i16[w*2 + 1] + CPU.GPR[rc]._i32[w]; + CPU.GPR[rt]._i32[w] = CPU.GPR[ra]._i16[w*2] * CPU.GPR[rb]._i16[w*2] + CPU.GPR[rc]._i32[w]; } void FNMS(u32 rt, u32 ra, u32 rb, u32 rc) { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 4cda6c586b..ade6b92574 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -204,6 +204,7 @@ union SPU_GPR_hdr { u128 _u128; s128 _i128; + __m128 _m128; u64 _u64[2]; s64 _i64[2]; u32 _u32[4]; From 1cfcc742d8937d1533c9ce26a3b092640079edd9 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 1 Dec 2013 21:30:40 +0400 Subject: [PATCH 06/16] SPU Fixes 3 Almost all implemented instructions are fixed. Partialy tested. Some instructions are still unimplemented. --- rpcs3/Emu/Cell/SPUInterpreter.h | 201 +++++++++++++++++--------------- 1 file changed, 108 insertions(+), 93 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 07cb71baf6..85b22a667f 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -301,7 +301,7 @@ private: } void STQX(u32 rt, u32 ra, u32 rb) { - u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0xFFFFFFF0; + u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQX: bad lsa (0x%x)", lsa); @@ -317,9 +317,10 @@ private: } void BISL(u32 rt, u32 ra) { - CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); + const u32 NewPC = CPU.GPR[ra]._u32[3]; CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[3] = CPU.PC + 4; + CPU.GPR[rt]._u32[3] = CPU.PC + 4; + CPU.SetBranch(branchTarget(NewPC, 0)); } void IRET(u32 ra) { @@ -335,40 +336,48 @@ private: } void GB(u32 rt, u32 ra) { - CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[0] & 1) | ((CPU.GPR[ra]._u32[1] & 1) << 1) | ((CPU.GPR[ra]._u32[2] & 1) << 2) | ((CPU.GPR[ra]._u32[3] & 1) << 3); + CPU.GPR[rt]._u32[2] = 0; + CPU.GPR[rt]._u64[0] = 0; } void GBH(u32 rt, u32 ra) { - CPU.GPR[rt].Reset(); - + u32 temp = 0; for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u32[3] |= (CPU.GPR[ra]._u16[h] & 1) << h; + temp |= (CPU.GPR[ra]._u16[h] & 1) << h; + CPU.GPR[rt]._u32[3] = temp; + CPU.GPR[rt]._u32[2] = 0; + CPU.GPR[rt]._u64[0] = 0; } void GBB(u32 rt, u32 ra) { - CPU.GPR[rt].Reset(); - + u32 temp; for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u32[3] |= (CPU.GPR[ra]._u8[b] & 1) << b; + temp |= (CPU.GPR[ra]._u8[b] & 1) << b; + CPU.GPR[rt]._u32[3] = temp; + CPU.GPR[rt]._u32[2] = 0; + CPU.GPR[rt]._u64[0] = 0; } void FSM(u32 rt, u32 ra) { + const u32 pref = CPU.GPR[ra]._u32[3]; for (int w = 0; w < 4; w++) - CPU.GPR[rt]._u32[w] = (CPU.GPR[ra]._u32[3] & (1 << w)) ? ~0 : 0; + CPU.GPR[rt]._u32[w] = (pref & (1 << w)) ? ~0 : 0; } void FSMH(u32 rt, u32 ra) { + const u32 pref = CPU.GPR[ra]._u32[3]; for (int h = 0; h < 8; h++) - CPU.GPR[rt]._u16[h] = (CPU.GPR[ra]._u32[3] & (1 << h)) ? ~0 : 0; + CPU.GPR[rt]._u16[h] = (pref & (1 << h)) ? ~0 : 0; } void FSMB(u32 rt, u32 ra) { + const u32 pref = CPU.GPR[ra]._u32[3]; for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = (CPU.GPR[ra]._u32[3] & (1 << b)) ? ~0 : 0; + CPU.GPR[rt]._u8[b] = (pref & (1 << b)) ? ~0 : 0; } void FREST(u32 rt, u32 ra) { @@ -386,7 +395,7 @@ private: } void LQX(u32 rt, u32 ra, u32 rb) { - u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0xFFFFFFF0; + u32 lsa = (CPU.GPR[ra]._u32[3] + CPU.GPR[rb]._u32[3]) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQX: bad lsa (0x%x)", lsa); @@ -399,25 +408,25 @@ private: void ROTQBYBI(u32 rt, u32 ra, u32 rb) { const int s = (CPU.GPR[rb]._u32[3] >> 3) & 0xf; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; + CPU.GPR[rt]._u8[b] = temp._u8[(b - s) & 0xf]; } void ROTQMBYBI(u32 rt, u32 ra, u32 rb) { const int s = (0 - (CPU.GPR[rb]._u32[3] >> 3)) & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = 0; b < 16 - s; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; + CPU.GPR[rt]._u8[b] = temp._u8[b + s]; } void SHLQBYBI(u32 rt, u32 ra, u32 rb) { const int s = (CPU.GPR[rb]._u32[3] >> 3) & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = s; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; + CPU.GPR[rt]._u8[b] = temp._u8[b - s]; } void CBX(u32 rt, u32 ra, u32 rb) { @@ -454,57 +463,58 @@ private: void ROTQBI(u32 rt, u32 ra, u32 rb) { const int t = CPU.GPR[rb]._u32[3] & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << t) | (CPU.GPR[ra]._u32[3] >> (32 - t)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << t) | (CPU.GPR[ra]._u32[0] >> (32 - t)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << t) | (CPU.GPR[ra]._u32[1] >> (32 - t)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << t) | (CPU.GPR[ra]._u32[2] >> (32 - t)); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] << t) | (temp._u32[3] >> (32 - t)); + CPU.GPR[rt]._u32[1] = (temp._u32[1] << t) | (temp._u32[0] >> (32 - t)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] << t) | (temp._u32[1] >> (32 - t)); + CPU.GPR[rt]._u32[3] = (temp._u32[3] << t) | (temp._u32[2] >> (32 - t)); } void ROTQMBI(u32 rt, u32 ra, u32 rb) { const int t = (0 - CPU.GPR[rb]._u32[3]) & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] >> t) | (CPU.GPR[ra]._u32[1] << (32 - t)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> t) | (CPU.GPR[ra]._u32[2] << (32 - t)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> t) | (CPU.GPR[ra]._u32[3] << (32 - t)); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] >> t) | (temp._u32[1] << (32 - t)); + CPU.GPR[rt]._u32[1] = (temp._u32[1] >> t) | (temp._u32[2] << (32 - t)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] >> t) | (temp._u32[3] << (32 - t)); CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> t); } void SHLQBI(u32 rt, u32 ra, u32 rb) { const int t = CPU.GPR[rb]._u32[3] & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << t); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << t) | (CPU.GPR[ra]._u32[0] >> (32 - t)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << t) | (CPU.GPR[ra]._u32[1] >> (32 - t)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << t) | (CPU.GPR[ra]._u32[2] >> (32 - t)); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] << t); + CPU.GPR[rt]._u32[1] = (temp._u32[1] << t) | (temp._u32[0] >> (32 - t)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] << t) | (temp._u32[1] >> (32 - t)); + CPU.GPR[rt]._u32[3] = (temp._u32[3] << t) | (temp._u32[2] >> (32 - t)); } void ROTQBY(u32 rt, u32 ra, u32 rb) { const int s = CPU.GPR[rb]._u32[3] & 0xf; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; for (int b = 0; b < 16; ++b) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; + CPU.GPR[rt]._u8[b] = temp._u8[(b - s) & 0xf]; } void ROTQMBY(u32 rt, u32 ra, u32 rb) { const int s = (0 - CPU.GPR[rb]._u32[3]) & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = 0; b < 16 - s; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; + CPU.GPR[rt]._u8[b] = temp._u8[b + s]; } void SHLQBY(u32 rt, u32 ra, u32 rb) { const int s = CPU.GPR[rb]._u32[3] & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = s; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; + CPU.GPR[rt]._u8[b] = temp._u8[b - s]; } void ORX(u32 rt, u32 ra) { + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._u32[0] | CPU.GPR[ra]._u32[1] | CPU.GPR[ra]._u32[2] | CPU.GPR[ra]._u32[3]; + CPU.GPR[rt]._u32[3] = temp._u32[0] | temp._u32[1] | temp._u32[2] | temp._u32[3]; } void CBD(u32 rt, u32 ra, s32 i7) { @@ -541,52 +551,52 @@ private: void ROTQBII(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << s) | (CPU.GPR[ra]._u32[3] >> (32 - s)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << s) | (CPU.GPR[ra]._u32[0] >> (32 - s)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << s) | (CPU.GPR[ra]._u32[1] >> (32 - s)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << s) | (CPU.GPR[ra]._u32[2] >> (32 - s)); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] << s) | (temp._u32[3] >> (32 - s)); + CPU.GPR[rt]._u32[1] = (temp._u32[1] << s) | (temp._u32[0] >> (32 - s)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] << s) | (temp._u32[1] >> (32 - s)); + CPU.GPR[rt]._u32[3] = (temp._u32[3] << s) | (temp._u32[2] >> (32 - s)); } void ROTQMBII(u32 rt, u32 ra, s32 i7) { const int s = (0 - i7) & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] >> s) | (CPU.GPR[ra]._u32[1] << (32 - s)); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] >> s) | (CPU.GPR[ra]._u32[2] << (32 - s)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] >> s) | (CPU.GPR[ra]._u32[3] << (32 - s)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] >> s); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] >> s) | (temp._u32[1] << (32 - s)); + CPU.GPR[rt]._u32[1] = (temp._u32[1] >> s) | (temp._u32[2] << (32 - s)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] >> s) | (temp._u32[3] << (32 - s)); + CPU.GPR[rt]._u32[3] = (temp._u32[3] >> s); } void SHLQBII(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0x7; - - CPU.GPR[rt]._u32[0] = (CPU.GPR[ra]._u32[0] << s); - CPU.GPR[rt]._u32[1] = (CPU.GPR[ra]._u32[1] << s) | (CPU.GPR[ra]._u32[0] >> (32 - s)); - CPU.GPR[rt]._u32[2] = (CPU.GPR[ra]._u32[2] << s) | (CPU.GPR[ra]._u32[1] >> (32 - s)); - CPU.GPR[rt]._u32[3] = (CPU.GPR[ra]._u32[3] << s) | (CPU.GPR[ra]._u32[2] >> (32 - s)); + const SPU_GPR_hdr temp = CPU.GPR[ra]; + CPU.GPR[rt]._u32[0] = (temp._u32[0] << s); + CPU.GPR[rt]._u32[1] = (temp._u32[1] << s) | (temp._u32[0] >> (32 - s)); + CPU.GPR[rt]._u32[2] = (temp._u32[2] << s) | (temp._u32[1] >> (32 - s)); + CPU.GPR[rt]._u32[3] = (temp._u32[3] << s) | (temp._u32[2] >> (32 - s)); } void ROTQBYI(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0xf; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; for (int b = 0; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[(b - s) & 0xf]; + CPU.GPR[rt]._u8[b] = temp._u8[(b - s) & 0xf]; } void ROTQMBYI(u32 rt, u32 ra, s32 i7) { const int s = (0 - i7) & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = 0; b < 16 - s; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b + s]; + CPU.GPR[rt]._u8[b] = temp._u8[b + s]; } void SHLQBYI(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0x1f; - + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); for (int b = s; b < 16; b++) - CPU.GPR[rt]._u8[b] = CPU.GPR[ra]._u8[b - s]; + CPU.GPR[rt]._u8[b] = temp._u8[b - s]; } void NOP(u32 rt) { @@ -618,10 +628,12 @@ private: } void SUMB(u32 rt, u32 ra, u32 rb) { + const SPU_GPR_hdr _a = CPU.GPR[ra]; + const SPU_GPR_hdr _b = CPU.GPR[rb]; for (int w = 0; w < 4; w++) { - CPU.GPR[rt]._u16[w*2] = CPU.GPR[ra]._u8[w*4] + CPU.GPR[ra]._u8[w*4 + 1] + CPU.GPR[ra]._u8[w*4 + 2] + CPU.GPR[ra]._u8[w*4 + 3]; - CPU.GPR[rt]._u16[w*2 + 1] = CPU.GPR[rb]._u8[w*4] + CPU.GPR[rb]._u8[w*4 + 1] + CPU.GPR[rb]._u8[w*4 + 2] + CPU.GPR[rb]._u8[w*4 + 3]; + CPU.GPR[rt]._u16[w*2] = _a._u8[w*4] + _a._u8[w*4 + 1] + _a._u8[w*4 + 2] + _a._u8[w*4 + 3]; + CPU.GPR[rt]._u16[w*2 + 1] = _b._u8[w*4] + _b._u8[w*4 + 1] + _b._u8[w*4 + 2] + _b._u8[w*4 + 3]; } } //HGT uses signed values. HLGT uses unsigned values @@ -654,11 +666,11 @@ private: } void CNTB(u32 rt, u32 ra) { + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); - for (int b = 0; b < 16; b++) for (int i = 0; i < 8; i++) - CPU.GPR[rt]._u8[b] += (CPU.GPR[ra]._u8[b] & (1 << i)) ? 1 : 0; + CPU.GPR[rt]._u8[b] += (temp._u8[b] & (1 << i)) ? 1 : 0; } void XSBH(u32 rt, u32 ra) { @@ -851,50 +863,51 @@ private: const u64 DoubleExpMask = 0x7ff0000000000000; const u64 DoubleFracMask = 0x000fffffffffffff; const u64 DoubleSignMask = 0x8000000000000000; + const SPU_GPR_hdr temp = CPU.GPR[ra]; CPU.GPR[rt].Reset(); if (i7 & 1) //Negative Denorm Check (-, exp is zero, frac is non-zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] & DoubleFracMask) - if (CPU.GPR[ra]._u64[i] & DoubleSignMask & DoubleExpMask == DoubleSignMask) + if (temp._u64[i] & DoubleFracMask) + if (temp._u64[i] & DoubleSignMask & DoubleExpMask == DoubleSignMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] & DoubleFracMask) - if (CPU.GPR[ra]._u64[i] & DoubleSignMask & DoubleExpMask == 0) + if (temp._u64[i] & DoubleFracMask) + if (temp._u64[i] & DoubleSignMask & DoubleExpMask == 0) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] == DoubleSignMask) + if (temp._u64[i] == DoubleSignMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 8) //Positive Zero Check (+, exp is zero, frac is zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] == 0) + if (temp._u64[i] == 0) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] == DoubleSignMask & DoubleExpMask) + if (temp._u64[i] == DoubleSignMask & DoubleExpMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] == DoubleExpMask) + if (temp._u64[i] == DoubleExpMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 64) //Not-a-Number Check (any sign, exp is 0x7ff, frac is non-zero) for (int i = 0; i < 2; i++) { - if (CPU.GPR[ra]._u64[i] & DoubleFracMask) - if (CPU.GPR[ra]._u64[i] & DoubleExpMask == DoubleExpMask) + if (temp._u64[i] & DoubleFracMask) + if (temp._u64[i] & DoubleExpMask == DoubleExpMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } } @@ -992,7 +1005,7 @@ private: } void STQA(u32 rt, s32 i16) { - u32 lsa = (i16 << 2) & 0xFFFFFFF0; + u32 lsa = (i16 << 2) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQA: bad lsa (0x%x)", lsa); @@ -1019,7 +1032,7 @@ private: } void STQR(u32 rt, s32 i16) { - u32 lsa = branchTarget(CPU.PC, (i16 << 2) & 0xFFFFFFF0); + u32 lsa = branchTarget(CPU.PC, i16) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQR: bad lsa (0x%x)", lsa); @@ -1035,7 +1048,7 @@ private: } void LQA(u32 rt, s32 i16) { - u32 lsa = (i16 << 2) & 0xFFFFFFF0; + u32 lsa = (i16 << 2) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQA: bad lsa (0x%x)", lsa); @@ -1047,9 +1060,9 @@ private: } void BRASL(u32 rt, s32 i16) { - CPU.SetBranch(branchTarget(0, i16)); CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[3] = CPU.PC + 4; + CPU.SetBranch(branchTarget(0, i16)); } void BR(s32 i16) { @@ -1073,13 +1086,13 @@ private: } void BRSL(u32 rt, s32 i16) { - CPU.SetBranch(branchTarget(CPU.PC, i16)); CPU.GPR[rt].Reset(); CPU.GPR[rt]._u32[3] = CPU.PC + 4; + CPU.SetBranch(branchTarget(CPU.PC, i16)); } void LQR(u32 rt, s32 i16) { - u32 lsa = branchTarget(CPU.PC, i16); + u32 lsa = branchTarget(CPU.PC, i16) & 0xFFFFFFF0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQR: bad lsa (0x%x)", lsa); @@ -1164,9 +1177,9 @@ private: for(u32 h = 0; h < 8; ++h) CPU.GPR[rt]._i16[h] = CPU.GPR[ra]._i16[h] + i10; } - void STQD(u32 rt, s32 i10, u32 ra) //hello_world addr=0x178, value won't be saved + void STQD(u32 rt, s32 i10, u32 ra) //i10 is shifted left by 4 while decoding { - const u32 lsa = (CPU.GPR[ra]._u32[3] + (i10 << 4)) & 0xFFFFFFF0; + const u32 lsa = (CPU.GPR[ra]._i32[3] + i10) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("STQD: bad lsa (0x%x)", lsa); @@ -1175,9 +1188,9 @@ private: } CPU.WriteLS128(lsa, CPU.GPR[rt]._u128); } - void LQD(u32 rt, s32 i10, u32 ra) + void LQD(u32 rt, s32 i10, u32 ra) //i10 is shifted left by 4 while decoding { - const u32 lsa = (CPU.GPR[ra]._u32[3] + (i10 << 4)) & 0xFFFFFFF0; + const u32 lsa = (CPU.GPR[ra]._i32[3] + i10) & 0x3fff0; if(!CPU.IsGoodLSA(lsa)) { ConLog.Error("LQD: bad lsa (0x%x)", lsa); @@ -1277,7 +1290,7 @@ private: //0 - 6 void HBRA(s32 ro, s32 i16) - { + { //i16 is shifted left by 2 while decoding } void HBRR(s32 ro, s32 i16) { @@ -1293,15 +1306,17 @@ private: //0 - 3 void SELB(u32 rt, u32 ra, u32 rb, u32 rc) { - for(u32 i = 0; i < 4; ++i) + for(u64 i = 0; i < 2; ++i) { - CPU.GPR[rt]._u32[i] = - ( CPU.GPR[rc]._u32[i] & CPU.GPR[rb]._u32[i]) | - (~CPU.GPR[rc]._u32[i] & CPU.GPR[ra]._u32[i]); + CPU.GPR[rt]._u64[i] = + ( CPU.GPR[rc]._u64[i] & CPU.GPR[rb]._u64[i]) | + (~CPU.GPR[rc]._u64[i] & CPU.GPR[ra]._u64[i]); } } void SHUFB(u32 rt, u32 ra, u32 rb, u32 rc) { + const SPU_GPR_hdr _a = CPU.GPR[ra]; + const SPU_GPR_hdr _b = CPU.GPR[rb]; for (int i = 0; i < 16; i++) { u8 b = CPU.GPR[rc]._u8[i]; @@ -1315,9 +1330,9 @@ private: CPU.GPR[rt]._u8[i] = 0x00; } else { if(b & 0x10) - CPU.GPR[rt]._u8[i] = CPU.GPR[rb]._u8[15 - (b & 0x0F)]; + CPU.GPR[rt]._u8[i] = _b._u8[15 - (b & 0x0F)]; else - CPU.GPR[rt]._u8[i] = CPU.GPR[ra]._u8[15 - (b & 0x0F)]; + CPU.GPR[rt]._u8[i] = _a._u8[15 - (b & 0x0F)]; } } } From 38fabf7cd2328bda4ecdec86bbe92d4e794de2d8 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 2 Dec 2013 14:40:58 +0400 Subject: [PATCH 07/16] SPU Fixes 3.1 Small fixes --- rpcs3/Emu/Cell/SPUInterpreter.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 85b22a667f..ad2721572c 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -287,12 +287,12 @@ private: } void BIHZ(u32 rt, u32 ra) { - if(CPU.GPR[rt]._u16[7] == 0) + if(CPU.GPR[rt]._u16[6] == 0) CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void BIHNZ(u32 rt, u32 ra) { - if(CPU.GPR[rt]._u16[7] != 0) + if(CPU.GPR[rt]._u16[6] != 0) CPU.SetBranch(branchTarget(CPU.GPR[ra]._u32[3], 0)); } void STOPD(u32 rc, u32 ra, u32 rb) @@ -512,9 +512,9 @@ private: } void ORX(u32 rt, u32 ra) { - const SPU_GPR_hdr temp = CPU.GPR[ra]; - CPU.GPR[rt].Reset(); - CPU.GPR[rt]._u32[3] = temp._u32[0] | temp._u32[1] | temp._u32[2] | temp._u32[3]; + CPU.GPR[rt]._u32[3] = CPU.GPR[ra]._u32[0] | CPU.GPR[ra]._u32[1] | CPU.GPR[ra]._u32[2] | CPU.GPR[ra]._u32[3]; + CPU.GPR[rt]._u32[2] = 0; + CPU.GPR[rt]._u64[0] = 0; } void CBD(u32 rt, u32 ra, s32 i7) { @@ -1022,12 +1022,12 @@ private: } void BRHZ(u32 rt, s32 i16) { - if (CPU.GPR[rt]._u16[7] == 0) + if (CPU.GPR[rt]._u16[6] == 0) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void BRHNZ(u32 rt, s32 i16) { - if (CPU.GPR[rt]._u16[7] != 0) + if (CPU.GPR[rt]._u16[6] != 0) CPU.SetBranch(branchTarget(CPU.PC, i16)); } void STQR(u32 rt, s32 i16) From 73c2628ef40d52845081fdb0c2ea20b6db474cbf Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 2 Dec 2013 22:49:06 +0400 Subject: [PATCH 08/16] SPU Fixes 3.2 --- rpcs3/Emu/Cell/SPUInterpreter.h | 12 +++---- rpcs3/Emu/Cell/SPUThread.h | 63 +++++++++++++++++++++++++++++++-- rpcs3/rpcs3.vcxproj | 3 +- rpcs3/rpcs3.vcxproj.filters | 5 ++- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index ad2721572c..160febdbca 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -390,8 +390,8 @@ private: //(SSE) RSQRTPS - Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values //rt = approximate(1/sqrt(abs(ra))) //abs(ra) === ra & FloatAbsMask - const __m128 FloatAbsMask = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; - CPU.GPR[rt]._m128 = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[ra]._m128, FloatAbsMask)); + const __m128i FloatAbsMask = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; + CPU.GPR[rt]._m128 = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[ra]._m128, (__m128&)FloatAbsMask)); } void LQX(u32 rt, u32 ra, u32 rb) { @@ -869,14 +869,14 @@ private: for (int i = 0; i < 2; i++) { if (temp._u64[i] & DoubleFracMask) - if (temp._u64[i] & DoubleSignMask & DoubleExpMask == DoubleSignMask) + if ((temp._u64[i] & (DoubleSignMask & DoubleExpMask)) == DoubleSignMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 2) //Positive Denorm Check (+, exp is zero, frac is non-zero) for (int i = 0; i < 2; i++) { if (temp._u64[i] & DoubleFracMask) - if (temp._u64[i] & DoubleSignMask & DoubleExpMask == 0) + if ((temp._u64[i] & (DoubleSignMask & DoubleExpMask)) == 0) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 4) //Negative Zero Check (-, exp is zero, frac is zero) @@ -894,7 +894,7 @@ private: if (i7 & 16) //Negative Infinity Check (-, exp is 0x7ff, frac is zero) for (int i = 0; i < 2; i++) { - if (temp._u64[i] == DoubleSignMask & DoubleExpMask) + if (temp._u64[i] == (DoubleSignMask & DoubleExpMask)) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } if (i7 & 32) //Positive Infinity Check (+, exp is 0x7ff, frac is zero) @@ -907,7 +907,7 @@ private: for (int i = 0; i < 2; i++) { if (temp._u64[i] & DoubleFracMask) - if (temp._u64[i] & DoubleExpMask == DoubleExpMask) + if ((temp._u64[i] & DoubleExpMask) == DoubleExpMask) CPU.GPR[rt]._u64[i] = 0xffffffffffffffff; } } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index ade6b92574..9db744895b 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -233,13 +233,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() @@ -356,6 +356,34 @@ public: { 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(); @@ -379,6 +407,23 @@ public: switch(ch) { + case SPU_WrEventMask: //Write event mask + case SPU_WrEventAck: //Write end of event processing + case SPU_WrDec: //Write decrementer count + case SPU_WrSRR0: //Write SPU machine state save/restore register 0 (SRR0) + case MFC_WrMSSyncReq: //Write multisource synchronization request + 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_WrListStallAck: //Write DMA list stall-and-notify acknowledge + ConLog.Error("%s error: unimplemented channel (%s).", __FUNCTION__, spu_ch_name[ch]); + break; + case SPU_WrOutIntrMbox: ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v); @@ -410,6 +455,20 @@ public: switch(ch) { + case SPU_RdEventStat: //Read event status with mask applied + case SPU_RdSigNotify1: //Signal notification 1 + case SPU_RdSigNotify2: //Signal notification 2 + case SPU_RdDec: //Read decrementer count + case SPU_RdEventMask: //Read event mask + case SPU_RdMachStat: //Read SPU run status + case SPU_RdSRR0: //Read SPU machine state save/restore register 0 (SRR0) + case MFC_RdTagMask: //Read tag mask + case MFC_RdTagStat: //Read tag status with mask applied + case MFC_RdListStallStat: //Read DMA list stall-and-notify status + 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_RdInMbox: if(!SPU.In_MBox.Pop(v)) v = 0; ConLog.Warning("%s: SPU_RdInMbox(0x%x).", __FUNCTION__, v); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 62a417b4d9..ae92a31c8d 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -1,4 +1,4 @@ - + @@ -322,6 +322,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 7ac21c6caa..e01793878c 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -510,5 +510,8 @@ Utilities + + Include + \ No newline at end of file From 241ae8364519090d830f3924ff519264b07bac8d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 4 Dec 2013 00:35:45 +0400 Subject: [PATCH 09/16] SPU Improvement Implemented CFLTS, CFLTU, CSFLT and CUFLT. Finally fixed FREST. --- rpcs3/Emu/Cell/SPUInterpreter.h | 78 +++++++++++++++++++++++++++++---- rpcs3/Emu/Cell/SPUThread.h | 1 + 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 160febdbca..23832209e3 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -7,6 +7,13 @@ #define UNIMPLEMENTED() UNK(__FUNCTION__) +typedef union _CRT_ALIGN(16) __u32x4 { + unsigned __int32 _u32[4]; + __m128i m128i; + __m128 m128; + __m128d m128d; + } __u32x4; + class SPUInterpreter : public SPUOpcodes { private: @@ -390,8 +397,8 @@ private: //(SSE) RSQRTPS - Compute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values //rt = approximate(1/sqrt(abs(ra))) //abs(ra) === ra & FloatAbsMask - const __m128i FloatAbsMask = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; - CPU.GPR[rt]._m128 = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[ra]._m128, (__m128&)FloatAbsMask)); + const __u32x4 FloatAbsMask = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; + CPU.GPR[rt]._m128 = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[ra]._m128, FloatAbsMask.m128)); } void LQX(u32 rt, u32 ra, u32 rb) { @@ -972,7 +979,9 @@ private: } void FI(u32 rt, u32 ra, u32 rb) { - UNIMPLEMENTED(); + //Floating Interpolation: ra will be ignored. + //It should work correctly if result of preceding FREST or FRSQEST is sufficiently exact + CPU.GPR[rt] = CPU.GPR[rb]; } void HEQ(u32 rt, u32 ra, u32 rb) { @@ -982,19 +991,70 @@ private: //0 - 9 void CFLTS(u32 rt, u32 ra, s32 i8) { - UNIMPLEMENTED(); + const u32 scale = 173 - (i8 & 0xff); //unsigned immediate + for (int i = 0; i < 4; i++) + { + u32 exp = ((CPU.GPR[ra]._u32[i] >> 23) & 0xff) + scale; + + if (exp > 255) + exp = 255; + + CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._u32[i] & 0x807fffff) | (exp << 23); + } + //(SSE2) CVTTPS2DQ - Convert with Truncation Packed Single FP to Packed Dword Int + CPU.GPR[rt]._m128i = _mm_cvttps_epi32(CPU.GPR[rt]._m128); } void CFLTU(u32 rt, u32 ra, s32 i8) { - UNIMPLEMENTED(); + const u32 scale = 173 - (i8 & 0xff); //unsigned immediate + for (int i = 0; i < 4; i++) + { + u32 exp = ((CPU.GPR[ra]._u32[i] >> 23) & 0xff) + scale; + + if (exp > 255) + exp = 255; + + if (CPU.GPR[ra]._u32[i] & 0x80000000) //if negative, result = 0 + CPU.GPR[rt]._u32[i] = 0; + else + { + CPU.GPR[rt]._u32[i] = (CPU.GPR[ra]._u32[i] & 0x807fffff) | (exp << 23); + + if (CPU.GPR[rt]._f[i] > 0xffffffff) //if big, result = max + CPU.GPR[rt]._u32[i] = 0xffffffff; + else + CPU.GPR[rt]._u32[i] = floor(CPU.GPR[rt]._f[i]); + } + } } void CSFLT(u32 rt, u32 ra, s32 i8) { - UNIMPLEMENTED(); + //(SSE2) CVTDQ2PS - Convert Packed Dword Integers to Packed Single-Precision FP Values + CPU.GPR[rt]._m128 = _mm_cvtepi32_ps(CPU.GPR[ra]._m128i); + const u32 scale = 155 - (i8 & 0xff); //unsigned immediate + for (int i = 0; i < 4; i++) + { + u32 exp = ((CPU.GPR[rt]._u32[i] >> 23) & 0xff) - scale; + + if (exp > 255) //< 0 + exp = 0; + + CPU.GPR[rt]._u32[i] = (CPU.GPR[rt]._u32[i] & 0x807fffff) | (exp << 23); + } } void CUFLT(u32 rt, u32 ra, s32 i8) { - UNIMPLEMENTED(); + const u32 scale = 155 - (i8 & 0xff); //unsigned immediate + for (int i = 0; i < 4; i++) + { + CPU.GPR[rt]._f[i] = (float)CPU.GPR[ra]._u32[i]; + u32 exp = ((CPU.GPR[rt]._u32[i] >> 23) & 0xff) - scale; + + if (exp > 255) //< 0 + exp = 0; + + CPU.GPR[rt]._u32[i] = (CPU.GPR[rt]._u32[i] & 0x807fffff) | (exp << 23); + } } //0 - 8 @@ -1169,8 +1229,8 @@ private: } void AI(u32 rt, u32 ra, s32 i10) { - for(u32 i = 0; i < 4; ++i) - CPU.GPR[rt]._i32[i] = CPU.GPR[ra]._i32[i] + i10; + const __u32x4 imm = {i10, i10, i10, i10}; + CPU.GPR[rt]._m128i = _mm_add_epi32(CPU.GPR[ra]._m128i, imm.m128i); } void AHI(u32 rt, u32 ra, s32 i10) { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 9db744895b..cf47369de4 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -205,6 +205,7 @@ union SPU_GPR_hdr u128 _u128; s128 _i128; __m128 _m128; + __m128i _m128i; u64 _u64[2]; s64 _i64[2]; u32 _u32[4]; From a9a246a8661d28000b84cd33fa7ac7ee3cf21ee2 Mon Sep 17 00:00:00 2001 From: Hykem Date: Sat, 7 Dec 2013 20:56:42 +0000 Subject: [PATCH 10/16] 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. --- rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl | 66 ++ rpcs3/Emu/Memory/Memory.cpp | 10 +- rpcs3/Emu/Memory/Memory.h | 10 + rpcs3/Emu/Memory/MemoryBlock.h | 8 + rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 13 +- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 23 +- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 7 +- rpcs3/Emu/SysCalls/SysCalls.cpp | 18 +- rpcs3/Emu/SysCalls/SysCalls.h | 23 + rpcs3/Emu/SysCalls/lv2/SC_Event.cpp | 97 ++ rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp | 48 +- rpcs3/Emu/SysCalls/lv2/SC_Memory.h | 59 + rpcs3/Emu/SysCalls/lv2/SC_VM.cpp | 286 +++++ rpcs3/Emu/System.cpp | 5 + rpcs3/Emu/System.h | 2 + rpcs3/Emu/event.h | 22 + rpcs3/Gui/MainFrame.cpp | 143 +++ rpcs3/rpcs3.vcxproj | 733 ++++++------- rpcs3/rpcs3.vcxproj.filters | 1035 +++++++++--------- 19 files changed, 1658 insertions(+), 950 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_Memory.h create mode 100644 rpcs3/Emu/SysCalls/lv2/SC_VM.cpp diff --git a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl index 61550a8e3a..d8da141b53 100644 --- a/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl +++ b/rpcs3/Emu/Memory/DynamicMemoryBlockBase.inl @@ -133,6 +133,7 @@ bool DynamicMemoryBlockBase::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::GetMem(u64 addr) const assert(0); return nullptr; } + +template +bool DynamicMemoryBlockBase::IsLocked(const u64 addr) +{ + for(u32 i=0; i +void DynamicMemoryBlockBase::AppendLockedMem(u64 addr, u32 size) +{ + m_locked_mem.Move(new MemBlockInfo(addr, size)); +} + +template +bool DynamicMemoryBlockBase::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 +bool DynamicMemoryBlockBase::Unlock(u64 addr , u32 size) +{ + for(u32 i=0; i 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; +} diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index d9e7f0bd4f..6fcea3252f 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -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; diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 66123e36ca..34b1426e52 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -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)) diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index a35757468e..7d497bb1c4 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -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 class DynamicMemoryBlockBase : public PT { Array m_used_mem; + Array 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" diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 2b8c47f63e..6a9c2a9258 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -107,12 +107,14 @@ int cellGameBootCheck(mem32_t type, mem32_t attributes, mem_ptr_thddFreeSizeKB = 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 contentInfoPath, mem_list_ptr_t 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 46ff1d3965..e3bc93c238 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -386,17 +386,32 @@ int cellVideoOutGetConfiguration(u32 videoOut, u32 config_addr, u32 option_addr) int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, mem_ptr_t 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index dd53ba1d89..ed9c2a73d8 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -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); } diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 6cbc20a907..686e5e78b7 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -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 diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 20c54bb211..8e9b151099 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -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); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp index 28044cdc06..f423c778fa 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Event.cpp @@ -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) { diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp index 65e98f195c..412571f29d 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp @@ -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; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.h b/rpcs3/Emu/SysCalls/lv2/SC_Memory.h new file mode 100644 index 0000000000..88837dcb4e --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.h @@ -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; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_VM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_VM.cpp new file mode 100644 index 0000000000..307dcaf75c --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_VM.cpp @@ -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; +} \ No newline at end of file diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index d81b93dcae..d3b82b1fc5 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -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& threads = GetCPU().GetThreads(); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 5090e2e2f5..0b2192049f 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -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 OpenFile(const wxString& path, vfsOpenMode mode = vfsRead) { diff --git a/rpcs3/Emu/event.h b/rpcs3/Emu/event.h index ed4084bc32..8c5d94c360 100644 --- a/rpcs3/Emu/event.h +++ b/rpcs3/Emu/event.h @@ -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; diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 75c5993a9f..b1752a6edc 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -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 key_version; + f.Read(&key_version, sizeof(key_version)); + + if(key_version.ToBE() == const_se_t::value) + { + ConLog.Warning("Debug SELF detected! Removing fake header..."); + + // Get the real elf offset. + f.Seek(0x10); + be_t 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)) diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index ae92a31c8d..b5c8620aab 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -1,367 +1,368 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12} - Win32Proj - rpcs3 - - - - Application - true - MultiByte - v110 - - - Application - true - MultiByte - v110 - - - Application - false - true - MultiByte - v110 - false - - - Application - false - true - MultiByte - v110 - false - - - - - - - - - - - - - - - - - - - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) - $(SolutionDir)bin\ - ..\libs\$(Configuration)\;$(LibraryPath) - $(ProjectName)-$(PlatformShortName)-dbg - - - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) - $(SolutionDir)bin\ - ..\libs\$(Configuration)\;$(LibraryPath) - $(ProjectName)-$(PlatformShortName)-dbg - - - false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) - $(SolutionDir)bin\ - ..\libs\$(Configuration)\;$(LibraryPath) - false - false - $(ProjectName)-$(PlatformShortName) - - - false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) - $(SolutionDir)bin\ - ..\libs\$(Configuration)\;$(LibraryPath) - false - false - $(ProjectName)-$(PlatformShortName) - - - - Level3 - Disabled - EditAndContinue - Use - true - - - true - adv.lib;base.lib;core.lib;aui.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) - %(IgnoreSpecificDefaultLibraries) - false - - - - - - - - - Level3 - Disabled - ProgramDatabase - Use - - - true - adv.lib;base.lib;core.lib;aui.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) - %(IgnoreSpecificDefaultLibraries) - false - - - $(SolutionDir)\Utilities\git-version-gen.cmd - - - - - TurnOffAllWarnings - Full - true - true - - - MultiThreadedDLL - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - Use - Speed - Sync - false - - - Windows - true - true - true - adv.lib;base.lib;core.lib;aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregex.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) - - - %(IgnoreSpecificDefaultLibraries) - false - - - - - - - - - Level3 - Full - true - true - - - MultiThreadedDLL - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - false - Use - Speed - Sync - false - - - Windows - true - true - true - adv.lib;base.lib;core.lib;aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregex.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) - - - %(IgnoreSpecificDefaultLibraries) - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {70CD65B0-91D6-4FAE-9A7B-4AF55D0D1B12} + Win32Proj + rpcs3 + + + + Application + true + MultiByte + v110 + + + Application + true + MultiByte + v110 + + + Application + false + true + MultiByte + v110 + false + + + Application + false + true + MultiByte + v110 + false + + + + + + + + + + + + + + + + + + + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) + $(SolutionDir)bin\ + ..\libs\$(Configuration)\;$(LibraryPath) + $(ProjectName)-$(PlatformShortName)-dbg + + + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) + $(SolutionDir)bin\ + ..\libs\$(Configuration)\;$(LibraryPath) + $(ProjectName)-$(PlatformShortName)-dbg + + + false + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) + $(SolutionDir)bin\ + ..\libs\$(Configuration)\;$(LibraryPath) + false + false + $(ProjectName)-$(PlatformShortName) + + + false + .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;$(IncludePath) + $(SolutionDir)bin\ + ..\libs\$(Configuration)\;$(LibraryPath) + false + false + $(ProjectName)-$(PlatformShortName) + + + + Level3 + Disabled + EditAndContinue + Use + true + + + true + adv.lib;base.lib;core.lib;aui.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) + %(IgnoreSpecificDefaultLibraries) + false + + + + + + + + + Level3 + Disabled + ProgramDatabase + Use + + + true + adv.lib;base.lib;core.lib;aui.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;%(AdditionalDependencies) + %(IgnoreSpecificDefaultLibraries) + false + + + $(SolutionDir)\Utilities\git-version-gen.cmd + + + + + TurnOffAllWarnings + Full + true + true + + + MultiThreadedDLL + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Use + Speed + Sync + false + + + Windows + true + true + true + adv.lib;base.lib;core.lib;aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregex.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) + + + %(IgnoreSpecificDefaultLibraries) + false + + + + + + + + + Level3 + Full + true + true + + + MultiThreadedDLL + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Use + Speed + Sync + false + + + Windows + true + true + true + adv.lib;base.lib;core.lib;aui.lib;odbc32.lib;odbccp32.lib;comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;rpcrt4.lib;wxtiff.lib;wxjpeg.lib;wxpng.lib;wxzlib.lib;wxregex.lib;wxexpat.lib;wsock32.lib;wininet.lib;%(AdditionalDependencies) + + + %(IgnoreSpecificDefaultLibraries) + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index e01793878c..655f0f421a 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -1,517 +1,520 @@ - - - - - {29c70b04-59a5-4d5b-98f9-3584df137ed1} - - - {98fb6fa5-9a9a-48a6-a6b4-be4b9a69b76e} - - - {47155d25-741d-42c0-8850-f22aafca082a} - - - {f306c137-6d2c-4e21-ba79-ac87d0ded22c} - - - {adfec460-d940-4482-9fdb-18cb0814c3d5} - true - - - {6c36f15e-07fd-45d6-a81c-1ab43ee1b58b} - - - {57263311-75a4-4309-81aa-b86fd212794b} - - - {461eddb5-b8a8-46be-918c-98cc7eaf995b} - - - {6fb03753-064a-456d-bb6f-9ceaed3776c7} - - - {e79e49c8-6967-4776-8f50-5479c3821b51} - - - {9bd88f78-8528-48f3-b9e0-78e06476b04d} - - - {fd7cea02-e77f-41b1-8b61-f78e7d280e04} - - - {dfd581c4-aed0-4229-bb30-7ee5816049e1} - - - {718bc358-b7ef-4988-8547-2148d14bb08b} - - - {f66e37f9-5e58-443b-bcff-2e9e002ac89e} - - - {041a844e-9f8b-4b4b-a4c5-6c72ecbde475} - - - {bee6a4b4-6371-4c1b-8558-fc7888b1574e} - - - - - rpcs3 - - - rpcs3 - - - Gui - - - Gui - - - Emu - - - Gui - - - Gui - - - Emu - - - rpcs3 - - - Gui - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Gui - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Gui - - - Loader - - - Loader - - - Loader - - - Loader - - - Loader - - - Loader - - - Emu\Cell - - - Emu\Cell - - - Emu\SysCalls - - - Emu\SysCalls\lv2 - - - Emu\Io - - - Emu - - - Emu\GS - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\GS\GL - - - Emu\GS\GL - - - Emu\GS\GL - - - Emu\GS - - - Emu\SysCalls\lv2 - - - Emu\GS - - - Emu\Cell - - - Emu\SysCalls\lv2 - - - Utilities - - - Emu\SysCalls - - - Emu\SysCalls\lv2 - - - Emu\SysCalls - - - Emu\FS - - - Emu\FS - - - Emu\FS - - - Emu\FS - - - Emu\FS - - - Emu\FS - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Gui - - - rpcs3 - - - Emu\Cell - - - Emu\SysCalls\lv2 - - - Emu\SysCalls - - - Emu\SysCalls\Modules - - - Emu\Cell - - - Emu\Cell - - - Emu\HDD - - - Gui - - - Gui - - - Gui - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\Io - - - Emu\SysCalls\lv2 - - - Emu\Io - - - Emu\SysCalls\lv2 - - - Emu\FS - - - Emu\CPU - - - Emu\CPU - - - Emu\Cell - - - Emu\ARMv7 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\lv2 - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\SysCalls\Modules - - - Emu\GS\GL - - - Emu\GS\GL - - - Emu\GS\GL - - - Emu\GS\GL - - - Emu\SysCalls\Modules - - - - - - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Include - - - Utilities - - - Utilities - - - Utilities - - - Utilities - - - Utilities - - - Include - - - Include - - - Include - - - Include - - - Include - - - Utilities - - - Include - - + + + + + {29c70b04-59a5-4d5b-98f9-3584df137ed1} + + + {98fb6fa5-9a9a-48a6-a6b4-be4b9a69b76e} + + + {47155d25-741d-42c0-8850-f22aafca082a} + + + {f306c137-6d2c-4e21-ba79-ac87d0ded22c} + + + {adfec460-d940-4482-9fdb-18cb0814c3d5} + true + + + {6c36f15e-07fd-45d6-a81c-1ab43ee1b58b} + + + {57263311-75a4-4309-81aa-b86fd212794b} + + + {461eddb5-b8a8-46be-918c-98cc7eaf995b} + + + {6fb03753-064a-456d-bb6f-9ceaed3776c7} + + + {e79e49c8-6967-4776-8f50-5479c3821b51} + + + {9bd88f78-8528-48f3-b9e0-78e06476b04d} + + + {fd7cea02-e77f-41b1-8b61-f78e7d280e04} + + + {dfd581c4-aed0-4229-bb30-7ee5816049e1} + + + {718bc358-b7ef-4988-8547-2148d14bb08b} + + + {f66e37f9-5e58-443b-bcff-2e9e002ac89e} + + + {041a844e-9f8b-4b4b-a4c5-6c72ecbde475} + + + {bee6a4b4-6371-4c1b-8558-fc7888b1574e} + + + + + rpcs3 + + + rpcs3 + + + Gui + + + Gui + + + Emu + + + Gui + + + Gui + + + Emu + + + rpcs3 + + + Gui + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Gui + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Gui + + + Loader + + + Loader + + + Loader + + + Loader + + + Loader + + + Loader + + + Emu\Cell + + + Emu\Cell + + + Emu\SysCalls + + + Emu\SysCalls\lv2 + + + Emu\Io + + + Emu + + + Emu\GS + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS + + + Emu\SysCalls\lv2 + + + Emu\GS + + + Emu\Cell + + + Emu\SysCalls\lv2 + + + Utilities + + + Emu\SysCalls + + + Emu\SysCalls\lv2 + + + Emu\SysCalls + + + Emu\FS + + + Emu\FS + + + Emu\FS + + + Emu\FS + + + Emu\FS + + + Emu\FS + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Gui + + + rpcs3 + + + Emu\Cell + + + Emu\SysCalls\lv2 + + + Emu\SysCalls + + + Emu\SysCalls\Modules + + + Emu\Cell + + + Emu\Cell + + + Emu\HDD + + + Gui + + + Gui + + + Gui + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\Io + + + Emu\SysCalls\lv2 + + + Emu\Io + + + Emu\SysCalls\lv2 + + + Emu\FS + + + Emu\CPU + + + Emu\CPU + + + Emu\Cell + + + Emu\ARMv7 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\lv2 + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\SysCalls\Modules + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\GS\GL + + + Emu\SysCalls\Modules + + + Emu\SysCalls\lv2 + + + + + + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Include + + + Utilities + + + Utilities + + + Utilities + + + Utilities + + + Utilities + + + Include + + + Include + + + Include + + + Include + + + Include + + + Utilities + + + Include + + \ No newline at end of file From bba1b6a6e0d72d73e03a4b8f202cc430c61bb3a2 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 8 Dec 2013 00:52:41 +0200 Subject: [PATCH 11/16] SPU improvements - Implemented more SPU Channels. - Improved interpreter. Minor improvements. --- rpcs3/Emu/Cell/RawSPUThread.cpp | 55 +++------- rpcs3/Emu/Cell/SPUDisAsm.h | 2 +- rpcs3/Emu/Cell/SPUInterpreter.h | 38 ++++--- rpcs3/Emu/Cell/SPUOpcodes.h | 2 +- rpcs3/Emu/Cell/SPUThread.h | 123 ++++++++++++++-------- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 46 ++++++-- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 1 + rpcs3/Emu/SysCalls/SysCalls.h | 3 - 8 files changed, 158 insertions(+), 112 deletions(-) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 36848ab401..ee0cf6c4b3 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -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> 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) @@ -395,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; } @@ -406,28 +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_WrEventMask: //Write event mask - case SPU_WrEventAck: //Write end of event processing - case SPU_WrDec: //Write decrementer count - case SPU_WrSRR0: //Write SPU machine state save/restore register 0 (SRR0) - case MFC_WrMSSyncReq: //Write multisource synchronization request - 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_WrListStallAck: //Write DMA list stall-and-notify acknowledge - ConLog.Error("%s error: unimplemented channel (%s).", __FUNCTION__, spu_ch_name[ch]); - break; - case SPU_WrOutIntrMbox: - ConLog.Warning("SPU_WrOutIntrMbox = 0x%x", v); - while(!SPU.OutIntr_Mbox.Push(v) && !Emu.IsStopped()) { Sleep(1); @@ -435,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; } } @@ -456,29 +504,20 @@ public: switch(ch) { - case SPU_RdEventStat: //Read event status with mask applied - case SPU_RdSigNotify1: //Signal notification 1 - case SPU_RdSigNotify2: //Signal notification 2 - case SPU_RdDec: //Read decrementer count - case SPU_RdEventMask: //Read event mask - case SPU_RdMachStat: //Read SPU run status - case SPU_RdSRR0: //Read SPU machine state save/restore register 0 (SRR0) - case MFC_RdTagMask: //Read tag mask - case MFC_RdTagStat: //Read tag status with mask applied - case MFC_RdListStallStat: //Read DMA list stall-and-notify status - 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_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; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index bfef39781b..b7ac55744d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -39,9 +39,18 @@ 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(); @@ -144,6 +153,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 +163,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; @@ -308,14 +318,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); @@ -353,7 +355,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 ctxt, u32 id) +{ + cellGcmSys.Warning("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 ctxt) +{ + cellGcmSys.Warning("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); + + //GSLockCurrent lock(GS_LOCK_WAIT_FLIP); + return CELL_OK; } int cellGcmInitCursor() @@ -531,6 +549,8 @@ int cellGcmSetDebugOutputLevel (int level) default: return CELL_EINVAL; } + + return CELL_OK; } int cellGcmSetSecondVFrequency (u32 freq) @@ -547,6 +567,8 @@ int cellGcmSetSecondVFrequency (u32 freq) default: return CELL_EINVAL; } + + return CELL_OK; } void cellGcmSys_init() @@ -596,4 +618,6 @@ void cellGcmSys_init() cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); + cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); + cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index 700f51ef03..55700fd4fc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -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 { diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 8e9b151099..b779f0b68e 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -233,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(); From 76a93443c37beda725e4c0d359f9ca4b4b497ca6 Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 8 Dec 2013 02:09:16 +0200 Subject: [PATCH 12/16] Improved OpenGL renderer - Implemented color buffer reading. --- rpcs3/Emu/GS/GL/GLGSRender.cpp | 15 ++++++++++++++- rpcs3/Emu/GS/RSXThread.cpp | 12 +++++++++--- rpcs3/Emu/GS/RSXThread.h | 3 +++ rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 4 +++- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 21074093bd..229d15bb42 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1051,7 +1051,20 @@ 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)) + { + void* pixels = Memory.VirtualToRealAddr(addr); + glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + } + } + else if(m_fbo.IsCreated()) { m_fbo.Bind(GL_READ_FRAMEBUFFER); GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 51bf52c3ae..c8f4c84c19 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -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; diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 893466edc7..48bdb55bfd 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -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; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index b7ac55744d..674b7a1d12 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -55,6 +55,8 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 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); @@ -370,7 +372,7 @@ int cellGcmSetWaitFlip(mem_ptr_t ctxt) { cellGcmSys.Warning("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); - //GSLockCurrent lock(GS_LOCK_WAIT_FLIP); + GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; } From 34f5997f821896d6242abe68b1c76c4172473b9f Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 8 Dec 2013 02:42:59 +0200 Subject: [PATCH 13/16] Improved OpenGL renderer. - Rotate color buffer. --- rpcs3/Emu/GS/GL/GLGSRender.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 229d15bb42..91f5e0dad2 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1058,10 +1058,22 @@ void GLGSRender::Flip() u32 height = re(buffers[m_gcm_current_buffer].height); u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL); + glRotated(90, 1, 0, 0); + if(Memory.IsGoodAddr(addr)) { - void* pixels = Memory.VirtualToRealAddr(addr); - glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + //TODO + //buffer rotating + static Array pixels; + pixels.SetCount(width * height * 4); + u8* src = (u8*)Memory.VirtualToRealAddr(addr); + + for(u32 y=0; y Date: Sun, 8 Dec 2013 15:47:54 +0200 Subject: [PATCH 14/16] Improved PSF loader. Improved Game Viewer. Implemented cellPadGetInfo. Minor improvements. --- rpcs3/Emu/Cell/SPUInterpreter.h | 6 +- rpcs3/Emu/GS/GL/GLGSRender.cpp | 2 - rpcs3/Emu/SysCalls/Modules/sys_io.cpp | 1 + rpcs3/Emu/SysCalls/SysCalls.h | 1 + rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp | 40 +- rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp | 39 + rpcs3/Gui/GameViewer.cpp | 17 +- rpcs3/Gui/MainFrame.cpp | 1678 ++++++++++++------------- rpcs3/Loader/PSF.cpp | 230 +--- rpcs3/Loader/PSF.h | 50 +- 10 files changed, 1024 insertions(+), 1040 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 62eadeb184..e71eb5a7f0 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -1238,8 +1238,10 @@ private: } void AI(u32 rt, u32 ra, s32 i10) { - const __u32x4 imm = {i10, i10, i10, i10}; - CPU.GPR[rt]._m128i = _mm_add_epi32(CPU.GPR[ra]._m128i, imm.m128i); + CPU.GPR[rt]._i32[0] = CPU.GPR[ra]._i32[0] + i10; + CPU.GPR[rt]._i32[1] = CPU.GPR[ra]._i32[1] + i10; + CPU.GPR[rt]._i32[2] = CPU.GPR[ra]._i32[2] + i10; + CPU.GPR[rt]._i32[3] = CPU.GPR[ra]._i32[3] + i10; } void AHI(u32 rt, u32 ra, s32 i10) { diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 91f5e0dad2..0fbb8f2eeb 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1058,8 +1058,6 @@ void GLGSRender::Flip() u32 height = re(buffers[m_gcm_current_buffer].height); u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL); - glRotated(90, 1, 0, 0); - if(Memory.IsGoodAddr(addr)) { //TODO diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index db6e727c0e..9485b6f440 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -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); diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index b779f0b68e..7dfb90e6cf 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -240,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); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp index 412571f29d..be8a6ecb5d 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Memory.cpp @@ -80,7 +80,28 @@ int sys_mmapper_allocate_address(u32 size, u64 flags, u32 alignment, u32 alloc_a { sc_mem.Warning("sys_mmapper_allocate_address(size=0x%x, flags=0x%llx, alignment=0x%x, alloc_addr=0x%x)", size, flags, alignment, alloc_addr); - Memory.Write32(alloc_addr, Memory.Alloc(size, alignment)); + 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; } @@ -91,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, 4); + 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; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp index a052cd041b..54f4878e00 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp @@ -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& pads = Emu.GetPadManager().GetPads(); + + for(u32 i=0; i= pads.GetCount()) break; + + info.status[i] = re(pads[i].m_port_status); + info.product_id[i] = 0xdead; //TODO + info.vendor_id[i] = 0xbeaf; //TODO + } + + Memory.WriteData(info_addr, info); + + return CELL_OK; +} + int cellPadGetInfo2(u32 info_addr) { sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info_addr); diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 14dc7ad303..30f7371c6d 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -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 - -#include "scetool/scetool.cpp" -#include "unpkg/unpkg.c" - -BEGIN_EVENT_TABLE(MainFrame, FrameBase) - EVT_CLOSE(MainFrame::OnQuit) -END_EVENT_TABLE() - -enum IDs -{ - id_boot_elf = 0x555, - id_boot_self, - id_boot_game, - id_boot_pkg, - id_sys_pause, - id_sys_stop, - id_sys_send_open_menu, - id_sys_send_exit, - id_config_emu, - id_config_vfs_manager, - id_config_vhdd_manager, - id_tools_compiler, - id_tools_memory_viewer, - id_help_about, - id_update_dbg, -}; - -wxString GetPaneName() -{ - static int pane_num = 0; - - return wxString::Format("Pane_%d", pane_num++); -} - +#include "stdafx.h" +#include "MainFrame.h" +#include "CompilerELF.h" +#include "MemoryViewer.h" + +#include "git-version.h" +#include "Emu/System.h" +#include "Ini.h" +#include "Emu/GS/sysutil_video.h" +#include "Gui/VHDDManager.h" +#include "Gui/VFSManager.h" +#include "Gui/AboutDialog.h" +#include + +#include "scetool/scetool.cpp" +#include "unpkg/unpkg.c" + +BEGIN_EVENT_TABLE(MainFrame, FrameBase) + EVT_CLOSE(MainFrame::OnQuit) +END_EVENT_TABLE() + +enum IDs +{ + id_boot_elf = 0x555, + id_boot_self, + id_boot_game, + id_boot_pkg, + id_sys_pause, + id_sys_stop, + id_sys_send_open_menu, + id_sys_send_exit, + id_config_emu, + id_config_vfs_manager, + id_config_vhdd_manager, + id_tools_compiler, + id_tools_memory_viewer, + id_help_about, + id_update_dbg, +}; + +wxString GetPaneName() +{ + static int pane_num = 0; + + 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; @@ -84,795 +84,795 @@ bool wxMoveDir(wxString sFrom, wxString sTo) } ::wxRmdir(sFrom); return true; -} - -MainFrame::MainFrame() - : FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(800, 600)) - , m_aui_mgr(this) - , m_sys_menu_opened(false) -{ - -#ifdef _DEBUG - SetLabel(wxString::Format(_PRGNAME_ " git-" RPCS3_GIT_VERSION)); -#else - SetLabel(wxString::Format(_PRGNAME_ " " _PRGVER_)); -#endif - - wxMenuBar& menubar(*new wxMenuBar()); - - wxMenu& menu_boot(*new wxMenu()); - wxMenu& menu_sys(*new wxMenu()); - wxMenu& menu_conf(*new wxMenu()); - wxMenu& menu_tools(*new wxMenu()); - wxMenu& menu_help(*new wxMenu()); - - menubar.Append(&menu_boot, "Boot"); - menubar.Append(&menu_sys, "System"); - menubar.Append(&menu_conf, "Config"); - menubar.Append(&menu_tools, "Tools"); - menubar.Append(&menu_help, "Help"); - - menu_boot.Append(id_boot_game, "Boot game"); - menu_boot.Append(id_boot_pkg, "Install PKG"); - menu_boot.AppendSeparator(); - menu_boot.Append(id_boot_elf, "Boot ELF"); - menu_boot.Append(id_boot_self, "Boot SELF"); - - menu_sys.Append(id_sys_pause, "Pause")->Enable(false); - menu_sys.Append(id_sys_stop, "Stop\tCtrl + S")->Enable(false); - menu_sys.AppendSeparator(); - menu_sys.Append(id_sys_send_open_menu, "Send open system menu cmd")->Enable(false); - menu_sys.Append(id_sys_send_exit, "Send exit cmd")->Enable(false); - - menu_conf.Append(id_config_emu, "Settings"); - menu_conf.AppendSeparator(); - menu_conf.Append(id_config_vfs_manager, "Virtual File System Manager"); - menu_conf.Append(id_config_vhdd_manager, "Virtual HDD Manager"); - - menu_tools.Append(id_tools_compiler, "ELF Compiler"); - menu_tools.Append(id_tools_memory_viewer, "Memory Viewer"); - - menu_help.Append(id_help_about, "About..."); - - SetMenuBar(&menubar); - - m_game_viewer = new GameViewer(this); - AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM); - - Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) ); - Connect( id_boot_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootPkg) ); - Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) ); - Connect( id_boot_self, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootSelf) ); - - Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) ); - Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) ); - Connect( id_sys_send_open_menu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendOpenCloseSysMenu) ); - Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) ); - - Connect( id_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) ); - Connect( id_config_vfs_manager, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVFS) ); - Connect( id_config_vhdd_manager,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVHDD) ); - - Connect( id_tools_compiler, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenELFCompiler)); - Connect( id_tools_memory_viewer,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenMemoryViewer)); - - Connect( id_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::AboutDialogHandler) ); - - Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) ); - - m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)0, this); - m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(MainFrame::UpdateUI), (wxObject*)0, this); -} - -MainFrame::~MainFrame() -{ - m_aui_mgr.UnInit(); -} - -void MainFrame::AddPane(wxWindow* wind, const wxString& caption, int flags) -{ - wind->SetSize(-1, 300); - m_aui_mgr.AddPane(wind, wxAuiPaneInfo().Name(GetPaneName()).Caption(caption).Direction(flags).CloseButton(false).MaximizeButton()); -} - -void MainFrame::DoSettings(bool load) -{ - IniEntry ini; - ini.Init("Settings", "MainFrameAui"); - - if(load) - { - m_aui_mgr.LoadPerspective(ini.LoadValue(m_aui_mgr.SavePerspective())); - } - else - { - ini.SaveValue(m_aui_mgr.SavePerspective()); - } -} - -void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event)) -{ - bool stopped = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - stopped = true; - } - - wxDirDialog ctrl(this, L"Select game folder", wxEmptyString); - - if(ctrl.ShowModal() == wxID_CANCEL) - { - if(stopped) Emu.Resume(); - return; - } - - Emu.Stop(); - - 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(ctrl.GetPath() + elf[i], wxFile::read)) - { - ConLog.Write("SELF: booting..."); - - Emu.Stop(); - - wxString fileIn = ctrl.GetPath()+elf[i]; - wxString fileOut = (ctrl.GetPath()+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 key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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(); - - Emu.SetPath(fileOut); - Emu.Load(); - if (!wxRemoveFile(fileOut)) - ConLog.Warning("Could not delete the decrypted ELF file"); - - ConLog.Write("Game: boot done."); - return; - } - } - - ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().mb_str()); - return; -} - - -void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) -{ - bool stopped = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - stopped = true; - } - - wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "*.*", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); - - if(ctrl.ShowModal() == wxID_CANCEL) - { - if(stopped) Emu.Resume(); - return; - } - - ConLog.Write("PKG: extracting..."); - - Emu.Stop(); - - wxString fileName = ctrl.GetPath(); - pkg_unpack((const char *)fileName.mb_str()); - - 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 key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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)) -{ - bool stopped = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - stopped = true; - } - - wxFileDialog ctrl(this, L"Select ELF", wxEmptyString, wxEmptyString, "*.*", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); - - if(ctrl.ShowModal() == wxID_CANCEL) - { - if(stopped) Emu.Resume(); - return; - } - - ConLog.Write("ELF: booting..."); - - Emu.Stop(); - - Emu.SetPath(ctrl.GetPath()); - Emu.Load(); - - ConLog.Write("ELF: boot done."); -} - -void MainFrame::BootSelf(wxCommandEvent& WXUNUSED(event)) -{ - bool stopped = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - stopped = true; - } - - wxFileDialog ctrl(this, L"Select SELF", wxEmptyString, wxEmptyString, "*.*", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); - - if(ctrl.ShowModal() == wxID_CANCEL) - { - if(stopped) Emu.Resume(); - return; - } - - ConLog.Write("SELF: booting..."); - - Emu.Stop(); - - wxString fileIn = ctrl.GetPath(); - wxString fileOut = ctrl.GetPath()+".elf"; - - // Check if the data really needs to be decrypted. - if(!wxFileExists(fileIn)) - { - ConLog.Error("Could not open SELF file!"); - return; - } - - wxFile f(fileIn); - // Get the key version. - f.Seek(0x08); - be_t key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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("SELF: Could not decrypt file"); - return; - } - } - - f.Close(); - - Emu.SetPath(fileOut); - Emu.Load(); - if (!wxRemoveFile(fileOut)) - ConLog.Warning("Could not delete the decrypted ELF file"); - - ConLog.Write("SELF: boot done."); -} - -void MainFrame::Pause(wxCommandEvent& WXUNUSED(event)) -{ - if(Emu.IsReady()) - { - Emu.Run(); - } - else if(Emu.IsPaused()) - { - Emu.Resume(); - } - else if(Emu.IsRunning()) - { - Emu.Pause(); - } -} - -void MainFrame::Stop(wxCommandEvent& WXUNUSED(event)) -{ - Emu.Stop(); -} - -void MainFrame::SendExit(wxCommandEvent& event) -{ - Emu.GetCallbackManager().m_exit_callback.Handle(0x0101, 0); -} - -void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event) -{ - Emu.GetCallbackManager().m_exit_callback.Handle(m_sys_menu_opened ? 0x0132 : 0x0131, 0); - m_sys_menu_opened = !m_sys_menu_opened; - wxCommandEvent ce; - UpdateUI(ce); -} - -void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) -{ - //TODO - - bool paused = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - paused = true; - } - - wxDialog diag(this, wxID_ANY, "Settings", wxDefaultPosition); - - wxBoxSizer* s_panel(new wxBoxSizer(wxHORIZONTAL)); - wxBoxSizer* s_subpanel1(new wxBoxSizer(wxVERTICAL)); - wxBoxSizer* s_subpanel2(new wxBoxSizer(wxVERTICAL)); - - wxStaticBoxSizer* s_round_cpu( new wxStaticBoxSizer( wxVERTICAL, &diag, _("CPU") ) ); - wxStaticBoxSizer* s_round_cpu_decoder( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Decoder") ) ); - - wxStaticBoxSizer* s_round_gs( new wxStaticBoxSizer( wxVERTICAL, &diag, _("GS") ) ); - wxStaticBoxSizer* s_round_gs_render( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Render") ) ); - wxStaticBoxSizer* s_round_gs_res( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Default resolution") ) ); - wxStaticBoxSizer* s_round_gs_aspect( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Default aspect ratio") ) ); - - wxStaticBoxSizer* s_round_io( new wxStaticBoxSizer( wxVERTICAL, &diag, _("IO") ) ); - wxStaticBoxSizer* s_round_pad_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Pad Handler") ) ); - wxStaticBoxSizer* s_round_keyboard_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Keyboard Handler") ) ); - wxStaticBoxSizer* s_round_mouse_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Mouse Handler") ) ); - - wxComboBox* cbox_cpu_decoder = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_gs_render = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_gs_resolution = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_gs_aspect = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_pad_handler = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_keyboard_handler = new wxComboBox(&diag, wxID_ANY); - wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY); - - wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors"); - wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Dump Depth Buffer"); - wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Dump Color Buffers"); - wxCheckBox* chbox_gs_vsync = new wxCheckBox(&diag, wxID_ANY, "VSync"); - - //cbox_cpu_decoder->Append("DisAsm"); - cbox_cpu_decoder->Append("Interpreter & DisAsm"); - cbox_cpu_decoder->Append("Interpreter"); - - for(int i=1; iAppend(wxString::Format("%dx%d", ResolutionTable[i].width, ResolutionTable[i].height)); - } - - cbox_gs_aspect->Append("4:3"); - cbox_gs_aspect->Append("16:9"); - - cbox_gs_render->Append("Null"); - cbox_gs_render->Append("OpenGL"); - //cbox_gs_render->Append("Software"); - - cbox_pad_handler->Append("Null"); - cbox_pad_handler->Append("Windows"); - //cbox_pad_handler->Append("DirectInput"); - - cbox_keyboard_handler->Append("Null"); - cbox_keyboard_handler->Append("Windows"); - //cbox_keyboard_handler->Append("DirectInput"); - - cbox_mouse_handler->Append("Null"); - cbox_mouse_handler->Append("Windows"); - //cbox_mouse_handler->Append("DirectInput"); - - chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue()); - chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue()); - chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue()); - chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); - - cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0); - cbox_gs_render->SetSelection(Ini.GSRenderMode.GetValue()); - cbox_gs_resolution->SetSelection(ResolutionIdToNum(Ini.GSResolution.GetValue()) - 1); - cbox_gs_aspect->SetSelection(Ini.GSAspectRatio.GetValue() - 1); - cbox_pad_handler->SetSelection(Ini.PadHandlerMode.GetValue()); - cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue()); - cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue()); - - s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_cpu->Add(chbox_cpu_ignore_rwerrors, wxSizerFlags().Border(wxALL, 5).Expand()); - - s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs_aspect->Add(cbox_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_gs->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5)); - s_round_gs->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5)); - s_round_gs->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5)); - - s_round_pad_handler->Add(cbox_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_keyboard_handler->Add(cbox_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_mouse_handler->Add(cbox_mouse_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_io->Add(s_round_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_io->Add(s_round_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - s_round_io->Add(s_round_mouse_handler, wxSizerFlags().Border(wxALL, 5).Expand()); - - wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); - - s_b_panel->Add(new wxButton(&diag, wxID_OK), wxSizerFlags().Border(wxALL, 5).Center()); - s_b_panel->Add(new wxButton(&diag, wxID_CANCEL), wxSizerFlags().Border(wxALL, 5).Center()); - - //wxBoxSizer* s_conf_panel(new wxBoxSizer(wxHORIZONTAL)); - - s_subpanel1->Add(s_round_cpu, wxSizerFlags().Border(wxALL, 5).Expand()); - s_subpanel1->Add(s_round_gs, wxSizerFlags().Border(wxALL, 5).Expand()); - s_subpanel2->Add(s_round_io, wxSizerFlags().Border(wxALL, 5).Expand()); - s_subpanel1->Add(s_b_panel, wxSizerFlags().Border(wxALL, 8).Expand()); - - s_subpanel2->AddSpacer(180); - s_panel->Add(s_subpanel1, wxSizerFlags().Border(wxALL, 5).Expand()); - s_panel->Add(s_subpanel2, wxSizerFlags().Border(wxALL, 5).Expand()); - - diag.SetSizerAndFit( s_panel ); - - if(diag.ShowModal() == wxID_OK) - { - Ini.CPUDecoderMode.SetValue(cbox_cpu_decoder->GetSelection() + 1); - Ini.CPUIgnoreRWErrors.SetValue(chbox_cpu_ignore_rwerrors->GetValue()); - Ini.GSRenderMode.SetValue(cbox_gs_render->GetSelection()); - Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1)); - Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1); - Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue()); - Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue()); - Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue()); - Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection()); - Ini.KeyboardHandlerMode.SetValue(cbox_keyboard_handler->GetSelection()); - Ini.MouseHandlerMode.SetValue(cbox_mouse_handler->GetSelection()); - - Ini.Save(); - } - - if(paused) Emu.Resume(); -} - -void MainFrame::ConfigVFS(wxCommandEvent& WXUNUSED(event)) -{ - VFSManagerDialog(this).ShowModal(); -} - -void MainFrame::ConfigVHDD(wxCommandEvent& WXUNUSED(event)) -{ - VHDDManagerDialog(this).ShowModal(); -} - -void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event)) -{ - (new CompilerELF(this)) -> Show(); -} - -void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event)) -{ - (new MemoryViewerPanel(this)) -> Show(); -} - -void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event)) -{ - AboutDialog(this).ShowModal(); -} - -void MainFrame::UpdateUI(wxCommandEvent& event) -{ - event.Skip(); - - bool is_running, is_stopped, is_ready; - - if(event.GetEventType() == wxEVT_DBG_COMMAND) - { - switch(event.GetId()) - { - case DID_START_EMU: - case DID_STARTED_EMU: - is_running = true; - is_stopped = false; - is_ready = false; - break; - - case DID_STOP_EMU: - case DID_STOPPED_EMU: - is_running = false; - is_stopped = true; - is_ready = false; - m_sys_menu_opened = false; - break; - - case DID_PAUSE_EMU: - case DID_PAUSED_EMU: - is_running = false; - is_stopped = false; - is_ready = false; - break; - - case DID_RESUME_EMU: - case DID_RESUMED_EMU: - is_running = true; - is_stopped = false; - is_ready = false; - break; - - case DID_READY_EMU: - is_running = false; - is_stopped = false; - is_ready = true; - break; - - case DID_REGISTRED_CALLBACK: - is_running = Emu.IsRunning(); - is_stopped = Emu.IsStopped(); - is_ready = Emu.IsReady(); - break; - - default: - return; - } - } - else - { - is_running = Emu.IsRunning(); - is_stopped = Emu.IsStopped(); - is_ready = Emu.IsReady(); - } - - wxMenuBar& menubar( *GetMenuBar() ); - wxMenuItem& pause = *menubar.FindItem( id_sys_pause ); - wxMenuItem& stop = *menubar.FindItem( id_sys_stop ); - wxMenuItem& send_exit = *menubar.FindItem( id_sys_send_exit ); - wxMenuItem& send_open_menu = *menubar.FindItem( id_sys_send_open_menu ); - pause.SetText(is_running ? "Pause\tCtrl + P" : is_ready ? "Start\tCtrl + C" : "Resume\tCtrl + C"); - pause.Enable(!is_stopped); - stop.Enable(!is_stopped); - //send_exit.Enable(false); - bool enable_commands = !is_stopped && Emu.GetCallbackManager().m_exit_callback.m_callbacks.GetCount(); - - send_open_menu.SetText(wxString::Format("Send %s system menu cmd", m_sys_menu_opened ? "close" : "open")); - send_open_menu.Enable(enable_commands); - send_exit.Enable(enable_commands); - - //m_aui_mgr.Update(); - - //wxCommandEvent refit( wxEVT_COMMAND_MENU_SELECTED, id_update_dbg ); - //GetEventHandler()->AddPendingEvent( refit ); -} - -void MainFrame::OnQuit(wxCloseEvent& event) -{ - DoSettings(false); - TheApp->Exit(); -} - -struct state_hdr -{ - u32 magic; - u16 version; - u32 mem_count; - u32 mem_offset; - u32 mem_size; - u32 hle_count; - u32 hle_offset; -}; - -static const u32 state_magic = *(u32*)"R3SS"; -static const u32 state_version = 0x1000; - -void MakeSaveState(wxFile& f) -{ - const ArrayF& mb = Memory.MemoryBlocks; - - state_hdr state; - memset(&state, 0, sizeof(state_hdr)); - - state.magic = state_magic; - state.version = state_version; - state.mem_count = mb.GetCount(); - //state.hle_count = mb.GetCount(); - - state.mem_offset = sizeof(state_hdr) + 4; - - f.Seek(state.mem_offset); - for(u32 i=0; iEnable(false); + menu_sys.Append(id_sys_stop, "Stop\tCtrl + S")->Enable(false); + menu_sys.AppendSeparator(); + menu_sys.Append(id_sys_send_open_menu, "Send open system menu cmd")->Enable(false); + menu_sys.Append(id_sys_send_exit, "Send exit cmd")->Enable(false); + + menu_conf.Append(id_config_emu, "Settings"); + menu_conf.AppendSeparator(); + menu_conf.Append(id_config_vfs_manager, "Virtual File System Manager"); + menu_conf.Append(id_config_vhdd_manager, "Virtual HDD Manager"); + + menu_tools.Append(id_tools_compiler, "ELF Compiler"); + menu_tools.Append(id_tools_memory_viewer, "Memory Viewer"); + + menu_help.Append(id_help_about, "About..."); + + SetMenuBar(&menubar); + + m_game_viewer = new GameViewer(this); + AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM); + + Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) ); + Connect( id_boot_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootPkg) ); + Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) ); + Connect( id_boot_self, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootSelf) ); + + Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) ); + Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) ); + Connect( id_sys_send_open_menu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendOpenCloseSysMenu) ); + Connect( id_sys_send_exit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::SendExit) ); + + Connect( id_config_emu, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Config) ); + Connect( id_config_vfs_manager, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVFS) ); + Connect( id_config_vhdd_manager,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::ConfigVHDD) ); + + Connect( id_tools_compiler, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenELFCompiler)); + Connect( id_tools_memory_viewer,wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OpenMemoryViewer)); + + Connect( id_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::AboutDialogHandler) ); + + Connect( id_update_dbg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::UpdateUI) ); + + m_app_connector.Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MainFrame::OnKeyDown), (wxObject*)0, this); + m_app_connector.Connect(wxEVT_DBG_COMMAND, wxCommandEventHandler(MainFrame::UpdateUI), (wxObject*)0, this); +} + +MainFrame::~MainFrame() +{ + m_aui_mgr.UnInit(); +} + +void MainFrame::AddPane(wxWindow* wind, const wxString& caption, int flags) +{ + wind->SetSize(-1, 300); + m_aui_mgr.AddPane(wind, wxAuiPaneInfo().Name(GetPaneName()).Caption(caption).Direction(flags).CloseButton(false).MaximizeButton()); +} + +void MainFrame::DoSettings(bool load) +{ + IniEntry ini; + ini.Init("Settings", "MainFrameAui"); + + if(load) + { + m_aui_mgr.LoadPerspective(ini.LoadValue(m_aui_mgr.SavePerspective())); + } + else + { + ini.SaveValue(m_aui_mgr.SavePerspective()); + } +} + +void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event)) +{ + bool stopped = false; + + if(Emu.IsRunning()) + { + Emu.Pause(); + stopped = true; + } + + wxDirDialog ctrl(this, L"Select game folder", wxEmptyString); + + if(ctrl.ShowModal() == wxID_CANCEL) + { + if(stopped) Emu.Resume(); + return; + } + + Emu.Stop(); + + 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(ctrl.GetPath() + elf[i], wxFile::read)) + { + ConLog.Write("SELF: booting..."); + + Emu.Stop(); + + wxString fileIn = ctrl.GetPath()+elf[i]; + wxString fileOut = (ctrl.GetPath()+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 key_version; + f.Read(&key_version, sizeof(key_version)); + + if(key_version.ToBE() == const_se_t::value) + { + ConLog.Warning("Debug SELF detected! Removing fake header..."); + + // Get the real elf offset. + f.Seek(0x10); + be_t 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(); + + Emu.SetPath(fileOut); + Emu.Load(); + if (!wxRemoveFile(fileOut)) + ConLog.Warning("Could not delete the decrypted ELF file"); + + ConLog.Write("Game: boot done."); + return; + } + } + + ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().mb_str()); + return; +} + + +void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) +{ + bool stopped = false; + + if(Emu.IsRunning()) + { + Emu.Pause(); + stopped = true; + } + + wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "*.*", + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + + if(ctrl.ShowModal() == wxID_CANCEL) + { + if(stopped) Emu.Resume(); + return; + } + + ConLog.Write("PKG: extracting..."); + + Emu.Stop(); + + wxString fileName = ctrl.GetPath(); + pkg_unpack((const char *)fileName.mb_str()); + + 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 key_version; + f.Read(&key_version, sizeof(key_version)); + + if(key_version.ToBE() == const_se_t::value) + { + ConLog.Warning("Debug SELF detected! Removing fake header..."); + + // Get the real elf offset. + f.Seek(0x10); + be_t 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)) +{ + bool stopped = false; + + if(Emu.IsRunning()) + { + Emu.Pause(); + stopped = true; + } + + wxFileDialog ctrl(this, L"Select ELF", wxEmptyString, wxEmptyString, "*.*", + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + + if(ctrl.ShowModal() == wxID_CANCEL) + { + if(stopped) Emu.Resume(); + return; + } + + ConLog.Write("ELF: booting..."); + + Emu.Stop(); + + Emu.SetPath(ctrl.GetPath()); + Emu.Load(); + + ConLog.Write("ELF: boot done."); +} + +void MainFrame::BootSelf(wxCommandEvent& WXUNUSED(event)) +{ + bool stopped = false; + + if(Emu.IsRunning()) + { + Emu.Pause(); + stopped = true; + } + + wxFileDialog ctrl(this, L"Select SELF", wxEmptyString, wxEmptyString, "*.*", + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + + if(ctrl.ShowModal() == wxID_CANCEL) + { + if(stopped) Emu.Resume(); + return; + } + + ConLog.Write("SELF: booting..."); + + Emu.Stop(); + + wxString fileIn = ctrl.GetPath(); + wxString fileOut = ctrl.GetPath()+".elf"; + + // Check if the data really needs to be decrypted. + if(!wxFileExists(fileIn)) + { + ConLog.Error("Could not open SELF file!"); + return; + } + + wxFile f(fileIn); + // Get the key version. + f.Seek(0x08); + be_t key_version; + f.Read(&key_version, sizeof(key_version)); + + if(key_version.ToBE() == const_se_t::value) + { + ConLog.Warning("Debug SELF detected! Removing fake header..."); + + // Get the real elf offset. + f.Seek(0x10); + be_t 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("SELF: Could not decrypt file"); + return; + } + } + + f.Close(); + + Emu.SetPath(fileOut); + Emu.Load(); + //if (!wxRemoveFile(fileOut)) + // ConLog.Warning("Could not delete the decrypted ELF file"); + + ConLog.Write("SELF: boot done."); +} + +void MainFrame::Pause(wxCommandEvent& WXUNUSED(event)) +{ + if(Emu.IsReady()) + { + Emu.Run(); + } + else if(Emu.IsPaused()) + { + Emu.Resume(); + } + else if(Emu.IsRunning()) + { + Emu.Pause(); + } +} + +void MainFrame::Stop(wxCommandEvent& WXUNUSED(event)) +{ + Emu.Stop(); +} + +void MainFrame::SendExit(wxCommandEvent& event) +{ + Emu.GetCallbackManager().m_exit_callback.Handle(0x0101, 0); +} + +void MainFrame::SendOpenCloseSysMenu(wxCommandEvent& event) +{ + Emu.GetCallbackManager().m_exit_callback.Handle(m_sys_menu_opened ? 0x0132 : 0x0131, 0); + m_sys_menu_opened = !m_sys_menu_opened; + wxCommandEvent ce; + UpdateUI(ce); +} + +void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) +{ + //TODO + + bool paused = false; + + if(Emu.IsRunning()) + { + Emu.Pause(); + paused = true; + } + + wxDialog diag(this, wxID_ANY, "Settings", wxDefaultPosition); + + wxBoxSizer* s_panel(new wxBoxSizer(wxHORIZONTAL)); + wxBoxSizer* s_subpanel1(new wxBoxSizer(wxVERTICAL)); + wxBoxSizer* s_subpanel2(new wxBoxSizer(wxVERTICAL)); + + wxStaticBoxSizer* s_round_cpu( new wxStaticBoxSizer( wxVERTICAL, &diag, _("CPU") ) ); + wxStaticBoxSizer* s_round_cpu_decoder( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Decoder") ) ); + + wxStaticBoxSizer* s_round_gs( new wxStaticBoxSizer( wxVERTICAL, &diag, _("GS") ) ); + wxStaticBoxSizer* s_round_gs_render( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Render") ) ); + wxStaticBoxSizer* s_round_gs_res( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Default resolution") ) ); + wxStaticBoxSizer* s_round_gs_aspect( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Default aspect ratio") ) ); + + wxStaticBoxSizer* s_round_io( new wxStaticBoxSizer( wxVERTICAL, &diag, _("IO") ) ); + wxStaticBoxSizer* s_round_pad_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Pad Handler") ) ); + wxStaticBoxSizer* s_round_keyboard_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Keyboard Handler") ) ); + wxStaticBoxSizer* s_round_mouse_handler( new wxStaticBoxSizer( wxVERTICAL, &diag, _("Mouse Handler") ) ); + + wxComboBox* cbox_cpu_decoder = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_gs_render = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_gs_resolution = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_gs_aspect = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_pad_handler = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_keyboard_handler = new wxComboBox(&diag, wxID_ANY); + wxComboBox* cbox_mouse_handler = new wxComboBox(&diag, wxID_ANY); + + wxCheckBox* chbox_cpu_ignore_rwerrors = new wxCheckBox(&diag, wxID_ANY, "Ignore Read/Write errors"); + wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(&diag, wxID_ANY, "Dump Depth Buffer"); + wxCheckBox* chbox_gs_dump_color = new wxCheckBox(&diag, wxID_ANY, "Dump Color Buffers"); + wxCheckBox* chbox_gs_vsync = new wxCheckBox(&diag, wxID_ANY, "VSync"); + + //cbox_cpu_decoder->Append("DisAsm"); + cbox_cpu_decoder->Append("Interpreter & DisAsm"); + cbox_cpu_decoder->Append("Interpreter"); + + for(int i=1; iAppend(wxString::Format("%dx%d", ResolutionTable[i].width, ResolutionTable[i].height)); + } + + cbox_gs_aspect->Append("4:3"); + cbox_gs_aspect->Append("16:9"); + + cbox_gs_render->Append("Null"); + cbox_gs_render->Append("OpenGL"); + //cbox_gs_render->Append("Software"); + + cbox_pad_handler->Append("Null"); + cbox_pad_handler->Append("Windows"); + //cbox_pad_handler->Append("DirectInput"); + + cbox_keyboard_handler->Append("Null"); + cbox_keyboard_handler->Append("Windows"); + //cbox_keyboard_handler->Append("DirectInput"); + + cbox_mouse_handler->Append("Null"); + cbox_mouse_handler->Append("Windows"); + //cbox_mouse_handler->Append("DirectInput"); + + chbox_cpu_ignore_rwerrors->SetValue(Ini.CPUIgnoreRWErrors.GetValue()); + chbox_gs_dump_depth->SetValue(Ini.GSDumpDepthBuffer.GetValue()); + chbox_gs_dump_color->SetValue(Ini.GSDumpColorBuffers.GetValue()); + chbox_gs_vsync->SetValue(Ini.GSVSyncEnable.GetValue()); + + cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0); + cbox_gs_render->SetSelection(Ini.GSRenderMode.GetValue()); + cbox_gs_resolution->SetSelection(ResolutionIdToNum(Ini.GSResolution.GetValue()) - 1); + cbox_gs_aspect->SetSelection(Ini.GSAspectRatio.GetValue() - 1); + cbox_pad_handler->SetSelection(Ini.PadHandlerMode.GetValue()); + cbox_keyboard_handler->SetSelection(Ini.KeyboardHandlerMode.GetValue()); + cbox_mouse_handler->SetSelection(Ini.MouseHandlerMode.GetValue()); + + s_round_cpu_decoder->Add(cbox_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_cpu->Add(s_round_cpu_decoder, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_cpu->Add(chbox_cpu_ignore_rwerrors, wxSizerFlags().Border(wxALL, 5).Expand()); + + s_round_gs_render->Add(cbox_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs_res->Add(cbox_gs_resolution, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs_aspect->Add(cbox_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs->Add(s_round_gs_render, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs->Add(s_round_gs_res, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs->Add(s_round_gs_aspect, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_gs->Add(chbox_gs_dump_depth, wxSizerFlags().Border(wxALL, 5)); + s_round_gs->Add(chbox_gs_dump_color, wxSizerFlags().Border(wxALL, 5)); + s_round_gs->Add(chbox_gs_vsync, wxSizerFlags().Border(wxALL, 5)); + + s_round_pad_handler->Add(cbox_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_keyboard_handler->Add(cbox_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_mouse_handler->Add(cbox_mouse_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_io->Add(s_round_pad_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_io->Add(s_round_keyboard_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + s_round_io->Add(s_round_mouse_handler, wxSizerFlags().Border(wxALL, 5).Expand()); + + wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); + + s_b_panel->Add(new wxButton(&diag, wxID_OK), wxSizerFlags().Border(wxALL, 5).Center()); + s_b_panel->Add(new wxButton(&diag, wxID_CANCEL), wxSizerFlags().Border(wxALL, 5).Center()); + + //wxBoxSizer* s_conf_panel(new wxBoxSizer(wxHORIZONTAL)); + + s_subpanel1->Add(s_round_cpu, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel1->Add(s_round_gs, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel2->Add(s_round_io, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel1->Add(s_b_panel, wxSizerFlags().Border(wxALL, 8).Expand()); + + s_subpanel2->AddSpacer(180); + s_panel->Add(s_subpanel1, wxSizerFlags().Border(wxALL, 5).Expand()); + s_panel->Add(s_subpanel2, wxSizerFlags().Border(wxALL, 5).Expand()); + + diag.SetSizerAndFit( s_panel ); + + if(diag.ShowModal() == wxID_OK) + { + Ini.CPUDecoderMode.SetValue(cbox_cpu_decoder->GetSelection() + 1); + Ini.CPUIgnoreRWErrors.SetValue(chbox_cpu_ignore_rwerrors->GetValue()); + Ini.GSRenderMode.SetValue(cbox_gs_render->GetSelection()); + Ini.GSResolution.SetValue(ResolutionNumToId(cbox_gs_resolution->GetSelection() + 1)); + Ini.GSAspectRatio.SetValue(cbox_gs_aspect->GetSelection() + 1); + Ini.GSVSyncEnable.SetValue(chbox_gs_vsync->GetValue()); + Ini.GSDumpDepthBuffer.SetValue(chbox_gs_dump_depth->GetValue()); + Ini.GSDumpColorBuffers.SetValue(chbox_gs_dump_color->GetValue()); + Ini.PadHandlerMode.SetValue(cbox_pad_handler->GetSelection()); + Ini.KeyboardHandlerMode.SetValue(cbox_keyboard_handler->GetSelection()); + Ini.MouseHandlerMode.SetValue(cbox_mouse_handler->GetSelection()); + + Ini.Save(); + } + + if(paused) Emu.Resume(); +} + +void MainFrame::ConfigVFS(wxCommandEvent& WXUNUSED(event)) +{ + VFSManagerDialog(this).ShowModal(); +} + +void MainFrame::ConfigVHDD(wxCommandEvent& WXUNUSED(event)) +{ + VHDDManagerDialog(this).ShowModal(); +} + +void MainFrame::OpenELFCompiler(wxCommandEvent& WXUNUSED(event)) +{ + (new CompilerELF(this)) -> Show(); +} + +void MainFrame::OpenMemoryViewer(wxCommandEvent& WXUNUSED(event)) +{ + (new MemoryViewerPanel(this)) -> Show(); +} + +void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event)) +{ + AboutDialog(this).ShowModal(); +} + +void MainFrame::UpdateUI(wxCommandEvent& event) +{ + event.Skip(); + + bool is_running, is_stopped, is_ready; + + if(event.GetEventType() == wxEVT_DBG_COMMAND) + { + switch(event.GetId()) + { + case DID_START_EMU: + case DID_STARTED_EMU: + is_running = true; + is_stopped = false; + is_ready = false; + break; + + case DID_STOP_EMU: + case DID_STOPPED_EMU: + is_running = false; + is_stopped = true; + is_ready = false; + m_sys_menu_opened = false; + break; + + case DID_PAUSE_EMU: + case DID_PAUSED_EMU: + is_running = false; + is_stopped = false; + is_ready = false; + break; + + case DID_RESUME_EMU: + case DID_RESUMED_EMU: + is_running = true; + is_stopped = false; + is_ready = false; + break; + + case DID_READY_EMU: + is_running = false; + is_stopped = false; + is_ready = true; + break; + + case DID_REGISTRED_CALLBACK: + is_running = Emu.IsRunning(); + is_stopped = Emu.IsStopped(); + is_ready = Emu.IsReady(); + break; + + default: + return; + } + } + else + { + is_running = Emu.IsRunning(); + is_stopped = Emu.IsStopped(); + is_ready = Emu.IsReady(); + } + + wxMenuBar& menubar( *GetMenuBar() ); + wxMenuItem& pause = *menubar.FindItem( id_sys_pause ); + wxMenuItem& stop = *menubar.FindItem( id_sys_stop ); + wxMenuItem& send_exit = *menubar.FindItem( id_sys_send_exit ); + wxMenuItem& send_open_menu = *menubar.FindItem( id_sys_send_open_menu ); + pause.SetText(is_running ? "Pause\tCtrl + P" : is_ready ? "Start\tCtrl + C" : "Resume\tCtrl + C"); + pause.Enable(!is_stopped); + stop.Enable(!is_stopped); + //send_exit.Enable(false); + bool enable_commands = !is_stopped && Emu.GetCallbackManager().m_exit_callback.m_callbacks.GetCount(); + + send_open_menu.SetText(wxString::Format("Send %s system menu cmd", m_sys_menu_opened ? "close" : "open")); + send_open_menu.Enable(enable_commands); + send_exit.Enable(enable_commands); + + //m_aui_mgr.Update(); + + //wxCommandEvent refit( wxEVT_COMMAND_MENU_SELECTED, id_update_dbg ); + //GetEventHandler()->AddPendingEvent( refit ); +} + +void MainFrame::OnQuit(wxCloseEvent& event) +{ + DoSettings(false); + TheApp->Exit(); +} + +struct state_hdr +{ + u32 magic; + u16 version; + u32 mem_count; + u32 mem_offset; + u32 mem_size; + u32 hle_count; + u32 hle_offset; +}; + +static const u32 state_magic = *(u32*)"R3SS"; +static const u32 state_version = 0x1000; + +void MakeSaveState(wxFile& f) +{ + const ArrayF& mb = Memory.MemoryBlocks; + + state_hdr state; + memset(&state, 0, sizeof(state_hdr)); + + state.magic = state_magic; + state.version = state_version; + state.mem_count = mb.GetCount(); + //state.hle_count = mb.GetCount(); + + state.mem_offset = sizeof(state_hdr) + 4; + + f.Seek(state.mem_offset); + for(u32 i=0; i= 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; iFormat(); + 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) { diff --git a/rpcs3/Loader/PSF.h b/rpcs3/Loader/PSF.h index c665734408..1deb1e639a 100644 --- a/rpcs3/Loader/PSF.h +++ b/rpcs3/Loader/PSF.h @@ -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 m_entries; + + PsfEntry* SearchEntry(const std::string& key); + + //wxArrayString m_table; GameInfo m_info; PsfHeader psfhdr; + Array m_psfindxs; virtual bool Load(bool show = true); virtual bool Close(); private: bool LoadHdr(); bool LoadKeyTable(); - bool LoadValuesTable(); + bool LoadDataTable(); }; \ No newline at end of file From 23539f13b5d761054acf708a1a03e167afd5787b Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 8 Dec 2013 18:54:45 +0200 Subject: [PATCH 15/16] Improved Boot UI. Added dev_usb000. Fixed Game Viewer. Minor fixes. --- bin/dev_usb000/.gitignore | 4 + rpcs3/Emu/FS/VFS.cpp | 17 +- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 4 +- rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp | 4 +- rpcs3/Emu/System.cpp | 126 ++++++++- rpcs3/Emu/System.h | 4 + rpcs3/Gui/GameViewer.cpp | 9 +- rpcs3/Gui/MainFrame.cpp | 328 ++++------------------ rpcs3/Gui/MainFrame.h | 3 +- rpcs3/rpcs3.vcxproj | 6 + rpcs3/rpcs3.vcxproj.filters | 6 + scetool/elf_inlines.h | 1 + scetool/scetool.cpp | 2 + scetool/scetool.h | 5 + 14 files changed, 222 insertions(+), 297 deletions(-) create mode 100644 bin/dev_usb000/.gitignore create mode 100644 scetool/scetool.h diff --git a/bin/dev_usb000/.gitignore b/bin/dev_usb000/.gitignore new file mode 100644 index 0000000000..86d0cb2726 --- /dev/null +++ b/bin/dev_usb000/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 24141c5ff4..148a6b15eb 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -175,17 +175,16 @@ void VFS::SaveLoadDevices(Array& 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& 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; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 674b7a1d12..0eef3bd6c8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -362,7 +362,7 @@ int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 lab int cellGcmSetFlip(mem_ptr_t ctxt, u32 id) { - cellGcmSys.Warning("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.GetAddr(), 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; @@ -370,7 +370,7 @@ int cellGcmSetFlip(mem_ptr_t ctxt, u32 id) int cellGcmSetWaitFlip(mem_ptr_t ctxt) { - cellGcmSys.Warning("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); + cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.GetAddr()); GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp index 54f4878e00..7ff708405c 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp @@ -172,8 +172,8 @@ int cellPadGetInfo(u32 info_addr) if(i >= pads.GetCount()) break; info.status[i] = re(pads[i].m_port_status); - info.product_id[i] = 0xdead; //TODO - info.vendor_id[i] = 0xbeaf; //TODO + info.product_id[i] = const_se_t::value; + info.vendor_id[i] = const_se_t::value; } Memory.WriteData(info_addr, info); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index d3b82b1fc5..f3903bcbea 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -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 #include 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) { } @@ -85,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 key_version; + f.Read(&key_version, sizeof(key_version)); + + if(key_version.ToBE() == const_se_t::value) + { + ConLog.Warning("Debug SELF detected! Removing fake header..."); + + // Get the real elf offset. + f.Seek(0x10); + be_t 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 -#include "scetool/scetool.cpp" #include "unpkg/unpkg.c" BEGIN_EVENT_TABLE(MainFrame, FrameBase) @@ -22,9 +21,8 @@ END_EVENT_TABLE() enum IDs { id_boot_elf = 0x555, - id_boot_self, id_boot_game, - id_boot_pkg, + id_install_pkg, id_sys_pause, id_sys_stop, id_sys_send_open_menu, @@ -47,43 +45,43 @@ wxString GetPaneName() 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 (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; - } - } + 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); + 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; - } - } + } + 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); - } + } + bIsFile = fDir.GetNext(&sNext); + } ::wxRmdir(sFrom); - return true; + return true; } MainFrame::MainFrame() @@ -113,10 +111,9 @@ MainFrame::MainFrame() menubar.Append(&menu_help, "Help"); menu_boot.Append(id_boot_game, "Boot game"); - menu_boot.Append(id_boot_pkg, "Install PKG"); + menu_boot.Append(id_install_pkg, "Install PKG"); menu_boot.AppendSeparator(); - menu_boot.Append(id_boot_elf, "Boot ELF"); - menu_boot.Append(id_boot_self, "Boot SELF"); + menu_boot.Append(id_boot_elf, "Boot (S)ELF"); menu_sys.Append(id_sys_pause, "Pause")->Enable(false); menu_sys.Append(id_sys_stop, "Stop\tCtrl + S")->Enable(false); @@ -140,9 +137,8 @@ MainFrame::MainFrame() AddPane(m_game_viewer, "Game List", wxAUI_DOCK_BOTTOM); Connect( id_boot_game, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootGame) ); - Connect( id_boot_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootPkg) ); + Connect( id_install_pkg, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::InstallPkg) ); Connect( id_boot_elf, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootElf) ); - Connect( id_boot_self, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::BootSelf) ); Connect( id_sys_pause, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Pause) ); Connect( id_sys_stop, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::Stop) ); @@ -209,87 +205,20 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event)) } Emu.Stop(); - - 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(Emu.BootGame(ctrl.GetPath().c_str())) { - if(wxFile::Access(ctrl.GetPath() + elf[i], wxFile::read)) - { - ConLog.Write("SELF: booting..."); - - Emu.Stop(); - - wxString fileIn = ctrl.GetPath()+elf[i]; - wxString fileOut = (ctrl.GetPath()+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 key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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(); - - Emu.SetPath(fileOut); - Emu.Load(); - if (!wxRemoveFile(fileOut)) - ConLog.Warning("Could not delete the decrypted ELF file"); - - ConLog.Write("Game: boot done."); - return; - } + ConLog.Write("Game: boot done."); + } + else + { + ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().mb_str()); } - - ConLog.Error("Ps3 executable not found in selected folder (%s)", ctrl.GetPath().mb_str()); - return; } - -void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) +void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) { + //TODO: progress bar bool stopped = false; if(Emu.IsRunning()) @@ -298,7 +227,7 @@ void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) stopped = true; } - wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "*.*", + wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "*.pkg", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if(ctrl.ShowModal() == wxID_CANCEL) @@ -333,8 +262,8 @@ void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) wxString mainDir = wxGetCwd(); // Set PKG dir. - wxString oldPkgDir = wxT(wxGetCwd() + "\\" + titleID_full); - wxString newPkgDir = wxT(wxGetCwd() + gamePath + titleID); + wxString oldPkgDir = wxT(mainDir + "\\" + titleID_full); + wxString newPkgDir = wxT(mainDir + gamePath + titleID); // Move the final folder. wxMoveDir(oldPkgDir, newPkgDir); @@ -344,82 +273,10 @@ void MainFrame::BootPkg(wxCommandEvent& WXUNUSED(event)) ConLog.Write("PKG: extract done."); - // Travel to the installed PKG. - wxSetWorkingDirectory(newPkgDir); + // Travel to the main dir. + wxSetWorkingDirectory(mainDir); - 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 key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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; - } - } + Emu.BootGame(newPkgDir.c_str()); } void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) @@ -432,7 +289,7 @@ void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) stopped = true; } - wxFileDialog ctrl(this, L"Select ELF", wxEmptyString, wxEmptyString, "*.*", + wxFileDialog ctrl(this, L"Select (S)ELF", wxEmptyString, wxEmptyString, "*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if(ctrl.ShowModal() == wxID_CANCEL) @@ -441,91 +298,14 @@ void MainFrame::BootElf(wxCommandEvent& WXUNUSED(event)) return; } - ConLog.Write("ELF: booting..."); + ConLog.Write("(S)ELF: booting..."); Emu.Stop(); Emu.SetPath(ctrl.GetPath()); Emu.Load(); - ConLog.Write("ELF: boot done."); -} - -void MainFrame::BootSelf(wxCommandEvent& WXUNUSED(event)) -{ - bool stopped = false; - - if(Emu.IsRunning()) - { - Emu.Pause(); - stopped = true; - } - - wxFileDialog ctrl(this, L"Select SELF", wxEmptyString, wxEmptyString, "*.*", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); - - if(ctrl.ShowModal() == wxID_CANCEL) - { - if(stopped) Emu.Resume(); - return; - } - - ConLog.Write("SELF: booting..."); - - Emu.Stop(); - - wxString fileIn = ctrl.GetPath(); - wxString fileOut = ctrl.GetPath()+".elf"; - - // Check if the data really needs to be decrypted. - if(!wxFileExists(fileIn)) - { - ConLog.Error("Could not open SELF file!"); - return; - } - - wxFile f(fileIn); - // Get the key version. - f.Seek(0x08); - be_t key_version; - f.Read(&key_version, sizeof(key_version)); - - if(key_version.ToBE() == const_se_t::value) - { - ConLog.Warning("Debug SELF detected! Removing fake header..."); - - // Get the real elf offset. - f.Seek(0x10); - be_t 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("SELF: Could not decrypt file"); - return; - } - } - - f.Close(); - - Emu.SetPath(fileOut); - Emu.Load(); - //if (!wxRemoveFile(fileOut)) - // ConLog.Warning("Could not delete the decrypted ELF file"); - - ConLog.Write("SELF: boot done."); + ConLog.Write("(S)ELF: boot done."); } void MainFrame::Pause(wxCommandEvent& WXUNUSED(event)) diff --git a/rpcs3/Gui/MainFrame.h b/rpcs3/Gui/MainFrame.h index 27da011f28..bc90b3485b 100644 --- a/rpcs3/Gui/MainFrame.h +++ b/rpcs3/Gui/MainFrame.h @@ -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); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index b5c8620aab..f67f7f436d 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -199,6 +199,12 @@ + + NotUsing + NotUsing + NotUsing + NotUsing + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 655f0f421a..feb18fc019 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -53,6 +53,9 @@ {bee6a4b4-6371-4c1b-8558-fc7888b1574e} + + {52b11fe8-a967-4d52-bf88-a3210d4ffb27} + @@ -343,6 +346,9 @@ Emu\SysCalls\lv2 + + Utilities\scetool + diff --git a/scetool/elf_inlines.h b/scetool/elf_inlines.h index ce36290552..79d9660099 100644 --- a/scetool/elf_inlines.h +++ b/scetool/elf_inlines.h @@ -8,6 +8,7 @@ #include +#define NOCOMPILE #include "types.h" #include "elf.h" diff --git a/scetool/scetool.cpp b/scetool/scetool.cpp index 57dbf40946..8f6df226c3 100644 --- a/scetool/scetool.cpp +++ b/scetool/scetool.cpp @@ -3,6 +3,8 @@ * This file is released under the GPLv2. */ +#include "stdafx.h" + #include #include diff --git a/scetool/scetool.h b/scetool/scetool.h new file mode 100644 index 0000000000..00ce0ea159 --- /dev/null +++ b/scetool/scetool.h @@ -0,0 +1,5 @@ +#pragma once + +#include "types.h" + +bool scetool_decrypt(scetool::s8 *_file_in, scetool::s8 *_file_out); \ No newline at end of file From bf03874be2b13cf53c5aa43e808797f5d71944fe Mon Sep 17 00:00:00 2001 From: DH Date: Sun, 8 Dec 2013 19:06:20 +0200 Subject: [PATCH 16/16] Refresh Game Viewer after Install PKG --- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 2 +- rpcs3/Gui/MainFrame.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index ed9c2a73d8..424b0139e1 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -30,7 +30,7 @@ int sys_spu_printf_initialize(int a1, int a2, int a3, int a4, int a5) s64 sys_prx_register_library(u32 lib_addr) { - sysPrxForUser.Error("sys_prx_register_library(lib_addr=0x%x)"); + sysPrxForUser.Error("sys_prx_register_library(lib_addr=0x%x)", lib_addr); return 0; } diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 7c0f5d81d7..ea154ffc1b 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -276,6 +276,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) // Travel to the main dir. wxSetWorkingDirectory(mainDir); + m_game_viewer->Refresh(); Emu.BootGame(newPkgDir.c_str()); }