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];
56 uint32_t olp
= OPGetListPointer();
57 sprintf(string
, "OLP = $%X<br>", olp
);
58 opDump
+= QString(string
);
62 DumpObjectList(opDump
);
65 text
->setText(opDump
);
70 void OPBrowserWindow::keyPressEvent(QKeyEvent
* e
)
72 if (e
->key() == Qt::Key_Escape
)
74 else if (e
->key() == Qt::Key_Enter
)
79 bool OPBrowserWindow::ObjectExists(uint32_t address
)
81 // Yes, we really do a linear search, every time. :-/
82 for(uint32_t i
=0; i
<numberOfObjects
; i
++)
84 if (address
== object
[i
])
92 void OPBrowserWindow::DiscoverObjects(uint32_t address
)
94 uint8_t objectType
= 0;
98 // If we've seen this object already, bail out!
99 // Otherwise, add it to the list
100 if (ObjectExists(address
))
103 object
[numberOfObjects
++] = address
;
105 // Get the object & decode its type, link address
106 uint32_t hi
= JaguarReadLong(address
+ 0, OP
);
107 uint32_t lo
= JaguarReadLong(address
+ 4, OP
);
108 objectType
= lo
& 0x07;
109 uint32_t link
= ((hi
<< 11) | (lo
>> 21)) & 0x3FFFF8;
113 // Branch if YPOS < 2047 (or YPOS > 0) can be treated as a GOTO, so
114 // don't do any discovery in that case. Otherwise, have at it:
115 if (((lo
& 0xFFFF) != 0x7FFB) && ((lo
& 0xFFFF) != 0x8003))
116 // Recursion needed to follow all links! This does depth-first
117 // recursion on the not-taken objects
118 DiscoverObjects(address
+ 8);
121 // Get the next object...
124 while (objectType
!= 4);
128 void OPBrowserWindow::DumpObjectList(QString
& list
)
130 const char * opType
[8] = {
131 "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)",
132 "(STOP)", "???", "???", "???"
134 const char * ccType
[8] = {
135 "==", "<", ">", "(opflag set)",
136 "(second half line)", "?", "?", "?"
140 for(uint32_t i
=0; i
<numberOfObjects
; i
++)
142 uint32_t address
= object
[i
];
144 uint32_t hi
= JaguarReadLong(address
+ 0, OP
);
145 uint32_t lo
= JaguarReadLong(address
+ 4, OP
);
146 uint8_t objectType
= lo
& 0x07;
147 uint32_t link
= ((hi
<< 11) | (lo
>> 21)) & 0x3FFFF8;
148 sprintf(buf
, "<br>%06X: %08X %08X %s -> %06X", address
, hi
, lo
, opType
[objectType
], link
);
149 list
+= QString(buf
);
153 uint16_t ypos
= (lo
>> 3) & 0x7FF;
154 uint8_t cc
= (lo
>> 14) & 0x07; // Proper # of bits == 3
155 sprintf(buf
, " YPOS %s %u", ccType
[cc
], ypos
);
156 list
+= QString(buf
);
161 // Yes, the OP really determines bitmap/scaled bitmap address for the
162 // following phrases this way...!
164 DumpFixedObject(list
, OPLoadPhrase(address
+ 0),
165 OPLoadPhrase(address
| 0x08));
168 DumpScaledObject(list
, OPLoadPhrase(address
+ 0),
169 OPLoadPhrase(address
| 0x08), OPLoadPhrase(address
| 0x10));
171 if (address
== link
) // Ruh roh...
173 // Runaway recursive link is bad!
174 sprintf(buf
, "***** SELF REFERENTIAL LINK *****<br>");
175 list
+= QString(buf
);
183 void OPBrowserWindow::DumpScaledObject(QString
& list
, uint64_t p0
, uint64_t p1
, uint64_t p2
)
187 sprintf(buf
, " %08X %08X<br>", (uint32_t)(p1
>> 32), (uint32_t)(p1
& 0xFFFFFFFF));
188 list
+= QString(buf
);
189 sprintf(buf
, " %08X %08X<br>", (uint32_t)(p2
>> 32), (uint32_t)(p2
& 0xFFFFFFFF));
190 list
+= QString(buf
);
191 DumpBitmapCore(list
, p0
, p1
);
192 uint32_t hscale
= p2
& 0xFF;
193 uint32_t vscale
= (p2
>> 8) & 0xFF;
194 uint32_t remainder
= (p2
>> 16) & 0xFF;
195 sprintf(buf
, " [hsc: %02X, vsc: %02X, rem: %02X]<br>", hscale
, vscale
, remainder
);
196 list
+= QString(buf
);
200 void OPBrowserWindow::DumpFixedObject(QString
& list
, uint64_t p0
, uint64_t p1
)
204 sprintf(buf
, " %08X %08X<br>", (uint32_t)(p1
>> 32), (uint32_t)(p1
& 0xFFFFFFFF));
205 list
+= QString(buf
);
206 DumpBitmapCore(list
, p0
, p1
);
210 void OPBrowserWindow::DumpBitmapCore(QString
& list
, uint64_t p0
, uint64_t p1
)
213 uint8_t op_bitmap_bit_depth
[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
215 uint32_t bdMultiplier
[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
216 uint8_t bitdepth
= (p1
>> 12) & 0x07;
217 //WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)?
218 int16_t ypos
= ((p0
>> 3) & 0x7FF); // ??? What if not interlaced (/2)?
219 int32_t xpos
= p1
& 0xFFF;
220 xpos
= (xpos
& 0x800 ? xpos
| 0xFFFFF000 : xpos
); // Sign extend that mutha!
221 uint32_t iwidth
= ((p1
>> 28) & 0x3FF);
222 uint32_t dwidth
= ((p1
>> 18) & 0x3FF); // Unsigned!
223 uint16_t height
= ((p0
>> 14) & 0x3FF);
224 uint32_t link
= ((p0
>> 24) & 0x7FFFF) << 3;
225 uint32_t ptr
= ((p0
>> 43) & 0x1FFFFF) << 3;
226 uint32_t firstPix
= (p1
>> 49) & 0x3F;
227 uint8_t flags
= (p1
>> 45) & 0x0F;
228 uint8_t idx
= (p1
>> 38) & 0x7F;
229 uint32_t pitch
= (p1
>> 15) & 0x07;
231 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>",
232 iwidth
* bdMultiplier
[bitdepth
],
233 height
, xpos
, ypos
, iwidth
, dwidth
, op_bitmap_bit_depth
[bitdepth
],
234 ptr
, firstPix
, (flags
& OPFLAG_REFLECT
? "REFLECT " : ""),
235 (flags
& OPFLAG_RMW
? "RMW " : ""), (flags
& OPFLAG_TRANS
? "TRANS " : ""),
236 (flags
& OPFLAG_RELEASE
? "RELEASE" : ""), idx
, pitch
);
237 list
+= QString(buf
);