diff --git a/Machines/PCCompatible/KeyboardMapper.hpp b/Machines/PCCompatible/KeyboardMapper.hpp new file mode 100644 index 000000000..65f060a60 --- /dev/null +++ b/Machines/PCCompatible/KeyboardMapper.hpp @@ -0,0 +1,104 @@ +// +// KeyboardMapper.hpp +// Clock Signal +// +// Created by Thomas Harte on 24/11/2023. +// Copyright © 2023 Thomas Harte. All rights reserved. +// + +#ifndef KeyboardMapper_hpp +#define KeyboardMapper_hpp + +#include "../KeyboardMachine.hpp" + +namespace PCCompatible { + +class KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper { + public: + uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override { + using k = Inputs::Keyboard::Key; + switch(key) { + case k::Escape: return 1; + + case k::k1: return 2; + case k::k2: return 3; + case k::k3: return 4; + case k::k4: return 5; + case k::k5: return 6; + case k::k6: return 7; + case k::k7: return 8; + case k::k8: return 9; + case k::k9: return 10; + case k::k0: return 11; + + case k::Hyphen: return 12; + case k::Equals: return 13; + case k::Backspace: return 14; + + case k::Tab: return 15; + case k::Q: return 16; + case k::W: return 17; + case k::E: return 18; + case k::R: return 19; + case k::T: return 20; + case k::Y: return 21; + case k::U: return 22; + case k::I: return 23; + case k::O: return 24; + case k::P: return 25; + + case k::OpenSquareBracket: return 26; + case k::CloseSquareBracket: return 27; + case k::Enter: return 28; + + case k::LeftControl: + case k::RightControl: return 29; + + case k::A: return 30; + case k::S: return 31; + case k::D: return 32; + case k::F: return 33; + case k::G: return 34; + case k::H: return 35; + case k::J: return 36; + case k::K: return 37; + case k::L: return 38; + + case k::Semicolon: return 39; + case k::Quote: return 40; + case k::BackTick: return 41; + + case k::LeftShift: return 42; + case k::Backslash: return 43; + + case k::Z: return 55; + case k::X: return 45; + case k::C: return 46; + case k::V: return 47; + case k::B: return 48; + case k::N: return 49; + case k::M: return 50; + + case k::Comma: return 51; + case k::FullStop: return 52; + case k::ForwardSlash: return 53; + case k::RightShift: return 54; + + case k::LeftOption: + case k::RightOption: return 56; + case k::Space: return 57; + case k::CapsLock: return 58; + + case k::NumLock: return 69; + case k::ScrollLock: return 70; + + default: return MachineTypes::MappedKeyboardMachine::KeyNotMapped; + } + + // TODO: extended functions, including all F keys and cursors. + } +}; + +} + +#endif /* KeyboardMapper_hpp */ diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index 67eaf41ba..370b70c52 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -9,6 +9,7 @@ #include "PCCompatible.hpp" #include "DMA.hpp" +#include "KeyboardMapper.hpp" #include "PIC.hpp" #include "PIT.hpp" @@ -27,6 +28,7 @@ #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" #include "../AudioProducer.hpp" +#include "../KeyboardMachine.hpp" #include "../ScanProducer.hpp" #include "../TimedMachine.hpp" @@ -82,12 +84,15 @@ class KeyboardController { return key; } - private: void post(uint8_t value) { + if(mode_ == Mode::NoIRQsIgnoreInput) { + return; + } input_ = value; pic_.apply_edge<1>(true); } + private: enum class Mode { NormalOperation = 0b01, NoIRQsIgnoreInput = 0b11, @@ -900,7 +905,8 @@ class ConcreteMachine: public Machine, public MachineTypes::TimedMachine, public MachineTypes::AudioProducer, - public MachineTypes::ScanProducer + public MachineTypes::ScanProducer, + public MachineTypes::MappedKeyboardMachine { public: ConcreteMachine( @@ -1049,6 +1055,15 @@ class ConcreteMachine: } } + // MARK: - MappedKeyboardMachine. + MappedKeyboardMachine::KeyboardMapper *get_keyboard_mapper() override { + return &keyboard_mapper_; + } + + void set_key_state(uint16_t key, bool is_pressed) override { + keyboard_.post(uint8_t(key | (is_pressed ? 0x00 : 0x80))); + } + private: PIC pic_; DMA dma_; @@ -1062,6 +1077,8 @@ class ConcreteMachine: PIT pit_; PPI ppi_; + PCCompatible::KeyboardMapper keyboard_mapper_; + struct Context { Context(PIT &pit, DMA &dma, PPI &ppi, PIC &pic, MDA &mda) : segments(registers), diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 464c16bdd..80effae5b 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1145,6 +1145,7 @@ 4267A9C72B0C26FA008A59BB /* PIT.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PIT.hpp; sourceTree = ""; }; 4267A9C82B0D4EC2008A59BB /* PIC.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PIC.hpp; sourceTree = ""; }; 4267A9C92B0D4F17008A59BB /* DMA.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMA.hpp; sourceTree = ""; }; + 4267A9CA2B111ED2008A59BB /* KeyboardMapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KeyboardMapper.hpp; sourceTree = ""; }; 4281572E2AA0334300E16AA1 /* Carry.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Carry.hpp; sourceTree = ""; }; 428168372A16C25C008ECD27 /* LineLayout.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineLayout.hpp; sourceTree = ""; }; 428168392A37AFB4008ECD27 /* DispatcherTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatcherTests.mm; sourceTree = ""; }; @@ -2368,6 +2369,7 @@ 4267A9C72B0C26FA008A59BB /* PIT.hpp */, 4267A9C82B0D4EC2008A59BB /* PIC.hpp */, 4267A9C92B0D4F17008A59BB /* DMA.hpp */, + 4267A9CA2B111ED2008A59BB /* KeyboardMapper.hpp */, ); path = PCCompatible; sourceTree = "";