HP-65 Number Entry Microcode

Here’s what happens when you press 123.45 EEX 78 CHS.

The numbers (0-9) end up in A[0].

A[0] starts with 0 because of:
00701 shiftl a[w]        ; A= 00000000009990

pressing the 0-9 keys give:
key scan  addr  instr
[0] (044) 01044	rom 5 ;-> 02445
[1] (004) 01004	rom 5 ;-> 02405
[2] (003) 01003	rom 5 ;-> 02404
[3] (002) 01002	rom 5 ;-> 02403
[4] (024) 01024	rom 5 ;-> 02425
[5] (023) 01023	rom 5 ;-> 02424
[6] (022) 01022	rom 5 ;-> 02423
[7] (064) 01064	rom 5 ;-> 02465
[8] (063) 01063	rom 5 ;-> 02464
[9] (062) 01062	rom 5 ;-> 02463

which leads to:
d9: 02463 a + 1 -> a[x]
d8: 02464 a + 1 -> a[x]
d7: 02465 ... : a + 1 -> a[x]
d6: 02423 a + 1 -> a[x]
d5: 02424 a + 1 -> a[x]
d4: 02425 ... : a + 1 -> a[x]
d3: 02403 a + 1 -> a[x]
d2: 02404 a + 1 -> a[x]
d1: 02405 ... :	a + 1 -> a[x]
d0: 02445 goto 02506

so A[0] ends with 0-9 to match the pressed key.

What happens next with the digits is:

02506 if c[m] = 0        ; if no prefix(es)
02507 goto 02736
; put C and M back 
02736 c <-> m            ; C= 00000000000000 M= 00000000000221
02737 if s3 = 0          ; if in RUN mode
02740 goto 02511
02511 rom 2
01112 if s1 = 0          ; if not input_started
01113 goto 01245

;if the auto_enter flag is set
;  c -> stack
;endif
;clear auto_enter flag
;
01245 0 -> s11
01246 0 -> f1            ; clear auto_enter flag
01247 if s11 = 0         ; if f1 wasn't set
01250 goto 01252
01251 c -> stack

; set B for "".
01252 0 -> c[w]
01253 12 -> p
01254 c - 1 -> c[wp]     ; C= 09999999999999
01255 c + 1 -> c[s]      ; C= 19999999999999
01256 c + 1 -> c[s]      ; C= 29999999999999
01257 b <-> c[w]         ; B= 29999999999999 C= 02009999999999
; set C=0
01260 0 -> c[w]          ; C= 00000000000000

; if . not yet pressed
;   move decimal point another place to the right
; endif
01261 if s2 = 0          ; if not dot_pressed
01262 goto 01127
01263 goto 01130
01127 shiftr b[w]        ; B= 02999999999999

; // put A[0] digit in next available position
; // (the next available position is determined from the mask normally in B)
; for (p=0; C[p]==0; p++)
;   shift digit in A[0] left
01130 b <-> c[w]         ; B= 00000000000000 C= 02999999999999
01131 c + 1 -> c[w]      ; C= 03000000000000
01132 0 -> p             ; P= 0
01133 if c[p] >= 1
01134 goto 01151
01135 p + 1 -> p         ; P= 1
01136 shiftl a[wp]       ; A= 00000000009910
01137 goto 01133
; P= 2 A= 00000000009100
; P= 3 A= 00000000001000
; P= 4 A= 00000000010000
; P= 5 A= 00000000100000
; P= 6 A= 00000001000000
; P= 7 A= 00000010000000
; P= 8 A= 00000100000000
; P= 9 A= 00001000000000
; P=10 A= 00010000000000
; P=11 A= 00100000000000
; P=12 A= 01000000000000
01137 goto 01133
01133 if c[p] >= 1
01134 goto 01151

; restore mask
01151 c - 1 -> c[w]      ; C= 02999999999999
01152 b <-> c[w]         ; B= 02999999999999 C= 00000000000000 

We now have the digit(s) in the A register and the mask (B register) set. Next is:

; if just started data entry (this is digit 1)
01153 if p # 3
01154 goto 01366
01366 if s1 = 0
01367 goto 01361
; then
01361 shiftl a[w]        ; A= 10000000000000
01362 1 -> s1            ; S= .1.......... (input_started)
01363 goto 01156
01156 shiftr a[ms]       ; A= 01000000000000
01157 c -> a[s]
01160 if s7 = 0          ; no EEX yet
01161 goto 01163
01163 1 -> s9            ; S= .1.......9.. (display_input)
01164 0 -> f3            ; S= .1.......9.b f= ..2..5.. (not display_x)
01165 1 -> f1            ; f= .12..5.. (set auto_enter)
01166 rom 1
00567 a <-> c[w]         ; A= 00000000000000 C= 01000000000000
00570 c -> a[w]          ; A= 01000000000000
00571 if a[m] >= 1       ; often if a[m]=0 then a[w]=0 (ie set exp 0 too)
00572 goto 00546
00546 c + 1 -> c[xs]     ; C= 01000000000100 (actually test xs. if 9 dont goto)
00547 goto 00470
00470 0 -> c[xs]         ; C= 01000000000000
00471 13 -> p            ; P= 13
00472 c - 1 -> c[x]      ; C= 01000000000999
00473 if b[p] = 0
00474 goto 00463
00463 p - 1 -> p         ; P= 12
00464 c + 1 -> c[x]      ; C= 01000000000000
00465 jsb 00473
00473 if b[p] = 0
00474 goto 00463
00475 12 -> p
00476 if a[p] >= 1
00477 goto 00574
00574 a <-> c[m]
00575 rom 2
01176 if c[xs] = 0
01177 goto 01334
01334 if c[m] >= 1
01335 goto 01337
01337 if p # 14
01340 goto 01217
01217 rom 1
00620 if s8 = 0
00621 goto 00531 

The input_started flag has been set.

We have also set the display_input flag instead of the more usual display_x flag.

The C register (stack X) contains the actual value (1e0) in case we decide to use it as currently keyed in (ie press a operation key).

If we key in additional digits, input_started is set so we don’t initialize values like we just did. A slightly different path gets followed:

; elseif this is digit 2+ (but pre . pre EEX)
; A= 12000000000000 B= 02999999999999 C= 01000000000000
01153 if p # 3
01154 goto 01366
01366 if s1 = 0          ; if not input_started
01367 goto 01361
; then
01370 if s2 = 0          ; if not dot_pressed
01371 goto 01107
01107 shiftr b[wp]       ; B= 00299999999999
01110 jsb 01156
01156 ...
(as above)
; S= .1.......9.b f= .12..5..
; A= 01200000000000 C= 01200000000001 P= 12
00621 goto 00531 

Pressing dot changes subsequent behaviour. It no longer pushes the decimal point to the right with each digit entered:

; press [.]
; key scan  addr  instr
; [.] (043) 01043 goto 01271
;
; which leads to:
01271 if c[m] >= 1       ; if prefix(es)
01272 goto 01270
01273 1 -> s2            ; S= .12......... (dot_pressed)
01274 if s1 = 0          ; if not input_started
01275 goto 01044
01276 goto 01304         ; but it has
01304 c <-> m            ; C= 01230000000002 M= 00000000000221
01305 shiftr a[w]        ; A= 01230000000000
01306 jsb 01157          ; never returns?
01157 ...
(as above but more looping and s2 set)
; S= .12......9.b f= .12..5..
; A= 01230000000000 C= 01230000000000
; P= 13 C= 01230000000999
; P= 12 C= 01230000000000
; P= 11 C= 01230000000001
; P= 10 C= 01230000000002 (C= 1.23e2 ie "123.")
; P= 12
00621 goto 00531

; press [4]
;
; which leads to:
; P=10 A= 12340000000000 B= 00029999999999 C= 01230000000002

; if this is digit 2+ (but after . pre EEX)
01153 if p # 3
01154 goto 01366
01366 if s1 = 0          ; if not input_started (not digit 1)
01367 goto 01361
01370 if s2 = 0          ; if not dot_pressed
01371 goto 01107
; then
01372 p - 1 -> p         ; P= 9
01373 0 -> b[p]          ; B= 00020999999999
01374 jsb 01156
01156 ...
(as above)
; S= .12......9.b f= .12..5..
; A= 01234000000000 C= 01234000000002 P= 12
00621 goto 00531

The dot_pressed (s2) flag is set.

You can see the mask in B now has a “hole” (0) to the right of the decimal point digit (2). This lets the “4” show through on the display. We see ” 123.4″ because A contains “01234” and B contains “00020999999999”.

More digits add more holes (0s) to the right of the decimal point in the mask (register B). eg:

; press [5]
;
; which leads to:
; P= 9 A= 12345000000000 B= 00020999999999 C= 01234000000002

; if this is digit 2+ (but after . pre EEX: s2=1 s7=0)
01153 if p # 3
01154 goto 01366
01366 if s1 = 0          ; if not input_started (not digit 1)
01367 goto 01361
01370 if s2 = 0          ; if not dot_pressed
01371 goto 01107
; then
01372 p - 1 -> p         ; P= 8
01373 0 -> b[p]          ; B= 00020099999999
01374 jsb 01156
01156 ...
(as above)
; S= .12......9.b f= .12..5..
; A= 01234500000000 C= 01234500000002 P= 12
00621 goto 00531 

The mask now looks like “00020099999999”. There are two “holes” in the mask to the right of the decimal point to allow the “4” and “5” to show through. We see ” 123.45″.

The C register contains 1.2345e2 or 123.45

Pressing EEX activates another part of the number entry microcode. It looks like:

; press [EEX]
; key scan  addr  instr
; EEX (072) 01072 goto 01277
;
; which leads to:
01277 if c[m] >= 1       ; if prefix(es)
01300 goto 01047
01301 1 -> s7            ; S= .12....7.... (eex_pressed)
01302 if s1 = 0          ; if not input_started
01303 goto 01004         ; (put a 1 in mantissa)
01304 c <-> m            ; C= 01234500000002 M= 00000000000221
01305 shiftr a[w]        ; A= 01234500000000
01306 jsb 01157

01157 c -> a[s]          ; get the sign from stack X
; if EEX was pressed show exponent digits
01160 if s7 = 0
01161 goto 01163
01162 0 -> b[x]          ; B= 00020099999000
; endif
01163 1 -> s9            ; S= .12....7.9.. (display_input)
01164 0 -> f3            ; S= .12....7.9.b f= .12..5.. (not display_x)
01165 1 -> f1            ; set auto_enter
01166 rom 1
00567 a <-> c[w]         ; A= 01234500000002 C= 01234500000000
00570 c -> a[w]          ; A= 01234500000000
00571 if a[m] >= 1
00572 goto 00546
00546 c + 1 -> c[xs]     ; C= 01234500000100 (if c[xs]=9 dont goto...)
00547 goto 00470
00470 0 -> c[xs]         ; C= 01234500000000
00471 13 -> p            ; P= 13
00472 c - 1 -> c[x]      ; C= 01234500000999
00473 if b[p] = 0
00474 goto 00463
00463 p - 1 -> p         ; P= 12
00464 c + 1 -> c[x]      ; C= 01234500000000
00465 jsb 00473
; P=11 C= 01234500000001
; P=10 C= 01234500000002 (=1.2345e2 "123.45")
00465 jsb 00473
00473 if b[p] = 0
00474 goto 00463
00475 12 -> p            ; P= 12
00476 if a[p] >= 1
00477 goto 00574
00574 a <-> c[m]
00575 rom 2
01176 if c[xs] = 0
01177 goto 01334
01334 if c[m] >= 1
01335 goto 01337
01337 if p # 14
01340 goto 01217
01217 rom 1
00620 if s8 = 0
00621 goto 00531 

We see the ” 00″ bit on the end (right) of the number keyed in so far. Then when we add more digits, these go into the exponent:

; press [7]
;
; which leads to:
; A= 12345000000007
02506 if c[m] = 0        ; if no prefix(es)
; put C and M back
02507 goto 02736
02736 c <-> m            ; C= 01234500000002 M= 00000000000221
02737 if s3 = 0          ; if in RUN mode
02740 goto 02511
02511 rom 2
01112 if s1 = 0          ; if not input_started
01113 goto 01245         ; but it has
01114 if s7 = 0          ; if not eex_pressed
01115 goto 01130         ; but it was
01116 a <-> c[x]         ; A= 12345000000002 C= 01234500000007
01117 shiftr a[w]        ; A= 01234500000000
01120 1 -> p             ; P= 1
01121 c -> a[wp]         ; A= 01234500000007
01122 goto 01157
01157 ...
; S= .12....7.9.b f= .12..5..
; C= 01234500000009 P= 12
00621 goto 00531

; press [8]
;
; which leads to:
; A= 12345000000078
02506 if c[m] = 0        ; if no prefix(es)
02507 goto 02736
; put C and M back
02736 c <-> m            ; C= 01234500000009 M= 00000000000221
02737 if s3 = 0          ; if in RUN mode
02740 goto 02511
02511 ...
; S= .12....7.9.b f= .12..5..
; A= 01234500000078 C= 01234500000080 P=12
00621 goto 00531 

The “7” went into the rightmost exponent digit. Then, the “8” pushed the “7” to the left and took the rightmost position.

Note that the exponent in the C register is “80”. This is because we keyed in “123.45e78” and that should be “1.2345e80” in normal scientific notation. It has added the e2 from keying in “123” to the e78 we entered into the exponent and come up with e80.

The display value (A register content) still shows exactly what you keyed in “123.45e78”.

If you press CHS at this point it affects the exponent sign like this:

; press [CHS]
; key scan  addr  instr
; CHS (073) 01073 goto 01375
;
; which leads to:
01375 if c[m] = 0        ; if no prefix(es)
01376 goto 01140
01140 c <-> m            ; C= 01234500000080 M= 00000000000221
01141 shiftr a[w]        ; A= 01234500000078
01142 if s7 = 0          ; if not eex_pressed
01143 goto 01227         ; but it was
01144 a <-> c[x]         ; A= 01234500000080 C= 01234500000078
01145 0 - c - 1 -> c[xs] ; C= 01234500000978
01146 a <-> c[x]         ; A= 01234500000978 C= 01234500000080
01147 goto 01157
01157 ...
; S= .12....7.9.b f= .12..5..
; A= 01234500000978 P=12 C= 01234500000924
00621 goto 00531 

The A register has a “9” in the exponent sign position. This will show as a “-” in front of the other exponent digits “78”.

The C register exponent is e924. This is 1000 + -76. The exponent in the C register is -76. Your HP-65 calculator has converted “123.45e-78” to “1.2345*10^2 e-78” or “1.2345e(2-78)” = “1.2345e-76”. e-76 is 100 times more than e-78, just like e80 is 100 times more than e78, because we keyed in 100 (and a bit) e-78.

For a full trace of the microcode for this key sequence, see 65-123.45e78-.txt.

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 *