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