mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Made an attempt to insert proper conversions to/from rotational speed. The Time
class is now really turning into a full-on quotient. Might need refactoring.
This commit is contained in:
parent
e57ab1025d
commit
3e90b85ff8
@ -17,7 +17,11 @@ DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int clock_rate_multiplier
|
|||||||
_head_position(0),
|
_head_position(0),
|
||||||
|
|
||||||
TimedEventLoop(clock_rate * clock_rate_multiplier)
|
TimedEventLoop(clock_rate * clock_rate_multiplier)
|
||||||
{}
|
{
|
||||||
|
_rotational_multiplier.length = 60;
|
||||||
|
_rotational_multiplier.clock_rate = revolutions_per_minute;
|
||||||
|
_rotational_multiplier.simplify();
|
||||||
|
}
|
||||||
|
|
||||||
void DiskDrive::set_expected_bit_length(Time bit_length)
|
void DiskDrive::set_expected_bit_length(Time bit_length)
|
||||||
{
|
{
|
||||||
@ -49,7 +53,9 @@ bool DiskDrive::get_is_track_zero()
|
|||||||
void DiskDrive::step(int direction)
|
void DiskDrive::step(int direction)
|
||||||
{
|
{
|
||||||
_head_position = std::max(_head_position + direction, 0);
|
_head_position = std::max(_head_position + direction, 0);
|
||||||
_time_into_track += get_time_into_next_event();
|
Time extra_time = get_time_into_next_event() / _rotational_multiplier;
|
||||||
|
extra_time.simplify();
|
||||||
|
_time_into_track += extra_time;
|
||||||
set_track(_time_into_track);
|
set_track(_time_into_track);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,10 +64,10 @@ void DiskDrive::set_track(Time initial_offset)
|
|||||||
_track = _disk->get_track_at_position((unsigned int)_head_position);
|
_track = _disk->get_track_at_position((unsigned int)_head_position);
|
||||||
// TODO: probably a better implementation of the empty track?
|
// TODO: probably a better implementation of the empty track?
|
||||||
Time offset;
|
Time offset;
|
||||||
if(_track)
|
if(_track && _time_into_track.length > 0)
|
||||||
{
|
{
|
||||||
Time time_found = _track->seek_to(_time_into_track);
|
Time time_found = _track->seek_to(_time_into_track).simplify();
|
||||||
offset = _time_into_track - time_found;
|
offset = (_time_into_track - time_found).simplify();
|
||||||
_time_into_track = time_found;
|
_time_into_track = time_found;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -72,7 +78,7 @@ void DiskDrive::set_track(Time initial_offset)
|
|||||||
|
|
||||||
reset_timer();
|
reset_timer();
|
||||||
get_next_event();
|
get_next_event();
|
||||||
reset_timer_to_offset(offset);
|
reset_timer_to_offset(offset * _rotational_multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskDrive::run_for_cycles(int number_of_cycles)
|
void DiskDrive::run_for_cycles(int number_of_cycles)
|
||||||
@ -104,11 +110,7 @@ void DiskDrive::get_next_event()
|
|||||||
|
|
||||||
// divide interval, which is in terms of a rotation of the disk, by rotation speed, and
|
// divide interval, which is in terms of a rotation of the disk, by rotation speed, and
|
||||||
// convert it into revolutions per second
|
// convert it into revolutions per second
|
||||||
Time event_interval = _current_event.length;
|
set_next_event_time_interval(_current_event.length * _rotational_multiplier);
|
||||||
event_interval.length *= 60;
|
|
||||||
event_interval.clock_rate *= _revolutions_per_minute;
|
|
||||||
event_interval.simplify();
|
|
||||||
set_next_event_time_interval(event_interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskDrive::process_next_event()
|
void DiskDrive::process_next_event()
|
||||||
|
@ -93,6 +93,7 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
|||||||
unsigned int _clock_rate;
|
unsigned int _clock_rate;
|
||||||
unsigned int _clock_rate_multiplier;
|
unsigned int _clock_rate_multiplier;
|
||||||
unsigned int _revolutions_per_minute;
|
unsigned int _revolutions_per_minute;
|
||||||
|
Time _rotational_multiplier;
|
||||||
|
|
||||||
std::shared_ptr<DigitalPhaseLockedLoop> _pll;
|
std::shared_ptr<DigitalPhaseLockedLoop> _pll;
|
||||||
std::shared_ptr<Disk> _disk;
|
std::shared_ptr<Disk> _disk;
|
||||||
|
@ -86,7 +86,7 @@ Time PCMTrack::seek_to(Time time_since_index_hole)
|
|||||||
unsigned int time_found = time_remaining - (time_remaining % bit_length);
|
unsigned int time_found = time_remaining - (time_remaining % bit_length);
|
||||||
|
|
||||||
// resolve that into the stateful bit count
|
// resolve that into the stateful bit count
|
||||||
_bit_pointer = time_remaining / bit_length;
|
_bit_pointer = 1 + (time_remaining / bit_length);
|
||||||
|
|
||||||
// update and return the time sought to
|
// update and return the time sought to
|
||||||
time_so_far.length += time_found;
|
time_so_far.length += time_found;
|
||||||
|
@ -25,11 +25,12 @@ struct Time {
|
|||||||
Reduces this @c Time to its simplest form — eliminates all common factors from @c length
|
Reduces this @c Time to its simplest form — eliminates all common factors from @c length
|
||||||
and @c clock_rate.
|
and @c clock_rate.
|
||||||
*/
|
*/
|
||||||
inline void simplify()
|
inline Time &simplify()
|
||||||
{
|
{
|
||||||
unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate);
|
unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate);
|
||||||
length /= common_divisor;
|
length /= common_divisor;
|
||||||
clock_rate /= common_divisor;
|
clock_rate /= common_divisor;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -40,12 +41,12 @@ struct Time {
|
|||||||
return (float)length / (float)clock_rate;
|
return (float)length / (float)clock_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator<(Time other)
|
inline bool operator < (Time other)
|
||||||
{
|
{
|
||||||
return other.clock_rate * length < clock_rate * other.length;
|
return other.clock_rate * length < clock_rate * other.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Time operator+(Time other)
|
inline Time operator + (Time other)
|
||||||
{
|
{
|
||||||
Time result;
|
Time result;
|
||||||
result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
||||||
@ -53,7 +54,7 @@ struct Time {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Time &operator +=(Time other)
|
inline Time &operator += (Time other)
|
||||||
{
|
{
|
||||||
unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
||||||
length = length * (combined_clock_rate / clock_rate) + other.length * (combined_clock_rate / other.clock_rate);
|
length = length * (combined_clock_rate / clock_rate) + other.length * (combined_clock_rate / other.clock_rate);
|
||||||
@ -61,7 +62,7 @@ struct Time {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Time operator-(Time other)
|
inline Time operator - (Time other)
|
||||||
{
|
{
|
||||||
Time result;
|
Time result;
|
||||||
result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
result.clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
||||||
@ -69,6 +70,44 @@ struct Time {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Time operator -= (Time other)
|
||||||
|
{
|
||||||
|
unsigned int combined_clock_rate = NumberTheory::least_common_multiple(clock_rate, other.clock_rate);
|
||||||
|
length = length * (combined_clock_rate / clock_rate) - other.length * (combined_clock_rate / other.clock_rate);
|
||||||
|
clock_rate = combined_clock_rate;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Time operator * (Time other)
|
||||||
|
{
|
||||||
|
Time result;
|
||||||
|
result.clock_rate = clock_rate * other.clock_rate;
|
||||||
|
result.length = length * other.length;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Time &operator *= (Time other)
|
||||||
|
{
|
||||||
|
length *= other.length;
|
||||||
|
clock_rate *= other.clock_rate;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Time operator / (Time other)
|
||||||
|
{
|
||||||
|
Time result;
|
||||||
|
result.clock_rate = clock_rate * other.length;
|
||||||
|
result.length = length * other.clock_rate;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Time &operator /= (Time other)
|
||||||
|
{
|
||||||
|
length *= other.clock_rate;
|
||||||
|
clock_rate *= other.length;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline void set_zero()
|
inline void set_zero()
|
||||||
{
|
{
|
||||||
length = 0;
|
length = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user