mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-27 15:29:34 +00:00
commit
88b5f6b148
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
//};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user