Apollo-11 源代码怎么看:AGC 指令舱与登月舱程序阅读指南

介绍 chrislgarry/Apollo-11 仓库中的 Comanche055 与 Luminary099,说明如何下载、定位导航程序、理解 AGC 汇编文件并使用 Virtual AGC 继续编译研究。

chrislgarry/Apollo-11 保存了 Apollo 11 导航计算机的源代码转录。这里不是纪念性质的代码仿写,而是从 MIT Museum 保存的纸质程序清单数字化而来的 AGC 源码,包括指令舱使用的 Comanche055 和登月舱使用的 Luminary099

第一次打开仓库时,最容易困惑的地方是:为什么没有熟悉的 src、构建脚本和应用入口?答案是,这套软件来自 1969 年,其组织方式、汇编工具和硬件模型都早于现代软件工程习惯。本文从目录入手,给出一条能够实际读下去的路线。

快速答案

先克隆源码:

1
2
git clone https://github.com/chrislgarry/Apollo-11.git
cd Apollo-11

然后根据飞船模块选择目录:

  • Comanche055/:指令舱 Command Module 的 Colossus 2A 程序;
  • Luminary099/:登月舱 Lunar Module 的 Luminary 1A 程序。

建议不要从头逐行阅读。先打开各目录的 README.mdMAIN.agc,再按任务查看 ALARM_AND_ABORT.agcEXECUTIVE.agcDISPLAY_INTERFACE_ROUTINES.agc 等模块。若要编译或模拟运行,应转向 Virtual AGC,Apollo-11 仓库本身主要承担历史源码保存和校对工作。

这个仓库保存了什么

Apollo Guidance Computer,简称 AGC,是 Apollo 飞船制导、导航和控制系统的重要组成部分。Apollo 11 的指令舱和登月舱任务不同,因此使用两套程序:

目录 对应程序 用途
Comanche055 Colossus 2A / Comanche revision 055 指令舱导航、姿态控制、轨道计算和再入等任务
Luminary099 Luminary 1A / LMY99 登月舱下降、着陆、上升和交会等任务

仓库说明记录的装配日期分别是 1969 年 4 月 1 日和 1969 年 7 月 14 日。源码由 Virtual AGC 社区和 MIT Museum 相关人员根据纸质清单扫描件转录、整理,并持续接受对照原始扫描件的校正。

这意味着仓库的主要目标是忠实保存历史材料,而不是把程序重构成现代代码。看到拼写、注释格式或不熟悉的模块边界时,不宜直接按今天的编码规范去“修复”。

为什么源代码被拆成大量 .agc 文件

原始程序是整体装配的单体代码。当时没有今天常见的编译、链接流程,程序模块更接近一叠叠按顺序组合的穿孔卡片。数字化项目为了方便管理,才把庞大的源码拆成多个 .agc 文件,再通过包含关系还原整体顺序。

因此,这里的文件拆分代表自然的子程序边界,但不等同于现代项目中的独立编译单元。每个目录的 README.md 都提供 Source Code Index,把文件与原始打印清单页码对应起来。阅读时应把它当作目录索引,而不是普通项目说明。

AGC 原有的 YUL 和后来的 GAP 汇编器已经无法直接取得。Virtual AGC 项目提供的 yaYUL 使用略有不同的输入格式,仓库中的转录源码也为 yaYUL 做了适配。

推荐的阅读顺序

1. 先看合同、装配信息和入口

从下面三个文件开始,可以先建立程序全貌:

1
2
3
CONTRACT_AND_APPROVALS.agc
ASSEMBLY_AND_OPERATION_INFORMATION.agc
MAIN.agc

CONTRACT_AND_APPROVALS.agc 保留项目身份、合同和审批信息。ASSEMBLY_AND_OPERATION_INFORMATION.agc 说明装配结构与子程序调用。MAIN.agc 则把多个源码片段按顺序纳入完整程序。

2. 再看任务含义明确的模块

相比直接研究指令集,先选择文件名能够说明用途的模块更容易进入状态:

1
2
3
4
5
6
ALARM_AND_ABORT.agc
FRESH_START_AND_RESTART.agc
EXECUTIVE.agc
WAITLIST.agc
DISPLAY_INTERFACE_ROUTINES.agc
PINBALL_GAME_BUTTONS_AND_LIGHTS.agc

其中 EXECUTIVE.agcWAITLIST.agc 有助于理解任务调度;PINBALL_GAME_BUTTONS_AND_LIGHTS.agc 与宇航员使用的显示和键盘界面有关;告警与重启模块则能看到系统如何处理异常状态。

3. 最后进入具体飞行阶段

指令舱目录包含轨道积分、自动机动、再入控制和姿态控制等程序。登月舱目录更适合从下降制导、着陆阶段、数字自动驾驶和上升程序等任务切入。

文件名中的 Pxx 通常对应宇航员通过 DSKY 选择的程序编号,例如仓库中可以看到 P40-P47.agcP51-P53.agc 等文件。Rxx 则常用于例程编号。阅读这些文件前,先了解对应飞行阶段和操作流程,会比单独翻译汇编指令有效得多。

在本地快速定位代码

仓库文件很多,使用文本搜索比逐个点击更方便。在 Git Bash、Linux 或 macOS 中可以运行:

1
2
3
find Comanche055 Luminary099 -name "*.agc" | sort
grep -Rni "ALARM" Comanche055 Luminary099
grep -Rni "RESTART" Comanche055 Luminary099

安装了 ripgrep 时,可以使用更快的搜索方式:

1
2
rg -n "ALARM|RESTART" Comanche055 Luminary099 -g "*.agc"
rg -n "1201|1202" Luminary099 -g "*.agc"

第二条命令可用于寻找著名的 12011202 程序告警相关位置,但不要仅凭一次字符串匹配就断定完整触发逻辑。告警编号、产生条件、任务调度和显示过程可能分散在多个模块中,需要结合调用关系阅读。

在 PowerShell 中可以这样列出源码:

1
2
Get-ChildItem -Path Comanche055,Luminary099 -Filter *.agc -Recurse
Select-String -Path Comanche055\*.agc,Luminary099\*.agc -Pattern 'ALARM|RESTART'

.agc 文件应该怎么看

AGC 汇编与今天常见的 x86 或 ARM 汇编差异很大。面对一行代码时,可以依次识别以下部分:

  1. 标签:为程序入口或数据位置命名;
  2. 操作码:AGC 指令或解释器指令;
  3. 操作数:地址、常量或符号;
  4. 注释:解释算法、飞行条件和工程限制;
  5. 页码标记:帮助与原始纸质清单和扫描件对应。

不要只把注释当趣味文本。对历史软件而言,注释常常承担需求说明、运行条件和设计理由的作用。结合相邻模块、符号定义和原始清单页码阅读,才能避免把一个局部标签误解为完整功能。

如何编译和模拟运行

Apollo-11 仓库的 README 明确把编译需求指向 Virtual AGC。推荐流程是:

  1. 保留 Apollo-11 仓库作为历史源码和文件索引;
  2. 阅读 Virtual AGC 当前平台的构建说明;
  3. 使用其中的 yaYUL 汇编器和 AGC 模拟器;
  4. 对照目标程序版本选择 Comanche 或 Luminary 源码;
  5. 比较汇编结果、校验和与项目提供的参考信息。

Virtual AGC 支持的平台、依赖和构建命令可能随版本变化,执行前应以其仓库最新文档为准。不要假设在 Apollo-11 根目录运行通用的 makenpm install 就能得到飞行程序镜像;根目录中出现现代项目文件,并不改变 .agc 历史源码的实际工具链。

如何验证转录是否准确

这个项目欢迎贡献,但修正必须以原始扫描件为依据。发现可疑字符或拼写时,建议按以下步骤处理:

  1. 在目录 README.md 中找到对应的原始页码;
  2. 打开项目链接的 Comanche 055 或 Luminary 099 扫描资料;
  3. 对比代码、注释、符号和页码标记;
  4. 阅读 CONTRIBUTING.md
  5. 提交只包含明确转录差异的 Pull Request。

不要为了统一大小写、修正历史拼写或采用现代格式而批量格式化源码。历史档案项目首先追求可追溯性,一次看似整洁的机械修改可能让校对工作更困难。

常见问题

这是 Margaret Hamilton 一个人写的吗?

不是。仓库的合同与审批资料列出 Margaret H. Hamilton 为 Colossus Programming Leader,同时也记录了多位项目负责人。Apollo 软件由团队协作完成,把整个仓库归于单个程序员并不准确。

GitHub 上的代码就是飞船当年保存的原始文件吗?

更准确地说,它是根据 MIT Museum 保存的纸质清单扫描件转录并为 yaYUL 适配的版本。仓库保留了原始程序内容和页码对应关系,但载体与格式已经过数字化整理。

为什么分成指令舱和登月舱两套程序?

两个飞行器承担的任务不同。指令舱要处理轨道、姿态、交会和再入等工作,登月舱则要完成下降、着陆、月面起飞和交会,因此各自使用针对任务设计的 AGC 程序。

可以把这些代码直接用于现代航天系统吗?

不应这样做。该仓库适合历史研究、计算机体系结构学习和模拟实验,不是经过现代环境验证的生产软件。现代安全关键系统需要独立的需求、验证、认证和硬件适配流程。

总结

阅读 Apollo 11 源码的正确入口不是从第一行硬啃到最后一行,而是先区分 Comanche055Luminary099,利用目录索引找到任务模块,再结合原始页码、AGC 指令集和 Virtual AGC 工具链逐层深入。这个仓库既是一份可搜索的历史软件档案,也展示了在资源极其有限的计算机上,飞行控制、任务调度、告警恢复和人机交互如何被组织成完整系统。

项目地址:chrislgarry/Apollo-11

模拟与编译工具:Virtual AGC