Jump to content
SlithyMatt

"Hello, World!" with cc65

Recommended Posts

This may be a dumb question. In the assembler tutorial, the code starts at address $80D, which is in the BASIC memory that starts at $800, according to the documentation. Why does the program start at that address? To prevent clashes with the LOAD "HELLOASM.PRG" , which may still be in the BASIC memory?

And also, how does the BASIC interpreter know, when typing RUN, where to jump?

Thanks BTW for the great content to help beginners with setting up everything for Development on the X16!

Edited by kliepatsch

Share this post


Link to post
Share on other sites

I think both of your questions are answered at the same time:

The assembly code starts at $080d  (2061 decimal) so that it leaves enough room to put a tiny one liner basic program before it, starting at the usual $0801.

The basic program is just   10  SYS 2061     -- so when you type RUN , the first thing basic does is doing the SYS into the assembly routine starting at 2061 that then takes over

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Sounds like you have it figured out. The SYS call needs to be loaded with the rest of the program. You could always load it anywhere and do the SYS call yourself, but just typing LOAD and RUN is a lot easier! 🙂

  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you very much. I did the listing and got indeed

Quote

800 SYS2061

just like you mentioned. To me, the 2061 still seems like a magic number. Where does it come from?
With a hex editor, I see that the .PRG file is loaded at $801 and that this BASIC program is actually included in the binary file. Therefore it must stem from the assembler.
I assume that there should be a possibility to define what's at the start of the file. But I couldn't find it anywhere in the config files for the X16 (I mean cc65 config files).

Is this (i.e. the "SYS2061" at the start) the default behaviour if cc65 compiles for the X16?

Edited by kliepatsch

Share this post


Link to post
Share on other sites

I did a little more research and it seems to be common practice to put the SYS2061 command in front of machine code programs. Not only on the X16 but even on the C64.

Well, I think I can accept that it is like this for now, as I don't have a good reason to not make use of this convenient auto-starter 😉

Thanks @desertfish and @SlithyMatt again for the explanations.

Share this post


Link to post
Share on other sites
2 hours ago, kliepatsch said:

. To me, the 2061 still seems like a magic number. Where does it come from?

 

2061 = $080D

It's simply the start of the machine language program. Before that is just tokenized BASIC and the CPU would choke trying to run that directly, instead of with the BASIC interpreter.

Share this post


Link to post
Share on other sites
45 minutes ago, SlithyMatt said:

2061 = $080D

It's simply the start of the machine language program. Before that is just tokenized BASIC and the CPU would choke trying to run that directly, instead of with the BASIC interpreter.

My hello.asm does a byte by byte commentary on these magic numbers before your assembly code:

Quote

 

;
; cl65 -o hello2.prg -t cx16 -C cx16-asm.cfg hello2.asm
;
; Also, you should count on CHROUT modifying X, so you should flank that jsr with phx and plx.
; Run with x16emu.exe -prg hello2.prg -run -scale 2

    .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

    CHROUT = $FFD2

    ldx #0
again:
    lda hello, x
    cmp #0
    beq done
    stx SaveX
    jsr CHROUT
    ldx SaveX
    inx
    jmp again
done:
    rts
SaveX: .byte 0
hello:
    .byte   "hello world! ", $00

 

Enjoy!

  • Like 1

Share this post


Link to post
Share on other sites
On 10/10/2020 at 11:18 PM, SlithyMatt said:

You can lose that CMP #0 instruction. It's unnecessary. The LDA before already sets the Z bit the exact same way.

Point noted, just as the stx/ldx SaveX could be replaced by the most efficient phx/plx to save a few bytes more. Sometimes a more verbose code explains better than an efficient code 😉 Efficient code sometimes look like magic!

Share this post


Link to post
Share on other sites

I can't get hello world to work.  I'm running ubuntu 20 and compiled cc65.

When I make I get the following:

(base) rick@rick:~/workspace/x16-hello-cc65$ make
make -C asm
make[1]: Entering directory '/home/rick/workspace/x16-hello-cc65/asm'
cl65 -t cx16 -o HELLOASM.PRG -l hello.list hello.asm
ld65: Error: Cannot find config file 'cx16.cfg'
make[1]: *** [Makefile:4: all] Error 1
make[1]: Leaving directory '/home/rick/workspace/x16-hello-cc65/asm'
make: *** [Makefile:2: all] Error 2

I have cc65/bin in my path. I suspect I need to hack the make file to point to configs.

Share this post


Link to post
Share on other sites

What's the performance penalty of using cc65 C over pure assembly?  Have to admit would like to rapid prototype in C w/o the assembly albatross.  Would you say cc65 C is 2x slower?  It certainly can't be worse than basic 2.0.

Edited by MontyHall

Share this post


Link to post
Share on other sites
1 hour ago, MontyHall said:

What's the performance penalty of using cc65 C over pure assembly?  Have to admit would like to rapid prototype in C w/o the assembly albatross.  Would you say cc65 C is 2x slower?  It certainly can't be worse than basic 2.0.

Just don't do a printf() version of "Hello, World!" That'll generate a binary of at least 2,000 bytes! Use CHROUT or STROUT instead with assembly or C using a specific X16 library.

Share this post


Link to post
Share on other sites
1 hour ago, MontyHall said:

I have cc65/bin in my path.

You need other directories defined as well... here's my Windows batch file I run before compiling with cc65:

Quote

set CC65_HOME=c:\cc65
set CA65_INC=c:\cc65\asminc
set CC65_INC=c:\cc65\include
set LD65_LIB=c:\cc65\lib
set LD65_CFG=c:\cc65\cfg
set LD65_OBJ=c:\cc65\obj
set PATH=%PATH%;c:\cc65\bin

 

Share this post


Link to post
Share on other sites
3 hours ago, MontyHall said:

I can't get hello world to work.  I'm running ubuntu 20 and compiled cc65.

When I make I get the following:

(base) rick@rick:~/workspace/x16-hello-cc65$ make
make -C asm
make[1]: Entering directory '/home/rick/workspace/x16-hello-cc65/asm'
cl65 -t cx16 -o HELLOASM.PRG -l hello.list hello.asm
ld65: Error: Cannot find config file 'cx16.cfg'
make[1]: *** [Makefile:4: all] Error 1
make[1]: Leaving directory '/home/rick/workspace/x16-hello-cc65/asm'
make: *** [Makefile:2: all] Error 2

I have cc65/bin in my path. I suspect I need to hack the make file to point to configs.

You shouldn't have to do that. cl65 should automatically look in ../cfg relative to the executable for the config file. Make sure it's still there, and that you are using the cc65 you built. Do a "which cl65" and see what comes up. If you have another cc65 toolchain in your path, that could mess things up, especially if that one doesn't have cx16 support built in. Worst case, if you can't figure out what's wrong, you can explicitly point to cx16.cfg by using the -C option with cl65.

Share this post


Link to post
Share on other sites

This is what I get when I "which cl65": /home/rick/workspace/cc65/bin/cl65.   

 

Yeah, I don't know what's going on.  I'll just hack the make file.  but I think I'll try the env vars first.

 

EDIT: I tried the exports, no luck.  I guess I'll hack the make file.

 

 

Edited by MontyHall

Share this post


Link to post
Share on other sites

Thanks, looks like -C ${HOME}/workspace/cc65/cfg/cx16.cfg work.  too bad that it has to be so verbose, but at least I can get moving.

 

Thanks

 

  • Like 1

Share this post


Link to post
Share on other sites
23 minutes ago, Greg King said:

Please try an experiment.  Execute this command:


cl65 --print-target-path

Does it show "/home/rick/workspace/cc65/target"?

For @MontyHall:

cl65-path.PNG.5d58f5e226b6b297fa0cab244f836954.PNG

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use