1969 Apollo 11 used these 30 lines of assembly language code to calculate transcendental functions for navigation
The successful launch of SpaceX Dragon over the weekend has sparked interest among young people and others. Many people are asking how Apollo computers evaluated the transcendental functions like sine, arctangent, log? Thanks to NASA for sharing the source code and posting it in a public domain at GitHub.
The code is part of the source code for Luminary 1A build 099. It is part of the source code for the Command Module (CM) and here for the Lunar Lander (LM) used for Apollo Guidance Computer (AGC), for Apollo 11. The AGC is a digital computer produced for the Apollo program that was installed on board each Apollo command module (CM) and Apollo Lunar Module (LM). The AGC provided computation and electronic interfaces for guidance, navigation, and control of the spacecraft. The AGC software was written in AGC assembly language and stored on rope memory.
The AGC was designed at the MIT Instrumentation Laboratory under Charles Stark Draper, with hardware design led by Eldon C. Hall. The flight hardware was fabricated by Raytheon, whose Herb Thaler was also on the architectural team.
The codes were used to implement sine and cosine functions: see here for the command module and here for the lunar lander (it looks like it is the same code).
# Page 1102 BLOCK 02 # 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.
Below is an explanation of the code. Hats off to Nathan Tuggy at stackexchange
# SINGLE PRECISION SINE AND COSINE
indicates, that the following is indeed an implementation of the sine and cosine functions.
Information about the type of assembler used, can be found on Wikipedia.
Partial explanation of the code:
SPSIN actually calculates , and
SPCOS calculates .
SPCOS first adds one half to the input, and then proceeds to calculate the sine (this is valid because of ). The argument is doubled at the beginning of the
SPT subroutine. That is why we now have to calculate for .
POLLEY calculates an almost Taylor polynomial approximation of . First, we store in the register SQ (where denotes the input). This is used to calculate the polynomial
The values for the constants can be found in the same GitHub repository and are
which look like the first Taylor coefficients for the function .
These values are not exact! So this is a polynomial approximation, which is very close to the Taylor approximation, but even better (see below, also thanks to @uhoh and @zch).
Finally, the result is doubled with the
DDOUBL command, and the subroutine
POLLEY returns an approximation to .
Note that for this polynomial approximation you only need four multiplications and two additions (
AD in the code). For the Apollo Guidance Computer, memory and CPU cycles were only available in small numbers.
There are some ways to increase accuracy and input range, which would have been available for them, but it would result in more code and more computation time. For example, exploiting symmetry and periodicity of sine and cosine, using the Taylor expansion for cosine, or simply adding more terms of the Taylor expansion would have improved the accuracy and would also have allowed for arbitrary large input values.
Below is an old NASA video which shows how the DSKY worked, about 6 minutes into the program: