mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Converted the TimedEventLoop and the things that sit atop it into ClockReceiver
s.
This commit is contained in:
parent
9bff787ee1
commit
8a2bdb8d22
@ -124,10 +124,11 @@ uint8_t WD1770::get_register(int address) {
|
||||
}
|
||||
}
|
||||
|
||||
void WD1770::run_for_cycles(unsigned int number_of_cycles) {
|
||||
Storage::Disk::Controller::run_for_cycles((int)number_of_cycles);
|
||||
void WD1770::run_for(const Cycles &cycles) {
|
||||
Storage::Disk::Controller::run_for(cycles);
|
||||
|
||||
if(delay_time_) {
|
||||
unsigned int number_of_cycles = (unsigned int)cycles.as_int();
|
||||
if(delay_time_ <= number_of_cycles) {
|
||||
delay_time_ = 0;
|
||||
posit_event(Event::Timer);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "../../Storage/Disk/DiskController.hpp"
|
||||
#include "../../NumberTheory/CRC.hpp"
|
||||
#include "../ClockReceiver.hpp"
|
||||
|
||||
namespace WD {
|
||||
|
||||
@ -18,7 +19,7 @@ namespace WD {
|
||||
Provides an emulation of various Western Digital drive controllers, including the
|
||||
WD1770, WD1772, FDC1773 and FDC1793.
|
||||
*/
|
||||
class WD1770: public Storage::Disk::Controller {
|
||||
class WD1770: public ClockReceiver<WD1770>, public Storage::Disk::Controller {
|
||||
public:
|
||||
enum Personality {
|
||||
P1770, // implies automatic motor-on management, with Type 2 commands offering a spin-up disable
|
||||
@ -43,7 +44,7 @@ class WD1770: public Storage::Disk::Controller {
|
||||
uint8_t get_register(int address);
|
||||
|
||||
/// Runs the controller for @c number_of_cycles cycles.
|
||||
void run_for_cycles(unsigned int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
|
||||
enum Flag: uint8_t {
|
||||
NotReady = 0x80,
|
||||
|
@ -83,7 +83,7 @@ void Machine::run_for_cycles(int number_of_cycles) {
|
||||
CPU::MOS6502::Processor<Machine>::run_for(Cycles(number_of_cycles));
|
||||
set_motor_on(drive_VIA_.get_motor_enabled());
|
||||
if(drive_VIA_.get_motor_enabled()) // TODO: motor speed up/down
|
||||
Storage::Disk::Controller::run_for_cycles(number_of_cycles);
|
||||
Storage::Disk::Controller::run_for(Cycles(number_of_cycles));
|
||||
}
|
||||
|
||||
#pragma mark - 6522 delegate
|
||||
|
@ -187,7 +187,7 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation
|
||||
typer_.reset();
|
||||
}
|
||||
}
|
||||
tape_->run_for_cycles(1);
|
||||
tape_->run_for(Cycles(1));
|
||||
if(c1540_) c1540_->run_for_cycles(1);
|
||||
|
||||
return 1;
|
||||
|
@ -329,7 +329,7 @@ unsigned int Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation
|
||||
}
|
||||
|
||||
if(typer_) typer_->update((int)cycles);
|
||||
if(plus3_) plus3_->run_for_cycles(4*cycles);
|
||||
if(plus3_) plus3_->run_for(Cycles(4*(int)cycles));
|
||||
if(shift_restart_counter_) {
|
||||
shift_restart_counter_ -= cycles;
|
||||
if(shift_restart_counter_ <= 0) {
|
||||
|
@ -84,7 +84,7 @@ void Tape::run_for_cycles(unsigned int number_of_cycles) {
|
||||
if(is_enabled_) {
|
||||
if(is_in_input_mode_) {
|
||||
if(is_running_) {
|
||||
TapePlayer::run_for_cycles((int)number_of_cycles);
|
||||
TapePlayer::run_for(Cycles((int)number_of_cycles));
|
||||
}
|
||||
} else {
|
||||
output_.cycles_into_pulse += number_of_cycles;
|
||||
|
@ -109,7 +109,7 @@ void Microdisc::run_for_cycles(unsigned int number_of_cycles) {
|
||||
head_load_request_counter_ += number_of_cycles;
|
||||
if(head_load_request_counter_ >= head_load_request_counter_target) set_head_loaded(true);
|
||||
}
|
||||
WD::WD1770::run_for_cycles(number_of_cycles);
|
||||
WD::WD1770::run_for(Cycles((int)number_of_cycles));
|
||||
}
|
||||
|
||||
bool Microdisc::get_drive_is_ready() {
|
||||
|
@ -243,7 +243,7 @@ void Machine::VIA::flush() {
|
||||
void Machine::VIA::run_for_cycles(unsigned int number_of_cycles) {
|
||||
cycles_since_ay_update_ += number_of_cycles;
|
||||
MOS::MOS6522<VIA>::run_for_cycles(number_of_cycles);
|
||||
tape->run_for_cycles((int)number_of_cycles);
|
||||
tape->run_for(Cycles((int)number_of_cycles));
|
||||
}
|
||||
|
||||
void Machine::VIA::update_ay() {
|
||||
|
@ -55,7 +55,7 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
||||
|
||||
if(is_zx81_) horizontal_counter_ %= HalfCycles(Cycles(207));
|
||||
if(!tape_advance_delay_) {
|
||||
tape_player_.run_for_cycles(cycle.length.as_int());
|
||||
tape_player_.run_for(cycle.length);
|
||||
} else {
|
||||
tape_advance_delay_ = std::max(tape_advance_delay_ - cycle.length, HalfCycles(0));
|
||||
}
|
||||
|
@ -78,13 +78,13 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
|
||||
|
||||
// find end of lead-in
|
||||
while(shift_register_ == 0x3ff && index_count_ < 2) {
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
}
|
||||
|
||||
// continue for a further nine bits
|
||||
bit_count_ = 0;
|
||||
while(bit_count_ < 9 && index_count_ < 2) {
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
}
|
||||
|
||||
return Storage::Encodings::CommodoreGCR::decoding_from_dectet(shift_register_);
|
||||
@ -92,14 +92,14 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
|
||||
|
||||
unsigned int get_next_byte() {
|
||||
bit_count_ = 0;
|
||||
while(bit_count_ < 10) run_for_cycles(1);
|
||||
while(bit_count_ < 10) run_for(Cycles(1));
|
||||
return Storage::Encodings::CommodoreGCR::decoding_from_dectet(shift_register_);
|
||||
}
|
||||
|
||||
void proceed_to_shift_value(unsigned int shift_value) {
|
||||
index_count_ = 0;
|
||||
while(shift_register_ != shift_value && index_count_ < 2) {
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ void Controller::run_for(const Cycles &cycles) {
|
||||
}
|
||||
}
|
||||
}
|
||||
TimedEventLoop::run_for_cycles(cycles_to_run_for);
|
||||
TimedEventLoop::run_for(Cycles(cycles_to_run_for));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ uint8_t Parser::get_byte_for_shift_value(uint16_t value) {
|
||||
|
||||
uint8_t Parser::get_next_byte() {
|
||||
bit_count_ = 0;
|
||||
while(bit_count_ < 16) run_for_cycles(1);
|
||||
while(bit_count_ < 16) run_for(Cycles(1));
|
||||
uint8_t byte = get_byte_for_shift_value((uint16_t)shift_register_);
|
||||
crc_generator_.add(byte);
|
||||
return byte;
|
||||
@ -309,7 +309,7 @@ std::vector<uint8_t> Parser::get_track() {
|
||||
|
||||
// align to the next index hole
|
||||
index_count_ = 0;
|
||||
while(!index_count_) run_for_cycles(1);
|
||||
while(!index_count_) run_for(Cycles(1));
|
||||
|
||||
// capture every other bit until the next index hole
|
||||
index_count_ = 0;
|
||||
@ -319,7 +319,7 @@ std::vector<uint8_t> Parser::get_track() {
|
||||
bool found_sync = false;
|
||||
while(!index_count_ && !found_sync && bit_count_ < 16) {
|
||||
int previous_bit_count = bit_count_;
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
|
||||
if(!distance_until_permissible_sync && bit_count_ != previous_bit_count) {
|
||||
uint16_t low_shift_register = (shift_register_&0xffff);
|
||||
@ -393,7 +393,7 @@ std::shared_ptr<Sector> Parser::get_next_sector()
|
||||
// look for an ID address mark
|
||||
bool id_found = false;
|
||||
while(!id_found) {
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
if(is_mfm_) {
|
||||
while(shift_register_ == MFMSync) {
|
||||
uint8_t mark = get_next_byte();
|
||||
@ -424,7 +424,7 @@ std::shared_ptr<Sector> Parser::get_next_sector()
|
||||
// look for data mark
|
||||
bool data_found = false;
|
||||
while(!data_found) {
|
||||
run_for_cycles(1);
|
||||
run_for(Cycles(1));
|
||||
if(is_mfm_) {
|
||||
while(shift_register_ == MFMSync) {
|
||||
uint8_t mark = get_next_byte();
|
||||
|
@ -92,9 +92,9 @@ void TapePlayer::get_next_pulse() {
|
||||
set_next_event_time_interval(current_pulse_.length);
|
||||
}
|
||||
|
||||
void TapePlayer::run_for_cycles(int number_of_cycles) {
|
||||
void TapePlayer::run_for(const Cycles &cycles) {
|
||||
if(has_tape()) {
|
||||
TimedEventLoop::run_for_cycles(number_of_cycles);
|
||||
TimedEventLoop::run_for(cycles);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,8 +125,8 @@ bool BinaryTapePlayer::get_input() {
|
||||
return motor_is_running_ && input_level_;
|
||||
}
|
||||
|
||||
void BinaryTapePlayer::run_for_cycles(int number_of_cycles) {
|
||||
if(motor_is_running_) TapePlayer::run_for_cycles(number_of_cycles);
|
||||
void BinaryTapePlayer::run_for(const Cycles &cycles) {
|
||||
if(motor_is_running_) TapePlayer::run_for(cycles);
|
||||
}
|
||||
|
||||
void BinaryTapePlayer::set_delegate(Delegate *delegate) {
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include "../TimedEventLoop.hpp"
|
||||
#include "../../Components/ClockReceiver.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
@ -91,7 +92,7 @@ class Tape {
|
||||
Will call @c process_input_pulse instantaneously upon reaching *the end* of a pulse. Therefore a subclass
|
||||
can decode pulses into data within process_input_pulse, using the supplied pulse's @c length and @c type.
|
||||
*/
|
||||
class TapePlayer: public TimedEventLoop {
|
||||
class TapePlayer: public ClockReceiver<TapePlayer>, public TimedEventLoop {
|
||||
public:
|
||||
TapePlayer(unsigned int input_clock_rate);
|
||||
|
||||
@ -99,7 +100,7 @@ class TapePlayer: public TimedEventLoop {
|
||||
bool has_tape();
|
||||
std::shared_ptr<Storage::Tape::Tape> get_tape();
|
||||
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
void run_for_input_pulse();
|
||||
|
||||
protected:
|
||||
@ -121,14 +122,14 @@ class TapePlayer: public TimedEventLoop {
|
||||
|
||||
They can also provide a delegate to be notified upon any change in the input level.
|
||||
*/
|
||||
class BinaryTapePlayer: public TapePlayer {
|
||||
class BinaryTapePlayer: public ClockReceiver<BinaryTapePlayer>, public TapePlayer {
|
||||
public:
|
||||
BinaryTapePlayer(unsigned int input_clock_rate);
|
||||
void set_motor_control(bool enabled);
|
||||
void set_tape_output(bool set);
|
||||
bool get_input();
|
||||
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
|
||||
class Delegate {
|
||||
public:
|
||||
|
@ -15,8 +15,8 @@ using namespace Storage;
|
||||
TimedEventLoop::TimedEventLoop(unsigned int input_clock_rate) :
|
||||
input_clock_rate_(input_clock_rate) {}
|
||||
|
||||
void TimedEventLoop::run_for_cycles(int number_of_cycles) {
|
||||
cycles_until_event_ -= number_of_cycles;
|
||||
void TimedEventLoop::run_for(const Cycles &cycles) {
|
||||
cycles_until_event_ -= cycles.as_int();
|
||||
while(cycles_until_event_ <= 0) {
|
||||
process_next_event();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include "../SignalProcessing/Stepper.hpp"
|
||||
#include "../Components/ClockReceiver.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
@ -36,7 +37,7 @@ namespace Storage {
|
||||
@c reset_timer to initiate a distinctly-timed stream or @c jump_to_next_event to short-circuit the timing
|
||||
loop and fast forward immediately to the next event.
|
||||
*/
|
||||
class TimedEventLoop {
|
||||
class TimedEventLoop: public ClockReceiver<TimedEventLoop> {
|
||||
public:
|
||||
/*!
|
||||
Constructs a timed event loop that will be clocked at @c input_clock_rate.
|
||||
@ -46,7 +47,7 @@ namespace Storage {
|
||||
/*!
|
||||
Advances the event loop by @c number_of_cycles cycles.
|
||||
*/
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
|
||||
/*!
|
||||
@returns the number of whole cycles remaining until the next event is triggered.
|
||||
|
Loading…
Reference in New Issue
Block a user