4KB of Memory Went to the Moon: From Apollo to the Game Boy
Apollo 11's computer overloaded during the lunar descent, yet its recovery system kept the mission going. Decades later, developers are compiling Vue components for the Game Boy. How do you make so little memory go so far?
On July 20, 1969, Apollo 11's lunar module was approaching the Moon's surface. With only minutes to go before landing, the computer displayed an alarm code.
1202
A historical photograph of an Apollo cockpit, its panels covered in instruments, switches, and numerical displays.
Mission Control's answer: go ahead.
The 1201 and 1202 alarms appeared several more times. The lunar module kept descending. The computer kept working.1
The machine handling guidance had roughly 4 KB of read/write memory.
I first came across this story through a video about Apollo's source code. What caught my attention wasn't just that tiny number. The computer was already struggling to keep up. How could it still get them to the surface?
It also reminded me of the PocketJS team I met at RustChinaConf. They're compiling Vue components for old handhelds like the Game Boy. From the lunar module to a handheld console, I kept coming back to the same question: how do you make so little hardware do so much?
1Why Didn't the Alarm Stop the Landing?
Apollo used the Apollo Guidance Computer (AGC), developed under the leadership of MIT's Instrumentation Laboratory.


Left: the AGC and its DSKY interface. Right: an illuminated DSKY, showing the VERB, NOUN, and numerical display areas.
First, a clarification about that 4 KB: it was read/write memory, not the size of the entire lunar landing program. The AGC also had about 72 KiB of fixed memory for programs and constants. Its memory was organized into words rather than modern bytes; these conversions simply give a sense of scale.2
Small memory didn't mean a lightweight machine. The AGC weighed about 32 kilograms.3
During the descent, trouble came from the rendezvous radar interface. This radar was intended to help the lunar module rejoin the command module, and the checklist called for it to be set to automatic tracking. A phase mismatch between two reference signals in the interface produced a stream of meaningless counter-update requests, consuming as much as 15% of the computer's time.45
Work that would normally finish on time now ran late. Before one round of calculations finished, the next was due. Jobs piled up until the workspaces needed to manage them ran out.
That was what the 1201 and 1202 alarms meant: the AGC's task manager, the Executive, could no longer allocate a workspace. A 1202 meant no Core Sets were available; a 1201 meant no VAC areas were available.6
What happened next sounds counterintuitive: the computer triggered a software restart, and the landing continued.
The restart preserved essential data and reestablished the execution state of critical jobs. Some work that didn't need to be recovered was left behind, freeing up its workspaces. Guidance and other essential work could carry on.6
If “restart” makes you picture a PC slowly returning to its login screen, doing one during a lunar descent sounds terrifying. But the AGC's recovery mechanism was built for keeping the computer working in flight.

An installed DSKY, through which astronauts read computer status and alarms.
The people on the ground also had to understand the alarm before they could give the go-ahead. The computer recovered, Mission Control assessed whether it was safe to continue, and the astronauts kept flying. The 1202 alarm remained part of the story, but it didn't get to end it.1
A resolver converted the radar antenna's angle into electrical signals, and a coupling data unit (CDU) converted those signals into digital counts. The sensor and CDU each used an 800 Hz AC reference. Their frequencies matched, but their phases didn't necessarily match. The CDU could interpret that difference as continuous antenna movement and repeatedly request counter updates.
Each high-priority request cost the AGC one memory cycle. In the worst case, each of two angle counters could generate 6,400 requests per second, at about 11.72 microseconds apiece:
That amounts to roughly 15% of each second. The navigation and guidance job, SERVICER, was scheduled every two seconds. With the added overhead, one run could still be unfinished when the next was scheduled, eventually exhausting the job workspaces.
Testing had accounted for extra load, requiring the system to work even with about 10% of its running time lost. But this interface could take roughly 15%, and the hardware behavior wasn't fully reproduced in simulation. George W. Cherry's original post-mission analysis traces this chain of events in detail.5
2Once You Wrote the Program, Someone Had to Weave It
Another detail about the AGC has stayed with me: its fixed programs were stored in core rope memory.
Whether a wire passed through or around a magnetic core formed part of the encoding. Bundles of wires and cores became memory modules, with the program physically fixed inside them.7

A worker threading wires for core rope memory.
The software still had to be designed, coded, assembled, and tested first, then converted into wiring data for manufacturing. Production workers, many of them women, carried out the threading and assembly.8
Today, if you find a wrong instruction, you edit a file and compile again. With this fixed memory, a formal program change also meant manufacturing and validating replacement modules. “This is the final version” had a very physical meaning.
Even so, a program woven into rope didn't leave the computer entirely inflexible in flight. On Apollo 14, an abnormal abort-switch signal prompted ground engineers to devise a workaround, which the astronauts entered into the computer.9
On one side, programs you couldn't casually change once they were woven. On the other, a flight that could still throw surprises at you. After reading about all this, “4 KB went to the Moon” started to feel like it left out the most interesting parts.
3More Than Fifty Years Later, You Can Still Find That Line of Code
The Apollo-11 GitHub repository that got me reading contains Comanche055 for the command module and Luminary099 for the lunar module. The source comes from digitized and proofread historical assembly listings.10
Open the lunar module's EXECUTIVE.agc, and you'll find this path for when no Core Set is available:
TC BAILOUT1 # NO CORE SETS AVAILABLE.
OCT 1202TC is a transfer-of-control instruction, and OCT means the following number is written in octal. This code enters the BAILOUT1 path with 1202 as the alarm code. The same file also contains 1201 for the VAC workspace shortage.11
That number I'd kept seeing in accounts of the landing was right there, on a line of source code. I like that more than simply knowing how small the memory was: more than fifty years later, you can still follow the alarm into the code.
To keep going, follow Executive, Alarm and Abort, and Restart Routine. Virtual AGC also provides tools for assembling and simulating the programs.
4Decades Later, Someone Is Writing Vue for the Game Boy
Nintendo released the original Game Boy in 1989. It had 8 KiB of working RAM, 8 KiB of video RAM, and a 160 × 144 screen.12
In October 2026, I attended Bantang's talk at RustChinaConf: “Vue Without JavaScript: Exploring Embedded UI with Rust.” I met Xuebi, Bantang, and Jimmy from the PocketJS team that day. Later, we had hot pot, walked by the sea, and talked about old devices, compilers, and game development.
I've already written about those encounters in “Why Make Vue Run on a PSP?”. But I wanted to share this Game Boy photo again.

The PocketJS team's demo, photographed at RustChinaConf.
Writing Vue for a machine like this raises an obvious question: where does the JavaScript engine fit?
The handheld experiment in Pocket Vapor takes a different route. It compiles supported Vue components ahead of time into C code, then builds a ROM using the target platform's toolchain. The final Game Boy program doesn't need to include a full browser or Vue runtime.13
A simplified view of Pocket Vapor's handheld compilation path.
Some of what makes Vue pleasant to use survives: components describe the interface, and reactive state describes changes. The device doesn't have to reproduce the original implementation, though. For components with known structures and limited capabilities, the compiler can work out which state affects which elements, then generate fixed data layouts and update logic.
The tradeoff is straightforward: you can only use the supported subset. Taking an existing Vue website, complete with its DOM, CSS, and arbitrary dynamic JavaScript, and exporting it as a Game Boy ROM is beyond the scope of this experiment.
The team demonstrated similar Vue to-do components on several consoles: the Game Boy ROM was 32 KB, and the NES ROM was 40 KB. Those are the demo programs' ROM sizes, not their runtime memory usage.13
A to-do list probably wouldn't have been my first reason to buy a Game Boy. But a familiar Vue component turning into a program this machine can understand? That's fun enough on its own.
This section is about Pocket Vapor's handheld experiment. Regular PocketJS can execute JavaScript through QuickJS, with a native Rust UI core handling layout and drawing. MicroTS explores compiling supported Vue / TypeScript ahead of time into Rust. They don't all follow the same compilation path.14
5What Else Can You Do with So Little?
I'm not keen to use “4 KB went to the Moon” to mock today's apps for taking up hundreds of megabytes. Modern software needs networking, encryption, audio and video processing, and support for all kinds of devices. Comparing sizes alone doesn't tell you much.
But both stories make me want to look a little deeper. When the AGC couldn't keep up, what could it leave behind, and what had to be restored? When a Vue component becomes a handheld program, which conveniences can stay, and which costs can the compiler take on in advance?
Those astonishing numbers are just a way in. Follow them, and you find counters, job workspaces, wires threaded through magnetic cores, and the C code generated at the other end.
As for the Game Boy, I'd always thought of playing games on one. Writing its interface in Vue had never crossed my mind.
注释
-
NASA Apollo Lunar Surface Journal, Apollo 11 Lunar Landing. Includes the real-time exchanges about the alarms between the astronauts and Mission Control during descent. ↩ ↩2
-
NASA, Apollo Guidance Computer historical resources. The AGC is commonly specified as having 2,048 words of read/write memory and 36,864 words of fixed memory. The conversion here counts 16 physical bits per word and should not be treated as an equivalent usable capacity in modern eight-bit bytes. ↩
-
Lorenz Keller, Mondlandung mit Steinzeit-Technik, Blick, 2019. Reports the AGC's approximate 32-kilogram weight and includes hardware photographs. Its memory-capacity units differ from the word specifications used here, so it is not used as the source for memory capacity. ↩
-
NASA, Apollo 11 Mission Report, 1969, section 16.2.5. Analyzes the 1201 / 1202 alarms during descent and the additional interrupt load from the rendezvous radar. ↩
-
George W. Cherry, MIT Instrumentation Laboratory, Exegesis of the 1201 and 1202 Alarms Which Occurred During the Mission G Lunar Landing, August 4, 1969, especially pages 2, 3, 7, and 8. This original analysis explains the 800 Hz phase mismatch, the roughly 15% counter-request overhead, the two-second scheduling cycle, and software restart behavior. ↩ ↩2
-
NASA Apollo Lunar Surface Journal, The 1201 and 1202 Program Alarms. Collects participants' technical accounts explaining Executive workspaces, restarts, and recovery. ↩ ↩2
-
Virtual AGC. Preserves historical material and source-code resources relating to the AGC, fixed memory, and software manufacturing. ↩
-
Nancy Atkinson, The Story of the Apollo Guidance Computer, Part 2, Universe Today, 2019. Covers early integrated circuits, AGC hardware tradeoffs, and core rope memory manufacturing. ↩
-
NASA Apollo Lunar Surface Journal, Apollo 14 Lunar Surface Journal. Provides background on the abnormal abort signal, the ground team's workaround, and flight operations. ↩
-
Compiled by Chris Garry, Apollo-11 source code. A digitized version of historical AGC program listings, rather than a modern reimplementation. ↩
-
Apollo-11 source code, Luminary099/EXECUTIVE.agc. Contains the handling branches for both
OCT 1201(no VAC areas) andOCT 1202(no Core Sets). ↩ -
Pan Docs, Game Boy Technical Reference. The original Game Boy's memory map documents 8 KiB of WRAM and 8 KiB of VRAM. ↩
-
PocketJS, Pocket Vapor, 2026. The development team's firsthand account of Vue subset compilation, C generation, console targets, and demo ROM sizes. ↩ ↩2
-
PocketJS, Architecture, and MicroTS. Official descriptions of the JS guest / Rust UI core and the separate ahead-of-time compilation route to Rust. ↩
评论与交流
在 GitHub 查看讨论欢迎补充、提问,或分享不同的看法。使用 GitHub 账号登录后即可评论。