HP-29C Keypress Routine

So, you bought an old calculator; or a new one a very long time ago. You press a button and an answer pops out. How does it get from the first thing, to the second? This’ll answer the “getting from” part. I’ll leave the “getting to” part to later (get the HP-65 book if you’re not good at waiting). Here’s what happens …

Pressing a key results in the s15 flag inside the calculator getting set and a scancode being passed to its processor. (See HP-29C Wait Loop and HP-29 Scan Codes).

The Wait Loop is waiting for something to happen, such as s15 getting set. This article covers what the microcode inside the calculator does as a result.

Here’s part of the Wait Loop:

00173: if 0 = s 15 then goto 00152
00152: ...
00166: ... then goto 00173


It checks that there isn’t a key press, goes to 00152, checks some other things, and then ends up back at 00173 again.

Here’s what happens is s15 isn’t 0:

(press the "x<->y" key, scan code 0x43)
(s 15 gets set, shown here as "S= ..F")
00156: if 0 = s 11 then goto 00165         ; S=...3.5...9.....F
00165: 0 -> s 5                            ;
00166: if 1 = s 5 then goto 00173          ;
00173: if 0 = s 15 then goto 00152         ; it's not, so we're not going
00175: ...                                 ;


We’re no longer in the loop – we didn’t go to 00152. The “if (something) then goto (somewhere)” instruction is a two-word instruction. We went instead, to the next instruction after 00173 – to 00175. That makes 00175 the “keypressed” address. It looks like:

00175: display off                         ;
00176: b exchange c[w]                     ; B=00000000000000 C=29000000000000
00177: keys to a                           ; A=0000FFFFFFF430
00200: 0 -> s 13                           ;


It turns the display off and we see that as a blink when we press a key. It saves anything in the C register, by putting it in B for now, because it is about to use A and C to work some things out. The keys to a” instruction puts the current scan code in A[2] and A[1]. You can see 43 there. Remember that we pressed the “x<->y” key which has a scan code of 0x43. It also clears s13. I don’t know why as yet.

The next thing it does is multiply the scan code row (the 4) by 5 and add the scan code column. This is a simple way of reducing the range down to something smaller. If you look at the HP-29 scan code article, you’ll see that column numbers are all within 0-4 so multiplying row by 5 and adding column makes sense. In theory, you could reduce a range of (potentially) 00-FF down to 35 keys. Scan codes are easier for hardware. A short list of possible keys is easier for software. In practice, the row numbers range from 4-D(=13) so it isn’t quite as neat as it could be; but it does reduce the span of the jump table.

The row*5+col code looks like this:

00201: binary                              ;
00202: 0 -> c[x]                           ;
00203: c + 1 -> c[x]                       ; C=29000000000001
00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF330
00205: if n/c goto 0203                    ;
00203: c + 1 -> c[x]                       ; C=29000000000002
00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF230
00205: if n/c goto 0203                    ;
00203: c + 1 -> c[x]                       ; C=29000000000003
00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF130
00205: if n/c goto 0203                    ;
00203: c + 1 -> c[x]                       ; C=29000000000004
00204: a - 1 -> a[xs]                      ; A=0000FFFFFFF030
00205: if n/c goto 0203                    ;
00203: c + 1 -> c[x]                       ; C=29000000000005
00204: a - 1 -> a[xs]                      ; A=0000FFFFFFFF30
00205: if n/c goto 0203                    ;
00206: c - 1 -> c[x]                       ; C=29000000000004 c[0]= was a[2]
00207: 0 -> a[xs]                          ; A=0000FFFFFFF030
00210: shift right a[x]                    ; A=0000FFFFFFF003 a[0]= was a[1]
00211: a + c -> a[x]                       ; A=0000FFFFFFF007 a[x]= was a[2]+a[1]
00212: c + c -> c[x]                       ; C=29000000000008 c[0]= 2x was a[2]
00213: c + c -> c[x]                       ; C=29000000000010 c[0]= 4x was a[2]
00214: a + c -> a[x]                       ; A=0000FFFFFFF017 a[x]= 5x was a[2] + was a[1]


00203-00205 is a loop reducing the row number by 1 each time and adding 1 to C[0]. It is like doing “a -> c [xs]” then “shift right a[x]” twice (A[2]->C[2]; C[2]->C[1]->C[0]). We end up with the 4 from 0x43 in C[0].

We still have the 3 from 0x43 in A[1] so 00210 moves it into A[0].

As shown, the sequence 00211-00214: adds row+col (4+3=7), sets C[x] to 4*row (4*4=0x10), and adds that too. We get (row+col + 4*row = 5*row+col). For 0x43, row=4, col=3, 5*4+3= 23= 1*16+7=) 0x17 in A[x].

The next bit looks a little confusing; but it is really just a jump to 00400 + 5*row+col

00215: shift left a[x]                     ; A=0000FFFFFFF170
00216: p <- 1                              ; P= 1
00217: m1 -> c                             ; C=00000000000000
00220: 0 -> c[x]                           ;
00221: delayed rom 1                       ; to 00400-00777
00222: a -> rom address                    ; 0x17 = 10111 = 027
; scancode 043 -> row4,col3 -> 5*4+3 = 23
; 23= 1*16+7 so hex  = 0x17
; 23= 2* 8+7 so octal= 027 
00427: if n/c goto 0151                    ; 00400 + 5*row + col


You end up with:

Keycode Key Scan Code Goto
11 SST 0xb3 00472
12 GSB 0xb2 00471
13 GTO 0xb1 00470
14 f 0xb0 00467
15 g 0xb4 00473
21 x<->y 0x43 00427
22 Rv 0x42 00426
23 STO 0x41 00425
24 RCL 0x40 00424
25 SUM 0x44 00430
31 ENTER 0xd3 00504
33 CHS 0xd1 00502
34 EEX 0xd0 00501
35 CLx 0xd4 00505
41 0x63 00441
42 7 0x62 00440
43 8 0x61 00437
44 9 0x60 00436
51 + 0xa3 00465
52 4 0xa2 00464
53 5 0xa1 00463
54 6 0xa0 00462
61 x 0x73 00446
62 1 0x72 00445
63 2 0x71 00444
64 3 0x70 00443
71 / 0x93 00460
72 0 0x92 00457
73 . 0x91 00456
74 R/S 0x90 00455
It's only fair to share...Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUponDigg thisPin on PinterestEmail this to someone

Leave a Reply

Your email address will not be published. Required fields are marked *