The Atlas Interrupt Mechanism, illustrated with Paper Tape Input

Note that this description has not been exhaustively researched. It is consistent with the paper "The Atlas Supervisor" by T. Kilburn, R.B. Payne and D.J. Howarth, written in 1961 (i.e. a year before the Atlas was operational), and my Atlas Programming Manual of 1965. Material where I am less sure of the accuracy is indicated by the italicised phrases "In principle" (applying to the end of the paragraph) or "say" (applying to the following quantity or phrase). -- Brian Napper

The Atlas Computer

Atlas had a "one-level", or "virtual", store. It was organised in "pages" of 1024 24-bit words, where a 24-bit word could be an integer or 4 6-bit characters, and two successive words starting on an even address could be a 48-bit instruction or floating-point number. From the user's point of view, there was a virtual address space of 220 48-bit words. Any particular page of this space that had been referenced so far in a program run could exist anywhere in immediate access ("core") store, i.e. RAM, or drum store (and later disc), i.e. fast random-access magnetic store, or on magnetic tape, i.e. slow serial magnetic store. It could migrate around the different media as the program was obeyed, under the control of the Supervisor (i.e. the operating system), so long as each time it was actually being referenced it was physically somewhere in core store. (The unit of transfer to and from the magnetic stores was a page.)

Atlas had one 96-bit double-length floating-point accumulator, and 128 "B-lines" -- 24-bit integer accumulators used for integer arithmetic as well as the classical address modification. The order code was one-address with double-modification for accumulator orders, and two-address with single-modification for B-line orders. The address field was 24 bits, so it covered the full virtual address space.

Program Control Layers

There were three layers of program control, each with its own control register: Main Control (B127), Extracode Control (B126) and Interrupt Control (B125). Main Control was used by user programs and the higher level routines/subprograms of the Supervisor. Extracode Control was used for the key routines of the Supervisor plus the nearly 300 "Extracodes" on Atlas, i.e. function codes of the instruction set that were implemented by subroutines -- in contrast to the 100 or so codes implemented directly by hardware. Extracodes were available for example to provide trigonometric functions and character-handling operations directly in the order code, and to program the wide range of peripheral operations. Interrupt Control was used by a small set of fast routines that handled situations requiring immediate real-time attention, like peripheral operations and error situations.

The Stores

The Extracode and Interrupt routines were stored in a special ROM, the "Fixed" store, separate from the main core store RAM. In addition they had a special area of RAM store as working space, the "Auxiliary Store", and a set of the B-lines reserved. There was also a "V-store" consisting of a collection of bits and longer strings associated with e.g. peripheral equipment. The Fixed, Auxiliary and V-store stores had fixed addresses outside the virtual address space generally available to the user (i.e. negative addresses, read-only for the user). There was of course a comprehensive system of store lockout that ensured that no process (in particular no user process) could access store that it was not entitled to.
Configuration of the Manchester Atlas
Internal Store      Peripheral Equipment (say)
RAM core store 32 pages 8 magnetic tape decks
ROM Fixed store 16 pages 4 paper tape readers
RAM Auxiliary Store2 pages 4 paper tape punches
Magnetic drum store192 pages 1 card reader
Virtual Store (approx.)2,048 pages 1 card punch
Disc (1967)32,000 pages 2 teleprinters
1 line printer

Pseudo-parallel Process Control

At any one time there could be any number of processes active in the system. There was only ever one interrupt active, and if so it would also be in control, i.e. actually running, using B125. There could be any number of Extracode processes (or routines) active, one actually in control (using B126) and the rest in a priority queue, suspended but ready to run when given the chance, or suspended but awaiting an event before they could continue. A process "in control" here means that the address in B126 refers to its current instruction, but it may not be actually being obeyed because Interrupt Control is running. Similarly there could be any number of prioritised Main processes, one in control of Main Control (B127), and any number suspended-and-ready or suspended-and-waiting. The one in control might be actually running, or waiting for Interrupt Control and/or Extracode control to finish before resuming.

Nothing (not even another interrupt) could interrupt Interrupt Control. Extracode Control could be interrupted by Interrupt Control, but not another Extracode Control. All Extracode processes active and able to run would be cleared before control was returned to Main Control. Main Control could of course be interrupted by either Interrupt or Extracode Control. A Main process could not be interrupted by another Main process directly, but it could happen indirectly, where an Interrupt routine had just fielded a flag signalling an event that a higher priority suspended Main process was waiting for.

Obviously the switching of control between processes was organised by the Supervisor (usually running in Interrupt or Extracode control). The key point is that, with the Control layering, and with special stores and dedicated control registers, switching between processes was kept to a time related to the urgency. It cost nothing to switch between layers, and therefore in particular it cost nothing to switch in and out of the Interrupt layer. The average instruction time at the level of Supervisor operations (mostly B-line instructions and using fast stores), was say between 1.5 and 2 microseconds. The switching time between Extracode routines was say around 60 µsecs. Switching between Main processes (certainly between user processes) required copying out accumulator and relevant B-lines, plus status information, into core store, and then restoring the corresponding information for the incoming process. This would cost of the order of say 1,200 µsecs.

Processing Interrupts

Each part of the machine that would require instantaneous attention would have an interrupt bit that it could set in the V-store. This included error situations and peripheral handling. In principle, at the beginning of each instruction, except under Interrupt Control, the hardware would poll the interrupt bits in a standard order (reflecting priority), and for the first one it found set (if any) it would pass control to the corresponding Interrupt routine. Once the routine was finished, it would recheck the interrupt bits. When there were no interrupt bits set it would check if there was an Extracode process in Control. If not, but there was a queue, it would invoke a (Interrupt or Extracode?) routine to give control to the highest priority Extracode process. If no Extracode process was in control or queued (a hardware check), but a Main process was in control, it would pass control to Main control. If no Main process was in control but there were processes suspended-and-ready, it would pass control to an extracode to bring in a new Main process.

The interrupt routines were kept very short, and arranged in a priority sequence that ensured that the required interrupt routine would always be obeyed before the next interrupt could occur from the same source, whatever the source.

Note that a drum or tape transfer to or from a page in core store was carried out "autonomously", i.e. there would be a hardware transfer operation of all 512 48-bit words which took place independent of the rest of the machine operation. (The core page would be locked to prevent access from any running process while the transfer was taking place.) Otherwise there would have needed to be an interrupt for each word every (around) 4 µsec (for drum) or 100 µsec (for tape), and the standard interrupt mechansim would certainly not have worked for the drum situation, as there would only have been time to obey two instructions before the next word was due.

Reading an Input File 'Offline'

So now we can see what happens with a paper tape input file. The file would be read in to the system at the convenience of the (human) operators, at some arbitrary time before the program(s) requiring it was actually executed. At the start of the tape (without going into detail) the Supervisor would have combined low level actions to read characters with high level actions to process the header information, e.g. to open a new file in the one-level store to accommodate the information, and to do the administration to remember what user it belongs to. It would then open a page in core store (which it hoped would remain there!) to take the first (in general the current) page of the file. Each particular paper tape reader also had its own (smaller) private buffer area in the Supervisor's working store. The completed input file would in general eventually be stored on a special Supervisor magnetic tape, the "Input Well".

Now when the next set of holes comes under the reader, the peripheral hardware will copy the 5 or 7 bits into its V-store buffer and set its V-store interrupt bit. At 300 chars/sec there is now about 3,300 µsec before the next character is due. Either immediately, or fairly quickly, its interrupt routine will be entered. The minimum action is to apply the tape 5/7-bit code to a look-up table to do any conversions required and check for control characters, e.g. the end of the file; for 7-hole tape there is also a parity check. (Atlas used a specific 64 character code for internal representation of characters, that was independent of the input/output media it might be associated with; in fact double the number of characters were catered for, using special "shift/case" codes to specify which of two sets of characters the following characters belonged to.) The interrupt routine will then copy the resulting 6-bit code to the next character position in the reader's private buffer. This will all take say a dozen instructions, say 20 µsec. However if the checks show that the private buffer is full, or the file is finished, it will call the appropriate Supervisor routine into the Extracode queue (if buffer full) or Main queue (if file finished), with appropriate priority. This will then carry out the longer procedure required to deal with these situations. In principle the private-buffer-full situation will be fairly quick if the file's current page still has room; otherwise it is probably a Main store routine that will be used to append the page to the input file, and set up the next page for the file. In general it would be expected that the system is ready to receive the next character when it is due to arrive (e.g. by making sure there is always space to receive the next character); if it still hasn't dealt with the preceding character, then the reader is stopped, and restarted when there is room to deal with it.

In this way the whole paper tape file is read, without the tape stopping (unless the machine is very busy), and with no effect on the running of the computer except for a small degradation in speed of say around 1%, i.e. 30 µsec per 3,300 µsec (basic 20 µs, plus periodic longer bursts to flush buffers, averaging 10 µs per character). A short hesitation might be discernable every 4096 characters, i.e. after a completed page of characters.

Note that e.g. card equipment and the line printer used longer V-store buffers than the paper tape, e.g. a row/column/line wide; so the time between successive flushes of the V-store buffer might be so long that the appropriate Interrupt routine might do little more than hand straight over to an Extracode routine.

Reading the Input File from a Running Program

When the file was fully read in, in general onto the Input Well magnetic tape, it would stay in the machine until such time as a program using it was started. When the program was started, the file would be logically attached to the program, i.e. given a stream number as directed by the JOB control file, and (the first page at least) moved to a more immediate level of store. The program handled the file as if it had a virtual input stream on-line. There was an appropriate extracode instruction to set (or reset) the current stream number and another to read the next character from the current stream. From the programmer's point of view, these were just the same as basic instructions, and had instantaneous effect. In practice, if there was no current extracode or interrupt routine in operation, it would take very few instructions to enter the Extracode routine and extract the next character from the current page of the stream, say 30 µsec. But of course it could take an indefinite time in real time, for example if there was other interrupt and extracode activity current, or if the next character started a new page in the file store and the new page was not yet in core store, or indeed if the current page had been thrown out of core store since the last read operation on it. And of course at any time the user's program could be suspended (and maybe all its program, data and I/O pages in use thrown out of core store) to give way to another Main process with higher priority that had been awaiting an event (e.g. a magnetic tape positioning request completed); this would have been given Main control as a result of the Interrupt/Extracode routines handling the event.

Copyright The University of Manchester 1998, 1999, 2000