core: Fix libdwarf and Qt build failure
[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 // JPM Aug./2020 Display only the code related to the traced function, added different layouts & a status bar, Qt/HTML text format support
14 //
15
16 // STILL TO DO:
17 //
18
19 #include <stdlib.h>
20 #include "debugger/m68kDasmWin.h"
21 #include "m68000/m68kinterface.h"
22 #include "dsp.h"
23 #include "gpu.h"
24 #include "DBGManager.h"
25 #include "settings.h"
26
27
28 //
29 m68KDasmWindow::m68KDasmWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
30 layout(new QVBoxLayout),
31 #if MD_LAYOUTFILE == 1
32 statusbar(new QStatusBar),
33 #endif
34 #ifdef MD_LAYOUTTEXTS
35 text(new QTextBrowser),
36 #endif
37 memBase(0)
38 {
39 // Set font
40 QFont fixedFont("Lucida Console", 8, QFont::Normal);
41 fixedFont.setStyleHint(QFont::Monospace); //TypeWriter
42 fixedFont.setLetterSpacing(QFont::PercentageSpacing, 100);
43
44 // Set text in layout
45 #ifdef MD_LAYOUTTEXTS
46 text->setFont(fixedFont);
47 layout->addWidget(text);
48 #endif
49
50 // Status bar
51 #if MD_LAYOUTFILE == 1
52 layout->addWidget(statusbar);
53 setLayout(layout);
54 #endif
55
56 // Set layout
57 setLayout(layout);
58 }
59
60
61 //
62 void m68KDasmWindow::RefreshContents(void)
63 {
64 QString s;
65 char buffer[1024], string[1024], adresse[16];
66 size_t pc = memBase, oldpc;
67 size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
68 size_t m68KPCNbrDisasmLines = 0;
69 char *Symbol = NULL, *LineSrc, *CurrentLineSrc = NULL;
70 bool m68kPCShow = false;
71 bool constant, adr, equal;
72 DBGstatus Status;
73 size_t j, i;
74 size_t nbr = vjs.nbrdisasmlines;
75 char *PtrFullSource, *CurrentPtrFullSource = (char *)calloc(1, 1);
76 size_t NumLine; // , CurrentNumLine = 0;
77 size_t CurrentNumLine;
78 char singleCharString[2] = { 0, 0 };
79 #if MD_LAYOUTFILE == 1
80 bool In = true;
81 #else
82 #define In true
83 #endif
84
85 for (i = 0; (i < nbr) && In; i++)
86 {
87 oldpc = pc;
88 adr = constant = equal = false;
89
90 // Display source filename based on the program address
91 if (vjs.displayFullSourceFilename && (PtrFullSource = DBGManager_GetFullSourceFilenameFromAdr(oldpc, &Status)) && strcmp(CurrentPtrFullSource, PtrFullSource))
92 {
93 #if defined(MD_LAYOUTFILE)
94 if (i)
95 #if MD_LAYOUTFILE != 1
96 {
97 // add an empty line for the display of the new filename
98 nbr++;
99 s += QString("<br>");
100 }
101 #else
102 {
103 In = false;
104 }
105 else
106 #endif
107 #endif
108 {
109 CurrentNumLine = DBGManager_GetNumLineFromAdr(pc, DBG_NO_TAG) - 1;
110 CurrentPtrFullSource = (char *)realloc(CurrentPtrFullSource, strlen(PtrFullSource) + 1);
111 strcpy(CurrentPtrFullSource, PtrFullSource);
112 #if defined(MD_LAYOUTFILE)
113 if (Status)
114 {
115 // Referenced filename doesn't exist
116 sprintf(string, "<font color='#ff0000'><b>%s</b></font><br>", PtrFullSource);
117 #if MD_LAYOUTFILE == 1
118 // Display status bar
119 if ((Status & DBGSTATUS_OUTDATEDFILE))
120 {
121 statusbar->setStyleSheet("background-color: lightyellow; font: bold");
122 statusbar->showMessage(QString("Outdated source file"));
123 }
124 else
125 {
126 statusbar->setStyleSheet("background-color: tomato; font: bold");
127 statusbar->showMessage(QString("Unavailable source file"));
128 }
129 #endif
130 }
131 else
132 {
133 // Referenced filename does exist
134 sprintf(string, "<font color='#00ff00'><b>%s</b></font><br>", PtrFullSource);
135 #if MD_LAYOUTFILE == 1
136 // Display status bar
137 statusbar->setStyleSheet("background-color: transparent; font: bold");
138 statusbar->showMessage(QString(""));
139 #endif
140 }
141 nbr++;
142 s += QString(string);
143 #endif
144 }
145 }
146 else
147 {
148 // Display line number based on the program address
149 if ((NumLine = DBGManager_GetNumLineFromAdr(oldpc, DBG_NO_TAG)) && ((signed)NumLine > (signed)CurrentNumLine) && !Status)
150 {
151 #if MD_LAYOUTFILE != 1
152 if ((signed)CurrentNumLine < 0)
153 {
154 CurrentNumLine = NumLine - 1;
155 }
156 #endif
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 #if 0
169 // add a color on the line text
170 sprintf(string, "<font color='#006400'>%s</font><br>", (CurrentLineSrc = LineSrc));
171 s += QString(string);
172 #else
173 // add a color on the line text with HTML encoding
174 s += QString("<font color='#006400'>");
175 s += QString(QString((CurrentLineSrc = LineSrc)).toHtmlEscaped());
176 s += QString("</font><br>");
177 #endif
178 nbr++;
179 }
180 else
181 {
182 // Display symbol, or line source, based on the program address
183 if (!CurrentLineSrc && !Symbol && (Symbol = DBGManager_GetSymbolNameFromAdr(oldpc)))
184 {
185 sprintf(string, "%s:<br>", Symbol);
186 s += QString(string);
187 nbr++;
188 }
189 // Display the assembly line based on the current PC
190 else
191 {
192 pc += m68k_disassemble(buffer, (unsigned int)pc, 0, vjs.disasmopcodes);
193
194 if (m68kPC == oldpc)
195 {
196 sprintf(string, "-> <u>%06X: %s</u><br>", (unsigned int)oldpc, buffer);
197 m68kPCShow = true;
198 m68KPCNbrDisasmLines = i;
199 }
200 else
201 {
202 sprintf(string, " %06X: %s<br>", (unsigned int)oldpc, buffer);
203 }
204
205 buffer[0] = 0; // Clear string
206
207 for (j = 0; j < strlen(string); j++)
208 {
209 if (string[j] == ' ')
210 {
211 strcat(buffer, "&nbsp;");
212 adr = constant = false;
213 }
214 else
215 {
216 switch (string[j])
217 {
218 case '#':
219 constant = true;
220 break;
221
222 case '$':
223 adr = true;
224 break;
225
226 case ',':
227 constant = adr = equal = false;
228 break;
229
230 case '=':
231 equal = true;
232 break;
233 }
234
235 if (!constant && adr && !equal)
236 {
237 int l = 0;
238 char *p;
239 do
240 {
241 adresse[l++] = string[++j];
242 } while ((string[(j + 1)] >= '0') && (string[(j + 1)] <= '9') || (string[(j + 1)] >= 'A') && (string[(j + 1)] <= 'F'));
243 adresse[l] = 0;
244
245 if (Symbol = DBGManager_GetSymbolNameFromAdr(strtoul(adresse, &p, 16)))
246 {
247 strcat(buffer, Symbol);
248 }
249 else
250 {
251 strcat(buffer, "$");
252 strcat(buffer, adresse);
253 }
254
255 adr = false;
256 }
257 else
258 {
259 singleCharString[0] = string[j];
260 strcat(buffer, singleCharString);
261 }
262 }
263 }
264
265 Symbol = NULL;
266 s += QString(buffer);
267 }
268 }
269 }
270 }
271
272 // Display generated text
273 text->clear();
274 if (m68kPCShow)
275 {
276 text->setText(s);
277 }
278 else
279 {
280 Use68KPCAddress();
281 RefreshContents();
282 }
283
284 // Set the scrollbar position in accordance of the M68K PC pointer
285 if (m68KPCNbrDisasmLines > (nbr / 2))
286 {
287 text->verticalScrollBar()->setValue(text->verticalScrollBar()->maximum());
288 }
289 else
290 {
291 text->verticalScrollBar()->setValue(text->verticalScrollBar()->minimum());
292 }
293
294 free(CurrentPtrFullSource);
295 }
296
297
298 // Set mem base PC address using the 68K pc current address
299 void m68KDasmWindow::Use68KPCAddress(void)
300 {
301 memBase = m68k_get_reg(NULL, M68K_REG_PC);
302 }
303
304
305 // Set mem base PC address
306 void m68KDasmWindow::SetAddress(int address)
307 {
308 memBase = address;
309 }