1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Post key actions to the nominated serial line.

Albeit that I'm still thinking through whether I want the option of including a clock on Serial::Line. It'd be natural in one sense — there's already one built in — but might weaken Serial::Line's claim to be a one-stop shop for both enqueued and real-time connections without a reasonable bit of extra work.
This commit is contained in:
Thomas Harte 2021-11-06 12:03:09 -07:00
parent f102d8a4b4
commit c0c2b5e3a9
5 changed files with 152 additions and 18 deletions

View File

@ -23,6 +23,7 @@
#include "../../Outputs/Log.hpp"
#include "Chipset.hpp"
#include "Keyboard.hpp"
#include "MemoryMap.hpp"
namespace {
@ -39,6 +40,7 @@ namespace Amiga {
class ConcreteMachine:
public Activity::Source,
public CPU::MC68000::BusHandler,
public MachineTypes::MappedKeyboardMachine,
public MachineTypes::MediaTarget,
public MachineTypes::MouseMachine,
public MachineTypes::ScanProducer,
@ -201,7 +203,22 @@ class ConcreteMachine:
Inputs::Mouse &get_mouse() final {
return chipset_.get_mouse();;
}
};
// MARK: - Keyboard.
Amiga::KeyboardMapper keyboard_mapper_;
KeyboardMapper *get_keyboard_mapper() {
return &keyboard_mapper_;
}
void set_key_state(uint16_t key, bool is_pressed) {
chipset_.get_keyboard().set_key_state(key, is_pressed);
}
void clear_all_keys() {
chipset_.get_keyboard().clear_all_keys();
}
};
}

View File

@ -79,7 +79,8 @@ Chipset::Chipset(MemoryMap &map, int input_clock_rate) :
cia_a(cia_a_handler_),
cia_b(cia_b_handler_),
disk_(DMA_CONSTRUCT),
disk_controller_(Cycles(input_clock_rate), *this, disk_, cia_b) {
disk_controller_(Cycles(input_clock_rate), *this, disk_, cia_b),
keyboard_(cia_a.serial_input) {
disk_controller_.set_clocking_hint_observer(this);
}

View File

@ -28,6 +28,7 @@
#include "Copper.hpp"
#include "DMADevice.hpp"
#include "Flags.hpp"
#include "Keyboard.hpp"
#include "MemoryMap.hpp"
namespace Amiga {
@ -95,6 +96,10 @@ class Chipset: private ClockingHint::Observer {
disk_controller_.set_activity_observer(observer);
}
Keyboard &get_keyboard() {
return keyboard_;
}
private:
friend class DMADeviceBase;
@ -447,6 +452,10 @@ class Chipset: private ClockingHint::Observer {
void set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference) final;
bool disk_controller_is_sleeping_ = false;
uint16_t paula_disk_control_ = 0;
// MARK: - Keyboard.
Keyboard keyboard_;
};
}

View File

@ -42,7 +42,11 @@
using namespace Amiga;
uint8_t Keyboard::update(uint8_t input) {
Keyboard::Keyboard(Serial::Line &output) : output_(output) {
output_.set_writer_clock_rate(HalfCycles(1'000'000)); // Use µs.
}
/*uint8_t Keyboard::update(uint8_t input) {
// If a bit transmission is ongoing, continue that, up to and including
// the handshake. If no handshake comes, set a macro state of synchronising.
switch(shift_state_) {
@ -89,4 +93,89 @@ uint8_t Keyboard::update(uint8_t input) {
}
return lines_;
}*/
void Keyboard::set_key_state(uint16_t key, bool is_pressed) {
output_.write<false>(
HalfCycles(60),
uint8_t(((key << 1) | (is_pressed ? 0 : 1)) ^ 0xff)
);
}
void Keyboard::clear_all_keys() {
}
// MARK: - KeyboardMapper.
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return uint16_t(Key::dest)
#define DIRECTBIND(source) BIND(source, source)
switch(key) {
default: break;
DIRECTBIND(Escape);
DIRECTBIND(Delete);
DIRECTBIND(F1); DIRECTBIND(F2); DIRECTBIND(F3); DIRECTBIND(F4); DIRECTBIND(F5);
DIRECTBIND(F6); DIRECTBIND(F7); DIRECTBIND(F8); DIRECTBIND(F9); DIRECTBIND(F10);
BIND(BackTick, Tilde);
DIRECTBIND(k1); DIRECTBIND(k2); DIRECTBIND(k3); DIRECTBIND(k4); DIRECTBIND(k5);
DIRECTBIND(k6); DIRECTBIND(k7); DIRECTBIND(k8); DIRECTBIND(k9); DIRECTBIND(k0);
DIRECTBIND(Hyphen);
DIRECTBIND(Equals);
DIRECTBIND(Backslash);
DIRECTBIND(Backspace);
DIRECTBIND(Tab);
DIRECTBIND(CapsLock);
BIND(LeftControl, Control);
BIND(RightControl, Control);
DIRECTBIND(LeftShift);
DIRECTBIND(RightShift);
BIND(LeftOption, Alt);
BIND(RightOption, Alt);
BIND(LeftMeta, LeftAmiga);
BIND(RightMeta, RightAmiga);
DIRECTBIND(Q); DIRECTBIND(W); DIRECTBIND(E); DIRECTBIND(R); DIRECTBIND(T);
DIRECTBIND(Y); DIRECTBIND(U); DIRECTBIND(I); DIRECTBIND(O); DIRECTBIND(P);
DIRECTBIND(A); DIRECTBIND(S); DIRECTBIND(D); DIRECTBIND(F); DIRECTBIND(G);
DIRECTBIND(H); DIRECTBIND(J); DIRECTBIND(K); DIRECTBIND(L); DIRECTBIND(Z);
DIRECTBIND(X); DIRECTBIND(C); DIRECTBIND(V); DIRECTBIND(B); DIRECTBIND(N);
DIRECTBIND(M);
DIRECTBIND(OpenSquareBracket);
DIRECTBIND(CloseSquareBracket);
DIRECTBIND(Help);
BIND(Insert, Help);
BIND(Home, Help);
BIND(End, Help);
BIND(Enter, Return);
DIRECTBIND(Semicolon);
DIRECTBIND(Quote);
DIRECTBIND(Comma);
DIRECTBIND(FullStop);
DIRECTBIND(ForwardSlash);
DIRECTBIND(Space);
DIRECTBIND(Up);
DIRECTBIND(Down);
DIRECTBIND(Left);
DIRECTBIND(Right);
DIRECTBIND(Keypad0); DIRECTBIND(Keypad1); DIRECTBIND(Keypad2);
DIRECTBIND(Keypad3); DIRECTBIND(Keypad4); DIRECTBIND(Keypad5);
DIRECTBIND(Keypad6); DIRECTBIND(Keypad7); DIRECTBIND(Keypad8);
DIRECTBIND(Keypad9);
DIRECTBIND(KeypadDecimalPoint);
DIRECTBIND(KeypadMinus);
DIRECTBIND(KeypadEnter);
}
#undef DIRECTBIND
#undef BIND
return MachineTypes::MappedKeyboardMachine::KeyNotMapped;
}

View File

@ -6,10 +6,12 @@
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Keyboard_hpp
#define Keyboard_hpp
#ifndef Machines_Amiga_Keyboard_hpp
#define Machines_Amiga_Keyboard_hpp
#include <cstdint>
#include "../KeyboardMachine.hpp"
#include "../../Components/Serial/Line.hpp"
namespace Amiga {
@ -41,8 +43,8 @@ enum class Key: uint16_t {
X = 0x32, C = 0x33, V = 0x34, B = 0x35, N = 0x36,
M = 0x37,
OpenSquareBrackets = 0x1a,
CloseSquareBrackets = 0x1b,
OpenSquareBracket = 0x1a,
CloseSquareBracket = 0x1b,
Help = 0x5f,
Return = 0x44,
Semicolon = 0x29,
@ -57,21 +59,35 @@ enum class Key: uint16_t {
Up = 0x4c, Left = 0x4f, Right = 0x4e, Down = 0x4d,
KeyPad7 = 0x3d, KeyPad8 = 0x3e, KeyPad9 = 0x3f,
KeyPad4 = 0x2d, KeyPad5 = 0x2e, KeyPad6 = 0x2f,
KeyPad1 = 0x1d, KeyPad2 = 0x1e, KeyPad3 = 0x1f,
KeyPad0 = 0x0f, KeyPadDecimalPoint = 0x3c,
KeyPadMinus = 0x4a, KeyPadEnter = 0x43,
Keypad7 = 0x3d, Keypad8 = 0x3e, Keypad9 = 0x3f,
Keypad4 = 0x2d, Keypad5 = 0x2e, Keypad6 = 0x2f,
Keypad1 = 0x1d, Keypad2 = 0x1e, Keypad3 = 0x1f,
Keypad0 = 0x0f, KeypadDecimalPoint = 0x3c,
KeypadMinus = 0x4a, KeypadEnter = 0x43,
KeypadOpenBracket = 0x5a,
KeypadCloseBracket = 0x5b,
KeypadDivide = 0x5c,
KeypadMultiply = 0x5d,
KeypadPlus = 0x5e,
};
struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final;
};
class Keyboard {
public:
enum Lines: uint8_t {
Data = (1 << 0),
Clock = (1 << 1),
};
Keyboard(Serial::Line &output);
uint8_t update(uint8_t);
// enum Lines: uint8_t {
// Data = (1 << 0),
// Clock = (1 << 1),
// };
//
// uint8_t update(uint8_t);
void set_key_state(uint16_t, bool);
void clear_all_keys();
private:
enum class ShiftState {
@ -89,8 +105,10 @@ class Keyboard {
int bits_remaining_ = 0;
uint8_t lines_ = 0;
Serial::Line &output_;
};
}
#endif /* Keyboard_hpp */
#endif /* Machines_Amiga_Keyboard_hpp */