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

Switches disk seeking logic fully to floating point.

This commit is contained in:
Thomas Harte 2020-07-17 22:08:58 -04:00
parent cbb0594e6b
commit 4ee29b3266
8 changed files with 26 additions and 22 deletions

View File

@ -80,6 +80,10 @@ bool Drive::get_is_track_zero() const {
}
void Drive::step(HeadPosition offset) {
if(offset == HeadPosition(0)) {
return;
}
if(ready_type_ == ReadyType::IBMRDY) {
is_ready_ = true;
}
@ -94,7 +98,7 @@ void Drive::step(HeadPosition offset) {
}
// If the head moved, flush the old track.
if(head_position_ != old_head_position) {
if(disk_ && disk_->tracks_differ(Track::Address(head_, head_position_), Track::Address(head_, old_head_position))) {
track_ = nullptr;
}
@ -355,8 +359,8 @@ void Drive::setup_track() {
}
float offset = 0.0f;
const auto track_time_now = get_time_into_track();
const auto time_found = track_->seek_to(Time(track_time_now)).get<float>();
const float track_time_now = get_time_into_track();
const float time_found = track_->seek_to(track_time_now);
// `time_found` can be greater than `track_time_now` if limited precision caused rounding.
if(time_found <= track_time_now) {

View File

@ -109,9 +109,9 @@ Storage::Time PCMSegmentEventSource::get_length() {
return segment_->length_of_a_bit * unsigned(segment_->data.size());
}
Storage::Time PCMSegmentEventSource::seek_to(const Time &time_from_start) {
float PCMSegmentEventSource::seek_to(float time_from_start) {
// test for requested time being beyond the end
const Time length = get_length();
const float length = get_length().get<float>();
if(time_from_start >= length) {
next_event_.type = Track::Event::IndexHole;
bit_pointer_ = segment_->data.size()+1;
@ -122,21 +122,21 @@ Storage::Time PCMSegmentEventSource::seek_to(const Time &time_from_start) {
next_event_.type = Track::Event::FluxTransition;
// test for requested time being before the first bit
Time half_bit_length = segment_->length_of_a_bit;
half_bit_length.length >>= 1;
const float bit_length = segment_->length_of_a_bit.get<float>();
const float half_bit_length = bit_length / 2.0f;
if(time_from_start < half_bit_length) {
bit_pointer_ = 0;
return Storage::Time(0);
return 0.0f;
}
// adjust for time to get to bit zero and determine number of bits in;
// bit_pointer_ always records _the next bit_ that might trigger an event,
// so should be one beyond the one reached by a seek.
const Time relative_time = time_from_start - half_bit_length;
bit_pointer_ = 1 + (relative_time / segment_->length_of_a_bit).get<unsigned int>();
const float relative_time = time_from_start + half_bit_length; // the period [0, 0.5) should map to window 0; [0.5, 1.5) should map to window 1; etc.
bit_pointer_ = 1 + size_t(relative_time / bit_length);
// map up to the correct amount of time
return half_bit_length + segment_->length_of_a_bit * unsigned(bit_pointer_ - 1);
return half_bit_length + segment_->length_of_a_bit.get<float>() * float(bit_pointer_ - 1);
}
const PCMSegment &PCMSegmentEventSource::segment() const {

View File

@ -183,7 +183,7 @@ class PCMSegmentEventSource {
@returns the time the source is now at.
*/
Time seek_to(const Time &time_from_start);
float seek_to(float time_from_start);
/*!
@returns the total length of the stream of data that the source will provide.

View File

@ -121,17 +121,17 @@ Track::Event PCMTrack::get_next_event() {
return event;
}
Storage::Time PCMTrack::seek_to(const Time &time_since_index_hole) {
float PCMTrack::seek_to(float time_since_index_hole) {
// initial condition: no time yet accumulated, the whole thing requested yet to navigate
Storage::Time accumulated_time;
Storage::Time time_left_to_seek = time_since_index_hole;
float accumulated_time = 0.0f;
float time_left_to_seek = time_since_index_hole;
// search from the first segment
segment_pointer_ = 0;
do {
// if this segment extends beyond the amount of time left to seek, trust it to complete
// the seek
Storage::Time segment_time = segment_event_sources_[segment_pointer_].get_length();
const float segment_time = segment_event_sources_[segment_pointer_].get_length().get<float>();
if(segment_time > time_left_to_seek) {
return accumulated_time + segment_event_sources_[segment_pointer_].seek_to(time_left_to_seek);
}

View File

@ -50,7 +50,7 @@ class PCMTrack: public Track {
// as per @c Track
Event get_next_event() final;
Time seek_to(const Time &time_since_index_hole) final;
float seek_to(float time_since_index_hole) final;
Track *clone() const final;
// Obtains a copy of this track, flattened to a single PCMSegment, which

View File

@ -35,7 +35,7 @@ Storage::Disk::PCMSegment Storage::Disk::track_serialisation(const Track &track,
length_multiplier.simplify();
// start at the index hole
track_copy->seek_to(Time(0));
track_copy->seek_to(0.0f);
// grab events until the next index hole
Time time_error = Time(0);
@ -54,7 +54,7 @@ Storage::Disk::PCMSegment Storage::Disk::track_serialisation(const Track &track,
if(history_size) {
history_size--;
if(!history_size) {
track_copy->seek_to(Time(0));
track_copy->seek_to(0.0f);
time_error.set_zero();
result_accumulator.is_recording = true;
}

View File

@ -17,8 +17,8 @@ Track::Event UnformattedTrack::get_next_event() {
return event;
}
Storage::Time UnformattedTrack::seek_to(const Time &) {
return Time(0);
float UnformattedTrack::seek_to(float) {
return 0.0f;
}
Track *UnformattedTrack::clone() const {

View File

@ -20,7 +20,7 @@ namespace Disk {
class UnformattedTrack: public Track {
public:
Event get_next_event() final;
Time seek_to(const Time &time_since_index_hole) final;
float seek_to(float time_since_index_hole) final;
Track *clone() const final;
};