2016-01-18 21:46:41 +00:00
|
|
|
//
|
|
|
|
// Tape.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 18/01/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "Tape.hpp"
|
2016-07-29 09:19:01 +00:00
|
|
|
#include "../../NumberTheory/Factors.hpp"
|
2016-01-18 21:46:41 +00:00
|
|
|
|
2016-08-27 21:18:12 +00:00
|
|
|
using namespace Storage::Tape;
|
2016-01-18 21:46:41 +00:00
|
|
|
|
2016-09-11 21:09:00 +00:00
|
|
|
#pragma mark - Lifecycle
|
2016-06-26 23:03:57 +00:00
|
|
|
|
|
|
|
TapePlayer::TapePlayer(unsigned int input_clock_rate) :
|
2016-07-29 11:15:46 +00:00
|
|
|
TimedEventLoop(input_clock_rate)
|
2016-06-26 23:03:57 +00:00
|
|
|
{}
|
|
|
|
|
2016-09-11 21:09:00 +00:00
|
|
|
#pragma mark - Seeking
|
|
|
|
|
|
|
|
void Storage::Tape::Tape::seek(Time &seek_time)
|
|
|
|
{
|
|
|
|
_current_time.set_zero();
|
|
|
|
_next_time.set_zero();
|
|
|
|
while(_next_time < seek_time) get_next_pulse();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Storage::Tape::Tape::reset()
|
|
|
|
{
|
|
|
|
_current_time.set_zero();
|
|
|
|
_next_time.set_zero();
|
|
|
|
virtual_reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
Tape::Pulse Tape::get_next_pulse()
|
|
|
|
{
|
|
|
|
Tape::Pulse pulse = virtual_get_next_pulse();
|
|
|
|
_current_time = _next_time;
|
|
|
|
_next_time += pulse.length;
|
|
|
|
return pulse;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - Player
|
|
|
|
|
2016-08-27 21:09:45 +00:00
|
|
|
void TapePlayer::set_tape(std::shared_ptr<Storage::Tape::Tape> tape)
|
2016-06-26 23:03:57 +00:00
|
|
|
{
|
|
|
|
_tape = tape;
|
2016-07-29 11:15:46 +00:00
|
|
|
reset_timer();
|
2016-06-26 23:03:57 +00:00
|
|
|
get_next_pulse();
|
|
|
|
}
|
|
|
|
|
2016-09-13 02:22:23 +00:00
|
|
|
std::shared_ptr<Storage::Tape::Tape> TapePlayer::get_tape()
|
|
|
|
{
|
|
|
|
return _tape;
|
|
|
|
}
|
|
|
|
|
2016-06-26 23:03:57 +00:00
|
|
|
bool TapePlayer::has_tape()
|
|
|
|
{
|
|
|
|
return (bool)_tape;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TapePlayer::get_next_pulse()
|
|
|
|
{
|
2016-07-29 09:19:01 +00:00
|
|
|
// get the new pulse
|
2016-06-26 23:03:57 +00:00
|
|
|
if(_tape)
|
2016-07-29 11:15:46 +00:00
|
|
|
_current_pulse = _tape->get_next_pulse();
|
2016-06-26 23:03:57 +00:00
|
|
|
else
|
|
|
|
{
|
2016-07-29 11:15:46 +00:00
|
|
|
_current_pulse.length.length = 1;
|
|
|
|
_current_pulse.length.clock_rate = 1;
|
2016-08-27 21:09:45 +00:00
|
|
|
_current_pulse.type = Tape::Pulse::Zero;
|
2016-06-26 23:03:57 +00:00
|
|
|
}
|
2016-07-29 09:19:01 +00:00
|
|
|
|
2016-07-29 11:15:46 +00:00
|
|
|
set_next_event_time_interval(_current_pulse.length);
|
2016-06-26 23:03:57 +00:00
|
|
|
}
|
|
|
|
|
2016-07-29 15:03:09 +00:00
|
|
|
void TapePlayer::run_for_cycles(int number_of_cycles)
|
2016-06-26 23:03:57 +00:00
|
|
|
{
|
|
|
|
if(has_tape())
|
|
|
|
{
|
2016-08-27 21:18:12 +00:00
|
|
|
TimedEventLoop::run_for_cycles(number_of_cycles);
|
2016-06-26 23:03:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TapePlayer::run_for_input_pulse()
|
|
|
|
{
|
2016-07-29 11:15:46 +00:00
|
|
|
jump_to_next_event();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TapePlayer::process_next_event()
|
|
|
|
{
|
|
|
|
process_input_pulse(_current_pulse);
|
2016-06-26 23:03:57 +00:00
|
|
|
get_next_pulse();
|
|
|
|
}
|
2016-10-20 23:33:25 +00:00
|
|
|
|
|
|
|
#pragma mark - Binary Player
|
|
|
|
|
|
|
|
BinaryTapePlayer::BinaryTapePlayer(unsigned int input_clock_rate) :
|
|
|
|
TapePlayer(input_clock_rate), _motor_is_running(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void BinaryTapePlayer::set_motor_control(bool enabled)
|
|
|
|
{
|
|
|
|
_motor_is_running = enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BinaryTapePlayer::set_tape_output(bool set)
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BinaryTapePlayer::get_input()
|
|
|
|
{
|
|
|
|
return _input_level;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BinaryTapePlayer::run_for_cycles(int number_of_cycles)
|
|
|
|
{
|
|
|
|
if(_motor_is_running) TapePlayer::run_for_cycles(number_of_cycles);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BinaryTapePlayer::set_delegate(Delegate *delegate)
|
|
|
|
{
|
|
|
|
_delegate = delegate;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BinaryTapePlayer::process_input_pulse(Storage::Tape::Tape::Pulse pulse)
|
|
|
|
{
|
|
|
|
bool new_input_level = pulse.type == Tape::Pulse::Low;
|
|
|
|
if(_input_level != new_input_level)
|
|
|
|
{
|
|
|
|
_input_level = new_input_level;
|
|
|
|
if(_delegate) _delegate->tape_did_change_input(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|