How does the floating point math package in BASIC work?

Hardware Hacking, Programming and Game Solutions/Cheats
User avatar
JeeK
Posts: 67
Joined: Fri Aug 16, 2013 10:45 am
Location: Vienna, Austria
Contact:

Re: How does the floating point math package in BASIC work?

Post by JeeK »

jedie wrote:I try my new filter stuff to analyse the xroar trace...

Get this, e.g.:

Code: Select all

... [Skip 21546 lines] ...
4003| bd8c37      JSR     $8c37               cc=a0 a=00 b=06 dp=00 x=4000 y=890b u=0000 s=7f1f | $4003: UNKNOWN
... [Skip 78 lines] ...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=0d dp=00 x=83c0 y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=0d dp=00 x=83c0 y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e52        LDX     <$52                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7052      STX     $7052               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
4015| 9e54        LDX     <$54                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4015: UNKNOWN
4017| bf7054      STX     $7054               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4017: UNKNOWN
401a| 39          RTS                         cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f23 | $401a: UNKNOWN
... [Skip 21579 lines] ...
4003| bd8c37      JSR     $8c37               cc=a0 a=00 b=07 dp=00 x=4000 y=890b u=0000 s=7f1f | $4003: UNKNOWN
... [Skip 78 lines] ...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=0d dp=00 x=83e0 y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=0d dp=00 x=83e0 y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e52        LDX     <$52                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7052      STX     $7052               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
4015| 9e54        LDX     <$54                cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4015: UNKNOWN
4017| bf7054      STX     $7054               cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4017: UNKNOWN
I see that X is e.g.: $83c0 and $83e0
But in my BASIC PRINT's i see only $83 (the FPA0 exponent) and not $c0 and $e0 (the FPA0 MS)

But it's also clear that NMS,NLS,LS and SIGN is $00 :?
[..]
The copy from FPA0 to $70xx area is still some kind of inefficient:
To transfer 6 byte, I would suggest three 16 bit transfers are sufficient ...
Why not simply

Code: Select all

LDX <$4F
STX $704F
LDX <$51
STX $7051
LDX <$53
STX $7053
Gets all values from $4F to $54.

$83E0 seem to be to EXP and most significant mantissa part representing 0.111*2^3 = 7, isn't it? I suspect the routine was called with D=7

You will never see the most significant byte of the mantissa if you do not print it ... your print statement or the variable names before fits not together ...

Code: Select all

PRINT "D=";RIGHT$("  "+STR$(D2),4);" FPA0=$"+HEX$(EX)+" $"+HEX$(MS)+" $"+HEX$(NMS)+" $"+HEX$(NLS)+" $"+HEX$(LS)+" $"+HEX$(SIGN)
According to your variable names it should go this way:

Code: Select all

PRINT "D=";RIGHT$("  "+STR$(D2),4);" FPA0=$"+HEX$(EX)+" $"+HEX$(MP)+" $"+HEX$(NMS)+" $"+HEX$(NLS)+" $"+HEX$(LS)+" $"+HEX$(SIGN)
Or change the assignment to

Code: Select all

MS  =PEEK(&H7050) ' $50 FPA0 MS
;)
The dragon on my side: http://klasek.at/hc/dragon/
User avatar
JeeK
Posts: 67
Joined: Fri Aug 16, 2013 10:45 am
Location: Vienna, Austria
Contact:

Re: How does the floating point math package in BASIC work?

Post by JeeK »

jedie wrote:[..]

From https://github.com/6809/rom-info/blob/m ... agon32.txt :

Code: Select all

$4f-$54 ; Floating Point Accumulator Num 1
$4f ; Exponent
$50-$53 ; Mantissa
$50-$51 ; 16 bit values in FAC stored here
$52-$53 ; VARPTR of variables is stored here {1}
$54 ; Mantissa Sign (0x00 positive, 0xff negative)
$55 ; Temp sign of FAC
$63         ; CoCo - Extended precision byte {1} - also Dragon ?
So $63 is the "Extended precision byte" ? Don't know what function this is.
In various operation (normalization, multiplication, ...) the mantissa is expanded by 8 bit (=extended precision byte) to keep more mantissa bits "alive" which possibly find their way back into final mantissa bits later on. It's part of the Microsoft Basic floating point implementation and therefore can be found on both platforms ...
The dragon on my side: http://klasek.at/hc/dragon/
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: How does the floating point math package in BASIC work?

Post by jedie »

Thanks for your feedback...

I updated the script, see: https://gist.github.com/jedie/22dba94f5 ... /revisions
Changed MP to MS and now $4F, $51 and $53 moved via X

The result is the same :(
JeeK wrote:$83E0 seem to be to EXP and most significant mantissa part representing 0.111*2^3 = 7, isn't it? I suspect the routine was called with D=7
No, i called it with 2, you see it in the first line, here: https://gist.github.com/jedie/4c884924d ... df4770be98

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=02 dp=00 x=4000 y=890b u=0000 s=7f21
D was set to $0002

That seems to be correct, in my Emulation, with the test value 2 is the same result:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $82 (dez: 130)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $80 (dez: 128)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN

Float value was: 2
	exponent......: dez.: 2 hex: $02
	exponent byte.: dez.: 130 hex: $82
	mantissa value: dez.: 0.5
	mantissa bytes: dez.: [128, 0, 0, 0] hex: $80, $00, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $82, $80, $00, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10000010 10000000 00000000 00000000 00000000 00000000
Note: The "Memory dump" is the result of the Emulation via Simple6809 ROM, witch is the same as in Xroar with D32 ROM.
The Info unter "Float value was: 255" is my own Python Implementation.
The Binary is both: $82, $80, $00, $00, $00, $00




There the new trace with 7 as test value: https://gist.github.com/jedie/4c884924d ... 8f68b91f7d
Interesting lines:

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=07 dp=00 x=4000 y=890b u=0000 s=7f21
...
4006| 9e4f LDX <$4f cc=88 a=00 b=0d dp=00 x=83e0 y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f STX $704f cc=88 a=00 b=0d dp=00 x=83e0 y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51 LDX <$51 cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051 STX $7051 cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e53 LDX <$53 cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7053 STX $7053 cc=84 a=00 b=0d dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
...
So it's: $83, $e0, $00, $00, $00, $00

That's also the same as in my Emulation:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $83 (dez: 131)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $e0 (dez: 224)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN
Float value was: 7
	exponent......: dez.: 3 hex: $03
	exponent byte.: dez.: 131 hex: $83
	mantissa value: dez.: 0.875
	mantissa bytes: dez.: [224, 0, 0, 0] hex: $e0, $00, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $83, $e0, $00, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10000011 11100000 00000000 00000000 00000000 00000000


One of the differed result is 129 (in hex: $81):
XRoar:

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=81 dp=00 x=4000 y=890b u=0000 s=7f21
...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=08 dp=00 x=8881 y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=08 dp=00 x=8881 y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e53        LDX     <$53                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7053      STX     $7053               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
4015| 39          RTS                         cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f23 | $4015: UNKNOWN
In my Emulation:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $88 (dez: 136)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $81 (dez: 129)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN

Float value was: 129
	exponent......: dez.: 8 hex: $08
	exponent byte.: dez.: 136 hex: $88
	mantissa value: dez.: 0.50390625
	mantissa bytes: dez.: [128, 128, 0, 0] hex: $80, $80, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $88, $80, $80, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10001000 10000000 10000000 00000000 00000000 00000000
So:
Xroar D32 == Own Emulation == $88 $81 $00 $00 $00 $00 $00
Python Version is: $88, $80, $80, $00, $00, $00


Also a different result with 255 ($00ff):
Xroar:

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=ff dp=00 x=4000 y=890b u=0000 s=7f21
...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=08 dp=00 x=88ff y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=08 dp=00 x=88ff y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e53        LDX     <$53                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7053      STX     $7053               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
In my Emulation:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $88 (dez: 136)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $ff (dez: 255)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN
Float value was: 255
	exponent......: dez.: 8 hex: $08
	exponent byte.: dez.: 136 hex: $88
	mantissa value: dez.: 0.99609375
	mantissa bytes: dez.: [254, 128, 0, 0] hex: $fe, $80, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $88, $fe, $80, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10001000 11111110 10000000 00000000 00000000 00000000
Xroar==Emulation== $88, $ff, $00, $00, $00, $00
Python Implementation: $88, $fe, $80, $00, $00, $00



The good news for me: My Emulation has the same values (in this case)...
Bad news: My FP-Implementation https://github.com/jedie/DragonPy/blob/ ... g_point.py is wrong.
And bad: The BASIC Test program is still buggy ;(
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
User avatar
JeeK
Posts: 67
Joined: Fri Aug 16, 2013 10:45 am
Location: Vienna, Austria
Contact:

Re: How does the floating point math package in BASIC work?

Post by JeeK »

jedie wrote:Thanks for your feedback...

I updated the script, see: https://gist.github.com/jedie/22dba94f5 ... /revisions
Changed MP to MS and now $4F, $51 and $53 moved via X

The result is the same :(
Which result do you mean?
I don't think so. The results are fine now!
jedie wrote:
JeeK wrote:$83E0 seem to be to EXP and most significant mantissa part representing 0.111*2^3 = 7, isn't it? I suspect the routine was called with D=7
No, i called it with 2, you see it in the first line, here: https://gist.github.com/jedie/4c884924d ... df4770be98

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=02 dp=00 x=4000 y=890b u=0000 s=7f21
D was set to $0002
Yes, but the corresponding result is exp. $82 and MS mant. $80 with is 0.1*2^2 = 2 ...

Code: Select all

4006| 9e4f        LDX     <$4f                cc=88 a=00 b=0e dp=00 x=8280 y=890b u=0000 s=7f21 | $4006: UNKNOWN
Correct!
jedie wrote: That seems to be correct, in my Emulation, with the test value 2 is the same result:
[..]
There the new trace with 7 as test value: https://gist.github.com/jedie/4c884924d ... 8f68b91f7d
[..]

One of the differed result is 129 (in hex: $81):
XRoar:

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=81 dp=00 x=4000 y=890b u=0000 s=7f21
...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=08 dp=00 x=8881 y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=08 dp=00 x=8881 y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e53        LDX     <$53                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7053      STX     $7053               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
4015| 39          RTS                         cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f23 | $4015: UNKNOWN
In my Emulation:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $88 (dez: 136)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $81 (dez: 129)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN

Float value was: 129
	exponent......: dez.: 8 hex: $08
	exponent byte.: dez.: 136 hex: $88
	mantissa value: dez.: 0.50390625
	mantissa bytes: dez.: [128, 128, 0, 0] hex: $80, $80, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $88, $80, $80, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10001000 10000000 10000000 00000000 00000000 00000000
So:
Xroar D32 == Own Emulation == $88 $81 $00 $00 $00 $00 $00
Python Version is: $88, $80, $80, $00, $00, $00
Looks like an off by one error ...
jedie wrote: Also a different result with 255 ($00ff):
Xroar:

Code: Select all

4000| fc1052      LDD     $1052               cc=a0 a=00 b=ff dp=00 x=4000 y=890b u=0000 s=7f21
...
4006| 9e4f        LDX     <$4f                cc=88 a=00 b=08 dp=00 x=88ff y=890b u=0000 s=7f21 | $4006: UNKNOWN
4008| bf704f      STX     $704f               cc=88 a=00 b=08 dp=00 x=88ff y=890b u=0000 s=7f21 | $4008: UNKNOWN
400b| 9e51        LDX     <$51                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400b: UNKNOWN
400d| bf7051      STX     $7051               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $400d: UNKNOWN
4010| 9e53        LDX     <$53                cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4010: UNKNOWN
4012| bf7053      STX     $7053               cc=84 a=00 b=08 dp=00 x=0000 y=890b u=0000 s=7f21 | $4012: UNKNOWN
In my Emulation:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $88 (dez: 136)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $ff (dez: 255)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN
Float value was: 255
	exponent......: dez.: 8 hex: $08
	exponent byte.: dez.: 136 hex: $88
	mantissa value: dez.: 0.99609375
	mantissa bytes: dez.: [254, 128, 0, 0] hex: $fe, $80, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $88, $fe, $80, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10001000 11111110 10000000 00000000 00000000 00000000
Xroar==Emulation== $88, $ff, $00, $00, $00, $00
Python Implementation: $88, $fe, $80, $00, $00, $00
As already mentioned, I think a shifting loop runs one extra time inserting an additional "0" ...
Sure, you will spot it soon ...
jedie wrote: The good news for me: My Emulation has the same values (in this case)...
Bad news: My FP-Implementation https://github.com/jedie/DragonPy/blob/ ... g_point.py is wrong.
And bad: The BASIC Test program is still buggy ;(
Why, do have a screen shot? With my latest pointers I would suggest that things are gonna better now ...
The dragon on my side: http://klasek.at/hc/dragon/
User avatar
JeeK
Posts: 67
Joined: Fri Aug 16, 2013 10:45 am
Location: Vienna, Austria
Contact:

Re: How does the floating point math package in BASIC work?

Post by JeeK »

JeeK wrote:
jedie wrote: The good news for me: My Emulation has the same values (in this case)...
Bad news: My FP-Implementation https://github.com/jedie/DragonPy/blob/ ... g_point.py is wrong.
And bad: The BASIC Test program is still buggy ;(
Why, do have a screen shot? With my latest pointers I would suggest that things are gonna better now ...
EDIT: too much quoting ...

Found the error in your FP-Implementation:

Code: Select all

<             for bit_no in reversed(xrange(1, 8)):
---
>             for bit_no in reversed(xrange(0, 8)):
xrange need start start value (0) and the count - bit no has to start with 0 if this is used to calculate the correct bit value 1, 2, 4, 8, ...

Off-by-one, as expected ... ;)
The dragon on my side: http://klasek.at/hc/dragon/
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: How does the floating point math package in BASIC work?

Post by jedie »

JeeK wrote:Found the error in your FP-Implementation:

Code: Select all

<             for bit_no in reversed(xrange(1, 8)):
---
>             for bit_no in reversed(xrange(0, 8)):
You are right! Big thanks!

With commit https://github.com/jedie/DragonPy/commi ... c7742beb60 it works from $1-$ff ;)

Only the 0 is wrong:
in RAM...: $00, $00, $00, $00, $00, $00
Reference: $80, $00, $00, $00, $00, $00

It's from this lines:

Code: Select all

        self.mantissa, self.exponent = math.frexp(value)
        self.exponent_byte = unsigned8(self.exponent - 128)
math.frexp() returns (0,0) if value is 0... But the unsigned8 stuff results in $80...

I see there is extra code to handle 0:

Code: Select all

2852 ec7e c1 28                        CMPB #5*8           CHECK FOR 5 SHIFTS 
2853 ec80 2d e4                        BLT  LBA1D          BRANCH IF < 5 SHIFTS, IF > 5, THEN MANTISSA = 0 
2854 ec82 4f                 LBA39     CLRA                A ZERO EXPONENT = 0 FLOATING POINT 
2855 ec83 97 4f              LBA3A     STA  FP0EXP         ZERO OUT THE EXPONENT 
2856 ec85 97 54                        STA  FP0SGN         ZERO OUT THE MANTISSA SIGN 
I have also add a special case handling, if value==0, see: https://github.com/jedie/DragonPy/commi ... d5f4a60d28

Now $0-$ff values are the same... :D

Great!



Next test is with:
$e778 = CONVERT THE VALUE IN ACCD INTO A FLOATING POINT NUMBER IN FPA0
After $7fff is failed:
$0000 (dez.: 0): *** OK

$0001 (dez.: 1): *** OK

$0002 (dez.: 2): *** OK

...


$007f (dez.: 127): *** OK

$0080 (dez.: 128): *** OK

$0081 (dez.: 129): *** OK

...


$00fe (dez.: 254): *** OK

$00ff (dez.: 255): *** OK

$0100 (dez.: 256): *** OK

...


$7ffe (dez.: 32766): *** OK

$7fff (dez.: 32767): *** OK

$8000 (dez.: 32768): *** ERROR:
in RAM...: $90, $80, $00, $00, $00, $ff
Reference: $90, $80, $00, $00, $00, $00

$8001 (dez.: 32769): *** ERROR:
in RAM...: $8f, $ff, $fe, $00, $00, $ff
Reference: $90, $80, $01, $00, $00, $00

$8002 (dez.: 32770): *** ERROR:
in RAM...: $8f, $ff, $fc, $00, $00, $ff
Reference: $90, $80, $02, $00, $00, $00

...


$fffd (dez.: 65533): *** ERROR:
in RAM...: $82, $c0, $00, $00, $00, $ff
Reference: $90, $ff, $fd, $00, $00, $00

$fffe (dez.: 65534): *** ERROR:
in RAM...: $82, $80, $00, $00, $00, $ff
Reference: $90, $ff, $fe, $00, $00, $00

$ffff (dez.: 65535): *** ERROR:
in RAM...: $81, $80, $00, $00, $00, $ff
Reference: $90, $ff, $ff, $00, $00, $00

OK: [0, 1, 2, 127, 128, 129, 254, 255, 256, 32766, 32767]
Failed: [32768, 32769, 32770, 65533, 65534, 65535]
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: How does the floating point math package in BASIC work?

Post by jedie »

I think it's time to try a division...

I searched for "divide" in simle6809 ROM Listing. The interesting ones seems:

$edcb: DIVIDE FPA0 BY 10
$edda: DIVIDE FPA1 BY FPA0 - Here i can use $eea8 to transfer FPA0 to FPA1
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
User avatar
JeeK
Posts: 67
Joined: Fri Aug 16, 2013 10:45 am
Location: Vienna, Austria
Contact:

Re: How does the floating point math package in BASIC work?

Post by JeeK »

jedie wrote: [..]
I have also add a special case handling, if value==0, see: https://github.com/jedie/DragonPy/commi ... d5f4a60d28

Now $0-$ff values are the same... :D

Great!
Congrats!
jedie wrote: Next test is with:
$e778 = CONVERT THE VALUE IN ACCD INTO A FLOATING POINT NUMBER IN FPA0
After $7fff is failed:
$0000 (dez.: 0): *** OK
[..]
$7fff (dez.: 32767): *** OK

$8000 (dez.: 32768): *** ERROR:
in RAM...: $90, $80, $00, $00, $00, $ff
Reference: $90, $80, $00, $00, $00, $00
[..]
$ffff (dez.: 65535): *** ERROR:
in RAM...: $81, $80, $00, $00, $00, $ff
Reference: $90, $ff, $ff, $00, $00, $00

OK: [0, 1, 2, 127, 128, 129, 254, 255, 256, 32766, 32767]
Failed: [32768, 32769, 32770, 65533, 65534, 65535]
No wonder, D is taken as signed integer (2-complement)!
As you can see, the sign byte is $FF, so the float is a negative number.

32768 = -32768 0.5*2^16 (hence exp is 16 without bias) and mant. 80 is 0.1 (dec. 0.5)
65535 = -1 ... left to the reader ;)
The dragon on my side: http://klasek.at/hc/dragon/
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: How does the floating point math package in BASIC work?

Post by jedie »

Ah! Really cool, thanks!

With commit https://github.com/jedie/DragonPy/commi ... 3e885ed002 is works, completely!
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
jedie
Posts: 655
Joined: Wed Aug 14, 2013 12:23 pm
Location: germany
Contact:

Re: How does the floating point math package in BASIC work?

Post by jedie »

I tried the ROM routine "DIVIDE FPA0 BY 10".

ROM code is here: https://github.com/jedie/DragonPy/blob/ ... .LST#L3062

My Test code for 5 / 10 is:

Code: Select all

        dividend = 0x5

        self.cpu.accu_d.set(dividend)
        self.cpu_test_run(start=0x0300, end=None, mem=[
            0xBD, 0xE7, 0x78, # JSR   $e778  ; Convert D to a float in FPA0
        ])
        self.assertFPA0(dividend) # Test if value is in FPA0

        setup_logging(log, level=20)
        self.cpu_test_run(start=0x0300, end=None, mem=[
            0xBD, 0xed, 0xcb, # JSR   $edcb  ; DIVIDE FPA0 BY 10
        ])

        self.cpu.memory.ram.print_dump(0x004f, 0x0054) # FPA0
        self.cpu.memory.ram.print_dump(0x005c, 0x0062) # FPA1

The memory dumps:

Code: Select all

Memory dump from $004f to $0054:
	$004f: $80 (dez: 128)    | $4f: *PV FLOATING POINT ACCUMULATOR #0 FPA0 EXPONENT
	$0050: $d0 (dez: 208)    | $50: *PV FLOAT.ACCU #0 FPA0 MANTISSA MS  Most Significant Byte
	$0051: $00 (dez: 0)      | $51: *PV FLOAT.ACCU #0 FPA0 MANTISSA NMS Next Most Significant Byte
	$0052: $00 (dez: 0)      | $52: *PV FLOAT.ACCU #0 FPA0 MANTISSA NLS Next Least Significant Byte
	$0053: $00 (dez: 0)      | $53: *PV FLOAT.ACCU #0 FPA0 MANTISSA LS  Least Significant Byte
	$0054: $00 (dez: 0)      | $54: *PV FLOATING POINT ACCUMULATOR #0 FPA0 SIGN
Memory dump from $005c to $0062:
	$005c: $83 (dez: 131)    | $5c: *PV FLOATING POINT ACCUMULATOR #1 FPA0 EXPONENT
	$005d: $00 (dez: 0)      | $5d: *PV FLOAT.ACCU #1 FPA0 MANTISSA MS  Most Significant Byte
	$005e: $00 (dez: 0)      | $5e: *PV FLOAT.ACCU #1 FPA0 MANTISSA NMS Next Most Significant Byte
	$005f: $00 (dez: 0)      | $5f: *PV FLOAT.ACCU #1 FPA0 MANTISSA NLS Next Least Significant Byte
	$0060: $00 (dez: 0)      | $60: *PV FLOAT.ACCU #1 FPA0 MANTISSA LS  Least Significant Byte
	$0061: $00 (dez: 0)      | $61: *PV FLOATING POINT ACCUMULATOR #1 FPA0 SIGN
	$0062: $00 (dez: 0)      | $62: SIGN OF RESULT OF FLOATING POINT OPERATION

My references values:

Code: Select all

Float value was: 5
	exponent......: dez.: 3 hex: $03
	exponent byte.: dez.: 131 hex: $83
	mantissa value: dez.: 0.625
	mantissa bytes: dez.: [160, 0, 0, 0] hex: $a0, $00, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $83, $a0, $00, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10000011 10100000 00000000 00000000 00000000 00000000

Float value was: 10
	exponent......: dez.: 4 hex: $04
	exponent byte.: dez.: 132 hex: $84
	mantissa value: dez.: 0.625
	mantissa bytes: dez.: [160, 0, 0, 0] hex: $a0, $00, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $84, $a0, $00, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10000100 10100000 00000000 00000000 00000000 00000000

Float value was: 0.5
	exponent......: dez.: 0 hex: $00
	exponent byte.: dez.: 128 hex: $80
	mantissa value: dez.: 0.5
	mantissa bytes: dez.: [128, 0, 0, 0] hex: $80, $00, $00, $00
	matissa-sign..: hex: $00
	binary........: hex: $80, $80, $00, $00, $00, $00
	exponent |            mantissa             | mantissa-sign
	10000000 10000000 00000000 00000000 00000000 00000000

The trace when calling $edcb is here:
https://gist.github.com/jedie/a17def9a40f01e435d72
raw view seems to be better:
https://gist.githubusercontent.com/jedi ... y%2010.asm




Conslusion: I expected the value 0.5 binary $80, $80, $00, $00, $00, $00 in FPA0
But there is: $80, $d0, $00, $00, $00, $00

btw. a python routine to calculate from binary back to float would be helpfull ;)
... too many ideas and too little time ... Related stuff written in Python:
Dragon 32 emulator / PyDC - Python Dragon 32 converter: https://github.com/jedie/DragonPy
DWLOAD server / Dragon-Lib and other stuff: https://github.com/6809
Post Reply