When the HP67 detects that a key has been pressed, it exits the HP67 Keypress Wait Loop and gets to instruction 0214 (octal). Then this happens:
00214: display off 00215: b exchange c[w] 00216: CRC 400 ; sets a_key=true. tested by crc 500. maybe SF3 on keypress 00217: keys to a ; a[2]=scan row (a9134567) a[1]=scan col (43210, 3210 on 4 col rows) 00220: 0 -> c[x] 00221: a exchange c[xs] ; c[xs]=scan row 00222: shift right a[x] ; a[x] =scan col ; a[x]= 5*scan_row + scan_col 00223: p <- 0 00224: load constant 5 00225: a + c -> a[x] 00226: c - 1 -> c[xs] 00227: if n/c go to 0225 00230: a - c -> a[x] 00231: shift left a[x] ; result to a[2,1] 00232: 0 -> c[x] 00233: p <- 2 00234: load constant 4 00235: 0 -> s 3 00236: if 0 = s 4 ; if no prefix key 00237: then go to 0254 00254: m1 exch c ; go to bank 0 rom 3 instruction nn (014nn), nn= octal(a[2,1]) 00255: delayed rom 03 00256: a -> rom address
Each rom contains 0400 addresses (Octal 0000-0377 = 2 bits + 3 bits + 3 bits = 8 bits = 256 in decimal).
Rom 0 starts at address 00000.
Rom 3 starts at address 0400+0400+0400 = 01400.
The key scan codes and go to addresses are:
// A B C D E
0xa4 (row=10, col=4, 5*10+4=54 =6*8+6 = 066) addr=01466
0xa3 (row=10, col=3, 5*10+3=53 =6*8+5 = 065) addr=01465
0xa2 (r=10 c=2 so 52, =6*8+4 = 064) addr=01464
0xa1 (r=10 c=1 so 51, =6*8+3 = 063) addr=01463
0xa0 (r=10 c=0 so 50, =6*8+2 = 062) addr=01462
// SUM GTO DSP (i) SST
0x94 (r=9 c=4 so “n”=45+4=49 =6*8+1 = 061) addr=01461
0x93 (r=9 c=3 n=48 =6*8+0 = 060) addr=01460
0x92 (r=9 c=2 n=47 =5*8+7 = 057) addr=01457
0x91 (9,1,46 =5*8+6 =056) 01456
0x90 (9,0,45 =5*8+5 =055) 01455
// f g STO RCL h
0x14 (1,4,9 =1*8+1 =011) 01411
0x13 (1,3,8 =1*8+0 =010) 01410
0x12 (1,2,7 =0*8+7 =007) 01407
0x11 (1,1,6 =0*8+6 =006) 01406
0x10 (1,0,5 =0*8+5 =005) 01405
// ENTER CHS EEX CLX
0x33 (,,18 =2*8+2 =022) 01422
0x32 (,,17 =2*8+1 =021) 01421
0x31 (,,16 =2*8+0 =020) 01420
0x30 (,,15 =1*8+7 =017) 01417
// – 7 8 9
0x43 (23 027) 01427
0x42 (22 026) 01426
0x41 (21 025) 01425
0x40 (20 024) 01424
// + 4 5 6
0x53 (28 034) 01434
0x52 (27 033) 01433
0x51 (26 032) 01432
0x50 (25 031) 01431
// * 1 2 3
0x63 (33 041) 01441
0x62 (32 040) 01440
0x61 (31 037) 01437
0x60 (30 036) 01436
// / 0 . R/S
0x73 (38 046) 01446
0x72 (37 045) 01445
0x71 (36 044) 01444
0x70 (35 043) 01443
If you’ve pressed a prefix key ([f], [g] or [h]) then it ends up running instructions to go to rom1 (004nn) instead of to rom3 (014nn).
If also adds 4 to a[2] a number of times depending on whether [f], [g] or [h] was pressed. This is equivalent to adding 0100 octal each time so you get:
normal to 01400 + 5*r+c
f, key to 00400 + 3*0100 =00700, + 5*r+c
g, key to 00400 + 2*0100 =00600, + 5*r+c
h, key to 00400 + 1*0100 =00500, + 5*r+c
[h] [3] (ie h REG) would go to 00500 + 036 = 00536