Test programs to test keyboard input from BASIC =============================================== KBDTest ======= This tests the keyboard character codes returned by the key and displays what keypress should return the code, primarily to test that function and editing keys return their correct values. If changing keymaps is supported, pressing Escape will toggle between them. Pressing Escape twice will quit. KBDDemo ======= This tests GET and INKEY and extensions to keyboard input, also primarily to test that function and editing keys return their correct values. Keymaps ======= In the non-Acorn/BBC world, function keys and editing keys return an erratic range of keypress codes or sequences of multiple characters. On Acorn/BBC platforms function and editing keys return a consistant set of values that also encode the Shift, Ctrl and Alt modifier state. The host interface to the MOS should interpret and translate the incoming keypress stream and return regularised characters to BASIC. There are two main keycode maps, the RISC OS 'semi-regular' keymap and the 'regular' keymap. Richard Russell's BBC BASIC for Windows and SDL uses a third keymap, which is quite simple to translate to either of the regular keymaps. Note, this is about what characters the keypresses return, not how the physical keyboard itself is laid out. With the regular keymap: &80+n: F0/Print F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 &C0+n: Windows Menu Break Ins Del Home End PgDn PgUp <- -> Dn Up function keys return &80+function key number editing keys return &C0+editing key number, 'End' is also 'Copy' With top-bit-set keys, Shift XORs 16, Ctrl XORs 32, and Alt XORs 48 The editing keys are in a back/forward/back/forward order. With the RISC OS semi-regular keymap &10+n Home &70+n Del &80+n: F0/Print F1 F2 F3 F4 F5 F6 F7 F8 F9 End <- -> Dn Up &90+n PgDn PgUp &C0+n: LeftWin Menu F10 F11 F12 Ins MsDn MsUp &D0+n: RightWin function keys 0-9 return &80+function key number function keys 10-12 and Insert return &C0+function key number cursor editing keys return &80+key number, 'End' is also 'Copy' With top-bit-set keys, Shift XORs 16, Ctrl XORs 32, and Alt XORs 48 BBC BASIC for Windows and SDL uses its own keymap: &80+n: c<- c-> Home End PgUp PgDn Ins Del <- -> Dn Up MsDn MsUp &90+n: F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 With function keys, Shift adds 16, Ctrl adds 32, and Alt adds 48 It can be seen that the RISC OS keymapping swaps the function keys between two rows (due to being an evolution from systems with only ten function keys) and it is not possible to tell apart Shift-Up/Dn and PgUp/PgDn and their converse Up/Dn and Shift-PgUp/PgDn. When implementing a host interface, you should use the regular keymap and ensure OSBYTE 0 returns 8 or higher, and optionally implement *FX254 to switch to a RISC OS keymap. You should only return the Richard Russell keymap if INKEY-256 also returns ASC"W", ASC"w", ASC"S" or ASC"s", so that (INKEY-256AND&DB)=&53 is TRUE. See mdfs.net/Docs/Comp/KeyMap for more details and mapping additional keypresses. KBDTest keyboard tests ====================== On running KBDTest, the keymap that the host is expected to be using is displayed. As you press keys a textual description of what keyboard key should return that code is displayed. KBDDemo keyboard tests ====================== On running KBDDemo, the keymap that the host is expected to be using is displayed. When selecting an option, the keymap that option is expected to use is displayed. There are three keyboard tests. Each test should return and display the keycode from the keyboard according to the keymap displayed. Other than the native GET test, the tests should return &180+n for function and editing keys to distinguish them from top-bit-set character keys. GET --- This uses GET and should wait until a keypress and return the keycode INKEY(100) ---------- This uses INKEY and should wait for up to 100cs (ie, 1 second) for a keypress. It should return -1 (displayed as FFF) for no keypress. INKEY(100+&8000) ---------------- Some host interface layers extend INKEY to allow bit 15 to indicate that a 16-bit "deep" keycode should be returned, with &180+n for function and editing keys. If this is not implemented, it will function as with INKEY(100), except that it will wait for 328 seconds. There are some more related tests: ADVAL(128-1) ------------ ADVAL(-n) where n indicates the buffer number tests for the amount of space in a buffer. Some systems implement ADVAL(128-n) to read a low level value from the buffer. Just as ADVAL(-1) tests the keyboard buffer, ADVAL(128-1) reads low-level data from the keyboard buffer. The values returned will be &000+ for normal character keys and &180+n for function and editing keys. ADVAL(-1) and EOF#0 ------------------- ADVAL(-1) returns the number of bytes in the keyboard buffer. Some systems implement EOF#0 to return zero if there is keyboard input pending, so that a program can do IF NOT EOF#0 THEN key%=GET. Some systems also return information from PTR#0 and EXT#0. This test will let you type characters and display what the functions return. The minimum compliance is that ADVAL(-1) returns 0 if the keyboard buffer is empty and non-zero if there are bytes in the keyboard buffer. Note that 'bytes in the keyboard buffer' is not synonymous with 'characters waiting for the next GET'. Consider what happens with definable function keys if a function key is undefined, and it is pressed. ADVAL(-1) will return non-zero indicating that there is a byte in the keyboard buffer. If you then call GET to read that byte, the input handler will remove the function key from the buffer, see that it is undefined, and then *continue* *waiting* *for* *another* *keypress*. Similarly, if a function key is defined, when the function key is pressed ADVAL(-1) will return indicating that the keypress is in the keyboard buffer. When you call GET the handler will remove the one byte from the keyboard buffer and start expanding the function key string. The next call to ADVAL(-1) will correctly report that there are 0 bytes in the keyboard buffer, but the next call to GET *will* return characters as long as the function key expansion still has characters to return. Also, if an EXEC file is active, but there is nothing in the keyboard buffer, ADVAL(-1) will correctly return zero, but the next GET will not wait, it will read a byte from the EXEC file and return immediately. Unless the EXEC file is at EOF, when the input handler will close it and go back to waiting for a keypress. If you implement EOF#0 it should return whether the next GET will return immediately or not, regardless of what the input stream is or what keypresses are pending. This test can be erratic if EOF#0, PTR#0 and EXT#0 do not return cleanly. Toggle kbd map -------------- You can implement an extension to *FX254 where on non-Acorn platforms the top four bits indicate a keyboard mapping to use. If it is implemented, *FX254,128 should select the native keymap that matches what the host claims it is, and *FX254,192 should select the RISC OS mapping. Quit and Restart ---------------- These options are not displayed. If the display gets messy, press TAB to clear the screen and restart. You can press 0 or Escape to exit the program. KeyTest ======= This dislays a graphical representation of the keyboard showing the hexadecimal internal key numbers that keypresses should repond to. On other platforms these are often called scancodes. The internal key numbers are negative INKEY numbers EOR'd with -1. As you press keys the key the negative INKEY number that detects it is lit up. Some keys will respond to more than one negative INKEY as keyboard layouts have evolved. Note that some systems do not distinguish between the main RETURN key and the keypad ENTER key, and BBC BASIC for Windows and SDL maps the Japanese modfier keys and the Windows keys opposite to Acorn documentation. Original program written by Tricky at StarDot. See mdfs.net/Docs/Comp/BBC/Keyboard/NegInkey for the negative INKEY values that should be used. KeyScan ======= This performs a similar function to KeyTest, but with a plain text display.