| Routines

02BF: THE 'KEYBOARD' SUBROUTINE

Used by the routine at MASK_INT. 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.
KEYBOARD | 02BF | CALL KEY_SCAN | Fetch a key value in the DE register pair but return immediately if the zero flag is reset.
| 02C2 | RET NZ
A double system of 'KSTATE system variables' (KSTATE0-KSTATE3 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/10th. of a second, i.e. five calls to KEYBOARD.
| 02C3 | LD HL,$5C00 | Start with KSTATE0.
K_ST_LOOP | 02C6 | BIT 7,(HL) | Jump forward if a 'set is free', i.e. KSTATE0/4 holds +FF.
| 02C8 | JR NZ,K_CH_SET
| 02CA | INC HL | However if the set is not free decrease its '5 call counter' and when it reaches zero signal the set as free.
| 02CB | DEC (HL)
| 02CC | DEC HL
| 02CD | JR NZ,K_CH_SET
| 02CF | LD (HL),$FF
After considering the first set change the pointer and consider the second set.
K_CH_SET | 02D1 | LD A,L | Fetch the low byte of the address and jump back if the second set (KSTATE4) has still to be considered.
| 02D2 | LD HL,$5C04
| 02D5 | CP L
| 02D6 | JR NZ,K_ST_LOOP
Return now if the key value indicates 'no-key' or a shift key only.
| 02D8 | CALL K_TEST | Make the necessary tests and return if needed. Also change the key value to a 'main code'.
| 02DB | RET NC
A key stroke that is being repeated (held down) is now separated from a new key stroke.
| 02DC | LD HL,$5C00 | Look first at KSTATE0.
| 02DF | CP (HL) | Jump forward if the codes match - indicating a repeat.
| 02E0 | JR Z,K_REPEAT
| 02E2 | EX DE,HL | Save the address of KSTATE0.
| 02E3 | LD HL,$5C04 | Now look at KSTATE4.
| 02E6 | CP (HL) | Jump forward if the codes match - indicating a repeat.
| 02E7 | JR Z,K_REPEAT
But a new key will not be accepted unless one of the sets of KSTATE system variables is 'free'.
| 02E9 | BIT 7,(HL) | Consider the second set.
| 02EB | JR NZ,K_NEW | Jump forward if 'free'.
| 02ED | EX DE,HL | Now consider the first set.
| 02EE | BIT 7,(HL) | Continue if the set is 'free' but exit if not.
| 02F0 | RET Z
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.
K_NEW | 02F1 | LD E,A | The code is passed to the E register and to KSTATE0/4.
| 02F2 | LD (HL),A
| 02F3 | INC HL | The '5 call counter' for this set is reset to '5'.
| 02F4 | LD (HL),$05
| 02F6 | INC HL | The third system variable of the set holds the REPDEL value (normally 0.7 secs.).
| 02F7 | LD A,($5C09)
| 02FA | LD (HL),A
| 02FB | 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'.
| 02FC | LD C,(IY+$07) | Fetch MODE.
| 02FF | LD D,(IY+$01) | Fetch FLAGS.
| 0302 | PUSH HL | Save the pointer whilst the 'main code' is decoded.
| 0303 | CALL K_DECODE
| 0306 | POP HL
| 0307 | 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 instructions are common to the handling of both 'new keys' and 'repeat keys'.
K_END | 0308 | LD ($5C08),A | Enter the final code value into LAST-K and signal 'a new key' by setting bit 5 of FLAGS.
| 030B | SET 5,(IY+$01)
| 030F | RET | Finally return.
A key will 'repeat' on the first occasion after the delay period (REPDEL - normally 0.7s) and on subsequent occasions after the delay period (REPPER - normally 0.1s).
K_REPEAT | 0310 | INC HL | Point to the '5 call counter' of the set being used and reset it to 5.
| 0311 | LD (HL),$05
| 0313 | INC HL | Point to the third system variable - the REPDEL/REPPER value - and decrement it.
| 0314 | DEC (HL)
| 0315 | RET NZ | Exit from the KEYBOARD subroutine if the delay period has not passed.
| 0316 | LD A,($5C0A) | However once it has passed the delay period for the next repeat is to be REPPER.
| 0319 | LD (HL),A
| 031A | INC HL | The repeat has been accepted so the final code value is fetched from KSTATE3/7 and passed to K_END.
| 031B | LD A,(HL)
| 031C | JR K_END