Jesse A. Green / notebook

Apollo 11 AGC Source Administrator & Developer Guide

Generated April 2026 from chrislgarry/Apollo-11 at 247dd7d

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

A maintainer's, archivist's, and developer's reference for the chrislgarry/Apollo-11 repository — the digitised source code of the Apollo Guidance Computer (AGC) flight programs that flew aboard Columbia and Eagle in July 1969.

This guide is for repository maintainers, deep-dive readers, embedded-systems researchers, and engineers who want to understand the AGC architecture, the transcription workflow, the verb/noun command surface, the operating-system layer (executive, waitlist, interpreter), and the fault-tolerant design patterns that allowed the lunar landing to proceed through the now-famous 1201/1202 program alarms.


1. Architecture Overview

1.1 What this repository is

chrislgarry/Apollo-11 is a historical archive, not a live software product. It preserves two flight programs that were physically loaded into the core-rope memory of Apollo Guidance Computer hardware in 1969:

  • Comanche055 — Build 055 of the Colossus 2A flight program (Command Module Computer, CMC), aboard Columbia.
  • Luminary099 — Build 099 of the Luminary 1A flight program (Lunar Module Guidance Computer, LGC), aboard Eagle.

Both programs were digitised from MIT Museum hardcopies by Paul Fjeld, are in the public domain, and are mirrored across multiple archives including Software Heritage for long-term preservation.

The repository is not a fork of Virtual AGC; it ships the source listings only. Assembly and simulation are out of scope.

1.2 The AGC at a glance

Understanding the hardware is essential to understanding the source code. Every quirk in the listing maps to a property of the AGC.

Property Specification
Word size 15 bits + 1 parity bit
Address space 12-bit, banked
Erasable memory 2 KW (2,048 words) of 16-bit core (RAM equivalent)
Fixed memory 36 KW (36,864 words) of core rope (read-only, mask-programmed at manufacture)
Clock 1.024 MHz master, ~2.048 µs per memory cycle (~12 µs per typical instruction)
Instruction set ~36 native opcodes plus interpretive virtual-machine opcodes
Multitasking Cooperative + interrupt-driven via a hand-coded executive and waitlist
I/O DSKY (display/keyboard), IMU, optical telescope/sextant, radars, engines, RCS jets, downlink telemetry
Mass / power ~32 kg, ~55 W; two units flew on every CSM/LM pair

The Block II AGC is a fixed-architecture computer — there is no microcode, no abstraction layer, no operating system in the modern sense. The "operating system" is the executive and waitlist hand-written into the rope.

Note

The repository's source files map one-to-one to the AGC's internal subroutine log sections. Reading a file is reading a printout — the bank directives, page-number anchors, and R0000 line markers are all load-bearing artefacts of the original 1969 printout layout, not modern conveniences.

1.3 Memory model

AGC memory is split into erasable (writeable) and fixed (rope, read-only):

Erasable:                                Fixed:
+--------------------+                   +--------------------+
| 0000-002F  Unswitched/                 | 02000-03777  Fixed-fixed (always mapped)
|            "Lower"                     |   (banks 02 and 03)
| 0030-04FF  E-banks 0-7                 | 04000-07777  Switched fixed (banks 4-7)
|   (switched, 256w each)                |
+--------------------+                   | 10000-77777  Switched fixed (banks 10-43)
                                         |   (rope-stored, read-only)
                                         +--------------------+

Bank registers (FBANK, EBANK) select which fixed/erasable bank is mapped into the windowed regions. Source code uses BANK n and EBANK= label directives to declare which banks the assembler should pack code/data into.

In the source you will see this pattern constantly:

        BANK    32                 # pack the following into fixed bank 32
        SETLOC  F2DPS*32           # address inside bank 32 (label-relative)
        BANK
        EBANK=  E2DPS              # assume erasable bank E2DPS in scope

Bank-management bugs were a major source of original-development complexity. The BANKCALL macro (used heavily) handles cross-bank function calls correctly.

1.4 Component inventory

Component Path Role
Command Module flight program Comanche055/ 80 .agc files; CSM control software
Lunar Module flight program Luminary099/ 86 .agc files; LM control software
Localised documentation Translations/ 70 README.<lang>.md / CONTRIBUTING.<lang>.md
Project documentation README.md, CONTRIBUTING.md, LICENSE.md English originals
Lint configuration .markdownlint.yml, package.json, .editorconfig Markdown lint pipeline
Repository hygiene .gitignore, bun.lockb Standard ignores; Bun lockfile

1.5 Technology stack

Layer Technology
Source language AGC assembly (yaYUL dialect)
Original assembler YUL → GAP (1968, no longer available)
Modern assembler yaYUL (Virtual AGC project)
Modern simulator yaAGC + yaDSKY2 (Virtual AGC project)
Documentation GitHub-Flavored Markdown
Lint markdownlint-cli2 ^0.16.0
Package manager Bun (lockfile shipped); npm-compatible
Hosting GitHub + Software Heritage mirror

2. System Requirements

2.1 For reading and proof-reading

Requirement Minimum
Disk ~30 MB (text only)
RAM None beyond OS baseline
Tooling git, any text editor, optionally grep/less
Network Required only for cloning / fetching scans

Proof-reading does not require a build toolchain. The reviewer's job is to compare the diff against scanned printout images, which can be done with two browser windows.

2.2 For markdown linting

Requirement Minimum
Node.js (npm path) 18+ recommended for markdownlint-cli2 0.16
Bun (lockfile path) Any recent version
Disk A few MB for node_modules/
Network Required only on first install

2.3 For assembly and simulation

The Virtual AGC toolchain has its own requirements; the canonical reference is the virtualagc/virtualagc README. In practice on Linux:

Requirement Minimum
Compiler GCC or Clang with C11 support
Build system GNU Make
GUI libraries wxWidgets (for yaDSKY2), Tcl/Tk (legacy DSKY)
Disk ~1 GB for full Virtual AGC build

Important

Virtual AGC is the only supported assembler/simulator. The original 1969 YUL and GAP assemblers are no longer available. Any toolchain claim in legacy documentation that does not refer to yaYUL/yaAGC is historical and not actionable today.

2.4 Supported platforms

Platform Read Lint Assemble (Virtual AGC)
Linux Yes Yes Yes (canonical)
macOS Yes Yes Yes
Windows (WSL2) Yes Yes Yes
Windows (native MinGW) Yes Yes Possible, manual setup
FreeBSD / other UNIX Yes Yes Probably (community)

3. Configuration Reference

There is no runtime configuration. The only configuration files in the tree govern editor behaviour, markdown linting, and repository hygiene.

3.1 .editorconfig

root = true

[*]
indent_style = tab
indent_size = 8
trim_trailing_whitespace = true

Tab indentation with width 8 matches the original 1969 printout convention. Trimming trailing whitespace prevents accidental whitespace-only diffs. Editors that respect .editorconfig (most modern ones) will pick this up automatically.

Key Value Why
indent_style tab Original printout used hard tabs
indent_size 8 Original printout column width
trim_trailing_whitespace true Avoids whitespace-only diffs

3.2 .markdownlint.yml

default: true
MD007: false
MD010: false
MD013: false
MD026: false
MD033: false
MD034: false
MD036: false
MD041: false
MD050: false
MD053: false

The configuration disables 10 default rules that conflict with the multilingual / historical-attribution / table-heavy nature of the documentation. Enabling any of these would generate hundreds of false-positive lint failures across the translations folder.

Rule Default Disabled — Why
MD007 (ul-indent) error Translation lists use varied indentation
MD010 (no-hard-tabs) error Tabs are intentional (matches .editorconfig)
MD013 (line-length) error Translation lines and attribution tables are intentionally long
MD026 (no-trailing-punct in headings) error Translation headings use punctuation in some scripts
MD033 (no-inline-html) error RTL languages (Arabic, Hebrew, Persian) use HTML for direction
MD034 (no-bare-urls) error Translation links in the README header are bare by design
MD036 (emphasis-as-heading) error Contract block uses bold-italic for role labels
MD041 (first-line-h1) error Some translations open with a TOC table
MD050 (strong-style) error Translations use varying bold conventions
MD053 (link-image-reference-defs) error Reference-link blocks span sections

3.3 package.json

{
  "scripts": {
    "lint": "markdownlint-cli2 *.md translations/*.md Comanche055/*.md Luminary099/*.md --config .markdownlint.yml",
    "lint:fix": "markdownlint-cli2 *.md translations/*.md Comanche055/*.md Luminary099/*.md --config .markdownlint.yml --fix"
  },
  "dependencies": {},
  "devDependencies": {
    "markdownlint-cli2": "^0.16.0"
  }
}
Script Purpose
npm run lint Lint all markdown files under root, translations/, Comanche055/, Luminary099/ against .markdownlint.yml. Used in CI / pre-merge.
npm run lint:fix Same scope, but auto-fixes what is auto-fixable.

Important

The script glob translations/*.md is lower-case while the directory in the repository is Translations/ (capitalised). On case-sensitive filesystems (Linux, CI runners), this glob may not match unless filesystem case-folding is on. Verify against your runner's filesystem semantics; if you need full coverage, run npx markdownlint-cli2 'Translations/*.md' separately.

3.4 .gitignore

Standard Node.js / IDE patterns: node_modules/, .DS_Store, *.log, IDE config dirs. No build outputs (the repository produces no build artefacts).

3.5 Lockfile choice

The repository ships bun.lockb, indicating the maintainer uses Bun as the package manager rather than npm. npm install works (resolving from package.json), but contributors who modify devDependencies should use bun install to keep the lockfile coherent.

There is no package-lock.json checked in; when contributors run npm install it generates a transient lockfile that should not be committed.

3.6 Environment variables and runtime config

There are none. The repository has no runtime — only static text files plus an opt-in markdown lint pipeline.


4. Deployment & Scaling

There is no traditional deployment. The repository is a static collection of text files plus a markdown lint dev-dependency. "Deployment" here means publication and mirroring for long-term preservation.

4.1 Publication channels

Channel URL Cadence
Primary GitHub repository https://github.com/chrislgarry/Apollo-11 Continuous
Software Heritage archive https://archive.softwareheritage.org/browse/origin/https://github.com/chrislgarry/Apollo-11/ Snapshot of master automatic
Virtual AGC mirror (independent transcription) https://github.com/virtualagc/virtualagc Independent

4.2 Release process

There are no releases. The repository has no build outputs, no tags driven by content, no semantic version. Software Heritage snapshots master automatically; that is the canonical "release" surface.

Note

The absence of versions is by design: each merged PR is a small proof-reading delta, and tagging cuts would be arbitrary. If a published artefact is required (e.g. for citation), reference a specific commit hash.

4.3 Scaling considerations

Dimension Approach
Storage Negligible (~30 MB total). Git repo is fine for archival.
Read traffic GitHub handles all read load; no operational concern.
Contributor scale Limited by reviewer bandwidth (proof-reading PRs need careful eye-against-scan review).
Translation scale 39+ README translations and 28 CONTRIBUTING translations exist; new languages welcome but no automation.

4.4 Rebuild from scratch

To produce a clean local copy for archival:

git clone --mirror https://github.com/chrislgarry/Apollo-11.git
cd Apollo-11.git
git bundle create apollo-11.bundle --all
sha256sum apollo-11.bundle > apollo-11.bundle.sha256

The mirror clone preserves all branches, tags, and refs. The bundle is a single-file artefact suitable for offline storage.

Tip

Pair the bundle with a copy of the linked scans at http://www.ibiblio.org/apollo/ScansForConversion/ for a fully self-contained archive that does not depend on third-party uptime.


5. Operations

5.1 Repository maintenance

There is no on-call rotation, no SLO, no production runbook. Day-to-day "operations" are PR review and issue triage.

Merging proof-reading PRs

  • Squash by default — proof-reading commits are often noisy ("fix typo", "fix typo again"), and the per-page work is the meaningful unit.
  • Preserve the page-number reference in the squashed commit message.
  • If the PR touches multiple files, prefer keeping commits per-file and merging unsquashed.

Translations updates

When merging a translation PR:

  1. Verify the file is named Translations/README.<lang>.md or Translations/CONTRIBUTING.<lang>.md.
  2. Confirm the language link is added to root README.md and CONTRIBUTING.md headers.
  3. Run npm run lint to verify the new file passes the relaxed config.

New scans / new programs

The repository deliberately limits scope to Apollo 11 only (Comanche055 and Luminary099). Other AGC programs (Comanche072, Luminary116/131/210, Sundance, etc.) live at Virtual AGC. PRs that add new program directories should be redirected there.

5.2 Issue triage

Issues fall into recognisable categories:

Category Example Action
Per-file proof campaign "Proof XYZ.agc" Leave open until the file is reconciled with scans
Typo report "Line 42 has wrong word" Convert to PR or close after fix
Off-topic YouTube channel (#973) Close politely
Validation tooling request #960 "automated scan validation" Track as long-running enhancement

Tip

When closing an off-topic issue, point the submitter to the Virtual AGC project for assembly/simulation questions and to the Apollo Guidance Computer Software History on Wikipedia for general context. Most off-topic submissions are honest curiosity, not spam.

5.3 Active proof-reading campaigns

The following per-file campaigns are open as of commit 247dd7d:

Issue File Status
#960 (project-level) Add line-by-line validation tests against scans OPEN
#608 MEASUREMENT_INCORPORATION.agc OPEN
#217 INTERPRETER.agc OPEN
#566 AOTMARK.agc OPEN
#234 P34-35_P74-75.agc OPEN
#204 ERASABLE_ASSIGNMENTS.agc OPEN
#639 SPS_BACK-UP_RCS_CONTROL.agc OPEN
#648 TJET_LAW.agc OPEN
#647 TIME_OF_FREE_FALL.agc OPEN

5.4 Reviewer protocol

When reviewing a proof-reading PR:

  • [ ] Open the cited scan page in a separate window or tab
  • [ ] Walk every changed line in the diff against the scan
  • [ ] Verify whitespace was changed only where scan-justified
  • [ ] Check that no R0000 marker was removed or moved
  • [ ] Verify no perceived "code improvement" was bundled into the PR (out of scope)
  • [ ] Run npm run lint if the PR touched any .md file
  • [ ] Confirm the page number is in the commit message; ask for it if missing

Note

The reviewer's most common pushback is "please cite the scan page". This is non-negotiable: without it the reviewer cannot perform the comparison and cannot merge.

5.5 Edge cases

  • Missing pages: If a scan page is illegible, the contact for higher-resolution images is [email removed] (Ron Burkey, Virtual AGC).
  • Disagreement between scans and Virtual AGC's mirror: This repository's transcription is independent of Virtual AGC's. Where they differ, the chrislgarry repo follows its own scans-first rule.
  • GAP-generated tables: The original printouts include cross-reference tables generated by the GAP assembler at the end of each section. These are not transcribed — they are GAP-tool artefacts, not source. They are noted as "GAP-generated tables" in the program READMEs.

5.6 The transcription pipeline

   1969 hardcopy printouts
            |
            v
   MIT Museum custody
            |
            v
   Paul Fjeld scans pages → high-resolution PNG/JPEG images
            |
            v
   Hosted at ibiblio.org/apollo/ScansForConversion/
            |
            v
   Community transcribes to .agc (line-by-line)
            |
            v
   Pull request against chrislgarry/Apollo-11
            |
            v
   Reviewer compares scan vs diff
            |
            v
   Merge into master
            |
            v
   Software Heritage mirror snapshots master

The community's tooling at https://28gpc.csb.app/ presents scan and transcription side-by-side for reviewers.


6. Performance

The repository itself has no runtime performance — it is a collection of text files. This section concerns:

  1. Lint pipeline performance (the only "build" step in the repo).
  2. AGC runtime performance characteristics, captured here because they are essential context for reading the source.

6.1 Lint pipeline

markdownlint-cli2 walks the four globs (*.md, Translations/*.md, Comanche055/*.md, Luminary099/*.md), parses each file, and reports rule violations.

Phase Wall time (modern laptop)
npm install (cold, no cache) 5–15 s
bun install (cold) <2 s
npm run lint ~1 s
npm run lint:fix ~1 s

There is no parallelism beyond what markdownlint-cli2 provides internally. The lint completes well within any reasonable CI budget.

6.2 AGC runtime characteristics (for source-reading context)

The original AGC ran at 1.024 MHz with ~12 µs per typical instruction — extraordinary slow by modern standards. This drove every architectural decision in the source:

Constraint Source-code consequence
~80,000 instructions/second Tight loops written in interpreter VM rather than native to save program memory; native code for time-critical paths only
36 KW fixed memory Aggressive code reuse; the interpreter "fan" is itself a compression mechanism
2 KW erasable memory VAC areas (vector accumulator scratch) are pooled and recycled
Bank-switched memory Bank-aware boilerplate (BANK n, EBANK= label) at the top of every section
No floating point Fixed-point arithmetic everywhere; scaling is encoded into the noun definitions in PINBALL_NOUN_TABLES.agc

Tip

If a routine seems impossibly compact for the math it performs, check whether it is interpretive. The interpreter's higher-level opcodes pack a lot of capability per source line — VLOAD, VSL4, MXV, STCALL and so on each do work that would take many native instructions.

6.3 The interpreter as a runtime

INTERPRETER.agc is the longest single source file in either program (Comanche055 pages 1107–1199, Luminary099 pages 1002–1094). It implements approximately 100 interpretive opcodes used pervasively by guidance, navigation, and integration code. Structurally, it is a small VM complete with:

  • An opcode dispatch table (the interpretive "fan").
  • A push-down stack.
  • VAC and MPAC scratch areas (vector and primary accumulators).
  • Type-aware opcodes (single-precision, double-precision, vector, mixed).
  • Subroutine call / return (CALL, EXIT).

Code that does any meaningful guidance math (Kalman filter updates, conic propagation, IMU compensation, lunar guidance equations) is mostly interpretive. Reading INTERPRETER.agc is essentially reading the runtime that those routines target.

When you see code like:

        STCALL  TPIP                # interpretive: store, then call
        VSL4    MXV
        REFSMMAT

…that is interpretive code, executed by the interpreter, not native AGC instructions. Native instructions are short opcodes like TC, CA, TS, XCH, INDEX, EXTEND. The transition between the two modes is mediated by TC INTPRET (enter interpreter) and EXIT (return to native).

6.4 Real-time scheduling

The most timing-critical code in either program is the Digital Auto-Pilot (DAP): P-AXIS_RCS_AUTOPILOT.agc, Q_R-AXIS_RCS_AUTOPILOT.agc, DAPIDLER_PROGRAM.agc, DAP_INTERFACE_SUBROUTINES.agc in Luminary099; RCS-CSM_DIGITAL_AUTOPILOT.agc and the TVCDAPS.agc family in Comanche055.

DAP runs at high priority off T5RUPT for fast-loop autopilot updates. Spurious interrupts (rendezvous-radar in Apollo 11) can starve the executive of VAC areas — this is exactly what triggered the 1201/1202 alarms during the descent. The restart logic was specifically designed to handle this scheduling failure and recover the active mission program.


7. Security

There is no traditional attack surface: the repository ships text files, no executables, no installable code, no service. Standard "supply chain" considerations:

Concern Status
Executable code in the repo None. .agc files are plain text.
Network exposure None. Static files.
Secrets / credentials None. Public domain code with public attribution.
Dependency CVEs Surface limited to markdownlint-cli2. Watch via npm audit.

Warning

The markdownlint-cli2 lint dependency itself has occasionally had transitive vulnerabilities. Run npm audit fix periodically and bump the pinned ^0.16.0 upper bound when a security release lands. This is the only realistic security maintenance burden the repository carries.

7.1 Public-domain status

NASA software written under government contract before 1978 has no copyright protection in the United States. The original Apollo Guidance Computer source code was developed by the MIT Instrumentation Laboratory under contract NAS 9-4065 with the NASA Manned Spacecraft Center (now Johnson Space Center). The contract block in Comanche055/CONTRACT_AND_APPROVALS.agc records the names and signing date of the original engineering team, including Margaret H. Hamilton (Colossus Programming Leader), Daniel J. Lickly, Fred H. Martin, Norman E. Sears, Richard H. Battin, David G. Hoag, and Ralph R. Ragan, dated 28 March 1969.

The LICENSE.md and per-file # Copyright: Public domain. headers reaffirm the public-domain status. Anyone may copy, modify, and redistribute the source without restriction.

Important

The transcription work performed by community contributors is also released under the same public-domain understanding. The repository accepts proof-reading PRs only; "improvements" or new code would not be in the public domain by default and are out of scope.

7.2 Mirroring for preservation

To protect against single-platform availability risk, the repository is mirrored at:

  • Software Heritage — guaranteed preservation infrastructure.
  • Virtual AGC — independent transcription with its own scan source.
  • Multiple personal forks and mirrors across GitHub, GitLab, and other Git hosts.

Any maintainer who is concerned about long-term availability should clone with git clone --mirror to preserve the full history independent of GitHub.

7.3 No CI / no automation today

There is no GitHub Actions workflow checked in. Linting is performed locally by contributors. Adding a workflow that runs npm run lint on PRs is an obvious enhancement (see Section 8.6). Until that lands, the repository does not run any automated code on push, which means the CI attack surface is also nil.


8. Developer Internals

8.1 The operating-system layer

The AGC has no traditional OS — its scheduler, multitasker, and interrupt dispatch are all hand-coded into the rope. The relevant source files form a tightly-coupled core:

                          +------------------+
                          | INTERRUPT_LEAD_  |   <- vector table at fixed addr 4000
                          | INS.agc          |
                          +---------+--------+
                                    |
            +-----------------------+--------------------+
            v                                            v
    +---------------+                          +---------------------+
    | T4RUPT_PROGRAM|---------+                | KEYRUPT_UPRUPT.agc  |
    | T6-RUPT_PROG..|         |                | (DSKY + uplink ISR) |
    +---------------+         |                +---------------------+
            |                 v
            v          +-----------+
    +---------------+  | WAITLIST  |  <-- timed-task scheduler
    | EXECUTIVE.agc |<-+ .agc      |       (TASKOVER, NEWJOB, etc.)
    | (cooperative  |  +-----------+
    | priority      |        |
    | scheduler)    |        v
    +-------+-------+  +----------------+
            |          | RESTARTS_      |  <-- fault-tolerant restart
            +--------> | ROUTINE.agc    |       (1201, 1202, etc.)
                       +----------------+

Interrupt vector

INTERRUPT_LEAD_INS.agc is the AGC's vector table at fixed address 4000. Each interrupt type lands at a specific offset:

Vector Source Trigger
4000 GO (fresh start) Power-on reset
4004 T6RUPT TIME6 counter overflow (digital autopilot)
4010 T5RUPT TIME5 counter overflow (autopilot)
4014 T3RUPT TIME3 counter overflow (waitlist)
4020 T4RUPT TIME4 counter overflow (DSKY refresh, ~10 ms)
4024 KEYRUPT1 DSKY keypress
4030 KEYRUPT2 (LM only) AOT mark button
4034 UPRUPT Uplink telemetry character received
4040 DOWNRUPT Downlink telemetry character buffer empty
4044 RADAR RUPT Radar data ready
4050 RUPT10 Hand-controller / CDU drift

Each lead-in saves accumulator state (DXCH ARUPT) and dispatches to the actual handler in another bank.

The executive

EXECUTIVE.agc is the cooperative priority scheduler. Jobs are submitted via two entry points:

  • NOVAC — priority job that needs no Vector Accumulator (VAC) area.
  • FINDVAC — priority job that needs a VAC area (for interpretive math).

Each job carries a priority byte. The executive maintains a fixed-size table of core sets (job control blocks) and VAC areas (interpretive scratch). Overflow of either table is the cause of the now-famous 1202 (no VAC) and 1201 (no core set) restart alarms.

Job dispatch is cooperative: a running job yields by calling TC ENDOFJOB (no more work), TC JOBSLEEP (block on event), or TC CHANG1 (suspend for higher priority).

The waitlist

WAITLIST.agc implements the timed task scheduler — a min-heap-like structure where each entry has a delta-time relative to the entry above it. The T3RUPT interrupt fires on TIME3 overflow, decrements the head entry, and runs any task whose delta has reached zero.

This is how the AGC schedules deferred work: TC WAITLIST with a delta-time and a 2CADR (bank+address) installs a future task without blocking the current job.

Restart logic

The restart architecture is one of the AGC's most celebrated achievements. RESTARTS_ROUTINE.agc and FRESH_START_AND_RESTART.agc together implement:

  • Phase tables (PHASE_TABLE_MAINTENANCE.agc): each major mission program registers its current phase as a redundant pair of phase numbers.
  • Restart on alarm: when the executive overflows or the program detects an inconsistency, it invokes a software restart that re-validates phase tables, kills broken jobs, and resumes from the last known-good phase.
  • Hardware restart (V69): the operator can force a restart manually.

Important

During the Apollo 11 powered descent, spurious rendezvous-radar interrupts overloaded the executive's VAC pool, triggering 1201/1202 alarms. The restart logic in these files re-issued the in-progress mission program (P63 then P64) without losing position/velocity state. Buzz Aldrin and Neil Armstrong continued the descent because the restart system worked exactly as designed by the MIT team.

8.2 The verb/noun operating language

The astronaut interacts with the AGC through the DSKY — a 19-key keypad and a 7-digit display. Operations are encoded as a verb (action) plus a noun (data subject).

File Role
PINBALL_GAME_BUTTONS_AND_LIGHTS.agc Keypad scanner, display driver, lamp logic, verb/noun decoder
PINBALL_NOUN_TABLES.agc Noun definitions, scaling, units, decimal/octal display rules
EXTENDED_VERBS.agc Verbs ≥40 (the operator-action verbs)
DISPLAY_INTERFACE_ROUTINES.agc Display-mode arbitration (priority displays vs. monitor displays)

Verb taxonomy

Verbs <40 are decoded inside PINBALL_GAME_BUTTONS_AND_LIGHTS.agc and are mostly display verbs (V01-V05 = display octal, V06-V07 = display decimal, V11-V25 = monitor variants, V37 = change major mode).

Verbs ≥40 are dispatched from a fan-out table at the top of EXTENDED_VERBS.agc (the LST2FAN table). A representative excerpt from Luminary099:

Verb Routine Action
V37 (in pinball) Change major mode (selects P-program)
V40 VBZERO Zero (used with Noun 20 or 72 only)
V42 IMUFINEK Fine-align IMU
V47 V47TXACT AGS (Abort Guidance System) initialisation
V49 CREWMANU Start automatic attitude maneuver
V57 LRON Permit landing-radar updates
V58 LROFF Inhibit landing-radar updates
V63 R04 Sample radar once per second
V69 VERB69 Force a hardware restart
V70-V73 V7?UPDAT Telemetry update (liftoff time, universal block, single, AGC time)
V75 OUTSNUFF Enable U,V jets during DPS burns
V76 MINIMP Minimum-impulse mode
V77 NOMINIMP Rate-command mode
V82 V82PERF Request orbit-parameter display (R30)
V83 V83PERF Request rendezvous-parameter display (R31)
V92 SYSTEST Operate IMU performance test
V96 VERB96 Interrupt integration and go to P00

The exact verb roster differs between Comanche055 and Luminary099 — the LM has lunar-radar verbs, the CSM has reentry verbs.

Noun taxonomy

PINBALL_NOUN_TABLES.agc defines each noun's:

  • Component count (1, 2, or 3 registers).
  • Scale factor (units interpretation).
  • Display format (octal vs. decimal, sign rules).
  • Type (normal noun vs. mixed-noun).

Nouns 0–17 are reserved for DSKY internal use; nouns 18+ encode mission data (e.g. N17 = ICDU angle, N20 = present spacecraft attitude, N62 = present velocity).

8.3 Mission programs (P-program catalogue)

Mission programs are the high-level state machines. Each P-program drives one phase of the mission.

Comanche055 (CSM) major P-programs

Program File(s) Phase
P11 P11.agc Earth orbit insertion monitor
P20-P25 P20-P25.agc Rendezvous navigation, sextant marking
P30-P37 P30-P37.agc External Δv, return-to-Earth, deorbit targeting
P32-P33 P32-P33_P72-P73.agc Coelliptic sequence initiate (CSI)
P34-P35 P34-35_P74-75.agc Transfer phase initiate (TPI) targeting
P40-P47 P40-P47.agc Major SPS / RCS burns
P51-P53 P51-P53.agc IMU realignment via star sightings
P61-P67 P61-P67.agc Atmospheric entry guidance
P76 P76.agc Target Δv update from MSFN
P37/P70 P37_P70.agc Return-to-Earth + entry maneuver

Luminary099 (LM) major P-programs

Program File(s) Phase
P12 P12.agc LM ascent — aborted-stage
P20-P25 P20-P25.agc Rendezvous navigation (LM perspective)
P30/P37 P30_P37.agc External Δv targeting
P32-P35/P72-P75 P32-P35_P72-P75.agc CSI, TPI, and active-vehicle counterparts
P40-P47 P40-P47.agc DPS / APS burn programs
P63-P67 THE_LUNAR_LANDING.agc + LUNAR_LANDING_GUIDANCE_EQUATIONS.agc Powered descent (P63 braking, P64 visibility, P66 ROD, P67 landed)
P70-P71 P70-P71.agc DPS / APS abort
P76 P76.agc Target Δv update

R-routine catalogue (selected)

R-routines are reusable subroutines callable from any P-program:

Routine File Purpose
R02 various IMU status check
R04 (called via V63) Sample radar
R30 R30.agc Orbit parameter display
R31 R31.agc Rendezvous parameter display
R60/R61/R62 R60_62.agc Crew-defined attitude maneuver display
R63 R63.agc (LM only) LM body-vector pointing
R77 (called via V78/V79) LR spurious-return test

The full catalogue is enumerated in each program's README.md.

8.4 The "executive overflow" pattern (1201/1202)

The cause of the famous Apollo 11 alarms is structurally simple:

  1. The executive maintains fixed-size tables of core sets (job control blocks) and VAC areas (interpretive scratch).
  2. When a new job is requested via NOVAC or FINDVAC and either table is full, the executive cannot allocate.
  3. Rather than hang, the executive posts a program alarm (1201 or 1202) and triggers a software restart.
                NOVAC entry
                    |
        +-----------+-----------+
        v                       v
    free core set?          alarm 1201
        |                  + restart
        v
    install in pool

The restart path:

  1. Saves the current major mode and any registered restart-protected variables.
  2. Walks the phase table; each P-program records its current phase as a redundant pair (PHASE_TABLE_MAINTENANCE.agc).
  3. Re-issues the active P-program from its last good phase.
  4. Continues at the recovered point, having dropped the broken jobs.

Caution

The restart only works because every mission program is written to be restart-safe: it must register its phase before doing irreversible work, and it must be re-entrant from the registered phase. New code added to a P-program without honouring this contract would break restart recovery — but no new code is being added (this is a historical archive), so the contract is automatically preserved.

8.5 Idiomatic patterns

Reading any .agc file, you will see consistent conventions established by MIT in 1969:

  • Tab-indented two-column layout: label column + opcode/operand column, both at fixed character positions.
  • All-caps labels and opcodes: no mixed case anywhere in source.
  • Pound-sign comments: # introduces a line or trailing comment.
  • Bank-aware boilerplate: every section starts with BANK n / SETLOC ... / EBANK= ... to assert assembler context.
  • Page-number anchors: # Page NNN comments mark printout page boundaries.
  • Header copyright/provenance block: every file has the standard header described in Section 4.4 of the User Guide.
  • COUNT* directives: COUNT* $$/<TAG> records the section name for the GAP-generated cross-reference (yaYUL emits these into the .lst.html).

Common macros:

  • BANKCALL + CADR <label> — call a routine in another fixed bank with automatic bank save/restore.
  • TC INTPRET — enter the interpreter; the next bytes are interpretive opcodes until EXIT.
  • INHINT / RELINT — disable / enable interrupts (used to bracket critical sections).
  • EXTEND — flag the next instruction as an "extend" instruction (extra opcode space).
  • CCS — count, compare, skip (the AGC's primary branch instruction; tests sign + zero of operand and skips by 0/1/2 instructions).

These conventions are historical artefacts. Do not modernise them.

8.6 Potential improvements

These are out-of-scope for the proof-reading focus of the repository, but worth tracking as long-term enhancements:

Automated scan-vs-source validation (issue #960)

A pipeline that runs OCR on each scanned page, normalises whitespace, and diffs against the transcription would catch many proof-reading discrepancies automatically. Likely tools: Tesseract OCR with a custom AGC training set, or a hand-tuned matcher that exploits the highly regular two-column layout.

GitHub Actions CI for markdown lint

A workflow file at .github/workflows/lint.yml would run npm run lint on every PR. This catches translation-formatting regressions before merge.

name: Lint
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - run: npm run lint

Per-program assembly check

A second CI step could git submodule add or pin a Virtual AGC commit and run yaYUL Luminary099/MAIN.agc, asserting that the binary image matches a known-good SHA-256. This would catch semantic corruption (label shifts, missing instructions) that markdownlint cannot.

Translations/ glob case sensitivity

package.json's lint script targets translations/*.md (lower-case) but the repository folder is Translations/. Aligning the glob to Translations/*.md would make linting consistent on case-sensitive filesystems.

Translation status table

A maintained table mapping language → last-updated commit → up-to-date-vs-master status would help translators identify which localisations need refreshing. Could be auto-generated from git log on each Translations/README.<lang>.md.

Page-number index

A machine-readable manifest (e.g. pages.json) mapping (program, file, page-range) would enable scan-viewer tools to deep-link from a page number to the exact file and line, accelerating proof-reading.

8.7 Code quality signals

Both Comanche055 and Luminary099 are remarkably well-commented for assembly code of their era. Substantial blocks of in-line prose explain mission intent, rationale for constants, and edge-case handling. Many comments preserve the original engineers' voices — BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc is the most-quoted example, but any file's comment density is striking compared to typical 1960s assembly listings.

The interpreter's existence is itself a quality signal: a 1965-1969 team built a compact virtual machine for vector and double-precision arithmetic to compress program memory and improve readability, and they carried it forward across multiple program builds. The INTERPRETER.agc file is a genuinely impressive piece of language design for a memory-constrained machine.


9. Integration Points

9.1 Upstream dependencies

Dependency Role Direction
MIT Museum (hardcopy custody) Source of scanned printouts Inbound (scans flow in)
Paul Fjeld (digitisation) Page-image scans Inbound
markdownlint-cli2 (npm) Markdown lint of all .md files Build-time only
Bun runtime (optional) Faster install via lockfile Optional

9.2 Downstream consumers

Consumer Role URL
Virtual AGC Independent transcription + simulator + assembler https://github.com/virtualagc/virtualagc
Software Heritage Archival mirror Snapshots master automatically
Educational sites and books Cite individual files / lines e.g. Digital Apollo, Sunburst and Luminary
Side-by-side scan viewer Web tool that renders source next to scans https://28gpc.csb.app/

9.3 No webhooks, no APIs

There are no webhooks fired from this repository, no REST API exposed, no push-notification integration. Downstream consumers poll GitHub or rely on the Software Heritage snapshot cadence.

9.4 Maintainer contact channels

Channel URL / Contact
Repository issues https://github.com/chrislgarry/Apollo-11/issues
Repository PRs https://github.com/chrislgarry/Apollo-11/pulls
Virtual AGC project (assembler/simulator) https://github.com/virtualagc/virtualagc
High-resolution scan custodian Ron Burkey, [email removed]
Original digitisation Paul Fjeld (via Virtual AGC project)
Hardcopy custodian MIT Museum, https://web.mit.edu/museum/

9.5 File-tree statistics

Metric Value
Total tracked files (commit 247dd7d) 254
.agc source files 165 (80 Comanche, 85 Luminary)
Markdown files (root + program + translations) 76
Configuration files 5 (.editorconfig, .gitignore, .markdownlint.yml, package.json, bun.lockb)
Languages with README translations 39+
Languages with CONTRIBUTING translations 28

9.6 Key historical dates encoded in source

Date Event
28 March 1969 Margaret Hamilton signs off Comanche055 contract block
1 April 1969 Comanche055 assembled (10:28 APR. 1, 1969)
14 July 1969 Luminary099 hardcopy printed (16:27 JUL. 14, 1969)
16 July 1969 Apollo 11 launch
20 July 1969 Eagle lands at Tranquility Base, running Luminary099
24 July 1969 Splashdown, Columbia running Comanche055 through reentry

9.7 Quick command reference

# Clone
git clone https://github.com/chrislgarry/Apollo-11.git
cd Apollo-11

# Install lint deps (npm)
npm install

# Or with Bun (matches checked-in lockfile)
bun install

# Lint markdown
npm run lint
npm run lint:fix

# Find a label across the whole tree
grep -rn "^P63LM" .

# Show file headers (page ranges, transcriber, mod history)
head -20 Luminary099/THE_LUNAR_LANDING.agc

# Count source files in each program
ls Comanche055/*.agc | wc -l
ls Luminary099/*.agc | wc -l

9.8 Glossary

AGC — Apollo Guidance Computer. The 15-bit, ~64 KW core-rope flight computer.

Bank, BANK directive — Memory-bank selector. AGC has banked fixed and erasable memory; BANK n directives in source declare which bank the assembler should fill.

BANKCALL — Macro for cross-bank function calls (saves and restores FBANK).

Block II — The AGC hardware revision used on Apollo 11 (and all manned Block lunar missions). Block I was the unmanned/early-test variant.

CADR — A 2-word combined-address-register. Encodes (bank, address) for cross-bank dispatch.

CDU — Coupling Data Unit. Hardware that translates IMU resolver angles into AGC-readable counters.

CMC / LGC — Command Module Computer / Lunar [Module] Guidance Computer. Two AGC instances on each mission.

Colossus — Family name of CSM flight programs across multiple Apollo missions. Build 055 = "Comanche" (Apollo 11).

Core rope — The mask-programmed read-only memory used for fixed program storage. Wires literally hand-woven through ferrite cores.

DAP — Digital Auto-Pilot. RCS-jet attitude control law.

DSKY — Display/Keyboard. The astronaut's interface to the AGC.

EBANK — Erasable bank register; EBANK= label declares the assumed bank for subsequent code.

Executive — The AGC's cooperative priority scheduler in EXECUTIVE.agc.

Fixed-fixed — The always-mapped portion of fixed memory (banks 02 and 03), addressable without bank switching.

GAP — The original 1968-era assembler that replaced YUL. No longer available.

IMU — Inertial Measurement Unit. Stable-platform gyro/accelerometer assembly.

Interpreter — The software-implemented virtual machine in INTERPRETER.agc that executes interpretive opcodes (vector/double-precision math).

Interpretive opcode — An opcode of the interpreter VM (e.g. VLOAD, VSL4, MXV, STCALL). Executed by the interpreter, not natively.

Luminary — Family name of LM flight programs. Build 099 = "Luminary 1A" (Apollo 11).

MPAC / VAC — Primary Accumulator / Vector Accumulator. Interpreter scratch areas.

P-program — Mission Program. State machine driving a mission phase (e.g. P63 = lunar-landing braking phase).

R-routine — Reusable subroutine called by P-programs (e.g. R30 = orbit-parameter display).

RCS — Reaction Control System. Attitude-control thrusters.

RUPT — Interrupt. Lead-ins live in INTERRUPT_LEAD_INS.agc at fixed address 4000.

Software restart — The fault-tolerant recovery path triggered by executive overflow. RESTARTS_ROUTINE.agc re-issues the active mission program from its last good phase.

SPS — Service Propulsion System. The CSM main engine. Fired in P40-P47 burns.

TVC — Thrust Vector Control. SPS-engine gimbal control (CSM only).

VAC area — Vector Accumulator scratch block allocated by the executive to interpretive jobs.

Verb / Noun — DSKY operating language. Verb = action, Noun = data subject.

Waitlist — Timed-task scheduler in WAITLIST.agc, driven by T3RUPT.

yaYUL / yaAGC / yaDSKY2 — yet-another re-implementations of the historical assembler / simulator / DSKY-UI under the Virtual AGC project (virtualagc/virtualagc).

YUL — The original AGC assembler. No longer available.