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