Something wrong with Steve Wozniak floating point software??

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
Mats
Posts: 111
Joined: 24 Aug 2003

Something wrong with Steve Wozniak floating point software??

Post by Mats »

Our WEB page:

http://www.6502.org/source/floats/wozfp1.txt

contains floating point software from:

Dr. Dobb's Journal, August 1976, pages 17-19.

Floating Point Routines for the 6502

by Roy Rankin, Department of Mechanical Engineering,
Stanford University, Stanford, CA 94305
(415) 497-1822

and

Steve Wozniak, Apple Computer Company
770 Welch Road, Suite 154
Palo Alto, CA 94304
(415) 326-4248

It is said:

All routines are called and exited in a uniform manner:
The arguments(s) are placed in the specified floating point
storage locations (for specifics, see the documentation preceeding
each routine in the listing), then a JSR is used to
enter the desired routine. Upon normal completion, the
called routine is exited via a subroutine return instruction (RTS).

I tested FADD and FSUB, both work perfectly. But not Floating Multiply - FMUL!!!

Putting floating point 1.5 which is $00600000 both in $04,$05,$06,$07 and in $08,$09,$0A,$0B and then calling FMUL
I get an unchanged $00600000 in $04,$05,$06,$07 and a value $00000000 in $08,$09,$0A,$0B. Not the expected 2.25 which is $01480000 in either place!

Checking the code one finds that one comes to the statement:

1F 0D 06 03 MD1 ASL SIGN CLEAR LSB OF SIGN

without having set variable "SIGN" anywhere previously! The value $EA ("NOP") is given to variable "SIGN" initially when assembled

0003 EA SIGN NOP

and this is the value I had:

But the ASL changes this to $D4 for the next call!

Then comes statements:

1F12 24 09 ABSWAP BIT M1 MANT1 NEG?
1F14 10 05 BPL ABSWP1 NO,SWAP WITH MANT2 AND RETURN

without previously having set the accumulator to any special value! If "MANT1" is negative the branch taken then depends on the random contents of the accumulator! Is a statement "LDA #$FF" missing?

Anyway, the software does not give the correct result!

Can anybody explain what is wrong? Maybe Steve Wozniak himself should be asked! But APPLE BASIC sure worked correctly!!!!
Mats
Posts: 111
Joined: 24 Aug 2003

Post by Mats »

OK! Looking in the programming manual I saw that the BIT operation differs from AND in that the N flag only is determined by the sign bit in memory, not by the "A ^ M" operation.

Code: Select all

   BIT   M
Is therfore meaningful also with undefined random accumulator content!

But this does not change that "FMUL" gives wrong result!
Mats
Posts: 111
Joined: 24 Aug 2003

Post by Mats »

OK, it is all clear now!

I wrote:

Putting floating point 1.5 which is $00600000 both in $04,$05,$06,$07 and in $08,$09,$0A,$0B and then calling FMUL I get an unchanged $00600000 in $04,$05,$06,$07 and a value $00000000 in $08,$09,$0A,$0B. Not the expected 2.25 which is $01480000 in either place!

Well, the strange thing with the Apple representation is that the sign bit of the exponent is complemented! It should be:

Putting floating point 1.5 which is $80600000 both in $04,$05,$06,$07 and in $08,$09,$0A,$0B and then calling FMUL I get $81480000 in $08,$09,$0A,$0B which is 2.25. Everything fine, FMUL OK!

FADD and FSUB happens to work without complementing the sign bit of the exponent!
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Re: Something wrong with Steve Wozniak floating point softwa

Post by dclxvi »

Mats wrote:
Checking the code one finds that one comes to the statement:

1F 0D 06 03 MD1 ASL SIGN CLEAR LSB OF SIGN

without having set variable "SIGN" anywhere previously! The value $EA ("NOP") is given to variable "SIGN" initially when assembled

0003 EA SIGN NOP

and this is the value I had:

But the ASL changes this to $D4 for the next call!
Here's why it is not necessary to initialize SIGN before the ASL SIGN. Both FMUL and FDIV start with a JSR MD1 and exit through MDEND. FMUL computes:

FP1 = ABS(FP2) * ABS(FP1) if the signs of FP1 and FP2 are equal
FP1 = -(ABS(FP2) * ABS(FP1)) if the signs of FP1 and FP2 are not equal

FDIV is similar. It computes:

FP1 = ABS(FP2) / ABS(FP1) if the signs of FP1 and FP2 are equal
FP1 = -(ABS(FP2) / ABS(FP1)) if the signs of FP1 and FP2 are not equal

At MD1 the ASL SIGN makes SIGN an even number. Then the absolute value of FP1 is computed and SIGN is incremented if FP1 was negative. (FP1 and FP2 are then swapped). Then the absolute value of what was originally FP2 is computed and SIGN is incremented if what was originally FP2 was negative. (FP1 and FP2 are swapped again, i.e. back to where they started).

So, if FP1 and FP2 were both postive, SIGN won't be incremented at all, and remains an even number.

If one is negative and the other is positive, SIGN gets incremented once making it an odd number.

If both are negative, SIGN is incremented twice and it becomes an even number.

So, if the signs of FP1 and FP2 were equal, SIGN will be even. If they were unequal SIGN, will be odd.

After returning from MD1, an unsigned multiplication (FMUL) or unsigned division (FDIV) is computed, leaving the result (product or quotient) in FP1. Then (at MDEND), the LSR SIGN checks if SIGN is even or odd. If odd, then FP1 = -FP1 is computed, since the signs were originally unequal.

So, basically, the ASL SIGN initializes SIGN since only one bit of that byte must be initialized.
Mats wrote:
But APPLE BASIC sure worked correctly!!!!
Arrgh! Chapter 1 of the FP user guide that I seem to be writing one post at a time is going to read "APPLE BASIC MAKES NO USE OF THESE ROUTINES AT ALL!!". Or perhaps that should be the title? :)
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Something wrong with Steve Wozniak floating point softwa

Post by BigEd »

So, while the head post of this (old!) thread turned out to be a false alarm, there does seem to have been a fix needed to the library as found in Dr Dobbs:
Quote:
ERRATA FOR RANKIN'S 6502 FLOATING POINT ROUTINES
Dr. Dobb's Journal, November/December 1976, page 57.

Sept. 22, 1976

Dear Jim,

Subsequent to the publication of "Floating Point
Routines for the 6502" (Vol.1, No.7) an error which I made in
the LOG routine came to light which causes improper results
if the argument is less than 1. The following changes will
correct the error.
  • 1.

    Code: Select all

        After:            CONT JSR SWAP (1D07)
        Add:    A2 00          LDX =0    LOAD X FOR HIGH BYTE OF EXPONENT
    
    
    2.

    Code: Select all

        After:                 STA M1+1 (1D12)
        Delete:                LDA =0
                               STA M1
        Add:    10 01          BPL *+3   IS EXPONENT NEGATIVE
                CA             DEX       YES, SET X TO $FF
                86 09          STX M1    SET UPPER BYTE OF EXPONENT
3. Changes 1 and 2 shift the code by 3 bytes so add 3 to the
addresses of the constants LN10 through MHLF whenever
they are referenced. For example the address of LN10 changes
from 1DCD to 1DD0. Note also that the entry point for
LOG10 becomes 1DBF. The routines stays within the page
and hence the following routines (EXP etc.) are not affected.

Yours truly,

Roy Rankin
Dep. of Mech. Eng.
Stanford University
(Found here, via this discussion)

See also this more recent thread. And see also Jeff Tranter's blog post and repo.

And for fun, see also this interview with Woz:
Quote:
I wrote down a complete syntax chart of the commands that were in the H-P BASIC manual, and I included floating point arithmetic, decimal points, numbers and everything. Then I started thinking it was going to take me a month longer - I could save a month if I left out the floating point.
Quote:
So I thought, I'll save a month writing my BASIC, and I'll have a chance to be known as the first one to write a BASIC for the 6502 processor. I said: I'll become famous like Bill Gates if I write it the fastest I could. So I stripped out the floating point.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Something wrong with Steve Wozniak floating point softwa

Post by BigEd »

(Worth noting that the source archive on this site presents the original as-published FP library as well as the later published correction and a related article. So, link here:
http://www.6502.org/source/#floatingpoint
and see also this other bug and correction:
viewtopic.php?p=43806#p43806
)
Post Reply