From c306d705e1e6fa269186f9deee71ae18a998500d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 26 Jun 2016 19:43:09 -0400 Subject: [PATCH] Made a quick first attempt at all-the-way-through tape wiring for the Vic. --- Components/6522/6522.hpp | 1 + Machines/Vic-20/Vic20.cpp | 31 ++++++++++++++++++++----- Machines/Vic-20/Vic20.hpp | 49 ++++++++++++++++++++++++--------------- Storage/Tape/Tape.cpp | 9 ++++--- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index a9cebfe6f..dec85b13a 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -178,6 +178,7 @@ template class MOS6522 { _registers.interrupt_flags |= port ? InterruptFlag::CB1ActiveEdge : InterruptFlag::CA1ActiveEdge; reevaluate_interrupts(); } + _control_inputs[port].line_one = value; break; case Line::Two: diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Vic-20/Vic20.cpp index a1e030128..66e7ce578 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Vic-20/Vic20.cpp @@ -17,6 +17,7 @@ Machine::Machine() : { _userPortVIA.set_delegate(this); _keyboardVIA.set_delegate(this); + _tape.set_delegate(this); set_reset_line(true); } @@ -83,6 +84,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin _userPortVIA.run_for_half_cycles(2); _keyboardVIA.run_for_half_cycles(2); if(_typer) _typer->update(1); + _tape.run_for_cycles(1); return 1; } @@ -140,12 +142,12 @@ void Machine::add_prg(size_t length, const uint8_t *data) void Machine::set_tape(std::shared_ptr tape) { - tape->get_next_pulse(); - tape->get_next_pulse(); - tape->get_next_pulse(); - tape->get_next_pulse(); - tape->get_next_pulse(); - tape->get_next_pulse(); + _tape.set_tape(tape); +} + +void Machine::tape_did_change_input(Tape *tape) +{ + _keyboardVIA.set_control_line(KeyboardVIA::Port::A, KeyboardVIA::Line::One, tape->get_input()); } #pragma mark - Typer @@ -262,3 +264,20 @@ bool Machine::typer_set_next_character(::Utility::Typer *typer, char character, return true; } + +#pragma mark - Tape + +Tape::Tape() : TapePlayer(1022727) {} + +void Tape::set_motor_control(bool enabled) {} +void Tape::set_tape_output(bool set) {} + +void Tape::process_input_pulse(Storage::Tape::Pulse pulse) +{ + bool new_input_level = pulse.type == Storage::Tape::Pulse::Low; + if(_input_level != new_input_level) + { + _input_level = new_input_level; + if(_delegate) _delegate->tape_did_change_input(this); + } +} diff --git a/Machines/Vic-20/Vic20.hpp b/Machines/Vic-20/Vic20.hpp index fb6d5c007..2412b335c 100644 --- a/Machines/Vic-20/Vic20.hpp +++ b/Machines/Vic-20/Vic20.hpp @@ -49,24 +49,6 @@ enum Key: uint16_t { TerminateSequence = 0, NotMapped = 0xffff }; -class Tape { - public: - void set_motor_control(bool enabled); - void set_tape_output(bool set); - bool get_tape_input(); - bool has_tape(); - - void set_tape(std::shared_ptr tape); - void run_for_cycles(int number_of_cycles); - - private: - struct { - Storage::Tape::Pulse current_pulse; - std::unique_ptr pulse_stepper; - uint32_t time_into_pulse; - } _input; -}; - class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { }; @@ -112,11 +94,36 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg uint8_t _activation_mask; }; +class Tape: public Storage::TapePlayer { + public: + Tape(); + + void set_motor_control(bool enabled); + void set_tape_output(bool set); + inline bool get_input() { return _input_level; } + + class Delegate { + public: + virtual void tape_did_change_input(Tape *tape) = 0; + }; + void set_delegate(Delegate *delegate) + { + _delegate = delegate; + } + + private: + Delegate *_delegate; + virtual void process_input_pulse(Storage::Tape::Pulse pulse); + bool _input_level; +}; + + class Machine: public CPU6502::Processor, public CRTMachine::Machine, public MOS::MOS6522IRQDelegate::Delegate, - public Utility::TypeRecipient { + public Utility::TypeRecipient, + public Tape::Delegate { public: Machine(); @@ -150,6 +157,9 @@ class Machine: virtual int get_typer_frequency(); virtual bool typer_set_next_character(Utility::Typer *typer, char character, int phase); + // for Tape::Delegate + virtual void tape_did_change_input(Tape *tape); + private: uint8_t _characterROM[0x1000]; uint8_t _basicROM[0x2000]; @@ -182,6 +192,7 @@ class Machine: std::unique_ptr _mos6560; UserPortVIA _userPortVIA; KeyboardVIA _keyboardVIA; + Tape _tape; }; } diff --git a/Storage/Tape/Tape.cpp b/Storage/Tape/Tape.cpp index dc8ac86bd..b1a9babde 100644 --- a/Storage/Tape/Tape.cpp +++ b/Storage/Tape/Tape.cpp @@ -51,10 +51,13 @@ void TapePlayer::run_for_cycles(unsigned int number_of_cycles) { if(has_tape()) { - _input.time_into_pulse += (unsigned int)_input.pulse_stepper->step(); - if(_input.time_into_pulse == _input.current_pulse.length.length) + while(number_of_cycles--) { - run_for_input_pulse(); + _input.time_into_pulse += (unsigned int)_input.pulse_stepper->step(); + while(_input.time_into_pulse >= _input.current_pulse.length.length) + { + run_for_input_pulse(); + } } } }