From 4d4a0cf1d2912c23aac3abcd34bda4022c3e30f6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 14 Sep 2017 22:30:40 -0400 Subject: [PATCH] Puts the disk controller back into the loop with knowledge about reading mode, and uses that knowledge to cut off the PLL. --- Components/1770/1770.cpp | 8 ++++---- Components/8272/i8272.cpp | 8 ++++---- Storage/Disk/DiskController.cpp | 14 ++++++++++++-- Storage/Disk/DiskController.hpp | 20 +++++++++++++++++--- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index f235068b4..43f59df80 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -541,7 +541,7 @@ void WD1770::posit_event(int new_event_type) { }); WAIT_FOR_EVENT(Event::DataWritten); if(status_.data_request) { - get_drive().end_writing(); + end_writing(); update_status([] (Status &status) { status.lost_data = true; }); @@ -554,7 +554,7 @@ void WD1770::posit_event(int new_event_type) { write_crc(); write_byte(0xff); WAIT_FOR_EVENT(Event::DataWritten); - get_drive().end_writing(); + end_writing(); if(command_ & 0x10) { sector_++; @@ -755,11 +755,11 @@ void WD1770::posit_event(int new_event_type) { update_status([] (Status &status) { status.lost_data = true; }); - get_drive().end_writing(); + end_writing(); goto wait_for_command; } if(index_hole_count_) { - get_drive().end_writing(); + end_writing(); goto wait_for_command; } diff --git a/Components/8272/i8272.cpp b/Components/8272/i8272.cpp index 62ffab6c9..30cbb0cb1 100644 --- a/Components/8272/i8272.cpp +++ b/Components/8272/i8272.cpp @@ -525,7 +525,7 @@ void i8272::posit_event(int event_type) { WAIT_FOR_EVENT(Event::DataWritten); if(!has_input_) { SetOverrun(); - get_drive().end_writing(); + end_writing(); goto abort; } write_byte(input_); @@ -540,7 +540,7 @@ void i8272::posit_event(int event_type) { write_crc(); expects_input_ = false; WAIT_FOR_EVENT(Event::DataWritten); - get_drive().end_writing(); + end_writing(); if(sector_ != command_[6]) { sector_++; @@ -646,7 +646,7 @@ void i8272::posit_event(int event_type) { switch(event_type) { case (int)Event::IndexHole: SetOverrun(); - get_drive().end_writing(); + end_writing(); goto abort; break; case (int)Event::DataWritten: @@ -683,7 +683,7 @@ void i8272::posit_event(int event_type) { WAIT_FOR_EVENT((int)Event::DataWritten | (int)Event::IndexHole); if(event_type != (int)Event::IndexHole) goto format_track_pad; - get_drive().end_writing(); + end_writing(); cylinder_ = header_[0]; head_ = header_[1]; diff --git a/Storage/Disk/DiskController.cpp b/Storage/Disk/DiskController.cpp index 0444fb62b..429f94695 100644 --- a/Storage/Disk/DiskController.cpp +++ b/Storage/Disk/DiskController.cpp @@ -48,7 +48,7 @@ void Controller::process_event(const Track::Event &event) { } void Controller::advance(const Cycles cycles) { - pll_->run_for(Cycles(cycles.as_int() * clock_rate_multiplier_)); + if(is_reading_) pll_->run_for(Cycles(cycles.as_int() * clock_rate_multiplier_)); } void Controller::process_write_completed() { @@ -72,7 +72,7 @@ void Controller::set_expected_bit_length(Time bit_length) { } void Controller::digital_phase_locked_loop_output_bit(int value) { - process_input_bit(value); + if(is_reading_) process_input_bit(value); } void Controller::set_drive(std::shared_ptr drive) { @@ -99,5 +99,15 @@ void Controller::set_drive(std::shared_ptr drive) { } void Controller::begin_writing(bool clamp_to_index_hole) { + is_reading_ = false; get_drive().begin_writing(bit_length_, clamp_to_index_hole); } + +void Controller::end_writing() { + is_reading_ = true; + get_drive().end_writing(); +} + +bool Controller::is_reading() { + return is_reading_; +} diff --git a/Storage/Disk/DiskController.hpp b/Storage/Disk/DiskController.hpp index ec0b63016..a259d1dda 100644 --- a/Storage/Disk/DiskController.hpp +++ b/Storage/Disk/DiskController.hpp @@ -68,13 +68,25 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public Drive::EventDe virtual void process_write_completed(); /*! - Puts the drive returned by get_drive() into write mode, supplying the current bit length. + Puts the drive returned by get_drive() into write mode, supplying the current bit length + and marks the controller as being in write mode. @param clamp_to_index_hole If @c true then writing will automatically be truncated by the index hole. Writing will continue over the index hole otherwise. */ void begin_writing(bool clamp_to_index_hole); + /*! + Puts the drive returned by get_drive() out of write mode, and marks the controller + as no longer being in write mode. + */ + void end_writing(); + + /*! + @returns @c true if the controller is in reading mode; @c false otherwise. + */ + bool is_reading(); + /*! Returns the connected drive or, if none is connected, an invented one. No guarantees are made about the lifetime or the exclusivity of the invented drive. @@ -85,8 +97,10 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public Drive::EventDe private: Time bit_length_; - int clock_rate_multiplier_; - int clock_rate_; + int clock_rate_multiplier_ = 1; + int clock_rate_ = 1; + + bool is_reading_ = true; std::shared_ptr pll_; std::shared_ptr drive_;