diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 81296a36f..47f9c7286 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -70,9 +70,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - enableAddressSanitizer = "YES" enableASanStackUseAfterReturn = "YES" - enableUBSanitizer = "YES" disableMainThreadChecker = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" diff --git a/Storage/Disk/Controller/DiskController.cpp b/Storage/Disk/Controller/DiskController.cpp index 8146a23be..8c69c1335 100644 --- a/Storage/Disk/Controller/DiskController.cpp +++ b/Storage/Disk/Controller/DiskController.cpp @@ -15,9 +15,8 @@ using namespace Storage::Disk; Controller::Controller(Cycles clock_rate) : clock_rate_multiplier_(128000000 / clock_rate.as_integral()), clock_rate_(clock_rate.as_integral() * clock_rate_multiplier_), - pll_(100), + pll_(100, *this), empty_drive_(new Drive(int(clock_rate.as_integral()), 1, 1)) { - pll_.set_delegate(this); set_expected_bit_length(Time(1)); set_drive(empty_drive_); } diff --git a/Storage/Disk/DPLL/DigitalPhaseLockedLoop.hpp b/Storage/Disk/DPLL/DigitalPhaseLockedLoop.hpp index cece24d9d..b81643149 100644 --- a/Storage/Disk/DPLL/DigitalPhaseLockedLoop.hpp +++ b/Storage/Disk/DPLL/DigitalPhaseLockedLoop.hpp @@ -21,6 +21,7 @@ namespace Storage { /*! Template parameters: + @c bit_handler A class that must implement a method, digital_phase_locked_loop_output_bit(int) for receving bits from the DPLL. @c length_of_history The number of historic pulses to consider in locking to phase. */ template class DigitalPhaseLockedLoop { @@ -30,8 +31,8 @@ template class DigitalPhaseL @param clocks_per_bit The expected number of cycles between each bit of input. */ - DigitalPhaseLockedLoop(int clocks_per_bit) : - window_length_(clocks_per_bit), clocks_per_bit_(clocks_per_bit) {} + DigitalPhaseLockedLoop(int clocks_per_bit, BitHandler &handler) : + bit_handler_(handler), window_length_(clocks_per_bit), clocks_per_bit_(clocks_per_bit) {} /*! Changes the expected window length. @@ -51,12 +52,10 @@ template class DigitalPhaseL if(phase_ >= window_length_) { auto windows_crossed = phase_ / window_length_; - // check whether this triggers any 0s, if anybody cares - if(delegate_) { - if(window_was_filled_) --windows_crossed; - for(int c = 0; c < windows_crossed; c++) - delegate_->digital_phase_locked_loop_output_bit(0); - } + // Check whether this triggers any 0s. + if(window_was_filled_) --windows_crossed; + for(int c = 0; c < windows_crossed; c++) + bit_handler_.digital_phase_locked_loop_output_bit(0); window_was_filled_ = false; phase_ %= window_length_; @@ -68,22 +67,15 @@ template class DigitalPhaseL */ void add_pulse() { if(!window_was_filled_) { - if(delegate_) delegate_->digital_phase_locked_loop_output_bit(1); + bit_handler_.digital_phase_locked_loop_output_bit(1); window_was_filled_ = true; post_phase_offset(phase_, offset_); offset_ = 0; } } - /*! - A receiver for PCM output data; called upon every recognised bit. - */ - void set_delegate(BitHandler *delegate) { - delegate_ = delegate; - } - private: - BitHandler *delegate_ = nullptr; + BitHandler &bit_handler_; void post_phase_offset(Cycles::IntType new_phase, Cycles::IntType new_offset) { // Erase the effect of whatever is currently in this slot. diff --git a/Storage/Disk/Track/TrackSerialiser.cpp b/Storage/Disk/Track/TrackSerialiser.cpp index f8590fd6c..1ac070127 100644 --- a/Storage/Disk/Track/TrackSerialiser.cpp +++ b/Storage/Disk/Track/TrackSerialiser.cpp @@ -20,12 +20,13 @@ Storage::Disk::PCMSegment Storage::Disk::track_serialisation(const Track &track, // its PCMSegment. struct ResultAccumulator { PCMSegment result; + bool is_recording = false; void digital_phase_locked_loop_output_bit(int value) { - result.data.push_back(!!value); + if(is_recording) result.data.push_back(!!value); } } result_accumulator; result_accumulator.result.length_of_a_bit = length_of_a_bit; - DigitalPhaseLockedLoop pll(100); + DigitalPhaseLockedLoop pll(100, result_accumulator); // Obtain a length multiplier which is 100 times the reciprocal // of the expected bit length. So a perfect bit length from @@ -55,7 +56,7 @@ Storage::Disk::PCMSegment Storage::Disk::track_serialisation(const Track &track, if(!history_size) { track_copy->seek_to(Time(0)); time_error.set_zero(); - pll.set_delegate(&result_accumulator); + result_accumulator.is_recording = true; } } } diff --git a/Storage/Tape/Parsers/Acorn.cpp b/Storage/Tape/Parsers/Acorn.cpp index 1997f4d5a..46d3b0516 100644 --- a/Storage/Tape/Parsers/Acorn.cpp +++ b/Storage/Tape/Parsers/Acorn.cpp @@ -66,13 +66,11 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) { Shifter::Shifter() : - pll_(PLLClockRate / 4800), + pll_(PLLClockRate / 4800, *this), was_high_(false), input_pattern_(0), input_bit_counter_(0), - delegate_(nullptr) { - pll_.set_delegate(this); -} + delegate_(nullptr) {} void Shifter::process_pulse(const Storage::Tape::Tape::Pulse &pulse) { pll_.run_for(Cycles(static_cast(static_cast(PLLClockRate) * pulse.length.get())));