]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/debug/opbrowser.cpp
3c1d2eab17800a0be0038329aeed8f97d42f056b
[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 QLabel),
25         refresh(new QPushButton(tr("Refresh")))
26 {
27         setWindowTitle(tr("OP Browser"));
28
29         // Need to set the size as well...
30 //      resize(560, 480);
31
32         QFont fixedFont("Lucida Console", 8, QFont::Normal);
33         text->setFont(fixedFont);
34 ////    layout->setSizeConstraint(QLayout::SetFixedSize);
35         setLayout(layout);
36
37         QScrollArea * scrollArea = new QScrollArea;
38         scrollArea->setWidgetResizable(true);
39         scrollArea->setWidget(text);
40         layout->addWidget(scrollArea);
41         layout->addWidget(refresh);
42
43         connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
44 }
45
46
47 void OPBrowserWindow::RefreshContents(void)
48 {
49         char string[1024];//, buf[64];
50         QString opDump;
51
52         uint32_t olp = OPGetListPointer();
53         sprintf(string, "OLP = $%X<br>", olp);
54         opDump += QString(string);
55
56         numberOfObjects = 0;
57         DiscoverObjects(olp);
58         DumpObjectList(opDump);
59
60         text->clear();
61         text->setText(opDump);
62 }
63
64
65 void OPBrowserWindow::keyPressEvent(QKeyEvent * e)
66 {
67         if (e->key() == Qt::Key_Escape)
68                 hide();
69         else if (e->key() == Qt::Key_Enter)
70                 RefreshContents();
71 }
72
73
74 bool OPBrowserWindow::ObjectExists(uint32_t address)
75 {
76         // Yes, we really do a linear search, every time. :-/
77         for(uint32_t i=0; i<numberOfObjects; i++)
78         {
79                 if (address == object[i])
80                         return true;
81         }
82
83         return false;
84 }
85
86
87 void OPBrowserWindow::DiscoverObjects(uint32_t address)
88 {
89         uint8_t objectType = 0;
90
91         do
92         {
93                 // If we've seen this object already, bail out!
94                 // Otherwise, add it to the list
95                 if (ObjectExists(address))
96                         return;
97
98                 object[numberOfObjects++] = address;
99
100                 // Get the object & decode its type, link address
101                 uint32_t hi = JaguarReadLong(address + 0, OP);
102                 uint32_t lo = JaguarReadLong(address + 4, OP);
103                 objectType = lo & 0x07;
104                 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
105
106                 if (objectType == 3)
107                 {
108                         // Recursion needed to follow all links! This does depth-first recursion
109                         // on the not-taken objects
110                         DiscoverObjects(address + 8);
111                 }
112
113                 // Get the next object...
114                 address = link;
115         }
116         while (objectType != 4);
117 }
118
119
120 void OPBrowserWindow::DumpObjectList(QString & list)
121 {
122         const char * opType[8] = {
123                 "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)",
124                 "(STOP)", "???", "???", "???"
125         };
126         const char * ccType[8] = {
127                 "==", "&lt;", "&gt;", "(opflag set)",
128                 "(second half line)", "?", "?", "?"
129         };
130         char buf[512];
131
132         for(uint32_t i=0; i<numberOfObjects; i++)
133         {
134                 uint32_t address = object[i];
135
136                 uint32_t hi = JaguarReadLong(address + 0, OP);
137                 uint32_t lo = JaguarReadLong(address + 4, OP);
138                 uint8_t objectType = lo & 0x07;
139                 uint32_t link = ((hi << 11) | (lo >> 21)) & 0x3FFFF8;
140 //              WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]);
141                 sprintf(buf, "<br>%06X: %08X %08X %s -> %06X", address, hi, lo, opType[objectType], link);
142                 list += QString(buf);
143
144                 if (objectType == 3)
145                 {
146                         uint16_t ypos = (lo >> 3) & 0x7FF;
147                         uint8_t  cc   = (lo >> 14) & 0x07;      // Proper # of bits == 3
148 //                      WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link);
149 //                      sprintf(buf, " YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link);
150                         sprintf(buf, " YPOS %s %u", ccType[cc], ypos);
151                         list += QString(buf);
152                 }
153
154 //              WriteLog("\n");
155                 list += "<br>";
156
157                 if (objectType == 0)
158                         DumpFixedObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8));
159
160                 if (objectType == 1)
161                         DumpScaledObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8),
162                                 OPLoadPhrase(address + 16));
163
164                 if (address == link)    // Ruh roh...
165                 {
166                         // Runaway recursive link is bad!
167 //                      WriteLog("***** SELF REFERENTIAL LINK *****\n\n");
168                         sprintf(buf, "***** SELF REFERENTIAL LINK *****<br>");
169                         list += QString(buf);
170                 }
171         }
172
173 //      WriteLog("\n");
174         list += "<br>";
175 }
176
177
178 void OPBrowserWindow::DumpScaledObject(QString & list, uint64_t p0, uint64_t p1, uint64_t p2)
179 {
180         char buf[512];
181
182 //      WriteLog("          %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
183         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%08X %08X<br>", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
184         list += QString(buf);
185 //      WriteLog("          %08X %08X\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
186         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%08X %08X<br>", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF));
187         list += QString(buf);
188         DumpBitmapCore(list, p0, p1);
189         uint32 hscale = p2 & 0xFF;
190         uint32 vscale = (p2 >> 8) & 0xFF;
191         uint32 remainder = (p2 >> 16) & 0xFF;
192 //      WriteLog("    [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder);
193         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[hsc: %02X, vsc: %02X, rem: %02X]<br>", hscale, vscale, remainder);
194         list += QString(buf);
195 }
196
197
198 void OPBrowserWindow::DumpFixedObject(QString & list, uint64_t p0, uint64_t p1)
199 {
200         char buf[512];
201
202 //      WriteLog("          %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
203         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%08X %08X<br>", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF));
204         list += QString(buf);
205         DumpBitmapCore(list, p0, p1);
206 }
207
208
209 void OPBrowserWindow::DumpBitmapCore(QString & list, uint64_t p0, uint64_t p1)
210 {
211         char buf[512];
212         uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 };
213
214         uint32_t bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 };
215         uint8_t bitdepth = (p1 >> 12) & 0x07;
216 //WAS:  int16 ypos = ((p0 >> 3) & 0x3FF);                       // ??? What if not interlaced (/2)?
217         int16_t ypos = ((p0 >> 3) & 0x7FF);                     // ??? What if not interlaced (/2)?
218         int32_t xpos = p1 & 0xFFF;
219         xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos);       // Sign extend that mutha!
220         uint32_t iwidth = ((p1 >> 28) & 0x3FF);
221         uint32_t dwidth = ((p1 >> 18) & 0x3FF);         // Unsigned!
222         uint16_t height = ((p0 >> 14) & 0x3FF);
223         uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3;
224         uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3;
225         uint32_t firstPix = (p1 >> 49) & 0x3F;
226         uint8_t flags = (p1 >> 45) & 0x0F;
227         uint8_t idx = (p1 >> 38) & 0x7F;
228         uint32_t pitch = (p1 >> 15) & 0x07;
229 //      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",
230 //              iwidth * bdMultiplier[bitdepth],
231 //              height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link,
232 //              ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
233 //              (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
234 //              (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
235         sprintf(buf, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[%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>",
236                 iwidth * bdMultiplier[bitdepth],
237                 height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth],
238                 ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""),
239                 (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""),
240                 (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch);
241         list += QString(buf);
242 }
243