ballz d538cf46e2 Phase 5: raster IRQ + frame timing
Replace busy-wait frame counter with a 50 Hz raster IRQ at line 311
(PAL stable line).  The IRQ handler increments a 16-bit frame_count
and calls game_step() once per frame.  Per-state timing now uses
enter_frame timestamps + frame_count comparisons.

- New tick.h/tick.c: install one RIRQ via Oscar64's rirq library,
  call a __interrupt handler that bumps frame_count and runs the
  state machine.  Mask CIA 1 + CIA 2 IRQs and set RST8 (the high
  bit of the 9-bit raster register) so the IRQ fires at line 311
  not line 55.
- game.h: expose volatile frame_count, replace per-state 'frame'
  counter with enter_frame timestamps.
- game.c: use frame_count - enter_frame everywhere; sample SID
  $D41B at READY enter for a random 100..250 frame WAIT duration;
  trigger a low-square-wave stinger on SID voice 1 when DRAW
  faults out (no fire for 500 frames) and gate it off ~0.2 sec
  later via a counter decremented every frame.
- main.c: replace the busy-wait loop with rasterirq_setup() and
  an empty for(;;); idle.

(Filename is tick.c/.h not rasterirq.c/.h because the oscar64
library's own rasterirq.c does '#include "rasterirq.h"' to pull
in its own header, and that include would otherwise pick up
ours and lose NUM_IRQS.)
2026-07-17 02:02:51 +02:00
2026-07-17 02:02:51 +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%