From c7db5b18b41a657255bbcc4c8595fa02a4dfd686 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2024 16:02:42 +0100 Subject: [PATCH] Serial Keyboard and other improvements (#10) * ps/2 and hardware serial keyboards * docs * remove setjmp * hardware_run * ... --- .gitignore | 1 + Apple1.ino | 83 +++++++++++++++++++++++++++++++----------------------- Makefile | 16 ++++++----- README.md | 14 +++++---- config.h | 2 -- io.cpp | 61 ++++++--------------------------------- io.h | 11 ++++---- 7 files changed, 79 insertions(+), 109 deletions(-) diff --git a/.gitignore b/.gitignore index 2405d77..8e8ec94 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ spiffs.img .build *.txt.mk +*.swp # Compiled Object files *.slo diff --git a/Apple1.ino b/Apple1.ino index 5b46f5e..d83a72b 100644 --- a/Apple1.ino +++ b/Apple1.ino @@ -26,10 +26,20 @@ sd_filer files(PROGRAMS); #else flash_filer files(PROGRAMS); #endif -io io(files); + +#if defined(PS2_SERIAL_KBD) +ps2_serial_kbd kbd; + +#elif defined(HW_SERIAL_KBD) +hw_serial_kbd kbd(Serial); + +#else +#error "No keyboard defined!" +#endif + +io io(files, kbd); r6502 cpu(memory); -const char *filename; void reset() { bool ok = hardware_reset(); @@ -47,6 +57,37 @@ void reset() { #endif } +void function_key(uint8_t fn) { + static const char *filename; + + switch(fn) { + case 1: + reset(); + break; + case 2: + filename = io.files.advance(); + io.status(filename); + break; + case 3: + filename = io.files.rewind(); + io.status(filename); + break; + case 4: + io.load(); + break; + case 6: + io.status(io.files.checkpoint()); + break; + case 7: + if (filename) + io.files.restore(filename); + break; + case 10: + hardware_debug_cpu(); + break; + } +} + void setup() { #if defined(DEBUGGING) || defined(CPU_DEBUG) Serial.begin(TERMINAL_SPEED); @@ -81,42 +122,12 @@ void setup() { memory.put(m, 0xff00); #endif + kbd.register_fnkey_handler(function_key); + reset(); } void loop() { - if (ps2.available()) { - unsigned scan = ps2.read2(); - byte key = scan & 0xff; - if (is_down(scan)) - io.down(key); - else - switch (key) { - case PS2_F1: - reset(); - break; - case PS2_F2: - filename = io.files.advance(); - io.status(filename); - break; - case PS2_F3: - filename = io.files.rewind(); - io.status(filename); - break; - case PS2_F4: - io.load(); - break; - case PS2_F6: - io.status(io.files.checkpoint()); - break; - case PS2_F7: - if (filename) - io.files.restore(filename); - break; - default: - io.up(key); - break; - } - } else if (!cpu.halted()) - cpu.run(CPU_INSTRUCTIONS); + + hardware_run(); } diff --git a/Makefile b/Makefile index a40b642..1b3b1c2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ t ?= esp32 TERMINAL_SPEED := 115200 +CPPFLAGS = -DDEBUGGING -DCPU_DEBUG=false -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DPS2_SERIAL_KBD=\"UK\" +#CPPFLAGS = -DDEBUGGING -DCPU_DEBUG -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DUSE_OWN_KBD -DHW_SERIAL_KBD +LIBRARIES = PS2KeyAdvanced PS2KeyMap ifeq ($t, esp8266) BOARD := d1_mini @@ -8,23 +11,22 @@ BAUD := 921600 FS_DIR := programs EESZ := 4M1M F_CPU := 80 -CPPFLAGS = -DUSER_SETUP_LOADED -DILI9341_DRIVER -DTFT_CS=PIN_D8 -DTFT_DC=PIN_D1 \ +CPPFLAGS += -DUSER_SETUP_LOADED -DILI9341_DRIVER -DTFT_CS=PIN_D8 -DTFT_DC=PIN_D1 \ -DTFT_RST=-1 -DSPI_FREQUENCY=40000000 -DLOAD_GLCD \ - -DHARDWARE_H=\"hw/esp8bit.h\" -DTERMINAL_SPEED=$(TERMINAL_SPEED) -DDEBUGGING=1 -LIBRARIES := TFT_eSPI SpiRAM LittleFS + -DHARDWARE_H=\"hw/esp8bit.h\" +LIBRARIES += TFT_eSPI SpiRAM LittleFS endif ifeq ($t, tivac) BOARD := EK-LM4F120XL -CPPFLAGS := -DHARDWARE_H=\"hw/stellarpad-example.h\" -DTERMINAL_SPEED=$(TERMINAL_SPEED) -LIBRARIES := UTFT SD SpiRAM +CPPFLAGS += -DHARDWARE_H=\"hw/stellarpad-example.h\" +LIBRARIES += UTFT SD SpiRAM endif ifeq ($t, esp32) UPLOADSPEED := 921600 FS_DIR := programs -CPPFLAGS = -DDEBUGGING -DCPU_DEBUG -DTERMINAL_SPEED=$(TERMINAL_SPEED) -LIBRARIES = FS SPIFFS +LIBRARIES += FS SPIFFS ifeq ($b, lilygo) BOARD := ttgo-t7-v14-mini32 diff --git a/README.md b/README.md index 5af3f07..a4bdadd 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,11 @@ Requirements Keyboard -------- -- F1: reset -- F2: advance tape -- F3: rewind tape -- F4: load program from tape (by simulating typing it) -- F6: checkpoint machine -- F7: restore from current checkpoint on tape +- F1 (^N): reset +- F2 (^M): advance tape +- F3 (^O): rewind tape +- F4 (^P): load program from tape (by simulating typing it) +- F6 (^R): checkpoint machine +- F7 (^S): restore from current checkpoint on tape +- F10(^W): watch CPU execute instructions +- Underscore is rubout diff --git a/config.h b/config.h index d26c1ba..2c57b7b 100644 --- a/config.h +++ b/config.h @@ -16,8 +16,6 @@ #endif -#define CPU_INSTRUCTIONS 1000 - #define FG_COLOUR GREEN #define BG_COLOUR BLACK diff --git a/io.cpp b/io.cpp index 4898afc..4122677 100644 --- a/io.cpp +++ b/io.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -21,6 +21,8 @@ void io::reset() { for (int i = 0; i < COLS; i++) screen[j][i] = ' '; + _kbd.reset(); + _loading = false; PIA::reset(); } @@ -54,64 +56,12 @@ void io::load() { } } -// ascii map for scan-codes -static const uint8_t scanmap[] PROGMEM = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x00 - 0xff, 0xff, 0xff, 0xff, 0xff, 0x09, 0x60, 0xff, // 0x08 - 0xff, 0xff, 0xff, 0xff, 0xff, 0x51, 0x31, 0xff, // 0x10 - 0xff, 0xff, 0x5a, 0x53, 0x41, 0x57, 0x32, 0xff, // 0x18 - 0xff, 0x43, 0x58, 0x44, 0x45, 0x34, 0x33, 0xff, // 0x20 - 0xff, 0x20, 0x56, 0x46, 0x54, 0x52, 0x35, 0xff, // 0x28 - 0xff, 0x4e, 0x42, 0x48, 0x47, 0x59, 0x36, 0xff, // 0x30 - 0xff, 0xff, 0x4d, 0x4a, 0x55, 0x37, 0x38, 0xff, // 0x38 - 0xff, 0x2c, 0x4b, 0x49, 0x4f, 0x30, 0x39, 0xff, // 0x40 - 0xff, 0x2e, 0x2f, 0x4c, 0x3b, 0x50, 0x2d, 0xff, // 0x48 - 0xff, 0xff, 0x27, 0xff, 0x5b, 0x3d, 0xff, 0xff, // 0x50 - 0xff, 0xff, 0x0d, 0x5d, 0xff, 0x23, 0xff, 0xff, // 0x58 - 0xff, 0x5c, 0xff, 0xff, 0xff, 0xff, 0x5f, 0xff, // 0x60 - 0xff, 0x31, 0xff, 0x34, 0x37, 0xff, 0xff, 0xff, // 0x68 - 0x30, 0x08, 0x32, 0x35, 0x36, 0x38, 0x1b, 0xff, // 0x70 - 0xff, 0x2b, 0x33, 0x2d, 0x2a, 0x39, 0xff, 0xff, // 0x78 -}; - -static const uint8_t shiftmap[] PROGMEM = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x00 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x08 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x21, 0xff, // 0x10 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22, 0xff, // 0x18 - 0xff, 0xff, 0xff, 0xff, 0xff, 0x24, 0x23, 0xff, // 0x20 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x25, 0xff, // 0x28 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0xff, // 0x30 - 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x2a, 0xff, // 0x38 - 0xff, 0x3c, 0xff, 0xff, 0xff, 0x29, 0x28, 0xff, // 0x40 - 0xff, 0x3e, 0x3f, 0xff, 0x3a, 0xff, 0x5f, 0xff, // 0x48 - 0xff, 0xff, 0x40, 0xff, 0x7b, 0x2b, 0xff, 0xff, // 0x50 - 0xff, 0xff, 0xff, 0x7d, 0xff, 0x7e, 0xff, 0xff, // 0x58 - 0xff, 0x7c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x60 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x68 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x70 - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0x78 -}; - -void io::down(uint8_t scan) { - if (isshift(scan)) - _shift = true; -} - void io::enter(uint8_t key) { PIA::write_ca1(false); PIA::write_porta_in(key + 0x80); PIA::write_ca1(true); } -void io::up(uint8_t scan) { - if (isshift(scan)) { - _shift = false; - return; - } - enter(_shift? pgm_read_byte(shiftmap + scan): pgm_read_byte(scanmap + scan)); -} - void io::draw(char ch, int i, int j) { if (screen[j][i] != ch) { screen[j][i] = ch; @@ -168,7 +118,12 @@ uint8_t io::read_cra() { enter(files.read()); else _loading = false; + } else if (_kbd.available()) { + int c = _kbd.read(); + if (c != -1) + enter(c); } + return PIA::read_cra(); } diff --git a/io.h b/io.h index 2a8c418..2a7ffaf 100644 --- a/io.h +++ b/io.h @@ -1,18 +1,17 @@ #ifndef _IO_H #define _IO_H -class io: public Memory::Device, public Display, Keyboard, public PIA { +class serial_kbd; + +class io: public Memory::Device, public Display, public PIA { public: - io(filer &files): Memory::Device(Memory::page_size), files(files) {} + io(filer &files, serial_kbd &kbd): Memory::Device(Memory::page_size), files(files), _kbd(kbd) {} void reset(); bool start(); static void on_tick(); - void down(uint8_t); - void up(uint8_t); - void operator=(uint8_t b) { PIA::write(_acc, b); } operator uint8_t() { return PIA::read(_acc); } @@ -29,6 +28,8 @@ public: static const uint8_t COLS = 40; private: + serial_kbd &_kbd; + void cursor(bool on); void display(uint8_t); void draw(char, int, int);