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