From 3e5c209039d770d8641480a498935a74679f4bca Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 9 Jul 2017 22:00:34 -0400 Subject: [PATCH 1/3] Added basic Typer support for the ZX80 and '81. --- Machines/ZX8081/Typer.cpp | 156 ++++++++++++++++++ Machines/ZX8081/ZX8081.cpp | 2 + Machines/ZX8081/ZX8081.hpp | 9 + .../Clock Signal.xcodeproj/project.pbxproj | 4 + 4 files changed, 171 insertions(+) create mode 100644 Machines/ZX8081/Typer.cpp diff --git a/Machines/ZX8081/Typer.cpp b/Machines/ZX8081/Typer.cpp new file mode 100644 index 000000000..7bc08fa32 --- /dev/null +++ b/Machines/ZX8081/Typer.cpp @@ -0,0 +1,156 @@ +// +// Typer.cpp +// Clock Signal +// +// Created by Thomas Harte on 09/07/2017. +// Copyright © 2017 Thomas Harte. All rights reserved. +// + +#include "ZX8081.hpp" + +uint16_t *ZX8081::Machine::sequence_for_character(Utility::Typer *typer, char character) { +#define KEYS(...) {__VA_ARGS__, TerminateSequence} +#define SHIFT(...) {KeyShift, __VA_ARGS__, TerminateSequence} +#define X {NotMapped} + typedef Key KeyTable[126][3]; + KeyTable zx81_key_sequences = { + /* NUL */ X, /* SOH */ X, + /* STX */ X, /* ETX */ X, + /* EOT */ X, /* ENQ */ X, + /* ACK */ X, /* BEL */ X, + /* BS */ SHIFT(Key0), /* HT */ X, + /* LF */ KEYS(KeyEnter), /* VT */ X, + /* FF */ X, /* CR */ X, + /* SO */ X, /* SI */ X, + /* DLE */ X, /* DC1 */ X, + /* DC2 */ X, /* DC3 */ X, + /* DC4 */ X, /* NAK */ X, + /* SYN */ X, /* ETB */ X, + /* CAN */ X, /* EM */ X, + /* SUB */ X, /* ESC */ X, + /* FS */ X, /* GS */ X, + /* RS */ X, /* US */ X, + /* space */ KEYS(KeySpace), /* ! */ X, + /* " */ SHIFT(KeyP), /* # */ X, + /* $ */ SHIFT(KeyU), /* % */ X, + /* & */ X, /* ' */ X, + /* ( */ SHIFT(KeyI), /* ) */ SHIFT(KeyO), + /* * */ SHIFT(KeyB), /* + */ SHIFT(KeyK), + /* , */ SHIFT(KeyDot), /* - */ SHIFT(KeyJ), + /* . */ KEYS(KeyDot), /* / */ SHIFT(KeyV), + /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), + /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), + /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), + /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), + /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), + /* : */ SHIFT(KeyZ), /* ; */ SHIFT(KeyX), + /* < */ SHIFT(KeyN), /* = */ SHIFT(KeyL), + /* > */ SHIFT(KeyM), /* ? */ SHIFT(KeyC), + /* @ */ X, /* A */ KEYS(KeyA), + /* B */ KEYS(KeyB), /* C */ KEYS(KeyC), + /* D */ KEYS(KeyD), /* E */ KEYS(KeyE), + /* F */ KEYS(KeyF), /* G */ KEYS(KeyG), + /* H */ KEYS(KeyH), /* I */ KEYS(KeyI), + /* J */ KEYS(KeyJ), /* K */ KEYS(KeyK), + /* L */ KEYS(KeyL), /* M */ KEYS(KeyM), + /* N */ KEYS(KeyN), /* O */ KEYS(KeyO), + /* P */ KEYS(KeyP), /* Q */ KEYS(KeyQ), + /* R */ KEYS(KeyR), /* S */ KEYS(KeyS), + /* T */ KEYS(KeyT), /* U */ KEYS(KeyU), + /* V */ KEYS(KeyV), /* W */ KEYS(KeyW), + /* X */ KEYS(KeyX), /* Y */ KEYS(KeyY), + /* Z */ KEYS(KeyZ), /* [ */ X, + /* \ */ X, /* ] */ X, + /* ^ */ X, /* _ */ X, + /* ` */ X, /* a */ KEYS(KeyA), + /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), + /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), + /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), + /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), + /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), + /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), + /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), + /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), + /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), + /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), + /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), + /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), + /* z */ KEYS(KeyZ), /* { */ X, + /* | */ X, /* } */ X, + }; + + KeyTable zx80_key_sequences = { + /* NUL */ X, /* SOH */ X, + /* STX */ X, /* ETX */ X, + /* EOT */ X, /* ENQ */ X, + /* ACK */ X, /* BEL */ X, + /* BS */ SHIFT(Key0), /* HT */ X, + /* LF */ KEYS(KeyEnter), /* VT */ X, + /* FF */ X, /* CR */ X, + /* SO */ X, /* SI */ X, + /* DLE */ X, /* DC1 */ X, + /* DC2 */ X, /* DC3 */ X, + /* DC4 */ X, /* NAK */ X, + /* SYN */ X, /* ETB */ X, + /* CAN */ X, /* EM */ X, + /* SUB */ X, /* ESC */ X, + /* FS */ X, /* GS */ X, + /* RS */ X, /* US */ X, + /* space */ KEYS(KeySpace), /* ! */ X, + /* " */ SHIFT(KeyY), /* # */ X, + /* $ */ SHIFT(KeyU), /* % */ X, + /* & */ X, /* ' */ X, + /* ( */ SHIFT(KeyI), /* ) */ SHIFT(KeyO), + /* * */ SHIFT(KeyP), /* + */ SHIFT(KeyK), + /* , */ SHIFT(KeyDot), /* - */ SHIFT(KeyJ), + /* . */ KEYS(KeyDot), /* / */ SHIFT(KeyV), + /* 0 */ KEYS(Key0), /* 1 */ KEYS(Key1), + /* 2 */ KEYS(Key2), /* 3 */ KEYS(Key3), + /* 4 */ KEYS(Key4), /* 5 */ KEYS(Key5), + /* 6 */ KEYS(Key6), /* 7 */ KEYS(Key7), + /* 8 */ KEYS(Key8), /* 9 */ KEYS(Key9), + /* : */ SHIFT(KeyZ), /* ; */ SHIFT(KeyX), + /* < */ SHIFT(KeyN), /* = */ SHIFT(KeyL), + /* > */ SHIFT(KeyM), /* ? */ SHIFT(KeyC), + /* @ */ X, /* A */ KEYS(KeyA), + /* B */ KEYS(KeyB), /* C */ KEYS(KeyC), + /* D */ KEYS(KeyD), /* E */ KEYS(KeyE), + /* F */ KEYS(KeyF), /* G */ KEYS(KeyG), + /* H */ KEYS(KeyH), /* I */ KEYS(KeyI), + /* J */ KEYS(KeyJ), /* K */ KEYS(KeyK), + /* L */ KEYS(KeyL), /* M */ KEYS(KeyM), + /* N */ KEYS(KeyN), /* O */ KEYS(KeyO), + /* P */ KEYS(KeyP), /* Q */ KEYS(KeyQ), + /* R */ KEYS(KeyR), /* S */ KEYS(KeyS), + /* T */ KEYS(KeyT), /* U */ KEYS(KeyU), + /* V */ KEYS(KeyV), /* W */ KEYS(KeyW), + /* X */ KEYS(KeyX), /* Y */ KEYS(KeyY), + /* Z */ KEYS(KeyZ), /* [ */ X, + /* \ */ X, /* ] */ X, + /* ^ */ X, /* _ */ X, + /* ` */ X, /* a */ KEYS(KeyA), + /* b */ KEYS(KeyB), /* c */ KEYS(KeyC), + /* d */ KEYS(KeyD), /* e */ KEYS(KeyE), + /* f */ KEYS(KeyF), /* g */ KEYS(KeyG), + /* h */ KEYS(KeyH), /* i */ KEYS(KeyI), + /* j */ KEYS(KeyJ), /* k */ KEYS(KeyK), + /* l */ KEYS(KeyL), /* m */ KEYS(KeyM), + /* n */ KEYS(KeyN), /* o */ KEYS(KeyO), + /* p */ KEYS(KeyP), /* q */ KEYS(KeyQ), + /* r */ KEYS(KeyR), /* s */ KEYS(KeyS), + /* t */ KEYS(KeyT), /* u */ KEYS(KeyU), + /* v */ KEYS(KeyV), /* w */ KEYS(KeyW), + /* x */ KEYS(KeyX), /* y */ KEYS(KeyY), + /* z */ KEYS(KeyZ), /* { */ X, + /* | */ X, /* } */ X, + }; +#undef KEYS +#undef SHIFT +#undef X + + if(character > sizeof(zx81_key_sequences) / sizeof(*zx81_key_sequences)) return nullptr; + + KeyTable *table = is_zx81_ ? &zx81_key_sequences : &zx80_key_sequences; + if((*table)[character][0] == NotMapped) return nullptr; + return (uint16_t *)(*table)[character]; +} diff --git a/Machines/ZX8081/ZX8081.cpp b/Machines/ZX8081/ZX8081.cpp index c0df523be..f58d62013 100644 --- a/Machines/ZX8081/ZX8081.cpp +++ b/Machines/ZX8081/ZX8081.cpp @@ -181,6 +181,8 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) { default: break; } + if(typer_) typer_->update(cycle.length); + return 0; } diff --git a/Machines/ZX8081/ZX8081.hpp b/Machines/ZX8081/ZX8081.hpp index 2e87be5d8..23d773dbf 100644 --- a/Machines/ZX8081/ZX8081.hpp +++ b/Machines/ZX8081/ZX8081.hpp @@ -11,6 +11,7 @@ #include "../ConfigurationTarget.hpp" #include "../CRTMachine.hpp" +#include "../Typer.hpp" #include "../../Processors/Z80/Z80.hpp" #include "../../Storage/Tape/Tape.hpp" @@ -36,11 +37,14 @@ enum Key: uint16_t { 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, + + TerminateSequence = 0xffff, NotMapped = 0xfffe }; class Machine: public CPU::Z80::Processor, public CRTMachine::Machine, + public Utility::TypeRecipient, public ConfigurationTarget::Machine { public: Machine(); @@ -69,6 +73,11 @@ class Machine: } inline void set_tape_is_playing(bool is_playing) { tape_is_playing_ = is_playing; } + // for Utility::TypeRecipient::Delegate + uint16_t *sequence_for_character(Utility::Typer *typer, char character); + int get_typer_delay() { return 7000000; } + int get_typer_frequency() { return 390000; } + private: std::shared_ptr