]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/debug/opbrowser.cpp
Added Object Processor browser window for debug mode.
[virtualjaguar] / src / gui / debug / opbrowser.cpp
1 //
2 // opbrowser.cpp - Jaguar Object Processor browser
3 //
4 // by James Hammons
5 // (C) 2012 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -------------------------------------------------------------
11 // JLH  12/01/2012  Created this file
12 //
13
14 // STILL TO DO:
15 //
16
17 #include "opbrowser.h"
18 #include "jaguar.h"
19 #include "memory.h"
20 #include "op.h"
21
22
23 OPBrowserWindow::OPBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
24 //      layout(new QVBoxLayout), text(new QTextBrowser),
25         layout(new QVBoxLayout), text(new QLabel),
26         refresh(new QPushButton(tr("Refresh")))//,
27 //      memBase(0)
28 {
29         setWindowTitle(tr("OP Browser"));
30
31         // Need to set the size as well...
32 //      resize(560, 480);
33
34         QFont fixedFont("Lucida Console", 10, QFont::Normal);
35         text->setFont(fixedFont);
36 ////    layout->setSizeConstraint(QLayout::SetFixedSize);
37         setLayout(layout);
38
39         layout->addWidget(text);
40         layout->addWidget(refresh);
41
42         connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
43 }
44
45
46 void OPBrowserWindow::RefreshContents(void)
47 {
48         char string[1024];//, buf[64];
49         QString opDump;
50
51 #if 0
52         for(uint32_t i=0; i<480; i+=16)
53         {
54                 sprintf(string, "%s%06X: ", (i != 0 ? "<br>" : ""), memBase + i);
55
56                 for(uint32_t j=0; j<16; j++)
57                 {
58                         sprintf(buf, "%02X ", jaguarMainRAM[memBase + i + j]);
59                         strcat(string, buf);
60                 }
61
62                 sprintf(buf, "| ");
63                 strcat(string, buf);
64
65                 for(uint32_t j=0; j<16; j++)
66                 {
67                         uint8_t c = jaguarMainRAM[memBase + i + j];
68                         sprintf(buf, "&#%i;", c);
69
70                         if (c == 0x20)
71                                 sprintf(buf, "&nbsp;");
72
73                         if ((c < 0x20) || ((c > 0x7F) && (c < 0xA0)))
74                                 sprintf(buf, ".");
75
76                         strcat(string, buf);
77                 }
78
79                 memDump += QString(string);
80         }
81 #endif
82         uint32_t olp = OPGetListPointer();
83         sprintf(string, "OLP = $%08X<br><br>", olp);
84         opDump += QString(string);
85
86         numberOfObjects = 0;
87         DiscoverObjects(olp);
88         DumpObjectList(opDump);
89
90         text->clear();
91         text->setText(opDump);
92 }
93
94
95 void OPBrowserWindow::keyPressEvent(QKeyEvent * e)
96 {
97         if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return)
98                 hide();
99 #if 0
100         else if (e->key() == Qt::Key_PageUp)
101         {
102                 memBase -= 480;
103
104                 if (memBase < 0)
105                         memBase = 0;
106
107                 RefreshContents();
108         }
109         else if (e->key() == Qt::Key_PageDown)
110         {
111                 memBase += 480;
112
113                 if (memBase > (0x200000 - 480))
114                         memBase = 0x200000 - 480;
115
116                 RefreshContents();
117         }
118         else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)
119         {
120                 memBase -= 16;
121
122                 if (memBase < 0)
123                         memBase = 0;
124
125                 RefreshContents();
126         }
127         else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)
128         {
129                 memBase += 16;
130
131                 if (memBase > (0x200000 - 480))
132                         memBase = 0x200000 - 480;
133
134                 RefreshContents();
135         }
136 #endif
137 }
138
139
140 bool OPBrowserWindow::ObjectExists(uint32_t address)
141 {
142         // Yes, we really do a linear search, every time. :-/
143         for(uint32_t i=0; i<numberOfObjects; i++)
144         {
145                 if (address == object[i])
146                         return true;
147         }
148
149         return false;
150 }
151
152
153 void OPBrowserWindow::DiscoverObjects(uint32_t address)
154 {
155         uint8_t objectType = 0;
156
157         do
158         {
159                 // If we've seen this object already, bail out!
160                 // Otherwise, add it to the list
161                 if (ObjectExists(address))
162                         return;
163
164                 object[numberOfObjects++] = address;
165
166                 // Get the object & decode its type, link address
167                 uint32_t hi = JaguarReadLong(address + 0, OP);
168                 uint32_t lo = JaguarReadLong(address + 4, OP);
169                 objectType = lo & 0x07;
170                 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
171
172                 if (objectType == 3)
173                 {
174                         // Recursion needed to follow all links! This does depth-first recursion
175                         // on the not-taken objects
176                         DiscoverObjects(address + 8);
177                 }
178
179                 // Get the next object...
180                 address = link;
181         }
182         while (objectType != 4);
183 }
184
185
186 void OPBrowserWindow::DumpObjectList(QString & list)
187 {
188         const char * opType[8] = {
189                 "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)",
190                 "(STOP)", "???", "???", "???"
191         };
192         const char * ccType[8] = {
193                 "==", "&lt;", "&gt;", "(opflag set)",
194                 "(second half line)", "?", "?", "?"
195         };
196         char buf[512];
197
198         for(uint32_t i=0; i<numberOfObjects; i++)
199         {
200                 uint32_t address = object[i];
201
202                 uint32_t hi = JaguarReadLong(address + 0, OP);
203                 uint32_t lo = JaguarReadLong(address + 4, OP);
204                 uint8_t objectType = lo & 0x07;
205                 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
206 //              WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]);
207                 sprintf(buf, "%08X: %08X %08X %s -> %08X", address, hi, lo, opType[objectType], link);
208                 list += QString(buf);
209
210                 if (objectType == 3)
211                 {
212                         uint16_t ypos = (lo >> 3) & 0x7FF;
213                         uint8_t  cc   = (lo >> 14) & 0x07;      // Proper # of bits == 3
214 //                      WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link);
215 //                      sprintf(buf, " YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link);
216                         sprintf(buf, " YPOS %s %u", ccType[cc], ypos);
217                         list += QString(buf);
218                 }
219
220 //              WriteLog("\n");
221                 list += "<br>";
222
223                 if (objectType == 0)
224                         DumpFixedObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8));
225
226                 if (objectType == 1)
227                         DumpScaledObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8),
228                                 OPLoadPhrase(address + 16));
229
230                 if (address == link)    // Ruh roh...
231                 {
232                         // Runaway recursive link is bad!
233 //                      WriteLog("***** SELF REFERENTIAL LINK *****\n\n");
234                         sprintf(buf, "***** SELF REFERENTIAL LINK *****<br><br>");
235                         list += QString(buf);
236                 }
237         }
238
239 //      WriteLog("\n");
240         list += "<br>";
241 }
242
243
244 void OPBrowserWindow::DumpScaledObject(QString & list, uint64_t p0, uint64_t p1, uint64_t p2)
245 {
246         char buf[512];
247
248 //      WriteLog("          %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
249         sprintf(buf, "_________ %08X %08X<br>", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
250         list += QString(buf);
251 //      WriteLog("          %08X %08X\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
252         sprintf(buf, "_________ %08X %08X<br>", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
253         list += QString(buf);
254         DumpBitmapCore(list, p0, p1);
255         uint32 hscale = p2 & 0xFF;
256         uint32 vscale = (p2 >> 8) & 0xFF;
257         uint32 remainder = (p2 >> 16) & 0xFF;
258 //      WriteLog("    [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
259         sprintf(buf, "[hsc: %02X, vsc: %02X, rem: %02X]<br>", hscale, vscale, remainder);
260         list += QString(buf);
261 }
262
263
264 void OPBrowserWindow::DumpFixedObject(QString & list, uint64_t p0, uint64_t p1)
265 {
266         char buf[512];
267
268 //      WriteLog("          %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
269         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%08X %08X<br>", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
270         list += QString(buf);
271         DumpBitmapCore(list, p0, p1);
272 }
273
274
275 void OPBrowserWindow::DumpBitmapCore(QString & list, uint64_t p0, uint64_t p1)
276 {
277         char buf[512];
278         uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
279
280         uint32_t bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
281         uint8_t bitdepth = (p1 >> 12) & 0x07;
282 //WAS:  int16 ypos = ((p0 >> 3) & 0x3FF);                       // ??? What if not interlaced (/2)?
283         int16_t ypos = ((p0 >> 3) & 0x7FF);                     // ??? What if not interlaced (/2)?
284         int32_t xpos = p1 & 0xFFF;
285         xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos);       // Sign extend that mutha!
286         uint32_t iwidth = ((p1 >> 28) & 0x3FF);
287         uint32_t dwidth = ((p1 >> 18) & 0x3FF);         // Unsigned!
288         uint16_t height = ((p0 >> 14) & 0x3FF);
289         uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
290         uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
291         uint32_t firstPix = (p1 >> 49) & 0x3F;
292         uint8_t flags = (p1 >> 45) & 0x0F;
293         uint8_t idx = (p1 >> 38) & 0x7F;
294         uint32_t pitch = (p1 >> 15) & 0x07;
295 //      WriteLog("    [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), l:%08X, p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n",
296 //              iwidth * bdMultiplier[bitdepth],
297 //              height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link,
298 //              ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
299 //              (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
300 //              (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
301         sprintf(buf, "    [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]<br>",
302                 iwidth * bdMultiplier[bitdepth],
303                 height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth],
304                 ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
305                 (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
306                 (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
307         list += QString(buf);
308 }