mirror of https://github.com/stella-emu/stella.git
add total and delta cycle counter (resolves #565)
make VSync and VBlank editable
This commit is contained in:
parent
030f4140c7
commit
2f144349fb
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef STATE_MANAGER_HXX
|
||||
#define STATE_MANAGER_HXX
|
||||
|
||||
#define STATE_HEADER "06000007state"
|
||||
#define STATE_HEADER "06000008state"
|
||||
|
||||
class OSystem;
|
||||
class RewindManager;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(), "");
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<const char*, 4> 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]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue