diff --git a/.vscode/settings.json b/.vscode/settings.json index 826b7d7b7..917818c91 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,7 @@ "-I/home/cnspeckn/git/stella/src/emucore/tia/6502ts_core" ], "editor.tabSize": 2, - "files.trimTrailingWhitespace": false, + "files.trimTrailingWhitespace": true, "files.exclude": { "**/.git": true, "**/.svn": true, diff --git a/src/emucore/tia/core_6502ts/DelayQueue.cxx b/src/emucore/tia/core_6502ts/DelayQueue.cxx new file mode 100644 index 000000000..52c16556d --- /dev/null +++ b/src/emucore/tia/core_6502ts/DelayQueue.cxx @@ -0,0 +1,67 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +//====================================== + +#include "DelayQueue.hxx" + +namespace TIA6502tsCore { + + DelayQueue::DelayQueue(uInt8 length, uInt8 size) + : myIndex(0) + { + myMembers.reserve(length); + + for (uInt16 i = 0; i < length; i++) + myMembers.emplace_back(size); + + for (uInt8& i : myIndices) + i = 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"); + + uInt8 currentIndex = myIndices[address]; + + if (currentIndex < 0xFF) + myMembers.at(currentIndex).remove(address); + + uInt8 index = (myIndex + delay) % length; + myMembers.at(index).push(address, value); + + myIndices[address] = index; + } + + void DelayQueue::execute(Executor& executor) { + DelayQueueMember& currentMember = myMembers.at(myIndex); + + for (auto&& entry : currentMember) { + executor(entry.address, entry.value); + myIndices[entry.address] = 0xFF; + } + + currentMember.clear(); + + myIndex = (myIndex + 1) & myMembers.size(); + } + +} // namespace TIA6502tsCore \ No newline at end of file diff --git a/src/emucore/tia/core_6502ts/DelayQueue.hxx b/src/emucore/tia/core_6502ts/DelayQueue.hxx new file mode 100644 index 000000000..ba78827dd --- /dev/null +++ b/src/emucore/tia/core_6502ts/DelayQueue.hxx @@ -0,0 +1,72 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +//============================================================================ + +#ifndef TIA_6502TS_CORE_DELAY_QUEUE +#define TIA_6502TS_CORE_DELAY_QUEUE + +#include "bspf.hxx" +#include "DelayQueueMember.hxx" + +namespace TIA6502tsCore { + +class DelayQueue { + + public: + + class Executor { + + public: + + virtual void operator()(uInt8 address, uInt8 value) = 0; + + virtual ~Executor() = default; + + }; + + public: + + DelayQueue(uInt8 length, uInt8 size); + + public: + + void push(uInt8 address, uInt8 value, uInt8 delay); + + void execute(Executor& executor); + + private: + + vector myMembers; + + uInt8 myIndex; + + uInt8 myIndices[0xFF]; + + private: + + DelayQueue() = delete; + DelayQueue(const DelayQueue&) = delete; + DelayQueue(DelayQueue&&) = delete; + DelayQueue& operator=(const DelayQueue&) = delete; + DelayQueue& operator=(DelayQueue&&) = delete; + +}; + +} // namespace TIA6502tsCore + +#endif // TIA_6502TS_CORE_DELAY_QUEUE \ No newline at end of file diff --git a/src/emucore/tia/core_6502ts/DelayQueueMember.cxx b/src/emucore/tia/core_6502ts/DelayQueueMember.cxx new file mode 100644 index 000000000..aa78eef48 --- /dev/null +++ b/src/emucore/tia/core_6502ts/DelayQueueMember.cxx @@ -0,0 +1,66 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +//============================================================================ + +#include "DelayQueueMember.hxx" + +namespace TIA6502tsCore { + + DelayQueueMember::DelayQueueMember(uInt8 capacity) + : myEntries(capacity), + mySize(0) + {} + + void DelayQueueMember::push(uInt8 address, uInt8 value) + { + Entry& entry = myEntries.at(mySize++); + + entry.address = address; + entry.value = value; + } + + void DelayQueueMember::remove(uInt8 address) + { + size_t index; + + for (index = 0; index < mySize; index++) { + if (myEntries.at(index).address == address) break; + } + + if (index < mySize) { + myEntries.at(index) = myEntries.at(mySize - 1); + mySize--; + } + } + + vector::const_iterator DelayQueueMember::begin() const + { + return myEntries.begin(); + } + + vector::const_iterator DelayQueueMember::end() const + { + return myEntries.end(); + } + + void DelayQueueMember::clear() + { + mySize = 0; + } + +} // namespace TIA6502tsCore \ No newline at end of file diff --git a/src/emucore/tia/core_6502ts/DelayQueueMember.hxx b/src/emucore/tia/core_6502ts/DelayQueueMember.hxx new file mode 100644 index 000000000..68d6f3fc2 --- /dev/null +++ b/src/emucore/tia/core_6502ts/DelayQueueMember.hxx @@ -0,0 +1,72 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2016 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id$ +//============================================================================ + +#ifndef TIA_6502TS_CORE_DELAY_QUEUE_MEMBER +#define TIA_6502TS_CORE_DELAY_QUEUE_MEMBER + +#include "bspf.hxx" + +namespace TIA6502tsCore { + +class DelayQueueMember { + + public: + + struct Entry { + uInt8 address; + uInt8 value; + }; + + public: + + DelayQueueMember(uInt8 capacity); + + DelayQueueMember(DelayQueueMember&&) = default; + + DelayQueueMember& operator=(DelayQueueMember&&) = default; + + public: + + void push(uInt8 address, uInt8 value); + + void remove(uInt8 address); + + vector::const_iterator begin() const; + + vector::const_iterator end() const; + + void clear(); + + private: + + vector myEntries; + + size_t mySize; + + private: + + DelayQueueMember() = delete; + DelayQueueMember(const DelayQueueMember&) = delete; + DelayQueueMember& operator=(const DelayQueueMember&) = delete; + +}; + +} // namespace TIA6502tsCore + +#endif // TIA_6502TS_CORE_DELAY_QUEUE_MEMBER \ No newline at end of file diff --git a/src/emucore/tia/core_6502ts/TIA.cxx b/src/emucore/tia/core_6502ts/TIA.cxx index 2578ca7fd..4ecdd330f 100644 --- a/src/emucore/tia/core_6502ts/TIA.cxx +++ b/src/emucore/tia/core_6502ts/TIA.cxx @@ -1,8 +1,8 @@ //============================================================================ // -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa // SSSS tt ee ee ll ll aa // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" // SS SS tt ee ll ll aa aa @@ -26,8 +26,29 @@ namespace TIA6502tsCore { TIA::TIA(Console& console, Sound& sound, Settings& settings) : myConsole(console), mySound(sound), - mySettings(settings) - {} + mySettings(settings), + myDelayQueue(10, 20) + { + class DelayedWriteExecutor : public DelayQueue::Executor { + + public: + + DelayedWriteExecutor(TIA& tia) : myTia(tia) + {} + + void operator()(uInt8 address, uInt8 value) override + { + myTia.delayedWrite(address, value); + } + + private: + + TIA& myTia; + + }; + + myDelayQueueExecutor.reset(new DelayedWriteExecutor(*this)); + } // TODO: stub void TIA::reset() @@ -63,7 +84,7 @@ namespace TIA6502tsCore { bool TIA::poke(uInt16 address, uInt8 value) { return false; - } + } // TODO: stub void TIA::installDelegate(System& system, Device& device) @@ -217,4 +238,8 @@ namespace TIA6502tsCore { void TIA::setJitterRecoveryFactor(Int32 f) {} + // TODO: stub + void TIA::delayedWrite(uInt8 address, uInt8 value) + {} + } // namespace TIA6502tsCore \ No newline at end of file diff --git a/src/emucore/tia/core_6502ts/TIA.hxx b/src/emucore/tia/core_6502ts/TIA.hxx index ffa536ce5..a1ddba8a3 100644 --- a/src/emucore/tia/core_6502ts/TIA.hxx +++ b/src/emucore/tia/core_6502ts/TIA.hxx @@ -1,8 +1,8 @@ //============================================================================ // -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa // SSSS tt ee ee ll ll aa // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" // SS SS tt ee ll ll aa aa @@ -25,6 +25,7 @@ #include "Sound.hxx" #include "Settings.hxx" #include "TIATypes.hxx" +#include "DelayQueue.hxx" class Console; @@ -56,7 +57,7 @@ class TIA : public AbstractTIA { uInt8 peek(uInt16 address) override; - bool poke(uInt16 address, uInt8 value) override; + bool poke(uInt16 address, uInt8 value) override; void installDelegate(System& system, Device& device) override; @@ -114,6 +115,10 @@ class TIA : public AbstractTIA { void setJitterRecoveryFactor(Int32 f) override; + private: + + void delayedWrite(uInt8 address, uInt8 value); + private: Console& myConsole; @@ -121,7 +126,10 @@ class TIA : public AbstractTIA { Sound& mySound; Settings& mySettings; - + + DelayQueue myDelayQueue; + unique_ptr myDelayQueueExecutor; + private: TIA() = delete; diff --git a/src/emucore/tia/core_6502ts/module.mk b/src/emucore/tia/core_6502ts/module.mk index 213b3a76a..5096f2878 100644 --- a/src/emucore/tia/core_6502ts/module.mk +++ b/src/emucore/tia/core_6502ts/module.mk @@ -1,10 +1,13 @@ MODULE := src/emucore/tia/core_6502ts MODULE_OBJS := \ - src/emucore/tia/core_6502ts/TIA.o + src/emucore/tia/core_6502ts/TIA.o \ + src/emucore/tia/core_6502ts/DelayQueueMember.o \ + src/emucore/tia/core_6502ts/DelayQueue.o + MODULE_DIRS += \ src/emucore/tia/core_6502ts -# Include common rules +# Include common rules include $(srcdir)/common.rules