HP Forums

Full Version: 41 MCODE - Floating FIX Mode (Fix ALL)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Floating FIX Mode

As discussed in a forum thread, it's often valuable to see the maximum number of digits with a meaningful contribution to the result value. The idea for the 41 was to use the I/O_SVC interrupt polling point to adjust the FIX setting in a dynamic fashion, depending on the value stored in the stack register X.

Some folks call this a FIX ALL mode, but I favor the Floating FIX terminology - after all a fix ALL would always be a static FIX_9, for it isn't about ALL digits but ALL NEEDED ones. Bur semantics aside, the code below shows the core of the routine, i.e. the actual determination of the FIX settings.

The formulas used are as follows:

Let x be represented by the following convention used in the 41 platform, with one digit for the mantissa sign, 10 digits for the mantissa, one for the exponent sign and two for the exponent. This enables a numeric range between +/-9,999999999 E99, with a "whole" around zero defined by the interval +/-1E-99.

Then the fix setting to use is a function of the number in X , represented as follows:

" s|abcdefghij|xyz "

1. If number >=1 (or x="0")

let z# = number of mantissa digits equal to zero, starting from the most significant one (i.e. from PT= 3 to PT=12), and XP = value of exponent (yz). Then we have:
FIX = max { 0 , [(9-z#) + XP }

2. if number < 1 (or x="9")

let |XP| = 100 - xyz, and z# as defined above. Then we have:
FIX = min { 9 , [(9-z#) + |XP| }

And here is the code to be executed by the OS upon each qualifying I/O_SVC event:

Code:

384    CLRF 0    default is  XP > 0
0F8    READ 3(X)    
2FA    ?C#0 M    is it zero??
15B    JNC +43d    (has 10 zeroes in mantissa)
2A0    SETDEC    decimal math
01C    PT= 3    
006    A=0 S&X    
2E2    ?C#0 @PT    
037    JC  +06    [EXIT]
166    A=A+1 S&X    # of zero digits in A[S&X]
354    ?PT= 12    
01F    JC  +03    [EXIT]
3DC    PT=PT+1    
3D3    JNC -06    
130    LDI S&X    
009    CON:    mantissa field length
0A6    A<>C S&X    #z in C[S&X]
1C6    A=A-C S&X    mant# = (9 - z#)
086    B=A S&X    keep copy in B[S&X]
0F8    READ 3(X)    
106    A=C S&X    put it in A[S&X]
356    ?A#0 XS    lower than one?
03B    JNC  +07    no, jump to section
388    SETF 0    marks  XP < 0
016    A=0 XS    yes, remove sign
130    LDI S&X    
100    CON:    normalize constant
0A6    A<>C S&X    
1C6    A=A-C S&X    |XP| = (100 - XP)  in A[S&X]
130    LDI S&X    
009    CON:    maximum FIX setting
260    SETHEX    HEX mode
306    ?A<C S&X    is |XP| < 9 ?
063    JNC  +12d    no, out of bounds
0A6    A<>C S&X    put |XP| in C[S&X]
066    A<>B S&X    put (9-z#) in A[S&X]
38C    ?FSET 0    
01B    JNC +03    
206    C=C+A S&X    mant# + |XP|
03B    JNC +07    
246    C=A-C S&X    mant# - |XP|
2F6    ?C#0 XS    zeros in tens, hundreds...
023    JNC  +04    no, stay put
046    C=0 S&X    yes, it was integer!
013    JNC +02    skip next
0C6    C=B S&X    put (9-z#) in C[S&X]
0FC    RCR 10    puts it in C<4>
10E    A=C ALL    save result in A<4>
3B8    READ 14(d)    read flag register
158    M=C  ALL    save it for later
05C    PT= 4    
0A2    A<>C @PT    get fix# to C<4>
01C    PT= 3    
210    LD@PT- 8    FIX mode
3A8    WRIT 14(d)    temporary settings
0F8    READ 3(X)    puts value in C
099    ?NC XQ    Sends C to display - sets HEX
02C    ->0B26    [DSPCRG]
198    C=M  ALL    recall original FIX settings
205    ?NC GO    Set MSG flag (from C)
00E    ->0381    [STMSF]+3
(02-15-2015 02:29 PM)Geir Isene Wrote: [ -> ]Now where do I put the code and how to make the OS catch it?

Ah, that's the secret sauce ;-) Stay tuned for a second part article... but in all likelihood you wouldn't want to re-reinvent this wheel so use the SandMath 4x4 instead.
(02-15-2015 05:16 PM)Geir Isene Wrote: [ -> ]
(02-15-2015 04:09 PM)Ángel Martin Wrote: [ -> ]Ah, that's the secret sauce ;-) Stay tuned for a second part article... but in all likelihood you wouldn't want to re-reinvent this wheel so use the SandMath 4x4 instead.

But - I have all my ports pretty much covered. But I want this Floating FIX mode... and SandMath breaks my config. Put it in Library #4 perhaps?

Page#4 does not have interrupts - sorry not a chance. Perhaps the AMC_OS/X but that'd mean serious surgery and complete rewrite of many sections - too much effort for something it's already done. Also the RCL math needs the five additional functions... and it's all connected.- See the next post.
Implementation Details – a MCODE digression.

Taking advantage of the I/O_SVC Interrupt is not easy to implement, even if conceptually simple. For starters, one needs to keep in mind that the event is triggered after the operations have occurred – thus is not to be mistaken with a code break during the execution.

Then there is also the fact that a constant polling of the I/O_SVC will introduce noticeable overhead on the system performance, thus one needs to carefully choose the instances and scenarios where the supplemental code is to be run. Doing it too often will cause annoying delays, but missing some will result in an inconsistent or incomplete implementation of the added functionality.

To make it more complicated, this technique is also used by other modules that the implementation here needs to be compatible with. Not an easy task; you probably know that the ZENROM and the CCD Module are not compatible, and that the AECROM takes over all the attention to maintain the results in the chosen unit (Foot, meters, inch fractions).

The criteria followed by the SandMath is full compatibility with the AMC_OS/X and CCD-style modules, regardless of the order they are plugged in the machine. That’s why the criteria needs to go to lower-level conditions (like pending addresses in the RTN stack and keycodes for the pressed keys) instead og more general events, like parsing OS routines.

Here’s the conditional tree used to qualify I/O events into triggering points in the SandMath.

General conditions:

1. Is Alpha ON? - Ignore if true.
2. Is the 1st. RTN address from the OS ROM_0 / ROM_1? - Ignore if False.

Conditions for the Floating FIX mode:

3. Is the message flag ON? - Ignore if true.
4. Is the 1st. RTN address = 00F0 [NFRPU], or 0CCA [STO], or 10DA [AJ]? - Ignore if False


Conditions for the RCL Math and Prompt Lengtheners

5. Is the 1st. RTN adr = 0CDE [PAR110]? - Mid term of a 2-digit prompt when True
a. Further check on keycode to exclude XEQ, replace it otherwise.

6. Is the 1st. RTN adr = 0D22 [PARA05]? – Mid term of a 1-digit prompt when True
a. Further check on keycode to exclude CAT, replace it otherwise

7. Is the 1st. RTN adr = 0DC4 [IND20] ? IND prompt situation when True
a. Is the 2nd. RTN adr = 122E [RCL]? – Replace the first adr when True (IND 1_ _ )

Say what?, Not a Fool-Proof result !

One last word about the expected results:- This is a good example of the additional difficulty arising from the afterthought nature of a task that would be basically simple had it been done integrated into the OS. Coming from behind the OS to supplement/complement its doings is not the best way to implement this functionality, which ideally belongs to the OS displaying routines instead. Thus you’ll find some instances when the Floating FIX mode won’t kick in, like using STO and then numeric keys (but note that it does work using the top-two rows, A-J).

I have tested the outcome of all functions within the SandMath, modifying some of them to make sure that they provide the triggering conditions for the Floating mode to operate. With other modules the implementation may have some glitches, depending on how their functions were written.

There is currently a limitation for some functions when you execute them using the LASTFunction method, so be aware of that as well.
Reference URL's