007c2b377a1e935c02f3e3c40f37c47827fdef27
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / m68kDasmWin.cpp
1 //
2 // m68kDasmWin.cpp - M68K disassembly window
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // Who When What
9 // --- ---------- -------------------------------------------------------------
10 // JPM 06/27/2016 Created this file
11 // JPM 12/04/2016 Suport ELF debug information
12 // JPM Replacing the ELF support by the debugger information manager calls
13 //
14
15 // STILL TO DO:
16 //
17
18 #include <stdlib.h>
19 #include "debugger/m68kDasmWin.h"
20 //#include "memory.h"
21 #include "m68000/m68kinterface.h"
22 #include "dsp.h"
23 #include "gpu.h"
24 //#include "jaguar.h"
25 //#include "ELFManager.h"
26 #include "DBGManager.h"
27 //extern jaguarRunAddress;
28 #include "settings.h"
29
30
31 //
32 m68KDasmWindow::m68KDasmWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
33 layout(new QVBoxLayout), text(new QTextBrowser),
34 // layout(new QTabWidget), text(new QLabel),
35 #if 0
36 refresh(new QPushButton(tr("Refresh"))),
37 address(new QLineEdit),
38 go(new QPushButton(tr("Go"))),
39 #endif
40 // memBase(0x4000)
41 //sb(new QScrollBar),
42 memBase(0)
43 {
44 // m68kDasmWindow *m68kDasmWin = new m68kDasmWindow();
45 // setWindowTitle(tr("Jaguar Disassembly Window"));
46 // layout->addTab(new m68KDasmWindow(), tr("M68K Disassembly"));
47 //layout = new QTabWidget;
48 //layout->QWidget();
49
50 #if 0
51 address->setInputMask("hhhhhh");
52 QHBoxLayout * hbox1 = new QHBoxLayout;
53 hbox1->addWidget(refresh);
54 hbox1->addWidget(address);
55 hbox1->addWidget(go);
56 #endif
57
58 // Need to set the size as well...
59 // resize(560, 480);
60
61 QFont fixedFont("Lucida Console", 8, QFont::Normal);
62 // QFont fixedFont("", 8, QFont::Normal);
63 fixedFont.setStyleHint(QFont::Monospace); //TypeWriter
64 fixedFont.setLetterSpacing(QFont::PercentageSpacing, 100);
65 text->setFont(fixedFont);
66 // sb = layout->text->verticalScrollBar();
67 // text->setStyleSheet("background-color: DeepSkyBlue;");
68 //// layout->setSizeConstraint(QLayout::SetFixedSize);
69 setLayout(layout);
70
71 layout->addWidget(text);
72 // layout->addWidget(refresh);
73 #if 0
74 layout->addLayout(hbox1);
75 #endif
76
77 #if 0
78 connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
79 connect(go, SIGNAL(clicked()), this, SLOT(GoToAddress()));
80 #endif
81 }
82
83
84 //
85 void m68KDasmWindow::RefreshContents(void)
86 {
87 //char ; //, buf[64];
88 QString s;
89 char buffer[1024], string[1024], adresse[16];
90 size_t pc = memBase, oldpc;
91 size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
92 size_t m68KPCNbrDisasmLines = 0;
93 char *Symbol = NULL, *LineSrc, *CurrentLineSrc = NULL;
94 bool m68kPCShow = false;
95 bool constant, adr, equal, Error;
96 size_t j, i;
97 size_t nbr = vjs.nbrdisasmlines;
98 char *PtrFullSource, *CurrentPtrFullSource = (char *)calloc(1, 1);
99 size_t NumLine; // , CurrentNumLine = 0;
100 // size_t CurrentNumLine = DBGManager_GetNumLineFromAdr(pc, DBG_NO_TAG) - 1;
101 size_t CurrentNumLine;
102 char singleCharString[2] = { 0, 0 };
103
104 //text->clear();
105
106 for (i = 0; i < nbr; i++)
107 {
108 //sb->setValue(sb->maximum());
109 //j = text->verticalScrollBar()->maximum();
110 //text->verticalScrollBar()->setValue(text->verticalScrollBar()->maximum());
111 //if (text->verticalScrollBar()->value())
112 //{
113 // j = 1;
114 //}
115
116 oldpc = pc;
117 // WriteLog("%06X: %s\n", oldpc, buffer);
118 adr = constant = equal = false;
119
120 // Display source filename based on the program address
121 if (vjs.displayFullSourceFilename && (PtrFullSource = DBGManager_GetFullSourceFilenameFromAdr(oldpc, &Error)) && strcmp(CurrentPtrFullSource, PtrFullSource))
122 {
123 #if 0
124 if (strcmp(OldPtrFullSource, PtrFullSource))
125 #endif
126 {
127 #if 1
128 if (i)
129 {
130 nbr++;
131 s += QString("<br>");
132 }
133 #endif
134 CurrentNumLine = DBGManager_GetNumLineFromAdr(pc, DBG_NO_TAG) - 1;
135 nbr++;
136 CurrentPtrFullSource = (char *)realloc(CurrentPtrFullSource, strlen(PtrFullSource) + 1);
137 strcpy(CurrentPtrFullSource, PtrFullSource);
138 if (!Error)
139 {
140 sprintf(string, "<font color='#ff0000'><b>%s</b></font><br>", PtrFullSource);
141 }
142 else
143 {
144 sprintf(string, "<font color='#00ff00'><b>%s</b></font><br>", PtrFullSource);
145 }
146 s += QString(string);
147 }
148 }
149
150 // Display line number based on the program address
151 if ((NumLine = DBGManager_GetNumLineFromAdr(oldpc, DBG_NO_TAG)) && ((signed)NumLine > (signed)CurrentNumLine))
152 {
153 if ((signed)CurrentNumLine < 0)
154 {
155 CurrentNumLine = NumLine - 1;
156 }
157 sprintf(string, "| <font color='#006400'>%5u</font> | ", (unsigned int)++CurrentNumLine); // (CurrentNumLine = NumLine));
158 }
159 else
160 {
161 sprintf(string, "| | ");
162 }
163 s += QString(string);
164
165 // Display line source based on the program address
166 if (((signed)CurrentNumLine > 0) && (LineSrc = DBGManager_GetLineSrcFromNumLineBaseAdr(oldpc, CurrentNumLine)) && (LineSrc != CurrentLineSrc))
167 {
168 sprintf(string, "<font color='#006400'>%s</font><br>", (CurrentLineSrc = LineSrc));
169 s += QString(string);
170 nbr++;
171 }
172 else
173 {
174 // Display symbol, or line source, based on the program address
175 if (!CurrentLineSrc && !Symbol && (Symbol = DBGManager_GetSymbolNameFromAdr(oldpc)))
176 {
177 sprintf(string, "%s:<br>", Symbol);
178 s += QString(string);
179 nbr++;
180 }
181 // Display the assembly line based on the current PC
182 else
183 {
184 pc += m68k_disassemble(buffer, (unsigned int)pc, 0, vjs.disasmopcodes);
185
186 if (m68kPC == oldpc)
187 {
188 sprintf(string, "-> <u>%06X: %s</u><br>", (unsigned int)oldpc, buffer);
189 m68kPCShow = true;
190 m68KPCNbrDisasmLines = i;
191 }
192 else
193 {
194 sprintf(string, " %06X: %s<br>", (unsigned int)oldpc, buffer);
195 }
196
197 buffer[0] = 0; // Clear string
198 //char singleCharString[2] = { 0, 0 };
199
200 for (j = 0; j < strlen(string); j++)
201 {
202 if (string[j] == ' ')
203 {
204 strcat(buffer, "&nbsp;");
205 adr = constant = false;
206 }
207 else
208 {
209 switch (string[j])
210 {
211 case '#':
212 constant = true;
213 break;
214
215 case '$':
216 adr = true;
217 break;
218
219 case ',':
220 constant = adr = equal = false;
221 break;
222
223 case '=':
224 equal = true;
225 break;
226 }
227
228 if (!constant && adr && !equal)
229 {
230 int l = 0;
231 char *p;
232 do
233 {
234 adresse[l++] = string[++j];
235 } while ((string[(j + 1)] >= '0') && (string[(j + 1)] <= '9') || (string[(j + 1)] >= 'A') && (string[(j + 1)] <= 'F'));
236 adresse[l] = 0;
237
238 if (Symbol = DBGManager_GetSymbolNameFromAdr(strtoul(adresse, &p, 16)))
239 {
240 strcat(buffer, Symbol);
241 }
242 else
243 {
244 strcat(buffer, "$");
245 strcat(buffer, adresse);
246 }
247
248 adr = false;
249 }
250 else
251 {
252 singleCharString[0] = string[j];
253 strcat(buffer, singleCharString);
254 }
255 }
256 }
257
258 Symbol = NULL;
259 // s += QString(string);
260 s += QString(buffer);
261 // text->setStyleSheet("QLabel { background-color : red; color : blue; }");
262 }
263 }
264 }
265
266 // Display generated text
267 text->clear();
268 if (m68kPCShow)
269 {
270 text->setText(s);
271 }
272 else
273 {
274 Use68KPCAddress();
275 RefreshContents();
276 }
277
278 // Set the scrollbar position in accordance of the M68K PC pointer
279 if (m68KPCNbrDisasmLines > (nbr / 2))
280 {
281 text->verticalScrollBar()->setValue(text->verticalScrollBar()->maximum());
282 }
283 else
284 {
285 text->verticalScrollBar()->setValue(text->verticalScrollBar()->minimum());
286 }
287
288 free(CurrentPtrFullSource);
289 }
290
291
292 #if 0
293 //
294 void m68KDasmWindow::keyPressEvent(QKeyEvent * e)
295 {
296 // if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return)
297 // hide();
298 #if 0
299 else if (e->key() == Qt::Key_PageUp)
300 {
301 memBase -= 64;
302
303 if (memBase < 0)
304 memBase = 0;
305
306 RefreshContents();
307 }
308 else if (e->key() == Qt::Key_PageDown)
309 {
310 memBase += 64;
311
312 if (memBase > (0xF00000 - 64))
313 memBase = 0xF00000 - 64;
314
315 RefreshContents();
316 }
317 else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)
318 {
319 memBase -= 16;
320
321 if (memBase < 0)
322 memBase = 0;
323
324 RefreshContents();
325 }
326 else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)
327 {
328 memBase += 16;
329
330 if (memBase > (0xF00000 - 64))
331 memBase = 0xF00000 - 64;
332
333 RefreshContents();
334 }
335 #endif
336 }
337 #endif
338
339
340 // Set mem base PC address using the 68K pc current address
341 void m68KDasmWindow::Use68KPCAddress(void)
342 {
343 memBase = m68k_get_reg(NULL, M68K_REG_PC);
344 }
345
346
347 // Set mem base PC address
348 void m68KDasmWindow::SetAddress(int address)
349 {
350 memBase = address;
351 // RefreshContents();
352 }
353
354
355 #if 0
356 // Set mem base PC address based on user interaction
357 void m68KDasmWindow::GoToAddress(void)
358 {
359 bool ok;
360
361 QString newAddress = address->text();
362 memBase = newAddress.toUInt(&ok, 16);
363 RefreshContents();
364 }
365 #endif