From 1e970a9772d7ff3126a2b5759ceb34fb5e0958a9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 24 Dec 2016 13:07:23 -0500 Subject: [PATCH] Started stepping slowly towards allowing writing on the disk controller, taking the opportunity to introduce self-simplifying behaviour to Storage::Time. --- Storage/Disk/DiskController.cpp | 53 ++++++++++-- Storage/Disk/DiskController.hpp | 11 ++- Storage/Storage.hpp | 138 ++++++++++++++++++++++---------- 3 files changed, 148 insertions(+), 54 deletions(-) diff --git a/Storage/Disk/DiskController.cpp b/Storage/Disk/DiskController.cpp index f8b727eca..03ae45a20 100644 --- a/Storage/Disk/DiskController.cpp +++ b/Storage/Disk/DiskController.cpp @@ -13,6 +13,8 @@ using namespace Storage::Disk; Controller::Controller(unsigned int clock_rate, unsigned int clock_rate_multiplier, unsigned int revolutions_per_minute) : clock_rate_(clock_rate * clock_rate_multiplier), clock_rate_multiplier_(clock_rate_multiplier), + is_reading_(true), + track_is_dirty_(false), TimedEventLoop(clock_rate * clock_rate_multiplier) { @@ -28,18 +30,20 @@ Controller::Controller(unsigned int clock_rate, unsigned int clock_rate_multipli void Controller::setup_track() { track_ = drive_->get_track(); + track_is_dirty_ = false; Time offset; - if(track_ && time_into_track_.length > 0) + Time track_time_now = get_time_into_track(); + if(track_ && track_time_now > Time(0)) { - Time time_found = track_->seek_to(time_into_track_).simplify(); - offset = (time_into_track_ - time_found).simplify(); - time_into_track_ = time_found; + Time time_found = track_->seek_to(track_time_now); + offset = track_time_now - time_found; + time_into_track_of_last_event_ = time_found; } else { - offset = time_into_track_; - time_into_track_.set_zero(); + offset = track_time_now; + time_into_track_of_last_event_.set_zero(); } reset_timer_to_offset(offset * rotational_multiplier_); @@ -56,7 +60,10 @@ void Controller::run_for_cycles(int number_of_cycles) { int cycles_until_next_event = (int)get_cycles_until_next_event(); int cycles_to_run_for = std::min(cycles_until_next_event, number_of_cycles); + cycles_since_index_hole_ += (unsigned int)cycles_to_run_for; + cycles_since_event_ += (unsigned int)cycles_to_run_for; + number_of_cycles -= cycles_to_run_for; pll_->run_for_cycles(cycles_to_run_for); TimedEventLoop::run_for_cycles(cycles_to_run_for); @@ -84,21 +91,51 @@ void Controller::get_next_event() void Controller::process_next_event() { + cycles_since_event_ = 0; switch(current_event_.type) { case Track::Event::FluxTransition: pll_->add_pulse(); - time_into_track_ += current_event_.length; + time_into_track_of_last_event_ += current_event_.length; break; case Track::Event::IndexHole: + printf("%d [/%d = %d]\n", cycles_since_index_hole_, clock_rate_multiplier_, cycles_since_index_hole_ / clock_rate_multiplier_); cycles_since_index_hole_ = 0; - time_into_track_.set_zero(); + time_into_track_of_last_event_.set_zero(); process_index_hole(); break; } get_next_event(); } +Storage::Time Controller::get_time_into_track() +{ + // this is proportion of a second + Time result(cycles_since_index_hole_, 8000000 * clock_rate_multiplier_); + result /= rotational_multiplier_; + result.simplify(); + return result; +} + +#pragma mark - Writing + +void Controller::begin_writing() +{ + write_segment_.length_of_a_bit = bit_length_ * rotational_multiplier_; + write_segment_.data.clear(); + write_segment_.number_of_bits = 0; + +// write_start_time_; +} + +void Controller::write_bit(bool value) +{ +} + +void Controller::end_writing() +{ +} + #pragma mark - PLL control and delegate void Controller::set_expected_bit_length(Time bit_length) diff --git a/Storage/Disk/DiskController.hpp b/Storage/Disk/DiskController.hpp index 8e7ab7902..3efc94099 100644 --- a/Storage/Disk/DiskController.hpp +++ b/Storage/Disk/DiskController.hpp @@ -11,6 +11,7 @@ #include "Drive.hpp" #include "DigitalPhaseLockedLoop.hpp" +#include "PCMSegment.hpp" #include "../TimedEventLoop.hpp" namespace Storage { @@ -107,14 +108,20 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop std::shared_ptr pll_; std::shared_ptr drive_; std::shared_ptr track_; - unsigned int cycles_since_index_hole_; + unsigned int cycles_since_index_hole_, cycles_since_event_; inline void get_next_event(); Track::Event current_event_; - Time time_into_track_; + Time time_into_track_of_last_event_; bool motor_is_on_; + bool is_reading_; + bool track_is_dirty_; + PCMSegment write_segment_; + Time write_start_time_; + void setup_track(); + Time get_time_into_track(); }; } diff --git a/Storage/Storage.hpp b/Storage/Storage.hpp index e86c0bfea..7c9a02e56 100644 --- a/Storage/Storage.hpp +++ b/Storage/Storage.hpp @@ -10,6 +10,9 @@ #define Storage_hpp #include "../NumberTheory/Factors.hpp" +#include +#include +#include namespace Storage { @@ -20,19 +23,27 @@ namespace Storage { struct Time { unsigned int length, clock_rate; Time() : length(0), clock_rate(1) {} - Time(unsigned int int_value) : length(int_value), clock_rate(1) {} + Time(unsigned int unsigned_int_value) : length(unsigned_int_value), clock_rate(1) {} + Time(int int_value) : Time((unsigned int)int_value) {} Time(unsigned int length, unsigned int clock_rate) : length(length), clock_rate(clock_rate) {} + Time(uint64_t length, uint64_t clock_rate) + { + install_result(length, clock_rate); + } + Time(float value) + { + install_float(value); + } /*! Reduces this @c Time to its simplest form — eliminates all common factors from @c length and @c clock_rate. */ - inline Time &simplify() + void simplify() { unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate); length /= common_divisor; clock_rate /= common_divisor; - return *this; } /*! @@ -50,116 +61,116 @@ struct Time { inline bool operator < (const Time &other) const { - return other.clock_rate * length < clock_rate * other.length; + return (uint64_t)other.clock_rate * (uint64_t)length < (uint64_t)clock_rate * (uint64_t)other.length; } inline bool operator <= (const Time &other) const { - return other.clock_rate * length <= clock_rate * other.length; + return (uint64_t)other.clock_rate * (uint64_t)length <= (uint64_t)clock_rate * (uint64_t)other.length; } inline bool operator > (const Time &other) const { - return other.clock_rate * length > clock_rate * other.length; + return (uint64_t)other.clock_rate * (uint64_t)length > (uint64_t)clock_rate * (uint64_t)other.length; } inline bool operator >= (const Time &other) const { - return other.clock_rate * length >= clock_rate * other.length; + return (uint64_t)other.clock_rate * (uint64_t)length >= (uint64_t)clock_rate * (uint64_t)other.length; } inline bool operator == (const Time &other) const { - return other.clock_rate * length == clock_rate * other.length; + return (uint64_t)other.clock_rate * (uint64_t)length == (uint64_t)clock_rate * (uint64_t)other.length; } inline Time operator + (const Time &other) const { - Time result; - result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); - result.length = length * (result.clock_rate / clock_rate) + other.length * (result.clock_rate / other.clock_rate); - return result; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + return Time(result_length, result_clock_rate); } inline Time &operator += (const Time &other) { - unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); - length = length * (combined_clock_rate / clock_rate) + other.length * (combined_clock_rate / other.clock_rate); - clock_rate = combined_clock_rate; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate + (uint64_t)other.length * (uint64_t)clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + install_result(result_length, result_clock_rate); return *this; } inline Time operator - (const Time &other) const { - Time result; - result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); - result.length = length * (result.clock_rate / clock_rate) - other.length * (result.clock_rate / other.clock_rate); - return result; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + return Time(result_length, result_clock_rate); } inline Time operator -= (const Time &other) { - unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate); - length = length * (combined_clock_rate / clock_rate) - other.length * (combined_clock_rate / other.clock_rate); - clock_rate = combined_clock_rate; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate - (uint64_t)other.length * (uint64_t)clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + install_result(result_length, result_clock_rate); return *this; } inline Time operator * (const Time &other) const { - Time result; - result.clock_rate = clock_rate * other.clock_rate; - result.length = length * other.length; - return result; + uint64_t result_length = (uint64_t)length * (uint64_t)other.length; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + return Time(result_length, result_clock_rate); } inline Time &operator *= (const Time &other) { - length *= other.length; - clock_rate *= other.clock_rate; + uint64_t result_length = (uint64_t)length * (uint64_t)other.length; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.clock_rate; + install_result(result_length, result_clock_rate); return *this; } inline Time operator * (unsigned int multiplier) const { - Time result; - result.clock_rate = clock_rate; - result.length = length * multiplier; - return result; + uint64_t result_length = (uint64_t)length * (uint64_t)multiplier; + uint64_t result_clock_rate = (uint64_t)clock_rate; + return Time(result_length, result_clock_rate); } inline Time &operator *= (unsigned int multiplier) { - length *= multiplier; + uint64_t result_length = (uint64_t)length * (uint64_t)multiplier; + uint64_t result_clock_rate = (uint64_t)clock_rate; + install_result(result_length, result_clock_rate); return *this; } inline Time operator / (const Time &other) const { - Time result; - result.clock_rate = clock_rate * other.length; - result.length = length * other.clock_rate; - return result; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.length; + return Time(result_length, result_clock_rate); } inline Time &operator /= (const Time &other) { - length *= other.clock_rate; - clock_rate *= other.length; + uint64_t result_length = (uint64_t)length * (uint64_t)other.clock_rate; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)other.length; + install_result(result_length, result_clock_rate); return *this; } inline Time operator / (unsigned int divisor) const { - Time result; - result.length = length; - result.clock_rate = clock_rate * divisor; - return result; + uint64_t result_length = (uint64_t)length; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)divisor; + return Time(result_length, result_clock_rate); } inline Time &operator /= (unsigned int divisor) { - clock_rate *= divisor; + uint64_t result_length = (uint64_t)length; + uint64_t result_clock_rate = (uint64_t)clock_rate * (uint64_t)divisor; + install_result(result_length, result_clock_rate); return *this; } @@ -174,6 +185,45 @@ struct Time { length = 1; clock_rate = 1; } + + private: + inline void install_result(uint64_t long_length, uint64_t long_clock_rate) + { + // TODO: switch to appropriate values if the result is too large or small to fit, even with trimmed accuracy. + + while(!(long_length&1) && !(long_clock_rate&1)) + { + long_length >>= 1; + long_clock_rate >>= 1; + } + + if(long_length > std::numeric_limits::max() || long_clock_rate > std::numeric_limits::max()) + { + uint64_t common_divisor = NumberTheory::greatest_common_divisor(long_length, long_clock_rate); + long_length /= common_divisor; + long_clock_rate /= common_divisor; + + // Okay, in desperation accept a loss of accuracy. + while(long_length > std::numeric_limits::max() || long_clock_rate > std::numeric_limits::max()) + { + long_length >>= 1; + long_clock_rate >>= 1; + } + } + length = (unsigned int)long_length; + clock_rate = (unsigned int)long_clock_rate; + } + + inline void install_float(float value) + { + int exponent; + float mantissa = frexpf(value, &exponent); + float loaded_mantissa = ldexpf(mantissa, 24); + + uint64_t result_length = (uint64_t)loaded_mantissa; + uint64_t result_clock_rate = 1 << (exponent - 24); + install_result(result_length, result_clock_rate); + } };