
Programmer's Toolbox
by Jack W. Crenshaw
More on Interpreters
Last month, I gave you some history concerning a class of computers that popped up in the early 60s and thrived for a few short
years. They were computers such as the Royal McBee LGP-30 and the North American Recomp II and Recomp III, among others. One of the key features of these computers was the interpretive languages that came with them. The native programming languages of such machines was so obscure and baroque that no vendor would dream of asking the end user to program in it. Instead, the manufacturers hid the horrors of the real computer behind an interpreter that presented a different interface to the user, one
that appeared, for all practical purposes, to be the native programming language of the machine. The interpretive languages allowed us to use the computers as personal computers, which they were in the very real sense that only one person could use them at a time, and they were used interactively. As higher-order languages such as Fortran became more readily available, these personal computers faded away, and the batch-programming mentality took over. Though Professors John Kemeny and
Thomas Kurtz of Dartmouth College were already working on a little interpretive language called BASIC, it depended on the availability of time-share systems and would not be readily available to the general public until much later.
This month, I want to tell you one more story about an older computer. Then well move on to some more interesting developments in the world of microcomputers. Understand, I am making no attempt here to write a history of early computers; that would take a lot more
research than Im able to do. Instead, what youre getting is history as it happened to me. The stories Im telling have a shamelessly personal perspective, and I dont apologize for that.
You can expect this trend to continue as I tell you about my own exposure to interpreters, and how theyve affected my work. My story will be mostly chronological, but based on my own personal chronology, not that of the rest of the computing world. I suppose I might be prejudiced on this score, but
I think the story is more interesting when told from such a perspective. The downside of this approach is that the history is necessarily slanted. You wont hear about computers I never saw or heard of, or languages that might have been wildly successful, but that no one told me about. However, in the interest of a broader coverage, if any readers here want to add their own unique perspectives and recollections of those early days, Ill be happy to add them to the tale.
A real programmer
In the spirit of reader contributions, I offer the following gem, apparently posted originally to Usenet by Ed Nather in 1983, and forwarded to me by Robert H. Morrison.
A recent article devoted to the
macho
side of programming made the bald and unvarnished statement: Real Programmers write in FORTRAN. Maybe they do now, in this decadent era of Lite beer, hand calculators, and user-friendly software, but back in the Good Old Days, when the term
software sounded funny and Real Computers were made out of drums and vacuum tubes, Real Programmers wrote in machine code. Not FORTRAN. Not RATFOR. Not even assembly language. Machine Code. Raw, unadorned, inscrutable hexadecimal numbers. Directly.
Lest a whole new generation of programmers grow up in ignorance of this glorious past, I feel duty-bound to describe, as best I can through the generation gap, how a Real Programmer wrote code. Ill call him Mel, because that was his name.
I first
met Mel when I went to work for Royal McBee Computer Corp., a now-defunct subsidiary of the typewriter company. The firm manufactured the LGP-30, a small, cheap (by the standards of the day) drum-memory computer, and had just started to manufacture the RPC-4000, a much-improved, bigger, better, faster drum-memory computer. Cores cost too much, and werent here to stay, anyway. (Thats why you havent heard of the company, or the computer.)
I had been hired to write a FORTRAN
compiler for this new marvel and Mel was my guide to its wonders. Mel didnt approve of compilers. If a program cant rewrite its own code, he asked, what good is it?
Mel had written, in hexadecimal, the most popular computer program the company owned. It ran on the LGP-30 and played blackjack with potential customers at computer shows. Its effect was always dramatic. The LGP-30 booth was packed at every show, and the IBM salesmen stood around talking to each other.
Whether or not this actually sold computers was a question we never discussed.
Mels job was to re-write the blackjack program for the RPC-4000. (Port? What does that mean?) The new computer had a one-plus-one addressing scheme, in which each machine instruction, in addition to the operation code and the address of the needed operand, had a second address that indicated where, on the revolving drum, the next instruction was located. In modern parlance, every single instruction was followed by a GO
TO! Put that in Pascals pipe and smoke it.
Mel loved the RPC-4000 because he could optimize his code: that is, locate instructions on the drum so that just as one finished its job, the next would be just arriving at the read head and available for immediate execution. There was a program to do that job, an optimizing assembler, but Mel refused to use it. You never know where its going to put things, he explained, so youd have to use
separate constants.
It was a long time before I understood that remark. Since Mel knew the numerical value of every operation code, and assigned his own drum addresses, every instruction he wrote could also be considered a numerical constant. He could pick up an earlier add instruction, say, and multiply by it, if it had the right numeric value. His code was not easy for someone else to modify.
I compared Mels hand-optimized programs with the same code massaged by the optimizing
assembler program, and Mels always ran faster. That was because the top-down method of program design hadnt been invented yet, and Mel wouldnt have used it anyway. He wrote the innermost parts of his program loops first, so they would get first choice of the optimum address locations on the drum. The optimizing assembler wasnt smart enough to do it that way.
Mel never wrote time-delay loops, either, even when the balky Flexowriter required a delay between output
characters to work right. He just located instructions on the drum so each successive one was just past the read head when it was needed; the drum had to execute another complete revolution to find the next instruction.
He coined an unforgettable term for this procedure. Although optimum is an absolute term, like unique, it became common verbal practice to make it relative: not quite optimum, less optimum, or not very optimum. Mel called the
maximum time-delay locations the most pessimum.
After he finished the blackjack program and got it to run (Even the initializer is optimized, he said proudly), he got a Change Request from the sales department.
The program used an elegant (optimized) random number generator to shuffle the cards and deal from the deck, and some of the salesmen felt it was too fair, since sometimes the customers lost. They wanted Mel to modify the program so,
at the setting of a sense switch on the console, they could change the odds and let the customer win.
Mel balked. He felt this was patently dishonest, which it was, and that it impinged on his personal integrity as a programmer, which it did, so he refused to do it. The Head Salesman talked to Mel, as did the Big Boss and, at the bosss urging, a few Fellow Programmers. Mel finally gave in and wrote the code, but he got the test backwards, and, when the sense switch was turned on, the program
would cheat, winning every time.
Mel was delighted with this, claiming his subconscious was uncontrollably ethical, and adamantly refused to fix it.
After Mel had left the company for greener pastures, the Big Boss asked me to look at the code and see if I could find the test and reverse it. Somewhat reluctantly, I agreed to look.
Tracking Mels code was a real adventure. I have often felt that programming is an art form, whose real value can only be appreciated by another
versed in the same arcane art; there are lovely gems and brilliant coups hidden from human view and admiration, sometimes forever, by the very nature of the process. You can learn a lot about an individual just by reading through his code, even in hexadecimal. Mel was, I think, an unsung genius.
Perhaps my greatest shock came when I found an innocent loop that had no test in it. No test. None. Common sense said it had to be a closed loop, where the program would circle, forever, endlessly. Program
control passed right through it, however, and safely out the other side.
It took me two weeks to figure it out. The RPC-4000 computer had a really modern facility called an index register. It allowed the programmer to write a program loop that used an indexed instruction inside; each time through, the number in the index register was added to the address of that instruction, so it would refer to the next datum in a series. He had only to increment the index register each time through.
Mel
never used it. Instead, he would pull the instruction into a machine register, add one to its address, and store it back. He would then execute the modified instruction right from the register. The loop was written so this additional execution time was taken into accountjust as this instruction finished, the next one was right under the drums read head, ready to go. But the loop had no test in it.
The vital clue came when I noticed the index register bit, the bit that lay between the
address and the operation code in the instruction word, was turned onyet Mel never used the index register, leaving it zero all the time. When the light went on it nearly blinded me. He had located the data he was working on near the top of memorythe largest locations the instructions could addressso, after the last datum was handled, incrementing the instruction address would make it overflow. The carry would add one to the operation code, changing it to the next one in the instruction set: a
jump instruction.
Sure enough, the next program instruction was in address location zero, and the program went happily on its way.
I havent kept in touch with Mel, so I dont know if he ever gave in to the flood of change that has washed over programming techniques since those long-gone days. I like to think he didnt. In any event, I was impressed enough that I quit looking for the offending test, telling the Big Boss I couldnt find it. He didnt seem
surprised.
When I left the company, the blackjack program would still cheat if you turned on the right sense switch, and I think thats how it should be. I didnt feel comfortable hacking up the code of a Real Programmer.
What a delightful story! I certainly hope Mel is still doing well. If not, surely he is in Real Programmer Heaven. Though I, too, once met a systems programmer who proudly proclaimed that real programmers program in absolute binary, I never got quite that
carried away. Nevertheless, Mels proud statement, Even the initializer is optimized definitely strikes a resonant chord with me. Im afraid that I, too, must admit that Ive occasionally spent inordinate amounts of time tweaking optimizations into places where they really didnt matter, simply for the pride of having created a work of art.
the ibm 1130
For some years after the demise of the early personal computers, I worked with what I had to work
with, which in those days were the big IBM mainframes and the occasional IBM 1620, which was a minicomputer in name only. Its operation was batch-oriented like its larger cousins, so to us users it was simply a slow mainframe. I progressed through the IBM 704 to the 709, 7090, 7094, and System 360, all the while gritting my teeth at the horrors of JCL, and missing the little desktop minis and their interpretive languages.
In 1968 I got my first exposure to the IBM 1130 minicomputer. In my somewhat biased
opinion, the 1130 is the only good computer IBM has ever built after the 704-7090 series. It was a 16-bit mini with core RAM and a single, removable-medium hard drive. The minimum RAM size was 4K and was expandable to, I think, 32K. Ours had a whopping 16K.
Each removable disk held 512K, which made them somewhat smaller than the old 5.25-in., low-density PC floppies. They cost an arm and a leg, and our company had a whole two of them: one for all accounting work, another for all engineering.
Lest you lose
the significance of that statement, let me repeat it: in our company, which supported 300 engineers, the only computer engineers used had 16K of RAM and
one
512K floppy. On that disk resided the operating system, the system tools, the Fortran compiler, the libraries, and certain favored source and object files for all 300 engineers.
For me, the best thing about the 1130 was that I got to run it. It normally operated under closed-shop, batch-oriented rules like any other mainframe.
However, over lunch hour and after hours, those of us who got checked out on it were allowed to use it hands-on. Though we still had to use it in absolutely batch mode, feeding it cards through a hopper and getting our results on a line printer, we still got pretty fast turnaround. Though the computer had no terminal (except the operators console, which we didnt use), there was an O29 card punch in the same room. I typed my programs into the card punch in real time, and transferred them
to the card reader via sneakernet. It was the closest I could get, in those days, to the little personal computers like the LGP-30.
Most of the engineers in the company developed an interesting attitude about that old 1130, which definitely worked to my advantage. As NASA contractors, they had access to NASAs monster array of mainframes at Marshall Space Flight Center, like the Univac 1108s. They tended to run their jobs there, submitting their card decks via courier, and
getting their printouts the same way. Turnaround time was about three to four days (!). They tended to look down their collective noses at the lowly 1130 in the floor below them, pronouncing haughtily,
My
program could
never
run on a computer that small.
A few times, I gently tried to explain to them that I was using it to solve serious problems, like trajectories to the Moon, altitude control simulations, and rocket launcher simulations for the Army. I also gently pointed out that
the object of the game was not to see how large a computer program one could make, but how small and efficient. (An example: one of their simulations contained tables of atmospheric density data on a card deck a good six inches thick. My simulation used the analytical formula for the US Standard atmosphere, and was not only more accurate, but consisted of something closer to six
cards
.)
They were unmoved, which was fine with me, because it meant more time for me to have the 1130 to myself. While
they waited for their results to come back from NASA via courier, I was getting 20 to 30 turnarounds per day.
At about this time, I formulated a principle I still live by: computer size and clock speeds, or compiler speeds as measured in lines of code per minute, are not the best measure of system speed. That best measure is the time required from the point a problem is conceived to the point where you have the answers in your hand. In that context, I was getting at least two orders of magnitude better
response out of that old 1130.
Our crowning achievement came when NASA had a problem with the Skylab vehicle. A solar panel had failed to deploy, and the spacecraft was tumbling because its attitude control system was not functioning. NASA was trying to get it under control by commanding attitude jet pulses from the ground, but they were having trouble understanding the data they saw from its horizon sensors, and ended up making things worse.
A colleague and I decided that we could figure out the
attitude by analyzing the data from the system, using an altitude determination system coupled to a simulation. The only problem was, none of the simulations we had were up to the job. So we rewired one. We heard about the problem at 9:00 a.m., defined the solution by 10:00 a.m., and set out to implement it on that IBM 1130. We wrote the equations, I coded the simulation, and we began debugging it. By 10:00 p.m., we were getting answersfrom conception to data in-hand in 12 hours. Not bad for a machine too
small for serious work. (Postscript: NASA never used the data. They didnt believe we could have gotten it so quickly.)
something strange in the neighborhood
Again, it helps to get yourself into the mindset of what was going on there. Here was a computer that would not even qualify as a TV game today, with a grand total of 16K of RAM and a single 512K disk. When compiling a program, that disk not only had to hold the operating system, Fortran compiler, all associated libraries and stored
files, and so on; it also had to hold the source file, the object file, and any intermediate files for the program being processed. Not to mention the data files for those lucky few like me who had approval to leave their files on disk.
Do you think you could get a Fortran compiler to run in 16K today? I certainly dont. I dont know for sure, but Ive been told that while the Fortran compiler would not run in the 4K minimum configuration, it was specifically designed to run in the next step
up, 8K. Imagine: a compiler that uses a
total
of 8K of RAM, while coexisting with the operating system, and can handle programs of arbitrary size. Put
that
in your EMS RAM and smoke it. As far as I know, the only concession that compiler made to computer size, as compared to standard Fortran IV, was that it allowed only five-character, instead of six-character variable names. IBM had invented all manner of neat ways to save on RAM space, including paging bit of programs out to that
huge 512K drive. Recognizing that many programs required startup code that was never used again, they arranged for the programmer to specify overlays in a single line of control code. They also offered a neat little trick that left object code out of RAM unless it was needed. IBM called this scheme LOCAL (for load on call). Today, wed call it DLL.
My first indication that that 1130 was something special came the first time I compiled a program hands-on. Having worked on the 7090 series,
I was used to having object decks (binary decks, the equivalent of .obj files) coming back that were somewhat smaller than the source decks (Fortran files). When I had transferred to a company using the System 360, I discovered, somewhat to my horror, that the object decks it produced were typically about 30% to 40%
larger
than the source decks, thanks to inefficiency in every aspect of the 360s design. It was, to my knowledge, the only computer ever built whose compilers produced .obj files
larger than the source files.
The first time I tried the 1130, I ran a rather small program, with a source deck about 1/4 in. thick. The compiler digested the cards, thought about them for a moment, and spit out something like two binary cards. I was convinced that I must have done wrong; no compiler could create object files
that
small. Having no idea, however, what to do next, I tried to run the file anyhow. Imagine my surprise when the program ran perfectly! I was blown away. As they say in the
TV show, Howd they do that?
My next pleasant surprise came when I began to write serious programs for that system. They also were quite small in size. To give an example, all my simulation programs were based upon a general-purpose,
N
-dimensional (with no practical limit on
N
), numerical integrator for writing simulations. It was not a trivial piece of software, and made no concessions to gain small size, other than careful programming and serious optimization that Mel
would have smiled upon. It used a variable-step, fifth-order variation of the Runge-Kutta method, could handle discontinuities that were either time-dependent or dependent on some arbitrary switching function (iterating on the latter), and would print at arbitrary intervals of either time or a specified number of integration steps, or both. It was 936 bytes long.
Curious about how this compiler could generate code so small, I ran the compiler once with a small test program, and with a flag set that forced it
to output the generated assembly language code. It was nothing but a series of subroutine calls. Even a 16-bit integer add, surely a native instruction on the 1130, was implemented via a subroutine call. The next time I saw IBMs sales rep, I asked him what was going on there. He answered, Im not exactly sure, but its something they call threaded code.
on to micros
Fast forward about ten years to 1978. By this point the microcomputer revolution was well
under way. After the introduction of the Intel 4004 in 1972, I got micro fever in a big way. I took to writing programs in 8008 assembler, just as an intellectual exercise, though I didnt have a computer, and by 1976 was running a company which built embedded systems based on the 4040 and 8080.
For the record, I dont think many people appreciate the giant leap forward represented by the Intel 8080. It was not only the first really capable microprocessor, but it introduced many innovations that
were not available even in the minicomputers of that day, or the mainframes either, for that matter. Chief among these innovations was a flat address structure with a then-astonishing 64K range, and that most wonderful of all inventions, the RAM-based stack.
The 8080s predecessor, the 4040, had subroutine call and return instructions, and a stack for return addresses to support them. This, in itself, was an innovation. Early mainframes had no such stackthe programmer or the compiler had to
handle them in software. Software for the IBM 709x reserved one register for use as a stack pointer, and the stack was actually a linked list, chained from function call to function call. Many minicomputers of the day had similar stackless architectures.
The 4040s CALL instruction automatically pushed the return address onto a stack reserved for the purpose. Its companion instruction, RET, popped the address back off again. The whole idea, to me, was a stroke of genius. However, the 4040s
return address stack was on-chip, and had limited depth of, if memory serves me correctly, eight levels. That, the designers figured, should be enough for anybody.
As long as were assigning credit, I think we should also thank Intel for having the foresight to allow instructions like CALL, RET, PUSH, POP, and so on, rather than the traditional three-character mnemonics like CAL, or even worse, horrors like JSR, BSR, and RTS.
Unlike the solution chosen for the 4040, the designers of the 8080 allowed
the stack to reside in RAM, which meant it could use all of the memory not used by programs. The availability of this virtually limitless stack made all the difference. We could not only use it for return addresses, but for anything else our hearts desired, especially and emphatically to include passed parameters and any other data we wanted to store temporarily. Intel (and later, Zilog) thoughtfully provided instructions to make it easy to manipulate stack-based data, and those of us who programmed the
machines learned how to do all manner of neat tricks using the stack.
One such trick involved putting literal data such as constants or character strings in line, right after the subroutine call. In the 8080 and Z-80, the processor automatically increments the current address before pushing it onto the stack, so that when its popped by the RET instruction, it points to the next executable instruction. If you put data in line after the call, the last address pushed onto the stack points to that data. The
subroutine can pop the address, use it to operate on the data, increment as needed, and jump to the new value, which now points to the next truly executable instruction. Such a subroutine, which printed literal strings to the console, became sufficiently popular among 8080 and Z-80 programmers to earn and deserve its own universal name: ILPRT, for in-line print.
By this time, the 1974 introduction of the MITS Altair 8800, normally credited with launching the revolution, was history (though, to
keep the record straight, a few hard-core hackers, like Carl Helmers and Don Tarbell, had launched that revolution years earlier). That first flurry of micro-based hobby computers like the Altair, which evolved into very capable S-100 class machines like the Imsai, had passed. Up in Atlantic City in 1976, a couple of guys named Steve had introduced a little single-board computer called the Apple. Magazines like
Byte
and
Kilobaud
had been launched and were selling like hotcakes. A little
newspaper-like magazine called
Dr. Dobbs Journal of Computers, Calisthenics, and Orthodontia
(subtitle, Running Light without Overbyte) was presiding over efforts to define and develop the perfect dialect of a language called Tiny BASIC.
By 1978, the first of the true personal computers, like the Commodore PET and the Radio Shack (nee Tandy) TRS-80 were hitting the streets. And I had one. The original TRS-80 had 4K to 16K of RAM, and a ROM containing what they called Level I
BASIC. The only mass storage device was an ordinary audio cassette. The BASIC was called Level I because it was only an interim BASIC, marking time until the real BASIC, Level II from Microsoft, arrived. As so often happens, Microsofts schedule had slipped (some things never seem to change). So the programmers at Tandy had developed Level I to fill the gap.
The most significant thing about that old TRS-80, like the Altair before it, was that it was
mine
! No more batch
programming, no more battles with intractable systems operators, systems programmers, and systems administrators. No more cases of perfectly good programs that stopped working because someone had upgraded the operating system without telling anyone. The computer was all mine, and I could use it for anything I liked, without having to sell the idea to anyone. No software, except what was in the ROM, could ever go into the computer unless I put it there.
For the record, I note sadly, and in passing, that with the
advent of networked PCs and Internet updates to software, it seems that we are now thoroughly back in the clutches of the systems programmers and systems administrators. Again, some things never seem to change.
Anyhow, by the time I got that TRS-80, I was deeply into assembly language programming, and desperately wanted to get into the guts of that computer. In short, I didnt even want the ROM getting in the way. I wanted to own every line of code that was executed in that computer.
Most people who
knew the TRS-80 and its Level I BASIC never knew that it was possible to get past the BASIC in ROM. After all, it took control after every reset, and tenaciously resisted giving it up. I got lucky. I called Tandy and got hold of a systems developer, who quietly shipped me an advance copy of a tape with the name, TBUG, written on it by hand. I put the tape in my cassette, typed LOAD, waited for a bit, and lo and behold, suddenly I was in a hex debugger. Again I found myself asking,
Howd they do that?
It turns out that the Tandy folks had found a trick worthy of Mel, the Real Programmer. Under normal operation, the LOAD command simply read a BASIC file into memory, then returned control to the operating systemreally a command processorof Level I BASIC. When the user typed LOAD, this command processor called a subroutine to load the program. After loading was complete, the subroutine naturally returned to the command processor that
had called it, as good little subroutines are supposed to do.
The format of the data used with Level I tapes, however, did not consist of a simple stream of source-file characters. It was blocked into records, very similar to Intel or Motorola hex file records. Each record had a byte count, checksum, and, significantly, a load address. The Tandy programmers, who obviously knew the internals of the system theyd written, knew how deep the call stack would be when the command processor called the load
subroutine (the address never changes, because the command processor is the top-level task). This means they could easily calculate the address where the call instruction would push its return address. All they had to do was to add one more record to the file, which had for a load address, this magic address, and for data, the starting address for the debugger. When the load subroutine completed its assigned task and dutifully executed its RET instruction, the address that it popped was no longer that of
the next instruction in the command processor; it was the address of the debugger itself. Voila! Instant escape from the confines of the ROM.
Within months of the arrival of that magic tape from Tandy, several third-party vendors had already learned the same trick, and I soon had a bewildering and magical array of assemblers, debuggers, and a disassembler. The first thing I did was to set out to disassemble the code in the Level I ROMs.
I realize that this is all ancient history now, but if youve
never seen the inside of those ROMs, you should to find a way to do so, just as a lesson in how to write assembly language. The Radio Shack/Tandy Level I BASIC wasnt developed out of whole cloth; it was a Tandy extension to Li-Chen Wangs Palo Alto Tiny BASIC (Li-Chen Wang, Palo Alto Tiny Basic,
Dr. Dobbs Journal
, May 1976, p. 12). Palo Alto Tiny is nothing less than a work of art. Among other things, its a wonderful object lesson in how to write recursive-descent
parsers. You really owe it to yourself to see what Wang wrought.
The original Palo Alto Tiny BASIC fit nicely into 2K of 8080 RAM (lets see you try
that
today!). It was, however, an integer-only BASIC, as all Tinies were. The Tandy engineers extended the math, replacing all integer arithmetic with floating-point versions. They also added the LOAD and SAVE functions, and a few other features, and managed to squeeze the whole thing into 4K. Today, 20 years later, Palo Alto Tiny BASIC
still lives on in several new guises, having been given real-time extensions and given the generic name Real-time BASIC.
For the record, I must be one of the very few TRS-80 owners who never got around to adding floppy disk drives (the Tandy 5.25-in. floppy drives were pricey, and notoriously unreliable). Instead, I added an exquisitely cute mini-cassette drive called the Exatron Stringy Floppy, which used continuous-loop, 1/16-in. tape. As a further matter of trivia, the Exatron tape format
used Manchester encoding (just as Don Tarbell used) to achieve 14K read-write speeds. The code, which was also a work of art, was developed by none other than Li-Chen Wang.
I really didnt need mass storage very much. In those days, assembly language tools were quite small; The assembler system, consisting of the (line-oriented) source editor, debugger, assembler, and command processor, fit into 4K, as did the largest single application, the disassembler. I also wrote my own debugger,
which was barely 1K.
With a 32K internal memory expansion, giving me 48K total with no expansion unit, I had memory to burn. My RAM could hold the assembler, editor, debugger, disassembler, and my own debugger, as well as my source and object files, all in RAM memory simultaneously, with room to spare. I needed only to execute a jump in any of the tools to get to the other. Turnaround time was measured in seconds. The computer stayed turned on constantly, and the Stringy Floppy was more of a backup device
than a mass storage device. All this with nary a sound from the computer, be it cooling fan or twirling hard drive. Though it may sound like a case of the good old days syndrome gone mad, its taken me decades to get a system with comparable turnaround time. I never
have
managed to get back the silence.
Before we leave the TRS-80, I should mention that, eventually, I bit the bullet and bought the ROM upgrade to Level II Basic, which was really Microsoft Basic. The first thing I
noticed immediately was that the old cassette load-and-jump method no longer worked. The tape load software in Level II was no longer a subroutine, but inline code, so there was no return address to diddle.
I noticed the second difference when I tried to disassemble the ROMs. I soon gave up, not because the ROMs were three times bigger, but because I kept getting these recurring waves of nausea. Where every line of Wangs code had been a delight, a revelation of how to write assembly language, I had a
much different reaction to Level II. I can best describe the style of the code by the term gratuitous complexitya syndrome that remains aggressively with us, to this day. Thats hardly surprising, of course, seeing that the developers of Level II Basic are still with us.
As for me, I had gotten the Level II ROMs specifically to get support for the floppy disk drives that were then available. When TRSDOS v. 1.0, proved as unreliable as the drives themselves, I returned the
drives to Tandy, thankfully pulled the plug on the Level II ROMs, put the old faithful Wang/Tandy version back in, and never looked back.
You may be wondering just what this nostalgia binge has to do with interpreters. That will begin to be clear next month. See you then.
Jack W. Crenshaw is a staff scientist at Invivo Research in Orlando, FL. He did much early work in the space program and has developed numerous analysis and real-time programs. He holds a PhD in physics from Auburn University.
Crenshaw enjoys contact and can be reached via e-mail at
jcrens@earthlink.net.
|