02-15-2015, 01:59 PM
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:
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