From 2860be706842ca55800cacf1ad4a92929d46d04f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 31 Jan 2021 12:25:22 -0500 Subject: [PATCH] Permit a longer pause at startup for Electron commands that start with shift, control or func. --- Machines/AmstradCPC/AmstradCPC.cpp | 2 +- Machines/Electron/Electron.cpp | 13 +++++++++++-- Machines/Electron/Keyboard.hpp | 6 +++++- Machines/Utility/Typer.hpp | 4 ++-- Machines/ZX8081/ZX8081.cpp | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 15aae6c87..485bc162c 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -1089,7 +1089,7 @@ template class ConcreteMachine: return Utility::TypeRecipient::can_type(c); } - HalfCycles get_typer_delay() const final { + HalfCycles get_typer_delay(const std::string &) const final { return z80_.get_is_resetting() ? Cycles(3'400'000) : Cycles(0); } diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 80bc3ccf7..4344e44a4 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -452,8 +452,17 @@ class ConcreteMachine: evaluate_interrupts(); } - HalfCycles get_typer_delay() const final { - return m6502_.get_is_resetting() ? Cycles(750'000) : Cycles(0); + HalfCycles get_typer_delay(const std::string &text) const final { + if(!m6502_.get_is_resetting()) { + return Cycles(0); + } + + // Add a longer delay for a command at reset that involves pressing a modifier; + // empirically this seems to be a requirement, in order to avoid a collision with + // the system's built-in modifier-at-startup test (e.g. to perform shift+break). + CharacterMapper test_mapper; + const uint16_t *const sequence = test_mapper.sequence_for_character(text[0]); + return is_modifier(Key(sequence[0])) ? Cycles(1'000'000) : Cycles(750'000); } HalfCycles get_typer_frequency() const final { diff --git a/Machines/Electron/Keyboard.hpp b/Machines/Electron/Keyboard.hpp index d41f6500c..3583bd55d 100644 --- a/Machines/Electron/Keyboard.hpp +++ b/Machines/Electron/Keyboard.hpp @@ -31,11 +31,15 @@ enum Key: uint16_t { KeyShift = 0x00d0 | 0x08, KeyControl = 0x00d0 | 0x04, KeyFunc = 0x00d0 | 0x02, KeyEscape = 0x00d0 | 0x01, // Virtual keys. - KeyF1 = 0xfff0, KeyF2, KeyF3, KeyF4, KeyF5, KeyF6, KeyF7, KeyF8, KeyF9, KeyF0, + KeyF1 = 0xfff0, KeyF2, KeyF3, KeyF4, KeyF5, KeyF6, KeyF7, KeyF8, KeyF9, KeyF0, KeyBreak = 0xfffd, }; +constexpr bool is_modifier(Key key) { + return (key == KeyShift) || (key == KeyControl) || (key == KeyFunc); +} + struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper { uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final; }; diff --git a/Machines/Utility/Typer.hpp b/Machines/Utility/Typer.hpp index 5ca3bd57d..d6bdc80f7 100644 --- a/Machines/Utility/Typer.hpp +++ b/Machines/Utility/Typer.hpp @@ -109,7 +109,7 @@ class TypeRecipient: public Typer::Delegate { /// Attaches a typer to this class that will type @c string using @c character_mapper as a source. void add_typer(const std::string &string) { if(!typer_) { - typer_ = std::make_unique(string, get_typer_delay(), get_typer_frequency(), character_mapper, this); + typer_ = std::make_unique(string, get_typer_delay(string), get_typer_frequency(), character_mapper, this); } else { typer_->append(string); } @@ -137,7 +137,7 @@ class TypeRecipient: public Typer::Delegate { typer_ = nullptr; } - virtual HalfCycles get_typer_delay() const { return HalfCycles(0); } + virtual HalfCycles get_typer_delay(const std::string &) const { return HalfCycles(0); } virtual HalfCycles get_typer_frequency() const { return HalfCycles(0); } std::unique_ptr typer_; diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index eb7912bd0..ee64335a4 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -387,7 +387,7 @@ template class ConcreteMachine: } // MARK: - Typer timing - HalfCycles get_typer_delay() const final { + HalfCycles get_typer_delay(const std::string &) const final { return z80_.get_is_resetting() ? Cycles(7'000'000) : Cycles(0); }