Page 7 of 8
"Hello, World!" with cc65
Posted: Sun Oct 18, 2020 2:42 am
by geek504
52 minutes ago, Ender said:
Oh cool, well if you already have an example of how to use it, then it's worth a try. You'd just change the definition of STROUT to $CD52, and make sure to change the ROM bank to 4 first.
Yay, it works! How did you figure out the ROM address for STROUT from code7.s? Hex string search or an easier way?
Quote
;
; cl65 -o hw.prg -t cx16 -C cx16-asm.cfg hw.asm
;
; Run with x16emu.exe -prg hw.prg -run -scale 2
;
; hw.s: example using BASIC ROM routine to output a string
.org $0801 ; Assembled code should start at $0801
; (where BASIC programs start)
; The real program starts at $0810 = 2064
; 10 SYS 2064
.byte $0C, $08 ; $080C - pointer to next line of BASIC code
.byte $0A, $00 ; 2-byte line number ($000A = 10)
.byte $9E ; SYS BASIC token
.byte $20 ; [space]
.byte $32, $30, $36, $34 ; $32="2",$30="0",$36="6",$34="4"
.byte $00 ; End of Line
.byte $00, $00 ; This is address $080C containing
; 2-byte pointer to next line of BASIC code
; ($0000 = end of program)
.byte $00, $00 ; Padding so code starts at $0810
STROUT = $CD52 ; BASIC in ROM BANK #4
VIA1 = $9F60 ; PB0-2 = 0-7
LDA #4
STA VIA1
LDA #<msg
LDY #>msg
JMP STROUT
LDA #0
STA VIA1
RTS
msg:
.byte "hello world! ", 0
"Hello, World!" with cc65
Posted: Sun Oct 18, 2020 6:06 am
by Ender
3 hours ago, geek504 said:
Yay, it works! How did you figure out the ROM address for STROUT from code7.s? Hex string search or an easier way?
If you've compiled the rom, it creates .sym files in "build/x16" for each module that has all the labels and their addresses. So if you look in "build/x16/basic.sym" there's one for strout.
"Hello, World!" with cc65
Posted: Sun Oct 18, 2020 11:06 am
by desertfish
Personally, I just wrote my own little strout routine that only uses the CHROUT kernal routine at its documented location. It's only a few instructions long. Any reason you really want to use basic's STROUT?
"Hello, World!" with cc65
Posted: Sun Oct 18, 2020 4:10 pm
by geek504
4 hours ago, desertfish said:
Personally, I just wrote my own little strout routine that only uses the CHROUT kernal routine at its documented location. It's only a few instructions long. Any reason you really want to use basic's STROUT?
Mainly because I was thinking about economy of code, if it already exists in ROM, why not use it? Floating-point math also comes to mind.
But you're right, it's probably easier and much more compact to write our own PRINT function. I was already certain that a library would exist in HIGH RAM for my other functions such as 32-bit fixed-point math and Woz's 32-bit floating-point math.
The real reason I did it was because it's another way of doing HELLO WORLD and I learned a thing or two doing it!
"Hello, World!" with cc65
Posted: Mon Oct 19, 2020 10:25 am
by desertfish
About the floating point math routines, yeah I gladly use the ROM for that. I happily assumed the Cx16 has a proper documented fixed jump table for them (
https://github.com/commanderx16/x16-rom/blob/0ebe2ab1556a0c46df41e5894ccae9b776c8a6a7/fplib/fplib.inc) but perhaps this is still subject to change for newer ROM versions? I hope not
? On the C64 we jump straight into BASIC ROM somewhere... but these won't change anymore
"Hello, World!" with cc65
Posted: Tue Oct 20, 2020 1:11 am
by geek504
I'm happy to share a preview of my INTEGER BASIC compiler written in Python using Lark for lexer and parser. Below shows the BASIC "hello world" program, followed by the AST, and the compiled code. Note the use of the virtual ABI r0 register to pass the string pointer to the PRINT routine:
Hmm... that "CMP #0" in the PRINT routine can now vanish... forgot about it! As a matter of fact, "PHX" and "PLX" should be changed because I replaced the index from X-reg to Y-reg for (indirect), Y addressing mode.
"Hello, World!" with cc65
Posted: Thu Nov 12, 2020 5:23 am
by rje
While we're talking about CC65...
I'm writing some C code, but I'd like to call $FF50 -- which is the X16's "gettime" extended KERNAL routine. It dumps time into the first five (or so) pseudo-registers in zero page, and that's useful to me.
But, for the life of me, I can't figure out (or remember) how to call that sub. So I shove it in a variable, cast that to a function pointer, and call it? I can't do that, because it's not a C function. So..... how?
"Hello, World!" with cc65
Posted: Thu Nov 12, 2020 6:14 am
by Ender
48 minutes ago, rje said:
While we're talking about CC65...
I'm writing some C code, but I'd like to call $FF50 -- which is the X16's "gettime" extended KERNAL routine. It dumps time into the first five (or so) pseudo-registers in zero page, and that's useful to me.
But, for the life of me, I can't figure out (or remember) how to call that sub. So I shove it in a variable, cast that to a function pointer, and call it? I can't do that, because it's not a C function. So..... how?
Greg King is the expert on this, but it looks like you can call clock_gettime()
Quote
int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp);
The code for it is here
https://github.com/cc65/cc65/blob/master/libsrc/cx16/gettime.s
"Hello, World!" with cc65
Posted: Mon Nov 16, 2020 2:16 pm
by rje
Good enough, for now... gettime() of course returns the epoch timestamp. Eventually I would like to call $ff50 directly.
"Hello, World!" with cc65
Posted: Mon Nov 16, 2020 3:09 pm
by Ender
58 minutes ago, rje said:
Good enough, for now... gettime() of course returns the epoch timestamp. Eventually I would like to call $ff50 directly.
Well, you can also set the time
? Unfortunately with the emulator, it forgets the date and time every time you close it and open it again.
Quote
int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp);
https://github.com/cc65/cc65/blob/master/libsrc/cx16/settime.s Actually, that seems like a pretty doable feature for the emulator, to set the date and time when you start it to emulate a RTC...