Banner text rendering (PRESS FIRE / HARE WINS! / SCOOT WINS!): - src/banner.c, src/banner.h: new module; renders NUL-terminated ASCII text in any character row of the multicolor bitmap, using the same 4x8 custom font as the score bar. Truncates to 40 chars, centers in the row, clears the row first. - src/score.c, src/score.h: font extended from 8 to 16 entries — added P, F, W, I, N, !, space (and one reserved). font_lookup() maps ASCII to font index. - src/game.c: TITLE renders 'PRESS FIRE' in row 1 below the score bar; GAMEOVER renders 'HARE WINS!' or 'SCOOT WINS!' based on last_winner (set by game_enter_win_p1/p2). Other states clear row 1 on entry. State transition stinger: - src/audio.c, src/audio.h: audio_play_stinger(voice, duration) starts a low square-wave burst that auto-cleans up via audio_advance_stinger (called from audio_state_step). A 5-frame stinger is fired on every state transition; the per-state voice is chosen to avoid colliding with the new state's audio (TITLE/READY: voice 0/1 free, WAIT: voice 2 free, DRAW: voice 0 free, WIN/GAMEOVER: voice 2 free). Stinger is silenced by the next audio_state_enter() via the existing audio_stop() call. TITLE border flash changed from 12.5 Hz to 1 Hz (50 on, 50 off). Build system: - src/build.sh: added -O0/-O1/-O2/-O3/-Os/-g flag handling. Both default (-O1) and -O3 builds produce a 43913-byte .prg (well under the 51308-byte LOAD"*",8,1 limit). - src/main.c: pinned #pragma stacksize(0x400) — the oscar64 default is the same, but pinning makes the layout predictable across optimization levels. -O3 needs this exact size; larger values cause 'Cannot place stack section' link errors because the optimizer's larger code section leaves less room in the stack/heap gap. - src/tick.c: marked frame_tick_handler __noinline so -O3 doesn't inline the entire state machine (6000+ bytes) into the IRQ handler. With __noinline, the handler is 136 bytes — small enough for the raster line budget. - src/game.h: marked game_step __noinline for the same reason. The .prg is 173 blocks (out of 202 max), well within the BASIC load area. Both default and -O3 builds run cleanly in the oscar64 built-in emulator.
nyuller
A C64 programming project using Oscar64
as the cross-compiler. Oscar64 is checked in as a git submodule under
./oscar64/.
Layout
.
├── oscar64/ # Oscar64 cross-compiler (git submodule)
├── docs/c64/ # Low-level C64 reference (memory map, VIC, CIA, SID, …)
├── src/ # Your C code
│ ├── helloworld.c
│ └── build.sh # Compile + run helper
├── OSCAR64.md # Notes on the Oscar64 compiler internals
└── PROG_C64.md # Notes on programming the C64 hardware
First-time setup
# 1. Clone with submodules:
git clone --recurse-submodules <this-repo-url>
# Or, if you already cloned without --recurse-submodules:
git submodule update --init --recursive
Building
cd src
./build.sh # compile helloworld.c → src/build/helloworld.prg
./build.sh -e # run in oscar64's built-in emulator (headless, fast)
./build.sh -v # run in VICE x64 (interactive, needs a real display)
./build.sh -V # run in VICE x64sc (interactive, cycle-exact)
./build.sh -c # just compile
build.sh will build the oscar64 compiler automatically the first time
(it runs make -C make compiler inside ./oscar64/ if
./oscar64/bin/oscar64 doesn't exist yet).
Default test tool is the oscar64 built-in emulator (-e): it
runs headless, needs no ROMs, no display, and is fast. Every Verify
step in tasks.md uses this.
VICE 3.9 is installed at /usr/bin/ (x64, x64sc, x128,
xvic, xpet) and is available via -v / -V. It is a GUI
emulator and needs a real X11 / Wayland display to render — it
won't produce useful screenshots in this headless environment.
Use it from a real terminal session for interactive play-testing
and cycle-exact validation of raster IRQ and SID timing; don't
expect to script it.
Documentation
PROG_C64.md— how the C64 hardware actually works, from a low-level programming perspective. Start here if you want to understand what's going on under the hood.OSCAR64.md— how the Oscar64 compiler works internally, plus a C64- specific section on how to use it well (memory model, bank switching, raster IRQs, common mistakes).docs/c64/— downloaded reference material: the full Commodore 64 Programmer's Reference Guide text, Christian Bauer's canonical VIC-II paper, and per-chip reference notes.