ComSquare
APUDebug.hpp
Go to the documentation of this file.
1 //
2 // Created by Melefo on 19/02/2020.
3 //
4 
5 #pragma once
6 
7 #include "ClosableWindow.hpp"
8 #include "ui/ui_apuView.h"
9 #include <QTimer>
10 
11 namespace ComSquare
12 {
13  class SNES;
14 
15  namespace APU
16  {
17  class APU;
18  }
19 
20  namespace Debugger::APU
21  {
23  enum Operand
24  {
26  A,
27  X,
28  Y,
29  SP,
30  PSW,
44  };
45 
47  struct Instruction
48  {
49  std::string name;
50  int size;
51  std::tuple<Operand, Operand> operands;
52  };
53 
54  class APUDebug : public QObject
55  {
56  Q_OBJECT
57  private:
59  const std::array<Instruction, 0x100> _instructions {{
60  {"NOP", 1, {None, None}},
61  {"TCALL", 1, {None, None}},
62  {"SET1", 2, {DirectAddr, None}},
63  {"BBS", 3, {DirectAddr, ImmediateData}},
64  {"OR", 2, {DirectAddr, None}},
65  {"OR", 3, {AbsoluteAddr, None}},
66  {"OR", 1, {IndexXAddr, None}},
67  {"OR", 2, {AbsoluteDirectByXAddr, None}},
68  {"OR", 2, {ImmediateData, None}},
69  {"OR", 3, {DirectAddr, DirectAddr}},
70  {"OR1", 3, {AbsoluteBit, None}},
71  {"ASL", 2, {DirectAddr, None}},
72  {"ASL", 3, {AbsoluteAddr, None}},
73  {"PUSH", 1, {PSW, None}},
74  {"TSET1", 3, {AbsoluteAddr, None}},
75  {"BRK", 1, {None, None}},
76  {"BPL", 2, {ImmediateData, None}},
77  {"TCALL", 1, {None, None}},
78  {"CLR1", 2, {DirectAddr, None}},
79  {"BBC", 3, {DirectAddr, ImmediateData}},
80  {"OR", 2, {DirectAddrByX, None}},
81  {"OR", 3, {AbsoluteAddrByX, None}},
82  {"OR", 3, {AbsoluteAddrByY, None}},
83  {"OR", 2, {AbsoluteDirectAddrByY, None}},
84  {"OR", 3, {DirectAddr, ImmediateData}},
85  {"OR", 1, {IndexYAddr, IndexYAddr}},
86  {"DECW", 2, {DirectAddr, None}},
87  {"ASL", 2, {DirectAddrByX, None}},
88  {"ASL", 1, {A, None}},
89  {"DEC", 1, {X, None}},
90  {"CMP", 3, {X, AbsoluteAddr}},
91  {"JMP", 3, {AbsoluteByXAddr, None}},
92  {"CLRP", 1, {None, None}},
93  {"TCALL", 1, {None, None}},
94  {"SET1", 2, {DirectAddr, None}},
95  {"BBS", 3, {DirectAddr, ImmediateData}},
96  {"AND", 2, {DirectAddr, None}},
97  {"AND", 3, {AbsoluteAddr, None}},
98  {"AND", 1, {IndexXAddr, None}},
99  {"AND", 2, {AbsoluteDirectByXAddr, None}},
100  {"AND", 2, {ImmediateData, None}},
101  {"AND", 3, {DirectAddr, DirectAddr}},
102  {"OR1", 3, {AbsoluteBit, None}},
103  {"ROL", 2, {DirectAddr, None}},
104  {"ROL", 3, {AbsoluteAddr, None}},
105  {"PUSH", 1, {A, None}},
106  {"CBNE", 3, {DirectAddrByX, ImmediateData}},
107  {"BRA", 2, {ImmediateData, None}},
108  {"BMI", 2, {ImmediateData, None}},
109  {"TCALL", 1, {None, None}},
110  {"CLR1", 2, {DirectAddr, None}},
111  {"BBC", 3, {DirectAddr, ImmediateData}},
112  {"AND", 2, {DirectAddrByX, None}},
113  {"AND", 3, {AbsoluteAddrByX, None}},
114  {"AND", 3, {AbsoluteAddrByY, None}},
115  {"AND", 2, {AbsoluteDirectAddrByY, None}},
116  {"AND", 3, {DirectAddr, ImmediateData}},
117  {"AND", 1, {IndexXAddr, IndexYAddr}},
118  {"INCW", 2, {DirectAddr, None}},
119  {"ROL", 2, {AbsoluteAddrByX, None}},
120  {"ROL", 1, {A, None}},
121  {"INC", 1, {X, None}},
122  {"CMP", 2, {X, DirectAddr}},
123  {"CALL", 3, {AbsoluteAddr, None}},
124  {"SETP", 1, {None, None}},
125  {"TCALL", 1, {None, None}},
126  {"SET1", 2, {DirectAddr, None}},
127  {"BBS", 3, {DirectAddr, ImmediateData}},
128  {"EOR", 2, {DirectAddr, None}},
129  {"EOR", 3, {AbsoluteAddr, None}},
130  {"EOR", 1, {IndexXAddr, None}},
131  {"EOR", 2, {AbsoluteDirectByXAddr, None}},
132  {"EOR", 2, {ImmediateData, None}},
133  {"EOR", 3, {DirectAddr, DirectAddr}},
134  {"AND1", 3, {AbsoluteBit, None}},
135  {"LSR", 2, {DirectAddr, None}},
136  {"LSR", 3, {AbsoluteAddr, None}},
137  {"PUSH", 1, {X, None}},
138  {"TCLR1", 3, {AbsoluteAddr, None}},
139  {"PCALL", 3, {None, None}},
140  {"BVC", 2, {ImmediateData, None}},
141  {"TCALL", 1, {None, None}},
142  {"CLR1", 2, {DirectAddr, None}},
143  {"BBC", 3, {DirectAddr, ImmediateData}},
144  {"EOR", 2, {DirectAddrByX, None}},
145  {"EOR", 3, {AbsoluteAddrByX, None}},
146  {"EOR", 3, {AbsoluteAddrByY, None}},
147  {"EOR", 2, {AbsoluteDirectAddrByY, None}},
148  {"EOR", 3, {DirectAddr, ImmediateData}},
149  {"EOR", 1, {IndexXAddr, IndexYAddr}},
150  {"CMPW", 2, {DirectAddr, None}},
151  {"LSR", 2, {DirectAddrByX, None}},
152  {"LSR", 1, {A, None}},
153  {"MOV", 1, {A, X}},
154  {"CMP", 3, {Y, AbsoluteAddr}},
155  {"JMP", 3, {AbsoluteAddr, None}},
156  {"CLRC", 1, {None, None}},
157  {"TCALL", 1, {None, None}},
158  {"SET1", 2, {DirectAddr, None}},
159  {"BBS", 3, {DirectAddr, ImmediateData}},
160  {"CMP", 2, {A, DirectAddr}},
161  {"CMP", 3, {A, AbsoluteAddr}},
162  {"CMP", 1, {A, IndexXAddr,}},
163  {"CMP", 2, {A, AbsoluteDirectByXAddr}},
164  {"CMP", 2, {A, ImmediateData}},
165  {"CMP", 3, {DirectAddr, DirectAddr}},
166  {"AND1", 3, {AbsoluteBit, None}},
167  {"ROR", 2, {DirectAddr, None}},
168  {"ROR", 3, {AbsoluteAddr, None}},
169  {"PUSH", 1, {Y, None}},
170  {"DBNZ", 3, {ImmediateData, None}},
171  {"RET", 1, {None, None}},
172  {"BVS", 2, {ImmediateData, None}},
173  {"TCALL", 1, {None, None}},
174  {"CLR1", 2, {DirectAddr, None}},
175  {"BBC", 3, {DirectAddr, ImmediateData}},
176  {"CMP", 2, {A, DirectAddrByX}},
177  {"CMP", 3, {A, AbsoluteAddrByX}},
178  {"CMP", 3, {A, AbsoluteAddrByY}},
179  {"CMP", 2, {A, AbsoluteDirectAddrByY}},
180  {"CMP", 3, {DirectAddr, ImmediateData}},
181  {"CMP", 1, {IndexXAddr, IndexYAddr}},
182  {"ADDW", 2, {DirectAddr, None}},
183  {"ROR", 2, {DirectAddrByX, None}},
184  {"ROR", 1, {A, None}},
185  {"MOV", 1, {X, A}},
186  {"CMP", 3, {Y, DirectAddr}},
187  {"RETI", 1, {None, None}},
188  {"SETC", 1, {None, None}},
189  {"TCALL", 1, {None, None}},
190  {"SET1", 2, {DirectAddr, None}},
191  {"BBS", 3, {DirectAddr, ImmediateData}},
192  {"ADC", 2, {DirectAddr, None}},
193  {"ADC", 3, {AbsoluteAddr, None}},
194  {"ADC", 1, {IndexXAddr, None}},
195  {"ADC", 2, {AbsoluteDirectByXAddr, None}},
196  {"ADC", 2, {ImmediateData, None}},
197  {"ADC", 3, {DirectAddr, DirectAddr}},
198  {"EOR1", 3, {AbsoluteBit, None}},
199  {"DEC", 2, {DirectAddr, None}},
200  {"DEC", 3, {AbsoluteAddr, None}},
201  {"MOV", 2, {ImmediateData, Y}},
202  {"POP", 1, {PSW, None}},
203  {"MOV", 3, {DirectAddr, ImmediateData}},
204  {"BCC", 2, {ImmediateData, None}},
205  {"TCALL", 1, {None, None}},
206  {"CLR1", 2, {DirectAddr, None}},
207  {"BBC", 3, {DirectAddr, ImmediateData}},
208  {"ADC", 2, {DirectAddrByX, None}},
209  {"ADC", 3, {AbsoluteAddrByX, None}},
210  {"ADC", 3, {AbsoluteAddrByY, None}},
211  {"ADC", 2, {AbsoluteDirectAddrByY, None}},
212  {"ADC", 3, {DirectAddr, ImmediateData}},
213  {"ADC", 1, {IndexXAddr, IndexYAddr}},
214  {"SUBW", 2, {DirectAddr, None}},
215  {"DEC", 2, {DirectAddrByX, None}},
216  {"DEC", 1, {A, None}},
217  {"MOV", 1, {SP, X}},
218  {"DIV", 1, {None, None}},
219  {"XCN", 1, {None, None}},
220  {"EI", 1, {None, None}},
221  {"TCALL", 1, {None, None}},
222  {"SET1", 2, {DirectAddr, None}},
223  {"BBS", 3, {DirectAddr, ImmediateData}},
224  {"SBC", 2, {DirectAddr, None}},
225  {"SBC", 3, {AbsoluteAddr, None}},
226  {"SBC", 1, {IndexXAddr, None}},
227  {"SBC", 2, {AbsoluteDirectByXAddr, None}},
228  {"SBC", 2, {ImmediateData, None}},
229  {"SBC", 3, {DirectAddr, DirectAddr}},
230  {"MOV1", 3, {AbsoluteBit, None}},
231  {"INC", 2, {DirectAddr, None}},
232  {"INC", 3, {AbsoluteAddr, None}},
233  {"CMP", 2, {Y, ImmediateData}},
234  {"POP", 1, {A, None}},
235  {"MOV", 1, {A, IndexXAddr}},
236  {"BCS", 2, {ImmediateData, None}},
237  {"TCALL", 1, {None, None}},
238  {"CLR1", 2, {DirectAddr, None}},
239  {"BBC", 3, {DirectAddr, ImmediateData}},
240  {"SBC", 2, {DirectAddrByX, None}},
241  {"SBC", 3, {AbsoluteAddrByX, None}},
242  {"SBC", 3, {AbsoluteAddrByY, None}},
243  {"SBC", 2, {AbsoluteDirectAddrByY, None}},
244  {"SBC", 2, {DirectAddr, ImmediateData}},
245  {"SBC", 1, {IndexXAddr, IndexYAddr}},
246  {"MOVW", 2, {DirectAddr, None}},
247  {"INC", 2, {DirectAddrByX, None}},
248  {"INC", 1, {A, None}},
249  {"MOV", 1, {X, SP}},
250  {"DAS", 1, {None, None}},
251  {"MOV", 1, {IndexXAddr, A}},
252  {"DI", 1, {None, None}},
253  {"TCALL", 1, {None, None}},
254  {"SET1", 2, {DirectAddr, None}},
255  {"BBS", 3, {DirectAddr, ImmediateData}},
256  {"MOV", 2, {A, DirectAddr}},
257  {"MOV", 3, {A, AbsoluteAddr}},
258  {"MOV", 1, {A, IndexXAddr}},
259  {"MOV", 2, {A, AbsoluteDirectByXAddr}},
260  {"CMP", 2, {X, ImmediateData}},
261  {"MOV", 3, {X, AbsoluteAddr}},
262  {"MOV1", 3, {AbsoluteBit, None}},
263  {"MOV", 2, {Y, DirectAddr}},
264  {"MOV", 3, {Y, AbsoluteAddr}},
265  {"MOV", 2, {ImmediateData, X}},
266  {"POP", 1, {X, None}},
267  {"MUL", 1, {None, None}},
268  {"BNE", 2, {ImmediateData, None}},
269  {"TCALL", 1, {None, None}},
270  {"CLR1", 2, {DirectAddr, None}},
271  {"BBC", 3, {DirectAddr, ImmediateData}},
272  {"MOV", 2, {A, DirectAddrByX}},
273  {"MOV", 3, {A, AbsoluteAddrByX}},
274  {"MOV", 3, {A, AbsoluteAddrByY}},
275  {"MOV", 2, {A, AbsoluteDirectAddrByY}},
276  {"MOV", 2, {X, DirectAddr}},
277  {"MOV", 2, {X, DirectAddrByY}},
278  {"MOVW", 2, {DirectAddr, None}},
279  {"MOV", 2, {Y, DirectAddrByX}},
280  {"DEC", 1, {Y, None}},
281  {"MOV", 1, {Y, A}},
282  {"CBNE", 3, {DirectAddrByX, ImmediateData}},
283  {"DAA", 1, {None, None}},
284  {"CLRV", 1, {None, None}},
285  {"TCALL", 1, {None, None}},
286  {"SET1", 2, {DirectAddr, None}},
287  {"BBS", 3, {DirectAddr, ImmediateData}},
288  {"MOV", 2, {DirectAddr, A}},
289  {"MOV", 3, {AbsoluteAddrByX, A}},
290  {"MOV", 1, {IndexXAddr, A}},
291  {"MOV", 2, {AbsoluteDirectByXAddr, A}},
292  {"MOV", 2, {ImmediateData, A}},
293  {"MOV", 3, {AbsoluteAddr, X}},
294  {"NOT1", 3, {AbsoluteBit, None}},
295  {"MOV", 2, {DirectAddr, Y}},
296  {"MOV", 3, {AbsoluteAddr, Y}},
297  {"NOTC", 1, {None, None}},
298  {"POP", 1, {Y, None}},
299  {"SLEEP", 1, {None, None}},
300  {"BEQ", 2, {ImmediateData, None}},
301  {"TCALL", 1, {None, None}},
302  {"CLR1", 2, {DirectAddr, None}},
303  {"BBC", 3, {DirectAddr, ImmediateData}},
304  {"MOV", 2, {DirectAddrByX, A}},
305  {"MOV", 3, {AbsoluteAddrByX, A}},
306  {"MOV", 3, {AbsoluteAddrByY, A}},
307  {"MOV", 2, {AbsoluteDirectAddrByY, A}},
308  {"MOV", 2, {DirectAddr, X}},
309  {"MOV", 2, {DirectAddrByY, X}},
310  {"MOV", 3, {DirectAddr, DirectAddr}},
311  {"MOV", 2, {DirectAddrByX, Y}},
312  {"INC", 1, {Y, None}},
313  {"MOV", 1, {A, Y}},
314  {"DBNZ", 3, {ImmediateData, None}},
315  {"STOP", 1, {None, None}}
316  }};
317 
319  int _appendInstruction(int row);
320 
324  QTimer _timer;
325 
327  Ui::APUView _ui;
328 
330  bool _isPaused = true;
332  bool _isStepping = false;
333 
336 
338  void _updatePanel();
339 
341  void _updateLogger();
342 
344  [[nodiscard]] const Instruction &_getInstruction() const;
345 
347  [[nodiscard]] std::string _getOperand(Operand ope) const;
348 
349  public slots:
351  void pause();
353  void step();
355  void update();
356  public:
358  explicit APUDebug(ComSquare::APU::APU &apu, SNES &snes);
359  APUDebug(const APUDebug &) = delete;
360  APUDebug &operator=(const APUDebug &) = delete;
361  ~APUDebug() override;
362 
364  void focus();
365  };
366  }
367 }
ComSquare::Debugger::APU::AbsoluteAddrByX
@ AbsoluteAddrByX
Definition: APUDebug.hpp:36
ComSquare::Debugger::APU::AbsoluteBit
@ AbsoluteBit
Definition: APUDebug.hpp:34
ComSquare::Debugger::APU::APUDebug::_instructions
const std::array< Instruction, 0x100 > _instructions
List of instructions and their information.
Definition: APUDebug.hpp:59
ComSquare::Debugger::APU::AbsoluteDirectAddrByY
@ AbsoluteDirectAddrByY
Definition: APUDebug.hpp:40
ComSquare::Debugger::APU::IndexXAddr
@ IndexXAddr
Definition: APUDebug.hpp:32
ComSquare::Debugger::APU::AbsoluteAddrByY
@ AbsoluteAddrByY
Definition: APUDebug.hpp:37
ComSquare::Debugger::APU::APUDebug::_isStepping
bool _isStepping
If this is set to true, the APU will execute one instruction and pause itself.
Definition: APUDebug.hpp:332
ComSquare::Debugger::APU::APUDebug::_appendInstruction
int _appendInstruction(int row)
Add instruction to disassembly.
Definition: APUDebug.cpp:289
ComSquare::Debugger::APU::SP
@ SP
Definition: APUDebug.hpp:29
ComSquare::Debugger::APU::APUDebug::_timer
QTimer _timer
Internal timer used for update intervals.
Definition: APUDebug.hpp:324
ComSquare::Debugger::APU::X
@ X
Definition: APUDebug.hpp:27
ComSquare::Debugger::APU::APUDebug::focus
void focus()
Focus the debugger's window.
Definition: APUDebug.cpp:425
ComSquare::Debugger::APU::APUDebug::_getOperand
std::string _getOperand(Operand ope) const
Returns an operand in text format.
Definition: APUDebug.cpp:308
ComSquare::Debugger::APU::Instruction::name
std::string name
Definition: APUDebug.hpp:49
ComSquare::Debugger::APU::APUDebug::_updateLogger
void _updateLogger()
Updates the object that serves as the disassembly.
Definition: APUDebug.cpp:261
ComSquare::Debugger::ClosableWindow
Definition: ClosableWindow.hpp:12
ComSquare::Debugger::APU::APUDebug::_isPaused
bool _isPaused
If this is set to true, the execution of the APU will be paused.
Definition: APUDebug.hpp:330
ComSquare::Debugger::APU::Instruction::size
int size
Definition: APUDebug.hpp:50
ComSquare::Debugger::APU::None
@ None
Definition: APUDebug.hpp:25
ComSquare::Debugger::APU::APUDebug::_ui
Ui::APUView _ui
A widget that contain the whole UI.
Definition: APUDebug.hpp:327
ComSquare::Debugger::APU::IndexYAddr
@ IndexYAddr
Definition: APUDebug.hpp:33
ComSquare::Debugger::APU::PSW
@ PSW
Definition: APUDebug.hpp:30
ComSquare::Debugger::APU::APUDebug::_getInstruction
const Instruction & _getInstruction() const
Retrieves the instruction from the SP location.
Definition: APUDebug.cpp:377
ComSquare::Debugger::APU::AbsoluteByXAddr
@ AbsoluteByXAddr
Definition: APUDebug.hpp:38
ComSquare::Debugger::APU::A
@ A
Definition: APUDebug.hpp:26
ComSquare::SNES
Container of all the components of the SNES.
Definition: SNES.hpp:32
ComSquare::Debugger::APU::DirectAddrByY
@ DirectAddrByY
Definition: APUDebug.hpp:43
ComSquare::Debugger::APU::APUDebug::pause
void pause()
Pause/Resume the APU.
Definition: APUDebug.cpp:416
ComSquare::Debugger::APU::AbsoluteAddr
@ AbsoluteAddr
Definition: APUDebug.hpp:35
ComSquare::Debugger::APU::Operand
Operand
List of all types of operands used by the instructions.
Definition: APUDebug.hpp:23
ComSquare::Debugger::APU::Instruction::operands
std::tuple< Operand, Operand > operands
Definition: APUDebug.hpp:51
ComSquare::Debugger::APU::APUDebug::APUDebug
APUDebug(ComSquare::APU::APU &apu, SNES &snes)
Convert a basic APU to a debugging APU.
Definition: APUDebug.cpp:13
ComSquare::Debugger::APU::APUDebug::operator=
APUDebug & operator=(const APUDebug &)=delete
ComSquare::Debugger::APU::DirectAddrByX
@ DirectAddrByX
Definition: APUDebug.hpp:42
ComSquare::Debugger::APU::APUDebug::step
void step()
Step - Execute a single instruction.
Definition: APUDebug.cpp:410
ComSquare::Debugger::APU::APUDebug::_apu
ComSquare::APU::APU & _apu
The APU to debug.
Definition: APUDebug.hpp:335
ClosableWindow.hpp
ComSquare::Debugger::APU::APUDebug::_updatePanel
void _updatePanel()
Update the debugger panel values.
Definition: APUDebug.cpp:42
ComSquare::Debugger::APU::AbsoluteDirectByXAddr
@ AbsoluteDirectByXAddr
Definition: APUDebug.hpp:39
ComSquare::APU::APU
Definition: APU.hpp:138
ComSquare::Debugger::APU::ImmediateData
@ ImmediateData
Definition: APUDebug.hpp:31
ComSquare::Debugger::APU::Instruction
Small structure to store some values on the instructions.
Definition: APUDebug.hpp:47
ComSquare::Debugger::APU::DirectAddr
@ DirectAddr
Definition: APUDebug.hpp:41
ComSquare::Debugger::APU::Y
@ Y
Definition: APUDebug.hpp:28
ComSquare::Debugger::APU::APUDebug::update
void update()
Update the debugger and the underlying APU.
Definition: APUDebug.cpp:384
ComSquare::Debugger::APU::APUDebug
Definition: APUDebug.hpp:54
ComSquare::Debugger::APU::APUDebug::~APUDebug
~APUDebug() override
Definition: APUDebug.cpp:37
ComSquare
Definition: APU.cpp:12
ComSquare::Debugger::APU::APUDebug::_window
ClosableWindow * _window
The QT window for this debugger.
Definition: APUDebug.hpp:322