From dfa6b1173770f13f2c618290d3b0143ddbdb73f8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 24 Dec 2019 20:53:37 -0500 Subject: [PATCH] Adds responsibility for an ongoing index pulse to the drive. --- Components/1770/1770.cpp | 4 ++-- Storage/Disk/Drive.cpp | 24 ++++++++++++++---------- Storage/Disk/Drive.hpp | 28 ++++++++++++++++++---------- Storage/TimedEventLoop.cpp | 4 ++-- Storage/TimedEventLoop.hpp | 4 ++-- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index 61c476088..b91aeb6dd 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -68,8 +68,8 @@ uint8_t WD1770::get_register(int address) { status |= (get_drive().get_is_track_zero() ? Flag::TrackZero : 0) | (status_.seek_error ? Flag::SeekError : 0) | - (get_drive().get_is_read_only() ? Flag::WriteProtect : 0); - // TODO: index hole + (get_drive().get_is_read_only() ? Flag::WriteProtect : 0) | + (get_drive().get_index_pulse() ? Flag::Index : 0); break; case Status::Two: diff --git a/Storage/Disk/Drive.cpp b/Storage/Disk/Drive.cpp index c4087236c..fea9cc277 100644 --- a/Storage/Disk/Drive.cpp +++ b/Storage/Disk/Drive.cpp @@ -63,7 +63,7 @@ void Drive::set_disk(const std::shared_ptr &disk) { update_clocking_observer(); } -bool Drive::has_disk() { +bool Drive::has_disk() const { return has_disk_; } @@ -71,7 +71,7 @@ ClockingHint::Preference Drive::preferred_clocking() { return (!motor_is_on_ || !has_disk_) ? ClockingHint::Preference::None : ClockingHint::Preference::JustInTime; } -bool Drive::get_is_track_zero() { +bool Drive::get_is_track_zero() const { return head_position_ == HeadPosition(0); } @@ -114,11 +114,11 @@ void Drive::set_head(int head) { } } -int Drive::get_head_count() { +int Drive::get_head_count() const { return available_heads_; } -bool Drive::get_tachometer() { +bool Drive::get_tachometer() const { // I have made a guess here that the tachometer is a symmetric square wave; // if that is correct then around 60 beats per rotation appears to be correct // to proceed beyond the speed checks I've so far uncovered. @@ -126,22 +126,22 @@ bool Drive::get_tachometer() { return int(get_rotation() * 2.0f * ticks_per_rotation) & 1; } -float Drive::get_rotation() { +float Drive::get_rotation() const { return get_time_into_track(); } -float Drive::get_time_into_track() { +float Drive::get_time_into_track() const { // i.e. amount of time since the index hole was seen, as a proportion of a second, // converted to a proportion of a rotation. return float(cycles_since_index_hole_) / (float(get_input_clock_rate()) * rotational_multiplier_); } -bool Drive::get_is_read_only() { +bool Drive::get_is_read_only() const { if(disk_) return disk_->get_is_read_only(); return true; } -bool Drive::get_is_ready() { +bool Drive::get_is_ready() const { return ready_index_count_ == 2; } @@ -164,10 +164,14 @@ void Drive::set_motor_on(bool motor_is_on) { } } -bool Drive::get_motor_on() { +bool Drive::get_motor_on() const { return motor_is_on_; } +bool Drive::get_index_pulse() const { + return index_pulse_remaining_ > Cycles(0); +} + void Drive::set_event_delegate(Storage::Disk::Drive::EventDelegate *delegate) { event_delegate_ = delegate; } @@ -384,7 +388,7 @@ void Drive::end_writing() { } } -bool Drive::is_writing() { +bool Drive::is_writing() const { return !is_reading_; } diff --git a/Storage/Disk/Drive.hpp b/Storage/Disk/Drive.hpp index f33b0d23a..330cdd734 100644 --- a/Storage/Disk/Drive.hpp +++ b/Storage/Disk/Drive.hpp @@ -36,12 +36,12 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { /*! @returns @c true if a disk is currently inserted; @c false otherwise. */ - bool has_disk(); + bool has_disk() const; /*! @returns @c true if the drive head is currently at track zero; @c false otherwise. */ - bool get_is_track_zero(); + bool get_is_track_zero() const; /*! Steps the disk head the specified number of tracks. Positive numbers step inwards (i.e. away from track 0), @@ -57,17 +57,17 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { /*! Gets the head count for this disk. */ - int get_head_count(); + int get_head_count() const; /*! @returns @c true if the inserted disk is read-only or no disk is inserted; @c false otherwise. */ - bool get_is_read_only(); + bool get_is_read_only() const; /*! @returns @c true if the drive is ready; @c false otherwise. */ - bool get_is_ready(); + bool get_is_ready() const; /*! Sets whether the disk motor is on. @@ -77,7 +77,12 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { /*! @returns @c true if the motor is on; @c false otherwise. */ - bool get_motor_on(); + bool get_motor_on() const; + + /*! + @returns @c true if the index pulse output is active; @c false otherwise. + */ + bool get_index_pulse() const; /*! Begins write mode, initiating a PCM sampled region of data. Bits should be written via @@ -104,7 +109,7 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { @returns @c true if the drive has received a call to begin_writing but not yet a call to end_writing; @c false otherwise. */ - bool is_writing(); + bool is_writing() const; /*! Advances the drive by @c number_of_cycles cycles. @@ -163,7 +168,7 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { /*! @returns the current value of the tachometer pulse offered by some drives. */ - bool get_tachometer(); + bool get_tachometer() const; protected: /*! @@ -180,7 +185,7 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { @returns the current rotation of the disk, a float in the half-open range 0.0 (the index hole) to 1.0 (back to the index hole, a whole rotation later). */ - float get_rotation(); + float get_rotation() const; private: // Drives contain an entire disk; from that a certain track @@ -210,6 +215,9 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { // Motor control state. bool motor_is_on_ = false; + // Current state of the index pulse output. + Cycles index_pulse_remaining_; + // If the drive is not currently reading then it is writing. While writing // it can optionally be told to clamp to the index hole. bool is_reading_ = true; @@ -235,7 +243,7 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { void advance(const Cycles cycles) override; // Helper for track changes. - float get_time_into_track(); + float get_time_into_track() const; // The target (if any) for track events. EventDelegate *event_delegate_ = nullptr; diff --git a/Storage/TimedEventLoop.cpp b/Storage/TimedEventLoop.cpp index c7326bb13..aba194ae2 100644 --- a/Storage/TimedEventLoop.cpp +++ b/Storage/TimedEventLoop.cpp @@ -46,11 +46,11 @@ void TimedEventLoop::run_for(const Cycles cycles) { assert(cycles_until_event_ > 0); } -Cycles::IntType TimedEventLoop::get_cycles_until_next_event() { +Cycles::IntType TimedEventLoop::get_cycles_until_next_event() const { return std::max(cycles_until_event_, Cycles::IntType(0)); } -Cycles::IntType TimedEventLoop::get_input_clock_rate() { +Cycles::IntType TimedEventLoop::get_input_clock_rate() const { return input_clock_rate_; } diff --git a/Storage/TimedEventLoop.hpp b/Storage/TimedEventLoop.hpp index 465e47292..64d4ce3a0 100644 --- a/Storage/TimedEventLoop.hpp +++ b/Storage/TimedEventLoop.hpp @@ -52,12 +52,12 @@ namespace Storage { /*! @returns the number of whole cycles remaining until the next event is triggered. */ - Cycles::IntType get_cycles_until_next_event(); + Cycles::IntType get_cycles_until_next_event() const; /*! @returns the input clock rate. */ - Cycles::IntType get_input_clock_rate(); + Cycles::IntType get_input_clock_rate() const; protected: /*!