diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 99dae94713..be3431671b 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -118,6 +118,46 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_function_t ptr) } } +// Breakpoint entry point +static bool ppu_break(ppu_thread& ppu, ppu_opcode_t op) +{ + // Pause and wait if necessary + if (!ppu.state.test_and_set(cpu_flag::dbg_pause) && ppu.check_state()) + { + return false; + } + + // Fallback to the interpreter function + if (reinterpret_cast(std::uintptr_t{ppu_cache(ppu.cia)})(ppu, op)) + { + ppu.cia += 4; + } + + return false; +} + +// Set or remove breakpoint +extern void ppu_breakpoint(u32 addr) +{ + if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm) + { + return; + } + + const auto _break = ::narrow(reinterpret_cast(&ppu_break)); + + if (s_ppu_compiled[addr / 4] == _break) + { + // Remove breakpoint + s_ppu_compiled[addr / 4] = ppu_cache(addr); + } + else + { + // Set breakpoint + s_ppu_compiled[addr / 4] = _break; + } +} + std::string ppu_thread::get_name() const { return fmt::format("PPU[0x%x] Thread (%s)", id, m_name); diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index 10ec0de6a2..f77a0f84e6 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -13,14 +13,18 @@ #include "Emu/Cell/PPUDisAsm.h" #include "Emu/Cell/SPUDisAsm.h" #include "Emu/PSP2/ARMv7DisAsm.h" +#include "Emu/Cell/PPUInterpreter.h" #include "InstructionEditor.h" #include "RegisterEditor.h" //static const int show_lines = 30; #include + std::map g_breakpoints; +extern void ppu_breakpoint(u32 addr); + u32 InterpreterDisAsmFrame::GetPc() const { const auto cpu = this->cpu.lock(); @@ -159,6 +163,11 @@ void InterpreterDisAsmFrame::UpdateUI() } } } + + if (Emu.IsStopped()) + { + g_breakpoints.clear(); + } } void InterpreterDisAsmFrame::UpdateUnitList() @@ -516,9 +525,11 @@ bool InterpreterDisAsmFrame::IsBreakPoint(u32 pc) void InterpreterDisAsmFrame::AddBreakPoint(u32 pc) { g_breakpoints.emplace(pc, false); + ppu_breakpoint(pc); } -bool InterpreterDisAsmFrame::RemoveBreakPoint(u32 pc) +void InterpreterDisAsmFrame::RemoveBreakPoint(u32 pc) { - return g_breakpoints.erase(pc) != 0; + g_breakpoints.erase(pc); + ppu_breakpoint(pc); } diff --git a/rpcs3/Gui/InterpreterDisAsm.h b/rpcs3/Gui/InterpreterDisAsm.h index d48f16fbe8..af8323a27b 100644 --- a/rpcs3/Gui/InterpreterDisAsm.h +++ b/rpcs3/Gui/InterpreterDisAsm.h @@ -51,5 +51,5 @@ public: void MouseWheel(wxMouseEvent& event); bool IsBreakPoint(u32 pc); void AddBreakPoint(u32 pc); - bool RemoveBreakPoint(u32 pc); + void RemoveBreakPoint(u32 pc); };