Added some 'Stella-isms' to the new TIA core code, like brace placement,

comment lines above each method, deleting new/d'tors whenever possible, etc.

Rename Missile.cpp to Missile.cxx.
This commit is contained in:
Stephen Anthony 2016-11-22 15:44:20 -03:30
parent 14b701ef72
commit ec2ee2c570
16 changed files with 300 additions and 265 deletions

View File

@ -15,12 +15,13 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id$
//======================================
//============================================================================
#include "DelayQueue.hxx"
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DelayQueue::DelayQueue(uInt8 length, uInt8 size)
: myIndex(0)
{
@ -32,12 +33,13 @@ DelayQueue::DelayQueue(uInt8 length, uInt8 size)
memset(myIndices, 0xFF, 0xFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueue::push(uInt8 address, uInt8 value, uInt8 delay)
{
uInt8 length = myMembers.size();
if (delay >= length)
throw new runtime_error("delay exceeds queue length");
throw runtime_error("delay exceeds queue length");
uInt8 currentIndex = myIndices[address];
@ -50,10 +52,11 @@ void DelayQueue::push(uInt8 address, uInt8 value, uInt8 delay)
myIndices[address] = index;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueue::reset()
{
for (DelayQueueMember& member : myMembers)
member.clear();
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -25,10 +25,9 @@
namespace TIA6502tsCore {
class DelayQueue {
class DelayQueue
{
public:
DelayQueue(uInt8 length, uInt8 size);
public:
@ -48,20 +47,19 @@ class DelayQueue {
uInt8 myIndices[0xFF];
private:
DelayQueue() = delete;
DelayQueue(const DelayQueue&) = delete;
DelayQueue(DelayQueue&&) = delete;
DelayQueue& operator=(const DelayQueue&) = delete;
DelayQueue& operator=(DelayQueue&&) = delete;
};
// ############################################################################
// Implementation
// ############################################################################
template<class T> void DelayQueue::execute(T executor) {
template<class T> void DelayQueue::execute(T executor)
{
DelayQueueMember& currentMember = myMembers.at(myIndex);
for (auto&& entry : currentMember) {
@ -76,4 +74,4 @@ template<class T> void DelayQueue::execute(T executor) {
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_DELAY_QUEUE
#endif // TIA_6502TS_CORE_DELAY_QUEUE

View File

@ -21,11 +21,14 @@
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DelayQueueMember::DelayQueueMember(uInt8 size)
: myEntries(size),
mySize(0)
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueueMember::push(uInt8 address, uInt8 value)
{
Entry& entry = myEntries.at(mySize++);
@ -34,6 +37,7 @@ void DelayQueueMember::push(uInt8 address, uInt8 value)
entry.value = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DelayQueueMember::remove(uInt8 address)
{
size_t index;
@ -48,19 +52,4 @@ void DelayQueueMember::remove(uInt8 address)
}
}
vector<DelayQueueMember::Entry>::const_iterator DelayQueueMember::begin() const
{
return myEntries.begin();
}
vector<DelayQueueMember::Entry>::const_iterator DelayQueueMember::end() const
{
return (mySize < myEntries.size() - 1) ? (myEntries.begin() + mySize) : myEntries.end();
}
void DelayQueueMember::clear()
{
mySize = 0;
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -24,8 +24,8 @@
namespace TIA6502tsCore {
class DelayQueueMember {
class DelayQueueMember
{
public:
struct Entry {
@ -47,11 +47,17 @@ class DelayQueueMember {
void remove(uInt8 address);
vector<Entry>::const_iterator begin() const;
vector<Entry>::const_iterator begin() const {
return myEntries.begin();
}
vector<Entry>::const_iterator end() const;
vector<Entry>::const_iterator end() const {
return (mySize < myEntries.size() - 1) ? (myEntries.begin() + mySize) : myEntries.end();
}
void clear();
void clear() {
mySize = 0;
}
private:
@ -60,7 +66,6 @@ class DelayQueueMember {
size_t mySize;
private:
DelayQueueMember() = delete;
DelayQueueMember(const DelayQueueMember&) = delete;
DelayQueueMember& operator=(const DelayQueueMember&) = delete;
@ -69,4 +74,4 @@ class DelayQueueMember {
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_DELAY_QUEUE_MEMBER
#endif // TIA_6502TS_CORE_DELAY_QUEUE_MEMBER

View File

@ -23,34 +23,30 @@
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* const* DrawCounterDecodes::playerDecodes() const
{
return myPlayerDecodes;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt8* const* DrawCounterDecodes::missileDecodes() const
{
return myMissileDecodes;
}
DrawCounterDecodes DrawCounterDecodes::myInstance;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DrawCounterDecodes& DrawCounterDecodes::DrawCounterDecodes::get()
{
return myInstance;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DrawCounterDecodes::DrawCounterDecodes()
{
myDecodes0 = new uInt8[160];
myDecodes1 = new uInt8[160];
myDecodes2 = new uInt8[160];
myDecodes3 = new uInt8[160];
myDecodes4 = new uInt8[160];
myDecodes6 = new uInt8[160];
myDecodesWide = new uInt8[160];
for (uInt8 *decodes : {myDecodes0, myDecodes1, myDecodes2, myDecodes3, myDecodes4, myDecodes6}) {
for (uInt8 *decodes : {myDecodes0, myDecodes1, myDecodes2, myDecodes3,
myDecodes4, myDecodes6})
{
memset(decodes, 0, 160);
decodes[156] = 1;
}
@ -83,11 +79,7 @@ DrawCounterDecodes::DrawCounterDecodes()
myMissileDecodes[7] = myDecodes0;
}
DrawCounterDecodes::~DrawCounterDecodes()
{
for (uInt8 *decodes : {myDecodes0, myDecodes1, myDecodes2, myDecodes3, myDecodes4, myDecodes6, myDecodesWide}) {
delete[] decodes;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DrawCounterDecodes DrawCounterDecodes::myInstance;
}
} // namespace TIA6502tsCore

View File

@ -24,8 +24,8 @@
namespace TIA6502tsCore {
class DrawCounterDecodes {
class DrawCounterDecodes
{
public:
const uInt8* const* playerDecodes() const;
@ -34,24 +34,22 @@ class DrawCounterDecodes {
static DrawCounterDecodes& get();
~DrawCounterDecodes();
protected:
DrawCounterDecodes();
private:
uInt8 *myPlayerDecodes[8];
uInt8* myPlayerDecodes[8];
uInt8 *myMissileDecodes[8];
uInt8* myMissileDecodes[8];
uInt8 *myDecodes0, *myDecodes1, *myDecodes2, *myDecodes3, *myDecodes4, *myDecodes6, *myDecodesWide;
uInt8 myDecodes0[160], myDecodes1[160], myDecodes2[160], myDecodes3[160],
myDecodes4[160], myDecodes6[160], myDecodesWide[160];
static DrawCounterDecodes myInstance;
private:
DrawCounterDecodes(const DrawCounterDecodes&) = delete;
DrawCounterDecodes(DrawCounterDecodes&&) = delete;
DrawCounterDecodes& operator=(const DrawCounterDecodes&) = delete;

View File

@ -19,18 +19,18 @@
#include "FrameManager.hxx"
enum Metrics : uInt32 {
vblankNTSC = 40,
vblankPAL = 48,
kernelNTSC = 192,
kernelPAL = 228,
overscanNTSC = 30,
overscanPAL = 36,
vsync = 3,
visibleOverscan = 20,
maxUnderscan = 10,
maxFramesWithoutVsync = 50,
tvModeDetectionTolerance = 20
enum Metrics: uInt32 {
vblankNTSC = 40,
vblankPAL = 48,
kernelNTSC = 192,
kernelPAL = 228,
overscanNTSC = 30,
overscanPAL = 36,
vsync = 3,
visibleOverscan = 20,
maxUnderscan = 10,
maxFramesWithoutVsync = 50,
tvModeDetectionTolerance = 20
};
static constexpr uInt32
@ -39,22 +39,25 @@ static constexpr uInt32
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameManager::FrameManager()
: myMode(TvMode::pal)
{
myMode = TvMode::pal;
setTvMode(TvMode::ntsc);
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setHandlers(
FrameManager::callback frameStartCallback,
FrameManager::callback frameCompleteCallback
) {
)
{
myOnFrameStart = frameStartCallback;
myOnFrameComplete = frameCompleteCallback;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::reset()
{
myState = State::waitForVsyncStart;
@ -66,19 +69,20 @@ void FrameManager::reset()
myVblank = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::nextLine()
{
myCurrentFrameTotalLines++;
myLineInState++;
switch (myState) {
switch (myState)
{
case State::waitForVsyncStart:
case State::waitForVsyncEnd:
if (myLinesWithoutVsync > myMaxLinesWithoutVsync) {
myWaitForVsync = false;
setState(State::waitForFrameStart);
}
break;
case State::waitForFrameStart:
@ -90,21 +94,18 @@ void FrameManager::nextLine()
setState(State::frame);
}
}
break;
case State::frame:
if (myLineInState >= myKernelLines + Metrics::visibleOverscan) {
finalizeFrame();
}
break;
case State::overscan:
if (myLineInState >= myOverscanLines - Metrics::visibleOverscan) {
setState(myWaitForVsync ? State::waitForVsyncStart : State::waitForFrameStart);
}
break;
default:
@ -114,23 +115,25 @@ void FrameManager::nextLine()
if (myWaitForVsync) myLinesWithoutVsync++;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setVblank(bool vblank)
{
myVblank = vblank;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setVsync(bool vsync)
{
if (!myWaitForVsync || vsync == myVsync) return;
myVsync = vsync;
switch (myState) {
switch (myState)
{
case State::waitForVsyncStart:
case State::waitForFrameStart:
case State::overscan:
if (myVsync) setState(State::waitForVsyncEnd);
break;
case State::waitForVsyncEnd:
@ -138,12 +141,10 @@ void FrameManager::setVsync(bool vsync)
setState(State::waitForFrameStart);
myLinesWithoutVsync = 0;
}
break;
case State::frame:
if (myVsync) finalizeFrame();
break;
default:
@ -151,45 +152,55 @@ void FrameManager::setVsync(bool vsync)
}
}
bool FrameManager::isRendering() const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameManager::isRendering() const
{
return myState == State::frame;
}
FrameManager::TvMode FrameManager::tvMode() const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameManager::TvMode FrameManager::tvMode() const
{
return myMode;
}
bool FrameManager::vblank() const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameManager::vblank() const
{
return myVblank;
}
uInt32 FrameManager::height() const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::height() const
{
return myKernelLines + Metrics::visibleOverscan;
}
uInt32 FrameManager::currentLine() const {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameManager::currentLine() const
{
return myState == State::frame ? myLineInState : 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setTvMode(FrameManager::TvMode mode)
{
if (mode == myMode) return;
myMode = mode;
switch (myMode) {
switch (myMode)
{
case TvMode::ntsc:
myVblankLines = Metrics::vblankNTSC;
myKernelLines = Metrics::kernelNTSC;
myOverscanLines = Metrics::overscanNTSC;
break;
case TvMode::pal:
myVblankLines = Metrics::vblankPAL;
myKernelLines = Metrics::kernelPAL;
myOverscanLines = Metrics::overscanPAL;
break;
default:
@ -200,6 +211,7 @@ void FrameManager::setTvMode(FrameManager::TvMode mode)
myMaxLinesWithoutVsync = myFrameLines * Metrics::maxFramesWithoutVsync;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::setState(FrameManager::State state)
{
if (myState == state) return;
@ -210,6 +222,7 @@ void FrameManager::setState(FrameManager::State state)
if (myState == State::frame && myOnFrameStart) myOnFrameStart();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameManager::finalizeFrame()
{
const uInt32
@ -228,4 +241,4 @@ void FrameManager::finalizeFrame()
setState(State::overscan);
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -25,15 +25,15 @@
namespace TIA6502tsCore {
class FrameManager {
class FrameManager
{
public:
enum TvMode {
pal, ntsc
};
typedef std::function<void()> callback;
using callback = std::function<void()>;
public:
@ -101,14 +101,12 @@ class FrameManager {
uInt32 myMaxLinesWithoutVsync;
private:
FrameManager(const FrameManager&) = delete;
FrameManager(FrameManager&&) = delete;
FrameManager& operator=(const FrameManager&) = delete;
FrameManager& operator=(FrameManager&&) = delete;
};
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_FRAME_MANAGER
#endif // TIA_6502TS_CORE_FRAME_MANAGER

View File

@ -20,20 +20,20 @@
#include "Missile.hxx"
#include "DrawCounterDecodes.hxx"
enum Count : Int8 {
enum Count: Int8 {
renderCounterOffset = -4
};
namespace TIA6502tsCore {
uInt8 Missile::myWidths[4] = {1, 2, 4, 8};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Missile::Missile(uInt32 collisionMask)
: myCollisionMask(collisionMask)
{
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::reset()
{
myDecodes = DrawCounterDecodes::get().missileDecodes()[0];
@ -49,36 +49,44 @@ void Missile::reset()
myColor = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::enam(uInt8 value)
{
myEnam = (value & 0x02) > 0;
myEnabled = myEnam && (myResmp == 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::hmm(uInt8 value)
{
myHmmClocks = (value >> 4) ^ 0x08;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::resm(bool hblank)
{
myCounter = hblank ? 159 : 157;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::nusiz(uInt8 value)
{
myWidth = myWidths[(value & 0x30) >> 4];
static constexpr uInt8 ourWidths[] = { 1, 2, 4, 8 };
myWidth = ourWidths[(value & 0x30) >> 4];
myDecodes = DrawCounterDecodes::get().missileDecodes()[value & 0x07];
if (myIsRendering && myRenderCounter >= myWidth)
myIsRendering = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::startMovement()
{
myIsMoving = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Missile::movementTick(uInt32 clock, bool apply)
{
if (clock == myHmmClocks) myIsMoving = false;
@ -91,11 +99,13 @@ bool Missile::movementTick(uInt32 clock, bool apply)
return myIsMoving;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::render()
{
collision = (myIsRendering && myRenderCounter >= 0 && myEnabled) ? 0 : myCollisionMask;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::tick()
{
if (myDecodes[myCounter]) {
@ -108,14 +118,16 @@ void Missile::tick()
if (++myCounter >= 160) myCounter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Missile::setColor(uInt8 color)
{
myColor = color;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Missile::getPixel(uInt8 colorIn) const
{
return collision ? colorIn : myColor;
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -24,71 +24,68 @@
namespace TIA6502tsCore {
class Missile {
class Missile
{
public:
Missile(uInt32 collisionMask);
public:
public:
Missile(uInt32 collisionMask);
void reset();
public:
void enam(uInt8 value);
void reset();
void hmm(uInt8 value);
void enam(uInt8 value);
void resm(bool hblank);
void hmm(uInt8 value);
// TODO: resmp
void resm(bool hblank);
void nusiz(uInt8 value);
// TODO: resmp
void startMovement();
void nusiz(uInt8 value);
bool movementTick(uInt32 clock, bool apply);
void startMovement();
void render();
bool movementTick(uInt32 clock, bool apply);
void tick();
void render();
void setColor(uInt8 color);
void tick();
uInt8 getPixel(uInt8 colorIn) const;
void setColor(uInt8 color);
public:
uInt8 getPixel(uInt8 colorIn) const;
uInt32 collision;
public:
private:
uInt32 collision;
uInt32 myCollisionMask;
private:
bool myEnabled;
bool myEnam;
uInt8 myResmp;
uInt32 myCollisionMask;
uInt8 myHmmClocks;
uInt8 myCounter;
bool myIsMoving;
uInt8 myWidth;
bool myEnabled;
bool myEnam;
uInt8 myResmp;
bool myIsRendering;
Int8 myRenderCounter;
uInt8 myHmmClocks;
uInt8 myCounter;
bool myIsMoving;
uInt8 myWidth;
const uInt8* myDecodes;
bool myIsRendering;
Int8 myRenderCounter;
uInt8 myColor;
const uInt8 *myDecodes;
static uInt8 myWidths[4];
uInt8 myColor;
private:
Missile(const Missile&) = delete;
Missile(Missile&&) = delete;
Missile& operator=(const Missile&) = delete;
Missile& operator=(Missile&&) = delete;
};
private:
Missile(const Missile&) = delete;
Missile(Missile&&) = delete;
Missile& operator=(const Missile&) = delete;
Missile& operator=(Missile&&) = delete;
};
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_MISSILE
#endif // TIA_6502TS_CORE_MISSILE

View File

@ -20,18 +20,20 @@
#include "Player.hxx"
#include "DrawCounterDecodes.hxx"
enum Count : Int8 {
enum Count: Int8 {
renderCounterOffset = -5
};
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Player::Player(uInt32 collisionMask)
: myCollisionMask(collisionMask)
{
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::reset()
{
myDecodes = DrawCounterDecodes::get().playerDecodes()[0];
@ -48,6 +50,7 @@ void Player::reset()
myIsDelaying = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::grp(uInt8 pattern)
{
myPatternNew = pattern;
@ -55,23 +58,24 @@ void Player::grp(uInt8 pattern)
if (!myIsDelaying) updatePattern();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::hmp(uInt8 value)
{
myHmmClocks = (value >> 4) ^ 0x8;
myHmmClocks = (value >> 4) ^ 0x08;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::nusiz(uInt8 value)
{
const uInt8 masked = value & 0x07;
const uInt8 oldWidth = myWidth;
if (masked == 5) {
if (masked == 5)
myWidth = 16;
} else if (masked == 7) {
else if (masked == 7)
myWidth = 32;
} else {
else
myWidth = 8;
}
myDecodes = DrawCounterDecodes::get().playerDecodes()[masked];
@ -81,11 +85,13 @@ void Player::nusiz(uInt8 value)
if (oldWidth != myWidth) updatePattern();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::resp(bool hblank)
{
myCounter = hblank ? 159 : 157;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::refp(uInt8 value)
{
const bool oldIsReflected = myIsReflected;
@ -95,6 +101,7 @@ void Player::refp(uInt8 value)
if (myIsReflected != oldIsReflected) updatePattern();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::vdelp(uInt8 value)
{
const bool oldIsDelaying = myIsDelaying;
@ -104,16 +111,19 @@ void Player::vdelp(uInt8 value)
if (myIsDelaying != oldIsDelaying) updatePattern();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::setColor(uInt8 color)
{
myColor = color;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::startMovement()
{
myIsMoving = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Player::movementTick(uInt32 clock, bool apply)
{
if (clock == myHmmClocks) {
@ -128,6 +138,7 @@ bool Player::movementTick(uInt32 clock, bool apply)
return myIsMoving;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::render()
{
collision = (
@ -137,6 +148,7 @@ void Player::render()
) ? 0 : myCollisionMask;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::tick()
{
if (myDecodes[myCounter]) {
@ -149,23 +161,27 @@ void Player::tick()
if (++myCounter >= 160) myCounter = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Player::getPixel(uInt8 colorIn) const
{
return collision ? colorIn : myColor;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::shufflePatterns()
{
const uInt8 oldPatternOld = myPatternOld;
const uInt8 oldPatternOld = myPatternOld;
myPatternOld = myPatternNew;
myPatternOld = myPatternNew;
if (myIsDelaying && oldPatternOld != myPatternOld) updatePattern();
if (myIsDelaying && oldPatternOld != myPatternOld) updatePattern();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Player::getRespClock() const
{
switch (myWidth) {
switch (myWidth)
{
case 8:
return myCounter - 3;
@ -180,27 +196,28 @@ uInt8 Player::getRespClock() const
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Player::updatePattern()
{
const uInt32 pattern = myIsDelaying ? myPatternOld : myPatternNew;
const uInt32 pattern = myIsDelaying ? myPatternOld : myPatternNew;
switch (myWidth) {
case 8:
if (myIsReflected) {
myPattern =
((pattern & 0x01) << 7) |
((pattern & 0x02) << 5) |
((pattern & 0x04) << 3) |
((pattern & 0x08) << 1) |
((pattern & 0x10) >> 1) |
((pattern & 0x20) >> 3) |
((pattern & 0x40) >> 5) |
((pattern & 0x80) >> 7);
} else {
myPattern = pattern;
}
break;
switch (myWidth)
{
case 8:
if (myIsReflected) {
myPattern =
((pattern & 0x01) << 7) |
((pattern & 0x02) << 5) |
((pattern & 0x04) << 3) |
((pattern & 0x08) << 1) |
((pattern & 0x10) >> 1) |
((pattern & 0x20) >> 3) |
((pattern & 0x40) >> 5) |
((pattern & 0x80) >> 7);
} else {
myPattern = pattern;
}
break;
case 16:
if (myIsReflected) {
@ -224,7 +241,6 @@ switch (myWidth) {
((3 * (pattern & 0x40)) << 6) |
((3 * (pattern & 0x80)) << 7);
}
break;
case 32:
@ -240,19 +256,17 @@ switch (myWidth) {
((0xF * (pattern & 0x80)) >> 7);
} else {
myPattern =
((0xF * (pattern & 0x01))) |
((0xF * (pattern & 0x02)) << 3) |
((0xF * (pattern & 0x04)) << 6) |
((0xF * (pattern & 0x08)) << 9) |
((0xF * (pattern & 0x10)) << 12) |
((0xF * (pattern & 0x20)) << 15) |
((0xF * (pattern & 0x40)) << 18) |
((0xF * (pattern & 0x01))) |
((0xF * (pattern & 0x02)) << 3) |
((0xF * (pattern & 0x04)) << 6) |
((0xF * (pattern & 0x08)) << 9) |
((0xF * (pattern & 0x10)) << 12) |
((0xF * (pattern & 0x20)) << 15) |
((0xF * (pattern & 0x40)) << 18) |
((0xF * (pattern & 0x80)) << 21);
}
break;
}
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -24,10 +24,9 @@
namespace TIA6502tsCore {
class Player {
class Player
{
public:
Player(uInt32 collisionMask);
public:
@ -89,19 +88,16 @@ class Player {
uInt8 myPatternNew;
uInt32 myPattern;
bool myIsReflected;
bool myIsDelaying;
private:
Player(const Player&) = delete;
Player(Player&&) = delete;
Player& operator=(const Player&) = delete;
Player& operator=(Player&&) = delete;
};
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_PLAYER
#endif // TIA_6502TS_CORE_PLAYER

View File

@ -21,12 +21,14 @@
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Playfield::Playfield(uInt32 collisionMask)
: myCollisionMask(collisionMask)
{
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::reset()
{
myPattern = 0;
@ -47,11 +49,13 @@ void Playfield::reset()
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::pf0(uInt8 value)
{
myPattern = (myPattern & 0x000FFFF0) | ((value & 0xF0) >> 4);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::pf1(uInt8 value)
{
myPattern = (myPattern & 0x000FF00F)
@ -65,11 +69,13 @@ void Playfield::pf1(uInt8 value)
| ((value & 0x01) << 11);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::pf2(uInt8 value)
{
myPattern = (myPattern & 0x00000FFF) | ((value & 0xFF) << 12);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::ctrlpf(uInt8 value)
{
myReflected = (value & 0x01) > 0;
@ -77,24 +83,28 @@ void Playfield::ctrlpf(uInt8 value)
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::setColor(uInt8 color)
{
myColor = color;
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::setColorP0(uInt8 color)
{
myColorP0 = color;
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::setColorP1(uInt8 color)
{
myColorP1 = color;
applyColors();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::tick(uInt32 x)
{
myX = x;
@ -118,6 +128,7 @@ void Playfield::tick(uInt32 x)
collision = currentPixel ? 0 : myCollisionMask;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Playfield::getPixel(uInt8 colorIn) const
{
if (!collision) return myX < 80 ? myColorLeft : myColorRight;
@ -125,9 +136,11 @@ uInt8 Playfield::getPixel(uInt8 colorIn) const
return colorIn;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Playfield::applyColors()
{
switch (myColorMode) {
switch (myColorMode)
{
case ColorMode::normal:
myColorLeft = myColorRight = myColor;
break;
@ -139,4 +152,4 @@ void Playfield::applyColors()
}
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -24,10 +24,9 @@
namespace TIA6502tsCore {
class Playfield {
class Playfield
{
public:
Playfield(uInt32 collisionMask);
public:
@ -86,7 +85,6 @@ class Playfield {
uInt32 myCollisionMask;
private:
Playfield() = delete;
Playfield(const Playfield&) = delete;
Playfield(Playfield&&) = delete;
@ -96,4 +94,4 @@ class Playfield {
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_PLAYFIELD
#endif // TIA_6502TS_CORE_PLAYFIELD

View File

@ -21,7 +21,7 @@
#include "TIATypes.hxx"
#include "M6502.hxx"
enum CollisionMask : uInt32 {
enum CollisionMask: uInt32 {
player0 = 0b0111110000000000,
player1 = 0b0100001111000000,
missile0 = 0b0010001000111000,
@ -48,6 +48,7 @@ enum DummyRegisters: uInt8 {
namespace TIA6502tsCore {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::TIA(Console& console, Sound& sound, Settings& settings)
: myConsole(console),
mySound(sound),
@ -74,6 +75,7 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::reset()
{
myHblankCtr = 0;
@ -102,6 +104,7 @@ void TIA::reset()
myFrameManager.reset();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::systemCyclesReset()
{
const uInt32 cycles = mySystem->cycles();
@ -110,11 +113,13 @@ void TIA::systemCyclesReset()
mySound.adjustCycleCounter(-cycles);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::install(System& system)
{
installDelegate(system, *this);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::installDelegate(System& system, Device& device)
{
// Remember which system I'm installed in
@ -129,19 +134,21 @@ void TIA::installDelegate(System& system, Device& device)
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::save(Serializer& out) const
{
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::load(Serializer& in)
{
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIA::peek(uInt16 address)
{
updateEmulation();
@ -149,13 +156,15 @@ uInt8 TIA::peek(uInt16 address)
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::poke(uInt16 address, uInt8 value)
{
updateEmulation();
address &= 0x3F;
switch (address) {
switch (address)
{
case WSYNC:
// TODO: Make sure that we understand the +1... :)
mySystem->incrementCycles((227 - myHctr) / 3 + 1);
@ -176,17 +185,14 @@ bool TIA::poke(uInt16 address, uInt8 value)
case AUDC0:
case AUDC1:
mySound.set(address, value, mySystem->cycles());
break;
case HMOVE:
myDelayQueue.push(HMOVE, value, Delay::hmove);
break;
case COLUBK:
myColorBk = value & 0xFE;
break;
case COLUP0:
@ -195,7 +201,6 @@ bool TIA::poke(uInt16 address, uInt8 value)
myPlayfield.setColorP0(value);
myMissile0.setColor(value);
myPlayer0.setColor(value);
break;
case COLUP1:
@ -204,166 +209,145 @@ bool TIA::poke(uInt16 address, uInt8 value)
myPlayfield.setColorP1(value);
myMissile1.setColor(value);
myPlayer1.setColor(value);
break;
case CTRLPF:
myLinesSinceChange = 0;
myPriority = (value & 0x04) ? Priority::inverted : Priority::normal;
myPlayfield.ctrlpf(value);
break;
case COLUPF:
myLinesSinceChange = 0;
myPlayfield.setColor(value & 0xFE);
break;
case PF0:
myDelayQueue.push(PF0, value, Delay::pf);
break;
case PF1:
myDelayQueue.push(PF1, value, Delay::pf);
break;
case PF2:
myDelayQueue.push(PF2, value, Delay::pf);
break;
case ENAM0:
myLinesSinceChange = 0;
myMissile0.enam(value);
break;
case ENAM1:
myLinesSinceChange = 0;
myMissile1.enam(value);
break;
case RESM0:
myLinesSinceChange = 0;
myMissile0.resm(myHstate == HState::blank);
break;
case RESM1:
myLinesSinceChange = 0;
myMissile1.resm(myHstate == HState::blank);
break;
case NUSIZ0:
myLinesSinceChange = 0;
myMissile0.nusiz(value);
myPlayer0.nusiz(value);
break;
case NUSIZ1:
myLinesSinceChange = 0;
myMissile1.nusiz(value);
myPlayer1.nusiz(value);
break;
case HMM0:
myDelayQueue.push(HMM0, value, Delay::hmm);
break;
case HMM1:
myDelayQueue.push(HMM1, value, Delay::hmm);
break;
case HMCLR:
myDelayQueue.push(HMCLR, value, Delay::hmclr);
break;
case GRP0:
myDelayQueue.push(GRP0, value, Delay::grp);
myDelayQueue.push(DummyRegisters::shuffleP1, 0, Delay::shufflePlayer);
break;
case GRP1:
myDelayQueue.push(GRP1, value, Delay::grp);
myDelayQueue.push(DummyRegisters::shuffleP0, 0, Delay::shufflePlayer);
break;
case RESP0:
myLinesSinceChange = 0;
myPlayer0.resp(myHstate == HState::blank);
break;
case RESP1:
myLinesSinceChange = 0;
myPlayer1.resp(myHstate == HState::blank);
break;
case REFP0:
myLinesSinceChange = 0;
myPlayer0.refp(value);
break;
case REFP1:
myLinesSinceChange = 0;
myPlayer1.refp(value);
break;
case VDELP0:
myLinesSinceChange = 0;
myPlayer0.vdelp(value);
break;
case VDELP1:
myLinesSinceChange = 0;
myPlayer1.vdelp(value);
break;
case HMP0:
myDelayQueue.push(HMP0, value, Delay::hmp);
break;
case HMP1:
myDelayQueue.push(HMP1, value, Delay::hmp);
break;
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::frameReset()
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::saveDisplay(Serializer& out) const
{
return true;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::loadDisplay(Serializer& in)
{
return true;
return false;
}
// TODO: stub
@ -377,43 +361,56 @@ uInt8* TIA::currentFrameBuffer() const
return myCurrentFrameBuffer.get();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
uInt8* TIA::previousFrameBuffer() const
{
return myPreviousFrameBuffer.get();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::height() const
{
return myFrameManager.height();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIA::ystart() const
{
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::setHeight(uInt32 height)
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::setYStart(uInt32 ystart)
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::enableAutoFrame(bool enabled)
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::enableColorLoss(bool enabled)
{}
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIA::isPAL() const
{
return myFrameManager.tvMode() == FrameManager::TvMode::pal;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
uInt32 TIA::clocksThisLine() const
{
@ -426,77 +423,92 @@ uInt32 TIA::scanlines() const
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::partialFrame() const
{
return myFrameManager.isRendering();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
uInt32 TIA::startScanline() const
{
return 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::scanlinePos(uInt16& x, uInt16& y) const
{
return 0;
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleBit(TIABit b, uInt8 mode)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleBits()
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleCollision(TIABit b, uInt8 mode)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleCollisions()
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleHMOVEBlank()
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleFixedColors(uInt8 mode)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::driveUnusedPinsRandom(uInt8 mode)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
bool TIA::toggleJitter(uInt8 mode)
{
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// TODO: stub
void TIA::setJitterRecoveryFactor(Int32 f)
{}
{
}
void TIA::updateEmulation() {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::updateEmulation()
{
const uInt32 cycles = mySystem->cycles();
cycle(3 * (cycles - myLastCycle));
@ -504,9 +516,11 @@ void TIA::updateEmulation() {
myLastCycle = cycles;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::cycle(uInt32 colorClocks)
{
for (uInt32 i = 0; i < colorClocks; i++) {
for (uInt32 i = 0; i < colorClocks; i++)
{
myDelayQueue.execute(
[this] (uInt8 address, uInt8 value) {delayedWrite(address, value);}
);
@ -524,6 +538,7 @@ void TIA::cycle(uInt32 colorClocks)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::tickMovement()
{
if (!myMovementInProgress) return;
@ -547,6 +562,7 @@ void TIA::tickMovement()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::tickHblank()
{
if (myIsFreshLine) {
@ -559,6 +575,7 @@ void TIA::tickHblank()
myHctr++;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::tickHframe()
{
const uInt32 y = myFrameManager.currentLine();
@ -579,6 +596,7 @@ void TIA::tickHframe()
if (++myHctr >= 228) nextLine();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::renderSprites()
{
myPlayer0.render();
@ -588,6 +606,7 @@ void TIA::renderSprites()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::tickSprites()
{
myMissile0.tick();
@ -596,6 +615,7 @@ void TIA::tickSprites()
myPlayer1.tick();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::nextLine()
{
myHctr = 0;
@ -608,11 +628,13 @@ void TIA::nextLine()
myFrameManager.nextLine();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::updateCollision()
{
// TODO: update collision mask with sprite masks
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
{
if (lineNotCached) {
@ -638,15 +660,18 @@ void TIA::renderPixel(uInt32 x, uInt32 y, bool lineNotCached)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::clearHmoveComb()
{
if (myFrameManager.isRendering() && myHstate == HState::blank)
memset(myCurrentFrameBuffer.get() + myFrameManager.currentLine() * 160, 0, 8);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::delayedWrite(uInt8 address, uInt8 value)
{
switch (address) {
switch (address)
{
case HMOVE:
myLinesSinceChange = 0;
@ -663,37 +688,31 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
myMissile1.startMovement();
myPlayer0.startMovement();
myPlayer1.startMovement();
break;
case PF0:
myLinesSinceChange = 0;
myPlayfield.pf0(value);
break;
case PF1:
myLinesSinceChange = 0;
myPlayfield.pf1(value);
break;
case PF2:
myLinesSinceChange = 0;
myPlayfield.pf2(value);
break;
case HMM0:
myLinesSinceChange = 0;
myMissile0.hmm(value);
break;
case HMM1:
myLinesSinceChange = 0;
myMissile1.hmm(value);
break;
case HMCLR:
@ -702,45 +721,38 @@ void TIA::delayedWrite(uInt8 address, uInt8 value)
myMissile1.hmm(0);
myPlayer0.hmp(0);
myPlayer1.hmp(0);
break;
case GRP0:
myLinesSinceChange = 0;
myPlayer0.grp(value);
break;
case GRP1:
myLinesSinceChange = 0;
myPlayer1.grp(value);
break;
case DummyRegisters::shuffleP0:
myLinesSinceChange = 0;
myPlayer0.shufflePatterns();
break;
case DummyRegisters::shuffleP1:
myLinesSinceChange = 0;
myPlayer1.shufflePatterns();
break;
case HMP0:
myLinesSinceChange = 0;
myPlayer0.hmp(value);
break;
case HMP1:
myLinesSinceChange = 0;
myPlayer1.hmp(value);
break;
}
}
} // namespace TIA6502tsCore
} // namespace TIA6502tsCore

View File

@ -35,10 +35,9 @@ class Console;
namespace TIA6502tsCore {
class TIA : public AbstractTIA {
class TIA : public AbstractTIA
{
public:
TIA(Console& console, Sound& sound, Settings& settings);
virtual ~TIA() = default;
@ -195,15 +194,13 @@ class TIA : public AbstractTIA {
Player myPlayer1;
private:
TIA() = delete;
TIA(const TIA&) = delete;
TIA(TIA&&) = delete;
TIA& operator=(const TIA&) = delete;
TIA& operator=(TIA&&) = delete;
};
} // namespace TIA6502tsCore
#endif // TIA_6502TS_CORE_TIA
#endif // TIA_6502TS_CORE_TIA