1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Adds responsibility for an ongoing index pulse to the drive.

This commit is contained in:
Thomas Harte 2019-12-24 20:53:37 -05:00
parent 42926e72cc
commit dfa6b11737
5 changed files with 38 additions and 26 deletions

View File

@ -68,8 +68,8 @@ uint8_t WD1770::get_register(int address) {
status |= status |=
(get_drive().get_is_track_zero() ? Flag::TrackZero : 0) | (get_drive().get_is_track_zero() ? Flag::TrackZero : 0) |
(status_.seek_error ? Flag::SeekError : 0) | (status_.seek_error ? Flag::SeekError : 0) |
(get_drive().get_is_read_only() ? Flag::WriteProtect : 0); (get_drive().get_is_read_only() ? Flag::WriteProtect : 0) |
// TODO: index hole (get_drive().get_index_pulse() ? Flag::Index : 0);
break; break;
case Status::Two: case Status::Two:

View File

@ -63,7 +63,7 @@ void Drive::set_disk(const std::shared_ptr<Disk> &disk) {
update_clocking_observer(); update_clocking_observer();
} }
bool Drive::has_disk() { bool Drive::has_disk() const {
return has_disk_; return has_disk_;
} }
@ -71,7 +71,7 @@ ClockingHint::Preference Drive::preferred_clocking() {
return (!motor_is_on_ || !has_disk_) ? ClockingHint::Preference::None : ClockingHint::Preference::JustInTime; 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); 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_; 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; // 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 // 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. // 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; return int(get_rotation() * 2.0f * ticks_per_rotation) & 1;
} }
float Drive::get_rotation() { float Drive::get_rotation() const {
return get_time_into_track(); 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, // i.e. amount of time since the index hole was seen, as a proportion of a second,
// converted to a proportion of a rotation. // converted to a proportion of a rotation.
return float(cycles_since_index_hole_) / (float(get_input_clock_rate()) * rotational_multiplier_); 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(); if(disk_) return disk_->get_is_read_only();
return true; return true;
} }
bool Drive::get_is_ready() { bool Drive::get_is_ready() const {
return ready_index_count_ == 2; 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_; 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) { void Drive::set_event_delegate(Storage::Disk::Drive::EventDelegate *delegate) {
event_delegate_ = delegate; event_delegate_ = delegate;
} }
@ -384,7 +388,7 @@ void Drive::end_writing() {
} }
} }
bool Drive::is_writing() { bool Drive::is_writing() const {
return !is_reading_; return !is_reading_;
} }

View File

@ -36,12 +36,12 @@ class Drive: public ClockingHint::Source, public TimedEventLoop {
/*! /*!
@returns @c true if a disk is currently inserted; @c false otherwise. @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. @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), 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. 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. @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. @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. 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. @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 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 @returns @c true if the drive has received a call to begin_writing but not yet a call to
end_writing; @c false otherwise. end_writing; @c false otherwise.
*/ */
bool is_writing(); bool is_writing() const;
/*! /*!
Advances the drive by @c number_of_cycles cycles. 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. @returns the current value of the tachometer pulse offered by some drives.
*/ */
bool get_tachometer(); bool get_tachometer() const;
protected: 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 @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). 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: private:
// Drives contain an entire disk; from that a certain track // Drives contain an entire disk; from that a certain track
@ -210,6 +215,9 @@ class Drive: public ClockingHint::Source, public TimedEventLoop {
// Motor control state. // Motor control state.
bool motor_is_on_ = false; 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 // If the drive is not currently reading then it is writing. While writing
// it can optionally be told to clamp to the index hole. // it can optionally be told to clamp to the index hole.
bool is_reading_ = true; bool is_reading_ = true;
@ -235,7 +243,7 @@ class Drive: public ClockingHint::Source, public TimedEventLoop {
void advance(const Cycles cycles) override; void advance(const Cycles cycles) override;
// Helper for track changes. // Helper for track changes.
float get_time_into_track(); float get_time_into_track() const;
// The target (if any) for track events. // The target (if any) for track events.
EventDelegate *event_delegate_ = nullptr; EventDelegate *event_delegate_ = nullptr;

View File

@ -46,11 +46,11 @@ void TimedEventLoop::run_for(const Cycles cycles) {
assert(cycles_until_event_ > 0); 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)); 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_; return input_clock_rate_;
} }

View File

@ -52,12 +52,12 @@ namespace Storage {
/*! /*!
@returns the number of whole cycles remaining until the next event is triggered. @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. @returns the input clock rate.
*/ */
Cycles::IntType get_input_clock_rate(); Cycles::IntType get_input_clock_rate() const;
protected: protected:
/*! /*!