When I first began using microcomputers in the late 1970’s, development tools for 8-bit machines were precious and mysterious commodities. Most of these sorts of tools that looked to be useful were very expensive. My usage of most of these tools was driven by budgetary constraints.
The Gateway Drug : BASIC
All it really took to pique someone’s interest in microcomputers was to show them a simple program such as:
10 PRINT "HELLO, WORLD! "; 20 GOTO 10
…to convince them that they could learn to tell a computer what to do and the computer would carry out the request.
While the 8-bit BASIC implementations allowed one to stumble into the art and science of programming, BASIC wasn’t always the friendliest choice for larger projects.
The limitations on variable names, usage of numbered subroutines, and lack of features for modular programming limited the expressiveness of those implementations of the language.
Due to limited memory, the implementations of BASIC that were available in ROM for most 8-bit home computers executed code slowly. Although disciplined BASIC coders knew how to arrange their code for optimal performance, the language was soon tagged with a reputation of being slow.
Under the Hood
Most of the microcomputer BASIC’s allowed the developer to invoke subroutines written in the given microprocessor’s native tongue; machine language.
Machine language subroutines could execute much more quickly than equivalent BASIC code and could often perform tasks for which on-board BASIC was not suited.
Machine language subroutines were often inserted into BASIC code via DATA statements. These statements held numbers that represented the processor’s mnemonic commands and arguments for the given subroutine. The BASIC code would then find a spot in memory to place the subroutine and would then READ and POKE the values into that spot in RAM.
To invoke the subroutine, one then used the appropriate BASIC verb ( CALL, SYS, or USR() )
Many magazines of the day simply presented the subroutines as the DATA statement loader code, which added an air of mystery to what this odd section of code was doing and how minor miracles could be accomplished via a set of numbers.
Other magazines, like 80 Micro for the TRS-80 family, published commented assembly language source code listings in addition to the BASIC loader code. In fact, 80 Micro went further and hosted a column by Hardin Brothers called The Next Step which provided a TRS-80-specific Z-80 assembly language tutorial in each installment. ( It was through this column and one of Bill Barden Jr.’s books that I first learned assembly language ).
My brother gave me his unused edition of the Radio Shack Editor/Assembler. At school, I had access to Apple II series computers. We had no formal editor/assembler package to use nor any other languages except for the Apple-supplied boat-anchor called SuperPilot.
My machine code excursion on the Apples involved the traditional CALL -151 to invoke the machine language monitor program.
My first efforts in learning 6502 assembly language from one of the Apple manuals involved hand-assembling the routines that I wanted to try. I would then type them in as hex numbers in the monitor. I later found that if I entered CALL -151 via Integer BASIC, that flavor of the machine language monitor program supported a mini-assembler syntax allowing me to enter the symbolic 6502 mnemonics.
When using Commodore 64 computers at school, I used Jim Butterfield’s Supermon64 monitor program to experiment. When I bought my own Commodore 64, I ended up typing in Bill Yee’s Micromon64 from a hex listing in one of the Compute!’s First Book of C64 collected editions. I preferred that monitor to any other in the C64 family.
I later used full-blown assemblers on the C64. Although assemblers with macro capabilities were on the market, the code that I often saw in magazines was macro free. Nothing but line after line of 6502 / 6510 code. Looking at a CP/M-related publication during this same time-frame was a different story. Most of the assembly language listings in 8080 or Z-80 contained fairly heavy use of macros in the code.
Merlin was a popular editor/assembler for the C64 that had a pretty easy-to-use editor and could assemble code rather quickly. However, the prevalent C64 techie mag ( in my neck of the woods ), The Transactor, published assembly language listings in PAL format.
PAL was an assembler that resided in memory. One would enter their assembly programs in BASIC with BASIC line numbers. A quick SYS invocation launched the assembly process. In a nutshell, PAL allowed one to use whatever programming tools they had for BASIC ( renumber, search/replace, …etc. ) and provided only the assembler functionality.
The Transactor later offered their own PAL-compatible assembler called SYMASS, the symbolic assembler. The people who published Compute! and the Commodore-specific Compute!’s Gazette magazines published their own assembler called LADS ( Label Assembler Development System ).
When learning Z-80, I wanted to just set BASIC aside and wanted to write everything in assembly language. When learning 6502, however, I was growing more content with the idea of writing time-critical code in assembly language and writing the primary routines in something else.
In fact, I wrote a disk copier that would copy a 1541 disk in three passes using the RAM that lay underneath the BASIC, KERNEL, and character-set ROM’s for temporary storage. The bulk of the program was written in assembly language. However, my sectors-per-track calculation was written in BASIC. I had lifted the expression, I believe, from the book Inside Commodore DOS. As I recall, it was a one-line expression that I probably could have unwound into assembly language, but that portion of the code took up a modicum of memory and was not a performance bottleneck.
Many of my friends who were learning assembly language at this time were really gung-ho about writing everything in assembly language. In fact, in various trade-magazines for various computer systems, reviewers often noted when a given game or program was written completely in assembly language, equating the execution-speed and smaller memory footprints to quality.
I continued to write full assembly language programs into my 8086 days, but opted for something else when a choice was available. However, I was warming up to the idea of getting programs out the door that were faster to write and had acceptable memory footprints and execution-speed.
Transactor magazine began to publish a series centered around a growing piece of software called TransBASIC. TransBASIC was a nucleus that allowed one to add new commands to Commodore 64 BASIC by writing assembly language modules.
One could fine-tune their own TransBASIC kernel by adding in only the language modules that they needed. Some modules added structured programming constructs, others added better access to underlying hardware or graphics.
Unfortunately, there wasn’t a standard way to distribute a TransBASIC program to friends. You’d have to package up a loader that would load your TransBASIC kernel, then load and execute your BASIC program.
Other supplements to address the drawbacks of interpreted BASIC were p-code compilers like Blitz! from Skyles Electric Works.
Blitz! would translate a BASIC program into a pseudo-compiled format that optimized a few areas where normal BASIC spent a lot of time processing code.
- Math expressions were translated into equivalent Reverse-Polish-Notation (RPN) expressions. This prevented BASIC from having to spend time re-parsing expressions.
- GOTO and GOSUB targets were precomputed to relate to addresses in the Blitz! virtual machine. BASIC interpreters often spent time poring over a linked-list of lines to find a given line in memory.
- Variable lookups were also optimized by pre-creating the descriptors for each and then setting given variable references directly to the descriptors.
Blitz! interfaced nicely to machine language supplements including many of those that altered BASIC’s syntax to accept new commands. Resulting programs were often larger as a runtime package that weighed in at about 6K was added to the generated target.
Blitz! pretty much dealt with most of C64 BASIC’s known runtime constraints with the exception of the string garbage-collection delays, but those could be handled with a little machine language code.
However, the syntactic shortcomings … short variable names and line-number flow-control targets did little to make BASIC a very welcome environment for me.
The Pascal programming language was taking the trade-press and learning institutions by storm. Many commercial and free BASIC supplements altered BASIC’s syntax adding Pascal-like features. These new features, named procedures and functions, longer variable names, and better flow-control constructs all but eliminated the need for the GOTO verb.
I tried a few of these and found the experience to be the opposite of the Blitz! experience. The software model in my head had a better analog in the code that I wrote with COMAL or Simon’s BASIC, but the execution-speed was far from stellar. In fact, sometimes the language extensions slowed down the C64’s interpreter.
On a whim, I picked up Oxford Pascal at a Sears store. OP was a good-enough Pascal compiler that, like PAL assembler, allowed one to write Pascal code using the BASIC editor and would then compile the result to disk. I had heard that there was a cassette version, but I’ve never used it.
I actually found a YouTube video of someone typing in a short program in OP and compiling/running it. ( You might want to turn your sound down a bit for both of the following YouTube clips ).
I seem to remember that short programs would compile/run in acceptable amount of time, but generating stand-alone, runnable programs from OP seemed to take forever. This is not necessarily due to a flaw with the compiler itself. The 1541’s serial access routines were slow and cause I/O bottlenecks during the compile process for this and other compilers.
I had bought an early version of Abacus Pascal64, but that version broke due to a track-35-error protection scheme when I got my 1571 disk drive.
I was taking a course in Pascal at the time and was elated with the abstractions that the language gave to the programmer. I just couldn’t find a decent compiler.
I tinkered with a C compiler and a few Forth’s on the C64 being happiest with the free Blazin’ Forth compiler by Scott Ballantyne. Nothing was providing my desire for a structured programming language that generated better-than-BASIC runtime code in a decent compile time.
A Different OS
One of the selling points for the Commodore 128 home computer was the inclusion of CP/M mode, which allowed the machine to run a version of Digital Research’s CP/M operating system.
My earlier attempts at using compilers were all related to menu-driven or shoehorned-into-BASIC compiler offerings. Once I booted CP/M, I began to see how real compilers worked.
A friend demonstrated Turbo Pascal for CP/M for me and I was hooked. I got my own version and spent a lot of time writing code, not because Pascal was the best language ever … it was a pleasant enough. The TP implementation, however, was very friendly and very speedy compared to other offerings.
I soon bridged over to TP development in MS-DOS and also found myself using an Amiga 500 and C. My 8-bit days and their tools were fading into the sunset.
There are times when I forget how painful it was just to try to learn the rudimentary ideas and philosophies of a new programming language. Back in the day, one might drop $60 of mid-80’s money on a “compiler” that really turned out to be a dud.
Today’s computer enthusiasts have so much more available for free. In fact, the sheer number of options can be daunting for the beginner.
I suppose that the limited options that were available back then caused a number of people to take very similar inroads when learning to program.