4.6 KiB
FS2 Port Session Recovery
This file is the entry point for resuming work after a session break. Updated 2026-09-06.
How to recover
- Read this file (current state + ground rules).
- Read
~/.claude/projects/-home-scott-claude-flight/memory/MEMORY.mdand follow the indexed entries that are relevant to the current task. - Read
port/PORT_STATUS.mdfor what the port is and how it is verified. - Read
port/PORT_64K_AUDIT.mdif working on 64K-mode patch hooks.
Build
Disassembly (needs a git build of cc65; the Ubuntu package is too old
for .refto and --warnings-as-errors):
export PATH=$PWD/tmp/cc65/bin:$PATH
export CC65_HOME=$PWD/tmp/cc65
make clean && make && make validate
If tmp/cc65 is missing: cd tmp && git clone --depth 1 https://github.com/cc65/cc65.git && cd cc65 && make -j8 bin.
make validate checks the four chunks AND the four overlay sources
(src/ovl25.s, ovl2d.s, ovl42.s, ovl2b.s) against the sections
extracted from the FS2.1 file (orig/ovl_*.bin).
Port: make -C port (gcc, SDL2). Headless render:
port/bin/fs2port --screenshot tmp/x.ppm. Regenerate the symbol
header after renaming labels in src/:
ca65 --target apple2 -g -o tmp/complete_g.o src/complete.s
ld65 --config src/asm.cfg --dbgfile tmp/complete.dbg -o /dev/null tmp/complete_g.o
python3 port/tools/genSymbols.py tmp/complete.dbg port/include/fs2Symbols.h
Current state (2026-09-06)
The port is a byte-faithful C translation of the whole program running
over a 64K RAM image (see port/PORT_STATUS.md). It matches the 6502
oracle (port/tools/fs2trace.c) tick for tick, byte for byte, on the
twelve key scripts of port/tools/verify/regress.sh (boot, flight,
modes, edit, ww1, radios, slew, reality, night, course, logdisk, demo).
Key findings this session, in case they need revisiting:
- The
PatchSlot_*slots at$A7E8..$A7FFare rewritten by the scenery file, not by the 64K patch table:LoadSceneryFileCommonreads sector$2B's page over$A7E0. The editor, the WW1 mode and the Ctrl+E page are 6502 overlays inside the FS2.1 file. They are disassembled with semantic labels and per-routine comments (src/ovl*.s) and translated (port/src/ovl*.c). PerspectiveDivideis a non-restoring divide whose quotient for a negative numerator is not the magnitude quotient;chunk5Vertex.ctransliterates it register by register (PerspXTable/PerspYTableat$7D80/$7E00are now labelled insrc/chunk5.s).- Sector
sof the scenery file is file offset(s + 4) * 1024; a loader "page" call moves 1K (four 256-byte pages), clipped at$C000.
Verifying a change
port/tools/verify/regress.sh # everything (a few minutes)
port/tools/verify/regress.sh flight # one script
port/tools/verify/compareRun.sh NAME TICKS "KEYS"
python3 port/tools/verify/snapDiff.py tmp/NAME.oracle.snaps tmp/NAME.port.snaps 1 25 all
compareRun.sh leaves per-tick RAM snapshots in tmp/NAME.*.snaps;
snapDiff.py names the first differing bytes with their symbols. For
draw-level diffs run the oracle with FS2TRACE_DRAWLOG=1 and the port
with PORT_DRAW_DUMP=1 and diff the line/span/plot/project
lines; for the work counter use FS2TRACE_WATCH=0x32-0x33 and
PORT_WORK_TRACE=1. port/tools/codeMap.py maps code and data in an
overlay image from its entry points.
Files NOT to delete
tmp/cc65/- the assembler builddownloads/scenery/extracted/*.blocks- block lists fs2trace readsorig/- the original chunks, the disk image and the overlay sections
Ground rules
- Do not run git for port work.
port/is committed alongside the disassembly, but the user manages it; do not stage or commit port files. - Scratch files go in
./tmp/inside the project, NOT/tmp/. - Screenshots go in
port/screenshots/, neverport/or/tmp/. - Port uses fixed-point math - translate the byte arithmetic; no float reinterpretations.
- No 6502 emulation in the port. fs2trace keeps its own emulator for offline oracle runs of the real binary; the game never uses it.
- Byte-identical validation discipline applies to
src/*.s: every change must keepmake validategreen. - Style: see the user's global CLAUDE.md.
port/tools/style.pyis the normaliser (braces, one statement per line, camelCase, alphabetical functions with a prototype block, aligned declaration runs); it is idempotent and safe to re-run after edits.
NEVER Read PNGs
The user views PNGs directly. Compare images with text tools:
port/tools/imgDiagnose.sh diff tmp/mame_boot.png port/screenshots/x.ppm --ascii
port/tools/imgDiagnose.sh stats port/screenshots/x.ppm