1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-27 15:29:34 +00:00

Merge pull request #1437 from TomHarte/Plus4Typer

Add TED typer.
This commit is contained in:
Thomas Harte 2025-01-03 21:31:56 -05:00 committed by GitHub
commit 88b5f6b148
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 111 additions and 81 deletions

View File

@ -58,77 +58,79 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const {
return MachineTypes::MappedKeyboardMachine::KeyNotMapped; return MachineTypes::MappedKeyboardMachine::KeyNotMapped;
} }
//const uint16_t *CharacterMapper::sequence_for_character(char character) const { const uint16_t *CharacterMapper::sequence_for_character(char character) const {
//#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} constexpr KeySequence X = { MachineTypes::MappedKeyboardMachine::KeyNotMapped };
//#define SHIFT(...) {KeyLShift, __VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence} const auto key = [](Key k) -> KeySequence {
//#define X {MachineTypes::MappedKeyboardMachine::KeyNotMapped} return { k, MachineTypes::MappedKeyboardMachine::KeyEndSequence };
// static KeySequence key_sequences[] = { };
// /* NUL */ X, /* SOH */ X, const auto shift = [](Key k) -> KeySequence {
// /* STX */ X, /* ETX */ X, return { Key::Shift, k, MachineTypes::MappedKeyboardMachine::KeyEndSequence };
// /* EOT */ X, /* ENQ */ X, };
// /* ACK */ X, /* BEL */ X,
// /* BS */ KEYS(KeyDelete), /* HT */ X, static KeySequence key_sequences[] = {
// /* LF */ KEYS(KeyReturn), /* VT */ X, /* NUL */ X, /* SOH */ X,
// /* FF */ X, /* CR */ X, /* STX */ X, /* ETX */ X,
// /* SO */ X, /* SI */ X, /* EOT */ X, /* ENQ */ X,
// /* DLE */ X, /* DC1 */ X, /* ACK */ X, /* BEL */ X,
// /* DC2 */ X, /* DC3 */ X, /* BS */ key(Key::InsDel), /* HT */ X,
// /* DC4 */ X, /* NAK */ X, /* LF */ key(Key::Return), /* VT */ X,
// /* SYN */ X, /* ETB */ X, /* FF */ X, /* CR */ X,
// /* CAN */ X, /* EM */ X, /* SO */ X, /* SI */ X,
// /* SUB */ X, /* ESC */ X, /* DLE */ X, /* DC1 */ X,
// /* FS */ X, /* GS */ X, /* DC2 */ X, /* DC3 */ X,
// /* RS */ X, /* US */ X, /* DC4 */ X, /* NAK */ X,
// /* space */ KEYS(KeySpace), /* ! */ SHIFT(Key1), /* SYN */ X, /* ETB */ X,
// /* " */ SHIFT(Key2), /* # */ SHIFT(Key3), /* CAN */ X, /* EM */ X,
// /* $ */ SHIFT(Key4), /* % */ SHIFT(Key5), /* SUB */ X, /* ESC */ X,
// /* & */ SHIFT(Key6), /* ' */ SHIFT(Key7), /* FS */ X, /* GS */ X,
// /* ( */ SHIFT(Key8), /* ) */ SHIFT(Key9), /* RS */ X, /* US */ X,
// /* * */ KEYS(KeyAsterisk), /* + */ KEYS(KeyPlus), /* space */ key(Key::Space), /* ! */ shift(Key::k1),
// /* , */ KEYS(KeyComma), /* - */ KEYS(KeyDash), /* " */ shift(Key::k2), /* # */ shift(Key::k3),
// /* . */ KEYS(KeyFullStop), /* / */ KEYS(KeySlash), /* $ */ shift(Key::k4), /* % */ shift(Key::k5),
// /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), /* & */ shift(Key::k6), /* ' */ shift(Key::k7),
// /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), /* ( */ shift(Key::k8), /* ) */ shift(Key::k9),
// /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), /* * */ key(Key::Asterisk), /* + */ key(Key::Plus),
// /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), /* , */ key(Key::Comma), /* - */ key(Key::Minus),
// /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), /* . */ key(Key::FullStop), /* / */ key(Key::Slash),
// /* : */ KEYS(KeyColon), /* ; */ KEYS(KeySemicolon), /* 0 */ key(Key::k0), /* 1 */ key(Key::k1),
// /* < */ SHIFT(KeyComma), /* = */ KEYS(KeyEquals), /* 2 */ key(Key::k2), /* 3 */ key(Key::k3),
// /* > */ SHIFT(KeyFullStop), /* ? */ SHIFT(KeySlash), /* 4 */ key(Key::k4), /* 5 */ key(Key::k5),
// /* @ */ KEYS(KeyAt), /* A */ KEYS(KeyA), /* 6 */ key(Key::k6), /* 7 */ key(Key::k7),
// /* B */ KEYS(KeyB), /* C */ KEYS(KeyC), /* 8 */ key(Key::k8), /* 9 */ key(Key::k9),
// /* D */ KEYS(KeyD), /* E */ KEYS(KeyE), /* : */ key(Key::Colon), /* ; */ key(Key::Semicolon),
// /* F */ KEYS(KeyF), /* G */ KEYS(KeyG), /* < */ shift(Key::Comma), /* = */ key(Key::Equals),
// /* H */ KEYS(KeyH), /* I */ KEYS(KeyI), /* > */ shift(Key::FullStop), /* ? */ shift(Key::Slash),
// /* J */ KEYS(KeyJ), /* K */ KEYS(KeyK), /* @ */ key(Key::At), /* A */ key(Key::A),
// /* L */ KEYS(KeyL), /* M */ KEYS(KeyM), /* B */ key(Key::B), /* C */ key(Key::C),
// /* N */ KEYS(KeyN), /* O */ KEYS(KeyO), /* D */ key(Key::D), /* E */ key(Key::E),
// /* P */ KEYS(KeyP), /* Q */ KEYS(KeyQ), /* F */ key(Key::F), /* G */ key(Key::G),
// /* R */ KEYS(KeyR), /* S */ KEYS(KeyS), /* H */ key(Key::H), /* I */ key(Key::I),
// /* T */ KEYS(KeyT), /* U */ KEYS(KeyU), /* J */ key(Key::J), /* K */ key(Key::K),
// /* V */ KEYS(KeyV), /* W */ KEYS(KeyW), /* L */ key(Key::L), /* M */ key(Key::M),
// /* X */ KEYS(KeyX), /* Y */ KEYS(KeyY), /* N */ key(Key::N), /* O */ key(Key::O),
// /* Z */ KEYS(KeyZ), /* [ */ SHIFT(KeyColon), /* P */ key(Key::P), /* Q */ key(Key::Q),
// /* \ */ X, /* ] */ SHIFT(KeySemicolon), /* R */ key(Key::R), /* S */ key(Key::S),
// /* ^ */ X, /* _ */ X, /* T */ key(Key::T), /* U */ key(Key::U),
// /* ` */ X, /* a */ KEYS(KeyA), /* V */ key(Key::V), /* W */ key(Key::W),
// /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), /* X */ key(Key::X), /* Y */ key(Key::Y),
// /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), /* Z */ key(Key::Z), /* [ */ shift(Key::Colon),
// /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), /* \ */ X, /* ] */ shift(Key::Semicolon),
// /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), /* ^ */ X, /* _ */ X,
// /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), /* ` */ X, /* a */ key(Key::A),
// /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), /* b */ key(Key::B), /* c */ key(Key::C),
// /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), /* d */ key(Key::D), /* e */ key(Key::E),
// /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), /* f */ key(Key::F), /* g */ key(Key::G),
// /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), /* h */ key(Key::H), /* i */ key(Key::I),
// /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), /* j */ key(Key::J), /* k */ key(Key::K),
// /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), /* l */ key(Key::L), /* m */ key(Key::M),
// /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), /* n */ key(Key::N), /* o */ key(Key::O),
// /* z */ KEYS(KeyZ) /* p */ key(Key::P), /* q */ key(Key::Q),
// }; /* r */ key(Key::R), /* s */ key(Key::S),
//#undef KEYS /* t */ key(Key::T), /* u */ key(Key::U),
//#undef SHIFT /* v */ key(Key::V), /* w */ key(Key::W),
//#undef X /* x */ key(Key::X), /* y */ key(Key::Y),
// /* z */ key(Key::Z)
// return table_lookup_sequence_for_character(key_sequences, character); };
//}
return table_lookup_sequence_for_character(key_sequences, character);
}

View File

@ -75,8 +75,8 @@ struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMappe
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final; uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final;
}; };
//struct CharacterMapper: public ::Utility::CharacterMapper { struct CharacterMapper: public ::Utility::CharacterMapper {
// const uint16_t *sequence_for_character(char character) const final; const uint16_t *sequence_for_character(char character) const final;
//}; };
} }

View File

@ -24,6 +24,8 @@
#include "../SerialBus.hpp" #include "../SerialBus.hpp"
#include "../1540/C1540.hpp" #include "../1540/C1540.hpp"
#include <algorithm>
using namespace Commodore; using namespace Commodore;
using namespace Commodore::Plus4; using namespace Commodore::Plus4;
@ -128,7 +130,8 @@ class ConcreteMachine:
public MachineTypes::TimedMachine, public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer, public MachineTypes::ScanProducer,
public MachineTypes::MediaTarget, public MachineTypes::MediaTarget,
public Machine { public Machine,
public Utility::TypeRecipient<CharacterMapper> {
public: public:
ConcreteMachine(const Analyser::Static::Commodore::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : ConcreteMachine(const Analyser::Static::Commodore::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
m6502_(*this), m6502_(*this),
@ -176,7 +179,9 @@ public:
tape_player_ = std::make_unique<Storage::Tape::BinaryTapePlayer>(clock); tape_player_ = std::make_unique<Storage::Tape::BinaryTapePlayer>(clock);
insert_media(target.media); insert_media(target.media);
printf("Loading command is: %s\n", target.loading_command.c_str()); // if(!target.loading_command.empty()) {
// type_string(target.loading_command);
// }
} }
~ConcreteMachine() { ~ConcreteMachine() {
@ -320,6 +325,16 @@ public:
case 0xff05: timers_.write<5>(*value); break; case 0xff05: timers_.write<5>(*value); break;
case 0xff08: case 0xff08:
// Observation here: the kernel posts a 0 to this
// address upon completing each keyboard scan cycle,
// once per frame.
if(typer_ && !*value) {
if(!typer_->type_next_character()) {
clear_all_keys();
typer_.reset();
}
}
keyboard_latch_ = ~( keyboard_latch_ = ~(
((*value & 0x01) ? 0x00 : key_states_[0]) | ((*value & 0x01) ? 0x00 : key_states_[0]) |
((*value & 0x02) ? 0x00 : key_states_[1]) | ((*value & 0x02) ? 0x00 : key_states_[1]) |
@ -505,6 +520,14 @@ private:
return &keyboard_mapper_; return &keyboard_mapper_;
} }
void type_string(const std::string &string) final {
Utility::TypeRecipient<CharacterMapper>::add_typer(string);
}
bool can_type(const char c) const final {
return Utility::TypeRecipient<CharacterMapper>::can_type(c);
}
void set_key_state(uint16_t key, bool is_pressed) override { void set_key_state(uint16_t key, bool is_pressed) override {
if(is_pressed) { if(is_pressed) {
key_states_[line(key)] |= mask(key); key_states_[line(key)] |= mask(key);
@ -513,6 +536,10 @@ private:
} }
} }
void clear_all_keys() final {
std::fill(key_states_.begin(), key_states_.end(), 0);
}
std::array<uint8_t, 8> key_states_{}; std::array<uint8_t, 8> key_states_{};
uint8_t keyboard_latch_ = 0xff; uint8_t keyboard_latch_ = 0xff;

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <array>
#include <memory> #include <memory>
#include <string> #include <string>
@ -40,7 +41,7 @@ class CharacterMapper {
virtual bool needs_pause_after_key([[maybe_unused]] uint16_t key) const { return true; } virtual bool needs_pause_after_key([[maybe_unused]] uint16_t key) const { return true; }
protected: protected:
typedef uint16_t KeySequence[16]; using KeySequence = std::array<uint16_t, 16>;
/*! /*!
Provided in the base class as a convenience: given the C array of key sequences @c sequences, Provided in the base class as a convenience: given the C array of key sequences @c sequences,
@ -50,7 +51,7 @@ class CharacterMapper {
std::size_t ucharacter = size_t((unsigned char)character); std::size_t ucharacter = size_t((unsigned char)character);
if(ucharacter >= sizeof(sequences) / sizeof(KeySequence)) return nullptr; if(ucharacter >= sizeof(sequences) / sizeof(KeySequence)) return nullptr;
if(sequences[ucharacter][0] == MachineTypes::MappedKeyboardMachine::KeyNotMapped) return nullptr; if(sequences[ucharacter][0] == MachineTypes::MappedKeyboardMachine::KeyNotMapped) return nullptr;
return sequences[ucharacter]; return sequences[ucharacter].data();
} }
}; };