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