From 6a15bb15ca2b104d3cf2261ff530983c7c84f237 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 7 Aug 2021 17:29:21 -0400 Subject: [PATCH] Adds a simpler way of deferring single values. --- ClockReceiver/DeferredValue.hpp | 48 +++++++++++++++++++ .../Clock Signal.xcodeproj/project.pbxproj | 2 + 2 files changed, 50 insertions(+) create mode 100644 ClockReceiver/DeferredValue.hpp diff --git a/ClockReceiver/DeferredValue.hpp b/ClockReceiver/DeferredValue.hpp new file mode 100644 index 000000000..35fbdf974 --- /dev/null +++ b/ClockReceiver/DeferredValue.hpp @@ -0,0 +1,48 @@ +// +// DeferredValue.hpp +// Clock Signal +// +// Created by Thomas Harte on 07/08/2021. +// Copyright © 2021 Thomas Harte. All rights reserved. +// + +#ifndef DeferredValue_h +#define DeferredValue_h + +/*! + Provides storage for a single deferred value: one with a current value and a certain number + of future values. +*/ +template class DeferredValue { + private: + static_assert(sizeof(ValueT) <= 4); + + constexpr int elements_per_uint32 = sizeof(uint32_t) / sizeof(ValueT); + constexpr int unit_shift = sizeof(ValueT) * 8; + constexpr int insert_shift = (DeferredDepth & (elements_per_uint32 - 1)) * unit_shift; + constexpr uint32_t insert_mask = ~(0xffff'ffff << insert_shift); + + std::array backlog; + + public: + /// @returns the current value. + ValueT value() const { + return uint8_t(backlog[0]); + } + + /// Advances to the next enqueued value. + void advance() { + for(size_t c = 0; c < backlog.size() - 1; c--) { + backlog[c] = (backlog[c] >> unit_shift) | (backlog[c+1] << (32 - unit_shift)); + } + backlog[backlog.size() - 1] >>= unit_shift; + } + + /// Inserts a new value, replacing whatever is currently at the end of the queue. + void insert(ValueT value) { + backlog[DeferredDepth / elements_per_uint32] = + (backlog[DeferredDepth / elements_per_uint32] & insert_mask) | (value << insert_shift); + } +}; + +#endif /* DeferredValue_h */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 1713b31bb..8fa9ea1c8 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1585,6 +1585,7 @@ 4B98A0601FFADCDE00ADF63B /* MSXStaticAnalyserTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MSXStaticAnalyserTests.mm; sourceTree = ""; }; 4B98A1CD1FFADEC400ADF63B /* MSX ROMs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "MSX ROMs"; sourceTree = ""; }; 4B996B2D2496DAC2001660EF /* VSyncPredictor.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VSyncPredictor.hpp; sourceTree = ""; }; + 4B99EBD026BF2D9F00CA924D /* DeferredValue.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DeferredValue.hpp; sourceTree = ""; }; 4B9BE3FE203A0C0600FFAE60 /* MultiSpeaker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiSpeaker.cpp; sourceTree = ""; }; 4B9BE3FF203A0C0600FFAE60 /* MultiSpeaker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MultiSpeaker.hpp; sourceTree = ""; }; 4B9D0C4A22C7D70900DE1AD3 /* 68000BCDTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000BCDTests.mm; sourceTree = ""; }; @@ -4733,6 +4734,7 @@ 4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */, 4B449C942063389900A095C8 /* TimeTypes.hpp */, 4B996B2D2496DAC2001660EF /* VSyncPredictor.hpp */, + 4B99EBD026BF2D9F00CA924D /* DeferredValue.hpp */, ); name = ClockReceiver; path = ../../ClockReceiver;