What is yaAGC?

yaAGC is a computer program which emulates the behavior of the "Block 2" Apollo Guidance Computer (AGC).  (There was also an earlier "Block 1" AGC that never flew in any manned missions.)   It is a virtual computer (existing within, for example, a desktop PC) which is capable of running software written for the original AGCs used in the Apollo project.  yaAGC emulates only the computer itself, and not the peripheral devices used by the AGC.  For example, the display/keyboard (DSKY) used by the AGC is a peripheral device and is emulated by a completely different computer program called yaDSKY.  Just as the true AGC and DSKY communicated between themselves by mean of wiring, the virtual yaAGC and yaDSKY communicate between themselves using communication channels (sockets) that act like virtual wires. 

Similarly, as a "computer", yaAGC by itself provided little or no functionality.  To be useful, it needs to be "loaded" with appropriate flight software—in other words, with the Command Module (CM) or Lunar Module (LM) flight-software written for the original Apollo missions.   The CM and LM software are called Colossus and Luminary, respectively.

What, Exactly, is Being Simulated?

Guidance&Navigation block architecture

Photograph of core-rope
A small section of the cores in the "core rope" non-volatile memory of the AGC.  (The photo was taken from the web; it was credited to Raytheon Corp.)
Click to
Logic modules, plugged into a backplane.  Though you cannot tell it from this photo, if the modules were disassembled, you would see that they are of "welded cordwood" construction.  What that means is that the modules are full of cylindrical holes, like swiss cheese; the electrical components, such a resistors, slide into these holes, and their leads protrude from either side of the module.  Wires are weldednot solderedonto the leads to interconnect the components.  (Photo by Stephan Hotto, taken at the Computer History Museum in Mountain View, California.)
Click to
The backplane the logic and memory modules  which the logic and memory modules plug into.  Notice that it is wire-wrapped.  Even the production models were wire-wrapped, and not just the engineering models.  (Photo by Stephan Hotto, taken at the Computer History Museum in Mountain View, California.)

Invoking yaAGC

yaAGC is a command-line program that requires no user interaction once started.  The syntax is

yaAGC [OPTIONS] --core=BinaryExecutable

The BinaryExecutable will be the name of a file containing an AGC core-rope binary image, either downloaded or else assembled from Luminary or Colossus source code using yaYUL.  If a complete pathname for BinaryExecutable is not specified, then yaAGC will look first in the current directory, and then (for software versions 05/06/2004 or later) in the installation directory (which is /usr/local/bin by default, but which may be changed when yaAGC is built). 

I'm not certain the debugging options described below are up-to-date (see the debugging section instead), but the other currently-defined options are:

Displays a list of options (such as this one) and then quits.

The yaAGC program and programs simulating peripheral devices (such as yaDSKY) have a server/client relationship.  yaAGC listens on a set of ports (by default, 19697 through 19706) for client connection-requests.  The base (lowest) port number can be changed using the "--port" command-line switch.  (The number of ports scanned remains 10, however.  To change the number of scanned ports requires changing yaAGC's source code and recompiling the program.)  One might wish to change the base port if, for example, simultaneously running an instance of yaAGC for the CM and another instance of yaAGC for the LM.  The port ranges of the two instances of yaAGC shouldn't overlap, so one instance could be run (for example) with the command-line switch "--port=19707".

This setting is useful for debugging a DSKY simulation (such as yaDSKY).  This switch causes the "--core" setting to be ignored (in fact, the "--core" switch can be omitted).  Instead of running an AGC executable, yaAGC simply echoes command sequences back to the DSKY upon receiving keystrokes from the DSKY.  These command sequences are defined in the configuration file (see "--cfg" below), and can actually relate to any peripheral devices (not just the DSKY).

This setting is useful for debugging a DEDA simulation (such as yaDEDA).  Unlike --debug-dsky, yaAGC runs the AGC simulation as normal.  But in addition, it interprets communications from yaDEDA.  (In normal operation, of course, it completely ignores data originating from yaDEDA, or indeed any other messages in yaAGS format.)  For each communication received from yaDEDA (for key sequences such as CLR-OctalDigit-OctalDigit-OctalDigit-READOUT) it prints out a message indicating what was received.  For the specific key sequence just mentioned, it goes further and acts similarly to the AEA software, in that it interprets the 3 octal digits as an address in erasable memory, and outputs the value found at that address (in octal) every 1/2 second to yaDEDA.  The addresses most meaningfully observed in this fashion are timer registers like 25 (octal) which increment at 10 ms. intervals, and therefore increments by about 50 (62 octal) every 1/2 second.

This setting is used in conjunction with --debug-deda to eliminate the outputs from yaAGC to yaDEDA which --debug-deda normally creates.  In other words, lets yaAGC parse the messages being received from yaDEDA, but never to send any itself.

This presently has no effect unless used with "--debug-dsky".  It causes a configuration file to be loaded which defines the command sequences used in --debug-dsky mode.  The same directory assumptions are used in searching for the file as are used with the --core switch (see above).  Full instructions can be found within the provided sample files  (presently LM.ini, CM.ini, LM1.ini, and CM0.ini).  The configuration files are really provided for use with the yaDSKY program, and the same file should be selected for yaAGC as is selected for yaDSKY (if --debug-dsky is going to be used).   Only the "DEBUG" lines within the configuration files are relevant to yaAGC.  If no configuration file is selected, or if no DEBUG lines appear within the configuration file, then --debug-dsky will be non-functional.

Causes the AGC program to halt prior to executing its first instruction, and activates a debugging mode (very primitive) in which you can do things like examine AGC registers, single-step through the AGC program, etc.  This mode is described further below.   In Linux (though not necessarily in *BSD, MacOS X, or Win32), you can put yaAGC into debug mode without the --debug switch, simply by hitting the carriage-return key any time after starting the program; the AGC program will simply be halted wherever it is, and you can begin debugging at that point.

For versions 20050728 and later, yaYUL outputs symbol-table information that yaAGC can use in "--debug" mode to aid symbolic debugging.  In other words, if you load a symbol table into yaAGC, then in debug-mode you can sometimes use program labels and variable names rather than having to know the absolute numerical addresses for everything.  The --symtab switch is used to specify the name of the symbol-table file.  The same search path is used as for --core and --cfg.  Since the symbol tables for Luminary131 and Colossus249 (namely, Luminary131.symtab and Colossus249.symtab) are "installed" along with the executables, you can simply say "--symtab=Luminary131.symtab" or "--symtab=Colossus249.symtab".  However, if you want to assemble your own AGC source code, the symbol table output by yaYUL will be named the same as your source file, but with ".symtab" suffixed to it.  For example, if you assemble "MyFile.s", then the symbol table will be "MyFile.s.symtab".  In this case, you'll want to use the complete pathname for the symbol-table as the filename for --symtab.  This feature, and all of the debugging commands associated with it are courtesy of Jordan Slott.  (Thanks, Jordan.)

Normally when the emulator runs an AGC program it sets all i/o channels, erasable memory, and hidden CPU state variables to what it considers reasonable power-up defaults.  (But see "--dump-time", below.)  The --resume option instead allows these items to be loaded from a previously-created file.  (The file itself is created from --debug mode using the COREDUMP command as explained below.)  In effect, this allows execution to continue from the exact point in the AGC program at which the COREDUMP was made, rather than forcing the AGC program to its reset condition.  The file must be either in the current directory, or else a full pathname must be given for it.

For versions 20050705 and later, yaAGC attempts to save the contents of erasable memory, and to restore them automatically at startup (but not i/o channels and hidden CPU state variables).  This means that things like pad loads are preserved even when the AGC is "powered down", just as they would have been in the true AGC's core memory.  In an effort to keep this from increasing system overhead too much, the saving is actually done only every N seconds (10, by default).  The data is saved either in a file called LM.core or CM.core, and is compatible with the "core dumps" described above for the "--resume" switch.  You can start with a clean system by erasing LM.core or CM.core.  Or, you can use "--resume=LM.core" or "--resume=CM.core" if you'd like to restore more than just the erasable memory.  Because separate files are used for the LM and CM, you can run both simulations at once without any conflict.  However, if you want to run more than one LM simulation (or more than one CM simulation), you'd better start them from different directories, to make sure that the .core files are stored in different directories.

On some PC's the act of checking the socket connections (i.e., the mechanism used by yaAGC to communicate with yaDSKY and/or other peripheral devices) can make the simulation very sluggish.  Therefore yaAGC only performs this check every N-th CPU instruction, where by default N=50.  Changing the value of N does not affect the reliability of the communication (i.e., no data is lost).  Making N smaller theoretically improves the responsiveness of the system, except on slow PC's where the overhead from checking the sockets may exceed the computing time taken by the simulation.  For example, a value of N=1 works fine on my ~2.5 GHz P4 Linux and Windows XP systems, but results in about a 10-to-1 slowdown of the simulation on my 450 MHz P2 Windows 98 system.  On the latter system, a value of N=10 seems to work perfectly.  Conversely, increasing N reduces the overhead, but results in a larger time-jitter in signalling, and (in theory) for large enough values a steadily-increasing backlog of data waiting to be delivered.  As far as time-jitter is concerned, it's important to realize that yaAGC does not actually execute a machine cycle every 11.7 microseconds, but merely keeps up appearances of doing so in a way not detectable by the user.  Therefore, there is a pretty large time-jitter anyway, and the amount of jitter is dependent on both the speed of the PC and on the operating system used by the PC.  The value N=50 has been chosen in the belief that it will work well for most PC's, and does work well on all of the example systems mentioned above.  (On my 150 MHz P1, on the other hand, the simulation runs about 50% slow no matter what the setting of --interlace.)  Nevertheless, the --interlace switch may be of value when fine-tuning of the timing is required.

Used only for debugging.  Causes a file called yaAGC.cdulog to be created, containing data related to the bandwidth-limiting of CDU inputs PCDU and MCDU.

Verification of yaAGC Correctness

We're very lucky in this regard, in that I can provide pretty confident assurance that yaAGC does execute AGC code correctly.

How can I make such a bold statement?  Well, for the first 10 years of the Virtual AGC project, I couldn't really have done so with any confidence ... and would have been overreaching if I had done so.  Some things worked, and some didn't.  Although to be fair, many things that "didn't work" actually worked well enough and couldn't have produced any errors, and were usually very obscure anyway.  But I couldn't guarantee it.  The problem was basically that there was no way to compare the behavior of yaAGC vs a real AGC, plus the fact that while the original AGC software had contained self-test code, almost all of that self-test code had been removed by the time of Luminary and Colossus in order to save precious memory.  In other words, we didn't have any of the test code.

However, there was a textual description of the test code in one of the original Apollo documents, "Block II AGC Self-Check and Show-Banksum" by Edwin Smally.  Smally's described tests give the CPU a pretty rigorous (if not 100% complete) going-over.  So I went through Smally's document in detail, and wrote an AGC program myself that performed each of his tests, as well as other tests that seemed reasonable to me from other available documents.  I called this the Validation test suite and corrected yaAGC until it could pass the Validation testing.

But however helpful, that falls far short of a 100% guarantee of completely correct operation, even though I had to content myself with having done as much as I could.

That's all changed now.

What has changed?  Two things.  First, we eventually acquired an early AGC program called AURORA from the collection of the original AGC developer Don Eyles.  AURORA is old enough that it actually still contains the full built-in test software.  In fact, it is the last such software to contain the full self-test, and was itself used back during the original Project Apollo to perform acceptance tests on AGCs.  Second, the electrical schematics of the Block II AGC, or at least a large enough subset of those schematics, had eventually become available, and people began to be interested in building cloned AGC hardware from those schematics.  One such person was developer Mike Stewart.  Mike transcribed those schematics into CAD form, and from there transformed the electrical design into the Verilog programming language with two aims: a) to simulate the AGC electrical design using a Verilog simulator; and b) once the design was fully debugged, to create his own hardware AGC by creating FPGAs from the Verilog description.  The Verilog simulation is very complete, and able to run actual AGC source code ... which of course, we had!   Mike compared the Verilog simulation of the vs the behavior of yaAGC and found discrepancies ... i.e., bugs.  Then he fixed those bugs, either in his CAD transcription or else in yaAGC, depending on where the discrepancies came from. 

In case you wonder just how much detail we're talking about, consider the case of the AGC's DV (divide) instruction.  DV operates on two numbers which it interprets as being between 0.0 and 1.0.  It requires that the divisor be greater than or equal to the dividend in absolute value, and we are told by one document that if the divisor is actually greater than the dividend then "we get total nonsense".  Mike didn't mind the result being "total nonsense", but he wanted yaAGC and the Verilog simulation to give exactly the same bit patterns of "total nonsense".  Now in practice, it simply doesn't matter, since the AGC code was written in such a way that the conditions were always met, so no nonsense could occur anyway.  But Mike worked hard, and eventually the total nonsense matched.  And he did that with everything, not just with DV.  Great work, Mike!

The end result of Mike's efforts is thus that we have two independently-developed implementations of the AGC, namely yaAGC and the Verilog description of the AGC's electrical schematics, which not only agree with each other, but which can pass the full built-in-test suite in AURORA.  I'm happy to interpret that as meaning that yaAGC works correctly now.

Debugging Mode

The debugging capabilities of yaAGC have completely changed over time.  My original debugging features are no longer supported, as of mid-2009.  The best place to read about the debugging features now is in the wiki for our GitHub repository: 

This page is available under the Creative Commons No Rights Reserved License
Last modified by Ronald Burkey on 2022-10-27.

Virtual AGC is hosted
              by ibiblio.org