Add the source level tracing
[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, 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 #ifdef MD_LAYOUTTEXTS
32 text(new QTextBrowser),
33 #endif
34 memBase(0)
35 {
36 // Set font
37 QFont fixedFont("Lucida Console", 8, QFont::Normal);
38 fixedFont.setStyleHint(QFont::Monospace); //TypeWriter
39 fixedFont.setLetterSpacing(QFont::PercentageSpacing, 100);
40
41 // Set text in layout
42 #ifdef MD_LAYOUTTEXTS
43 text->setFont(fixedFont);
44 layout->addWidget(text);
45 #endif
46
47 // Set layout
48 setLayout(layout);
49 }
50
51
52 //
53 void m68KDasmWindow::RefreshContents(void)
54 {
55 QString s;
56 char buffer[1024], string[1024], adresse[16];
57 size_t pc = memBase, oldpc;
58 size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
59 size_t m68KPCNbrDisasmLines = 0;
60 char *Symbol = NULL, *LineSrc, *CurrentLineSrc = NULL;
61 bool m68kPCShow = false;
62 bool constant, adr, equal, Error;
63 size_t j, i;
64 size_t nbr = vjs.nbrdisasmlines;
65 char *PtrFullSource, *CurrentPtrFullSource = (char *)calloc(1, 1);
66 size_t NumLine; // , CurrentNumLine = 0;
67 size_t CurrentNumLine;
68 char singleCharString[2] = { 0, 0 };
69 #if MD_LAYOUTFILE == 1
70 bool In = true;
71 #else
72 #define In true
73 #endif
74
75 for (i = 0; (i < nbr) && In; i++)
76 {
77 oldpc = pc;
78 adr = constant = equal = false;
79
80 // Display source filename based on the program address
81 if (vjs.displayFullSourceFilename && (PtrFullSource = DBGManager_GetFullSourceFilenameFromAdr(oldpc, &Error)) && strcmp(CurrentPtrFullSource, PtrFullSource))
82 {
83 #if defined(MD_LAYOUTFILE)
84 if (i)
85 #if MD_LAYOUTFILE != 1
86 {
87 // add an empty line for the display of the new filename
88 nbr++;
89 s += QString("<br>");
90 }
91 #else
92 {
93 In = false;
94 }
95 else
96 #endif
97 #endif
98 {
99 CurrentNumLine = DBGManager_GetNumLineFromAdr(pc, DBG_NO_TAG) - 1;
100 CurrentPtrFullSource = (char *)realloc(CurrentPtrFullSource, strlen(PtrFullSource) + 1);
101 strcpy(CurrentPtrFullSource, PtrFullSource);
102 #if defined(MD_LAYOUTFILE)
103 if (!Error)
104 {
105 // Referenced filename does exist
106 sprintf(string, "<font color='#ff0000'><b>%s</b></font><br>", PtrFullSource);
107 }
108 else
109 {
110 // Referenced filename doesn't exist
111 sprintf(string, "<font color='#00ff00'><b>%s</b></font><br>", PtrFullSource);
112 }
113 nbr++;
114 s += QString(string);
115 #endif
116 }
117 }
118 else
119 {
120 // Display line number based on the program address
121 if ((NumLine = DBGManager_GetNumLineFromAdr(oldpc, DBG_NO_TAG)) && ((signed)NumLine > (signed)CurrentNumLine))
122 {
123 #if MD_LAYOUTFILE != 1
124 if ((signed)CurrentNumLine < 0)
125 {
126 CurrentNumLine = NumLine - 1;
127 }
128 #endif
129 sprintf(string, "| <font color='#006400'>%5u</font> | ", (unsigned int)++CurrentNumLine); // (CurrentNumLine = NumLine));
130 }
131 else
132 {
133 sprintf(string, "| | ");
134 }
135 s += QString(string);
136
137 // Display line source based on the program address
138 if (((signed)CurrentNumLine > 0) && (LineSrc = DBGManager_GetLineSrcFromNumLineBaseAdr(oldpc, CurrentNumLine)) && (LineSrc != CurrentLineSrc))
139 {
140 #if 0
141 // add a color on the line text
142 sprintf(string, "<font color='#006400'>%s</font><br>", (CurrentLineSrc = LineSrc));
143 s += QString(string);
144 #else
145 // add a color on the line text with HTML encoding
146 s += QString("<font color='#006400'>");
147 s += QString(QString((CurrentLineSrc = LineSrc)).toHtmlEscaped());
148 s += QString("</font><br>");
149 #endif
150 nbr++;
151 }
152 else
153 {
154 // Display symbol, or line source, based on the program address
155 if (!CurrentLineSrc && !Symbol && (Symbol = DBGManager_GetSymbolNameFromAdr(oldpc)))
156 {
157 sprintf(string, "%s:<br>", Symbol);
158 s += QString(string);
159 nbr++;
160 }
161 // Display the assembly line based on the current PC
162 else
163 {
164 pc += m68k_disassemble(buffer, (unsigned int)pc, 0, vjs.disasmopcodes);
165
166 if (m68kPC == oldpc)
167 {
168 sprintf(string, "-> <u>%06X: %s</u><br>", (unsigned int)oldpc, buffer);
169 m68kPCShow = true;
170 m68KPCNbrDisasmLines = i;
171 }
172 else
173 {
174 sprintf(string, " %06X: %s<br>", (unsigned int)oldpc, buffer);
175 }
176
177 buffer[0] = 0; // Clear string
178
179 for (j = 0; j < strlen(string); j++)
180 {
181 if (string[j] == ' ')
182 {
183 strcat(buffer, "&nbsp;");
184 adr = constant = false;
185 }
186 else
187 {
188 switch (string[j])
189 {
190 case '#':
191 constant = true;
192 break;
193
194 case '$':
195 adr = true;
196 break;
197
198 case ',':
199 constant = adr = equal = false;
200 break;
201
202 case '=':
203 equal = true;
204 break;
205 }
206
207 if (!constant && adr && !equal)
208 {
209 int l = 0;
210 char *p;
211 do
212 {
213 adresse[l++] = string[++j];
214 } while ((string[(j + 1)] >= '0') && (string[(j + 1)] <= '9') || (string[(j + 1)] >= 'A') && (string[(j + 1)] <= 'F'));
215 adresse[l] = 0;
216
217 if (Symbol = DBGManager_GetSymbolNameFromAdr(strtoul(adresse, &p, 16)))
218 {
219 strcat(buffer, Symbol);
220 }
221 else
222 {
223 strcat(buffer, "$");
224 strcat(buffer, adresse);
225 }
226
227 adr = false;
228 }
229 else
230 {
231 singleCharString[0] = string[j];
232 strcat(buffer, singleCharString);
233 }
234 }
235 }
236
237 Symbol = NULL;
238 s += QString(buffer);
239 }
240 }
241 }
242 }
243
244 // Display generated text
245 text->clear();
246 if (m68kPCShow)
247 {
248 text->setText(s);
249 }
250 else
251 {
252 Use68KPCAddress();
253 RefreshContents();
254 }
255
256 // Set the scrollbar position in accordance of the M68K PC pointer
257 if (m68KPCNbrDisasmLines > (nbr / 2))
258 {
259 text->verticalScrollBar()->setValue(text->verticalScrollBar()->maximum());
260 }
261 else
262 {
263 text->verticalScrollBar()->setValue(text->verticalScrollBar()->minimum());
264 }
265
266 free(CurrentPtrFullSource);
267 }
268
269
270 // Set mem base PC address using the 68K pc current address
271 void m68KDasmWindow::Use68KPCAddress(void)
272 {
273 memBase = m68k_get_reg(NULL, M68K_REG_PC);
274 }
275
276
277 // Set mem base PC address
278 void m68KDasmWindow::SetAddress(int address)
279 {
280 memBase = address;
281 }