From: Shamus Hammons Date: Mon, 3 Dec 2012 04:35:15 +0000 (-0600) Subject: Merge branch 'master' of http://shamusworld.gotdns.org/git/virtualjaguar X-Git-Tag: 2.1.0~9 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45113b457300c698d876c8e4ebc71ed1deb93c66;hp=70a54a68244ca80111cf2c9b2230072051a9f839;p=virtualjaguar Merge branch 'master' of shamusworld.gotdns.org/git/virtualjaguar Sometimes things get out of sync... :-P --- diff --git a/src/gui/about.cpp b/src/gui/about.cpp index 5cf1ade..14ccfd8 100644 --- a/src/gui/about.cpp +++ b/src/gui/about.cpp @@ -28,13 +28,9 @@ AboutWindow::AboutWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog) layout->setSizeConstraint(QLayout::SetFixedSize); setLayout(layout); - image = new QLabel(); - image->setAlignment(Qt::AlignRight); - image->setPixmap(QPixmap(":/res/vj_title_small.png")); - layout->addWidget(image); - QString s; s.append(tr( + "" "" "
Version: " VJ_RELEASE_VERSION " (" VJ_RELEASE_SUBVERSION ")" diff --git a/src/gui/debug/m68kdasmbrowser.cpp b/src/gui/debug/m68kdasmbrowser.cpp new file mode 100644 index 0000000..5c52cf0 --- /dev/null +++ b/src/gui/debug/m68kdasmbrowser.cpp @@ -0,0 +1,127 @@ +// +// m68kdasmbrowser.cpp - Jaguar M68K disassembly browser +// +// by James Hammons +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ------------------------------------------------------------- +// JLH 12/01/2012 Created this file +// + +// STILL TO DO: +// + +#include "m68kdasmbrowser.h" +//#include "memory.h" +#include "m68000/m68kinterface.h" +#include "dsp.h" +#include "gpu.h" + + +M68KDasmBrowserWindow::M68KDasmBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog), +// layout(new QVBoxLayout), text(new QTextBrowser), + layout(new QVBoxLayout), text(new QLabel), + refresh(new QPushButton(tr("Refresh"))), + memBase(0x4000) +{ + setWindowTitle(tr("M68K Disassembly Browser")); + + // Need to set the size as well... +// resize(560, 480); + + QFont fixedFont("Lucida Console", 10, QFont::Normal); + text->setFont(fixedFont); +//// layout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(layout); + + layout->addWidget(text); + layout->addWidget(refresh); + + connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents())); +} + + +void M68KDasmBrowserWindow::RefreshContents(void) +{ + char string[1024];//, buf[64]; + QString s; + + char buffer[2048]; + int pc = memBase, oldpc; + + for(uint32_t i=0; i<32; i++) + { + oldpc = pc; + pc += m68k_disassemble(buffer, pc, 0); +// WriteLog("%06X: %s\n", oldpc, buffer); + sprintf(string, "%06X: %s
", oldpc, buffer); + + buffer[0] = 0; // Clear string + char singleCharString[2] = { 0, 0 }; + + for(int j=0; jclear(); + text->setText(s); +} + + +void M68KDasmBrowserWindow::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return) + hide(); +#if 1 + else if (e->key() == Qt::Key_PageUp) + { + memBase -= 480; + + if (memBase < 0) + memBase = 0; + + RefreshContents(); + } + else if (e->key() == Qt::Key_PageDown) + { + memBase += 480; + + if (memBase > (0x200000 - 480)) + memBase = 0x200000 - 480; + + RefreshContents(); + } + else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus) + { + memBase -= 16; + + if (memBase < 0) + memBase = 0; + + RefreshContents(); + } + else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal) + { + memBase += 16; + + if (memBase > (0x200000 - 480)) + memBase = 0x200000 - 480; + + RefreshContents(); + } +#endif +} diff --git a/src/gui/debug/m68kdasmbrowser.h b/src/gui/debug/m68kdasmbrowser.h new file mode 100644 index 0000000..77550ee --- /dev/null +++ b/src/gui/debug/m68kdasmbrowser.h @@ -0,0 +1,38 @@ +// +// m68kdasmbrowser.h: Jaguar 68K disassembly browser +// +// by James Hammons +// (C) 2012 Underground Software +// + +#ifndef __M68KDASMBROWSER_H__ +#define __M68KDASMBROWSER_H__ + +#include +#include + +class M68KDasmBrowserWindow: public QWidget +{ + Q_OBJECT + + public: + M68KDasmBrowserWindow(QWidget * parent = 0); + + + public slots: +// void DefineAllKeys(void); + void RefreshContents(void); + + protected: + void keyPressEvent(QKeyEvent *); + + private: + QVBoxLayout * layout; +// QTextBrowser * text; + QLabel * text; + QPushButton * refresh; + + int32_t memBase; +}; + +#endif // __M68KDASMBROWSER_H__ diff --git a/src/gui/debug/opbrowser.cpp b/src/gui/debug/opbrowser.cpp new file mode 100644 index 0000000..52f40ef --- /dev/null +++ b/src/gui/debug/opbrowser.cpp @@ -0,0 +1,308 @@ +// +// opbrowser.cpp - Jaguar Object Processor browser +// +// by James Hammons +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ------------------------------------------------------------- +// JLH 12/01/2012 Created this file +// + +// STILL TO DO: +// + +#include "opbrowser.h" +#include "jaguar.h" +#include "memory.h" +#include "op.h" + + +OPBrowserWindow::OPBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog), +// layout(new QVBoxLayout), text(new QTextBrowser), + layout(new QVBoxLayout), text(new QLabel), + refresh(new QPushButton(tr("Refresh")))//, +// memBase(0) +{ + setWindowTitle(tr("OP Browser")); + + // Need to set the size as well... +// resize(560, 480); + + QFont fixedFont("Lucida Console", 10, QFont::Normal); + text->setFont(fixedFont); +//// layout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(layout); + + layout->addWidget(text); + layout->addWidget(refresh); + + connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents())); +} + + +void OPBrowserWindow::RefreshContents(void) +{ + char string[1024];//, buf[64]; + QString opDump; + +#if 0 + for(uint32_t i=0; i<480; i+=16) + { + sprintf(string, "%s%06X: ", (i != 0 ? "
" : ""), memBase + i); + + for(uint32_t j=0; j<16; j++) + { + sprintf(buf, "%02X ", jaguarMainRAM[memBase + i + j]); + strcat(string, buf); + } + + sprintf(buf, "| "); + strcat(string, buf); + + for(uint32_t j=0; j<16; j++) + { + uint8_t c = jaguarMainRAM[memBase + i + j]; + sprintf(buf, "&#%i;", c); + + if (c == 0x20) + sprintf(buf, " "); + + if ((c < 0x20) || ((c > 0x7F) && (c < 0xA0))) + sprintf(buf, "."); + + strcat(string, buf); + } + + memDump += QString(string); + } +#endif + uint32_t olp = OPGetListPointer(); + sprintf(string, "OLP = $%08X

", olp); + opDump += QString(string); + + numberOfObjects = 0; + DiscoverObjects(olp); + DumpObjectList(opDump); + + text->clear(); + text->setText(opDump); +} + + +void OPBrowserWindow::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return) + hide(); +#if 0 + else if (e->key() == Qt::Key_PageUp) + { + memBase -= 480; + + if (memBase < 0) + memBase = 0; + + RefreshContents(); + } + else if (e->key() == Qt::Key_PageDown) + { + memBase += 480; + + if (memBase > (0x200000 - 480)) + memBase = 0x200000 - 480; + + RefreshContents(); + } + else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus) + { + memBase -= 16; + + if (memBase < 0) + memBase = 0; + + RefreshContents(); + } + else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal) + { + memBase += 16; + + if (memBase > (0x200000 - 480)) + memBase = 0x200000 - 480; + + RefreshContents(); + } +#endif +} + + +bool OPBrowserWindow::ObjectExists(uint32_t address) +{ + // Yes, we really do a linear search, every time. :-/ + for(uint32_t i=0; i> 21)) & 0x3FFFF8; + + if (objectType == 3) + { + // Recursion needed to follow all links! This does depth-first recursion + // on the not-taken objects + DiscoverObjects(address + 8); + } + + // Get the next object... + address = link; + } + while (objectType != 4); +} + + +void OPBrowserWindow::DumpObjectList(QString & list) +{ + const char * opType[8] = { + "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", + "(STOP)", "???", "???", "???" + }; + const char * ccType[8] = { + "==", "<", ">", "(opflag set)", + "(second half line)", "?", "?", "?" + }; + char buf[512]; + + for(uint32_t i=0; i> 21)) & 0x3FFFF8; +// WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]); + sprintf(buf, "%08X: %08X %08X %s -> %08X", address, hi, lo, opType[objectType], link); + list += QString(buf); + + if (objectType == 3) + { + uint16_t ypos = (lo >> 3) & 0x7FF; + uint8_t cc = (lo >> 14) & 0x07; // Proper # of bits == 3 +// WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link); +// sprintf(buf, " YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link); + sprintf(buf, " YPOS %s %u", ccType[cc], ypos); + list += QString(buf); + } + +// WriteLog("\n"); + list += "
"; + + if (objectType == 0) + DumpFixedObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8)); + + if (objectType == 1) + DumpScaledObject(list, OPLoadPhrase(address + 0), OPLoadPhrase(address + 8), + OPLoadPhrase(address + 16)); + + if (address == link) // Ruh roh... + { + // Runaway recursive link is bad! +// WriteLog("***** SELF REFERENTIAL LINK *****\n\n"); + sprintf(buf, "***** SELF REFERENTIAL LINK *****

"); + list += QString(buf); + } + } + +// WriteLog("\n"); + list += "
"; +} + + +void OPBrowserWindow::DumpScaledObject(QString & list, uint64_t p0, uint64_t p1, uint64_t p2) +{ + char buf[512]; + +// WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + sprintf(buf, "_________ %08X %08X
", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + list += QString(buf); +// WriteLog(" %08X %08X\n", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + sprintf(buf, "_________ %08X %08X
", (uint32)(p2>>32), (uint32)(p2&0xFFFFFFFF)); + list += QString(buf); + DumpBitmapCore(list, p0, p1); + uint32 hscale = p2 & 0xFF; + uint32 vscale = (p2 >> 8) & 0xFF; + uint32 remainder = (p2 >> 16) & 0xFF; +// WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder); + sprintf(buf, "[hsc: %02X, vsc: %02X, rem: %02X]
", hscale, vscale, remainder); + list += QString(buf); +} + + +void OPBrowserWindow::DumpFixedObject(QString & list, uint64_t p0, uint64_t p1) +{ + char buf[512]; + +// WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + sprintf(buf, "          %08X %08X
", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); + list += QString(buf); + DumpBitmapCore(list, p0, p1); +} + + +void OPBrowserWindow::DumpBitmapCore(QString & list, uint64_t p0, uint64_t p1) +{ + char buf[512]; + uint8_t op_bitmap_bit_depth[8] = { 1, 2, 4, 8, 16, 24, 32, 0 }; + + uint32_t bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 }; + uint8_t bitdepth = (p1 >> 12) & 0x07; +//WAS: int16 ypos = ((p0 >> 3) & 0x3FF); // ??? What if not interlaced (/2)? + int16_t ypos = ((p0 >> 3) & 0x7FF); // ??? What if not interlaced (/2)? + int32_t xpos = p1 & 0xFFF; + xpos = (xpos & 0x800 ? xpos | 0xFFFFF000 : xpos); // Sign extend that mutha! + uint32_t iwidth = ((p1 >> 28) & 0x3FF); + uint32_t dwidth = ((p1 >> 18) & 0x3FF); // Unsigned! + uint16_t height = ((p0 >> 14) & 0x3FF); + uint32_t link = ((p0 >> 24) & 0x7FFFF) << 3; + uint32_t ptr = ((p0 >> 43) & 0x1FFFFF) << 3; + uint32_t firstPix = (p1 >> 49) & 0x3F; + uint8_t flags = (p1 >> 45) & 0x0F; + uint8_t idx = (p1 >> 38) & 0x7F; + uint32_t pitch = (p1 >> 15) & 0x07; +// 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", +// iwidth * bdMultiplier[bitdepth], +// height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link, +// ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), +// (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), +// (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); + 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]
", + iwidth * bdMultiplier[bitdepth], + height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], + ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), + (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), + (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); + list += QString(buf); +} diff --git a/src/gui/debug/opbrowser.h b/src/gui/debug/opbrowser.h new file mode 100644 index 0000000..b2a4028 --- /dev/null +++ b/src/gui/debug/opbrowser.h @@ -0,0 +1,46 @@ +// +// opbrowser.h: Jaguar memory browser +// +// by James Hammons +// (C) 2012 Underground Software +// + +#ifndef __OPBROWSER_H__ +#define __OPBROWSER_H__ + +#include +#include + +class OPBrowserWindow: public QWidget +{ + Q_OBJECT + + public: + OPBrowserWindow(QWidget * parent = 0); + + + public slots: + void RefreshContents(void); + + protected: + void keyPressEvent(QKeyEvent *); + + bool ObjectExists(uint32_t address); + void DiscoverObjects(uint32_t address); + void DumpObjectList(QString &); + void DumpScaledObject(QString &, uint64_t p0, uint64_t p1, uint64_t p2); + void DumpFixedObject(QString &, uint64_t p0, uint64_t p1); + void DumpBitmapCore(QString &, uint64_t p0, uint64_t p1); + + private: + QVBoxLayout * layout; +// QTextBrowser * text; + QLabel * text; + QPushButton * refresh; + +// int32_t memBase; + uint32_t object[8192]; + uint32_t numberOfObjects; +}; + +#endif // __OPBROWSER_H__ diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index fb667e9..892d5a7 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -43,8 +43,10 @@ #include "configdialog.h" #include "generaltab.h" #include "version.h" -#include "debug/memorybrowser.h" #include "debug/cpubrowser.h" +#include "debug/m68kdasmbrowser.h" +#include "debug/memorybrowser.h" +#include "debug/opbrowser.h" #include "dac.h" #include "jaguar.h" @@ -100,6 +102,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), filePickWin = new FilePickerWindow(this); memBrowseWin = new MemoryBrowserWindow(this); cpuBrowseWin = new CPUBrowserWindow(this); + opBrowseWin = new OPBrowserWindow(this); + m68kDasmBrowseWin = new M68KDasmBrowserWindow(this); videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -216,6 +220,16 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), // memBrowseAct->setCheckable(true); connect(cpuBrowseAct, SIGNAL(triggered()), this, SLOT(ShowCPUBrowserWin())); + opBrowseAct = new QAction(QIcon(":/res/generic.png"), tr("OP Browser"), this); + opBrowseAct->setStatusTip(tr("Shows the Jaguar OP browser window")); +// memBrowseAct->setCheckable(true); + connect(opBrowseAct, SIGNAL(triggered()), this, SLOT(ShowOPBrowserWin())); + + m68kDasmBrowseAct = new QAction(QIcon(":/res/generic.png"), tr("68K Listing Browser"), this); + m68kDasmBrowseAct->setStatusTip(tr("Shows the 68K disassembly browser window")); +// memBrowseAct->setCheckable(true); + connect(m68kDasmBrowseAct, SIGNAL(triggered()), this, SLOT(ShowM68KDasmBrowserWin())); + // Misc. connections... connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString))); connect(filePickWin, SIGNAL(FilePickerHiding()), this, SLOT(Unpause())); @@ -236,6 +250,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), debugMenu = menuBar()->addMenu(tr("&Debug")); debugMenu->addAction(memBrowseAct); debugMenu->addAction(cpuBrowseAct); + debugMenu->addAction(opBrowseAct); + debugMenu->addAction(m68kDasmBrowseAct); } helpMenu = menuBar()->addMenu(tr("&Help")); @@ -263,6 +279,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), debugbar = addToolBar(tr("&Debug")); debugbar->addAction(memBrowseAct); debugbar->addAction(cpuBrowseAct); + debugbar->addAction(opBrowseAct); + debugbar->addAction(m68kDasmBrowseAct); } // Create status bar @@ -864,6 +882,20 @@ void MainWin::ShowCPUBrowserWin(void) } +void MainWin::ShowOPBrowserWin(void) +{ + opBrowseWin->show(); + opBrowseWin->RefreshContents(); +} + + +void MainWin::ShowM68KDasmBrowserWin(void) +{ + m68kDasmBrowseWin->show(); + m68kDasmBrowseWin->RefreshContents(); +} + + void MainWin::ResizeMainWindow(void) { // videoWidget->setFixedSize(zoomLevel * 320, zoomLevel * (vjs.hardwareTypeNTSC ? 240 : 256)); diff --git a/src/gui/mainwin.h b/src/gui/mainwin.h index fe88892..27c99ce 100644 --- a/src/gui/mainwin.h +++ b/src/gui/mainwin.h @@ -18,6 +18,8 @@ class HelpWindow; class FilePickerWindow; class MemoryBrowserWindow; class CPUBrowserWindow; +class OPBrowserWindow; +class M68KDasmBrowserWindow; class MainWin: public QMainWindow { @@ -58,6 +60,8 @@ class MainWin: public QMainWindow void ShowMemoryBrowserWin(void); void ShowCPUBrowserWin(void); + void ShowOPBrowserWin(void); + void ShowM68KDasmBrowserWin(void); private: void HandleKeys(QKeyEvent *, bool); @@ -74,6 +78,8 @@ class MainWin: public QMainWindow FilePickerWindow * filePickWin; MemoryBrowserWindow * memBrowseWin; CPUBrowserWindow * cpuBrowseWin; + OPBrowserWindow * opBrowseWin; + M68KDasmBrowserWindow * m68kDasmBrowseWin; QTimer * timer; bool running; int zoomLevel; @@ -120,6 +126,8 @@ class MainWin: public QMainWindow QAction * memBrowseAct; QAction * cpuBrowseAct; + QAction * opBrowseAct; + QAction * m68kDasmBrowseAct; QIcon powerGreen; QIcon powerRed; diff --git a/src/jaguar.cpp b/src/jaguar.cpp index cff72cc..1916304 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -376,8 +376,21 @@ CD_switch:: -> $306C WriteLog("\nM68K encountered an illegal instruction at %08X!!!\n\nAborting!\n", m68kPC); uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7); WriteLog("M68K: Top of stack: %08X. Stack trace:\n", JaguarReadLong(topOfStack)); + uint32 address = topOfStack - (4 * 4 * 3); + for(int i=0; i<10; i++) - WriteLog("%06X: %08X\n", topOfStack - (i * 4), JaguarReadLong(topOfStack - (i * 4))); + { + WriteLog("%06X:", address); + + for(int j=0; j<4; j++) + { + WriteLog(" %08X", JaguarReadLong(address)); + address += 4; + } + + WriteLog("\n"); + } + WriteLog("Jaguar: VBL interrupt is %s\n", ((TOMIRQEnabled(IRQ_VIDEO)) && (JaguarInterruptHandlerIsValid(64))) ? "enabled" : "disabled"); M68K_show_context(); @@ -1817,9 +1830,26 @@ void JaguarDone(void) // for(int i=M68K_REG_A0; i<=M68K_REG_A7; i++) // WriteLog("\tA%i = 0x%.8x\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i)); int32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7); - WriteLog("M68K: Top of stack: %08X. Stack trace:\n", JaguarReadLong(topOfStack)); + WriteLog("M68K: Top of stack: %08X -> (%08X). Stack trace:\n", topOfStack, JaguarReadLong(topOfStack)); +#if 0 for(int i=-2; i<9; i++) WriteLog("%06X: %08X\n", topOfStack + (i * 4), JaguarReadLong(topOfStack + (i * 4))); +#else + uint32 address = topOfStack - (4 * 4 * 3); + + for(int i=0; i<10; i++) + { + WriteLog("%06X:", address); + + for(int j=0; j<4; j++) + { + WriteLog(" %08X", JaguarReadLong(address)); + address += 4; + } + + WriteLog("\n"); + } +#endif /* WriteLog("\nM68000 disassembly at $802288...\n"); jaguar_dasm(0x802288, 3); @@ -1977,7 +2007,7 @@ void JaguarExecuteNew(void) // it will be half this number for a half frame. BUT, since we're counting // HALF lines, we double this number and we're back at 525 for NTSC, 625 for PAL. // -// Scanline times are 63.5555... µs in NTSC and 64 µs in PAL +// Scanline times are 63.5555... s in NTSC and 64 s in PAL // Half line times are, naturally, half of this. :-P void HalflineCallback(void) { diff --git a/src/op.cpp b/src/op.cpp index 8708d9b..516af69 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -42,10 +42,12 @@ #define CONDITION_OP_FLAG_SET 3 #define CONDITION_SECOND_HALF_LINE 4 +#if 0 #define OPFLAG_RELEASE 8 // Bus release bit #define OPFLAG_TRANS 4 // Transparency bit #define OPFLAG_RMW 2 // Read-Modify-Write bit #define OPFLAG_REFLECT 1 // Horizontal mirror bit +#endif // Private function prototypes @@ -125,6 +127,7 @@ void OPInit(void) OPReset(); } + // // Object Processor reset // @@ -134,15 +137,17 @@ void OPReset(void) objectp_running = 0; } + static const char * opType[8] = { "(BITMAP)", "(SCALED BITMAP)", "(GPU INT)", "(BRANCH)", "(STOP)", "???", "???", "???" }; static const char * ccType[8] = - { "\"==\"", "\"<\"", "\">\"", "(opflag set)", "(second half line)", "?", "?", "?" }; + { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" }; static uint32 object[8192]; static uint32 numberOfObjects; //static uint32 objectLink[8192]; //static uint32 numberOfLinks; + void OPDone(void) { //#warning "!!! Fix OL dump so that it follows links !!!" @@ -180,9 +185,9 @@ void OPDone(void) WriteLog("\n"); #else -#warning "!!! Fix lockup in OPDiscoverObjects() !!!" +//#warning "!!! Fix lockup in OPDiscoverObjects() !!!" //temp, to keep the following function from locking up on bad/weird OLs -return; +//return; numberOfObjects = 0; OPDiscoverObjects(olp); @@ -190,21 +195,34 @@ return; #endif } -void OPDiscoverObjects(uint32 address) + +bool OPObjectExists(uint32 address) { - // Check to see if we've already seen this object + // Yes, we really do a linear search, every time. :-/ for(uint32 i=0; i> 3) & 0x7FF; - uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3 - - // Recursion needed to follow all links! + // Recursion needed to follow all links! This does depth-first recursion + // on the not-taken objects OPDiscoverObjects(address + 8); } - if (address == link) // Ruh roh... - { - // Runaway recursive link is bad! - return; - } - + // Get the next object... address = link; - - // Check to see if we've already seen this object, and add it if not - bool seenObject = false; - - for(uint32 i=0; i> 21)) & 0x3FFFF8; - WriteLog("%08X: %08X %08X %s", address, hi, lo, opType[objectType]); + WriteLog("%08X: %08X %08X %s -> $08X", address, hi, lo, opType[objectType], link); if (objectType == 3) { uint16 ypos = (lo >> 3) & 0x7FF; uint8 cc = (lo >> 14) & 0x07; // Proper # of bits == 3 - WriteLog(" YPOS=%u, CC=%s, link=$%08X", ypos, ccType[cc], link); + WriteLog(" YPOS %s %u", ccType[cc], ypos); } WriteLog("\n"); @@ -283,6 +280,7 @@ void OPDumpObjectList(void) WriteLog("\n"); } + // // Object Processor memory access // Memory range: F00010 - F00027 @@ -323,12 +321,14 @@ WriteLog("OP: Setting hi list pointer: %04X\n", data);//*/ } #endif + uint32 OPGetListPointer(void) { // Note: This register is LO / HI WORD, hence the funky look of this... return GET16(tomRam8, 0x20) | (GET16(tomRam8, 0x22) << 16); } + // This is WRONG, since the OBF is only 16 bits wide!!! [FIXED] uint32 OPGetStatusRegister(void) @@ -336,6 +336,7 @@ uint32 OPGetStatusRegister(void) return GET16(tomRam8, 0x26); } + // This is WRONG, since the OBF is only 16 bits wide!!! [FIXED] void OPSetStatusRegister(uint32 data) @@ -344,6 +345,7 @@ void OPSetStatusRegister(uint32 data) tomRam8[0x27] |= (data & 0xFE); } + void OPSetCurrentObject(uint64 object) { //Not sure this is right... Wouldn't it just be stored 64 bit BE? @@ -369,12 +371,14 @@ void OPSetCurrentObject(uint64 object) tomRam8[0x10] = object & 0xFF; } + uint64 OPLoadPhrase(uint32 offset) { offset &= ~0x07; // 8 byte alignment return ((uint64)JaguarReadLong(offset, OP) << 32) | (uint64)JaguarReadLong(offset+4, OP); } + void OPStorePhrase(uint32 offset, uint64 p) { offset &= ~0x07; // 8 byte alignment @@ -382,6 +386,7 @@ void OPStorePhrase(uint32 offset, uint64 p) JaguarWriteLong(offset + 4, p & 0xFFFFFFFF, OP); } + // // Debugging routines // @@ -396,12 +401,14 @@ void DumpScaledObject(uint64 p0, uint64 p1, uint64 p2) WriteLog(" [hsc: %02X, vsc: %02X, rem: %02X]\n", hscale, vscale, remainder); } + void DumpFixedObject(uint64 p0, uint64 p1) { WriteLog(" %08X %08X\n", (uint32)(p1>>32), (uint32)(p1&0xFFFFFFFF)); DumpBitmapCore(p0, p1); } + void DumpBitmapCore(uint64 p0, uint64 p1) { uint32 bdMultiplier[8] = { 64, 32, 16, 8, 4, 2, 1, 1 }; @@ -419,21 +426,22 @@ void DumpBitmapCore(uint64 p0, uint64 p1) uint8 flags = (p1 >> 45) & 0x0F; uint8 idx = (p1 >> 38) & 0x7F; uint32 pitch = (p1 >> 15) & 0x07; - 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", + WriteLog(" [%u x %u @ (%i, %u) (iw:%u, dw:%u) (%u bpp), p:%08X fp:%02X, fl:%s%s%s%s, idx:%02X, pt:%02X]\n", iwidth * bdMultiplier[bitdepth], - height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], link, + height, xpos, ypos, iwidth, dwidth, op_bitmap_bit_depth[bitdepth], ptr, firstPix, (flags&OPFLAG_REFLECT ? "REFLECT " : ""), (flags&OPFLAG_RMW ? "RMW " : ""), (flags&OPFLAG_TRANS ? "TRANS " : ""), (flags&OPFLAG_RELEASE ? "RELEASE" : ""), idx, pitch); } + // // Object Processor main routine // #warning "Need to fix this so that when an GPU object IRQ happens, we can pick up OP processing where we left off. !!! FIX !!!" void OPProcessList(int halfline, bool render) { -#warning "!!! NEED TO HANDLE MULTIPLE FIELDS PROPERLY !!! +#warning "!!! NEED TO HANDLE MULTIPLE FIELDS PROPERLY !!!" // We ignore them, for now; not good halfline &= 0x7FF; @@ -865,6 +873,7 @@ OP: Scaled bitmap 4x? 4bpp at 34,? hscale=80 fpix=0 data=000756E8 pitch 1 hflipp } } + // // Store fixed size bitmap in line buffer // @@ -1329,6 +1338,7 @@ if (firstPix) } } + // // Store scaled bitmap in line buffer // diff --git a/src/op.h b/src/op.h index 20e7190..760f593 100644 --- a/src/op.h +++ b/src/op.h @@ -11,6 +11,8 @@ void OPInit(void); void OPReset(void); void OPDone(void); +uint64 OPLoadPhrase(uint32 offset); + void OPProcessList(int scanline, bool render); uint32 OPGetListPointer(void); void OPSetStatusRegister(uint32 data); @@ -22,6 +24,11 @@ void OPSetCurrentObject(uint64 object); //void OPWriteByte(uint32, uint8, uint32 who = UNKNOWN); //void OPWriteWord(uint32, uint16, uint32 who = UNKNOWN); +#define OPFLAG_RELEASE 8 // Bus release bit +#define OPFLAG_TRANS 4 // Transparency bit +#define OPFLAG_RMW 2 // Read-Modify-Write bit +#define OPFLAG_REFLECT 1 // Horizontal mirror bit + // Exported variables extern uint8 objectp_running; diff --git a/virtualjaguar.pro b/virtualjaguar.pro index 7a6992e..0c42810 100644 --- a/virtualjaguar.pro +++ b/virtualjaguar.pro @@ -74,7 +74,9 @@ HEADERS = \ src/gui/keygrabber.h \ src/gui/mainwin.h \ src/gui/debug/cpubrowser.h \ + src/gui/debug/m68kdasmbrowser.h \ src/gui/debug/memorybrowser.h \ + src/gui/debug/opbrowser.h \ # src/gui/sdljoystick.h SOURCES = \ @@ -94,5 +96,7 @@ SOURCES = \ src/gui/keygrabber.cpp \ src/gui/mainwin.cpp \ src/gui/debug/cpubrowser.cpp \ + src/gui/debug/m68kdasmbrowser.cpp \ src/gui/debug/memorybrowser.cpp \ + src/gui/debug/opbrowser.cpp \ # src/gui/sdljoystick.cpp