Implement delay queue (untested).

This commit is contained in:
Christian Speckner 2016-11-08 23:54:22 +01:00
parent a99a4e1efd
commit 208f630a3c
8 changed files with 327 additions and 14 deletions

View File

@ -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,

View File

@ -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

View File

@ -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<DelayQueueMember> 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

View File

@ -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<DelayQueueMember::Entry>::const_iterator DelayQueueMember::begin() const
{
return myEntries.begin();
}
vector<DelayQueueMember::Entry>::const_iterator DelayQueueMember::end() const
{
return myEntries.end();
}
void DelayQueueMember::clear()
{
mySize = 0;
}
} // namespace TIA6502tsCore

View File

@ -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<Entry>::const_iterator begin() const;
vector<Entry>::const_iterator end() const;
void clear();
private:
vector<Entry> 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

View File

@ -26,9 +26,30 @@ 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()
{}
@ -217,4 +238,8 @@ namespace TIA6502tsCore {
void TIA::setJitterRecoveryFactor(Int32 f)
{}
// TODO: stub
void TIA::delayedWrite(uInt8 address, uInt8 value)
{}
} // namespace TIA6502tsCore

View File

@ -25,6 +25,7 @@
#include "Sound.hxx"
#include "Settings.hxx"
#include "TIATypes.hxx"
#include "DelayQueue.hxx"
class Console;
@ -114,6 +115,10 @@ class TIA : public AbstractTIA {
void setJitterRecoveryFactor(Int32 f) override;
private:
void delayedWrite(uInt8 address, uInt8 value);
private:
Console& myConsole;
@ -122,6 +127,9 @@ class TIA : public AbstractTIA {
Settings& mySettings;
DelayQueue myDelayQueue;
unique_ptr<DelayQueue::Executor> myDelayQueueExecutor;
private:
TIA() = delete;

View File

@ -1,7 +1,10 @@
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