Have you ever had this nagging feeling that you're less worth because you never actually coded assembly on the C64? Of course you have! Fortunately, here's how you can finally do something about it, using the OS X or Linux command line.
Fun fact: The original Lucasfilm Commodore 64 games, such as Maniac Mansion, were cross-compiled on UNIX workstations, transferred over the network and uploaded to running C64s — way back in 1987! (Source: The Thimbleweed Park podcasts, which I highly recommend.) That's an excellent workflow that we'll mimic here. But instead of using real C64s, we'll be using the VICE emulator.
To install ACME and VICE on OSX,
On Linux, you may find those in your package manager. If you don't, just
download VICE and compile from source. It's really simple and straight forward,
and you get the C64 ROMs with the source (but not with the binary packages).
Just don't install to a non-standard location; VICE didn't like that the last
time I tried. The ACME assembler is very old, but should be readily
available from archive.org . It's very small and doesn't even have a kludgy
configure script, if I recall correctly.
To compile a C64 assembly file with ACME, type
foo.prg. I am aware that the 6502 and the C64's 6510 CPUs are
supposed to be instruction set compatible; I pass
--cpu 6510 anyway, just in
case there should be minor ISA differences.
If you use the Dust demo
(referenced above), you can type
acme index.asm to compile it. Files are
placed in the
With VICE you can execute the
.prg file directly, but using its
utility you can also put them into
.d64 disk images. On OSX, the tool is
located in /Applications/Vice64/tools/c1541. For the Dust demo, the image can
be made with
I've just used
diskname as the name of the dist, and
id as its ID.
Now that you know how to compile and create disk images, you can put it together in a makefile.
If you have a file
foo.asm in the same directory, you can type
foo.prg, put it into a
foo.d64 disk image and run it from VICE.
prg-file is an implicit target,
make will delete it before
executing the code. You can keep it with
make foo.prg or by adding it to
You can also launch VICE and run the code the old-fashioned way. This requires a disk image. From VICE, open the file browser to mount the image, then do
to list the disk contents. Then do
to load and run the program. While loading, hit Command-W to enter warp speed, making it load faster, then disable warp mode again before running the code.
.prg file format is very simple: It starts with a two-byte memory address
which the rest of the contents are loaded into. You have to specify the
secondary load argument
,1 to make sure the contents are loaded into this
memory address: The default is to load the contents into the start of BASIC
$0801, meaning it expects the
.prg file to contain just a BASIC
program. The usual trick is to add a small BASIC program at the beginning of
.prg that just jumps to the real assembly program in memory.
So, if your assembly program is set to start at
$0900, then the
You can omit the starting BASIC program in your files if you're very clever, but most programs seem to use this trick.
You can see some example files at https://github.com/cslarsen/c64-examples.
The BASIC loader I use there is given below. It may be a bit much to understand
as a first tutorial, but it just encodes a
10 SYS <start address> program:
The contents of
constants.asm is just some memory mapped locations for the
start of BASIC memory and foreground and background colors. By writing to the
color locations, you can change the colors.
To use the BASIC booter, include the file and invoke the macro with
It wraps the loader in an ACME macro
start_at. The main assembly here starts
$0900, meaning it loads super fast: The BASIC loader starts
the rest of the code at
$0900. Now, the
.PRG file format simply consists of
a destination address in memory to load the file contents into. If the space
between your BASIC loader (which must start at
$0801) and your entry point
is huge, then you'll waste space, and the file will take forever to load, even
if you're using warp mode in your emulator. If you need more space, let the
.PRG file be a loader so your program gets up and running quickly.
If you put the above code into
flicker.asm, using the above makefile you can
now run it by typing
The output is given below
The only thing you need now is a lot of time on your hands, a good C64 reference manual and memory map, and you're set for hours of fun (after you've made a stable raster, of course).