Up

Digits entry routine

Before hitting a function key, the user can enter digits to build numbers.

There are 9 digits keys on the keyboard of the HP 35, plus one key for the decimal point “.”, one key for the exponent “EEX” (enter Exponent) and one key to change the sign of the fraction part or exponent (CHS).

This article is about entering data, that is to say numbers in the HP 35.

Please read the “Output format” article first, I won’t repeat my explanations about the display context.

Before beginning one point must be explained.

A hand help calculator is always in a run mode. When it is idling, the micro program is looping (in the “dsp” loop) displaying the previous result and waiting for a key to be pressed.

 

We are precisely at that time, (see chart below) returning from a math routine at label 00333.

 A call is then made to “of13” to construct a display context and a call to “dsp1” is made to loop a while (the flag s7 is set to 1, requesting the stack to be pushed – more on this later).

Returning from “dsp” that is to say when a key is hit by the user, a call to “fst3” will be issued to take care of the operational stack (an article about the 4 level stack will soon be in line) and finally we go to the data entry routine at entry point “den2”.

1) Digit entry

The mechanism to get a digit is simple; we got in the “dsp” loop by a subroutine call (jsb). Then when in the loop a digit key is pressed the processor branches to the right address: for example if it the “8” key we go to the “dig8” label, sum the value 8 in the exponent of register A (it has been set to zero entering “dsp”) and finally when we encounter the “return” instruction (address ) we get back to the first address following label “fst2zx” (address 00336)  then call “fst3” and go to “den2” as already explained.

At address "00326" the "shift left a[w]" makes room in a[x] for the new digit. Note that a digit "0" simply executes the "return" instruction address 0044 (the register's exponent is zero).    

So, entering “den2” (main entry point) the value of the digit we are processing is in a[x] ; it could part of a set composing a number.

 Note that the pointer p = 12 when the user is entering digits, but p=3 if the user hit the “.” key (decimal point).

The code between “den2” and “den4 is simple but crucial: it is due to place the new digit in place, according to the current display mask. 

Let’s use take the example of entering number 12, from scratch (PWO or CLR).

At address 00214, the display mask is copied into C which is (00215) incremented: the current mask for the previous digit (or possibly for a “0”) is =”02999999999999”; thus incremented it becomes “30000000000000”.

Here is the sequence:

00212:     den2:       if p # 12
A=00000000000001  B=29999999999999  C=02999999999999
00213:     00223           then go to den4
A=00000000000001  B=29999999999999  C=02999999999999
00214:     b -> c[w]
A=00000000000001  B=29999999999999  C=29999999999999
00215:     c + 1 -> c[w]
A=00000000000001  B=29999999999999  C=30000000000000

After that, the pointer p is set to 1 (00216) and we enter in a loop “den3 – 00222” in which the digit just being entered is moved from register A position 0 to the position of digit “3” in register C.

00217:             den3:    shift left a[wp]
00220:             p + 1 -> p
00221:             if c[p] = 0 then go to den3 

Here is register A entering the loop,

A=00000000000010  C=30000000000000
And exiting the loop:

A=01000000000000  C=30000000000000

At “den4” the new digit is in place and is copied to C (A is discarded), we go to”den5” and to “den6” if no decimal point was entered (s6=0).

Label “den6” is the normal exit point, the current mask in B is updated making room with a shift right and a call to eex4 is issued. This is the normal entry point for the “eex” routine which is going to finish working out the exponent.

Note that is the new digit is not the first but part of a number, the loop “den3” is placing it to the first right location in A:

e.g. a digit “2” entered after a “1”
A=01200000000000  C=03000000000000  

Precisely, in the case of a decimal point “entered”, the key entry point is:

00043:             3 -> p
return

Nothing happens in the loop “den3”, but p = 3 and we go to “00226” and:
- put a zero in register C exponent,
- set flag s6 to one meaning “.” has been entered and exponent must be calculated properly,
-  we go to eex4.

Note that if at “den5” we have a flag s6=0 (meaning “.” was previously entered), we have to skip a location in the mask:

00371:                                    den5:       if s6 = 0
A=00300000000000  B=00299999999999  C=91230000000000
D=00000000000000  M=00000000000000  P=b  S=0..3..678..b
00372:                    00374           then go to den6
A=00300000000000  B=00299999999999  C=91230000000000
D=00000000000000  M=00000000000000  P=b  S=0..3..678..b
00373:                                    p - 1 -> p
A=00300000000000  B=00299999999999  C=91230000000000
D=00000000000000  M=00000000000000  P=a  S=0..3..678..b
00374:                                    den6:       shift right b[wp]
A=00300000000000  B=00209999999999  C=91230000000000
D=00000000000000  M=00000000000000  P=a  S=0..3..678..b
00375:                                    00172      jsb eex4
A=00300000000000  B=00209999999999  C=91230000000000
D=00000000000000  M=00000000000000  P=a  S=0..3..678..b

At “den6” the mask is updated and we go to “eex4” which is the normal entry point in the “eex” routine, where the exponent is going to be processed.

2) Exponent entry

The “eex” routine entry point coming from “den” is at address “eex4”.

The first thing done is to copy register C into A, starting to build the floating point form.

Then at address 00173 a test is made on the normalized exponent sign.

a) Number with null exponent

In this first and most simple case a number has been entered in "den" without exponent; I'll take the example of the entry of the number "00015" (no exponent or sign is entered).

As you can verified it if your own a HP35, numbers are entered in the display register (C) as the key are pressed; it's a "free field" that includes leading and trailing zeros. So, the firmware handled numbers as "00015" and transformed them into 1.5 101.

In my example (see trace), nothing happens for the three leading digits:

-the SL a[ms] at eex6 has no effect (A=0),
-the exponent of C is decremented at 00201,
-the test at 00202 if a[s]>=1 (left most digit is not zero) fails,

-the test at 00204 if a[ms] >=1 (A mantissa + sign not null) fails too, so we go down to 00206 where we set C exponent to zero (has been decremented in 00201) and we call "dsp1" returning in the display loop.

But when the first digit "1" is entered the things are different.

On entry "eex4", we copy C to A and the context is:
A=00000100000000  B=00000299999999  C=00000100000000
the test at 00204 is true and we loop to "eex6". 

In this loop, the digits in A are shifted left until the first of them reaches the leftmost position. Then the test at 00202 is true, and we go to "eex8".
The context is now:
A=10000000000000  B=00000299999999  C=00000100000995
flag p=d (13) since 00120. 

At "eex8" we are in another loop that's going to build normalized exponent.

In the loop to "eex7" which is done until the first mask digit <> 0 in B register (from left to right) p is decremented and the exponent c[x] is incremented.

In our example (on exit):
A=10000000000000  B=00000299999999  C=00000100000000
One digit further, "5" has been entered and the context is:
A=15000000000000  B=00000029999999  C=00000150000001 

At 00120 we set the flag S11 to 1, to remember that a mantissa has been entered (versus EEX alone displaying "1 00") and at 00121 we SR A mantissa + sign to make room for sign (cf. SL at "eex6") and we exchange mantissa of A and of C (at 00122); then floating point form is in A, while normalized is in C.

Finally, at 00123 we test if the flag s4 is = 0 (s4=1 means EEX pressed) and to go "den1" and finally call "dsp1".

b) Number with a decimal point "."

In this second case the exponent is entered using the decimal point like in "12.3"    

We have seen the first part of the process in "den": status flag s6 is set to 1 before going to "eex4" and during the next digit ("3" in the example) a test is made at 00371 and if s6 = 1 the point p is decremented once to skip the decimal point location in the mask executing "den6" and the mask is updated (shift right b[wp]).

In our example, at 00120 the context is

A=12300000000000  B=00209999999999  C=01230000000001

the mask takes in account the decimal point position while C has the right exponent.

c) Exponent entered with the EEX key.

In the third case we enter first a mantissa (possibly with a sign and a decimal point) then we press the EEX key (see the trace for the complete case -12.3    -02 keys : "1" "2" "chs" "." "3" "eex" "chs" "2").

The entry point for the EEX case is "eex2" at 00362 and we set on entry the status flag s4 to 1, to remember that the EEX key has been pressed.

Then we test flag s11 to check if we pressed "EEX" first for the number (e.g. sequence EEX 2), in this case we go directly to label "dig1", the path is "dig1" - "fst3" - "fst5" - "den2" - "eex4" and the typical display is "1 00" (see trace).

But in the main case (mantissa already entered) we go to "eex3" and we first (at 00157) shift right A (reverse to the SL A at 00326 to make room in a[x] for digit).

·        If p = 12 mantissa has been entered and we continue to 00162 exchanging A and C (but not the sign of C) and continuing to "eex4" - "eex5" - "eex6" - "eex7" - "eex8" up to 00123 where s4=1, so we exit the routine by a call to "of14" before going in the meeting point at "fst2zx". This call is to format the display mask for exponent:
In our example having entered -12.3 and after EEX is pressed "of14" is called to format the mask
B=00209999999999 -> B=00209999999000

·        If p <> 12, we came here after a "." entry with p=3 and we go to "den7" where the sign of C is copied to A before re-entering "den2". This path is tricky (see the trace):

o       entering the first digit "1" leads the control at address 00123 (end of routine "eex8") to take the route to "den1" at 00207 where s4 = 0 and a call to "dsp1" is issued waiting for the next one,

o       the next one is a "." so we "return" at 00210 (next address after the jsb disp1) where we shift right A (room in a[x] is useless) and we restore the sign in A (lost with the previous SL),

o       p = 3 (since we came from the decimal point entry point) and we go to "den4" to get the exponent digits.

  

J Laporte
Thursday, 23 February 2006