How the AGC INTERPRETER System Performs Calculations: Apollo-11 Virtual Machine Architecture

The AGC INTERPRETER system executes interpretive programs stored in erasable memory by decoding opcode pairs in a fetch-dispatch loop, resolving three addressing modes (direct, indexed, and push-down), and delegating arithmetic operations to specialized sub-routines.

The Apollo Guidance Computer (AGC) utilized a sophisticated INTERPRETER system to perform complex mathematical calculations without the memory overhead of native machine code. As implemented in the chrislgarry/Apollo-11 repository, this virtual machine—located in Luminary099/INTERPRETER.agc—reads compact opcode sequences from erasable memory and dispatches operations to dedicated arithmetic handlers, enabling compact representation of flight software algorithms.

Architecture and Entry Point of the INTERPRETER System

The interpreter acts as a virtual machine layer between native AGC assembly and high-level mathematical algorithms. It resides in Luminary099/INTERPRETER.agc, included by MAIN.agc at line 55 via the assembly directive $INTERPRETER.agc.

Initializing Interpretive Mode with INTPRET

The public entry point INTPRET (lines 34-55) initializes the interpreter state when the main dispatcher (DANZIG) invokes interpretive execution. According to the file comments on lines 34-38, this routine performs four critical setup actions:

  • Set the location counter: EXTEND / QXCH LOC loads the starting address of the interpretive program into LOC (lines 34-45)
  • Configure bank addressing: CA BBANK / TS BANKSET loads the interpretive program's bank into BANKSET, enabling addressability without super-bank switching (lines 46-48)
  • Record bank flags: MASK BIT15 / TS INTBIT15 captures the bit-15 flag of FBANK to handle high-bank versus low-bank addressing rules (lines 49-50)
  • Prepare first opcode: TS EDOP clears any leftover instruction residue before TCF NEWOPS fetches the initial opcode pair (lines 52-55)

The Opcode Dispatch Loop

Once initialized, the interpreter enters NEWOPS, the core fetch-decode-execute cycle that processes interpretive programs stored in erasable memory until encountering an exit code.

Fetching Opcode Pairs with NEWOPS

The NEWOPS routine implements the main loop that drives the virtual machine:

NEWOPS  INDEX LOC                # Advance location counter and load next word

        CA  0                    # Load opcode pair into accumulator

        CCS A                    # Sign test → absolute value

        TCF DOSTORE              # Branch to store-code handler if applicable

This sequence uses INDEX LOC to advance the program counter, loads the 15-bit opcode pair into the accumulator, and applies CCS A to obtain the absolute value. If the high-order bits indicate a store operation, control transfers to DOSTORE; otherwise, execution falls through to the next instruction handler. The dispatcher (DANZIG) calls back to INTPRET whenever a new interpretive job must start after interrupts or mode changes.

Address Handling in the INTERPRETER System

The AGC INTERPRETER supports three distinct addressing modes to access operands in erasable memory, managed by the ADDRESS routine (lines 1005-1008).

Direct and Indexed Addressing

The interpreter determines the addressing mode by testing the low-order bit of the address word:

ADDRESS MASK  BIT1               # Test indexing flag (BIT1)

        CCS  A
        TCF  INDEX               # If set, resolve via INDEX routine

When BIT1 is set, the interpreter jumps to the INDEX routine (lines 1006-1010), which resolves the index register and constructs the full 12-bit address in ADDRWD. Direct addressing places the sub-address directly into ADDRWD without indexing.

Push-Down List Operations

If no address word follows a store code, the interpreter implicitly uses the push-down list (a hardware stack). The PUSHUP routine (lines 1230-1240) manages this stack, allowing arithmetic operations to consume operands from or push results to the top of stack without explicit memory addressing.

Store Codes and Arithmetic Dispatch

The INTERPRETER system does not implement arithmetic logic directly; instead, it dispatches to specialized sub-routines based on decoded opcodes.

Processing Store Codes via DOSTORE

Store codes (such as STADR, STCALL, and STODL) are handled by DOSTORE (lines 1004-1013):

DOSTORE TS  ADDRWD
        MASK  LOW11
        XCH  ADDRWD
        MASK  B12T14
        EXTEND
        MP  BIT5                # Prepare for vector operand fetch

        INDEX  A
        TCF  STORJUMP           # Jump to store-specific handler

The sub-address in ADDRWD selects the specific store routine from the STORJUMP table. After the store operation completes, control returns to the dispatcher (DANZIG), which fetches the next opcode pair.

Arithmetic Sub-Routine Delegation

Mathematical operations dispatch via the INDJUMP (lines 1028-1035) and UNAJUMP tables defined in ASSEMBLY_AND_OPERATION_INFORMATION.agc. For example, the square-root operation (SQRT) is invoked through the UNAJUMP table (lines 1062-1065), executing the iterative algorithm located in SINGLE_PRECISION_SUBROUTINES.agc. Similarly, triple-precision add (TAD) and vector add (VAD) dispatch through INDJUMP to routines in VECTOR_SUBROUTINES.agc.

Exiting the INTERPRETER System

When the decoder encounters an opcode pair of 0, the EXIT routine (lines 1051-1057) terminates interpretive execution:

EXIT    CA  BANKSET
        TS  BBANK               # Restore original bank set

        INDEX  LOC
        TC  1                   # Return to native dispatcher (DANZIG)

This sequence restores the user's bank settings (BBANK) and returns control to the native AGC instruction stream via the dispatcher.

Practical Implementation Example

The following assembly demonstrates calculating a vector magnitude using the interpreter to execute DOT followed by SQRT, leveraging the push-down list for operand passing:

; Interpretive program stored at address 3000 in erasable memory
3000:  0025          ; DOT opcode (vector dot product) - INDJUMP entry 27
3001:  0010          ; SQRT opcode - UNAJUMP entry
3002:  0000          ; EXIT opcode or dummy word

; Native AGC setup code
        CAF   XCOMP
        PDDL                 ; Push X component onto stack
        CAF   YCOMP
        PDDL                 ; Push Y component
        CAF   ZCOMP  
        PDDL                 ; Push Z component
        CAF   3000           ; Load interpretive program address
        TC    INTPRET        ; Enter interpreter
        ; Vector magnitude now resides in MPAC registers

The interpreter fetches the DOT opcode, computes the vector dot product of the three pushed components, then processes the SQRT opcode to produce the magnitude, leaving the final result in the MPAC (Multi-Purpose Accumulator) registers before executing EXIT.

Summary

  • The AGC INTERPRETER system in Luminary099/INTERPRETER.agc provides a virtual machine that executes compact interpretive programs stored in erasable memory, distinct from native AGC instructions.
  • Entry via INTPRET initializes the location counter LOC, bank set BANKSET, and bit-15 flags before entering the NEWOPS fetch-decode loop.
  • The system supports three addressing modes: direct (12-bit ADDRWD), indexed (via INDEX routine when BIT1 is set), and push-down list (stack-based via PUSHUP).
  • Store codes dispatch through DOSTORE and STORJUMP, while arithmetic operations delegate to specialized sub-routines via INDJUMP and UNAJUMP tables in external files.
  • Execution terminates through the EXIT opcode (lines 1051-1057), which restores native bank settings and returns control to the DANZIG dispatcher.

Frequently Asked Questions

What is the primary function of the INTERPRETER system in the AGC?

The INTERPRETER system serves as a virtual machine that executes mathematical algorithms stored as compact opcode sequences in erasable memory. It enables the Apollo Guidance Computer to perform complex calculations—such as vector arithmetic, trigonometric functions, and coordinate transformations—without requiring every operation to be coded in native AGC assembly, significantly reducing memory usage while maintaining computational flexibility.

How does the AGC INTERPRETER handle arithmetic operations?

The interpreter does not implement arithmetic logic directly within INTERPRETER.agc. Instead, it uses jump tables (INDJUMP for binary operations like TAD and VAD, UNAJUMP for unary operations like SQRT) to dispatch to dedicated sub-routines located in files such as SINGLE_PRECISION_SUBROUTINES.agc and VECTOR_SUBROUTINES.agc. When the decoder identifies an arithmetic opcode, it transfers control to the appropriate routine, which executes the calculation and returns to the dispatch loop.

What addressing modes does the AGC INTERPRETER support?

The system supports three distinct operand addressing modes: direct addressing (placing a 12-bit sub-address directly in ADDRWD), indexed addressing (setting BIT1 to trigger the INDEX routine for register-relative addressing), and push-down list (using the hardware stack managed by PUSHUP when no explicit address follows a store code). The ADDRESS routine (lines 1005-1008) tests the low-order bit to determine whether indexing applies.

Where is the INTERPRETER system code located in the Apollo-11 repository?

The core virtual machine implementation resides in Luminary099/INTERPRETER.agc (pages 1002-1094), which MAIN.agc includes at assembly time. Supporting arithmetic routines live in SINGLE_PRECISION_SUBROUTINES.agc and VECTOR_SUBROUTINES.agc, while constant tables and opcode documentation appear in ASSEMBLY_AND_OPERATION_INFORMATION.agc and INTERPRETIVE_CONSTANT.agc.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →