ZX81 KEYBOARD Subroutine—Commentary

by drj

Chapter Ten of "Mastering Machine Code On Your ZX81" [BAKER81], has a description of the new ROM (ZX81) keyboard scanning routine. In the new ROM it is at 0x02BB and is called KEYBOARD in [LH1982].

KEYBOARD is a neat little routine that deposits in HL information about which keys are pressed, and additionally if Shift is pressed; Shift can be pressed in combination with another key.

The keyboard is divided into 8 horizontal zones (sections in [BAKER81]) of 5 keys each (except zone 0 which only has 4 keys); each zone corresponding to a bit in L. The keyboard is also divided into 5 vertical zones (sections) of 8 keys each again except Zone 1 which has only 7), and a bonus "vertical" zone (Zone 0), that has only the Shift key (bottom left); each zone corresponding to a bit in H.

After calling the routine the bits of H and L are all set, except for where the corresponding zone has keypress. When there is no keypress, all the bits are set. If a single key is pressed, we can cross-reference the horizontal zones with the vertical zones and work out which key is pressed.

The horizontal zones are arranged so that an adjacent block of 5 keys is one zone (QWERT is zone 2 for example); The vertical zones are arranged so that 2 coloumns of 4 keys each is one zone. Conveniently the number keys 1 2 3 4 5 are in vertical zones 1 to 5; the vertical zones are mirrored on the right-hand side of the keyboard.

The zones look like this:

   +--V1---------------+
   |                   |
   |   +-V3--------+   |
   |   |           |   |
   |   |   +V5-+   |   |
   |   |   |   |   |   |
H3 1 2 3 4 5   6 7 8 9 0    H4
H2 Q W E R T   Y U I O P    H5
H1 A S D F G   H J K L [NL] H6
H0   Z X C V   B N M . [SP] H7
     |   |       |   |  
     |   +-V4----+   |  
     |               |  
     +--V2-----------+

Thus when S is pressed H is 0xFB (vertical zone 2 is clear), and L is 0xFD (horizontal zone 1 is clear).

The hardware for the ZX81 keyboard is very simple and is a more regular version of the above scheme: the keys are arranged logically in a 8x5 matrix, the shift key is not special in hardware, it is part of the Shift Z X C V zone. Reading a keyboard port returns 5 bits corresponding to the keys pressed in one of the 8 zones according to which port was read (sort of).

Thanks to this github repo where someone is reconstructing the ZX80 PCB i can show this detail from the schematic (the ZX81 and the ZX Spectrum have the same keyboard schematic):

The Z80 address bus A8 through to A15 are wired to the 8 horizontal zones, and five wires come off the bottom which are are fed into the Z80 D0 to D4 lines through a 74LS135 driver which is selected when the keyboard I/O port is read. When a key is pressed in a zone that has its A- wire low, the corresponding D wire will be driven low and sensed by the Z80 IN instruction (as a 0 bit).

The routine for scanning the keyboard is given on [BAKER81] page 95 (here, numbers are in hexadecimal, but in my text i shall try and use a 0x prefix):

K00: LD HL,FFFF
K03: LD BC,FEFE
K06: IN A,(C)
K08: OR 01
K0A: OR E0  ; loop target
K0C: LD D,A
K0D: CPL
K0E: CP 01
K10: SBC A,A
K11: OR B
K12: AND L
K13: LD L,A
K14: LD A,H
K15: AND D
K16: LD H,A
K17: RLC B
K19: IN A,(C)
K1B: JR C,K0A
K1D: RRA
K1E: RL H
K20: RET

If you are not that familiar with Z80 assembler or you need a refresher, i've put an emergency cheatsheet at the end, but be warned it is not a tutorial—probably best if you know some sort of assembler already.

The keypress information returned by this KEYBOARD routine is a bit raw, [BAKER81] has a further routine that converts this raw keypress information into character codes.

The ZX81 keyboard seems a little bit primitive (it is), but more or less elaborate versions of this exist in most keyboards. Even things that you might not think of as keyboads, like the Game Boy action and direction buttons which are arranged in a 2×4 matrix.

Emergency Cheatsheet for Z80 assembler

REFERENCES

[BAKER81] "Mastering Machine Code On Your ZX81"; Toni Baker; 1981.

[LH1982] "The Complete Timex TS1000 & Sinclair ZX81 ROM Disassembly"; Dr. Ian Logan, Dr. Frank O‘Hara.

END