This info is from personal memory, and for the most part is not in books in my possession (SRLM, Programming Manual). Where I have doubts about the accuracy, this doubt is indicated. You may find it helpful to open the order-code listing in another window/tab.
The programmer sees two push-down stores, each with 16 cells, which are implemented so as to give register-speed access. Arithmetic takes place on the upper cells (known as N1, N2, etc), e.g. the + instruction adds the values in N1 and N2 leaving the result in N1. The contents of N3 are moved into N2, N4 into N3, and so on. Any attempt to remove information that it not there (e.g. ding + with only one cell occupied) causes a program interrupt, and is treated as a failure by director. What happens next depends entirely on what the director does. The EE directors output a verbose console message and a query offering a restart at word 4, or program termination. The Eldon2 director had a facility for a program to request that in the event of any failure a word 4 restart would occur without any operator intervention or awareness.
In a multiprogramming KDF9, there were facilites for multiprogramming between four programs, including four nesting stores, four SJNSs and four sets of Q-stores.
In order to see how the machine operated it is best first to take the view as seen by director, and then the program-mode view becomes clear.
There are four core store stacks, each with 16 cells. Which one is used depends on the two bit register that specifies which set is used (I cannot remember where it is exactly, but it is part of the =K3 instruction -- which almost certainly explains why =K instructions do not nest up).
When something new is put in the nest, the contents of W3 are pushed into into the appropriate stack, the contents of W2 go into W3, and the contents of W1 go into W2. W1 takes the new data.
If you look at the code in P0 of director just after label 30:
http://sw.ccs.bcs.org/KDF9/EDNTSD990.htm
you will see that after obeying =K3 to swap the nest, there are three cells removed (and one from
SJNS which has a single flip-flop register) before obeying EXITD.
This has the effect of taking the program’s info from its own core
stack and sliding it up into W1-3 ready for the program to use.
Director programming involves taking great care not to use more than 3 cells before deciding to borrow the programmer’s nest and SJNS by calling P1 to dump them to memory. Notice that there is a second loop of ERASEs to flush out any data that might have got put there while doing a FAIL 00N. Presumably data was written in with an or process and read out destructively.
The other place to look is P29 which gives director access to the program’s nest. At this stage, the nest of the interrupted program is in the V-stores of P1, but the other three nests have to be acesses by use of the =K3 instruction. Judging by the slightly puerile style of the comment at the head pf P29, I made extensive modifications to EE’s original.
In the early days, the practice was to use mnemonics which indicated the type of device in the first letter, e.g. PREQ7 for a paper tape read to end-message using the parameters in Q7, or MFRQQ7 for a mag-tape forward read, or MBRQQ7 for a mag-tape backward read. Some time around 1965 EE seems to have got fed up of putting in new mnemonics for new types of peripheral like disk drives, and introduced new “mnemonics”, all begining with PI for peripheral input, PO for peripheral output and PM for peripheral manipulation/messing-about. So far so good, but the third letter was then just chosen in some sort of order (perhaps numerical order). The fourth letter was always Q. PIAQ5 (124,120) does a read on anything, mag-tape, paper tape, disk drive. The older mnemonics PRQ5, MFRQ5 (the ones in my book) both assembled to the same machine code as PIAQ5.
PIAQq | 124 | 20q |
read forwards (no special treatment of end-message) e.g. MFRQq, PRQq
read data from the moving head area of the disc |
PIBQq | 125 | 20q | read forwards (upto and including end-message) e.g. MFREQq, PREQq |
PICQq | reads fixed head on disk, may be same as MBREQq | ||
PMAQq | 134? | 20q? | set head position of a moving head on the disc |
PMAQq | 134 | 20q |
forward skip mag tape Set seek address on disk - the address is in the upper bits of Cq The seek actually happens when the data transfer is initiated |
PMBQq | 120 | 20q + 10 | test beginning of mag tape |
PMEQq | 136 | 20q + 10 | rewind mag tape or backskip??? |
It would appear that there was a convention of not putting in enough comments. I plan to add in lots of commentary marked to show that it is a later addition.
Immediately after loading director is entered at word 4, i.e. P200. This part of the code is free to use any registers and finishes by jumping into the tail end of the main director path which is entered on interrupt via word 0.
There is a short path in which the choice of next program to run can be made very quickly. This occurs for peripheral termination and lock-out violation relating to transfers on peripherals owned by user programs. The short path is the first part of the main program, and ends with the EXITD instruction immediately before label 35.
Other events cause much more computational fun -- called the long path.
I will add to these jottings when I have a bit of spare time. Please feed in any questions, contradictions that occur to you.
This starts at label 1 in P0. There is various worrying about program failure (especially nesting store failure) and calculation of ludicrously small amounts of time. Unless there has been a nesting store failure, the nest, SJNS and Q4, Q6 and Q7 of the interrupted program are dumped into core store by JSP1. Q5 was dumped earlier. This gives director some registers to work in. At label 20 it starts to look why the interrupt happened and calls the appropriate subroutines to service the interrupt.
P5 is of particular importance. It is called whenever a director-initiated transfer ends (EDT). Activities inside director that are not processed without interruption (e.g. disc transfers, waiting for mag tape to be loaded), are managed by a system of 10 “subprograms”, numbered 0 to 9. Subprograms 0 and 1 are used by the system (especially for implementing TINTs -- operator commands). Subprograms 2 and 3 are involved in servicing requests for program in priority 0. Subprograms 4 and 5 are involved in servicing requests for program in priority 1, etc. Priority 0 program is run if not held up. If it is held up priority 1 program is run if it is not held up, etc. Each program is given a program letter, P, Q, R or S. Program P runs on register set 0, through to S which runs on register set 3. When subprogram 2 is active, priority 0 is inhibited from running (held up), but subprogram 3 can run concurrently with the user program 0. Subprograms 4 and 5 have a similar relationship to the priority 1 program, while 6 and 7 relate to priority 2 and 8 and 9 to priority 3.
Much of the information relating to individual programs is held in the V-stores of P104. This are arranged in quartets. For the most part the relevant program priority is in M5. When executing code in a subprogram C4 holds the subprogram number, and M4 points at its memory area (which resides in the V=stores of P11). In order to enter subprogram mode it is only necessary to call P30. This sets up Q4, so that when a routine is called which causes the subprogram to be suspended awaiting anything, the relevant info is stored in the correct V-stores in P11. Subprogram suspension is normally by calling P10, when the subprogram’s SJNS is put in E30M4 and control returned to P11. A program keeps the same register set throughout its existence, but its priority can be swapped (TINT V), and when this happens all the corresponding V-stores in P104 are swapped over, and lots more besides, see P105;
Much more to follow but first I think that I need to put lots of comments into the director source listing, comments that I should have put there in 1967-70!
The Eldon2 paper from Computer Journal wrongly states that 640 words was used as the block size because it was one revolution of the disk. The real reason is that it was the same size as used by the english Electric PROMPT system, and we operated with exactly the same file format.
The disc (from Data Products) had individually addressable sectors of 40 words each (perhaps reflecting the zeitgeist where card images were commonly stored on magnetic media). There were 96 sectors on a track. There were 16 actual discs each with an independently moving head. There was also a set of fixed heads giving another 96 sectors for which no seek was involved.
The vanilla EE system allocated actual disks as work area, and reserved some as system disks.
The Eldon2 system reorganised the disk in terms of logical cylinders, each of which was composed of one track on each of the 16 discs. A quantitly of cylinders were reserved as the system area, and the rest claimable by programs for their own work area. The Eldon2 multi-access system used such space as swap area, with 19 sectors per teletype, i.e. 5 work areas per track (one sector wasted). A logical user disk had 8 tracks, i.e. half a cylinder.
Both regimes used the 640 word block as the allocation unit in the system disk area, i.e. 16 to one track.
The fixed heads held the ASL (Allocated Space List -- a bit map one bit per block, not a FAT), and the directory of binary programs loadable directly by director.