From 8e19af530b7424d073540aa40766e9117a15e01d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:03:54 +0400 Subject: [PATCH 01/10] .gitignore fix --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 43afefc806..84200d4e1b 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,7 @@ rpcs3/git-version.h !/bin/dev_hdd0/game/TEST12345/ # Ignore other system generated files -bin/dev_hdd0/log.txt +bin/dev_hdd0/*.txt x64/Debug/emucore.lib x64/Release/emucore.lib From b487dcee277681e0765f7bb48d5407e554373fc7 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:06:58 +0400 Subject: [PATCH 02/10] RawSPU initialization fix --- rpcs3/Emu/CPU/CPUThreadManager.cpp | 26 ++++++++++++++++++++------ rpcs3/Emu/CPU/CPUThreadManager.h | 1 - rpcs3/Emu/Cell/RawSPUThread.cpp | 7 +++---- rpcs3/Emu/Cell/RawSPUThread.h | 2 +- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 01ba798add..d162bc493b 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -11,7 +11,6 @@ #include "Emu/ARMv7/ARMv7Thread.h" CPUThreadManager::CPUThreadManager() - : m_raw_spu_num(0) { } @@ -22,7 +21,6 @@ CPUThreadManager::~CPUThreadManager() void CPUThreadManager::Close() { - m_raw_spu_num = 0; while(m_threads.size()) RemoveThread(m_threads[0]->GetId()); } @@ -34,10 +32,26 @@ CPUThread& CPUThreadManager::AddThread(CPUThreadType type) switch(type) { - case CPU_THREAD_PPU: new_thread = new PPUThread(); break; - case CPU_THREAD_SPU: new_thread = new SPUThread(); break; - case CPU_THREAD_RAW_SPU: new_thread = new RawSPUThread(m_raw_spu_num++); break; - case CPU_THREAD_ARMv7: new_thread = new ARMv7Thread(); break; + case CPU_THREAD_PPU: + { + new_thread = new PPUThread(); + break; + } + case CPU_THREAD_SPU: + { + new_thread = new SPUThread(); + break; + } + case CPU_THREAD_RAW_SPU: + { + new_thread = new RawSPUThread(); + break; + } + case CPU_THREAD_ARMv7: + { + new_thread = new ARMv7Thread(); + break; + } default: assert(0); } diff --git a/rpcs3/Emu/CPU/CPUThreadManager.h b/rpcs3/Emu/CPU/CPUThreadManager.h index ba71cb78b9..ad312108d7 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.h +++ b/rpcs3/Emu/CPU/CPUThreadManager.h @@ -7,7 +7,6 @@ class CPUThreadManager { std::vector m_threads; std::mutex m_mtx_thread; - u32 m_raw_spu_num; public: CPUThreadManager(); diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 4f81ccf513..7255e31952 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -7,12 +7,11 @@ #include "Emu/Cell/RawSPUThread.h" -RawSPUThread::RawSPUThread(u32 index, CPUThreadType type) +RawSPUThread::RawSPUThread(CPUThreadType type) : SPUThread(type) , MemoryBlock() - , m_index(index) { - Memory.InitRawSPU(SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_PROB_OFFSET), m_index); + m_index = Memory.InitRawSPU(this); Reset(); } @@ -344,7 +343,7 @@ void RawSPUThread::Task() { PC = SPU.NPC.GetValue(); - CPUThread::Task(); + SPUThread::Task(); SPU.NPC.SetValue(PC); } diff --git a/rpcs3/Emu/Cell/RawSPUThread.h b/rpcs3/Emu/Cell/RawSPUThread.h index d8765a3b25..c7b3479f98 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.h +++ b/rpcs3/Emu/Cell/RawSPUThread.h @@ -19,7 +19,7 @@ class RawSPUThread u32 m_index; public: - RawSPUThread(u32 index, CPUThreadType type = CPU_THREAD_RAW_SPU); + RawSPUThread(CPUThreadType type = CPU_THREAD_RAW_SPU); virtual ~RawSPUThread(); virtual bool Read32(const u64 addr, u32* value) override; From e1a9f08a91f55aedf836ee6a6e0b6c6f08d91ee4 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:07:38 +0400 Subject: [PATCH 03/10] sys_raw_spu_destroy implemented --- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 72 +++++++++++++----------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 4a88fb9c48..68303a28a4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -18,46 +18,12 @@ u32 LoadSpuImage(vfsStream& stream, u32& spu_ep) { ELFLoader l(stream); l.LoadInfo(); - const u32 alloc_size = 256 * 1024 /*0x1000000 - stream.GetSize()*/; + const u32 alloc_size = 256 * 1024; u32 spu_offset = Memory.MainMem.AllocAlign(alloc_size); l.LoadData(spu_offset); spu_ep = l.GetEntry(); return spu_offset; } -/*u64 g_last_spu_offset = 0; -static const u64 g_spu_alloc_size = 0x1000000; - -u32 LoadSpuImage(vfsStream& stream, u64 address) -{ - ELFLoader l(stream); - l.LoadInfo(); - l.LoadData(address); - - return address + l.GetEntry(); -} - -u32 LoadSpuImage(vfsStream& stream) -{ - g_last_spu_offset = Memory.MainMem.Alloc(g_spu_alloc_size); - return LoadSpuImage(stream, g_last_spu_offset); -}*/ - -/*u32 _max_usable_spu = 0; -u32 _max_raw_spu = 0; - -s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu) -{ - sc_spu.Log("sys_spu_initialize(max_usable_spu=%d, max_raw_spu=%d)", max_usable_spu, max_raw_spu); - _max_usable_spu = max_usable_spu; - _max_raw_spu = max_raw_spu; - return CELL_OK; -} - -s32 sys_raw_spu_create(u32 id_addr, u32 attr_addr) -{ - Memory.Write32(id_addr, Emu.GetIdManager().GetNewID("raw_spu")); - return CELL_OK; -}*/ //156 s32 sys_spu_image_open(mem_ptr_t img, u32 path_addr) @@ -349,13 +315,23 @@ s32 sys_spu_thread_group_join(u32 id, mem32_t cause, mem32_t status) return CELL_ESRCH; } + if (cause.GetAddr() && !cause.IsGood()) + { + return CELL_EFAULT; + } + + if (status.GetAddr() && !status.IsGood()) + { + return CELL_EFAULT; + } + if (group_info->lock.exchange(1)) // acquire lock { return CELL_EBUSY; } - cause = SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT; - status = 0; //unspecified because of ALL_THREADS_EXIT + if (cause.GetAddr()) cause = SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT; + if (status.GetAddr()) status = 0; //unspecified because of ALL_THREADS_EXIT for (u32 i = 0; i < group_info->list.size(); i++) { @@ -796,24 +772,38 @@ s32 sys_raw_spu_create(mem32_t id, u32 attr_addr) { sc_spu.Warning("sys_raw_spu_create(id_addr=0x%x, attr_addr=0x%x)", id.GetAddr(), attr_addr); - //Emu.GetIdManager().GetNewID("sys_raw_spu", new u32(attr_addr)); CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); + if (((RawSPUThread&)new_thread).GetIndex() >= 5) + { + Emu.GetCPU().RemoveThread(new_thread.GetId()); + return CELL_EAGAIN; + } + id = ((RawSPUThread&)new_thread).GetIndex(); new_thread.Run(); - return CELL_OK; } s32 sys_raw_spu_destroy(u32 id) { - sc_spu.Error("sys_raw_spu_destroy(id=%d)", id); + sc_spu.Warning("sys_raw_spu_destroy(id=%d)", id); + RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); + + if (!t) + { + return CELL_ESRCH; + } + + // TODO: check if busy + + Emu.GetCPU().RemoveThread(t->GetId()); return CELL_OK; } s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, mem32_t intrtag) { - sc_spu.Error("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag_addr=0x%x)", id, class_id, hwthread, intrtag.GetAddr()); + sc_spu.Warning("sys_raw_spu_create_interrupt_tag(id=%d, class_id=%d, hwthread=0x%x, intrtag_addr=0x%x)", id, class_id, hwthread, intrtag.GetAddr()); RawSPUThread* t = Emu.GetCPU().GetRawSPUThread(id); From d94ce7094e857f11baac31f70addb5f9041771ea Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:09:20 +0400 Subject: [PATCH 04/10] Rounding mode set --- rpcs3/Emu/Cell/SPUThread.cpp | 15 +++++++++++++++ rpcs3/Emu/Cell/SPUThread.h | 1 + 2 files changed, 16 insertions(+) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index a8355bc296..9c020cb219 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -10,6 +10,8 @@ #include "Emu/Cell/SPUDisAsm.h" #include "Emu/Cell/SPURecompiler.h" +#include + SPUThread& GetCurrentSPUThread() { PPCThread* thread = GetCurrentPPCThread(); @@ -35,6 +37,19 @@ SPUThread::~SPUThread() { } +void SPUThread::Task() +{ + const int round = std::fegetround(); + std::fesetround(FE_TOWARDZERO); + + CPUThread::Task(); + if (std::fegetround() != FE_TOWARDZERO) + { + LOG_ERROR(Log::SPU, "Rounding mode has changed(%d)", std::fegetround()); + } + std::fesetround(round); +} + void SPUThread::DoReset() { PPCThread::DoReset(); diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index a56751bbe8..5f38235859 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -1444,6 +1444,7 @@ public: public: virtual void InitRegs(); virtual u64 GetFreeStackSize() const; + virtual void Task(); protected: virtual void DoReset(); From 3d9c76a80d7fe0d74932b3afb20452dccf380fc0 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:09:43 +0400 Subject: [PATCH 05/10] RawSPU initialization fix --- rpcs3/Emu/Memory/Memory.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 6430e27d80..88cc1dea6d 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -214,12 +214,22 @@ public: } } - void InitRawSPU(MemoryBlock* raw_spu, const u32 num) + u32 InitRawSPU(MemoryBlock* raw_spu) { std::lock_guard lock(m_mutex); - MemoryBlocks.push_back(raw_spu); - if (num < sizeof(RawSPUMem) / sizeof(RawSPUMem[0])) RawSPUMem[num] = raw_spu; + u32 index; + for (index = 0; index < sizeof(RawSPUMem) / sizeof(RawSPUMem[0]); index++) + { + if (!RawSPUMem[index]) + { + RawSPUMem[index] = raw_spu; + break; + } + } + + MemoryBlocks.push_back(raw_spu->SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_PROB_OFFSET)); + return index; } void CloseRawSPU(MemoryBlock* raw_spu, const u32 num) From 3d0983e7d021ccc24ea2f462c9f2cc1bfcecf225 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:13:11 +0400 Subject: [PATCH 06/10] SPU Interpreter fix (these bugs weren't in SPURecompiler) --- rpcs3/Emu/Cell/SPUInterpreter.h | 156 +++++++++++++++++++++----------- 1 file changed, 102 insertions(+), 54 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUInterpreter.h b/rpcs3/Emu/Cell/SPUInterpreter.h index 32fa60e91c..b340677966 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.h +++ b/rpcs3/Emu/Cell/SPUInterpreter.h @@ -503,29 +503,50 @@ private: void ROTQBI(u32 rt, u32 ra, u32 rb) { const int t = CPU.GPR[rb]._u32[3] & 0x7; - 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)); + if (t) // not an optimization, it fixes shifts + { + 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)); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void ROTQMBI(u32 rt, u32 ra, u32 rb) { const int t = (0 - CPU.GPR[rb]._u32[3]) & 0x7; - 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] = (temp._u32[3] >> t); + if (t) // not an optimization, it fixes shifts + { + 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] = (temp._u32[3] >> t); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void SHLQBI(u32 rt, u32 ra, u32 rb) { const int t = CPU.GPR[rb]._u32[3] & 0x7; - 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)); + if (t) // not an optimization, it fixes shifts + { + 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)); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void ROTQBY(u32 rt, u32 ra, u32 rb) { @@ -591,29 +612,50 @@ private: void ROTQBII(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0x7; - 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)); + if (s) // not an optimization, it fixes shifts + { + 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)); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void ROTQMBII(u32 rt, u32 ra, s32 i7) { const int s = (0 - i7) & 0x7; - 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); + if (s) // not an optimization, it fixes shifts + { + 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); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void SHLQBII(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0x7; - 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)); + if (s) // not an optimization, it fixes shifts + { + 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)); + } + else + { + CPU.GPR[rt] = CPU.GPR[ra]; + } } void ROTQBYI(u32 rt, u32 ra, s32 i7) { @@ -747,24 +789,27 @@ private: } void FA(u32 rt, u32 ra, u32 rb) { - 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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[ra]._f[w] + CPU.GPR[rb]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void FS(u32 rt, u32 ra, u32 rb) { - 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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[ra]._f[w] - CPU.GPR[rb]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void FM(u32 rt, u32 ra, u32 rb) { - 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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[ra]._f[w] * CPU.GPR[rb]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void CLGTH(u32 rt, u32 ra, u32 rb) { @@ -1513,24 +1558,27 @@ private: } void FNMS(u32 rt, u32 ra, u32 rb, u32 rc) { - 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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[rc]._f[w] - CPU.GPR[ra]._f[w] * CPU.GPR[rb]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void FMA(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[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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[rc]._f[w] + CPU.GPR[ra]._f[w] * CPU.GPR[rb]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void FMS(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[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]; + for (int w = 0; w < 4; w++) + { + CPU.GPR[rt]._f[w] = CPU.GPR[ra]._f[w] * CPU.GPR[rb]._f[w] - CPU.GPR[rc]._f[w]; + //if (CPU.GPR[rt]._f[w] == -0.0f) CPU.GPR[rt]._f[w] = 0.0f; + } } void UNK(u32 code, u32 opcode, u32 gcode) From 694a2b774ed3eb415df26bf92d46b5affef84296 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 16:15:20 +0400 Subject: [PATCH 07/10] SPU Recompiler fix --- rpcs3/Emu/Cell/SPURecompiler.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 7b019ac5ca..0851c70a3e 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -1485,8 +1485,8 @@ private: c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); XmmFinalize(vr, rt); XmmInvalidate(rt); - c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[0])), 0x00010203); - c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[1])), 0x04050607); + c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[0])), 0x04050607); + c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[1])), 0x00010203); LOG_OPCODE(); } void ROTQBI(u32 rt, u32 ra, u32 rb) @@ -1628,8 +1628,8 @@ private: c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); XmmFinalize(vr, rt); XmmInvalidate(rt); - c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[0])), 0x00010203); - c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[1])), 0x04050607); + c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[0])), 0x04050607); + c.mov(dword_ptr(*cpu_var, *addr, 0, offsetof(SPUThread, GPR[rt]._u32[1])), 0x00010203); LOG_OPCODE(); } void ROTQBII(u32 rt, u32 ra, s32 i7) From ecbc9d1b080494342f5682937e93881f1590b49e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 20:10:18 +0400 Subject: [PATCH 08/10] RawSPU cleanup --- rpcs3/Emu/Cell/RawSPUThread.cpp | 183 ++++---------------------------- rpcs3/Emu/Cell/SPUThread.cpp | 6 +- rpcs3/Emu/Cell/SPUThread.h | 49 ++++----- rpcs3/Emu/Memory/Memory.h | 10 +- 4 files changed, 54 insertions(+), 194 deletions(-) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 7255e31952..2337f6d0e1 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -22,75 +22,20 @@ RawSPUThread::~RawSPUThread() bool RawSPUThread::Read32(const u64 addr, u32* value) { - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Read32(addr, value); - } + const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - - switch(offset) + switch (offset) { - case MFC_LSA_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_LSA)", m_index); - *value = MFC2.LSA.GetValue(); - break; - } - - case MFC_EAH_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAH)", m_index); - *value = MFC2.EAH.GetValue(); - break; - } - - case MFC_EAL_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_EAL)", m_index); - *value = MFC2.EAL.GetValue(); - break; - } - - case MFC_Size_Tag_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_Size_Tag)", m_index); - *value = MFC2.Size_Tag.GetValue(); - break; - } - case MFC_CMDStatus_offs: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(MFC_CMDStatus)", m_index); *value = MFC2.CMDStatus.GetValue(); break; } case MFC_QStatus_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(MFC_QStatus)", m_index); - *value = MFC2.QStatus.GetValue(); - break; - } - - case Prxy_QueryType_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_QueryType)", m_index); - *value = Prxy.QueryType.GetValue(); - break; - } - - case Prxy_QueryMask_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_QueryMask)", m_index); - *value = Prxy.QueryMask.GetValue(); - break; - } - - case Prxy_TagStatus_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(Prxy_TagStatus)", m_index); - *value = Prxy.TagStatus.GetValue(); + // TagStatus is not used: mask is written directly + *value = MFC2.QueryMask.GetValue(); break; } @@ -100,62 +45,23 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) SPU.Out_MBox.PopUncond(*value); break; } - - case SPU_In_MBox_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_In_MBox)", m_index); - while (!SPU.In_MBox.Pop(*value) && !Emu.IsStopped()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - break; - } case SPU_MBox_Status_offs: { - //LOG_WARNING(Log::SPU, "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.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8)); - *value = SPU.MBox_Status.GetValue(); + *value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8); break; } - case SPU_RunCntl_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); - *value = (u32)IsRunning(); - break; - } - case SPU_Status_offs: { *value = SPU.Status.GetValue(); break; } - - case SPU_NPC_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_NPC)", m_index); - *value = SPU.NPC.GetValue(); - break; - } - - case SPU_RdSigNotify1_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify1)", m_index); - *value = SPU.SNR[0].GetValue(); - break; - } - - case SPU_RdSigNotify2_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RdSigNotify2)", m_index); - *value = SPU.SNR[1].GetValue(); - break; - } default: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%x)", m_index, offset); - Emu.Pause(); + // TODO: read value from LS if necessary (not important) + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read32(0x%llx)", m_index, offset); return false; } } @@ -165,14 +71,9 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) bool RawSPUThread::Write32(const u64 addr, const u32 value) { - if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) - { - return MemoryBlock::Write32(addr, value); - } + const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; - - switch(offset) + switch (offset) { case MFC_LSA_offs: { @@ -205,53 +106,26 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) break; } - case MFC_QStatus_offs: - { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(MFC_QStatus, 0x%x)", m_index, value); - //MFC2.QStatus.SetValue(value); - break; - } - case Prxy_QueryType_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_QueryType, 0x%x)", m_index, value); - Prxy.QueryType.SetValue(value); - switch(value) { - case 2: - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Prxy Query Immediate.", m_index); - break; + case 2: break; default: + { LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Unknown Prxy Query Type. (prxy_query=0x%x)", m_index, value); - break; + return false; + } } - Prxy.QueryType.SetValue(0); - MFC2.QStatus.SetValue(Prxy.QueryMask.GetValue()); + MFC2.QueryType.SetValue(value); // not used break; } case Prxy_QueryMask_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_QueryMask, 0x%x)", m_index, value); - Prxy.QueryMask.SetValue(value); - break; - } - - case Prxy_TagStatus_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(Prxy_TagStatus, 0x%x)", m_index, value); - Prxy.TagStatus.SetValue(value); - break; - } - - case SPU_Out_MBox_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Out_MBox, 0x%x)", m_index, value); - while (!SPU.Out_MBox.Push(value) && !Emu.IsStopped()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + MFC2.QueryMask.SetValue(value); // TagStatus is not used break; } @@ -261,13 +135,6 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) SPU.In_MBox.PushUncond(value); break; } - - case SPU_MBox_Status_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); - SPU.MBox_Status.SetValue(value); - break; - } case SPU_RunCntl_offs: { @@ -289,39 +156,29 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) break; } - case SPU_Status_offs: - { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); - SPU.Status.SetValue(value); - break; - } - case SPU_NPC_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_NPC, 0x%x)", m_index, value); SPU.NPC.SetValue(value); break; } case SPU_RdSigNotify1_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify1, 0x%x)", m_index, value); - SPU.SNR[0].SetValue(value); + WriteSNR(0, value); break; } case SPU_RdSigNotify2_offs: { - LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify2, 0x%x)", m_index, value); - SPU.SNR[1].SetValue(value); + WriteSNR(1, value); break; } default: { - LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%x, 0x%x)", m_index, offset, value); - Emu.Pause(); - break; + // TODO: write value to LS if necessary (not important) + LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(0x%llx, 0x%x)", m_index, offset, value); + return false; } } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 9c020cb219..235b73700c 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -75,9 +75,13 @@ void SPUThread::InitRegs() dmac.queue_lock = 0;*/ SPU.Status.SetValue(SPU_STATUS_STOPPED); - Prxy.QueryType.SetValue(0); + + // TODO: check initialization if necessary + MFC2.QueryType.SetValue(0); // prxy MFC1.CMDStatus.SetValue(0); MFC2.CMDStatus.SetValue(0); + MFC1.TagStatus.SetValue(0); + MFC2.TagStatus.SetValue(0); //PC = SPU.NPC.GetValue(); } diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 5f38235859..abc187e9c2 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -523,16 +523,11 @@ public: Channel<1> EAL; Channel<1> Size_Tag; Channel<1> CMDStatus; - Channel<1> QStatus; - } MFC1, MFC2; - - struct - { - Channel<1> QueryType; + Channel<1> QueryType; // only for prxy Channel<1> QueryMask; Channel<1> TagStatus; Channel<1> AtomicStat; - } Prxy; + } MFC1, MFC2; struct StalledList { @@ -555,7 +550,6 @@ public: Channel<1> Out_MBox; Channel<1> Out_IntrMBox; Channel<4> In_MBox; - Channel<1> MBox_Status; Channel<1> Status; Channel<1> NPC; Channel<1> SNR[2]; @@ -831,7 +825,7 @@ public: reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; *(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; } - Prxy.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); } else if (op == MFC_PUTLLC_CMD) // store conditional { @@ -854,7 +848,7 @@ public: } if (changed == 0) // nothing changed? { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else if (changed == 1) { @@ -862,7 +856,7 @@ public: { LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 128bit compare and swap"); Emu.Pause(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else { @@ -871,11 +865,11 @@ public: if (InterlockedCompareExchange64((volatile long long*)(Memory + (u32)ea + last * 16 + last_q * 8), buf[last]._u64[last_q], reservation.data[last]._u64[last_q]) == reservation.data[last]._u64[last_q]) { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } else { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } /*u32 last_d = last_q * 2; if (buf[last]._u32[last_d] == reservation.data[last]._u32[last_d] && buf[last]._u32[last_d+1] != reservation.data[last]._u32[last_d+1]) @@ -890,7 +884,7 @@ public: { LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: TODO: 64bit compare and swap"); Emu.Pause(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); }*/ } } @@ -900,18 +894,18 @@ public: LOG_ERROR(Log::SPU, "MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 16x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", changed, mask, op, cmd, lsa, ea, tag, size); Emu.Pause(); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } } else { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } reservation.clear(); } else // failed { - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); } } else // store unconditional @@ -920,7 +914,7 @@ public: ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); if (op == MFC_PUTLLUC_CMD) { - Prxy.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); + MFCArgs.AtomicStat.PushUncond(MFC_PUTLLUC_SUCCESS); } if ((reservation.addr + reservation.size > ea && reservation.addr <= ea + size) || (ea + size > reservation.addr && ea <= reservation.addr + reservation.size)) @@ -944,12 +938,12 @@ public: { case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount(); case SPU_RdInMbox: return SPU.In_MBox.GetCount(); - case MFC_RdTagStat: return Prxy.TagStatus.GetCount(); + case MFC_RdTagStat: return MFC1.TagStatus.GetCount(); case MFC_RdListStallStat: return StallStat.GetCount(); - case MFC_WrTagUpdate: return Prxy.TagStatus.GetCount(); // hack + case MFC_WrTagUpdate: return MFC1.TagStatus.GetCount(); // hack case SPU_RdSigNotify1: return SPU.SNR[0].GetCount(); case SPU_RdSigNotify2: return SPU.SNR[1].GetCount(); - case MFC_RdAtomicStat: return Prxy.AtomicStat.GetCount(); + case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount(); default: { @@ -1115,14 +1109,14 @@ public: case MFC_WrTagMask: { //ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v); - Prxy.QueryMask.SetValue(v); + MFC1.QueryMask.SetValue(v); break; } case MFC_WrTagUpdate: { //ConLog.Warning("%s: %s = 0x%x", __FUNCTION__, spu_ch_name[ch], v); - Prxy.TagStatus.PushUncond(Prxy.QueryMask.GetValue()); + MFC1.TagStatus.PushUncond(MFC1.QueryMask.GetValue()); break; } @@ -1184,7 +1178,7 @@ public: case SPU_WrDec: { - m_dec_start = get_system_time(); + m_dec_start = get_time(); m_dec_value = v; break; } @@ -1215,7 +1209,7 @@ public: case MFC_RdTagStat: { - while (!Prxy.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + while (!MFC1.TagStatus.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); //ConLog.Warning("%s: 0x%x = %s", __FUNCTION__, v, spu_ch_name[ch]); break; } @@ -1236,7 +1230,7 @@ public: case MFC_RdAtomicStat: { - while (!Prxy.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + while (!MFC1.AtomicStat.Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1)); break; } @@ -1248,8 +1242,7 @@ public: case SPU_RdDec: { - // decrementer freq is probably 80 MHz - v = m_dec_value - (u32)(get_system_time() - m_dec_start) * 80; + v = m_dec_value - (u32)(get_time() - m_dec_start); break; } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 88cc1dea6d..c552fe2f7b 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -401,7 +401,10 @@ public: } else { - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data); + if (!RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data)) + { + *(u32*)((u8*)GetBaseAddr() + addr) = re32(data); + } } } else @@ -474,7 +477,10 @@ public: else { u32 res; - RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res); + if (!RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res)) + { + res = re32(*(u32*)((u8*)GetBaseAddr() + addr)); + } return res; } } From c3e06694351b6ee153b2253502818aa9cdf1fb24 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 20:21:09 +0400 Subject: [PATCH 09/10] Time functions fixed --- rpcs3/Emu/SysCalls/lv2/sys_time.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp index 0a5ded0ce9..df4d2b109a 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp @@ -14,22 +14,32 @@ SysCallBase sys_time("sys_time"); -//static const u64 timebase_frequency = 79800000; +static const u64 timebase_frequency = /*79800000*/ 80000000; // 80 Mhz extern int cellSysutilGetSystemParamInt(int id, mem32_t value); // Auxiliary functions u64 get_time() { #ifdef _WIN32 + static struct PerformanceFreqHolder + { + u64 value; + + PerformanceFreqHolder() + { + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + value = freq.QuadPart; + } + } freq; + LARGE_INTEGER cycle; - LARGE_INTEGER freq; QueryPerformanceCounter(&cycle); - QueryPerformanceFrequency(&freq); - return cycle.QuadPart * 10000000 / freq.QuadPart; + return cycle.QuadPart * timebase_frequency / freq.value; #else struct timespec ts; if (!clock_gettime(CLOCK_MONOTONIC, &ts)) - return ts.tv_sec * (s64)10000000 + (s64)ts.tv_nsec / (s64)100; + return ts.tv_sec * (s64)timebase_frequency + (s64)ts.tv_nsec * (s64)timebase_frequency / 1000000000; // Should never occur. assert(0); @@ -40,7 +50,7 @@ u64 get_time() // Returns some relative time in microseconds, don't change this fact u64 get_system_time() { - return get_time() / 10; + return get_time() / (timebase_frequency / 1000000); } @@ -61,8 +71,8 @@ s32 sys_time_get_current_time(u32 sec_addr, u32 nsec_addr) u64 time = get_time(); - Memory.Write64(sec_addr, time / 10000000); - Memory.Write64(nsec_addr, (time % 10000000) * 100); + Memory.Write64(sec_addr, time / timebase_frequency); + Memory.Write64(nsec_addr, (time % timebase_frequency) * 1000000000 / (s64)(timebase_frequency)); return CELL_OK; } @@ -76,5 +86,5 @@ s64 sys_time_get_system_time() u64 sys_time_get_timebase_frequency() { sys_time.Log("sys_time_get_timebase_frequency()"); - return 10000000; + return timebase_frequency; } From 7816843dfbe9ca5767267ef359270e063acacde8 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Jul 2014 22:29:26 +0400 Subject: [PATCH 10/10] Little fix --- rpcs3/Emu/SysCalls/lv2/sys_time.cpp | 5 +++-- rpcs3/Emu/SysCalls/lv2/sys_time.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp index df4d2b109a..aada49f665 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.cpp @@ -35,7 +35,8 @@ u64 get_time() LARGE_INTEGER cycle; QueryPerformanceCounter(&cycle); - return cycle.QuadPart * timebase_frequency / freq.value; + u64 sec = cycle.QuadPart / freq.value; + return sec * timebase_frequency + (cycle.QuadPart % freq.value) * timebase_frequency / freq.value; #else struct timespec ts; if (!clock_gettime(CLOCK_MONOTONIC, &ts)) @@ -50,7 +51,7 @@ u64 get_time() // Returns some relative time in microseconds, don't change this fact u64 get_system_time() { - return get_time() / (timebase_frequency / 1000000); + return get_time() / (timebase_frequency / MHZ); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_time.h b/rpcs3/Emu/SysCalls/lv2/sys_time.h index 921504cb42..3ebdefb7da 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_time.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_time.h @@ -1,5 +1,7 @@ #pragma once +#define MHZ (10000000) + // Auxiliary functions u64 get_time(); u64 get_system_time();