fully resolved #165 (added timer read cycles count)
refined TiaInfoWidget again added doc
|
@ -753,6 +753,8 @@ that holds 'number of scanlines' on an actual console).</p>
|
|||
<tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
|
||||
<tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
|
||||
<tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
|
||||
<tr><td> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
||||
<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
||||
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
|
||||
<tr><td> _scan</td><td> Current scanline count</td></tr>
|
||||
<tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
|
||||
|
@ -1137,12 +1139,16 @@ as illustrated:</p>
|
|||
<p><img src="graphics/debugger_tiainfo.png"></p>
|
||||
<p>The indicators are as follows (note that all these are read-only):</p>
|
||||
<ul>
|
||||
<li><b>Frame Count</b>: The number of frames since this ROM was loaded or reset.</li>
|
||||
<li><b>Frame Cycle</b>: The number of CPU cycles that have been executed this frame since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
<li><b>WSync Cycl.</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
<li><b>Timer Cycl.</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
|
||||
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
|
||||
interrupt.</li>
|
||||
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
|
||||
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
|
||||
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
|
||||
3 scanlines, as per the Stella Programmer's Guide).</li>
|
||||
|
@ -1275,10 +1281,9 @@ are lost (they will NOT end up in the Carry flag).</p>
|
|||
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
|
||||
of the 2600's zero-page RAM.</p>
|
||||
<p>You can navigate with either the mouse or the keyboard arrow keys.
|
||||
To change a RAM location, either double-click on it or press Enter while
|
||||
it's highlighted. Enter the new value (hex only for now, sorry), then
|
||||
press Enter to make the change. If you change your mind, press Escape
|
||||
and the original value will be restored. The currently selected RAM cell
|
||||
To change a RAM location, either double-click on it or press 'Enter' while
|
||||
it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
|
||||
press 'Enter' to make the change. The currently selected RAM cell
|
||||
can also be changed by using the
|
||||
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
|
||||
shortcut keys.</p>
|
||||
|
@ -1289,7 +1294,8 @@ more comprehensive. It will undo <b>all</b> operations on <b>all</b> cells
|
|||
since you first made a change.</p>
|
||||
<p>The UI objects at the bottom refer to the currently selected RAM cell.
|
||||
The 'Label' textbox shows the label attached to this RAM location (if any),
|
||||
and the other two textboxes show the decimal and binary equivalent value.</p>
|
||||
and the other three textboxes show the hex, decimal and binary equivalent value.
|
||||
The values can be edited here too.</p>
|
||||
|
||||
<p>The remaining buttons to the right are further explained in the next section.</p>
|
||||
|
||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -877,7 +877,7 @@ std::array<Debugger::BuiltinFunction, 18> Debugger::ourBuiltinFunctions = { {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Names are defined here, but processed in YaccParser
|
||||
std::array<Debugger::PseudoRegister, 15> Debugger::ourPseudoRegisters = { {
|
||||
std::array<Debugger::PseudoRegister, 16> 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, 15> 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" },
|
||||
{ "_ftimreadcycles","Number of cycles used by timer reads since frame started" },
|
||||
{ "_fwsynccycles", "Number of cycles skipped by WSYNC since frame started" },
|
||||
{ "_icycles", "Number of cycles of last instruction" },
|
||||
{ "_scan", "Current scanline count" },
|
||||
|
|
|
@ -363,7 +363,7 @@ class Debugger : public DialogContainer
|
|||
string name, help;
|
||||
};
|
||||
static std::array<BuiltinFunction, 18> ourBuiltinFunctions;
|
||||
static std::array<PseudoRegister, 15> ourPseudoRegisters;
|
||||
static std::array<PseudoRegister, 16> ourPseudoRegisters;
|
||||
|
||||
private:
|
||||
// rewind/unwind n states
|
||||
|
|
|
@ -68,6 +68,8 @@ const DebuggerState& RiotDebug::getState()
|
|||
myState.INTIMCLKS = intimClocks();
|
||||
myState.TIMDIV = timDivider();
|
||||
|
||||
myState.timReadCycles = timReadCycles();
|
||||
|
||||
return myState;
|
||||
}
|
||||
|
||||
|
@ -111,6 +113,8 @@ void RiotDebug::saveOldState()
|
|||
myOldState.TIMCLKS = timClocks();
|
||||
myOldState.INTIMCLKS = intimClocks();
|
||||
myOldState.TIMDIV = timDivider();
|
||||
|
||||
myOldState.timReadCycles = timReadCycles();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -247,6 +251,12 @@ int RiotDebug::timWrappedOnWrite() const
|
|||
return mySystem.m6532().myTimWrappedOnWrite;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int RiotDebug::timReadCycles() const
|
||||
{
|
||||
return mySystem.m6532().myTimReadCycles;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool RiotDebug::diffP0(int newVal)
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ class RiotState : public DebuggerState
|
|||
|
||||
uInt8 TIM1T{0}, TIM8T{0}, TIM64T{0}, T1024T{0}, INTIM{0}, TIMINT{0};
|
||||
Int32 TIMCLKS{0}, INTIMCLKS{0}, TIMDIV{0};
|
||||
uInt16 timReadCycles;
|
||||
|
||||
// These are actually from the TIA, but are I/O related
|
||||
uInt8 INPT0{0}, INPT1{0}, INPT2{0}, INPT3{0}, INPT4{0}, INPT5{0};
|
||||
|
@ -83,6 +84,8 @@ class RiotDebug : public DebuggerSystem
|
|||
int timWrappedOnRead() const;
|
||||
int timWrappedOnWrite() const;
|
||||
|
||||
int timReadCycles() const;
|
||||
|
||||
/* Console switches */
|
||||
bool diffP0(int newVal = -1);
|
||||
bool diffP1(int newVal = -1);
|
||||
|
|
|
@ -478,20 +478,21 @@ void DebuggerDialog::addStatusArea()
|
|||
{
|
||||
const int lineHeight = myLFont->getLineHeight();
|
||||
const Common::Rect& r = getStatusBounds();
|
||||
const int HBORDER = 10;
|
||||
const int VGAP = lineHeight / 3;
|
||||
int xpos, ypos;
|
||||
|
||||
xpos = r.x(); ypos = r.y();
|
||||
myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w());
|
||||
xpos = r.x() + HBORDER; ypos = r.y();
|
||||
myTiaInfo = new TiaInfoWidget(this, *myLFont, *myNFont, xpos, ypos, r.w() - HBORDER);
|
||||
|
||||
ypos += myTiaInfo->getHeight() + 8;
|
||||
myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos + 10, ypos,
|
||||
r.w() - 10, r.h() - lineHeight - ypos - 3);
|
||||
ypos = myTiaInfo->getBottom() + VGAP;
|
||||
myTiaZoom = new TiaZoomWidget(this, *myNFont, xpos, ypos,
|
||||
r.w() - HBORDER, r.h() - ypos - VGAP - lineHeight + 3);
|
||||
addToFocusList(myTiaZoom->getFocusList());
|
||||
|
||||
xpos += 10; ypos += myTiaZoom->getHeight() + 6;
|
||||
myMessageBox = new EditTextWidget(this, *myLFont,
|
||||
xpos, ypos, myTiaZoom->getWidth(),
|
||||
myLFont->getLineHeight(), "");
|
||||
ypos = myTiaZoom->getBottom() + VGAP;
|
||||
myMessageBox = new EditTextWidget(this, *myLFont, xpos, ypos,
|
||||
myTiaZoom->getWidth(), lineHeight);
|
||||
myMessageBox->setEditable(false, false);
|
||||
myMessageBox->clearFlags(Widget::FLAG_RETAIN_FOCUS);
|
||||
myMessageBox->setTextColor(kTextColorEm);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Font.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Debugger.hxx"
|
||||
#include "RiotDebug.hxx"
|
||||
#include "TIADebug.hxx"
|
||||
#include "TIA.hxx"
|
||||
#include "Widget.hxx"
|
||||
|
@ -34,55 +35,71 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
: Widget(boss, lfont, x, y, 16, 16),
|
||||
CommandSender(boss)
|
||||
{
|
||||
bool longstr = 11 + 32 * lfont.getMaxCharWidth() + 9
|
||||
+ EditTextWidget::calcWidth(lfont) * 3 <= max_w;
|
||||
const int VGAP = lfont.getLineHeight() / 4;
|
||||
const int VBORDER = 5 + 1;
|
||||
|
||||
x += 11;
|
||||
const int COLUMN_GAP = _fontWidth * 1.25;
|
||||
bool longstr = lfont.getStringWidth("Frame Cycle12345") + _fontWidth * 0.5
|
||||
+ COLUMN_GAP + lfont.getStringWidth("Scanline262262")
|
||||
+ EditTextWidget::calcWidth(lfont) * 3 <= max_w;
|
||||
const int lineHeight = lfont.getLineHeight();
|
||||
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 lwidth = lfont.getStringWidth(longstr ? "Frame Cycle" : "F. Cycle");
|
||||
int lwidth8 = lwidth - lfont.getMaxCharWidth() * 3;
|
||||
int lwidthR = lfont.getStringWidth(longstr ? "Frame Cnt." : "Frame ");
|
||||
int fwidth = EditTextWidget::calcWidth(lfont, 5);
|
||||
int twidth = EditTextWidget::calcWidth(lfont, 8);
|
||||
const int twidth = EditTextWidget::calcWidth(lfont, 8);
|
||||
const int LGAP = (max_w - lwidth - EditTextWidget::calcWidth(lfont, 5)
|
||||
- lwidthR - EditTextWidget::calcWidth(lfont, 5)) / 4;
|
||||
|
||||
lwidth += LGAP;
|
||||
lwidth8 += LGAP;
|
||||
lwidthR += LGAP;
|
||||
|
||||
// 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 + 1, longstr ? "Frame Cycle " : "F. Cycle ");
|
||||
xpos = x;
|
||||
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);
|
||||
|
||||
// Left: WSync Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "WSync Cycl. " : "WSync C. ");
|
||||
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: Timer Cycles
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Timer Cycl." : "Timer C.");
|
||||
myTimerCylces = new EditTextWidget(boss, nfont, xpos + lwidth, ypos - 1, fwidth, lineHeight);
|
||||
myTimerCylces->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);
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Total");
|
||||
myTotalCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
|
||||
myTotalCycles->setEditable(false, true);
|
||||
|
||||
// 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);
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, "Delta");
|
||||
myDeltaCycles = new EditTextWidget(boss, nfont, xpos + lwidth8, ypos - 1, twidth, lineHeight);
|
||||
myDeltaCycles->setEditable(false, true);
|
||||
|
||||
// Right column
|
||||
xpos = myFrameCycles->getRight() + _fontWidth * 1.25; ypos = y + VBORDER;
|
||||
lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ");
|
||||
xpos = x + max_w - lwidthR - EditTextWidget::calcWidth(lfont, 5); ypos = y + VBORDER;
|
||||
//xpos = myDeltaCycles->getRight() + LGAP * 2; ypos = y + VBORDER;
|
||||
|
||||
// Right: Frame Count
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Frame Cnt." : "Frame");
|
||||
myFrameCount = new EditTextWidget(boss, nfont, xpos + lwidthR, ypos - 1, fwidth, lineHeight);
|
||||
myFrameCount->setEditable(false, true);
|
||||
|
||||
lwidth = lfont.getStringWidth(longstr ? "Color Clock " : "Pixel Pos ") + LGAP;
|
||||
fwidth = EditTextWidget::calcWidth(lfont, 3);
|
||||
|
||||
// Right: Scanline
|
||||
ypos += lineHeight + VGAP;
|
||||
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);
|
||||
|
@ -93,25 +110,25 @@ TiaInfoWidget::TiaInfoWidget(GuiObject* boss, const GUI::Font& lfont,
|
|||
|
||||
// Right: Scan Cycle
|
||||
ypos += lineHeight + VGAP;
|
||||
new StaticTextWidget(boss, lfont, xpos, ypos + 1, longstr ? "Scan Cycle " : "Scn Cycle");
|
||||
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 + 1, "Pixel Pos ");
|
||||
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 + 1, longstr ? "Color Clock " : "Color Clk ");
|
||||
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->getRight() - x;
|
||||
_h = myDeltaCycles->getBottom();
|
||||
_h = myColorClocks->getBottom();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -131,6 +148,8 @@ void TiaInfoWidget::loadConfig()
|
|||
Debugger& dbg = instance().debugger();
|
||||
TIADebug& tia = dbg.tiaDebug();
|
||||
const TiaState& oldTia = static_cast<const TiaState&>(tia.getOldState());
|
||||
RiotDebug& riot = dbg.riotDebug();
|
||||
const RiotState& oldRiot = static_cast<const RiotState&>(riot.getOldState());
|
||||
|
||||
myFrameCount->setText(Common::Base::toString(tia.frameCount(), Common::Base::Fmt::_10_5),
|
||||
tia.frameCount() != oldTia.info[0]);
|
||||
|
@ -159,4 +178,7 @@ void TiaInfoWidget::loadConfig()
|
|||
|
||||
myWSyncCylces->setText(Common::Base::toString(tia.frameWsyncCycles(), Common::Base::Fmt::_10_5),
|
||||
tia.frameWsyncCycles() != oldTia.info[7]);
|
||||
|
||||
myTimerCylces->setText(Common::Base::toString(riot.timReadCycles(), Common::Base::Fmt::_10_5),
|
||||
riot.timReadCycles() != oldRiot.timReadCycles);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class TiaInfoWidget : public Widget, public CommandSender
|
|||
EditTextWidget* myTotalCycles{nullptr};
|
||||
EditTextWidget* myDeltaCycles{nullptr};
|
||||
EditTextWidget* myWSyncCylces{nullptr};
|
||||
EditTextWidget* myTimerCylces{nullptr};
|
||||
|
||||
EditTextWidget* myScanlineCount{nullptr};
|
||||
EditTextWidget* myScanlineCountLast{nullptr};
|
||||
|
|
|
@ -226,6 +226,7 @@ uInt8 M6532::peek(uInt16 addr)
|
|||
if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myTimWrappedOnRead = myWrappedThisCycle;
|
||||
myTimReadCycles += 7;
|
||||
#endif
|
||||
return myTimer;
|
||||
}
|
||||
|
@ -236,6 +237,9 @@ uInt8 M6532::peek(uInt16 addr)
|
|||
// PA7 Flag is always cleared after accessing TIMINT
|
||||
uInt8 result = myInterruptFlag;
|
||||
myInterruptFlag &= ~PA7Bit;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myTimReadCycles += 7;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -376,6 +380,9 @@ bool M6532::save(Serializer& out) const
|
|||
out.putBool(myWrappedThisCycle);
|
||||
out.putLong(myLastCycle);
|
||||
out.putLong(mySetTimerCycle);
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
out.putInt(myTimReadCycles);
|
||||
#endif
|
||||
|
||||
out.putByte(myDDRA);
|
||||
out.putByte(myDDRB);
|
||||
|
@ -408,6 +415,9 @@ bool M6532::load(Serializer& in)
|
|||
myWrappedThisCycle = in.getBool();
|
||||
myLastCycle = in.getLong();
|
||||
mySetTimerCycle = in.getLong();
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myTimReadCycles = in.getInt();
|
||||
#endif
|
||||
|
||||
myDDRA = in.getByte();
|
||||
myDDRB = in.getByte();
|
||||
|
|
|
@ -137,6 +137,11 @@ class M6532 : public Device
|
|||
@return The access counters as comma separated string
|
||||
*/
|
||||
string getAccessCounters() const override;
|
||||
|
||||
/**
|
||||
Reset the timer read CPU cycle counter
|
||||
*/
|
||||
void resetTimReadCylces() { myTimReadCycles = 0; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -254,6 +259,8 @@ class M6532 : public Device
|
|||
// Detect timer being accessed on wraparound
|
||||
bool myTimWrappedOnRead{false};
|
||||
bool myTimWrappedOnWrite{false};
|
||||
// Timer read CPU cycles
|
||||
uInt16 myTimReadCycles{0};
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "TIA.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "M6532.hxx"
|
||||
#include "Control.hxx"
|
||||
#include "Paddles.hxx"
|
||||
#include "DelayQueueIteratorImpl.hxx"
|
||||
|
@ -162,8 +163,10 @@ void TIA::initialize()
|
|||
|
||||
myDelayQueue.reset();
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myCyclesAtFrameStart = 0;
|
||||
myFrameWsyncCycles = 0;
|
||||
#endif
|
||||
|
||||
if (myFrameManager)
|
||||
myFrameManager->reset();
|
||||
|
@ -279,8 +282,10 @@ bool TIA::save(Serializer& out) const
|
|||
|
||||
out.putByteArray(myShadowRegisters.data(), myShadowRegisters.size());
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
out.putLong(myCyclesAtFrameStart);
|
||||
out.putLong(myFrameWsyncCycles);
|
||||
#endif
|
||||
|
||||
out.putInt(myFrameBufferScanlines);
|
||||
out.putInt(myFrontBufferScanlines);
|
||||
|
@ -352,8 +357,10 @@ bool TIA::load(Serializer& in)
|
|||
|
||||
in.getByteArray(myShadowRegisters.data(), myShadowRegisters.size());
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myCyclesAtFrameStart = in.getLong();
|
||||
myFrameWsyncCycles = in.getLong();
|
||||
#endif
|
||||
|
||||
myFrameBufferScanlines = in.getInt();
|
||||
myFrontBufferScanlines = in.getInt();
|
||||
|
@ -1307,7 +1314,10 @@ void TIA::updateEmulation()
|
|||
void TIA::onFrameStart()
|
||||
{
|
||||
myXAtRenderingStart = 0;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myFrameWsyncCycles = 0;
|
||||
mySystem->m6532().resetTimReadCylces();
|
||||
#endif
|
||||
|
||||
// Check for colour-loss emulation
|
||||
if (myColorLossEnabled)
|
||||
|
@ -1333,7 +1343,9 @@ void TIA::onFrameStart()
|
|||
void TIA::onFrameComplete()
|
||||
{
|
||||
mySystem->m6502().stop();
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myCyclesAtFrameStart = mySystem->cycles();
|
||||
#endif
|
||||
|
||||
if (myXAtRenderingStart > 0)
|
||||
std::fill_n(myBackBuffer.begin(), myXAtRenderingStart, 0);
|
||||
|
@ -1355,7 +1367,9 @@ void TIA::onHalt()
|
|||
{
|
||||
mySubClock += (TIAConstants::H_CLOCKS - myHctr) % TIAConstants::H_CLOCKS;
|
||||
mySystem->incrementCycles(mySubClock / TIAConstants::CYCLE_CLOCKS);
|
||||
myFrameWsyncCycles += mySubClock / TIAConstants::CYCLE_CLOCKS;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myFrameWsyncCycles += 3 + mySubClock / TIAConstants::CYCLE_CLOCKS;
|
||||
#endif
|
||||
mySubClock %= TIAConstants::CYCLE_CLOCKS;
|
||||
}
|
||||
|
||||
|
|
|
@ -322,6 +322,7 @@ class TIA : public Device
|
|||
*/
|
||||
uInt64 cycles() const { return uInt64(mySystem->cycles()); }
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
/**
|
||||
Answers the frame count from the start of the emulation.
|
||||
*/
|
||||
|
@ -340,6 +341,7 @@ class TIA : public Device
|
|||
uInt32 frameWSyncCycles() const {
|
||||
return uInt32(myFrameWsyncCycles);
|
||||
}
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
/**
|
||||
* Get the CPU cycles since the last dump ports change.
|
||||
|
@ -560,7 +562,7 @@ class TIA : public Device
|
|||
@return The access counters as comma separated string
|
||||
*/
|
||||
string getAccessCounters() const override;
|
||||
#endif
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -941,6 +943,7 @@ class TIA : public Device
|
|||
|
||||
std::array<uInt32, 16> myColorCounts;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
/**
|
||||
* System cycles at the end of the previous frame / beginning of next frame.
|
||||
*/
|
||||
|
@ -950,6 +953,7 @@ class TIA : public Device
|
|||
* System cycles used by WSYNC during current frame.
|
||||
*/
|
||||
uInt64 myFrameWsyncCycles{0};
|
||||
#endif // DEBUGGER_SUPPORT
|
||||
|
||||
/**
|
||||
* The frame manager can change during our lifetime, so we buffer those two.
|
||||
|
|
|
@ -236,6 +236,8 @@ RiotMethod getRiotSpecial(char* ch)
|
|||
return &RiotDebug::timWrappedOnRead;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_timwrapwrite"))
|
||||
return &RiotDebug::timWrappedOnWrite;
|
||||
else if(BSPF::equalsIgnoreCase(ch, "_ftimreadcycles"))
|
||||
return &RiotDebug::timReadCycles;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
|