
GameBoy/Z80 BCD Floating Point Math Package Specification, v1.2
---------------------------------------------------------------

 There is a define PERCISION at compile time that determines the
percision of the floating point operations. It is a static value
and is not designed to be modifiable during code execution. It's
value may be any even number, i.e.:

 PERCISION = 2  -> 3.1
 PERCISION = 4  -> 3.141
 PERCISION = 6  -> 3.14159
 etc...

 The exponent can range from -127 to +127. In later releases this
might drop to -64 to +64 in order to compress floating point storage
space by one byte.

 Higher percision settings require more memory for variable storage
and take longer execution times to perform. The default value for
percision is 6. IF THIS VALUE IS MODIFIED, THEN THE INTERNAL FLOATING
POINT CONSTANTS TABLES NEEDS TO BE MODIFIED. These tables are all
located in one place at the end of the math source code.

 Due to the structure of floating point number handling, pointers
to buffers for these numbers should point to the LAST byte of the
storage space.

 The current math routines are based on using a stack for operation
similiar to Reverse Polish Notation (RPN). This involves putting
arguments onto a stack and then calling a math function. The math
function will return any values on this stack as well.

Support Functions
-----------------

 Note: All references to the word value below refer to floating
       point values unless the word integer is specifically stated.

 InitializeFP -

        Should be called first to initialize Floating Point
        Stack, etc.

 FPToString -

        Convert value pointed to by HL to a null-terminated ascii
        string at location pointed to by DE. Up to PERCISION+8
        bytes may be required for storage of this string.

 PopArgument -

        Pop value on argument stack to address pointed to by HL.

 PopFix -

        Pop value on argument stack and convert it to integer
        value and put into registers DE. Carry flag set on exit
        if number negative or too large to convert.

 StringToFP -

        Convert a null-terminated ascii string containing a floating
        point number at location DE to a value at location HL.
        Carry flag set on exit if valid number not found.

 PushArgument -

        Push value addressed by HL onto argument stack.
 


Math Functions
--------------

 ComputeAbs -

        Return absolute value of a number. (If it's a negative
        number, convert it to positive.) X is on top of argument
        stack. Return result in place of X on stack.

 ComputeAdd -

        Return result of addition of top two stack arguments.
        Replace top two arguments on stack with result.

 ComputeCosine -

        Return cosine of argument given in radians in
        place of argument on stack.
 
 ComputeDiv -

        Similiar to ComputeAdd in stack operation.
        (In X = Y / Z, argument first put on stack is Y.)

 ComputeInt -

	Return the largest integer less than or equal to its
        argument. Similiar to ComputeAbsolute in stack operation.

 ComputeMult -

        Similiar to ComputeAdd in stack operation.

 ComputeNeg -

        Replace what's on stack with its negative value.

 ComputeSign -

        Returns a value of 1 if argument is greater than or equal
        to 0. Returns a value of -1 if argument is negative.
        Similiar to ComputeAbsolute in stack operation.

 ComputeSine -

        Return sine of argument given in radians in
        place of argument on stack.

 ComputeSqrRoot -

        Similiar to ComputeAbsolute in stack operation.

 ComputeSub -

        Similiar to ComputeAdd in stack operation.
        (In X = Y - Z, argument first put on stack is Y.)

 ComputeTan -

        Return tangent of argument given in radians in
        place of argument on stack.


Example Code to perform math
----------------------------

; Return an ascii string of the result of  8.72 * (5.4 + 3.2).
; Return string in StringOut.

        ld      de,Value1
        ld      hl,TempFP
        call    StringToFP        ; Set TempFP to 8.72

        ld      hl,TempFP
        call    PushArgument      ; Put TempFP on argument stack

        ld      de,Value2
        ld      hl,TempFP
        call    StringToFP        ; Set TempFP to 5.4

        ld      hl,TempFP
        call    PushArgument      ; Put TempFP on argument stack

        ld      de,Value3
        ld      hl,TempFP
        call    StringToFP        ; Set TempFP to 3.2

        ld      hl,TempFP
        call    PushArgument      ; Put TempFP on argument stack

        call    ComputeAdd        ; Replace top two arguments with 8.6 (5.4 + 3.2)

        call    ComputeMult       ; Replace top two arguments with 74.992 (8.6 * 8.72)

        ld      hl,TempFP
        call    PopArgument       ; Put result into TempFP

        ld      hl,TempFP
        ld      de,StringOut
        call    FPToString        ; Convert TempFP to ascii string at StringOut



; *** Floating-Point Constants ***

Value1:
        .byte   '8.72',0
Value2:
        .byte   '5.4',0
Value3:
        .byte   '3.2',0

; *** Ram Storage ***

TempFP  .equ    $+FP_SIZE-1       ; Point to last byte of FP storage
        .block  FP_SIZE           ; Reserve FP_SIZE bytes for temporary storage.

StringOut:                        ; '-3.14159e+128',0
        .block  PERCISION+8       ; Reserve (PERCISION+8) bytes for return ascii string.
