From 8fa19895c8308c0a1aee537f971c740eea4bab9e Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 14 Aug 2012 22:39:04 -0500 Subject: [PATCH] Added memory browser, fixed documentation, M68000 exception explanations. Fixed documentation to reflect the current state of Virtual Jaguar, added text to the M68000 exception handler to show what kind of exception occured. Also added a rudimentary memory browser to allow developers a peek at the RAM of the emulated Jaguar. --- res/help.html | 9 +-- src/gui/debug/memorybrowser.cpp | 124 ++++++++++++++++++++++++++++++++ src/gui/debug/memorybrowser.h | 38 ++++++++++ src/gui/help.cpp | 4 +- src/gui/mainwin.cpp | 27 +++++++ src/gui/mainwin.h | 10 ++- src/m68000/cpuextra.c | 14 +++- virtualjaguar.pro | 3 + 8 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 src/gui/debug/memorybrowser.cpp create mode 100644 src/gui/debug/memorybrowser.h diff --git a/res/help.html b/res/help.html index 86daf51..ac07ec6 100644 --- a/res/help.html +++ b/res/help.html @@ -22,7 +22,7 @@

System Requirements

-

Virtual Jaguar should be able to run on most late model computers equipped with an OpenGL compliant video card. It requires a lot of raw oomph in it’s present form to run well; do not be surprised if it doesn’t run at 100% speed with all the options, such as sound and DSP, turned on. Certain subsystems of the Jaguar are not optimized yet and as such take more time than they would if they were optimized. To run Virtual Jaguar at full speed with all options on, we recommend using liquid nitrogen. At least until we get it properly optimized. ;-)

+

Virtual Jaguar should be able to run on most late model computers equipped with an OpenGL compliant video card. It requires a lot of raw oomph in it’s present form to run well; do not be surprised if it doesn’t run at 100% speed with all the options turned on. Certain subsystems of the Jaguar are not optimized yet and as such take more time than they would if they were optimized. To run Virtual Jaguar at full speed with all options on, we recommend using liquid nitrogen. At least until we get it properly optimized. ;-)

Virtual Jaguar In Depth

@@ -152,7 +152,6 @@
  • Enable Jaguar BIOS
  • Enable GPU
  • Enable DSP
  • -
  • Enable audio playback
  • Show all files in file chooser
  • @@ -176,11 +175,7 @@

    Enable DSP

    -

    The DSP is one of the three main processors in the Jaguar, and checking this option enables it. Much software will work without it, however, there is some software that will not.

    - -

    Enable audio playback

    - -

    Checking this option will allow Virtual Jaguar to attempt to output sound to your sound card. It will not output any sound without the DSP being enabled.

    +

    The DSP is one of the three main processors in the Jaguar, and checking this option enables it. Much software will work without it, however, there is some software that will not. Note that if the DSP is disabled, there will be no sound.

    Show all files in file chooser

    diff --git a/src/gui/debug/memorybrowser.cpp b/src/gui/debug/memorybrowser.cpp new file mode 100644 index 0000000..b67ff32 --- /dev/null +++ b/src/gui/debug/memorybrowser.cpp @@ -0,0 +1,124 @@ +// +// memorybrowser.cpp - Jaguar memory browser +// +// by James Hammons +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// Who When What +// --- ---------- ------------------------------------------------------------- +// JLH 08/14/2012 Created this file +// + +// STILL TO DO: +// + +#include "memorybrowser.h" +#include "memory.h" + + +MemoryBrowserWindow::MemoryBrowserWindow(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("Memory 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 MemoryBrowserWindow::RefreshContents(void) +{ + char string[1024], buf[64]; + QString memDump; + + 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); + } + + text->clear(); + text->setText(memDump); +} + + +void MemoryBrowserWindow::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return) + hide(); + 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(); + } +} diff --git a/src/gui/debug/memorybrowser.h b/src/gui/debug/memorybrowser.h new file mode 100644 index 0000000..e373e51 --- /dev/null +++ b/src/gui/debug/memorybrowser.h @@ -0,0 +1,38 @@ +// +// memorybrowser.h: Jaguar memory browser +// +// by James Hammons +// (C) 2012 Underground Software +// + +#ifndef __MEMORYBROWSER_H__ +#define __MEMORYBROWSER_H__ + +#include +#include + +class MemoryBrowserWindow: public QWidget +{ + Q_OBJECT + + public: + MemoryBrowserWindow(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 // __MEMORYBROWSER_H__ diff --git a/src/gui/help.cpp b/src/gui/help.cpp index da29009..3194f90 100644 --- a/src/gui/help.cpp +++ b/src/gui/help.cpp @@ -1,10 +1,10 @@ // // help.cpp - Help file // -// by James L. Hammons +// by James Hammons // (C) 2011 Underground Software // -// JLH = James L. Hammons +// JLH = James Hammons // // Who When What // --- ---------- ------------------------------------------------------------- diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index 4399688..b9c0724 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -43,6 +43,7 @@ #include "configdialog.h" #include "generaltab.h" #include "version.h" +#include "debug/memorybrowser.h" #include "dac.h" #include "jaguar.h" @@ -96,6 +97,7 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), aboutWin = new AboutWindow(this); helpWin = new HelpWindow(this); filePickWin = new FilePickerWindow(this); + memBrowseWin = new MemoryBrowserWindow(this); videoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -197,6 +199,12 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), frameAdvanceAct->setShortcut(QKeySequence(tr("F7"))); connect(frameAdvanceAct, SIGNAL(triggered()), this, SLOT(FrameAdvance())); + // Debugger Actions + memBrowseAct = new QAction(QIcon(":/res/generic.png"), tr("Memory Browser"), this); + memBrowseAct->setStatusTip(tr("Shows the Jaguar memory browser window")); +// memBrowseAct->setCheckable(true); + connect(memBrowseAct, SIGNAL(triggered()), this, SLOT(ShowMemoryBrowserWin())); + // Misc. connections... connect(filePickWin, SIGNAL(RequestLoad(QString)), this, SLOT(LoadSoftware(QString))); connect(filePickWin, SIGNAL(FilePickerHiding()), this, SLOT(Unpause())); @@ -212,6 +220,12 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), fileMenu->addAction(configAct); fileMenu->addAction(quitAppAct); + if (vjs.hardwareTypeAlpine) + { + debugMenu = menuBar()->addMenu(tr("&Debug")); + debugMenu->addAction(memBrowseAct); + } + helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(helpAct); helpMenu->addAction(aboutAct); @@ -231,6 +245,12 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), toolbar->addSeparator(); toolbar->addAction(blurAct); + if (vjs.hardwareTypeAlpine) + { + debugbar = addToolBar(tr("&Debug")); + debugbar->addAction(memBrowseAct); + } + // Create status bar statusBar()->showMessage(tr("Ready")); @@ -759,6 +779,13 @@ void MainWin::FrameAdvance(void) } +void MainWin::ShowMemoryBrowserWin(void) +{ + memBrowseWin->show(); + memBrowseWin->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 ece5324..fd6aef1 100644 --- a/src/gui/mainwin.h +++ b/src/gui/mainwin.h @@ -16,6 +16,7 @@ class GLWidget; class AboutWindow; class HelpWindow; class FilePickerWindow; +class MemoryBrowserWindow; class MainWin: public QMainWindow { @@ -53,6 +54,8 @@ class MainWin: public QMainWindow void ToggleCDUsage(void); void FrameAdvance(void); + void ShowMemoryBrowserWin(void); + private: void HandleKeys(QKeyEvent *, bool); void ResizeMainWindow(void); @@ -65,6 +68,7 @@ class MainWin: public QMainWindow AboutWindow * aboutWin; HelpWindow * helpWin; FilePickerWindow * filePickWin; + MemoryBrowserWindow * memBrowseWin; QTimer * timer; bool running; int zoomLevel; @@ -82,7 +86,9 @@ class MainWin: public QMainWindow private: QMenu * fileMenu; QMenu * helpMenu; + QMenu * debugMenu; QToolBar * toolbar; + QToolBar * debugbar; QActionGroup * zoomActs; QActionGroup * tvTypeActs; @@ -102,7 +108,9 @@ class MainWin: public QMainWindow QAction * configAct; QAction * useCDAct; QAction * frameAdvanceAct; - + + QAction * memBrowseAct; + QIcon powerGreen; QIcon powerRed; }; diff --git a/src/m68000/cpuextra.c b/src/m68000/cpuextra.c index b29860c..3b57590 100644 --- a/src/m68000/cpuextra.c +++ b/src/m68000/cpuextra.c @@ -108,7 +108,19 @@ NB: Seems that when an address exception occurs, it doesn't get handled properly // void Exception(int nr, uint32_t oldpc, int ExceptionSource) { -printf("Exception #%i occurred!\n", nr); +char excNames[33][64] = { + "???", "???", "Bus Error", "Address Error", + "Illegal Instruction", "Zero Divide", "CHK", "TrapV", + "Privilege Violation", "Trace", "Line A", "Line F", + "???", "???", "Format Error", "Uninitialized Interrupt", + "???", "???", "???", "???", + "???", "???", "???", "???", + "Spurious/Autovector", "???", "???", "???", + "???", "???", "???", "???", + "Trap #" +}; + +printf("Exception #%i occurred! (%s)\n", nr, (nr < 32 ? excNames[nr] : (nr < 48 ? "Trap #" : "????"))); printf("Vector @ #%i = %08X\n", nr, m68k_read_memory_32(nr * 4)); //abort(); uint32_t currpc = m68k_getpc(), newpc; diff --git a/virtualjaguar.pro b/virtualjaguar.pro index 86bfcca..f16d7ce 100644 --- a/virtualjaguar.pro +++ b/virtualjaguar.pro @@ -52,6 +52,7 @@ INCLUDEPATH += \ DEPENDPATH = \ src \ src/gui \ + src/gui/debug \ src/m68000 # The GUI @@ -72,6 +73,7 @@ HEADERS = \ src/gui/imagedelegate.h \ src/gui/keygrabber.h \ src/gui/mainwin.h \ + src/gui/debug/memorybrowser.h \ # src/gui/sdljoystick.h SOURCES = \ @@ -90,4 +92,5 @@ SOURCES = \ src/gui/imagedelegate.cpp \ src/gui/keygrabber.cpp \ src/gui/mainwin.cpp \ + src/gui/debug/memorybrowser.cpp \ # src/gui/sdljoystick.cpp -- 2.37.2