1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Implements most of keyboard input.

This commit is contained in:
Thomas Harte 2019-11-02 22:30:02 -04:00
parent f93cdd21de
commit f40dbefa67
3 changed files with 130 additions and 4 deletions

View File

@ -9,6 +9,7 @@
#include "AtariST.hpp"
#include "../CRTMachine.hpp"
#include "../KeyboardMachine.hpp"
#include "../MouseMachine.hpp"
//#define LOG_TRACE
@ -45,7 +46,8 @@ class ConcreteMachine:
public Motorola::ACIA::ACIA::InterruptDelegate,
public Motorola::MFP68901::MFP68901::InterruptDelegate,
public DMAController::InterruptDelegate,
public MouseMachine::Machine {
public MouseMachine::Machine,
public KeyboardMachine::MappedMachine {
public:
ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
mc68000_(*this),
@ -488,7 +490,18 @@ class ConcreteMachine:
Inputs::Mouse &get_mouse() final {
return ikbd_;
}
};
// MARK: - KeyboardMachine
void set_key_state(uint16_t key, bool is_pressed) final {
ikbd_.set_key_state(Key(key), is_pressed);
}
IntelligentKeyboard::KeyboardMapper keyboard_mapper_;
KeyboardMapper *get_keyboard_mapper() final {
return &keyboard_mapper_;
}
};
}
}

View File

@ -58,6 +58,16 @@ void IntelligentKeyboard::run_for(HalfCycles duration) {
}
// Forward key changes; implicit assumption here: mutexs are cheap while there's
// negligible contention.
{
std::lock_guard<decltype(key_queue_mutex_)> guard(key_queue_mutex_);
for(uint8_t key: key_queue_) {
output_bytes({key});
}
key_queue_.clear();
}
output_line_.advance_writer(duration);
}
@ -66,8 +76,6 @@ void IntelligentKeyboard::output_bytes(std::initializer_list<uint8_t> values) {
for(auto value : values) {
output_line_.write(2, 10, 0x200 | (value << 1));
}
// TODO: this isn't thread safe! Might need this class to imply a poll?
update_clocking_observer();
}
@ -225,6 +233,77 @@ void IntelligentKeyboard::post_relative_mouse_event(int x, int y) {
} while(x || y);
}
// MARK: - Keyboard Input
void IntelligentKeyboard::set_key_state(Key key, bool is_pressed) {
std::lock_guard<decltype(key_queue_mutex_)> guard(key_queue_mutex_);
if(is_pressed) {
key_queue_.push_back(uint8_t(key));
} else {
key_queue_.push_back(0x80 | uint8_t(key));
}
}
uint16_t IntelligentKeyboard::KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) {
using Key = Inputs::Keyboard::Key;
using STKey = Atari::ST::Key;
switch(key) {
default: return KeyboardMachine::MappedMachine::KeyNotMapped;
#define Bind(x, y) case Key::x: return uint16_t(STKey::y)
#define QBind(x) case Key::x: return uint16_t(STKey::x)
QBind(k1); QBind(k2); QBind(k3); QBind(k4); QBind(k5); QBind(k6); QBind(k7); QBind(k8); QBind(k9); QBind(k0);
QBind(Q); QBind(W); QBind(E); QBind(R); QBind(T); QBind(Y); QBind(U); QBind(I); QBind(O); QBind(P);
QBind(A); QBind(S); QBind(D); QBind(F); QBind(G); QBind(H); QBind(J); QBind(K); QBind(L);
QBind(Z); QBind(X); QBind(C); QBind(V); QBind(B); QBind(N); QBind(M);
QBind(Left); QBind(Right); QBind(Up); QBind(Down);
QBind(BackTick); QBind(Tab);
QBind(Hyphen); QBind(Equals); QBind(Backspace);
QBind(OpenSquareBracket);
QBind(CloseSquareBracket);
QBind(CapsLock);
QBind(Semicolon);
QBind(Quote);
Bind(Enter, Return);
QBind(LeftShift);
QBind(RightShift);
Bind(Comma, Comma);
Bind(FullStop, FullStop);
Bind(ForwardSlash, ForwardSlash);
Bind(LeftOption, Alt);
Bind(RightOption, Alt);
QBind(Space);
QBind(Backslash);
/* Bind(KeyPadDelete, KeyPadDelete);
Bind(KeyPadEquals, KeyPadEquals);
Bind(KeyPadSlash, KeyPadSlash);
Bind(KeyPadAsterisk, KeyPadAsterisk);
Bind(KeyPadMinus, KeyPadMinus);
Bind(KeyPadPlus, KeyPadPlus);
Bind(KeyPadEnter, KeyPadEnter);
Bind(KeyPadDecimalPoint, KeyPadDecimalPoint);
Bind(KeyPad9, KeyPad9);
Bind(KeyPad8, KeyPad8);
Bind(KeyPad7, KeyPad7);
Bind(KeyPad6, KeyPad6);
Bind(KeyPad5, KeyPad5);
Bind(KeyPad4, KeyPad4);
Bind(KeyPad3, KeyPad3);
Bind(KeyPad2, KeyPad2);
Bind(KeyPad1, KeyPad1);
Bind(KeyPad0, KeyPad0);*/
#undef QBind
#undef Bind
}
}
// MARK: - Mouse Input
void IntelligentKeyboard::move(int x, int y) {
@ -252,3 +331,4 @@ void IntelligentKeyboard::reset_all_buttons() {
// MARK: - Joystick Output
void IntelligentKeyboard::disable_joysticks() {
}

View File

@ -11,14 +11,38 @@
#include "../../ClockReceiver/ClockingHintSource.hpp"
#include "../../Components/SerialPort/SerialPort.hpp"
#include "../KeyboardMachine.hpp"
#include "../../Inputs/Mouse.hpp"
#include <atomic>
#include <mutex>
namespace Atari {
namespace ST {
enum class Key: uint16_t {
Escape = 1,
k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, Hyphen, Equals, Backspace,
Tab, Q, W, E, R, T, Y, U, I, O, P, OpenSquareBracket, CloseSquareBracket, Return,
Control, A, S, D, F, G, H, J, K, L, Semicolon, Quote, BackTick,
LeftShift, Backslash, Z, X, C, V, B, N, M, Comma, FullStop, ForwardSlash, RightShift,
/* 0x37 is unused. */
Alt = 0x38, Space, CapsLock, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,
/* Various gaps follow. */
Home = 0x47, Up,
KeypadMinus = 0x4a, Left,
Right = 0x4d, KeypadPlus,
Down = 0x50,
Insert = 0x52, Delete,
ISO = 0x60, Undo, Help, KeypadOpenBracket, KeypadCloseBracket, KeypadDivide, KeypadMultiply,
Keypad7, Keypad8, Keypad9, Keypad4, KeyPad5, Keypad6, Keypad1, Keypad2, Keypad3, Keypad0, KeypadDecimalPoint,
KeypadEnter
};
static_assert(uint16_t(Key::RightShift) == 0x36, "RightShift should have key code 0x36; check intermediate entries");
static_assert(uint16_t(Key::F10) == 0x44, "F10 should have key code 0x44; check intermediate entries");
static_assert(uint16_t(Key::KeypadEnter) == 0x72, "KeypadEnter should have key code 0x72; check intermediate entries");
/*!
A receiver for the Atari ST's "intelligent keyboard" commands, which actually cover
keyboard input and output and mouse handling.
@ -32,7 +56,16 @@ class IntelligentKeyboard:
ClockingHint::Preference preferred_clocking() final;
void run_for(HalfCycles duration);
void set_key_state(Key key, bool is_pressed);
class KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) final;
};
private:
// MARK: - Key queue.
std::mutex key_queue_mutex_;
std::vector<uint8_t> key_queue_;
// MARK: - Serial line state.
int bit_count_ = 0;
int command_ = 0;