1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Formally separates keyboard code.

With an eye to formalising the Spectrum/ZX81/ZX80 differences.
This commit is contained in:
Thomas Harte 2021-03-19 10:36:08 -04:00
parent 93b9ea67e6
commit 2371048ad1
5 changed files with 76 additions and 38 deletions

View File

@ -10,10 +10,12 @@
#include <cstring>
using namespace Sinclair::ZX8081;
using namespace Sinclair::ZX::Keyboard;
KeyboardMapper::KeyboardMapper(Machine machine) : machine_(machine) {}
uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const {
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return ZX8081::dest
#define BIND(source, dest) case Inputs::Keyboard::Key::source: return dest
switch(key) {
default: break;
@ -44,7 +46,7 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const {
return MachineTypes::MappedKeyboardMachine::KeyNotMapped;
}
CharacterMapper::CharacterMapper(bool is_zx81) : is_zx81_(is_zx81) {}
CharacterMapper::CharacterMapper(Machine machine) : machine_(machine) {}
const uint16_t *CharacterMapper::sequence_for_character(char character) const {
#define KEYS(...) {__VA_ARGS__, MachineTypes::MappedKeyboardMachine::KeyEndSequence}
@ -185,17 +187,21 @@ const uint16_t *CharacterMapper::sequence_for_character(char character) const {
#undef SHIFT
#undef X
if(is_zx81_)
switch(machine_) {
case Machine::ZX81:
case Machine::ZXSpectrum: // TODO: some differences exist for the Spectrum.
return table_lookup_sequence_for_character(zx81_key_sequences, sizeof(zx81_key_sequences), character);
else
case Machine::ZX80:
return table_lookup_sequence_for_character(zx80_key_sequences, sizeof(zx80_key_sequences), character);
}
}
bool CharacterMapper::needs_pause_after_key(uint16_t key) const {
return key != KeyShift;
}
Keyboard::Keyboard(bool is_zx81) : is_zx81_(is_zx81) {
Keyboard::Keyboard(Machine machine) : machine_(machine) {
clear_all_keys();
}
@ -217,7 +223,7 @@ void Keyboard::set_key_state(uint16_t key, bool is_pressed) {
ShiftedKey(KeyDown, Key6);
ShiftedKey(KeyLeft, Key5);
ShiftedKey(KeyRight, Key8);
ShiftedKey(KeyEdit, is_zx81_ ? Key1 : KeyEnter);
ShiftedKey(KeyEdit, (machine_ == Machine::ZX80) ? KeyEnter : Key1);
#undef ShiftedKey
}

View File

@ -13,7 +13,12 @@
#include "../../Utility/Typer.hpp"
namespace Sinclair {
namespace ZX8081 {
namespace ZX {
namespace Keyboard {
enum class Machine {
ZX80, ZX81, ZXSpectrum
};
enum Key: uint16_t {
KeyShift = 0x0000 | 0x01, KeyZ = 0x0000 | 0x02, KeyX = 0x0000 | 0x04, KeyC = 0x0000 | 0x08, KeyV = 0x0000 | 0x10,
@ -23,41 +28,53 @@ enum Key: uint16_t {
Key0 = 0x0400 | 0x01, Key9 = 0x0400 | 0x02, Key8 = 0x0400 | 0x04, Key7 = 0x0400 | 0x08, Key6 = 0x0400 | 0x10,
KeyP = 0x0500 | 0x01, KeyO = 0x0500 | 0x02, KeyI = 0x0500 | 0x04, KeyU = 0x0500 | 0x08, KeyY = 0x0500 | 0x10,
KeyEnter = 0x0600 | 0x01, KeyL = 0x0600 | 0x02, KeyK = 0x0600 | 0x04, KeyJ = 0x0600 | 0x08, KeyH = 0x0600 | 0x10,
KeySpace = 0x0700 | 0x01, KeyDot = 0x0700 | 0x02, KeyM = 0x0700 | 0x04, KeyN = 0x0700 | 0x08, KeyB = 0x0700 | 0x10,
KeySpace = 0x0700 | 0x01, KeyM = 0x0700 | 0x04, KeyN = 0x0700 | 0x08, KeyB = 0x0700 | 0x10,
// Add some virtual keys; these do not exist on a real ZX80 or ZX81. They're just a convenience.
// The ZX80 and ZX81 keyboards have a full stop; the ZX Spectrum replaces that key with symbol shift.
KeyDot = 0x0700 | 0x02, KeySymbolShift = KeyDot,
// Add some virtual keys; these do not exist on a real ZX80, ZX81 or early Spectrum, those all were added to the 128kb Spectrums.
// Either way, they're a convenience.
KeyDelete = 0x0801,
KeyBreak, KeyLeft, KeyRight, KeyUp, KeyDown, KeyEdit
};
struct Keyboard {
Keyboard(bool is_zx81);
class Keyboard {
public:
Keyboard(Machine machine);
void set_key_state(uint16_t key, bool is_pressed);
void clear_all_keys();
void set_key_state(uint16_t key, bool is_pressed);
void clear_all_keys();
uint8_t read(uint16_t address);
uint8_t read(uint16_t address);
private:
uint8_t key_states_[8];
const bool is_zx81_;
const Machine machine_;
};
struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper {
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override;
class KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper {
public:
KeyboardMapper(Machine machine);
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override;
private:
const Machine machine_;
};
class CharacterMapper: public ::Utility::CharacterMapper {
public:
CharacterMapper(bool is_zx81);
CharacterMapper(Machine machine);
const uint16_t *sequence_for_character(char character) const override;
bool needs_pause_after_key(uint16_t key) const override;
private:
bool is_zx81_;
const Machine machine_;
};
}
}
}

View File

@ -24,7 +24,7 @@
#include "../../../Analyser/Static/ZX8081/Target.hpp"
#include "Keyboard.hpp"
#include "../Keyboard/Keyboard.hpp"
#include "Video.hpp"
#include <cstdint>
@ -49,6 +49,8 @@ enum ROMType: uint8_t {
ZX80 = 0, ZX81
};
using CharacterMapper = Sinclair::ZX::Keyboard::CharacterMapper;
template<bool is_zx81> class ConcreteMachine:
public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer,
@ -61,9 +63,10 @@ template<bool is_zx81> class ConcreteMachine:
public Machine {
public:
ConcreteMachine(const Analyser::Static::ZX8081::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
Utility::TypeRecipient<CharacterMapper>(is_zx81),
Utility::TypeRecipient<CharacterMapper>(keyboard_machine()),
z80_(*this),
keyboard_(is_zx81),
keyboard_(keyboard_machine()),
keyboard_mapper_(keyboard_machine()),
tape_player_(ZX8081ClockRate),
ay_(GI::AY38910::Personality::AY38910, audio_queue_),
speaker_(ay_) {
@ -341,6 +344,10 @@ template<bool is_zx81> class ConcreteMachine:
keyboard_.clear_all_keys();
}
static constexpr Sinclair::ZX::Keyboard::Machine keyboard_machine() {
return is_zx81 ? Sinclair::ZX::Keyboard::Machine::ZX81 : Sinclair::ZX::Keyboard::Machine::ZX80;
}
// MARK: - Tape control
void set_use_automatic_tape_motor_control(bool enabled) {
@ -418,8 +425,8 @@ template<bool is_zx81> class ConcreteMachine:
bool vsync_ = false, hsync_ = false;
int line_counter_ = 0;
Keyboard keyboard_;
ZX8081::KeyboardMapper keyboard_mapper_;
Sinclair::ZX::Keyboard::Keyboard keyboard_;
Sinclair::ZX::Keyboard::KeyboardMapper keyboard_mapper_;
HalfClockReceiver<Storage::Tape::BinaryTapePlayer> tape_player_;
Storage::Tape::ZX8081::Parser parser_;

View File

@ -30,8 +30,7 @@
#include "../../../ClockReceiver/JustInTime.hpp"
// TODO: Factor this file into an appropriate place and namespace.
#include "../ZX8081/Keyboard.hpp"
#include "../Keyboard/Keyboard.hpp"
#include <array>
@ -52,7 +51,8 @@ template<Model model> class ConcreteMachine:
audio_toggle_(audio_queue_),
mixer_(ay_, audio_toggle_),
speaker_(mixer_),
keyboard_(true)
keyboard_(Sinclair::ZX::Keyboard::Machine::ZXSpectrum),
keyboard_mapper_(Sinclair::ZX::Keyboard::Machine::ZXSpectrum)
{
set_clock_rate(clock_rate());
speaker_.set_input_rate(float(clock_rate()) / 2.0f);
@ -355,8 +355,8 @@ template<Model model> class ConcreteMachine:
JustInTimeActor<Video<video_timing>> video_;
// MARK: - Keyboard.
Sinclair::ZX8081::Keyboard keyboard_;
ZX8081::KeyboardMapper keyboard_mapper_;
Sinclair::ZX::Keyboard::Keyboard keyboard_;
Sinclair::ZX::Keyboard::KeyboardMapper keyboard_mapper_;
};

View File

@ -128,10 +128,10 @@
4B0F1BDE2602FF9900B85C66 /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCD2602F17B00B85C66 /* Video.cpp */; };
4B0F1BE22602FF9C00B85C66 /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCC2602F17B00B85C66 /* ZX8081.cpp */; };
4B0F1BE62602FF9D00B85C66 /* ZX8081.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCC2602F17B00B85C66 /* ZX8081.cpp */; };
4B0F1BEA2602FFA000B85C66 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCF2602F17B00B85C66 /* Keyboard.cpp */; };
4B0F1BEB2602FFA100B85C66 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BCF2602F17B00B85C66 /* Keyboard.cpp */; };
4B0F1BFC260300D900B85C66 /* ZXSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BFA260300D900B85C66 /* ZXSpectrum.cpp */; };
4B0F1BFD260300D900B85C66 /* ZXSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1BFA260300D900B85C66 /* ZXSpectrum.cpp */; };
4B0F1C1C2604EA1000B85C66 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1C1B2604EA1000B85C66 /* Keyboard.cpp */; };
4B0F1C1D2604EA1000B85C66 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F1C1B2604EA1000B85C66 /* Keyboard.cpp */; };
4B0F94FE208C1A1600FE41D9 /* NIB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */; };
4B0F94FF208C1A1600FE41D9 /* NIB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */; };
4B121F9B1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B121F9A1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm */; };
@ -1061,16 +1061,16 @@
4B0E61061FF34737002A9DBD /* MSX.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = MSX.hpp; path = Parsers/MSX.hpp; sourceTree = "<group>"; };
4B0F1BB02602645900B85C66 /* StaticAnalyser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticAnalyser.cpp; sourceTree = "<group>"; };
4B0F1BB12602645900B85C66 /* StaticAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StaticAnalyser.hpp; sourceTree = "<group>"; };
4B0F1BCB2602F17B00B85C66 /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
4B0F1BCC2602F17B00B85C66 /* ZX8081.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ZX8081.cpp; sourceTree = "<group>"; };
4B0F1BCD2602F17B00B85C66 /* Video.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Video.cpp; sourceTree = "<group>"; };
4B0F1BCE2602F17B00B85C66 /* Video.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Video.hpp; sourceTree = "<group>"; };
4B0F1BCF2602F17B00B85C66 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
4B0F1BD02602F17B00B85C66 /* ZX8081.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ZX8081.hpp; sourceTree = "<group>"; };
4B0F1BFA260300D900B85C66 /* ZXSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZXSpectrum.cpp; sourceTree = "<group>"; };
4B0F1BFB260300D900B85C66 /* ZXSpectrum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ZXSpectrum.hpp; sourceTree = "<group>"; };
4B0F1C04260391F100B85C66 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
4B0F1C092603BA5F00B85C66 /* Video.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Video.hpp; sourceTree = "<group>"; };
4B0F1C1A2604EA1000B85C66 /* Keyboard.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
4B0F1C1B2604EA1000B85C66 /* Keyboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
4B0F94FC208C1A1600FE41D9 /* NIB.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NIB.cpp; sourceTree = "<group>"; };
4B0F94FD208C1A1600FE41D9 /* NIB.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = NIB.hpp; sourceTree = "<group>"; };
4B0F9500208C42A300FE41D9 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = Target.hpp; path = AppleII/Target.hpp; sourceTree = "<group>"; };
@ -2177,6 +2177,7 @@
4B0F1BC92602F17B00B85C66 /* Sinclair */ = {
isa = PBXGroup;
children = (
4B0F1C192604EA1000B85C66 /* Keyboard */,
4B0F1BCA2602F17B00B85C66 /* ZX8081 */,
4B0F1BF9260300D900B85C66 /* ZXSpectrum */,
);
@ -2186,11 +2187,9 @@
4B0F1BCA2602F17B00B85C66 /* ZX8081 */ = {
isa = PBXGroup;
children = (
4B0F1BCB2602F17B00B85C66 /* Keyboard.hpp */,
4B0F1BCC2602F17B00B85C66 /* ZX8081.cpp */,
4B0F1BCD2602F17B00B85C66 /* Video.cpp */,
4B0F1BCE2602F17B00B85C66 /* Video.hpp */,
4B0F1BCF2602F17B00B85C66 /* Keyboard.cpp */,
4B0F1BD02602F17B00B85C66 /* ZX8081.hpp */,
);
path = ZX8081;
@ -2206,6 +2205,15 @@
path = ZXSpectrum;
sourceTree = "<group>";
};
4B0F1C192604EA1000B85C66 /* Keyboard */ = {
isa = PBXGroup;
children = (
4B0F1C1A2604EA1000B85C66 /* Keyboard.hpp */,
4B0F1C1B2604EA1000B85C66 /* Keyboard.cpp */,
);
path = Keyboard;
sourceTree = "<group>";
};
4B1414561B58879D00E04248 /* 6502 */ = {
isa = PBXGroup;
children = (
@ -5094,7 +5102,6 @@
4B65086122F4CFE0009C1100 /* Keyboard.cpp in Sources */,
4BBB70A9202014E2002FE009 /* MultiProducer.cpp in Sources */,
4B2E86BF25D74F160024F1E9 /* Mouse.cpp in Sources */,
4B0F1BEB2602FFA100B85C66 /* Keyboard.cpp in Sources */,
4B6ED2F1208E2F8A0047B343 /* WOZ.cpp in Sources */,
4B5D5C9825F56FC7001B4623 /* Spectrum.cpp in Sources */,
4B2E86D025D8D8C70024F1E9 /* Keyboard.cpp in Sources */,
@ -5141,6 +5148,7 @@
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */,
4B055AB01FAE86070060FFFF /* PulseQueuedTape.cpp in Sources */,
4B0F1C1D2604EA1000B85C66 /* Keyboard.cpp in Sources */,
4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */,
4BB307BC235001C300457D33 /* 6850.cpp in Sources */,
4B055AB31FAE860F0060FFFF /* CSW.cpp in Sources */,
@ -5291,6 +5299,7 @@
4B0E04EA1FC9E5DA00F43484 /* CAS.cpp in Sources */,
4B7A90ED20410A85008514A2 /* StaticAnalyser.cpp in Sources */,
4B58601E1F806AB200AEE2E3 /* MFMSectorDump.cpp in Sources */,
4B0F1C1C2604EA1000B85C66 /* Keyboard.cpp in Sources */,
4B228CD924DA12C60077EF25 /* CSScanTargetView.m in Sources */,
4B6AAEAD230E40250078E864 /* Target.cpp in Sources */,
4B448E841F1C4C480009ABD6 /* PulseQueuedTape.cpp in Sources */,
@ -5436,7 +5445,6 @@
4B0ACC02237756ED008902D0 /* Line.cpp in Sources */,
4B89453A201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */,
4B0F1BEA2602FFA000B85C66 /* Keyboard.cpp in Sources */,
4BDACBEC22FFA5D20045EF7E /* ncr5380.cpp in Sources */,
4B54C0C21F8D91CD0050900F /* Keyboard.cpp in Sources */,
4BD0FBC3233706A200148981 /* CSApplication.m in Sources */,