9cafa71db671c0dcab6c572a0208a5dba7f8a95e
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / localbrowser.cpp
1 //
2 // localbrowser.cpp - Local variables
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 // RG = Richard Goedeken
8 //
9 // Who When What
10 // --- ---------- -----------------------------------------------------------
11 // JPM 11/03/2017 Created this file
12 // JPM Sept./2018 Added a status bar and better status report, and set information values in a tab
13 // RG Jan./2021 Linux build fixes
14 //
15
16 // STILL TO DO:
17 // Feature to list the pointer(s) in the code using the allocation
18 // To set the information display at the right
19 // To support the array
20 // To support the static variables
21 // To add a filter
22 //
23
24 #include <stdlib.h>
25
26 #include "debugger/localbrowser.h"
27 #include "memory.h"
28 #include "debugger/DBGManager.h"
29 #include "settings.h"
30 #include "m68000/m68kinterface.h"
31
32
33 //
34 LocalBrowserWindow::LocalBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
35 layout(new QVBoxLayout),
36 #ifdef LOCAL_LAYOUTTEXTS
37 text(new QTextBrowser),
38 #else
39 TableView(new QTableView),
40 model(new QStandardItemModel),
41 #endif
42 NbLocal(0),
43 FuncName((char *)calloc(1, 1)),
44 LocalInfo(NULL),
45 statusbar(new QStatusBar)
46 {
47 setWindowTitle(tr("Locals"));
48
49 // Set the font
50 QFont fixedFont("Lucida Console", 8, QFont::Normal);
51 fixedFont.setStyleHint(QFont::TypeWriter);
52
53 #ifdef LOCAL_LAYOUTTEXTS
54 // Set original layout
55 text->setFont(fixedFont);
56 layout->addWidget(text);
57 #else
58 // Set the new layout with proper identation and readibility
59 model->setColumnCount(3);
60 model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
61 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));
62 model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));
63 // Information table
64 TableView->setModel(model);
65 TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
66 TableView->setShowGrid(0);
67 TableView->setFont(fixedFont);
68 TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());
69 TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);
70 layout->addWidget(TableView);
71 #endif
72
73 // Status bar
74 layout->addWidget(statusbar);
75 setLayout(layout);
76 }
77
78
79 //
80 LocalBrowserWindow::~LocalBrowserWindow(void)
81 {
82 free(LocalInfo);
83 free(FuncName);
84 }
85
86
87 //
88 bool LocalBrowserWindow::UpdateInfos(void)
89 {
90 size_t Adr;
91 char *Ptr;
92
93 if (NbLocal = DBGManager_GetNbLocalVariables(Adr = m68k_get_reg(NULL, M68K_REG_PC)))
94 {
95 if (Ptr = DBGManager_GetFunctionName(Adr))
96 {
97 if (strcmp(FuncName, Ptr))
98 {
99 if (FuncName = (char *)realloc(FuncName, strlen(Ptr) + 1))
100 {
101 strcpy(FuncName, Ptr);
102
103 if (LocalInfo = (WatchInfo *)realloc(LocalInfo, (sizeof(WatchInfo) * NbLocal)))
104 {
105 for (size_t i = 0; i < NbLocal; i++)
106 {
107 // Get local variable name and his information
108 if (LocalInfo[i].PtrVariableName = DBGManager_GetLocalVariableName(Adr, i + 1))
109 {
110 LocalInfo[i].Op = DBGManager_GetLocalVariableOp(Adr, i + 1);
111 LocalInfo[i].Adr = NULL;
112 LocalInfo[i].PtrCPURegisterName = NULL;
113 LocalInfo[i].TypeTag = DBGManager_GetLocalVariableTypeTag(Adr, i + 1);
114 LocalInfo[i].PtrVariableBaseTypeName = DBGManager_GetLocalVariableTypeName(Adr, i + 1);
115 LocalInfo[i].TypeEncoding = DBGManager_GetLocalVariableTypeEncoding(Adr, i + 1);
116 LocalInfo[i].TypeByteSize = DBGManager_GetLocalVariableTypeByteSize(Adr, i + 1);
117 LocalInfo[i].Offset = DBGManager_GetLocalVariableOffset(Adr, i + 1);
118 }
119 }
120 }
121 }
122 }
123
124 return true;
125 }
126 }
127
128 *FuncName = 0;
129
130 return false;
131 }
132
133
134 //
135 void LocalBrowserWindow::RefreshContents(void)
136 {
137 #ifdef LOCAL_LAYOUTTEXTS
138 char string[1024];
139 #endif
140 size_t Error = LOCAL_NOERROR;
141 QString Local;
142 QString MSG;
143 char Value1[100];
144 #ifdef LOCAL_SUPPORTARRAY
145 char Value[100];
146 #endif
147 char *PtrValue;
148
149 const char *CPURegName[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" };
150
151 if (isVisible())
152 {
153 #ifndef LOCAL_LAYOUTTEXTS
154 model->setRowCount(0);
155 #endif
156 if (UpdateInfos())
157 {
158 for (size_t i = 0; i < NbLocal; i++)
159 {
160 if (LocalInfo[i].PtrVariableName)
161 {
162 memset(Value1, 0, sizeof(Value1));
163 #ifdef LOCAL_LAYOUTTEXTS
164 if (i)
165 {
166 Local += QString("<br>");
167 }
168 #else
169 model->insertRow(i);
170 #endif
171 // Local or parameters variables
172 if (((LocalInfo[i].Op >= DBG_OP_breg0) && (LocalInfo[i].Op <= DBG_OP_breg31)) || (LocalInfo[i].Op == DBG_OP_fbreg))
173 {
174 LocalInfo[i].Adr = m68k_get_reg(NULL, M68K_REG_A6) + LocalInfo[i].Offset;
175
176 if ((LocalInfo[i].Op == DBG_OP_fbreg))
177 {
178 LocalInfo[i].Adr += 8;
179 }
180
181 if ((LocalInfo[i].Adr >= 0) && (LocalInfo[i].Adr < vjs.DRAM_size))
182 {
183 if ((LocalInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure)))
184 {
185 #if defined(LOCAL_SUPPORTARRAY) || defined(LOCAL_SUPPORTSTRUCTURE)
186 //memcpy(Value1, &jaguarMainRAM[LocalInfo[i].Adr], 20);
187 #ifdef LOCAL_LAYOUTTEXTS
188 //sprintf(Value, "\"%s\"", Value1);
189 #else
190 //sprintf(Value, "0x%06X, \"%s\"", LocalInfo[i].Adr, Value1);
191 #endif
192 //PtrValue = Value;
193 PtrValue = NULL;
194 #else
195 PtrValue = NULL;
196 #endif
197 }
198 else
199 {
200 PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize);
201 }
202 }
203 else
204 {
205 PtrValue = NULL;
206 }
207 }
208 else
209 {
210 // Value from CPU register
211 if ((LocalInfo[i].Op >= DBG_OP_reg0) && (LocalInfo[i].Op <= DBG_OP_reg31))
212 {
213 LocalInfo[i].PtrCPURegisterName = (char *)CPURegName[(LocalInfo[i].Op - DBG_OP_reg0)];
214 sprintf(Value1, "%d", m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))));
215 PtrValue = Value1;
216 }
217 else
218 {
219 PtrValue = NULL;
220 }
221 }
222
223 #ifndef LOCAL_LAYOUTTEXTS
224 model->setItem(i, 0, new QStandardItem(QString("%1").arg(LocalInfo[i].PtrVariableName)));
225 #endif
226 // Check if the local variable is use by the code
227 if (!LocalInfo[i].Op)
228 {
229 #ifdef LOCAL_LAYOUTTEXTS
230 sprintf(string, "<font color='#A52A2A'>%i : %s | %s | [Not used]</font>", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"), LocalInfo[i].PtrVariableName);
231 #else
232 #endif
233 }
234 else
235 {
236 #ifndef LOCAL_LAYOUTTEXTS
237 model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue)));
238 #else
239 sprintf(string, "%i : %s | %s | ", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"), LocalInfo[i].PtrVariableName);
240 Local += QString(string);
241
242 if ((unsigned int)LocalInfo[i].Adr)
243 {
244 sprintf(string, "0x%06X", (unsigned int)LocalInfo[i].Adr);
245 }
246 else
247 {
248 if (LocalInfo[i].PtrCPURegisterName)
249 {
250 sprintf(string, "<font color='#0000FF'>%s</font>", LocalInfo[i].PtrCPURegisterName);
251 }
252 else
253 {
254 sprintf(string, "%s", (char *)"<font color='#ff0000'>N/A</font>");
255 }
256 }
257
258 Local += QString(string);
259 sprintf(string, " | %s", (!PtrValue ? (char *)"<font color='#ff0000'>N/A</font>" : PtrValue));
260 #endif
261 }
262 #ifndef LOCAL_LAYOUTTEXTS
263 model->setItem(i, 2, new QStandardItem(QString("%1").arg((LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"))));
264 #else
265 Local += QString(string);
266 #endif
267 }
268 }
269
270 MSG += QString("Ready");
271 #ifdef LOCAL_LAYOUTTEXTS
272 text->clear();
273 text->setText(Local);
274 #endif
275 }
276 else
277 {
278 // No locals
279 MSG += QString("No locals");
280 Error = LOCAL_NOLOCALS;
281 #ifdef LOCAL_LAYOUTTEXTS
282 text->clear();
283 #endif
284 }
285
286 // Display status bar
287 if (Error)
288 {
289 if ((Error & LOCAL_WARNING))
290 {
291 statusbar->setStyleSheet("background-color: lightyellow; font: bold");
292 }
293 else
294 {
295 statusbar->setStyleSheet("background-color: tomato; font: bold");
296 }
297 }
298 else
299 {
300 statusbar->setStyleSheet("background-color: lightgreen; font: bold");
301 }
302 statusbar->showMessage(MSG);
303 }
304 }
305
306
307 //
308 void LocalBrowserWindow::keyPressEvent(QKeyEvent * e)
309 {
310 if (e->key() == Qt::Key_Escape)
311 {
312 hide();
313 }
314 }