mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 22:00:39 -06:00
PowerPC: Refactor to class, move to System.
This commit is contained in:
@ -18,6 +18,7 @@
|
||||
#include "Core/PowerPC/Expression.h"
|
||||
#include "Core/PowerPC/PPCSymbolDB.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "DolphinQt/Debugger/BreakpointDialog.h"
|
||||
#include "DolphinQt/Debugger/MemoryWidget.h"
|
||||
@ -34,7 +35,8 @@ enum CustomRole
|
||||
};
|
||||
}
|
||||
|
||||
BreakpointWidget::BreakpointWidget(QWidget* parent) : QDockWidget(parent)
|
||||
BreakpointWidget::BreakpointWidget(QWidget* parent)
|
||||
: QDockWidget(parent), m_system(Core::System::GetInstance())
|
||||
{
|
||||
setWindowTitle(tr("Breakpoints"));
|
||||
setObjectName(QStringLiteral("breakpoints"));
|
||||
@ -172,8 +174,12 @@ void BreakpointWidget::Update()
|
||||
return item;
|
||||
};
|
||||
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
auto& breakpoints = power_pc.GetBreakPoints();
|
||||
auto& memchecks = power_pc.GetMemChecks();
|
||||
|
||||
// Breakpoints
|
||||
for (const auto& bp : PowerPC::breakpoints.GetBreakPoints())
|
||||
for (const auto& bp : breakpoints.GetBreakPoints())
|
||||
{
|
||||
m_table->setRowCount(i + 1);
|
||||
|
||||
@ -215,7 +221,7 @@ void BreakpointWidget::Update()
|
||||
}
|
||||
|
||||
// Memory Breakpoints
|
||||
for (const auto& mbp : PowerPC::memchecks.GetMemChecks())
|
||||
for (const auto& mbp : memchecks.GetMemChecks())
|
||||
{
|
||||
m_table->setRowCount(i + 1);
|
||||
auto* active =
|
||||
@ -279,11 +285,11 @@ void BreakpointWidget::OnDelete()
|
||||
if (is_memcheck)
|
||||
{
|
||||
const QSignalBlocker blocker(Settings::Instance());
|
||||
PowerPC::memchecks.Remove(address);
|
||||
m_system.GetPowerPC().GetMemChecks().Remove(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerPC::breakpoints.Remove(address);
|
||||
m_system.GetPowerPC().GetBreakPoints().Remove(address);
|
||||
}
|
||||
|
||||
emit BreakpointsChanged();
|
||||
@ -292,10 +298,10 @@ void BreakpointWidget::OnDelete()
|
||||
|
||||
void BreakpointWidget::OnClear()
|
||||
{
|
||||
PowerPC::debug_interface.ClearAllBreakpoints();
|
||||
m_system.GetPowerPC().GetDebugInterface().ClearAllBreakpoints();
|
||||
{
|
||||
const QSignalBlocker blocker(Settings::Instance());
|
||||
PowerPC::debug_interface.ClearAllMemChecks();
|
||||
m_system.GetPowerPC().GetDebugInterface().ClearAllMemChecks();
|
||||
}
|
||||
|
||||
m_table->setRowCount(0);
|
||||
@ -314,12 +320,14 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp)
|
||||
{
|
||||
if (is_instruction_bp)
|
||||
{
|
||||
auto* dialog = new BreakpointDialog(this, PowerPC::breakpoints.GetBreakpoint(address));
|
||||
auto* dialog =
|
||||
new BreakpointDialog(this, m_system.GetPowerPC().GetBreakPoints().GetBreakpoint(address));
|
||||
dialog->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* dialog = new BreakpointDialog(this, PowerPC::memchecks.GetMemCheck(address));
|
||||
auto* dialog =
|
||||
new BreakpointDialog(this, m_system.GetPowerPC().GetMemChecks().GetMemCheck(address));
|
||||
dialog->exec();
|
||||
}
|
||||
|
||||
@ -339,16 +347,18 @@ void BreakpointWidget::OnLoad()
|
||||
BreakPoints::TBreakPointsStr new_bps;
|
||||
if (ini.GetLines("BreakPoints", &new_bps, false))
|
||||
{
|
||||
PowerPC::breakpoints.Clear();
|
||||
PowerPC::breakpoints.AddFromStrings(new_bps);
|
||||
auto& breakpoints = m_system.GetPowerPC().GetBreakPoints();
|
||||
breakpoints.Clear();
|
||||
breakpoints.AddFromStrings(new_bps);
|
||||
}
|
||||
|
||||
MemChecks::TMemChecksStr new_mcs;
|
||||
if (ini.GetLines("MemoryBreakPoints", &new_mcs, false))
|
||||
{
|
||||
PowerPC::memchecks.Clear();
|
||||
auto& memchecks = m_system.GetPowerPC().GetMemChecks();
|
||||
memchecks.Clear();
|
||||
const QSignalBlocker blocker(Settings::Instance());
|
||||
PowerPC::memchecks.AddFromStrings(new_mcs);
|
||||
memchecks.AddFromStrings(new_mcs);
|
||||
}
|
||||
|
||||
emit BreakpointsChanged();
|
||||
@ -360,8 +370,8 @@ void BreakpointWidget::OnSave()
|
||||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false);
|
||||
ini.SetLines("BreakPoints", PowerPC::breakpoints.GetStrings());
|
||||
ini.SetLines("MemoryBreakPoints", PowerPC::memchecks.GetStrings());
|
||||
ini.SetLines("BreakPoints", m_system.GetPowerPC().GetBreakPoints().GetStrings());
|
||||
ini.SetLines("MemoryBreakPoints", m_system.GetPowerPC().GetMemChecks().GetStrings());
|
||||
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini");
|
||||
}
|
||||
|
||||
@ -381,7 +391,7 @@ void BreakpointWidget::OnContextMenu()
|
||||
|
||||
if (!is_memory_breakpoint)
|
||||
{
|
||||
const auto& inst_breakpoints = PowerPC::breakpoints.GetBreakPoints();
|
||||
const auto& inst_breakpoints = m_system.GetPowerPC().GetBreakPoints().GetBreakPoints();
|
||||
const auto bp_iter =
|
||||
std::find_if(inst_breakpoints.begin(), inst_breakpoints.end(),
|
||||
[bp_address](const auto& bp) { return bp.address == bp_address; });
|
||||
@ -390,7 +400,7 @@ void BreakpointWidget::OnContextMenu()
|
||||
|
||||
menu->addAction(tr("Show in Code"), [this, bp_address] { emit ShowCode(bp_address); });
|
||||
menu->addAction(bp_iter->is_enabled ? tr("Disable") : tr("Enable"), [this, &bp_address]() {
|
||||
PowerPC::breakpoints.ToggleBreakPoint(bp_address);
|
||||
m_system.GetPowerPC().GetBreakPoints().ToggleBreakPoint(bp_address);
|
||||
|
||||
emit BreakpointsChanged();
|
||||
Update();
|
||||
@ -398,7 +408,7 @@ void BreakpointWidget::OnContextMenu()
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& memory_breakpoints = PowerPC::memchecks.GetMemChecks();
|
||||
const auto& memory_breakpoints = m_system.GetPowerPC().GetMemChecks().GetMemChecks();
|
||||
const auto mb_iter =
|
||||
std::find_if(memory_breakpoints.begin(), memory_breakpoints.end(),
|
||||
[bp_address](const auto& bp) { return bp.start_address == bp_address; });
|
||||
@ -407,7 +417,7 @@ void BreakpointWidget::OnContextMenu()
|
||||
|
||||
menu->addAction(tr("Show in Memory"), [this, bp_address] { emit ShowMemory(bp_address); });
|
||||
menu->addAction(mb_iter->is_enabled ? tr("Disable") : tr("Enable"), [this, &bp_address]() {
|
||||
PowerPC::memchecks.ToggleBreakPoint(bp_address);
|
||||
m_system.GetPowerPC().GetMemChecks().ToggleBreakPoint(bp_address);
|
||||
|
||||
emit BreakpointsChanged();
|
||||
Update();
|
||||
@ -428,7 +438,7 @@ void BreakpointWidget::AddBP(u32 addr)
|
||||
void BreakpointWidget::AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit,
|
||||
const QString& condition)
|
||||
{
|
||||
PowerPC::breakpoints.Add(
|
||||
m_system.GetPowerPC().GetBreakPoints().Add(
|
||||
addr, temp, break_on_hit, log_on_hit,
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt);
|
||||
|
||||
@ -452,7 +462,7 @@ void BreakpointWidget::AddAddressMBP(u32 addr, bool on_read, bool on_write, bool
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt;
|
||||
{
|
||||
const QSignalBlocker blocker(Settings::Instance());
|
||||
PowerPC::memchecks.Add(std::move(check));
|
||||
m_system.GetPowerPC().GetMemChecks().Add(std::move(check));
|
||||
}
|
||||
|
||||
emit BreakpointsChanged();
|
||||
@ -475,7 +485,7 @@ void BreakpointWidget::AddRangedMBP(u32 from, u32 to, bool on_read, bool on_writ
|
||||
!condition.isEmpty() ? Expression::TryParse(condition.toUtf8().constData()) : std::nullopt;
|
||||
{
|
||||
const QSignalBlocker blocker(Settings::Instance());
|
||||
PowerPC::memchecks.Add(std::move(check));
|
||||
m_system.GetPowerPC().GetMemChecks().Add(std::move(check));
|
||||
}
|
||||
|
||||
emit BreakpointsChanged();
|
||||
|
@ -12,6 +12,10 @@ class QCloseEvent;
|
||||
class QShowEvent;
|
||||
class QTableWidget;
|
||||
class QToolBar;
|
||||
namespace Core
|
||||
{
|
||||
class System;
|
||||
}
|
||||
|
||||
class BreakpointWidget : public QDockWidget
|
||||
{
|
||||
@ -51,6 +55,8 @@ private:
|
||||
|
||||
void UpdateIcons();
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
QToolBar* m_toolbar;
|
||||
QTableWidget* m_table;
|
||||
QAction* m_new;
|
||||
|
@ -487,8 +487,9 @@ void CodeDiffDialog::OnSetBLR()
|
||||
return;
|
||||
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
PowerPC::debug_interface.SetPatch(guard, symbol->address, 0x4E800020);
|
||||
auto& system = Core::System::GetInstance();
|
||||
Core::CPUThreadGuard guard(system);
|
||||
system.GetPowerPC().GetDebugInterface().SetPatch(guard, symbol->address, 0x4E800020);
|
||||
}
|
||||
|
||||
int row = item->row();
|
||||
|
@ -184,7 +184,7 @@ CodeViewWidget::~CodeViewWidget() = default;
|
||||
|
||||
static u32 GetBranchFromAddress(const Core::CPUThreadGuard& guard, u32 addr)
|
||||
{
|
||||
std::string disasm = PowerPC::debug_interface.Disassemble(&guard, addr);
|
||||
std::string disasm = guard.GetSystem().GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
|
||||
size_t pos = disasm.find("->0x");
|
||||
|
||||
if (pos == std::string::npos)
|
||||
@ -294,8 +294,11 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
|
||||
for (int i = 0; i < rows; i++)
|
||||
setRowHeight(i, rowh);
|
||||
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
auto& debug_interface = power_pc.GetDebugInterface();
|
||||
|
||||
const std::optional<u32> pc =
|
||||
guard ? std::make_optional(m_system.GetPPCState().pc) : std::nullopt;
|
||||
guard ? std::make_optional(power_pc.GetPPCState().pc) : std::nullopt;
|
||||
|
||||
const bool dark_theme = qApp->palette().color(QPalette::Base).valueF() < 0.5;
|
||||
|
||||
@ -304,16 +307,16 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
|
||||
for (int i = 0; i < rowCount(); i++)
|
||||
{
|
||||
const u32 addr = AddressForRow(i);
|
||||
const u32 color = PowerPC::debug_interface.GetColor(guard, addr);
|
||||
const u32 color = debug_interface.GetColor(guard, addr);
|
||||
auto* bp_item = new QTableWidgetItem;
|
||||
auto* addr_item = new QTableWidgetItem(QStringLiteral("%1").arg(addr, 8, 16, QLatin1Char('0')));
|
||||
|
||||
std::string disas = PowerPC::debug_interface.Disassemble(guard, addr);
|
||||
std::string disas = debug_interface.Disassemble(guard, addr);
|
||||
auto split = disas.find('\t');
|
||||
|
||||
std::string ins = (split == std::string::npos ? disas : disas.substr(0, split));
|
||||
std::string param = (split == std::string::npos ? "" : disas.substr(split + 1));
|
||||
std::string desc = PowerPC::debug_interface.GetDescription(addr);
|
||||
std::string desc = debug_interface.GetDescription(addr);
|
||||
|
||||
// Adds whitespace and a minimum size to ins and param. Helps to prevent frequent resizing while
|
||||
// scrolling.
|
||||
@ -360,19 +363,19 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
|
||||
branch.dst_addr = branch_addr;
|
||||
branch.is_link = IsBranchInstructionWithLink(ins);
|
||||
|
||||
description_item->setText(tr("--> %1").arg(
|
||||
QString::fromStdString(PowerPC::debug_interface.GetDescription(branch_addr))));
|
||||
description_item->setText(
|
||||
tr("--> %1").arg(QString::fromStdString(debug_interface.GetDescription(branch_addr))));
|
||||
param_item->setForeground(Qt::magenta);
|
||||
}
|
||||
|
||||
if (ins == "blr")
|
||||
ins_item->setForeground(dark_theme ? QColor(0xa0FFa0) : Qt::darkGreen);
|
||||
|
||||
if (PowerPC::debug_interface.IsBreakpoint(addr))
|
||||
if (debug_interface.IsBreakpoint(addr))
|
||||
{
|
||||
auto icon =
|
||||
Resources::GetScaledThemeIcon("debugger_breakpoint").pixmap(QSize(rowh - 2, rowh - 2));
|
||||
if (!PowerPC::breakpoints.IsBreakPointEnable(addr))
|
||||
if (!m_system.GetPowerPC().GetBreakPoints().IsBreakPointEnable(addr))
|
||||
{
|
||||
QPixmap disabled_icon(icon.size());
|
||||
disabled_icon.fill(Qt::transparent);
|
||||
@ -536,8 +539,8 @@ void CodeViewWidget::ReplaceAddress(u32 address, ReplaceWith replace)
|
||||
{
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
PowerPC::debug_interface.SetPatch(guard, address,
|
||||
replace == ReplaceWith::BLR ? 0x4e800020 : 0x60000000);
|
||||
m_system.GetPowerPC().GetDebugInterface().SetPatch(
|
||||
guard, address, replace == ReplaceWith::BLR ? 0x4e800020 : 0x60000000);
|
||||
|
||||
Update(&guard);
|
||||
}
|
||||
@ -598,7 +601,7 @@ void CodeViewWidget::OnContextMenu()
|
||||
{
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
const u32 pc = m_system.GetPPCState().pc;
|
||||
const std::string disasm = PowerPC::debug_interface.Disassemble(&guard, pc);
|
||||
const std::string disasm = m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, pc);
|
||||
|
||||
if (addr == pc)
|
||||
{
|
||||
@ -642,7 +645,8 @@ void CodeViewWidget::OnContextMenu()
|
||||
action->setEnabled(valid_load_store);
|
||||
}
|
||||
|
||||
restore_action->setEnabled(running && PowerPC::debug_interface.HasEnabledPatch(addr));
|
||||
restore_action->setEnabled(running &&
|
||||
m_system.GetPowerPC().GetDebugInterface().HasEnabledPatch(addr));
|
||||
|
||||
menu->exec(QCursor::pos());
|
||||
Update();
|
||||
@ -745,14 +749,14 @@ void CodeViewWidget::OnCopyTargetAddress()
|
||||
|
||||
const std::string code_line = [this, addr] {
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
return PowerPC::debug_interface.Disassemble(&guard, addr);
|
||||
return m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
|
||||
}();
|
||||
|
||||
if (!IsInstructionLoadStore(code_line))
|
||||
return;
|
||||
|
||||
const std::optional<u32> target_addr =
|
||||
PowerPC::debug_interface.GetMemoryAddressFromInstruction(code_line);
|
||||
m_system.GetPowerPC().GetDebugInterface().GetMemoryAddressFromInstruction(code_line);
|
||||
|
||||
if (target_addr)
|
||||
{
|
||||
@ -775,14 +779,14 @@ void CodeViewWidget::OnShowTargetInMemory()
|
||||
|
||||
const std::string code_line = [this, addr] {
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
return PowerPC::debug_interface.Disassemble(&guard, addr);
|
||||
return m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
|
||||
}();
|
||||
|
||||
if (!IsInstructionLoadStore(code_line))
|
||||
return;
|
||||
|
||||
const std::optional<u32> target_addr =
|
||||
PowerPC::debug_interface.GetMemoryAddressFromInstruction(code_line);
|
||||
m_system.GetPowerPC().GetDebugInterface().GetMemoryAddressFromInstruction(code_line);
|
||||
|
||||
if (target_addr)
|
||||
emit ShowMemory(*target_addr);
|
||||
@ -794,7 +798,7 @@ void CodeViewWidget::OnCopyCode()
|
||||
|
||||
const std::string text = [this, addr] {
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
return PowerPC::debug_interface.Disassemble(&guard, addr);
|
||||
return m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
|
||||
}();
|
||||
|
||||
QApplication::clipboard()->setText(QString::fromStdString(text));
|
||||
@ -818,7 +822,8 @@ void CodeViewWidget::OnCopyFunction()
|
||||
const u32 end = start + symbol->size;
|
||||
for (u32 addr = start; addr != end; addr += 4)
|
||||
{
|
||||
const std::string disasm = PowerPC::debug_interface.Disassemble(&guard, addr);
|
||||
const std::string disasm =
|
||||
m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
|
||||
fmt::format_to(std::back_inserter(text), "{:08x}: {}\r\n", addr, disasm);
|
||||
}
|
||||
}
|
||||
@ -832,7 +837,7 @@ void CodeViewWidget::OnCopyHex()
|
||||
|
||||
const u32 instruction = [this, addr] {
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
return PowerPC::debug_interface.ReadInstruction(guard, addr);
|
||||
return m_system.GetPowerPC().GetDebugInterface().ReadInstruction(guard, addr);
|
||||
}();
|
||||
|
||||
QApplication::clipboard()->setText(
|
||||
@ -843,8 +848,8 @@ void CodeViewWidget::OnRunToHere()
|
||||
{
|
||||
const u32 addr = GetContextAddress();
|
||||
|
||||
PowerPC::debug_interface.SetBreakpoint(addr);
|
||||
PowerPC::debug_interface.RunToBreakpoint();
|
||||
m_system.GetPowerPC().GetDebugInterface().SetBreakpoint(addr);
|
||||
m_system.GetPowerPC().GetDebugInterface().RunToBreakpoint();
|
||||
Update();
|
||||
}
|
||||
|
||||
@ -997,11 +1002,12 @@ void CodeViewWidget::OnReplaceInstruction()
|
||||
if (!read_result.valid)
|
||||
return;
|
||||
|
||||
PatchInstructionDialog dialog(this, addr, PowerPC::debug_interface.ReadInstruction(guard, addr));
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
PatchInstructionDialog dialog(this, addr, debug_interface.ReadInstruction(guard, addr));
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted)
|
||||
{
|
||||
PowerPC::debug_interface.SetPatch(guard, addr, dialog.GetCode());
|
||||
debug_interface.SetPatch(guard, addr, dialog.GetCode());
|
||||
Update(&guard);
|
||||
}
|
||||
}
|
||||
@ -1012,7 +1018,7 @@ void CodeViewWidget::OnRestoreInstruction()
|
||||
|
||||
const u32 addr = GetContextAddress();
|
||||
|
||||
PowerPC::debug_interface.UnsetPatch(guard, addr);
|
||||
m_system.GetPowerPC().GetDebugInterface().UnsetPatch(guard, addr);
|
||||
Update(&guard);
|
||||
}
|
||||
|
||||
@ -1091,10 +1097,11 @@ void CodeViewWidget::showEvent(QShowEvent* event)
|
||||
|
||||
void CodeViewWidget::ToggleBreakpoint()
|
||||
{
|
||||
if (PowerPC::debug_interface.IsBreakpoint(GetContextAddress()))
|
||||
PowerPC::breakpoints.Remove(GetContextAddress());
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
if (power_pc.GetDebugInterface().IsBreakpoint(GetContextAddress()))
|
||||
power_pc.GetBreakPoints().Remove(GetContextAddress());
|
||||
else
|
||||
PowerPC::breakpoints.Add(GetContextAddress());
|
||||
power_pc.GetBreakPoints().Add(GetContextAddress());
|
||||
|
||||
emit BreakpointsChanged();
|
||||
Update();
|
||||
@ -1102,7 +1109,7 @@ void CodeViewWidget::ToggleBreakpoint()
|
||||
|
||||
void CodeViewWidget::AddBreakpoint()
|
||||
{
|
||||
PowerPC::breakpoints.Add(GetContextAddress());
|
||||
m_system.GetPowerPC().GetBreakPoints().Add(GetContextAddress());
|
||||
|
||||
emit BreakpointsChanged();
|
||||
Update();
|
||||
|
@ -442,12 +442,13 @@ void CodeWidget::Step()
|
||||
|
||||
Common::Event sync_event;
|
||||
|
||||
PowerPC::CoreMode old_mode = PowerPC::GetMode();
|
||||
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
|
||||
PowerPC::breakpoints.ClearAllTemporary();
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
PowerPC::CoreMode old_mode = power_pc.GetMode();
|
||||
power_pc.SetMode(PowerPC::CoreMode::Interpreter);
|
||||
power_pc.GetBreakPoints().ClearAllTemporary();
|
||||
cpu.StepOpcode(&sync_event);
|
||||
sync_event.WaitFor(std::chrono::milliseconds(20));
|
||||
PowerPC::SetMode(old_mode);
|
||||
power_pc.SetMode(old_mode);
|
||||
Core::DisplayMessage(tr("Step successful!").toStdString(), 2000);
|
||||
// Will get a UpdateDisasmDialog(), don't update the GUI here.
|
||||
}
|
||||
@ -466,8 +467,9 @@ void CodeWidget::StepOver()
|
||||
|
||||
if (inst.LK)
|
||||
{
|
||||
PowerPC::breakpoints.ClearAllTemporary();
|
||||
PowerPC::breakpoints.Add(m_system.GetPPCState().pc + 4, true);
|
||||
auto& breakpoints = m_system.GetPowerPC().GetBreakPoints();
|
||||
breakpoints.ClearAllTemporary();
|
||||
breakpoints.Add(m_system.GetPPCState().pc + 4, true);
|
||||
cpu.EnableStepping(false);
|
||||
Core::DisplayMessage(tr("Step over in progress...").toStdString(), 2000);
|
||||
}
|
||||
@ -501,14 +503,16 @@ void CodeWidget::StepOut()
|
||||
using clock = std::chrono::steady_clock;
|
||||
clock::time_point timeout = clock::now() + std::chrono::seconds(5);
|
||||
|
||||
auto& ppc_state = m_system.GetPPCState();
|
||||
auto& power_pc = m_system.GetPowerPC();
|
||||
auto& ppc_state = power_pc.GetPPCState();
|
||||
auto& breakpoints = power_pc.GetBreakPoints();
|
||||
{
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
PowerPC::breakpoints.ClearAllTemporary();
|
||||
breakpoints.ClearAllTemporary();
|
||||
|
||||
PowerPC::CoreMode old_mode = PowerPC::GetMode();
|
||||
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
|
||||
PowerPC::CoreMode old_mode = power_pc.GetMode();
|
||||
power_pc.SetMode(PowerPC::CoreMode::Interpreter);
|
||||
|
||||
// Loop until either the current instruction is a return instruction with no Link flag
|
||||
// or a breakpoint is detected so it can step at the breakpoint. If the PC is currently
|
||||
@ -518,7 +522,7 @@ void CodeWidget::StepOut()
|
||||
{
|
||||
if (WillInstructionReturn(m_system, inst))
|
||||
{
|
||||
PowerPC::SingleStep();
|
||||
power_pc.SingleStep();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -528,24 +532,24 @@ void CodeWidget::StepOut()
|
||||
u32 next_pc = ppc_state.pc + 4;
|
||||
do
|
||||
{
|
||||
PowerPC::SingleStep();
|
||||
power_pc.SingleStep();
|
||||
} while (ppc_state.pc != next_pc && clock::now() < timeout &&
|
||||
!PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc));
|
||||
!breakpoints.IsAddressBreakPoint(ppc_state.pc));
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerPC::SingleStep();
|
||||
power_pc.SingleStep();
|
||||
}
|
||||
|
||||
inst = PowerPC::MMU::HostRead_Instruction(guard, ppc_state.pc);
|
||||
} while (clock::now() < timeout && !PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc));
|
||||
} while (clock::now() < timeout && !breakpoints.IsAddressBreakPoint(ppc_state.pc));
|
||||
|
||||
PowerPC::SetMode(old_mode);
|
||||
power_pc.SetMode(old_mode);
|
||||
}
|
||||
|
||||
emit Host::GetInstance()->UpdateDisasmDialog();
|
||||
|
||||
if (PowerPC::breakpoints.IsAddressBreakPoint(ppc_state.pc))
|
||||
if (breakpoints.IsAddressBreakPoint(ppc_state.pc))
|
||||
Core::DisplayMessage(tr("Breakpoint encountered! Step out aborted.").toStdString(), 2000);
|
||||
else if (clock::now() >= timeout)
|
||||
Core::DisplayMessage(tr("Step out timed out!").toStdString(), 2000);
|
||||
|
@ -170,7 +170,8 @@ private:
|
||||
MemoryViewWidget* m_view;
|
||||
};
|
||||
|
||||
MemoryViewWidget::MemoryViewWidget(QWidget* parent) : QWidget(parent)
|
||||
MemoryViewWidget::MemoryViewWidget(QWidget* parent)
|
||||
: QWidget(parent), m_system(Core::System::GetInstance())
|
||||
{
|
||||
auto* layout = new QHBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
@ -571,7 +572,7 @@ void MemoryViewWidget::UpdateBreakpointTags()
|
||||
}
|
||||
|
||||
if (m_address_space == AddressSpace::Type::Effective &&
|
||||
PowerPC::memchecks.GetMemCheck(address, GetTypeSize(m_type)) != nullptr)
|
||||
m_system.GetPowerPC().GetMemChecks().GetMemCheck(address, GetTypeSize(m_type)) != nullptr)
|
||||
{
|
||||
row_breakpoint = true;
|
||||
cell->setBackground(Qt::red);
|
||||
@ -808,15 +809,17 @@ void MemoryViewWidget::ToggleBreakpoint(u32 addr, bool row)
|
||||
const int breaks = row ? (m_bytes_per_row / length) : 1;
|
||||
bool overlap = false;
|
||||
|
||||
auto& memchecks = m_system.GetPowerPC().GetMemChecks();
|
||||
|
||||
// Row breakpoint should either remove any breakpoint left on the row, or activate all
|
||||
// breakpoints.
|
||||
if (row && PowerPC::memchecks.OverlapsMemcheck(addr, m_bytes_per_row))
|
||||
if (row && memchecks.OverlapsMemcheck(addr, m_bytes_per_row))
|
||||
overlap = true;
|
||||
|
||||
for (int i = 0; i < breaks; i++)
|
||||
{
|
||||
u32 address = addr + length * i;
|
||||
TMemCheck* check_ptr = PowerPC::memchecks.GetMemCheck(address, length);
|
||||
TMemCheck* check_ptr = memchecks.GetMemCheck(address, length);
|
||||
|
||||
if (check_ptr == nullptr && !overlap)
|
||||
{
|
||||
@ -829,12 +832,12 @@ void MemoryViewWidget::ToggleBreakpoint(u32 addr, bool row)
|
||||
check.log_on_hit = m_do_log;
|
||||
check.break_on_hit = true;
|
||||
|
||||
PowerPC::memchecks.Add(std::move(check));
|
||||
memchecks.Add(std::move(check));
|
||||
}
|
||||
else if (check_ptr != nullptr)
|
||||
{
|
||||
// Using the pointer fixes misaligned breakpoints (0x11 breakpoint in 0x10 aligned view).
|
||||
PowerPC::memchecks.Remove(check_ptr->start_address);
|
||||
memchecks.Remove(check_ptr->start_address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,8 @@ enum class Type;
|
||||
namespace Core
|
||||
{
|
||||
class CPUThreadGuard;
|
||||
}
|
||||
class System;
|
||||
} // namespace Core
|
||||
|
||||
class MemoryViewTable;
|
||||
|
||||
@ -85,6 +86,8 @@ private:
|
||||
void ScrollbarSliderReleased();
|
||||
QString ValueToString(const Core::CPUThreadGuard& guard, u32 address, Type type);
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
MemoryViewTable* m_table;
|
||||
QScrollBar* m_scrollbar;
|
||||
AddressSpace::Type m_address_space{};
|
||||
|
@ -409,7 +409,9 @@ void RegisterWidget::PopulateTable()
|
||||
|
||||
// Special registers
|
||||
// TB
|
||||
AddRegister(16, 5, RegisterType::tb, "TB", PowerPC::ReadFullTimeBaseValue, nullptr);
|
||||
AddRegister(
|
||||
16, 5, RegisterType::tb, "TB",
|
||||
[this] { return m_system.GetPowerPC().ReadFullTimeBaseValue(); }, nullptr);
|
||||
|
||||
// PC
|
||||
AddRegister(
|
||||
|
@ -314,7 +314,7 @@ void ThreadWidget::Update()
|
||||
m_queue_tail->setText(format_hex_from(guard, 0x800000E0));
|
||||
|
||||
// Thread group
|
||||
m_threads = PowerPC::debug_interface.GetThreads(guard);
|
||||
m_threads = guard.GetSystem().GetPowerPC().GetDebugInterface().GetThreads(guard);
|
||||
|
||||
int i = 0;
|
||||
m_thread_table->setRowCount(i);
|
||||
@ -458,9 +458,10 @@ void ThreadWidget::UpdateThreadCallstack(const Core::CPUThreadGuard& guard,
|
||||
{
|
||||
const u32 lr_save = PowerPC::MMU::HostRead_U32(guard, sp + 4);
|
||||
m_callstack_table->setItem(i, 2, new QTableWidgetItem(format_hex(lr_save)));
|
||||
m_callstack_table->setItem(i, 3,
|
||||
new QTableWidgetItem(QString::fromStdString(
|
||||
PowerPC::debug_interface.GetDescription(lr_save))));
|
||||
m_callstack_table->setItem(
|
||||
i, 3,
|
||||
new QTableWidgetItem(QString::fromStdString(
|
||||
guard.GetSystem().GetPowerPC().GetDebugInterface().GetDescription(lr_save))));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -23,7 +23,8 @@
|
||||
#include "DolphinQt/Resources.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
WatchWidget::WatchWidget(QWidget* parent) : QDockWidget(parent)
|
||||
WatchWidget::WatchWidget(QWidget* parent)
|
||||
: QDockWidget(parent), m_system(Core::System::GetInstance())
|
||||
{
|
||||
// i18n: This kind of "watch" is used for watching emulated memory.
|
||||
// It's not related to timekeeping devices.
|
||||
@ -167,15 +168,16 @@ void WatchWidget::Update()
|
||||
m_table->setDisabled(false);
|
||||
m_table->clearContents();
|
||||
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
auto& debug_interface = guard.GetSystem().GetPowerPC().GetDebugInterface();
|
||||
|
||||
int size = static_cast<int>(PowerPC::debug_interface.GetWatches().size());
|
||||
int size = static_cast<int>(debug_interface.GetWatches().size());
|
||||
|
||||
m_table->setRowCount(size + 1);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
const auto& entry = PowerPC::debug_interface.GetWatch(i);
|
||||
const auto& entry = debug_interface.GetWatch(i);
|
||||
|
||||
auto* label = new QTableWidgetItem(QString::fromStdString(entry.name));
|
||||
auto* address =
|
||||
@ -263,7 +265,7 @@ void WatchWidget::OnDelete()
|
||||
|
||||
void WatchWidget::OnClear()
|
||||
{
|
||||
PowerPC::debug_interface.ClearWatches();
|
||||
m_system.GetPowerPC().GetDebugInterface().ClearWatches();
|
||||
Update();
|
||||
}
|
||||
|
||||
@ -297,16 +299,17 @@ void WatchWidget::OnLoad()
|
||||
return;
|
||||
}
|
||||
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
if (ini.GetLines("Watches", &watches, false))
|
||||
{
|
||||
for (const auto& watch : PowerPC::debug_interface.GetWatches())
|
||||
auto& debug_interface = guard.GetSystem().GetPowerPC().GetDebugInterface();
|
||||
for (const auto& watch : debug_interface.GetWatches())
|
||||
{
|
||||
PowerPC::debug_interface.UnsetPatch(guard, watch.address);
|
||||
debug_interface.UnsetPatch(guard, watch.address);
|
||||
}
|
||||
PowerPC::debug_interface.ClearWatches();
|
||||
PowerPC::debug_interface.LoadWatchesFromStrings(watches);
|
||||
debug_interface.ClearWatches();
|
||||
debug_interface.LoadWatchesFromStrings(watches);
|
||||
}
|
||||
|
||||
Update();
|
||||
@ -317,7 +320,7 @@ void WatchWidget::OnSave()
|
||||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
|
||||
false);
|
||||
ini.SetLines("Watches", PowerPC::debug_interface.SaveWatchesToStrings());
|
||||
ini.SetLines("Watches", m_system.GetPowerPC().GetDebugInterface().SaveWatchesToStrings());
|
||||
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini");
|
||||
}
|
||||
|
||||
@ -394,7 +397,7 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
||||
if (item->text().isEmpty())
|
||||
DeleteWatchAndUpdate(row);
|
||||
else
|
||||
PowerPC::debug_interface.UpdateWatchName(row, item->text().toStdString());
|
||||
m_system.GetPowerPC().GetDebugInterface().UpdateWatchName(row, item->text().toStdString());
|
||||
break;
|
||||
case COLUMN_INDEX_ADDRESS:
|
||||
case COLUMN_INDEX_HEX:
|
||||
@ -407,19 +410,20 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
||||
|
||||
if (good)
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
if (column == COLUMN_INDEX_ADDRESS)
|
||||
{
|
||||
const auto& watch = PowerPC::debug_interface.GetWatch(row);
|
||||
PowerPC::debug_interface.UnsetPatch(guard, watch.address);
|
||||
PowerPC::debug_interface.UpdateWatchAddress(row, value);
|
||||
const auto& watch = debug_interface.GetWatch(row);
|
||||
debug_interface.UnsetPatch(guard, watch.address);
|
||||
debug_interface.UpdateWatchAddress(row, value);
|
||||
if (watch.locked)
|
||||
LockWatchAddress(guard, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
PowerPC::MMU::HostWrite_U32(guard, value, PowerPC::debug_interface.GetWatch(row).address);
|
||||
PowerPC::MMU::HostWrite_U32(guard, value, debug_interface.GetWatch(row).address);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -430,13 +434,14 @@ void WatchWidget::OnItemChanged(QTableWidgetItem* item)
|
||||
}
|
||||
case COLUMN_INDEX_LOCK:
|
||||
{
|
||||
PowerPC::debug_interface.UpdateWatchLockedState(row, item->checkState() == Qt::Checked);
|
||||
const auto& watch = PowerPC::debug_interface.GetWatch(row);
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
debug_interface.UpdateWatchLockedState(row, item->checkState() == Qt::Checked);
|
||||
const auto& watch = debug_interface.GetWatch(row);
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
if (watch.locked)
|
||||
LockWatchAddress(guard, watch.address);
|
||||
else
|
||||
PowerPC::debug_interface.UnsetPatch(guard, watch.address);
|
||||
debug_interface.UnsetPatch(guard, watch.address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -455,13 +460,13 @@ void WatchWidget::LockWatchAddress(const Core::CPUThreadGuard& guard, u32 addres
|
||||
bytes.push_back(static_cast<u8>(c));
|
||||
}
|
||||
|
||||
PowerPC::debug_interface.SetFramePatch(guard, address, bytes);
|
||||
m_system.GetPowerPC().GetDebugInterface().SetFramePatch(guard, address, bytes);
|
||||
}
|
||||
|
||||
void WatchWidget::DeleteSelectedWatches()
|
||||
{
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
std::vector<int> row_indices;
|
||||
for (const auto& index : m_table->selectionModel()->selectedRows())
|
||||
{
|
||||
@ -486,14 +491,15 @@ void WatchWidget::DeleteSelectedWatches()
|
||||
|
||||
void WatchWidget::DeleteWatch(const Core::CPUThreadGuard& guard, int row)
|
||||
{
|
||||
PowerPC::debug_interface.UnsetPatch(guard, PowerPC::debug_interface.GetWatch(row).address);
|
||||
PowerPC::debug_interface.RemoveWatch(row);
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
debug_interface.UnsetPatch(guard, debug_interface.GetWatch(row).address);
|
||||
debug_interface.RemoveWatch(row);
|
||||
}
|
||||
|
||||
void WatchWidget::DeleteWatchAndUpdate(int row)
|
||||
{
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
DeleteWatch(guard, row);
|
||||
}
|
||||
|
||||
@ -502,24 +508,25 @@ void WatchWidget::DeleteWatchAndUpdate(int row)
|
||||
|
||||
void WatchWidget::AddWatchBreakpoint(int row)
|
||||
{
|
||||
emit RequestMemoryBreakpoint(PowerPC::debug_interface.GetWatch(row).address);
|
||||
emit RequestMemoryBreakpoint(m_system.GetPowerPC().GetDebugInterface().GetWatch(row).address);
|
||||
}
|
||||
|
||||
void WatchWidget::ShowInMemory(int row)
|
||||
{
|
||||
emit ShowMemory(PowerPC::debug_interface.GetWatch(row).address);
|
||||
emit ShowMemory(m_system.GetPowerPC().GetDebugInterface().GetWatch(row).address);
|
||||
}
|
||||
|
||||
void WatchWidget::AddWatch(QString name, u32 addr)
|
||||
{
|
||||
PowerPC::debug_interface.SetWatch(addr, name.toStdString());
|
||||
m_system.GetPowerPC().GetDebugInterface().SetWatch(addr, name.toStdString());
|
||||
Update();
|
||||
}
|
||||
|
||||
void WatchWidget::LockSelectedWatches()
|
||||
{
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
for (const auto& index : m_table->selectionModel()->selectedRows())
|
||||
{
|
||||
const auto* item = m_table->item(index.row(), index.column());
|
||||
@ -527,10 +534,10 @@ void WatchWidget::LockSelectedWatches()
|
||||
if (row_variant.isNull())
|
||||
continue;
|
||||
const int row = row_variant.toInt();
|
||||
const auto& watch = PowerPC::debug_interface.GetWatch(row);
|
||||
const auto& watch = debug_interface.GetWatch(row);
|
||||
if (watch.locked)
|
||||
continue;
|
||||
PowerPC::debug_interface.UpdateWatchLockedState(row, true);
|
||||
debug_interface.UpdateWatchLockedState(row, true);
|
||||
LockWatchAddress(guard, watch.address);
|
||||
}
|
||||
}
|
||||
@ -541,7 +548,8 @@ void WatchWidget::LockSelectedWatches()
|
||||
void WatchWidget::UnlockSelectedWatches()
|
||||
{
|
||||
{
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
auto& debug_interface = m_system.GetPowerPC().GetDebugInterface();
|
||||
Core::CPUThreadGuard guard(m_system);
|
||||
for (const auto& index : m_table->selectionModel()->selectedRows())
|
||||
{
|
||||
const auto* item = m_table->item(index.row(), index.column());
|
||||
@ -549,11 +557,11 @@ void WatchWidget::UnlockSelectedWatches()
|
||||
if (row_variant.isNull())
|
||||
continue;
|
||||
const int row = row_variant.toInt();
|
||||
const auto& watch = PowerPC::debug_interface.GetWatch(row);
|
||||
const auto& watch = debug_interface.GetWatch(row);
|
||||
if (!watch.locked)
|
||||
continue;
|
||||
PowerPC::debug_interface.UpdateWatchLockedState(row, false);
|
||||
PowerPC::debug_interface.UnsetPatch(guard, watch.address);
|
||||
debug_interface.UpdateWatchLockedState(row, false);
|
||||
debug_interface.UnsetPatch(guard, watch.address);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,8 @@ class QToolBar;
|
||||
namespace Core
|
||||
{
|
||||
class CPUThreadGuard;
|
||||
};
|
||||
class System;
|
||||
}; // namespace Core
|
||||
|
||||
class WatchWidget : public QDockWidget
|
||||
{
|
||||
@ -62,6 +63,8 @@ private:
|
||||
void LockSelectedWatches();
|
||||
void UnlockSelectedWatches();
|
||||
|
||||
Core::System& m_system;
|
||||
|
||||
QAction* m_new;
|
||||
QAction* m_delete;
|
||||
QAction* m_clear;
|
||||
|
Reference in New Issue
Block a user