Here’s what happens as you key in digits into the calculator.
First Digit
1. The first thing that happens is the digit key gets converted to a program code (prgcode). This is the internal value that would get stored in program memory as a program step if we were pressing the key in PRGM mode. Here’s the process:
KeyPressed: 00762 display off 00763 binary 00764 p <- 0 00765 0 -> c[x] 00766 a exchange b[w] ; A= 21000000000000 B= 0000ffffffffff 00767 0 -> s 13 00770 keys -> rom address ; 0162 = 01 110 010 = 0111 0010 = 72H = [1] key pressed 00562 if n/c goto 00647 00647 c + 1 -> c[x] ; C= 00000000000001 00650 return 00674 p <- 1 ; P= 1 00675 load constant 12 ; C= 000000000000c1 P= 0 00676 p <- 1 ; P= 1
C[1,0] now contains "c1", the prgcode for the [1] key.
2. The calculator then checks for prefix keys (in case [f], [g] or [STO] had been pressed):
00677 if 1 = s 10 then goto 00704 ; if g_pressed, no 00701 if 0 = s 9 then goto 00616 ; if not f_pressed, yes 00616 delayed rom 3 00617 if n/c goto 00526 01526 if 1 = s 3 then goto 01766 ; if RUN
3. It then runs the prgcode, exactly as if it had come from program memory:
execut: 01766 0 -> c[xs] 01767 c -> a[x] ; A= 210000000000c1 01770 a + 1 -> a[xs] ; A= 210000000001c1 01771 a -> rom address
4. Every digit key (0-9), and each of the undocumented "a"-"f" ones, ends up at the same place:
; 1c 01434 select rom 0 00035 if 1 = s 7 then goto 00076 ; if EEX, no 00037 jsb 00356 push: 00356 if 1 = s 8 then goto 00376 ; if input_mode, not yet 00360 0 -> c[w] ; C= 00000000000000 00361 m2 exch c 00362 if 0 = s 2 then goto 00365 ; if not auto_enter, true 00365 1 -> s 2 ; S= ..23.5.........f auto_enter 00366 0 -> c[w] 00367 binary 00370 c - 1 -> c[w] ; C= ffffffffffffff CY 00371 f exch a ; A= 210000000001c0 (f=1) 00372 0 -> a[w] ; A= 00000000000000 00373 f exch a ; A= 00000000000001 00374 0 -> c[s] ; C= 0fffffffffffff 00375 b exchange c[w] ; B= 0fffffffffffff C= 0000ffffffffff 00376 1 -> s 8 ; S= ..23.5..8......f input_mode 00377 return
If this is the first digit (HP labelled s8 as "firdig"), the new X value gets set to 0, the old X value gets "push"ed up the stack (00364 is c -> stack) and B is set to a positive sign "0" then 13 "f"s. Our "1" digit is also in A[0].
The s2 flag is called "push" by HP. I refer to it as "auto_enter" for historic reasons. Both mean the same thing: it is clear after a CLx or an ENTER, and set otherwise. It is the flag that causes a new value to push the existing values up the stack (Z to T, Y to Z, X to Y).
5. Next, the digit in A[0] is shifted left for as many positions as there are "f"s. The "f"s display as blanks so this is effectively putting the digit in the next available spot. (This is also why trying to put an "f" digit in a spot results in the "f" digit getting overwritten by the next digit - see HP-25 Non Normalized Numbers). The process look like this:
00040 b -> c[w] ; C= 0fffffffffffff 00041 p <- 1 ; 00042 c + 1 -> c[p] ; C= 0fffffffffff0f CY 00043 if n/c goto 00332 00044 shift left a[w] ; A= 00000000000010 00045 p + 1 -> p ; P= 2 00046 if p # 13 then goto 00042 ; 00042 ... ; C= 0ffffffffff00f A= 00000000000100 P= 3 00042 ... ; C= 0fffffffff000f A= 00000000001000 P= 4 00042 ... ; C= 0ffffffff0000f A= 00000000010000 P= 5 00042 ... ; C= 0fffffff00000f A= 00000000100000 P= 6 00042 ... ; C= 0ffffff000000f A= 00000001000000 P= 7 00042 ... ; C= 0fffff0000000f A= 00000010000000 P= 8 00042 ... ; C= 0ffff00000000f A= 00000100000000 P= 9 00042 ... ; C= 0fff000000000f A= 00001000000000 P=10 00042 ... ; C= 0ff0000000000f A= 00010000000000 P=11 00042 ... ; C= 0f00000000000f A= 00100000000000 P=12 00042 ... ; C= 0000000000000f A= 01000000000000 P=13 00046 if p # 13 then goto 00042 00050 p - 1 -> p ; P= 12 00051 a exchange c[wp] ; A= 0000000000000f C= 01000000000000 00052 p - 1 -> p ; P= 11 00053 c -> a[w] ; A= 01000000000000
6. It puts the "f"s back on the RHS of our shifted digit:
00054 c - 1 -> c[wp] ; C= 01ffffffffffff CY
7. There is some work with the exponent which makes more sense on subsequent digits:
00055 a exchange c[x] ; A= 01000000000fff C= 01fffffffff000 00056 decimal 00057 if a[m] # 0 then goto 00006 00006 jsb 00133 delook: 00133 a exchange b[x] 00134 0 -> a[x] ; A= 01000000000000 00135 f -> a 00136 a + c -> c[x] 00137 p <- 12 ; P= 12 00140 if c[p] # 0 then goto 00353 00353 a exchange b[x] ; A= 01000000000fff B= 0ffffffffff000 00354 0 -> b[x] 00355 return
8. The keyed in digit(s) (X value) gets stored in M2
00007 if n/c goto 00062 00062 a exchange c[ms] ; A= 01ffffffffffff C= 01000000000000 00063 m2 exch c ; C= 00000000000000 M2=01000000000000 00064 a exchange b[w] ; A= 0ffffffffff000 B= 01ffffffffffff
9. Then we put "21" in B to turn on the sign and show a decimal point, and then show the digit(s):
00065 jsb 00341 deb: ; digit entry, set B ; this mostly puts "21" in B to show sign and decimal point ; the entered digits are currently in B and will end up in A 00341 0 -> a[w] ; A= 00000000000000 00342 a + 1 -> a[s] ; A= 10000000000000 00343 shift right a[w] ; A= 01000000000000 00344 a + 1 -> a[s] ; A= 11000000000000 00345 a + 1 -> a[s] ; A= 21000000000000 00346 a exchange b[ms] ; A= 01fffffffff000 B= 21000000000fff 00347 f -> a 00350 p <- 0 ; P= 0 00351 a - 1 -> a[p] ; A= 01fffffffff009 CY 00352 if n/c goto 00233 00353 a exchange b[x] ; A= 01ffffffffffff B= 21000000000009 00354 0 -> b[x] ; B= 21000000000000 00355 return 00066 a exchange b[w] ; A= 21000000000000 B= 01ffffffffffff 00067 if 1 = s 1 then goto 01754 ; if running, no 00071 a exchange b[w] ; A= 01ffffffffffff B= 21000000000000 00072 if 0 = s 3 then goto 01672 ; if PRGM, no 00074 delayed rom 1 00075 if n/c goto 00165 $plain: 00565 0 -> s 9 ; f_pressed= no 00566 0 -> s 10 ; g_pressed= no 00567 if n/c goto 00672 00672 0 -> s 14 ; sto_prefix= no 00673 jsb 00751 00751 display toggle ; " 1."
After this, we wait for any pressed key to be released and go into the WaitLoop for the next key press.
Second Digit
10. I'll skip over some of the detail above, but here's what happens when you now press [2]:
KeyPressed: 00762 ... 00770 keys -> rom address ... 00675 ... ; C= 000000000000c2 (c2= prgcode for [2]) execut: 01766 ... ; A= 210000000001c2 01771 a -> rom address ; 1c 01434 select rom 0 00035 if 1 = s 7 then goto 00076 00037 jsb 00356 00356 if 1 = s 8 then goto 00376 00376 1 -> s 8 00377 return 00040 b -> c[w] ; C= 01ffffffffffff 00041 p <- 1 00042 ... ; C= 01ffffffffff0f A= 10000000001c20 P= 2 00042 ... ; C= 01fffffffff00f A= 0000000001c200 P= 3 00042 ... ; C= 01ffffffff000f A= 000000001c2000 P= 4 00042 ... ; C= 01fffffff0000f A= 00000001c20000 P= 5 00042 ... ; C= 01ffffff00000f A= 0000001c200000 P= 6 00042 ... ; C= 01fffff000000f A= 000001c2000000 P= 7 00042 ... ; C= 01ffff0000000f A= 00001c20000000 P= 8 00042 ... ; C= 01fff00000000f A= 0001c200000000 P= 9 00042 ... ; C= 01ff000000000f A= 001c2000000000 P=10 00042 ... ; C= 01f0000000000f A= 01c20000000000 P=11 00042 ... ; C= 0100000000000f A= 1c200000000000 P=12 00042 c + 1 -> c[p] ; C= 0200000000000f 00043 if n/c goto 00332 00332 c - 1 -> c[p] ; C= 0100000000000f 00333 if p # 3 then goto 00171 00171 if 1 = s 6 then goto 00050 ; if dp (decimal point), no 00173 f exch a ; f=0 from last time (0th digit) 00174 a + 1 -> a[x] ; A= 1c200000000001 00175 f exch a ; A= 1c200000000000, f now 1 00176 if n/c goto 00050 00050 p - 1 -> p ; P= 11 00051 a exchange c[wp] ; A= 1c00000000000f C= 01200000000000 00052 p - 1 -> p ; P= 10 00053 c -> a[w] ; A= 01200000000000 00054 c - 1 -> c[wp] ; C= 012fffffffffff CY 00055 a exchange c[x] ; A= 01200000000fff C= 012ffffffff000 00056 decimal 00057 if a[m] # 0 then goto 00006 00006 jsb 00133 00133 a exchange b[x] 00134 0 -> a[x] ; A= 01200000000000 00135 f -> a ; A= 01200000000001 00136 a + c -> c[x] ; C= 012ffffffff001 00137 p <- 12 ; P= 12 00140 if c[p] # 0 then goto 00353 00353 a exchange b[x] ; A= 01200000000fff B= 01fffffffff001 00354 0 -> b[x] ; B= 01fffffffff000 00355 return 00007 if n/c goto 00062 00062 a exchange c[ms] ; A= 012fffffffffff C= 01200000000001 00063 m2 exch c ; C= 01000000000000 M2=01200000000001 00064 a exchange b[w] ; A= 01fffffffff000 B= 012fffffffffff 00065 jsb 00341 deb: ; digit entry, set B ; this time B=201 for sign, 2 digits, decimal point 00341 0 -> a[w] ; A= 00000000000000 00342 a + 1 -> a[s] ; A= 10000000000000 00343 shift right a[w] ; A= 01000000000000 00344 a + 1 -> a[s] ; A= 11000000000000 00345 a + 1 -> a[s] ; A= 21000000000000 00346 a exchange b[ms] ; A= 012ffffffff000 B= 21000000000fff 00347 f -> a ; A= 012ffffffff001 00350 p <- 0 ; P= 0 00351 a - 1 -> a[p] ; A= 012ffffffff000 00352 if n/c goto 00233 00233 shift right b[m] ; B= 20100000000fff 00234 if n/c goto 00351 00351 a - 1 -> a[p] ; A= 012ffffffff009 CY 00352 if n/c goto 00233 00353 a exchange b[x] ; A= 012fffffffffff B= 20100000000009 00354 0 -> b[x] ; B= 20100000000000 00355 return 00066 ... $plain: 00565 ... 00751 display toggle ; " 12."
Third Digit
11. The process repeats for further digits. Here's a third one so the pattern is clear:
KeyPressed: 00762 ... 00770 keys -> rom address key_3: 00560 ... ; C= 010000000000c3 (c3= prgcode for [3]) execut: 01766 ... ; A= 201000000001c3 01771 a -> rom address 01434 ... 00037 jsb 00356 00356 if 1 = s 8 then goto 00376 ; already input mode 00376 1 -> s 8 ; nothing to do here 00377 return 00040 b -> c[w] ; C= 012fffffffffff 00041 p <- 1 00042 ... ; C= 012fffffffff0f A= 01000000001c30 P= 2 00042 ... ; C= 012ffffffff00f A= 1000000001c300 P= 3 00042 ... ; C= 012fffffff000f A= 000000001c3000 P= 4 00042 ... ; C= 012ffffff0000f A= 00000001c30000 P= 5 00042 ... ; C= 012fffff00000f A= 0000001c300000 P= 6 00042 ... ; C= 012ffff000000f A= 000001c3000000 P= 7 00042 ... ; C= 012fff0000000f A= 00001c30000000 P= 8 00042 ... ; C= 012ff00000000f A= 0001c300000000 P= 9 00042 ... ; C= 012f000000000f A= 001c3000000000 P=10 00042 ... ; C= 0120000000000f A= 01c30000000000 P=11 00042 c + 1 -> c[p] ; C= 0130000000000f 00043 if n/c goto 00332 00332 c - 1 -> c[p] ; C= 0120000000000f (3 back to 2) 00333 if p # 3 then goto 00171 00171 if 1 = s 6 then goto 00050 00173 f exch a ; A= 01c30000000001 00174 a + 1 -> a[x] ; A= 01c30000000002 00175 f exch a ; A= 01c30000000000 00176 if n/c goto 00050 00050 p - 1 -> p ; P= 10 00051 a exchange c[wp] ; A= 01c0000000000f C= 01230000000000 00052 p - 1 -> p ; P= 9 00053 c -> a[w] ; A= 01230000000000 00054 c - 1 -> c[wp] ; C= 0123ffffffffff CY 00055 a exchange c[x] ; A= 01230000000fff C= 0123fffffff000 00056 decimal 00057 if a[m] # 0 then goto 00006 00006 jsb 00133 00133 a exchange b[x] 00134 0 -> a[x] ; A= 01230000000000 00135 f -> a ; A= 01230000000002 00136 a + c -> c[x] ; C= 0123fffffff002 00137 p <- 12 ; P= 12 00140 if c[p] # 0 then goto 00353 00353 a exchange b[x] ; A= 01230000000fff B= 012ffffffff002 00354 0 -> b[x] ; B= 012ffffffff000 00355 return 00007 if n/c goto 00062 00062 a exchange c[ms] ; A= 0123ffffffffff C= 01230000000002 00063 m2 exch c ; C= 01200000000001 M2=01230000000002 00064 a exchange b[w] ; A= 012ffffffff000 B= 0123ffffffffff 00065 jsb 00341 deb: ; digit entry, set B ; B = "2001" ie sign, 3 x digit, decimal point 00341 0 -> a[w] ; A= 00000000000000 00342 a + 1 -> a[s] ; A= 10000000000000 00343 shift right a[w] ; A= 01000000000000 00344 a + 1 -> a[s] ; A= 11000000000000 00345 a + 1 -> a[s] ; A= 21000000000000 00346 a exchange b[ms] ; A= 0123fffffff000 B= 21000000000fff 00347 f -> a ; A= 0123fffffff002 00350 p <- 0 ; P= 0 00351 a - 1 -> a[p] ; A= 0123fffffff001 00352 if n/c goto 00233 00233 shift right b[m] ; B= 20100000000fff 00234 if n/c goto 00351 00351 a - 1 -> a[p] ; A= 0123fffffff000 00352 if n/c goto 00233 00233 shift right b[m] ; B= 20010000000fff 00234 if n/c goto 00351 00351 a - 1 -> a[p] ; A= 0123fffffff009 CY 00352 if n/c goto 00233 00353 a exchange b[x] ; A= 0123ffffffffff B= 20010000000009 00354 0 -> b[x] ; B= 20010000000000 00355 return 00066 ... $plain: 00565 ... 00751 display toggle ; " 123."
As you can see, each time we add a digit (and the decimal point shifts one place to the right), the value in f goes up by one and the exponent in M2 goes up by one.
Digit | f | M2 |
First | 0 to 1 | 01000000000000 |
Second | 1 to 2 | 01200000000001 |
Third | 2 to 3 | 01230000000002 |
This is part of the HP-25 topic.