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:
parent
42926e72cc
commit
dfa6b11737
@ -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:
|
||||||
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
Reference in New Issue
Block a user