* * * * *
Converting IEEE-754 floating point to Color BASIC floating point
I'm still playing around with floating point on the 6809 [1]—specifically,
support for floating point for the Color Computer. The format for floating
point for Color BASIC (Beginners' All-purpose Symbolic Instruction Code)
(written by Microsoft) predates the IEEE (Institute of Electrical and
Electronics Engineers)-754 Floating Point Standard [2] by a few years and
thus, isn't quite compatible. It's close, though. It's defined as an 8-bit
exponent, biased by 129, a single sign bit (after the exponent) and 31 bits
for the mantissa (the leading one assumed). It also does not support ±∞ nor
NaN (Not a Number). This differs from the IEEE-754 single precision that uses
a single sign bit, an 8-bit exponent biased by 127 and 23 bits for the
mantissa (which also assumes a leafing one) and support for infinities and
NaN. The IEEE-754 double precision uses a single sign bit, an 11-bit exponent
biased by 1023 and 52 bit for the mantissa (leading one assumed) plus support
for infinities and NaN.
So the Color BASIC is about halfway between single precision and double
precision. This lead me to use IEEE-754 double precision for the Color
Computer backend (generating an error for inifinities and NaN) then massaging
the resulting double into the proper format [3]. I double checked this by
finding some floating point constants in the Color BASIC ROM (Read Only
Memory) as shown in the book Color BASIC Unravelled II, (available on the
Computer Computer Archives [4]), like this table:
-----[ Listing ]-----
4634 * MODIFIED TAYLOR SERIES SIN COEFFICIENTS
4635 BFC7 05 LBFC7 FCB 6-1 SIX COEFFICIENTS
4636 BFC8 84 E6 1A 2D 1B LBFC8 FCB $84,$E6,$1A,$2D,$1B * -((2*PI)**11)/11!
4637 BFCD 85 28 07 FB F8 LBFCD FCB $86,$28,$07,$FB,$F8 * ((2*PI)**9)/9!
4638 BFD2 87 99 68 89 01 LBFD2 FCB $87,$99,$68,$89,$01 * -((2*PI)**7)/7!
4639 BFD7 87 23 35 DF E1 LBFD7 FCB $87,$23,$35,$DF,$E1 * ((2*PI)**5)/5!
4640 BFDC 86 A5 5D E7 28 LBFDC FCB $86,$A5,$5D,$E7,$28 * -((2*PI)**3)/3!
4641 BFE1 83 49 0F DA A2 LBFE1 FCB $83,$49,$0F,$DA,$A2 * 2*PI
-----[ END OF LINE ]-----
Then using the byte values to populate a variable and printing it inside
BASIC (this is the expression -2π^3/3!):
-----[ BASIC ]-----
X=0 ' CREATE A VARIABLE
Y=VARPTR(X) ' GET ITS ADDRESS
POKE Y,&H86 ' AND SET ITS VALUE
POKE Y+1,&HA5 ' THE HARD WAY
POKE Y+2,&H5D
POKE Y+3,&HE7
POKE Y+4,&H28
PRINT X ' LET'S SEE WHAT IT IS
-41.3417023
-----[ END OF LINE ]-----
Then using that to create a floating point value:
-----[ Assembly ]-----
org $1000
.float -41.3417023
end
-----[ END OF LINE ]-----
Checking the resulting bytes that were generated:
-----[ Listing ]-----
| FILE ff.a
1 | org $1000
1000: 86A55DE735 2 | .float -41.3417023
3 | end
-----[ END OF LINE ]-----
And adjusting the floating point constant until I got bytes that matched:
-----[ Listing ]-----
| FILE ff.a
1 | org $1000
1000: 86A55DE728 2 | .float -41.341702110
3 | end
-----[ END OF LINE ]-----
I figure it's “close enough.” The parsing code in the Color BASIC ROM is old
and predates the IEEE-754 floating point standard, so a few different digits
at the end I think is okay.
As a final check, I wrote the following bit of code to calculate and display
2π^3/3!, display the pre-calculated result, as well as display the pre-
calculated value of 2π:
-----[ Assembly ]-----
include "Coco/basic.i"
include "Coco/dp.i"
CB.FSUBx equ $B9B9 ; FP0 = X - FP0 ; addresses for
CB.FSUB equ $B9BC ; FP0 = FP1 - FP0 ; these routines
CB.FADDx equ $B9C2 ; FP0 = X + FP0 ; from
CB.FADD equ $B9C5 ; FP0 = FP1 + FP1 ; Color BASIC Unravelled II
CB.FMULx equ $BACA ; FP0 = X * FP0
CB.FMUL equ $BAD0 ; FP0 = FP0 * FP1
CB.FDIVx equ $BB8F ; FP0 = X / FP0
CB.FDIV equ $BB91 ; FP0 = FP1 / FP0
CB.FP0fx equ $BC14 ; FP0 = X
CB.xfFP0 equ $BC35 ; X = FP0
CB.FP1f0 equ $BC5F ; FP1 = FP0
CB.FP0txt equ $BDD9 ; result in X, NUL terminated
org $4000
start ldx #tau ; point to 2*pi
jsr CB.FP0fx ; copy to FP0
ldx #tau ; 2PI * 2PI
jsr CB.FMULx
ldx #tau ; 2PI * 2PI * 2PI
jsr CB.FMULx
jsr CB.FP1f0 ; copy fp acc to FP1
ldx #fact3 ; point to 3!
jsr CB.FP0fx ; copy to FP0
jsr CB.FDIV ; FP0 = FP1 / FP0
neg CB.fp0sgn ; negate result by flippping FP0 sign
jsr CB.FP0txt ; generate string
bsr display ; display on screen
ldx #answer ; point to precalculated result
jsr CB.FP0fx ; copy to FP0
jsr CB.FP0txt ; generate string
bsr display ; display
ldx #tau ; now display 2*pi
jsr CB.FP0fx ; just to see how close
jsr CB.FP0txt ; it is.
bsr display
rts
display.char jsr [CHROUT] ; display character
display lda ,x+ ; get character
bne .char ; if not NUL byte, display
lda #13 ; go to next line
jsr [CHROUT]
rts
tau .float 6.283185307
fact3 .float 3!
answer .float -(6.283185307 ** 3 / 3!)
end start
-----[ END OF LINE ]-----
The results were:
-----[ data ]-----
-41.3417023
-41.3417023
6.23418531
-----[ END OF LINE ]-----
The calculation results in -41.3417023 and the direct result stored in answer
also prints out -41.3417023, so that matches and it reinforces my approach to
this nominally right.
But I think Microsoft had issues with either generating some of the floating
point constants for the larger terms, or transcribing the byte values of the
larger terms. Take for instance -2π^11/11!. The correct answer is -
15.0946426, but the bytes in the ROM define the constant -14.3813907, a
difference of .7. And it's not like Color BASIC can't calculate that
correctly—when I typed in the expression by hand, it was able to come up with
-15.0946426.
Or it could be that [DELETED-Walter K. Zydhek,-DELETED] the author of Color
BASIC Unravelled II, is wrong in his interpretation of the expressions used
to generate the values, or his interpretation of what the values are used
for. I'm not sure who is at fault here.
Update on Friday, March 1^st, 2024
I was wrong about the authorship of Color BASIC Unravelled II. It was not
Walter K. Zydhek, but some unknown author of Spectral Associates, a company
that is no longer in business. All Zydhek did was to transcribe a physical
copy of the book (which is no longer available for purchase anywhere) into a
PDF (Portable Document Format) and make it available.
[1]
gopher://gopher.conman.org/0Phlog:2024/02/07.1
[2]
https://codedocs.org/what-is/ieee-754
[3]
https://github.com/spc476/a09/blob/8682748ac0f98d7f83bbdb0b6e772270cf3fc89f/frsdos.c#L292
[4]
https://colorcomputerarchive.com/repo/Documents/Books/Unravelled%20Series/
---
Discussions about this page
Two Stop Bits | Converting IEEE-754 floating point to Color BASIC floating point
https://twostopbits.com/item?id=2447
Email author at
[email protected]