Assembler access to floating-point math functions

All aspects of programming on the Commander X16.
Post Reply
Bill Leue
Posts: 20
Joined: Thu Sep 08, 2022 5:52 pm

Assembler access to floating-point math functions

Post by Bill Leue »

If one is coding a program in assembler, is there a standard way to access floating-point math functions? That it, can one initialize a memory location to have a floating-point value, do 4-function math operations, and access library functions such as trig functions, abs(), int(), and so on?
-Bill
vermiceli
Posts: 1
Joined: Tue Jan 02, 2024 7:37 pm

Re: Assembler access to floating-point math functions

Post by vermiceli »

You should be able to take a look at the documentation around X16 Reference - 05 - Math Library.md. There is a section, called "How to use the routines", with an example in assembly. You can see that abs() is $FE4E, int() at $FE2D, etc.
SolarSurfer
Posts: 30
Joined: Sun Nov 26, 2023 2:18 am

Re: Assembler access to floating-point math functions

Post by SolarSurfer »

You might also find this post: https://www.commanderx16.com/forum/viewtopic.php?t=889

and the source materials mentioned in the linked github repo quite helpful.
Bill Leue
Posts: 20
Joined: Thu Sep 08, 2022 5:52 pm

Re: Assembler access to floating-point math functions

Post by Bill Leue »

Thanks to vermiceli and SolarSurfer! Those posts are very helpful.
-Bill
SolarSurfer
Posts: 30
Joined: Sun Nov 26, 2023 2:18 am

Re: Assembler access to floating-point math functions

Post by SolarSurfer »

I've started to play around with the C128 math routines myself, but I've immediately hit a roadblock. I wanted to see if I could load the FACC with the equivalent of value 10, then ask it to convert to an integer. Per the C128 documentation, FACC starts at address $63 and is 6 bytes long. And it says the "AYINT" method is at $AF00 ... so I wrote this:

Code: Select all

    lda #'x'
    jsr $FFD2

    lda #$84   ; load 84A0000000 into FACC
    sta $63    ; store value $84 to EXP
    lda #$A0
    sta $64    ; store value $A0 to FACHO
    stz $65    ; store zero to FACMOH
    stz $66    ; store zero to FACMO
    stz $67    ; store zero to FACLO
    stz $68    ; store zero to SIGN
    jsr $AF00

    lda #'x'
    jsr $FFD2
and ran it in the emulator (R45). I was expecting to see "xx" displayed on the screen. That would prove to me that whatever $AF00 does, it did it.

But instead I one of three outcomes:

1) It prints an "x" and then seems to hang
2) the screen clears and I get a dump of registers, similar to below (the values are different every time)

Code: Select all

B*
   PC  RA RO AC XR YR SP NV#BDIZC
.;BB69 01 04 FF 07 08 EF *.**....
.
3) the debugger opens on the right-hand side

I checked ZP addr $01 before running my program and it is set to $04 ... so, ROM bank 4 is selected. What am I doing wrong?


EDIT: I forgot to mention ... I'm a bit skeptical of the C128 documentation, given that for the FOUT routine ($AF06) it says the result is "$0100 contains ASCII string (null terminated)" ... but $0100 is our stack! Why would this routine clobber the stack? I'm confused.
DragWx
Posts: 342
Joined: Tue Mar 07, 2023 9:07 pm

Re: Assembler access to floating-point math functions

Post by DragWx »

Two things: first, the C128 manual is only useful for its description of what each routine does and what its parameters and output are. Please ignore any memory addresses it points out; use the X16 documentation for that instead.

Second, the X16 documentation also states that the exact memory location of FACC cannot be guaranteed and that it's better to use various math library functions (such as GIVAYF, MOVFM, MOVMF) to move data into and out of FACC (and ARG) instead of poking it directly. Case in point, on the X16, FACC currently lives at $61 and not $63. Using the library functions guarantees that future Kernal updates won't break your code by moving FACC again.



About the stack, the 6502's stack starts at $01FF and grows towards $0100. There no problem with putting variables in the stack page as long as (1) they're kept closer to $0100 and (2) the program is careful never to grow the stack so large as to overlap with the variables. As a fun fact, the Atari 2600 only had 128 bytes of RAM, so the stack and program variables were forced to occupy the same space, and the programmer just had to be careful not to grow the stack too large.
SolarSurfer
Posts: 30
Joined: Sun Nov 26, 2023 2:18 am

Re: Assembler access to floating-point math functions

Post by SolarSurfer »

Thanks for clarifying.

I don't know about everyone else, but when it says "The full documentation of these functions can be found in the book ..." it is my assumption that I should stop what I'm doing and read the cited material ... and that it would fully document everything I need to know. Personally, I would not expect that I should keep reading to find out all the ways in which the cited material is not actually the full documentation.

(I'm not complaining ... CX16 has a LOT of good documentation! Perhaps I am too robotic in my consumption of it)

I suggest a slightly different wording. Instead of
The full documentation of these functions can be found in (blah blah)
it could say something like
For context, the original full documentation of these functions can be found in (blah blah). However, the CX16 implementation has significant differences, discussed below.
Then (at least for me) I'd know to just read that documentation as a background education, then continue reading the CX16 doc to see how to actually make all the calls.
SolarSurfer
Posts: 30
Joined: Sun Nov 26, 2023 2:18 am

Re: Assembler access to floating-point math functions

Post by SolarSurfer »

Good news, I'm now able to do a ton of stuff with floating points ... now using the C128 doc only as added historical insight :)

I'm hitting a problem with VAL_1 though ... the documentation is clear enough: .A holds the length, and .X & .Y hold the address of the string. But, when I run my code, the emulator crashes.

Using the emulator's debug mode, I stepped into the "jsr $FE09" call, and it takes me to some weird disassembly. I used the debugger to view FE00 in bank 4 and it looks like a big jump table but the offsets FE09,FE0A,FE0B are all zero.

So it seems VAL_1 is a missing entry in the jump table. I didn't see it called out in the ROM release notes, so maybe this is a bug or oversight?

There's an open issue related to VAL_1 but it's described as a reminder to eventually refactor the implementation, which implies that it should be functional, just not optimal. https://github.com/X16Community/x16-rom/issues/240
DragWx
Posts: 342
Joined: Tue Mar 07, 2023 9:07 pm

Re: Assembler access to floating-point math functions

Post by DragWx »

You're right, the official r46 release does not contain an implementation for VAL_1.

But, as you saw, an implementation has been added since then. To get the latest snapshot of the ROM, go to the ROM repo on Github, click "actions", click a recent commit, scroll to "artifacts" and click "rom image" to download.

I'm sorry about everything seeming so incomplete, but this is what it's like to work with something that's still under active development, and it's very helpful when somebody is trying to use a feature and is finding where the flaws are. :D
Post Reply