From e940288f0f2ff9977b7c5339d88d62ba50a0e3bf Mon Sep 17 00:00:00 2001 From: stefan-b-jakobsson <70063525+stefan-b-jakobsson@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:32:55 +0300 Subject: [PATCH] Bugfix sticky modifier keys, bumping version to 47.2.2 (#39) --- ps2.h | 31 +++++++++++++++++++++++++++++-- version.h | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/ps2.h b/ps2.h index fa5800a..228afdd 100644 --- a/ps2.h +++ b/ps2.h @@ -335,6 +335,7 @@ enum PS2_MODIFIER_STATE : uint8_t { RWIN = 128 }; +// Conversion table: PS/2 regular non-extended scan codes to IBM System/2 key numbers const uint8_t PS2_REG_SCANCODES[] PROGMEM = { 120, 0, 116, 114, 112, 113, 123, 0, 121, 119, 117, 115, 16, 1, 0, 0, @@ -358,6 +359,32 @@ const uint8_t PS2_REG_SCANCODES[] PROGMEM = { template class PS2KeyboardPort : public PS2Port { + /* + * This class transforms PS/2 keyboard scan codes to + * IBM System/2 key numbers. The IBM key numbers are stored + * in a buffer to be fetched by the X16 Kernal over I2C. + * + * The IBM key numbers are one byte, whereof bits 0-6 identify a + * key, and bit 7 indicates key down (0) or key up (1) events. + * + * A complete list of IBM key numbers is available in the X16 Kernal sources, + * x16-rom/inc/keycode.inc. + * + * In the event of buffer overflow, subsequent key events are + * ignored until the content of the buffer has been read by + * the X16 Kernal. Modifier key events are, however, tracked + * during buffer overflow, and modifier key state changes that + * happened during a buffer overflow are pushed to the buffer + * when it's empty again. This is to prevent "sticky" modifer keys. + * + * This class also detects and handles the following two key + * combinations that are available even if the X16 Kernal + * is not responding: + * + * - Ctrl+Alt+Del, triggers system reset + * - Ctrl+Alt+PrtScr/Restore, triggers system NMI + */ + protected: volatile bool buffer_overrun = false; // Set to true on buffer full, and to false when buffer is empty again volatile uint8_t scancode_state = 0x00; // Tracks the type and byte position of the scan code currently being received (bits 4-7 = scan code type, bits 0-3 = number of bytes) @@ -365,7 +392,7 @@ class PS2KeyboardPort : public PS2Port volatile uint8_t modifier_oldstate = 0x00; // Previous modifier key state, used to compare what's changed during buffer full volatile bool reset_request = false; volatile bool nmi_request = false; - uint8_t modifier_codes[8] = {0x11, 0x12, 0x14, 0x59, 0x11, 0x14, 0x1f, 0x27}; // Last byte of modifier key scan codes: LALT, LSHIFT, LCTRL, RSHIFT, RALT, RCTRL, LWIN, RWIN + uint8_t modifier_key_codes[8] = {60, 44, 58, 57, 62, 64, 59, 63}; // IBM PS/2 key numbers for left Alt, left Shift, left Control, right Shift, right Alt, right Control, left Win and right Win volatile uint8_t bat = 0; /// @brief Converts a PS/2 Set 2 scan code to a IBM System/2 key number @@ -600,7 +627,7 @@ class PS2KeyboardPort : public PS2Port uint8_t shifted_bit = 0x01; for (uint8_t i = 0; i < 8; i++) { if ((modifier_state & shifted_bit) != (modifier_oldstate & shifted_bit)) { - uint8_t mod = modifier_codes[i]; + uint8_t mod = modifier_key_codes[i]; if (!(modifier_state & shifted_bit)) { mod |= 0x80; } diff --git a/version.h b/version.h index a3cabfc..51b5d8a 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ #define version_major 47 #define version_minor 2 -#define version_patch 1 +#define version_patch 2