14

I'm quite unfamiliar with how operating systems used to be written but its clear to me that operating systems were clearly written for these systems. I'm particularly interested in how operating systems were written for systems like the 6502 like Apple DOS. A modern operating system's responsibilities seem to (greatly simplified) entail the following:

  1. Provide automatic switching between processes. The standard trick here is to have a clock attached to an interrupt that the OS can use to perform a context switch. This seems doable on the 6502 with the correct external hardware.

  2. Ensure not only that a process can't access other processes' memory but that a process can't access the operating system's memory. If we assume that all memory is written to disk on a context switch, it isn't so hard to isolate one process from another but it doesn't seem clear to me how the operating system protects itself on the 6502 or PDP-11. The oldest method of accomplishing this that I'm aware of is segmentation which also provides RWX permissions as well, a thing that I wouldn't even begin to expect on something like the 6502. Surely there has to be some set of privileged instructions or some mechanism to ensure that an errant process can't break the system, right? It seems it would be sufficient to ensure that there was some space in memory that could be accessed (written and executed) during an interrupt that couldn't be accessed outside of an interrupt.

  3. Manage drivers for external hardware. This seems pretty doable since interrupt tables exist.

  • 4
    As explained here, the scope for Apple DOS was a lot smaller. ; - ) – Nick Westgate Sep 19 at 2:18
  • 4
    Like many answers correctly state, contemporary OSes lacked most of these features. But check out Contiki, an operating system for memory constrained devices that also supports 6502, which supports some advanced stuff like multitasking. – cyco130 Sep 19 at 12:37
  • 1
    I cannot speak to the 6502, but as for the PDP-11 I can say that the answers here do not generally apply to it or it's operating systems (RT-11, RSX, RSTS and UNIX). Well, maybe to the 11/20 and rt-11. – RBarryYoung Sep 19 at 12:46
  • 4
    The 6502 was just a CPU, and the PDP-11 was a full-blown system with models spanning from 1970 to 1994. Thus, associating them is deeply flawed. – RonJohn Sep 19 at 14:15
  • 2
    If you are still interested in the PDP-11, I suggest you post a separate question, as all these answers are about microcomputers like the 6502. – Qsigma Sep 19 at 19:04

11 Answers 11

25

For "home" computer systems such as the Apple II, the "operating system" wasn't anything like a modern one with processes and device drivers and so on; by the standards of modern OSes there wasn't really one at all.

As a warning: all these explanations (long as they are) are for the most part considerably simplified. This answer is intended to give you the general sense of how things worked, but you should ask separate, more specific questions if you need to know the exact details.

The "BASIC" System

The most common "operating system" of late-70s/early-80s, home computers, especially starting with the "1977 trinity" of the Apple II, Commodore PET 2001, and TRS-80 Model I, was the BASIC interpreter. Here you could type in either line numbers followed by BASIC code or "direct" commands, which along with many regular BASIC commands (PRINT, LET, etc.) would usually include commands such as LOAD and SAVE. This was just as single process with full access to and control over all aspects of the hardware.

Typically the binary code (in ROM or RAM) wasn't entirely monolithic. Generally it consisted of two parts. The BIOS (Basic Input Output System) or KERNAL (if you were Commodore and couldn't spell) had low-level routines that dealt with things such as input/output and other handling of devices. The BASIC interpreter itself, most often provided by Microsoft, would handle most higher-level stuff and talk to the BIOS to interact with the hardware. The line here was pretty hazy, though, and it was quite normal for BASIC programs to directly PEEK and POKE the hardware or directly call machine-language routines to do what they wanted to get done.

The BIOS could be as simple as a few routines to check for, read and write a character from/to an attached terminal or considerably more sophisticated.

Simple Example: Altair

One of the simplest examples of a BIOS was the 1975 Altair 680 PROM Monitor. This provided POLCAT (check for character available), INCH (read character) and OUTCH (print character) routines used by both itself and BASIC, and a few simple commands for examining and depositing values to memory, loading memory from a paper tape, and jumping to a memory location to start a program, all in 256 bytes. This would be used to load Altair BASIC (which expected POLCAT, INCH and OUTCH to be at specific addresses in memory) from paper tape and start it, at which point that would be doing everything you could do. (If it had LOAD and SAVE commands, those would have been built directly into the BASIC binary. But if you weren't so lucky to have a cassette tape interface and a BASIC that knew how to use it, you would "save" your program merely by typing LIST, turning on the paper tape punch on your Teletype, and hitting Return.)

If you didn't have any ROM at all in your system, even the INCH etc. routines would have been "baked in" to the BASIC itself, and you'd toggle in a small routine to load the tape and run it, as demonstrated in this Altair 8800 video.

Sophisticated Example: Commodore

At the other extreme, Commodore from the start had split their software into two parts. The "KERNAL", usually in its own 8K ROM, was a fairly sophisticated I/O core that handled regular keyboard scanning via interrupts, had a longish list of routines to do I/O, and even had a concept of device-independent I/O. For example, you could open/setup devices 1 (cassette), 3 (screen), 4 (printer) and 8 (diskette drive), assigning them file numbers of your choice, and use the same CHROUT routine with all of them, passing it the file number. CHROUT would, based on the file number, find the correct device and use the correct "device driver" for each of these.

Commodore's version of Microsoft BASIC, in its own 8K ROM, was then built on top of this and the BASIC LOAD OPEN, PRINT etc. commands let you specify the device numbers or logical file numbers assigned with OPEN to do I/O to various devices via the KERNAL.

"Had to Hack It" Example: Apple II

The Apple II did have a logical split between the "monitor ROM" and the BASIC ROM, but it wasn't as well planned out as the Commodore version and, in particular, it didn't start with much support for devices beyond the keyboard, screen and cassette. The system design did provide for code in ROM on each card intended to handle input and output, callable with the BASIC INPUT and PRINT statements, but this was fairly limited. So when DOS came along it had to wedge itself between the BASIC and the BIOS without any real coöperation from either.

It did this by having a "print" routine in ROM to start the bootstrap process (thus the famous PR#6 to boot a disk). This would load in DOS from disk and run its initialization routine, which in turn would replace some vectors that let it intercept keyboard input and screen output. So after booting, when you typed a command at the BASIC prompt it would first be checked by DOS to see if it was a DOS command. If it was one, like CATALOG, DOS would execute it, print the output and return you to the prompt. If not, the input line would be passed on to BASIC which would execute your LIST command or whatever you gave it.

While this worked for interactive commands, BASIC had no facilities for calling DOS. So DOS hooked into the screen output routines as well and you'd use an escape character, Ctrl-D at the start of an output line, to inform DOS that it should treat output as a command. Thus, to print a list of the files on the disk from BASIC you'd use something like

100 PRINT CHR$(4);"CATALOG"

If you wanted to read or write a file, this would have to be done by changing the source or destination of the standard input and output routines via a sequence of commands like the one above. This of course meant that you couldn't get input from the user or print to the screen while you had a file open for input or output.

Other Operating Systems

There were other systems not oriented around BASIC (and not used so much on "home" computers) that are much closer to what you'd think of as a "real OS" today. The most famous of these is CP/M, but there was also North Star DOS and a few others. These provided a a core set of "system calls" to do disk and terminal I/O and a few programs that ran on top of them, such as a command-line interpreter, a program to copy files, and so on. These would be used to launch your applications (word processor, editor, assembler, the assembly-language program you'd written) in a way much like you do today when using a command-line interface. But once running, they were still a single process with no real separation (other than what the programmer desired) between the application code and the OS code, or even the hardware.

In 1979 Microware introduced OS-9 on the Motorola 6809, which did support multiple processes (using co-operative multitasking) and many other modern features. But for various reasons (high pricing as mentioned by RichF below, using a less popular—in the U.S., anyway—processor), it started out as a niche product. Though these problems were addressed (including a port to the very popular 68000) it never really overcame this, probably because by the time these problems were finally getting worked out we were on significantly larger machines and could get something even closer to a "real" Unix, such as Coherent or maybe even Xenix.

  • 4
    OS-9 had a lot going for it, but my company back then would not use it. There was an annual fee to use its development environment. There was an additional fee for each end-user system sold (but end-users need not pay the annual fee). IIRC, the fees were in the thousands of dollars. Microware likely changed its policies eventually. I understand why they needed the fees (low volume, high, on-going development cost), but the fees did limit their customer base. Since there were one-time upfront cost environtments, my company worked with those instead. – RichF Sep 19 at 13:18
  • I recall that the ROM in the Commodore 64 could be swapped out of addressable memory space so the entire 64k of RAM could be used. There were a number of use cases in games. – Peter Smith Sep 19 at 14:19
  • @PeterSmith Indeed it could! I just happened to be researching this over the last couple of days, but it's a conversation probably best continued in chat. – Curt J. Sampson Sep 20 at 5:00
  • @PeterSmith Well, the Hardware could be made to swap the ROMs. But there was no OS support to do so. At least not until BASIC 3.5, which never officially made it to the C64 (but there was Business BASIC, a third party development to do so) – Raffzahn Sep 20 at 13:52
  • @CurtJ.Sampson Well, for one, the PR# isn't a print command, but a call to a device for (optional) redirection. More important, DOS was programmed offering plenty calls to allow quite clean file handling. When Paul Laughton delivered DOS to apple, they (aka Mr. Jobs) wanted a simple interface for BASIC, nothing else, so the D$ hack was created as an afterthought, much against the intention of Mr. Laughton. Internally these interfaces were kept and used by many programs. With ProDOS Apple finally reconsidered and did split functionality between DOS and BASIC interface. – Raffzahn Sep 20 at 14:01
33

The simple answer is that early operating systems for the systems you mention did not provide those features.

Apple DOS, for example, makes no use of interrupts, and has no concept of processes or memory protection. Nor does DOS have any concept of hardware drivers, as it includes support to drive the Disk II (a deep assumption in DOS) and nothing else. Apple DOS doesn't even have a proper shell, instead hooking into BASIC to intercept commands. Ultimately, Apple DOS is little more than some subroutines for disk IO.

ProDOS is a bit more sophisticated, with the concept of device drivers to provide a general interface to block and character devices. Still no processes, protection, or shell though.

This is typical of most early 8-bit systems including those beyond the Apple II. For example, CP/M 2.2 is quite similar. While CP/M had some features like a separate shell, beyond that it really only provides some utilities and disk and console IO.

  • 2
    Quite. Early home computers were single user, single thing-at-a-time systems. Part of what made the Amiga "bouncing ball" demo so mind-blowing to people in 1985 was that it was doing it in a window while other things were going on in the computer. The Amiga of course used an M68000. – T.E.D. Sep 20 at 14:00
17

We talk about the late 1970s and mainstream 6502 machines, right?

It wasn't so much that programs run under OS control as that OS was a support function to Programs. More like what we would today see as a standard library with routines supporting simple I/O abstraction plus basic file handling on the user side and hard coded drivers within. Some, like Apple DOS provided only the file handling part. Features like memory management were rare. Memory protection ot loadable drivers were basically unheard of due missing hardware support and more important, missing RAM size.

This is true for next to all OS including PC-DOS - which can be seen as one of the most advanced offspring, as it did offer some of the features you mentioned.


1) Provide automatic switching between processes.

There are no processes in these old system. They are single user, single task, single program.

2) Ensure not only that a process can't access other processes memory but that a process can't access the operating system's memory.

There was no memory protection. Not even between OS and user

If we assume that all memory is written to disk on context switch

Again, No context switch - there wasn't anything to switch. Not to mention that an Apple II had 64 or more KiB of memory, while the Disk II offered 143 KiB of storage - not much room to swap out a process anyway.

Surely there has to be some set of privileged instructions or some mechanism to ensure that an errant process can't break the system, right?

Nope. Again, no processes, no support for such and no need as well.

3) Manage drivers for external hardware.

Nop. There were no manageable drivers. Drivers were hard build into the OS/BIOS. o way to add such or alike.

This seems pretty doable since interrupt tables exist.

Well, they didn't. At least not as easy. The 6502 had only one interrupt, and if all, it had to be chained. The Apple II had no provision for cooperative interrupt support. While some standard evolved later on, it was always more of a hack than a solution. Similar for other 6502 Systems.

While there were very few more advanced systems, What you have in mind are solutions for problems that didn't exist back then on most of systems.

Later OS (like ProDOS) added some of the rudimentary features like mentioned (basic Memory management interrupt handling, even basic driver detection), but still stayed true to the original one man, one machine, one program dogma

  • 3
    Technically, the 6502 has four interrupts: NMI, IRQ, RESET, and BRK. The latter is a software interrupt rather than a hardware signal, and uses the IRQ vector. Since NMI is difficult to use reliably, and RESET is a rare event, the IRQ vector does get a lot of stuff heaped upon it. – Chromatix Sep 19 at 3:32
  • @Chromatix: From what I understand, BRK is even harder to use reliably in the presence of IRQ, since the B flag doesn't actually indicate whether a BRK instruction was executed, but instead indicates whether an IRQ was received. – supercat Sep 24 at 20:30
  • Which just means you need to invert the test. You can treat BRK as a one-byte equivalent to JSR BrkEntry : PHP : SEI : JMP ($FFFE), as both versions would push the same status byte on the stack. With that said, the 65816 added separate BRK and COP entry points from IRQ and NMI, as long as you were running in native mode. – Chromatix Sep 25 at 0:15
12

The typical circa-1980 8-bit CPU provided almost no support for modern operating system features. It was often possible to add such support using external logic, but very few machines actually did so because it would have added costs to the hardware with little practical benefit. Even many minicomputers of the time left those features out, at least in the cheaper models.

It was considered a major advance, for example, when the 68030 and the i80386 arrived with built-in MMUs in the mid-1980s. The MMU is what enabled memory paging and protection, a central feature in any modern OS. Prior to that, the nearest equivalent was the 65551 which was an external MMU for the 68020. Even then, it was many years before home-computer operating systems actually made good use of those features, as they had been designed around not having them, and there were still many older computers which had to be supported.

You may, however, be interested in the BBC Micro and its MOS operating system. The BBC Micro's hardware is not particularly special, but it does have a built-in mechanism to map any of 16 ROMs onto the $8000-$BFFF segment, and with a common hardware mod, it was also possible to put paged RAM there. This was the basis for providing floppy-disk and network support as loadable drivers, as well as alternative languages and applications. The BBC Master embraced this mechanism even further.

It was also possible to extend the BBC Micro with a primitive user/system distinction, in the form of the Second Processor module. This was actually a complete extra 6502 CPU and 64KB RAM set which communicated with the "host" machine over a ribbon cable called the "Tube". Application code would then run on the external CPU (which was faster and had much more usable RAM available) while the BBC Micro itself took care of such drudgery as keyboard, display, and disk handling.

This was possible because not only did MOS have something resembling a coherent system-call API, but those calls were automatically sent over the Tube by the Second Processor's firmware to be processed. But there was very little hardware support involved.

  • Indeed. And as for interrupts, the Beeb used them extensively. Non-maskable interrupts were only for disk and network handling; but maskable ones were used for things like sending/receiving characters across the serial interface, recognising keypresses and light-pen strobes, updating clock values, and updating flashing colours during vertical flyback. You could add your own handlers (by chaining) too; I remember using them for implementing much larger sound buffers, and for timing sprite redraws to start just after their last line had been displayed. Just not for process switching! – gidds Sep 19 at 11:05
  • As another example, Apple went the other way. The absurdly-priced Lisa had an MMU. The less-absurdly-priced Macintosh ejected the MMU, amongst its dozens of cost reductions. And Apple paid for that decision for the next 17 years. – Tommy Sep 19 at 12:14
  • The MMU (and the large memory for its time) were among the things that pushed the Lisa's price up. By cutting it back to make the Macintosh, Apple made a computer affordable enough to succeed. But they did have to redesign the OS to fit the smaller machine. – Chromatix Sep 20 at 5:03
10

Contemporary operating systems for the 6502 did not have those features. But not because they couldn't. It just wasn't considered necessary or desirable.

Provide automatic switching between processes. The standard trick here is to have a clock attached to an interrupt that the OS can use to perform a context switch. This seems doable on the 6502 with the correct external hardware.

Yes, this is quite easy to do. But with limited RAM and no GUI, pre-emptive multitasking isn't much use.

Ensure not only that a process can't access other processe's memory but that a process can't access the operating system's memory.

Memory protection could be achieved using an external MMU, which in a simple implementation could just be bank switching. But why have it? So long as programs behave there's no reason not to let them access all the memory, and good reasons to allow it.

If we assume that all memory is written to disk on context switch it isn't so hard to isolate one process from another...

Using floppy disks? Only if you don't mind slowing down to a crawl...

but it doesn't seem clear to me how the operating system protects itself on the 6502

It doesn't. However if the OS code is stored in ROM it only takes a second to reboot if the RAM gets corrupted.

Surely there has to be some set of privileged instructions or some mechanism to ensure that an errant process can't break the system, right?

Why? Much easier (and more efficient) to just ensure that errant processes don't exist in the first place.

It seems it would be sufficent to ensure that there was some space in memory that could be accessed (written and executed) during an interrupt that couldn't be accessed outside of an interrupt.

Perhaps. But when you have a slow CPU, limited RAM, low resolution screen etc. it makes more sense to just let the current 'process' access everything.

Many features of modern operating systems that we consider 'essential' today are only relevant to modern hardware and applications. Security was a non-issue when you didn't have the Internet and the computer was truly 'personal'. When the machine could barely run one process at an acceptable speed, you didn't want to load it up with multiple tasks running at the same time. You certainly didn't want virtual memory when the disk drive had access times in the seconds range, and if you just wanted to play games...

  • 2
    floppy disks? We only had tape drives. Ten minutes per task switch... – Stig Hemmer Sep 20 at 7:25
3

I have done this with an 8051, (8 bit running about same speed as 6502) with a 4 task scheduler, driven by interrupts, task switching at about 10Hz.
Reading position from NMEA on a GPS, sending and receiving GSM SMS messages, logging data to flash.

No memory protection at all. Running in something like 1k RAM and 32k of ROM.

Used a combination of preeemptive and cooperative multitasking to allow more than 4 tasks in total while only ever having 4 live tasks.

2

it doesn't seem clear to me how the operating system protects itself on the 6502 or PDP-11.

With respect to the PDP-11: it's pretty conventional. In general, there are at least 2 execution modes (kernel, user; some models add a third, supervisor); certain instructions are legal in kernel mode only; there is a memory management unit that controls virtual to physical mapping on a page basis (4KW/page, therefore 8 pages) with separate maps for the different processor modes. That's all you need to isolate tasks from each other and from the kernel. Each task gets its own memory map; context switches require reloading the user-mode map.

For the older, smaller models the MMU hardware that gives all this is 'optional'. As soon as you get to the point where a 28KW system (note1) is too small, then you're going to need the MMU anyway. And it's generally not an optional option on larger systems.

The original PDP-11, the 11/20, did not have a standard MMU, though DEC's Computer Special Systems (note2) division could supposedly fit you up with one by special order (KT11-B). The smaller and cheaper PDP-11/10 had no standard MMU, and AFAIK nothing from CSS either.

The replacement for the 11/20, the 11/40, had an optional KT11-D MMU. The 'fast' machine, the 11/45, had an optional KT11-C MMU. Here, optional means required if you want more than 28KW of core.

In case anyone is wondering, I don't know whether there was ever a KT11-A.


Note1: 16 bit address space = 64K byte, 32 K words. Top 4K words of physical address space is the I/O page, so that leaves 28 K words for memory.

Note2: CSS was separate from central engineering; they built hardware either for specific customer requests, or because they saw a need that central engineering was not addressing.

2

The specific details of what a 6502 Apple II was doing when it was sitting at the BASIC command prompt or Monitor command prompt is this:

  • Periodically check for a keyboard key press to be detected at address $C000
  • If no input, it runs a delay routine to display a blinking white box or a square checkerboard (later enhanced IIe ROM) as a cursor at the current screen position.

And that is all. Nothing else is going on. The 6502 processor is frantically spinning away at a constant 1 million cycles per second to... blink the cursor and read the keyboard input.

,

The system Monitor ROM and BASIC ROM were designed to be extremely memory efficient, because the very first of the Apple II series could be sold with as little as 4 kilobytes of memory installed. For such a tiny amount, nearly half of it is reserved for use by the system:

  • $0000-$00FF - 256 bytes - Zero page for 1-byte CPU memory instructions
  • $0100-$01FF - 256 bytes - CPU Stack
  • $0200-$02FF - 256 bytes - Keyboard input buffer
  • $03D0-$03FF - 24 bytes - Interrupt vector, soft vector table
  • $0400-$07FF - 1024 bytes - 40x24 text page 1

Which left just 2048 bytes free for an actual BASIC program, and still less than that if the BASIC program needed number or string variables, as those had to fit into that same available 2048 byte region of memory. (Hi-res graphics are impossible with 4k, need at least 4k + 8k addressed to hi-res page 1 bank, skipping over the 4k from $1000-1FFF.)

If the programmer knew how to write 6502 assembly, they could tuck a tiny set of custom 6502 subroutines into the 208 byte gap at $0300-$03CF such as to play sound.

,

The 6502 Apple II boot process was equally just as simple. There is a small amount of ROM for each interface card, but what is there is absolutely tiny.

Each slot only had a permanent 256 bytes of ROM reserved to it, from $C100-C1FF for slot 1 to $C700-C7FF for slot 7. There was a way to activate an additional 2k of ROM for each slot, but each slot had to share the same 2 kilobytes from $C800-CFFF, and two of these extended ROM spaces could not be active at the same time.

During the Apple II boot, all that happens is that the Monitor ROM tries to locate some signature bytes to identify the location of the Disk II interface, scanning in reverse from slot 7 to slot 1, and then runs the boot ROM on the first Disk II interface it finds.

The boot ROM is only capable of selecting drive 1, turning on the spindle motor, moving the drive head to track zero, and then sitting there looking for the sync bytes for sector zero of track zero.

If it succeeds, the boot ROM reads sector zero into memory and then runs whatever code it found there. If the boot ROM can't find sector zero, it will keep trying, and spins the drive motor forever.

Actually booting the early DOS 3.2 (13-sector) / DOS 3.3 (16-sector) involved a similar set of tiny steps, one after the other. Sector zero contains just enough code in 256 bytes, to tell the drive to re-read sector zero and then also read sector one. The combined two sectors have enough code to tell the drive how to read all the sectors in track zero, and run that code. The combined sectors of track zero are now finally large and complex enough to read in the rest of DOS in tracks 1 and 2.

With DOS now running, it tries to find a startup program on the disk, and run it. If no such program is found, it returns control to the BASIC/Monitor prompt, but with "hooks" active to check for typed DOS commands before BASIC commands.

,

And that's all that is happening, there are no background tasks running, no task manager. Two different programs can't run at the same time. It was all very simple back in the early days.

0

These computers were meant to be usable without a disk drive (which was sold separately and often cost as much as the computer did). DOS stood strictly for Disk Operating System and was just a way for the CPU to communicate with a disk drive. It wasn't an operating system in today's terms, which didn't come about until Mac OS and Windows took over in the late '80s.

0

I can't speak to the PDP-11, but the earlier PDP-10 was a computer built for timesharing. Memory protection was built into the processor. Every user mode memory reference went through a translation process controlled by two protection and relocation registers that in turn were controlled by the operating system.

This memory system allowed the operating system to protect both other programs and itself from rogue programs.

Later models of the PDP-10 featured a page map which allowed a more sophisticated translation scheme. This more sophisticated scheme would allow for virtual memory as well as separate user spaces.

The earliest microprocessors lacked these facilities, and a rogue program could indeed bring down the system, or carry out misdeeds by manipulating memory not allocated to that process. Other answers speak to the facilities on a 6502.

0

I wrote some fairly deep systems code for the BBC Micro, a popular 6502 based machine. The OS for that machine struck me at the time as a lot more systematic than most of its 8 bit peers, in the sense of being well organised and a well thought out overarching design, but that was just my impression, it could be wrong.

Ensure not only that a process can't access other processes' memory but that a process can't access the operating system's memory

The 6502 didn't support privilege levels. It supported a simple hierarchy of interrupts (IRQ which could be temporarily set as ignorable during sensitive operations, NMI - Non Maskable Interrupts - which couldn't be ignored), and it had additional circuitry that allowed one of several 16KB ROMs to be paged in as alternatives, but that was all.

Software was simply trusted to use the machine while running. There was no equivalent of protected pages, or R^X, or user vs. system, except informally - the manual directed programmers what memory areas were used for what, and beyond that, programmers were trusted to write code that worked. Usually it did. As one example, when a program had loaded from tape or disk, the storage buffer used by that device wouldn't be needed by the OS and the program could assume it was usable space, if memory was tight.

Provide automatic switching between processes

There wasn't multitasking as such. Any multitasking was limited to system interrupt handling, and anything implemented in the software that the user was running. What happened instead was, events such as keyboard presses, data available from storage devices, or video scan refreshes, gave rise to interrupts. The interrupt would process the event, and return control to whatever had been running previously - usually the user's software.

Surely there has to be some set of privileged instructions or some mechanism to ensure that an errant process can't break the system, right?

Wrong. Surprisingly, by today's standards, software was generally "worked reliably on release". The internet didn't exist for downloads, and you didn't take your tape/ROM chip/disk/cartridge back to the store to upgrade Game v1.2 to Game v1.2.1 for bugfixes. The OS released with the BBC was the OS you kept. And it was reliable. Games and software you bought, were reliable, too, for the most part.

Because the systems weren't multitasking, basically whatever you were running got the whole machine to play with. So the consequences of an errant process were simply that your machine stopped working. If it happened enough, you just didn't use that software, or avoided the part with the bug in it. Your data for other programs was typically on different disks or tapes, and unaffected. Restarting the OS was a simple key press and 0.2 second delay (it was all in ROM and almost nothing to set up) and you often used that to exit programs too.

So the point being, there was actually not much of a problem from errant software. Software was usually reliable, and where it wasn't, you learned to avoid the issue or ditched it. But either way bugs and erroneous processing had very little potential to do harm. After all, your system was ROM based, so it wasn't like it could overwrite or modify any of it. Restarting the OS always got you back to a clean starting point anyway.

Manage drivers for external hardware

Drivers as we have them now, didn't exist. Hardware control came in 3 ways:

  • some was baked into the OS: tape, keyboard, audio.

  • some hardware was standardised and different ROMs could be bought to manage them: Acorn and Watford Electronics were both popular ROMs for handling a typical disk drive. You wanted a disk, you got the ROM chip, and plugged it into the motherboard.

  • in some cases, software authors also wrote their own hardware handlers. This was often done as a form of early copyright protection. The disk, tape or ROM couldn't be copied by usual processes, because it wasn't written using standard methods. A disk containing a game, might have a custom driver that stored 13 sectors per track, or scrambled the sectors, or manually controlled the servo motor to access data on half-track physical locations. This was pretty common on the Apple II as well as the BBC Micro.

As above, these usually worked first time, and updates weren't needed.

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.