implemented WSYNC part of #165 (TODO: doc)

refined TiaInfoWidget, CpuWidget and RamWidget
This commit is contained in:
thrust26 2020-10-12 21:30:03 +02:00
parent d9dce4064f
commit 720cad7e76
12 changed files with 97 additions and 64 deletions

View File

@ -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" },

View File

@ -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

View File

@ -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
{

View File

@ -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;

View File

@ -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;
}

View File

@ -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());

View File

@ -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);

View File

@ -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]);
}

View File

@ -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};

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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"))