14

My colleague and I have just had a conversation and we were wondering how the process of developing an application was done in the era of cassette tapes.

Today we have HDDs, backup HDDs, FTPs, repositories in the cloud, etc. -- so we don't care: we just save, send and share our data, but...

I myself, as a child, had a Timex 2048 (ZX Spectrum clone) in the 90s and I remember that creating an application involved saving my work on the tape, then next day I loaded it into Timex's memory, made changes, saved on the tape again and so on. But I worked alone for my own happiness and the applications I created weren't complex.

But what about cases when there were two or more developers? How did they share their code?

What about complex applications? Graphics (simple, but still) for games?

What about the durability of their work? We all know that cassette tapes were very unreliable: errors during saving and reloading data were common. (Eventually FDDs became available for computers such as Spectrum, Atari and Commodore, but as far as I remember they were quite expensive; and they weren't available from the very first moment, were they?)

11

Obviously, you can just switch tapes as you go, but systems that used cassette tapes for storage weren't really viable for collaborative development.

Simply because with a cassette tape, you had "what's in memory" and "what's on tape", and the occasional task of saving and loading from a tape.

So you could have someone walk over with a cassette so they can work on it, but there was no effective way to "merge" work at the basic cassette level.

Since cassettes dominated the micro market, you're basically stuck with BASIC as a primary development tool. And some BASICs allowed you to read in text, possibly from tape, like an "include", but it was rare.

In the end, the cassette tape was barely viable for individual development (being both very slow and absolutely notorious for unreliability, along with a whole host of other problems), much less collaborative work.

So, much of the "professional" development on such systems weren't done on those systems at all, but rather they were developed on mini computers with cross development environments. Those systems obviously were much more sophisticated.

| improve this answer | |
  • 7
    The fact that the cassette were standard audio-cassette allowed distribution of programmes over FM radio, which was done in Finland in the 1980’s (Ars Technica paper about it) – Frédéric Grosshans Aug 29 '18 at 16:45
  • 1
    @FrédéricGrosshans So was done in Poland; this broadcast was called "Radiokomputer" (en: radio-computer) – jacek.ciach Aug 29 '18 at 17:46
  • 2
    "*you're basically stuck with BASIC as a primary development tool:": not really. Assemblers such as HiSoft Devpac supported tape, and (IIRC) came with instructions to save a working copy at the beginning of a tape, so you could keep track of revisions with the tape counter. – scruss Aug 29 '18 at 21:50
  • 1
    @WillHartung I'd probably go so far as to say that assembly was the dominant option for any serious programming. BASIC was fine for quick toy programs, but I think a lot of early stuff (C64/ZX era) on early personal computers was all written in assembly, not the least for its efficiency with very limited memory and CPU resources. – J... Aug 30 '18 at 13:38
  • 1
    ZX Spectrum BASIC did indeed have a MERGE command, that merged the program in memory with the one on tape by line numbers, overwriting lines in memory when a line with identical number was loaded from tape. – followed Monica to Codidact Sep 2 '18 at 5:51
10

Probably, no serious software development was done purely on tapes. Floppies were used extensively, as well as cross-tools, ROM emulators etc.

This nice and free book, telling about the creation of the famous ZX Spectrum game named "R-Type", has also some insights into the typical development process for ZX Spectrum.

| improve this answer | |
  • 1
    That's an interesting read, @lvd - so Bob Pape started on Microdrive, moved up to a floppy system, then onto PDS. By utter coincidence, I knew some of the Atari ST developers mentioned. They were at Strathclyde University while I was, and the mechanical engineering 1st year comp lab had Atari STs. I helped play-test a few levels when I should've been doing lab work ... – scruss Aug 30 '18 at 4:38
7

What about complex applications?

You bought a floppy drive, or before that, used punch tape. The period where cassettes were the only form of storage on micros was basically zero.

Up to about 1976 the ASR33 was widely used as the main I/O system for micros, and it had a punch tape system. You could also buy stand-alone punches and readers, both RS232 and current loop. Recall that the first Microsoft BASIC was published on punch tape, and these were widely traded at the Homebrew meetings.

The cassette was developed after the Altair, notably by Processor Technology's CUPS system, and the later KSS, both from late 1975.

But floppies appeared very quickly; MITS was advertising their 88-DCDD Pertec-based 8" system in March 1976. Digital Systems apparently was shipping a similar system in 1975.

I couldn't afford a floppy for my Atari, so I used cassettes right through the early 1980s, but everyone else I knew had a floppy, no matter what platform.

| improve this answer | |
  • 2
    “The period where cassettes were the only form of storage on micros was basically zero.” That’s true in general, but some micros didn‘t benefit from it. For example, the ZX Spectrum and its clones didn’t have a floppy drive for several years... The Apple II also didn’t have a floppy drive for a little while, and other micros similarly started out with no drives (or vapourware drives). – Stephen Kitt Aug 29 '18 at 18:04
  • I don't think that's the universal experience. In some countries, floppy drives and media were hit with very high import duties. In the UK, this was purely protectionist. – scruss Aug 29 '18 at 21:52
  • @scruss - indeed, I understand that tapes were widely used in eastern europe and south america well into the 1990s? – Maury Markowitz Aug 30 '18 at 19:14
  • How common were faster alternatives to the ASR-33? Conceptually, it would seem that if one didn't mind using custom software for it, all one would need for a faster tape reader would be nine CdS light sensors or phototransistors (whichever was more available), nine transistors, a bunch of resistors, and a means of reading the state of nine I/O lines with the CPU. – supercat Jul 13 at 23:01
6

It depends a lot on the machine, the job and your team size and what time we're talking.

Professional developers usually didn't work on the same minimal setup as their target user. Especially in the begining it was common to develop on a larger, somewhat compatible system (or total different with cross compilers) with 'real' mass storage, and usually better editors and so on. And even when workign on the target machine, it was common to have it souped up with disk drives and alike.

Next most jobs where still in a region a single programmer could (and did) handle on his own, so no need to exchange data or files with others. Even if there was a team, theIr job was usually rather seperated, so they exchanged their parts on a regular base and each integrated what the others did.

Compared to today it was way more a world of single coding heroes than teams.

At a point when realy teams where build and multiple programmers (and designers) worked on the same project, disks, including centralized stores where already available. Much like today.

| improve this answer | |
3

If you were really determined, you could develop a program in assembly, on a tape-based micro, where the program was too large for the source to fit in memory.

I did this on a TRS-80 model I with... I think 32KB of RAM. It was a long time ago, but I think that's right.

The idea is to break the program up into modules, with each module having some related functions. Each source file, small enough to fit in memory, contained the assembly source for one module. Each module's object code was absolutely located in memory.

I had to keep track each module's location in memory, and it's size. I was serving the role normally held by a relocating linker. When a module grew so large that it was going to impinge upon the following module, I would move modules around in memory, which would mean individually editing each module's source to change its start address.

In a fixed location in memory that did not move around, I kept a jump table. Each public function in a module wrote a JP instruction to a fixed location in that jump table. So when function FOO needed to be called, instead of calling FOO direction, the calling code would CALL foo's entry in the jump table, which would in turn jump to the function.

Each module initialized its locations in the jump table when it was loaded.

The process of creating the program was:

Assemble each module, writing its object to tape as absolutely located binary.

Now load each module's object, one after the other. As each module loaded, it loaded its code into its proper place in memory, and also initialized its entries in the jump table.

Now run it. If it's bad, debug it. If it's good, write the combined RAM image of the program out to a tape. That new tape is the complete program.

I only wrote one program like this. It was a fairly OK rendition of the Atari two-player "Tank" game.

| improve this answer | |
2

What about complex applications?

Some of the more complex applications were cross-assembled on larger (minicomputer) systems (see Basic, Gates and Allen, and Tiny, also Apple DOS, et.al.).

Some more complex applications (in ASM and Basic) were printed in multi-part magazine or newsletter articles, and typed in by the user by hand. Cassette tape was used for checkpointing, just in case the cat got tangled in and pulled out the power cord after hours of typing.

Some FORTH systems may have allowed saving and loading of "blocks" (which could be used as modules for larger applications) to/from cassette tape.

| improve this answer | |
2

You most likely wrote your early experimental programs in the BASIC language, using Timex’s ROM-resident BASIC interpreter and line editor. Cassette-tape storage would have been accessed using the SAVE and LOAD commands in the interpreter’s immediate mode.

Commercial software, however, would nearly always get written in machine language — to gain the best performance and the tightest control over the system. On the Timex 2048, this would have been machine code native to the Zilog Z80 microprocessor.

* * *

A few words on the usage of audio cassettes for storage:

In many countries, the audio cassette was the most popular storage media for the non-business-oriented 8-bit home computers. That is, more popular than the floppy disk.

Don’t get me wrong: floppy disk drives were quite popular as well — among advanced hobbyists, committed gamers, and the rich kids. But for their price, they offered just too little obvious benefit to the great unwashed masses. An FDD could cost as much as the computer itself! Hence, in many markets, tape-based systems comprised of the majority of the installed base.

The UK company behind the original design of the Timex computers — Sinclair Research — were a bit of a special case in that they did not even want to offer floppy disk drives to their users: the company deliberately dragged their feet on specifying how FDDs should be interfaced to their systems and wanted to promote a proprietary storage technology called the Microdrive in their place, effectively preventing FDDs from getting common on their systems. For the Sinclair computers, tape was the primary, standard storage format “by design”.

The original Sinclair systems were very cost-reduced. Favoring tape-based storage was maybe part of this cost-reduction strategy. But they were also very popular, and Sinclair was a major player whose products inspired and incubated lots of computer programmers who would go on to write commercial software for the platform — especially in the UK.

This needed to be said as some answers suggest tape-only setups would not have been too relevant as platforms to program on, or at all. That might have been true for the US market, but the US swiftly abandoning tapes and moving to all disk-based systems was rather the exception than the global norm.

* * *

With that out of the way, some points:

Firstly, many programmers cut their teeth on tape-based setups: owning one was nothing out of the ordinary for many markets, and would not have been viewed as any great impediment by most users, but rather just the natural state of affairs; the standard baseline.

Secondly, developing a software title for an 8-bitter was often a single-man affair. There was a man and his machine, and his wacky idea for a game — say, mutant camels. What more could one want or need — besides a publisher? (A team? Hah! Get me the cheerleaders, instead.)

Thirdly, 8-bit home computers were pretty much designed on the premise of being general-purpose computers: fully capable of self-hosting their programming environments. “A man and his machine” was understood to be quite sufficient for writing all the software in the world that the machine is capable of running. There was no underlying assumption or implication of having to purchase a separate external development kit.

Many of the programmers who got commercially published were self-taught, and started out with bog-standard, entry-level hobbyist setups.

* * *

So how would you go about writing something more advanced on that tape-based system than what the BASIC language is capable of?

Many software titles were developed directly on the target system by self-taught programmers, only using very primitive tools, such as machine language monitors and pencil notes jotted in a cross-ruled notebook.

In this kind of a workflow, you carve the machine-language code directly into the RAM of the running target system by editing the content of the memory live, as in these videos:

https://www.youtube.com/watch?v=0gBoQgeg9r0

https://www.youtube.com/watch?v=MEjnMt_3wkU

You would basically view everything in the computer’s RAM as ever-malleable putty that you can work “hands-on” and keep shaping towards the shape of the program you’re envisioning.

You could copy arbitrary memory ranges (blocks of code or data) around, and directly modify the individual bytes representing the machine-language opcodes and operands.

You could also save arbitrary ranges of memory to a disk or tape, or load bytes from a file into a desired absolute memory address — this way integrating data or code created elsewhere, or saving bits and pieces for later (re)use.

If your machine-language program were to freeze, you could hit the reset button and start your machine-langauge monitor tool again and continue modifying the code — it would remain in the memory.

The finished software title would not be the product of a compiler-linker toolchain, but a dump of the relevant RAM memory ranges; basically a curated snapshot of the developer’s system RAM from the time they deemed the project was ready for release.

The saved memory dumps would maybe have to be further prepared for commercial, cassette tape-based distribution by using a simple compression algorithm, along with some chain-loader/unpacking/initialization code, and a publisher would likely want it to be equipped with a loading screen (perhaps with music) to entertain the user while they wait for the main code to load and start.

This is certainly not the most sophisticated way to work on a software project, but you’re not really working on a fancy “software project” — you’re constructing a computer program, which is something more raw and manly. Also, simple tools, such as a machine-language monitor, do not require much in the way of resources or workflow: you do not need to manage source code files, deal with editors, compilers or linkers, etc. on your limited little system. Everything is raw and direct and immediate.

* * *

What about working with other people?

Many 8-bit commercial titles (those which were not the work of a lone coder but more grandious in their design) have maybe three persons credited: the main programmer, the guy who drew the graphics, and the guy who composed the music.

There isn’t much need for constant integration if the responsibilities are this clearly divided. Meeting up occasionally or sending in your work on cassette, by mail, would be enough.

To allow e.g. the music guy to contribute to the project, the main programmer could just set aside a block of memory at an absolute address and tell them to fit their music code and data in there while informing them that the music player subroutine may only take up so much “raster time” (CPU time during single video raster refresh) in order not to interfere with the game-play mechanics, and let them work from there.

When the guy delivers their piece, you integrate it by loading the binary data blob into the designated address, and call the agreed-upon entry point into the music player routine in each raster interrupt.

Many other things could be handled in a similar fashion.

* * *

As for keeping your work safe, you would save often and keep multiple copies. And keep hand-written notes. Or print out a hard copy of your code on continuous-fold paper if you were lucky enough to own a printer. Floppy disks were known to get random bad sectors, too, so purchasing an FDD would not have saved you from such chores.

Tapes and their content can be kept organized by maintaining an index on the inlay card, or rather in a separate notebook, by using a pencil. The index would be based on the mechanical tape counter readings and file names. (Most implementations of cassette tape-based storage stored a header with a filename on the tape so you could theoretically search for a given file from the current position onward, by its name. But this could only be done at the normal playback speed, so in the normal case, you would first want to rewind or fast-forward the tape roughly to the correct position, using the manually operated, mechanical tape transport buttons and the tape counter readings as your guide.)

* * *

The above descriptions concern a scenario where you pretty much only have a standard tape-based system in your possession, with no expansions.

Would a more elaborate programming kit have helped an aspiring programmer? Certainly. But was it a necessity for commercial software development? Definitely not. Determined, clever people could do wonders using the rather simple tools and environments they had at hand. Things were maybe tedious and tricky — but they sort of always were, on these systems. You would have to figure out the best solutions for overcoming any obstacles mostly by yourself (most people would not have had access to any online community), but as they say, where there’s a will, there’s a way.

Granted, getting some expansions for your lowest-specification base system — such as a RAM expansion, or a more advanced method of mass storage — would make things more convenient.

Be that as it might, a cassette tape-based development workflow on a standard, unexpanded system would have been fully possible — even when having a couple of more guys working on some particular aspects of the game.

Ultimately, programming the 8-bit systems in machine language can be reduced to arranging the bit patterns in the RAM (or in a file) into the desired order — and you can practically always do that, even without purchasing anything extra. Almost all systems came with a built-in BASIC interpreter which readily allows such memory and file manipulation, and therefore writing your own tools. Even if you would not want to keep using BASIC itself for anything, you can bootstrap yourself to better, self-written machine-language tools using BASIC.

* * *

Overall, there was a vast range of possible tools, environments, and development styles. The answer written by Wayne Conrad covers the use of an assembler-based workflow — self-hosted on the system. Other answers mention cross-development tools. However, obtaining another, more powerful PC would have been out of the financial reach of many.

Big, established companies with actual programming teams on their payroll would do things in a much more organized manner than a lone coder, using fancier in-house tools — especially in the later years, on the most popular systems. But were most software titles actually developed that methodical way, for these machines? I’d say hell no. A man and his machine — the lone developer and possibly his cat, maybe accompanied by a GFX or SFX guy, the bossy boss, and Laura from the front desk (who also answered the phone, drew the cover art, tested the levels, and handled packing and shipping) — played a big part. Or so I would imagine.

It must be understood the overwhelming majority of the actual users of these systems were kids, teenagers, and young adults with no formal education in computer science or background in programming. These were also the people who ended up writing much of the software for them.

8-bit home computers were, for many, the first dip into the world of general-purpose computers. Previously, computers were these large multi-user systems or batch-processing behemoths owned and operated by an organization — a university or a telecommunications company, a bank, an insurance company, or your friendly tax authorities. But now you could own an itty-bitty computer yourself, as an individual, and were free to experiment with it as you please.

Not only that, but the home computers had color graphics and sound — features making them suitable for video games — or for some new kind of digital underground art, even — and features definitely not offered by the “serious” systems, because they were oh-so-serious and “all business”. (Business, as we all know, is dull and monochrome and gets by with green-screen text mode and square-wave error bleeps only.)

Personal computers — especially the cheap, colorful, TV-connectable, home-oriented ones — were a great paradigm shift in how people could access and use computers. Much of their early use, and the practices related to those uses — including the practices related to developing commercial software for them — could be labeled as being experimentative and hobbyist-amateur-driven. But that was exactly the fun of it.

* * *

Finally, to expand a bit on the tools and hardware additions, floppy disk drives were not the only way to beef up your programmer’s kit, and not even the only way to get access to a better form of mass storage than audio tape. Many systems had fancy aftermarket memory expansion and ROM tool cartridges available — providing much more RAM workspace than is available in the standard out-of-the-box configuration, and possibly including ROM-based tools — such as a machine language monitor. A programmer could use the extra memory as workspace for storing code or data snippets or memory-resident tools while working on the project which targets the unexpanded hardware.

Some of the more advanced expansion cartridges allowed much more memory to be installed on them than the CPU could address (the extra memory being accessible via memory banking) and were battery backed-up and able to retain their content for as long as the capacity of the battery allowed. They could also simulate a disk drive, in RAM disk style. This made them usable as semi-persistent, lightning-fast scratchpad for your project files or tools.

There were also aftermarket HDD controllers for the 8-bit home computer systems. The very cost-reduced Sinclair ZX81 apparently had one designed for it as early as in 1982 — something Sir Clive Sinclair himself has been quoted as characterizing as “quite overgilding the lily”. These, equipped with an actual HDD, would likely have been prohibitively expensive and viewed as very exotic special-purpose kit by the typical users of such systems, but such solutions did exist for those who had the need and could afford one.

As mentioned, commercial cross-development toolkits were available for some platforms. Another, more powerful system — such as an IBM PC or AT-compatible machine — was harnessed for editing and compiling code for the 8-bit target system. There was typically a cross-assembler running on the development system, and a proprietary data link of some sort connected to an expansion port on the target system. The latter would allow quickly uploading the compiled code to the target system’s memory space for testing. If you were very professionally-minded about software development, you could have used one of these — at the cost of obtaining another, much more expensive computer and an expensive cross-development product to run on it.


The answer provided by Wayne Conrad is an excellent read, as are the entries in the ”Linked” section and the free PDF book (It’s Behind You: the making of a computer game) mentioned by lvd.

| improve this answer | |
  • I would think that on a computer that had two cassette drives, with start/stop control for each, one could design a build/link system that would allow someone to start with a rewound tape in the destination drive, feed each source tape in sequence into the source drive, and end up with tape that could then either be directly loaded or fed to a linker that would produce a more compact tape (forward references would be accommodated by writing dummy values during code generation, and writing a list of fix-ups afterward; a linker could eliminate the need for fix-ups). – supercat Jul 6 at 17:27
  • @supercat Using two cassette-tape data recorders is an interesting idea – reminiscent of linear tape-to-tape video editing on professional VCRs. I can’t think of any 8-bit home computer system that would have supported connecting two data recorders out-of-the-box, though, although surely such interface could have been made. – Jukka Aho Jul 13 at 22:02
  • Hooking up two tape drives, one read-only and one write-only, to a Commodore VIC-20 or Commodore 64 would be a simple matter of cabling if one didn't need separate start/stop control. That could be accommodated by modifying the record-only drive so that the motor would be switched by the play/ff/rewind buttons unless record was engaged, in which case it would start and stop based upon whether the computer was outputting anything on the tape-write line. – supercat Jul 13 at 22:46
  • It's too bad the threshold of work required to hook up or even emulate two datasettes is a bit beyond what most people would be inclined to bother with in order to play with a dev environment designed for such a system. – supercat Jul 14 at 15:27
1

What about complex applications? Graphics (simple, but still) for games?

You couldn't really have that complex of a program on the small home computers that used audio tapes. For example, your Timex 2048 had 16k of RAM. Most of these programs were written in BASIC, which meant you had to store the entire program in source form, along with the interpreter. That gives you at best only 16,384 characters, which works out to about a 430 line BASIC program. I have C++ source files I'm working right now much longer than that. I don't even consider it "code smell" until a source file gets over 1000 lines.

Most programs didn't use Assember directly, due to porting issues (porting between BASICs was bad enough, TYVM). But for ones that did, a <16K binary still meant the amount of source code that went into creating it really couldn't be too much more than a single person could handle.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.