1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-01 22:41:32 +00:00

Fixes mouse input when a button is pressed; attempts keyboard input.

I think the VIA is somehow sending spurious commands.
This commit is contained in:
Thomas Harte 2019-07-02 21:14:33 -04:00
parent 191a7a9386
commit 96c0253ee2
4 changed files with 138 additions and 14 deletions

View File

@ -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 <vector>
#include <set>
@ -75,4 +75,4 @@ class Keyboard {
}
#endif /* Keyboard_hpp */
#endif /* Inputs_Keyboard_hpp */

View File

@ -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 <mutex>
#include <vector>
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<decltype(key_queue_mutex_)> 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<decltype(key_queue_mutex_)> 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<uint8_t> 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 */

View File

@ -18,6 +18,7 @@
#include "Video.hpp"
#include "../../CRTMachine.hpp"
#include "../../KeyboardMachine.hpp"
#include "../../MediaTarget.hpp"
#include "../../MouseMachine.hpp"
@ -49,7 +50,8 @@ template <Analyser::Static::Macintosh::Target::Model model> 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 <Analyser::Static::Macintosh::Target::Model model> 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 <Analyser::Static::Macintosh::Target::Model model> 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 <Analyser::Static::Macintosh::Target::Model model> 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];

View File

@ -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 {