The TIA image in the debugger is now correctly rendered in greyscale

below the current electron beam position.

Fix long-standing bug whereby entering the debugger for the first time
and tracing/scanline advancing, the TIA image was blanked, and didn't
work correctly until you exited and re-entered the debugger.

Minor refactoring optimizations, and renaming of methods.
This commit is contained in:
Stephen Anthony 2017-02-20 19:51:59 -03:30
parent 39f756f821
commit c99cb33cda
8 changed files with 63 additions and 142 deletions

View File

@ -111,7 +111,7 @@ void TiaOutputWidget::handleCommand(CommandSender* sender, int cmd, int data, in
{
ostringstream command;
int lines = myClickY + ystart;
if(instance().console().tia().partialFrame())
if(instance().console().tia().isRendering())
lines -= instance().console().tia().scanlines();
if(lines > 0)
{
@ -156,7 +156,7 @@ void TiaOutputWidget::drawWidget(bool hilite)
// This determines where the frame greying should start, and where a
// scanline 'pointer' should be drawn
uInt16 scanx, scany, scanoffset;
bool visible = instance().console().tia().scanlinePos(scanx, scany);
bool visible = instance().console().tia().electronBeamPos(scanx, scany);
scanoffset = width * scany + scanx;
for(uInt32 y = 0, i = 0; y < height; ++y)
@ -164,7 +164,7 @@ void TiaOutputWidget::drawWidget(bool hilite)
uInt32* line_ptr = myLineBuffer;
for(uInt32 x = 0; x < width; ++x, ++i)
{
uInt8 shift = i > scanoffset ? 1 : 0;
uInt8 shift = i >= scanoffset ? 1 : 0;
uInt32 pixel = instance().frameBuffer().tiaSurface().pixel(i, shift);
*line_ptr++ = pixel;
*line_ptr++ = pixel;

View File

@ -254,7 +254,7 @@ void TiaZoomWidget::drawWidget(bool hilite)
// Get current scanline position
// This determines where the frame greying should start
uInt16 scanx, scany, scanoffset;
instance().console().tia().scanlinePos(scanx, scany);
instance().console().tia().electronBeamPos(scanx, scany);
scanoffset = width * scany + scanx;
int x, y, col, row;

View File

@ -405,8 +405,6 @@ void Console::setProperties(const Properties& props)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FBInitStatus Console::initializeVideo(bool full)
{
setPalette(myOSystem.settings().getString("palette"));
FBInitStatus fbstatus = kSuccess;
if(full)
@ -421,6 +419,7 @@ FBInitStatus Console::initializeVideo(bool full)
myOSystem.frameBuffer().showFrameStats(myOSystem.settings().getBool("stats"));
generateColorLossPalette();
}
setPalette(myOSystem.settings().getString("palette"));
// Set the correct framerate based on the format of the ROM
// This can be overridden by changing the framerate in the

View File

@ -274,7 +274,7 @@ void FrameBuffer::update()
const ConsoleInfo& info = myOSystem.console().about();
char msg[30];
std::snprintf(msg, 30, "%3u @ %3.2ffps => %s",
myOSystem.console().tia().scanlines(),
myOSystem.console().tia().scanlinesLastFrame(),
myOSystem.console().getFramerate(), info.DisplayFormat.c_str());
myStatsMsg.surface->fillRect(0, 0, myStatsMsg.w, myStatsMsg.h, kBGColor);
myStatsMsg.surface->drawString(infoFont(),

View File

@ -230,7 +230,7 @@ void FrameManager::updateAutodetectedTvMode()
updateTvMode(deltaNTSC <= deltaPAL ? TvMode::ntsc : TvMode::pal);
else if (!myModeConfirmed) {
if (
(myCurrentFrameFinalLines < frameLinesPAL) &&
(myCurrentFrameFinalLines < frameLinesPAL) &&
(myCurrentFrameFinalLines > frameLinesNTSC) &&
(myCurrentFrameFinalLines % 2)
)
@ -289,7 +289,8 @@ void FrameManager::setYstart(uInt32 ystart)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::ystart() const {
uInt32 FrameManager::ystart() const
{
return myVblankManager.ystart();
}
@ -329,6 +330,12 @@ uInt32 FrameManager::scanlines() const
return myCurrentFrameTotalLines;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::scanlinesLastFrame() const
{
return myCurrentFrameFinalLines;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setTvMode(TvMode mode)
{

View File

@ -61,13 +61,12 @@ class FrameManager : public Serializable
void setFixedHeight(uInt32 height);
uInt32 getY() const
{
return myY;
}
uInt32 getY() const { return myY; }
uInt32 scanlines() const;
uInt32 scanlinesLastFrame() const;
uInt32 frameCount() const { return myTotalFrames; }
float frameRate() const { return myFrameRate; }

View File

@ -199,12 +199,13 @@ bool TIA::save(Serializer& out) const
// TODO - save instance variables
// Save the state of each graphics object
if(!myPlayfield.save(out)) return false;
if(!myMissile0.save(out)) return false;
if(!myMissile1.save(out)) return false;
if(!myPlayer0.save(out)) return false;
if(!myPlayer1.save(out)) return false;
if(!myBall.save(out)) return false;
if(!myBackground.save(out)) return false;
if(!myPlayfield.save(out)) return false;
if(!myMissile0.save(out)) return false;
if(!myMissile1.save(out)) return false;
if(!myPlayer0.save(out)) return false;
if(!myPlayer1.save(out)) return false;
if(!myBall.save(out)) return false;
// Save the sound sample stuff ...
mySound.save(out);
@ -229,12 +230,13 @@ bool TIA::load(Serializer& in)
// TODO - load instance variables
// Load the state of each graphics object
if(!myPlayfield.load(in)) return false;
if(!myMissile0.load(in)) return false;
if(!myMissile1.load(in)) return false;
if(!myPlayer0.load(in)) return false;
if(!myPlayer1.load(in)) return false;
if(!myBall.load(in)) return false;
if(!myBackground.load(in)) return false;
if(!myPlayfield.load(in)) return false;
if(!myMissile0.load(in)) return false;
if(!myMissile1.load(in)) return false;
if(!myPlayer0.load(in)) return false;
if(!myPlayer1.load(in)) return false;
if(!myBall.load(in)) return false;
}
catch(...)
{
@ -344,6 +346,7 @@ bool TIA::poke(uInt16 address, uInt8 value)
// It appears that the 6507 only halts during a read cycle so
// we test here for follow-on writes which should be ignored as
// far as halting the processor is concerned.
// See issue #42 for more information.
if (mySystem->m6502().lastAccessWasRead())
{
mySubClock += (228 - myHctr) % 228;
@ -614,54 +617,6 @@ void TIA::update()
mySystem->m6502().execute(25000);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::height() const
{
return myFrameManager.height();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::ystart() const
{
return myFrameManager.ystart();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setHeight(uInt32 height)
{
myFrameManager.setFixedHeight(height);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setYStart(uInt32 ystart)
{
myFrameManager.setYstart(ystart);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::autodetectTvMode(bool toggle)
{
myFrameManager.autodetectTvMode(toggle);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::setTvMode(TvMode mode)
{
myFrameManager.setTvMode(mode);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TvMode TIA::tvMode() const
{
return myFrameManager.tvMode();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::enableAutoFrame(bool enabled)
{
myAutoFrameEnabled = enabled;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::enableColorLoss(bool enabled)
@ -669,48 +624,12 @@ void TIA::enableColorLoss(bool enabled)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::clocksThisLine() const
bool TIA::electronBeamPos(uInt16& x, uInt16& y) const
{
return myHctr + myXDelta;
}
x = clocksThisLine();
y = myFrameManager.getY();
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::scanlines() const
{
return myFrameManager.scanlines();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::partialFrame() const
{
return myFrameManager.isRendering();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::scanlinePos(uInt16& x, uInt16& y) const
{
if(partialFrame())
{
// We only care about the scanline position when it's in the viewable area
if(1)//myFramePointerClocks >= myFramePointerOffset)
{
x = clocksThisLine();//(myFramePointerClocks - myFramePointerOffset) % 160;
y = myFrameManager.getY();//(myFramePointerClocks - myFramePointerOffset) / 160;
return true;
}
else
{
x = 0;
y = 0;
return false;
}
}
else
{
x = width();
y = height();
return false;
}
return isRendering();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -850,12 +769,8 @@ void TIA::updateScanline()
{
// Update frame by one scanline at a time
uInt32 line = scanlines();
cerr << "-> " << line << endl;
while (line == scanlines())
{
updateScanlineByStep();
cerr << line << endl;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -151,31 +151,27 @@ class TIA : public Device
/**
Answers the current and previous frame buffer pointers
*/
uInt8* currentFrameBuffer() const {
return myCurrentFrameBuffer.get();
}
uInt8* previousFrameBuffer() const {
return myPreviousFrameBuffer.get();
}
uInt8* currentFrameBuffer() const { return myCurrentFrameBuffer.get(); }
uInt8* previousFrameBuffer() const { return myPreviousFrameBuffer.get(); }
/**
Answers dimensional info about the framebuffer
*/
uInt32 width() const { return 160; }
uInt32 height() const;
uInt32 ystart() const;
uInt32 width() const { return 160; }
uInt32 height() const { return myFrameManager.height(); }
uInt32 ystart() const { return myFrameManager.ystart(); }
/**
Changes the current Height/YStart properties.
Note that calls to these method(s) must be eventually followed by
::frameReset() for the changes to take effect.
*/
void setHeight(uInt32 height);
void setYStart(uInt32 ystart);
void setHeight(uInt32 height) { myFrameManager.setFixedHeight(height); }
void setYStart(uInt32 ystart) { myFrameManager.setYstart(ystart); }
void autodetectTvMode(bool toggle);
void setTvMode(TvMode mode);
TvMode tvMode() const;
void autodetectTvMode(bool toggle) { myFrameManager.autodetectTvMode(toggle); }
void setTvMode(TvMode mode) { myFrameManager.setTvMode(mode); }
TvMode tvMode() const { return myFrameManager.tvMode(); }
/**
Enables/disables auto-frame calculation. If enabled, the TIA
@ -183,7 +179,7 @@ class TIA : public Device
@param enabled Whether to enable or disable all auto-frame calculation
*/
void enableAutoFrame(bool enabled);
void enableAutoFrame(bool enabled) { myAutoFrameEnabled = enabled; }
/**
Enables/disables color-loss for PAL modes only.
@ -197,7 +193,7 @@ class TIA : public Device
@return The current color clock
*/
uInt32 clocksThisLine() const;
uInt32 clocksThisLine() const { return myHctr + myXDelta; }
/**
Answers the total number of scanlines the TIA generated in producing
@ -206,27 +202,32 @@ class TIA : public Device
@return The total number of scanlines generated
*/
uInt32 scanlines() const;
uInt32 scanlines() const { return myFrameManager.scanlines(); }
/**
Answers whether the TIA is currently in 'partial frame' mode
Answers the total number of scanlines the TIA generated in the
previous frame.
@return The total number of scanlines generated in the last frame.
*/
uInt32 scanlinesLastFrame() const { return myFrameManager.scanlinesLastFrame(); }
/**
Answers whether the TIA is currently in being rendered
(we're in between the start and end of drawing a frame).
@return If we're in partial frame mode
@return If the frame is in rendering mode
*/
bool partialFrame() const;
bool isRendering() const { return myFrameManager.isRendering(); }
/**
Answers the current position of the virtual 'electron beam' used to
draw the TIA image. If not in partial frame mode, the position is
defined to be in the lower right corner (@ width/height of the screen).
Note that the coordinates are with respect to currentFrameBuffer(),
taking any YStart values into account.
draw the TIA image.
@return The x/y coordinates of the scanline electron beam, and whether
it is in the visible/viewable area of the screen
*/
bool scanlinePos(uInt16& x, uInt16& y) const;
bool electronBeamPos(uInt16& x, uInt16& y) const;
/**
Enables/disable/toggle the specified (or all) TIA bit(s). Note that