"Hello, World!" with cc65

Chat about anything CX16 related that doesn't fit elsewhere
geek504
Posts: 95
Joined: Wed Aug 26, 2020 4:52 pm

"Hello, World!" with cc65

Post 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



 

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

"Hello, World!" with cc65

Post 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.

User avatar
desertfish
Posts: 1096
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

"Hello, World!" with cc65

Post 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?

geek504
Posts: 95
Joined: Wed Aug 26, 2020 4:52 pm

"Hello, World!" with cc65

Post 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!

User avatar
desertfish
Posts: 1096
Joined: Tue Aug 25, 2020 8:27 pm
Location: Netherlands

"Hello, World!" with cc65

Post 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

geek504
Posts: 95
Joined: Wed Aug 26, 2020 4:52 pm

"Hello, World!" with cc65

Post 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:

spacer.pnghello.thumb.PNG.4c165c270ba342a10808d0492c27fc66.PNG

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.

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

"Hello, World!" with cc65

Post 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?

 

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

"Hello, World!" with cc65

Post 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

rje
Posts: 1263
Joined: Mon Apr 27, 2020 10:00 pm
Location: Dallas Area

"Hello, World!" with cc65

Post by rje »


Good enough, for now... gettime() of course returns the epoch timestamp.  Eventually I would like to call $ff50 directly.

Ender
Posts: 220
Joined: Sat May 09, 2020 9:32 pm

"Hello, World!" with cc65

Post 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...

Post Reply