ballz 65a2e5d2a1 Phase 4: state machine skeleton (TITLE→READY→WAIT→DRAW→WIN)
Implement the full state machine from GAME.md §9 with no audio yet,
fixed (not random) durations, and the basic score-update + reset logic
needed to drive the GAMEOVER transition.

src/game.h / src/game.c:
  - enum: STATE_TITLE, STATE_READY, STATE_WAIT, STATE_DRAW,
    STATE_WIN_P1, STATE_WIN_P2, STATE_GAMEOVER
  - byte state global + game_init() / game_step() pair
  - per-state enter (show_screen + score_render + reset frame counter)
    and step (check inputs, advance counter, transition) functions
  - TITLE: flash border at 25 Hz, debounce both-fire-within-8-frames
  - READY: 60 frames, WAIT: 100, DRAW: 500-frame fault timeout,
    WIN: 100 frames, GAMEOVER: 300 frames
  - DRAW uses rising-edge detection so holding fire from before
    DRAW doesn't auto-trigger a win
  - WIN_P1/WIN_P2 increment the score and re-render the score bar
  - GAMEOVER shows the title screen with scores reset to 0/0

src/screens.c / src/screens.h:
  - show_screen(n) now handles all 5 SCREEN_* IDs via a per-screen
    descriptor table (5 × 8000-byte bitmaps + 5 × 1000-byte attrs)
  - LZO-compress the 8000-byte bitmaps at build time so the 5 screens
    fit in the main region; the 5 .attr tables go in a custom 'screens'
    region at $A000-$C000 (BASIC ROM area, banked out as RAM)
  - new show_white_screen() fills the bitmap with 0s, sets $D021/
    $D022/$D023/$D020 to white, for the all-white DRAW screen

src/main.c:
  - simplified to: memmap_setup → score_init → game_init → while (1)
    game_step()
  - sets #pragma heapsize(0) since the program doesn't use malloc

Build: ./build.sh -e — .prg is 43.9 KB, well under the 51 KB BASIC
load limit. The oscar64 emulator runs the state machine indefinitely
(both fire buttons read as pressed in the emulator, so the game
cycles through the states); no crash.

Memory layout (from .map):
  $0801-$0853  startup
  $0880-$0E51  code (1489 bytes)
  $0E51-$7FE4  data: 5 LZO bitmaps + small tables (28723 bytes)
  $7FE4-$7FEC  BSS: state, frame, title_input, etc.
  $7FF0-$9000  heap (16 bytes)
  $9000-$A000  stack
  $A000-$B388  custom 'screens' region: 5 .attr tables (5000 bytes)
2026-07-17 01:50:03 +02:00

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.
S
Description
No description provided
Readme
14 MiB
Languages
C 74.6%
Python 16%
Makefile 9.4%