summaryrefslogtreecommitdiff
path: root/src/citra_qt/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt/debugger')
-rw-r--r--src/citra_qt/debugger/disassembler.cpp81
-rw-r--r--src/citra_qt/debugger/disassembler.h7
-rw-r--r--src/citra_qt/debugger/graphics_breakpoints_p.h2
-rw-r--r--src/citra_qt/debugger/profiler.cpp4
-rw-r--r--src/citra_qt/debugger/profiler.h2
-rw-r--r--src/citra_qt/debugger/registers.cpp33
-rw-r--r--src/citra_qt/debugger/registers.h4
7 files changed, 82 insertions, 51 deletions
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index f620687ae..08c6b49bd 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -18,8 +18,8 @@
18#include "core/arm/disassembler/arm_disasm.h" 18#include "core/arm/disassembler/arm_disasm.h"
19 19
20 20
21DisassemblerModel::DisassemblerModel(QObject* parent) : QAbstractListModel(parent), base_address(0), code_size(0), program_counter(0), selection(QModelIndex()) { 21DisassemblerModel::DisassemblerModel(QObject* parent) :
22 22 QAbstractListModel(parent), base_address(0), code_size(0), program_counter(0), selection(QModelIndex()) {
23} 23}
24 24
25int DisassemblerModel::columnCount(const QModelIndex& parent) const { 25int DisassemblerModel::columnCount(const QModelIndex& parent) const {
@@ -158,34 +158,28 @@ void DisassemblerModel::SetNextInstruction(unsigned int address) {
158 emit dataChanged(prev_index, prev_index); 158 emit dataChanged(prev_index, prev_index);
159} 159}
160 160
161DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread& emu_thread) : QDockWidget(parent), base_addr(0), emu_thread(emu_thread) 161DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread) :
162{ 162 QDockWidget(parent), emu_thread(emu_thread), base_addr(0) {
163 disasm_ui.setupUi(this);
164 163
165 model = new DisassemblerModel(this); 164 disasm_ui.setupUi(this);
166 disasm_ui.treeView->setModel(model);
167 165
168 RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut); 166 RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut);
169 RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut); 167 RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut);
170 RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut); 168 RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut);
171 RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut); 169 RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut);
172 170
173 connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), model, SLOT(OnSetOrUnsetBreakpoint()));
174 connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep())); 171 connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep()));
175 connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause())); 172 connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause()));
176 connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue())); 173 connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue()));
177 174
178 connect(disasm_ui.treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
179 model, SLOT(OnSelectionChanged(const QModelIndex&)));
180
181 connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, SLOT(OnToggleStartStop())); 175 connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, SLOT(OnToggleStartStop()));
182 connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep())); 176 connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep()));
183 connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto())); 177 connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto()));
184 connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), model, SLOT(OnSetOrUnsetBreakpoint())); 178
179 setEnabled(false);
185} 180}
186 181
187void DisassemblerWidget::Init() 182void DisassemblerWidget::Init() {
188{
189 model->ParseFromAddress(Core::g_app_core->GetPC()); 183 model->ParseFromAddress(Core::g_app_core->GetPC());
190 184
191 disasm_ui.treeView->resizeColumnToContents(0); 185 disasm_ui.treeView->resizeColumnToContents(0);
@@ -197,25 +191,21 @@ void DisassemblerWidget::Init()
197 disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 191 disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
198} 192}
199 193
200void DisassemblerWidget::OnContinue() 194void DisassemblerWidget::OnContinue() {
201{ 195 emu_thread->SetRunning(true);
202 emu_thread.SetCpuRunning(true);
203} 196}
204 197
205void DisassemblerWidget::OnStep() 198void DisassemblerWidget::OnStep() {
206{
207 OnStepInto(); // change later 199 OnStepInto(); // change later
208} 200}
209 201
210void DisassemblerWidget::OnStepInto() 202void DisassemblerWidget::OnStepInto() {
211{ 203 emu_thread->SetRunning(false);
212 emu_thread.SetCpuRunning(false); 204 emu_thread->ExecStep();
213 emu_thread.ExecStep();
214} 205}
215 206
216void DisassemblerWidget::OnPause() 207void DisassemblerWidget::OnPause() {
217{ 208 emu_thread->SetRunning(false);
218 emu_thread.SetCpuRunning(false);
219 209
220 // TODO: By now, the CPU might not have actually stopped... 210 // TODO: By now, the CPU might not have actually stopped...
221 if (Core::g_app_core) { 211 if (Core::g_app_core) {
@@ -223,17 +213,15 @@ void DisassemblerWidget::OnPause()
223 } 213 }
224} 214}
225 215
226void DisassemblerWidget::OnToggleStartStop() 216void DisassemblerWidget::OnToggleStartStop() {
227{ 217 emu_thread->SetRunning(!emu_thread->IsRunning());
228 emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning());
229} 218}
230 219
231void DisassemblerWidget::OnDebugModeEntered() 220void DisassemblerWidget::OnDebugModeEntered() {
232{
233 ARMword next_instr = Core::g_app_core->GetPC(); 221 ARMword next_instr = Core::g_app_core->GetPC();
234 222
235 if (model->GetBreakPoints().IsAddressBreakPoint(next_instr)) 223 if (model->GetBreakPoints().IsAddressBreakPoint(next_instr))
236 emu_thread.SetCpuRunning(false); 224 emu_thread->SetRunning(false);
237 225
238 model->SetNextInstruction(next_instr); 226 model->SetNextInstruction(next_instr);
239 227
@@ -242,16 +230,35 @@ void DisassemblerWidget::OnDebugModeEntered()
242 disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); 230 disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
243} 231}
244 232
245void DisassemblerWidget::OnDebugModeLeft() 233void DisassemblerWidget::OnDebugModeLeft() {
246{
247
248} 234}
249 235
250int DisassemblerWidget::SelectedRow() 236int DisassemblerWidget::SelectedRow() {
251{
252 QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex(); 237 QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex();
253 if (!index.isValid()) 238 if (!index.isValid())
254 return -1; 239 return -1;
255 240
256 return disasm_ui.treeView->selectionModel()->currentIndex().row(); 241 return disasm_ui.treeView->selectionModel()->currentIndex().row();
257} 242}
243
244void DisassemblerWidget::OnEmulationStarting(EmuThread* emu_thread) {
245 this->emu_thread = emu_thread;
246
247 model = new DisassemblerModel(this);
248 disasm_ui.treeView->setModel(model);
249
250 connect(disasm_ui.treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
251 model, SLOT(OnSelectionChanged(const QModelIndex&)));
252 connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), model, SLOT(OnSetOrUnsetBreakpoint()));
253 connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), model, SLOT(OnSetOrUnsetBreakpoint()));
254
255 Init();
256 setEnabled(true);
257}
258
259void DisassemblerWidget::OnEmulationStopping() {
260 disasm_ui.treeView->setModel(nullptr);
261 delete model;
262 emu_thread = nullptr;
263 setEnabled(false);
264}
diff --git a/src/citra_qt/debugger/disassembler.h b/src/citra_qt/debugger/disassembler.h
index 5e19d7c51..45b0a7e08 100644
--- a/src/citra_qt/debugger/disassembler.h
+++ b/src/citra_qt/debugger/disassembler.h
@@ -51,7 +51,7 @@ class DisassemblerWidget : public QDockWidget
51 Q_OBJECT 51 Q_OBJECT
52 52
53public: 53public:
54 DisassemblerWidget(QWidget* parent, EmuThread& emu_thread); 54 DisassemblerWidget(QWidget* parent, EmuThread* emu_thread);
55 55
56 void Init(); 56 void Init();
57 57
@@ -65,6 +65,9 @@ public slots:
65 void OnDebugModeEntered(); 65 void OnDebugModeEntered();
66 void OnDebugModeLeft(); 66 void OnDebugModeLeft();
67 67
68 void OnEmulationStarting(EmuThread* emu_thread);
69 void OnEmulationStopping();
70
68private: 71private:
69 // returns -1 if no row is selected 72 // returns -1 if no row is selected
70 int SelectedRow(); 73 int SelectedRow();
@@ -75,5 +78,5 @@ private:
75 78
76 u32 base_addr; 79 u32 base_addr;
77 80
78 EmuThread& emu_thread; 81 EmuThread* emu_thread;
79}; 82};
diff --git a/src/citra_qt/debugger/graphics_breakpoints_p.h b/src/citra_qt/debugger/graphics_breakpoints_p.h
index 232bfc863..34e72e859 100644
--- a/src/citra_qt/debugger/graphics_breakpoints_p.h
+++ b/src/citra_qt/debugger/graphics_breakpoints_p.h
@@ -25,7 +25,7 @@ public:
25 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; 25 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
26 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 26 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
27 27
28 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); 28 bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
29 29
30public slots: 30public slots:
31 void OnBreakPointHit(Pica::DebugContext::Event event); 31 void OnBreakPointHit(Pica::DebugContext::Event event);
diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp
index ae0568b6a..2ac1748b7 100644
--- a/src/citra_qt/debugger/profiler.cpp
+++ b/src/citra_qt/debugger/profiler.cpp
@@ -26,7 +26,7 @@ static QVariant GetDataForColumn(int col, const AggregatedDuration& duration)
26static const TimingCategoryInfo* GetCategoryInfo(int id) 26static const TimingCategoryInfo* GetCategoryInfo(int id)
27{ 27{
28 const auto& categories = GetProfilingManager().GetTimingCategoriesInfo(); 28 const auto& categories = GetProfilingManager().GetTimingCategoriesInfo();
29 if (id >= categories.size()) { 29 if ((size_t)id >= categories.size()) {
30 return nullptr; 30 return nullptr;
31 } else { 31 } else {
32 return &categories[id]; 32 return &categories[id];
@@ -98,7 +98,7 @@ QVariant ProfilerModel::data(const QModelIndex& index, int role) const
98 const TimingCategoryInfo* info = GetCategoryInfo(index.row() - 2); 98 const TimingCategoryInfo* info = GetCategoryInfo(index.row() - 2);
99 return info != nullptr ? QString(info->name) : QVariant(); 99 return info != nullptr ? QString(info->name) : QVariant();
100 } else { 100 } else {
101 if (index.row() - 2 < results.time_per_category.size()) { 101 if (index.row() - 2 < (int)results.time_per_category.size()) {
102 return GetDataForColumn(index.column(), results.time_per_category[index.row() - 2]); 102 return GetDataForColumn(index.column(), results.time_per_category[index.row() - 2]);
103 } else { 103 } else {
104 return QVariant(); 104 return QVariant();
diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h
index a6d87aa0f..fabf279b8 100644
--- a/src/citra_qt/debugger/profiler.h
+++ b/src/citra_qt/debugger/profiler.h
@@ -18,7 +18,7 @@ class ProfilerModel : public QAbstractItemModel
18public: 18public:
19 ProfilerModel(QObject* parent); 19 ProfilerModel(QObject* parent);
20 20
21 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 21 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
22 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; 22 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
23 QModelIndex parent(const QModelIndex& child) const override; 23 QModelIndex parent(const QModelIndex& child) const override;
24 int columnCount(const QModelIndex& parent = QModelIndex()) const override; 24 int columnCount(const QModelIndex& parent = QModelIndex()) const override;
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp
index ab3666156..5527a2afd 100644
--- a/src/citra_qt/debugger/registers.cpp
+++ b/src/citra_qt/debugger/registers.cpp
@@ -7,8 +7,7 @@
7#include "core/core.h" 7#include "core/core.h"
8#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
9 9
10RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) 10RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) {
11{
12 cpu_regs_ui.setupUi(this); 11 cpu_regs_ui.setupUi(this);
13 12
14 tree = cpu_regs_ui.treeWidget; 13 tree = cpu_regs_ui.treeWidget;
@@ -18,8 +17,7 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
18 registers->setExpanded(true); 17 registers->setExpanded(true);
19 CSPR->setExpanded(true); 18 CSPR->setExpanded(true);
20 19
21 for (int i = 0; i < 16; ++i) 20 for (int i = 0; i < 16; ++i) {
22 {
23 QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0')))); 21 QTreeWidgetItem* child = new QTreeWidgetItem(QStringList(QString("R[%1]").arg(i, 2, 10, QLatin1Char('0'))));
24 registers->addChild(child); 22 registers->addChild(child);
25 } 23 }
@@ -39,12 +37,16 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent)
39 CSPR->addChild(new QTreeWidgetItem(QStringList("C"))); 37 CSPR->addChild(new QTreeWidgetItem(QStringList("C")));
40 CSPR->addChild(new QTreeWidgetItem(QStringList("Z"))); 38 CSPR->addChild(new QTreeWidgetItem(QStringList("Z")));
41 CSPR->addChild(new QTreeWidgetItem(QStringList("N"))); 39 CSPR->addChild(new QTreeWidgetItem(QStringList("N")));
40
41 setEnabled(false);
42} 42}
43 43
44void RegistersWidget::OnDebugModeEntered() 44void RegistersWidget::OnDebugModeEntered() {
45{
46 ARM_Interface* app_core = Core::g_app_core; 45 ARM_Interface* app_core = Core::g_app_core;
47 46
47 if (app_core == nullptr)
48 return;
49
48 for (int i = 0; i < 16; ++i) 50 for (int i = 0; i < 16; ++i)
49 registers->child(i)->setText(1, QString("0x%1").arg(app_core->GetReg(i), 8, 16, QLatin1Char('0'))); 51 registers->child(i)->setText(1, QString("0x%1").arg(app_core->GetReg(i), 8, 16, QLatin1Char('0')));
50 52
@@ -66,7 +68,22 @@ void RegistersWidget::OnDebugModeEntered()
66 CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than 68 CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than
67} 69}
68 70
69void RegistersWidget::OnDebugModeLeft() 71void RegistersWidget::OnDebugModeLeft() {
70{ 72}
73
74void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) {
75 setEnabled(true);
76}
77
78void RegistersWidget::OnEmulationStopping() {
79 // Reset widget text
80 for (int i = 0; i < 16; ++i)
81 registers->child(i)->setText(1, QString(""));
82
83 for (int i = 0; i < 15; ++i)
84 CSPR->child(i)->setText(1, QString(""));
85
86 CSPR->setText(1, QString(""));
71 87
88 setEnabled(false);
72} 89}
diff --git a/src/citra_qt/debugger/registers.h b/src/citra_qt/debugger/registers.h
index bf8955625..68e3fb908 100644
--- a/src/citra_qt/debugger/registers.h
+++ b/src/citra_qt/debugger/registers.h
@@ -8,6 +8,7 @@
8#include <QTreeWidgetItem> 8#include <QTreeWidgetItem>
9 9
10class QTreeWidget; 10class QTreeWidget;
11class EmuThread;
11 12
12class RegistersWidget : public QDockWidget 13class RegistersWidget : public QDockWidget
13{ 14{
@@ -20,6 +21,9 @@ public slots:
20 void OnDebugModeEntered(); 21 void OnDebugModeEntered();
21 void OnDebugModeLeft(); 22 void OnDebugModeLeft();
22 23
24 void OnEmulationStarting(EmuThread* emu_thread);
25 void OnEmulationStopping();
26
23private: 27private:
24 Ui::ARMRegisters cpu_regs_ui; 28 Ui::ARMRegisters cpu_regs_ui;
25 29