mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Debugger fix
Crash fixes GUI fixes Debug enhancements
This commit is contained in:
parent
ff07595519
commit
257b9a2015
26 changed files with 282 additions and 455 deletions
|
@ -2380,10 +2380,6 @@ void named_thread::start_thread(const std::shared_ptr<void>& _this)
|
|||
LOG_FATAL(GENERAL, "%s thrown: %s", typeid(e).name(), e.what());
|
||||
Emu.Pause();
|
||||
}
|
||||
catch (EmulationStopped)
|
||||
{
|
||||
LOG_NOTICE(GENERAL, "Thread aborted");
|
||||
}
|
||||
|
||||
on_exit();
|
||||
});
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
#include "Emu/System.h"
|
||||
#include "CPUThread.h"
|
||||
|
||||
#include <mutex>
|
||||
DECLARE(cpu_thread::g_threads_created){0};
|
||||
DECLARE(cpu_thread::g_threads_deleted){0};
|
||||
|
||||
template<>
|
||||
void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
|
||||
|
@ -11,15 +12,15 @@ void fmt_class_string<cpu_flag>::format(std::string& out, u64 arg)
|
|||
{
|
||||
switch (f)
|
||||
{
|
||||
STR_CASE(cpu_flag::stop);
|
||||
STR_CASE(cpu_flag::exit);
|
||||
STR_CASE(cpu_flag::suspend);
|
||||
STR_CASE(cpu_flag::ret);
|
||||
STR_CASE(cpu_flag::signal);
|
||||
STR_CASE(cpu_flag::dbg_global_pause);
|
||||
STR_CASE(cpu_flag::dbg_global_stop);
|
||||
STR_CASE(cpu_flag::dbg_pause);
|
||||
STR_CASE(cpu_flag::dbg_step);
|
||||
case cpu_flag::stop: return "STOP";
|
||||
case cpu_flag::exit: return "EXIT";
|
||||
case cpu_flag::suspend: return "s";
|
||||
case cpu_flag::ret: return "ret";
|
||||
case cpu_flag::signal: return "sig";
|
||||
case cpu_flag::dbg_global_pause: return "G.PAUSE";
|
||||
case cpu_flag::dbg_global_stop: return "G.EXIT";
|
||||
case cpu_flag::dbg_pause: return "PAUSE";
|
||||
case cpu_flag::dbg_step: return "STEP";
|
||||
case cpu_flag::__bitset_enum_max: break;
|
||||
}
|
||||
|
||||
|
@ -41,10 +42,8 @@ void cpu_thread::on_task()
|
|||
|
||||
g_tls_current_cpu_thread = this;
|
||||
|
||||
Emu.SendDbgCommand(DID_CREATE_THREAD, this);
|
||||
|
||||
// Check thread status
|
||||
while (!test(state & cpu_flag::exit))
|
||||
while (!test(state, cpu_flag::exit + cpu_flag::dbg_global_stop))
|
||||
{
|
||||
// Check stop status
|
||||
if (!test(state & cpu_flag::stop))
|
||||
|
@ -79,11 +78,13 @@ void cpu_thread::on_stop()
|
|||
|
||||
cpu_thread::~cpu_thread()
|
||||
{
|
||||
g_threads_deleted++;
|
||||
}
|
||||
|
||||
cpu_thread::cpu_thread(u32 id)
|
||||
: id(id)
|
||||
{
|
||||
g_threads_created++;
|
||||
}
|
||||
|
||||
bool cpu_thread::check_state()
|
||||
|
|
|
@ -56,6 +56,9 @@ public:
|
|||
return id >> 24;
|
||||
}
|
||||
|
||||
// Thread stats for external observation
|
||||
static atomic_t<u64> g_threads_created, g_threads_deleted;
|
||||
|
||||
// Print CPU state
|
||||
virtual std::string dump() const;
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#endif
|
||||
|
||||
#include <cfenv>
|
||||
#include "Utilities/GSL.h"
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
|
@ -90,6 +91,7 @@ std::string ppu_thread::dump() const
|
|||
{
|
||||
std::string ret = cpu_thread::dump();
|
||||
ret += fmt::format("Priority: %d\n", prio);
|
||||
ret += fmt::format("Last function: %s\n", last_function ? last_function : "");
|
||||
|
||||
ret += "\nRegisters:\n=========\n";
|
||||
for (uint i = 0; i < 32; ++i) ret += fmt::format("GPR[%d] = 0x%llx\n", i, gpr[i]);
|
||||
|
@ -210,6 +212,11 @@ void ppu_thread::exec_task()
|
|||
if (UNLIKELY(test(state)))
|
||||
{
|
||||
if (check_state()) return;
|
||||
|
||||
// Decode single instruction (may be step)
|
||||
const u32 op = *reinterpret_cast<const be_t<u32>*>(base + cia);
|
||||
if (table[ppu_decode(op)](*this, {op})) { cia += 4; }
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reinitialize
|
||||
|
@ -223,11 +230,11 @@ void ppu_thread::exec_task()
|
|||
func3 = table[_i._u32[3]];
|
||||
}
|
||||
|
||||
while (LIKELY(func0(*this, { _op._u32[0] })))
|
||||
while (LIKELY(func0(*this, {_op._u32[0]})))
|
||||
{
|
||||
if (cia += 4, LIKELY(func1(*this, { _op._u32[1] })))
|
||||
if (cia += 4, LIKELY(func1(*this, {_op._u32[1]})))
|
||||
{
|
||||
if (cia += 4, LIKELY(func2(*this, { _op._u32[2] })))
|
||||
if (cia += 4, LIKELY(func2(*this, {_op._u32[2]})))
|
||||
{
|
||||
cia += 4;
|
||||
func0 = func3;
|
||||
|
@ -343,8 +350,7 @@ be_t<u64>* ppu_thread::get_stack_arg(s32 i, u64 align)
|
|||
|
||||
void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
||||
{
|
||||
const auto old_pc = cia;
|
||||
const auto old_stack = gpr[1];
|
||||
const auto old_cia = cia;
|
||||
const auto old_rtoc = gpr[2];
|
||||
const auto old_lr = lr;
|
||||
const auto old_func = last_function;
|
||||
|
@ -357,46 +363,46 @@ void ppu_thread::fast_call(u32 addr, u32 rtoc)
|
|||
|
||||
g_tls_log_prefix = []
|
||||
{
|
||||
const auto ppu = static_cast<ppu_thread*>(get_current_cpu_thread());
|
||||
const auto _this = static_cast<ppu_thread*>(get_current_cpu_thread());
|
||||
|
||||
return fmt::format("%s [0x%08x]", ppu->get_name(), ppu->cia);
|
||||
return fmt::format("%s [0x%08x]", _this->get_name(), _this->cia);
|
||||
};
|
||||
|
||||
auto at_ret = gsl::finally([&]()
|
||||
{
|
||||
if (std::uncaught_exception())
|
||||
{
|
||||
if (last_function)
|
||||
{
|
||||
LOG_WARNING(PPU, "'%s' aborted (%fs)", last_function, (get_system_time() - gpr[10]) / 1000000.);
|
||||
}
|
||||
|
||||
last_function = old_func;
|
||||
}
|
||||
else
|
||||
{
|
||||
state -= cpu_flag::ret;
|
||||
cia = old_cia;
|
||||
gpr[2] = old_rtoc;
|
||||
lr = old_lr;
|
||||
last_function = old_func;
|
||||
g_tls_log_prefix = old_fmt;
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
exec_task();
|
||||
|
||||
if (gpr[1] != old_stack && !test(state, cpu_flag::ret + cpu_flag::exit)) // gpr[1] shouldn't change
|
||||
{
|
||||
fmt::throw_exception("Stack inconsistency (addr=0x%x, rtoc=0x%x, SP=0x%llx, old=0x%llx)", addr, rtoc, gpr[1], old_stack);
|
||||
}
|
||||
}
|
||||
catch (cpu_flag _s)
|
||||
{
|
||||
state += _s;
|
||||
if (_s != cpu_flag::ret) throw;
|
||||
}
|
||||
catch (EmulationStopped)
|
||||
{
|
||||
if (last_function) LOG_WARNING(PPU, "'%s' aborted (%fs)", last_function, (get_system_time() - gpr[10]) / 1000000.);
|
||||
last_function = old_func;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (last_function) LOG_ERROR(PPU, "'%s' aborted", last_function);
|
||||
last_function = old_func;
|
||||
throw;
|
||||
}
|
||||
|
||||
state -= cpu_flag::ret;
|
||||
|
||||
cia = old_pc;
|
||||
gpr[1] = old_stack;
|
||||
gpr[2] = old_rtoc;
|
||||
lr = old_lr;
|
||||
last_function = old_func;
|
||||
g_tls_log_prefix = old_fmt;
|
||||
if (_s != cpu_flag::ret)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 ppu_thread::stack_push(u32 size, u32 align_v)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Emu/IdManager.h"
|
||||
|
||||
#include "Emu/Cell/ErrorCodes.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "sys_lwmutex.h"
|
||||
#include "sys_lwcond.h"
|
||||
#include "sys_mutex.h"
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
enum DbgCommand
|
||||
{
|
||||
DID_FIRST_COMMAND = 0x500,
|
||||
|
||||
DID_START_EMU,
|
||||
DID_STARTED_EMU,
|
||||
DID_STOP_EMU,
|
||||
DID_STOPPED_EMU,
|
||||
DID_PAUSE_EMU,
|
||||
DID_PAUSED_EMU,
|
||||
DID_RESUME_EMU,
|
||||
DID_RESUMED_EMU,
|
||||
DID_READY_EMU,
|
||||
DID_CREATE_THREAD,
|
||||
DID_CREATED_THREAD,
|
||||
DID_REMOVE_THREAD,
|
||||
DID_REMOVED_THREAD,
|
||||
DID_RENAME_THREAD,
|
||||
DID_RENAMED_THREAD,
|
||||
DID_START_THREAD,
|
||||
DID_STARTED_THREAD,
|
||||
DID_STOP_THREAD,
|
||||
DID_STOPED_THREAD,
|
||||
DID_PAUSE_THREAD,
|
||||
DID_PAUSED_THREAD,
|
||||
DID_RESUME_THREAD,
|
||||
DID_RESUMED_THREAD,
|
||||
DID_EXEC_THREAD,
|
||||
DID_REGISTRED_CALLBACK,
|
||||
DID_UNREGISTRED_CALLBACK,
|
||||
|
||||
DID_LAST_COMMAND,
|
||||
};
|
|
@ -7,6 +7,8 @@
|
|||
#include "ARMv7Opcodes.h"
|
||||
#include "ARMv7Interpreter.h"
|
||||
|
||||
#include "Utilities/GSL.h"
|
||||
|
||||
namespace vm { using namespace psv; }
|
||||
|
||||
const arm_decoder<arm_interpreter> s_arm_interpreter;
|
||||
|
@ -19,6 +21,9 @@ std::string ARMv7Thread::get_name() const
|
|||
std::string ARMv7Thread::dump() const
|
||||
{
|
||||
std::string result = cpu_thread::dump();
|
||||
result += "Last function: ";
|
||||
result += last_function ? last_function : "";
|
||||
result += "\n\n";
|
||||
result += "Registers:\n=========\n";
|
||||
for(int i=0; i<15; ++i)
|
||||
{
|
||||
|
@ -40,7 +45,7 @@ extern thread_local std::string(*g_tls_log_prefix)();
|
|||
|
||||
void ARMv7Thread::cpu_task()
|
||||
{
|
||||
return custom_task ? custom_task(*this) : fast_call(PC);
|
||||
return fast_call(PC);
|
||||
}
|
||||
|
||||
void ARMv7Thread::cpu_task_main()
|
||||
|
@ -113,50 +118,46 @@ ARMv7Thread::ARMv7Thread(const std::string& name, u32 prio, u32 stack)
|
|||
void ARMv7Thread::fast_call(u32 addr)
|
||||
{
|
||||
const auto old_PC = PC;
|
||||
const auto old_SP = SP;
|
||||
const auto old_LR = LR;
|
||||
const auto old_task = std::move(custom_task);
|
||||
const auto old_func = last_function;
|
||||
|
||||
PC = addr;
|
||||
LR = Emu.GetCPUThreadStop();
|
||||
custom_task = nullptr;
|
||||
last_function = nullptr;
|
||||
|
||||
auto at_ret = gsl::finally([&]()
|
||||
{
|
||||
if (std::uncaught_exception())
|
||||
{
|
||||
if (last_function)
|
||||
{
|
||||
LOG_ERROR(ARMv7, "'%s' aborted", last_function);
|
||||
}
|
||||
|
||||
last_function = old_func;
|
||||
}
|
||||
else
|
||||
{
|
||||
state -= cpu_flag::ret;
|
||||
PC = old_PC;
|
||||
LR = old_LR;
|
||||
last_function = old_func;
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
cpu_task_main();
|
||||
|
||||
if (SP != old_SP && !test(state, cpu_flag::ret + cpu_flag::exit)) // SP shouldn't change
|
||||
{
|
||||
fmt::throw_exception("Stack inconsistency (addr=0x%x, SP=0x%x, old=0x%x)", addr, SP, old_SP);
|
||||
}
|
||||
}
|
||||
catch (cpu_flag _s)
|
||||
{
|
||||
state += _s;
|
||||
if (_s != cpu_flag::ret) throw;
|
||||
}
|
||||
catch (EmulationStopped)
|
||||
{
|
||||
if (last_function) LOG_WARNING(ARMv7, "'%s' aborted", last_function);
|
||||
last_function = old_func;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (last_function) LOG_ERROR(ARMv7, "'%s' aborted", last_function);
|
||||
last_function = old_func;
|
||||
throw;
|
||||
}
|
||||
|
||||
state -= cpu_flag::ret;
|
||||
|
||||
PC = old_PC;
|
||||
SP = old_SP;
|
||||
LR = old_LR;
|
||||
custom_task = std::move(old_task);
|
||||
last_function = old_func;
|
||||
if (_s != cpu_flag::ret)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 ARMv7Thread::stack_push(u32 size, u32 align_v)
|
||||
|
|
|
@ -139,8 +139,6 @@ public:
|
|||
|
||||
const std::string m_name;
|
||||
|
||||
std::function<void(ARMv7Thread&)> custom_task;
|
||||
|
||||
const char* last_function = nullptr;
|
||||
|
||||
void write_pc(u32 value, u32 size)
|
||||
|
|
|
@ -312,7 +312,6 @@ void Emulator::Load()
|
|||
}
|
||||
|
||||
debug::autopause::reload();
|
||||
SendDbgCommand(DID_READY_EMU);
|
||||
if (g_cfg_autostart) Run();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
@ -340,8 +339,6 @@ void Emulator::Run()
|
|||
|
||||
rpcs3::on_run()();
|
||||
|
||||
SendDbgCommand(DID_START_EMU);
|
||||
|
||||
m_pause_start_time = 0;
|
||||
m_pause_amend_time = 0;
|
||||
m_status = Running;
|
||||
|
@ -355,8 +352,6 @@ void Emulator::Run()
|
|||
idm::select<ARMv7Thread>(on_select);
|
||||
idm::select<RawSPUThread>(on_select);
|
||||
idm::select<SPUThread>(on_select);
|
||||
|
||||
SendDbgCommand(DID_STARTED_EMU);
|
||||
}
|
||||
|
||||
bool Emulator::Pause()
|
||||
|
@ -377,8 +372,6 @@ bool Emulator::Pause()
|
|||
LOG_ERROR(GENERAL, "Emulator::Pause() error: concurrent access");
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_PAUSE_EMU);
|
||||
|
||||
auto on_select = [](u32, cpu_thread& cpu)
|
||||
{
|
||||
cpu.state += cpu_flag::dbg_global_pause;
|
||||
|
@ -388,9 +381,6 @@ bool Emulator::Pause()
|
|||
idm::select<ARMv7Thread>(on_select);
|
||||
idm::select<RawSPUThread>(on_select);
|
||||
idm::select<SPUThread>(on_select);
|
||||
|
||||
SendDbgCommand(DID_PAUSED_EMU);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -416,8 +406,6 @@ void Emulator::Resume()
|
|||
LOG_ERROR(GENERAL, "Emulator::Resume() error: concurrent access");
|
||||
}
|
||||
|
||||
SendDbgCommand(DID_RESUME_EMU);
|
||||
|
||||
auto on_select = [](u32, cpu_thread& cpu)
|
||||
{
|
||||
cpu.state -= cpu_flag::dbg_global_pause;
|
||||
|
@ -430,8 +418,6 @@ void Emulator::Resume()
|
|||
idm::select<SPUThread>(on_select);
|
||||
|
||||
rpcs3::on_resume()();
|
||||
|
||||
SendDbgCommand(DID_RESUMED_EMU);
|
||||
}
|
||||
|
||||
void Emulator::Stop()
|
||||
|
@ -444,12 +430,11 @@ void Emulator::Stop()
|
|||
LOG_NOTICE(GENERAL, "Stopping emulator...");
|
||||
|
||||
rpcs3::on_stop()();
|
||||
SendDbgCommand(DID_STOP_EMU);
|
||||
|
||||
auto on_select = [](u32, cpu_thread& cpu)
|
||||
{
|
||||
cpu.state += cpu_flag::dbg_global_stop;
|
||||
cpu.get()->set_exception(std::make_exception_ptr(EmulationStopped()));
|
||||
cpu.get()->set_exception(std::make_exception_ptr(cpu_flag::dbg_global_stop));
|
||||
};
|
||||
|
||||
idm::select<ppu_thread>(on_select);
|
||||
|
@ -476,8 +461,6 @@ void Emulator::Stop()
|
|||
RSXIOMem.Clear();
|
||||
vm::close();
|
||||
|
||||
SendDbgCommand(DID_STOPPED_EMU);
|
||||
|
||||
if (g_cfg_autoexit)
|
||||
{
|
||||
GetCallbacks().exit();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "VFS.h"
|
||||
#include "DbgCommand.h"
|
||||
|
||||
enum class system_type
|
||||
{
|
||||
|
@ -20,7 +19,6 @@ struct EmuCallbacks
|
|||
std::function<void(std::function<void()>)> call_after;
|
||||
std::function<void()> process_events;
|
||||
std::function<void()> exit;
|
||||
std::function<void(DbgCommand, class cpu_thread*)> send_dbg_command;
|
||||
std::function<std::shared_ptr<class KeyboardHandlerBase>()> get_kb_handler;
|
||||
std::function<std::shared_ptr<class MouseHandlerBase>()> get_mouse_handler;
|
||||
std::function<std::shared_ptr<class PadHandlerBase>()> get_pad_handler;
|
||||
|
@ -39,9 +37,6 @@ enum Status : u32
|
|||
Ready,
|
||||
};
|
||||
|
||||
// Emulation Stopped exception event
|
||||
class EmulationStopped {};
|
||||
|
||||
class Emulator final
|
||||
{
|
||||
atomic_t<u32> m_status;
|
||||
|
@ -71,11 +66,6 @@ public:
|
|||
return m_cb;
|
||||
}
|
||||
|
||||
void SendDbgCommand(DbgCommand cmd, class cpu_thread* thread = nullptr)
|
||||
{
|
||||
if (m_cb.send_dbg_command) m_cb.send_dbg_command(cmd, thread);
|
||||
}
|
||||
|
||||
// Call from the GUI thread
|
||||
void CallAfter(std::function<void()>&& func) const
|
||||
{
|
||||
|
@ -135,6 +125,7 @@ public:
|
|||
bool IsPaused() const { return m_status == Paused; }
|
||||
bool IsStopped() const { return m_status == Stopped; }
|
||||
bool IsReady() const { return m_status == Ready; }
|
||||
auto GetStatus() const { return m_status.load(); }
|
||||
};
|
||||
|
||||
extern Emulator Emu;
|
||||
|
|
|
@ -107,17 +107,11 @@ enum
|
|||
id_timer,
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(LogFrame, wxPanel)
|
||||
EVT_CLOSE(LogFrame::OnQuit)
|
||||
EVT_TIMER(id_timer, LogFrame::OnTimer)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
LogFrame::LogFrame(wxWindow* parent)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(600, 500))
|
||||
, m_tabs(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS)
|
||||
, m_log(new wxTextCtrl(&m_tabs, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2))
|
||||
, m_tty(new wxTextCtrl(&m_tabs, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2))
|
||||
, m_timer(this, id_timer)
|
||||
, m_cfg_level(g_gui_cfg["Log Level"])
|
||||
, m_cfg_tty(g_gui_cfg["Log TTY"])
|
||||
{
|
||||
|
@ -142,13 +136,12 @@ LogFrame::LogFrame(wxWindow* parent)
|
|||
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_level, id_log_level + 7);
|
||||
Bind(wxEVT_MENU, &LogFrame::OnContextMenu, this, id_log_tty);
|
||||
|
||||
Bind(wxEVT_CLOSE_WINDOW, [](wxCloseEvent& event) { event.Skip(); });
|
||||
|
||||
Show();
|
||||
|
||||
// Update listener info
|
||||
s_gui_listener.enabled = get_cfg_level();
|
||||
|
||||
// Check for updates every ~10 ms
|
||||
m_timer.Start(10);
|
||||
}
|
||||
|
||||
LogFrame::~LogFrame()
|
||||
|
@ -160,11 +153,6 @@ bool LogFrame::Close(bool force)
|
|||
return wxWindowBase::Close(force);
|
||||
}
|
||||
|
||||
void LogFrame::OnQuit(wxCloseEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// Deals with the RightClick on Log Console, shows up the Context Menu.
|
||||
void LogFrame::OnRightClick(wxMouseEvent& event)
|
||||
{
|
||||
|
@ -237,7 +225,7 @@ void LogFrame::OnContextMenu(wxCommandEvent& event)
|
|||
event.Skip();
|
||||
}
|
||||
|
||||
void LogFrame::OnTimer(wxTimerEvent& event)
|
||||
void LogFrame::UpdateUI()
|
||||
{
|
||||
std::vector<char> buf(4096);
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ class LogFrame : public wxPanel
|
|||
//Copy Action in Context Menu
|
||||
wxTextDataObject* m_tdo;
|
||||
|
||||
wxTimer m_timer;
|
||||
|
||||
YAML::Node m_cfg_level;
|
||||
YAML::Node m_cfg_tty;
|
||||
|
||||
|
@ -32,14 +30,9 @@ public:
|
|||
~LogFrame();
|
||||
|
||||
bool Close(bool force = false);
|
||||
void UpdateUI();
|
||||
|
||||
private:
|
||||
virtual void Task(){};
|
||||
|
||||
void OnQuit(wxCloseEvent& event);
|
||||
void OnRightClick(wxMouseEvent& event); // Show context menu
|
||||
void OnContextMenu(wxCommandEvent& event); // After select
|
||||
void OnTimer(wxTimerEvent& event);
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@ class DbgEmuPanel : public wxPanel
|
|||
wxButton* m_btn_stop;
|
||||
wxButton* m_btn_restart;
|
||||
wxButton* m_btn_capture_frame;
|
||||
u32 m_last_status = Ready;
|
||||
|
||||
public:
|
||||
DbgEmuPanel(wxWindow* parent) : wxPanel(parent)
|
||||
|
@ -43,30 +44,37 @@ public:
|
|||
Layout();
|
||||
|
||||
UpdateUI();
|
||||
wxGetApp().Bind(wxEVT_DBG_COMMAND, &DbgEmuPanel::HandleCommand, this);
|
||||
}
|
||||
|
||||
void UpdateUI()
|
||||
{
|
||||
m_btn_run->Enable(!Emu.IsStopped());
|
||||
m_btn_stop->Enable(!Emu.IsStopped());
|
||||
m_btn_restart->Enable(!Emu.GetPath().empty());
|
||||
const auto status = Emu.GetStatus();
|
||||
|
||||
if (m_last_status != status)
|
||||
{
|
||||
m_last_status = status;
|
||||
|
||||
m_btn_run->Enable(status != Stopped);
|
||||
m_btn_stop->Enable(status != Stopped);
|
||||
m_btn_restart->Enable(!Emu.GetPath().empty());
|
||||
m_btn_run->SetLabel(status == Paused ? "Resume" : status == Running ? "Pause" : "Run");
|
||||
}
|
||||
}
|
||||
|
||||
void OnRun(wxCommandEvent& event)
|
||||
{
|
||||
if(Emu.IsRunning())
|
||||
if (Emu.IsReady())
|
||||
{
|
||||
Emu.Run();
|
||||
}
|
||||
else if (Emu.IsRunning())
|
||||
{
|
||||
Emu.Pause();
|
||||
}
|
||||
else if(Emu.IsPaused())
|
||||
else if (Emu.IsPaused())
|
||||
{
|
||||
Emu.Resume();
|
||||
}
|
||||
else
|
||||
{
|
||||
Emu.Run();
|
||||
}
|
||||
}
|
||||
|
||||
void OnStop(wxCommandEvent& event)
|
||||
|
@ -84,37 +92,16 @@ public:
|
|||
{
|
||||
user_asked_for_frame_capture = true;
|
||||
}
|
||||
|
||||
void HandleCommand(wxCommandEvent& event)
|
||||
{
|
||||
event.Skip();
|
||||
|
||||
switch(event.GetId())
|
||||
{
|
||||
case DID_STOP_EMU:
|
||||
m_btn_run->SetLabel("Run");
|
||||
break;
|
||||
|
||||
case DID_PAUSE_EMU:
|
||||
m_btn_run->SetLabel("Resume");
|
||||
break;
|
||||
|
||||
case DID_START_EMU:
|
||||
case DID_RESUME_EMU:
|
||||
m_btn_run->SetLabel("Pause");
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
};
|
||||
|
||||
DebuggerPanel::DebuggerPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(400, 600), wxTAB_TRAVERSAL)
|
||||
{
|
||||
m_aui_mgr.SetManagedWindow(this);
|
||||
|
||||
m_aui_mgr.AddPane(new DbgEmuPanel(this), wxAuiPaneInfo().Top());
|
||||
m_aui_mgr.AddPane(new InterpreterDisAsmFrame(this), wxAuiPaneInfo().Center().CaptionVisible(false).CloseButton().MaximizeButton());
|
||||
m_dbg_panel = new DbgEmuPanel(this);
|
||||
m_disasm_frame = new InterpreterDisAsmFrame(this);
|
||||
m_aui_mgr.AddPane(m_dbg_panel, wxAuiPaneInfo().Top());
|
||||
m_aui_mgr.AddPane(m_disasm_frame, wxAuiPaneInfo().Center().CaptionVisible(false).CloseButton().MaximizeButton());
|
||||
m_aui_mgr.Update();
|
||||
}
|
||||
|
||||
|
@ -125,4 +112,6 @@ DebuggerPanel::~DebuggerPanel()
|
|||
|
||||
void DebuggerPanel::UpdateUI()
|
||||
{
|
||||
m_dbg_panel->UpdateUI();
|
||||
m_disasm_frame->UpdateUI();
|
||||
}
|
||||
|
|
|
@ -2,10 +2,16 @@
|
|||
#include <wx/listctrl.h>
|
||||
#include <wx/aui/aui.h>
|
||||
|
||||
class DbgEmuPanel;
|
||||
class InterpreterDisAsmFrame;
|
||||
|
||||
class DebuggerPanel : public wxPanel
|
||||
{
|
||||
wxAuiManager m_aui_mgr;
|
||||
|
||||
DbgEmuPanel* m_dbg_panel;
|
||||
InterpreterDisAsmFrame* m_disasm_frame;
|
||||
|
||||
public:
|
||||
DebuggerPanel(wxWindow* parent);
|
||||
~DebuggerPanel();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "InstructionEditor.h"
|
||||
|
||||
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm)
|
||||
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
||||
, pc(_pc)
|
||||
, cpu(_cpu)
|
||||
|
@ -61,6 +61,8 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u32 _pc, cpu_t
|
|||
s_panel_margin_x->Add(s_panel_margin_y);
|
||||
s_panel_margin_x->AddSpacer(12);
|
||||
|
||||
const auto cpu = _cpu.get();
|
||||
|
||||
const u32 cpu_offset = g_system == system_type::ps3 && cpu->id_type() != 1 ? static_cast<SPUThread&>(*cpu).offset : 0;
|
||||
|
||||
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
|
||||
|
|
|
@ -8,10 +8,10 @@ class InstructionEditorDialog : public wxDialog
|
|||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
cpu_thread* cpu;
|
||||
std::weak_ptr<cpu_thread> cpu;
|
||||
|
||||
public:
|
||||
InstructionEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm);
|
||||
InstructionEditorDialog(wxPanel *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm);
|
||||
|
||||
void updatePreview(wxCommandEvent& event);
|
||||
};
|
||||
|
|
|
@ -23,10 +23,17 @@ std::map<u32, bool> g_breakpoints;
|
|||
|
||||
u32 InterpreterDisAsmFrame::GetPc() const
|
||||
{
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (!cpu)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (g_system)
|
||||
{
|
||||
case system_type::ps3: return cpu->id_type() == 1 ? static_cast<ppu_thread*>(cpu)->cia : static_cast<SPUThread*>(cpu)->pc;
|
||||
case system_type::psv: return static_cast<ARMv7Thread*>(cpu)->PC;
|
||||
case system_type::ps3: return cpu->id_type() == 1 ? static_cast<ppu_thread*>(cpu.get())->cia : static_cast<SPUThread*>(cpu.get())->pc;
|
||||
case system_type::psv: return static_cast<ARMv7Thread*>(cpu.get())->PC;
|
||||
}
|
||||
|
||||
return 0xabadcafe;
|
||||
|
@ -40,7 +47,6 @@ u32 InterpreterDisAsmFrame::CentrePc(u32 pc) const
|
|||
InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(500, 700), wxTAB_TRAVERSAL)
|
||||
, m_pc(0)
|
||||
, cpu(nullptr)
|
||||
, m_item_count(30)
|
||||
{
|
||||
wxBoxSizer* s_p_main = new wxBoxSizer(wxVERTICAL);
|
||||
|
@ -68,19 +74,12 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
|
|||
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_DONTWRAP | wxNO_BORDER | wxTE_RICH2);
|
||||
m_regs->SetEditable(false);
|
||||
|
||||
//Call Stack
|
||||
m_calls = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_DONTWRAP | wxNO_BORDER | wxTE_RICH2);
|
||||
m_calls->SetEditable(false);
|
||||
|
||||
m_list->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_regs->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
m_calls->SetFont(wxFont(8, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
|
||||
|
||||
wxBoxSizer* s_w_list = new wxBoxSizer(wxHORIZONTAL);
|
||||
s_w_list->Add(m_list, 2, wxEXPAND | wxLEFT | wxDOWN, 5);
|
||||
s_w_list->Add(m_regs, 1, wxEXPAND | wxRIGHT | wxDOWN, 5);
|
||||
s_w_list->Add(m_calls, 1, wxEXPAND | wxRIGHT | wxDOWN, 5);
|
||||
|
||||
s_p_main->Add(s_b_main, 0, wxEXPAND | wxLEFT | wxRIGHT, 5);
|
||||
s_p_main->Add(s_w_list, 1, wxEXPAND | wxDOWN, 5);
|
||||
|
@ -107,7 +106,6 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
|
|||
|
||||
Bind(wxEVT_SIZE, &InterpreterDisAsmFrame::OnResize, this);
|
||||
Bind(wxEVT_KEY_DOWN, &InterpreterDisAsmFrame::OnKeyDown, this);
|
||||
wxGetApp().Bind(wxEVT_DBG_COMMAND, &InterpreterDisAsmFrame::HandleCommand, this);
|
||||
|
||||
ShowAddr(CentrePc(m_pc));
|
||||
UpdateUnitList();
|
||||
|
@ -117,8 +115,68 @@ InterpreterDisAsmFrame::~InterpreterDisAsmFrame()
|
|||
{
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::UpdateUI()
|
||||
{
|
||||
UpdateUnitList();
|
||||
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (!cpu)
|
||||
{
|
||||
if (m_last_pc != -1 || m_last_stat)
|
||||
{
|
||||
m_last_pc = -1;
|
||||
m_last_stat = 0;
|
||||
DoUpdate();
|
||||
|
||||
m_btn_run->Disable();
|
||||
m_btn_step->Disable();
|
||||
m_btn_pause->Disable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto cia = GetPc();
|
||||
const auto state = cpu->state.load();
|
||||
|
||||
if (m_last_pc != cia || m_last_stat != static_cast<u32>(state))
|
||||
{
|
||||
m_last_pc = cia;
|
||||
m_last_stat = static_cast<u32>(state);
|
||||
DoUpdate();
|
||||
|
||||
if (test(state & cpu_flag::dbg_pause))
|
||||
{
|
||||
m_btn_run->Enable();
|
||||
m_btn_step->Enable();
|
||||
m_btn_pause->Disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_btn_run->Disable();
|
||||
m_btn_step->Disable();
|
||||
m_btn_pause->Enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::UpdateUnitList()
|
||||
{
|
||||
const u64 threads_created = cpu_thread::g_threads_created;
|
||||
const u64 threads_deleted = cpu_thread::g_threads_deleted;
|
||||
|
||||
if (threads_created != m_threads_created || threads_deleted != m_threads_deleted)
|
||||
{
|
||||
m_threads_created = threads_created;
|
||||
m_threads_deleted = threads_deleted;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
m_choice_units->Freeze();
|
||||
m_choice_units->Clear();
|
||||
|
||||
|
@ -133,36 +191,41 @@ void InterpreterDisAsmFrame::UpdateUnitList()
|
|||
idm::select<SPUThread>(on_select);
|
||||
|
||||
m_choice_units->Thaw();
|
||||
m_choice_units->Update();
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
|
||||
{
|
||||
m_disasm.reset();
|
||||
|
||||
if (cpu = (cpu_thread*)event.GetClientData())
|
||||
const auto on_select = [&](u32, cpu_thread& cpu)
|
||||
{
|
||||
switch (g_system)
|
||||
{
|
||||
case system_type::ps3:
|
||||
{
|
||||
if (cpu->id_type() == 1)
|
||||
{
|
||||
m_disasm = std::make_unique<PPUDisAsm>(CPUDisAsm_InterpreterMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
|
||||
}
|
||||
return event.GetClientData() == &cpu;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case system_type::psv:
|
||||
{
|
||||
m_disasm = std::make_unique<ARMv7DisAsm>(CPUDisAsm_InterpreterMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (event.GetClientData() == nullptr)
|
||||
{
|
||||
// Nothing selected
|
||||
}
|
||||
else if (auto ppu = idm::select<ppu_thread>(on_select))
|
||||
{
|
||||
m_disasm = std::make_unique<PPUDisAsm>(CPUDisAsm_InterpreterMode);
|
||||
cpu = ppu.ptr;
|
||||
}
|
||||
else if (auto spu1 = idm::select<SPUThread>(on_select))
|
||||
{
|
||||
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
|
||||
cpu = spu1.ptr;
|
||||
}
|
||||
else if (auto rspu = idm::select<RawSPUThread>(on_select))
|
||||
{
|
||||
m_disasm = std::make_unique<SPUDisAsm>(CPUDisAsm_InterpreterMode);
|
||||
cpu = rspu.ptr;
|
||||
}
|
||||
else if (auto arm = idm::select<ARMv7Thread>(on_select))
|
||||
{
|
||||
m_disasm = std::make_unique<ARMv7DisAsm>(CPUDisAsm_InterpreterMode);
|
||||
cpu = arm.ptr;
|
||||
}
|
||||
|
||||
DoUpdate();
|
||||
|
@ -238,7 +301,6 @@ void InterpreterDisAsmFrame::DoUpdate()
|
|||
wxCommandEvent ce;
|
||||
Show_PC(ce);
|
||||
WriteRegs();
|
||||
WriteCallStack();
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::ShowAddr(u32 addr)
|
||||
|
@ -246,6 +308,8 @@ void InterpreterDisAsmFrame::ShowAddr(u32 addr)
|
|||
m_pc = addr;
|
||||
m_list->Freeze();
|
||||
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (!cpu)
|
||||
{
|
||||
for (uint i = 0; i<m_item_count; ++i, m_pc += 4)
|
||||
|
@ -291,6 +355,8 @@ void InterpreterDisAsmFrame::ShowAddr(u32 addr)
|
|||
|
||||
void InterpreterDisAsmFrame::WriteRegs()
|
||||
{
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (!cpu)
|
||||
{
|
||||
m_regs->Clear();
|
||||
|
@ -303,105 +369,6 @@ void InterpreterDisAsmFrame::WriteRegs()
|
|||
m_regs->Thaw();
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::WriteCallStack()
|
||||
{
|
||||
if (!cpu)
|
||||
{
|
||||
m_calls->Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
m_calls->Freeze();
|
||||
m_calls->Clear();
|
||||
//m_calls->WriteText(fmt::FromUTF8(data));
|
||||
m_calls->Thaw();
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::HandleCommand(wxCommandEvent& event)
|
||||
{
|
||||
cpu_thread* thr = (cpu_thread*)event.GetClientData();
|
||||
event.Skip();
|
||||
|
||||
if (!thr)
|
||||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case DID_STOPPED_EMU:
|
||||
UpdateUnitList();
|
||||
break;
|
||||
|
||||
case DID_PAUSED_EMU:
|
||||
//DoUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cpu && thr == cpu)
|
||||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case DID_PAUSE_THREAD:
|
||||
m_btn_run->Disable();
|
||||
m_btn_step->Disable();
|
||||
m_btn_pause->Disable();
|
||||
break;
|
||||
|
||||
case DID_PAUSED_THREAD:
|
||||
m_btn_run->Enable();
|
||||
m_btn_step->Enable();
|
||||
m_btn_pause->Disable();
|
||||
DoUpdate();
|
||||
break;
|
||||
|
||||
case DID_START_THREAD:
|
||||
case DID_EXEC_THREAD:
|
||||
case DID_RESUME_THREAD:
|
||||
m_btn_run->Disable();
|
||||
m_btn_step->Disable();
|
||||
m_btn_pause->Enable();
|
||||
break;
|
||||
|
||||
case DID_REMOVE_THREAD:
|
||||
case DID_STOP_THREAD:
|
||||
m_btn_run->Disable();
|
||||
m_btn_step->Disable();
|
||||
m_btn_pause->Disable();
|
||||
|
||||
if (event.GetId() == DID_REMOVE_THREAD)
|
||||
{
|
||||
//m_choice_units->SetSelection(-1);
|
||||
//wxCommandEvent event;
|
||||
//event.SetInt(-1);
|
||||
//event.SetClientData(nullptr);
|
||||
//OnSelectUnit(event);
|
||||
UpdateUnitList();
|
||||
//DoUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case DID_CREATE_THREAD:
|
||||
UpdateUnitList();
|
||||
if (m_choice_units->GetSelection() == -1)
|
||||
{
|
||||
//m_choice_units->SetSelection(0);
|
||||
//wxCommandEvent event;
|
||||
//event.SetInt(0);
|
||||
//event.SetClientData(&Emu.GetCPU().GetThreads()[0]);
|
||||
//OnSelectUnit(event);
|
||||
}
|
||||
break;
|
||||
|
||||
case DID_REMOVED_THREAD:
|
||||
UpdateUnitList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::OnUpdate(wxCommandEvent& event)
|
||||
{
|
||||
//WriteRegs();
|
||||
|
@ -425,6 +392,8 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
|
|||
|
||||
diag->SetSizerAndFit(s_panel);
|
||||
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (cpu) p_pc->SetValue(wxString::Format("%x", GetPc()));
|
||||
|
||||
if (diag->ShowModal() == wxID_OK)
|
||||
|
@ -437,21 +406,25 @@ void InterpreterDisAsmFrame::Show_Val(wxCommandEvent& WXUNUSED(event))
|
|||
|
||||
void InterpreterDisAsmFrame::Show_PC(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (cpu) ShowAddr(CentrePc(GetPc()));
|
||||
if (const auto cpu = this->cpu.lock()) ShowAddr(CentrePc(GetPc()));
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::DoRun(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (cpu && test(cpu->state & cpu_state_pause))
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
if (cpu && cpu->state.test_and_reset(cpu_flag::dbg_pause))
|
||||
{
|
||||
cpu->state -= cpu_flag::dbg_pause;
|
||||
cpu->notify();
|
||||
if (!test(cpu->state, cpu_state_pause))
|
||||
{
|
||||
cpu->notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (cpu)
|
||||
if (const auto cpu = this->cpu.lock())
|
||||
{
|
||||
cpu->state += cpu_flag::dbg_pause;
|
||||
}
|
||||
|
@ -459,7 +432,7 @@ void InterpreterDisAsmFrame::DoPause(wxCommandEvent& WXUNUSED(event))
|
|||
|
||||
void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (cpu)
|
||||
if (const auto cpu = this->cpu.lock())
|
||||
{
|
||||
if (test(cpu_flag::dbg_pause, cpu->state.fetch_op([](bs_t<cpu_flag>& state)
|
||||
{
|
||||
|
@ -474,6 +447,8 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
|
|||
|
||||
void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
|
||||
{
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
long i = m_list->GetFirstSelected();
|
||||
if (i < 0 || !cpu)
|
||||
{
|
||||
|
|
|
@ -9,20 +9,25 @@ class InterpreterDisAsmFrame : public wxPanel
|
|||
std::unique_ptr<CPUDisAsm> m_disasm;
|
||||
u32 m_pc;
|
||||
wxTextCtrl* m_regs;
|
||||
wxTextCtrl* m_calls;
|
||||
wxButton* m_btn_step;
|
||||
wxButton* m_btn_run;
|
||||
wxButton* m_btn_pause;
|
||||
u32 m_item_count;
|
||||
wxChoice* m_choice_units;
|
||||
|
||||
u64 m_threads_created = 0;
|
||||
u64 m_threads_deleted = 0;
|
||||
u32 m_last_pc = -1;
|
||||
u32 m_last_stat = 0;
|
||||
|
||||
public:
|
||||
cpu_thread* cpu;
|
||||
std::weak_ptr<cpu_thread> cpu;
|
||||
|
||||
public:
|
||||
InterpreterDisAsmFrame(wxWindow* parent);
|
||||
~InterpreterDisAsmFrame();
|
||||
|
||||
void UpdateUI();
|
||||
void UpdateUnitList();
|
||||
|
||||
u32 GetPc() const;
|
||||
|
@ -33,9 +38,7 @@ public:
|
|||
void DoUpdate();
|
||||
void ShowAddr(u32 addr);
|
||||
void WriteRegs();
|
||||
void WriteCallStack();
|
||||
|
||||
void HandleCommand(wxCommandEvent& event);
|
||||
void OnUpdate(wxCommandEvent& event);
|
||||
void Show_Val(wxCommandEvent& event);
|
||||
void Show_PC(wxCommandEvent& event);
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
#include "frame_icon.xpm"
|
||||
#endif
|
||||
|
||||
BEGIN_EVENT_TABLE(MainFrame, FrameBase)
|
||||
EVT_CLOSE(MainFrame::OnQuit)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
enum IDs
|
||||
{
|
||||
id_boot_elf = 0x555,
|
||||
|
@ -68,6 +64,7 @@ wxString GetPaneName()
|
|||
|
||||
MainFrame::MainFrame()
|
||||
: FrameBase(nullptr, wxID_ANY, "", "MainFrame", wxSize(900, 600))
|
||||
, m_timer(this, id_update_dbg)
|
||||
, m_aui_mgr(this)
|
||||
, m_sys_menu_opened(false)
|
||||
{
|
||||
|
@ -160,9 +157,17 @@ MainFrame::MainFrame()
|
|||
Bind(wxEVT_MENU, &MainFrame::AboutDialogHandler, this, id_help_about);
|
||||
|
||||
Bind(wxEVT_MENU, &MainFrame::UpdateUI, this, id_update_dbg);
|
||||
Bind(wxEVT_TIMER, &MainFrame::UpdateUI, this, id_update_dbg);
|
||||
Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent&)
|
||||
{
|
||||
DoSettings(false);
|
||||
TheApp->Exit();
|
||||
});
|
||||
|
||||
wxGetApp().Bind(wxEVT_KEY_DOWN, &MainFrame::OnKeyDown, this);
|
||||
wxGetApp().Bind(wxEVT_DBG_COMMAND, &MainFrame::UpdateUI, this);
|
||||
|
||||
// Check for updates every ~10 ms
|
||||
m_timer.Start(10);
|
||||
}
|
||||
|
||||
MainFrame::~MainFrame()
|
||||
|
@ -494,67 +499,11 @@ void MainFrame::AboutDialogHandler(wxCommandEvent& WXUNUSED(event))
|
|||
AboutDialog(this).ShowModal();
|
||||
}
|
||||
|
||||
void MainFrame::UpdateUI(wxCommandEvent& event)
|
||||
void MainFrame::UpdateUI(wxEvent& 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();
|
||||
}
|
||||
const bool is_running = Emu.IsRunning();
|
||||
const bool is_stopped = Emu.IsStopped();
|
||||
const bool is_ready = Emu.IsReady();
|
||||
|
||||
// Update menu items based on the state of the emulator
|
||||
wxMenuBar& menubar( *GetMenuBar() );
|
||||
|
@ -583,12 +532,12 @@ void MainFrame::UpdateUI(wxCommandEvent& event)
|
|||
memory_viewer.Enable(!is_stopped);
|
||||
rsx_debugger.Enable(!is_stopped);
|
||||
string_search.Enable(!is_stopped);
|
||||
}
|
||||
|
||||
void MainFrame::OnQuit(wxCloseEvent& event)
|
||||
{
|
||||
DoSettings(false);
|
||||
TheApp->Exit();
|
||||
// Debugger
|
||||
m_debugger_frame->UpdateUI();
|
||||
|
||||
// Logs
|
||||
m_log_frame->UpdateUI();
|
||||
}
|
||||
|
||||
void MainFrame::OnKeyDown(wxKeyEvent& event)
|
||||
|
|
|
@ -8,9 +8,10 @@ class GameViewer;
|
|||
|
||||
class MainFrame : public FrameBase
|
||||
{
|
||||
wxTimer m_timer;
|
||||
DebuggerPanel* m_debugger_frame;
|
||||
GameViewer* m_game_viewer;
|
||||
LogFrame * m_log_frame;
|
||||
LogFrame* m_log_frame;
|
||||
wxAuiManager m_aui_mgr;
|
||||
bool m_sys_menu_opened;
|
||||
|
||||
|
@ -22,8 +23,6 @@ public:
|
|||
void DoSettings(bool load);
|
||||
|
||||
private:
|
||||
void OnQuit(wxCloseEvent& event);
|
||||
|
||||
void BootGame(wxCommandEvent& event);
|
||||
void BootGameAndRun(wxCommandEvent& event);
|
||||
void InstallPkg(wxCommandEvent& event);
|
||||
|
@ -46,9 +45,6 @@ private:
|
|||
void OpenCgDisasm(wxCommandEvent& evt);
|
||||
void DecryptSPRXLibraries(wxCommandEvent& event);
|
||||
void AboutDialogHandler(wxCommandEvent& event);
|
||||
void UpdateUI(wxCommandEvent& event);
|
||||
void UpdateUI(wxEvent& event);
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
|
||||
private:
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "RegisterEditor.h"
|
||||
|
||||
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm)
|
||||
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm)
|
||||
: wxDialog(parent, wxID_ANY, "Edit registers")
|
||||
, pc(_pc)
|
||||
, cpu(_cpu)
|
||||
|
@ -86,6 +86,8 @@ RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread*
|
|||
|
||||
if (ShowModal() == wxID_OK)
|
||||
{
|
||||
const auto cpu = _cpu.get();
|
||||
|
||||
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
|
||||
std::string value = fmt::ToUTF8(t2_value->GetValue());
|
||||
|
||||
|
@ -166,12 +168,14 @@ RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread*
|
|||
|
||||
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
|
||||
{
|
||||
const auto cpu = this->cpu.lock();
|
||||
|
||||
std::string reg = fmt::ToUTF8(t1_register->GetStringSelection());
|
||||
std::string str;
|
||||
|
||||
if (g_system == system_type::ps3 && cpu->id_type() == 1)
|
||||
{
|
||||
auto& ppu = *static_cast<ppu_thread*>(cpu);
|
||||
auto& ppu = *static_cast<ppu_thread*>(cpu.get());
|
||||
|
||||
std::size_t first_brk = reg.find('[');
|
||||
if (first_brk != -1)
|
||||
|
@ -187,7 +191,7 @@ void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
|
|||
}
|
||||
else if (g_system == system_type::ps3 && cpu->id_type() != 1)
|
||||
{
|
||||
auto& spu = *static_cast<SPUThread*>(cpu);
|
||||
auto& spu = *static_cast<SPUThread*>(cpu.get());
|
||||
|
||||
std::string::size_type first_brk = reg.find('[');
|
||||
if (first_brk != std::string::npos)
|
||||
|
|
|
@ -9,10 +9,10 @@ class RegisterEditorDialog : public wxDialog
|
|||
wxStaticText* t3_preview;
|
||||
|
||||
public:
|
||||
cpu_thread* cpu;
|
||||
std::weak_ptr<cpu_thread> cpu;
|
||||
|
||||
public:
|
||||
RegisterEditorDialog(wxPanel *parent, u32 _pc, cpu_thread* _cpu, CPUDisAsm* _disasm);
|
||||
RegisterEditorDialog(wxPanel *parent, u32 _pc, const std::shared_ptr<cpu_thread>& _cpu, CPUDisAsm* _disasm);
|
||||
|
||||
void updateRegister(wxCommandEvent& event);
|
||||
};
|
||||
|
|
|
@ -606,7 +606,6 @@
|
|||
<ClInclude Include="Emu\Cell\SPUThread.h" />
|
||||
<ClInclude Include="Emu\CPU\CPUDisAsm.h" />
|
||||
<ClInclude Include="Emu\CPU\CPUThread.h" />
|
||||
<ClInclude Include="Emu\DbgCommand.h" />
|
||||
<ClInclude Include="Emu\Memory\wait_engine.h" />
|
||||
<ClInclude Include="Emu\RSX\Common\TextGlyphs.h" />
|
||||
<ClInclude Include="Emu\RSX\gcm_enums.h" />
|
||||
|
|
|
@ -1000,9 +1000,6 @@
|
|||
<ClInclude Include="..\Utilities\Timer.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\DbgCommand.h">
|
||||
<Filter>Emu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Utilities\Log.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -65,8 +65,6 @@ void save_gui_cfg()
|
|||
s_gui_cfg.write(out.c_str(), out.size());
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(wxEVT_DBG_COMMAND, wxCommandEvent);
|
||||
|
||||
IMPLEMENT_APP(Rpcs3App)
|
||||
Rpcs3App* TheApp;
|
||||
|
||||
|
@ -156,11 +154,6 @@ bool Rpcs3App::OnInit()
|
|||
wxGetApp().Exit();
|
||||
};
|
||||
|
||||
callbacks.send_dbg_command = [](DbgCommand id, cpu_thread* t)
|
||||
{
|
||||
wxGetApp().SendDbgCommand(id, t);
|
||||
};
|
||||
|
||||
callbacks.get_kb_handler = []{ return g_cfg_kb_handler.get()(); };
|
||||
|
||||
callbacks.get_mouse_handler = []{ return g_cfg_mouse_handler.get()(); };
|
||||
|
@ -245,13 +238,6 @@ void Rpcs3App::Exit()
|
|||
wxApp::Exit();
|
||||
}
|
||||
|
||||
void Rpcs3App::SendDbgCommand(DbgCommand id, cpu_thread* thr)
|
||||
{
|
||||
wxCommandEvent event(wxEVT_DBG_COMMAND, id);
|
||||
event.SetClientData(thr);
|
||||
AddPendingEvent(event);
|
||||
}
|
||||
|
||||
Rpcs3App::Rpcs3App()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "Gui/MainFrame.h"
|
||||
#include "Emu/DbgCommand.h"
|
||||
#include <wx/app.h>
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
wxDECLARE_EVENT(wxEVT_DBG_COMMAND, wxCommandEvent);
|
||||
|
||||
class Rpcs3App : public wxApp
|
||||
{
|
||||
private:
|
||||
|
@ -20,8 +17,6 @@ public:
|
|||
virtual void Exit();
|
||||
|
||||
Rpcs3App();
|
||||
|
||||
void SendDbgCommand(DbgCommand id, class cpu_thread* thr = nullptr);
|
||||
};
|
||||
|
||||
DECLARE_APP(Rpcs3App)
|
||||
|
|
Loading…
Add table
Reference in a new issue