190 lines
6.2 KiB
Plaintext
190 lines
6.2 KiB
Plaintext
;;********************************************************************************
|
|
;; @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 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 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 that.
|
|
;;
|
|
;; Using scancode set 3 also adds the benefit that all scancodes are only 1 byte large,
|
|
;; making the recognition of scancodes trivial.
|
|
;;
|
|
;; Scancodes from the keyboard are processed immediately, as the handling functions is called
|
|
;; from the keyboard's interrupt handler.
|
|
;;
|
|
;; @subsection 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 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 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 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"
|
|
|
|
.scope kb
|
|
Import kb, init, char, keycode
|
|
Import kb, CHARS_NOMOD, CHARS_MODRALT, CHARS_MODSHIFT, CHARS_NUMLOCK_OFF, CHARS_NUMLOCK_ON
|
|
ImportZp kb, modifier
|
|
|
|
.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
|
|
|
|
K_BREAK = $F0
|
|
|
|
.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
|