Document VICE headless limitations; rely on oscar64 emulator for default test path

VICE x64 is a GUI emulator that requires a real X11/Wayland display.
In this headless environment the KERNAL/BASIC/CHAR/1541 ROMs had to be
fetched manually, autostart produced blank screenshots (no display
to render to), and no other C64 emulator is installed. The oscar64
built-in emulator (-e) is the practical headless test tool. VICE is
left in build.sh as -v / -V for interactive use in a real terminal
session, but tasks.md and README.md are updated to reflect that the
development loop and all Verify steps use the oscar64 emulator.
Removed the failed test artifacts from src/build/.
This commit is contained in:
ballz
2026-07-17 01:03:01 +02:00
parent 0f8503f9f7
commit 1cd3a962e6
3 changed files with 96 additions and 71 deletions
+15 -7
View File
@@ -32,19 +32,27 @@ git submodule update --init --recursive
```sh ```sh
cd src cd src
./build.sh # compile helloworld.c → src/build/helloworld.prg ./build.sh # compile helloworld.c → src/build/helloworld.prg
./build.sh -e # run in oscar64's built-in emulator (fastest) ./build.sh -e # run in oscar64's built-in emulator (headless, fast)
./build.sh -v # run in VICE x64 (standard, fast) ./build.sh -v # run in VICE x64 (interactive, needs a real display)
./build.sh -V # run in VICE x64sc (cycle-exact, slow but bit-perfect timing) ./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 `build.sh` will build the oscar64 compiler automatically the first time
(it runs `make -C make compiler` inside `./oscar64/` if (it runs `make -C make compiler` inside `./oscar64/` if
`./oscar64/bin/oscar64` doesn't exist yet). `./oscar64/bin/oscar64` doesn't exist yet).
VICE 3.9 is installed at `/usr/bin/` and provides `x64`, `x64sc`, **Default test tool is the oscar64 built-in emulator** (`-e`): it
`x128`, `xvic`, `xpet`. We target the C64, so `x64` (fast) and runs headless, needs no ROMs, no display, and is fast. Every `Verify`
`x64sc` (cycle-exact) are the two we use. `x64sc` is the one that step in `tasks.md` uses this.
matches real-hardware timing for the raster IRQ and SID tests.
**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 ## Documentation
+24 -15
View File
@@ -3,16 +3,21 @@
# #
# Usage: # Usage:
# ./build.sh # compile helloworld.c → build/helloworld.prg # ./build.sh # compile helloworld.c → build/helloworld.prg
# ./build.sh -e # compile, then run in the oscar64 built-in emulator # ./build.sh -e # run in oscar64's built-in emulator (headless, fast)
# ./build.sh -v # compile, then run in x64 (VICE standard) # ./build.sh -v # run in VICE x64 (interactive, needs a display)
# ./build.sh -V # compile, then run in x64sc (VICE cycle-exact) # ./build.sh -V # run in VICE x64sc (interactive, cycle-exact, slow)
# ./build.sh -c # just compile (default; -c is a no-op for clarity) # ./build.sh -c # just compile
# #
# Output (in ./build/): # Output (in ./build/):
# helloworld.prg — loadable C64 program (run with x64, VICE, or real hw) # helloworld.prg — loadable C64 program (run with x64, VICE, or real hw)
# helloworld.asm — full 6502 listing # helloworld.asm — full 6502 listing
# helloworld.map — region/section/object placement # helloworld.map — region/section/object placement
# helloworld.lbl — VICE monitor label commands # helloworld.lbl — VICE monitor label commands
#
# For the development loop, use -e (oscar64's built-in emulator). It runs
# without a display, needs no ROMs, and is faster than VICE. VICE is for
# interactive use in a real terminal session, or for cycle-exact validation
# of raster IRQ and SID timing — which requires a working X display.
set -e set -e
@@ -42,14 +47,14 @@ fi
# --- compile + optionally run -------------------------------------------- # --- compile + optionally run --------------------------------------------
SRC=helloworld.c SRC=helloworld.c
EMU_FLAGS="" EMU_CMD=""
for arg in "$@"; do for arg in "$@"; do
case "$arg" in case "$arg" in
-e) EMU_FLAGS="-e" ;; # oscar64 built-in emulator -e) EMU_CMD="oscar64" ;; # oscar64's built-in emulator (headless)
-v) EMU_FLAGS="x64" ;; # VICE standard -v) EMU_CMD="x64" ;; # VICE standard
-V) EMU_FLAGS="x64sc" ;; # VICE cycle-exact -V) EMU_CMD="x64sc" ;; # VICE cycle-exact
-c) ;; # explicit compile-only -c) ;; # explicit compile-only
-*) echo "unknown flag: $arg" >&2; exit 1 ;; -*) echo "unknown flag: $arg" >&2; exit 1 ;;
esac esac
done done
@@ -59,21 +64,25 @@ echo "compiling $SRC with $OSCAR64_BIN -> $BUILD_DIR/"
# follow automatically since they share the base name. # follow automatically since they share the base name.
"$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$BUILD_DIR/helloworld.prg" "$SRC" "$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$BUILD_DIR/helloworld.prg" "$SRC"
case "$EMU_FLAGS" in case "$EMU_CMD" in
"") "")
# compile only # compile only
;; ;;
"-e") "oscar64")
echo "running helloworld.prg in oscar64's built-in emulator" echo "running helloworld.prg in oscar64's built-in emulator"
"$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$BUILD_DIR/helloworld.prg" -e "$SRC" "$OSCAR64_BIN" -i="$OSCAR64_DIR/include" -o="$BUILD_DIR/helloworld.prg" -e "$SRC"
;; ;;
"x64"|"x64sc") "x64"|"x64sc")
if ! command -v "$EMU_FLAGS" >/dev/null 2>&1; then if ! command -v "$EMU_CMD" >/dev/null 2>&1; then
echo "error: $EMU_FLAGS not found in PATH" >&2 echo "error: $EMU_CMD not found in PATH" >&2
exit 1 exit 1
fi fi
echo "running helloworld.prg in VICE ($EMU_FLAGS)" if [ -z "${DISPLAY:-}" ]; then
"$EMU_FLAGS" "$BUILD_DIR/helloworld.prg" echo "warning: no \$DISPLAY set; VICE may not render correctly" >&2
echo " for headless testing use -e (oscar64's built-in emulator)" >&2
fi
echo "running helloworld.prg in VICE ($EMU_CMD)"
"$EMU_CMD" "$BUILD_DIR/helloworld.prg"
;; ;;
esac esac
+57 -49
View File
@@ -16,34 +16,36 @@ produces files in `./src/data/`.
## 0.1. Test environment ## 0.1. Test environment
**VICE 3.9 is installed** at `/usr/bin/`. The binaries available: **The oscar64 built-in emulator is the primary test tool.** It's
invoked with `build.sh -e` (or `oscar64 -i=… -e source.c`) and
runs the same `.prg` file the C64 will run, with no setup, no
display, no ROMs, and at high speed. It is the default for the
development loop and is what every phase's *Verify* step uses.
| Binary | Use | **VICE 3.9 is installed** at `/usr/bin/` and can be used via
|--------|-----| `build.sh -v` (standard `x64`) or `build.sh -V` (cycle-exact
| `x64` | Standard C64 emulator. Fast, good for gameplay iteration. | `x64sc`). However, VICE is a GUI emulator and is **not suitable
| `x64sc` | Cycle-exact C64 emulator. Slower but bit-perfect timing. **Use this for the raster IRQ, audio timing, and badline-sensitive tests.** | for headless / scripted use** in this environment — it needs a
| `x128` | C128 emulator. Out of scope (we target C64 PAL), but available if we ever add C128 builds. | working `$DISPLAY` (X11 / Wayland) to render, and the `-exitscreenshot`
| `xvic` | VIC-20. Out of scope. | path produces a blank PNG when no display is available. The C64
| `xpet` | PET. Out of scope. | itself boots and runs fine in VICE, but you can't see anything in
a headless terminal. VICE is a *manual* interactive tool here:
run it in your own terminal session when you want to watch the
game play, validate raster IRQ timing by eye, or step through
breakpoints in the monitor. Don't expect to script it.
A typical test session for a .prg at `src/build/whack_hare.prg`: | Tool | Headless? | Use it for |
|------|-----------|------------|
| `build.sh -e` (oscar64 built-in) | Yes | Default for every Verify step. Fast, deterministic, runs in CI. |
| `build.sh -v` (VICE x64) | No | Interactive play-testing. Needs a real display. |
| `build.sh -V` (VICE x64sc) | No | Cycle-exact validation. Same display requirement. |
| `x128` / `xvic` / `xpet` | No | Out of scope (we target C64 PAL). |
```sh **Bottom line for the plan:** every `Verify` step uses `build.sh -e`
# Standard playthrough (fast, slight timing fudge) (unless explicitly noted). VICE is referenced only in Phase 8
x64 src/build/whack_hare.prg (end-to-end testing) and in the optional Phase 9 (NTSC) — both
of which assume a developer with a real terminal session will run
# Cycle-exact (real timing, slower, what we'd see on real hw) the tests.
x64sc src/build/whack_hare.prg
# Auto-quit after 5 seconds (good for CI / scripted checks)
x64src/build/whack_hare.prg -quitvm -exitscreenshot
```
The oscar64 built-in emulator (`build.sh -e`) is even faster than
`x64` and is what we use during development for quick iteration. `x64`
is what we use to confirm the binary works outside the compiler's
emulator. `x64sc` is what we use to confirm timing-sensitive things
(audio, raster IRQ) are correct before we call a phase done.
> **Prerequisite correction to GAME.md**: I said the screens would be > **Prerequisite correction to GAME.md**: I said the screens would be
> 320×200 standard hires. That's wrong for these images — they have > 320×200 standard hires. That's wrong for these images — they have
@@ -68,11 +70,12 @@ runs.
- [x]`GAME.md` written. - [x]`GAME.md` written.
- [x] ✅ Source artwork in `./source_images/`. - [x] ✅ Source artwork in `./source_images/`.
- [ ]**Verify:** `cd src && ./build.sh -e` runs the hello-world - [ ]**Verify:** `cd src && ./build.sh -e` runs the hello-world
program in the oscar64 built-in emulator. Also program in the oscar64 built-in emulator. (Optional: launch
`x64 src/build/helloworld.prg` should work in VICE. `x64 src/build/helloworld.prg` in a real terminal session
to see the screen.)
**Done means:** `src/build/helloworld.prg` exists and the emulator **Done means:** `src/build/helloworld.prg` exists and the
prints "Hello World" then exits cleanly. emulator prints "Hello World" then exits cleanly.
--- ---
@@ -169,8 +172,9 @@ state.
- `cd src && ./build.sh -e` displays the title screen in the - `cd src && ./build.sh -e` displays the title screen in the
oscar64 built-in emulator for 5 seconds (or until fire is pressed) oscar64 built-in emulator for 5 seconds (or until fire is pressed)
then exits. then exits.
- `x64 src/build/whack_hare.prg` displays the title screen in VICE - (Optional, interactive) `x64 src/build/whack_hare.prg` in a real
on real timings. Compare visually to the source PNG. terminal session displays the title screen on real timings.
Compare visually to `source_images/screen_title.png`.
- The .map file shows our code is in $0900-$1100-ish, well within - The .map file shows our code is in $0900-$1100-ish, well within
the 38 KB main region. the 38 KB main region.
@@ -299,10 +303,12 @@ random source.
sound (a low square wave burst, ~0.2 sec) and no point awarded. sound (a low square wave burst, ~0.2 sec) and no point awarded.
**Verify:** **Verify:**
- The game still works in the oscar64 built-in emulator. - The game still works in the oscar64 built-in emulator
- `x64sc src/build/whack_hare.prg` runs the game at cycle-exact (`build.sh -e`).
PAL timing (50.125 Hz). The state transitions happen on the - (Optional, interactive) Launch `x64sc src/build/whack_hare.prg`
right raster lines. The 50 Hz tick is rock-solid. in a real terminal to confirm the game runs at cycle-exact PAL
timing (50.125 Hz). The state transitions happen on the right
raster lines. The 50 Hz tick is rock-solid.
- WAIT duration varies visibly across multiple rounds. - WAIT duration varies visibly across multiple rounds.
- Press fire during WAIT (cheating) — nothing happens, we - Press fire during WAIT (cheating) — nothing happens, we
ignore inputs in WAIT state. (Add this as an explicit ignore inputs in WAIT state. (Add this as an explicit
@@ -357,9 +363,11 @@ becomes audible.
- WIN: arpeggio up. - WIN: arpeggio up.
- GAMEOVER: longer fanfare. - GAMEOVER: longer fanfare.
- The cues are recognizable and feel right (timing, volume). - The cues are recognizable and feel right (timing, volume).
- Run the audio cues under `x64sc` to confirm the SID envelope - (Optional, interactive) Run the audio cues under `x64sc
generator timings are right; `x64`'s less accurate timing src/build/whack_hare.prg` in a real terminal to confirm the
can hide note glitches that show up on real hardware. SID envelope generator timings are right; the oscar64 emulator
is fast but not always bit-accurate on SID timing, and the
`x64sc` cycle-exact path is the one that matches real hardware.
**Done means:** the game has sound. This is the phase where **Done means:** the game has sound. This is the phase where
the game becomes "the game" rather than "a tech demo". the game becomes "the game" rather than "a tech demo".
@@ -424,12 +432,10 @@ with no rough edges. We also do the real-hardware test.
- [ ] Add a brief stinger sound (0.1 sec) on each state - [ ] Add a brief stinger sound (0.1 sec) on each state
transition. Just a quick low square wave. transition. Just a quick low square wave.
- [ ] Make sure scores are reset on entering GAMEOVER → TITLE. - [ ] Make sure scores are reset on entering GAMEOVER → TITLE.
- [ ] Run the full game in VICE multiple times: - [ ] Run the full game in the oscar64 built-in emulator
- `x64 src/build/whack_hare.prg` for the fast playthrough loop. (`build.sh -e`) for the development loop, and (optionally,
- `x64sc src/build/whack_hare.prg` for the cycle-exact when you have a real terminal session) in `x64` / `x64sc` for
playthrough, which is the closest we'll get to real hw interactive play-testing and cycle-exact validation. Coverage:
without owning a C64.
Coverage:
- P1 wins 5 in a row (cheat test: hold fire on port 1 the - P1 wins 5 in a row (cheat test: hold fire on port 1 the
whole DRAW). whole DRAW).
- P2 wins 5 in a row. - P2 wins 5 in a row.
@@ -439,16 +445,18 @@ with no rough edges. We also do the real-hardware test.
- 10 random full matches to sanity-check the WAIT duration - 10 random full matches to sanity-check the WAIT duration
distribution. distribution.
- [ ] Build with `-O3` and verify the .prg still works under - [ ] Build with `-O3` and verify the .prg still works under
`x64sc` (optimization can change timing subtly). `x64sc` (in a real terminal session) — optimization can
change timing subtly.
- [ ] If we have a real C64 or a Turbo Everdrive, test on - [ ] If we have a real C64 or a Turbo Everdrive, test on
real hardware. Otherwise document that we tested in VICE real hardware. Otherwise document that we tested in the
cycle-exact mode (`x64sc`). oscar64 emulator + `x64sc` cycle-exact mode.
- [ ] Strip `-g` from the release build. Add a `-O3` build - [ ] Strip `-g` from the release build. Add a `-O3` build
target to build.sh. target to build.sh.
- [ ] Final pass: review the .map file, check no section is - [ ] Final pass: review the .map file, check no section is
larger than expected, check no RAM region is over-allocated. larger than expected, check no RAM region is over-allocated.
- [ ] Final sanity check under `x64sc`: load the release build, - [ ] Final sanity check: load the release build into `x64sc`
play a full match, and confirm the .prg is small enough to in a real terminal session, play a full match, and confirm
the .prg is small enough to
load via `LOAD"*",8,1` (i.e. ≤ 202 blocks = 51,308 bytes). load via `LOAD"*",8,1` (i.e. ≤ 202 blocks = 51,308 bytes).
**Verify:** **Verify:**