diff --git a/rpcs3/Emu/CPU/CPUThreadManager.h b/rpcs3/Emu/CPU/CPUThreadManager.h index f335b871da..0bdcb05ce4 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.h +++ b/rpcs3/Emu/CPU/CPUThreadManager.h @@ -1,7 +1,6 @@ #pragma once class CPUThread; -class RawSPUThread; enum CPUThreadType : unsigned char; class CPUThreadManager diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 1d9d336a2a..d7945fd2f9 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -681,7 +681,7 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc) m_status = old_status; PC = old_PC; - if (GPR[1] != old_stack) // GPR[1] shouldn't change + if (GPR[1] != old_stack && !Emu.IsStopped()) // GPR[1] shouldn't change { LOG_ERROR(PPU, "PPUThread::FastCall2(0x%x,0x%x): stack inconsistency (SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); GPR[1] = old_stack; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index c145c3bf57..ff2da7e06b 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -693,7 +693,7 @@ namespace vm { PPUThread& context = static_cast(CPU); - if (context.GPR[1] != addr) + if (context.GPR[1] != addr && !Emu.IsStopped()) { LOG_ERROR(PPU, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%llx)", addr, old_pos, context.GPR[1]); } @@ -713,7 +713,7 @@ namespace vm { ARMv7Context& context = static_cast(CPU).context; - if (context.SP != addr) + if (context.SP != addr && !Emu.IsStopped()) { LOG_ERROR(ARMv7, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%x)", addr, old_pos, context.SP); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index 5da5c863e0..89a6146f34 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -106,15 +106,20 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, ppu.custom_task = [t, &tag, arg](PPUThread& CPU) { - auto func = vm::ptr::make(CPU.entry); + const auto func = vm::ptr::make(CPU.entry); + const auto pc = vm::read32(func.addr()); + const auto rtoc = vm::read32(func.addr() + 4); std::unique_lock cond_lock(tag.handler_mutex); while (!Emu.IsStopped()) { + // call interrupt handler until int status is clear if (tag.stat.read_relaxed()) { - func(CPU, arg); // call interrupt handler until int status is clear + //func(CPU, arg); + CPU.GPR[3] = arg; + CPU.FastCall2(pc, rtoc); } tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1)); @@ -152,5 +157,8 @@ void sys_interrupt_thread_eoi(PPUThread& CPU) { sys_interrupt.Log("sys_interrupt_thread_eoi()"); + // TODO: maybe it should actually unwind the stack (ensure that all the automatic objects are finalized)? + CPU.GPR[1] = align(CPU.GetStackAddr() + CPU.GetStackSize(), 0x200) - 0x200; // supercrutch (just to hide error messages) + CPU.FastStop(); }