新手考古路线图:3 步定位登月舱降落代码 BURN, BABY, BURN——从 Luminary099 源码索引到 P63 着陆算法【免费下载链接】Apollo-11Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.项目地址: https://gitcode.com/GitHub_Trending/ap/Apollo-112019 年 7 月,为纪念人类登月 50 周年,阿波罗 11 号制导计算机(AGC)的原始汇编源码被上传至 GitHub 并连续霸榜趋势热区。这个仓库里没有一行 C 语言,只有数千页由 NASA/MIT Instrumentation Laboratory 工程师逐页敲出的 AGC 汇编——指令舱跑 Colossus 2A(Comanche055),登月舱跑 Luminary 1A(Luminary099)。对很多新手来说,第一次打开它时的体验是崩溃的:几十个名为P20-P25.agc、R60_62.agc的大写文件,动辄上千行的TCF/CAF/DXCH助记符,既没有函数签名也没有调用图。但恰恰是这套代码,在 1969 年 7 月 20 日把鹰号登月舱从环月轨道安全降落到静海。其中最关键的一段,就是那个以电台 DJ 口头禅命名的点火主流程BURN, BABY, BURN。这篇文章将沿着一条「索引 → 入口 → 运行时」的三步路线,带你亲手定位 P63 着陆程序与点火模块,看懂 DSKY 上闪烁的告警码背后到底发生了什么。第一步:把 Luminary099 当成「按页组织的线装书」来读这个仓库的根目录下躺着两套源码,Luminary099 就是登月舱那一套。与今天的工程惯例不同,它没有任何目录层级——80 多个.agc文件平铺在一个目录里,而真正的「索引」恰恰藏在其中两个文件里。打开 Luminary099/README.md,你会看到一张完整的Source Code Index表:每个源文件都对应一份原始纸质扫描清单上的页码区间。例如:源文件原始页码BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc731–751THE_LUNAR_LANDING.agc785–792P40-P47.agc752–784LUNAR_LANDING_GUIDANCE_EQUATIONS.agc798–828EXECUTIVE.agc1103–1116ALARM_AND_ABORT.agc1381–1385为什么按页组织?因为这套代码是从 MIT 博物馆保存的纸质硬拷贝逐页扫描、逐行转录出来的(README 中记录了 Paul Fjeld 负责数字化、Deborah Douglas 促成此事的来历),页码就是回溯原始扫描件的事实依据。理解这套代码的组织方式,还有一个更本质的入口:Luminary099/MAIN.agc。它只有 91 行,内容是从$ASSEMBLY_AND_OPERATION_INFORMATION.agc到$SPS_BACK-UP_RCS_CONTROL.agc的完整$包含清单,即所谓的monolithic 单体构建——所有子程序被汇编器拼进一个可执行映像,而不是各自汇编后链接。README 对此解释得很直白:当年开发团队根本没有链接器。复用代码的方式是把你的那叠打孔卡插到别人的那叠打孔卡里。所以当你看到某个符号(比如BURNBABY)在多个文件间跳转时,别惊讶,这就是 1960 年代的「模块化」。第二步:沿 WHICH 寄存器追踪 P63 → BURNBABY 的调用链有了索引,定位就有了抓手。P63(着陆制动段,BRAKING PHASE)的入口在 THE_LUNAR_LANDING.agc 第 785–792 页,文件头注释直接标注了它的身份:P63: THE LUNAR LANDING, BRAKING PHASE。它的入口标签是P63LM:P63LM TC PHASCHNG # 进入 P63 阶段 OCT 04024 TC BANKCALL # 执行 IMU 状态检查 R02 CADR R02BOTH CAF P63ADRES # 初始化 WHICH 供 BURNBABY 使用 TS WHICH ... TC POSTJUMP # 交给点火主流程 CADR BURNBABY注意CAF P63ADRES/TS WHICH这两条:WHICH是 ERASABLE_ASSIGNMENTS.agc 中定义的擦写寄存器(WHICH ERASE # B(1),地址 E4),而P63ADRES是GENADR P63TABLE——它把本程序专属配置表的地址放进WHICH,然后跳进点火主流程。这就是 AGC 实现「多程序复用一段公共代码」的方式:点火逻辑只写一遍,程序差异全部收敛到一张常量表里。现在跳到 BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc(第 731–751 页)。文件头注释把设计意图交代得一清二楚:THE MASTER IGNITION ROUTINE IS DESIGNED FOR USE BY THE FOLLOWING LEM PROGRAMS: P12, P40, P42, P61, P63. IT PERFORMS ALL FUNCTIONS IMMEDIATELY ASSOCIATED WITH APS OR DPS IGNITION... BETWEEN THE PRE-IGNITION TIME CHECK -- ARE WE WITHIN 45 SECONDS OF TIG? -- AND TIG + 26 SECONDS, WHEN DPS PROGRAMS THROTTLE UP.也就是说,这个模块覆盖从「点火前 45 秒时间检查」到「TIG+26 秒 DPS 全油门」的整段窗口。而 P63 的专属表P63TABLE就在文件第 127 行:P63TABLE VN 0662 # (0) TCF ULLGNOT # (1) TCF COMFAIL3 # (2) TCF V99RECYC # (3) TCF TASKOVER # (4) TCF P63SPOT # (5) DEC 2240 # (6) EBANK= WHICH 2CADR SERVEXIT # (7) ... TCF P63IGN # (13)主流程BURNBABY通过INDEX WHICH+TCF 5之类的指令按索引取表项,从而把 P12/P40/P42/P63 各自的点火行为区分开。所谓「索引化调度」在今天的表驱动编程里稀松平常,但在 1969 年、在只有 15 位字的机器上,这就是软件工程的最高段位。顺着表项继续追,你能看到完整的点火时间线:TIG-35 ~ TIG-30:设置TIG-35/TIG-30任务点,为重启(restart)留下OCT 20254、OCT 40154之类的阶段标志(PHASCHNG 参数),并在 TIG-35 清屏 5 秒提示「平均 G 计算开始」;TIG-5:TWIDDLE挂起TIG-0任务,同时通过INDEX WHICH / TCF 11进入程序各自的显示切换逻辑;TIG-0(点火时刻):设置IGNFLAG,再TC CHECKMM / DEC 63判断「是不是 P63」——是则启动P63ZOOM(把着陆制导LUNLANAD挂到AVEGEXIT,执行FLATOUT);IGNYET?:检查ASTNFLAG,宇航员是否已在 DSKY 上确认「启动引擎」请求;IGNITION:设置ENGONFLG,往DSALMOUT写入BIT13打开引擎,并用TGO修正TIG;P63IGN(表项 13):初始化燃烧显示、把TIG设为当前时刻供 P70/P71 使用、清空WCHPHASE/FLPASS0——也就是为后续着陆制导算法重置迭代状态。值得一提的是,这套点火程序里还埋着两处拉丁文格言:HONI SOIT QUI MAL Y PENSE(心怀邪念者蒙羞)和表区开头的NOLI SE TANGERE(勿触我)——后者更像写给后来者看的「这里别乱改」。而「BURN, BABY, BURN」这个名字本身也是一段历史:文件头注释记载,在 AGC 开发者 40 周年聚会上,本模块的作者之一 Don Eyles 亲口讲述了命名由来——它源自 1965 年洛杉矶骚乱时期的灵魂乐电台 DJ Magnificent Montague 播放新碟时的招牌口号。一个点火子程序,就这样把太空时代和电台黄金时代串在了一起。第三步:用 DSKY 告警码把代码「运行」起来代码读完了,怎么验证自己读对了?答案是回到它的运行时上下文——DSKY(Display and Keyboard)。阿姆斯特朗和奥尔德林盯着的那块布满数字的小键盘,就是 AGC 唯一的「人机界面」。而告警码,正是理解这段代码在真实飞行中遭遇了什么的钥匙。1969 年 7 月 20 日下降途中,鹰号曾反复响起1201、1202告警。在源码里,这两个码的出处清晰可查——EXECUTIVE.agc 第 147、208 行,任务调度器FINDVAC2找不到空闲 VAC 工作区时:TC BAILOUT1 OCT 1201 # NO VAC AREAS. ... TC BAILOUT1 # NO CORE SETS AVAILABLE. OCT 1202这两行代码的含义,对照 ASSEMBLY_AND_OPERATION_INFORMATION.agc 里完整的告警码总表(Page 23–24)可以确认:# 01201 * EXECUTIVE OVERFLOW - NO VAC AREAS EXEC # 01202 * EXECUTIVE OVERFLOW - NO CORE SETS EXEC换句话说,1201/1202 是执行器(EXECUTIVE)的资源耗尽告警——任务队列里同时并发的任务太多,申请不到 VAC 区或核心集。它不是导航计算「算错了」,而是调度器「忙不过来」。这就是为什么休斯顿的指导官 Steve Bales 能在几秒内判定「继续着陆」:告警揭示的是资源竞争而非算法故障,而BURNBABY里 P63 特有的DEC 63检查、TIGTASK1用CAF PRIO16抢占任务等设计,正是为了把优先级收拢在点火窗口附近。告警的实际显示机制则在 ALARM_AND_ABORT.agc(第 1381–1385 页):ALARM子程序的调用约定是TC ALARM+OCT AAANN(AAA 为告警分类、NN 为编号),它点亮 DSKY 上的PROGRAM ALARM灯,但并不打断正在执行的程序——所以告警与点火主流程可以并行共存。顺着告警码表,你还会发现 P63 专属的几个告警,全部指向本次下降的实时计算:01412 DESCENT IGNALG NOT CONVERGING (P63):着陆点火算法IGNALG未收敛;01406 BAD RETURN FROM ROOTPSRS:表里特别注明,在点火算法阶段它是 POODOO(程序进入死亡状态),而在实际制导阶段才是告警;01703 IGNITION TIME SLIPPED (MIDTOAVE):点火时刻被修正——对应的正是BURNBABY中那段TIG WAS SLIPPED, SO RESET TIG TO 29.9 SECONDS的注释和DCA PIPTIME1 / DXCH TIG代码。至此,三步路线已经走完:索引(README 源码表)→ 入口(THE_LUNAR_LANDING 的 P63LM)→ 运行时(BURNBABY 点火表 + DSKY 告警语义)。回头看,这套 1969 年的「历史遗留代码」之所以至今仍有阅读价值,恰恰在于它把现代嵌入式开发的几大命题——表驱动、可重启的阶段机(PHASCHNG)、资源受限下的任务优先级、以及人与机器的协作接口——全部压缩在了 64KB、1.024MHz 的极端约束里。读懂 BURN, BABY, BURN,不只是读一段汇编,而是读懂了人类第一次在另一个世界着陆时,软件所扮演的角色。【免费下载链接】Apollo-11Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.项目地址: https://gitcode.com/GitHub_Trending/ap/Apollo-11创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
新手考古路线图:3 步定位登月舱降落代码 BURN, BABY, BURN——从 Luminary099 源码索引到 P63 着陆算法【免费下载链接】Apollo-11Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.项目地址: https://gitcode.com/GitHub_Trending/ap/Apollo-112019 年 7 月,为纪念人类登月 50 周年,阿波罗 11 号制导计算机(AGC)的原始汇编源码被上传至 GitHub 并连续霸榜趋势热区。这个仓库里没有一行 C 语言,只有数千页由 NASA/MIT Instrumentation Laboratory 工程师逐页敲出的 AGC 汇编——指令舱跑 Colossus 2A(Comanche055),登月舱跑 Luminary 1A(Luminary099)。对很多新手来说,第一次打开它时的体验是崩溃的:几十个名为P20-P25.agc、R60_62.agc的大写文件,动辄上千行的TCF/CAF/DXCH助记符,既没有函数签名也没有调用图。但恰恰是这套代码,在 1969 年 7 月 20 日把鹰号登月舱从环月轨道安全降落到静海。其中最关键的一段,就是那个以电台 DJ 口头禅命名的点火主流程BURN, BABY, BURN。这篇文章将沿着一条「索引 → 入口 → 运行时」的三步路线,带你亲手定位 P63 着陆程序与点火模块,看懂 DSKY 上闪烁的告警码背后到底发生了什么。第一步:把 Luminary099 当成「按页组织的线装书」来读这个仓库的根目录下躺着两套源码,Luminary099 就是登月舱那一套。与今天的工程惯例不同,它没有任何目录层级——80 多个.agc文件平铺在一个目录里,而真正的「索引」恰恰藏在其中两个文件里。打开 Luminary099/README.md,你会看到一张完整的Source Code Index表:每个源文件都对应一份原始纸质扫描清单上的页码区间。例如:源文件原始页码BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc731–751THE_LUNAR_LANDING.agc785–792P40-P47.agc752–784LUNAR_LANDING_GUIDANCE_EQUATIONS.agc798–828EXECUTIVE.agc1103–1116ALARM_AND_ABORT.agc1381–1385为什么按页组织?因为这套代码是从 MIT 博物馆保存的纸质硬拷贝逐页扫描、逐行转录出来的(README 中记录了 Paul Fjeld 负责数字化、Deborah Douglas 促成此事的来历),页码就是回溯原始扫描件的事实依据。理解这套代码的组织方式,还有一个更本质的入口:Luminary099/MAIN.agc。它只有 91 行,内容是从$ASSEMBLY_AND_OPERATION_INFORMATION.agc到$SPS_BACK-UP_RCS_CONTROL.agc的完整$包含清单,即所谓的monolithic 单体构建——所有子程序被汇编器拼进一个可执行映像,而不是各自汇编后链接。README 对此解释得很直白:当年开发团队根本没有链接器。复用代码的方式是把你的那叠打孔卡插到别人的那叠打孔卡里。所以当你看到某个符号(比如BURNBABY)在多个文件间跳转时,别惊讶,这就是 1960 年代的「模块化」。第二步:沿 WHICH 寄存器追踪 P63 → BURNBABY 的调用链有了索引,定位就有了抓手。P63(着陆制动段,BRAKING PHASE)的入口在 THE_LUNAR_LANDING.agc 第 785–792 页,文件头注释直接标注了它的身份:P63: THE LUNAR LANDING, BRAKING PHASE。它的入口标签是P63LM:P63LM TC PHASCHNG # 进入 P63 阶段 OCT 04024 TC BANKCALL # 执行 IMU 状态检查 R02 CADR R02BOTH CAF P63ADRES # 初始化 WHICH 供 BURNBABY 使用 TS WHICH ... TC POSTJUMP # 交给点火主流程 CADR BURNBABY注意CAF P63ADRES/TS WHICH这两条:WHICH是 ERASABLE_ASSIGNMENTS.agc 中定义的擦写寄存器(WHICH ERASE # B(1),地址 E4),而P63ADRES是GENADR P63TABLE——它把本程序专属配置表的地址放进WHICH,然后跳进点火主流程。这就是 AGC 实现「多程序复用一段公共代码」的方式:点火逻辑只写一遍,程序差异全部收敛到一张常量表里。现在跳到 BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc(第 731–751 页)。文件头注释把设计意图交代得一清二楚:THE MASTER IGNITION ROUTINE IS DESIGNED FOR USE BY THE FOLLOWING LEM PROGRAMS: P12, P40, P42, P61, P63. IT PERFORMS ALL FUNCTIONS IMMEDIATELY ASSOCIATED WITH APS OR DPS IGNITION... BETWEEN THE PRE-IGNITION TIME CHECK -- ARE WE WITHIN 45 SECONDS OF TIG? -- AND TIG + 26 SECONDS, WHEN DPS PROGRAMS THROTTLE UP.也就是说,这个模块覆盖从「点火前 45 秒时间检查」到「TIG+26 秒 DPS 全油门」的整段窗口。而 P63 的专属表P63TABLE就在文件第 127 行:P63TABLE VN 0662 # (0) TCF ULLGNOT # (1) TCF COMFAIL3 # (2) TCF V99RECYC # (3) TCF TASKOVER # (4) TCF P63SPOT # (5) DEC 2240 # (6) EBANK= WHICH 2CADR SERVEXIT # (7) ... TCF P63IGN # (13)主流程BURNBABY通过INDEX WHICH+TCF 5之类的指令按索引取表项,从而把 P12/P40/P42/P63 各自的点火行为区分开。所谓「索引化调度」在今天的表驱动编程里稀松平常,但在 1969 年、在只有 15 位字的机器上,这就是软件工程的最高段位。顺着表项继续追,你能看到完整的点火时间线:TIG-35 ~ TIG-30:设置TIG-35/TIG-30任务点,为重启(restart)留下OCT 20254、OCT 40154之类的阶段标志(PHASCHNG 参数),并在 TIG-35 清屏 5 秒提示「平均 G 计算开始」;TIG-5:TWIDDLE挂起TIG-0任务,同时通过INDEX WHICH / TCF 11进入程序各自的显示切换逻辑;TIG-0(点火时刻):设置IGNFLAG,再TC CHECKMM / DEC 63判断「是不是 P63」——是则启动P63ZOOM(把着陆制导LUNLANAD挂到AVEGEXIT,执行FLATOUT);IGNYET?:检查ASTNFLAG,宇航员是否已在 DSKY 上确认「启动引擎」请求;IGNITION:设置ENGONFLG,往DSALMOUT写入BIT13打开引擎,并用TGO修正TIG;P63IGN(表项 13):初始化燃烧显示、把TIG设为当前时刻供 P70/P71 使用、清空WCHPHASE/FLPASS0——也就是为后续着陆制导算法重置迭代状态。值得一提的是,这套点火程序里还埋着两处拉丁文格言:HONI SOIT QUI MAL Y PENSE(心怀邪念者蒙羞)和表区开头的NOLI SE TANGERE(勿触我)——后者更像写给后来者看的「这里别乱改」。而「BURN, BABY, BURN」这个名字本身也是一段历史:文件头注释记载,在 AGC 开发者 40 周年聚会上,本模块的作者之一 Don Eyles 亲口讲述了命名由来——它源自 1965 年洛杉矶骚乱时期的灵魂乐电台 DJ Magnificent Montague 播放新碟时的招牌口号。一个点火子程序,就这样把太空时代和电台黄金时代串在了一起。第三步:用 DSKY 告警码把代码「运行」起来代码读完了,怎么验证自己读对了?答案是回到它的运行时上下文——DSKY(Display and Keyboard)。阿姆斯特朗和奥尔德林盯着的那块布满数字的小键盘,就是 AGC 唯一的「人机界面」。而告警码,正是理解这段代码在真实飞行中遭遇了什么的钥匙。1969 年 7 月 20 日下降途中,鹰号曾反复响起1201、1202告警。在源码里,这两个码的出处清晰可查——EXECUTIVE.agc 第 147、208 行,任务调度器FINDVAC2找不到空闲 VAC 工作区时:TC BAILOUT1 OCT 1201 # NO VAC AREAS. ... TC BAILOUT1 # NO CORE SETS AVAILABLE. OCT 1202这两行代码的含义,对照 ASSEMBLY_AND_OPERATION_INFORMATION.agc 里完整的告警码总表(Page 23–24)可以确认:# 01201 * EXECUTIVE OVERFLOW - NO VAC AREAS EXEC # 01202 * EXECUTIVE OVERFLOW - NO CORE SETS EXEC换句话说,1201/1202 是执行器(EXECUTIVE)的资源耗尽告警——任务队列里同时并发的任务太多,申请不到 VAC 区或核心集。它不是导航计算「算错了」,而是调度器「忙不过来」。这就是为什么休斯顿的指导官 Steve Bales 能在几秒内判定「继续着陆」:告警揭示的是资源竞争而非算法故障,而BURNBABY里 P63 特有的DEC 63检查、TIGTASK1用CAF PRIO16抢占任务等设计,正是为了把优先级收拢在点火窗口附近。告警的实际显示机制则在 ALARM_AND_ABORT.agc(第 1381–1385 页):ALARM子程序的调用约定是TC ALARM+OCT AAANN(AAA 为告警分类、NN 为编号),它点亮 DSKY 上的PROGRAM ALARM灯,但并不打断正在执行的程序——所以告警与点火主流程可以并行共存。顺着告警码表,你还会发现 P63 专属的几个告警,全部指向本次下降的实时计算:01412 DESCENT IGNALG NOT CONVERGING (P63):着陆点火算法IGNALG未收敛;01406 BAD RETURN FROM ROOTPSRS:表里特别注明,在点火算法阶段它是 POODOO(程序进入死亡状态),而在实际制导阶段才是告警;01703 IGNITION TIME SLIPPED (MIDTOAVE):点火时刻被修正——对应的正是BURNBABY中那段TIG WAS SLIPPED, SO RESET TIG TO 29.9 SECONDS的注释和DCA PIPTIME1 / DXCH TIG代码。至此,三步路线已经走完:索引(README 源码表)→ 入口(THE_LUNAR_LANDING 的 P63LM)→ 运行时(BURNBABY 点火表 + DSKY 告警语义)。回头看,这套 1969 年的「历史遗留代码」之所以至今仍有阅读价值,恰恰在于它把现代嵌入式开发的几大命题——表驱动、可重启的阶段机(PHASCHNG)、资源受限下的任务优先级、以及人与机器的协作接口——全部压缩在了 64KB、1.024MHz 的极端约束里。读懂 BURN, BABY, BURN,不只是读一段汇编,而是读懂了人类第一次在另一个世界着陆时,软件所扮演的角色。【免费下载链接】Apollo-11Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.项目地址: https://gitcode.com/GitHub_Trending/ap/Apollo-11创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考