mirror of https://github.com/stella-emu/stella.git
implemented WSYNC part of #165 (TODO: doc)
refined TiaInfoWidget, CpuWidget and RamWidget
This commit is contained in:
parent
d9dce4064f
commit
720cad7e76
|
@ -877,7 +877,7 @@ std::array<Debugger::BuiltinFunction, 18> Debugger::ourBuiltinFunctions = { {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Names are defined here, but processed in YaccParser
|
||||
std::array<Debugger::PseudoRegister, 14> Debugger::ourPseudoRegisters = { {
|
||||
std::array<Debugger::PseudoRegister, 15> Debugger::ourPseudoRegisters = { {
|
||||
// Debugger::PseudoRegister Debugger::ourPseudoRegisters[NUM_PSEUDO_REGS] = {
|
||||
{ "_bank", "Currently selected bank" },
|
||||
{ "_cclocks", "Color clocks on current scanline" },
|
||||
|
@ -885,6 +885,7 @@ std::array<Debugger::PseudoRegister, 14> Debugger::ourPseudoRegisters = { {
|
|||
{ "_cycleslo", "Lower 32 bits of number of cycles since emulation started" },
|
||||
{ "_fcount", "Number of frames since emulation started" },
|
||||
{ "_fcycles", "Number of cycles since frame started" },
|
||||
{ "_fwsynccycles", "Number of cycles skipped by WSYNC since frame started" },
|
||||
{ "_icycles", "Number of cycles of last instruction" },
|
||||
{ "_scan", "Current scanline count" },
|
||||
{ "_scanend", "Scanline count at end of last frame" },
|
||||
|
|
|
@ -363,7 +363,7 @@ class Debugger : public DialogContainer
|
|||
string name, help;
|
||||
};
|
||||
static std::array<BuiltinFunction, 18> ourBuiltinFunctions;
|
||||
static std::array<PseudoRegister, 14> ourPseudoRegisters;
|
||||
static std::array<PseudoRegister, 15> ourPseudoRegisters;
|
||||
|
||||
private:
|
||||
// rewind/unwind n states
|
||||
|
|
|
@ -149,6 +149,7 @@ const DebuggerState& TIADebug::getState()
|
|||
myState.info.push_back(scanlines());
|
||||
myState.info.push_back(scanlinesLastFrame());
|
||||
myState.info.push_back(clocksThisLine());
|
||||
myState.info.push_back(frameWsyncCycles());
|
||||
|
||||
return myState;
|
||||
}
|
||||
|
@ -258,6 +259,7 @@ void TIADebug::saveOldState()
|
|||
myOldState.info.push_back(scanlines());
|
||||
myOldState.info.push_back(scanlinesLastFrame());
|
||||
myOldState.info.push_back(clocksThisLine());
|
||||
myOldState.info.push_back(frameWsyncCycles());
|
||||
}
|
||||
|
||||
/* the set methods now use mySystem.poke(). This will save us the
|
||||
|
@ -909,6 +911,12 @@ int TIADebug::frameCycles() const
|
|||
return myTIA.frameCycles();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int TIADebug::frameWsyncCycles() const
|
||||
{
|
||||
return myTIA.frameWSyncCycles();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int TIADebug::cyclesLo() const
|
||||
{
|
||||
|
|
|
@ -169,6 +169,7 @@ class TIADebug : public DebuggerSystem
|
|||
int scanlinesLastFrame() const;
|
||||
int frameCount() const;
|
||||
int frameCycles() const;
|
||||
int frameWsyncCycles() const;
|
||||
int cyclesLo() const;
|
||||
int cyclesHi() const;
|
||||
int clocksThisLine() const;
|
||||
|
|
|
@ -39,6 +39,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
const int fontWidth = lfont.getMaxCharWidth(),
|
||||
fontHeight = lfont.getFontHeight(),
|
||||
lineHeight = lfont.getLineHeight();
|
||||
const int VGAP = 2;
|
||||
int xpos, ypos, lwidth;
|
||||
|
||||
// Create a 1x1 grid with label for the PC register
|
||||
|
@ -58,7 +59,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
myPCLabel->setEditable(false, true);
|
||||
|
||||
// Create a 1x4 grid with labels for the other CPU registers
|
||||
xpos = x + lwidth; ypos += myPCGrid->getHeight() + 1;
|
||||
xpos = x + lwidth; ypos = myPCGrid->getBottom() + VGAP;
|
||||
myCpuGrid =
|
||||
new DataGridWidget(boss, nfont, xpos, ypos, 1, 4, 2, 8, Common::Base::Fmt::_16);
|
||||
myCpuGrid->setTarget(this);
|
||||
|
@ -88,17 +89,11 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
int src_y = ypos, src_w = (max_w - xpos + x) - 10;
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w,
|
||||
fontHeight+1, "");
|
||||
myCpuDataSrc[i] = new EditTextWidget(boss, nfont, xpos, src_y, src_w, fontHeight + 1);
|
||||
myCpuDataSrc[i]->setEditable(false, true);
|
||||
src_y += fontHeight+2;
|
||||
src_y += fontHeight + 2;
|
||||
}
|
||||
|
||||
// Last write destination address
|
||||
new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, src_y + 4, "Dest");
|
||||
myCpuDataDest = new EditTextWidget(boss, nfont, xpos, src_y + 2, src_w, fontHeight+1);
|
||||
myCpuDataDest->setEditable(false, true);
|
||||
|
||||
// Add labels for other CPU registers
|
||||
xpos = x;
|
||||
const std::array<string, 4> labels = { "SP ", "A ", "X ", "Y " };
|
||||
|
@ -121,7 +116,7 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
}
|
||||
|
||||
// Create a bitfield widget for changing the processor status
|
||||
xpos = x; ypos += 4*lineHeight + 2;
|
||||
xpos = x; ypos = myCpuGrid->getBottom() + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 2, lwidth-2, fontHeight,
|
||||
"PS ", TextAlign::Left);
|
||||
myPSRegister = new ToggleBitWidget(boss, nfont, xpos+lwidth, ypos, 8, 1);
|
||||
|
@ -140,6 +135,14 @@ CpuWidget::CpuWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
}
|
||||
myPSRegister->setList(off, on);
|
||||
|
||||
// Last write destination address
|
||||
xpos = myCpuDataSrc[0]->getLeft();
|
||||
new StaticTextWidget(boss, lfont, xpos - fontWidth * 4.5, ypos + 2, "Dest");
|
||||
myCpuDataDest = new EditTextWidget(boss, nfont, xpos, ypos, src_w, fontHeight + 1);
|
||||
myCpuDataDest->setEditable(false, true);
|
||||
|
||||
|
||||
|
||||
_h = ypos + myPSRegister->getHeight() - y;
|
||||
}
|
||||
|
||||
|
|
|
@ -589,7 +589,7 @@ void DebuggerDialog::addRomArea()
|
|||
DataGridOpsWidget* ops = new DataGridOpsWidget(this, *myLFont, xpos, ypos);
|
||||
|
||||
int max_w = xpos - r.x() - 10;
|
||||
xpos = r.x() + 10; ypos = 10;
|
||||
xpos = r.x() + 10; ypos = 5;
|
||||
myCpu = new CpuWidget(this, *myLFont, *myNFont, xpos, ypos, max_w);
|
||||
addToFocusList(myCpu->getFocusList());
|
||||
|
||||
|
|
|
@ -53,8 +53,9 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
|
||||
// Add RAM grid (with scrollbar)
|
||||
int xpos = x + _font.getStringWidth("xxxx");
|
||||
bool useScrollbar = ramsize / numrows > 16;
|
||||
myRamGrid = new DataGridWidget(_boss, _nfont, xpos, ypos,
|
||||
16, myNumRows, 2, 8, Common::Base::Fmt::_16, true);
|
||||
16, myNumRows, 2, 8, Common::Base::Fmt::_16, useScrollbar);
|
||||
myRamGrid->setTarget(this);
|
||||
myRamGrid->setID(kRamGridID);
|
||||
addFocusWidget(myRamGrid);
|
||||
|
@ -144,7 +145,6 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& lfont, const GUI::Font& n
|
|||
|
||||
// Add Hex display of selected RAM cell
|
||||
xpos -= 4.5 * myFontWidth;
|
||||
//s = new StaticTextWidget(boss, lfont, xpos, ypos, "$");
|
||||
myHexValue = new DataGridWidget(boss, nfont, xpos, ypos - 2,
|
||||
1, 1, 2, 8, Common::Base::Fmt::_16);
|
||||
myHexValue->setTarget(this);
|
||||
|
|
|
@ -36,85 +36,82 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
{
|
||||
bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9
|
||||
+ EditTextWidget::calcWidth(lfont) * 3 <= max_w;
|
||||
const int VGAP = 5;
|
||||
const int VGAP = lfont.getLineHeight() / 4;
|
||||
const int VBORDER = 5 + 1;
|
||||
|
||||
x += 11;
|
||||
const int lineHeight = lfont.getLineHeight();
|
||||
int xpos = x, ypos = y + 10;
|
||||
int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle " : "F. Cycle ");
|
||||
int xpos = x, ypos = y + VBORDER;
|
||||
int lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle") + _fontWidth * 0.5;
|
||||
int l2width = lwidth - lfont.getMaxCharWidth() * 3;
|
||||
int fwidth = EditTextWidget::calcWidth(lfont, 5);
|
||||
int twidth = EditTextWidget::calcWidth(lfont, 8);
|
||||
|
||||
// Add frame info
|
||||
// 1st column
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
|
||||
longstr ? "Frame Count " : "Frame ",
|
||||
TextAlign::Left);
|
||||
xpos += lwidth;
|
||||
myFrameCount = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, "");
|
||||
// Left column
|
||||
// Left: Frame Count
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Count " : "Frame ");
|
||||
myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myFrameCount->setEditable(false, true);
|
||||
|
||||
// Left: Frame Cycle
|
||||
xpos = x; ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
|
||||
longstr ? "Frame Cycle " : "F. Cycle ",
|
||||
TextAlign::Left);
|
||||
xpos += lwidth;
|
||||
myFrameCycles = new EditTextWidget(boss, nfont, xpos, ypos-1, fwidth, lineHeight, "");
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cycle " : "F. Cycle ");
|
||||
myFrameCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myFrameCycles->setEditable(false, true);
|
||||
|
||||
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, "");
|
||||
// Left: WSync Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl. " : "WSync C. ");
|
||||
myWSyncCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myWSyncCylces->setEditable(false, true);
|
||||
|
||||
// Left: Total Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total ");
|
||||
myTotalCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight);
|
||||
myTotalCycles->setEditable(false, true);
|
||||
|
||||
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, "");
|
||||
// Left: Delta Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta ");
|
||||
myDeltaCycles = new EditTextWidget(boss, nfont, xpos + l2width, ypos - 1, twidth, lineHeight);
|
||||
myDeltaCycles->setEditable(false, true);
|
||||
|
||||
// 2nd column
|
||||
xpos = x + lwidth + myFrameCycles->getWidth() + 9; ypos = y + 10;
|
||||
// Right column
|
||||
xpos = myFrameCycles->getRight() + _fontWidth * 1.25; ypos = y + VBORDER;
|
||||
lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ");
|
||||
fwidth = EditTextWidget::calcWidth(lfont, 3);
|
||||
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos, longstr ? "Scanline" : "Scn Ln");
|
||||
myScanlineCountLast = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
|
||||
lineHeight, "");
|
||||
// Right: Scanline
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scanline" : "Scn Ln");
|
||||
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, "");
|
||||
xpos + lwidth - myScanlineCountLast->getWidth() - 2, ypos - 1,
|
||||
fwidth, lineHeight);
|
||||
myScanlineCount->setEditable(false, true);
|
||||
|
||||
// Right: Scan Cycle
|
||||
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, "");
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle " : "Scn Cycle");
|
||||
myScanlineCycles = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myScanlineCycles->setEditable(false, true);
|
||||
|
||||
// Right: Pixel Pos
|
||||
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, "");
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Pixel Pos ");
|
||||
myPixelPosition = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myPixelPosition->setEditable(false, true);
|
||||
|
||||
// Right: Color Clock
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos, lwidth, lineHeight,
|
||||
longstr ? "Color Clock " : "Color Clk ", TextAlign::Left);
|
||||
|
||||
myColorClocks = new EditTextWidget(boss, nfont, xpos+lwidth, ypos-1, fwidth,
|
||||
lineHeight, "");
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Color Clock " : "Color Clk ");
|
||||
myColorClocks = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myColorClocks->setEditable(false, true);
|
||||
|
||||
// Calculate actual dimensions
|
||||
_w = myColorClocks->getAbsX() + myColorClocks->getWidth() - x;
|
||||
_h = ypos + lineHeight;
|
||||
_w = myColorClocks->getRight() - x;
|
||||
_h = myDeltaCycles->getBottom();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -159,4 +156,7 @@ void TiaInfoWidget::loadConfig()
|
|||
clk != oldTia.info[6]);
|
||||
myColorClocks->setText(Common::Base::toString(clk, Common::Base::Fmt::_10),
|
||||
clk != oldTia.info[6]);
|
||||
|
||||
myWSyncCylces->setText(Common::Base::toString(tia.frameWsyncCycles(), Common::Base::Fmt::_10_5),
|
||||
tia.frameWsyncCycles() != oldTia.info[7]);
|
||||
}
|
||||
|
|
|
@ -38,12 +38,13 @@ class TiaInfoWidget : public Widget, public CommandSender
|
|||
private:
|
||||
EditTextWidget* myFrameCount{nullptr};
|
||||
EditTextWidget* myFrameCycles{nullptr};
|
||||
EditTextWidget* myTotalCycles{ nullptr };
|
||||
EditTextWidget* myTotalCycles{nullptr};
|
||||
EditTextWidget* myDeltaCycles{nullptr};
|
||||
EditTextWidget* myWSyncCylces{nullptr};
|
||||
|
||||
EditTextWidget* myScanlineCount{nullptr};
|
||||
EditTextWidget* myScanlineCountLast{nullptr};
|
||||
EditTextWidget* myScanlineCycles{nullptr};
|
||||
EditTextWidget* myDeltaCycles{ nullptr };
|
||||
EditTextWidget* myPixelPosition{nullptr};
|
||||
EditTextWidget* myColorClocks{nullptr};
|
||||
|
||||
|
|
|
@ -163,6 +163,7 @@ void TIA::initialize()
|
|||
myDelayQueue.reset();
|
||||
|
||||
myCyclesAtFrameStart = 0;
|
||||
myFrameWsyncCycles = 0;
|
||||
|
||||
if (myFrameManager)
|
||||
myFrameManager->reset();
|
||||
|
@ -279,6 +280,7 @@ bool TIA::save(Serializer& out) const
|
|||
out.putByteArray(myShadowRegisters.data(), myShadowRegisters.size());
|
||||
|
||||
out.putLong(myCyclesAtFrameStart);
|
||||
out.putLong(myFrameWsyncCycles);
|
||||
|
||||
out.putInt(myFrameBufferScanlines);
|
||||
out.putInt(myFrontBufferScanlines);
|
||||
|
@ -351,6 +353,7 @@ bool TIA::load(Serializer& in)
|
|||
in.getByteArray(myShadowRegisters.data(), myShadowRegisters.size());
|
||||
|
||||
myCyclesAtFrameStart = in.getLong();
|
||||
myFrameWsyncCycles = in.getLong();
|
||||
|
||||
myFrameBufferScanlines = in.getInt();
|
||||
myFrontBufferScanlines = in.getInt();
|
||||
|
@ -1304,6 +1307,7 @@ void TIA::updateEmulation()
|
|||
void TIA::onFrameStart()
|
||||
{
|
||||
myXAtRenderingStart = 0;
|
||||
myFrameWsyncCycles = 0;
|
||||
|
||||
// Check for colour-loss emulation
|
||||
if (myColorLossEnabled)
|
||||
|
@ -1351,6 +1355,7 @@ void TIA::onHalt()
|
|||
{
|
||||
mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS;
|
||||
mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS);
|
||||
myFrameWsyncCycles += mySubClock / TIAConstants::CYCLE_CLOCKS;
|
||||
mySubClock %= TIAConstants::CYCLE_CLOCKS;
|
||||
}
|
||||
|
||||
|
|
|
@ -334,6 +334,13 @@ class TIA : public Device
|
|||
return uInt32(mySystem->cycles() - myCyclesAtFrameStart);
|
||||
}
|
||||
|
||||
/**
|
||||
Answers the system cycles used by WSYNC from the start of the current frame.
|
||||
*/
|
||||
uInt32 frameWSyncCycles() const {
|
||||
return uInt32(myFrameWsyncCycles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CPU cycles since the last dump ports change.
|
||||
*
|
||||
|
@ -939,6 +946,11 @@ class TIA : public Device
|
|||
*/
|
||||
uInt64 myCyclesAtFrameStart{0};
|
||||
|
||||
/**
|
||||
* System cycles used by WSYNC during current frame.
|
||||
*/
|
||||
uInt64 myFrameWsyncCycles{0};
|
||||
|
||||
/**
|
||||
* The frame manager can change during our lifetime, so we buffer those two.
|
||||
*/
|
||||
|
|
|
@ -254,6 +254,8 @@ TiaMethod getTiaSpecial(char* ch)
|
|||
return &TIADebug::frameCount;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_fcycles"))
|
||||
return &TIADebug::frameCycles;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_fwsynccycles"))
|
||||
return &TIADebug::frameWsyncCycles;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_cyclesLo"))
|
||||
return &TIADebug::cyclesLo;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_cyclesHi"))
|
||||
|
|
Loading…
Reference in New Issue