Il codice sorgente dell’AGC montato a bordo del CM e del LM per la missione Apollo 11, da circa dieci anni è liberamente disponibile e consultabile grazie al lavoro di Chris Garry, ex dipendente della NASA, che ha dedicato tempo a scansire e copiare i sorgenti in formato testuale (con estensione agc) e pubblicarli in un repository sulla piattaforma GitHub.
Apollo-11 (this link opens in a new window) by chrislgarry (this link opens in a new window)
Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.
Puntando il browser all’indirizzo qui sopra si apre il repository nel quale si tovano due directoy principali con i commenti dei programmatori originali.:
- Comanche055: il quale contiene il codice sorgente Colossus 2A (CM)
- Luminary099: il quale contiene il codice sorgente Luminary 1A (LM)
Il linguaggio mnemonico usato si chiama YUL
(assembler) il cui formato di ogni istruzione rispecchia la sintassi
<etichetta> <istruzione> <commento>
I token <etichetta>
e <commento>
sono opzionali. Il seguente estratto ad esempio:
ERRORS INHINT
CA Q
TS SFAIL # SAVE Q FOR FAILURE LOCATION
preso dal file AGC_BLOCK_TWO_SELF-CHECK.agc è costituito da tre istruzioni (una per riga). La prima riga rispecchia la sintassi <etichetta> <istruzione>
e possiede il seguente significato:
ERRORS
: nome dell’etichetta, ovvero riferimento di rimando nel codice.INHINT
: istruzione, per disabilitare le interruzioni. Nell’AGC tutti i task che richiedevano una temporizzzazione critica o lavoravano con dati in aree di memoria sensibili dovevano disabilitare le interruzioni per consentire loro di portare a termine il task in un periodo di tempo noto.
La seconda riga contiene solo il token <istruzione>
con il seguente significato:
CA Q
: azzera l’accumulatore e aggiungi il contenuto del registroQ
(registro di stash).
La terza riga ha il formato <istruzione> <commento>
e possiede il seguente significato:
TS SFAIL
: Trasferisci il contenuto dell’accumulatore nella locazione di memoria SFAIL
Come descrive il commento (la stringa che segue #
), queste tre istruzioni nel complesso mostrano la procedura di salvataggio dati e disabilita gli interrupt all’inizio della subroutine ERRORS
. In caso di cambio di contesto l’AGC non aveva la possibilità di gestire lo stack, quindi tutti i passaggi per il salvataggio di registri dovevano essere gestiti dal programmatore. In generale all’interno del codice sorgente si trovano numerose annotazioni dei programmatori dell’epoca che descrivono le funzioni dei singoli comandi o blocchi di codice. Questo accorgimento è considerato anche oggi una buona prassi di programmazione a patto di accompagnare il codice con commenti pertinenti. I commenti che si trovano nei sorgenti dell’AGC sono invece molto vari: alcuni commenti sono un po’ poetici e mostrano la creatività degli autori e vanno oltre il linguaggio tecnico .
Sebbene il listato originale sia costituito come un blocco monolitico ovvero come un unico blocco funzionale, nel repository l’autore lo ha riorganizzato in moduli al fine di migliorarne la leggibilità. Per un’analisi del listato si consiglia di partire dai file seguenti:
- file MAIN.agc di ogni modulo (Luminary e Comanche) che spiega come è strutturato il codice. Ognuno di questi due moduli contiene la suddivisione logica in moduli funzionali del software con le pagine di rimando nel caso di una ricerca veloce all’interno dello stesso. Qui sotto per esempio c’e un estratto del MAIN.agc del Luminary (Colossus 2A)
$ASSEMBLY_AND_OPERATION_INFORMATION.agc # pp. 1-27
$TAGS_FOR_RELATIVE_SETLOC.agc # pp. 28-37
$CONTROLLED_CONSTANTS.agc # pp. 38-53
- file CONTACT_AND_APPROVALS.agc che contiene le informazioni generali del progetto. In testa al file nella maschera d’intestazione si legge il seguente commento:
# SUBMITTED: MARGARET H. HAMILTON DATE: 28 MAR 69
# M.H.HAMILTON, COLOSSUS PROGRAMMING LEADER
# APOLLO GUIDANCE AND NAVIGATION
La maschera contiene le informazioni generali circa la descrizione del software, alcune indicazioni sulla struttura, il team di sviluppo e la storicità del sorgente.
- file ASSEMBLY_AND_OPERATION_INFORMATION.agc (Colossus 2A) contiene la suddivisione logica in moduli funzionali del software con le pagine di rimando nel caso di una ricerca veloce all’interno dello stesso. Un file analogo è presente anche per il Luminary.
- file ASSEMBLY_AND_OPERATION_INFORMATION.agc elenca i nomi (
NOUNS
) e verbi (VERBS
) che l’AGC era in grado di processare. L’AGC infatti era in grado di accettare ed interpretare i comandi impartiti dagli astronauti interagendo con l’interfacciaDSKY
secondo la sintassi:
<VERB> <NOUN>
Sia VERB
che NOUN
sono stringhe identificate da un codice univoco a due cifre. Ad ogni codice viene associato un comando (VERB
) seguito (eventualmente) da un parametro specifico di quel comando (NOUN
).
# NORMAL NOUNS COMPONENTS SCALE AND DECIMAL POINT RESTRICTIONS
# 00 NOT IN USE
# 01 SPECIFY MACHINE ADDRESS (FRACTIONAL) 3COMP .XXXXX FOR EACH
# 02 SPECIFY MACHINE ADDRESS (WHOLE) 3COMP XXXXX. FOR EACH
# 03 SPECIFY MACHINE ADDRESS (DEGREES) 3COMP XXX.XX DEG FOR EACH
Più in basso c’è l’elenco dei verbi:
# REGULAR VERBS
# 00 NOT IN USE
# 01 DISPLAY OCTAL COMP 1 IN R1
# 02 DISPLAY OCTAL COMP 2 IN R1
# 03 DISPLAY OCTAL COMP 3 IN R1
# 04 DISPLAY OCTAL COMP 1,2 IN R1,R2
All’interno del progetto i seguenti moduli software sono particolarmente importanti:
- BURN_BABY_BURN—MASTER_IGNITION_ROUTINE.agc esso contiene la sezione incaricata di inizializzare e controllare l’accensione del motore per la gestione dell’APS (programm
P42
), DPS (programmaP40
), PDI (programmaP63
) a l’ascesa dalla superficie lunare del LM (programmaP12
). - ALARM_AND_ABORT.agc contiene le routine di gestione degli errori (
P00DOO
,BAILOUT
)
Lo screenshot seguente invece è estratto dal modulo LUNAR_LANDING.agc (Luminary 1A):
P63SPOT3 CA BIT6 # IS THE LR ANTENNA IN POSITION 1 YET
EXTEND
RAND CHAN33
EXTEND
BZF P63SPOT4 # BRANCH IF ANTENNA ALREADY IN POSITION 1
CAF CODE500 # ASTRONAUT: PLEASE CRANK THE
TC BANKCALL # SILLY THING AROUND
CADR GOPERF1
TCF GOTOPOOH # TERMINATE
TCF P63SPOT3 # PROCEED SEE IF HÈS LYING
P63SPOT4 TC BANKCALL # ENTER INITIALIZE LANDING RADAR
CADR SETPOS1
TC POSTJUMP # OFF TO SEE THE WIZARD...
CADR BURNBABY
Esso esegue il controllo della lettura del Landing Radar (LR) per l’allunaggio. L’algoritmo implementato è il seguente:
- Controlla se il radar è in posizione leggendo lo stato dal bit 6 del canale
I/O33
dove viene memorizzato lo stato del radar.- In caso affermativo salta alla locazione
P63SPOT4
per l’inizializzazione - altrimenti lancia la routine
GOPERF1
per visualizzare sulDSKY
il messaggio il cui valore è indirizzato dalla costanteCODE500
- Se l’astronauta digita il comando “
TERMINATE
”, trasferisci il controllo aP00
(stato di idle, in attesa di altri comandi) che si trova nel modulo FRESH_START_AND_RESTART.agc - Se digita il comando “
PROCEED
” torna al punto 1 e rileggi lo stato del radar.
- Se l’astronauta digita il comando “
- In caso affermativo salta alla locazione
- Esegui la routine
SETPOS1
per inizializzare il LR, la routinePOSTJUMP
, e fai partire il motore del LM per iniziare la discesa (BURNBABY
).
Un’ultima sezione interessante da analizzare riguarda la routine di calcolo delle funzioni trigonometriche. Per muoversi nello spazio l’uso delle funzioni trascendenti quali seno e coseno (così come il calcolo matriciale) sono fondamentali per l’implementazione degli algoritmi di navigazione. Qui si può trovare l’algoritmo implementato da Margaret Hamilton datato Marzo 1969 usato sia nel CM che nel LM e per comodità riportato anche qui sotto.
# SINGLE PRECISION SINE AND COSINE
COUNT* $$/INTER
SPCOS AD HALF # ARGUMENTS SCALED AT PI
SPSIN TS TEMK
TCF SPT
CS TEMK
SPT DOUBLE
TS TEMK
TCF POLLEY
XCH TEMK
INDEX TEMK
AD LIMITS
COM
AD TEMK
TS TEMK
TCF POLLEY
TCF ARG90
POLLEY EXTEND
MP TEMK
TS SQ
EXTEND
MP C5/2
AD C3/2
EXTEND
MP SQ
AD C1/2
EXTEND
MP TEMK
DDOUBL
TS TEMK
TC Q
ARG90 INDEX A
CS LIMITS
TC Q # RESULT SCALED AT 1.
La routine (punto di ingresso SPCOS
) calcola sfruttando l’equivalenza:
cos(\pi x)=sin(\pi (x + \frac{1}{2}))
A tal scopo la funzione somma al valore iniziale
(nel registro
A
) quindi passa il controllo alla funzione SPSIN
per il calcolo della funzione seno. Viene salvato il contenuto nella locazione temporanea TEMK
per utilizzarlo in seguito nel calcolo del polinomio.
SINGLE PRECISION SUBROUTINE TEMPORARIES (3D)
# SPSIN, SPCOS, SPROOT VARIABLES.
# DO NOT SHARE. THESE ARE USED BY DAPS IN INTERRUPT
# AND CURRENTLY ARE NOT PROTECTED. IF OTHER USERS
# MATERIALIZE, THEN THIS CAN BE CHANGED.
HALFY ERASE
ROOTRET ERASE
SQRARG ERASE
TEMK EQUALS HALFY
Viene raddoppiato (DOUBLE
) il suo valore () e chiamata la routine
POLLEY
tramite l’istruzione TCF
. Lo scopo di POLLEY è calcolare :
\begin{cases} y = x + \frac{1}{2} \\ y_{a} = 2 y \\ y_{b} = \frac{1}{2} sin (\frac{\pi}{2} y_{a}) \end{cases}
tramite lo sviluppo in serie polinomiale di Taylor al quinto ordine (tre coefficienti).
Il blocco di codice racchiuso in SPT
calcola:
y^{'} = \frac{1}{2} sin (\frac{\pi}{2} x) \approx 0.7853134 x - 0.3216147 x^{3} + 0.0363551 x^{5}

Per un’analisi dettagliata vedere: https://fermatslibrary.com/s/apollo-11-implementation-of-trigonometric-functions
Fonte: https://www.desmos.com/calculator/fmnu5rs6d6
I coefficienti di Taylor:
\begin{cases} C_{1} = 0.7853134 \\ C_{3}=−0.3216147 \\ C_{5}=0.0363551 \end{cases}
I coefficienti sono definiti nel codice nel seguente file: FIXED_FIXED_CONSTANT_POOL.agc
C1/2 DEC .7853134 # (OCTAL 31103)
…
C5/2 DEC .0363551 # (OCTAL 01124)
…
C3/2 DEC -.3216147 # (OCTAL 65552)
Essi non sono uguali a quelli che si otterrebbero con lo sviluppo in serie, tuttavia sono molto simili; questo perché gli ingegneri hanno ottimizzato i loro valori allo scopo di minimizzare l’errore di approssimazione nell’intervallo di utilizzo della funzione sul campo .
Al termine di POLLEY viene nuovamente trasferito il controllo al programma chiamante ed il flusso di controllo procede con la chiamata alla routine ARG90
, si sottrae LIMITS
e si salva il risultato in virgola fissa, prima di ritornare il controllo al programma chiamante (TC Q
).
Bibliografia
- The Apollo Guidance Computer Architecture and Operation, Frank O’Brien – Springer
- https://www.pluralsight.com/courses/moon-landing-apollo-11
Per una descrizione più approfondita del codice di Margaret Hamilton, fare riferimento ai seguenti link in cui viene spiegato in maniera molto precisa e dettagliata.
- http://jeanmariechauvet.com/papers/curttrig.html
- https://fermatslibrary.com/s/apollo-11-implementation-of-trigonometric-functions
- https://observablehq.com/@fil/sine-margaret-hamilton
Glossario istruzioni assembler
- L’istruzione
TCF
lavora solo con indirizzi fissi e carica nel registroZ
l’operando passato come parametro quindi trasferisce il controllo del programma alla locazione specificata dall’operando. - L’istruzione
TC
serve per impostare l’indirizzo di ritorno da una subroutine. - L’istruzione
MP
effettua la moltiplicazione (sempre in doppia precisione) con la parte alta inA
e la parte bassa nel registroL
. Il valore originale del moltiplicando viene perso. - L’istruzione
XCH
scambia il contenuto diA
con il contenuto della locazione di memoria volatile specificata come parametro. - L’istruzione
TS
trasferisce il valore diA
nella locazione di memoria volatile specificata come parametro. - L’istruzione
CS
azzera e sottrae l’operando passato come parametro al registroA
. - L’istruzione
DOUBLE
raddoppia il contenuto diA
. - Le istruzioni
INDEX/EXTEND
sono usate per l’accesso a tabelle/array tramite l’indicizzazione. Rappresenta un offset per l’accesso in memoria di un elemento.
Categorie:Sorgente AGC