C64 Assembly Tutorial 1: Hello World

Yes, that’s right I’m on about assembly programming for the Commodore 64, a computer that’s nearly 30 years old. You may be wondering why I would want to learn how to program for such a machine, well the first reason is that I want to learn assembly and there are many C64 assembly books around. The second reason is that I want to see what I can do with it and more about the lower level hardware and how to control it.

Getting Started

First things first, unless you have an actual C64, you’ll need an emulator to run the programs you’re creating. I’m using VICE, but there are plenty of different emulators around. Next you’ll need an assembler, I’m using dasm that supports the 6502 processor plus several others. It is available from the project page http://dasm-dillon.sourceforge.net/

If you’re using a mac, after you’ve installed dasm, you can create an alias to dasm by entering ‘_open -a TextEdit -/.bashprofile’ in the terminal and then adding this line ‘alias dasm=“/path/dasm”’ where path is the path to your install of dasm. This means that you’ll only have to enter dasm rather than the full file path when you want to assemble your programs.

Hello World

So now we’ve got the emulator and the assembler we can actually get on with some code, below is code to display the text ‘Hello World’ on the screen. This may seem simple but it’s using loops, labels, branches and sub-routines, I’ll run through the code after.

Ok so first the line ‘_processor 6502’ _just tells dasm what processor we want to compile for the 6502 processor. (The C64 used a 6510 processor, however this is just a modified version of the 6502). The next line is where we want to store the program in memory as hexadecimal, I’ve placed it an used area of memory that has 4096 bytes free. If you change this be careful where you put it as a large amount of the memory is already being used for specifc purposes. There is a memory map for the C64 available at http://sta.c64.org/cbm64mem.html that gives details of what each section of memory does.

The C64 comes with a number of very useful sub routines that can be called from within your assembly program and in lines 9 and 10 we’re setting up some labels to two of these sub routines. The first labeled ‘CLEAR’ clears the screen goes to the hexadecimal address (noted by the $) E544, and the second ‘CHROUT’ pointing to the address FFD2, outputs a character stored in the A registor to the next position in the screen.

The next lines are where the program gets started, first we call the _CLEAR _subroutine by using JSR, this stands for ‘jump to subroutine’ and will execute the routine at the given address and return. Next we load the X registor with the decimal value 0 (denoted by the #) .

Before we move onto the next section of code I will explain how we can store the text “Hello World” in assembly to output. There are several ways to do it, we could for example put the code for the character ‘H’ in the A registor and then output using CHROUT, and then put the character code for ‘E’ in the A registor and use CHROUT to output this and so on…Indeed this is exactly how the code here works.

This may be fine for small amounts of text, but will soon get tiring after a while. Luckily there’s a pseudo-opcode available called _.BYTE _that allows us to define a string with each character in the string taking up a single byte. By giving it a label and using a registor as an index we can loop through the message displaying each character to the screen. The label ‘MSG’ actually points to the address of the first character in the string, in this case ‘H’. You may be wondering why we have the ‘#’ character at the end of the string when we don’t want to display this, well we’ll be using this as a termination character so we know when to stop looping through the string.

Now back to the code that will loop through the string and display it on line 15. I have given the first instruction a label ‘READ’ this is just so we know where to jump to for the next iteration of the loop. The actual instruction ‘LDA MSG,X’ loads the A registor with the value that is given by address denoted with the label MSG plus an offset value in the X registor. In the first iteration of the loop we have loaded X with 0, and so A will be the value at the address of MSG+0, in this case ‘H’.

In lines 17 and 18 we first use ‘CMP #35’ to compare the value stored in the A registor against the decimal character code for the ‘#’ character. If it’s equal we then use ‘BEQ END’ to branch to the END label where the routine ends. If it’s not equal then we haven’t reached the end of the message and we display the current character in the A registor using ‘JSR CHROUT’. We then increase the index in X so that the next iteration of the loop will move to the next character in the message. Finally we do an unconditional jump back to the ‘READ’ label to continue the loop and display the next character.

Executing the code

To run the code you’ll need to assemble it using dasm, if you have set an alias to it then the command will look like this:

dasm HelloWorld.asm -oHelloWorld.prg

Next, open HelloWorld.prg in VICE, or whatever emulator you’re using and then type in ‘SYS 49152’. (49152 or C000 in hex is where we’ve placed the code in line 6) . If all goes well you should see the below image with ‘HELLO WORLD’ displayed on the screen.

Helloworld After

It might not do much, but we’ve used quite a few features of assembly in our code, including jump, increment, branches, comparisons and I hope it’s given a bit of a help for anyone who wants to start learning assembly for the C64. In the second tutorial I’ll show how to do sprites and explain how to retrieve keyboard input to move the sprite.

For a fantastic book to learn how to program for the C64 I’d advise “Assembly Language for Kids Commodore 64”, Sanders. This goes from the very start all the way to how to produce sound and is the basis for these tutorials, as I’m learning at the same time!

David Roberts

Read more posts by this author.

Newcastle upon Tyne, UK https://davidatroberts.github.io/