• 0

# Floating Point Library example?

## Question

Does anyone have any examples of the built in floating point library in ASM?

I'm completely lost. haven't programmed any ASM in 25 years, and that was in DOS.

## Recommended Posts

• 0
Posted (edited)

What are you trying to accomplish? Isn’t it possible with fixed point math perhaps?

In any case, prog8 for instance  uses those kernal floating point routines for its float calculations.  If you’re not familiar with assembly programming it will be a large hurdle to grasp how it works. But essentially it revolves around loading FAC1 and possibly FAC2 with aa value, calling one of the float math functions, and converting FAC1 (which will usually contain the result) back to a number or string somewhere. FAC1 and FAC2 are internal floating point variables stored somewhere in ram.  It’s quite tedious to write this code by hand especially for complex calculations...

i can add a tiny example that adds 2 numbers later if you really want to pursue this

Edited by desertfish
##### Share on other sites

• 0
On 1/2/2022 at 9:30 PM, desertfish said:

What are you trying to accomplish? Isn’t it possible with fixed point math perhaps?

i can add a tiny example that adds 2 numbers later if you really want to pursue this

I would like to get cc65-floatlib to work on x16.

I'd very much like an example.

Currently I've tried to piece together an example to FMUL a float and print it:

.org \$080D
.segment "STARTUP"
.segment "INIT"
.segment "ONCE"
.segment "CODE"

jmp start

;Kernal
GETIN             = \$FFE4

;Float
FAC1              = \$61
FACEXP1       = \$61
FACHO1         = \$62 ; -\$65
FACSGN1       = \$66
SGNFLG1       = \$67
BIT1                = \$68

FMULT            = \$FE27 ;FAC *= mem(.Y:.A)
FOUT               = \$FE7B  ;Convert FAC to ASCIIZ string at fbuffr
GIVAYF2         = \$FE03 ;FAC = (s16).A:.Y

CHAR_Q          = \$51

mstring:           .res 32

; global data

start:
lda #04
sta \$9f61 ; ROM BANK 4

;load floating point number into FAC1
LDA <L1
LDY >L1
JSR GIVAYF2

JMP L2
L1:
.byte "\$87 \$48 \$00 \$00 \$00",0
L2:

LDY <L1
LDA >L1

jsr FMULT

LDA <mstring
LDY >mstring
;jsr FOUT

LDY #\$00
L3:
LDA mstring,Y
CMP #0
BEQ L4
JSR \$FFD2
INY
JMP L3
L4:
;jsr \$FFD2
@main_loop:
wai
jsr GETIN
cmp #CHAR_Q
bne @main_loop
rts

But whenever I uncomment FOUT the program crashes

##### Share on other sites

• 0

You'll have to make sure you're using the correct addresses of those kernal routines for the given emulator/rom revision you are using. They have changed from r38 to r39. It seems that you are using the r39 addresses on a r38 target?

The documentation in the master branch of the github repo shows the r39 state of affairs.

Here is the r38 one https://github.com/commanderx16/x16-rom/blob/r38/fplib/fplib.inc

##### Share on other sites

• 0
On 1/2/2022 at 10:53 PM, desertfish said:

You'll have to make sure you're using the correct addresses of those kernal routines for the given emulator/rom revision you are using. They have changed from r38 to r39. It seems that you are using the r39 addresses on a r38 target?

The documentation in the master branch of the github repo shows the r39 state of affairs.

Here is the r38 one https://github.com/commanderx16/x16-rom/blob/r38/fplib/fplib.inc

As far as I can tell the only address that was different was FOUT.

After changing it, my program no longer crashes, but still it doesn't print any characters.

The documentation says: fout = \$fe81 ; Convert FAC to ASCIIZ string at fbuffr
What is "fbuffr"?

I know it's a big task. My expertise is in C/C++

But I hope that by gaining a basic understanding of the Float Lib in asm, I might get floatlib to work with x16. Currently I can compile floatlib code, but if I try to actually do something with floats, the program crashes.

##### Share on other sites

• 0

for FOUT, 'fbuffr' is probably the name of the internal basic string buffer it uses.  Don't try to access it directly, instead, use the fact that FOUT returns the address of it in the A and Y registers. Store that somewhere and read the characters using that pointer.

##### Share on other sites

• 0
On 1/2/2022 at 11:27 PM, desertfish said:

for FOUT, 'fbuffr' is probably the name of the internal basic string buffer it uses.  Don't try to access it directly, instead, use the fact that FOUT returns the address of it in the A and Y registers. Store that somewhere and read the characters using that pointer.

That's were my assembly knowledge falls short.

My current code is:

LDY #\$00
L3:
LDA mstring,Y
CMP #0
BEQ L4
JSR \$FFD2
INY
JMP L3
L4:

How would I change that to an address in A.:.Y ?

##### Share on other sites

• 0
Posted (edited)

Here's a piece of code that adds two floating point numbers 1.11 and 1.22 and prints the result 2.33.   Note that \$7e/\$7f are just 2 zero page locations free for user programs.

lda  #<float5_111
ldy  #>float5_111
jsr  floats.MOVFM
lda  #<float5_122
ldy  #>float5_122
jsr  floats.FOUT
sta  \$7e
sty  \$7f
ldy  #0
_loop
lda  (\$7e),y
beq  _done
jsr  c64.CHROUT
iny
bne  _loop
_done
rts

float5_111    .byte  \$81, \$0e, \$14, \$7a, \$e1  ; float 1.11
float5_122    .byte  \$81, \$1c, \$28, \$f5, \$c2  ; float 1.22

But this piece of your code above doesn't look correct too:

L1:
.byte "\$87 \$48 \$00 \$00 \$00",0

Edited by desertfish
##### Share on other sites

• 0
Posted (edited)
On 1/2/2022 at 3:37 PM, Dacobi said:

That's were my assembly knowledge falls short.

My current code is:

LDY #\$00
L3:
LDA mstring,Y
CMP #0
BEQ L4
JSR \$FFD2
INY
JMP L3
L4:

How would I change that to an address in A.:.Y ?

The easiest way would be to store A & Y in a zero page pointer that you can use to index indirect.

ZPPTR = \$42 ; whatever address in ZP
STY ZPPTR+0
STA ZPPTR+1
LDY #\$00
L3:
LDA (ZPPTR),Y
BEQ L4 ; You don't have to compare with 0 first, load will set zero flag for you
; the rest goes here

Edit: assuming I'm understanding the question and that A has the high byte and Y has the low byte.

Edited by Scott Robison
##### Share on other sites

• 0
On 1/2/2022 at 11:42 PM, desertfish said:

Here's a piece of code that adds two floating point numbers 1.11 and 1.22 and prints the result 2.33.   Note that \$7e/\$7f are just 2 zero page locations free for user programs.

...

But this piece of your code above doesn't look correct too:

L1:
.byte "\$87 \$48 \$00 \$00 \$00",0

Thanks  got it working. But it seems you are using another assembler? I could only get it to compile by adding : after definitions. (ie float5_111:)

Also the programming reference said to select ROM BANK 4 but that doesn't seem to be necessary?

The L1: code was something I found online. Still haven't figured out how to format a float.

##### Share on other sites

• 0
On 1/2/2022 at 9:30 PM, desertfish said:

It’s quite tedious to write this code by hand especially for complex calculations...

I'm trying to port some C code that uses a lot of floating point math, so when I came over the cc65 floatlib I thought my troubles were over.

But looking at https://github.com/mrdudz/cc65-floatlib/blob/master/float.inc there seems to be some difference between which calls are used.

I would just really like to have the code running before trying to do any assembler optimisations.

##### Share on other sites

• 0

I just installed Prog8 and I think it might be helpful.

If nothing else it will help me learn the assembly syntax.

##### Share on other sites

• 0

For prog8 I'm using 64tass as the backend assembler , which uses a TurboAssembler derived syntax.

##### Share on other sites

• 0
Posted (edited)
On 1/2/2022 at 6:00 PM, Dacobi said:

... But it seems you are using another assembler? I could only get it to compile by adding : after definitions. (ie float5_111:)

Old school (1970s era) l assemblers often required a location label to end with a ":" to distinguish it from a value define by an equate ... it seems like most newer assemblers make the ":" optional and work out whether it's an equate or a location from the context.

However, standardization of assembler syntax is more about what people are used to than having an explicit standard to follow, so YMMV.

I always include the ":" ... that's more from habit than from any view on whether it is "best practice".

Edited by BruceMcF

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.