fs2port/SESSION_RECOVERY.md

113 lines
4.6 KiB
Markdown

# FS2 Port Session Recovery
This file is the entry point for resuming work after a session break.
Updated 2026-09-06.
## How to recover
1. Read this file (current state + ground rules).
2. Read `~/.claude/projects/-home-scott-claude-flight/memory/MEMORY.md`
and follow the indexed entries that are relevant to the current task.
3. Read `port/PORT_STATUS.md` for what the port is and how it is verified.
4. Read `port/PORT_64K_AUDIT.md` if 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..$A7FF` are rewritten by the
scenery file, not by the 64K patch table: `LoadSceneryFileCommon`
reads 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`).
- `PerspectiveDivide` is a non-restoring divide whose quotient for a
negative numerator is not the magnitude quotient; `chunk5Vertex.c`
transliterates it register by register (`PerspXTable`/`PerspYTable`
at `$7D80`/`$7E00` are now labelled in `src/chunk5.s`).
- Sector `s` of 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 build
- `downloads/scenery/extracted/*.blocks` - block lists fs2trace reads
- `orig/` - 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/`**, never `port/` 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 keep `make validate` green.
- **Style**: see the user's global CLAUDE.md. `port/tools/style.py`
is 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
```