mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Switches disk seeking logic fully to floating point.
This commit is contained in:
parent
cbb0594e6b
commit
4ee29b3266
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user