mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Took some small steps towards having a disk drive that at least can select a track and pump relevant events into a PLL.
This commit is contained in:
parent
0e581c7607
commit
f984de42a3
@ -13,17 +13,21 @@ using namespace Storage;
|
|||||||
DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) :
|
DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) :
|
||||||
_clock_rate(clock_rate),
|
_clock_rate(clock_rate),
|
||||||
_revolutions_per_minute(revolutions_per_minute),
|
_revolutions_per_minute(revolutions_per_minute),
|
||||||
_head_position(0) {}
|
_head_position(0),
|
||||||
|
|
||||||
|
TimedEventLoop(clock_rate)
|
||||||
|
{}
|
||||||
|
|
||||||
void DiskDrive::set_expected_bit_length(Time bit_length)
|
void DiskDrive::set_expected_bit_length(Time bit_length)
|
||||||
{
|
{
|
||||||
_bit_length = bit_length;
|
_bit_length = bit_length;
|
||||||
|
// _pll.reset(new DigitalPhaseLockedLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskDrive::set_disk(std::shared_ptr<Disk> disk)
|
void DiskDrive::set_disk(std::shared_ptr<Disk> disk)
|
||||||
{
|
{
|
||||||
_disk = disk;
|
_disk = disk;
|
||||||
// _track.reset();
|
set_track();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskDrive::has_disk()
|
bool DiskDrive::has_disk()
|
||||||
@ -39,21 +43,65 @@ 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);
|
||||||
_track = _disk->get_track_at_position((unsigned int)_head_position);
|
set_track();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskDrive::digital_phase_locked_loop_output_bit(int value)
|
void DiskDrive::set_track()
|
||||||
{
|
{
|
||||||
process_input_bit(value, _cycles_since_index_hole);
|
_track = _disk->get_track_at_position((unsigned int)_head_position);
|
||||||
|
reset_timer();
|
||||||
|
get_next_event();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskDrive::run_for_cycles(unsigned int number_of_cycles)
|
void DiskDrive::run_for_cycles(unsigned int number_of_cycles)
|
||||||
{
|
{
|
||||||
if(has_disk())
|
if(has_disk())
|
||||||
{
|
{
|
||||||
while(number_of_cycles--)
|
_cycles_since_index_hole += number_of_cycles;
|
||||||
{
|
TimedEventLoop::run_for_cycles(number_of_cycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Track timed event loop
|
||||||
|
|
||||||
|
void DiskDrive::get_next_event()
|
||||||
|
{
|
||||||
|
if(_track)
|
||||||
|
_current_event = _track->get_next_event();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_current_event.length.length = 1;
|
||||||
|
_current_event.length.clock_rate = 1;
|
||||||
|
_current_event.type = Track::Event::IndexHole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// divide interval, which is in terms of a rotation of the disk, by rotation speed, and
|
||||||
|
// convert it into revolutions per second
|
||||||
|
Time event_interval = _current_event.length;
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
switch(_current_event.type)
|
||||||
|
{
|
||||||
|
case Track::Event::FluxTransition:
|
||||||
|
_pll->add_pulse();
|
||||||
|
break;
|
||||||
|
case Track::Event::IndexHole:
|
||||||
|
_cycles_since_index_hole = 0;
|
||||||
|
process_index_hole();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
get_next_event();
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - PLL delegate
|
||||||
|
|
||||||
|
void DiskDrive::digital_phase_locked_loop_output_bit(int value)
|
||||||
|
{
|
||||||
|
process_input_bit(value, _cycles_since_index_hole);
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
|
|
||||||
#include "Disk.hpp"
|
#include "Disk.hpp"
|
||||||
#include "DigitalPhaseLockedLoop.hpp"
|
#include "DigitalPhaseLockedLoop.hpp"
|
||||||
#include "../../SignalProcessing/Stepper.hpp"
|
#include "../TimedEventLoop.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
|
class DiskDrive: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop {
|
||||||
public:
|
public:
|
||||||
DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute);
|
DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute);
|
||||||
|
|
||||||
@ -37,6 +37,9 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
|
|||||||
virtual void process_input_bit(int value, unsigned int cycles_since_index_hole) = 0;
|
virtual void process_input_bit(int value, unsigned int cycles_since_index_hole) = 0;
|
||||||
virtual void process_index_hole() = 0;
|
virtual void process_index_hole() = 0;
|
||||||
|
|
||||||
|
// for TimedEventLoop
|
||||||
|
virtual void process_next_event();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Time _bit_length;
|
Time _bit_length;
|
||||||
unsigned int _clock_rate;
|
unsigned int _clock_rate;
|
||||||
@ -47,14 +50,10 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
|
|||||||
std::shared_ptr<Track> _track;
|
std::shared_ptr<Track> _track;
|
||||||
int _head_position;
|
int _head_position;
|
||||||
unsigned int _cycles_since_index_hole;
|
unsigned int _cycles_since_index_hole;
|
||||||
|
void set_track();
|
||||||
|
|
||||||
void install_track();
|
inline void get_next_event();
|
||||||
|
Track::Event _current_event;
|
||||||
struct {
|
|
||||||
Track::Event current_event;
|
|
||||||
std::unique_ptr<SignalProcessing::Stepper> pulse_stepper;
|
|
||||||
uint32_t time_into_pulse;
|
|
||||||
} _input;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,19 @@
|
|||||||
#ifndef Storage_hpp
|
#ifndef Storage_hpp
|
||||||
#define Storage_hpp
|
#define Storage_hpp
|
||||||
|
|
||||||
|
#include "../NumberTheory/Factors.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
struct Time {
|
struct Time {
|
||||||
unsigned int length, clock_rate;
|
unsigned int length, clock_rate;
|
||||||
|
|
||||||
|
inline void simplify()
|
||||||
|
{
|
||||||
|
unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate);
|
||||||
|
length /= common_divisor;
|
||||||
|
clock_rate /= common_divisor;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user