Input and the keyboard decoder
Input from the keyboard can be achieved by treating it as a device and using the file I/O calls. Four calls read from the standard input, which unless it has been rebound by the CLI, will be the keyboard. These calls are:
OS_In        read a character from the standard input
OS_Tin       read a character from the standard input, with timeout
GN_Sip       standard input line routine
OS_Sr        reads a character when doing a "Page Wait". Returns always ASCII 8
             or an RC_ error code.
GN_Sip is described later in this section and OS_Sr is discussed in "Miscellaneous useful routines". OS_In and OS_Tin return the character read in register A and Fc = 0 to indicate success. Since these are pre-emptable calls they may return Fc = 1 and any of RC_SUSP, RC_DRAW, RC_ESC, RC_QUIT and, in the case of OS_Tin, RC_TIME. These calls usually returns ASCII values, but for special Z88 keys and menu commands, some other encoding is required. The solution is that when a special key or menu command occurrs, the OS_In or OS_Tin will return a zero. The call is then made again and the value returned by this second call corresponds to the special key or menu command. The codes for the special keyboard sequences are shown below, those marked * are not zero prefixed. Keys marked with ** are internal keycodes and not available to applications. Finally, note that register pair AF and the alternate registers are corrupted by OS_In (as almost all system calls). OS_Tin waits for keyboard input for as long as the number of centiseconds specified in the BC(in) register pair, and on exit BC will be the centiseconds of the timeout remaining, and so BC will have changed as well as AF and the alternate register set.Â
Â
Key          normal          <SQUARE>      <DIAMOND>     <SHIFT>
<SQUARE>Â Â Â Â Â IN_SQU, $B8 **
<DIAMOND>Â Â Â Â IN_DIA, $C8 **
<SHIFT>Â Â Â Â Â Â IN_SHI, $D8 **
<CAPS LOCK>Â Â IN_CAPS, $E8 ***
<SPACE>Â Â Â Â Â Â IN_SPC, $20Â Â Â Â Â IN_ASPC, $B0Â Â IN_DSPC, $C0Â Â -
<ENTER>Â Â Â Â Â Â IN_ENT, $0D *Â Â Â IN_AENT, $B1Â Â IN_DENT, $C1Â Â IN_SENT, $D1
<TAB>Â Â Â Â Â Â Â Â IN_TAB, $09 *Â Â Â IN_ATAB, $B2Â Â IN_DTAB, $C2Â Â IN_STAB, $D2
<DEL>Â Â Â Â Â Â Â Â IN_DEL, $7F *Â Â Â IN_ADEL, $B3Â Â IN_DDEL, $C3Â Â IN_SDEL, $D3
<ESC>Â Â Â Â Â Â Â Â IN_ESC, $1B *Â Â Â IN_AESC, $B4Â Â IN_DESC, $C4Â Â IN_SESC, $D4 **
<MENU>Â Â Â Â Â Â Â IN_MEN, $E5 **Â Â IN_AMEN, $B5Â Â IN_DMEN, $C5Â Â IN_SMEN, $D5
<INDEX>Â Â Â Â Â Â IN_IDX, $E6 **Â Â IN_AIDX, $B6Â Â IN_DIDX, $C6Â Â IN_SIDX, $D6
<HELP>Â Â Â Â Â Â Â IN_HLP, $E7 **Â Â IN_AHEL, $B7Â Â IN_DHEL, $C7Â Â IN_SHEL, $D7
<LEFT>Â Â Â Â Â Â Â IN_LFT, $FCÂ Â Â Â Â IN_ALFT, $F0Â Â IN_DLFT, $F4Â Â IN_SLFT, $F8
<RIGHT>Â Â Â Â Â Â IN_RGT, $FDÂ Â Â Â Â IN_ARGT, $F1Â Â IN_DRGT, $F5Â Â IN_SRGT, $F9
<DOWN>Â Â Â Â Â Â Â IN_DWN, $FEÂ Â Â Â Â IN_ADWN, $F2Â Â IN_DDWN, $F6Â Â IN_SDWN, $FA
<UP>Â Â Â Â Â Â Â Â Â IN_UP, $FFÂ Â Â Â Â Â IN_AUP, $F3Â Â Â IN_DUP, $F7Â Â Â IN_SUP, $FB
***) This 'key' is the forces Lock out state produced by switching the machine on, and while holding both <SHIFT> keys down, pressing the <CAPS> lock key.
Note that the diamond key operates like a <CTRL> key on a conventional keyboard and can be used to generate the sub-32 control characters, eg. <>G for BEL,
provided the key in question is not a menu command. The following is a list of obtainable control characters:
HEXÂ Â Â Â Â Â Â Â Â Â DECIMALÂ Â Â Â Â Â Â Â Â SYMBOLÂ Â Â Â Â Â Â Â KEYSÂ Â Â Â Â Â Â Â Â Â DESCRIPTION
$00Â Â Â Â Â Â Â Â Â Â 0Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NULÂ Â Â Â Â Â Â Â Â Â Â <>=Â Â Â Â Â Â Â Â Â Â Â NULL
$01Â Â Â Â Â Â Â Â Â Â 1Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SOHÂ Â Â Â Â Â Â Â Â Â Â <>AÂ Â Â Â Â Â Â Â Â Â Â Start of header
$02Â Â Â Â Â Â Â Â Â Â 2Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â STXÂ Â Â Â Â Â Â Â Â Â Â <>BÂ Â Â Â Â Â Â Â Â Â Â Start of text
$03Â Â Â Â Â Â Â Â Â Â 3Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ETXÂ Â Â Â Â Â Â Â Â Â Â <>CÂ Â Â Â Â Â Â Â Â Â Â End of text
$04Â Â Â Â Â Â Â Â Â Â 4Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â EOTÂ Â Â Â Â Â Â Â Â Â Â <>DÂ Â Â Â Â Â Â Â Â Â Â End of transmission
$05Â Â Â Â Â Â Â Â Â Â 5Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ENQÂ Â Â Â Â Â Â Â Â Â Â <>EÂ Â Â Â Â Â Â Â Â Â Â Enquiry
$06Â Â Â Â Â Â Â Â Â Â 6Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ACKÂ Â Â Â Â Â Â Â Â Â Â <>FÂ Â Â Â Â Â Â Â Â Â Â Acknowledge
$07Â Â Â Â Â Â Â Â Â Â 7Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â BELÂ Â Â Â Â Â Â Â Â Â Â <>GÂ Â Â Â Â Â Â Â Â Â Â Bell
$08Â Â Â Â Â Â Â Â Â Â 8Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â BSÂ Â Â Â Â Â Â Â Â Â Â Â <>HÂ Â Â Â Â Â Â Â Â Â Â Backspace
$09Â Â Â Â Â Â Â Â Â Â 9Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â HTÂ Â Â Â Â Â Â Â Â Â Â Â <>IÂ Â Â Â Â Â Â Â Â Â Â Horizontal tabulation
$0AÂ Â Â Â Â Â Â Â Â Â 10Â Â Â Â Â Â Â Â Â Â Â Â Â Â LFÂ Â Â Â Â Â Â Â Â Â Â Â <>JÂ Â Â Â Â Â Â Â Â Â Â Line feed
$0BÂ Â Â Â Â Â Â Â Â Â 11Â Â Â Â Â Â Â Â Â Â Â Â Â Â VTÂ Â Â Â Â Â Â Â Â Â Â Â <>KÂ Â Â Â Â Â Â Â Â Â Â Vertical tabulation
$0CÂ Â Â Â Â Â Â Â Â Â 12Â Â Â Â Â Â Â Â Â Â Â Â Â Â FFÂ Â Â Â Â Â Â Â Â Â Â Â <>LÂ Â Â Â Â Â Â Â Â Â Â Form feed
$0DÂ Â Â Â Â Â Â Â Â Â 13Â Â Â Â Â Â Â Â Â Â Â Â Â Â CRÂ Â Â Â Â Â Â Â Â Â Â Â <>MÂ Â Â Â Â Â Â Â Â Â Â Carriage return
$0EÂ Â Â Â Â Â Â Â Â Â 14Â Â Â Â Â Â Â Â Â Â Â Â Â Â SOÂ Â Â Â Â Â Â Â Â Â Â Â <>NÂ Â Â Â Â Â Â Â Â Â Â Shift out
$0FÂ Â Â Â Â Â Â Â Â Â 15Â Â Â Â Â Â Â Â Â Â Â Â Â Â SIÂ Â Â Â Â Â Â Â Â Â Â Â <>OÂ Â Â Â Â Â Â Â Â Â Â Shift in
$10Â Â Â Â Â Â Â Â Â Â 16Â Â Â Â Â Â Â Â Â Â Â Â Â Â DLEÂ Â Â Â Â Â Â Â Â Â Â <>PÂ Â Â Â Â Â Â Â Â Â Â Data link escape
$11Â Â Â Â Â Â Â Â Â Â 17Â Â Â Â Â Â Â Â Â Â Â Â Â Â DC1Â Â Â Â Â Â Â Â Â Â Â <>QÂ Â Â Â Â Â Â Â Â Â Â Device control 1 (XON)
$12Â Â Â Â Â Â Â Â Â Â 18Â Â Â Â Â Â Â Â Â Â Â Â Â Â DC2Â Â Â Â Â Â Â Â Â Â Â <>RÂ Â Â Â Â Â Â Â Â Â Â Device control 2
$13Â Â Â Â Â Â Â Â Â Â 19Â Â Â Â Â Â Â Â Â Â Â Â Â Â DC3Â Â Â Â Â Â Â Â Â Â Â <>SÂ Â Â Â Â Â Â Â Â Â Â Device control 1 (XOFF)
$14Â Â Â Â Â Â Â Â Â Â 20Â Â Â Â Â Â Â Â Â Â Â Â Â Â DC4Â Â Â Â Â Â Â Â Â Â Â <>TÂ Â Â Â Â Â Â Â Â Â Â Device control 4
$15Â Â Â Â Â Â Â Â Â Â 21Â Â Â Â Â Â Â Â Â Â Â Â Â Â NAKÂ Â Â Â Â Â Â Â Â Â Â <>UÂ Â Â Â Â Â Â Â Â Â Â Negative acknowledge
$16Â Â Â Â Â Â Â Â Â Â 22Â Â Â Â Â Â Â Â Â Â Â Â Â Â SYNÂ Â Â Â Â Â Â Â Â Â Â <>VÂ Â Â Â Â Â Â Â Â Â Â Synchronous idle
$17Â Â Â Â Â Â Â Â Â Â 23Â Â Â Â Â Â Â Â Â Â Â Â Â Â ETBÂ Â Â Â Â Â Â Â Â Â Â <>WÂ Â Â Â Â Â Â Â Â Â Â End of transmitted block
$18Â Â Â Â Â Â Â Â Â Â 24Â Â Â Â Â Â Â Â Â Â Â Â Â Â CANÂ Â Â Â Â Â Â Â Â Â Â <>XÂ Â Â Â Â Â Â Â Â Â Â Cancel line
$19Â Â Â Â Â Â Â Â Â Â 25Â Â Â Â Â Â Â Â Â Â Â Â Â Â EMÂ Â Â Â Â Â Â Â Â Â Â Â <>YÂ Â Â Â Â Â Â Â Â Â Â End of medium
$1AÂ Â Â Â Â Â Â Â Â Â 26Â Â Â Â Â Â Â Â Â Â Â Â Â Â SUBÂ Â Â Â Â Â Â Â Â Â Â <>ZÂ Â Â Â Â Â Â Â Â Â Â Substitute (End of file)
$1BÂ Â Â Â Â Â Â Â Â Â 27Â Â Â Â Â Â Â Â Â Â Â Â Â Â ESCÂ Â Â Â Â Â Â Â Â Â Â <>[ or ESCÂ Â Â Â Escape
$1CÂ Â Â Â Â Â Â Â Â Â 28Â Â Â Â Â Â Â Â Â Â Â Â Â Â FSÂ Â Â Â Â Â Â Â Â Â Â Â <>\Â Â Â Â Â Â Â Â Â Â Â File separator
$1DÂ Â Â Â Â Â Â Â Â Â 29Â Â Â Â Â Â Â Â Â Â Â Â Â Â GSÂ Â Â Â Â Â Â Â Â Â Â Â <>]Â Â Â Â Â Â Â Â Â Â Â Group separator
$1EÂ Â Â Â Â Â Â Â Â Â 30Â Â Â Â Â Â Â Â Â Â Â Â Â Â RSÂ Â Â Â Â Â Â Â Â Â Â Â <>`Â Â Â Â Â Â Â Â Â Â Â Record separator
$1FÂ Â Â Â Â Â Â Â Â Â 31Â Â Â Â Â Â Â Â Â Â Â Â Â Â USÂ Â Â Â Â Â Â Â Â Â Â Â <>-Â Â Â Â Â Â Â Â Â Â Â Unit separator
The Input Line Routine
GN_Sip is the standard system input line routine and used by most of the applications (Diary uses it for editing individual lines on a date page). It provides access to all the standard editing commands which are:
<>DELÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Delete line
<>DÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Delete to end of line
<>GÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Delete character under cursor, rightward
<>MÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â <ENTER>
<>SÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Swap case
<>TÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Delete word under cursor
<>UÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Insert character
<>VÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Insert/Overtype (see below for complications)
<><LEFT>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Start of line
<><RIGHT>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â End of line
<SHIFT><LEFT>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Previous word
<SHIFT><RIGHT>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Next word
Where appropriate the following editing commands should be implemented (this is machine conventions):
<>JÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Next option , where input is limited all the option can
                              be cycled through using this command
<><UP>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Top of current page
<><DOWN>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Bottom of current page
<SHIFT><UP>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Move up a screenful
<SHIFT><DOWN>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Move down a screenful
<TAB>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Next column or TAB
<SHIFT><TAB>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Previous column or TAB
The basic specifications of GN_Sip is as follows:
Â
RST 20H, DEFW $3909 IN:              DE = buffer for input string              A0 = 1, buffer already contains data to be edited              A1 = 1, force insert/overwrite mode (see A2)              A2 = 1, if A1 = 1, 0 = insert mode, 1 = overwrite mode              A3 = 1, return unexpected characters              A4 = 1, return if wrap occurs              A5 = 1, single line lock control              A6 = 1, disply in reverse video              A7 = 1, if A3 = 1, allow for insert/overwrite return              B = length of buffer              C = cursor position, if A0 = 1              L = width of line, if A5 = 1 (incl. null-terminator) OUT, if call successful:              Fc = 0              B = length of line entered, including terminating null              C = cursor position on exit              A = character which caused end of input OUT, if call failed:              Fc = 1              A = error code:                               RC_BAD ($04), bad arguments                               RC_WRAP ($0D), wrapping has occurred (only if A4 = 1)                               RC_SUSP ($69), suspicion of suspension                               RC_DRAW ($66), application screen needs redrawing                               RC_QUIT ($67), kill request (e.g. from INDEX)                               RC_ESC ($01), if escape detection is enabled Registers changed after return:              ....DEHL/IXIY same              AFBC..../.... different
If bit 0 of register A is set then DE should point to a null-terminated string which is no greater than the buffer length specified in B. GN_Sip will write this string to standard output starting at the cursor position and then place the cursor at the position in the buffer indicated by C. If C is greater than B, then the cursor is placed at the end of the buffer. Note that if GN_Sip is suspended then to continue editing the cursor needs to be re-positioned to the start of the input line and GN_Sip called again with A0 set and the buffer length reset to its initial value. Unless this is done suspension will not be transparent, eg. whenever <DIAMOND> is inadvertently pressed during input, the input would be terminated or ots output would be corrupted.
Setting A1 allows you to force insert or overtype mode, with A2, as the mode to be used in the input line, rather than using the default as set by the Panel. This can be useful in its own right and in addition can be used to implement a local insert or overtype mode.
If A3 is not set then input is terminated only by <ENTER>, A = IN_ENT, or <ESC>. <ESC> will return with A = IN_ESC if escape detection is disabled, or A = RC_ESC and Fc = 1 if escape detection is enabled. However, if A3 is set then many more key sequences will cause the routine to exit. All the single letter Diamond codes will return their control character, except for <>D, <>G, <>S, <>T, <>U and <>V, which carry out their normal editing functions. Menu commands in the form of diamond sequences, excepting those starting with D, G, S, T, U and V, will return their command code. <>S and the <LEFT> and <RIGHT> arrows, with or without <SHIFT> or <DIAMOND>, will return their codes if an attempt is made to move outside of the buffer and A4 is not set. Any other key sequence which has no meaning in the input line routine will cause an exit, eg. <SHIFT><UP> will return with A = IN_SUP. Note that if A7 is set then <>V will cause an exit, thus allowing a local inseert/overtype mode to be established, as is done in PipeDream.
If A4 is set then an attempt to move outside the limits of the buffer will cause an exit with A = RC_WRAP, and the key which caused the wrapping will be lost.
A5 is set to select single line lock mode. This sets up a horizontal window of length L and will scroll the input buffer, if necessary, within this window. This feature is useful if you have a limited space to display the input line, but may need a long input string.Â
Â
Example
The following example uses a locked line width of 15 characters. When <ENTER> is pressed the full input line is displayed. When the buffer is nearly full, try suspending GN_Sip, eg. by pressing the Square key twice, and you will see a slight flicker as GN_Sip re-displays and scrolls the line.
include "stdio.def"                      ; get standard I/O definitions include "errors.def"                     ; get error code definitions defc init = 32                               ; mode for GN_Sip (single line lock) ; assume that on entry IY points to 40 bytes of free space ; code starts here... .main        ld  a, 12              oz OS_Out                 ; clear screen              call fetch                     ; fetch the line                                              ; may need to check errors here...              push iy              pop hl                        ; HL points at start of input buffer              oz GN_Nln                 ; output a newline              oz GN_Sop                 ; display input buffer              oz GN_Nln                ; terminate with another newline              ret ; actual input line subroutine .fetch       ld  a, init                   ; initial mode of GN_Sip              push iy              pop de                        ; DE points at input buffer              ld  b, 30                     ; max. buffer size              ld  c, 0                      ; cursor position at beginning .sip         ld  hl, pos                   ; input prompt text              oz GN_Sop                ; to standard output              ld  l, 15                     ; max. line width              oz GN_Sip                ; edit line buffer...              ret nc                        ; return if no errors              cp  RC_SUSP                   ; check for suspension              ret nz                        ; return if some other error              ld  b, 30                     ; reset buffer length              ld  a, init | 1               ; buffer contains data              jr  sip                       ; re-enter GN_Sip ; define constant string .pos         defm 1, "3@", 32, 35         ; cursor at (0,3)              defm "Input: "                 ; prompt              defb 0                         ; null-terminator
Â
Â