Saturday, June 18, 2022

A G-15 Four-Word Memory Clear Program

A little over a year ago, while researching the Bendix G-15 computer system, I came across a blog, "The Way It Was: Tales from a life in computing," by Jim Horning. The earlier posts in that blog discuss his early programming experiences, starting in 1959, with a G-15 in the Data Processing Lab at Pacific Union College in Angwin, California. Jim went on to spend significant portions of his career at Xerox PARC and the DEC Systems Research Center.

I enjoyed Jim's stories of his adventures with the G-15, but one post in particular caught my attention, "My shortest Program," from 31 August 2006. In it he describes a program for the G-15, only four words long, that would completely clear the machine's drum-based main memory, its software-accessible registers, the arithmetic overflow flag, and a sign flip-flop used in double-precision arithmetic. That's a lot to accomplish in just four 29-bit words, especially since one of those words was executed only once, at the beginning of the program.

Jim did not provide the code for the program, and in the original post described it only in very general terms. His memory was stimulated by a reader's comment to that post, resulting in Jim appending a rather long comment of his own. In that comment he described in some detail the types of commands the program used, the general scheme by which they worked, and gave many clues for how the program used quirks in the G-15 architecture to achieve its ends. I suspect that in 2006 he was working entirely from an almost 50-year old memory and perhaps was unable to recreate the actual code of the program.

Having recently written a software emulator for the G-15 and taken it to the point where it is working fairly well, I thought it would be interesting to try to reconstruct that four-word program and get it to work. It would be a nice test of the emulator, and something of a programming challenge for me. So I started out by reading his post and long comment multiple times, making notes, and trying to write down what the commands must have looked like.

Overview

You can read Jim's post and long comment at the link above for details, but the general scheme of the program, once initialized, was a loop consisting of five commands:

  1. CLEAR—clear one "line" (track) on the drum using the value (initially) in AR, the accumulator register, which was cleared to zero during initialization by the command that got executed only once.
  2. SWAP—exchange that CLEAR command in memory with the zero in AR.
  3. NOOP—execute the zero word just swapped, which was effectively a no-op (short for "no operation"), i.e., it made no change to the internal state of the computer except to specify the location of the next command to be executed.
  4. INCREMENT—increase the value of a field in the original CLEAR command (now swapped into AR) such that it addressed a different line on the drum, and when executed would clear that line.
  5. SWAP—again exchange AR with the NOOP command in memory, leaving the zero value in AR and the incremented CLEAR command in memory ready to be executed again. Then specify the CLEAR command as the next one to be executed and repeat the process from step 1.

That's a five-word command sequence that fits in three words of memory! How is that possible? As Jim pointed out, one of the commands gets held in the AR register, alternating between CLEAR and NOOP on each cycle through the loop, so that's actually four words of storage. The fifth command is SWAP. It gets executed twice, but in both cases it's the same word in the same location of memory.

How that loop works requires some explanation. Understanding that explanation in turn requires some background on the G-15 and how its commands worked, so I'll start there. One of Jim's clues was that the program modified itself during initialization, so the form in which the program was loaded into the system was different than the form in which it did most of its work.

I'll describe that second form first, since it is easier to understand. After that, I'll describe the initial form the program had when it was loaded, then how it started executing and transformed itself into the second form that actually cleared system.

The Bendix G-15

The G-15 was a mid-1950s, binary, vacuum tube, drum memory computer. As Jim hinted in his blog, there were two models, the original G-15A and the 1957 G-15D. There were some minor differences between the two that need not concern us here. My emulator is for the D model.

Drum Memory

The drum memory was organized as 29-bit words arranged in "lines", or tracks. There were 20 108-word ("long") lines numbered 0-19, four 4-word ("short" or "fast") lines numbered 20-23, three 2-word lines that functioned as double-precision registers numbered 24, 25, 26, and known as MQ (Multiplier-Quotient), ID (Multiplicand-Denominator), and PN (Product-Numerator), respectively. There was a single 1-word line numbered 28, AR, the single-precision accumulator. Line numbers 27 and 29-31 did not directly reference storage lines on the drum, but instead specified special functions the processor could perform. Note that the arithmetic registers were storage lines on the drum, not sets of flip-flops inside the processor.

All of the storage lines were implemented as recirculating delay lines, meaning that all of them were read and completely rewritten during each cycle through the line. The long lines cycled every 108 words (about once every 29 milliseconds). The fast lines cycled every four words (about once every millisecond), and AR cycled every word (once every 0.269 milliseconds). The amount of time it took for one word to pass its read or write head on the drum was termed a "word-time," also 0.269 milliseconds.

The basic operation the G-15 performed when executing commands was termed "transfer." Usually this involved copying one or more words from a location on one of the drum lines (termed the "source") to the corresponding location on another line (termed the "destination"). In some cases it was meaningful to specify the same line as both source and destination. When transferring between lines of different sizes, the locations were interpreted modulo the line size, e.g., location 2 on a 4-word line was also location 6, 10, 14, 18,... 102, and 106. 

By default, the transfer simply copied the bits from source to destination without change. A command could specify that certain transformations on a word were to take place during transfer, however. We will see one example of that in the memory-clear program. When a line was not being written by a software command, its bits were simply copied from its read head to its write head, hence recirculating them. The "delay" in the line was the time it took a bit on the surface of the drum to rotate from its write head back around to its read head.

Command Words

A command word in the G-15 executed a specific operation and consisted of eight fields having the following arrangement:

G-15 Command Word Layout

Briefly, the fields in this word, from right to left, had these purposes:

S/D (Single/Double) Bit

This is the sign bit in the word. In a command word it usually specified whether the processor operated in single (0) or double (1) precision mode. It was always zero in the memory-clear program, so need not concern us further here.

D (Destination) Field

The destination line for the transfer operation. This five-bit field could have values from 0 to 31, corresponding to the line numbers described above for the drum. Destination 31 specified that a special function was to be performed. The S field in this case, sometimes in conjunction with the CH field, specified the function. You will see below that the INCREMENT command of the memory-clear program was a Destination 31 command.

S (Source) Field

The source line for the transfer operation. Like D, this five-bit field could have values from 0 to 31. Sources 27 and 29-31 were not storage lines. Instead they supplied a value generated from Boolean operations on other storage lines.

CH (Characteristic) Field

This 2-bit field usually specified a transformation that was applied to a word as it transferred from source to destination. In commands that did not involve line-to-line data transfer, this field sometimes specified optional or variant behavior of the command. In the memory-clear program, this field was always zero—meaning no transformation, the bits were just copied—except for the SWAP command, where it was 2. The meaning of that code will be explained in the next section.

N (Next Command Word-Time) Field

As with many drum or delay-line memory systems of its era, each G-15 command specified the location of the next command to be executed. In most systems with other types of memories, commands were taken from sequential locations unless some command specifically altered the sequence. In the G-15, commands were executed from a single drum line at a time, each command's N field specifying the location of the next command on that line to be executed. Execution continued from that line until a command switched it to a different line. The memory-clear program was loaded into and ran entirely from the 4-word line 23.

BP (Breakpoint) Bit

This bit, if 1, caused the processor to halt if the COMPUTE switch was in the BP position. It was also always zero in the memory-clear program, and thus can be ignored in this discussion.

T (Timing) Field

This field controlled the timing of the transfer phase of the command. The way that field was interpreted depended on the state of the I/D bit described next.

I/D (Immediate/Deferred) Bit

This bit specified whether the command was to be run in Immediate (0) or Deferred (1) mode. All commands in the memory-clear program were Immediate, so we need not be concerned with Deferred mode. In Immediate mode, transfer began with the word-time (location) immediately following that of the command itself, although often on different source and destination lines. Transfer continued up to, but not including, the word-time specified in the T field. You will see below that the use of the T field in the INCREMENT command of the memory-clear program was an exception to this.

For more detailed information on G-15 commands, you may wish to look at a prior post in this blog, which gives fuller descriptions. For the whole story, the best reference is the G-15 Programmers Reference Manual. If you are feeling particularly brave, circuit-level details of command execution can be found in the G-15 Theory of Operation Manual.

Precession

A very important concept in the G-15 is precession, which is a form of data shifting. The processor did precession in units of bits and whole words; the input/output subsystem did precession in units of one bit, three bits, and four bits. All of these were accomplished by interrupting the normal transfer path from the read head for the source drum line and routing that stream of bits through a shift register of length n bits before routing the bits to the write head for the destination line. The effect of this was to delay writing to the destination line by n bits. The end result was:

  • The original n bits of the register became the low-order n bits of the first word written to the destination line.
  • The original contents of the destination line were shifted to the left (towards higher addresses) by n bits.
  • The original high-order n bits in the last word from the source line were left in the register.

This was a powerful, if somewhat unusual, feature of the system and was used extensively in many programs. The SWAP command in the memory-clear program made use of whole-word precession, primarily to exchange the CLEAR and NOOP commands through the AR register, but also as part of the transformation the program underwent from its loaded to its executing form.

The Second Program Form

As previously mentioned, the memory-clear program changed during its initialization from the form in which it was initially loaded to the form in which it cleared the system. This section describes that second form the program took and how it worked. The following table shows the program's command words immediately following their initialization:

L Hex T N CH S D Description
0 060235z 6 2 0 26 31 INCREMENT AR by 3
1 02693vw 2 105 0 29 28 Set AR to 0 (not used here)
2 0403uz7 4 3 2 23 23 SWAP location 3 with AR
3 0402380* 4 2 0 28* 0* CLEAR a line to zero
0000000 0 0 0 0 0 NOOP (copy line 0 to itself)

L is the location of the command in line 23 on the drum. The Hex column shows the hexadecimal value of the command word with the low-order sign bit stripped off, since it is always zero, leaving the 7 hex digits of the remaining 28 bits. Note the use of the G-15 convention for hexadecimal digits: u=10(a), v=11(b), w=12(c), x=13(d), y=14(e), and z=15(f).

The initialization phase of the program loads zero into the AR register, transforms the code into this second form, and then sets location 3 to be the next command executed. The table entry for location 3 shows two commands, CLEAR and NOOP, because these commands are swapped with the AR register on each cycle through the program's loop. When the CLEAR command is in location 3, the NOOP command (a word of zeroes) is in AR, and vice versa.

Execution of this phase begins at location 3 with the CLEAR command, shown here in its initial state. That command copies zeroes from AR (line 28) to long line 0. This command is modified by the INCREMENT command, however, changing the value of the CLEAR command's D field to address a sequence of lines on the drum. Hence the asterisks and underscores in those table cells, indicating that these values change as the program runs.

The command in location 1 is not executed during this phase of the program and was used only once to initialize AR to zero. Note that this command has a strange N value of 105. How can you have a next-command location of 105 for a 4-word line? It turns out you can, and that value is critically important to the initialization process, as will be explained in the next section.

We are now ready to trace through the execution of this phase of the program, starting with the CLEAR command in word 3. The AR register is zero.

CLEAR—This command transfers the value of AR to a line on the drum, initially line 0. Because it executes in Immediate mode, transfer begins with the word-time (location) after that of the command itself. Since the command is at word-time 3, transfer begins at 4. The transfer phase for an Immediate command continues up to but not including the value in the T field, 4, so transfer ends at word-time 3. Thus this one command will copy the zero in AR to locations 4, 5, 6,... 106, 107, 0, 1, 2, and 3, clearing the entire 108-word line.

The N field of the command specifies that the next command will be taken from word-time 2, the SWAP command.

SWAP—This command has source 23 and destination 23, which is the line from which the program's commands are being executed. This seems like it will not accomplish anything useful other than to specify the next command location, but this command has a CH (characteristic) field of 2.

CH=2 specifies a type of transformation termed Transfer Via AR (TVA). This is a form of whole-word precession. During each word-time of the transfer phase, the value of the word from the source line is copied to AR, while simultaneously copying the value originally in AR to the corresponding location on the destination line.

Since this is an Immediate command at word-time 2 with a T field of 4, the transfer phase will start with word-time 3 and end with word-time 3. That means that a single word will be precessed from the source through AR to the destination. Also, in this case the source and destination lines are the same, so the effect is simply to swap the contents of AR with the word at location 3, leaving the CLEAR command in AR and the word of zeroes (the NOOP command) in location 3.

The N field of the command specifies that the next command will be taken from word-time 3, now the NOOP command.

NOOP—This command, being a word of zero, simply copies data from line 0 to line 0. Since the location of the command is 3 and the T field is 0, transfer state will extend from word-times 4 through 107, but that is not important, because nothing gets changed. The only effect of this command comes from its N field, which specifies the next command will be taken from word-time 0, the INCREMENT command. Another (passive) purpose of this command is to preserve the value of zero while the CLEAR command is in the AR register being incremented.

INCREMENT—As Jim pointed out in his long comment, this is actually a G-15 shift command. It shifts the MQ register (line 24) left while simultaneously shifting the ID register (line 25) right. Since these are 2-word registers, each shift requires two word-times. This command executes in Immediate mode, but the T field in this case is interpreted as an absolute count, not the ending word-time. Since each shift requires two word-times, the T value must be twice the number of shifts desired.

The shifting behavior of the command is not relevant to its purpose in this program, however, and those registers are eventually going to be cleared anyway. Instead, the command is used for a side effect—if the CH field of the command is 0, the AR register is incremented by one for each shift performed.

At this point, the AR register holds the CLEAR command. The T field has the value 6, which means that three shifts will be performed. Thus, the real purpose of this command is to increment the D field of the CLEAR command by 3. Jim explains the rationale for incrementing by 3 in his long comment, but suffice it to say that this results in a sequence of values for the D field of 0, 3, 9,... 24, 27, 30, 1, 4, 7,... 25, 28, 31, 2, 5, 8,... 23, 26, 29, 0. Overflows from field D into field S of the CLEAR command occur when incrementing from 30 to 1 (yielding S=29) and from 31 to 2 (yielding S=30). The reason why the CLEAR command continued to work properly after its S field no longer referenced AR is explained below.

The N field of the INCREMENT command specifies that the next command will be taken from word-time 2, which is again the SWAP command.

SWAP—This is exactly the same SWAP command as the one above and works in exactly the same way, swapping AR with the word in location 3. The difference this time, however, is that the incremented CLEAR command is in AR and the zero for the NOOP command is in location 3. These are exchanged so that once again the zero is in AR and the CLEAR command is in location 3.

The N field of this command is still 3, so the next command to be executed will be the now-incremented CLEAR command. This completes the program's cycle for one destination line. That cycle now starts over again at the CLEAR command.

There are a several additional details necessary to complete the picture of how this phase of the program worked, most of which Jim mentioned in his long comment.

  • How does the program terminate? It doesn't. Once line 23 gets cleared, the program no longer exists, or rather, its words have all been overwritten with zeroes, which are NOOP commands. No matter in which word-time the CLEAR for line 23 ends, the NOOP will copy line 0 to line 0 and take the next command from location 0, which is also a NOOP. Thus, the program finishes by endlessly executing NOOP commands, copying line 0 to line 0 until the operator halts the system.
  • The CLEAR command always executes with AR being zero, so once the CLEAR for line 23 finishes, AR remains zero, as do all of the other registers.
  • Note from the discussion of the INCREMENT command above that the sequence of incremented D field values for the CLEAR command does not end with 23—destinations 26 and 29 come after that. Thus, once line 23 is cleared and the system starts continuously executing NOOPs, those last two destinations do not get cleared. That does not matter, though, because:
    • As Jim pointed out, line 26 is the PN register, which the system automatically clears when a value is copied to line 25, the ID register. This happens before line 23 is cleared.
    • Destination 29 is not actually a storage line on the drum. Instead it is a destination used to add a value to AR. Thus, not copying (nor adding) anything to it is not a problem.
  • When a value from an even word-time is copied into line 25 (ID), the sign of that value is copied automatically into the IP flip-flop, which holds the sign for multiplication and division commands. Thus, when line 25 is cleared to zero, IP also gets reset.
  • Destination 27 is also not a storage line on the drum. It is the TEST destination. If during the transfer phase it receives any 1-bits, then the next command is taken from the location one after that specified in the N field of the test command. The CLEAR command only transfers zero bits, however, so this "skip on non-zero" action never takes place.
  • Similarly, destination 31 is not a storage line on the drum. It indicates that the operation specified by the S field in the command will be performed. Destination 31 will be addressed during the time that the S field in the CLEAR command has the value 29. The combination D=31, S=29 tests and resets the arithmetic overflow flip-flop. As with the TEST destination above, if the overflow flip-flop was set, the next command is taken from the location one after that specified in the N field of the command. The CLEAR command that triggers this test has an N field of 2, so if the overflow flip-flop was not set, execution continues to that location in the normal manner. If overflow was set, however, the next command will be taken from location 3, which is once again the CLEAR command for destination 27. This time, though, the overflow flip-flop is guaranteed to be reset, since the test done by the prior CLEAR would have reset it, and execution will still continue to location 2 in the normal manner.

How was I able to reconstruct this form of the program? Jim's description in his long comment of the individual commands and the sequence in which they operated gave me a general idea of what the commands needed to be. What wasn't so clear were the locations in which they needed to be stored and values of the T and N fields in each command. I was able to piece the rest of it together by reading between the lines a bit and taking into consideration some constraints imposed by the G-15 architecture.

  1. As Jim pointed out, the INCREMENT command had to be in location 0, because the NOOP command specified it as the next command, and the N field of the NOOP command was 0.
  2. The command that cleared AR to zero was executed only once during initialization, so its location was unimportant during this phase of the program, and it could be placed anywhere.
  3. The most tantalizing clue was this statement of Jim's:
    "The final bit of cleverness was the third use of SWAP. When used in the loop, it executed for a single word time, thereby exchanging AR and a single word of line 23. But it was a block command, and its first execution was at a different word time than all the others. It precessed line 23 to place INCREMENT in word 0."
    That suggested to me that the initial precession rotated all four words of line 23 by one word. The command that cleared AR probably had to be in location 0 initially, so that it would be first to be executed after the program loaded. Precession moves words to higher locations; thus after precession that command would be in location 1.
  4. That left only two undetermined locations, 2 and 3, which had to be used for the SWAP and CLEAR/NOOP commands. Since SWAP was an Immediate command, the CLEAR/NOOP command it operated on during its transfer phase had to start at the word-time immediately after its own. Therefore SWAP had to be at location 2 and CLEAR/NOOP at location 3.

Once those locations were determined, the values for the N fields were obvious (well, except for that weird N=105 in the command that cleared AR—that came later), and the values for the T fields were straightforward to calculate from the command locations.

Sad to say, this phase of the program was the easy part to figure out. Understanding how the program had to be structured for loading and how it got transformed into this second form was much more difficult and took a lot longer. That is the goal of the next section.

The Initial Program Form

Programs were typically loaded into the G-15 from paper tape, something that could be initiated from the typewriter by engaging the ENABLE switch on the base of the typewriter and pressing the "p" key. Jim pointed out that you could also enter programs directly from the typewriter keyboard using a different sequence of control commands that are discussed in the final section of this post. Typewriter entry was practical only for very small programs like this one, though. There was no way to backspace or make corrections—one mistake and you had to start all over.

An input operation read data from paper tape or the typewriter and precessed it into line 19 in blocks of up to 108 words. Line 19, however, with a cycle time of 29 milliseconds, was too slow to precess digits directly from the paper tape reader, which at 250 characters/second read tape frames every 4 milliseconds. To get around this, 4-word line 23, which cycled about once per millisecond, was used as an intermediate high-speed buffer. Once line 23 accumulated four words, an operation termed "reload" would cause the hardware to copy the contents of line 23 to another 4-word line, MZ, which was not visible to software. From there MZ had plenty of time to precess its data into the beginning of line 19 while line 23 continued to fill up with digits from the reader. Reload was triggered by a control frame on the tape or the "/" key on the typewriter, although a later enhancement to the G-15 to handle alphanumeric data allowed reload to happen automatically.

Input from the typewriter was slow enough that direct entry into line 19 would have been feasible, but typewriter input still went through the same Tinker-to-Evers-to-Chance process that input from paper tape did. Since the memory-clear program was only four words long, there was no need for a reload to move it into line 19, as those four words could be executed directly from line 23.

With that preface on how a program gets loaded into the G-15, my problem at this point was to figure out how to arrange the words of code for the memory-clear program so that it would start executing properly.

Since programs started executing at word 0 after loading and the command that cleared AR to zero was executed only once, it made sense to assume that one-time command should be loaded into word 0. That command transferred source 29 (the Input Register, IR) to destination 28 (the AR register). The IR was a means to read a word of bits from external equipment, but unless it was enabled and the external equipment was actually present, it supplied zeroes, thus clearing AR.

The next issue was to understand how the initial execution of the SWAP command could precess the words in line 23 so that the INCREMENT command would end up in word 0 on the line, where from the discussion in the prior section we know it had to be. The only thing that made sense was to have the SWAP command rotate the entire line by one word. This is tricky, because in doing that rotate, all of the words would change location, including that for the SWAP command itself. It also meant that the next command originally addressed by the N field of the SWAP wouldn't be there any more after the swap—a different command would be in that location.

How a SWAP command executed from one location could rotate all four words of the line and the exact same command executed from a different location after the rotation would exchange only one word on the line with AR was the most difficult part of the initialization phase to figure out. The fact that the SWAP command moved, though, was also a clue. Executing the command from a different location would change the effect of the T field in that command, namely, the number of word-times the command's transfer phase would last.

Recall that a command executing in Immediate mode starts its transfer phase in the word-time immediately after that command's word-time on the drum. Transfer continues up to, but not including the location specified by the T field. Thus far, I have been using the terms "word-time" and "location" as if they are interchangeable, but they are not. It is tempting to think of the values in the T and N fields of a command as locations (addresses) of words on a drum line, but they are not that either. Those values actually represent counts.

The G-15 did not keep track of addresses on the drum. Instead it loaded the T and N values into a register, which then counted its way to the correct position on the drum. In reality, it loaded the complement of the difference between the T or N value and the drum's current position into the register and counted up until the 7-bit register overflowed. The counts were held and incremented as fields in a 1-word line on the drum, CM, the Command register, that was not visible to software. Exactly how this worked is complicated and is described in the G-15 Theory of Operation manual, section C-17 (starting on page 40, or PDF page 46).

After struggling over a number of days with how the initial SWAP command could be made to do different things from different locations, I finally realized that the answer had to be in the potential difference between a command's drum location and its word-time. For the long 108-word lines there normally is no difference, but for a 4-word line, word-times are still accounted for on a 108-word basis, even though a word's physical location is its word-time modulo 4. What I needed to do was arrange for the SWAP command to start at a word-time that was congruent modulo 4 with its drum location but that allowed the command's transfer phase to run longer.

For that, I first had to determine how many word-times of the SWAP command's TVA transformation were necessary to rotate all four words of line 23 by one word. TVA uses AR for its precession, and AR at that point has the zero value that will be needed by the CLEAR commands later, so this execution of SWAP had to work in a way that also preserved the zero for later use.

The answer turned out to be six word-times. To see this, first look at the sequence of commands as I now knew they had to be loaded into line 23. Un-rotating the commands as presented in the prior section, that sequence is:

0: SET-ZERO (set AR to zero)
1: SWAP
2: CLEAR
3: INCREMENT

Precessing these words through six TVA transformations yields the following sequence of exchanges:

Step Drum
Word
Before After
AR Line 23 AR Line 23
1 2 0 CLEAR CLEAR 0
2 3 CLEAR INCREMENT INCREMENT CLEAR
3 0 INCREMENT SET-ZERO SET-ZERO INCREMENT
4 1 SET-ZERO SWAP SWAP SET-ZERO
5 2 SWAP 0 0 SWAP
6 3 0 CLEAR CLEAR 0

The SWAP is executed from location 1 (but not word-time 1—that important detail will be discussed next), so it starts operating on the word immediately after that at location 2. After the command finishes, line 23 has been rotated by one word and now has the following arrangement:

0: INCREMENT
1: SET-ZERO
2: SWAP
3: NOOP (the 0 originally in AR)

The only remaining piece of the puzzle was to arrange for the initial execution of the SWAP command to run for six word-times instead of one. The solution to that involves the difference between drum locations and word-times, and is the reason for that weird N value of 105 in the one-time command that sets the AR register to zero.

N=105 modulo 4 is 1, so that will specify the SWAP command, initially at location 1, as the next command. The SWAP command will then start its transfer phase in the word-time after that, 106, and will continue up to but not including the word-time specified by its T field, 4. Thus, the transfer phase for the initial SWAP command executes during word-times 106, 107, 0, 1, 2, and 3—for a total of 6 word times.

After this point, the SWAP is in location 2 and is specified as the next command by the INCREMENT and CLEAR commands, which both have N=2, so in those instances there is no difference between location and word-time, and thus the SWAP executes only during word-time 3.

The way in which this precession worked is pretty slick, but it left me with two curiosities. First the CLEAR command was not at word 3 in line 23 anymore where I thought it needed to be—it was now in AR and word 3 now had a 0, the NOOP command. Second, and even more curious, the N field of the SWAP command has a value of 3, and therefore:

  • The next command to be executed after the initial SWAP will be the NOOP.
  • The only effect of the NOOP will be to move on to the command specified by its N field, which is 0, specifying the INCREMENT command.
  • The INCREMENT command will add 3 to the contents of AR (the CLEAR command), then move to its next command, the SWAP, now at location 2.
  • The SWAP, now in its new location, will execute for a single word time and exchange the NOOP and CLEAR commands, leaving the value 0 in AR and the CLEAR command in location 3.
  • SWAP still designates its next command to be location 3, now the CLEAR, which starts the second phase of the program as described in the prior section.

Thus, this sequence of commands has rearranged the words of line 23 into precisely the form needed to clear the system, just as described in the prior section.

The only problem now is that the CLEAR command has already been incremented, so if it had originally been loaded ready to clear line 0, it now has a D field of 3, meaning line 3 would be the first to be cleared and the program would never get to line 0. This was disappointing—the program had transformed itself exactly as needed except for that initial INCREMENT messing up the CLEAR command's starting line number.

I couldn't see any way to bypass the INCREMENT step, and worried over the problem for more than an hour before finally realizing (and smacking myself upside the head for being so dense) that the obvious solution was to load the CLEAR command so that incrementing it would properly address line 0 at the start of the clearing phase. Instead of loading the command with S=28 and D=0, it needed to be loaded with S=27 and D=29. Adding 3 to the word would increase D to 32, which in its five-bit field would be zero, and the resulting overflow into S would increase that field to 28. VoilĂ !

Therefore, the initial form of the program as loaded is this:

L Hex T N CH S D Description
0 02693vw 2 105 0 29 28 Set AR to 0
1 0403uz7 4 3 2 23 23 SWAP (rotate line 23 by 1 word)
2 040237x* 4 2 0 27* 29* CLEAR (before initial INCREMENT)
3 060235z 6 2 0 26 31 INCREMENT AR by 3

The asterisks indicate fields that are modified by the initial INCREMENT command during the initialization process.

In Summary

The form of the program that Jim would have typed on the G-15 typewriter at Pacific Union likely would have been this:

060235z02011vy8100yvxw04x2778s

The "s" at the end is a Stop control code that terminated typewriter input. The hexadecimal string above is in a compact form where the 116 bits of the four 29-bit words are packed into 4-bit hex digits without regard to word boundaries. The underscores indicate digits that contain bits from adjacent words.

There is a less-compact and more-easily understood form that could also be used:

060235zT 040237xT 0403uz7T 02693vwT s

where the "T"s represent pressing the Tab key on the typewriter and "s" again represents the Stop code. The spaces are optional and will be ignored by the G-15 hardware. Note that the words must be entered in the reverse of the order that they will be stored in memory—an artifact of the precession mechanism used by the G-15 input/output subsystem.

Jim would have have preceded either of these forms by engaging the ENABLE switch on the base of the typewriter and typing "sc7fq". The ENABLE switch caused the G-15 hardware to recognize certain typewriter keys as control commands. These keys caused the following to occur:

  • "s" canceled any input/output operation that was currently in progress. This was not needed if no I/O was active.
  • "c7" set the system's Command Line register to 7, which would cause the processor to execute commands from line 23.
  • "f" set the location (word-time) of the next command to be executed as 0. When the system was started, it would thus take its first command from word 0 of line 23.
  • "q" enabled the typewriter for data input.

See the G-15 Operating Manual for more information on the ENABLE switch, its keyboard commands, and data entry from the typewriter.

I can't be certain that the code I have presented here is exactly what Jim would have remembered using. It's possible there may be variations on what I have managed to reconstruct that would also work, although my code does match his description, and more importantly, it works just as Jim described. In my retro-g15 emulator, which attempts to run at the same speed as a real G-15, the program takes about six seconds to complete.

You can download a paper-tape image of the program code, in a form that will work in my emulator, from the project's GitHub software repository. There is also a text file containing a trace of the program's execution as it initializes itself and proceeds to clear the system.

This program is a good example—perhaps even an extreme one—of the cleverness and trickery in which programmers were willing to engage during the 1950s and early 1960s in order to obtain maximum performance in minimum storage space from early computer systems. It illustrates a couple of important G-15 programming techniques, including precession and the gaming of word-times to control what a command did.

I was quite pleased with myself for being able to reconstruct this program from Jim's description and my still-growing knowledge of G-15 architecture and programming techniques. Multiple head-pounding episodes of frustration aside, it was a lot of fun, and very gratifying to accomplish.

I had hoped to contact Jim after getting the program to work and telling him about my efforts and my interest in the G-15. Alas, I learned from a mutual friend that Jim had passed away in 2011, and I regret that I was never able to know him. His blog is still available, though, and I recommend it to anyone who is interested in knowing what it was like ca. 1960 to use a slow and difficult system from computing's early days.


Sunday, June 5, 2022

Introducing the retro-g15 Emulator

In the prior post, I described the origins and architecture of the Bendix G-15, a mid-1950s, binary, vacuum tube, drum memory computer system. In this post I will describe the retro-g15 software emulator I have written for that system. As with my earlier retro-b5500, retro-205, and retro-220 emulators, retro-g15 is written in JavaScript and runs in a standard web browser.

At time I am writing this, the emulator is at version 1.00. We don't yet have much software for the system, but it successfully runs a diagnostic program we do have, and appears to run the ubiquitous PPR (Program Preparation Routine) utility program correctly. The emulator presently implements only a basic G-15 system, supporting just paper tape and typewriter input/output. Support for magnetic tape, punched cards, and alphanumeric devices is feasible, but we don't yet have any software that requires those devices. Until we do, it is not worth trying to implement them.

For those who would like to jump ahead and start using the emulator, the source code and resource files for it are maintained as an open-source project at https://github.com/pkimpel/retro-g15/. You can run the emulator from a hosting site I have set up, or you can clone or download the files from the project's Git repository and set them up on your own web server. See the section Using the Emulator, below, for details on how to do this. Additional set-up and operating instructions can be found in the project wiki.

Choosing to Emulate the G-15

I studied Chemical Engineering at the University of Delaware from 1966 to 1970. During that time the campus Computer Center was located on the third floor of DuPont Hall. Outside the doors to that room and a short distance down the hall from it was a stairwell that went down to the ground floor. DuPont Hall is a three-story building, but for some reason the stairwell went up another half floor, where there was a large landing at the top.

On that landing, for the entire time I was on campus, there sat a Bendix G-15 in its turquoise livery, disconnected, forlorn, and all alone. I suspect that this may have been the University's first digital computer. By 1966, the G-15 was out of production, no longer supported, and seriously obsolete. My guess is that it had been decommissioned and moved up to the landing a couple of years before I arrived, to make room for the University's Scientific Data Systems 9300 computer, and then forgotten about. When I visited campus some years after graduation, I climbed back up to that landing, but the G-15 by that time was gone. I have no idea what happened to it.

I was intrigued by that abandoned system and wondered how it worked and how it had been used. That has remained sort of an idle curiosity since. I have a faint memory that someone (I don't remember who, probably one of my instructors) told me a G-15 had been used by Professors Jack Gerster and Robert Pigford to do pioneering work in modeling multi-tray distillation towers, a subject that would have been important to the large chemical industry in the Delaware River valley. If so, it would be interesting to know more about that, even though my days of understanding the chemistry, physics, and math of such a thing are long past.

As I approached retirement and had some success in building software emulators for old computer systems, I realized that this was now an itch that I could scratch. The bitsavers.org web site has a good collection of scanned G-15 manuals, and for the past couple of years I have been looking at those periodically. In late 2021 I started working on the design and development of the emulator in earnest.

Using the Emulator

As mentioned above, the emulator runs in a standard web browser, with Firefox and Chrome being the two I have used the most. You will also need a reasonably powerful workstation. Emulation of the G-15 instructions requires almost nothing, but update of the panels and I/O device windows can be graphics-intensive, and requires a fair amount of horsepower. My eight-year old Dell PC with a 3GHz quad-core Pentium i3 processor handles the emulator without difficulty.

The emulator must be served to your browser from a web server over HTTP. You will not be able to download the emulator files to your workstation and run them directly from your local file system. That is a limitation with the way that browsers work, not with the emulator. Of course, there's no reason you can't run a web server on your workstation and serve the emulator files from there. Regardless, once the emulator is loaded into your workstation, it runs entirely locally, and needs no further access to the web server.

Setting Up the Emulator

The easiest way to get started with the emulator is to run it from the hosting site where I have set up the emulator files. Feel free to use it:

If you would prefer to run the emulator from another web server, download the files from the Git repository on the project site. You can download a zip file of the latest version of the emulator source code and related resources by clicking the Download ZIP button on the repository's home page:

Alternatively, you can clone the project from the repository using the following Git command:

git clone https://github.com/pkimpel/retro-g15 retro-g15

Although the GitHub project site uses a Git source code repository, GitHub also allows you to access the repository using Subversion clients. A read-only checkout of the emulator files can be performed using a Subversion command similar to this:

 svn checkout https://github.com/pkimpel/retro-g15/trunk retro-g15

You will need at least the emulator/, webUI/, and webUI/resources/ directories from the repository. The emulator/ and webUI/ directories must be rooted in the same virtual directory on your web server. You may also wish to download/check out the software/ directory, as it contains some utility scripts, but that directory is not required to run the emulator.

The emulator may open a number of sub-windows when it initializes. Most browsers will consider these windows to be "pop-ups," so if you are using a pop-up blocker, you may need to disable it before starting the emulator. Most pop-up blockers will allow you to disable blocking for specific web sites, however, which will allow you to run the emulator without having to forgo protection from pop-ups for all sites. Modern browsers enable a pop-up blocker by default, and many browser toolbar plug-ins implement additional ones. All of them may need to be disabled for the emulator site.

More information on system requirements, setting up the emulator, and using a local web server is available on the Getting Started wiki page.

The Emulator Home Page

When you first load the emulator, it initializes with a default configuration, which is adequate to get started using it. Once it loads into your browser, it's ready to run. The hosting-site URL above references the emulator's home page, which looks like this:

retro-g15 emulator Home Page
retro-g15 Emulator Home Page

The picture on the page is the late Harry Huskey, the G-15 designer, apparently at the typewriter of his personal G-15 system. To start the emulator, just click the Start the Emulator button on the page. That will open the Control Panel for the emulator, which will overlay the Home Page in the same browser tab.

The Emulator Control Panel

The Control Panel for the emulator is a somewhat simplified version of the G-15 front panel and looks like this:

retro-g15 Control Panel and Typewriter

The top portion of the panel has the controls for the in-built paper tape punch and reader. The middle portion reproduces the lamps from the front the physical G-15 cabinet.The portion below that shows a few buttons and lamps that on a real G-15 were used to power the machine up and down; in the emulator those serve to initialize and terminate the emulator and are discussed in more detail below.

The meters and knobs on a real G-15 front panel are not shown -- they were used for monitoring power levels and maintenance functions, and are not relevant to the implementation or operation of the emulator.

Below the Control Panel is a gray box with a number of radio-button controls. These represent three toggle switches that were located on the base of the system's typewriter.

  • The ENABLE switch controlled the ability to enter certain hardware control commands from the typewriter keyboard.
  • The PAPER TAPE switch in its PUNCH position caused all characters sent to the typewriter to be output as well to the paper tape punch; in its REWIND position, it caused the paper tape reader to rewind its tape.
  • The COMPUTE switch controlled the G-15 processor. In its center (off) position, the processor was halted. Moving the switch to its GO position started the processor executing commands. Moving the switch to its BP (breakpoint) position worked like GO, but in addition, if the processor executed a command word with a particular bit set, the processor would halt. This feature was typically used for debugging.

The white area below the switches represents the "paper" of the typewriter. Its size is responsive to the size of the browser window, and will scroll once the typed output fills up the visible area. Your workstation keyboard functions as the typewriter keyboard and is active whenever the browser window has the input focus. Whether pressing a key on the keyboard has any effect on the system other than echoing that character to the paper depends on the setting of the ENABLE switch and whether a "Type In" command is currently being executed.

To power up a real G-15, you turned on the master A/C switch (labeled START) on the front panel. After the tubes in the power supplies warmed up, you would then press and hold the RESET button until the red DC lamp lit, then release the RESET button. At that point, the G-15 hardware performed an automatic sequence of functions that included:

  1. Read the first block of data from the paper tape reader to line (track) 19 on the drum.
  2. Copy that data from line 19 to a separate line on the drum known as the Number Track. This track provided a set of timing and logic signals to the hardware logic. The hardware logic also wrote to portions of this track during its operation, so that line on the drum had to function as a recirculating delay line like all of the others on the drum. All data was lost from these recirculating delay lines when the system was powered off, which is why the Number Track had to be reloaded each time the system was powered up.
  3. Set the Command Line register to 7, which would cause the processor to execute instructions from the four-word ("fast") line 23.
  4. Set the location of the next word to be executed from that line to zero.
  5. Read the next block of data from the paper tape reader to line 19. This block was typically a loader routine for some program that followed it on the tape. The way that paper tape was read on the G-15 required that line 23 be used as a high-speed buffer, allowing four words at a time to be read from the tape, then precessed (shifted) from line 23 to the beginning of line 19. The words had to be on the tape in reverse order, and the reading worked in such a manner that a copy of the four words stored at the beginning of line 19 were also left in line 23. Thus you actually bootstrapped a program from line 23, which usually transferred control to the actual loader routine located somewhere in line 19.
  6. Terminate the initialization process by turning on the green READY lamp and leaving the system in a halted state.

Initializing the emulator works in a very similar way. Clicking the Start the Emulator button on the Home Page is equivalent to turning on the master A/C switch. Once the Control Panel appears, you click the RESET button (although holding it down is not necessary). After a short delay the DC lamp lights and the system attempts to read two blocks from paper tape and perform the other actions described above.

The emulator does not actually use the data on the Number Track for its operations, but a program can execute a command that will copy the Number Track to line 18 on the drum, from which the program could read and make use of that data. Except for that detail, the emulator will still function properly if there is no tape in the reader when the RESET button is clicked, or if the first block does not actually contain Number Track data.

As a convenience, the emulator preloads the paper tape reader's buffer with a tape image for PPR (the Program Preparation Routine), a very common utility program for the G-15. This image has the Number Track data and the PPR loader as its first two blocks. Thus, by default you can simply start the emulator, click the RESET button, wait for the green READY light to come on, then move the COMPUTE switch to GO to run PPR. If you want to initialize the system with a different tape image, just unload the PPR image from the reader and load the other image before clicking RESET.

As another convenience, the ESC key on the keyboard can substitute for the ENABLE switch. It is a little awkward in the emulator to have to turn on the ENABLE switch, press a typewriter key for one of the hardware control commands, and then turn the switch off. Instead, you can use the ESC key like a shift key. If you press and hold the ESC key, the ENABLE switch will move to its ON position. Once you release the ESC key, the switch will revert to its off position.

For more information on the layout and functioning of the Control Panel, including the paper tape and typewriter devices, see the "Using the Control Panel" wiki page. For information on the hardware control commands, use of the ENABLE switch, and the PPR program, see the G-15 Operating Manual.

The G-15 was not a particularly easy system to use, and a great deal of responsibility fell on the person running the system to know how to perform the necessary functions and to do them properly. Aside from a few conveniences in its interface, the retro-g15 emulator works the same way -- by design. This is a time trip to 1950s computing and you are going to suffer, so plan to do some reading before trying to use the emulator.

The Diagnostic Panel

To aid in debugging the emulator, I implemented a more detailed panel that shows all of the registers, the current command word separated into its several fields, the current drum and command locations, and several significant flip-flops in the system. The panel displays all four of the 4-word (fast) lines and the MZ line that was used as an I/O buffer but was not visible to software. You can select a single 108-word (long) line for display as well.

At the bottom of the panel are three buttons that can be used to start, stop, and single-step the processor.

retro-g15 Diagnostic Panel

To open this panel, double-click the G-15 logo on the Control Panel. You can open and close the Diagnostic Panel at will while the emulator is running. "Powering off" the emulator automatically closes the Diagnostic Panel window if it is open. The panel updates itself at a rate of about 20Hz. The display of the drum lines updates a couple of times a second.

Even if you don't use it for diagnostic purposes, this panel can be interesting to watch while the system is running.

Software

We do not yet have much software for the G-15 in terms of standalone programs. There is more available and I am working to acquire it, but that is probably going to take some time. In the interim, thanks to David Green in Western Australia and Paul Pierce in Portland, Oregon, we have these three interesting items.

PPR (Program Preparation Routine)

PPR, as mentioned earlier, was a utility program that was used by most G-15 sites and developers. It was operated from the system's typewriter and provided features for:

  • Entering object code words as a series of decimal fields and assembling those fields into binary command words.
  • Reading existing object code from paper tapes and editing the code in memory.
  • Merging library routines from other paper tapes into memory.
  • Punching new tape from the edited code.
  • Typing the contents of tape blocks in hexadecimal.
  • Computing and typing out checksums of tape block contents.
  • Disassembling code from tape blocks in a format similar to that used for entering command words.
  • Debugging programs with breakpoints and tracing.
  • Creating the loader routines for a program.
  • Relocating code for library routines so they could be moved to different lines on the memory drum.

A bootable paper tape image of the program can be downloaded from the G15-software code repository. As described above, the retro-g15 emulator preloads this tape image into its paper tape reader during initialization. This tape image was obtained from David Green.

Instructions for running PPR can be found in the G-15 Operating Manual. A listing of the object code for the program, in the form of G-15 coding sheets, is available on bitsavers.org.

BXTST

The standard G-15 diagnostic program that was provided by Bendix.

A bootable paper tape image of the program can be downloaded from the G15-software code repository. Instructions for running the program and discussions of the various error codes can be found in "PART III - APPENDIX" of the G-15 Theory of Operations manual, starting on PDF page 193.

This is a bootable paper tape image and includes the Number Track and test loader as the first two blocks on the tape. This tape image is from Paul Pierce's web site. A slightly different version of the program from David Green, G15TAPE, is also available in that repository.

TQ

This is a short, one-block program that plays a numeric version of the game "Twenty Questions." The idea is that the player chooses a number between zero and 1048575 (220 - 1) and the program will discover that number.

A bootable tape image of the program and instructions for it can be downloaded from the G15-software code repository. This tape image was obtained from Paul Pierce.

In the next post to this blog, I will describe another interesting, but very short, program that I have recently recovered.


Monday, May 30, 2022

Introducing the Bendix G-15

The Bendix G-15 was a mid-1950s, binary, vacuum-tube, drum-memory computer system. The system was designed by Harry Huskey for Bendix during 1952-1953, while he was at Wayne State University in Detroit, Michigan. It was first available to customers as the G-15A in 1956.

Huskey had worked on the ENIAC during World War II. After the war he spent a year in England at the National Physical Laboratory, participating in the design of Alan Turing's ACE computer and the development of its prototype, the Pilot ACE. After returning to the United States at the end of 1947, he worked for the National Bureau of Standards where he was responsible for the design of the SWAC (Standards Western Automatic Computer) at the University of California at Los Angeles.

The design of the G-15 was heavily influenced by the Pilot ACE, especially in its bit-serial operation, source-to-destination command structure, and implementation of memory and registers as recirculating delay lines. There is a video of an interesting lecture by Huskey in 1982, in which he describes the designs of the Pilot ACE and G-15, and how the one led to the other.

Over 400 G-15 systems were built, with about 300 of them installed in the United States, making it a popular and successful computer system during the late 1950s and early 1960s. It was particularly popular with engineering departments and consulting firms for road and structural design calculations.

Bendix corporate headquarters were in Detroit, but the G-15 was manufactured and supported by the Bendix Computer Division in Los Angeles, California. In 1963 Bendix sold its Computer Division to Control Data Corporation, but CDC did not support the G-15 for many years after that. Some systems may still have been running as late as the early 1970s, however.

Physical Characteristics

The G-15 was an unusually small and inexpensive computer for its day. A basic system consisted of one cabinet and a modified IBM Model B electric typewriter. The cabinet was 61 inches high by 27 inches wide by 32 inches deep (155 x 69 x 81cm), weighing 950 pounds (430kg) -- about the size of a home refrigerator. It ran on standard U.S. 110-volt power, drew 38 amps (about 3KW RMS), and dissipated 14,300 BTU/hour of heat. It used approximately 450 vacuum tubes (mostly dual triodes) and 3000 germanium diodes.

Bendix-G15 with Typewriter and Optional Magnetic Tape Drive

Two variants of the system were produced by Bendix. The initial one, the G-15A, and its better-known successor, the G-15D, released in 1957. Technical Applications Memo 29 (starting on PDF page 120) describes the programming and operational differences between the two systems.

An August 1957 price list indicates a basic G-15D system could be purchased for $49,500 USD or leased for $1,485 USD per month. In 2021 dollars, those prices would be approximately $477,000 and $14,300, respectively [source].

The basic G-15 system supported only paper-tape and typewriter input/output, and only hexadecimal data formatting. It had no facilities for reading or writing general text. Decimal input and output was done by way of software conversion routines. Optional peripherals included higher-speed paper-tape devices, magnetic tape, an adapter for alphanumeric input/output (using a Flexowriter electric typewriter), adapters for IBM punched-card devices, and an adapter for custom data interfaces. A digital differential analyzer was also available. These are briefly discussed in the "Input/Output (I/O) Subsystem" section below.

 Architecture

The design of the G-15 was unorthodox, clever, and extremely minimalist. All processing in the system was bit-sequential and took place as the bits were read from one of the drum lines. The bit-serial design was a major contributor to the system's small size and low cost, as it eliminated almost all need for parallel data paths and significantly reduced the number of components required. For example, words were read from the drum from the low- to high-order bits, which allowed for bit-sequential addition, so the adders only had to be one bit wide.

Word Formats and the Drum Memory

 The G-15 had a 29-bit word. The drum held 2160 words in 20 108-word "long" lines (or tracks), plus 16 words in four 4-word "fast" lines. The system had a single one-word accumulator register and three special-purpose two-word registers to perform double-precision arithmetic. All of these registers were implemented as lines on the drum and operated as recirculating delays lines.

Each of the lines on the drum was implemented as a recirculating delay line with separate read and write heads. In the normal course of operation, bits on the drum surface passed a read head, where they were sensed and gated to the corresponding write head, which wrote the bits further ahead on the surface in the direction of drum rotation. The circumferential  distance from the write head to the read head determined the line's recirculation delay. To change the data on a line, this recirculation path was interrupted and the new data gated to the write head. 

The drum was physically about 12 inches (30.5cm) in diameter and four inches (10cm) wide. For the 108-word long lines, the angle between read and write heads was about 45 degrees, making the circumferential length of those lines about 315 degrees. The heads for the shorter lines were nestled within the 45-degree angle so that some of the short lines overlapped the same tracks as some of the long lines, although the drum surface between the read and write heads for the long lines was not being used by the long lines while it was within the angle between those heads.

Data was recorded on the drum at about 95 bits/inch. The drum rotated at 1800 RPM. Average access time was approximately 15ms for the long lines and 0.5ms for the fast lines. The clock rate was 108KHz, derived from a timing track on the drum. All data on the drum except for the timing track was lost when the system was powered off.

The word format was 28 data bits (seven hexadecimal digits) plus a sign in the low-order bit position. The representation in memory was usually signed-magnitude, but when doing arithmetic in the registers, that was converted to twos-complement. When transferring words to and from the registers the programmer needed to specify whether that conversion should take place. The one-word accumulator could only add and subtract, although left shifts were possible by repeatedly adding the register to itself, something that could be done in a single command. The double-precision registers were used for addition, subtraction, multiplication, division, and shifting.

With a signed-magnitude number representation, it is possible to have the value -0. The single- and double-precision accumulators avoided generating a -0 result, but software could store -0 in memory and in the registers. Attempting to do addition or subtraction with a -0 operand could produce incorrect results.

The hardware supported only integer arithmetic. Floating-point calculations had to be done using software routines.

An important measure in the system was the "word-time" -- the amount of time it took one word to pass a read or write head on the drum, 0.269ms. Most timing calculations were done in terms of word-times.

On the drum, the 20 108-word long lines where numbered 0-19. A complete recirculation of the line (termed a drum cycle) took 29ms. The four, 4-word fast lines were numbered 20-23 and cycled every four word-times, or 1.08ms. The double-precision register lines were numbered 24-26 and referred to as MQ, ID, and PN, respectively, and cycled every two word-times, or 0.54ms. The single-precision accumulator (AR) was line 28 and cycled every word-time. Average access time was half of these cycle times, but that could be improved upon significantly by using minimum-delay coding techniques.

Commands for the G-15 processor were specified in terms of a source and a destination. These were encoded as five-bit numbers in the instruction word and usually referred to physical lines on the drum. The basic idea was that the word under the read head of the source line was transferred sequentially, bit by bit, to the corresponding word under the write head of the destination line. Thus, if a command was executing at word-time 27, the source was 3, and the destination was 15, then the contents of word 27 on line 3 were copied to word 27 on line 15. If the destination was 22, then the word would have been transferred to word 3 of line 22, as word-times for the shorter lines were interpreted modulo their line size.

During the source-to-destination transfer, certain transformations could be applied to a word, e.g., that for complementing negative numbers mentioned above. See the discussion on the CH (characteristic) field in a command word below.

Data could be read from and stored to any of the lines on the drum, but commands could be executed only from lines 0-5, 19, and 23. Lines 19 and 23 were also used as source and destination buffers by the input/output system, so execution from them was necessary in order to bootstrap a program after it was loaded from an external medium.

Command Structure

Like most computer systems of its day, the G-15 operated in two phases, fetch (when the next instruction to be executed was loaded into the processor and decoded) and execute (when the instruction performed its function). In the G-15, these two phases were referred to as "read command" and "transfer," respectively. Since a word could be read or written only when it was under the head of its line on the drum, the amount of time the processor had to wait for drum rotation between these phases had a major effect on the amount of time instructions took to to execute, and therefore the speed at which programs would run.

Understanding those delays was the programmer's job, and it was often a significant intellectual challenge to minimize them. The way the programmer did that was by carefully arranging the locations of command words and specifying the values of the T and N fields in the command word.

A command word in the G-15 looks like this (image from Drawing 6 in the G-15 Theory of Operations Manual):

G-15 Command word layout
G-15 Command Word

The following describes each of these fields from right to left and how they affected the computer's operation. Note that one command could operate on multiple data words depending on the values of the S/D, T, and I/D fields as described below.

This section gives only a brief overview of the G-15 commands. For a complete treatment, see the Programmer's Reference Manual and the Theory of Operation Manual.

S/D (Single/Double) Bit

The function of this field varied somewhat with the command, but generally for deferred commands (see the I/D bit below) it indicated whether the command acted upon one word or two. For most immediate commands, this bit was ignored.

D (Destination) Field

For values 0-26 and 28, this field indicated the destination line on the drum to which transfer would take place. The other values specified special actions that were performed during the transfer phase:

  • 27 - sending a source word (or a sequence of source words) to this destination tested the word for zero. If the source bit stream contained any 1 bits, then the next command would be read from a word-time one later than it would if the bit stream was all zero (see the N field below). This was a form of conditional branch, similar to "skip on non-zero" in other architectures.
  • 29 - the single-precision accumulator (AR) had two destinations, 28 and 29. When loading the register with a value, such as the augend before an addition was to be done, you specified destination 28. To actually do an addition or subtraction, you specified destination 29, which added the source word (or words) to the contents of AR.
  • 30 - similarly the double-precision accumulator (PN) had two destinations, 26 and 30. When loading the register, you used destination 26, when doing addition, you used destination 30.
  • 31 - instead of specifying a line on the drum, this destination specified that a special function was to be performed. The S (source) field in the command specified which function. In come cases the function performed varied depending on the CH (characteristic) field in the word.
    • 0 - terminate any input/output operation that is currently in progress.
    • 1-15 - initiate an input/output operation, e.g., 15 means read the next block from the paper-tape reader.
    • 16 - halt the processor.
    • 17 - ring the system's bell, plus variant functions depending on the CH field
    • 18 - transfer a value to the optional Output Register interface.
    • 19 - start or stop the optional DA-1 differential analyzer accessory.
    • 20 - return from a subroutine; optionally change the current command line.
    • 21 - mark the return location and enter a subroutine; optionally change the current command line.
    • 22 - test the sign of the source word(s) and skip if any are negative, similar to destination 27.
    • 23 - clear the double-precision registers or perform a special extract on PN (line 26), depending on the CH field.
    • 24 - multiply register MQ (24) by register ID (25), leaving the result in PN (26).
    • 25 - divide register PN (26) by register ID (25), leaving the result in MQ (24).
    • 26 - shift register MQ (24) left and register ID (25) right by a number of bits equal to half the value of the T field (discussed below), optionally adding the number of shifts done to AR.
    • 27 - normalize register MQ (24) by shifting it left until the high-order bit is a 1, optionally adding the number of shifts done to AR.
    • 28 - test whether an input/output operation is currently in progress and skip if not, plus some variant tests depending on the CH field.
    • 29 - test whether arithmetic overflow has occurred, then reset the overflow indicator; skip if overflow has occurred.
    • 30 - write a file code (similar to a tape mark or end-of-file) on a magnetic tape unit.
    • 31 - execute the next command from the AR register or copy certain data to line 18, depending on the CH field.

S (Source) Field

For values 0-26 and 28, this field indicated the source line on the drum from which transfer would take place. The other values specified special sources of data. For each word-time of the transfer phase, these source values operated as follows:

  • 27 - generate a source value by computing the logical AND of the words from lines 20 and 21, then computing the logical AND of the ones-complement of line 20 with the value in AR, finally computing the logical OR of those two ANDs, i.e., (L20 & L21) | ((~L20) & AR).
  • 29 - compute a source value from the word in line 20 and the logical AND of the contents of the Input Register. The Input Register was a data interface to optional, external custom devices, and unless enabled by a variant of the D=31, S=17 command, the value was zero. So this was often used as a source of constant zeroes.
  • 30 - compute a source value from the logical AND of the the ones-complement of the word in line 20 with the word from line 21, i.e., ((~L20) & L21).
  • 31 - compute a source value from the logical AND of the word in line 20 with the word from line 21, i.e., (L20 & L21).

CH (Characteristic) Field

The primary use of this two-bit field was to specify the transformation the hardware applied to words as they moved from source to destination during the transfer phase. For some commands, particularly those with D=31, this field specified an optional or variant behavior of the command.

When used in ordinary transfer commands, the value of this field specified the following transformations:

  • 0 - No transformation -- the word was simply transferred from source to destination.
  • 1 - Complement -- if the sign bit of the word was zero, the word was transferred without change. If the sign bit was a 1, the sign was transferred without change, but the other 28 bits were converted to their twos-complement value. The G-15 adders could only add, not subtract, so in order to add negative numbers or perform subtraction, the operands had to be converted to their complement form first.
  • 2 - This transformation depended upon the values of the S and D fields:
    • If S or D was greater than or equal to 28, the absolute value of the source word was transferred by simply setting its sign bit to zero. No de-complementation took place.
    • If S and D were both less than 28, the operation was termed "Transfer via AR" or TVA. During each word-time of transfer, the value of AR was copied to the destination word. Simultaneously, the value of the source word was copied into AR. If S=D and transfer lasted for one word-time, the effect was to swap the operand word with AR. If S=D and transfer lasted multiple word-times, the effect was to shift words on the line to higher addresses by one word. This type of shift is known as precession and had many useful applications.
  • 3 - This transformation also depended upon the values of the S and D fields:
    • If S or D was greater than or equal to 28, the sign bit of the source word was reversed. If the sign bit was now 1, the word was complemented during transfer as for CH=1 above. If the destination was one of the accumulators (29 or 30), the effect of this was to subtract the source value from the register. Otherwise it simply negated the value being transferred.
    • If S and D were both less than 28, the operation was termed "Add via AR" or AVA. It is similar to TVA and also does precession. During each word-time of transfer, the value of AR was copied to the destination word and the value of the source word was copied to AR, except that is was complemented as described above for CH=1. No addition actually took place -- perhaps "Complement via AR" would have been a better term.

These characteristic transformations, plus their dependencies on the values of S and D, added quirky complexity and not a little subtlety to the behavior of the transfer phase. When transferring to or from the double-precision registers MQ, ID, and PD (lines 24-26), there were even more complexities, too numerous to mention here. See the pages 38-50 in the Programmer's Reference Manual for the gory details.

N (Next Command Time) Field

This field specified the word-time of the next command to be executed. As with many drum-based architectures, each instruction specified the location of its successor. This allowed the programmer, with not a little effort, to choose the location of command words such that they would minimize the drum's rotational delay between processing phases and thereby decrease the running time of a program.

As mentioned above, commands could be executed in the G-15 only from drum lines 0-5, 19, and 23. The processor initially executed commands from line 23, after loading code from a peripheral device such as paper tape or the typewriter keyboard. Two D=31 commands, S=20 and S=21, could be used to specify a change in command the line in addition to their role in subroutine entry and exit. Once a command line was set, however, the G-15 executed commands only from that line until it was instructed to switch to a different one.

Since each command specified the location of its successor, there were no branch instructions in the G-15. Conditional paths were taken as a result of test commands. If the test was false, the N location in the test command word specified the location of the next command. If the test was true, the next command was taken from the word-time following N.

If an unconditional transfer of control was needed, the usual approach was to execute a "dummy" command that effectively was a no-op. Transferring AR to itself using CH=0 was a common method of doing this.

BP (Breakpoint) Bit

This bit could be used to set breakpoints in a program. The G-15 had a three-position switch labeled "COMPUTE" that controlled the processor's running state. See the image of the typewriter below. In the switch's center position (off), the processor was halted. Moving the switch to the right-hand position, labeled "GO" caused the processor to start executing commands continuously until the switch was moved back to the off position or it executed a halt command (D=31, S=8).

The left-hand position of the switch was labeled "BP." Moving the switch to this position acted like GO, except that if the processor encountered a command with the BP bit set to 1, it halted. The halt occurred after the read-command phase completed but before the transfer phase began. The operator could resume execution by moving the switch to the off position and then either to GO or BP.

This feature was typically used for debugging, but sometimes as a conditional halt to allow the operator to change something. One extraordinary quirk of the design allowed the BP setting of the COMPUTE switch to be used as a sense switch. See Tech Memo 41 (starting on PDF page 167).

T (Timing Number) Field

The interpretation of this 7-bit field depended upon the I/D bit, below.

  • When the I/D bit had the value 1 (deferred), then after reading the command word into the processor, the processor waited until the drum rotated to the word-time specified by the T field before the transfer phase began. In other words, T specified the location of the operand on the source line and behaved like an operand address in other architectures.
    • Transfer generally occupied one word-time if the S/D bit was 0 (a single-precision operation) or two word-times if the S/D bit was 1 (double-precision operation).
    • Note that in deferred mode the processor required one extra word-time after the command was read into the processor, so if the word-time specified by T was immediately after the word-time where the command was located, a delay of a full drum cycle took place before the transfer phase could begin. Good programmers tried to avoid this.
    • Wraparound from the last word on the line to word 0 was automatic.
    • Access to words in the shorter lines was modulo the line size, so word-times 2, 6, 10, 14, ..., 102, 106 all referred to word 2 in the 4-word lines.
  • When the I/D bit had the value 0 (immediate), the transfer phase began in the word-time immediately following that of the command word and continued up to but not including the word-time specified by T. This meant that a single command could execute against a vector of words, as long as the words resided on a single drum line.
    • This made it easy to set a sequence of words from a value in the AR register, to copy a sequence of words from one line to another, or to sum a sequence of words within a line. This was a powerful capability on an otherwise rather slow drum-based computer, and it was used extensively. The trick was to arrange for the command word so that it immediately preceded the sequence of words you wanted to process, although that sequence could be on a different drum line than the command.
    • In certain cases, it was useful to have T exceed 107.
    • As an exception, the T number in multiply, divide, and shift commands was interpreted not as a specific word-time but as two times the number of word-times that the transfer phase would last, because those commands implicitly used the double-precision register lines, MQ, ID, and PN.

I/D (Immediate/Deferred) Bit

This bit determined the mode in which the instruction operated, 0=immediate, 1=deferred. This affected when the transfer phase began and how long it lasted. See the T field above for details.

This very minimalist command structure supported a lot of useful, if unorthodox, capabilities. It provided a means to specify instruction sequences that would minimize rotational delay of the drum, but it also transferred a lot of responsibility and effort onto the programmer to specify things just right and to figure out optimal locations for commands and data. The programmer had to keep in mind at all times the current position of the drum, the length of the transfer phase, and the amount of delay there would be between the end of the read-command phase and the start of the transfer phase.

There were also a number of caveats and restrictions on commands not mentioned in the overview above, e.g., most commands involving the double-precision registers had to be located at an odd word-time so that when the transfer phase began at the next (even) word-time, the operation could start with low-order (even) word of the register on the drum. The G-15 was not an easy system to program, and it was significantly more difficult to program well.

One thing that should be apparent from this discussion is that the G-15 commands did not have what you could consider to be an operation code. The operation that a command performed was a function of at least the I/D, S, D, CH, and S/D fields, and in some cases the T field as well. That is up to 21 of the 29 bits in the word -- quite a large selection range. It was more like programming in what today we would call microcode than typical machine code.

Input-Output (I/O) Subsystem

For a computer system that had such a minimalist design, the G-15 had an interesting and capable input/output subsystem. I/O was built into the processor, but it functioned asynchronously. Once software initiated an I/O, the processor could continue executing while the input or output operation took place in parallel with its own access to the drum memory. Only one I/O could be in progress at a time, however there were situations where initiating an I/O operation while another I/O was still active could be useful. See Tech Note 33 (starting on PDF page 152) for one such case.

One of the test commands (D=31, S=28, CH=0) could be used to determine if an I/O was still in progress. If the I/O was still active, the next command would be taken from the location specified in the N field of the test command. If no I/O was active, the next command was taken from the location after that. This test command was often written with N specifying the command's own location, which caused the processor to repeatedly execute the test (with a full drum cycle delay between iterations) until the I/O finished, at which point execution would continue with the the command at N+1.

As mentioned earlier, the basic G-15 configuration supported only paper tape and the typewriter, and could read or write only hexadecimal data. It represented values externally using the digits 0-9 and letters u-z, rather than the 0-9, a-f scheme that is common today.

Data was generally output from drum line 19. Data was read into line 19 via line 23, which was used as a high-speed buffer. Words were stored in these lines in reverse order of their external appearance -- on input the first word read ended up in the last word of the line; on output the last word on the line was the first to be output.

The reason for this is that the I/O subsystem was not able to index to a particular word-time on a line. It could only index to word-time 0. The digit values on the line were precessed (there's that word again), i.e., shifted, four bits at a time. On input, as bits were read, they were shifted into word 0 on the line, with all of the remaining bits being shifted towards higher word-times, and the last bits on the line being discarded. Hence the first word read ended up as the last word on the line. On output, zero bits were shifted into word 0, all of the remaining bits were shifted upwards, and the last bits on the line ended in a buffer register from which they were routed to the device.

Paper Tape

The paper tape reader and punch were built into the top of the main cabinet. Both used a five-level tape code. This provided codes for the 16 hexadecimal digit values plus six special function codes used to format data and control the reader. See the Paper Tape Format document for details on the tape code.

The reader operated at 250 frames/second, or one frame every 4ms. Tapes were spooled inside flat metal cartridges that mounted onto the reader housing on the front of the cabinet, as shown in the G-15 picture above. This made changing tapes and interleaving data from multiple tapes quick and reliable.

The data was read in blocks of up to 108 words, but in groups of up to four words at a time. 4ms per frame was too fast for digits to be precessed directly to line 19, which cycled every 29ms. Instead they were precessed to the 4-word line 23, which cycled in about 1ms.

After no more than four words of data, the tape needed to have a frame with a certain control code, "Reload," which caused the four words in line 23 to be copied to another 4-word buffer line on the drum, MZ, which was not visible to software. That took another millisecond. From there, while input from the reader continued without pause into line 23, the four words were precessed from MZ, four bits at a time, to the first four words of line 19. The remaining four words of line 19 shifted upwards by four words, with the final four words on the line being discarded. There was plenty of time for MZ to be precessed to line 19 before line 23 filled up again.

Thus a block of paper tape typically looked like the following (this is a short block with new-lines inserted between the four-word groups for legibility):

 uv0yxu00000000000000002u8034u/
 131339z09898zz84444y7w2408738/
 0z0z39z08888zz83w3w37w1u1w4xw/
 000000006059wxu2w142z012123zy/
 0808333038573y81414y7w0y0y5zy/
 0000000020235zw0808994020215uS

The "/" characters represent the Reload codes. The "S" represents a Stop code, which terminated the block and halted the reader. An entire block was read in one I/O operation. This is an example of the so-called "compact" form of data entry, where the four words of 29 bits each are packed into a 29-digit hexadecimal string, with some of the hex digits containing bits from adjacent words. The canonical form of input represented the data word-wise, with tab or carriage-return frames between the words. In canonical form, the first line of the example above would be this:

uv0yxu0T0000000T0000000T15401u5C/

 where "T" represents a tab frame code and "C" represents a carriage-return frame code. In this canonical form, leading zeroes in a word did not need to be entered and signs were not entered unless they were negative. Negative signs ("-") could be entered at any point within a word. The input logic stored the state of the sign in a flip-flop until a tab or carriage-return frame was detected, which signaled the end of a word and caused a one-bit precession from the flip-flop into the sign's proper position in low-order bit of the word.

Blocks on paper tape needed to have about seven inches of blank tape (termed "leader") between them, to allow the reader time to accelerate and decelerate between blocks.

The paper tape punch operated at 17.2 frames/second. Since all 16 possible values of the four-bit digits precessed from line 19 were needed to represent the hexadecimal digits on output, there was no way to embed the necessary control characters with the data in memory. Instead, the digits coming from memory were processed against a formatting table composed of 3-bit codes. This table had to be present in the first four words of line 2. The formatting codes were:

Code Symbol Description
000 D Copy the next memory digit to output
001 E End of format
010 C Output a carriage-return control code
011 P Output a period (.) control code
100 S Output the sign of the current word, "-" for negative, space otherwise
101 R Output a reload control code and restart from the beginning of the format string
110 T Output a horizontal tab control code
111 H Discard the next digit from memory and do not output it (rarely used)

The standard format that was typically used for the paper tape punch and typewriter generated 4-word groups and looked like this, using the letter symbols from the table above to represent the codes:

SDDDDDDDTSDDDDDDDTSDDDDDDDTSDDDDDDDCE

In other words, format four words, each with a sign followed by seven hexadecimal digits. Tabs were output between the words, with the last word followed by a carriage-return. Note that there is no "R" to output a Reload code. Reload codes were seldom used in these format strings, because that could prevent the "E" code at the end of the string from ever being sensed. Instead, the reload process was handled as follows:

  • When an E code was encountered, line 19 was sensed to determine whether it was now zero or still contained some 1 bits.
  • If there were still 1 bits on the line, a Reload control code was output to the device and output continued at the beginning of the format string.
  • If the line was now all zeroes, the I/O operation terminated.

Typewriter

Output to the typewriter operated at 8.6 characters/second. It worked much the same as for paper tape, except that Reload codes were ignored. Carriage returns and tabs performed their customary typewriter carriage functions. The output of data words was zero-suppressed, with spaces replacing any leading zeroes in the word.

The typewriter could receive it data from either line 19 or the AR register. In the case of line 19, format codes were taken from the the first four words of line 2, as for the paper tape punch, and output terminated once the precession of line 19 resulting in the line containing all zeroes.

Output from AR always involved one word, with AR being cleared in the process. A separate format table was used for this operation, with the codes taken from the first four words of line 3.

There was a switch on the base of the typewriter, labeled "PAPER TAPE," as shown in the image below. When this switch was set to its "PUNCH" position, each character output to the typewriter was copied to the paper tape punch. The punch operated at half speed in this mode, the same as the typewriter.

G-15 Typewriter and Base
 

Input from the typewriter was handled in two ways, as an I/O operation or as control commands. Software could initiate an I/O operation known as "type in," which enabled the typewriter keyboard for data entry. Hexadecimal digits entered on the keyboard were precessed into line 23 in the same manner as for the paper tape reader. A Reload code (the "/" key) caused the contents of line 23 to be precessed to line MZ and from there into line 19. The canonical form was typically used when entering data from the typewriter, although compact form could be used as well.

One difference between entry from paper tape and entry from the typewriter was that a Reload code was required after the last word entered and before the Stop code (the "S" key) that terminated the I/O operation. Thus a four-word entry of data from the typewriter would typically look like this (with T representing the Tab key):

060235zT040237xT0403uz7T02693vwT/s

The second way the typewriter was used for input did not involve the Input/Output subsystem. The G-15 had a very minimal control panel, with few switches or buttons for controlling the operation of the computer. Instead, certain keys on the typewriter keyboard were hard-wired to logic circuits within the processor. Pressing one of these keys activated a control function. The keys used were chosen such that they did not conflict with keys required for data entry.

To prevent accidentally entering one of these control functions, there was another switch on the base of the typewriter labeled "ENABLE," and sometimes referred to as "safety." This switch had to be in its "on" position in order for a key to be recognized as triggering a control function. For example, ENABLE+P would cause the system to read the next block from paper tape. Obviously, the system should be halted when doing so. This was typically used to bootstrap a program into the system. The first block on a tape was usually a loader that would read the rest of the program into the drum and distribute it to memory lines as required.

As another example, ENABLE+S would cancel any I/O operation that was currently in progress. This could be used to abort output that was not wanted (typing 108 words from line 19 took about two minutes) or to recover from a hung I/O, e.g., trying to read from paper tape with no tape loaded in the reader.

Turning on the ENABLE switch would also pause output to the typewriter. Output would resume at the point it had been suspended when the switch was turned off.

See the G-15 Operating Manual, Part II, for details on entering data using the keyboard and on the ENABLE-switch control commands.

Other Input/Output Devices

The G-15 could support up to four magnetic tape units. These functioned somewhat like a faster paper tape that could be both read and written. Similar to paper tape, data could be written in blocks of up to 108 words. No formatting, as for paper tape and typewriter output, was done. Recording density was 57 bits/inch at 7.2 inches/second using six parallel recording tracks. The recording format was unique to the G-15 and incompatible with tape formats used with other systems. One tape could hold the equivalent of about 300,000 paper tape frames.

Although the basic G-15 only supported hexadecimal input and output, there was an optional adapter, the ANC-2, that could be inserted between the G-15 and its typewriter. This device allowed the typewriter to operate in either hexadecimal or alphanumeric mode. In alphanumeric mode, which was activated by the low-order (sign or double-precision) bit in the I/O command word, each character on the typewriter was represented by two adjacent hexadecimal digits in memory.

 Another alphanumeric adapter, the AN-1, supported input and output between the G-15 and a Friden Flexowriter electric typewriter or the HSP-8 and HSR-8 external paper tape units discussed below. It was also possible to connect the AN-1 to other types of devices through a custom interface.

The following optional paper tape devices were available:

  • The PR-1 paper tape reader was identical to the reader that was internal to the G-15 cabinet, running at the same speed and using the same five-level tape format. Up to three of these could be attached to a system. Additional units were daisy-chained from the one that plugged directly into the G-15 cabinet.
  • The PR-2 paper tape reader could read at 430 frames/second. It could also read tapes with five- to eight-level codes. When reading tapes with codes of six or more levels, alphanumeric mode was used as for the ANC-2.
  •  The PTP-1 paper tape punch produced five-level tapes with the same format as the inbuilt punch, but operated at 60 characters per second. PR-1 and PR-2 units could be daisy-chained from this punch.
  • The HSR-8 paper tape reader could read one-inch tapes having codes of eight or fewer levels at a speed of 60 frames/second.
  • The HSP-8 paper tape punch could punch one-inch tapes having codes of eight or fewer levels at a speed of 100 frames/second.

There were two adapters that allowed the G-15 to read and punch cards using IBM card devices:

  • The CA-1 was an interface between the G-15 and an IBM 026 keypunch. The interface supported only hexadecimal input and output using the standard IBM card codes for 0-9, U-Z, and the minus sign. Format of the data on input was controlled by the program-drum card in the 026. Format on output was controlled by a combination of the drum card and the four-word format codes in words 0-3 of line 2 on the G-15 drum. Cards were read at 17 columns/second and punched at 11 columns/second. The device could read 12-44 cards/minute, depending on the number of columns read from each card. Up to two 026 devices could be attached to a system through a single CA-1 adapter.
  • The CA-2 was an interface that allowed the G-15 to use IBM 514, 519, and 523 card reader-punches or IBM 402 and 403 tabulating machines. The interface could process all 48 characters in the standard IBM card code, although the alphanumeric encoding within the G-15 was different than that for the ANC-2. All units operated at a speed of 100 cards or printed lines per minute.

Although not strictly speaking an I/O device, the DA-1 Digital Differential Analyzer was a peripheral accessory for the G-15. It could be used, among other applications, to solve differential equations. It implemented 108 integrators that could be logically connected to each other in numerous ways to model the equations it was to solve. While in operation, it used several tracks on the G-15 drum for storage of working values. The DA-1 was a derivative of an earlier, standalone DDA, the Bendix D12.

Software

 The G-15 eventually had a large library of system and application software, much of it written by customers and freely shared with other customers. Bendix wrote a number of significant programs to aid in software development. Notable among these were:

  • PPR, the Program Preparation Routine -- a utility program that was loaded from paper tape and could often be left resident in the machine while developing and testing other programs. It allowed a user to enter and edit machine code as the decimal fields in a command word, load tapes with machine code for existing programs and edit it, merge routines from library tapes with the edited code, and punch new tapes from the edited code.
  •  INTERCOM -- an interpretive programming language with an assembler-like syntax that supported floating-point calculations and allowed users to perform complex calculations much more easily (and usually much more slowly) than by using G-15 machine code. It was apparently very popular.
  • INTERCARD -- another interpreter, similar to INTERCOM, but which read its programs and data from punched cards instead of paper tape. The interpreter was more efficient than INTERCOM, running about four times faster.
  • POGO -- a translator with a programming syntax somewhat similar to INTERCOMM. It generated actual machine code, however, and optimized the locations of instructions and data to reduce drum latency and increase the speed of execution.
  • ALTRAN -- another translator, developed at E. I. DuPont, with a programming syntax similar to G-15 machine code, but which provided scaled, fixed-point, double-precision calculations.
  • ALGO -- a compiler for an early variant of the International Algorithmic Language, also known as ALGOL-58.
  • CPM/PERT -- a program for evaluating project task networks using the Critical Path Method and the Program Evaluation and Review Technique.

A catalog of software developed and shared by G-15 customers is available on bitsavers.org in two parts, Volume 1 and Volume 2.

The retro-g15 Emulator

I have written a software emulator for the G-15. It runs in a web browser, reproduces much of the front panel of the system, and attempts to operate at the same speed that a G-15 would have. The emulator presently implements a basic G-15 configuration and supports only paper tape and typewriter I/O.

The project has a hosting site from which you can run the emulator. The source code is publicly available in a GitHub repository from which you can download the code and set it up on your own web server if desired. See the project's wiki for details. In the next post I will describe this emulator and briefly describe how it can be used.

There is not much G-15 software available at present, but I am actively looking for more. I have set up another GitHub repository as a software archive for the machine and am presently organizing the software I do have so it can be stored in that repository.

A G-15 Four-Word Memory Clear Program

A little over a year ago, while researching the Bendix G-15 computer system, I came across a blog, " The Way It Was: Tales from a life ...