diff --git a/src/common/Base.cxx b/src/common/Base.cxx index ffe1afe9b..ee125ee7e 100644 --- a/src/common/Base.cxx +++ b/src/common/Base.cxx @@ -68,6 +68,14 @@ string Base::toString(int value, Common::Base::Fmt outputBase) std::snprintf(vToS_buf, 6, "%5d", value); break; + case Base::Fmt::_10_6: // base 10: 6 digits + std::snprintf(vToS_buf, 7, "%6d", value); + break; + + case Base::Fmt::_10_8: // base 10: 8 digits + std::snprintf(vToS_buf, 9, "%8d", value); + break; + case Base::Fmt::_16_1: // base 16: 1 byte wide std::snprintf(vToS_buf, 2, hexUppercase() ? "%1X" : "%1x", value); break; diff --git a/src/common/Base.hxx b/src/common/Base.hxx index 8c7a25184..8537d6def 100644 --- a/src/common/Base.hxx +++ b/src/common/Base.hxx @@ -51,6 +51,8 @@ class Base _10_3, // base 10: 3 digits _10_4, // base 10: 4 digits _10_5, // base 10: 5 digits + _10_6, // base 10: 6 digits + _10_8, // base 10: 8 digits _2, // base 2: 8 or 16 bits (depending on value) _2_8, // base 2: 1 byte (8 bits) wide _2_16, // base 2: 2 bytes (16 bits) wide diff --git a/src/common/StateManager.hxx b/src/common/StateManager.hxx index a9fc87052..41bed3517 100644 --- a/src/common/StateManager.hxx +++ b/src/common/StateManager.hxx @@ -18,7 +18,7 @@ #ifndef STATE_MANAGER_HXX #define STATE_MANAGER_HXX -#define STATE_HEADER "06000007state" +#define STATE_HEADER "06000008state" class OSystem; class RewindManager; diff --git a/src/debugger/TIADebug.cxx b/src/debugger/TIADebug.cxx index d100255ce..abde49c69 100644 --- a/src/debugger/TIADebug.cxx +++ b/src/debugger/TIADebug.cxx @@ -126,6 +126,11 @@ const DebuggerState& TIADebug::getState() myState.size.push_back(nusizM1()); myState.size.push_back(sizeBL()); + // VSync/VBlank registers + myState.vsb.clear(); + myState.vsb.push_back(vsync()); + myState.vsb.push_back(vblank()); + // Audio registers myState.aud.clear(); myState.aud.push_back(audF0()); @@ -139,8 +144,8 @@ const DebuggerState& TIADebug::getState() myState.info.clear(); myState.info.push_back(frameCount()); myState.info.push_back(frameCycles()); - myState.info.push_back(vsyncAsInt()); - myState.info.push_back(vblankAsInt()); + myState.info.push_back(cyclesLo()); + myState.info.push_back(cyclesHi()); myState.info.push_back(scanlines()); myState.info.push_back(scanlinesLastFrame()); myState.info.push_back(clocksThisLine()); @@ -230,6 +235,11 @@ void TIADebug::saveOldState() myOldState.size.push_back(nusizM1()); myOldState.size.push_back(sizeBL()); + // VSync/VBlank registers + myOldState.vsb.clear(); + myOldState.vsb.push_back(vsync()); + myOldState.vsb.push_back(vblank()); + // Audio registers myOldState.aud.clear(); myOldState.aud.push_back(audF0()); @@ -243,8 +253,8 @@ void TIADebug::saveOldState() myOldState.info.clear(); myOldState.info.push_back(frameCount()); myOldState.info.push_back(frameCycles()); - myOldState.info.push_back(vsyncAsInt()); - myOldState.info.push_back(vblankAsInt()); + myOldState.info.push_back(cyclesLo()); + myOldState.info.push_back(cyclesHi()); myOldState.info.push_back(scanlines()); myOldState.info.push_back(scanlinesLastFrame()); myOldState.info.push_back(clocksThisLine()); @@ -935,12 +945,30 @@ int TIADebug::cyclesThisLine() const return myTIA.clocksThisLine()/3; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TIADebug::vsync(int newVal) +{ + if (newVal > -1) + mySystem.poke(VSYNC, newVal); + + return myTIA.registerValue(VSYNC) & 0x02; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIADebug::vsync() const { return myTIA.registerValue(VSYNC) & 0x02; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool TIADebug::vblank(int newVal) +{ + if (newVal > -1) + mySystem.poke(VBLANK, newVal); + + return myTIA.registerValue(VBLANK) & 0x02; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIADebug::vblank() const { diff --git a/src/debugger/TIADebug.hxx b/src/debugger/TIADebug.hxx index 16b2757c2..cf6171d17 100644 --- a/src/debugger/TIADebug.hxx +++ b/src/debugger/TIADebug.hxx @@ -45,6 +45,7 @@ class TiaState : public DebuggerState IntArray size; IntArray aud; IntArray info; + BoolArray vsb; // Indices for various IntArray above enum { P0, P1, M0, M1, BL }; @@ -128,6 +129,9 @@ class TIADebug : public DebuggerSystem bool scorePF(int newVal = -1); bool priorityPF(int newVal = -1); + bool vsync(int newVal = -1); + bool vblank(int newVal = -1); + /** Get specific bits in the collision register (used by collXX_XX) */ bool collision(CollisionBit id, bool toggle = false) const; diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx index 084f81a17..47e05da04 100644 --- a/src/debugger/gui/DebuggerDialog.cxx +++ b/src/debugger/gui/DebuggerDialog.cxx @@ -471,12 +471,12 @@ void DebuggerDialog::addStatusArea() xpos = r.x(); ypos = r.y(); myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w()); - ypos += myTiaInfo->getHeight() + 10; - myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos+10, ypos, - r.w()-10, r.h()-lineHeight-ypos-10); + ypos += myTiaInfo->getHeight() + 8; + myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos + 10, ypos, + r.w() - 10, r.h() - lineHeight - ypos - 3); addToFocusList(myTiaZoom->getFocusList()); - xpos += 10; ypos += myTiaZoom->getHeight() + 10; + xpos += 10; ypos += myTiaZoom->getHeight() + 6; myMessageBox = new EditTextWidget(this, *myLFont, xpos, ypos, myTiaZoom->getWidth(), myLFont->getLineHeight(), ""); diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx index 3aa027253..f9f11e459 100644 --- a/src/debugger/gui/DebuggerDialog.hxx +++ b/src/debugger/gui/DebuggerDialog.hxx @@ -60,7 +60,7 @@ class DebuggerDialog : public Dialog const GUI::Font& lfont() const { return *myLFont; } const GUI::Font& nfont() const { return *myNFont; } PromptWidget& prompt() const { return *myPrompt; } - TiaInfoWidget& tiaInfo() const { return *myTiaInfo; } + TiaInfoWidget& a() const { return *myTiaInfo; } TiaOutputWidget& tiaOutput() const { return *myTiaOutput; } TiaZoomWidget& tiaZoom() const { return *myTiaZoom; } RomWidget& rom() const { return *myRom; } diff --git a/src/debugger/gui/TiaInfoWidget.cxx b/src/debugger/gui/TiaInfoWidget.cxx index 6dc1f5abe..788f28c27 100644 --- a/src/debugger/gui/TiaInfoWidget.cxx +++ b/src/debugger/gui/TiaInfoWidget.cxx @@ -20,6 +20,7 @@ #include "OSystem.hxx" #include "Debugger.hxx" #include "TIADebug.hxx" +#include "TIA.hxx" #include "Widget.hxx" #include "EditTextWidget.hxx" #include "GuiObject.hxx" @@ -34,14 +35,17 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, CommandSender(boss) { bool longstr = 34 * lfont.getMaxCharWidth() <= max_w; + const int VGAP = 5; - x += 5; + x += 11; const int lineHeight = lfont.getLineHeight(); int xpos = x, ypos = y + 10; int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle " : "F. Cycle "); int fwidth = 5 * lfont.getMaxCharWidth() + 4; + int twidth = 8 * lfont.getMaxCharWidth() + 4; // Add frame info + // 1st column new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, longstr ? "Frame Count " : "Frame ", TextAlign::Left); @@ -49,7 +53,7 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, myFrameCount = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, ""); myFrameCount->setEditable(false, true); - xpos = x; ypos += lineHeight + 5; + xpos = x; ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, longstr ? "Frame Cycle " : "F. Cycle ", TextAlign::Left); @@ -57,48 +61,51 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont, myFrameCycles = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, ""); myFrameCycles->setEditable(false, true); - xpos = x + 20; ypos += lineHeight + 8; - myVSync = new CheckboxWidget(boss, lfont, xpos, ypos-3, "VSync", 0); - myVSync->setEditable(false); + xpos = x; ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, + "Total ", TextAlign::Left); + xpos += lfont.getStringWidth("Total "); + myTotalCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, ""); + myTotalCycles->setEditable(false, true); - xpos = x + 20; ypos += lineHeight + 5; - myVBlank = new CheckboxWidget(boss, lfont, xpos, ypos-3, "VBlank", 0); - myVBlank->setEditable(false); + xpos = x; ypos += lineHeight + VGAP; + new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, + "Delta ", TextAlign::Left); + xpos = x + lfont.getStringWidth("Delta "); + myDeltaCycles = new EditTextWidget(boss, nfont, xpos, ypos - 1, twidth, lineHeight, ""); + myDeltaCycles->setEditable(false, true); - xpos = x + lwidth + myFrameCycles->getWidth() + 8; ypos = y + 10; + // 2nd column + xpos = x + lwidth + myFrameCycles->getWidth() + 9; ypos = y + 10; lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos "); fwidth = 3 * lfont.getMaxCharWidth() + 4; new StaticTextWidget(boss, lfont, xpos, ypos, lfont.getStringWidth(longstr ? "Scanline" : "Scn Ln"), lineHeight, longstr ? "Scanline" : "Scn Ln", TextAlign::Left); - myScanlineCountLast = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, lineHeight, ""); myScanlineCountLast->setEditable(false, true); - myScanlineCount = new EditTextWidget(boss, nfont, xpos+lwidth - myScanlineCountLast->getWidth() - 2, ypos-1, fwidth, lineHeight, ""); myScanlineCount->setEditable(false, true); - ypos += lineHeight + 5; + ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, longstr ? "Scan Cycle " : "Scn Cycle", TextAlign::Left); - myScanlineCycles = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, lineHeight, ""); myScanlineCycles->setEditable(false, true); - ypos += lineHeight + 5; + ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, "Pixel Pos ", TextAlign::Left); - myPixelPosition = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth, lineHeight, ""); myPixelPosition->setEditable(false, true); - ypos += lineHeight + 5; + ypos += lineHeight + VGAP; new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight, longstr ? "Color Clock " : "Color Clk ", TextAlign::Left); @@ -134,8 +141,12 @@ void TiaInfoWidget::loadConfig() myFrameCycles->setText(Common::Base::toString(tia.frameCycles(), Common::Base::Fmt::_10_5), tia.frameCycles() != oldTia.info[1]); - myVSync->setState(tia.vsync(), tia.vsyncAsInt() != oldTia.info[2]); - myVBlank->setState(tia.vblank(), tia.vblankAsInt() != oldTia.info[3]); + uInt64 total = tia.cyclesLo() + (uInt64(tia.cyclesHi()) << 32); + uInt64 totalOld = oldTia.info[2] + (uInt64(oldTia.info[3]) << 32); + myTotalCycles->setText(Common::Base::toString(total / 1000000, Common::Base::Fmt::_10_6) + "e6", + total != totalOld); + uInt32 delta = total - totalOld; + myDeltaCycles->setText(Common::Base::toString(delta, Common::Base::Fmt::_10_8)); // no coloring int clk = tia.clocksThisLine(); myScanlineCount->setText(Common::Base::toString(tia.scanlines(), Common::Base::Fmt::_10_3), diff --git a/src/debugger/gui/TiaInfoWidget.hxx b/src/debugger/gui/TiaInfoWidget.hxx index 7a85ce1c9..cfea723fb 100644 --- a/src/debugger/gui/TiaInfoWidget.hxx +++ b/src/debugger/gui/TiaInfoWidget.hxx @@ -38,16 +38,15 @@ class TiaInfoWidget : public Widget, public CommandSender private: EditTextWidget* myFrameCount{nullptr}; EditTextWidget* myFrameCycles{nullptr}; + EditTextWidget* myTotalCycles{ nullptr }; EditTextWidget* myScanlineCount{nullptr}; EditTextWidget* myScanlineCountLast{nullptr}; EditTextWidget* myScanlineCycles{nullptr}; + EditTextWidget* myDeltaCycles{ nullptr }; EditTextWidget* myPixelPosition{nullptr}; EditTextWidget* myColorClocks{nullptr}; - CheckboxWidget* myVSync{nullptr}; - CheckboxWidget* myVBlank{nullptr}; - private: void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/debugger/gui/TiaWidget.cxx b/src/debugger/gui/TiaWidget.cxx index 83b7cf382..327ed7fa5 100644 --- a/src/debugger/gui/TiaWidget.cxx +++ b/src/debugger/gui/TiaWidget.cxx @@ -43,10 +43,26 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, fontHeight = lfont.getFontHeight(), lineHeight = lfont.getLineHeight(), buttonW = 7 * fontWidth; - int xpos = 10, ypos = 10 + lineHeight, buttonX = 0, buttonY = 0; + int xpos = 10, ypos = 10, buttonX = 0, buttonY = 0; StaticTextWidget* t = nullptr; ButtonWidget* b = nullptr; + + //////////////////////////// + // VSync/VBlank + //////////////////////////// + buttonX = xpos; buttonY = ypos; + myVSync = new CheckboxWidget(boss, lfont, buttonX, buttonY, "VSync", kVSyncCmd); + myVSync->setTarget(this); + addFocusWidget(myVSync); + + buttonX += myVSync->getRight() + 15; + myVBlank = new CheckboxWidget(boss, lfont, buttonX, buttonY, "VBlank", kVBlankCmd); + myVBlank->setTarget(this); + addFocusWidget(myVBlank); + + ypos += lineHeight * 2 + 6; + // Color registers static constexpr std::array regNames = { "COLUP0", "COLUP1", "COLUPF", "COLUBK" @@ -84,7 +100,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, myCOLUBKColor->setTarget(this); // Fixed debug colors - xpos += myCOLUP0Color->getWidth() + 30; ypos = 10; + xpos += myCOLUP0Color->getWidth() + 30; ypos = 10 + lineHeight + 6; myFixedEnabled = new CheckboxWidget(boss, lfont, xpos, ypos, "Debug Colors", kDbgClCmd); myFixedEnabled->setTarget(this); addFocusWidget(myFixedEnabled); @@ -102,7 +118,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, myFixedColors[row]->setTarget(this); } xpos += t->getWidth() + myFixedColors[0]->getWidth() + 24; - ypos = 10; + ypos = 10 + lineHeight + 6; for(uInt32 row = 4; row <= 7; ++row) { ypos += lineHeight; @@ -616,7 +632,7 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, addFocusWidget(myPriorityPF); xpos = 10; - ypos += 2 * lineHeight; + ypos += lineHeight + 10; t = new StaticTextWidget(boss, lfont, xpos, ypos, 13*fontWidth, fontHeight, "Queued Writes", TextAlign::Left); @@ -639,7 +655,8 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& lfont, b->setTarget(this); addFocusWidget(b); - buttonY += lineHeight + 3; + buttonX = b->getRight() + 20; + buttonY = ypos; b = new ButtonWidget(boss, lfont, buttonX, buttonY, buttonW, lineHeight, "HMOVE", kHmoveCmd); b->setTarget(this); @@ -704,6 +721,14 @@ void TiaWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) myFixedEnabled->setState(tia.tia().toggleFixedColors()); break; + case kVSyncCmd: + tia.vsync(tia.vsyncAsInt() & ~0x02 | (myVSync->getState() ? 0x02 : 0x00)); + break; + + case kVBlankCmd: + tia.vblank(tia.vblankAsInt() & ~0x02 | (myVBlank->getState() ? 0x02 : 0x00)); + break; + case DataGridWidget::kItemDataChangedCmd: switch(id) { @@ -1177,6 +1202,9 @@ void TiaWidget::loadConfig() myPriorityPF->setState(tia.priorityPF(), state.pf[5] != oldstate.pf[5]); myDelayQueueWidget->loadConfig(); + + myVSync->setState(tia.vsync(), tia.vsync() != oldstate.vsb[0]); + myVBlank->setState(tia.vblank(), tia.vblank() != oldstate.vsb[1]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/debugger/gui/TiaWidget.hxx b/src/debugger/gui/TiaWidget.hxx index 46a6ae115..bc6c6c632 100644 --- a/src/debugger/gui/TiaWidget.hxx +++ b/src/debugger/gui/TiaWidget.hxx @@ -98,6 +98,9 @@ class TiaWidget : public Widget, public CommandSender DelayQueueWidget* myDelayQueueWidget{nullptr}; + CheckboxWidget* myVSync{nullptr}; + CheckboxWidget* myVBlank{nullptr}; + // ID's for the various widgets // We need ID's, since there are more than one of several types of widgets enum { @@ -139,6 +142,8 @@ class TiaWidget : public Widget, public CommandSender kCxChgCmd = 'Sccc', kCxclrCmd = 'Scxl', kDbgClCmd = 'DBGc', + kVSyncCmd = 'Cvsn', + kVBlankCmd = 'Cvbl' }; // Color registers