Use the Spectrum 128 style menu below to navigate to the various sections detailing the keypad.
|Method Of Operation|
The software that handles the new keypad editing functions is contained within the EDITOR ROM of the Spectrum 128; the communication routines to the keypad are all contained within the 48K BASIC ROM. These communications routines are stored in the unused locations at the end of the standard Spectrum ROM, from address 386Eh onwards. These locations would normally all hold FFh, and so utilising this area in theory should not cause any incompatibility problems. These communications routines are accessed via a patch which has been inserted in the normal keyboard scanning routine at location 004Ah. It simply makes a call to address 386Eh where a check is made to see if the machine is in 128K mode and hence whether to attempt to scan the keypad. An immediate return is made to the keyboard scanning routine if in 48K mode, otherwise a call is made to address 3A42h.
The routine at address 3A42h monitors the FRAMES System Variable and will only attempt to scan the keypad upon every other keyboard scan, i.e. every 40ms. In this way, the keyboard scanning routine is not continually slowed down. After this check, a call to address 39A0h returns the state of the keypad. If any keys were being pressed, key repeat and decoding are performed to produce a key code which is then stored in System Variable LAST_K (5C08h). A 128K BASIC program could monitor the keypad by examining the contents of LAST_K, although only the numeric and arithmetic operator ASCII codes are returned. This is due to the ROM code knowing that it is currently running a BASIC program and hence the keypad could not possibly be providing editing functions. When editing a BASIC program the codes returned in LAST_K for the new editing functions are all above A0h. The codes for existing editing functions, i.e. DELETE, EDIT (i.e. CMND), ENTER and the cursor keys, are as the standard Spectrum control code values. The Spectrum 128 keypad operates in either CALCULATOR / BASIC mode or MENU / EDIT mode and the LAST_K values returned depends upon the mode that the Spectrum 128 is currently running in. Note that when in MENU / EDIT mode, SHIFT TOGGLE has no function but a LAST_K value of B2h is returned and then ignored.
The code at address 39A0h attempts to scan the keypad by first checking the contents of System Variable ROW2/ROW1 (5B89h). This holds a counter which must reach zero before the keypad will be read. This counter is initially set to 4Ch and is decremented every time an attempt is made to scan the keypad. This causes an actual scan of the keypad to only occur three seconds after the keypad is connected or the Spectrum 128 is powered up. When this counter reaches zero, a poll is sent to the keypad and an acknowledgement is expected. If a reply is not received, then the counter is reset to 4Ch and a fresh attempt at establishing communications with the keypad will not occur for a further three seconds. While communications has yet to be established, System Variable FLAGS/ROW3 (5B88h) will hold a value of 01h; this will change to 00h when the Spectrum 128 does established communications with the keypad.
|Row 1 (Read 3rd)|
|Row 2 (Read 4th)|
|Row 3 (Read 5th)|
|Row 4 (Read 2nd)|
|Row 5 (Read 1st)|
The keys on the keypad are arranged as a 5 row by 4 column matrix, with two keys on the bottom row not being implemented. Once a successful poll has occurred, the FLAGS nibble of 5B88h will be set to Ch and then each row of the keypad is read in. On subsequent reads of the keypad the poll is skipped if the FLAGS nibble (5B88h) already contains Ch and hence the rows are read in directly. It is therefore the two upper bits of the FLAGS nibble (5B88h) that indicate if communications to the keypad has already been established.
The rows are read in the following order: row 5, 4, 1, 2 and finally 3. Each row's data consists of four bits (one nibble) with each bit indicating the status of one of the keys in that row. Note that row 1 refers to the top row of the keypad. To avoid wasting time reading in rows where no keys have been pressed, a status bit is generated by the keypad and this indicates if any keys in the current row have been pressed. This status bit will be set (i.e. a value of 1) if any keys in the row are being pressed. The status bit is transmitted prior to each row, and only if this status bit is set (i.e. at least one key in the row has been pressed) will the row's nibble of data be transmitted. The Spectrum 128 will read in the status bit for the row and will therefore know whether to expect a nibble of data or to assume a nibble of 0h. If a nibble of data is transmitted then the bit corresponding to the right hand column of the keypad is transmitted first; this is referred to as column 4 in the rest of this text. A bit will be set to logic 1 if the corresponding key is being pressed. As each bit is read in, it is shifted into the most significant bit (msb) of the A register; previous bits read in to the accumulator are all shifted right.
The contents of the A register shown above indicate which column is stored in which bit.
The five nibbles obtained are then transferred to system variables FLAGS/ROW3 (5B88h), ROW2/ROW1 (5B89h) and ROW4/ROW5 (5B8Ah). The values of these system variables are then 'decoded' to form a unique code in the E register. A list of values for individual key presses is shown below; the value in the E register (in hex) is shown with and without the SHIFT key being pressed in each case. Multiple key presses will produce values in 5B88h, 5B89h and 5B8Ah generated by ORing together the two individual key values.
|KEY||E (unshifted)||E (shifted)||5B88||5B89||5B8A|
|Click here to view a graphical illustration of how the keypad rows are read and then decoded.|
The value of the E register can be monitored using the following program when in 128 BASIC mode:
This requires a simple machine code routine stored at address 50000. It is necessary to set RAMTOP with the command:
The machine code routine is as follows:
50000 CD A0 39 205 160 057 CALL 39A0h
50003 06 00 006 000 LD B,0
50005 4B 075 LD C,E
50006 C9 201 RET
Note that pressing down multiple keys will return unpredictable values. These would normally be trapped by other routines in the ROM.
The System Variables FLAGS/ROW3, ROW2/ROW1 and ROW4/ROW5 store information on the following keys:
|Column 1||Column 2||Column 3||Column 4|
|ROW4/ROW5 low||0||.||Row 5|
|ROW4/ROW5 high||1||2||3||ENTER||Row 4|
|ROW2/ROW1 low||/||*||(||)||Row 1|
|ROW2/ROW1 high||7||8||9||-||Row 2|
|FLAGS/ROW3 low||4||5||6||+||Row 3|
To allow the INKEY$ function to read the keypad when in 128 BASIC mode a patch to the 48K BASIC ROM was made at address 2646h to call a new routine located at 3B6Ch. In the standard Spectrum ROM the instruction at 2646h calls the keyboard scanning routine at address 028Eh. The new routine at 3B6Ch first calls this keyboard scanning routine (028Eh) and then, if in 128 BASIC mode, scans of the keypad via a call to 39A0h.