PowerPC: Refactor to class, move to System.

This commit is contained in:
Admiral H. Curtiss
2023-03-28 20:26:52 +02:00
parent ebbbdc49ab
commit 23843583bf
50 changed files with 705 additions and 531 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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{};

View File

@ -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(

View File

@ -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
{

View File

@ -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);
}
}

View File

@ -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;