Prev: 028E Up: Map Next: 031E
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
Prev: 028E Up: Map Next: 031E