First commit
[clinton/Virtual-Jaguar-Rx.git] / src / gui / debug / cpubrowser.cpp
1 //
2 // cpubrowser.cpp - Jaguar CPU browser
3 //
4 // by James Hammons
5 // (C) 2012 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 //
10 // Who When What
11 // --- ---------- -----------------------------------------------------------
12 // JLH 08/14/2012 Created this file
13 // JPM 08/09/2017 Added windows display detection in order to avoid the refresh
14 //
15
16 // STILL TO DO:
17 //
18
19 #include "cpubrowser.h"
20 //#include "memory.h"
21 #include "m68000/m68kinterface.h"
22 #include "dsp.h"
23 #include "gpu.h"
24 #include "jaguar.h"
25
26
27 CPUBrowserWindow::CPUBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
28 layout(new QVBoxLayout), text(new QLabel),
29 refresh(new QPushButton(tr("Refresh"))),
30 bpm(new QCheckBox(tr("BPM"))), bpmAddress(new QLineEdit),
31 bpmContinue(new QPushButton(tr("Resume")))
32 {
33 setWindowTitle(tr("CPU Browser"));
34
35 // Need to set the size as well...
36 // resize(560, 480);
37
38 // Limit input to 6 hex digits
39 bpmAddress->setInputMask("hhhhhh");
40 QHBoxLayout * hbox1 = new QHBoxLayout;
41 hbox1->addWidget(bpm);
42 hbox1->addWidget(bpmAddress);
43 hbox1->addWidget(bpmContinue);
44
45 QFont fixedFont("Lucida Console", 8, QFont::Normal);
46 // QFont fixedFont("", 8, QFont::Normal);
47 fixedFont.setStyleHint(QFont::TypeWriter);
48 text->setFont(fixedFont);
49 //// layout->setSizeConstraint(QLayout::SetFixedSize);
50 setLayout(layout);
51
52 layout->addWidget(text);
53 layout->addLayout(hbox1);
54 layout->addWidget(refresh);
55
56 connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
57 connect(bpm, SIGNAL(clicked(bool)), this, SLOT(HandleBPM(bool)));
58 connect(bpmAddress, SIGNAL(textChanged(const QString &)), this, SLOT(HandleBPMAddress(const QString &)));
59 connect(bpmContinue, SIGNAL(clicked()), this, SLOT(HandleBPMContinue()));
60 }
61
62
63 void CPUBrowserWindow::RefreshContents(void)
64 {
65 char string[2048];
66 QString s;
67
68 if (isVisible())
69 {
70 // 68K
71 uint32_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
72 uint32_t m68kSR = m68k_get_reg(NULL, M68K_REG_SR);
73 sprintf(string, "PC: %06X&nbsp;&nbsp;SR: %04X<br><br>", m68kPC, m68kSR);
74 s += QString(string);
75 /*
76 SR format:
77 +--+--+--+--+ +--+--+--+--+ +--+--+--+--+ +--+--+--+--+
78 |T1|T0| S| M| |--|I2|I1|I0| |--|--|--| X| | N| Z| V| C|
79 +--+--+--+--+ +--+--+--+--+ +--+--+--+--+ +--+--+--+--+
80 T - Trace (T1 only in 68K, T0 = 0)
81 S - Supervisor flag
82 M - Master/Interrupt flag (= 0 in 68K)
83 I - Interrupt level mask
84 X - Extend flag
85 N - Negative flag
86 Z - Zero flag
87 V - Overflow flag
88 C - Carry flag
89 */
90
91 uint32_t m68kA0 = m68k_get_reg(NULL, M68K_REG_A0);
92 uint32_t m68kA1 = m68k_get_reg(NULL, M68K_REG_A1);
93 uint32_t m68kA2 = m68k_get_reg(NULL, M68K_REG_A2);
94 uint32_t m68kA3 = m68k_get_reg(NULL, M68K_REG_A3);
95 sprintf(string, "A0: %08X&nbsp;&nbsp;A1: %08X&nbsp;&nbsp;A2: %08X&nbsp;&nbsp;A3: %08X<br>", m68kA0, m68kA1, m68kA2, m68kA3);
96 s += QString(string);
97
98 uint32_t m68kA4 = m68k_get_reg(NULL, M68K_REG_A4);
99 uint32_t m68kA5 = m68k_get_reg(NULL, M68K_REG_A5);
100 uint32_t m68kA6 = m68k_get_reg(NULL, M68K_REG_A6);
101 uint32_t m68kA7 = m68k_get_reg(NULL, M68K_REG_A7);
102 sprintf(string, "A4: %08X&nbsp;&nbsp;A5: %08X&nbsp;&nbsp;A6: %08X&nbsp;&nbsp;A7: %08X<br><br>", m68kA4, m68kA5, m68kA6, m68kA7);
103 s += QString(string);
104
105 uint32_t m68kD0 = m68k_get_reg(NULL, M68K_REG_D0);
106 uint32_t m68kD1 = m68k_get_reg(NULL, M68K_REG_D1);
107 uint32_t m68kD2 = m68k_get_reg(NULL, M68K_REG_D2);
108 uint32_t m68kD3 = m68k_get_reg(NULL, M68K_REG_D3);
109 sprintf(string, "D0: %08X&nbsp;&nbsp;D1: %08X&nbsp;&nbsp;D2: %08X&nbsp;&nbsp;D3: %08X<br>", m68kD0, m68kD1, m68kD2, m68kD3);
110 s += QString(string);
111
112 uint32_t m68kD4 = m68k_get_reg(NULL, M68K_REG_D4);
113 uint32_t m68kD5 = m68k_get_reg(NULL, M68K_REG_D5);
114 uint32_t m68kD6 = m68k_get_reg(NULL, M68K_REG_D6);
115 uint32_t m68kD7 = m68k_get_reg(NULL, M68K_REG_D7);
116 sprintf(string, "D4: %08X&nbsp;&nbsp;D5: %08X&nbsp;&nbsp;D6: %08X&nbsp;&nbsp;D7: %08X<br><br>", m68kD4, m68kD5, m68kD6, m68kD7);
117 s += QString(string);
118
119 // GPU
120 sprintf(string, "GPU PC: %06X&nbsp;&nbsp;FLAGS: %04X&nbsp;&nbsp;SR: %04X<br><br>", GPUReadLong(0xF02110, DEBUG), GPUReadLong(0xF02100, DEBUG), GPUReadLong(0xF02114, DEBUG));
121 s += QString(string);
122 /*
123 GPU Flags:
124 0 - Zero flag
125 1 - Carry flag
126 2 - Negative flag
127 3 - IMASK (writing 0 clears, 1 has no effect)
128 4-8 - IRQ enable 0 - 4
129 9-13 - IRQ latch clear 0 - 4
130 14 - REGPAGE
131 15 - DMAEN
132
133 GPU Control:
134 0 - GPU Go
135 1 - CPUINT
136 2 - GPUINT0
137 3 - Single Step
138 4 - Single step go
139 5 - Unused
140 6-10 - IRQ Latch 0 - 4
141 11 - Bus Hog
142 12-15 - Version
143 */
144
145 sprintf(string, "Bank 0:<br>"
146 "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
147 "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
148 "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
149 "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
150 "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
151 "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
152 "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
153 "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
154 gpu_reg_bank_0[0], gpu_reg_bank_0[1], gpu_reg_bank_0[2], gpu_reg_bank_0[3],
155 gpu_reg_bank_0[4], gpu_reg_bank_0[5], gpu_reg_bank_0[6], gpu_reg_bank_0[7],
156 gpu_reg_bank_0[8], gpu_reg_bank_0[9], gpu_reg_bank_0[10], gpu_reg_bank_0[11],
157 gpu_reg_bank_0[12], gpu_reg_bank_0[13], gpu_reg_bank_0[14], gpu_reg_bank_0[15],
158 gpu_reg_bank_0[16], gpu_reg_bank_0[17], gpu_reg_bank_0[18], gpu_reg_bank_0[19],
159 gpu_reg_bank_0[20], gpu_reg_bank_0[21], gpu_reg_bank_0[22], gpu_reg_bank_0[23],
160 gpu_reg_bank_0[24], gpu_reg_bank_0[25], gpu_reg_bank_0[26], gpu_reg_bank_0[27],
161 gpu_reg_bank_0[28], gpu_reg_bank_0[29], gpu_reg_bank_0[30], gpu_reg_bank_0[31]);
162 s += QString(string);
163
164 sprintf(string, "Bank 1:<br>"
165 "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
166 "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
167 "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
168 "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
169 "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
170 "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
171 "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
172 "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
173 gpu_reg_bank_1[0], gpu_reg_bank_1[1], gpu_reg_bank_1[2], gpu_reg_bank_1[3],
174 gpu_reg_bank_1[4], gpu_reg_bank_1[5], gpu_reg_bank_1[6], gpu_reg_bank_1[7],
175 gpu_reg_bank_1[8], gpu_reg_bank_1[9], gpu_reg_bank_1[10], gpu_reg_bank_1[11],
176 gpu_reg_bank_1[12], gpu_reg_bank_1[13], gpu_reg_bank_1[14], gpu_reg_bank_1[15],
177 gpu_reg_bank_1[16], gpu_reg_bank_1[17], gpu_reg_bank_1[18], gpu_reg_bank_1[19],
178 gpu_reg_bank_1[20], gpu_reg_bank_1[21], gpu_reg_bank_1[22], gpu_reg_bank_1[23],
179 gpu_reg_bank_1[24], gpu_reg_bank_1[25], gpu_reg_bank_1[26], gpu_reg_bank_1[27],
180 gpu_reg_bank_1[28], gpu_reg_bank_1[29], gpu_reg_bank_1[30], gpu_reg_bank_1[31]);
181 s += QString(string);
182
183 // DSP
184 sprintf(string, "DSP PC: %06X&nbsp;&nbsp;FLAGS: %05X&nbsp;&nbsp;SR: %05X<br><br>", DSPReadLong(0xF1A110, DEBUG), DSPReadLong(0xF1A100, DEBUG), DSPReadLong(0xF1A114, DEBUG));
185 s += QString(string);
186 /*
187 DSP Flags:
188 0 - Zero flag
189 1 - Carry flag
190 2 - Negative flag
191 3 - IMASK (writing 0 clears, 1 has no effect)
192 4-8 - IRQ enable 0 - 4
193 9-13 - IRQ latch clear 0 - 4
194 14 - REGPAGE
195 15 - DMAEN
196 16 - IRQ enable 5
197 17 - IRQ latch clear 5
198
199 DSP Control:
200 0 - DSP Go
201 1 - CPUINT
202 2 - DSPINT0
203 3 - Single Step
204 4 - Single step go
205 5 - Unused
206 6-10 - IRQ Latch 0 - 4
207 11 - Bus Hog
208 12-15 - Version
209 16 - IRQ Latch 5
210 */
211
212 sprintf(string, "Bank 0:<br>"
213 "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
214 "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
215 "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
216 "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
217 "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
218 "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
219 "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
220 "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br><br>",
221 dsp_reg_bank_0[0], dsp_reg_bank_0[1], dsp_reg_bank_0[2], dsp_reg_bank_0[3],
222 dsp_reg_bank_0[4], dsp_reg_bank_0[5], dsp_reg_bank_0[6], dsp_reg_bank_0[7],
223 dsp_reg_bank_0[8], dsp_reg_bank_0[9], dsp_reg_bank_0[10], dsp_reg_bank_0[11],
224 dsp_reg_bank_0[12], dsp_reg_bank_0[13], dsp_reg_bank_0[14], dsp_reg_bank_0[15],
225 dsp_reg_bank_0[16], dsp_reg_bank_0[17], dsp_reg_bank_0[18], dsp_reg_bank_0[19],
226 dsp_reg_bank_0[20], dsp_reg_bank_0[21], dsp_reg_bank_0[22], dsp_reg_bank_0[23],
227 dsp_reg_bank_0[24], dsp_reg_bank_0[25], dsp_reg_bank_0[26], dsp_reg_bank_0[27],
228 dsp_reg_bank_0[28], dsp_reg_bank_0[29], dsp_reg_bank_0[30], dsp_reg_bank_0[31]);
229 s += QString(string);
230
231 sprintf(string, "Bank 1:<br>"
232 "R00: %08X&nbsp;&nbsp;R01: %08X&nbsp;&nbsp;R02: %08X&nbsp;&nbsp;R03: %08X<br>"
233 "R04: %08X&nbsp;&nbsp;R05: %08X&nbsp;&nbsp;R06: %08X&nbsp;&nbsp;R07: %08X<br>"
234 "R08: %08X&nbsp;&nbsp;R09: %08X&nbsp;&nbsp;R10: %08X&nbsp;&nbsp;R11: %08X<br>"
235 "R12: %08X&nbsp;&nbsp;R13: %08X&nbsp;&nbsp;R14: %08X&nbsp;&nbsp;R15: %08X<br>"
236 "R16: %08X&nbsp;&nbsp;R17: %08X&nbsp;&nbsp;R18: %08X&nbsp;&nbsp;R19: %08X<br>"
237 "R20: %08X&nbsp;&nbsp;R21: %08X&nbsp;&nbsp;R22: %08X&nbsp;&nbsp;R23: %08X<br>"
238 "R24: %08X&nbsp;&nbsp;R25: %08X&nbsp;&nbsp;R26: %08X&nbsp;&nbsp;R27: %08X<br>"
239 "R28: %08X&nbsp;&nbsp;R29: %08X&nbsp;&nbsp;R30: %08X&nbsp;&nbsp;R31: %08X<br>",
240 dsp_reg_bank_1[0], dsp_reg_bank_1[1], dsp_reg_bank_1[2], dsp_reg_bank_1[3],
241 dsp_reg_bank_1[4], dsp_reg_bank_1[5], dsp_reg_bank_1[6], dsp_reg_bank_1[7],
242 dsp_reg_bank_1[8], dsp_reg_bank_1[9], dsp_reg_bank_1[10], dsp_reg_bank_1[11],
243 dsp_reg_bank_1[12], dsp_reg_bank_1[13], dsp_reg_bank_1[14], dsp_reg_bank_1[15],
244 dsp_reg_bank_1[16], dsp_reg_bank_1[17], dsp_reg_bank_1[18], dsp_reg_bank_1[19],
245 dsp_reg_bank_1[20], dsp_reg_bank_1[21], dsp_reg_bank_1[22], dsp_reg_bank_1[23],
246 dsp_reg_bank_1[24], dsp_reg_bank_1[25], dsp_reg_bank_1[26], dsp_reg_bank_1[27],
247 dsp_reg_bank_1[28], dsp_reg_bank_1[29], dsp_reg_bank_1[30], dsp_reg_bank_1[31]);
248 s += QString(string);
249
250 text->clear();
251 text->setText(s);
252 }
253 }
254
255
256 //
257 void CPUBrowserWindow::HoldBPM(void)
258 {
259 bpmSaveActive = bpmActive;
260 bpmActive = false;
261 }
262
263
264 //
265 void CPUBrowserWindow::UnholdBPM(void)
266 {
267 bpmActive = bpmSaveActive;
268 }
269
270
271 // Toggle breakpoint set
272 void CPUBrowserWindow::HandleBPM(bool state)
273 {
274 bpmSaveActive = bpmActive = state;
275
276 if (bpmActive)
277 {
278 printf("BPM Set: $%06X\n", bpmAddress1);
279 }
280 else
281 {
282 printf("BPM Unset: $%06X\n", bpmAddress1);
283 }
284 }
285
286
287 // Breakpoint address set
288 void CPUBrowserWindow::HandleBPMAddress(const QString & newText)
289 {
290 bool ok;
291 bpmAddress1 = newText.toUInt(&ok, 16);
292 }
293
294
295 void CPUBrowserWindow::HandleBPMContinue(void)
296 {
297 M68KDebugResume();
298 }
299
300
301 //
302 void CPUBrowserWindow::keyPressEvent(QKeyEvent * e)
303 {
304 if (e->key() == Qt::Key_Escape)
305 {
306 hide();
307 }
308 else
309 {
310 if (e->key() == Qt::Key_Return)
311 {
312 HandleBPM(true);
313 bpm->setChecked(true);
314 }
315 #if 0
316 else if (e->key() == Qt::Key_PageUp)
317 {
318 memBase -= 480;
319
320 if (memBase < 0)
321 memBase = 0;
322
323 RefreshContents();
324 }
325 else if (e->key() == Qt::Key_PageDown)
326 {
327 memBase += 480;
328
329 if (memBase > (0x200000 - 480))
330 memBase = 0x200000 - 480;
331
332 RefreshContents();
333 }
334 else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)
335 {
336 memBase -= 16;
337
338 if (memBase < 0)
339 memBase = 0;
340
341 RefreshContents();
342 }
343 else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)
344 {
345 memBase += 16;
346
347 if (memBase > (0x200000 - 480))
348 memBase = 0x200000 - 480;
349
350 RefreshContents();
351 }
352 #endif
353 }
354 }
355