Note that if the RFI register is only examined once during a
particular Interrupt, then the clock values added and subtracted
into RTR are equal, and therefore cancel, and so the only modification
to the RTR is the addition of 1.048576 seconds if clock overflow has
occurred, and the subtraction of the correction.
It should also be observed that, due to the inevitable variations
which exist in the times for execution of the actual Interruption
process in different circumstances, the corrections (x+y) cannot
always represent to the ultimate degree of accuracy, the actual
values. In other words, the run time record of a program may be
subject to small variations from one run to another if there are
large variations in actual hold-up times.
Figure 1. (zoom)
Part II. Description of the Director (KKNO0C310P1U) (In this description
"Tape Generator" labels of the form /ABCD/ are used to refer to the appropriate
instructions or constant words).
4. Paths through Director
This section is concerned primarily with Phases 1 and 3, which are described
in great detail. Phase 2 is dealt with in less detail in later sections,
one of which also covers Phase 0.
4.1 Phase 1, first stage
The Interruption entry
When the Director is entered at syllable 0 of word 0 after an
interruption, Phase 1 starts with the following standard sequence of
Q0; SHL+63; =+Q0;
SETB140000; = K1; ERASE;
The significance of the first line is that it includes two "dummy"
fetch instructions (=+QO includes a fetch) which puts the fetch buffers
right in case the interrupt is the result of a "Reset" which could
have upset them. Similarly the shift instruction is purely a dummy
to stabilize the shifting hardware if required.
The second line resets the NOL register to contain "all ones" so that
subsequently any word in the store may be accessed by Director without
causing LIV to be set.
Next the contents of the word /RDLS/ are examined; this is an
indicator of whether the interruption which has occurred took place
while the machine was in program mode (/RDLS/ negative) or Director
mode - the latter leads to a catastrophic (loop stop) failure.
Before the next step, which is to examine the Reasons for Interrupt,
the link (return address) is transferred from the top cell of SJNS
to /RDLS/. This serves two purposes - it enables Director to enter
a subroutine now without danger of corrupting the SJNS (2.2.3), and
it also acts as the marker showing that the machine is in Director mode.
K4 is now obeyed to fetch the RFIR, which is first tested to ensure
that at least one valid RFI is present. Failure of this check
causes a jump to a location further on in the "long path" with an
indicator in N1 to cause a program failure - though this is really
a machine error, it is best to cause this failure as it enables the
point at which this "spurious" interruption occurred to be typed out.
Assuming the check does not fail, Director, with a copy of the
contents of RFIR in N1, obeys a subroutine jump to /RWR1/. This is
an alternative entry to the subroutine /RWR/ described below. It
is worth noting that, except in the two failure cases mentioned above,
there has been no branching of the path so far, so the time of its
execution never varies.
4.2 Subroutine /RJR/
The purpose of this subroutine is to handle the RFIR and the clock,
and it is used every time the Director has to obey K4. One of its
functions is to decide whether any reasons for interrupt have
occurred which necessitate the Director taking particular action:
if this is the case, the subroutine ends EXIT 1, but if there are no
significant RFIs (i.e. at most LOV or PR) it ends EXIT 2. Again,
the path through the subroutine which leads to EXIT 2 is carefully
arranged to include no branching, and therefore always takes the same
amount of time, because this path forms part of the (x+y) correction
mentioned earlier. However, the subroutine may make its way to
EXIT 1 by several different routes: this does not matter because
the Director can never proceed to Phase 3 after EXIT 1, and there must
always be at least one more entry to this subroutine before entering
In detail, the subroutine first obeys K4 and then looks for the "Reset"
RFI (D29): if this is found, it proceeds straight to the
catastrophic (loop stop) failure. Otherwise the subroutine proceeds
to /RWR1/; this is the entry from Phase 1 mentioned above, used
because "Reset" is not catastrophic in this one case (K4 has already
been obeyed in Phase 1).
If the Clock RFI or FLEX are set, the subroutine examines the state
of the magnetic tape units. Any tapes of status L which are not on
BT, or of status U which are on BT, have their status changed to W for
subsequent unloading and loading operations (6.4). This process
involves using a Q-store, a subroutine, and TR, so Q6, the state of
TR, and the top cell of SJNS are "dumped" temporarily, being restored
before the next step. (If FLEX was set, a non-zero marker is set
The next steps are always obeyed - to set 1.048576/23 or zero in
/RCXS/ according to whether or not the CLOCK RFI was set, to add
/RCXS/ into /RRLT/ (the real time record), and to scale the remaining
bits of the clock as seconds to 23 i.p. and store this value in
/RCLK/. Then another branch occurs if RESET RFI is present (this
can only be detected if entry was at /RWR1/) leading to EXIT 1
with a failure indicator in NI; (prior to this particular EXIT 1,
a CLOQO is obeyed to clear lock-outs from words 0-31, which may have
been set by the action which caused RESET).
A further test is now made to see whether any RFIs other than PR or
LOV (D22, 28) were set; if not, EXIT 2 is obeyed. (As mentioned
above, this path to EXIT 2 always takes the same time). Otherwise
a non-zero marker is set in /REDT/ if EDT was set, and finally EXIT 1
obeyed with a marker left in N1 which may have l's in D0 (indicating
that OUT was set), D45 (LIV) and D46 (NOUV). The subroutine uses
1 cell of SJNS and 3 cells of Nesting Store; it leaves a word in
N1 if EXIT 1 ends it, but not for EXIT 2.
The action of the subroutine is summarised in Fig. 1,
4.3 Phase 1, second stage. The Long Path
If EXIT 1 is obeyed at the end of the first entry to /RWR/, a path
known as the "Long Path" is followed. At this stage N1 contains the
OUT-LIV-NOUV indicator in N1. The next steps are:-
- Remove D0 from N1, set /ROUT/ non-zero if it was a 1 (OUT), zero
if it was 0.
- Add /RCXS/ and /RCLK/ to /RTIM/ (the programs run time record) and,
if this exceeds the time limit (in the program's El) add D47 to N1.
- (At this point the path may be joined from the earlier test which
looked for "spurious" interrupts, i.e. with no RFI set) Store "all l's"
- Preserve overflow, TR
- Preserve Q5, 6, 7.
Branching now commences, depending on the RFIs.
- If N1 is non-zero (it may contain D45, 46, 47 corresponding to
LTV, NOUV and Time expiry, or alternatively indicators set for
"spurious" interruption, or RESET) branch to the "program failure"
routine, /RW8/. (section 7.1). (This is a transition from Phase 1
to Phase 2. Note that an OUT is ignored if a program failure of this
- If /ROUT/ is non-zero, branch to /RW6/ (section 5.2) (Transition to
The point now reached (/RW9/) is a most important position in Director.
It is followed by an entry to /RWR/ which decides whether or not
further RFIs have occurred which prevent an immediate return to the
program, and to this point all the Phase 2 processes (e.g. OUT, FLEX,
the EDT procedures) return when wholly or partly complete. The
exact steps are:
- (/RW9/) Enter /RWR/. If EXIT 1, go straight back to /RW9/, erasing
any indicators in N1, which are nothing to do with the program and
therefore irrelevant. (Phase 2 has been entered, and this jump back
inhibits entry to Phase 3).
If EXIT 2,
- go to /RW10/ (Phase 2) if /RFLX/ is non-zero.
- go to /RW11/ (Phase 2) if /REDT/ is non-zero.
(These two branches are in this order because a TINT must have rather
higher priority than an EDT. This is especially relevant because
some processes deliberately simulate EDT by setting /REDT/ non-zero;
the danger of loops arises if a TINT cannot be arranged to get out
of the cycle.
- If /SHU/ or /HUR/ are non-zero, go back to /RW9/. The
significance of /SHU/ and /HUR/ is explained below (6.2,3)
The point now reached in the Long Path is the beginning of Phase 3.
The steps now are:-
- Restore Q5, 6, 7.
- Restore overflow and TR
- Subtract /RCLK/ from /RTIM/ (run time). This value of /RCLK/
was recorded at the last entry to /RWR/, just after /RW9/, at which
the final examination of RFIR and clock occurred.
- Restore CPDAR to contain peripheral units allocated to program.
- Set the value of the path correction (x+y) for the Long Path.
- go to /RW3/
- (/RW3/ - in the Short Path) subtract the path correction from /RTIM/.
- Restore the link from /RDLS/ to SJNS.
- Set /RDLS/ negative to indicate Program mode is about to be resumed.
- Store away /RTIM/. (This is done now, rather than earlier,
deliberately to ensure that the storage of the negative marker in
/RDLS/ is not the last "store" executed by Director. If a Reset
occurs when program mode is resumed, the last outstanding store made
by Director may not be executed (Advance Control stores "one late").
It is important.to prevent catastrophic failure in this case by
ensuring that the "program mode" indicator has been actually stored).
- Transfer programs BA and NOL (stored in /RLIM/) to K1,
- EXIT D to return to program.
(The last word of instructions obeyed is * = K1; ERASE; EXIT D)
The path from the last K4 obeyed in the Long Path (EXIT 2 from /RWR/)
up to EXIT D always takes the same time.
4.4 The Short Path
If EXIT 2 is obeyed after the first entry to RWR, the path followed
is called the "Short Path". It represents a transition straight
from Phase 1 to Phase 3, and the path always takes the same time. The
- Fetch /RTIM/ (run time) and SET short path correction (x+y)
- (/RW3/) the steps from this point to EXIT D are described under
the Long Path (4.3).
For the Director KKNO0C310P1U, the values of the path corrections
397 microsec (short path) and
545 microsec (long path)
5. FLEX, OUT, and some Subroutines
Both these RFIs involve the Director in making a further branch, depending
on the value of a parameter - in the first case this parameter is the
character input by the operator, in the second it is the number left in N1
by the program.
5.1 FLEX (/RW10/)
The first step is to clear the marker (RFLX/ which indicated that
there had been a Typewriter Interrupt. The query TINT; is typed
out using subroutine /RTQ/ (6.1), which automatically checks the
correct termination of the operator's response. Any failure in a
TINT transfers control to /RW13/ which causes
to be typed.
The first character of the reply is extracted using subroutine
/RFC/ (5.3) - the parameters of this subroutine being left in a
state enabling the individual TINT routines to fetch further
characters or numbers using /RFN/ - and a check-and-branch is
performed in the following way; A bit-pattern is transferred to N2
(with zero in N1), whose non-zero digits represent the valid values
of the TINT responses (thus D33 = A, D34 = B, D37 = E, etc). Nl
and N2 are shifted up logically, double length, by an amount which
is the numerical value of the character (33 places for A, 34 for B,
etc.) so that only if N2 is negative is the chracter valid. If
it ia valid, the bit-sum of N1 (obtained using BITS) is transferred
to the SJNS, and EXIT 1/RTRE/ obeyed, transferring control to a table
of jump instructions stored in the less significant halves of words
starting with /RTRE/. This technique ensures that only jumps
corresponding to valid values of the character need be included in
the table which is thus as short as possible.
The table of "jumps" lead to labels /RTWA/, /RTWB/, etc., for
TINTS A, B, etc. Brief notes are given. below on these. For
further the coding should be consisulted.
-/RTWA/ (TINT A): If RTER is zero, i.e. program termination is not
already proceeding, the next character is examined, and if it is a +,
the "ending number" (4) is stored in /RTER/, and the routines for
typing out the SJNS and Nesting Store are entered. Either way,
control eventually reaches /RW23/ which initiates the program
termination procedure (7.2).
If /RTER/ is already non-zero, D0 of /RB7H/ is cleared - if it was a
1, it indicates that a program tape was required, and this will
have the effect of cancelling the requirement.
- /RTWB/ (Tint B): /RFN/ is used to read an octal number, provided
/RTER/ is clear. This number is stored in the program's E1.
- /RTWE/ (TINT E): When the unit number has been read and checked,
it is stored in /RPRT/, and /RB7H/ (see TINT A) is cleared altogether.
- TINT F causes a jump straight to RW9.
- /RTWG/ (TINT G) enters a subroutine /RTP/ which types out the state
of the peripheral list.
- /RTWH/ (TINT H) sets a marker which is normally only set when a
new magnetic tape assumes status L. This is sufficient to ensure
execution of the procedure followed when a tape allocation is
requested, i.e. the typing out of a "Wanted" message or query for each
-/RTWI/ (TINT I): if the restart is Even, one of the two marker words
which may cause a program to be suspended in the Long Path, /SHU/,
is cleared. This procedure is riot followed for an Odd restart.
Re-entry at word 4 of the program is caused by storing /RDLS/ in the
top cell of SJNS, replacing it by the address 4, syllable 0 or 3.
- /RTWJ/ (TINT J): the coding should be consulted.
- /RTWL/ (TINT L) changes the type number of a unit by effectively
first "allocating" it, and then deallocating it with its new type
number. The first step is omitted if the unit was not present before,
the second if the unit is being removed from the list. This action
ensures that a "Next-to-be-allocated" unit is assigned when necessary
and available. Note that by specifying that a unit should have
the same type number as it already possesses, it is possible to change
its status from being "Next-to-be-allocated", if there is another
of the same type which may be thus assigned.
- /RTWM/ (TINT M) - the coding should be consulted.
Note that the paper tape punch is assumed to be unit 3, and is not
allocated in the normal way.
All these TINT routines return control to /RW9/. Some of them
(e.g. TINT H) assume that the EDT RFT will be set by the typewriter
query procedure, to implement the full action of the TINT.
5.2 OUT (/RW6/)
The return address in /RDLS/ is first updated by adding 3 syllables.
After checking, the OUT number is stored in SJNS and used to transfer
control to one of a table, of "jumps" stored in the even halves of the
words starting at /RTRE/ (the TINT jumps were stored in the odd halves).
These jumps are to labels /RUTO)/, /RUT 1/, ... /RUT 9/, /UT 10/, etc.
Brief notes on some of the OUTS:
- OUTs 0, 1, 2 all, after various checks, go to /RW23/ with the
appropriate ending number and terminator in the nest (7.2).
- OUT 4 and OUT 10 use a subprogram (6.3) to obtain the required tape.
They are distinguished by one of them clearing /ROUT/ before entering
the subprogram, the other leaving it non-zero.
- OUTs 5, 6, 7 use the standard allocation and deallocation
subroutines described below.
- OUT 8 is a complicated procedure involving the use of a subsidiary
subprogram to perform a transfer from part of the program's core area,
the principles of which are described later (6.4). The main object
is not to return to the program (/HUR/ being used to control this)
until the transfer has actually started, so that the lock-out on the
store area is set.
All these OUTs return to /RW9/. Some of them deliberatly set
/REDT/ non-zero in order to implement the full action of the OUT
in the EDT procedures. /ROUT/ does not have to be cleared.
5.3 Some subroutines
In general, subroutines in the Director tend to use 3 cells of the
Nesting Store, and 1 or 2 cells of SJNS, though subroutines to be
used in particular circumstances may have to restrict themselves
to 2 and 1 cells, respectively. Some subroutines use /RTLS/ as
a standard location to dump a link temporarily, to avoid nesting
down SJNS too much. Director subroutines, effectively forming a
closed system, permit themselves to accept and leave data in Q-stores.
Q7 is rarely used because of the requirements of sub-programs
(6.2); Q5 is generally used for peripheral transfer parameters,
Q6 for addressing peripheral unit descriptors.
The most important of these subroutines are.-
- /RPS1/, which, given a peripheral unit type number and status
in N1, looks for the first unit having both these; this search
uses the modification properties of a Q-store (Q6) which counts
down the peripheral unit numbers in its counter, using M6 to
address the "descriptors" of the units. Most searches through
the list of peripheral units are conducted thus, starting with the
highest number and working down.
- /RPS2/, which is another entry to the above routine: instead of
starting at the top end of the list of peripheral units, it
continues the search from the last unit found, assuming that Q6
and N1 have remained unaltered.
- /RAU/, which, given the type number of a unit (as in OUT 5),
looks for the "N" unit of that type and allocates it, leaving the
unit number, as usual, in C6, and the address, -1, of its descriptor
- /RMDE/ which deallocates any type of unit, given its unit number.
Magnetic tape units are given status W and a standard "brick
indicator" (6.4). This subroutine starts by waiting until the
unit concerned is no longer busy.
- /RIMS/ is a special entry to the above for using a different
"brick indicator", given in N1.
- /RFC/ is a "fetch character" subroutine. Given a word address
in M6, a character number (x6) in C6, and I6 zero or non-zero to
indicate case normal or case shift, it fetches the next meaningful
character into C5, leaving Q6 updated. There are four EXITs:
EXIT 1 - space
EXIT 2 - CR-LF
EXIT 3 - Tab, semi-colon, EM, or any character in shift case.
EXIT 4 - Normal case characters excepting semi-colon or EM.
- /RFN/ is a subroutine which requires the same parameters as /RFC/,
and fetches the next octal number to N1. If an EM, or a number
including decimal digits (8 or 9), is detected, the subroutine ends
EXIT 1, with N1 negative if no octal number was found; otherwise
N1 contains the number, and C5 the number terminator. The subroutine
ends EXIT 2 if the terminator was not EM.
- /X1/ simply obeys EXIT 1
- /ERX1/ and /ERX2/ both erase N1 and obey EXIT 1 and EXIT 2
- /TLX1/ and /TLX2/ transfer /RTLS/ to SJNS and obey EXIT 1 and EXIT 2
- /ELX1/ and /ELX2/ transfer. N1 to SJNS and obey EXIT 1 and EXIT 2
6. Peripheral Operations and EDT. Subprograms
Peripheral operations carried out by the Director fall into three classes -
transfers on the Flexowriter, transfers on other devices controlled by
"sub-programs", and operations concerned with magnetic tape units in
6.1 Typewriter transfers
These transfers are not "queued" - if the typewriter is not available
when the Director wants to use it, it just waits for it without
doing anything else. However, as soon as the transfer is initiated,
the Director is free to move on, except when it is a Query, in which
case the Director goes on waiting until the end of the transfer.
(This system is undeniably inefficient: the Time-sharing Director
in fact "queues" Typewriter operations, but at the cost of
increased storage for the "queue" and for the extra complexity of
There are three Typewriter transfer subroutines:-
- /RTN/ types out the contents of N1 and N2, in that order.
- /RTM/ types out the message whose parameters are stored in Q5.
- /RTQ/ types out, and checks, the Query whose parameters are given
in Q5. The check (that the transfer terminates with the
characters 37 75) is carried out by looking through the message
for these characters, starting at the beginning of the second word.
Parity is also checked - parity failure, if it occurs, is only
detected in Director-called read operations.
All these transfers are to EM, using POBQ5.
Any sequence of peripheral operations initiated by the Director
must allow for the inevitable delay between the start of each
operation and the removal of the associated "Busy" or "Lock-out"
conditions, which will be signalled by an EDT RFI since it coincides
with the end of a Director-called transfer. To allow for the delay,
the Director incorporates a programmed "interrupt" system having
the following characteristics: whenever a routine requires access
to a peripheral unit or area of core store which may be Busy or
Locked-out - this access to be delayed until such restrictive
conditions have cleared - the "system" is capable of suspending the
routine while the conditions are in force, and restarting it as
soon as they go. The system also caters for a hold-up due to a
request for the allocation of a magnetic tape with a given identifier
which is not immediately available. During the delay other
activities can proceed normally.
This system requires routines using it to obey certain rules:
these routines are called "Sub-programs". The basis of the
system is the existence of a "sub-program parameter table"
consisting of a triad (3 words) for each sub-program, which contain
a record of the position at which the sub-program is held up, and
why. The first word of each triad contains the link for the
sub-program (so that if it is transferred to the SJNS and EXIT 1
is obeyed, the sub-program will be resumed at the correct point).
D0 of this word indicates whether the hold-up is due either to
a Busy/Lock-out condition (D0=0 : parameters of the appropriate
transfer in the 2nd word of the triad) or to a tape being wanted
(D0=1 : identifier in 2nd, or 2nd and 3rd words of triad).
The table is addressed via a Q-store (Q7) which, while any sub
program is operating, contains:
M7 = address of first word of triad
17 = +3 (for updating M7)
C7 = counter (initially number of sub-programs)
The table is stored in /SHU/ onwards, and there are (usually)
two sub-programs, so the initial contents of Q7 are C=2, I=+3,
M=/SHU/. This word is stored in /SHUQ/.
The main rule to be obeyed by any sub-program is that it must
not alter Q7, so that when it is held up its particulars are
stored in the right triad.
The way sub-programs fit into the general scheme is illustrated in Figure 2.
If /REDT/ is non-zero (as the result of an EDT RPI, or for some
other reason), the Long Path leads to /RW11/ and thence to the
operations illustrated in the diagram. This consists of:-
(1) Set up Q7 to address the table.
(2) Go to /RWL2/ to test whether the currently addressed sub
program can be resumed, leading to:
(3a) (it can't) Update Q7 and return to step 2 if C7 ≠ 0; otherwise,
all sub-programs having been dealt with, rejoin the Long Path