Scripts that classify and inspect Apollo Luminary099 descent-guidance source for a course paper. Narrow scope, and no AGC toolchain.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-05-26 23:31:15 -04:00
scripts Add AGC analysis scripts and README 2026-04-17 14:20:37 -04:00
.gitignore Add AGC analysis scripts and README 2026-04-17 14:20:37 -04:00
README.md Clean up README prior to repo archive 2026-05-26 23:31:15 -04:00
requirements.txt Add AGC analysis scripts and README 2026-04-17 14:20:37 -04:00

Apollo AGC Study

This repo holds the small script set I used to inspect Luminary099 descent-guidance code for an EP394 final paper. The scope is narrow. This is not a full AGC toolchain, and it does not vendor the upstream Virtual AGC source tree. The point is to make the interpretation work reproducible without dragging along the rest of the course project.

Scripts in Repo

  • scripts/agc_parse.py Classifies AGC source lines as basic instructions, interpretive pseudo-ops, assembler directives, data, label-only lines, and a few fallback categories for audit work.
  • scripts/cycle_budget_calc.py Takes the classifier CSV and applies R-700 basic-instruction timing plus a simple interpretive timing model to estimate file-level cost.
  • scripts/hot_path_timing.py Estimates one hand-traced P63 SERVICER pass rather than whole-file cost. This is the script closest to the timing argument in the paper.
  • scripts/yaagc_capture.py Connects to yaAGC and records a short sample of channel traffic to confirm that a Luminary rope image is actually running.
  • scripts/gen_cycle_budget.py Regenerates the P63 SERVICER timing figure from the final per-block values used in the paper.

Requirements

The parser and timing scripts use only the Python standard library. The figure script needs:

matplotlib
numpy

Install them with:

python3 -m pip install -r requirements.txt

Expected inputs

These scripts expect AGC source and, for emulator checks, a built yaAGC environment that already exist on your machine. I kept that dependency external because the upstream Virtual AGC tree is large and already maintained elsewhere.

Typical source inputs look like:

  • Luminary099/SERVICER.agc
  • Luminary099/P63-P65.agc
  • Luminary099/INTERPRETER.agc

For emulator checks you also need:

  • a yaAGC executable
  • a rope image such as oct2bin.bin

Quick start

Classify a few Luminary files and write CSV output:

python3 scripts/agc_parse.py \
  /path/to/Luminary099/SERVICER.agc \
  /path/to/Luminary099/P63-P65.agc \
  /path/to/Luminary099/INTERPRETER.agc \
  --csv out/classified.csv \
  --opcsv out/ops_hist.csv

Turn that CSV into a rough file-level timing estimate:

python3 scripts/cycle_budget_calc.py out/classified.csv

Print the hand-traced P63 hot-path timing estimate:

python3 scripts/hot_path_timing.py

Regenerate the cycle-budget figure:

python3 scripts/gen_cycle_budget.py --png

Capture a short yaAGC run:

python3 scripts/yaagc_capture.py \
  --launch \
  --yaagc-bin /path/to/yaAGC \
  --core /path/to/oct2bin.bin

Provenance and limits

The timing numbers are not all of the same type, and pretending otherwise would be sloppy.

  • agc_parse.py is a line classifier, not a reassembler.
  • cycle_budget_calc.py is useful for broad file-level cost, but it overcounts if a file contains routines that do not execute in the path you care about.
  • hot_path_timing.py is the opposite. It is narrow and hand-built, but it is much closer to the actual P63 SERVICER pass discussed in the paper.
  • gen_cycle_budget.py hard-codes the final per-block values because that figure came from a hand audit of the hot path, not from a direct parser pass.

The instruction timings come from MIT R-700. The interpretive op costs are an approximation anchored to R-700 benchmarks and then scaled by the kind of work each pseudo-op is doing. That is enough for the paper's comparison, but it is not a cycle-accurate simulator.