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