Commit | Line | Data |
---|---|---|
cf76e892 JPM |
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 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 A1: %08X A2: %08X 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 A5: %08X A6: %08X 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 D1: %08X D2: %08X 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 D5: %08X D6: %08X D7: %08X<br><br>", m68kD4, m68kD5, m68kD6, m68kD7); | |
117 | s += QString(string); | |
118 | ||
119 | // GPU | |
120 | sprintf(string, "GPU PC: %06X FLAGS: %04X 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 R01: %08X R02: %08X R03: %08X<br>" | |
147 | "R04: %08X R05: %08X R06: %08X R07: %08X<br>" | |
148 | "R08: %08X R09: %08X R10: %08X R11: %08X<br>" | |
149 | "R12: %08X R13: %08X R14: %08X R15: %08X<br>" | |
150 | "R16: %08X R17: %08X R18: %08X R19: %08X<br>" | |
151 | "R20: %08X R21: %08X R22: %08X R23: %08X<br>" | |
152 | "R24: %08X R25: %08X R26: %08X R27: %08X<br>" | |
153 | "R28: %08X R29: %08X R30: %08X 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 R01: %08X R02: %08X R03: %08X<br>" | |
166 | "R04: %08X R05: %08X R06: %08X R07: %08X<br>" | |
167 | "R08: %08X R09: %08X R10: %08X R11: %08X<br>" | |
168 | "R12: %08X R13: %08X R14: %08X R15: %08X<br>" | |
169 | "R16: %08X R17: %08X R18: %08X R19: %08X<br>" | |
170 | "R20: %08X R21: %08X R22: %08X R23: %08X<br>" | |
171 | "R24: %08X R25: %08X R26: %08X R27: %08X<br>" | |
172 | "R28: %08X R29: %08X R30: %08X 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 FLAGS: %05X 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 R01: %08X R02: %08X R03: %08X<br>" | |
214 | "R04: %08X R05: %08X R06: %08X R07: %08X<br>" | |
215 | "R08: %08X R09: %08X R10: %08X R11: %08X<br>" | |
216 | "R12: %08X R13: %08X R14: %08X R15: %08X<br>" | |
217 | "R16: %08X R17: %08X R18: %08X R19: %08X<br>" | |
218 | "R20: %08X R21: %08X R22: %08X R23: %08X<br>" | |
219 | "R24: %08X R25: %08X R26: %08X R27: %08X<br>" | |
220 | "R28: %08X R29: %08X R30: %08X 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 R01: %08X R02: %08X R03: %08X<br>" | |
233 | "R04: %08X R05: %08X R06: %08X R07: %08X<br>" | |
234 | "R08: %08X R09: %08X R10: %08X R11: %08X<br>" | |
235 | "R12: %08X R13: %08X R14: %08X R15: %08X<br>" | |
236 | "R16: %08X R17: %08X R18: %08X R19: %08X<br>" | |
237 | "R20: %08X R21: %08X R22: %08X R23: %08X<br>" | |
238 | "R24: %08X R25: %08X R26: %08X R27: %08X<br>" | |
239 | "R28: %08X R29: %08X R30: %08X 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 |