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