From aeac6b5888ccd204a350e8d2ffed2ec9d632484d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 16 Jan 2020 21:34:48 -0500 Subject: [PATCH] Allows the type of RDY signal to be specified. --- Storage/Disk/Drive.cpp | 24 +++++++++++++++++++----- Storage/Disk/Drive.hpp | 19 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Storage/Disk/Drive.cpp b/Storage/Disk/Drive.cpp index 261ba711d..39fa5f9ae 100644 --- a/Storage/Disk/Drive.cpp +++ b/Storage/Disk/Drive.cpp @@ -18,9 +18,10 @@ using namespace Storage::Disk; -Drive::Drive(int input_clock_rate, int revolutions_per_minute, int number_of_heads): +Drive::Drive(int input_clock_rate, int revolutions_per_minute, int number_of_heads, ReadyType rdy_type): Storage::TimedEventLoop(input_clock_rate), - available_heads_(number_of_heads) { + available_heads_(number_of_heads), + ready_type_(rdy_type) { set_rotation_speed(revolutions_per_minute); const auto seed = static_cast(std::chrono::system_clock::now().time_since_epoch().count()); @@ -35,7 +36,7 @@ Drive::Drive(int input_clock_rate, int revolutions_per_minute, int number_of_hea } } -Drive::Drive(int input_clock_rate, int number_of_heads) : Drive(input_clock_rate, 300, number_of_heads) {} +Drive::Drive(int input_clock_rate, int number_of_heads, ReadyType rdy_type) : Drive(input_clock_rate, 300, number_of_heads, rdy_type) {} void Drive::set_rotation_speed(float revolutions_per_minute) { // Rationalise the supplied speed so that cycles_per_revolution_ is exact. @@ -54,6 +55,9 @@ Drive::~Drive() { } void Drive::set_disk(const std::shared_ptr &disk) { + if(ready_type_ == ReadyType::ShugartModifiedRDY || ready_type_ == ReadyType::IBMRDY) { + is_ready_ = false; + } if(disk_) disk_->flush_tracks(); disk_ = disk; has_disk_ = !!disk_; @@ -76,6 +80,10 @@ bool Drive::get_is_track_zero() const { } void Drive::step(HeadPosition offset) { + if(ready_type_ == ReadyType::IBMRDY) { + is_ready_ = true; + } + HeadPosition old_head_position = head_position_; head_position_ += offset; if(head_position_ < HeadPosition(0)) { @@ -142,7 +150,7 @@ bool Drive::get_is_read_only() const { } bool Drive::get_is_ready() const { - return ready_index_count_ == 2; + return is_ready_; } void Drive::set_motor_on(bool motor_is_on) { @@ -303,7 +311,10 @@ void Drive::get_next_event(float duration_already_passed) { void Drive::process_next_event() { if(current_event_.type == Track::Event::IndexHole) { - if(ready_index_count_ < 2) ready_index_count_++; + ++ready_index_count_; + if(ready_index_count_ == 2 && (ready_type_ == ReadyType::ShugartRDY || ready_type_ == ReadyType::ShugartModifiedRDY)) { + is_ready_ = true; + } cycles_since_index_hole_ = 0; } if( @@ -427,6 +438,9 @@ void Drive::set_disk_is_rotating(bool is_rotating) { } if(!is_rotating) { + if(ready_type_ == ReadyType::ShugartRDY) { + is_ready_ = false; + } ready_index_count_ = 0; if(disk_) disk_->flush_tracks(); } diff --git a/Storage/Disk/Drive.hpp b/Storage/Disk/Drive.hpp index c568a399f..573e7b363 100644 --- a/Storage/Disk/Drive.hpp +++ b/Storage/Disk/Drive.hpp @@ -24,12 +24,21 @@ namespace Disk { class Drive: public ClockingHint::Source, public TimedEventLoop { public: - Drive(int input_clock_rate, int revolutions_per_minute, int number_of_heads); - Drive(int input_clock_rate, int number_of_heads); + enum class ReadyType { + /// Indicates that RDY will go active when the motor is on and two index holes have passed; it will go inactive when the motor is off. + ShugartRDY, + /// Indicates that RDY will go active when the motor is on and two index holes have passed; it will go inactive when the disk is ejected. + ShugartModifiedRDY, + /// Indicates that RDY will go active when the head steps; it will go inactive when the disk is ejected. + IBMRDY, + }; + + Drive(int input_clock_rate, int revolutions_per_minute, int number_of_heads, ReadyType rdy_type = ReadyType::ShugartRDY); + Drive(int input_clock_rate, int number_of_heads, ReadyType rdy_type = ReadyType::ShugartRDY); ~Drive(); /*! - Replaces whatever is in the drive with @c disk. + Replaces whatever is in the drive with @c disk. Supply @c nullptr to eject any current disk and leave none inserted. */ void set_disk(const std::shared_ptr &disk); @@ -232,8 +241,10 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { PCMSegment write_segment_; Time write_start_time_; - // Indicates progress towards drive ready state. + // Indicates progress towards Shugart-style drive ready states. int ready_index_count_ = 0; + ReadyType ready_type_; + bool is_ready_ = false; // Maintains appropriate counting to know when to indicate that writing // is complete.