The Service Bureau Corporation (SBC), in 1962, was an IBM subsidiary, with offices in several major cities. The Manhattan office, where I worked, occupied several floors at 635 Madison Avenue (at 59th Street).
On the first floor was a large computer room fronted by a glass wall facing Madison Avenue, containing the 7090 and 1401 computers. The 7090 (here seen at a different location) looked huge, but the vertical units were just tape drives. A 1401 usually accompanied a 7090, because it was much smaller and cheaper, was therefore was used to read cards onto tape for input to the 7090, and write from 7090 output tapes to its fast printer. Prime time (9-5) on the 7090 was rented by customers for $500/hour (> $4000 in 2021), which meant that programs written by in-house programmers usually ran after hours.
It is hard to imagine just how limited these machines were. The memory capacity of a 7090 was tiny even compared to today's smaller cellphones. And the machine was very slow; basic addition took 4 microseconds.
On another floor were rows and rows of punched card tabulating machines like the 407. They were used for accounting and other traditional jobs for customers. A job on such a machine was controlled by a wired board specifying the sequence of operations to be performed, which could include (depending on the machine) arithmetic operations, comparisons, sorting, punching new cards, and printing.
We, the programmers, lived on another crowded floor. Most of the area was divided into small 4-desk cubicles surrounded by shoulder-high partitions.
Possibly because large groups of programmers were something new, SBC seemed to be feeling its way about how to treat them as employees. The recent hires were both junior, and office workers, so it probably seemed appropriate that they punch time clocks, and not only morning and evening, but for lunch breaks as well. Also, they were part of an organization geared to customer service, so the dress codes were those of the IBM sales force, even though we never saw a customer. Jackets and ties for men, dresses and skirts for women. This was taken very seriously. We heard that a new hire was almost immediately fired for wearing khakis, even after explaining that, because he had just completed military service, he owned only two pairs of dress slacks, and they were both at the cleaners.
Managers at SBC had a wide "span of control", probably extending to 15 or 20 people each, divided into task-related groups, each with a group leader. So I didn't know the managers well at all. I recall I rather liked my first two managers, Bernie Roth and Herman Washington, but rarely saw them.
At the time I joined, the number of employees was growing rapidly, with a new cohort of mostly recent college graduates hired every few months. Employment usually began with a training class to learn the basics, because almost no one knew anything about programming.
After training, many were assigned to a government contract relating to missiles. All very secret, but when their missile landed at an intended spot there was a celebration. Others were working on a contract with IBM proper to "maintain" (i.e., "fix bugs in") distributed 7090 systems and do related support work. At the time, IBM computers were sold along with a tape containing standard software facilities. Customers encountering difficult problems consulted with a "customer engineer" at a local sales office, who referred problems to us if their source seemed to be in the IBM-distributed software.
Since this was the early sixties, the "real sixties" of flower children and anti-war protests hadn't happened yet, and most employees were fairly conventional, both socially and politically. But we were young... There was a popular bar around the corner, a rented ski lodge in a beautiful old Vermont village, and lots of people with similar backgrounds... Also, we spent many lunchtimes playing bridge, and, when the games ran too long, we would send someone with a stack of time cards to the time clock, so we could continue playing.
One important aspect might be noted. Approximately half the employees, or, at least of the recent hires were women. And, for a decade or more, women played important roles in software in the New York area, not only in IBM. When, some time later, I moved to the West Coast, the difference was startling.
When I reported to SBC on June 11, 1962, I first attended the several-month course for new hires. There was an excellent teacher, Reynaldo Reyes, who later became a high-level executive in IBM's Asia-Pacific Marketing organization
I really enjoyed the subject matter and exercises. Most of the instruction was about programming, focusing on the FAP assembly language, and the Fortran II programming language. Those were the languages usually associated scientific programming, and it was assumed that most of our work would be in that area. ( At the time, IBM sold different lines of computers for scientific and commercial programming respectively. Scientific computers provided built in integer and floating point arithmetic. "Commercial computers" provided decimal arithmetic. The 7090 (the one "downstairs") belonged to the line of scientific computers.) We were also taught a little COBOL ("Common Business Oriented Language").
FAP (and other assembly languages) primarily provided a way of coding machine level instructions but using symbolic names instead of numbers for operation codes and for machine addresses of both code and data. It also had some "pseudo-operations" for frequently used combinations of instructions, as well as a mechanism for defining additional ones (called "macros"). Here's an example of a FAP program. (A playful local programmer sometimes wrote code which, if you concatenated the sequence of names of locations encountered in a path through the code, expressed something, um, "improper". )
Fortran, one of the earliest, or the earliest, "high level language" (criteria vary) instead provided a way of specifying the work to be done in a way independent of particular target machine, and using instructions some of which looked like equations. Actually, between the mid-1950's and mid-1960's, the language evolved considerably, moving away from some echoes of machine instructions and toward greater convenience. And it continued to evolve for decades thereafter. Illustrations of the long-term evolution can be seen here.
Besides learning to program, we also learned how to wire a board to control a punched card machine (that was fun), and something about how the 7090 hardware worked.
The machines we used in training were the local 7090 and 1401. To create and run a program you might first write your program on a coding pad tailored to the spacing requirements of your programming language. You would then use a keypunch to transfer the program and related material onto a deck of punch cards, and, finally, submit the deck to be run by a machine operator. The deck would contain the program itself, along with some "control cards" at the beginning, and sometimes followed by "data" cards at the end.
After completing training class I was given a choice between working on IBM systems maintenance and support or on a small but interesting 1401 project. The 1401 project was to build an application to analyze a proposed product or brand name to determine whether it conflicted in look OR pronunciation with an existing one. I chose the maintenance project because it seemed that the 1401 was so tiny that accomplishing anything would be seriously hampered by memory size. That was one of the smaller but possibly significant decisions I've made in terms of career implications. My reservations were certainly well-founded; any computationally interesting 1401 program involved developing a method of dividing the work among many stages, each of which did a small part of the job. Also, choosing the maintenance project was useful because it led to a decade of mostly interesting work in compilers, then a major focus of computer science. BUT... the 1401 project was a natural language processing project, of sorts, an area I later became deeply attached to.
Let me start this section by expressing my indebtedness to Paul McJones for helping me sort out some background for the work described in this and the next few sections. Because I recalled the main elements of my own work, but not some very relevant context, Paul pointed me to the extensive material he had collected as the principal contributor to the Computer History Museum Software Preservation Group. He also suggested some other sources of related material. (Note: Paul has built important collections on many languages and systems; they can be seen at SPG_projects )
As noted earlier, I started work on maintaining the Fortran II compiler immediately after completing training class. The Fortran I and II compilers were brilliant pieces of pioneering computer science by John Backus and his colleagues at IBM research (see [FTN_1], [FTN_2] and [FTN_3] for detailed descriptions. Not only did they introduce the language, but also serious, highly successful compiler optimization focused on optimizing references to array references in loops, like
DO 10 I=1,100
DO 10 J=1,100
A(I,J) = B(I,J) + C(I,J)
10 CONTINUE
The reason for the array-reference focus was that while array references were important for ease of coding, just automatically replacing them with in situ calculations of the referenced addresses would require multiplication instructions, which were very slow. For example, in the above, if arrays A, B, and C all had dimensions of 100x100, each reference (I,J) would require a multiplication of one of the indexes (depending on the way the array was stored) by 100. So a blind translation would require 30000 multiplications to compute the offsets "(I,J)"! Optimizing these calculations essentially involved replacing the repeated multiplications by 100 within the loop by additions of 100 to created variables at loop boundaries. So, in the above, the 30000 multiplications would be replaced by at most 30000 additions, which would take, on average, about 20% of the time, and it is likely that only 10000 additions would be needed, because the commonality in this case would be noticed.
Returning to the maintenance work... while there were a few contemporary published descriptions of the compiler algorithms, neither I nor others around were aware of those publications, at least initially. Fortunately, most of the problems we were faced with were local. Bugs usually manifested themselves in an unexplained halt to the program, together with a computer memory dump showing the 36 bit words as 12 "octal digits". (Each octal digit was a number from 0 to 7, representing 3 bits, from 0 = 000 to 7 = 111). We could usually find the problem based on examining the compiler code (in an assembly language listing) surrounding the halt, together with the dump.
On the other hand, because our knowledge of the methods used by the compiler writers was so limited, people tended to be stumped by some types of problems. Here are two interesting ones that I recall.
The first one occurred in the analyzer for arithmetic expressions, which implemented the "precedence" rules for the order in which operations should be performed if an expression were not completely parenthesized to indicate the order of evaluation. The rules (now standard across languages) specified that exponentiation (**) was performed first, followed by divide and multiply, followed by addition and subtraction. For example, (from [FTN1]) the expression "A + B ** C * (E +F) ", had to be understood as equivalent to "A + ((B**C) * (E+F)) that is,
t1 = E + F
t2 = B ** C
t3 = t1 * t2
result = A + t3
The problem that I was assigned early on was to find out why there was an "infinite" loop somewhere in the above expression analyzer. I was petrified, having no idea of what the system was even trying to do. Fortunately, I found a very knowledgeable, kind person, Maynard ("Jack") Seelye, who helped with that and some other doozies. (He went on to a career in IBM's Systems Research Institute, and in compiler development.) He isolated the problem to a case of a sequence of unparenthesized exponentials, e.g., "A ** B ** C", for which the compiler kept trying to insert more and more parentheses.
The second problem I recall was one I may have had a role in solving. The bug had been around for so long it even had a name, "7VVU", so-called because, when it appeared, the printout read "7VVU". It turned out that the origin of the bug was early in a compilation, where symbolic labels were assigned to code locations which would become targets of branches. Actual offsets from the beginning of the program could not yet be assigned, because the lengths of the code sequences were not yet known. The symbolic labels were created by a kind of "hashing"; performing a prescribed (but meaningless) sequence of operations on the content of table entries relating to the branch. Unfortunately, every so often (but rarely), the same label would be generated for two different eventual locations.
After a while, I began working also maintaining the Fortran IV compiler, which supported a revised and extended version of the Fortran language, together with a new compiler written by a different group of people. While there were high hopes for the compiler (see [FTN_4]) it was inordinately slow and there was some consensus that the compiled code was not particularly efficient. However, it was the language and compiler released under a new subsystem called "IBJOB", which had some significant advantages (see next section).
My work on Fortran IV maintenance morphed into leading a small group responsible for maintaining the compiler, the new, associated IBMAP assembler (the new compiler produced IBMAP code for subsequent assembly), and the Fortran subroutine library. The group consisted of three other people: Marian Gunsher, Leigh Power, and someone whose name I can't recall, but who was fascinated by topology.
When the first Fortran compilers were made available, users (or machine operators) were essentially on their own as far as the surrounding operational necessities. To apply a Fortran program to some data, two machine runs were needed, the first to run the compiler on the program to convert it to machine code, and the second to execute the generated code on the data. This was rather painful so, after a time, user-groups working with IBM evolved the initial "operating systems", with several important types of facilities including:
An important milestone in this area was the "Fortran Monitor System" (see [FMS] ) containing the Fortran II compiler, the Fortran library, and the FAP assembler. Then, by the end of 1962, this had been replaced by the IBSYS system, providing additional components, and looked something like the following:
IBSYS Operating System
|
| Fortran Monitor (sub)System
| Fortran II Compiler
| Fortran Library
| FAP Assembler
| SORT
| 9Pac (report generator)
| Comtran (a commercial programming language)
.....
However, several years before the above system was released, it became clear that a more integrated approach would be useful, to allow more sharing of function across components, and provision for additional programming languages, so by sometime in 1963 releases began of an expanded version of IBSYS to include an "IBJOB" subsystem (see [IBJ_1]). The IBJOB portion initially included at least at least a revised Fortran language, Fortran IV (see [IBJ_2]) represented by its compiler and library, and a revised assembly language now called IBMAP ("Macro Assembly Program"). And, more logically, the Fortran IV compiler produced IBMAP code. The basic system also probably contained the common, cross language program loader and the input/output system (IOCS).
I don't recall (and can't easily find out) the exact sequence of program releases. It appears, based on the work I recall doing, that the components under IBJOB were expanded gradually to include at least a COBOL compiler, and the report generator. So the content of the subsystem eventually consisted of something like:
IBSYS Operating System
... original components
| IBJOB subsystem
| | Fortran IV Compiler
| | Fortran Library
| | IBMAP Assembler
| | 9Pac (report generator)
| | COBOL compiler
| | IBLDR (loader)
.....
with all components under IBJOB written in IBMAP. My rather forgettable contributions to all this consisted of:
I'll get to each of these in turn.
Possibly as part of my work on Fortran IV and related components, I was made responsible for converting several extant system components originally written in FAP to the new IBMAP ("macro assembly program") language. These included, I believe, the Report Generator and the COBOL compiler, which was probably originally developed in FAP. IBMAP was very similar to FAP, as most of the instructions were just symbolic versions of 7090/94 machine codes. But there were differences in the "pseudo-instructions", which subsumed frequent instruction sequences. Some of the FAP pseudo-instructions were dropped and new ones added. And some were defined differently. So the job involved finding the places where changes were necessary, and making and testing the required modifications. The most annoying problem, if I recall correctly, was taking care of the ubiquitous, and differentially defined, CALL pseudo-operation which invoked subprograms.
The job was a painstaking slog, and an operator was assigned to help, because we often ran the machines "third shift" (after midnight) to allow fast "test-debug..." turnaround. Also, because the SBC facilities were inadequate to test some aspects, some of the work was done at an IBM data center in the basement of the Time/Life building, hauling heavy magnetic tape containers there and back by taxi.
The work was quite successful, resulting, I think, in the last full release of the IBSYS System Tape (Version 13). Here's a copy of the announcement letter. However, I vaguely recall that the work did not find favor with the SBC management at that time, who believed that reporting for work at 9AM each day took priority over getting things done by working at 2AM. This echoed later ...
The 7090 Sort utility was a very useful component, but one with a very complex set of user controls and options (see [M_SORT]). In fact, it was a a "monitor" or subsystem in itself. The monitor invoked the included loader once for each SORT phase, to load the provided code for the phase, and also user-written extensions appropriate to that phase. A user-written code extension might, for example, modify the input records to be sorted.
Now, for some reason, it was decided not just to convert the Sort Utility code into IBMAP, but also to completely rewrite the Loader. And, at about the time that the need for this modification was identified, I had gone to my superiors at SBC and asked that, after a long stint in maintenance, I be given the opportunity to write an original program. This request was not greeted with enthusiasm; SBC team players were supposed to do what they were told. Nevertheless, the timing was fortuitous and I was assigned to write the new loader.
I don't recall the details of the loader operation. But one thing I recall very clearly. Having spent such a long time working with other people's code, I was determined to "do it right". Which involved making sure that the code was extremely modular, with almost all subprograms being quite short and having detailed introductory descriptions of what the subprogram did and how it was accessed.
After completing the loader, possibly because I was not considered a model employee (with failings including tardiness and inordinate initiative), I was exiled on loan to what was or became IBM's Information Marketing Division (IMD), located in the Time/Life building, to participate in the development of Quiktran.
Quiktran was IBM's first released timesharing system, and could accommodate approximately 50 simultaneous users. It was built for the 7040 system, which was a cheaper, somewhat limited version of the 7090. The system used the 7740, a communications processor, to mediate between communication lines and the 7040.
Although my work on this project related only to the communications processor, I'll start with a bit of context with respect to Quiktran and other time-sharing systems of the era. Publications about 1960s time-sharing systems often include rationales for the basic choices that were made, most importantly what programming language or languages were to be offered, and whether the implementation was to involve interpretation or compilation, and why. The first decision, on programming languages, generally depended on the target audience. The second, on the type of implementation, implicitly or explicitly related to the chosen language and audience, as well as to computational considerations. In [QT_1], Ted Dunn and John Morrissey explain that they decided on providing a subset of Fortran, because they were focusing on a scientific programming audience. Also, they decided on an interpretive implementation, to allow extensive debugging aids. (Interpretive implementations are also useful in a time-shared environment because they simplify swapping programs and data between main memory and storage.
The externals of the Quiktran system are described in [QT_1], and the internals in [QT_2]. The Fortran interpreter analyzed statements into an intermediate form, allowing on-line updating of individual program statements and resetting variable values in the midst of execution to help locate errors. The system also provided extensive program analysis information, both static and execution-based, such as indexes, traces, and variable value dumps.
My own responsibility was to implement all or part of the 7740 front end (I don't recall the details). Work on that component and related functions was directed by a talented, personable guy named Tom Mandey, who, after continuing to work for IBM for some years, founded a successful consulting firm. The 7740 program had to satisfy the somewhat new requirements of logging in users and verifying their identity. It also provided such basic services as polling terminals, and logging messages, buffering them, and monitoring them for correctness. See [QT_2, page 436] for a more complete description of the 7740 functions used in Quiktran.
What I recall most about the assignment, however, besides learning the 7740 assembly language, was one incident. Immediately after
managing to successfully assemble the front end program without errors, I was told that Mr. Mandey's immediate superior, Wes Guebert, as
well as some VIPs
, wanted to see a demonstration. This was frightening, because I had not yet tried to actually run the program.
But, surprisingly, it worked the first time, a feat that I probably never achieved for a sizable piece of code before or since. And it turned out
to be a useful accomplishment in the context of a future effort...
Nevertheless, after completing the front end work and returning to Service Bureau, I received a somewhat middling performance review, at least partly because the Service Bureau manager asked his IBM counterpart primarily about whether I had been arriving at 9AM. He responded that, no, I hadn't, but that normal start times at that location were somewhat later. In any case, I made the decision that the Service Bureau didn't hold a promising career future, and moved on to Computer Applications Inc., a software firm.