6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Jul 12, 2024 5:38 am

All times are UTC




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Thu Jan 04, 2018 7:30 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I am porting the Rankin and Wozniak 32 bit floating point code from Doctor Dobbs (posted here: http://www.6502.org/source/floats/wozfp1.txt) to the Ophis assembler. Reading the code is a head trip because the code flow is a bit convoluted to save space. There are two weird things that I would normally think were bugs if a mere mortal wrote it But given the origin and age of the code, they might actually do something useful.

I was curious if anyone had experience with them.

• The exp function contains an ADC at address 1E29 that doesn’t seem to do anything useful because there’s an LDA M1 directly afterwards.
Code:
1E26  18               CLC         CLEAR CARRY FOR ADD
1E27  A5 0A            LDA M1+1
1E29  69 78            ADC =120    ADD 120 TO INT
1E2B  A5 09            LDA M1
1E2D  69 00            ADC =0
1E2F  10 0B            BPL CONTIN  IF RESULT POSITIVE CONTINUE

Is there some side effect that is being exploited?

• The swap function contains a STY at 1F1E without an LDY prior.
Code:
1F1C  A2 04     SWAP   LDX =$04    INDEX FOR 4-BYTE SWAP.
1F1E  94 0B     SWAP1  STY E-1,X
1F20  B5 07            LDA X1-1,X  SWAP A BYTE OF EXP/MANT1 WITH
1F22  B4 03            LDY X2-1,X  EXP/MANT2 AND LEAVEA COPY OF
1F24  94 07            STY X1-1,X  MANT1 IN E(3BYTES). E+3 USED.
1F26  95 03            STA X2-1,X
1F28  CA               DEX         ADVANCE INDEX TO NEXT BYTE
1F29  D0 F3            BNE SWAP1   LOOP UNTIL DONE.
1F2B  60               RTS

I suspect that the first pass through the loop moves a junk byte, but all the rest of the iterations do something useful, so the junk byte is overwritten on the final iteration.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 04, 2018 8:32 pm 
Offline

Joined: Thu Jan 21, 2016 7:33 pm
Posts: 270
Location: Placerville, CA
Well, the LDA doesn't reset the carry flag, so that subsequent ADC would be affected by the result. I'll leave it to people who actually know from floating-point to analyze the implications.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 05, 2018 5:22 am 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 449
Location: Canada
IIRC there was an errata to the floating point routines that might be worth checking. The code and errata are also posted on this site somewhere I think. I ported the code to Verilog a while ago and it worked great.

_________________
http://www.finitron.ca


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 05, 2018 5:35 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1938
Location: Sacramento, CA, USA
Quote:
The code and errata are also posted on this site somewhere I think.

viewtopic.php?f=1&t=3633

Quote:
The exp function contains an ADC at address 1E29 that doesn’t seem to do anything useful because there’s an LDA M1 directly afterwards.

It looks like he might be doing a 16-bit compare, and is only interested in the flags, not the actual numeric result.

Quote:
I suspect that the first pass through the loop moves a junk byte, but all the rest of the iterations do something useful ...

I feel comfortable agreeing with you on that.

Mike B.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 05, 2018 6:32 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
Thanks for the pointer to the errata. I wrote a Python program to read the old style assembly and spit out Ophis style, so I reported using the corrected version. Some of my tests which were failing now work, so I think that fixed some issues.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 05, 2018 7:11 pm 
Offline

Joined: Sat Nov 26, 2016 2:49 pm
Posts: 25
Location: Tejas
Martin_H wrote:
... Some of my tests which were failing now work, so I think that fixed some issues.

So does that mean you've found other issues?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 05, 2018 8:37 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
DavidL wrote:
Martin_H wrote:
... Some of my tests which were failing now work, so I think that fixed some issues.

So does that mean you've found other issues?

I called float with 2 and it returned $89,$40,$00,$00. I think it should be $81,$40,$00,$00, so the exponent looks off.

Update: never mind. I was passing the value wrong and swapped the bytes which resulted in the bad exponent.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 06, 2018 8:04 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
I've completed my port of the code https://github.com/Martin-H1/Lisp65/blob/master/fmath32.asm and created a unit test https://github.com/Martin-H1/Lisp65/blob/master/tests/fmathTest.asm

But those routines don't include a print function, and I am getting sick of translating the hex to make sure the answers are correct. Does anyone have a pointer to a print function for this format, or general pointers for printing floating point in decimal?

I also found the Calc65 packed decimal routines. That library seems more complete, but also has a steeper learning curve.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 06, 2018 9:18 pm 
Offline

Joined: Sat Jul 28, 2012 11:41 am
Posts: 442
Location: Wiesbaden, Germany
I think EhBASIC uses the same floating point format. Just look for LAB_296E (convert FAC1 to ASCII string).

_________________
6502 sources on GitHub: https://github.com/Klaus2m5


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 07, 2018 5:00 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
Klaus2m5 wrote:
I think EhBASIC uses the same floating point format. Just look for LAB_296E (convert FAC1 to ASCII string).


Thanks for the pointer. Reading the code it sure looks like the same format, so it should help. It will take some time to understand it as the code uses somewhat obscure naming conventions.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jan 10, 2018 11:59 pm 
Offline

Joined: Thu Feb 10, 2011 3:14 am
Posts: 79
Code:
1E26  18               CLC         CLEAR CARRY FOR ADD
1E27  A5 0A            LDA M1+1
1E29  69 78            ADC =120    ADD 120 TO INT
1E2B  A5 09            LDA M1
1E2D  69 00            ADC =0
1E2F  10 0B            BPL CONTIN  IF RESULT POSITIVE CONTINUE


This is defintely a 16-bit compare. You have to use ADC or SBC because CMP ignores the Carry flag.

As I read it, the BPL branch will be taken if the 16 bit number at M1 is less than $0800.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 11, 2018 1:43 am 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1938
Location: Sacramento, CA, USA
CurtisP wrote:
Code:
1E26  18               CLC         CLEAR CARRY FOR ADD
1E27  A5 0A            LDA M1+1
1E29  69 78            ADC =120    ADD 120 TO INT
1E2B  A5 09            LDA M1
1E2D  69 00            ADC =0
1E2F  10 0B            BPL CONTIN  IF RESULT POSITIVE CONTINUE


This is defintely a 16-bit compare. You have to use ADC or SBC because CMP ignores the Carry flag.

As I read it, the BPL branch will be taken if the 16 bit number at M1 is less than $0800.

... except that M1 is the high byte and M1+1 is the low byte in this setup, so to me it looks like Woz (and/or Roy) could be CONTINing if $FF88 (-120) <= number < $7F88 (+32648).

Mike B.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: