6502 floating point

This is 6800 but I think one of the best explanations and coverages I’ve seen with real code.

3 Likes

Nice find! As it turns out, a couple of years later he wrote a 6502 version (which I just happen to have by me on my bookshelf…)

3 Likes

Well I thought BCD was the only 40 bit floating point, but Mr Gaters decided to have 32 bit binary fraction when he
ported BASIC from the 8080 to the 6502. Now your $2,900,00 computer has 8 digits, just like your
$29.00 calculator. Real BASIC’s have a MICROSOFT easter egg in it, that displays “MICRSOFT”,
like WAIT 6502 on your C64.

One thing that helped me finally put things together was figuring out what the Guard, Round, and Sticky bytes are and how they work. You can research that independent of any 6502 implementation.

Calc65 which you mentioned above is my creation, so I’m happy to answer any questions if that’s helpful.

2 Likes

Edit

Leaving this here because at the very least it might show other people with as limited understanding as I had why the code is perfectly fine. The reasoning I finally came to is a few posts down, there’s nothing wrong with the floating-point routines - just problems with my understanding of what the representation was.

Original text

I realise this is a necrobump of an old thread, but if anyone else comes looking (like I did) and finds this book (6502 Software Gourmet Guide And Cookbook), I hope to spare them the time I’ve spent trying to get floating point working using these routines…

Running the code looks as though it works at first, and I do really like the explanation (including diagrams, even) but the code can’t seem to perform (for example) 2-9. I’ve compared my code to the one in the book over and over, and I can’t see any typos, so …

It does work as long as the number doesn’t go negative (9-2=7), but 2-9 gives a result of 00:00:90:03…

… which resolves to 0.125 * 2^3 = 1, negated → -1

So unless someone else can validate that the code does in fact work, and I have, in fact, got a typo somewhere, I’d recommend steering clear of the book’s floating point routines.

Edit:

Actually now I’m wondering if there is something wrong with how I’m doing this. I just tried the same thing on the woz floating point code and I’m getting the same results…

Defining ‘2’ and 9…

@elysium% wozf 2 9
 f: 81:400000
 f: 83:480000

and putting them into the code so that it performs 2-9, I get 82:90:00:00

which corresponds to -1 also…

@elysium% wozf 0x82900000
 F: -1.000000

whereas reversing them gives ‘7’ as the answer (82:70:00:00)

I’m finding it difficult to believe that both of these are fundamentally broken in the same way, especially when ‘woz floating point format’ has been so extensively eyeballed over the years, so I’m guessing I’m making some sort of systemic error.

I guess I could always do a ‘compare’ before the sub of X-Y, and swap them around if Y>X as well as negate the result… Seems like a hack though.

Welcome! Something odd is happening, for sure. As you say, the woz routines are surely right. Are you sure of your emulator? And the ‘wozf’ program, are you sure of that? (I can’t see your math.s as the link times out.)

The easiest world for me to test is BBC Basic, but that uses a different floating point format which suppresses the leading 1 bit. See here though.

Thanks for the welcome :slight_smile:

Nope, not sure about the emulator, it’s relatively new to me - I can try another one and see, though. I guess in the last analysis I could push it over to the real, ancient, hardware that’s sitting in the other room :slight_smile:

The ‘wozf’ program is mine, and it does match vs constants in the original source. Also, 0x82900000 makes sense as -1 to me, based on:

  Exponent    Two's Complement Mantissa
  SEEEEEEE  SM.MMMMMM  MMMMMMMM  MMMMMMMM
     n         n+1       n+2       n+3

so 0x82 means “multiply by 4”, and 0x90 means -0.25, for a total of -1.

Maybe the next thing is to try and push it through a different emulator. I’ll see what I can find…

Edit:

Ok, well I don’t think it’s the emulator, unless two emulators are both failing in the same way (again, vanishingly unlikely :)) - The below is one emulator’s monitor window over the top of the same emulator I was using before… The values are the same

The next thing to check is the assembler, I guess…

Visual Transistor-level Simulation of the 6502 CPU, could be a good emulator to check with
as well.

In order to verify the emulator, an easy way to check it may be the online-emulatore here (there is also an assembler): https://www.masswerk.at/6502/

For a more complex online emulator, emulating entire systems together with full-fledged assemblers, have a look at https://8bitworkshop.com/

Ok, closing the loop on this. What was missing was my understanding :blush: Both assembler and emulator are working just fine …

Stepping through the code made it clear, the logic works well and we get to the penultimate step with an answer of +7 in the accumulator when subtracting 9 from 2. It then complements that and you end up with

00:00:90:03

I was interpreting the mantissa as

$90 = 10010000
      smmmmmmm

0x80 = 1  -> negative
0x40 = 0  -> 0 x 0.5
0x20 = 0  -> 0 x 0.25
0x10 = 1  -> 1 x 0.125 

where the exponent = 2^3 = 8 => (-1) * (8) * (0.125) => an answer of -1

But that’s not the case - the mantissa is to be regarded as valid for the number of bits specified in the exponent, and if it’s -ve then its a left-aligned 2’s complement number, so 0x90 is more recognizably specified (if it were a 32-bit int) as 0xfffffff9 or -7

And 2-9 is indeed -7, so the logic works just fine. I think I was being thrown off by the large number of zero-bits in a negative number, I normally expect to see 1-bits :slight_smile:

2 Likes