From d1fe07f14d76ae9bf236d600862e0c97e888bba3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 12 Jul 2016 21:42:23 -0400 Subject: [PATCH] Added test of perfect DPLL input timing. --- .../Clock Signal.xcodeproj/project.pbxproj | 16 ++++- .../Clock SignalTests-Bridging-Header.h | 1 + .../Bridges/DigitalPhaseLockedLoopBridge.h | 20 ++++++ .../Bridges/DigitalPhaseLockedLoopBridge.mm | 61 +++++++++++++++++++ .../Mac/Clock SignalTests/DPLLTests.swift | 28 +++++++++ Storage/Disk/DigitalPhaseLockedLoop.cpp | 2 +- Storage/Disk/DigitalPhaseLockedLoop.hpp | 2 +- 7 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.h create mode 100644 OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.mm create mode 100644 OSBindings/Mac/Clock SignalTests/DPLLTests.swift diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index ba1162644..f5b86b8d0 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -333,6 +333,8 @@ 4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; }; 4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; }; 4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */; }; + 4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */; }; + 4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -737,6 +739,9 @@ 4BCA98C21D065CA20062F44C /* 6522.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6522.hpp; sourceTree = ""; }; 4BD5F1931D13528900631CD1 /* CSBestEffortUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSBestEffortUpdater.h; path = Updater/CSBestEffortUpdater.h; sourceTree = ""; }; 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSBestEffortUpdater.m; path = Updater/CSBestEffortUpdater.m; sourceTree = ""; }; + 4BEF6AA81D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DigitalPhaseLockedLoopBridge.h; sourceTree = ""; }; + 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DigitalPhaseLockedLoopBridge.mm; sourceTree = ""; }; + 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DPLLTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -887,13 +892,15 @@ isa = PBXGroup; children = ( 4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */, - 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */, 4B3BA0C71D318B44005DD7A7 /* Clock SignalTests-Bridging-Header.h */, + 4BEF6AA81D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.h */, 4B3BA0C81D318B44005DD7A7 /* MOS6522Bridge.h */, - 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */, 4B3BA0CA1D318B44005DD7A7 /* MOS6532Bridge.h */, - 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */, 4B3BA0CC1D318B44005DD7A7 /* TestMachine.h */, + 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */, + 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */, + 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */, + 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */, 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */, ); path = Bridges; @@ -1335,6 +1342,7 @@ 4B1E85801D176468001EF87D /* 6532Tests.swift */, 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */, 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */, + 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */, 4B1414611B58888700E04248 /* KlausDormannTests.swift */, 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */, 4B3BA0C41D318B44005DD7A7 /* Bridges */, @@ -1903,10 +1911,12 @@ 4B14145D1B5887A600E04248 /* CPU6502.cpp in Sources */, 4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */, 4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */, + 4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */, 4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */, 4B3BA0D11D318B44005DD7A7 /* TestMachine.mm in Sources */, 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */, 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */, + 4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */, 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, 4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */, 4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h b/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h index 8333797fa..23c391390 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h +++ b/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h @@ -6,3 +6,4 @@ #import "MOS6522Bridge.h" #import "MOS6532Bridge.h" #import "C1540Bridge.h" +#import "DigitalPhaseLockedLoopBridge.h" diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.h b/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.h new file mode 100644 index 000000000..9f39f0f7d --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.h @@ -0,0 +1,20 @@ +// +// DigitalPhaseLockedLoopBridge.h +// Clock Signal +// +// Created by Thomas Harte on 12/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import + +@interface DigitalPhaseLockedLoopBridge : NSObject + +- (instancetype)initWithClocksPerBit:(NSUInteger)clocksPerBit tolerance:(NSUInteger)tolerance historyLength:(NSUInteger)historyLength; + +- (void)runForCycles:(NSUInteger)cycles; +- (void)addPulse; + +@property(nonatomic) NSUInteger stream; + +@end diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.mm new file mode 100644 index 000000000..7a4068f10 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/Bridges/DigitalPhaseLockedLoopBridge.mm @@ -0,0 +1,61 @@ +// +// DigitalPhaseLockedLoopBridge.m +// Clock Signal +// +// Created by Thomas Harte on 12/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import "DigitalPhaseLockedLoopBridge.h" + +#include "DigitalPhaseLockedLoop.hpp" +#include + +@interface DigitalPhaseLockedLoopBridge(BitPushing) +- (void)pushBit:(int)value; +@end + +class DigitalPhaseLockedLoopDelegate: public Storage::DigitalPhaseLockedLoop::Delegate { + public: + __weak DigitalPhaseLockedLoopBridge *bridge; + + void digital_phase_locked_loop_output_bit(int value) + { + [bridge pushBit:value ? 1 : 0]; + } +}; + +@implementation DigitalPhaseLockedLoopBridge +{ + std::unique_ptr _digitalPhaseLockedLoop; + DigitalPhaseLockedLoopDelegate _delegate; +} + +- (instancetype)initWithClocksPerBit:(NSUInteger)clocksPerBit tolerance:(NSUInteger)tolerance historyLength:(NSUInteger)historyLength +{ + self = [super init]; + if(self) + { + _digitalPhaseLockedLoop.reset(new Storage::DigitalPhaseLockedLoop((unsigned int)clocksPerBit, (unsigned int)tolerance, (unsigned int)historyLength)); + _delegate.bridge = self; + _digitalPhaseLockedLoop->set_delegate(&_delegate); + } + return self; +} + +- (void)runForCycles:(NSUInteger)cycles +{ + _digitalPhaseLockedLoop->run_for_cycles((unsigned int)cycles); +} + +- (void)addPulse +{ + _digitalPhaseLockedLoop->add_pulse(); +} + +- (void)pushBit:(int)value +{ + _stream = (_stream << 1) | value; +} + +@end diff --git a/OSBindings/Mac/Clock SignalTests/DPLLTests.swift b/OSBindings/Mac/Clock SignalTests/DPLLTests.swift new file mode 100644 index 000000000..696d6706d --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/DPLLTests.swift @@ -0,0 +1,28 @@ +// +// DPLLTests.swift +// Clock Signal +// +// Created by Thomas Harte on 12/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +import XCTest + +class DPLLTests: XCTestCase { + + func testPerfectInput() { + let pll = DigitalPhaseLockedLoopBridge(clocksPerBit: 100, tolerance: 20, historyLength: 5) + + // clock in two 1s, a 0, and a 1 + pll.runForCycles(50) + pll.addPulse() + pll.runForCycles(100) + pll.addPulse() + pll.runForCycles(200) + pll.addPulse() + pll.runForCycles(50) + + XCTAssert(pll.stream == 0xd, "PLL should have clocked four bits") + } + +} diff --git a/Storage/Disk/DigitalPhaseLockedLoop.cpp b/Storage/Disk/DigitalPhaseLockedLoop.cpp index 358575500..de1b834be 100644 --- a/Storage/Disk/DigitalPhaseLockedLoop.cpp +++ b/Storage/Disk/DigitalPhaseLockedLoop.cpp @@ -38,7 +38,7 @@ void DigitalPhaseLockedLoop::run_for_cycles(unsigned int number_of_cycles) _window_offset %= _current_window_length; } - // updte timing + // update timing _next_pulse_time += number_of_cycles; } diff --git a/Storage/Disk/DigitalPhaseLockedLoop.hpp b/Storage/Disk/DigitalPhaseLockedLoop.hpp index a8364631f..6eb38a7b5 100644 --- a/Storage/Disk/DigitalPhaseLockedLoop.hpp +++ b/Storage/Disk/DigitalPhaseLockedLoop.hpp @@ -41,7 +41,7 @@ class DigitalPhaseLockedLoop { */ class Delegate { public: - virtual void digital_phase_locked_loop_output_bit(bool value) = 0; + virtual void digital_phase_locked_loop_output_bit(int value) = 0; }; void set_delegate(Delegate *delegate) {