Added rudimentary first pass at advancing the TIA one scanline

at a time.  Of course, it doesn't actually do anything yet.

Logically, the algorithm is very simple (or at least I think it is).
I just have to figure out how to execute the 6502 until a scanline
is done.  In the process, the internal buffers (and hence the
external FrameBuffer) will be filled with data, and we just do
a FrameBuffer::refreshTIA() to 'see' the changes.  The first part
of this is the problem.  Any advice Brian??


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@656 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-07-15 15:27:29 +00:00
parent c271912023
commit dd5fa1d773
9 changed files with 190 additions and 13 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.cxx,v 1.64 2005-07-15 02:59:00 urchlay Exp $ // $Id: Debugger.cxx,v 1.65 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -632,6 +632,15 @@ const string& Debugger::disassemble(int start, int lines) {
return result; return result;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextScanline(int lines) {
saveOldState();
mySystem->unlockDataBus();
myTiaDebug->advanceScanline(lines);
myOSystem->frameBuffer().refreshTIA();
mySystem->lockDataBus();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextFrame(int frames) { void Debugger::nextFrame(int frames) {
saveOldState(); saveOldState();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.hxx,v 1.53 2005-07-15 02:19:07 urchlay Exp $ // $Id: Debugger.hxx,v 1.54 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_HXX #ifndef DEBUGGER_HXX
@ -63,7 +63,7 @@ typedef uInt16 (Debugger::*DEBUGGER_WORD_METHOD)();
for all debugging operations in Stella (parser, 6502 debugger, etc). for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony @author Stephen Anthony
@version $Id: Debugger.hxx,v 1.53 2005-07-15 02:19:07 urchlay Exp $ @version $Id: Debugger.hxx,v 1.54 2005-07-15 15:27:29 stephena Exp $
*/ */
class Debugger : public DialogContainer class Debugger : public DialogContainer
{ {
@ -164,6 +164,7 @@ class Debugger : public DialogContainer
int step(); int step();
int trace(); int trace();
void nextScanline(int lines);
void nextFrame(int frames); void nextFrame(int frames);
string showWatches(); string showWatches();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: TIADebug.cxx,v 1.11 2005-07-14 18:28:35 stephena Exp $ // $Id: TIADebug.cxx,v 1.12 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#include "System.hxx" #include "System.hxx"
@ -67,6 +67,12 @@ void TIADebug::saveOldState()
myOldState.coluRegs.push_back(coluBK()); myOldState.coluRegs.push_back(coluBK());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIADebug::advanceScanline(int lines)
{
myTIA->advanceFrameScanline(lines);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::coluP0(int newVal) uInt8 TIADebug::coluP0(int newVal)
{ {

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: TIADebug.hxx,v 1.7 2005-07-14 18:28:35 stephena Exp $ // $Id: TIADebug.hxx,v 1.8 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#ifndef TIA_DEBUG_HXX #ifndef TIA_DEBUG_HXX
@ -42,6 +42,8 @@ class TIADebug : public DebuggerSystem
void saveOldState(); void saveOldState();
void advanceScanline(int lines);
// FIXME - add whole slew of setXXX() methods // FIXME - add whole slew of setXXX() methods
uInt8 coluP0(int newVal = -1); uInt8 coluP0(int newVal = -1);
uInt8 coluP1(int newVal = -1); uInt8 coluP1(int newVal = -1);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBuffer.hxx,v 1.45 2005-07-03 00:53:59 stephena Exp $ // $Id: FrameBuffer.hxx,v 1.46 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_HXX #ifndef FRAMEBUFFER_HXX
@ -52,7 +52,7 @@ enum FrameStyle {
All GUI elements (ala ScummVM) are drawn here as well. All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.45 2005-07-03 00:53:59 stephena Exp $ @version $Id: FrameBuffer.hxx,v 1.46 2005-07-15 15:27:29 stephena Exp $
*/ */
class FrameBuffer class FrameBuffer
{ {
@ -146,7 +146,7 @@ class FrameBuffer
void refreshOverlay(bool now = false); void refreshOverlay(bool now = false);
/** /**
Indicates that the emulation should advance one frame. Indicates that the emulation should advance given number of frames.
*/ */
void advance(int frames); void advance(int frames);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: TIA.cxx,v 1.46 2005-07-03 06:49:39 urchlay Exp $ // $Id: TIA.cxx,v 1.47 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#include <cassert> #include <cassert>
@ -1808,6 +1808,145 @@ inline void TIA::waitHorizontalSync()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::advanceFrameScanline(int lines)
{
// Ignore # of lines for now
cerr << "TIA::advanceFrameScanline\n";
Int32 clock = mySystem->cycles() * 3;
// See if we're in the nondisplayable portion of the screen or if
// we've already updated this portion of the screen
if((clock < myClockStartDisplay) ||
(myClockAtLastUpdate >= myClockStopDisplay) ||
(myClockAtLastUpdate >= clock))
{
return;
}
// Truncate the number of cycles to update to the stop display point
if(clock > myClockStopDisplay)
{
clock = myClockStopDisplay;
}
// Update frame one scanline at a time
// do
{
// Compute the number of clocks we're going to update
Int32 clocksToUpdate = 0;
// Remember how many clocks we are from the left side of the screen
Int32 clocksFromStartOfScanLine = 228 - myClocksToEndOfScanLine;
// See if we're updating more than the current scanline
if(clock > (myClockAtLastUpdate + myClocksToEndOfScanLine))
{
// Yes, we have more than one scanline to update so finish current one
clocksToUpdate = myClocksToEndOfScanLine;
myClocksToEndOfScanLine = 228;
myClockAtLastUpdate += clocksToUpdate;
}
else
{
// No, so do as much of the current scanline as possible
clocksToUpdate = clock - myClockAtLastUpdate;
myClocksToEndOfScanLine -= clocksToUpdate;
myClockAtLastUpdate = clock;
}
Int32 startOfScanLine = HBLANK + myFrameXStart;
// Skip over as many horizontal blank clocks as we can
if(clocksFromStartOfScanLine < startOfScanLine)
{
uInt32 tmp;
if((startOfScanLine - clocksFromStartOfScanLine) < clocksToUpdate)
tmp = startOfScanLine - clocksFromStartOfScanLine;
else
tmp = clocksToUpdate;
clocksFromStartOfScanLine += tmp;
clocksToUpdate -= tmp;
}
// Remember frame pointer in case HMOVE blanks need to be handled
uInt8* oldFramePointer = myFramePointer;
// Update as much of the scanline as we can
if(clocksToUpdate != 0)
{
updateFrameScanline(clocksToUpdate, clocksFromStartOfScanLine - HBLANK);
}
// Handle HMOVE blanks if they are enabled
if(myHMOVEBlankEnabled && (startOfScanLine < HBLANK + 8) &&
(clocksFromStartOfScanLine < (HBLANK + 8)))
{
Int32 blanks = (HBLANK + 8) - clocksFromStartOfScanLine;
memset(oldFramePointer, 0, blanks);
if((clocksToUpdate + clocksFromStartOfScanLine) >= (HBLANK + 8))
{
myHMOVEBlankEnabled = false;
}
}
// See if we're at the end of a scanline
if(myClocksToEndOfScanLine == 228)
{
myFramePointer -= (160 - myFrameWidth - myFrameXStart);
// Yes, so set PF mask based on current CTRLPF reflection state
myCurrentPFMask = ourPlayfieldTable[myCTRLPF & 0x01];
// TODO: These should be reset right after the first copy of the player
// has passed. However, for now we'll just reset at the end of the
// scanline since the other way would be to slow (01/21/99).
myCurrentP0Mask = &ourPlayerMaskTable[myPOSP0 & 0x03]
[0][myNUSIZ0 & 0x07][160 - (myPOSP0 & 0xFC)];
myCurrentP1Mask = &ourPlayerMaskTable[myPOSP1 & 0x03]
[0][myNUSIZ1 & 0x07][160 - (myPOSP1 & 0xFC)];
// Handle the "Cosmic Ark" TIA bug if it's enabled
if(myM0CosmicArkMotionEnabled)
{
// Movement table associated with the bug
static uInt32 m[4] = {18, 33, 0, 17};
myM0CosmicArkCounter = (myM0CosmicArkCounter + 1) & 3;
myPOSM0 -= m[myM0CosmicArkCounter];
if(myPOSM0 >= 160)
myPOSM0 -= 160;
else if(myPOSM0 < 0)
myPOSM0 += 160;
if(myM0CosmicArkCounter == 1)
{
// Stretch this missle so it's at least 2 pixels wide
myCurrentM0Mask = &ourMissleMaskTable[myPOSM0 & 0x03]
[myNUSIZ0 & 0x07][((myNUSIZ0 & 0x30) >> 4) | 0x01]
[160 - (myPOSM0 & 0xFC)];
}
else if(myM0CosmicArkCounter == 2)
{
// Missle is disabled on this line
myCurrentM0Mask = &ourDisabledMaskTable[0];
}
else
{
myCurrentM0Mask = &ourMissleMaskTable[myPOSM0 & 0x03]
[myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFC)];
}
}
}
}
// while(myClockAtLastUpdate < clock);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIA::peek(uInt16 addr) uInt8 TIA::peek(uInt16 addr)
{ {

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: TIA.hxx,v 1.24 2005-07-03 06:49:40 urchlay Exp $ // $Id: TIA.hxx,v 1.25 2005-07-15 15:27:29 stephena Exp $
//============================================================================ //============================================================================
#ifndef TIA_HXX #ifndef TIA_HXX
@ -42,7 +42,7 @@ class Settings;
be displayed on screen. be displayed on screen.
@author Bradford W. Mott @author Bradford W. Mott
@version $Id: TIA.hxx,v 1.24 2005-07-03 06:49:40 urchlay Exp $ @version $Id: TIA.hxx,v 1.25 2005-07-15 15:27:29 stephena Exp $
*/ */
class TIA : public Device , public MediaSource class TIA : public Device , public MediaSource
{ {
@ -239,6 +239,9 @@ class TIA : public Device , public MediaSource
// Waste cycles until the current scanline is finished // Waste cycles until the current scanline is finished
void waitHorizontalSync(); void waitHorizontalSync();
// Draw the specified number of scanlines (for debugger use only)
void advanceFrameScanline(int lines);
private: private:
// Console the TIA is associated with // Console the TIA is associated with
const Console& myConsole; const Console& myConsole;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerDialog.cxx,v 1.23 2005-07-08 17:22:41 stephena Exp $ // $Id: DebuggerDialog.cxx,v 1.24 2005-07-15 15:27:29 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -35,6 +35,7 @@ enum {
kDDStepCmd = 'DDst', kDDStepCmd = 'DDst',
kDDTraceCmd = 'DDtr', kDDTraceCmd = 'DDtr',
kDDAdvCmd = 'DDav', kDDAdvCmd = 'DDav',
kDDSAdvCmd = 'DDsv',
kDDExitCmd = 'DDex' kDDExitCmd = 'DDex'
}; };
@ -94,6 +95,8 @@ DebuggerDialog::DebuggerDialog(OSystem* osystem, DialogContainer* parent,
yoff += 22; yoff += 22;
addButton(vWidth + 10, yoff, "Trace", kDDTraceCmd, 0); addButton(vWidth + 10, yoff, "Trace", kDDTraceCmd, 0);
yoff += 22; yoff += 22;
addButton(vWidth + 10, yoff, "Scanline +1", kDDSAdvCmd, 0);
yoff += 22;
addButton(vWidth + 10, yoff, "Frame +1", kDDAdvCmd, 0); addButton(vWidth + 10, yoff, "Frame +1", kDDAdvCmd, 0);
addButton(vWidth + 10, _h - 22 - 10, "Exit", kDDExitCmd, 0); addButton(vWidth + 10, _h - 22 - 10, "Exit", kDDExitCmd, 0);
@ -122,6 +125,8 @@ void DebuggerDialog::handleKeyDown(int ascii, int keycode, int modifiers)
doTrace(); doTrace();
else if(ascii == 'f') else if(ascii == 'f')
doAdvance(); doAdvance();
else if(ascii == 'l')
doScanlineAdvance();
} }
else else
myTab->handleKeyDown(ascii, keycode, modifiers); myTab->handleKeyDown(ascii, keycode, modifiers);
@ -147,6 +152,10 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd,
doAdvance(); doAdvance();
break; break;
case kDDSAdvCmd:
doScanlineAdvance();
break;
case kDDExitCmd: case kDDExitCmd:
doExit(); doExit();
break; break;
@ -177,6 +186,13 @@ void DebuggerDialog::doAdvance()
myTab->loadConfig(); myTab->loadConfig();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::doScanlineAdvance()
{
instance()->debugger().nextScanline(1);
myTab->loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::doExit() void DebuggerDialog::doExit()
{ {

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerDialog.hxx,v 1.11 2005-07-05 15:25:44 stephena Exp $ // $Id: DebuggerDialog.hxx,v 1.12 2005-07-15 15:27:29 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -48,6 +48,7 @@ class DebuggerDialog : public Dialog
private: private:
void doStep(); void doStep();
void doTrace(); void doTrace();
void doScanlineAdvance();
void doAdvance(); void doAdvance();
void doExit(); void doExit();
}; };