From 7729f1f3d00a3816f78f4c44790e0206422e8c75 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 19 Mar 2021 22:43:48 -0400 Subject: [PATCH] Attempts automatic Spectrum tape control. --- Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 36 ++++++++++++++++++--- Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp | 3 +- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index ff7b46ecc..84d5bd632 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -73,9 +73,6 @@ template class ConcreteMachine: // Insert media. insert_media(target.media); - - // TODO: intelligent motor control (?) - tape_player_.set_motor_control(true); } ~ConcreteMachine() { @@ -217,6 +214,23 @@ template class ConcreteMachine: *cycle.value &= keyboard_.read(address); *cycle.value &= tape_player_.get_input() ? 0xbf : 0xff; + + // If this read is within 200 cycles of the previous, + // count it as an adjacent hit; if 20 of those have + // occurred then start the tape motor. + if(use_automatic_tape_motor_control_) { + if(cycles_since_tape_input_read_ < HalfCycles(400)) { + ++recent_tape_hits_; + + if(recent_tape_hits_ == 20) { + tape_player_.set_motor_control(true); + } + } else { + recent_tape_hits_ = 0; + } + + cycles_since_tape_input_read_ = HalfCycles(0); + } } switch(address) { @@ -248,6 +262,17 @@ template class ConcreteMachine: // TODO: sleeping support here. tape_player_.run_for(duration.as_integral()); + + // Update automatic tape motor control, if enabled; if it's been + // 3 seconds since software last possibly polled the tape, stop it. + if(use_automatic_tape_motor_control_ && cycles_since_tape_input_read_ < HalfCycles(clock_rate() * 6)) { + cycles_since_tape_input_read_ += duration; + + if(cycles_since_tape_input_read_ >= HalfCycles(clock_rate() * 6)) { + tape_player_.set_motor_control(false); + recent_tape_hits_ = 0; + } + } } public: @@ -421,12 +446,13 @@ template class ConcreteMachine: // MARK: - Tape and disc. Storage::Tape::BinaryTapePlayer tape_player_; - bool use_automatic_tape_motor_control_ = false; + bool use_automatic_tape_motor_control_ = true; HalfCycles cycles_since_tape_input_read_; + int recent_tape_hits_ = 0; bool allow_fast_tape_hack_ = false; void set_use_fast_tape() { - + // TODO. } }; diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp index 451dd0e82..693cc3164 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp @@ -35,7 +35,8 @@ class Machine { Options(Configurable::OptionsType type) : Configurable::DisplayOption(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour), - Configurable::QuickloadOption(type == Configurable::OptionsType::UserFriendly) + Configurable::QuickloadOption(type == Configurable::OptionsType::UserFriendly), + automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) { if(needs_declare()) { DeclareField(automatic_tape_motor_control);