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
Assembler access to floating-point math functions
Re: Assembler access to floating-point math functions
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.
-
- Posts: 30
- Joined: Sun Nov 26, 2023 2:18 am
Re: Assembler access to floating-point math functions
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.
and the source materials mentioned in the linked github repo quite helpful.
Re: Assembler access to floating-point math functions
Thanks to vermiceli and SolarSurfer! Those posts are very helpful.
-Bill
-Bill
-
- Posts: 30
- Joined: Sun Nov 26, 2023 2:18 am
Re: Assembler access to floating-point math functions
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:
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)
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.
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
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 *.**....
.
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.
Re: Assembler access to floating-point math functions
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.
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.
-
- Posts: 30
- Joined: Sun Nov 26, 2023 2:18 am
Re: Assembler access to floating-point math functions
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
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
it could say something likeThe full documentation of these functions can be found in (blah blah)
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.For context, the original full documentation of these functions can be found in (blah blah). However, the CX16 implementation has significant differences, discussed below.
-
- Posts: 30
- Joined: Sun Nov 26, 2023 2:18 am
Re: Assembler access to floating-point math functions
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
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
Re: Assembler access to floating-point math functions
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.
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.