diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 06204d82f..ba1162644 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */; }; 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; }; 4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414571B58879D00E04248 /* CPU6502.cpp */; }; 4B14145D1B5887A600E04248 /* CPU6502.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414571B58879D00E04248 /* CPU6502.cpp */; }; @@ -354,6 +355,8 @@ /* Begin PBXFileReference section */ 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = ""; }; 4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTConstants.hpp; sourceTree = ""; }; + 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DigitalPhaseLockedLoop.cpp; sourceTree = ""; }; + 4B0BE4271D3481E700D5256B /* DigitalPhaseLockedLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DigitalPhaseLockedLoop.hpp; sourceTree = ""; }; 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRT.cpp; sourceTree = ""; }; 4B0CCC431C62D0B3001CAC5F /* CRT.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRT.hpp; sourceTree = ""; }; 4B1414501B58848C00E04248 /* ClockSignal-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ClockSignal-Bridging-Header.h"; sourceTree = ""; }; @@ -989,6 +992,8 @@ 4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */, 4BAB62B61D3302CA00DF5BA0 /* PCMTrack.cpp */, 4BAB62B71D3302CA00DF5BA0 /* PCMTrack.hpp */, + 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */, + 4B0BE4271D3481E700D5256B /* DigitalPhaseLockedLoop.hpp */, ); path = Disk; sourceTree = ""; @@ -1861,6 +1866,7 @@ 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */, 4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */, + 4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */, 4B73C71A1D036BD90074D992 /* Vic20Document.swift in Sources */, 4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */, 4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */, diff --git a/Storage/Disk/DigitalPhaseLockedLoop.cpp b/Storage/Disk/DigitalPhaseLockedLoop.cpp new file mode 100644 index 000000000..5d1319fc3 --- /dev/null +++ b/Storage/Disk/DigitalPhaseLockedLoop.cpp @@ -0,0 +1,9 @@ +// +// DigitalPhaseLockedLoop.cpp +// Clock Signal +// +// Created by Thomas Harte on 11/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "DigitalPhaseLockedLoop.hpp" diff --git a/Storage/Disk/DigitalPhaseLockedLoop.hpp b/Storage/Disk/DigitalPhaseLockedLoop.hpp new file mode 100644 index 000000000..f8b3910c1 --- /dev/null +++ b/Storage/Disk/DigitalPhaseLockedLoop.hpp @@ -0,0 +1,54 @@ +// +// DigitalPhaseLockedLoop.hpp +// Clock Signal +// +// Created by Thomas Harte on 11/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef DigitalPhaseLockedLoop_hpp +#define DigitalPhaseLockedLoop_hpp + +namespace Storage { + +class DigitalPhaseLockedLoop { + public: + /*! + Instantiates a @c DigitalPhaseLockedLoop. + + @param clocks_per_bit The expected number of cycles between each bit of input. + @param tolerance The maximum tolerance for bit windows — extremes will be clocks_per_bit ± tolerance. + */ + DigitalPhaseLockedLoop(unsigned int clocks_per_bit, unsigned int tolerance); + + /*! + Runs the loop, impliedly posting no pulses during that period. + + @c number_of_cycles The time to run the loop for. + */ + void run_for_cycles(unsigned int number_of_cycles); + + /*! + Announces a pulse at the current time. + */ + void add_pulse(); + + /*! + A receiver for PCM output data; called upon every recognised bit. + */ + class Delegate { + public: + virtual void digital_phase_locked_loop_output_bit(bool value) = 0; + }; + void set_delegate(Delegate *delegate) + { + _delegate = delegate; + } + + private: + Delegate *_delegate; +}; + +} + +#endif /* DigitalPhaseLockedLoop_hpp */