1. Apollo 11 – AGC Code review

Il y a quelque temps (été 2019) une information très intéressante est passée, il s’agit de la mise à disposition du code de l’Apollo Guidance Computer ou AGS. Étant à la fois passionné par le développement et par l’espace, j’ai trouvé cela deux fois plus intéressant. Cependant, j’ai vu peu de personnes prendre le temps de regarder ça de plus près.

D’ailleurs, si on se fie à la courbe de Google Trend, on constate qu’il y a eu un pic d’intérêt lors de la publication du code, puis un retour au calme.

Image non disponible

Avec Google Trend, on apprend aussi que les recherches autour d’Apollo sont plus cinématographiques qu’autre chose et que cela concerne surtout les États-Unis.

Image non disponible
Image non disponible

Donc, j’aimerais prendre un peu de temps aujourd’hui pour montrer avec un peu plus de détails ce que l’on trouve dans ce code.

Le billet ne va pas être très technique, car bien sûr le code est écrit dans un assembleur difficilement compréhensible, même si on fait de l’assembleur. En effet, chaque langage assembleur est fait pour s’exécuter sur une architecture spécifique et l’architecture de AGC est très différente de celle d’un ordinateur classique. On ne va donc pas s’attarder sur les instructions en elles-mêmes. Vous pouvez donc lire ce qui va suivre, peu importe votre langage de prédilection.

2. Le contexte

Il est d’abord important de rappeler quelques éléments de contexte, le code date de 1969 et il a été écrit quelques années avant. A cette époque, on est bien loin du Java ou du C# que l’on pratique aujourd’hui, en fait à cette époque, le C n’existe même pas.

  • 2008 - Python 3.0 ;
  • 2001 – C# ;
  • 1995 - Javascript, PHP, Java ;
  • 1990 – Haskell ;
  • 1980 – C++ ;
  • 1972 – C ;
  • 1969 - Apollo 11 AGC et invention du microprocesseur ;
  • 1964 - premier ordinateur personnel.

D'ailleurs, ceux qui ont écrit ces lignes de code ne sont pas appelés des développeurs et ce code, qui n'est qu'une suite d'instructions, n'est pas considéré comme un développement de logiciel. Beaucoup de codes ou programmes informatiques des différents programmes lunaires ont été perdus, car on considérait ce code de la même manière qu'on pourrait considérer un bout de coque de fusée, un écrou ou une vis, quelque chose de nécessaire, mais sans plus.

3. Obtenir le code

Le code est disponible sur Github. Mise à part des fichiers ReadMe en plusieurs langues (dont le nombre augmente au fur et à mesure des versions), il contient deux dossiers : le Comanche055 et le Luminary099.

Ces deux dossiers contiennent le code relatif à deux parties de la navette Apollo, le module de commande (CM) pour le Comanche055 et le module lunaire (LEM) pour le Luminary099

Les fichiers AGC, eux, sont juste des fichiers texte que l’on peut ouvrir avec Notepad ou Visual Code pour avoir la coloration syntaxique (avec une extension). Le code a été découpé en plusieurs fichiers pour pouvoir les ouvrir, mais il faut bien comprendre qu’il n’y a pas d’architecture du code. Le code est écrit sur un et un seul bout de papier dont la plus célèbre des photos est la suivante :

See the source image

On voit sur cette photo Margaret Hamilton, l’une des nombreuses personnes ayant travaillé sur le code d'Apollo 11. Si le code peut paraître impressionnant, il est toutefois nécessaire de relativiser.

En effet, contrairement à cette époque, on n’a plus l'habitude de voir du code imprimé, si on s'amusait à imprimer certains projets open source aujourd'hui cela serait aussi, voir encore plus, impressionnant.

Ensuite, Margaret Hamilton n’est pas très grande. 😊

Le langage utilisé dans ces fichiers AGC n’est rien d’autre que de l’assembleur. Cependant, ce code est très difficile à lire. Déjà, car la plupart des développeurs ne sont pas à l’aise ou ne connaissent pas l’assembleur, mais aussi parce que l’assembleur est très lié à la machine sur laquelle il est exécuté et ici on ne parle pas d’un ordinateur avec un processeur comme nous les connaissons, mais de l’ordinateur de contrôle du module de commande qui peut donc, par exemple, allumer ou éteindre les réacteurs.

4. Le premier fichier

On va commencer par explorer le premier fichier, dans Github, les fichiers sont classés par ordre alphabétique, ça sera donc AGC_BLOCK_TWO_SELF-CHECK.agc. Cependant on peut le voir au début en commentaire, ce code était en fait entre les pages 1394 et 1403.

 
Sélectionnez
# Pages:        1394-1403

On va prendre pour exemple la ligne 170 qui contient le label ERRORS, car c’est quelque chose que l’on connaît tous et qu’on a l’habitude de gérer.

Pour réussir à comprendre les instructions, on va se baser sur le manuel du langage disponible ici : http://www.ibiblio.org/apollo/assembly_language_manual.html

Ce court morceau de code va utiliser seulement 4 instructions différentes qui sont les suivantes :

Commande

Description

INHINT

Disable Interrupts.

CA

The "Clear and Add" (or "Clear and Add Erasable" or "Clear and Add Fixed") instruction moves the contents of a memory location into the accumulator.

TS

The "Transfer to Storage" instruction copies the accumulator into memory ... and so much more.

INCR

The "Increment" instruction increments an erasable-memory location in-place by +1.

 
Sélectionnez
170 ERRORS          INHINT

La première ligne de l’instruction de ce morceau de code est donc INHINT qui sert à désactiver ce qu’on appelle les interruptions, des éléments déclencheurs qui vont arrêter l’exécution de la routine en cours (comme une saisie sur le clavier par exemple).

 
Sélectionnez
 171               CA      Q

CA, pour l’instruction « Clear & Add », elle sert à effacer et stocker dans une zone mémoire dont l’accès est très rapide (la plus rapide) une information sur 16 bits, cette zone mémoire est nommée l’accumulateur. On y sauvegarde la valeur Q, qui est le nom d’un registre. Le registre Q va permettre de retourner à l’instruction de code qui à causé l’erreur et donc permettre au programme de revenir là où il était. Car oui, si le programme ne fait pas cela, il n’a aucun autre moyen de savoir où il en était au moment de l’erreur.

On a ensuite les lignes suivantes :

 
Sélectionnez
 172               TS      SFAIL           # SAVE Q FOR FAILURE LOCATION
 173               TS      ALMCADR         # FOR DISPLAY WITH BBANK AND ERCOUNT

TS pour « Transfert Storage ». Cette instruction permet de sauvegarder des valeurs de façon plus pérenne, contrairement à CA. On va donc prendre la valeur Q qui était dans l’accumulateur, pour la sauvegarder dans deux autres zones de la mémoire. Le premier TS permet de sauvegarder l’endroit où l’erreur s’est produite, le second permet d’afficher sur un écran l’erreur en question.

La dernière instruction est la suivante :

 
Sélectionnez
174                INCR    ERCOUNT         # KEEP TRACK OF NUMBER OF MALFUNCTIONS.

INCR sert à incrémenter la variable ERCOUNT qui stocke le nombre d’erreurs.

On voit donc que le code est assez difficile à lire et à déchiffrer et ce n’était là qu’une infime partie. Heureusement il y a quelque chose de très facile à lire dans ce code, ce sont les commentaires qui commencent par un # !

5. Les commentaires

Les commentaires les plus intéressants sont certainement dans le dossier du LEM.

Allez dans le fichier LUNAR_LANDING_GUIDANCE_EQUATIONS.agc. Vous pouvez trouver, en ligne 179 et 180 par exemple, les commentaires suivants :

 
Sélectionnez
179                TC      BANKCALL        # TEMPORARY, I HOPE HOPE HOPE
180                CADR    STOPRATE        # TEMPORARY, I HOPE HOPE HOPE

Un commentaire qu’on a sans doute tous déjà écrit ou voulu, mais jamais imaginé dans un programme qui allait permettre à des astronautes de se poser sur la lune.

On peut trouver d’autres commentaires intéressants, ici il s’agit de la vérification du positionnement de l’antenne radar :

 
Sélectionnez
239 P63SPOT3        CA      BIT6            # IS THE LR ANTENNA IN POSITION 1 YET
240                EXTEND
241                RAND    CHAN33
242                EXTEND
243                BZF     P63SPOT4        # BRANCH IF ANTENNA ALREADY IN POSITION 1
244
245                CAF     CODE500         # ASTRONAUT:    PLEASE CRANK THE
246                TC      BANKCALL        #               SILLY THING AROUND
247                CADR    GOPERF1
248                TCF     GOTOP00H        # TERMINATE
249                TCF     P63SPOT3        # PROCEED       SEE IF HE'S LYING
250
251 P63SPOT4        TC      BANKCALL        # ENTER         INITIALIZE LANDING RADAR
252                CADR    SETPOS1
253
254                TC      POSTJUMP        # OFF TO SEE THE WIZARD ...
255                CADR    BURNBABY

Ce code commence à la ligne 239, les instructions sont regroupées sous le label P63SPOT3. Un « Clear&Add » est effectué. Comme indiqué plus haut, ceci permet de stocker une valeur dans l'accumulateur. En l'occurrence la position de l'antenne.

Puis, en ligne 243, on trouve l'instruction BZF qui permet d'exécuter les instructions suivantes ou de directement se rendre au label P63SPOT4 selon la valeur dans l'accumulateur. C'est donc une sorte d'instruction If dans les langages plus modernes. Ce If a pour but de vérifier dans quelle position est l'antenne.

Si l’antenne n’est pas dans la bonne position, on continue donc avec les instructions suivantes qui commencent en ligne 245. On demande alors aux astronautes de mettre l’antenne dans la bonne position.

À la ligne 249 on rappelle le label P63SPOT3 pour retourner au début et à nouveau vérifier le positionnement de l’antenne et donc s’assurer que l’astronaute à bien fait ce qu’on lui a demandé. S’il ne l’a pas fait, bien sûr, on recommence tout, sinon on se rend au label P63SPOT4 pour continuer la suite du programme.

À la fin de ces instructions, on appelle une routine appelée BURNBABY, un nom assez peu commun.

On peut retrouver cette routine dans le fichier BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc.

Ce fichier contient un commentaire avec une explication plus récente sur l’origine du nom de cette routine, qui vient donc d’un DJ de Los Angeles qui criait cette phrase, « Burn, baby ! BURN ! » :

 
Sélectionnez
34 ## At the get-together of the AGC developers celebrating the 40th anniversary
35 ## of the first moonwalk, Don Eyles (one of the authors of this routine along
36 ## with Peter Adler) has related to us a little interesting history behind     the
37 ## naming of the routine.
38 ##
39 ## It traces back to 1965 and the Los Angeles riots, and was inspired
40 ## by disc jockey extraordinaire and radio station owner Magnificent Montague.
41 ## Magnificent Montague used the phrase "Burn, baby! BURN!" when spinning the
42 ## hottest new records. Magnificent Montague was the charismatic voice of
43 ## soul music in Chicago, New York, and Los Angeles from the mid-1950s to
44 ## the mid-1960s.

Si vous ne trouvez pas ces noms très professionnels, sachez que ce code contient aussi un commentaire en français :

 
Sélectionnez
66 #                  HONI SOIT QUI MAL Y PENSE

Vous pouvez trouver la référence de cette maxime ici : https://en.wikipedia.org/wiki/Honi_soit_qui_mal_y_pense

6. P00H

Le code de l’AGC contient aussi une instruction qui revient souvent, il s’agit de GOTOP00H. Cette instruction permet de revenir à l’état initial du programme, que les programmeurs prononçaient très probablement « Poo » et non « P-zero-zero-H ». Le programme P00H était l’état de base du programme AGC, un peu comme une page d’accueil.

Si on regarde dans le fichier FRESH_START_AND_RESTART.agc, on peut confirmer cette hypothèse quand on lit la routine Enema (qu’on peut traduire par lavement en français) qui permet de complètement reprendre le programme à zéro en le redémarrant.

On trouve, lié à cette routine, le commentaire suivant en ligne 353 :

 
Sélectionnez
353 # DO NOT USE GOPROG2 OR ENEMA WITHOUT CONSULTING P00H PEOPLE.

7. Les verbes et noms

Un fichier très intéressant à lire est le fichier ASSEMBLY_AND_OPERATION_INFORMATION.agc. Il correspond à la page 2 du programme, il ne contient pas de code, uniquement des commentaires.

On trouve notamment des verbes associés à des nombres, ces verbes sont des choses que l’AGC peut faire si on les lui demande, tester les lumières, exécuter un programme… :

 
Sélectionnez
200 # 35    TEST LIGHTS
201 # 37    CHANGE PROGRAM (MAJOR MODE)
202 # 70    UPDATE LIFTOFF TIME
203 # 97    PERFORM ENGINE FAIL PROCEDURE

En plus des verbes, il existe aussi des noms, des choses qui existent dans le système avec une valeur et qu’on peut éventuellement afficher, comme le code d’une alarme, la latitude, la longitude ou l’altitude, l’apogée et le périgée…  :

 
Sélectionnez
293 # 09    ALARM CODES                             3COMP   OCTAL ONLY FOR EACH
364 #43    LATITUDE,                               3COMP   xxx.xx DEG                              DEC ONLY
365 #       LONGITUDE,                                      xxx.xx DEG
366 #       ALTITUDE                                        xxxx.x NAUT MI
367 # 44    APOGEE,                                 3COMP   xxxx.x NAUT MI                          NO LOAD, DEC ONLY
368 #       PERIGEE,                                        xxxx.x NAUT MI
#

Il existe également des informations sur comment ces données sont stockées :

 
Sélectionnez
# -SCALE TYPE-                         PRECISION
# UNITS                 DECIMAL FORMAT          --      AGC FORMAT
# ------------          --------------          --      ----------

# -A-
# OCTAL                 xxxxx                   SP      OCTAL

# -B-                                                            -14
# FRACTIONAL            .xxxxx                  SP      BIT 1 = 2    UNITS
#                       (MAX .99996)

# -C-
# WHOLE                 xxxxx.                  SP      BIT 1 = 1 UNIT
#                       (MAX 16383.)

# -D-                                                                15
# CDU DEGREES           xxx.xx DEGREES          SP      BIT 1 = 360/2   DEGREES
#                       (MAX 359.99)                    (USES 15 BITS FOR MAGNI-
#                                                        TUDE AND 2-S COMP.)

# -E-                                                               14
# ELEVATION DEGREES     xx.xxx DEGREES          SP      BIT 1 = 90/2   DEGREES
#                       (MAX 89.999)

# -F-                                                                14
# DEGREES (180)         xxx.xx DEGREES          SP      BIT 1 = 180/2   DEGREES
#                       (MAX 179.99)

Enfin, on trouve aussi la liste des codes d’alarme :

 
Sélectionnez
# CODE        * TYPE                                            SET BY

# 00206         ZERO ENCODE NOT ALLOWED WITH COARSE ALIGN       IMU MODE SWITCHING
# 00206          + GIMBAL LOC
# 00207         ISS TURNON REQUEST NOT PRESENT FOR 90 SEC       T4RUPT
# 00210         IMU NOT OPERATING                               IMU MODE SWITCH, IMU-2, RD2, P51, P57
# 00211         COARSE ALIGN ERROR                              IMU MODE SWITCH
# 00212         PIPA FAIL BUT PIPA IS NOT BEING USED            IMU MODE SWITCH, T4RPT

# 01105         DOWNLINK TOO FAST                               T4RUPT
# 01106         UPLINK TOO FAST                                 T4RUPT
# 01107         PHASE TABLE FAILURE.  ASSUME                    RESTART
#               ERASABLE MEMORY IS SUSPECT.                     RESTART
# 01201       * EXECUTIVE OVERFLOW - NO VAC AREAS               EXEC
# 01202       * EXECUTIVE OVERFLOW - NO CORE SETS               EXEC
# 01203       * WAITLIST OVERFLOW - TOO MANY TASKS              WAITLIST
# 01204      ** WAITLIST, VARDELAY, FIXDELAY, OR LONGCALL       WAITLIST ROUTINES
#                 CALLED WITH ZERO OR NEGATIVE DELTA-TIME

8. LUNAR_AND_SOLAR_EPHEMERIDES_SUBROUTINES.agc

Si on parcourt la liste des noms, on se rend compte que beaucoup de données sont disponibles, notamment des données sur la position dans l’espace de certains points comme le périgée ou l’apogée. D’où viennent ces données, comment l’ordinateur pouvait faire des calculs si précis…

Il faut commencer par remettre quelque chose au clair. La puissance de l’ordinateur pour aller sur la lune est souvent comparée à la puissance d’une calculatrice de poche. Cet ordinateur (qui bien sûr n’en est pas vraiment un au sens strict) serait plutôt à comparer, en ce qui concerne la puissance CPU, à un Apple II ou à un Commodore 64.

Ensuite, beaucoup de données étaient calculées sur terre puis codées en dur pour servir de base à de nouveaux calculs faits par l’AGC.

On peut par exemple trouver dans le fichier suivant : LUNAR_AND_SOLAR_EPHEMERIDES_SUBROUTINES.agc, les instructions qui servent à calculer la position du soleil ou de la lune :

 
Sélectionnez
LUNPOS          AXT,1   GOTO            # COMPUTES THE POSITION VECTOR OF THE MOON
                        REM             # AND STORES IT IN MPAC.
                        LSTIME
SOLPOS          STQ     AXT,1           # COMPUTES THE POSITION VECTOR OF THE SUN
                        X2              # AND STORES IT IN MPAC.
                        RES

9. Les alarmes

Revenons à nos codes d’alarme vus précédemment afin de comprendre ce que cela peut impliquer :

 
Sélectionnez
# 00210         IMU NOT OPERATING                               IMU MODE SWITCH, IMU-2, RD2, P51, P57

IMU est l’acronyme pour « Inertial Management Unit », cet équipement est le gyroscope d’Apollo, il permet de le situer dans l’espace, de donner sa position ainsi que sa direction. On imagine donc que si l’IMU cesse de fonctionner, le module peut avoir de gros problèmes pour alunir.

Les 3 codes suivants ont aussi une histoire particulière :

 
Sélectionnez
#01201       * EXECUTIVE OVERFLOW - NO VAC AREAS               EXEC
# 01202       * EXECUTIVE OVERFLOW - NO CORE SETS               EXEC
# 01203       * WAITLIST OVERFLOW - TOO MANY TASKS              WAITLIST

Ces alarmes sont celles qui se sont déclenchées au moment de la descente vers la lune, à ce moment les astronautes ont demandé s’ils devaient abandonner la mission. Et voyant le type d’alarmes qui ont été déclenchées, les ingénieurs au sol ont confirmé à l’équipage qu’il pouvait continuer. En réalité, l’ingénieur au sol, qui était Russ Larson, n’a expressément pas dit qu’il fallait continuer : trop effrayé pour dire un mot, il s’est contenté de montrer un pouce levé vers le haut.

10. Overflow

La raison pour laquelle ces alarmes se sont déclenchées et la mission n’a pas été arrêtée repose sur le fonctionnement de l’AGC. Le module lunaire dispose de 2 radars, le Landing radar et le « RendezVous » radar. Seul le premier était nécessaire pour atterrir, cependant, au moment de la descente, le second était activé.

L’AGC avait donc trop d’informations à gérer, trop de tâches. Aujourd’hui ; quand un ordinateur à trop de tâches, il a tendance à juste planter. Heureusement, l’AGC, lui, n’était pas conçu pour réagir comme ça, à la place, il laissait juste tomber les tâches non prioritaires. Ceci fut la cause des alarmes.

11. DSKY

Pour afficher ces alarmes ou interagir avec les astronautes, on trouve dans le code un acronyme fréquent, DSKY pour « Display/Keyboard ».

Image result for dsky

L’interface semble basique, mais par exemple, pour exécuter le test des lumières qui avait le numéro 35, les astronautes pouvaient faire : « VERB – 35 - ENTR ». Sachant que les astronautes ont un équipement encombrant, ils devaient bien sûr avoir une interface Homme-Machine adaptée.

Les entrées utilisateurs sont ensuite capturées par une routine nommée Pinball qu’on trouve dans le fichier PINBALL_GAME_BUTTONS_AND_LIGHTS.agc.

Le DISKY s’utilisait avec plusieurs combinaisons, comme pour afficher l’heure où on a le verbe 16 qui permet d’afficher des nombres à l’écran :

 
Sélectionnez
# 16    MONITOR DECIMAL IN R1 OR R1,R2 OR R1,R2,R3

Le nom 65, qui correspond au temps écoulé depuis que l’AGS est allumé :

 
Sélectionnez
# 65    SAMPLED AGC TIME                        3COMP   00xxx. HRS.                             DEC ONLY

Un astronaute pouvait donc taper « VERB - 16 – NOUN – 65 – ENTR » pour afficher l’heure.

Ou lancer un programme comme le fameux programme P00H avec le verbe 37 :

 
Sélectionnez
# 37    CHANGE PROGRAM (MAJOR MODE)

Un simulateur de DSKY existe, basé sur Apollo 9, mais assez proche du 11 pour tester les commandes, il est disponible à l’URL suivante https://github.com/virtualagc/virtualagc

12. Qu’apprendre de ce code ?

Étudier ce code peut être en soi passionnant, mais il permet en plus de tirer quelques conseils toujours d’actualité sur la programmation d’aujourd’hui et pas seulement sur la programmation bas niveau.

On peut apprendre que :

  • les commentaires sont quelque chose qui ne se perd pas et qu’ils permettent une plus grande accessibilité du code ;
  • une interface utilisateur ne se néglige pas et s’étudie ;
  • la gestion et l’écriture de messages d’erreur permettent une compréhension plus facile des problèmes rencontrés et une prise de décision plus rapide ;
  • un système peut être pensé comme résilient et continuer de fonctionner même s’il rencontre des difficultés, cela s’applique bien sûr aujourd’hui notamment aux applications cloud qui doivent avoir des SLA ( Service-level agreement https://fr.wikipedia.org/wiki/Service-level_agreement) très hauts.

J’espère que cette courte revue de code d’Apollo 11 vous a plu, il y a bien sûr beaucoup plus à dire et à découvrir sur ce code et cette mission. À vous d’aller l’explorer !

13. Remerciements

Je remercie Laurent_ott, Gaby277, Chrtophe pour leurs relectures techniques, ainsi que escartefigue pour sa relecture orthographique.