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 QLabel),
25 refresh(new QPushButton(tr("Refresh")))
27 setWindowTitle(tr("OP Browser"));
29 // Need to set the size as well...
32 QFont fixedFont("Lucida Console", 8, QFont::Normal);
33 // QFont fixedFont("", 8, QFont::Normal);
34 fixedFont.setStyleHint(QFont::TypeWriter);
35 text->setFont(fixedFont);
36 //// layout->setSizeConstraint(QLayout::SetFixedSize);
39 QScrollArea * scrollArea = new QScrollArea;
40 scrollArea->setWidgetResizable(true);
41 scrollArea->setWidget(text);
42 layout->addWidget(scrollArea);
43 layout->addWidget(refresh);
45 connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
49 void OPBrowserWindow::RefreshContents(void)
51 char string[1024];//, buf[64];
54 uint32_t olp = OPGetListPointer();
55 sprintf(string, "OLP = $%X<br>", olp);
56 opDump += QString(string);
60 DumpObjectList(opDump);
63 text->setText(opDump);
67 void OPBrowserWindow::keyPressEvent(QKeyEvent * e)
69 if (e->key() == Qt::Key_Escape)
71 else if (e->key() == Qt::Key_Enter)
76 bool OPBrowserWindow::ObjectExists(uint32_t address)
78 // Yes, we really do a linear search, every time. :-/
79 for(uint32_t i=0; i<numberOfObjects; i++)
81 if (address == object[i])
89 void OPBrowserWindow::DiscoverObjects(uint32_t address)
91 uint8_t objectType = 0;
95 // If we've seen this object already, bail out!
96 // Otherwise, add it to the list
97 if (ObjectExists(address))
100 object[numberOfObjects++] = address;
102 // Get the object & decode its type, link address
103 uint32_t hi = JaguarReadLong(address + 0, OP);
104 uint32_t lo = JaguarReadLong(address + 4, OP);
105 objectType = lo & 0x07;
106 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
110 // Branch if YPOS < 2047 can be treated as a GOTO, so don't do any
111 // discovery in that case. Otherwise, have at it:
112 if ((lo & 0xFFFF) != 0x7FFB)
113 // Recursion needed to follow all links! This does depth-first
114 // recursion on the not-taken objects (N.B.: The object following
115 // the branch object is at +16, not +8!)
116 DiscoverObjects(address + 16);
119 // Get the next object...
122 while (objectType != 4);
126 void OPBrowserWindow::DumpObjectList(QString & list)
128 const char * opType[8] = {
129 "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)",
130 "(STOP)", "???", "???", "???"
132 const char * ccType[8] = {
133 "==", "<", ">", "(opflag set)",
134 "(second half line)", "?", "?", "?"
138 for(uint32_t i=0; i<numberOfObjects; i++)
140 uint32_t address = object[i];
142 uint32_t hi = JaguarReadLong(address + 0, OP);
143 uint32_t lo = JaguarReadLong(address + 4, OP);
144 uint8_t objectType = lo & 0x07;
145 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
146 sprintf(buf, "<br>%06X: %08X %08X %s -> %06X", address, hi, lo, opType[objectType], link);
147 list += QString(buf);
151 uint16_t ypos = (lo >> 3) & 0x7FF;
152 uint8_t cc = (lo >> 14) & 0x07; // Proper # of bits == 3
153 sprintf(buf, " YPOS %s %u", ccType[cc], ypos);
154 list += QString(buf);
160 DumpFixedObject(list, OPLoadPhrase(address + 0),
161 OPLoadPhrase(address + 8));
164 DumpScaledObject(list, OPLoadPhrase(address + 0),
165 OPLoadPhrase(address + 8), OPLoadPhrase(address + 16));
167 if (address == link) // Ruh roh...
169 // Runaway recursive link is bad!
170 sprintf(buf, "***** SELF REFERENTIAL LINK *****<br>");
171 list += QString(buf);
179 void OPBrowserWindow::DumpScaledObject(QString & list, uint64_t p0, uint64_t p1, uint64_t p2)
183 sprintf(buf, " %08X %08X<br>", (uint32_t)(p1 >> 32), (uint32_t)(p1 & 0xFFFFFFFF));
184 list += QString(buf);
185 sprintf(buf, " %08X %08X<br>", (uint32_t)(p2 >> 32), (uint32_t)(p2 & 0xFFFFFFFF));
186 list += QString(buf);
187 DumpBitmapCore(list, p0, p1);
188 uint32_t hscale = p2 & 0xFF;
189 uint32_t vscale = (p2 >> 8) & 0xFF;
190 uint32_t remainder = (p2 >> 16) & 0xFF;
191 sprintf(buf, " [hsc: %02X, vsc: %02X, rem: %02X]<br>", hscale, vscale, remainder);
192 list += QString(buf);
196 void OPBrowserWindow::DumpFixedObject(QString & list, uint64_t p0, uint64_t p1)
200 sprintf(buf, " %08X %08X<br>", (uint32_t)(p1 >> 32), (uint32_t)(p1 & 0xFFFFFFFF));
201 list += QString(buf);
202 DumpBitmapCore(list, p0, p1);
206 void OPBrowserWindow::DumpBitmapCore(QString & list, uint64_t p0, uint64_t p1)
209 uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
211 uint32_t bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
212 uint8_t bitdepth = (p1 >> 12) & 0x07;
213 //WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
214 int16_t ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)?
215 int32_t xpos = p1 & 0xFFF;
216 xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); // Sign extend that mutha!
217 uint32_t iwidth = ((p1 >> 28) & 0x3FF);
218 uint32_t dwidth = ((p1 >> 18) & 0x3FF); // Unsigned!
219 uint16_t height = ((p0 >> 14) & 0x3FF);
220 uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
221 uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
222 uint32_t firstPix = (p1 >> 49) & 0x3F;
223 uint8_t flags = (p1 >> 45) & 0x0F;
224 uint8_t idx = (p1 >> 38) & 0x7F;
225 uint32_t pitch = (p1 >> 15) & 0x07;
227 sprintf(buf, " [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), p:%06X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]<br>",
228 iwidth * bdMultiplier[bitdepth],
229 height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth],
230 ptr, firstPix, (flags & OPFLAG_REFLECT ? "REFLECT " : ""),
231 (flags & OPFLAG_RMW ? "RMW " : ""), (flags & OPFLAG_TRANS ? "TRANS " : ""),
232 (flags & OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
233 list += QString(buf);