A quick update for my little C64 RPG…
With the extra 256 ROM files now working, yesterday evening I started altering my sprite loading system, changing scripts from embedding sprite data to loading compressed sprite files. I had to rearrange the sprite layout in memory and split some files, but it’s all working properly now.
Now the C64 has (surprise, surprise) 64K of RAM, 16K of which can be designated as VRAM. The VRAM has to be located on a 16K boundary, so that means it can sit at either $0000, $4000, $8000 or $C000. For my game I use the top bank based at $C000 as it’s out of the way at the top of the memory map and gives me a nice contiguous area of RAM below it. But there are some issues with the $C000 bank, which I’ll discuss next…
Now anyone who knows about the C64 memory map will know that the top 16K region of memory looks like the following:
- $C000 – 4K RAM.
- $D000 – 4K I/O area (4K RAM underneath).
- $E000 – 8K Kernal ROM (8K RAM underneath).
I use a double-buffered full-screen 4-way scroll system, so my two screens sit at $C000 and $C400 where the CPU is free to access them without messing about with RAM bank switching.
I use one character set for both the background and the game’s font, and that’s located at $F800, tucked away under the Kernal ROM.
The rest of the VRAM is allocated for the sprites and gives me a total of 192. I use 32 sprites for creature combat (max 5 creatures at a time), as well as cutscenes and other uses. As this region gets frequently modified, I’ve located it in the free RAM at $C800, just after my two double-buffered screens.
I/O And Kernal ROM Areas
RAM exists underneath both the I/O registers and the Kernal ROM, always accessible by the video chip. Writing to the ROM area writes through to the RAM underneath, so it’s a good location for the charset as it’s only ever written to (initial loading plus animated background chars).
But the RAM under the I/O area cannot be directly accessed. Fortunately, the 6510 CPU has a pair of I/O control registers at the base of the memory map, and they can be used to bank in/out both the ROM and the I/O area so the RAM underneath can be accessed.
Since The I/O area RAM needs bank switching to access it, I’ve placed the player and weapon sprites needed for combat in this region. Once the game starts, interrupts are disabled and the RAM banked in so that the sprites can be copied here and left alone.
More Scripting Added
Another thing I added yesterday was to use my script system to load graphical data. This might sound a bit strange, but my script system now has all the commands needed to load and copy data, plus it allows me to conditionally load sprite data. To load the data now, I just trigger the appropriate script. I can also embed 6502 code if needed to perform any special initialisation the script system cannot do.
All cutscene and conversation scripts now load their additional sprite data from the 2nd ROM file bank. This not only makes scripts slightly faster to load, but using shared data also reduces the cartridge usage a little.
I still need to work on the sprite system some more, but it’s already looking much better.