; normal ;;******************************************************************************** ;; @module ps2_keyboard_text_handler ;; @type system ;; @details ;; This module processes keyboard scancodes from the ps2_keyboard driver. ;; It requires a PS/2 keyboard that supports scancode set 3. ;; ;; @section what What it does ;; - keeps track of modifier keys: shift, left/right alt, left right meta (super), ;; control, capslock, numlock, scrollock ;; - convert valid keycodes to chars, dependening on the state of shift and right alt ;; - update the keyboard LEDs (numlock, capslock,, scrolllock) ;; ;; This handler is designed for efficient text input. ;; It does not track the status of the keys (except modifiers) and is therefore not suitable for games. ;; ;; @section working_principle How it works ;; In the init function, the module disables the *typematic* behaviour for the modifier keys by ;; sending commands to the keyboard. The 3 lock keys will be set to *make only* mode and ;; the others to *make release*. ;; This makes tracking the modifier keys much easier and is the reason why scancode set 3 ;; is required, as these commands are only available with this set. ;; ;; Using scancode set 3 also adds the benefit that all scancodes are only 1 byte large, ;; making the recognition of scancodes trivial. ;; ;; Scancodes sent from the keyboard are processed immediately, as the handling functions is called ;; from the keyboard's interrupt handler. ;; ;; @subsection mapping Mapping keycodes to chars ;; The mapping of keycodes to chars is done using an array of chars for each state: ;; default, shift and right alt. The tables contains the ascii characters, `0` where the keycode does not ;; generate a character and `1` where the keycode is a modifier key. ;; This approach consumes a relatively large amount of ROM (3 * 144 bytes), but is super fast, ;; as loading a character is merely one indexed load instruction. ;; Checking for mod keys is now also fast, beceause we only have to do 1 comparison to see IF it is a modifier key. ;; ;; @section usage How to use it ;; Call `kb::init` and check if it was successful (`Z = 1`). ;; In your program loop, check if `kb::keycode` is 0. If it is not, a key has been pressed. ;; ;; If the keypress generated a character `kb::char` will be non-zero and contain the character. ;; ;; Note that if you will probably want to write a 0 to `kb::keycode` and `kb::char` ;; after processing the keycode. This will not be done by the handler. ;; ;; Conditional branches based on the status of a modifier (`SHIFT`, `RALT`, `LALT`, `CTRL`, `META`, `NUMLOCK`, `SCROLLLOCK`) can be done ;; using the `bbs` and `bbr` instructions, as each modifier is represented by a bit of the `kb::modifier` variable ;; in the zeropage. ;; ;; @subsection change_behaviour Changing the keyboard behaviour ;; You can change the typematic rate and delay (see PS/2 keyboard command `0xF3`) ;; and the typematic behavior (make, make/release, typematic) for all keys except the modifier keys. ;; ;; You may also send the echo (`0xEE`) and identify (`0xF2`) commands to the keyboard. ;;******************************************************************************** .ifndef INCLUDE_KEYBOARD_TEXT INCLUDE_KEYBOARD_TEXT = 1 .include "ps2_keyboard.h65" ;;******************************************************************************** ;; @brief Keyboard Handler ;;******************************************************************************** .scope kb Import kb, init, char, keycode Import kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON ImportZp kb, modifier ;;******************************************************************************** ;; @brief Bitmask for checking modifier keys ;;******************************************************************************** .enum MOD SHIFT = %10000000 ; set if either capslock is on or shift is pressed RALT = %01000000 ; set while rightalt is pressed LALT = %00100000 ; set while leftalt is pressed META = %00010000 ; set while left or right meta is pressed CTRL = %00001000 ; set while left or right ctrl is pressed CAPSLOCK = %00000100 ; ps/2 LED NUMLOCK = %00000010 ; ps/2 LED SCROLLLOCK = %00000001 ; ps/2 LED .endenum ;; @brief Scancode that is sent by the keyboard when a key is released K_BREAK = $F0 ;;******************************************************************************** ;; @brief S3 German Keycodes ;;******************************************************************************** .enum K F1 = $07 ESCAPE = $08 TAB = $0D GRAVE = $0E F2 = $0F LEFTCTRL = $11 LEFTSHIFT = $12 CAPSLOCK = $14 K_Q = $15 K_1 = $16 F3 = $17 LEFTALT = $19 K_Y = $1A K_S = $1B K_A = $1C K_W = $1D K_2 = $1E F4 = $1F K_C = $21 K_X = $22 K_D = $23 K_E = $24 K_4 = $25 K_3 = $26 F5 = $27 SPACE = $29 K_V = $2A K_F = $2B K_T = $2C K_R = $2D K_5 = $2E F6 = $2F K_N = $31 K_B = $32 K_H = $33 K_G = $34 K_Z = $35 K_6 = $36 F7 = $37 RIGHTALT = $39 K_M = $3A K_J = $3B K_U = $3C K_7 = $3D K_8 = $3E F8 = $3F COMMA = $41 K_K = $42 K_I = $43 K_O = $44 K_0 = $45 K_9 = $46 F9 = $47 DOT = $49 DASH = $4A KPDIVIDE = $4A K_L = $4B OUML = $4C K_P = $4D SSHARP = $4E KPMINUS = $4E F10 = $4F AUML = $52 UUML = $54 BACKTICK = $55 F11 = $56 PRINT = $57 RIGHTCTRL = $58 RIGHTSHIFT = $59 ENTER = $5A PLUS = $5B LESSTHAN = $5C HASH = $5D F12 = $5E SCROLLLOCK = $5F RIGHT = $60 LEFT = $61 PAUSE = $62 UP = $63 DELETE = $64 END = $65 BACKSPACE = $66 INSERT = $67 KP1 = $69 DOWN = $6A KP4 = $6B KP7 = $6C PAGEDOWN = $6D POS1 = $6E PAGEUP = $6F KP0 = $70 KPDOT = $71 KP2 = $72 KP5 = $73 KP6 = $74 KP8 = $75 NUMLOCK = $76 KPENTER = $79 KP3 = $7A KPPLUS = $7C KP9 = $7D KPASTERISK = $7E LEFTMETA = $8B RIGHTMETA = $8C MENU = $8D .endenum .endscope .endif ; guard