Jaap's Psion II Page

Home / Psion / Technical Reference Manual / Chapter 15
                                CHAPTER 15

                              _______________
                              MATHS FUNCTIONS



     This chapter describes the floating-point mathematics  routines  (add,
subtract,  multiply  and divide), the scientific functions and the routines
to convert between a floating-point number and an ascii text string.



      ______________________
15.1  FLOATING-POINT NUMBERS

These consist of a 12-digit precision BCD-packed mantissa with one byte for
the  sign  and  a  one byte signed binary exponent.  They are structured as
follows:  (low memory -> high memory)

        mantissa_1      low-order byte
        mantissa_2          .
        mantissa_3          .
        mantissa_4          .
        mantissa_5          .
        mantissa_6      high-order byte
        exponent        1 byte
        sign            1 byte

Each byte of the mantissa contains two decimal digits, the high-order digit
in  the  top 4 bits and the low-order digit in the bottom 4 bits.  The sign
byte has the normal sign convention i.e.  negative if bit  7  set,  positive
otherwise.   Standard practice in the Organiser operating system is $80 for
negative and zero for positive.  An  exponent  of  zero  (with  a  non-zero
mantissa)  implies  that  the  value  of  the  number  lies  between  1 and
9.99999999999 inclusive.

The mathematical routines operate on two  floating-point  registers,  which
are  identical  in  structure to the floating-point numbers described above
except for the addition of a guard byte to the mantissa.  These  bytes  are
used for rounding purposes.

The registers are arranged in zero-page  memory  as  follows  (see  section
6.5.1.2 on memory usage):
     _______    _____________           ________
     Address    Variable name           Function

        $c5      MTT_AMAN               accumulator: guard byte
        $c6         -                   start of accumulator mantissa
        $cc      MTB_AEXP               accumulator exponent
        $cd      MTB_ASGN               accumulator sign

        $ce      MTT_OMAN               operand: guard byte
        $cf         -                   start of operand mantissa
        $d5      MTB_OEXP               operand exponent
        $d6      MTB_OSGN               operand sign

Thus the floating-point number -12345.0006789 can be declared as follows:

FP_CONST:
        .BYTE   $89,$67,$00,$50,$34,$12         ;mantissa
        .BYTE   4                               ;exponent
        .BYTE   $80                             ;negative sign

and copied into the accumulator by the following code:

        LDD     #MTT_AMAN+1
        LDX     #8
        STX     UTW_S0:
        LDX     #FP_CONST
        OS      UT$CPYB




      _________________________
15.2  FLOATING-POINT ARITHMETIC

The four binary  operators  add,  subtract,  multiply  and  divide  operate
directly on the floating-point registers in the order

          accumulator (operator) operand = accumulator

e.g.  to do the operation 6/3 = 2, 6 is placed in the accumulator, 3 in the
operand  and  the  result after calling mt_fdiv will be in the accumulator.
Any number used as an argument to these routines must  be  normalised,  i.e.
the  most  significant  digit  of  the  mantissa  must  be non-zero for all
non-zero numbers.  Any number having zero in the most significant  byte  is
treated as zero.  For example declaring the number 0.00009999 as follows

        .BYTE   0,0,$99,$99,0,0         ;most significant digit is zero
        .BYTE   -1
        .BYTE   0

is incorrect. It should read:

        .BYTE   0,0,0,0,$99,$99         ;non-zero digits shifted to
                                        ;most significant position
        .BYTE   -5                      ;and exponent adjusted accordingly
        .BYTE   0

These routines also require the exponent to be in the range -99 to 99.  The
result  is  always  returned  as  a normalised floating-point number in the
accumulator, the operand remains  unchanged,  and  both  guard  digits  are
cleared to zero.  No validation is made of the contents of the registers on
input, and the arithmetic routines  will  attempt  to  operate  on  invalid
floating-point numbers with unpredictable results.

To prevent it from being corrupted, the operand is copied into the start of
the work buffer MTT_WBUF at $2288 (see section 6.5.1.3 on memory usage) and
then restored before returning from the routine.

A description of the system services to  handle  floating-point  arithmetic
follows.



        _______
15.2.1  MT$FADD

VECTOR NUMBER:          082
INPUT PARAMETERS:       Floating-point registers contain the two numbers
                        to be added.
OUTPUT VALUES:          Accumulator contains accumulator + operand.

DESCRIPTION

    Does a floating-point add on the accumulator and operand registers.

    When adding two numbers of equal exponent, the register  mantissas  are
    added  (or the smaller mantissa subtracted from the larger if the signs
    are not the same).  The exponent is incremented  by  1  if  the  result
    overflows,  and decremented if underflow occurs in subtraction.  If the
    exponents differ,  the  mantissa  of  the  register  with  the  smaller
    exponent  is  shifted  to  the  right (downwards in memory) by n digits
    where n is the difference  between  the  two  exponents.   The  shifted
    mantissa  is  then  added  to or subtracted from the other.  The larger
    exponent is taken as the exponent of the  result  after  adjusting  for
    over- or underflow as above.

    The alignment and addition/subtraction of mantissas are always done  on
    the  full 7 bytes of the register mantissas, i.e.  to 14 digit accuracy.
    If the result requires more than 12  digits  of  precision,  the  guard
    digits are used to round the least significant digit accordingly.

EXAMPLE

    To add 1.0E+11 and 202.88, the following constants can be set up:

    FP_CONST1:
        .BYTE   0,0,0,0,0,$10           ;mantissa
        .BYTE   11                      ;exponent
        .BYTE   0                       ;positive sign
    DUMMY_GUARD_BYTE:
        .BYTE   0
    FP_CONST2:
        .BYTE   0,0,0,$80,$28,$20       ;mantissa
        .BYTE   2                       ;exponent
        .BYTE   0                       ;sign

    and the following code executed (taking advantage of the fact that  the
    operand follows immediately after the accumulator in memory):

        LDD     #MTT_AMAN+1             ;D -> byte above guard digit
        LDX     #2*SZBCD+1              ;length to move
        STX     UTW_S0:
        LDX     #FP_CONST1
        OS      UT$CPYB                 ;copy constants into registers
        OS      MT$FADD

    then after the mantissas  have  been  aligned  they  will  contain  the
    following:

                                ________                    ___________
                                Mantissa                    Guard Digit

        Accumulator:            10 00 00 00 00 00           00
        Operand:                00 00 00 00 02 02           88

        Result after adding:    10 00 00 00 02 02           88

    Before returning this is rounded up and  the  guard  digit  cleared  to
    give:

                                10 00 00 00 02 03           00

ERRORS:                 ER_MT_EX - exponent overflow
                        i.e. MTB_AEXP > 99 or MTB_AEXP < -99



        _______
15.2.2  MT$FSUB

VECTOR NUMBER:          090
INPUT PARAMETERS:       Floating-point registers contain the two numbers
                        to be subtracted.
OUTPUT VALUES:          Accumulator contains accumulator - operand.

DESCRIPTION

    Subtracts the floating-point operand from the accumulator.

    The subtract routine simply toggles the sign byte of  the  operand  and
    adds  the registers as described in MT$FADD above, and is called in the
    same way.

ERRORS:                 ER_MT_EX - exponent overflow
                        i.e. MTB_AEXP > 99 or MTB_AEXP < -99



        _______
15.2.3  MT$FNGT

VECTOR NUMBER:          089
INPUT PARAMETERS:       X register - address of the floating-point
                        register to be negated.
OUTPUT VALUES:          None.

DESCRIPTION

    Toggles the sign of the register pointed to by X.

    Note that as this routine operates on a register, it assumes a mantissa
    length  of  7  bytes.  To negate a normal BCD number, X should point to
    the byte below the first byte of the number in memory.

EXAMPLE

    To change the sign of the accumulator, execute the following code:

        LDX     #MTT_AMAN
        OS      MT$FNGT

    and to negate the constant 202.88 in the addition  example  in  section
    15.2.1 above:

        LDX     #FP_CONST2-1
        OS      MT$FNGT

REGISTERS PRESERVED:    B and X.
ERRORS:                 None.



        _______
15.2.4  MT$FMUL

VECTOR NUMBER:          088
INPUT PARAMETERS:       Floating-point registers contain the numbers
                        to be multiplied.
OUTPUT VALUES:          Accumulator contains accumulator * operand.

DESCRIPTION

    Performs a floating-point multiply on the BCD registers.

    The mantissas are  multiplied  by  repeated  addition  of  the  operand
    mantissa into a temporary 28-digit double-precision mantissa (14 bytes)
    located in the floating-point  work  buffer  (see  section  6.5.1.3  on
    memory usage) at MTT_WBUF+8, i.e.  immediately following the stored copy
    of the operand (see 15.2 above).  The top seven bytes,  i.e.   the  most
    significant  14  digits,  are  then  copied from this register into the
    accumulator and rounded to 12 digits as for addition above.

EXAMPLE

    To multiply pi (3.14159265359) by -7160, set up the following:

    FP_PI:
        .BYTE   $59,$53,$26,$59,$41,$31 ;mantissa
        .BYTE   0                       ;exponent
        .BYTE   0                       ;sign
    DUMMY_GUARD_BYTE:
        .BYTE   0
    FP_CONST:
        .BYTE   0,0,0,0,$60,$71         ;mantissa
        .BYTE   3                       ;exponent
        .BYTE   $80

    and execute the following code (taking advantage of the fact  that  the
    operand follows immediately after the accumulator in memory):

        LDD     #MTT_AMAN+1             ;D -> byte above guard digit
        LDX     #2*SZBCD+1              ;length to move
        STX     UTW_S0:
        LDX     #FP_PI
        OS      UT$CPYB                 ;copy constants into registers
        OS      MT$FMUL

    The accumulator will now contain the result of -22493.8033997 and  will
    look like this:

    MTT_AMAN:   00
    MTT_AMAN+1: 97
    MTT_AMAN+2: 39
    MTT_AMAN+3: 03
    MTT_AMAN+4: 38
    MTT_AMAN+5: 49
    MTT_AMAN+6: 22
    MTB_AEXP:   04
    MTB_ASGN:   80

    The operand is not affected by the operation, so still contains -7160.

ERRORS:                 ER_MT_EX - exponent overflow
                        i.e. MTB_AEXP > 99 or MTB_AEXP < -99



        _______
15.2.5  MT$FDIV

VECTOR NUMBER:          087
INPUT PARAMETERS:       Floating-point dividend in accumulator, divisor in
                        operand.
OUTPUT VALUES:          Accumulator contains accumulator / operand.

DESCRIPTION

    Performs a floating-point divide on the BCD registers.

    The mantissas are divided  by  repeated  subtraction  of  the  operator
    mantissa  from the accumulator mantissa, with the result being built up
    in a seven-byte temporary mantissa located  at  MTT_WBUF+8.   Once  the
    process  is  complete,  the  contents  of  the  register  are copied to
    MTT_AMAN and rounded to 12 digits as with multiplication above.

EXAMPLE

    To divide the result of -22493.8033997 obtained in  the  multiplication
    example above by 0.00654, first set up the divisor as a constant:

    FP_DIVISOR:
        .BYTE   0,0,0,0,$40,$65         ;mantissa
        .BYTE   -3                      ;exponent
        .BYTE   0                       ;sign

    then execute the following code:

        LDD     #MTT_OMAN+1             ;target is operand
        LDX     #SZBCD                  ;length of one f.p. number
        STX     UTW_S0:
        LDX     #FP_DIVISOR
        OS      UT$CPYB                 ;copy divisor into operand
        OS      MT$FDIV                 ;and do division

    The accumulator will now contain the  result  -3439419.48008  and  will
    look like this:

    MTT_AMAN:   00
    MTT_AMAN+1: 08
    MTT_AMAN+2: 80
    MTT_AMAN+3: 94
    MTT_AMAN+4: 41
    MTT_AMAN+5: 39
    MTT_AMAN+6: 34
    MTB_AEXP:   06
    MTB_ASGN:   80

ERRORS:                 ER_MT_EX - exponent overflow
                        ER_MT_DI - divide by zero



      _________________________________________
15.3  CONVERTING NUMERIC TEXT TO FLOATING POINT

15.3.1  MT$BTOF

VECTOR NUMBER:          081
INPUT PARAMETERS:       X register - address of start of input string.
                        D register - address of target floating-point
                        number.
OUTPUT VALUES:          Floating-point representation of input string.
                        X points to terminator at end of input string.

DESCRIPTION

    Converts the numeric ascii string at X to the floating-point number  at
    D.   The string may be terminated by any character which is not numeric
    (and not by ".", "E" or "e" unless these have  previously  occurred  in
    the input string).

    The floating-point result is returned in  the  8  bytes  following  the
    address  given by D on entry (D should be preserved before calling this
    routine, as there is no pointer to the result on exit from it).

    Error ER_MT_IS is returned if:

     -  The exponent is greater than 99 or less than -99  (irrespective  of
        the value of the mantissa)

     -  The input string contains more  than  12  significant  digits  (not
        including leading or trailing zeros)

     -  The total of significant digits + trailing zeros exceeds 44

     -  There are no valid numeric digits in the mantissa (e.g.  .E5)

     -  There are no valid numeric digits in the exponent (e.g.  6E)


EXAMPLE

    The following code will convert the string "172.65" to floating-point:

        LDX     #INP_STRING
        LDD     #FP_BUF
        OS      MT$BTOF

    INP_STRING:
        .ASCIZ  "172.65"

    FP_BUF:
        .BLKB   8

    It may be useful to put the floating-point representation of  a  string
    into  one  of  the  registers used by the arithmetic routines described
    above.  The  following  code  will  convert  the  same  string  into  a
    floating-point number in the accumulator:

        LDX     #INP_STRING
        LDD     #MTT_AMAN+1             ;skip guard digit
        OS      MT$BTOF


ERRORS:                 ER_MT_IS - String to floating-point failed



      ________________________________________
15.4  CONVERTING FLOATING-POINT TO TEXT STRING

There are four routines to handle this, one for each of  the  four  formats
decimal,  scientific,  integer  and  general.   On  entry,  the  X register
contains the address of the start of the  output  string,  the  A  register
contains  the maximum length of the output string, and the B register gives
the number of decimal places if relevant.  The  floating-point  accumulator
(see  section  15.1 on floating-point numbers above) is always taken as the
source number to  be  converted,  since  it  contains  the  result  of  all
floating-point arithmetic operations.

The floating-point work buffer MTT_WBUF  (see  section  6.5.1.3  on  memory
usage) is used to build up the intermediate result, which is then copied to
the output area pointed to by X provided there is sufficient space for  it.
The floating-point registers are preserved.

If   successful,   these   routines   return   the   output   string   (not
zero-terminated) at the address given by X on entry, with the length of the
string in B.  There is no right-justification  of  the  string  within  the
given field width.  X should be preserved before calling these routines, as
there is no pointer to the output string on exit.

There is no validation of the number contained in the accumulator, so if it
contains garbage then the output routines will produce garbage.

A description of the four routines for floating-point  to  text  conversion
follows.



15.4.1  MT$FBDC


VECTOR NUMBER:          083
INPUT PARAMETERS:       A register - field width of output string.
                        B register - decimal places required.
                        X register - address of output buffer.
OUTPUT VALUES:          B register - length of the output string.

DESCRIPTION

    Converts floating-point accumulator  to  numeric  ascii  text,  decimal
    format.   This  is  the  format nnnn.nnn, i.e.  a decimal number with no
    exponent.  If the number of significant digits after the decimal  point
    is  greater  than  the  decimal  places  specified  in B, the number is
    rounded off to B decimal places.  Otherwise it is  zero-filled  on  the
    right to make up the necessary decimal places.

EXAMPLES

    The following  code  will  convert  the  value  172.65  placed  in  the
    accumulator  in  the  example  in  MT$BTOF  (section 15.3.1 above) to a
    decimal format string with 5 decimal places in a field width of 16:

        LDX     #STRING_BUF
        LDD     #16*256 + 5     ;field width in A, dec. places in B
        OS      MT$FBDC

    STRING_BUF:
        .BLKB   16

    STRING_BUF will now contain the string "172.65000" and the  B  register
    will  contain  9.   The  string  will  not  be  zero-terminated  unless
    STRING_BUF is zero-filled before the routine is called.

    Further  examples  of  the  output  strings  corresponding  to  various
    floating-point values follow:

    ___________         _____   ___________     _____________
    Accumulator         Width   Dec. Places     Output String

    0.0000004            20        4            0.0000
    0.00006              20        4            0.0001
    0                    20        4            0.0000
    1234.5               20        4            1234.5000
    1234.5                8        4            Error
                                                (Width too small)
    34E+10               20        4            340000000000.0000
    9E+20                60       14            Error
                                                (Too long for work buffer)

ERRORS:                 ER_MT_FL - output string too long for field width
                        or greater than maximum work buffer length of 34



15.4.2  MT$FBEX


VECTOR NUMBER:          084
INPUT PARAMETERS:       A register - field width of output string.
                        B register - decimal places required.
                        X register - address of output buffer.
OUTPUT VALUES:          B register - length of the output string.

DESCRIPTION

    Converts  floating-point  accumulator  to  numeric   ascii   text,   in
    exponential  (scientific)  format.   This is in the form n.nnnnnE+nn, a
    decimal mantissa with one digit before the decimal  point  followed  by
    the  exponent.   The  exponent  is  always  expressed  as a + or - sign
    followed by 2 numeric digits.

EXAMPLES

    The following  code  will  convert  the  value  172.65  placed  in  the
    accumulator  in  the  example  in  MT$BTOF (section 15.3.1 above) to an
    exponential format string with 4 decimal places in a field width of 16:

        LDX     #STRING_BUF
        LDD     #16*256 + 4     ;field width in A, dec. places in B
        OS      MT$FBEX

    STRING_BUF:
        .BLKB   16

    STRING_BUF will now contain the string "1.7267E+02" and the B  register
    will  contain 10.  Further examples of the output strings corresponding
    to various floating-point values follow:

    ___________         _____   ___________     _____________
    Accumulator         Width   Dec. Places     Output String

    0                    10         4           0.0000E+00
    640                  16         4           6.4000E+02
    112233445566         30        16           1.1223344556600000E+11
    112233445566         20        16           Error
                                                (Width too small)
    0.000071             10         0           7E-05
    0.000076             10         0           8E-05
    0.99999              10         3           1.000E+00

ERRORS:                 ER_MT_FL - output string too long for field width
                        or greater than maximum work buffer length of 34



15.4.3  MT$FBIN


VECTOR NUMBER:          086
INPUT PARAMETERS:       A register - field width of output string.
                        X register - address of output buffer.
OUTPUT VALUES:          B register - length of the output string.

DESCRIPTION

    Converts floating-point accumulator to numeric ascii text,  in  integer
    format.   The value in the B register is irrelevant in this routine, as
    there  are  no  decimal  places  involved.   If  the   value   in   the
    floating-point accumulator is not an integer, then the string output is
    the accumulator value rounded to the nearest integer.

EXAMPLES

    The following  code  will  convert  the  value  172.65  placed  in  the
    accumulator  in  the  example  in  MT$BTOF (section 15.3.1 above) to an
    integer format string in a field width of 16:

        LDX     #STRING_BUF
        LDA     A,#16           ;field width in A
        OS      MT$FBIN

    STRING_BUF:
        .BLKB   16

    STRING_BUF will now contain the string "173" and the  B  register  will
    contain  3.   Further  examples  of the output strings corresponding to
    various floating-point values follow:

    ___________         _____           _____________
    Accumulator         Width           Output String

    -10102               10             -10102
    500                   3             500
    -500                  3             Error
    6666.7               10             6667
    0                    10             0
    0.0002                5             0

ERRORS:                 ER_MT_FL - output string too long for field width
                        or greater than maximum work buffer length of 34



15.4.4  MT$FBGN


VECTOR NUMBER:          085
INPUT PARAMETERS:       A register - field width of output string.
                        B register - number of decimal places
                                     (disabled if negative).
                        X register - address of output buffer.
OUTPUT VALUES:          B register - length of the output string.

DESCRIPTION

    Converts floating-point accumulator to numeric ascii  text  in  general
    format,  i.e.   in  whichever  of  the  above  three formats is the most
    suitable for the given number and field width.

    The output string will  be  in  integer  format  if  the  number  is  a
    floating-point  integer,  otherwise decimal format.  If the field width
    is not sufficient for the above, the number  is  output  in  scientific
    format  rounded  to  as  many decimal places as can be accommodated.  A
    field width of 7 is sufficient to  convert  any  floating-point  number
    without  returning  an  error, though severe truncation of the mantissa
    may result.

    Fixing the number of decimal places is optional, and is disabled  if  B
    is  negative  (bit  7  set).  In this case the number of decimal places
    will be set equal to the number of significant digits to the  right  of
    the  decimal  point.   If B is positive, then it contains the number of
    decimal places to be fixed.

EXAMPLES

    The following  code  will  convert  the  value  172.65  placed  in  the
    accumulator  in the example in MT$BTOF (section 15.3.1 above) to a text
    string in a field width of 16:

        LDX     #STRING_BUF
        LDA     B,#$80          ;disable fixed decimal places
        LDA     A,#16           ;field width in A
        OS      MT$FBGN

    STRING_BUF:
        .BLKB   16

    STRING_BUF will now contain the string "172.65" and the B register will
    contain 6.  Note that the format in this case is decimal as this can be
    fitted into the given width.  Further examples of  the  output  strings
    corresponding to various floating-point values follow:

    ___________         _____   ___________     _____________
    Accumulator         Width   Dec. Places     Output String

    0                     1     Disabled        0
    3000000.078          20     Disabled        3000000.078
    -0.00005              8     Disabled        -0.00005
    -0.00005              7     Disabled        -5E-05
    123456789012000000   16     Disabled        1.2345678901E+17
    0.00123456789012     16     Disabled        0.00123456789012
    0.99999999            6     Disabled        1E+00
    -0.9                  6     Disabled        -0.9
    -0.99999999           7     Disabled        -1E+00
    7000000               4     Disabled        Error
    7000000               7     Disabled        7000000
    5000                 10        3            5000.000
    234.77               20       12            234.770000000000

ERRORS:                 ER_MT_FL - output string too long for field width



      ________________________
15.5  THE SCIENTIFIC FUNCTIONS

With a few exceptions, the system services for these  functions  require  a
single  floating-point  number  on the run-time stack (described in section
17.2.13) as input.  On exit this number is replaced by  the  floating-point
result,  with  the stack pointer unchanged.  The result is also left in the
floating-point  accumulator  (see  section  15.1  above  on  floating-point
numbers).

A call to one  of  these  services  can  be  set  up  by  decrementing  the
stack-pointer  RTA_SP at $A5 (see section 6.5.1.2 on memory usage) by 8 and
copying the argument into the 8 bytes pointed to by RTA_SP.  After  calling
the system service corresponding to the desired function the result will be
pointed to by RTA_SP which must be incremented by 8 to restore  it  to  its
original value.

Note that RTA_SP is used extensively  by  the  operating  system,  so  care
should  be  taken always to leave it pointing to the same place after using
it in these routines.  No testing for sufficient stack space  is  necessary
as  the  operating system ensures that there are always at least $100 bytes
available on the stack.  Beware of using the  stack  pointer  simply  as  a
pointer  to a floating-point constant in memory as intermediate results are
pushed onto the run-time stack and will destroy anything  in  memory  below
the  argument.   At least 60 bytes should be reserved as a work area in the
memory area immediately below the argument.

The functions make use of the table interpreter (see chapter  18)  and  the
floating-point  addition, subtraction, multiplication and division routines
described in section  15.2  above,  and  follow  the  algorithms  given  in
"Software Manual For The Elementary Functions" by Cody and Waite.



15.5.1  FN$ATAN

VECTOR NUMBER:          056
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the arctangent in radians of the floating-point number  on  the
    run-time stack.  The stack pointer (RTA_SP) remains unchanged.

EXAMPLE

    The following subroutine will return the arctan of 0.5 in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$ATAN
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   0,0,0,0,0,$50,-1,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result 0.463647609001.

ERRORS:                 ER_MT_EX - exponent overflow



15.5.2  FN$COS

VECTOR NUMBER:          057
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the cosine of the  floating-point  number  (assumed  to  be  in
    radians)  on  the  run-time  stack.  The stack pointer (RTA_SP) remains
    unchanged.

    Error ER_FN_BA is returned if the argument is greater than 3141590.4292
    or less than -3141590.4292.

EXAMPLE

    The following subroutine will return the cosine  of  3.1416  (PI  to  4
    decimal places) in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$COS
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   0,0,0,$60,$41,$31,0,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result -0.999999999974.

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.3  FN$EXP

VECTOR NUMBER:          058
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the result of the arithmetic constant  e  (2.71828...)  to  the
    power  of  the  floating-point number on the run-time stack.  The stack
    pointer (RTA_SP) remains unchanged.

    Error ER_FN_BA is returned if the argument is greater than or equal  to
    231.

EXAMPLE

    The following subroutine will return e to the power 230 in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$EXP
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   0,0,0,0,0,$23,2,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result 7.72201849998E+99

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.4  FN$LN

VECTOR NUMBER:          059
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the logarithm to the base e of the floating-point number on the
    run-time stack.  The stack pointer (RTA_SP) remains unchanged.

    Error ER_FN_BA is returned if the argument is negative or zero.

EXAMPLE

    The  following  subroutine  will  return   the   natural   log   of   e
    (2.71828182846) in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$LN
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   $46,$28,$18,$28,$18,$27,0,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result of 1.0.

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.5  FN$LOG

VECTOR NUMBER:          060
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the logarithm to the base 10 of the  floating-point  number  on
    the run-time stack.  The stack pointer (RTA_SP) remains unchanged.

    Error ER_FN_BA is returned if the argument is negative or zero.

EXAMPLE

    The following subroutine will return the log to  the  base  10  of  the
    largest floating-point number (9.99999999999E+99) in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$LOG
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   $99,$99,$99,$99,$99,$99,$63,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result of 100.

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.6  FN$POWR

VECTOR NUMBER:          064
INPUT PARAMETERS:       Two floating-point arguments on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the result of X ** Y where X and Y are  floating-point  numbers
    on  the  run-time stack.  The arguments should be pushed onto the stack
    in the order X first, then Y.   The  stack  pointer  (RTA_SP)  will  be
    incremented by 8 after the operation.

    Error ER_FN_BA is returned if:

     -  Both arguments are zero

     -  X is negative and Y non-integer

     -  The result is greater than 9.99999999999E+99


EXAMPLE

    The following subroutine will return 2 ** 10 in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #16             ;make room for arguments on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #16             ;length for copying arguments
        STX     UTW_S0:         ;(copying both together)
        LDX     #FN_Y           ;source address for UT$CPYB
        OS      UT$CPYB         ;copy arguments to stack
        OS      FN$POWR
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_Y:                               ;Y first, then X
        .BYTE   0,0,0,0,0,$10,1,0       ;(from low -> high memory)
    FN_X:
        .BYTE   0,0,0,0,0,$20,0,0
    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result 1024.0.

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.7  FN$RND

VECTOR NUMBER:          062
INPUT PARAMETERS:       None.
OUTPUT VALUES:          Floating-point random number on the stack.

DESCRIPTION

    Pushes a random floating-point number onto  the  run-time  stack.   The
    number  will  always  lie  between 0 and 0.999999999999 inclusive.  The
    stack pointer (RTA_SP) is decremented by 8.

    The seed for the random number generator is held  in  the  7  bytes  at
    FNT_SEED.   If  these  bytes  are  set  to  a particular value then the
    sequence of random numbers following this will always be the same.

EXAMPLE

    The following subroutine will place a random floating-point  number  in
    FN_RESULT.

        OS      FN$RND          ;call random number generator
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_RESULT:
        .BLKB   8

ERRORS:                 None.



15.5.8  FN$SIN

VECTOR NUMBER:          063
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the sine of the floating-point number (assumed to  be  radians)
    on the run-time stack.  The stack pointer (RTA_SP) remains unchanged.

    Error ER_FN_BA is returned if the argument is greater than  3141592  or
    less than -3141592.

EXAMPLE

    The following subroutine will return  the  sine  of  3.1416  (PI  to  4
    decimal places) in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$SIN
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   0,0,0,$60,$41,$31,0,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will contain the floating-point result -7.34641020669E-06.

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.9  FN$SQRT

VECTOR NUMBER:          064
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the square root of the floating-point number  on  the  run-time
    stack.  The stack pointer (RTA_SP) remains unchanged.

    Error ER_FN_BA is returned if the argument is negative.

EXAMPLE

    The following  subroutine  will  return  the  square  root  of  101  in
    FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$SQRT
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   0,0,0,0,$10,$10,2,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result 10.0498756211

ERRORS:                 ER_FN_BA - bad argument in function call



15.5.10  FN$TAN

VECTOR NUMBER:          065
INPUT PARAMETERS:       Floating-point argument on the stack.
OUTPUT VALUES:          Floating-point result on the stack.

DESCRIPTION

    Returns the tangent of the floating-point number on the run-time stack.
    The  stack pointer (RTA_SP) remains unchanged.  The argument is assumed
    to be in radians.

    Error ER_FN_BA is returned if the argument is greater than 3141590.4292
    or less than -3141590.4292.

EXAMPLE

    The  following  subroutine  will   return   the   tangent   of   3*PI/4
    (2.35619449019 radians) in FN_RESULT.

        LDD     RTA_SP:
        SUBD    #8              ;make room for argument on stack
        STD     RTA_SP:         ;D now has destination for UT$CPYB
        LDX     #8              ;length for copying argument
        STX     UTW_S0:
        LDX     #FN_ARG         ;source address for UT$CPYB
        OS      UT$CPYB         ;copy argument to stack
        OS      FN$TAN
        LDX     RTA_SP:         ;source address for copying result
        LDD     #8
        STD     UTW_S0:         ;length for copying result
        ADDD    RTA_SP:         ;add 8 to stack pointer
        STD     RTA_SP:         ;restore stack pointer
        LDD     #FN_RESULT      ;destination for copy
        OS      UT$CPYB
        RTS

    FN_ARG:
        .BYTE   $19,$90,$44,$19,$56,$23,0,0

    FN_RESULT:
        .BLKB   8

    FN_RESULT will now contain the floating-point result -1.0.

ERRORS:                 ER_FN_BA - bad argument in function call