From f984de42a36b39a1c6b677d146e1722b0abd30f0 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 29 Jul 2016 07:31:02 -0400 Subject: [PATCH] Took some small steps towards having a disk drive that at least can select a track and pump relevant events into a PLL. --- Storage/Disk/DiskDrive.cpp | 66 ++++++++++++++++++++++++++++++++------ Storage/Disk/DiskDrive.hpp | 17 +++++----- Storage/Storage.hpp | 9 ++++++ 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/Storage/Disk/DiskDrive.cpp b/Storage/Disk/DiskDrive.cpp index de0dda28d..e1e56ead1 100644 --- a/Storage/Disk/DiskDrive.cpp +++ b/Storage/Disk/DiskDrive.cpp @@ -13,17 +13,21 @@ using namespace Storage; DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) : _clock_rate(clock_rate), _revolutions_per_minute(revolutions_per_minute), - _head_position(0) {} + _head_position(0), + + TimedEventLoop(clock_rate) +{} void DiskDrive::set_expected_bit_length(Time bit_length) { _bit_length = bit_length; +// _pll.reset(new DigitalPhaseLockedLoop(); } void DiskDrive::set_disk(std::shared_ptr disk) { _disk = disk; -// _track.reset(); + set_track(); } bool DiskDrive::has_disk() @@ -39,21 +43,65 @@ bool DiskDrive::get_is_track_zero() void DiskDrive::step(int direction) { _head_position = std::max(_head_position + direction, 0); - _track = _disk->get_track_at_position((unsigned int)_head_position); + set_track(); } -void DiskDrive::digital_phase_locked_loop_output_bit(int value) +void DiskDrive::set_track() { - process_input_bit(value, _cycles_since_index_hole); + _track = _disk->get_track_at_position((unsigned int)_head_position); + reset_timer(); + get_next_event(); } void DiskDrive::run_for_cycles(unsigned int number_of_cycles) { if(has_disk()) { - while(number_of_cycles--) - { - - } + _cycles_since_index_hole += number_of_cycles; + TimedEventLoop::run_for_cycles(number_of_cycles); } } + +#pragma mark - Track timed event loop + +void DiskDrive::get_next_event() +{ + if(_track) + _current_event = _track->get_next_event(); + else + { + _current_event.length.length = 1; + _current_event.length.clock_rate = 1; + _current_event.type = Track::Event::IndexHole; + } + + // divide interval, which is in terms of a rotation of the disk, by rotation speed, and + // convert it into revolutions per second + Time event_interval = _current_event.length; + event_interval.length *= 60; + event_interval.clock_rate *= _revolutions_per_minute; + event_interval.simplify(); + set_next_event_time_interval(event_interval); +} + +void DiskDrive::process_next_event() +{ + switch(_current_event.type) + { + case Track::Event::FluxTransition: + _pll->add_pulse(); + break; + case Track::Event::IndexHole: + _cycles_since_index_hole = 0; + process_index_hole(); + break; + } + get_next_event(); +} + +#pragma mark - PLL delegate + +void DiskDrive::digital_phase_locked_loop_output_bit(int value) +{ + process_input_bit(value, _cycles_since_index_hole); +} diff --git a/Storage/Disk/DiskDrive.hpp b/Storage/Disk/DiskDrive.hpp index c3e857ec8..2e89fe3c6 100644 --- a/Storage/Disk/DiskDrive.hpp +++ b/Storage/Disk/DiskDrive.hpp @@ -11,11 +11,11 @@ #include "Disk.hpp" #include "DigitalPhaseLockedLoop.hpp" -#include "../../SignalProcessing/Stepper.hpp" +#include "../TimedEventLoop.hpp" namespace Storage { -class DiskDrive: public DigitalPhaseLockedLoop::Delegate { +class DiskDrive: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop { public: DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute); @@ -37,6 +37,9 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate { virtual void process_input_bit(int value, unsigned int cycles_since_index_hole) = 0; virtual void process_index_hole() = 0; + // for TimedEventLoop + virtual void process_next_event(); + private: Time _bit_length; unsigned int _clock_rate; @@ -47,14 +50,10 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate { std::shared_ptr _track; int _head_position; unsigned int _cycles_since_index_hole; + void set_track(); - void install_track(); - - struct { - Track::Event current_event; - std::unique_ptr pulse_stepper; - uint32_t time_into_pulse; - } _input; + inline void get_next_event(); + Track::Event _current_event; }; } diff --git a/Storage/Storage.hpp b/Storage/Storage.hpp index ac65da093..d4446b537 100644 --- a/Storage/Storage.hpp +++ b/Storage/Storage.hpp @@ -9,10 +9,19 @@ #ifndef Storage_hpp #define Storage_hpp +#include "../NumberTheory/Factors.hpp" + namespace Storage { struct Time { unsigned int length, clock_rate; + + inline void simplify() + { + unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate); + length /= common_divisor; + clock_rate /= common_divisor; + } }; }