The HP-21 keypress routine is incredibly simple. It looks like:
00400: display off ; 00401: p <- 0 ; 00402: 0 -> a[p] ; A=0000FFFFFFFFF0 00403: keys -> rom address ;
It really just does a goto based on which key was pressed.
The digit keys are, as usual, cleverly arranged and coded to put the correct value in A[0]. You can see from hp-21-scan-codes that ‘7’, ‘8’ and ‘9’ have key scancodes of 0x63, 0x62 and 0x61; and that ‘4’, ‘5’, ‘6’ and ‘1’, ‘2’, ‘3’ follow the pattern with 0xa3, 0xa2, 0xa1, 0x73, 0x72 and 0x71. ‘0’ has a keycode of 0x93 which also fits into the pattern.
The digit scancodes translate into octal values of 0143, 0142, 0141; 0243, 0242, 0241; 0163, 0162, 0161; and 0223. The instruction at 00403 above effectively adds 0400 to each of these values and does a goto. You get:
key9: 00541: a + 1 -> a[p] key8: 00542: a + 1 -> a[p] key7: 00543: if n/c go to 0640 00640: a + 1 -> a[p] key6: 00641: a + 1 -> a[p] key5: 00642: a + 1 -> a[p] key4: 00643: if n/c go to 0560 00560: a + 1 -> a[p] key3: 00561: a + 1 -> a[p] key2: 00562: a + 1 -> a[p] key1: 00563: if n/c go to 0730 00730: a + 1 -> a[p] 00731: return key0: 00623: return
The microcode puts 0-9 in A[0] to match the key (‘0’-‘9’) that was pressed. It is quite elegant and is a very tight way to implement 10 keys in 14 microinstructions total.
This same code is used whenever any of the digit keys are pressed. Even if you pressed the ‘g’ (blue, function) key beforehand or DSP or DSP and dot. Very efficient, and used for all cases.
Here’s what it looks like when you press ‘7’:
C:\Test\hp21w>hp21w -d HP21w Ver 0.01 Copyright 2018 Greg Sydney-Smith CPU speed is 200 kHz >>> g,403 Breakpoint 1 at 00403 >>> ts200 00403: keys -> rom address ; 00543: if n/c goto 0240 ; 00640: a + 1 -> a[p] ; A=0000FFFFFFFFF1 00641: a + 1 -> a[p] ; A=0000FFFFFFFFF2 00642: a + 1 -> a[p] ; A=0000FFFFFFFFF3 00643: if n/c goto 0160 ; 00560: a + 1 -> a[p] ; A=0000FFFFFFFFF4 00561: a + 1 -> a[p] ; A=0000FFFFFFFFF5 00562: a + 1 -> a[p] ; A=0000FFFFFFFFF6 00563: if n/c goto 0330 ; 00730: a + 1 -> a[p] ; A=0000FFFFFFFFF7 00731: return ; 00141: ...
The return takes us back to 00141 which suggests a jsb at 00140, which is the case. The HP-21 wait loop exists within a subroutine. I haven’t seen that done before, but the Woodstock CPU used in the HP-21 has a larger subroutine stack than its predecessors, so that might be why they considered it now.
This is part of the HP-21 topic.