What is the
Abort Guidance System (AGS) or Abort Electronics
Assembly (AEA)?

The
AGS was a
computer system used in the LM. It was a completely separate
computer system from the LM's AGC, with a different
architecture, different instruction-set, and different runtime
software. It was in the LM as a kind of backup for the AGC, but
was only supposed to be used (as the name implies) in case of an
aborted landing. The AGS doesn't have as commanding a rôle
in the history of lunar explanation as does the AGC, because no aborts
were ever needed in actual missions. However, when the AGS made
its few appearances in history it did so dramatically.

For example, the AGS was involved in a
near-disaster during the Apollo 10, at the closest approach of the LM
to the moon. This wasn't a flaw in the AGS or its software, of
course. It was caused by problems executing the crew procedures.
Recall that the mission of
Apollo 10 was to orbit the moon, then to take the LM close to the lunar
surface (but not to land), and then to jettison the LM's descent stage
and return to orbit with the LM's ascent stage. When the LM
("Snoopy") staged, the plan was to do it under AGS/Attitude Hold, with
Tom Stafford controlling the attitude with his hand-controller.
As the LM approached the perilune of the Descent Orbit, at the point of
simulated lunar liftoff, Stafford noticed a small yaw drift (caused, as
it turned out, by yaw rate-gyro stiction) and presumably he wanted to
not have to worry about controlling the LM's attitude when he was
punching off the Descent Stage and firing the down-jets for separation.
Unfortunately the AGS was mistakenly set for "CM pointing," only useful
during rendezvous, so when he toggled back to Auto, from Attitude Hold,
the AGS promptly fired the jets to get the LM facing the CM in its
orbit, above and ahead of them. Because there were no real attitude
rate limits for maneuvering in AGS, the Ascent Stage swung wildly back
and forth as the AGS crudely did its normal thing, damping out the
rates as it approached its target, and settled nicely where it was
"supposed" to be with no inputs from Stafford.
(See the mission
report.) So it all turned out okay.

The AGS was used on the Apollo 11 mission also, when Armstrong decided
not to do the proper attitude sequence as he was getting ready to
re-dock with Columbia after returning from the moon. He rolled the LM
through PGNS gimbal lock, instead of yawing and pitching, and had to
switch to the AGS for attitude control.

Amusingly, the AGS was orginally called the "Backup Guidance System"
but its acronym (BUGS) apparently was not considered suitable.

The AGS was developed by TRW,
rather than by the MIT Instrumention Lab that developed the AGC, so
there was no overlap in development personnel between the AGS and AGC
systems. Furthermore, there was almost no overlap in engineering
technique, other than that both groups of necessity were generally
constrained by the technology available at the time. For example,
both needed to use memory based on ferrite-core technology.
Moreover, there was no interaction between the AGS and AGC systems,
other than a downlink enabling the AGS to download the AGC's
navigational data (and thus avoiding manual entry of data) .

Strictly speaking, the computer part of the AGS is called the Abort
Electronics Assembly (AEA), and so you may
sometimes see references to the AEA rather than the AGS.
Various components in the AGS include:

The AEA can process Rendezvous Radar data but not Landing Radar data,
which makes sense because it's only potential use was to get away from
the immediate vicinity of the lunar surface. There is, however, a
story that Gene Cernan says they had figured out how to use the AGS to
land the LM without an AGC. This may have been Gene pulling
somebody's leg, but I'm gullable enough or possibly ignorant enough to
believe it.

(Thanks to Paul Fjeld for a lot of this explanation and, in fact, a lot
of the verbiage as well.)

AGS Documentation

The following documentation is not available (as far as I know)
anywhere else. It was digitized by John Pultorak (thanks, John!)
from physical documents preserved and donated by Davis Peticolas
(thanks, Davis!).

A block diagram of
the AEA, taken from document 69N33430 (LM/AGS Design
Survey), 3.5M bytes. (Actually, John had to outlay money
for this, as it's not one of Davis's docs, so we have additional cause
to thank him. He also tells us it's the best AEA architecture
diagram he has seen.) The complete LM/AGS Design Survey document
is now available
at klabs.org.

Abort
Electronic Assembly Programming Reference, H. L.
Stiverson, 7322.3-17, April 1966, 77 pages, 14.6M bytes. This
document is the principle (and almost complete) reference for
understanding the operation of the AEA CPU per se, the AEA assembly language
and assembler, and the operation of the CPU's i/o ports. There
are, however, some confusing aspects to the document:

Perhaps the
most confusing thing is that while the portion of the document that
covers the LEMAP assembler makes it clear that the integer -1 would be
encoded in octal as 0777777 (as anyone working with a modern PC would
expect), the portion of the document that covers assembly language
repeatedly refers to the octal 0400000 as being "-1". (More
specifically, the reference on these occasions is to "A0 = 1, A1 thru
A17 = 0", where A0 is the sign bit and A1-A17 are the data bits.)
In fact, this octal pattern encodes the "largest" 18-bit negative
number, namely -131072. In this detail, the assembly-language
portion of the manual is thus incorrect.

Perhaps the most serious omission is that the explanation of
division (the DVP
instruction) in the case where the dividend and/or divisor is negative
is completely lacking and (in the absence of this explanation) I've
never figured out satisfactorily how it is supposed to work

LM AGS, Programmed Equations Document, Flight Program 6,
11176-6041-T0-00, TRW, 1969 April. Because of the size, we
provide this in 2 chunks:

Architecture of
the Abort Electronics Assembly (AEA)

"As with the PGNCS computer, the AGS
computer went through an evolutionary period in which designers
clarified and settled the requirements. The first design for the system
did not include a true computer at all but rather a "programmer," a
fairly straightforward sequencer of about 2,000 words fixed memory,
which did not have navigation functions. Its job was simply to abort
the LEM to a "clear" lunar orbit (one that would be higher than any
mountain ranges) at which point the crew would wait for rescue from the
CM, with its more sophisticated navigation and maneuvering system. The requirements
changed in the fall of 1964. To, provide more autonomy and safety, the
AGS had to provide rendezvous capability without outside sources of
information. TRW, the contractor, then
decided to include a computer of about 4,000 words memory. The company
considered an existing Univector accumulation machine but, instead,
chose a custom designed computer.

"The computer built for the AGS was the
MARCO 4418 (for Man Rated Computer). ... The computer was 5 by 8 by 23.75 inches, weighed 32.7
pounds, and required 90 watts. The memory
was bit serial access, which made it slower than the PGNCS computer,
and it was divided into 2K of fixed cores and 2K of erasable cores. The actual cores used in the fixed and erasable
portions were of the same construction, unlike those in the PGNCS
computer. Therefore, the ratio of fixed memory to erasable in the MARCO
4418 was variable. TRW was obviously
thinking in terms of adaptability to later applications."

10000 (octal) words of memory. The lower 4000 (octal) words
were "temporary" memory, while the upper 4000 (octal) words were
"permanent" memory. These two banks differed in that an "inhibit"
signal was omitted in the upper bank, so that the contents could not be
altered by the running program. The memory-cycle time is 5
µs.

Memory words were 18 bits. Instructions used 5 bits as an
operation code, 12 bits as an address, and 1 bit to indicate whether or
not the address was indexed. (For an indexed instruction, the
address was altered when the instruction was executed by adding the
contents of a dedicated index register.)

Data words were 2's complement. In the case of many
calculations, a fixed-point discipline was used, so that fractional
values could be used. This method is similar using a slide rule—a
paradigm naturally quite familiar to the programmers of that
time. (A slide rule represents only numbers in the range 0 to 1
and the user is supposed to mentally track the position of the decimal
point for each successive multiplication or division he or she
performs.)

There were several dedicated registers, outside of the
memory-address space. Some of them, like the M register depicted in the
diagram at right, aren't of real interest to the programmer, since they
function at the hardware level, transparently to the program. The
registers of interest to the programmer are:

Register

Description

A

The "accumulator", involved
implicitly in most instructions as the source or destination for data.

Q

The "multiplier quotient"
register. A kind of less-significant-word register for extending
the length of the accumulator, but also used in a dedicated way for a
number of different kinds of operations like multiplication and
division.

Index

A three-bit register which can
optionally be added to addresses to create an indexed addressing mode
by setting the index flag in the instruction word. Also used as a
loop counter. Obviously, since the register can only take values
0-7, the array and loop sizes used were very small.

I/O space. There was an i/o address space, separate from
the memory address space, by which peripheral devices were accessed by
dedicated instructions. These i/o ports were used for such things
as accessing the DEDA (Data Entry and Display Assembly), reading gimbal
angles, controlling the engine, telemetry downlink, and so forth.
Only a handful of i/o ports were needed, but these were spread out over
the 12-bit i/o address space.

There were 27 different types of instructions, each requiring one
word of memory. Execution times ranging from 10 µs to 104
µs, but most were in the 10-16 µs range.
Multiplication and division required 70-73 µs.

yaAGS, the
AGS CPU Emulation

yaAGS is the program which
emulates the AGS CPU. In other words, it loads the binary form of
the AGS flight software, or other software newly written for
verification purposes, and then executes that software on a cycle by
cycle basis, emulating the CPU's architecture and instruction
set.

The program has just become operational (2005-06-15), but probably with
plenty of bugs to fix.

Of itself, the emulation is not very visually exciting,
since the CPU requires peripheral devices as well. The
peripherals are not provided directly by yaAGS; rather, they must be emulated
by separately-provided software. (Once these peripherals are
available for yaAGC, we'll
work to make them available for yaAGS
as well.) This technique allows a
developer of (for example) a lunar lander simulation to use the CPU
emulation, but to replace simulated peripherals in order to achieve
better integration. The principal peripheral is the DEDA (see
below).

The command-line syntax is:

yaAGS [OPTIONS] --core=Filename

The name of the file for the
"--core" switch is an executable binary created using the yaLEMAP cross-assembler or the binLEMAP utility. (Typically,
"--core=FP6.bin" or "--core=FP8.bin", since these are the available AEA
flight binaries.) Both
programs are described below. The core file format is discussed
in the binLEMAP section,
although it won't be of interest to most users.

The presently-defined options are:

--help

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

--debug

Causes the AGS program (such as Flight
Program 6 or Flight Program 8) to halt prior to
executing its first instruction, and activates a debugging mode (very
primitive) in which you can do things like examine AEA CPU registers,
single-step through the AGS program, etc. This mode is described
further below.

--debug-deda

(20090319 and later.) Prints
messages on the console about data packets received from the DEDA(s).

yaDEDA, the AGS
User-Interface Simulation

The
term
DEDA refers to the Data Entry
and Display Assembly, which is
the assembly used by the astronauts to enter data into the AGS, or to
see data displayed by the AGS. The DEDA was mounted in the
lower-right portion of the LM's control panel, just in front of the LMP
(Lunar Module Pilot). Recall that in the somewhat odd terminology
employed in the Apollo program, the LMP did not actually pilot the
LM. Rather, the commander piloted the LM from the left-hand
position.

yaDEDA
is an emulation of the DEDA for use with yaAGS. However, it is
certainly possible for the developer of a LM simulation to develop his
or her own emulation of the DEDA. Indeed, the program yaDEDA2 has now superceded the
original yaDEDA program,
although the original is still available if someone was interested in
it. When I refer to "yaDEDA" below, I actually mean to refer
interchangeably to both "yaDEDA" and "yaDEDA2" unless I state
otherwise. For information on developing these kinds of
alternative implementations, you should refer to the developer info
page. You'll notice that the screenshot of yaDEDA to the right is somewhat
different from the drawing of the DEDA above, particularly as to the
HOLD-key; that's because of discrepancies in the available
documentation, so feedback on this issue is particularly welcome.

Unlike the DSKY, which is basically completely useless without the AGC,
the DEDA has some built-in smarts. Actually, most of the DEDA
user-interface is built into the DEDA, and so yaDEDA can be operated even without
the presence of yaAGS.
Notice that the DEDA has two displays: a three-digit display
which is an octal "address", and a 5-digit display (plus sign) of
"data". Quite a lot of the operation of the DEDA was simply to
enter an address (in the first 512 bytes of AEA memory), after which
the AEA would output the value of that memory location every
half-second. The AEA software would format the data, which could
be either octal or decimal, or could involve various scale factors or
units. However, the units and scaling and octal vs. decimal
choices are hardcoded into the AEA software, and are not selectable by
the user. This mode persists until pressing the HOLD key, which
signals the AEA software to stop outputting data. (After hitting
HOLD, you could hit READOUT again to restart the
data-monitoring.) To put the DEDA/AEA in this continuous readout
mode, you do the following on the DEDA keypad:

CLR OctalDigitOctalDigitOctalDigit READOUT

The digits appear on the address display as you enter them. Any
error in entering this sequence causes the OPR ERR lamp to light,
making the DEDA basically inoperative until the CLR key is pressed
again. All of this, except for the actual generation of the data,
occurs within the DEDA without needing an AEA (yaAGS).

The other thing you can do with the DEDA user interface is to perform
data entry: i.e., to send the AEA a command or data. The
interpretation of the data you enter is dependent on the address you
enter:

Again, both the 3-octal-digit address and the 5-digit data (plus sign)
appear on the display as you strike the keys, but any departure from
the above sequence lights the OPR ERR lamp, which can only be cleared
with CLR. The 5-digit data can be either octal or decimal, but
this is address-dependent (as hardcoded into the AEA software), so it's
not a matter of your choice. Other than the actions which this
type of operation is supposed to cause within the AEA, all of this
takes place within yaDEDA.

The command-line syntax for the yaDEDA2
or yaDEDA program is:

yaDEDA2
[OPTIONS]or
yaDEDA [OPTIONS]

The
presently-defined options are:

--help

Display a list of options, something
like the information shown here.

--ip=addr

yaDEDA
and yaAGS are a client/server
pair, and can be running on the same computer or on different
computers. In order to connect to the yaAGS
server, yaDEDA has to know the
IP-address of the machine on which yaAGS
is running. By default this is "localhost"---i.e., the two are running
on the same computer. However, a different IP address may be specified
using this command-line switch. In Linux, this may be either the
machine's name, or else a numerical address in dotted format (n.n.n.n).
MS-Windows---at least Windows 98---is somewhat crippled in this
respect, and will only accept a host name rather than a numerical IP
address.

--port=port

Similarly (see above), in addition to
an IP address, a port number is needed. This must be in the range of
port numbers yaAGS is scanning
(which by default is 19897-19906). If no port is specified, yaDEDA will use 19897, in accordance
with the suggested port assignments on the developer
page.

--half-size

yaDEDA's
graphical interface is simply too big for PCs with lower graphical
resolution (smaller than 1024×768). If the --half-size
switch is used, half-size graphics are used, and so the interface
should be usable even down to 640×480 resolutions. The
smaller interface doesn't really look very good, because it is
simply blindly scaled down from the larger interface, rather than being
optimized, but at least it's usable at 800×600 and 640×480
resolutions.

--delay=Milliseconds

Adds a delay at start-up, so that yaDEDA
does not immediately begin attempting to communicate with yaAGS. The current defaults
are 0 ms. in Linux and 500 ms. in Win32. This "feature" has been
added as a temporary work-around for problem
report #23, and probably has no other sensible purpose. Even
on Win32 it isn't usually needed, but it's here for the 10% (or
whatever) of the time it's needed.

--relative-pixmaps

(Final version of yaDEDA only; not available on yaDEDA2.) Alters the locations
of graphics files used by the yaDEDA
program to the ./pixmaps/yaDEDA/ folder rather than the default system
folders. This makes the program compatible with the directory
structures and runtime assumptions of the VirtualAGC GUI system rather than
the previously used script-driven runtime system.

yaLEMAP, the AGS
Cross-Assembler

The original cross-assembler for AGS assembly language was known as the
"LEM Assembly Program", or LEMAP.
You can read all about it in the document by H. L. Stiverson (see
above). We don't have the code for the original cross-assembler,
nor (if we did) do most of you have access to the type of computer on
which it ran. So, we're providing you with a completely new
assembler that can assemble the original flight-software source code
into a binary usable by the AGS CPU emulation, yaAGS. Naturally, we call this
new cross-assembler yaLEMAP.

The command-line syntax for yaLEMAP
is:

yaLEMAP
[OPTIONS] SourceFilename

The only presently-defined option is:

--compare=Filename

This switch causes the assembler to
load the binary file called Filename,
and to compare the binary output produced by assembly of the source
code to the contents of Filename.
Presumably, Filename was
produced by an earlier run of yaLEMAP
or binLEMAP (see below).
This is type of comparison is useful principally for regression testing
of the assembler itself, and (indeed) such regression testing is
performed during a normal build. This switch also causes a change
in yaLEMAP's return codes,
which are normally based on the presence of errors and warnings.
(In other words, a non-zero return code normally occurs in case there
are errors during assembly.) With the "--compare" switch, though,
yaLEMAP has a return code of
zero when the binaries match, and a non-zero return code when they
don't match. Naturally, one could use operating-system utilities
(such as fc in Win32 or diff in Linux) to mimic this
functionality as well; however, the "--compare" switch also has the
property of adding meaningful messages about any mismatches to the
assembly listing, which the operating-system utilities do not.

--html

(20090629 and later.) Causes
creation of an HTML version of the assembly listing. The HTML
filename is the same as SourceFile,
except that the .ags filename extension (if present) is replaced with
.html. The HTML is
syntax-highlighted, so that it is easy to distinguish opcodes from line
labels, etc. Finally, the
HTML contains hyperlinking from where symbols are used to where they
are defined. It is also
possible to define modern annotations for the source code.

yaLEMAP is a simpler program in
may
ways than the AGC cross-assembler yaYUL.
There are several reasons for this:

The architecture, and particularly the memory-map of the AGS is
much more regular than that of the AGC.

The AGC assembler has to worry about assembling several different
kinds of languages in the same source file: AGC assembly
language, AGC interpretive language, telemetry downlink language, and
perhaps others I've forgotten about. The AGS assembler only has
to worry about AGS assembly language.

The AGS flight programs are so much shorter than AGC flight
programs -- about ten times shorter, in fact. Therefore, a
complete AGS flight program can be conveniently provided in a single
source file, rather than having to break it up into 30 or 40 shorter
files as is done with the AGC flight programs.

yaLEMAP always outputs its
binary in a file called yaLEMAP.bin, which has a format compatible with
both yaAGS (see above) and binLEMAP (see below).
Similarly, the assembly listing file is always output to the file
yaLEMAP.lst.
The listing format is not identical to that of the original LEMAP program, but its flavor is
pretty similar, and the changes are probably more in line with today's
thinking. (For example, in the symbol tables produced by yaLEMAP, the symbols are referenced
to their numerical values. In symbol tables produced by LEMAP, the symbols are referenced to
line numbers within the assembly listing, and you can look at that line
number to see the numerical value which has been assigned. That's
logical, perhaps, in a world where everybody is looking at paper
printouts; it's not logical in an online world, so I haven't felt too
bad about changing it.)

The syntax of the source code for yaLEMAP
similarly isn't identical to that accepted by LEMAP as outlined in the AGS programmer's
manual, but it's pretty close. The principal differences are:

yaLEMAP is not
column-dependent the way LEMAP
is, except that labels are still expected to begin in column 1.

Comments in yaLEMAP are
expected to begin with the symbol '#'. Anything following the '#'
symbol to the end of a line is ignored.

Utility Programs

binLEMAP, for ASCII Entry of AGS Executable Binary

There are two distinct ways of obtaining executable AGS binaries from
an AGS assembly listing. You could enter the assembly-language
instructions into the computer, creating source code that can be
assembled with yaLEMAP as
explained above. Or, you could enter the octal form of the
opcodes into the computer, creating a file of numbers that can be
processed with the binLEMAP
utility. In fact, for verification purposes we do both, and then
compare the results as explained below.

Use of the binLEMAP utility is
quite simple, as it has no command-line options. It simply reads
the standard input and creates a file called binLEMAP.bin. The
command-line syntax is:

binLEMAP
< InputFile

The
output file, binLEMAP.bin, consists of 10000 (octal) entries, each one
of which is a 32-bit unsigned integer in little-endian format (i.e.
with the least-significant byte first). The first entry
represents AGS memory address 0, the second represents AGS memory
address 1, and so forth. This file is therefore always exactly
16384 (decimal) bytes in size.

The input file obeys the following simple rules, tailored to match the
way the assembled data appears in LEMAP
assembly listings, in order to make data entry easy:

Anything following the '#' character is treated as a comment and
is discarded.

All appearances of the character 'p' are removed and replaced by
blank spaces.

A line of the form "ORG OctalValue"
resets the location counter (which starts at 0) to the indicated value.

A line consisting of an octal number is stored at the location
counter, which is then incremented.

A line consisting of three octal numbers is processed to a single
octal number, which is stored at the location counter, which is then
incremented. (The three values are treated as a 6-bit opcode, a
1-bit index flag, and a 12-bit address. The opcode and index flag
are logically ORred, the result is shifted upward 12 bits, and then
logically ORred with the address.)

The purpose of the rather odd rule about removal of the character 'p'
is that it means an optional 'p' can be inserted after an octal
number. It helps me in my proofing to run these files through the
text-to-speech converter on an iMac, and this subterfuge of adding the
extra 'p' fools the iMac's text-to-speech converter into pronouncing
the numbers in the way I want.

AGS Flight Software

Availability

The following versions of AGS flight software are available:

Flight Program 6 (FP6), June 1969. This was used in the
Apollo 11 mission. The source code and binary are available and
believed to be 100% complete and accurate.

Flight Program 8 (FP8), December 1970. Fabrizio Bernardini
tells us that according to the A17 Flight Readiness Review
documentation, that this was released April 28, 1971 ... and of course,
the fact that it was specified implies that it was used for Apollo
17. From the release date, we conclude that it could not have
flown before Apollo 15. Thus, we assume it was used for Apollo
15-17. The source code and binary are available, and are believed
to
be 100% complete and correct.

If you know of other existing versions of the AGS source code, give
them
to us!

Validity

Validation of the AGS source code is somewhat streamlined from the
method used to validate AGC source code. The following process is
used:

The source code is entered into the computer from the assembly
listings.

It is assembled with the yaLEMAP
cross-assembler. As a byproduct, a ASCII file is produced with
just the columns of the assembly listing containing the assembled octal
values.

The byproduct ASCII file mentioned above is fed into a
text-to-speech converter program, and the now-audible octal codes are
compared visually against the original scan of the assembly
listing. The source files are fixed as needed when mismatches are
found.

Obviously, it's a matter of opinion how many times the proofing
process described above needs to be repeated. I have repeated it
only until the embedded checksums are correct. If anyone wants to
volunteer to perform additional proofing—for example, of the program
comments, which are not checked by the process I used—feel free to
do so and to report the results to me.

Special
Problems of Flight Program 6

Unfortunately, the assembly listing we have of Flight Program 6 is
missing a couple of pages (namely, pp. 90 and 96). From
comparison of FP6 and FP8, I believe that the missing pages contain
code that has not changed between FP6 and FP8, and therefore have
simply substituted the corresponding chunks of code from FP8 into
FP6. The types of circumstantial evidence that this is acceptable
are as follows:

The code preceding and following the missing chunks is the same
in FP6 and FP8.

The line-count of the missing chunks matches in FP6 and
FP8. (37 lines are missing in both cases.)

The lengths of the address ranges of the missing chunks match in
FP6 and FP8. (Actually, the addresses themselves match rather
than
merely the lengths of the ranges. In other words, this entire
section of code assembles not just to the same binaries in FP6 and FP8,
but literally to the same memory addresses. That's stability for
you!)

The assembly listings contain both symbol tables (giving the
value of each symbol) and symbol-usage tables (listing all the lines of
code where each symbol is used). I have not yet compared the
symbol tables for FP6 and FP8 in the appropriate address ranges, since
it is very involved and I am busy. (If you want to volunteer to
do this, contact me!)

As explained earlier, the checksums need to be correct. And
indeed, they are
correct. Actually, it turns out that the checksum for the address
range 4000-7777 (octal), which contains these missing pages, is
identical for FP6 and FP8, leading us to believe that this entire
memory block has not changed at all.

Finally, if you refer to
page 72 of the TRW LM/AGS
Design
Survey document, you'll find the following explanation: "The
equations programmed into the hardwired portion of the memory are
identical in all flight computers (except for a few early
prototype computers used for test purposes). The equations
programmed into the softwired portion of the memory are subject to
change from mission to mission." The hardwired portion of the
program is, of course, the address range 4000-7777. On p. 30 of
the same document, you'll find the additional explanation that the
hardwired portion of the program is designated "HO3", but that the
earlier versions (for the "early prototype computers") were designated
"HO1" and "HO2". Consequently, invariance of the hardwired
portion of the program is a design feature rather than an accidental
characteristic.

This all seems pretty conclusive, but if you have a listing of FP6,
please scan pages 90 and 96 and send them to me and save us this
dreadful uncertainty! (Of course, if you have other versions of
the program, scan them and send them to me too! Or send them to
me via snail-mail, and I'll scan them and return them.)

yaAGS Debugging Mode (--debug)

Important Note!

The description that follows
covers the "classic" debugging mode for versions prior to
20090427. I retain this description
as-is for the benefit of those using one of those versions of yaAGS.
However, for versions 20090427 and later, command-line debugging is in
the process of changing to a style more closely related to that of the
widely used gdb program, and
the "classic" mode
described below will gradually disappear. Since these changes
have
been driven by Onno Hommes, we have agreed that Onno will maintain
documentation for the new debugging mode at his website.

When the "--debug" command-line switch is used, a mode is entered in
which AGS programs can be debugged. This mode is very primitive
compared (for example) to the facilities provided by a debugging
program like gdb, but has been
pretty useful for my purposes, and may conceivably be useful for
yours. You are unlikely to find this mode (or my description of
the mode!) of any use unless you are very familiar with AGS assembly
language, and are
writing/debugging AGS code. In this mode, rather than simply
running the software contained within the core image, yaAGS halts prior to executing the
first instruction of the program and allows you to interactively
determine its further actions. You are presented with a status
message and a prompt from which you can enter commands.

We see the current values (in
octal) of various important CPU registers. All numerical values
displayed by the debugger are in octal, because octal
notation is used almost exclusively throughout existing AGS code,
and because almost all of the numerical values reported by the LEMAP assembler were in octal.
The values shown are for:

The A(ccumulator) register.

The Q(uotient) register.

The Overflow flag.

The Index register.

Whether the CPU is halted (by the DLY instruction) until the next
20 ms. signal.

The number of times (in decimal) that this particular type of CPU
instruction has been executed.

How many cycles (of 0.9765625 microseconds each) have elapsed
since the program started.

The final status line is, of course, a disassembly of the next
instruction scheduled to be executed. It shows the current
address (6000), the
octal value of the instruction (706177),
and a disassembly of that octal value into assembly-language (DLY 6177). The debugging
mode does not currently understand any labels defined within the AGS
program itself; therefore, understanding code like "DLY 6177" as something like "DLY INIT" (involving labels)
is aided by having a symbol table or assembly listing at hand.

The debugger understands addresses in one of three formats:

Addresses within memory are represented by a single octal number,
such as 1234. Modifiable memory is in the range 0000-3777, while
non-modifiable memory is in the range 4000-7777.

Addresses within input-channel space (i.e., accessed by the INP instruction) are prefixed
by 'I', such as I2020.

Addresses within output-channel space (i.e., accessed by the OUT instruction) are prefixed
by 'O', such as O2020. There is also a fictional output register
O0, which is used by yaAGS to
combine all of the discrete outputs. The bit positions within O0
correspond to the AEA CPU's discrete outputs as follows:

Within the status display's
instruction-disassembly, the distinction between memory
locations and i/o channels is always obvious, so
i/o channel numbers are not prefixed by 'I' or 'O' in disassemblies.

The user-commands which are currently recognized by the debugger are:

#Anything—(i.e., any
string beginning with the character '#' in the first column) is a
comment,
which is discarded without a warning message. This is principally
useful for writing scripts (which has not yet been implemented).

BREAK A—defines a
new breakpoint at memory-address A.
The
program will halt upon encountering an instruction at the address of
the breakpoint.

BREAKPOINTS—displays all currently-defined breakpoints and
watchpoints.

CONT—begin running the program. The program will simply
run until encountering a breakpoint.

CONT-TIL-NEW—same, but also stop if an instruction-type not
previously encountered in this session is hit. (Only good,
obviously, for debugging the simulation.)

DELETE A—deletes
the breakpoint or watchpoint (if any) currently defined at address A. The address should be
prefixed with 'I' or 'O' for i/o channel addresses.

DUMP—without arguments (i.e, no N
and no A), a dump is
performed using the
last N and A previously used.

DUMP [N] A—displays the current contents
of N successive memory
locations or i/o channels, starting at address A. The formats allowed in A are described above. N is shown in brackets to indicate
that it is optional. If N
is omitted, it defaults to 1. Since no i/o channels are at
consecutive addresses, no N option
is allowed for i/o-channel addresses.

QUIT or EXIT—exits yaAGS.

STEP [N] or NEXT [N]—executes the next N assembly-language
instructions. If N is
omitted, then it defaults to 1. Notes that this command can be
abbreviated as 'S' or as 'N'.

WATCH A—defines a
new watchpoint at erasable-memory address A
(using one of the address formats described above). The
program will halt after
executing an instruction that changes the value stored at the address
of
the watchpoint.

EDIT A V—stores the
octal value V at the adress A. The formats allowed in A are described above. Unlike
the other commands above, this command supports the fictitious "output"
addresses like 2410 which set or reset a discrete output. Note
also that for output-channel addresses, appropriate instruction packets
associated with the output channels are transmitted to peripheral
devices. Instead of an address, you can also access the CPU's
internal registers using one of the following for A. (Note that "EDIT PC" only
changes the program counter, and not the complete CPU state, so it's
better to use the BACKTRACE command if possible.)

PC
A
Q
OVERFLOW
INDEX
HALT

BACKTRACES—displays the most recent (50) backtrace points
(i.e., points at which the program branched).

BACKTRACE N—restores
the state of the system (CPU, memory, i/o channels)
to backtrace point #N (from
the list displayed by the BACKTRACES command).

DISASSEMBLE [[N] A]—disassembles N instructions
starting at address A.
By default A is the current
address of the program counter and N
is its prior value (starting at 24 when the program starts).

COUNTS—displays a list of the number of times each type of
AEA instruction has been executed. The numbers are in decimal.

PATTERN V M—sets a
"pattern" with value V and
mask M. A pattern is
similar to a breakpoint, except that it uses the instruction code
rather than the program counter. In other words, execution is
halted upon finding that the instruction code is equal to the value V. The instruction code is
logically bitwise-ANDed with the mask M
prior to the comparison, so that only selected fields in the
instruction code are really used.