The other day I added a runtime configurable 4x4 keypad driver to EXTEND as a built-in device but as I was testing it on other hardware I had one device that had the row and columns scattered and not necessarily in order either. So I decided to redo the keypad driver so that I could specify a 32-bit mask for the rows and the same for the columns. These two longs are supplied to the keypad initialization routine !KEYPAD and the driver runs in the background (a timer cog task) only scanning and reading those bits that are specified in the masks.
Since we can have any combination of port pins for row and column this also means that it would be possible to scan a 16x16 matrix for 256 keys or even a 28x4 matrix etc. The driver generates a 10-bit code that corresponds to the row and column port pins and if a decode table is specified then the table is searched for a match but failing that it simply returns with the scancode.
How do you use it? Say if I had 4 columns on P0, P2, P4, P6, and 4 rows on P8,P9,P10,P11 then I would start up the scanner with:
0 %1111_00000000 %01010101 !KEYPAD
The zero value is if we don't have a scancode table to convert scancodes to more friendly values such as ASCII etc. If you want to setup a table just point to a sequence of pairs of 16-bit values with the scancode and the result with the table terminate by a zero word like this:
$0100 || '1' || $0120 || '2' ||
$0140 || '3' || $0160 || 'A' ||
$0102 || '4' || $0122 || '5' ||
$0142 || '6' || $0162 || 'B' ||
$0104 || '7' || $0124 || '8' ||
$0144 || '9' || $0164 || 'C' ||
$0106 || '*' || $0126 || '0' ||
$0146 || '#' || $0166 || 'D' ||
Then you can setup the keypad to use this table:
K1144 %1111_00000000 %01010101 !KEYPAD
As with the earlier driver you can also specify a beeper and also redirect console input to come from the keypad too etc.