THE KEYBOARD ROUTINES THE 'KEYBOARD SCANNING' SUBROUTINE This very important subroutine is called by both the main keyboard subroutine and the INKEY$ routine (in SCANNING). In all instances the E register is returned with a value in the range of $00 to $27, the value being different for each of the forty keys of the keyboard, or the value $FF, for no-key. The D register is returned with a value that indicates which single shift key is being pressed. If both shift keys are being pressed then the D and E registers are returned with the values for the CAPS SHIFT and SYMBOL SHIFT keys respectively. If no keys is being pressed then the DE register pair is returned holding $FFFF. The zero flag is returned reset if more than two keys are being pressed, or neither key of a pair of keys is a shift key. 028E KEY-SCAN ld l,$2F The initial key value for each line will be $2F, $2E,...,$28. (Eight lines.) ld de,$FFFF Initialise DE to 'no-key'. ld bc,$FEFE C = port address, B = counter. Now enter a loop. Eight passes are made with each pass having a different initial key value and scanning a different line of five keys. (The first line is CAPS SHIFT, Z, X, C, V.) 0296 KEY-LINE in a,(c) Read from the port specified. cpl A pressed key in the line will set and $1F its respective bit (from bit 0 - outer key, to bit 4 - inner key). jr z,02AB,KEY-DONE Jump forward if none of the five keys in the line are being pressed. ld h,a The key-bits go to the H register ld a,l whilst the initial key value is fetched. 029F KEY-3KEYS inc d If three keys are being pressed ret nz on the keyboard then the D register will no longer hold $FF - so return if this happens. 02A1 KEY-BITS sub $08 Repeatedly subtract '8' from srl h the present key value until a jr nc,02A1,KEY-BITS key-bit is found. ld d,e Copy any earlier key value to the D register. ld e,a Pass the new key value to the E register. jr nz,029F,KEY-3KEYS If there is a second, or possibly a third, pressed key in this line then jump back. 02AB KEY-DONE dec l The line has been scanned so the initial key value is reduced for the next pass. rlc b The counter is shifted and the jr c,0296,KEY-LINE jump taken if there are still lines to be scanned. Four tests are now made. ld a,d Accept any key value which still inc a has the D register holding $FF. ret z i.e. A single key pressed or 'no-key'. cp $28 Accept the key value for a pair ret z of keys if the 'D' key is CAPS SHIFT. cp $19 Accept the key value for a pair ret z of keys if the 'D' key is SYMBOL SHIFT. ld a,e It is however possible for the 'E' ld e,d key of a pair to be SYMBOL ld d,a SHIFT - so this has to be cp $18 considered. ret Return with the zero flag set if it was SYMBOL SHIFT and 'another key'; otherwise reset. THE 'KEYBOARD' SUBROUTINE This subroutine is called on every occasion that a maskable interrupt occurs. In normal operation this will happen once every 20 ms. The purpose of this subroutine is to scan the keyboard and decode the key value. The code produced will, if the 'repeat' status allows it, be passed to the system variable LAST-K. When a code is put into this system variable bit 5 of FLAGS is set to show that a 'new' key has been pressed. 02BF KEYBOARD call 028E,KEY-SCAN Fetch a key value in the DE ret nz register pair but return immedi- ately if the zero pair flag is reset. A double system of 'KSTATE system variables' (KSTATE0 - KSTATE 3 and KSTATE4 - KSTATE7) is used from now on. The two sets allow for the detection of a new key being pressed (using one set) whilst still within the 'repeat period' of the previous key to have been pressed (details in the other set). A set will only become free to handle a new key if the key is held down for about 1/10 th. of a second. i.e. Five calls to KEYBOARD. ld hl,KSTATE0 Start with KSTATE0. 02C6 K-ST-LOOP bit 7,(hl) Jump forward if a 'set is free'; jr nz,02D1,K-CH-SET i.e. KSTATE0/4 holds $FF. inc hl However if the set is not free dec (hl) decrease its '5 call counter' dec hl and when it reaches zero signal jr nz,02D1,K-CH-SET the set as free. ld (hl),$FF After considering the first set change the pointer and consider the second set. 02D1 K-CH-SET ld a,l Fetch the low byte of the ld hl,KSTATE4 address and jump back if the cp l second set has still to be jr nz,02C6,K-ST-LOOP considered. Return now if the key value indicates 'no-key' or a shift key only. call 031E,K-TEST Make the necessary tests and ret nc return if needed. Also change the key value to a 'main code'. A key stroke that is being repeated (held down) is now separated from a new key stroke. ld hl,KSTATE0 Look first at KSTATE0. cp (hl) Jump forward if the codes jr z,0310,K-REPEAT match - indicating a repeat. ex de,hl Save the address of KSTATE0. ld hl,KSTATE4 Now look at KSTATE4. cp (hl) Jump forward if the codes jr z,0310,K-REPEAT match - indicating a repeat. But a new key will not be accepted unless one of the sets of KSTATE system variables is 'free'. bit 7,(hl) Consider the second set. jr nz,02F1,K-NEW Jump forward if 'free'. ex de,hl Now consider the first set. bit 7,(hl) Continue if the set is 'free' but ret z exit from the KEYBOARD subroutine if not. The new key is to be accepted. But before the system variable LAST-K can be filled, the KSTATE system variables, of the set being used, have to be initialised to handle any repeats and the key's code has to be decoded. 02F1 K-NEW ld e,a The code is passed to the ld (hl),a E register and to KSTATE0/4. inc hl The '5 call counter' for this ld (hl),$05 set is reset to '5'. inc hl The third system variable of ld a,(REPDEL) the set holds the REPDEL value ld (hl),a (normally 0.7 secs.). inc hl Point to KSTATE3/7. The decoding of a 'main code' depends upon the present state of MODE, bit 3 of FLAGS and the 'shift byte'. ld c,(MODE) Fetch MODE. ld d,(FLAGS) Fetch FLAGS. push hl Save the pointer whilst the call 0333,K-DECODE 'main code' is decoded. pop hl ld (hl),a The final code value is saved in KSTATE3/7; from where it is collected in case of a repeat. The next three instruction lines are common to the handling of both 'new keys' and 'repeat keys'. 0308 K-END ld (LAST-K),a Enter the final code value into set 5,(FLAGS) LAST-K and signal 'a new key'. ret Finally return. THE 'REPEATING KEY' SUBROUTINE A key will 'repeat' on the first occasion after the delay period - REPDEL (normally 0.7 secs.) and on subsequent occasions after the delay period - REPPER (normally 0.1 secs.). 0310 K-REPEAT inc hl Point to the '5 call counter' ld (hl),$05 of the set being used and reset it to '5'. inc hl Point to the third system vari- dec (hl) able - the REPDEL/REPPER value, and decrement it. ret nz Exit from the KEYBOARD subroutine if the delay period has not passed. ld a,(REPPER) However once it has passed the ld (hl),a delay period for the next repeat is to be REPPER. inc hl The repeat has been accepted ld a,(hl) so the final code value is fetched from KSTATE3/7 and passed jr 0308,K-END to K-END. THE 'K-TEST' SUBROUTINE The key value is tested and a return made if 'no-key' or 'shift-only'; otherwise the 'main code' for that key is found. 031E K-TEST ld b,d Copy the shift byte. ld d,$00 Clear the D register for later. ld a,e Move the key number. cp $27 Return now if the key was ret nc 'CAPS SHIFT' only or 'no-key'. cp $18 Jump forward unless the 'E' jr nz,032C,K-MAIN key was SYMBOL SHIFT. bit 7,b However accept SYMBOL SHIFT ret nz and another key; return with SYMBOL SHIFT only. The 'main code' is found by indexing into the main key table. 032C K-MAIN ld hl,$0205 The base address of the table. add hl,de Index into the table and fetch ld a,(hl) the 'main code'. scf Signal 'valid keystroke' ret before returning. THE 'KEYBOARD DECODING' SUBROUTINE This subroutine is entered with the 'main code' in the E register, the value of FLAGS in the D register, the value of MODE in the C register and the 'shift byte' in the B register. By considering these four values and referring, as necessary, to the six key tables a 'final code' is produced. This is returned in the A register. 0333 K-DECODE ld a,e Copy the 'main code'. cp $3A Jump forward if a digit key is jr c,0367,K-DIGIT being considered; also SPACE, ENTER & both shifts. dec c Decrement the MODE value. jp m,034F,K-KLC-LET Jump forward, as needed, for jr z,0341,K-E-LET modes 'K', 'L', 'C' & 'E'. Only 'graphics' mode remains and the 'final code' for letter keys in graphics mode is computed from the 'main code'. add a,$4F Add the offset. ret Return with the 'final code'. Letter keys in extended mode are considered next. 0341 K-E-LET ld hl,$01EB The base address for table 'b'. inc b Jump forward to use this table jr z,034A,K-LOOK-UP if neither shift key is being pressed. ld hl,$0205 Otherwise use the base address for table 'c'. Key tables 'b-f' are all served by the following look-up routine. In all cases a 'final code' is found and returned. 034A K-LOOK-UP ld d,$00 Clear the D register. add hl,de Index the required table ld a,(hl) and fetch the 'final code'. ret Then return. Letter keys in 'K', 'L' or 'C' modes are now considered. But first the special SYMBOL SHIFT codes have to be dealt with. 034F K-KLC-LET ld hl,$0229 The base address for table 'e' bit 0,b Jump back if using the SYMBOL jr z,034A,K-LOOK-UP SHIFT key and a letter key. bit 3,d Jump forward if currently in jr z,0364,K-TOKENS 'K' mode. bit 3,(FLAGS2) If CAPS LOCK is set then ret nz return with the 'main code' inc b Also return in the same manner ret nz if CAPS SHIFT is being pressed. add a,$20 However if lower case codes are ret required then $20 has to be added to the 'main code' to give the correct 'final code'. The 'final code' values for tokens are found by adding $A5 to the 'main code'. 0364 K-TOKENS add a,$A5 Add the required offset and ret return. Next the digit keys; and SPACE, ENTER & both shifts; are considered. 0367 K-DIGIT cp $30 Proceed only with the digit keys. ret c i.e. Return with SPACE ($20), ENTER ($0D) & both shifts ($0E). dec c Now separate the digit keys into three groups - according to the mode. jp m,039D,K-KLC-DGT Jump with 'K', 'L' & 'C' modes; jr nz,0389,K-GRA-DGT and also with 'G' mode. Continue with 'E' mode. ld hl,$0254 The base address for table 'f'. bit 5,b Use this table for SYMBOL jr z,034A,K-LOOK-UP SHIFT & a digit key in extended mode. cp $38 Jump forward with digit keys jr nc,0382,K-8-&-9 '8' and '9'. The digit keys '0' to '7' in extended mode are to give either a 'paper colour code' or an 'ink colour code' depending on the use of the CAPS SHIFT. sub $20 Reduce the range $30 to $37 giving $10 to $17. inc b Return with this 'paper colour ret z code' if the CAPS SHIFT is not being used. add a,$08 But if it is then the range is to ret be $18 to $1F instead - indicat- ing an 'ink colour code'. The digit keys '8' and '9' are to give 'BRIGHT' & 'FLASH' codes. 0382 K-8-&-9 sub $36 $38 & $39 go to $02 & $03. inc b Return with these codes if CAPS ret z SHIFT is not being used. (These are 'BRIGHT' codes.) add a,$FE Subtract '2' is CAPS SHIFT is ret being used; giving $00 & $01 (as 'FLASH' codes). The digit keys in graphics mode are to give the block graphic characters ($80 to $8F), the GRAPHICS code ($0F) and the DELETE code ($0C). 0389 K-GRA-DGT ld hl,$0230 The base address of table 'd'. cp $39 Use this table directly for jr z,034A,K-LOOK-UP both digit key '9' that is to give cp $30 GRAPHICS, and digit key '0' jr z,034A,K-LOOK-UP that is to give DELETE. and $07 For keys '1' to '8' make the add a,$80 range $80 to $87. inc b Return with a value from this ret z range if neither shift key is being pressed. xor $0F But if 'shifted' make the range ret $88 to $8F. Finally consider the digit keys in 'K', 'L' & 'C' modes. 039D K-KLC-DGT inc b Return directly if neither shift ret z key is being used. (Final codes $30 to $39.) bit 5,b Use table 'd' if the CAPS ld hl,$0230 SHIFT key is also being jr nz,034A,K-LOOK-UP pressed. The codes for the various digit keys and SYMBOL SHIFT can now be found. sub $10 Reduce the range to give $20 to $29. cp $22 Separate the '@' character jr z,03B2,K-@-CHAR from the others. cp $20 The '-' character has also to be separated. ret nz Return now with the 'final codes' $21, $23 to $29. ld a,$5F Give the '-' character a ret code of $5F. 03B2 K-@-CHAR ld a,$40 Give the '@' character a code ret of $40. THE LOUDSPEAKER ROUTINES