First things first. I have been following The 8-bit Guys dream computer for quite a while now and finally decided that I would like to try my hand on some assembler programming for it.
I grew up with the Commodore 64, but never got beyond BASIC programming on it. Instead I jumped to the PC and went from BASIC to Pascal and later on to C and C++
It turned out it was harder than I thought to get started with assembler programming. First I needed to find a compiler/assember. I ended up with with the ACME Cross-Assembler which can be found here: https://sourceforge.net/projects/acme-crossass/ there are also versions available for Linux/Ubuntu.
Next I needed to learn a bit of assembly language for the 6502 processor and found a great guide here: http://skilldrick.github.io/easy6502/
I was ready. I looked at some of the examples for the Commander X16, saw how to compile and wrote my first assembler program for the Commander X16, or more precisely for the 6502.
ldx #0 ; Load register X with 0 inx ; Increment register X
I compiled the file with acme -f cbm -o test.prg test.asm started the emulator with ./x16emu -prg test.prg and then… Nothing.
I expected there to be some sort of code or something in the emulator, but when I did a LIST, nothing. I knew that RUN would not do anything. Obviously I was missing something. I posted a comment on the Commander X16 Prototype Facebook page asking how to get startet and was told that there are plenty of beginners guides.
After spending quite a lot of time searching through the documentation, the examples and the internet in general, I remembered that I was also a member of the joint forum of The 8-bit guy and The Geek Pub. I thought that maybe there was a bit more information to find there and by chance I saw a post from another new programmer who seemed to have come a bit further than me, so I asked him for help and he provided a great first example.
I compiled his example, loaded it into the emulator and… Still nothing. When I did a LIST, it showed nothing and RUN did not do anything. I startet writing a long reply to him, but the page updated and I saw his addition of how to actually run the program.
Suddenly all these memories started rolling in and things startet clicking into place. I remembered loading games on the C64, doing a LIST and seeing just a single line. I remembered that I was baffled as how an entire game could be contained in a single short line. A bit of looking around on the internet gave me the answer. BASIC programs can be startet with the RUN command, but assembler/binary programs needs to be started with the SYS command, telling it where in memory the program is located. Still, this program did not show anything when doing LIST.
The post is about the Commodore 64 and it made me remember that the official documentation for the Commander X16 states that it supports the C64 Kernal API. VincentF’s example had already showed me how to call an API function so I started searching for some documentation of the C64 Kernal API and found some here.
UPDATE: I have made my own list of C64 KERNAL functions. Find it on my new cx16 domain.
Finally I was ready to write my own “Hello, World!”-Example, and here it is:
*=$0801 ; Assembled code should start at $0801 ; (where BASIC programs start) ; The real program starts at $0810 = 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" ; (ASCII encoded nums for dec starting addr) !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) *=$0810 ; Here starts the real program CHROUT=$FFD2 ; CHROUT outputs a character (C64 Kernal API) CHRIN=$FFCF ; CHRIN read from default input ldx #0 ; X register is used to index the string loop: lda .string,x ; Load character from string into A reg beq end ; If the character was 0, jump to end label jsr CHROUT ; Output character stored in A register inx ; Increment X register jmp loop ; Jump back to loop label to print next char end: jsr CHRIN ; Read input until Enter/Return is pressed rts ; Return to caller .string !pet "hello, world!!",13,0
I hope that this will be able to help other newcomers understand how to write assembly programs for the 6502/Commodore 64/Commander X16. If anything at all is unclear or there are any questions, please do not hesitate to write a comment or contact me directly.