C256 Keyboard

From C256 Foenix Wiki
Revision as of 20:24, 31 May 2021 by PJW (talk | contribs) (Scan codes)
Jump to navigation Jump to search

Keyboards Supported

At a hardware level, the Foenix computers support keyboards with the old, PS/2 style interface. USB keyboards are not supported, unless they can provide a PS/2 interface through an adapter.

Reading Inputs

The Foenix kernel provides two ways that keyboard data can be read by a program.

First, characters can be read using the kernel function GETCH, which reads a single character at a time from the currently selected input channel (the keyboard is on channel #0). At this level, the user program receives ASCII characters corresponding to the user's keypresses.

Second, as of version 0.4 of the kernel, raw scan codes can be received for every keypress by calling the GETSCANCODE kernel routine, which will return the individual scan code for the next key pressed, or 0 if nothing has been pressed.

NOTE: a program should avoid mixing the two styles. Behind the scenes, GETCH uses GETSCANCODE, so scan codes returned by GETSCANCODE to the user program will not be seen by GETCH. This may confuse the results of a later call to GETCH.

Scan codes

Scan codes for the Foenix kernel are similar in many respects to the old set 1 standard scan codes. Each key has a unique number that is encoded in bits 0 through 6 of the scan code. Bit 7 indicates if the key was pressed or released by the user: if it is clear, the key was pressed; if it is set, the key was released.

The main difference between Foenix scan codes and the set 1 standard is that the multi-byte scan codes supported by the kernel are reassigned to single byte codes:

C256ScanCodes.png

ANSI Terminal Codes

GETCH returns the ASCII translation of the scan codes but it adds support for ANSI terminal escape sequences for certain special keys.

The cursor keys follow the xterm sequences:

Key Character sequence
UP <esc>[A
DOWN <esc>[B
RIGHT <esc>[C
LEFT <esc>[D

The function and other special keys follow the VT sequences:

Key Character sequence
HOME <esc>[1~
INSERT <esc>[2~
DELETE <esc>[3~
END <esc>[4~
PAGE UP <esc>[5~
PAGE DOWN <esc>[6~
F1 <esc>[11~
F2 <esc>[12~
F3 <esc>[13~
F4 <esc>[14~
F5 <esc>[15~
F6 <esc>[17~
F7 <esc>[18~
F8 <esc>[19~
F9 <esc>[20~
F10 <esc>[21~
F11 <esc>[23~
F12 <esc>[24~

These sequences can be modified by the SHIFT, CTRL, and ALT keys. If any of these modifiers are pressed with one of these special keys, the key number is followed by a semicolon a number in decimal indicating which modifier keys are currently pressed:

7 6 5 4 3 2 1 0
0 0 0 0 CTRL ALT SHIFT 0

For example, ALT-F1 would generate the sequence "<esc>[11;4~" and CTRL-SHIFT-HOME would generate the sequence "<esc>[1;10~".

Changing Keyboard Layouts

Starting with version 0.4 of the kernel, minimal support is present for keyboards with layouts other than the US keyboards. While there is no command or configuration option to set this up, there is now a kernel routine that will change the translation tables that map from scan codes to characters.

The kernel uses a set of 6 tables of 128 bytes each to map from a scan code to a character. The kernel looks at the state of the SHIFT and CTRL modifiers as well as the CAPS and NUM lock keys to select the correct translation table. Then, the lower 7 bits of the scan code are used to index the table to find the character to return.

Table Used...
UNMOD used when no lock key or modifier is in use
SHIFT used when SHIFT is the only modifier
CONTROL used when CONTROL is the only modifier
LOCK used when CAPSLOCK is down but SHIFT is not
LOCK+SHIFT used when CAPSLOCK is down and SHIFT is pressed
CONTROL+SHIFT used when CONTROL and SHIFT are pressed together

As an example of how the translation tables work: the scan code for the 1 key on the US keyboard is $02. The third byte (index 2) of each table would therefore contain $31, the ASCII code for the numeral '1' except for the tables SHIFT, LOCK+SHIFT, and CONTROL+SHIFT... which contain $21, the ASCII code for '!'.

The kernel allows a program to replace these translation tables with the SETTABLE call. The calling program must provide a pointer to its own version of all six tables arranged consecutively in memory in the order listed in the table above. The call expects the pointer to be in the X register, with the B register providing the bank containing the tables.

PAUSE/BREAK

There is special support for the PAUSE/BREAK key. As of v0.4, there is a kernel subroutine TESTBREAK which will set the carry flag if the PAUSE/BREAK has been pressed since the last call to TESTBREAK. BASIC816 uses this call to allow the user to interrupt the execution of the current program, but it will not interrupt machine language programs. A user program can call this routine to test for the BREAK key and use it as desired.