Manual · 7
C for ELF cartridges
ELF cartridges have an ARM processor that runs a C program and feeds the 2600 its instructions as it asks for them. VCSIDE has a template that follows the rules these cartridges need, and checks them after every build.
What runs where
The game is written in C and compiled for the cartridge's ARM (a Cortex-M0) with arm-none-eabi-gcc. During the visible lines, the ARM hands the 6507 every instruction it runs, through a library the cartridge's loader provides. During the overblank, the 6507 runs vertical sync, vertical blank and overscan from a small program of its own, and the ARM is free for the game logic.
The ROM, build/<name>.bin, is a relocatable ELF file. It runs in Stella and Gopher2600 and on the PlusCart and UnoCart. For the Chameleon Cart it is linked with that cartridge's firmware.

The template
A new C for ELF project has:
| File | What it is |
|---|---|
Makefile | Builds the ROM with the options these cartridges need, and checks the result. |
include/vcsLib.h | The TIA and RIOT registers and the loader's functions. |
src/main.c | The game. The example draws a scrolling rainbow, and goes back to the menu with RESET in a multicart. |
src/trampolines.S | Long calls to the loader, and to memcpy and memset. |
chameleon/support.c | What the Chameleon Cart's build adds. |
The template is CC0. You can also start from the animated-sprite example, with the same hero.vcsgfx as the assembly one and its src/hero.gfx.h. See what saving writes.
The rules it follows
- Code for a Cortex-M0, with data in their own sections and one section of code.
- A partial link with libgcc, stripped of what the loader doesn't need, and libgcc's divisions renamed.
- Calls to the loader are long calls, because the loader can be anywhere in the cartridge's flash.
- The kernel runs from RAM (
RAM_FUNC, the.RamFuncsection), where the ARM is fast enough for every line.
After linking, the Makefile checks the result:
- every undefined symbol that isn't the loader's is reported as an error on the file that uses it, such as
src/main.c: error: undefined symbol 'foo'(with a partial link the linker doesn't treat it as one, and the emulator would link it to address 0); - no call to the loader is a short one.
Building and errors
F7 runs the project's build_command, make. The folders of the Arm toolchain and of Make are put first in its PATH, since a program opened from the desktop doesn't have the shell's.
Everything goes to Problems: gcc's errors on their line, messages without a line, ld's (an undefined reference with the function that makes it, a region that overflows), the checks above and make's own errors.
For the Chameleon Cart:
make chameleon CHAMELEON_FW=<folder of the Chameleon Cart's template>
The Chameleon Cart's firmware template is not included with VCSIDE.
Space
The space report reads the ELF file: code, code in RAM, constants and variables, and the memory of the cartridge chosen for the project: the Chameleon Cart's flash and RAM, or the RAM of the PlusCart and UnoCart.
Running and debugging
F5 runs the ROM in Stella or Gopher2600 as an ELF cartridge. Neither emulator can stop on a line of C, so breakpoints are not passed. The emulator options include the ARM checks for ELF.