From 96c0253ee2ab191c098e29d853d5bb3248183bb2 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 2 Jul 2019 21:14:33 -0400 Subject: [PATCH] Fixes mouse input when a button is pressed; attempts keyboard input. I think the VIA is somehow sending spurious commands. --- Inputs/Keyboard.hpp | 6 +- Machines/Apple/Macintosh/Keyboard.hpp | 124 +++++++++++++++++++++++-- Machines/Apple/Macintosh/Macintosh.cpp | 20 +++- Machines/Electron/Keyboard.hpp | 2 +- 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/Inputs/Keyboard.hpp b/Inputs/Keyboard.hpp index e6f0f07b6..7b2481dab 100644 --- a/Inputs/Keyboard.hpp +++ b/Inputs/Keyboard.hpp @@ -6,8 +6,8 @@ // Copyright 2017 Thomas Harte. All rights reserved. // -#ifndef Keyboard_hpp -#define Keyboard_hpp +#ifndef Inputs_Keyboard_hpp +#define Inputs_Keyboard_hpp #include #include @@ -75,4 +75,4 @@ class Keyboard { } -#endif /* Keyboard_hpp */ +#endif /* Inputs_Keyboard_hpp */ diff --git a/Machines/Apple/Macintosh/Keyboard.hpp b/Machines/Apple/Macintosh/Keyboard.hpp index 7d2df18b4..d2ce08f21 100644 --- a/Machines/Apple/Macintosh/Keyboard.hpp +++ b/Machines/Apple/Macintosh/Keyboard.hpp @@ -6,8 +6,13 @@ // Copyright © 2019 Thomas Harte. All rights reserved. // -#ifndef Keyboard_hpp -#define Keyboard_hpp +#ifndef Apple_Macintosh_Keyboard_hpp +#define Apple_Macintosh_Keyboard_hpp + +#include "../../KeyboardMachine.hpp" + +#include +#include namespace Apple { namespace Macintosh { @@ -126,15 +131,25 @@ class Keyboard { } } + void enqueue_key_state(uint16_t key, bool is_pressed) { + // Front insert; messages will be pop_back'd. + std::lock_guard lock(key_queue_mutex_); + key_queue_.insert(key_queue_.begin(), (is_pressed ? 0x00 : 0x80) | uint8_t(key)); + } + private: int perform_command(int command) { switch(command) { - case 0x10: // Inquiry. - break; - - case 0x14: // Instant. - break; + case 0x10: // Inquiry. + case 0x14: { // Instant. + std::lock_guard lock(key_queue_mutex_); + if(!key_queue_.empty()) { + const auto new_message = key_queue_.back(); + key_queue_.pop_back(); + return new_message; + } + } break; case 0x16: // Model number. return @@ -162,9 +177,102 @@ class Keyboard { bool data_input_ = false; bool clock_output_ = false; + + // TODO: improve this very, very simple implementation. + std::mutex key_queue_mutex_; + std::vector key_queue_; +}; + +/*! + Provides a mapping from idiomatic PC keys to Macintosh keys. +*/ +class KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper { + uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) override { + using Key = Inputs::Keyboard::Key; + switch(key) { + default: return KeyboardMachine::MappedMachine::KeyNotMapped; + + /* + See p284 of the Apple Guide to the Macintosh Family Hardware + for documentation of the mapping below. + */ + + case Key::BackTick: return 0x65; + case Key::k1: return 0x25; + case Key::k2: return 0x27; + case Key::k3: return 0x29; + case Key::k4: return 0x2b; + case Key::k5: return 0x2f; + case Key::k6: return 0x2d; + case Key::k7: return 0x35; + case Key::k8: return 0x39; + case Key::k9: return 0x33; + case Key::k0: return 0x3b; + case Key::Hyphen: return 0x37; + case Key::Equals: return 0x31; + case Key::BackSpace: return 0x67; + + case Key::Tab: return 0x61; + case Key::Q: return 0x19; + case Key::W: return 0x1b; + case Key::E: return 0x1d; + case Key::R: return 0x1f; + case Key::T: return 0x23; + case Key::Y: return 0x21; + case Key::U: return 0x41; + case Key::I: return 0x45; + case Key::O: return 0x3f; + case Key::P: return 0x47; + case Key::OpenSquareBracket: return 0x43; + case Key::CloseSquareBracket: return 0x3d; + + case Key::CapsLock: return 0x73; + case Key::A: return 0x01; + case Key::S: return 0x03; + case Key::D: return 0x05; + case Key::F: return 0x07; + case Key::G: return 0x0b; + case Key::H: return 0x09; + case Key::J: return 0x4d; + case Key::K: return 0x51; + case Key::L: return 0x4b; + case Key::Semicolon: return 0x53; + case Key::Quote: return 0x4f; + case Key::Enter: return 0x49; + + case Key::LeftShift: return 0x71; + case Key::Z: return 0x0d; + case Key::X: return 0x0f; + case Key::C: return 0x11; + case Key::V: return 0x13; + case Key::B: return 0x17; + case Key::N: return 0x5b; + case Key::M: return 0x5d; + case Key::Comma: return 0x57; + case Key::FullStop: return 0x5f; + case Key::ForwardSlash: return 0x59; + case Key::RightShift: return 0x71; + + case Key::Left: return 0x0d; + case Key::Right: return 0x05; + case Key::Up: return 0x1b; + case Key::Down: return 0x11; + + case Key::LeftOption: + case Key::RightOption: return 0x75; + case Key::LeftMeta: + case Key::RightMeta: return 0x6f; + + case Key::Space: return 0x63; + case Key::BackSlash: return 0x55; + + /* TODO: the numeric keypad. */ + } + } + }; } } -#endif /* Keyboard_h */ +#endif /* Apple_Macintosh_Keyboard_hpp */ diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index a4651f697..79483ff73 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -18,6 +18,7 @@ #include "Video.hpp" #include "../../CRTMachine.hpp" +#include "../../KeyboardMachine.hpp" #include "../../MediaTarget.hpp" #include "../../MouseMachine.hpp" @@ -49,7 +50,8 @@ template class ConcreteMachin public CRTMachine::Machine, public MediaTarget::Machine, public MouseMachine::Machine, - public CPU::MC68000::BusHandler { + public CPU::MC68000::BusHandler, + public KeyboardMachine::MappedMachine { public: using Target = Analyser::Static::Macintosh::Target; @@ -396,6 +398,18 @@ template class ConcreteMachin return true; } + // MARK: Keyboard input. + + KeyboardMapper *get_keyboard_mapper() override { + return &keyboard_mapper_; + } + + void set_key_state(uint16_t key, bool is_pressed) override { + keyboard_.enqueue_key_state(key, is_pressed); + } + + // TODO: clear all keys. + private: Inputs::Mouse &get_mouse() override { return mouse_; @@ -475,7 +489,7 @@ template class ConcreteMachin case Port::B: return uint8_t( - (mouse_.get_button_mask() & 1) ? 0x00 : 0x08 | + ((mouse_.get_button_mask() & 1) ? 0x00 : 0x08) | ((mouse_.get_channel(0) & 2) << 3) | ((mouse_.get_channel(1) & 2) << 4) | (clock_.get_data() ? 0x02 : 0x00) | @@ -545,6 +559,8 @@ template class ConcreteMachin SonyDrive drives_[2]; Inputs::QuadratureMouse mouse_; + Apple::Macintosh::KeyboardMapper keyboard_mapper_; + uint32_t ram_mask_ = 0; uint32_t rom_mask_ = 0; uint16_t rom_[64*1024]; diff --git a/Machines/Electron/Keyboard.hpp b/Machines/Electron/Keyboard.hpp index a0e23e7c4..ee1ae0588 100644 --- a/Machines/Electron/Keyboard.hpp +++ b/Machines/Electron/Keyboard.hpp @@ -34,7 +34,7 @@ enum Key: uint16_t { }; struct KeyboardMapper: public KeyboardMachine::MappedMachine::KeyboardMapper { - uint16_t mapped_key_for_key(Inputs::Keyboard::Key key); + uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) override; }; struct CharacterMapper: public ::Utility::CharacterMapper {