| Routines

028E: THE 'KEYBOARD SCANNING' SUBROUTINE

This very important subroutine is called by both the main keyboard subroutine (KEYBOARD) and the INKEY$ routine (S_INKEY). 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 key 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.
Output
D | Shift key pressed (+18 or +27), or +FF if no shift key pressed
E | Other key pressed (+00 to +27), or +FF if no other key pressed
F | Zero flag reset if an invalid combination of keys is pressed
KEY_SCAN | 028E | LD L,$2F | The initial key value for each line will be +2F, +2E,..., +28. (Eight lines.)
| 0290 | LD DE,$FFFF | Initialise DE to 'no-key'.
| 0293 | 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.)
KEY_LINE | 0296 | IN A,(C) | Read from the port specified.
| 0298 | CPL | A pressed key in the line will set its respective bit, from bit 0 (outer key) to bit 4 (inner key).
| 0299 | AND $1F
| 029B | JR Z,KEY_DONE | Jump forward if none of the five keys in the line are being pressed.
| 029D | LD H,A | The key-bits go to the H register whilst the initial key value is fetched.
| 029E | LD A,L
KEY_3KEYS | 029F | INC D | If three keys are being pressed on the keyboard then the D register will no longer hold +FF - so return if this happens.
| 02A0 | RET NZ
KEY_BITS | 02A1 | SUB $08 | Repeatedly subtract 8 from the present key value until a key-bit is found.
| 02A3 | SRL H
| 02A5 | JR NC,KEY_BITS
| 02A7 | LD D,E | Copy any earlier key value to the D register.
| 02A8 | LD E,A | Pass the new key value to the E register.
| 02A9 | JR NZ,KEY_3KEYS | If there is a second, or possibly a third, pressed key in this line then jump back.
KEY_DONE | 02AB | DEC L | The line has been scanned so the initial key value is reduced for the next pass.
| 02AC | RLC B | The counter is shifted and the jump taken if there are still lines to be scanned.
| 02AE | JR C,KEY_LINE
Four tests are now made.
| 02B0 | LD A,D | Accept any key value which still has the D register holding +FF, i.e. a single key pressed or 'no-key'.
| 02B1 | INC A
| 02B2 | RET Z
| 02B3 | CP $28 | Accept the key value for a pair of keys if the D key is CAPS SHIFT.
| 02B5 | RET Z
| 02B6 | CP $19 | Accept the key value for a pair of keys if the D key is SYMBOL SHIFT.
| 02B8 | RET Z
| 02B9 | LD A,E | It is however possible for the E key of a pair to be SYMBOL SHIFT - so this has to be considered.
| 02BA | LD E,D
| 02BB | LD D,A
| 02BC | CP $18
| 02BE | RET | Return with the zero flag set if it was SYMBOL SHIFT and 'another key'; otherwise reset.