2 // opbrowser.cpp - Jaguar Object Processor browser
5 // (C) 2012 Underground Software
7 // JLH = James Hammons <jlhamm@acm.org>
10 // --- ---------- -------------------------------------------------------------
11 // JLH 12/01/2012 Created this file
17 #include "opbrowser.h"
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")))//,
29 setWindowTitle(tr("OP Browser"));
31 // Need to set the size as well...
34 QFont fixedFont("Lucida Console", 10, QFont::Normal);
35 text->setFont(fixedFont);
36 //// layout->setSizeConstraint(QLayout::SetFixedSize);
39 layout->addWidget(text);
40 layout->addWidget(refresh);
42 connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
46 void OPBrowserWindow::RefreshContents(void)
48 char string[1024];//, buf[64];
52 for(uint32_t i=0; i<480; i+=16)
54 sprintf(string, "%s%06X: ", (i != 0 ? "<br>" : ""), memBase + i);
56 for(uint32_t j=0; j<16; j++)
58 sprintf(buf, "%02X ", jaguarMainRAM[memBase + i + j]);
65 for(uint32_t j=0; j<16; j++)
67 uint8_t c = jaguarMainRAM[memBase + i + j];
68 sprintf(buf, "&#%i;", c);
71 sprintf(buf, " ");
73 if ((c < 0x20) || ((c > 0x7F) && (c < 0xA0)))
79 memDump += QString(string);
82 uint32_t olp = OPGetListPointer();
83 sprintf(string, "OLP = $%08X<br><br>", olp);
84 opDump += QString(string);
88 DumpObjectList(opDump);
91 text->setText(opDump);
95 void OPBrowserWindow::keyPressEvent(QKeyEvent * e)
97 if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return)
100 else if (e->key() == Qt::Key_PageUp)
109 else if (e->key() == Qt::Key_PageDown)
113 if (memBase > (0x200000 - 480))
114 memBase = 0x200000 - 480;
118 else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)
127 else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)
131 if (memBase > (0x200000 - 480))
132 memBase = 0x200000 - 480;
140 bool OPBrowserWindow::ObjectExists(uint32_t address)
142 // Yes, we really do a linear search, every time. :-/
143 for(uint32_t i=0; i<numberOfObjects; i++)
145 if (address == object[i])
153 void OPBrowserWindow::DiscoverObjects(uint32_t address)
155 uint8_t objectType = 0;
159 // If we've seen this object already, bail out!
160 // Otherwise, add it to the list
161 if (ObjectExists(address))
164 object[numberOfObjects++] = address;
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;
174 // Recursion needed to follow all links! This does depth-first recursion
175 // on the not-taken objects
176 DiscoverObjects(address + 8);
179 // Get the next object...
182 while (objectType != 4);
186 void OPBrowserWindow::DumpObjectList(QString & list)
188 const char * opType[8] = {
189 "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)",
190 "(STOP)", "???", "???", "???"
192 const char * ccType[8] = {
193 "==", "<", ">", "(opflag set)",
194 "(second half line)", "?", "?", "?"
198 for(uint32_t i=0; i<numberOfObjects; i++)
200 uint32_t address = object[i];
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);
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);
224 DumpFixedObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8));
227 DumpScaledObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8),
228 OPLoadPhrase(address + 16));
230 if (address == link) // Ruh roh...
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);
244 void OPBrowserWindow::DumpScaledObject(QString & list, uint64_t p0, uint64_t p1, uint64_t p2)
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);
264 void OPBrowserWindow::DumpFixedObject(QString & list, uint64_t p0, uint64_t p1)
268 // WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
269 sprintf(buf, " %08X %08X<br>", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
270 list += QString(buf);
271 DumpBitmapCore(list, p0, p1);
275 void OPBrowserWindow::DumpBitmapCore(QString & list, uint64_t p0, uint64_t p1)
278 uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
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);