Whether you are a grandmother of 95 years, a grossly overweight newly divorced 45 year old or perhaps only 2 months old, creating a full-blown demo on the Commodore 64 might seem a daunting task. In this self-contained tutorial, we will guide you on how to set up and create your very first demo on the c64.
Creating a (single-file) demo for the c64 requires careful planning of resources of code. You will have to think about packing, reusing both code and variables – and how everything should interact. First, we recommend you to go through some of the other tutorials on this page – such as the game tutorial series.
In order to keep code to a minimum (and preventing spaghetti code), we present an optimal automated solution that can serve as a basis for any demo. The project is included in in the TRSE framework (from version 0.05), and can be used as a starting project for a demo.
The idea is simple: The demo framework is split into two “parts”, one that controls rasters and one that performs background initialization, with a central part (the “progress tracker”) that connects the two. Take a look at the following flowchart:
Let’s go through a typical code path of a demo:
- The “Main routine” intializes the “wait raster”, which just plays music and renders a black screen. The “progress tracker”, which is updated from the “wait raster”, decides to start presenting “scene 1” (from a pre-defined table)
- “The progress” tracker tells the “main routine” to start performing “scene 1 intializations” : decrunching some data, calculating some large tables, that kind of stuff. The “wait raster” ensures that the screen remains black and that music is played at regular intervals (1 time per frame for PAL) while waiting for scene 1 to initialize.
- When scene 1 initialization is finished, the “main routine” sets a flag that initializations are complete – which triggers the “progress tracker” to load a new raster: the “scene 1 raster”.
- “Scene 1” now plays, shows stuff, all while “progress tracker” keeps track of timing. When the scene is nearing the ending, a “transition flag” is triggered, enabling the scene to take appropriate actions – such as start clearing portions, fading text or colors.
- When the progress tracker decides that it is time to move on to scene two, it loads the “wait raster” again while telling the “main routine” to start initializing “scene 2”.
The difficult part
The difficult (and somewhat entertaining) part of creating a c64 demo is resource management. You will have to think about packing, where to store data, how to reuse data and about code layout. Here are a couple of helpful tips:
- Assume your code will take up all of bank 1, that is, up to $4000. You therefore won’t be able to use the bank 0 video memory at all for displaying anything – and can use these $400 bytes of memory for storing temporary tables etc.
- You can disable the VIC chip and store data at $D000-$DFFF by using “EnableAllRam” (be sure to store and reset the value in $01 before and after using this method). This gives you an additional 8K of memory where you can stuff your packed data etc.
- If you use the memory area above $D000 make sure that you place your data here after you have loaded your PRG file. If you load a PRG file with your pre-loaded data in this area you will experience that your demo crashes – since you actully overwrite critical data in the $D000-$DFFF area.
- Make sure the zeropages that are used in your SID music don’t overlap with methods used in initialization (such as decrunch, math functions etc). The TRSE Memory Analyzer tool will give warnings on whether such problems exist.
- Pack pack and pack! We recommend using TRSE .Paw files to pack all your resources : images, charsets and sprites. These are then decrunched in the scene initialization routine.
- Make sure that your rasterroutines does not overlap with the “wait raster” routine. E.g. if your “wait raster” routines starts each frame at position $00 ($d012), make sure that your rasterroutine does not use too many rasterlines and overlaps $00. That would cause your “wait raster” routine to miss and odd artifacts (like strange audio playback) will appear.
- Be careful with VIC bank 0 and 2 – remember that the values $1000 – $2000 and $9000-$A000 are hard-wired to only display VIC character rom, so you won’t be able to put your own charsets/sprites here
- Don’t be afraid of moving your variables / procedures to another memory block by using the @startblock $Address “Name” preprocessor.
- Make sure to organize your resources into subdirectories: charsets in “charsets”, images in “images”, include files in “include” etc.
Memory Layout example
Take a look at this memory layout of a demo written in TRSE
- Most code is confined to bank 0, but due to code size about $600 bytes of code were moved to bank 3 (so it won’t overlap bank 1)
- $0400-$0800 is used for temporary data
- Music is located from $B000-$C000
- Packed data is stuffed at $C000 and onwards
- Packed data will unpack to bank 1 (and sometimes parts of bank 2)
- Therefore, bank 1 is reserved for “unpacking space”
- However, there is some initial data here : an unpacked image. This is the “intro image” which will be displayed at the start of the demo, and is instantly overwritten by the following scenes. This means that while all the other scenes can be displayed several times, the first intro image scene can only be showed once.
- Variables and extra code is placed at $F000+