c1edf584d85204e45164ea85191d813361fabdfd
[its.git] / sysdoc / intrup.108
1 Copyright (c) 1999 Massachusetts Institute of Technology
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or (at
6 your option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 ------------------------------
17
18 Overview of ITS User Interrupts
19
20 When ITS wishes to signal a user program of the existence of an
21 unusual interesting condition or occurrence, it does so via
22 the "user interrupt" mechanism.  This mechanism essentially
23 causes the user program to call an interrupt handling subroutine
24 in the middle of what it had been doing.  The interrupt handler has
25 enough information to be able to return to the interrupted code
26 without any effects on it if desired, and to determine the cause
27 of the interrupt so as to take appropriate action.  The program
28 can specify which interrupt conditions it wishes to handle, and
29 what their priority order should be; un-handled interrupts are
30 either ignored or fatal depending on the condition.  Some interrupt
31 conditions represent errors in the execution of the job;  some
32 indicate the occurrence of asynchronous events such as I/O operation
33 completion;  some exist for debugging and are always fatal.
34
35 The noun "interrupt" may mean either the event of interrupting
36 a program (causing it to call the handler), or a condition which
37 can cause a program to be interrupted.  Also, the distinction
38 between an interrupt condition and the bit which is 1 when the
39 condition is present is often blurred.
40
41 Unlike TENEX, ITS never gives the user an interrupt "in the middle
42 of a system call".  The PC saved by an interrupt is always a user-mode PC.
43 This is a great advantage when it comes to having the interrupt handler
44 understand what the interrupted code was doing and fix it up.
45 System calls will either be finished or backed out of (to be redone)
46 when it is necessary for the job to be interrupted.  To avoid having to
47 do a lot of work twice, all ITS system calls that take a long time to
48 complete are designed so that if restarted they will continue from
49 where they left off.  They do this by updating their arguments to
50 indicate how much progress they have made, just like the BLT instruction.
51 Now you know why SIOT and block-mode IOT update their pointer and
52 byte count as they go.
53
54 Section A describes how interrupts are signaled and enabled, etc.
55 Section B describes what is actually done to a job when it is
56   interrupted, if it uses the older simple interrupt mechanism.
57 Section C gives an example of an old-style interrupt handler.
58 Section D describes what is actually done to a job when it is
59   interrupted, if it uses the newer vectored interrupt mechanism.
60 Section E describes the individual interrupt conditions in the
61   first interrupt request word (.PIRQC).
62 Section F describes the individual interrupt conditions in the
63   second interrupt request word (.IFPIR).
64 \f
65 A. The ITS Interrupt Mechanism
66
67 Each ITS job has two "interrupt request words", called .PIRQC
68 and .IFPIR, and readable with .SUSET.  Each distinct interrupt
69 condition is assigned one of the bits in one of the words.
70 The interrupt is "pending" when the bit is 1.
71 .PIRQC is called the "first interrupt word" and interrupts in it
72 are "first word interrupts".  .IFPIR is the "second interrupt  word"
73 and its interrupts are "second word interrupts".
74
75 Interrupt conditions are divided by the system into three severity classes.
76 Class 1 interrupts are always fatal.  They are genarally conditions caused
77 by the user or the superior, for debugging purposes;  for example,
78 breakpoints, ^Z typed, and single-instruction-proceed interrupts are
79 of class 1.  Class 2 interrupts are fatal unless the program is set up
80 to handle the interrupt.  Most error conditions are class 2;  for example,
81 MPV (memory protect violation), ILOPR (illegal operation), IOCERR
82 (I/O channel error).  All class 1 and 2 interrupts are first word
83 interrupts.  Class 3 interrupts are never fatal unless the user
84 explicitly makes them so;  either the program is eventually interrupted
85 or nothing happens.  Most asynchronous conditions are class 3.
86
87 When a job receives a fatal interrupt, that job is not interrupted
88 itself;  instead, it is stopped, as if its superior had stopped it,
89 and an "inferior got a fatal interrupt" interrupt is signaled for the
90 superior.  If a top level job receives a fatal interrupt, then it will
91 be stopped and detached (see the symbolic system call DETACH).
92
93 Each interrupt word has a corresponding mask word:  .MASK for .PIRQC,
94 and .MSK2 for .IFPIR.  An interrupt is enabled if the appropriate bit in
95 the mask word is 1.  A program will not receive an interrupt which is
96 disabled, but if the interrupt condition is in class 2 it
97 will be fatal if it is not enabled.  Class 3 interrupts will not even
98 be signaled if they are disabled.  Class 1 interrupts are not allowed
99 to be enabled, the idea being that the job which gets an always-fatal
100 interrupt is not allowed to handle the interrupt itself.
101
102 Each interrupt word also has a defer word:  .DF1 for .PIRQC, and
103 .DF2 for .IFPIR.  If the appropriate bit in the defer word is set,
104 the interrupt is "deferred".  For a class 2 interrupt, deferment has
105 the same effect as disablement:  the interrupt becomes fatal.
106 For a class 1 interrupt, deferment has no effect.  For a class 3
107 interrupt, deferment differs from disablement in that a deferred
108 interrupt will still be signaled;  it will then remain pending until
109 it is no longer deferred, when it will be given to the user.
110 The system makes it easy to defer a specified set of interrupts while
111 processing an interrupt.  That is how different priorities of
112 interrupts may exist.
113
114 Slightly obsolete but still useful is the variable .PICLR, which is
115 normally -1.  If this variable is set to 0, all interrupts are deferred.
116 The actual values of the defer words are unaltered.  .PICLR was
117 the original way to defer interrupts, before the defer words existed.
118 The older style of interrupt handling on ITS sets .PICLR to 0 while
119 an interrupt is being processed;  thus, there is only one interrupt
120 priority level.
121
122 To help eliminate timing errors, the six variables .PIRQC, .IFPIR,
123 .MASK, .MSK2, .DF1 and .DF2 have aliases which have the same value
124 when read, but when written either IORM or ANDCAM into the variable
125 instead of setting all the bits in it.  These aliases are called
126 .IPIRQC, .IIFPIR, .IMASK, .IMSK2, .IDF1 and .IDF2 for IORM'ing,
127 and .APIRQC, .AIFPIR, .AMASK, .AMSK2, .ADF1 and .ADF2 for ANDCAM'ing.
128 Thus, depositing 20 in .APIRQC will clear the 20 bit in .PIRQC.
129
130 Error-condition interrupts (MPV, ILOPR, IOCERR, WIRO, DTTY and some others)
131 usually abort the instruction that causes them.  When this happens,
132 the old convention (still the default) is to leave the PC pointing
133 AFTER the aborted instruction.  This is very bad since it is hard
134 for the user's interrupt handler to tell whether to decrement the PC.
135 The new convention, selected by setting bit %OPOPC in the LH of the
136 .OPTION variable to 1, is for the system to decrement the PC when
137 a fatal interrupt happens, so that if the interrupt handler fixes
138 the problem (e.g. creates the nonexistent page of core) and dismisses,
139 the instruction will be retried.  All new programs should use the
140 new convention;  it would be nice to flush the old one entirely.
141 \f
142 B. How Jobs Are Informed about Their Interrupts (Old Style)
143
144 There are two ways for a program to receive interrupts from the 
145 system: the old way, and the new way.  The old scheme always stores
146 the PC in the same place, making recursive interrupts difficult.
147 It also makes all interrupts have the same priority level.
148 The new scheme pushes the interrupt information on a stack.  It also
149 has the ability to decode the interrupts for the user, whereas with the
150 old mechanism the program must decode the interrupts.  Nevertheless,
151 the old mechanism is not considered obsolete, since it is easier to use.
152
153 Both mechanisms have the user's interrupt handler information pointed
154 to by location 42.  More generally, the address of the interrupt pointer
155 is 2 plus the rh of the .40ADDR variable;  since .40ADDR usually holds
156 40, the interrupt pointer usually lives in 42.
157
158 The two mechanisms are selected by the %OPINT bit of the .OPTION
159 variable:  the new mode is used if the bit is 1.
160
161 In the old mode, 42 is expected to contain the address of the
162 interrupt handler itself.  Let that address be called "TSINT"
163 (every program should use that label, for the sake of humans).
164 If TSINT is 0, or addresses nonexistent or pure storage,
165 when the system attempts to interrupt the job, an always-fatal
166 BADPI (%PIB42) interrupt is signaled and the program does not
167 receive the original interrupts.  If the superior, handling the BADPI,
168 fixes up 42 and restarts the job, it will then be properly interrupted.
169
170 When an interrupt happens, all the
171 pending enabled undeferred first word interrupts will be given to
172 the user at once if there are any;  otherwise, all the pending
173 enabled undeferred second word interrupts will be given.  The
174 interrupts which are given will be cleared in the request word.
175 Whichever interrupt request word is being given will be stored in TSINT.
176 If the interrupts being handled are second-word interrupts, the sign
177 of TSINT will be set.  The PC is stored in TSINT+1.  The job is then
178 started at TSINT+2, with all PC flags except user and user-i/o zeroed.
179 The job's .PICLR will be set to 0, preventing further interrupts while
180 the interrupt handler is running.  Because more than one interrupt
181 may be given to the user at once, the interrupt routine should check
182 all of the interrupt bits, and after handling one interrupt should
183 return to check the remaining bits.
184
185 The normal way for the interrupt handler
186 to exit is with the .DISMIS uuo, which should address a word containing
187 the desired new PC.  .DISMIS jumps to that PC, restoring flags, and also
188 sets .PICLR to -1 to allow interrupts again.  To restart the program
189 where it was interrupted, .DISMIS TSINT+1 should be used.  The program
190 may desire to restore the saved PC flags but a different PC;  in that
191 case, it should probably clear the byte-interrupt flag (%PCFPD) before
192 restoring the flags.
193 \f
194 C. An Example of an Old Style Interrupt Handler
195
196 TSINT:
197 LOC 42
198         TSINT           ;this is the interrupt pointer. -> int handler.
199 LOC TSINT
200         0               ;first word of handler gets the bits for the interrupts
201         0               ;second gets the PC
202         EXCH A,TSINT
203         JUMPL A,TSINT2  ;sign of int word set => second word interrupts;
204         TLNE A,%PJRLT   ;otherwise, they are first word interrupts.
205          PUSHJ P,TIMINT ;if we got an alarm clock int, handle that.
206         TRNE A,%PIMPV
207          PUSHJ P,MPVINT ;if we got an MPV, handle that.
208         TRNE A,%PIIOC
209          PUSHJ P,IOCINT ;if we got an IOCERR, handle that.
210 TSINTX: EXCH A,TSINT
211         .DISMIS TSINT+1 ;then restore the saved PC and zero .PICLR.
212
213 TSINT2: TRNE A,1_TYIC
214          PUSHJ P,INPUTI ;handle characters typed on the tty (assuming
215                         ;that tty input is open on channel TYIC)
216         TDNE A,INFBIT
217          PUSHJ P,INFINT ;handle interrupts from one of our inferiors,
218                         ;assuming the inferior's .INTB variable was
219                         ;read into INFBIT.
220         JRST TSINTX
221
222 ;if the program can't recover from MPV's well, it might do this:
223 MPVINT: <TYPE ERROR MESSAGE SOMEHOW>
224         .DISMIS [RESTART]       ;re-initialize the program.
225
226 ;if it wanted to create the referenced page, it might do this:
227 MPVINT: PUSH P,B
228         .SUSET [.RMPVA,,B]
229         LSH B,-10.      ;get the referenced page's number.
230         .CALL [ SETZ ? 'CORBLK
231                 MOVEI 400000 ? MOVEI -1 ? B ? SETZI 400001]
232          .VALUE         ; ^ get a fresh page into page w/ number in B.
233         POP P,B
234         POPJ P,
235 \f
236 D. How Jobs Are Informed about Their Interrupts (New Style)
237
238 When using the newer interrupt mechanism, the program must divide
239 the interrupts that it handles into some number of groups (there
240 may be as few as one interrupt in a group, or all the interrupts
241 may be in one group).  The interrupts in a group are all handled
242 the same way;  they have the same relative priority to all other
243 interrupts, and have the same handler address.  For each group,
244 the user must specify to the system which interrupts are in it,
245 which interrupts are considered to have a lower priority than
246 those in the group, and where the handler for the group is located.
247 This is done with the "interrupt table", which should be 5n+1 words
248 long where n is the number of groups.  The interrupt table should
249 be identified to the system by means of an AOBJN pointer in 42.
250
251 The first word of the interrupt table should hold the address
252 of the interrupt stack (which may be an accumulator - P will work!).
253 The LH of this word specifies extra information to be pushed on
254 the interrupt stack at each interrupt, beyond the necessary minimum:
255   bits 3.5-3.1   # of ACs to push.  0 => don't push any ACs.
256   bits 3.7-4.1   # of first AC to push.
257   bit 4.9        1 => push the .JPC and .SUUOH variables, and the LSPCL
258                         (an internal ITS variable), after the ACs if any.
259
260 Then come five words for each interrupt group.  Their meanings are:
261   wd 1  The 1st word interrupts that are in this group.
262         If a bit is set in this word, the corresponding interrupt is
263         in this group.
264   wd 2  The 2nd word interrupts which are in this group.
265   wd 3  The 1st word interrupts that are of priority less than or equal to
266         this group's.  Give the bits for the appropriate interrupts.
267         When interrupts in this group happen, these bits will be
268         set in .DF1 to prevent the lower-priority interrupts from
269         happening.  Note that it is not obligatory to include the
270         interrupts of the group itself in this word;  if they are not
271         included, they will be able to interrupt recursively.  That is
272         sometimes desirable for recoverable synchronous conditions.
273   wd 4  The 2nd word interrupts that are ofthe same or lower priority.
274   wd 5  The address of the handler for this group.
275
276 Note that the priority-relation between interrupts, specified by the
277 second and third words of the groups in the interrupt table, need not
278 be even a partial order:  it is permissible for interrupt A to defer
279 only B, B to defer only C, and C to defer only A, although not very
280 useful.  Often, a synchronous interrupt is left incomparable with all
281 other interrupts - it defers only itself, or nothing.
282
283 Synchronous interrupts should come before asynchronous ones
284 in the table.  The only time an exception to that is safe is when
285 the asynchronous interrupt defers the synchronous one.  The reason for
286 this rule is that when a synchronous interrupt and an asynchronous one
287 are signalled at the same time, if the asynchronous interrupt comes
288 earlier in the table it will happen first;  if the synchronous one is
289 not then deferred, it will interrupt saving a PC pointing at the first
290 word of the asynchronous interrupt's handler - which is not the address
291 of the instruction that actually caused the synchronous interrupt.  If
292 the synchronous interrupt's handler looks at the PC, as many do, it will
293 be confused.
294 \f
295 This is an example of an interrupt table (taken from DDT).
296
297 TSINT:  LOC 42
298         -TSINTL,,TSINT
299 LOC TSINT
300
301         P               ;interrupt pdl pointer address.
302         %PIWRO ? 0 ? 0 ? 0 ? PURBR1
303                         ;pure-page violations don't inhibit anything.
304                         ;DDT wants to type out ":UNPURE", and doesn't
305                         ;like to type out with any interrupts inhibited.
306         %PITTY ? 0 ? %PITTY ? 0 ? TTYINT
307                         ;Don't-have-tty interrupts defer themselves
308                         ;so that they become fatal while one is being
309                         ;processed.  If DDT decides that the one
310                         ;that happened should have been fatal, it
311                         ;signals another by depositing in .IPIRQC, and
312                         ;that one IS fatal since it is deferred.
313         %PIIOC\%PIILO\%PIMPV\%PIOOB ? 0 ? #%PITTY ? -1 ? TSIN0
314                         ;Error interrupts inhibit asynchronous ints for
315                         ;safety's sake, and themselves so an error in
316                         ;the handler will be fatal.
317         #%PIIOC#%PIILO#%PIMPV#%PIOOB#%PIWRO#%PICLI#%PITTY ? #<1_TYOC>#1_TYOBC
318           #%PIIOC#%PIILO#%PIMPV#%PIOOB#%PIWRO#%PICLI#%PITTY ? -1 ? TSIN0
319                         ;Miscellaneous interrupts have the same handler
320                         ;as the errors - for historical reasons - but
321                         ;don't defer the errors, so that DDT can recover
322                         ;if an error happens in a miscellaneous int.
323         0 ? 1_TYOC+1_TYOBC ? 0 ? 0 ? MORINT
324                         ;Bottom-of-screen-on-terminal interrupts defer nothing,
325                         ;so they can exit by simply jumping if they wish.
326         %PICLI ? 0 ? %PICLI ? 0 ? CLIBRK
327                         ;Core-link interrupts (someone is :SEND'ing to me).
328 TSINTL==.-TSINT
329
330 The algorithm for giving a set of interrupts is:
331 Look through the interrupt block one group at a time.
332 If a group is found that applies to any of the interupts that
333 are to be given, all the interrupts that it applies to and that are
334 to be given are pushed, together, onto the interrupt stack
335 at once. The words pushed are:
336    First, two words containing the interrupts being pushed.
337         The first word interrupt bits are pushed first.
338    Next, two words containing the old settings of .DF1 and .DF2.
339         The old .DF1 is pushed first.
340    Next, a word containing the PC before the interrupt.
341    Last, any AC's or debugging variables specified by the LH of
342         the first word of the interrupt table.  These are pushed in the
343         order:  AC's first, then .JPC, then .SUUOH, and finally LSPCL.
344 If pdl overflow is enabled, it will be detected properly when the
345 interrupt data is pushed.
346 After the necessary information has been saved and the interrupt pdl
347 updated, the defer words and the PC will be set as specified
348 in the the interrupt table.
349 At this point, if there still remain any pending enabled undeferred
350 interrupts, the whole process is repeated, scanning through all the
351 groups from the beginning.  Note that giving one interrupt may cause
352 other previously undeferred interrupts to be deferred.  It may also
353 set the pdl overflow interrupt, in which case that interrupt will
354 be given immediately if not deferred.
355
356 If there are pending enabled undeferred interrupts not included
357 in any group, and they do not become deferred by the giving of other
358 interrupts, then they are considered immediately fatal.  Thus, the
359 user can make a nonfatal interrupt be fatal by enabling it but not
360 including it in any group.
361
362 The interrupt routine may conveniently
363 exit with the DISMIS Symbolic System Call.
364 The first arg, if not immediate, should point at the interrupt stack:
365         .CALL [SETZ ? 'DISMIS ? SETZ P]
366 The defer words and PC will be restored from the top 3
367 words on the stack and 5 words will be popped.  Stack overflow
368 will be detected.  You may specify that extra things should be popped
369 using the control bit argument; bit 2.9 specifies that three words
370 should be discarded, while <m>*100+<n> specifies that ACs <m> through
371 <m>+<n>-1 should be popped.  Thus, it is a win to give, as the control
372 bit argument (in the RH) whatever was put in the LH of the first word
373 of the interrupt table - that will cause the DISMIS to pop exactly
374 what interrupts push.
375
376 If the first arg is immediate, clearly nothing can be popped:
377         .CALL [SETZ ? 'DISMIS ? SETZI 2+[DF1 ? DF2 ? PC] ]
378 In this case the control-bit argument is ignored.
379 If a second argument is given, it is used as the new PC
380 instead of what is found on the interrupt stack.
381 Similarly, optional third and fourth arguments specify the new
382 contents of the defer words, overriding what was saved on the stack.
383 Thus, if four arguments are given and the first is immediate,
384 the first argument is effectively ignored.
385 \f
386 E. The Interrupt Bits in the First Interrupt Word.
387
388 The interrupt classes  are:
389   [1] stops job and interrupts superior (fatal intr)
390   [2] stops job and interrupts superior unless enabled and undeferred
391   [3] does nothing unless enabled;  waits if deferred.
392 Bits in the lh have two names: %PI... as a bit in the word,
393   and %PJ... shifted down by 18. bits.
394
395 The following interrupts abort the instruction, and leave the PC pointing
396 before the instruction if %OPOPC is 1 (as is winning), or after it if
397 %OPOPC is 0:  %PIMPV, %PIOOB, %PIIOC, %PIILO, %PJTTY, %PJWRO, %PJFET, %PJTRP.
398
399 "(S)" indicates a synchronous interrupt;  "(A)", an asynchronous one.
400 An interrupt is synchronous if its occurrence is always directly related
401 to the instruction that is being executed when it is signaled.
402
403 ;RH bits
404 %PICLI==400000  ;CLI interrupt                          [3] (A)
405                 ;Some job opened the CLI device with filenames equal
406                 ;to the uname and jname of this job.
407 %PIPDL==200000  ;PDL overflow                           [3] (S)
408 %PILTP==100000  ;340 or E&S light pen hit               [3] (A)
409 %PIMAR==40000   ;MAR hit.                               [2] (S)
410                 ;The MAR is a hardware feature that allows
411                 ;references to a specific memory location to
412                 ;be trapped.  This is the interrupt that happens
413                 ;when such a reference is detected.  The guilty
414                 ;instuction is usually not aborted;  if it is, the
415                 ;PC is SOS'ed regardless of the setting of %OPOPC.
416                 ;See the .MARA and .MARPC variables.
417 %PIMPV==20000   ;MPV (memory protect violation)         [2] (S)
418                 ;The job referenced a non-existent memory location.
419                 ;The address of that location (roundd down to
420                 ;a page boundary on KA-10's) may be found in .MPVA.
421                 ;The guilty instruction was aborted, and the PC was
422                 ;left set according to %OPOPC.
423 %PICLK==10000   ;Slow (1/2 sec) clock                   [3] (A)
424 %PI1PR==4000    ;Single-instruction proceed             [1] (S)
425                 ;If a job is started with the one-proceed flag
426                 ;(%PC1PR on KA-10's) set, after one instruction
427                 ;is completed a %PI1PR interrupt will occur.
428                 ;DDT's ^N command uses this feature.
429 %PIBRK==2000    ;.BREAK instruction executed.           [1] (S)
430                 ;.BREAK is used for DDT breakpoints, and for explicit
431                 ;program requests to DDT.
432 %PIOOB==1000    ;Address out of bounds                  [2] (S)
433                 ;This is an obscure condition that used to
434                 ;happen on USR device IOT's, when an attempt
435                 ;was made to refer to a nonexistent location in the
436                 ;other job.  Now this always causes an MPV.
437                 ;The guilty instruction was aborted, and the PC was
438                 ;left set according to %OPOPC.
439 %PIIOC==400     ;IOCERR (I/O channel error)             [2] (S)
440                 ;This indicates the failure of an I/O system
441                 ;call.  The channel that was being operated on is
442                 ;in .BCHN, and its .IOS word should contain, in
443                 ;bits 4.5 - 4.1, an error code.
444                 ;The guilty instruction was aborted, and the PC was
445                 ;left set according to %OPOPC.
446 %PIVAL==200     ;.VALUE instruction executed            [1] (S)
447 %PIDWN==100     ;System-going-down status change        [3] (A)
448                 ;If the system changes its mind about whether
449                 ;or when it is scheduled to go down, this interrupt
450                 ;is signaled.
451 %PIILO==40      ;ILOPR, ILUUO (illegal operation)       [2] (S)
452                 ;This can be caused by a returnable uuo when the
453                 ;program's 41 doesn't seem suitable for handling one
454                 ;(see ITS UUOS).  It can also be used to report
455                 ;the failure of certain more archaic system calls.
456                 ;The guilty instruction was aborted, and the PC was
457                 ;left set according to %OPOPC.
458 %PIDIS==20      ;Display memory protect                 [2] (A)
459                 ;The 340 or E&S display got an MPV.
460                 ;This is now obsolete since the 340 and E&S
461                 ;no longer work.
462 %PIARO==10      ;Arithmetic overflow                    [3] (S)
463                 ;The PDP-10's built-in arithmetic overflow
464                 ;condition was detected by the hardware.
465                 ;In fact, overflow occurs so often
466                 ;that enabling this interrupt causes the
467                 ;machine to slow down considerably,
468                 ;and it should be avoided.
469 %PIB42==4       ;BADPI (Bad location 42)                [1] (S)
470                 ;If in attempting to interrupt a job it turns out
471                 ;to be necessary to refer to nonexistent memory
472                 ;or write in read-only memory, this interrupt
473                 ;is signaled, instead of MPV or WIRO.
474                 ;This is so that the program will return to DDT
475                 ;instead of mysteriously looping.
476 %PIC.Z==2       ;^Z or CALL typed on terminal           [1] (A)
477 %PITYI==1       ;TTY input (obsolete)                   [3] (A)
478
479 ;LH bits
480 %PJRLT==200000  ;Real-time timer went off               [3] (A)
481                 ;These interrupts are controlled by the .REALT
482                 ;uuo.  See ITS UUOS.
483 %PJRUN==100000  ;Run-time timer went off                [3] (A)
484                 ;This interrupt is requested (in advance)
485                 ;by setting .RTMR.
486 %PJNXI==40000   ;Non-existent IO register               [2] (S)
487                 ;A Job in User IOT mode referenced a non-existent IO
488                 ;register on the KS10 Unibus.  The PC is left pointing
489                 ;before the guilty instruction.  The address of the
490                 ;non-existant register may be found in .MPVA.
491 %PJJST==20000   ;Job Status display request.            [3] (A)
492                 ;The sequence ^_J was typed on the
493                 ;console owned by this process or some inferior.
494 %PJDCL==10000   ;Deferred call.                         [1] (S)
495                 ;An attempt was made to read TTY input
496                 ;and the next character was a deferred-call
497                 ;character (^_D or Control-CALL).
498                 ;This deferred-call character is never seen
499                 ;by the program; it just causes the interrupt.
500                 ;It differs from ordinary CALL or ^Z
501                 ;in that it takes effect when the program
502                 ;gets around to reading it, not immediately.
503 %PJATY==4000    ;TTY returned.                          [3] (A)
504                 ;This interrupt happens when the TTY is
505                 ;returned by the superior, after having
506                 ;been taken away.  TECO uses this to know
507                 ;that it must redisplay the entire screen.
508 %PJTTY==2000    ;Don't have TTY                         [2] (S)
509                 ;This results from an attempt to use the job's
510                 ;console tty when the job does not own it, if
511                 ;%TBINT is 1 and %TBWAT is 0.  See ITS TTY.
512                 ;The guilty instruction is aborted, and the PC is
513                 ;left set according to %OPOPC.
514 %PJPAR==1000    ;Memory parity error                    [2] (A)
515                 ;Programs are not intended to try to recover
516                 ;from parity errors, on the assumption that they
517                 ;are probably permanently screwed up.
518                 ;This interrupt is asynchronous because it can
519                 ;be caused by a parity error in another job
520                 ;which destroys data in a page shared with this job.
521 %PJFOV==400     ;ARFOV (Floating overflow)              [3] (S)
522                 ;This is a non-aborting PDP-10 hardware condition.
523 %PJWRO==200     ;WIRO (Write in read-only page)         [2] (S)
524                 ;The guilty instruction was aborted, and the PC was
525                 ;left set according to %OPOPC.  The address of read
526                 ;only location (rounded down to a page boundary on
527                 ;KA-10's) may be found in .MPVA.
528 %PJFET==100     ;Fetched insn from impure page          [2] (S)
529                 ;On KA-10's, if bit %PCPUR of the PC flags is 1,
530                 ;fetching an instruction from an impure page
531                 ;will cause this interrupt.  This is supposed to
532                 ;facilitate catching jumps to randomness.
533                 ;The guilty instruction is aborted, and the PC is
534                 ;left set according to %OPOPC.
535 %PJTRP==40      ;SYSUUO (System uuo in trap mode)       [2] (S)
536                 ;A job whose .UTRAP variable was nonzero either
537                 ;attempted to execute an instruction that trapped
538                 ;to the system, or was about to be interrupted.
539                 ;This feature is intended to be used by the superior
540                 ;to provide a non-ITS environment for the inferior.
541                 ;For that purpose, this interrupt should not be
542                 ;enabled for the inferior, so that it will be fatal.
543                 ;The guilty instruction was aborted, and the PC was
544                 ;left set according to %OPOPC.
545 %PJDBG==2       ;System being debugged state change     [3] (A)
546                 ;When the system enters or leaves "debugging mode",
547                 ;this interrupt is signaled.
548 %PJLOS==1       ;A .LOSE UUO or a LOSE system call      [2] (S)
549                 ;was executed.
550 \f
551 F. The Interrupt Bits in the Second Word
552
553 The right half of the second word (.IFPIR) is used for I/O channel
554 interrupts that signal the arrival of or need for data.
555 They should not be confused with I/O channel error interrupts
556 or IOCERRors.  Each channel has its own bit: 1.1 is for channel
557 0;  1.2, for channel 1; ... 2.7, for channel 17 .
558 They are all class 3, and their significance depends on the device
559 open on the channel.
560
561 The left half of the second word (.IFPIR) is used for
562 "inferior got a fatal interrupt" interrupts.  Each of a job's
563 inferiors is assigned its own interrupt bit from among the
564 bottom 8 bits of the left half.  When an inferior job is created,
565 its interrupt bit should be read and remembered by reading the
566 .INTB variable with a .USET.  Every time that inferior gets a fatal
567 interrupt, it will be stopped and the superior will receive an
568 interrupt on that inferior's bit in .IFPIR.  The inferior may
569 be restarted by zeroing its .USTP variable, but if the fatal
570 interrupts remain and are still fatal the inferior will simply
571 stop and interrupt the superior again.  "Inferior got a fatal
572 interrupt" interrupts are all class 3.
573
574 The reason that inferiors interrupt through a special set of bits
575 instead of using I/O channel interrupts is that it makes it possible
576 to receive interrupts from all one's inferiors without having them
577 all open on I/O channels at all times.  DDT normally keeps only
578 its current job open, and when it receives an interrupt from some
579 other job it opens that job temporarily.