update Cheat files

This commit is contained in:
Nayla Hanegan 2023-04-20 20:32:13 -04:00
commit cbfd634a4b
No known key found for this signature in database
GPG key ID: BAFE9001DA16CFA2
217 changed files with 2263 additions and 1880 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();
}
@ -329,7 +337,7 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp)
void BreakpointWidget::OnLoad()
{
IniFile ini;
Common::IniFile ini;
if (!ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().GetGameID() + ".ini",
false))
{
@ -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();
@ -357,11 +367,11 @@ void BreakpointWidget::OnLoad()
void BreakpointWidget::OnSave()
{
IniFile ini;
Common::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

@ -135,7 +135,7 @@ constexpr int CODE_VIEW_COLUMN_DESCRIPTION = 4;
constexpr int CODE_VIEW_COLUMN_BRANCH_ARROWS = 5;
constexpr int CODE_VIEW_COLUMNCOUNT = 6;
CodeViewWidget::CodeViewWidget()
CodeViewWidget::CodeViewWidget() : m_system(Core::System::GetInstance())
{
setColumnCount(CODE_VIEW_COLUMNCOUNT);
setShowGrid(false);
@ -168,11 +168,11 @@ CodeViewWidget::CodeViewWidget()
&CodeViewWidget::FontBasedSizing);
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, [this] {
m_address = PowerPC::ppcState.pc;
m_address = m_system.GetPPCState().pc;
Update();
});
connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] {
m_address = PowerPC::ppcState.pc;
m_address = m_system.GetPPCState().pc;
Update();
});
@ -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)
@ -259,7 +259,7 @@ void CodeViewWidget::Update()
if (Core::GetState() == Core::State::Paused)
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
Update(&guard);
}
else
@ -294,7 +294,11 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard)
for (int i = 0; i < rows; i++)
setRowHeight(i, rowh);
const std::optional<u32> pc = guard ? std::make_optional(PowerPC::ppcState.pc) : std::nullopt;
auto& power_pc = m_system.GetPowerPC();
auto& debug_interface = power_pc.GetDebugInterface();
const std::optional<u32> pc =
guard ? std::make_optional(power_pc.GetPPCState().pc) : std::nullopt;
const bool dark_theme = qApp->palette().color(QPalette::Base).valueF() < 0.5;
@ -303,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.
@ -359,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);
@ -533,10 +537,10 @@ void CodeViewWidget::SetAddress(u32 address, SetAddressUpdate update)
void CodeViewWidget::ReplaceAddress(u32 address, ReplaceWith replace)
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
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);
}
@ -595,10 +599,11 @@ void CodeViewWidget::OnContextMenu()
bool follow_branch_enabled = false;
if (paused)
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
const std::string disasm = PowerPC::debug_interface.Disassemble(&guard, PowerPC::ppcState.pc);
Core::CPUThreadGuard guard(m_system);
const u32 pc = m_system.GetPPCState().pc;
const std::string disasm = m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, pc);
if (addr == PowerPC::ppcState.pc)
if (addr == pc)
{
const auto target_it = std::find(disasm.begin(), disasm.end(), '\t');
const auto target_end = std::find(target_it, disasm.end(), ',');
@ -640,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();
@ -651,7 +657,7 @@ void CodeViewWidget::AutoStep(CodeTrace::AutoStop option)
// Autosteps and follows value in the target (left-most) register. The Used and Changed options
// silently follows target through reshuffles in memory and registers and stops on use or update.
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
CodeTrace code_trace;
bool repeat = false;
@ -741,16 +747,16 @@ void CodeViewWidget::OnCopyTargetAddress()
const u32 addr = GetContextAddress();
const std::string code_line = [addr] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
return PowerPC::debug_interface.Disassemble(&guard, addr);
const std::string code_line = [this, addr] {
Core::CPUThreadGuard guard(m_system);
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)
{
@ -771,16 +777,16 @@ void CodeViewWidget::OnShowTargetInMemory()
const u32 addr = GetContextAddress();
const std::string code_line = [addr] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
return PowerPC::debug_interface.Disassemble(&guard, addr);
const std::string code_line = [this, addr] {
Core::CPUThreadGuard guard(m_system);
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);
@ -790,9 +796,9 @@ void CodeViewWidget::OnCopyCode()
{
const u32 addr = GetContextAddress();
const std::string text = [addr] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
return PowerPC::debug_interface.Disassemble(&guard, addr);
const std::string text = [this, addr] {
Core::CPUThreadGuard guard(m_system);
return m_system.GetPowerPC().GetDebugInterface().Disassemble(&guard, addr);
}();
QApplication::clipboard()->setText(QString::fromStdString(text));
@ -809,14 +815,15 @@ void CodeViewWidget::OnCopyFunction()
std::string text = symbol->name + "\r\n";
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
// we got a function
const u32 start = symbol->address;
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);
}
}
@ -828,9 +835,9 @@ void CodeViewWidget::OnCopyHex()
{
const u32 addr = GetContextAddress();
const u32 instruction = [addr] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
return PowerPC::debug_interface.ReadInstruction(guard, addr);
const u32 instruction = [this, addr] {
Core::CPUThreadGuard guard(m_system);
return m_system.GetPowerPC().GetDebugInterface().ReadInstruction(guard, addr);
}();
QApplication::clipboard()->setText(
@ -841,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();
}
@ -857,7 +864,7 @@ void CodeViewWidget::OnAddFunction()
{
const u32 addr = GetContextAddress();
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
g_symbolDB.AddFunction(guard, addr);
emit SymbolsChanged();
@ -882,8 +889,8 @@ void CodeViewWidget::OnFollowBranch()
{
const u32 addr = GetContextAddress();
const u32 branch_addr = [addr] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
const u32 branch_addr = [this, addr] {
Core::CPUThreadGuard guard(m_system);
return GetBranchFromAddress(guard, addr);
}();
@ -917,7 +924,7 @@ void CodeViewWidget::OnRenameSymbol()
void CodeViewWidget::OnSelectionChanged()
{
if (m_address == PowerPC::ppcState.pc)
if (m_address == m_system.GetPPCState().pc)
{
setStyleSheet(
QStringLiteral("QTableView::item:selected {background-color: #00FF00; color: #000000;}"));
@ -946,7 +953,7 @@ void CodeViewWidget::OnSetSymbolSize()
if (!good)
return;
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
PPCAnalyst::ReanalyzeFunction(guard, symbol->address, *symbol, size);
emit SymbolsChanged();
@ -974,7 +981,7 @@ void CodeViewWidget::OnSetSymbolEndAddress()
if (!good)
return;
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
PPCAnalyst::ReanalyzeFunction(guard, symbol->address, *symbol, address - symbol->address);
emit SymbolsChanged();
@ -983,7 +990,7 @@ void CodeViewWidget::OnSetSymbolEndAddress()
void CodeViewWidget::OnReplaceInstruction()
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
const u32 addr = GetContextAddress();
@ -995,22 +1002,23 @@ 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);
}
}
void CodeViewWidget::OnRestoreInstruction()
{
Core::CPUThreadGuard guard(Core::System::GetInstance());
Core::CPUThreadGuard guard(m_system);
const u32 addr = GetContextAddress();
PowerPC::debug_interface.UnsetPatch(guard, addr);
m_system.GetPowerPC().GetDebugInterface().UnsetPatch(guard, addr);
Update(&guard);
}
@ -1089,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();
@ -1100,7 +1109,7 @@ void CodeViewWidget::ToggleBreakpoint()
void CodeViewWidget::AddBreakpoint()
{
PowerPC::breakpoints.Add(GetContextAddress());
m_system.GetPowerPC().GetBreakPoints().Add(GetContextAddress());
emit BreakpointsChanged();
Update();

View file

@ -18,7 +18,8 @@ class QShowEvent;
namespace Core
{
class CPUThreadGuard;
};
class System;
} // namespace Core
struct CodeViewBranch;
class BranchDisplayDelegate;
@ -98,6 +99,8 @@ private:
void CalculateBranchIndentation();
Core::System& m_system;
bool m_updating = false;
u32 m_address = 0;

View file

@ -28,7 +28,7 @@
#include "DolphinQt/Host.h"
#include "DolphinQt/Settings.h"
CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent)
CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent), m_system(Core::System::GetInstance())
{
setWindowTitle(tr("Code"));
setObjectName(QStringLiteral("code"));
@ -51,7 +51,7 @@ CodeWidget::CodeWidget(QWidget* parent) : QDockWidget(parent)
connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, [this] {
if (Core::GetState() == Core::State::Paused)
SetAddress(PowerPC::ppcState.pc, CodeViewWidget::SetAddressUpdate::WithoutUpdate);
SetAddress(m_system.GetPPCState().pc, CodeViewWidget::SetAddressUpdate::WithoutUpdate);
Update();
});
@ -329,9 +329,9 @@ void CodeWidget::UpdateCallstack()
std::vector<Dolphin_Debugger::CallstackEntry> stack;
const bool success = [&stack] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
return Dolphin_Debugger::GetCallstack(Core::System::GetInstance(), guard, stack);
const bool success = [this, &stack] {
Core::CPUThreadGuard guard(m_system);
return Dolphin_Debugger::GetCallstack(m_system, guard, stack);
}();
if (!success)
@ -435,41 +435,41 @@ void CodeWidget::UpdateFunctionCallers(const Common::Symbol* symbol)
void CodeWidget::Step()
{
auto& system = Core::System::GetInstance();
auto& cpu = system.GetCPU();
auto& cpu = m_system.GetCPU();
if (!cpu.IsStepping())
return;
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.
}
void CodeWidget::StepOver()
{
auto& system = Core::System::GetInstance();
auto& cpu = system.GetCPU();
auto& cpu = m_system.GetCPU();
if (!cpu.IsStepping())
return;
const UGeckoInstruction inst = [&] {
Core::CPUThreadGuard guard(system);
return PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc);
Core::CPUThreadGuard guard(m_system);
return PowerPC::MMU::HostRead_Instruction(guard, m_system.GetPPCState().pc);
}();
if (inst.LK)
{
PowerPC::breakpoints.ClearAllTemporary();
PowerPC::breakpoints.Add(PowerPC::ppcState.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);
}
@ -480,23 +480,21 @@ void CodeWidget::StepOver()
}
// Returns true on a rfi, blr or on a bclr that evaluates to true.
static bool WillInstructionReturn(UGeckoInstruction inst)
static bool WillInstructionReturn(Core::System& system, UGeckoInstruction inst)
{
// Is a rfi instruction
if (inst.hex == 0x4C000064u)
return true;
bool counter =
(inst.BO_2 >> 2 & 1) != 0 || (CTR(PowerPC::ppcState) != 0) != ((inst.BO_2 >> 1 & 1) != 0);
bool condition =
inst.BO_2 >> 4 != 0 || PowerPC::ppcState.cr.GetBit(inst.BI_2) == (inst.BO_2 >> 3 & 1);
const auto& ppc_state = system.GetPPCState();
bool counter = (inst.BO_2 >> 2 & 1) != 0 || (CTR(ppc_state) != 0) != ((inst.BO_2 >> 1 & 1) != 0);
bool condition = inst.BO_2 >> 4 != 0 || ppc_state.cr.GetBit(inst.BI_2) == (inst.BO_2 >> 3 & 1);
bool isBclr = inst.OPCD_7 == 0b010011 && (inst.hex >> 1 & 0b10000) != 0;
return isBclr && counter && condition && !inst.LK_3;
}
void CodeWidget::StepOut()
{
auto& system = Core::System::GetInstance();
auto& cpu = system.GetCPU();
auto& cpu = m_system.GetCPU();
if (!cpu.IsStepping())
return;
@ -505,51 +503,53 @@ void CodeWidget::StepOut()
using clock = std::chrono::steady_clock;
clock::time_point timeout = clock::now() + std::chrono::seconds(5);
auto& power_pc = m_system.GetPowerPC();
auto& ppc_state = power_pc.GetPPCState();
auto& breakpoints = power_pc.GetBreakPoints();
{
Core::CPUThreadGuard guard(system);
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
// on a breakpoint, skip it.
UGeckoInstruction inst = PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc);
UGeckoInstruction inst = PowerPC::MMU::HostRead_Instruction(guard, ppc_state.pc);
do
{
if (WillInstructionReturn(inst))
if (WillInstructionReturn(m_system, inst))
{
PowerPC::SingleStep();
power_pc.SingleStep();
break;
}
if (inst.LK)
{
// Step over branches
u32 next_pc = PowerPC::ppcState.pc + 4;
u32 next_pc = ppc_state.pc + 4;
do
{
PowerPC::SingleStep();
} while (PowerPC::ppcState.pc != next_pc && clock::now() < timeout &&
!PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc));
power_pc.SingleStep();
} while (ppc_state.pc != next_pc && clock::now() < timeout &&
!breakpoints.IsAddressBreakPoint(ppc_state.pc));
}
else
{
PowerPC::SingleStep();
power_pc.SingleStep();
}
inst = PowerPC::MMU::HostRead_Instruction(guard, PowerPC::ppcState.pc);
} while (clock::now() < timeout &&
!PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc));
inst = PowerPC::MMU::HostRead_Instruction(guard, 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(PowerPC::ppcState.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);
@ -559,19 +559,19 @@ void CodeWidget::StepOut()
void CodeWidget::Skip()
{
PowerPC::ppcState.pc += 4;
m_system.GetPPCState().pc += 4;
ShowPC();
}
void CodeWidget::ShowPC()
{
m_code_view->SetAddress(PowerPC::ppcState.pc, CodeViewWidget::SetAddressUpdate::WithUpdate);
m_code_view->SetAddress(m_system.GetPPCState().pc, CodeViewWidget::SetAddressUpdate::WithUpdate);
Update();
}
void CodeWidget::SetPC()
{
PowerPC::ppcState.pc = m_code_view->GetAddress();
m_system.GetPPCState().pc = m_code_view->GetAddress();
Update();
}

View file

@ -22,6 +22,10 @@ namespace Common
{
struct Symbol;
}
namespace Core
{
class System;
}
class CodeWidget : public QDockWidget
{
@ -66,6 +70,8 @@ private:
void closeEvent(QCloseEvent*) override;
void showEvent(QShowEvent* event) override;
Core::System& m_system;
CodeDiffDialog* m_diff_dialog = nullptr;
QLineEdit* m_search_address;
QPushButton* m_code_diff;

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);
@ -437,6 +438,9 @@ void MemoryViewWidget::Update()
void MemoryViewWidget::UpdateColumns()
{
if (!isVisible())
return;
// Check if table is created
if (m_table->item(1, 1) == nullptr)
return;
@ -568,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);
@ -805,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)
{
@ -826,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);
}
}
@ -885,7 +891,7 @@ void MemoryViewWidget::OnContextMenu(const QPoint& pos)
auto* copy_hex = menu->addAction(tr("Copy Hex"), this, [this, addr] { OnCopyHex(addr); });
copy_hex->setEnabled(item_has_value);
auto* copy_value = menu->addAction(tr("Copy Value"), this, [this, item_selected] {
auto* copy_value = menu->addAction(tr("Copy Value"), this, [item_selected] {
QApplication::clipboard()->setText(item_selected->text());
});
copy_value->setEnabled(item_has_value);

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

@ -20,7 +20,8 @@
#include "DolphinQt/Host.h"
#include "DolphinQt/Settings.h"
RegisterWidget::RegisterWidget(QWidget* parent) : QDockWidget(parent)
RegisterWidget::RegisterWidget(QWidget* parent)
: QDockWidget(parent), m_system(Core::System::GetInstance())
{
setWindowTitle(tr("Registers"));
setObjectName(QStringLiteral("registers"));
@ -295,8 +296,8 @@ void RegisterWidget::AutoStep(const std::string& reg) const
while (true)
{
const AutoStepResults results = [&trace] {
Core::CPUThreadGuard guard(Core::System::GetInstance());
const AutoStepResults results = [this, &trace] {
Core::CPUThreadGuard guard(m_system);
return trace.AutoStepping(guard, true);
}();
@ -318,18 +319,19 @@ void RegisterWidget::PopulateTable()
{
// General purpose registers (int)
AddRegister(
i, 0, RegisterType::gpr, "r" + std::to_string(i), [i] { return PowerPC::ppcState.gpr[i]; },
[i](u64 value) { PowerPC::ppcState.gpr[i] = value; });
i, 0, RegisterType::gpr, "r" + std::to_string(i),
[this, i] { return m_system.GetPPCState().gpr[i]; },
[this, i](u64 value) { m_system.GetPPCState().gpr[i] = value; });
// Floating point registers (double)
AddRegister(
i, 2, RegisterType::fpr, "f" + std::to_string(i),
[i] { return PowerPC::ppcState.ps[i].PS0AsU64(); },
[i](u64 value) { PowerPC::ppcState.ps[i].SetPS0(value); });
[this, i] { return m_system.GetPPCState().ps[i].PS0AsU64(); },
[this, i](u64 value) { m_system.GetPPCState().ps[i].SetPS0(value); });
AddRegister(
i, 4, RegisterType::fpr, "", [i] { return PowerPC::ppcState.ps[i].PS1AsU64(); },
[i](u64 value) { PowerPC::ppcState.ps[i].SetPS1(value); });
i, 4, RegisterType::fpr, "", [this, i] { return m_system.GetPPCState().ps[i].PS1AsU64(); },
[this, i](u64 value) { m_system.GetPPCState().ps[i].SetPS1(value); });
}
// The IBAT and DBAT registers have a large gap between
@ -340,32 +342,36 @@ void RegisterWidget::PopulateTable()
// IBAT registers
AddRegister(
i, 5, RegisterType::ibat, "IBAT" + std::to_string(i),
[i] {
return (static_cast<u64>(PowerPC::ppcState.spr[SPR_IBAT0U + i * 2]) << 32) +
PowerPC::ppcState.spr[SPR_IBAT0L + i * 2];
[this, i] {
const auto& ppc_state = m_system.GetPPCState();
return (static_cast<u64>(ppc_state.spr[SPR_IBAT0U + i * 2]) << 32) +
ppc_state.spr[SPR_IBAT0L + i * 2];
},
nullptr);
AddRegister(
i + 4, 5, RegisterType::ibat, "IBAT" + std::to_string(4 + i),
[i] {
return (static_cast<u64>(PowerPC::ppcState.spr[SPR_IBAT4U + i * 2]) << 32) +
PowerPC::ppcState.spr[SPR_IBAT4L + i * 2];
[this, i] {
const auto& ppc_state = m_system.GetPPCState();
return (static_cast<u64>(ppc_state.spr[SPR_IBAT4U + i * 2]) << 32) +
ppc_state.spr[SPR_IBAT4L + i * 2];
},
nullptr);
// DBAT registers
AddRegister(
i + 8, 5, RegisterType::dbat, "DBAT" + std::to_string(i),
[i] {
return (static_cast<u64>(PowerPC::ppcState.spr[SPR_DBAT0U + i * 2]) << 32) +
PowerPC::ppcState.spr[SPR_DBAT0L + i * 2];
[this, i] {
const auto& ppc_state = m_system.GetPPCState();
return (static_cast<u64>(ppc_state.spr[SPR_DBAT0U + i * 2]) << 32) +
ppc_state.spr[SPR_DBAT0L + i * 2];
},
nullptr);
AddRegister(
i + 12, 5, RegisterType::dbat, "DBAT" + std::to_string(4 + i),
[i] {
return (static_cast<u64>(PowerPC::ppcState.spr[SPR_DBAT4U + i * 2]) << 32) +
PowerPC::ppcState.spr[SPR_DBAT4L + i * 2];
[this, i] {
const auto& ppc_state = m_system.GetPPCState();
return (static_cast<u64>(ppc_state.spr[SPR_DBAT4U + i * 2]) << 32) +
ppc_state.spr[SPR_DBAT4L + i * 2];
},
nullptr);
}
@ -375,114 +381,113 @@ void RegisterWidget::PopulateTable()
// Graphics quantization registers
AddRegister(
i + 16, 7, RegisterType::gqr, "GQR" + std::to_string(i),
[i] { return PowerPC::ppcState.spr[SPR_GQR0 + i]; }, nullptr);
[this, i] { return m_system.GetPPCState().spr[SPR_GQR0 + i]; }, nullptr);
}
// HID registers
AddRegister(
24, 7, RegisterType::hid, "HID0", [] { return PowerPC::ppcState.spr[SPR_HID0]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_HID0] = static_cast<u32>(value); });
24, 7, RegisterType::hid, "HID0", [this] { return m_system.GetPPCState().spr[SPR_HID0]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_HID0] = static_cast<u32>(value); });
AddRegister(
25, 7, RegisterType::hid, "HID1", [] { return PowerPC::ppcState.spr[SPR_HID1]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_HID1] = static_cast<u32>(value); });
25, 7, RegisterType::hid, "HID1", [this] { return m_system.GetPPCState().spr[SPR_HID1]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_HID1] = static_cast<u32>(value); });
AddRegister(
26, 7, RegisterType::hid, "HID2", [] { return PowerPC::ppcState.spr[SPR_HID2]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_HID2] = static_cast<u32>(value); });
26, 7, RegisterType::hid, "HID2", [this] { return m_system.GetPPCState().spr[SPR_HID2]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_HID2] = static_cast<u32>(value); });
AddRegister(
27, 7, RegisterType::hid, "HID4", [] { return PowerPC::ppcState.spr[SPR_HID4]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_HID4] = static_cast<u32>(value); });
27, 7, RegisterType::hid, "HID4", [this] { return m_system.GetPPCState().spr[SPR_HID4]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_HID4] = static_cast<u32>(value); });
for (int i = 0; i < 16; i++)
{
// SR registers
AddRegister(
i, 7, RegisterType::sr, "SR" + std::to_string(i), [i] { return PowerPC::ppcState.sr[i]; },
[i](u64 value) { PowerPC::ppcState.sr[i] = value; });
i, 7, RegisterType::sr, "SR" + std::to_string(i),
[this, i] { return m_system.GetPPCState().sr[i]; },
[this, i](u64 value) { m_system.GetPPCState().sr[i] = value; });
}
// 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(
17, 5, RegisterType::pc, "PC", [] { return PowerPC::ppcState.pc; },
[](u64 value) { PowerPC::ppcState.pc = value; });
17, 5, RegisterType::pc, "PC", [this] { return m_system.GetPPCState().pc; },
[this](u64 value) { m_system.GetPPCState().pc = value; });
// LR
AddRegister(
18, 5, RegisterType::lr, "LR", [] { return PowerPC::ppcState.spr[SPR_LR]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_LR] = value; });
18, 5, RegisterType::lr, "LR", [this] { return m_system.GetPPCState().spr[SPR_LR]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_LR] = value; });
// CTR
AddRegister(
19, 5, RegisterType::ctr, "CTR", [] { return PowerPC::ppcState.spr[SPR_CTR]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_CTR] = value; });
19, 5, RegisterType::ctr, "CTR", [this] { return m_system.GetPPCState().spr[SPR_CTR]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_CTR] = value; });
// CR
AddRegister(
20, 5, RegisterType::cr, "CR", [] { return PowerPC::ppcState.cr.Get(); },
[](u64 value) { PowerPC::ppcState.cr.Set(value); });
20, 5, RegisterType::cr, "CR", [this] { return m_system.GetPPCState().cr.Get(); },
[this](u64 value) { m_system.GetPPCState().cr.Set(value); });
// XER
AddRegister(
21, 5, RegisterType::xer, "XER", [] { return PowerPC::ppcState.GetXER().Hex; },
[](u64 value) { PowerPC::ppcState.SetXER(UReg_XER(value)); });
21, 5, RegisterType::xer, "XER", [this] { return m_system.GetPPCState().GetXER().Hex; },
[this](u64 value) { m_system.GetPPCState().SetXER(UReg_XER(value)); });
// FPSCR
AddRegister(
22, 5, RegisterType::fpscr, "FPSCR", [] { return PowerPC::ppcState.fpscr.Hex; },
[](u64 value) { PowerPC::ppcState.fpscr = static_cast<u32>(value); });
22, 5, RegisterType::fpscr, "FPSCR", [this] { return m_system.GetPPCState().fpscr.Hex; },
[this](u64 value) { m_system.GetPPCState().fpscr = static_cast<u32>(value); });
// MSR
AddRegister(
23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr.Hex; },
[](u64 value) { PowerPC::ppcState.msr.Hex = value; });
23, 5, RegisterType::msr, "MSR", [this] { return m_system.GetPPCState().msr.Hex; },
[this](u64 value) { m_system.GetPPCState().msr.Hex = value; });
// SRR 0-1
AddRegister(
24, 5, RegisterType::srr, "SRR0", [] { return PowerPC::ppcState.spr[SPR_SRR0]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_SRR0] = value; });
24, 5, RegisterType::srr, "SRR0", [this] { return m_system.GetPPCState().spr[SPR_SRR0]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_SRR0] = value; });
AddRegister(
25, 5, RegisterType::srr, "SRR1", [] { return PowerPC::ppcState.spr[SPR_SRR1]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_SRR1] = value; });
25, 5, RegisterType::srr, "SRR1", [this] { return m_system.GetPPCState().spr[SPR_SRR1]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_SRR1] = value; });
// Exceptions
AddRegister(
26, 5, RegisterType::exceptions, "Exceptions", [] { return PowerPC::ppcState.Exceptions; },
[](u64 value) { PowerPC::ppcState.Exceptions = value; });
26, 5, RegisterType::exceptions, "Exceptions",
[this] { return m_system.GetPPCState().Exceptions; },
[this](u64 value) { m_system.GetPPCState().Exceptions = value; });
// Int Mask
AddRegister(
27, 5, RegisterType::int_mask, "Int Mask",
[] {
auto& system = Core::System::GetInstance();
return system.GetProcessorInterface().GetMask();
},
nullptr);
[this] { return m_system.GetProcessorInterface().GetMask(); }, nullptr);
// Int Cause
AddRegister(
28, 5, RegisterType::int_cause, "Int Cause",
[] {
auto& system = Core::System::GetInstance();
return system.GetProcessorInterface().GetCause();
},
nullptr);
[this] { return m_system.GetProcessorInterface().GetCause(); }, nullptr);
// DSISR
AddRegister(
29, 5, RegisterType::dsisr, "DSISR", [] { return PowerPC::ppcState.spr[SPR_DSISR]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_DSISR] = value; });
29, 5, RegisterType::dsisr, "DSISR", [this] { return m_system.GetPPCState().spr[SPR_DSISR]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_DSISR] = value; });
// DAR
AddRegister(
30, 5, RegisterType::dar, "DAR", [] { return PowerPC::ppcState.spr[SPR_DAR]; },
[](u64 value) { PowerPC::ppcState.spr[SPR_DAR] = value; });
30, 5, RegisterType::dar, "DAR", [this] { return m_system.GetPPCState().spr[SPR_DAR]; },
[this](u64 value) { m_system.GetPPCState().spr[SPR_DAR] = value; });
// Hash Mask
AddRegister(
31, 5, RegisterType::pt_hashmask, "Hash Mask",
[] { return (PowerPC::ppcState.pagetable_hashmask << 6) | PowerPC::ppcState.pagetable_base; },
[this] {
const auto& ppc_state = m_system.GetPPCState();
return (ppc_state.pagetable_hashmask << 6) | ppc_state.pagetable_base;
},
nullptr);
emit RequestTableUpdate();

View file

@ -13,6 +13,10 @@
class QTableWidget;
class QCloseEvent;
class QShowEvent;
namespace Core
{
class System;
}
class RegisterWidget : public QDockWidget
{
@ -49,6 +53,8 @@ private:
void AutoStep(const std::string& reg) const;
void Update();
Core::System& m_system;
QTableWidget* m_table;
bool m_updating = false;
};

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();
}
@ -287,7 +289,7 @@ void WatchWidget::OnNewWatch()
void WatchWidget::OnLoad()
{
IniFile ini;
Common::IniFile ini;
std::vector<std::string> watches;
@ -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();
@ -314,10 +317,10 @@ void WatchWidget::OnLoad()
void WatchWidget::OnSave()
{
IniFile ini;
Common::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;