# Apollo 11 AGC Source Administrator & Developer Guide

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](https://archive.softwareheritage.org/browse/origin/https://github.com/chrislgarry/Apollo-11/) for long-term preservation.

The repository is *not* a fork of [Virtual AGC](https://github.com/virtualagc/virtualagc); 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):

```text
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:

```text
        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](https://github.com/virtualagc/virtualagc). 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`

```ini
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`

```yaml
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`

```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](https://bun.sh/) 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:

```bash
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](https://github.com/virtualagc/virtualagc). 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](https://github.com/chrislgarry/Apollo-11/issues/973)) | Close politely |
| Validation tooling request | [#960](https://github.com/chrislgarry/Apollo-11/issues/960) "automated scan validation" | Track as long-running enhancement |

> [!TIP]
> When closing an off-topic issue, point the submitter to the [Virtual AGC](https://github.com/virtualagc/virtualagc) project for assembly/simulation questions and to the [Apollo Guidance Computer Software History on Wikipedia](https://en.wikipedia.org/wiki/Apollo_Guidance_Computer) 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](https://github.com/chrislgarry/Apollo-11/issues/960) | (project-level) Add line-by-line validation tests against scans | OPEN |
| [#608](https://github.com/chrislgarry/Apollo-11/issues/608) | `MEASUREMENT_INCORPORATION.agc` | OPEN |
| [#217](https://github.com/chrislgarry/Apollo-11/issues/217) | `INTERPRETER.agc` | OPEN |
| [#566](https://github.com/chrislgarry/Apollo-11/issues/566) | `AOTMARK.agc` | OPEN |
| [#234](https://github.com/chrislgarry/Apollo-11/issues/234) | `P34-35_P74-75.agc` | OPEN |
| [#204](https://github.com/chrislgarry/Apollo-11/issues/204) | `ERASABLE_ASSIGNMENTS.agc` | OPEN |
| [#639](https://github.com/chrislgarry/Apollo-11/issues/639) | `SPS_BACK-UP_RCS_CONTROL.agc` | OPEN |
| [#648](https://github.com/chrislgarry/Apollo-11/issues/648) | `TJET_LAW.agc` | OPEN |
| [#647](https://github.com/chrislgarry/Apollo-11/issues/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

```text
   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:

```text
        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](https://archive.softwareheritage.org/browse/origin/https://github.com/chrislgarry/Apollo-11/) — guaranteed preservation infrastructure.
- [Virtual AGC](https://github.com/virtualagc/virtualagc) — 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:

```text
                          +------------------+
                          | 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.

```text
                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](https://github.com/chrislgarry/Apollo-11/issues/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.

```yaml
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](https://github.com/virtualagc/virtualagc) | Independent transcription + simulator + assembler | <https://github.com/virtualagc/virtualagc> |
| [Software Heritage](https://archive.softwareheritage.org/) | 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

```bash
# 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](https://github.com/virtualagc/virtualagc)).

**YUL** — The original AGC assembler. No longer available.

---

_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. Unofficial; not affiliated with or reviewed by the project._
