diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 30d484a93..a5372e281 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -543,7 +543,6 @@ void Console::changeHeight(int direction) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AbstractTIA* Console::createTIA() { string coreType = "default"; @@ -568,6 +567,7 @@ AbstractTIA* Console::createTIA() throw new runtime_error(buffer.str()); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Console::setTIAProperties() { // TODO - query these values directly from the TIA if value is 'AUTO' diff --git a/src/emucore/tia/core_6502ts/FrameManager.cxx b/src/emucore/tia/core_6502ts/FrameManager.cxx index 669619d27..75607cebe 100644 --- a/src/emucore/tia/core_6502ts/FrameManager.cxx +++ b/src/emucore/tia/core_6502ts/FrameManager.cxx @@ -61,7 +61,7 @@ void FrameManager::setHandlers( void FrameManager::reset() { myState = State::waitForVsyncStart; - myCurrentFrameTotalLines = 0; + myCurrentFrameTotalLines = myCurrentFrameFinalLines = 0; myLineInState = 0; myLinesWithoutVsync = 0; myWaitForVsync = true; @@ -182,6 +182,12 @@ uInt32 FrameManager::currentLine() const return myState == State::frame ? myLineInState : 0; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 FrameManager::scanlines() const +{ + return myState == State::frame ? myLineInState : myCurrentFrameFinalLines; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FrameManager::setTvMode(TvMode mode) { @@ -237,6 +243,7 @@ void FrameManager::finalizeFrame() myOnFrameComplete(); } + myCurrentFrameFinalLines = myCurrentFrameTotalLines; myCurrentFrameTotalLines = 0; setState(State::overscan); } diff --git a/src/emucore/tia/core_6502ts/FrameManager.hxx b/src/emucore/tia/core_6502ts/FrameManager.hxx index 0aa96d2f0..a784531ed 100644 --- a/src/emucore/tia/core_6502ts/FrameManager.hxx +++ b/src/emucore/tia/core_6502ts/FrameManager.hxx @@ -59,6 +59,8 @@ class FrameManager : public Serializable uInt32 currentLine() const; + uInt32 scanlines() const; + /** Serializable methods (see that class for more information). */ @@ -95,6 +97,7 @@ class FrameManager : public Serializable uInt32 myLineInState; uInt32 myLinesWithoutVsync; uInt32 myCurrentFrameTotalLines; + uInt32 myCurrentFrameFinalLines; bool myVsync; bool myVblank; diff --git a/src/emucore/tia/core_6502ts/PaddleReader.cxx b/src/emucore/tia/core_6502ts/PaddleReader.cxx index f9453bcf1..8ec60e91c 100644 --- a/src/emucore/tia/core_6502ts/PaddleReader.cxx +++ b/src/emucore/tia/core_6502ts/PaddleReader.cxx @@ -100,10 +100,10 @@ void PaddleReader::update(double value, double timestamp, TvMode tvMode) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PaddleReader::setTvMode(TvMode mode) { - myTvMode = mode; + myTvMode = mode; - myClockFreq = myTvMode == TvMode::ntsc ? 60 * 228 * 262 : 50 * 228 * 312; - myUThresh = USUPP * (1. - exp(-TRIPPOINT_LINES * 228 / myClockFreq / (RPOT + R0) / C)); + myClockFreq = myTvMode == TvMode::ntsc ? 60 * 228 * 262 : 50 * 228 * 312; + myUThresh = USUPP * (1. - exp(-TRIPPOINT_LINES * 228 / myClockFreq / (RPOT + R0) / C)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -117,4 +117,4 @@ void PaddleReader::updateCharge(double timestamp) myTimestamp = timestamp; } -} // namespace TIA6502tsCore \ No newline at end of file +} // namespace TIA6502tsCore diff --git a/src/emucore/tia/core_6502ts/TIA.cxx b/src/emucore/tia/core_6502ts/TIA.cxx index 14e88d715..951721cba 100644 --- a/src/emucore/tia/core_6502ts/TIA.cxx +++ b/src/emucore/tia/core_6502ts/TIA.cxx @@ -24,12 +24,12 @@ #include "Types.hxx" enum CollisionMask: uInt32 { - player0 = 0b0111110000000000, - player1 = 0b0100001111000000, - missile0 = 0b0010001000111000, - missile1 = 0b0001000100100110, - ball = 0b0000100010010101, - playfield = 0b0000010001001011 + player0 = 0b0111110000000000, + player1 = 0b0100001111000000, + missile0 = 0b0010001000111000, + missile1 = 0b0001000100100110, + ball = 0b0000100010010101, + playfield = 0b0000010001001011 }; enum Delay: uInt8 { @@ -119,6 +119,16 @@ void TIA::reset() mySound.reset(); myDelayQueue.reset(); myFrameManager.reset(); + frameReset(); // Recalculate the size of the display +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::frameReset() +{ + // Clear frame buffers + clearBuffers(); + + // TODO - make use of ystart and height } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -151,6 +161,13 @@ void TIA::installDelegate(System& system, Device& device) mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void TIA::clearBuffers() +{ + memset(myCurrentFrameBuffer.get(), 0, 160 * 320); + memset(myPreviousFrameBuffer.get(), 0, 160 * 320); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool TIA::save(Serializer& out) const { @@ -531,12 +548,6 @@ bool TIA::poke(uInt16 address, uInt8 value) return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub -void TIA::frameReset() -{ -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // TODO: stub bool TIA::saveDisplay(Serializer& out) const @@ -558,26 +569,14 @@ void TIA::update() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: add yoffset -uInt8* TIA::currentFrameBuffer() const -{ - return myCurrentFrameBuffer.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: add yoffset -uInt8* TIA::previousFrameBuffer() const -{ - return myPreviousFrameBuffer.get(); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: stub uInt32 TIA::height() const { - return myFrameManager.height(); + return 0; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TODO: stub uInt32 TIA::ystart() const { return 0; @@ -621,14 +620,12 @@ uInt32 TIA::clocksThisLine() const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub uInt32 TIA::scanlines() const { - return 0; + return myFrameManager.scanlines(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// TODO: stub bool TIA::partialFrame() const { return myFrameManager.isRendering(); @@ -858,9 +855,11 @@ void TIA::tickHframe() tickSprites(); - if (myFrameManager.isRendering()) renderPixel(x, y, lineNotCached); + if (myFrameManager.isRendering()) + renderPixel(x, y, lineNotCached); - if (++myHctr >= 228) nextLine(); + if (++myHctr >= 228) + nextLine(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/tia/core_6502ts/TIA.hxx b/src/emucore/tia/core_6502ts/TIA.hxx index b7f0014bd..7269ab68c 100644 --- a/src/emucore/tia/core_6502ts/TIA.hxx +++ b/src/emucore/tia/core_6502ts/TIA.hxx @@ -38,9 +38,30 @@ class Console; namespace TIA6502tsCore { +/** + This class is a device that emulates the Television Interface Adaptor + found in the Atari 2600 and 7800 consoles. The Television Interface + Adaptor is an integrated circuit designed to interface between an + eight bit microprocessor and a television video modulator. It converts + eight bit parallel data into serial outputs for the color, luminosity, + and composite sync required by a video modulator. + + This class outputs the serial data into a frame buffer which can then + be displayed on screen. + + @author Christian Speckner (DirtyHairy) and Stephen Anthony + @version $Id$ +*/ class TIA : public AbstractTIA { public: + /** + Create a new TIA for the specified console + + @param console The console the TIA is associated with + @param sound The sound object the TIA is associated with + @param settings The settings object for this TIA device + */ TIA(Console& console, Sound& sound, Settings& settings); virtual ~TIA() = default; @@ -48,6 +69,11 @@ class TIA : public AbstractTIA void reset() override; + /** + Reset frame to current YStart/Height properties + */ + void frameReset() override; + void systemCyclesReset() override; void install(System& system) override; @@ -58,17 +84,21 @@ class TIA : public AbstractTIA void installDelegate(System& system, Device& device) override; - void frameReset() override; - bool saveDisplay(Serializer& out) const override; bool loadDisplay(Serializer& in) override; void update() override; - uInt8* currentFrameBuffer() const override; - - uInt8* previousFrameBuffer() const override; + /** + Answers the current and previous frame buffer pointers + */ + uInt8* currentFrameBuffer() const override { + return myCurrentFrameBuffer.get(); + } + uInt8* previousFrameBuffer() const override { + return myPreviousFrameBuffer.get(); + } /** Answers vertical info about the framebuffer (height and starting line) @@ -118,6 +148,9 @@ class TIA : public AbstractTIA void setJitterRecoveryFactor(Int32 f) override; + // Clear both internal TIA buffers to black (palette color 0) + void clearBuffers(); + /** Save the current state of this device to the given Serializer. @@ -142,9 +175,7 @@ class TIA : public AbstractTIA string name() const override { return "TIA"; } private: - enum HState {blank, frame}; - enum Priority {pfp, score, normal}; private: @@ -217,6 +248,7 @@ class TIA : public AbstractTIA double myTimestamp; + // Pointer to the current and previous frame buffers BytePtr myCurrentFrameBuffer; BytePtr myPreviousFrameBuffer;