HP-25 Input Mode

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.

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 *