****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1435]S1435C1.SDML;164 defined in SYSMAC.SML, a system macro library stored on the system volume. The library also contains macro routines you use to write device handlers and interrupt service routines.

*************** (UNNUMBERED) Interrupt service routines Device handlers Memory management control blocks *************** I/O buffers Device handlers Interrupt service routines Queue elements Defined channels *************** handlers that are loaded. If a foreground job in a foreground/background environment accesses a device directly through an in-line interrupt service routine, the foreground job must notify the monitor that it must have exclusive use of the vectors. Using the .PROTECT programmed request lets the foreground job gain *************** Completion routines are part of your program that execute following the (Input/output operationscompletion routines) completion of some external operation, interrupting the normal program flow. On entry to an I/O completion routine, R0 contains the contents of the Channel Status Word and R1 contains the channel *************** jobs) and run at priority 0. Completion routines do not interrupt one another but are queued; the next completion routine is not entered until the first is completed. ***************

Also, it is possible to request a completion routine from an in-line interrupt service routine through a .SYNCH programmed request. This enables the interrupt service routine to issue other programmed requests to the monitor. *************** Completion routines should never reside in memory space that is used for the USR, since the USR can be interrupted when I/O terminates and the completion routine is entered. If the USR has overlaid the routine, control passes to a random place in the USR, with a HALT or error trap being the *************** I/O completion routines, .MRKT routines are asynchronous and independent of the main program. After the specified time elapses, the main program is interrupted, the timer completion routine executes, and control returns to the interrupted program.

*************** (DEV_BOOK). (Interrupt Service Routines)

Some macros in system macro library (SYSMAC.SML) are not (Interrupt service routines) programmed requests, but are used like programmed requests in interrupt service communication to the monitor.

.INTEN, the first macro call in every interrupt routine, causes the system to use the system stack for interrupt service and enables the monitor scheduler to make note of the interrupt. If device service is all the routine does, .INTEN is the only call it has to make.

You must issue the .SYNCH call whenever you need to issue from the interrupt service routine, one or more programmed requests, such as .READ or .WRITE. The .INTEN call switches execution to the system state and, since programmed requests can only be made in the user state, the *************** .SYNCH call is the return address on error, while the second word is the return on success. The (SIM_BOOK) contains a detailed description of interrupt service routines. ***************

Macros used in interrupt service routines and in writing device handlers are listed since they are a part of the system macro library. *************** Sets up .DPRINT environment.) (.DELETE(.DELETEsummary)\375\0\Deletes the file from the specified device) (.DEVICE(.DEVICEsummary)\375\14\Enables device interrupts to be disabled upon program termination) *************** handler data tables) (.DRVTB(.DRVTBsummary)\--\--\Used with multivector device handlers to generate a table that contains the vector location, interrupt entry point, and processor status word for each device vector) (.DSTAT(.DSTATsummary)\342\--\Returns the status of a specified device) *************** (.FORK(.FORKsummary)\--\--\Generates a subroutine call in an interrupt service routine that permits long but not critical processing to be postponed until all other interrupts are dismissed) (.FPROT(.FPROTsummary)\375\43\Sets or removes a file's protection) (.GFDAT(.GFDATsummary)\375\44\Returns in R0 the creation date from a *************** operation) (.INTEN(.INTENsummary)\--\--\Generates a subroutine call to notify the monitor that an interrupt has occurred, requests system state, and sets processor priority to the specified value) (.LOCK(.LOCKsummary)\346\--\Makes the monitor User Service Routine *************** (.SFINF(.SFINFsummary)\375\44\Returns in R0 the word contents of the directory entry offset specified in file's directory entry) (.SFPA(.SFPAsummary)\375\30\Sets user interrupt for floating-point processor exceptions) (.SFSTA(.SFSTAsummary)\375\44\Returns in R0 the status information from a *************** handlers from memory) (.SYNCH(.SYNCHsummary)\--\--\Generates a subroutine call that enables your program to perform programmed requests from within an interrupt service routine) (.TIMIO(.TIMIOsummary)\--\--\Generates a subroutine call in a handler to ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1435]S1435C2.SDML;292 describing each one in detail and providing an example of its use in a program. Also described are macros and subroutines that are used to implement device handlers and interrupt service routines. The following parameters are commonly used as arguments in the various calls: *************** The .CTIMIO macro cancels the device time-out request in the handler interrupt service section when an interrupt occurs to disable the completion routine (See .TIMIO). The device time-out feature is only useable if it was selected during the system generation *************** request or a CTRL/C from the terminal, the system loads these designated addresses with the corresponding values. In this way your program can turn off a device's interrupt enable bit whenever the program servicing the device terminates.

*************** ;+ ; .DEVICE - This is an example in the use of the .DEVICE request. ; The example shows how .DEVICE is used to disable interrupts from ; a device upon termination of the program. In this case the device ; is a DL11 Serial Line Interface. *************** START: .DEVICE #AREA,#LIST ;Setup disables DL11 interrupts ;on .EXIT or ^C^C .PROTECT #AREA,#DLVEC+4 ;Protect the DL11 output vector ***************

(.DRAST macrodescription) The .DRAST macro sets up the interrupt and abort entry points, lowers the processor priority, and enters the $INTEN routine in the resident monitor, which it finds by using the pointer $INPTR. *************** (\(name)\is the two-character device name) (\(pri)\is the priority of the device, and also the priority at which the interrupt service code is to execute) (\(abo)\is an optional argument that represents the label of an abort entry point. If you omit this argument, the macro generates a RETURN instruction at the abort entry point, which is the word immediately preceding the interrupt entry point.)

*************** BCC XXERR ;A read from a write/only device? BEQ XXDUN ;Zero word count...just exit XXRET: BIS #100,@#XX$CSR ;Enable DL-11 interrupt RETURN ;Return to monitor ; INTERRUPT SERVICE ROUTINE .DRAST XX,XX$PRI ;Use .DRAST to define Int Svc Sect. *************** TST @#XX$CSR ;Error? BMI XXRET ;Yes...'hang' until read, BIC #100,@#XX$CSR ;Disable interrupts .FORK XXFORK ;Continue at FORK level XXNXT: TSTB @#XX$CSR ;Is device ready? *************** RETURN .DRAST SK,4,ABORT ; Interrupt entry point BCS INT2 ; Interrupt from second vector ... RETURN INT2: ; Second interrupt vector code ... RETURN *************** The .DRVTB macro sets up a table of three-word entries for each vector of a multivector device. The table entries contain the vector location, interrupt entry point, and processor status word. You must use this macro once for each device vector. The .DRVTB macros must be placed consecutively in the device handler between the .DRBEG macro *************** (\(vec)\is the location of the vector, and must be between 0 and 474) (\(int)\is the symbolic name of the interrupt handling routine. It must appear elsewhere in the handler code. It generally takes the form ddINT, where dd represents the two-character device name) (\(ps)\is an optional value that specifies the low-order four bits of the new Processor Status Word in the interrupt vector. This argument defaults to zero if omitted. The priority bits of the PS are set to 7, even if you omit this argument) ***************

If you want to use the .FORK macro in an in-line interrupt service routine rather than in a device handler, you must set up $FKPTR. The recommended way to do this is as follows: *************** ... INTIN: ;Interrupt entry .INTEN 4 ;Declare interrupt and drop to PR4 ... ;Process quick stuff .FORK FORKBK ;do a fork ... ;Process slow stuff RETURN ;and return from interrupt AREA: .BLKW 2 ;EMT request block ***************

The fork request is linked into a fork queue and serviced on a first-in first-out basis. On return to the handler or interrupt service routine following the call, the interrupt has been dismissed and the processor is executing at priority 0. Therefore, the .FORK request must not be used where it can be reentered using the same fork block by another interrupt. It also should not be used with devices that have continuous interrupts that cannot be disabled. The (DEV_BOOK) gives additional information on the .FORK request. ***************

(.INTEN macro description) Interrupt service routines use .INTEN: (UNNUMBERED) To notify the monitor that an interrupt has occurred and to switch to system state. To set the processor priority to the correct value. To save the contents of R4 and R5 before returning to the Interrupt Service Routine. Any other registers must be saved by the routine. *************** (3\3\6) (\(prio)\is the processor priority at which the interrupt routine is to run, normally the priority at which the device requests an interrupt) (\(pic)\is an optional argument that should be non-blank if the interrupt routine is written as a PIC (position-independent code) routine. Any interrupt routine written as a device handler must be a PIC routine and must specify this argument) ***************

All external interrupts must cause the processor to go to priority level 7. .INTEN is used to lower the priority to the value, at which point the device should be run. On return from .INTEN, the device interrupt can be serviced, at which point the interrupt routine returns with a RETURN instruction. An RTI instruction should not be used to return from an interrupt routine that uses an .INTEN. *************** ;+ ; DL11.MAC - This is an example in the use of the .INTEN request. ; The example is an in-line, interrupt service routine, which may ; be assembled separately and linked with a mainline program. ; The routine transfers data from a user specified buffer to a DL11 *************** ASL WCNT ;Make word count byte count BEQ 1$ ;Just leave if zero word count MOV #DLINT,@#DLVEC ;Initialize DL11 interrupt vector BIS #100,@#DLCSR ;Enable interrupts 1$: RTS R5 ;Return to caller DLINT: .INTEN DLPRI ;Interrupt service - Notify RT-11 ;and drop priority to that of DL11 MOVB @BUFAD,@#DLCSR+2 ;Transfer a byte *************** DEC WCNT ;All bytes transferred? BEQ DLDUN ;Branch if yes RETURN ;No return from interrupt thru RT-11 DLDUN: BIC #100,@#DLCSR ;All done - disable DL11 interrupts RETURN ;Return thru RT-11 .END *************** (DTACH$\####20\\Detach in progress) (WRWT$\####40\\TT: I/O flag) (INEXP$\###100\\Output interrupt is expected) (PAGE$\###200\\Output is suspended by XOFF) (SHARE$\##2000\10\Terminal is shared console) *************** vector (two words) in the area of 0 to 474. If the request is successful, it indicates that the locations are not currently in use by another job or by the monitor. The job then can place an interrupt address and priority into the protected locations and begin using the associated device. *************** ; .PROTECT / .UNPROTECT - This is an example in the use of the .PROTECT ; and .UNPROTECT requests. The example illustrates how to protect the ; vectors of a device while an inline interrupt service routine does ; a data transfer (in this case the device is a DL11 Serial Line ;Interface). *************** .GLOBL DL11 START: .DEVICE #AREA,#LIST ;Setup to disable DL11 interrupts on ;.EXIT or ^C^C .PROTECT #AREA,#300 ;Protect the DL11 vectors *************** .SFPA #AREA,#FPTRAP ;Set up FPU error trap ; . ;continue mainline program DIVF F0,%1 ;cause a divide by 0 interrupt .EXIT ;Exit program *************** 10$: MOV (SP)+,R0 RTI ;Before returning from interrupt F0: .WORD 0,0 *************** A .SPND or .RSUM, like most other programmed requests, can be issued from within a user-written interrupt service routine if the .INTEN/.SYNCH sequence is followed. All notes referring to .SPND/.RSUM from a completion routine also apply to this case. *************** This macro call enables your program to issue programmed requests from an interrupt service routine. Code following the .SYNCH call runs at priority level 0 as a completion routine in the issuing job's context. Programmed requests issued from interrupt routines are not supported by the system and should not be performed unless a .SYNCH is used. .SYNCH, like .INTEN, is not an EMT monitor request, but rather a *************** (Notes)

The monitor dismisses the interrupt without returning to the .SYNCH routine if one of the following conditions occur: *************** free, and do not contain the same information they contained before the .SYNCH request. A long time can elapse before the program returns from a .SYNCH request since all interrupts must be serviced before the main program can continue. Enter a RETURN to exit from the routine. *************** ; .SYNCH - This is an example of the .SYNCH request. ; The example is a skeleton of a program which could input data ; from the outside world by means of an in-line interrupt service routine, ; buffer it until a whole block's worth has been input, then use ; a .WRITE request to store the data on an RT-11 device. *************** ; . ;Here we open an RT-11 output ; . ;device, then initiate input from ; . ;a "foreign" device, interrupts to ; . ;be handled by our in-line interrupt ; . ;service routine.... INTRPT: ;INTERRUPT SERVICE ROUTINE .INTEN 5 ;Notify RT-11 and drop to priority 5 ; . ;Process interrupt and buffer input ; . ;Time to write a buffer - switch ; . ;buffers (should be double buffered ; . ;so that interrupt processing can ; . ;continue during write operation). .SYNCH #SYNBLK ;Do a .SYNCH so we can use a .WRITE *************** ;Queue a write to store the data INC BLK ;and bump the block number. RETURN ;Re-enable interrupts and leave SYNBLK: .WORD 0 ;.SYNCH block *************** SYNFAIL: ;.SYNCH failed... ; . ;This can be a problem if the ; . ;next interrupt came in before the ; . ;buffer was written out! *************** runs in the context of the job indicated in the timer block. In mapped systems, the completion routine executes with Kernel mapping, since it is still a part of the interrupt service routine. (See the (SIM_BOOK) for more information about interrupt service routines and the mapped monitor.) As usual with completion routines, R0 and R1 are available for use. When the completion routine is entered, *************** MOV R5,TBLK+14 ;Move it to argument block .TIMIO TBLK,0,TIME ;Schedule a marktime BIS #100,@#SP$CSR ;Enable DL-11 interrupt RETURN ;Return to monitor ; INTERRUPT SERVICE ROUTINE .DRAST SP,SP$PRI ;Use .DRAST to define Int Svc Sect. ***************

In the mapped monitor, traps dispatched to a user program by .TRPSET execute in User mode. They appear as interrupts of the user program by a synchronous trap operation. Programs that intercept error traps by trying to steal the trap vectors must be carefully designed to handle ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1436]FIG_USR.SDML;5 500 | | | | +--------------------+ | USR | 476 | Interrupt Vectors | | | | | | | 60 | | +-----------+ ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1436]S1436C1.SDML;71 Facilities for communication between foreground and background jobs. FORTRAN language interrupt service routines for user devices. Complete timer support facilities, including *************** current job have higher priority than other parts of the job. When a completion routine is initiated (because of its associated event), it interrupts execution of the job and continues to execute until it relinquishes control. *************** If an error occurs in a completion routine or in a subroutine at completion (Completion routineserror handling) level, the error handler traces back through to the original interruption of the main program. Thus, the traceback is shown as though the completion routine were called from the main program. *************** subroutine can be used many times as a completion routine or as a routine in the main program, but a subroutine executing as main program code does not work properly if it is interrupted and then called again at the completion level. This restriction applies to all subroutines that can be invoked at the completion level while they are active in the main program. *************** (USRswapping over data) unpredictable results, you must restrict interrupt service routines and completion routines to locations outside the USR swapping area. Identify the limits of this swapping area by examining the link map *************** Routines that request USR functions (such as IENTER and LOOKUP) Data structures for USR requests Interrupt service routines Completion routines Data areas for interrupt service routines and completion routines

*************** requesting job will be blocked until the other job releases the USR. The requesting job may be locked out for seconds or minutes at a time. Interrupt service and completion routines can run, but mainline code cannot. You can minimize or eliminate these resulting timing problems by observing the following: *************** Do not use devices with slow directory operations, such as magtapes. Write real-time operations as completion and interrupt service routines in your foreground job so that a locked-out mainline program does not impede real-time operations. *************** An initialization phase that opens all required channels and begins a real-time operation A real-time phase that performs interrupt service and I/O operations A completion phase that halts real-time activity and then closes the channels. *************** foreground enables the background task to do USR operations during the real-time phase without locking out the foreground. This action simplifies USR swapping because the USR can swap over interrupt routines and I/O buffers as long as they are inactive. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1436]S1436C2.SDML;168 directly to another background program and pass specified information to it. CHAIN cannot be called from a completion or interrupt routine. The FORTRAN impure area is not preserved across a chain. Therefore, when chaining from one program to another, the information must be reset in the program being chained to. When chaining to *************** This function is primarily designed to allow user programs to load device registers with necessary values. In particular, it is used to turn off a device's interrupt enable bit when the program servicing the device terminates. *************** (UNNUMBERED) ENTER cannot be issued from a completion or interrupt routine. ENTER requires that the appropriate device handler be in memory. ***************

LOCK cannot be called from a completion or interrupt routine.

*************** Specified locations are not currently in use by another job or the monitor. Calling job can place an interrupt address and priority in the protected 2-word vector and begin the device associated with those vectors. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]C7.SDML;2 (1\Bits have meaning only if global SCCA is enabled.) (OFFSET\Symbol\ByteLengthin Octal\Description) (0\$RMON\4\Common interrupt entry point; contains the instruction JMP $INTEN. The .INTEN macro uses it.) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]C8.SDML;2

(Interrupt, Trap, and Software Vectors)

****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437C3.SDML;8 ([NO]WAIT) WAIT interrupts output to spooled device (x), while output to any other spooled device continues.

NOWAIT resumes sending spooled output to device (x) after output to that device has been interrupted. ([NO]WIDE) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437C3_QK.SDML;60 The .CTIMIO macro cancels the device time-out request in the handler interrupt service section when an interrupt occurs to disable the completion routine (See .TIMIO). (indent\1\smallskip)(.CTIMIO tbk) ***************

(.DRAST macrodescription) The .DRAST macro sets up the interrupt and abort entry points, lowers the processor priority, and references global symbol $INPTR, which contains a pointer to the $INTEN routine in the resident monitor. *************** (\(name)\is the two-character device name) (\(pri)\is the priority of the device, and also the priority at which the interrupt service code is to execute) (\(abo)\is an optional argument that represents the label of an abort entry point. If you omit this argument, the macro generates a RETURN instruction at the abort entry point, which is the word immediately preceding the interrupt entry point.) *************** The .DRVTB macro sets up a table of three-word entries for each vector of a multivector device. The table entries contain the vector location, interrupt entry point, and processor status word. You must use this macro once for each device vector. (indent\1\smallskip)(.DRVTB name,vec,int[,ps]) *************** (\(vec)\is the location of the vector, and must be between 0 and 474) (\(int)\is the symbolic name of the interrupt handling routine. It must appear elsewhere in the handler code. It generally takes the form ddINT, where dd represents the two-character device name) (\(ps)\is an optional value that specifies the low-order four bits of the new Processor Status Word in the interrupt vector. This argument defaults to zero if omitted. The priority bits of the PS are set to 7, even if you omit this argument) ***************

If you want to use the .FORK macro in an in-line interrupt service routine rather than in a device handler, you must set up $FKPTR. ***************

(.INTEN macro description) Interrupt service routines use .INTEN: (UNNUMBERED) To notify the monitor that an interrupt has occurred and to switch to system state. To set the processor priority to the correct value. To save the contents of R4 and R5 before returning to the Interrupt Service Routine. Any other registers must be saved by the routine. *************** (3\3\6) (\(prio)\is the processor priority at which the interrupt routine is to run, normally the priority at which the device requests an interrupt) (\(pic)\is an optional argument that should be non-blank if the interrupt routine is written as a PIC (position-independent code) routine. Any interrupt routine written as a device handler must be a PIC routine and must specify this argument) *************** (DTACH$\####20\Detach in progress) (WRWT$\####40\>>>Meaning???) (INEXP$\###100\Output interrupt is expected) (PAGE$\###200\Output is suspended by XOFF) (SHARE$\##2000\Terminal is shared console) *************** This macro call enables your program to issue programmed requests from an interrupt service routine. Code following the .SYNCH call runs at priority level 0 as a completion routine in the issuing job's context. (indent\1\smallskip)(.SYNCH area[,pic]) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437C5.SDML;28 The .CTIMIO macro cancels the device time-out request in the handler interrupt service section when an interrupt occurs to disable the completion routine (See .TIMIO). (indent\1\smallskip)(.CTIMIO tbk) ***************

(.DRAST macrodescription) The .DRAST macro sets up the interrupt and abort entry points, lowers the processor priority, and references global symbol $INPTR, which contains a pointer to the $INTEN routine in the resident monitor. *************** (\(name)\is the two-character device name) (\(pri)\is the priority of the device, and also the priority at which the interrupt service code is to execute) (\(abo)\is an optional argument that represents the label of an abort entry point. If you omit this argument, the macro generates a RETURN instruction at the abort entry point, which is the word immediately preceding the interrupt entry point.) *************** The .DRVTB macro sets up a table of three-word entries for each vector of a multivector device. The table entries contain the vector location, interrupt entry point, and processor status word. You must use this macro once for each device vector. (indent\1\smallskip)(.DRVTB name,vec,int[,ps]) *************** (\(vec)\is the location of the vector, and must be between 0 and 474) (\(int)\is the symbolic name of the interrupt handling routine. It must appear elsewhere in the handler code. It generally takes the form ddINT, where dd represents the two-character device name) (\(ps)\is an optional value that specifies the low-order four bits of the new Processor Status Word in the interrupt vector. This argument defaults to zero if omitted. The priority bits of the PS are set to 7, even if you omit this argument) ***************

If you want to use the .FORK macro in an in-line interrupt service routine rather than in a device handler, you must set up $FKPTR. ***************

(.INTEN macro description) Interrupt service routines use .INTEN: (UNNUMBERED) To notify the monitor that an interrupt has occurred and to switch to system state. To set the processor priority to the correct value. To save the contents of R4 and R5 before returning to the Interrupt Service Routine. Any other registers must be saved by the routine. *************** (3\3\6) (\(prio)\is the processor priority at which the interrupt routine is to run, normally the priority at which the device requests an interrupt) (\(pic)\is an optional argument that should be non-blank if the interrupt routine is written as a PIC (position-independent code) routine. Any interrupt routine written as a device handler must be a PIC routine and must specify this argument) *************** (DTACH$\####20\Detach in progress) (WRWT$\####40\TT: I/O flag) (INEXP$\###100\Output interrupt is expected) (PAGE$\###200\Output is suspended by XOFF) (SHARE$\##2000\Terminal is shared console) *************** This macro call enables your program to issue programmed requests from an interrupt service routine. Code following the .SYNCH call runs at priority level 0 as a completion routine in the issuing job's context. (indent\1\smallskip)(.SYNCH area[,pic]) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437C7.SDML;11 (1\Bits have meaning only if global SCCA is enabled.) (Offset\Symbol\ByteLengthin Octal\Description) (0\$RMON\4\Common interrupt entry point; contains the instruction JMP $INTEN. The .INTEN macro uses it.) *************** (12\SP$SCN\1 = Print screen (CTI bus-based computers only).) (13\SP$GTM\1 = Date and time request for flag pages.) (14\SP$IEN\1 = Fake interrupt enable.) (15\SP$ERR\1 = Error bit (set by SPOOL).) *************** line count.) (-\I.IRNG\2\Input ring buffer low limit.) (-\I.IPUT\2\Input PUT pointer for interrupts.) (-\I.ICTR\2\Input character count.) (-\I.IGET\2\Input GET pointer for .TTYIN.) *************** (-\I.OCTR\1\Output character count.) (-\I.CTLO\1\^C flag) (-\I.OGET\2\Output GET pointer for interrupts.) (-\I.OTOP\2\Output ring buffer high limit.) (-\------\TTYOUT\Output ring buffer.) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437C8.SDML;5 (.TXT\Text file) (Interrupt, Trap, and Software Vectors) (multipage) (2\10) *************** (230,232\Reserved) (234,236\Reserved) (240,242\PIRQ (programmed interrupt request)) (244,246\FPP/FIS floating-point exception) (250,252\KT11: Memory management fault) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1437]S1437FM.SDML;26 ASCII character set, left/right byte equivalents; Radix-50 character set; RT--11 device names and codes; standard RT--11 file types; interrupt, trap, and software vectors; K equivalents. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1438]S1438BOOK.SDML;24

**If only the monitor dot---without a message---appears, an interrupt through an empty vector to code at location 0 or another unexpected jump to location 0 is indicated. The following example shows the code *************** (unnumbered) A spurious interrupt request appeared A vector was never filled A filled vector was not *************** Absolute location 244 (octal)

The monitor executes this halt if a floating-point interrupt occurs under a monitor that does not have floating-point support. Programs that use floating-point instructions must be run under monitors with floating-point *************** The monitor executes this halt when it traps to 4 or 10 or when it encounters a memory error, but only when it is executing critical monitor or interrupt code---in interrupt service routines, device handlers, or selected portions of the monitor. (When the monitor is not executing critical code, it issues a message---(?MON--F--Memory error ***************

The address where the trap occurred is at the top of the stack. If this address is within user code, check for an error in an interrupt service routine or a device handler. Verify that handlers are not fetched into areas that will be destroyed by data buffers or overlaid when ***************

The general method for diagnosing a program loop condition is to disable any device that generates frequent interrupts (the KW11L clock, for example) and then to single-step through the set of looping instructions to find the location in memory where the loop occurs. (See the processor handbook for the PDP--11 you are using for instructions on single-stepping.) A frequent cause of looping is the loss of an interrupt or interrupt enable bit in a device or terminal interface. If you are familiar with the devices your program is using, you can examine the device registers to determine if this is the case. *************** memory and could not be fetched. Under the XM, ZB, and ZM monitor, there may not be enough space for the device in the interrupt-forwarding table. The value (

) is the address of the instruction following the instruction or *************** kernel active page registers 1 and 3. Alternatively, perform another system generation and include additional device slots to increase the size of the interrupt forwarding table. (?MONMRG--F--Device full ()) ***************

In a multiple file operation, the command was successfully executed on every file preceding the one interrupted by the error. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1479]S1479PART2.SDML;1 unload the device.

However, if you interrupt an operation that involves magtape, you must unload (with the UNLOAD command) and then load the appropriate device handler (MM, MT, or MS). *************** You can use REENTER to return to a system program or to any program that allows for a REENTER after the program terminates. You can also use REENTER after you have issued two CTRL/Cs to interrupt those programs.

*************** In the following example, the directory program (DIR) lists the directory of DK: on the line printer. Pressing (CTRL/C) twice interrupts the listing and returns you to the monitor. REENTER starts DIR at its reentry address, and DIR prompts for a line of input: ***************

Note in the example above that using REENTER does not mean that the directory listing continues from where it was interrupted, only that the DIRECTORY program recommences execution. *************** ([NO]WAIT) WAIT interrupts output to spooled device (x), while output to any other spooled device continues. If (x) is not specified, WAIT interrupts output to all spooled devices.

NOWAIT resumes output to spooled device (x) after output to that device has been interrupted. If (x) is not specified, NOWAIT resumes output to all spooled devices. *************** After you issue the UNLOAD command, RT--11 returns any memory it frees to a free memory list. The background job eventually reclaims free memory. Note that if you interrupt an operation that involves magtape, you must unload and then load (with the LOAD command) the appropriate device handler (MM, MT, or MS). ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1480]S1480AB.SDML;1 LS$PC = 1 ;LS support for both PRO 300 printer port ;and DL interfaces LS$PRI = n ;Specifies interrupt priority level M$INI = 1 ;Minimal commands *************** MQ$RES = 1 ;Message handler is resident in the monitor MQ$RES = 0 ;Message handler is non-resident in the monitor MQH$P2 = 1 ;Use 2 PARs for MQ: and interrupt forwarding MS$FSM = 1 ;TS11 file-structured support MS$UN = n ;NUMBER OF TS11 UNITS *************** ;(has hooks) XL$PDT = 1 ;Support for PDT lights display XL$PRI = n ;Specifies interrupt priority level XL$SBC = 1 ;Support for SBC-11/21 serial line and MXV ;serial-line units (including SET speed) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1480]S1480C1.SDML;1 Devices to be supported in the system you are generating Interrupt vector and control-status register (CSR) addresses for the system's physical devices Additional system conditionals you want defined *************** (Vectors and CSRs)

Identify the interrupt vector addresses and CSR addresses at which the Digital customer services technician installed each peripheral device in your configuration. *************** chapter.

Although most peripherals have standard interrupt vector and CSR addresses, some have floating addresses. The presence or absence of such ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1480]S1480C2.SDML;1 adds approximately 360(10) words to the resident monitor. Timer support reduces response time slightly because of the additional interrupt-level overhead. If your application requires timer support, you must select it. Note also that the SB monitor increments the date at midnight only if you specified that support. *************** 50 HZ CLOCK OPTION: A line clock generates periodic interrupts to allow the system to keep track of the time. The number of ticks per second depends on the power line frequency, 60 Hz or 50 Hz. RT-11 assumes a 60 Hz *************** substitute the KW11-P programmable clock as the system clock, but the KW11-P will not then be available for program use. The programmable clock normally allows you to program interrupts at preset intervals. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1481]S1481AA.SDML;2 Code cannot be moved onto the stack for execution. Interrupt service routines are not supported in separated I and D space programs, since such programs are completely outside of kernel memory. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1481]S1481AC11.SDML;1 You cannot halt FORMAT during an operation by pressing (CTRL/C) two times. If you use some other means to interrupt the program during a formatting operation, the disk or diskette involved will not be completely formatted. You will have to restart the operation on the ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1481]S1481AC15.SDML;1

You can assign initial values to memory locations 0--476 (which include the interrupt vectors and system communication area) by using an .ASECT assembler directive. The values appear in block 0 of the load module, but there are restrictions on the use of .ASECT directives in this region. You ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1481]S1481AC7.SDML;1 command until the operation completes; these three operations cannot be interrupted with (CTRL/C). To restart DUP, enter R DUP or REENTER in response ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1521]S1521.SDML;6 (Setting, Displaying, and Removing Breakpoints)

You can set up to eight breakpoints in your program to interrupt program execution and transfer control back to DBG--11. You can then use DBG--11 to examine the state of your program at the time of each breakpoint to ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1523]S1523C2.SDML;4 (MTTEMT.MAC\Multiterminal programmed request source file for system generation) (MTTINT.MAC\Multiterminal interrupt service source file for system generation) (NC.MAC\Ethernet port handler source file for system ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524C18.SDML;1 mode, type the EXIT command following the Ready message. The Ready message appears after any BASIC--PLUS execution that is completed or interrupted by pressing (CTRL/C) twice, or after any BASIC--PLUS wait condition that is terminated by pressing (CTRL/C) once. *************** BASIC--PLUS begins processing and enters an infinite loop, a series of commands that it repeats endlessly. After several lines have printed, press (CTRL/C) (CTRL/C); this interrupts execution and returns control to BASIC--PLUS command mode, as follows: *************** (simple) Under control of BASIC--PLUS only, interrupts execution of the BASIC--PLUS program and returns control to BASIC--PLUS command mode. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524C2.SDML;1 command with its /BRIEF option. After several lines have listed, interrupt the directory listing by pressing (CTRL/C) twice to abort the listing and return to monitor command mode. For example: ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524C22.SDML;1 Treating DBG--11 as a device handler is done purely for convenience. DBG--11 must interact with the monitor, the user program, and the BPT interrupt vector, and a program that looks like a device handler to the system fits that interface niche quite well. The complete DBG--11 package consists of several .SYS files and a .SAV file. *************** instruction to your program so DBG--11 gets entered when your program begins to execute. The BPT instruction causes what appears to be an interrupt through the vector at location 14. The SD handler (the DBG--11 program) handles interrrupts through location 14, so when the BPT instruction gets executed, control transfers to DBG--11. *************** to refer to the general PDP--11 registers 0 through 7.

Program execution was interrupted because of the BPT instruction at the program's start (transfer) address at the tag EXP. You can continue execution from that point now, using the DBG--11 ;P command. The ;P ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524C5.SDML;1 then the background job prints a complete line, and so on. Either job can interrupt your input at the terminal if it has a message to print. *************** The system prints the characters F(>) to remind you that you are now directing command input to the foreground job. Press (CTRL/C) twice to interrupt and terminate the execution of the foreground job and return control to the background job: ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524C8.SDML;2 That prompt informs you that at least one foreground or system job is currently loaded in your processor's memory. Soft-booting your processor could corrupt a file opened by a job or interrupt an operation being performed by a job. When you see that prompt, you should ask yourself: *************** SHOW JOBS command. Will interrupting the running of those jobs cause any problems?

At least you will want to close any file open on an editor before you soft-boot your processor. You should also consider the effect a memory rearrangement or interruption may have on any job currently loaded and perhaps running on your processor.

*************** processor. That rearrangement can lose the contents of any file open on a job such as an editor. Soft-booting your processor can also interrupt the operations of a job that is maintaining communications, performing input/output operations, or monitoring a device. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1524]S1524GLS.SDML;1 statement before translating and executing the next statement. (Interrupt) A signal that, when activated, causes a transfer of control to a *************** the routine being executed. (Interrupt-driven) Software that uses the interrupt facility of a computer to handle I/O and responds to user requests. RT--11 is such a system. (Interrupt vector) Two words containing the address of an interrupt service routine and the processor state at which that routine is to execute. *************** by hardware as a side effect of executing a processor instruction. The address location from which the jump occurs is recorded. It is distinguished from an interrupt, which is caused by an external event. (Truncation) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1525]S1525C2.SDML;1 report is the same and remains valid for all supported modems. Transfer speed enhancements were made to VTCOM for a previous release of RT-11. VTCOM sends data at the interface interrupt speed. That transfer speed can be too fast for the host terminal service to ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1525]S1525C3.SDML;1 code and completion code. If the mainline code and completion code both issue USR requests, a completion routine request may interrupt a mainline request and cause unpredictable errors.

***************

The BOOT/FOREIGN XXn: command can be used only for operating systems that tolerate interrupts enabled on device SSn: at hardware boot time. Specifically excluded from the BOOT/FOREIGN XXn: command is the case of XXDP on XXn:. *************** You cannot run DUP with the /O option (BOOT command), IND, RESORC, or SPOOL from VBGEXE. The program cannot contain interrupt service routines. The program cannot use the following programmed requests: .FORK, .INTEN, .MFPS, and .MTPS. *************** The multiterminal handler can support remote terminals. Modem control is available for both DL11--E and DZ11 interfaces. The DL11 control answers ring interrupts, letting terminals dial in to the system. Dial-in is possible with the DZ11 interface, despite lack of a ring interrupt in the DZ11, if the modem is operated in auto-answer mode. Dial-in is achieved through a polling routine that periodically checks the status of each line on the multiplexer ***************

(MTTINT)

The following problems with the multiterminal interrupt routine module have been corrected: (UNNUMBERED) *************** system job support no longer causes a branch out-of-range condition. Previously, this error occurred during the phase of SYSGEN that builds the multiterminal interrupt routine module (MTTINT).

*************** The BOOT/FOREIGN command (DUP/Q) leaves interrupts enabled on the device to be booted. It does not completely establish the hardware environment created by a CPU HALT/RESET followed by the specification of a device to a boot ROM. Some operating systems may not tolerate a hardware environment with interrupts enabled during their hardware boot code. Therefore, the BOOT/FOREIGN command is restricted to those operating systems which tolerate interrupts being enabled. The CREATE/ALLOCATE:-1 (filespec[-1]=/C) command incorrectly entered *************** The linkage established by INTSET between the processor and device priorities was performed improperly, which resulted in the processor executing the interrupt at a processor priority level that was lower than the device priority level. Now, the processor executes the interrupt when the processor and device priority levels are the same. INTSET has been removed from SYSLIB and added to the FORTRAN IV distributed FORLIB and the FORTRAN-77 distributed F77OTS libraries. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BAA.SDML;1 BATCH stream, or by typing a return on the console terminal. If a return is typed, the operator does not know exactly where the BATCH stream has been interrupted. When BATCH executes a command, it acknowledges the return and prints a return/line feed combination at the terminal. The operator can then enter a directive from ***************

In the following example, the operator must interrupt the BATCH handler to enter information from the console. As a result of a /WAIT or 'CTY' in the BATCH stream, the following message appears at the terminal: ***************

To abort BATCH while it is executing a BATCH stream, interrupt the BATCH handler by typing a return. When BATCH executes the next command after the return, it prints a return/line feed *************** Typing two CTRL/Cs terminates BATCH immediately. Use two CTRL/Cs when BATCH is in a loop or when a long assembly is running. In these cases, BATCH responds slowly to your return interrupt. (RT--11 BATCH and RSX-11D BATCH) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BC18.SDML;1

See the (SIM_BOOK) for information about debugging interrupt service routines, device handlers, multiterminal jobs, extended memory and virtual jobs. See also the (DBG_book) for a description of the DBG--11 symbolic debugging package that lets *************** Use the left-angle bracket (<) to modify a location, close it, and then open the next location of the previous sequence that was interrupted by an underline, @, or right-angle bracket command. Note that underline, @, or right-angle bracket causes a sequence change to the open word. If a sequence change has not occurred, the left-angle bracket *************** The program's status register contains the condition codes of the most (ODTaccessing internal registers) recent operational results and the interrupt priority level of the object program. Open it by typing $S. For example: *************** (carry, overflow, zero, \ITALIC)or (negative\ITALIC) (in that order) has resulted, and bits 5--7 indicate the interrupt priority level (in the range 0--7) of the object program. (Refer to the (PDP11_BOOK) for the Status Register format.) *************** a bit pattern search) ($P \Defines the operating priority of ODT ) ($S \Condition codes (bits 0--3) and interrupt priority level (bits 5--7) ) ($C \Constant register ) *************** (ODT Priority Level ($P)) $P identifies a location in ODT that contains the interrupt (or processor) (ODTpriority level) priority level at which ODT operates. If $P contains the value 377, ODT *************** contents, which you can then change: *$P/000006 4 (RET\TEXT) ;lowers the priority to allow interrupts * ;from the terminal *************** can use a device service routine that operates at a higher priority level. If you set $P low, ODT waits for terminal input at a low priority. If an interrupt occurs from a high-priority routine, the breakpoints in the high-priority routine will not be recognized because they were removed when the earlier breakpoint occurred. Thus, interrupts that are set at a priority higher than the one at which ODT is running will be serviced, but any breakpoints will not be recognized. To avoid this problem, set breakpoints at one priority level at a time. That is, set breakpoints within an interrupt service routine, but not at mainline code level. For a more complete discussion of how the PDP--11 handles priority and interrupts, refer to the processor handbook for your particular machine. ODT disables all breakpoints in the program whenever it gains control. Breakpoints are enabled when ;P and ;G commands are executed. For *************** *1000;G B0;001000 * ;an interrupt occurs and is serviced

If a higher-level interrupt occurs while ODT is waiting for input, the interrupt is serviced, and no breakpoints are recognized. (ASCII Input and Output (r;nA)) ***************

This command puts ODT into the wait state at level 0, not at level 7. If you leave ODT's priority at 7, all interrupts (including clock) are locked out while ODT is waiting for terminal input. (Functional Organization) *************** Resets processor priority to ODT's priority or user's priority. Makes sure a breakpoint or single-instruction mode caused the interrupt. If the breakpoint did not cause the interrupt, goes to step 15. Decrements repeat count. Goes to step 18 if nonzero; otherwise resets count to one. Saves terminal status. Types message about the breakpoint or single-instruction mode interrupt. Goes to command decoder. Clears T-bit in stack and internal T-bit flag. ***************

Note that steps 1--5 take approximately 100 microseconds. Interrupts are not permitted during this time, because ODT is running at priority level 7.

*************** Note the following rules concerning the ODT break routine: (unNUMBERED) If the console terminal interrupt is enabled upon entry to the ODT break routine, and no output interrupt is pending when ODT is entered, ODT generates an unexpected interrupt when returning control to the program. If the interrupt of the console terminal reader (the keyboard) is enabled upon entry to the ODT break routine, and the program is expecting to receive an interrupt to input a character, both the expected interrupt and the character are lost. If the console terminal reader (keyboard) has just read a character into *************** returns to the command decoder; otherwise, goes to step 1. (Terminal Interrupt) When *************** (NUMBERED) Saves the LSR status register (TKS). Clears interrupt enable and maintenance bits in the TKS. Saves the TT status register (TPS). Clears interrupt enable and maintenance bits in the TPS.

***************

If the TT display interrupt is enabled upon entry to the ODT break routine, the following can occur: (unNUMBERED) If no output interrupt is pending when ODT is entered, an additional interrupt always occurs when ODT returns control to the user. If an output interrupt is pending upon entry, the expected interrupt occurs when the user regains control. *************** reader data buffer is lost.

If the TT reader (keyboard) interrupt is enabled upon entry to the ODT break routine, and a character is pending, the interrupt (as well as the character) is lost. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BC20.SDML;1 follow one of the following recovery procedures. (NUMBERED) Transfer all good files from the interrupted tape to another tape and initialize the interrupted tape in the following manner: *MU1:*.*=MU0:*.* *************** Determine the sequential number of the file that was interrupted and use the /M:n construction to enter a replacement file (either a new file or a dummy) over the interrupted file. PIP writes the replacement file and a good LEOT after it. The following example assumes the bad file is the fourth file on the tape: ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BC24.SDML;1 SIPP aborts the patching procedure, and returns control to the monitor, without making any changes to your file. Any other response returns control to the procedure that was interrupted. You must press (CTRL/C) twice at any other time, including while running from a command file, to get the (?SIPP -- Are you sure?) message. *************** during the current patching session. After SIPP displays the addresses and new contents of all the locations that have changed, SIPP returns you to the operation that was interrupted.

You can use the ;V command at any time, except in response to the ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BC30.SDML;1 The (VBGEXErestrictions) program cannot contain interrupt service routines. The program cannot use the following programmed requests:

****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1708]S1481BC31.SDML;1 processor are controlled by TRANSF.

VTCOM sends data at the interface interrupt speed, but if that transfer speed is too fast for the host terminal service to process, you can slow down the baud rate or you can let VTCOM adjust the ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1763]S1763AE.SDML;1 ((CTRL/K)\1\Inserts a vertical-tab character.) ((CTRL/L)\1\Inserts a form-feed character.) ((CTRL/O)\0\Interrupts output to your screen. To recover, press (CTRL/O), and then, (CTRL/R) or (CTRL/W).) ((CTRL/Q)\0\Reenables output to your screen after a (CTRL/S).) ((CTRL/R)\1\Restores the display after you press (HELP) or after the display is interrupted or corrupted for another reason.

Restores the operation of the keypad.) ((CTRL/S)\0\Interrupts output to your screen. To recover, press (CTRL/Q).) ((CTRL/U)\1\Deletes the line to the left of the ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1763]S1763C2.SDML;1 Set the terminal error signal ((termwarn_sec)). Suppress the HELP display ((nohelp_sec)). Restore the screen display after an interruption ((restoredisplay_sec)). Stop an operation in progress ((stopoperation_sec)). *************** (HELP displays, suppressing) When you press (HELP), by default, KED displays a full-screen diagram of the keypad, thus interrupting your work session. Once you become familiar with KED, you may not need that diagram and the other full-screen HELP displays, so KED gives you a way to suppress them. *************** (Restoring the Screen Display After an Interruption\restoredisplay_sec)

(Restoringscreen display after interruption) (Interruption, restoring screen display from) (Keyboard keysCTRL/W) (CTRL/W function) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1763]S1763C9.SDML;1 The recovery operation reperforms the editing session and displays the session as it progresses. You can press (HOLD SCREEN) or (CTRL/S) to interrupt the recovery operation if you want to examine some part of the recovery more closely. Pressing again (HOLD SCREEN) or pressing (CTRL/Q) resumes the recovery operation. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560AB.SDML;11 The data and instructions in the simulation code must reside in kernel memory and must not be in PAR1 as they are accessed by the monitor from interrupt code. (Single Terminal Software Simulation)

Simulating the console terminal in a single terminal system requires redirecting either the terminal input or the output registers or both. Then, an interrupt to a redirected hardware register is directed to the software emulation. *************** (numbered) Raise the processor priority to prevent interrupts and other interference. *************** (postscript\s560ab_inafload.eps\16) (Providing an Interrupt Source\single_int_sec)

The software must simulate the action of a DL11, by using interrupts to notify the monitor of input characters, as follows: (unnumbered) Hook into the line time clock interrupt vector and use it as the interrupt source.

Save the current value in location 100. Replace the contents of 100 with the address of an interrupt routine in the simulation code. The interrupt routine determines if a console input interrupt is needed. If so, the routine can use the PIRQ hardware (if necessary) to post such an interrupt. The interrupt routine then jumps to the original contents of 100 to process the normal clock code. *************** (unnumbered) Entry from interrupt source

When the simulation code is entered by the interrupt source: (numbered) *************** Set the DONE bit in TTKS. If the IENABL bit is set in TTKS, then post an interrupt for the console input vector (60). *************** Posting interrupts

The input simulation cannot directly simulate an interrupt because the monitor may be using a priority level to synchronize operations. Instead of direct simulation, use the PIRQ hardware to post and deliver interrupts.

Interrupt dispatching for input or output (but not both) simulation is fairly simple. The interrupt dispatching for both input and output simulation is more complicated; PIRQ interrupts must be sorted out separately for input and output simulation. *************** (numbered) Raise the processor priority to prevent interrupts and other interference. *************** is discussed later. Clear @$TTPS to prevent interrupts from the actual hardware. Change the contents of $TTPS to point to a location in memory that ***************

If the IENABLE bit in PTTPS is clear and the IENABLE bit in TTPS is set, post an interrupt for the console output interrupt vector (64). Copy TTPS to PTTPS. *************** Set the DONE bit in PTTPS and TTPS. If the IENABLE bit (100) in TTPS is set, post an interrupt for the console output terminal vector (64). *************** Posting interrupts

The output simulation cannot directly simulate an interrupt because the monitor may be using a priority level to synchronize operations. Instead of direct simulation, use the PIRQ hardware to post and deliver interrupts.

Interrupt dispatching for input or output (but not both) simulation is fairly simple. The interrupt dispatching for both input and output simulation is more complicated; PIRQ interrupts must be sorted out separately for input and output simulation. *************** (numbered) Raise the processor priority to prevent interrupts and other interference. *************** simulated RCSR. Clear the hardware RCSR (pointed to by T.CSR) to prevent interrupts from the actual hardware. *************** second copy of XCSR at PTTPS.

Then, clear TTPS to prevent interrupts from the actual hardware. Change the contents of T.CSR to point to TTKS. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C1.SDML;7 area that is consistent with the one used in the FB and XM monitors. The XB monitor provides easy access to extended memory while allowing the largest possible amount of low memory space for handlers and interrupt service routines. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C2.SDML;57 Trap vectors System communication area Interrupt vectors Background job Resident Monitor (RMON) *************** (Interrupt Vectors)

(INTVEC_TAB) shows the locations in the low-memory area that are reserved for interrupt vectors. (RT--11 does not support all the devices in the table.) (INTVEC_FIG) shows how the interrupt vector area relates to the rest of memory.

(Interrupt Vectors\INTVEC_TAB) (2\8) (Location\Contents) *************** (230,232\CD11/CM11/CR11: card reader) (234,236\UDC11: Digital control subsystem) (240,242\PIRQ (programmed interrupt request)) (244,246\FPP or FIS floating-point exception) (250,252\KT11: memory management fault) ***************
(Interrupt Vector Area\INTVEC_FIG) (postscript\ml0-7361b\31.5) *************** RMON, KMON checks each word in block 0 of the file. It does not load locations that are protected, such as location 54 and the device interrupt vectors. It loads unprotected locations into memory from the USR buffer. Next, KMON sets $USRTO (location 50) to the top of the user program. *************** (XMSUBS\Extended Memory routines) (MTEMT$\Multi-terminal programmed requests ) (MTINT$\Multi-terminal interrupt service) (STACK$\RMON stacks) (PATCH$\Patch space) *************** Active device handlers Active completion routines Active interrupt service routines Active I/O buffers Queue elements from .QSET ***************

The LOCK/UNLOCK system permits one job to lock out another for a considerable length of time. During a lockout, interrupt service and completion routines can run, but not mainline code. This could cause serious difficulties in a real-time foreground program. There are some *************** magtape. Organize your real-time foreground program so that real-time operations are in interrupt service routines and completion routines and will not be affected if the mainline code is locked out with a pending USR request. *************** Typically, a real-time foreground job can be organized in three parts: an initialization phase, which opens all required channels and begins real-time operations; a real-time phase, which does interrupt service and I/O operations; and a completion phase, which stops real-time activity and closes the channels. With this arrangement, the background program can ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C3.SDML;72 The main purpose of the (Resident Monitor) (RMON) is to provide services to running programs and to the Keyboard Monitor. The services include fielding traps and interrupts, providing the programmed requests, and acting as the central manager of the device-independent I/O system. In a multi-job system, the monitor also arbitrates the demands of up to *************** (See (mtt_chap) for information on multiterminal systems.) It also describes how clock interrupts are handled and explains how timer support is implemented. The queued I/O system is discussed, scheduling for multi-job systems is described, and the system job feature is *************** programmed requests for terminal I/O. Because it uses ring buffers to implement the terminal service, RMON provides support for line-by-line editing. The terminal input interrupts are always enabled, which means that you can get the system's attention at any time by pressing CTRL/C, CTRL/B, CTRL/F, and so on. You can also type ahead to *************** will be stored and is used by the programmed requests that fill the buffer, such as .TTYOUT, .TTOUTR, and .PRINT. The GET pointer marks the next character to be retrieved and is used by the output interrupt service routine that sends characters to the terminal. The third pointer, HIGH, points to the first memory location past the buffer. Lastly, the monitor *************** (Removing a Character from the Output Ring Buffer)

The terminal output interrupt service routine removes characters from the output ring buffer. If the character count is 0, the routine terminates. The routine checks to see if the GET pointer is equal to the HIGH pointer. *************** pointing to a location that is within the buffer.

Next, the output interrupt service routine removes one character through the GET pointer and prepares to send it to the terminal. It increments the GET pointer and decrements the byte count. *************** (Storing a Character in the Input Ring Buffer)

When you type characters at the terminal, the keyboard interrupt service routine stores them in the input ring buffer. First, the routine checks to see if there is room in the buffer. If there is no room, it rings the *************** When the high-speed ring buffer is present, all character processing and interpretation is performed at fork level. The high-speed buffer is used to pass characters from interrupt level to fork level. The advantage of having the high-speed buffer is that it allows the monitor to handle short bursts of characters coming in at a very high rate. This is useful for systems *************** (CTRL/C)

When you type one CTRL/C at the terminal, the terminal interrupt service routine puts it into the input ring buffer, just as it would any other character. The monitor treats it as a line terminator and passes it to the *************** (CTRL/O)

When the terminal interrupt service routine detects a CTRL/O, it never places the character in the input ring buffer, even if it is in special mode. The monitor simply toggles a flag in the impure area. (This flag *************** A flag in RMON, called XEDOFF, indicates the XOFF/XON status. Typing CTRL/S sets the flag; typing CTRL/Q clears it. When XEDOFF is set, the monitor disables terminal output interrupts and stops emptying the output ring buffer. See the (SUG_BOOK) for a description of the SET TT: NOPAGE command, which disables *************** for more information on communicating with system jobs.) The CTRL/B, CTRL/F, and CTRL/X characters are not put into the input ring buffer. Instead, they are recognized by the input interrupt service routine (unless SET TT: NOFB is in effect, in which case the characters have no special meaning) and the monitor switches the set of ring buffers it is using.

The interrupt service routine uses two control words, TTOUSR and TTIUSR, to point to the impure area of the correct job. The job's identification is stored in a special buffer in the *************** RT--11 supports KW11--L and similar line frequency clocks, and KW11-P programmable clocks. (Support for the programmable clock is a feature that you select through system generation.) The default interrupt frequency for the clocks is the same as the line frequency. That is, the clock interrupts 60 times per second with 60 Hz power, and 50 times per second with 50 Hz power. Each time the clock interrupts, it adds one tick to the two-word time of day counter.

*************** two-word pseudoclock called PSCLOK (low-order word) and PSCLKH (high-order word). In this pseudoclock RMON stores the time, in ticks, that has elapsed since the system was bootstrapped. Each clock interrupt adds one tick to the counter. Two other words, $TIME and $TIME+2, contain a constant that, when added to the value of the pseudoclock, *************** queue roughly every 18 minutes to correct the time words.

Every time the system clock interrupts, the monitor increments the pseudoclock. It then checks the first element in the timer queue. If the high-order word of the timer element is 0 and the low-order word is *************** executes in a tight loop, waiting for a queue element to appear in the list of available elements. This condition is satisfied when a device interrupts and the handler issues the .DRFIN macro, which indicates that an I/O transfer is complete, and the monitor returns the queue element for that *************** The monitor switches to (system state )to modify important data structures and to perform operations that do not run entirely within a job. Stack operations and interrupts in system state use the monitor's stack rather than a job's stack. Jobs cannot run when the monitor is in system state, and *************** The monitor switches to system state before it puts the new element on the device handler's queue in order to prevent interference from other jobs. However, a device interrupt could remove an element from the queue while the monitor is adding the new element and adjusting the LQE and CQE pointers. To ensure the integrity of the queue, ***************

Holding a handler prevents any other process or routine from changing the I/O queue. For example, when a device interrupts and an I/O operation completes, the handler issues a .DRFIN call to return to the monitor and remove the current queue element from the I/O queue. Depending on the type *************** After the monitor and a device handler have started up an I/O transfer, a peripheral device performs the actual operation and interrupts when it is finished. The interrupt causes control to pass to the device handler's interrupt service section, where the code assesses the results of the I/O operation and restarts it if necessary. When the transfer is done, the handler uses the .DRFIN *************** (Completing the I/O Request)

When a device interrupts, an I/O transfer completes, and the handler issues the .DRFIN call, it is the monitor that must take the appropriate action to complete the I/O procedure. In general, this *************** I/O request could cause the monitor to hold the handler while it adds an element to the queue. In this case, the monitor simply sets a flag, dismisses the interrupt, and returns to the interrupted process, removing the element later.

*************** the I/O queue element into a completion queue element and puts it at the end of the job's completion queue. Then, the monitor returns control to the process or program that was interrupted.

If the element does not specify a completion routine address, the monitor simply returns the element to the available list. Control returns to the process or program that was interrupted, or the scheduler can run. (Scheduling in Multi-Job Systems) *************** and run as part of the user job in (user state). Any routines that run outside a job's context, including interrupts, use the monitor's stack and execute in (system state). This arrangement allows the monitor to (unwind) the stack after a series of interrupts without changing jobs or stacks.

*************** interference from other jobs. The monitor uses system state for operations that do not run entirely within a job context. These operations, which must not be interrupted by context switching, include the following: (UNNUMBERED) Blocking a job *************** Interlocking the USR Executing any mapping programmed request Servicing an interrupt Executing device handler code (except for .TIMIO completion routines and .SYNCH routines, which run in user state in a specific ***************

The monitor switches from user state to system state asynchronously whenever an interrupt occurs. As a result of the interrupt the monitor may modify important data structures. The switch to system state prevents interference from a context switch while the modifications *************** job's stack to the system stack. In mapped systems, the monitor does not perform the stack switch because the hardware does it automatically. Subsequent interrupts that occur in system state put information on the system stack. Note that these subsequent interrupts do not cause another switch to system state. (Interrupt Level Counter)

The monitor recognizes three levels of execution state. It uses a counter called INTLVL to distinguish among the three levels. Every interrupt increments this counter. When INTLVL is -1, execution is in user state. When INTLVL is 0, execution is in system state at level zero. When INTLVL is positive, execution is still in system state, but at a deeper interrupt level. (INTLVL_TAB) summarizes the relationship between the number of interrupts pending and the execution state.

(Values of the interrupt Level Counter (INTLVL)\INTLVL_TAB) (3\10\10) (Number ofInterrupts\Value ofINTLVL\Execution State) (0\-1\User State) (1\0\System State Level Zero) ***************

(INTEFFECTS_FIG) shows how interrupts influence the flow of events in a running system.

(Interrupts and Execution States\INTEFFECTS_FIG) (POSTSCRIPT\S560C3INTEFFECTS_FIG.EPS\28) *************** ($INTEN Monitor Routine)

When an interrupt occurs, control passes to the routine specified in the interrupt vector, and the current PS and PC are put on the job's stack. In RT--11, both device handlers and in-line interrupt service routines call the monitor at the common interrupt entry point, $INTEN. Device handlers use the .DRAST macro to call the monitor; in-line interrupt service routines use the .INTEN macro.

$INTEN is the monitor routine that performs the switch to system state. The routine assumes that it was called because an interrupt occurred. Therefore, it expects the old PS and PC to be on the job's stack. The priority should be 7, and the interrupt service routine must not have destroyed any registers between the time the interrupt occurred and the time $INTEN was called. Device handlers generally call the monitor immediately, before any processing is done. In-line interrupt service routines sometimes perform crucial operations immediately, at priority 7, then call $INTEN to lower processor priority to device priority. *************** (0\R4\$INTEN) (2\R5\.DRAST macro (JSR R5)) (4\PC\Interrupt) (6\PS\Interrupt)

*************** job's stack pointer in a memory location and switches to the system stack. $INTEN then lowers processor priority to device priority, and calls the device handler or interrupt service routine back as a coroutine. The interrupt service routine continues to execute in system state. ***************

The monitor switches to system state synchronously -- that is, without depending on an interrupt -- whenever other monitor routines need to go to system state temporarily to ensure the integrity of a certain operation. In these circumstances, the monitor routines can call the $ENSYS routine to *************** job (rather than in the monitor) needs to switch to system state. The routine can do this by artificially mimicking an interrupt and using the .INTEN macro to call the $INTEN monitor routine. *************** The $ENSYS routine is voluntarily and synchronously called by any other monitor routine that needs to switch to system state. $ENSYS mimics an interrupt by altering the job's stack so it duplicates the stack condition immediately after an interrupt. Routines call $ENSYS by using the following instructions: ***************

(ENSYSSTACK_TAB) shows how $ENSYS manipulates the stack to imitate an interrupt.

(Job's Stack After $ENSYS\ENSYSSTACK_TAB) *************** MOV @SP,-(SP) ;MAKE ROOM ON THE STACK CLR 2(SP) ;FAKE INTERRUPT PS = 0 .MTPS #340 ;GO TO PRIORITY 7 .INTEN 0,PIC ;ENTER SYSTEM STATE *************** Any routine that is executing in system state issues an RETURN instruction when it completes. The monitor (unwinds) its stack from one or more interrupts as each RETURN instruction is issued. As each routine completes, the monitor decrements the INTLVL counter.

When INTLVL is greater than 0, it indicates that the routine that was just interrupted was executing in system state. The monitor defers some special chores until it is just about to return to user state. If it is time to decrement INTLVL after a RETURN instruction, and the value of INTLVL is *************** Is there an outstanding fork routine? (Fork routines run before jobs or their completion routines.) Is a scheduling pass required? (As a result of an interrupt, a job that was previously blocked may now be runnable.) Are there outstanding clock ticks? (The monitor may need to normalize its time of day counter and check the timer queue.) Is there an outstanding floating-point interrupt?

*************** switching by saving and restoring the context only when it runs a different job. This is a significant saving because there are many situations in which a job is running, an interrupt triggers a switch to system state, and control passes back to the same job once the interrupt is serviced.

When the monitor saves a job's context, it preserves (does not modify) *************** tests for a pending completion routine by checking a status bit in I.STATE. If the job's completion queue has a completion queue element on it, the monitor puts a pseudointerrupt on the job's stack to call the completion queue manager when the scheduler actually starts up the job. *************** (The .TTYOUT, .PRINT, .MTOUT, and .MTPRNT programmed requests.\13TTOWT$20000\The monitor's terminal output interrupt service routine, when there is room in the output ring buffer.) *************** .MTIN, .CSISPC, and .GTLIN programmed requests.\14TTIWT$40000\The monitor's terminal input interrupt service routine, when a line or character is available.) *************** (point (A)).

$SYSWT runs the decision subroutine twice because interrupts can occur while $SYSWT is running. Since an interrupt can signal the removal of a blocking condition, the job's status can change even as $SYSWT is trying to determine it.

An interrupt can occur after the decision subroutine (point (A)) declares a job to be blocked, but before $SYSWT sets the blocking bit. This time interval is shown as (Window 1) in (SYSWT_FIG). *************** (Window 2) in (SYSWT_FIG) indicates the second time interval in which an interrupt can occur. The interrupt can remove the blocking condition immediately after $SYSWT correctly sets the blocking bit. In this case, the monitor's UNBLOK routine clears the *************** set.

When an interrupt occurs, control passes to an interrupt service routine. The interrupt routine enters system state by executing the $INTEN monitor routine. Then, the interrupt service routine assesses the meaning of the interrupt and takes appropriate action. In a device handler, for example, an interrupt can indicate that an I/O transfer is complete. The handler returns to the monitor to remove the current element from the I/O queue.

***************

The scheduler runs just before the monitor returns to a job. Remember that INTLVL, the interrupt level counter, is 0 when it is time to return to user state.

A scheduling pass needed to make a job runnable happens asynchronously, as a result of an interrupt that removed a blocking condition. A scheduling pass needed to make the current job nonrunnable happens synchronously, after a job issues a programmed request, after the *************** The scheduler runs only if INTACT is not equal to 0. When INTACT is 0, it indicates that no job changed its status, and, therefore, the same job that was interrupted should run again. When INTACT is not 0, it contains the number of the highest-priority job that changed its status. The scheduler runs only if the job number in INTACT is greater than the current number of *************** A job's completion routine can run even though the mainline program is blocked. When an asynchronous event occurs, such as the completion of an I/O request, the interrupt service routine enters system state through the $INTEN monitor routine. The device handler's interrupt service routine returns to the monitor when I/O completes, so the monitor can remove the I/O queue element from the device handler's queue. If the I/O *************** problem because extended memory is available to the system. Only a job's impure area, queue elements, channels, and (for privileged jobs) the interrupt service routines must reside in low memory. And like the USR, those four parts of a job cannot reside in the PAR1 area. The rest of the job can reside in extended memory. *************** generate code which uses kernel PAR2 to map the user buffers. In this case, all the kernel PAR1 restrictions also apply to PAR2. So, the USR, queue elements, channels, and interrupt service routines cannot reside within locations 20000 through 60000 in a system that actually uses the MQ handler. Note that you cannot run completely virtual jobs when a *************** (1\Bits have meaning only if global SCCA is enabled.) (Offset\Symbol\ByteLengthin Octal\Description) (0\$RMON\4\Common interrupt entry point; contains the instruction JMP $INTEN. The .INTEN macro uses it.) (4\$CSW\240\Background job channel area (16(10) *************** (322\$JOBNU\2\The executing job's number.) (324\$SYNCH\2\Address of monitor routine to handle .SYNCH requests. Your interrupt routines can issue the .SYNCH programmed request, which enters the monitor through this address to synchronize with the job they are servicing.) *************** 244--246 250--252 (for mapped systems only) The system device handler interrupt vector Interrupt vectors for loaded device handlers Vectors for all interfaces supported in a multiterminal system *************** (12\SP$SCN\1 = Print screen (CTI bus-based computers only).) (13\SP$GTM\1 = Date and time request for flag pages.) (14\SP$IEN\1 = Fake interrupt enable.) (15\SP$ERR\1 = Error bit (set by SPOOL).) *************** line count.) (-\I.IRNG\2\Input ring buffer low limit.) (-\I.IPUT\2\Input PUT pointer for interrupts.) (-\I.ICTR\2\Input character count.) (-\I.IGET\2\Input GET pointer for .TTYIN.) *************** (-\I.OCTR\1\Output character count.) (-\I.CTLO\1\^C flag) (-\I.OGET\2\Output GET pointer for interrupts.) (-\I.OTOP\2\Output ring buffer high limit.) (-\------\TTYOUT\Output ring buffer.) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C4.SDML;66 example), this job can unmap them and remap the addresses to memory above 28K words. It must leave certain areas mapped whenever a user interrupt service routine could run.) (Benefits\ *************** remapped.

Since interrupt service routines execute in kernel mapping, privileged jobs containing user interrupt service routines should not change the mapping of interrupt service routines, the I/O page, or parts of the monitor during any time period in which an interrupt could possibly occur. The monitor depends on the fact that kernel and user mapping are identical when it services user interrupts. (Privileged Background Job) ***************

It cannot contain interrupt service routines. No .REL linking is allowed. *************** of the run-time operating system software and must not be corrupted by other programs. RT--11 uses the processor's kernel mode for RMON and the USR, for interrupt service routines, and for device handlers, including .SYNCH and .FORK routines. Interrupts and traps vector through kernel mapping and cause execution to continue in kernel mode.

***************

Make all the programs virtual jobs, unless they really need access to the interrupt vectors in the SYSCOM area. Instead of using interrupt service routines in your program, consider writing a device handler. Special functions requests allow a great deal of flexibility in writing special handlers ***************

The root segment can be minimal in size. All you need put there are queue elements, channels, interrupt service routines (if any - there can be none in virtual jobs), and a JMP instruction to the first overlay. The overlay segments can be permanently resident in extended memory to speed up *************** not be located within the addresses 20000 through 37777. Remember to allow 10(10) words per queue element. Interrupt service routines must be located entirely within the low 28K words of memory. In addition, if your single-mapped monitor has been generated *************** in the range 20000 through 37777. (isr_chap) describes the factors you must take into consideration if your program includes an in-line interrupt service routine. Be sure to execute your program as a privileged job if it contains an interrupt service routine, so that it can access the monitor and the device I/O page. ***************

This aspect of RT--11's design is important for you to understand if you have a program with its own in-line interrupt service routine, if you put a data buffer for I/O in extended memory, or if you write a device handler for a single-mapped system. *************** that case, all the PAR1 restrictions apply as well to the virtual addresses in the range 40000 through 57777, controlled by PAR2. Therefore, the USR, queue elements, channels, and interrupt service routines cannot reside within locations 20000 through 57777 (kernel PARs 1 and 2) in a system that is actively using the MQ handler. Note that the QUEUE *************** (Synchronous System Traps)

A synchronous system trap is a software interrupt that takes place synchronously with your program's execution. For example, a TRAP instruction that a program issues is a synchronous system trap. A program ***************

In a mapped system, synchronous system traps, like device interrupts, take the new PS and PC from the appropriate vector in kernel space. For example, when a program issues a BPT instruction, the new PS and *************** for instructions on using ODT.

VDT does not contain the interrupt service or priority routines that ODT does. Unlike ODT, which runs at priority 7 and performs its own terminal I/O, VDT runs at the same ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C5.SDML;54 In describing the multiterminal feature of RT--11 this chapter provides background information on the hardware and describes the data structures of a multiterminal system. It also describes the interrupt service and polling routines, the programmed requests available to application programs, and typical situations in which you can use two terminals without *************** MTTEMT.MAC processes the multiterminal programmed requests. MTTINT.MAC contains the multiterminal interrupt service and polling routines. TRMTBL.MAC defines the multiterminal terminal control *************** the standard console addresses for diagnostic purposes and for operator communication at bootstrap time. Your hardware console interface must be a local DL. Its interrupt vectors are located at 60 and 64 in low memory, and its LUN is always 0.

*************** connect to the port controller on a terminal line without regard for the interface to which it is ultimately connected. The multiterminal interrupt service manages the port controller. Such support is called (multiterminal handler hooks) and the (hooks) are the connection between the handler and the interrupt service.

Multiterminal handler hooks support is valid for DH, DL, and *************** point contains the RAD50 physical name of the handler.

The basic protocol between the monitor interrupt service and the device handler is as follows: (numbered) An interrupt occurs and the interrupt service routine in the multiterminal monitor is entered. If the line on which the interrupt occurred is not attached by a handler, the interrupt is processed normally. If the line on which the interrupt occurred is attached by a handler (HANMT$ is set in T.STAT), the interrupt service code passes control to the handler hook routine (using the address in T.OWNR).

R0 indicates the type of interrrupt and R5 is used to pass characters between the handler and the interrupt service code.

If the monitor is passing a character to the handler (an input interrupt), the monitor clears R0 (function code TH.PIC) and passes the character to the ***************

If the monitor is requesting an output character from the handler because of an output interrupt, the monitor places the value 1 in R0 (function code TH.GOC) and calls the handler hook code, which returns a character in R5 with carry clear. *************** (numbered) The monitor interrupt service calls routine OUTCHR. OUTCHR calls the handler hook entry point (found in T.OWNR in that *************** When the monitor receives an interrupt request and that LUN is attached to a handler (the handler called the MTOENB routine): (numbered) The monitor interrupt service calls routine INCHAR. INCHAR calls the handler hook entry point at T.OWNR *************** initiate output but rather only responds to the monitor. The handler uses MTOENB to tell the monitor that it should enable output interrupts for the terminal line. The MTOENB offset calls the monitor's output interrupt routine, TTOENB.

MTOENB is called *************** MOV TCBADX,R3 ; R3 -> TCB CALL @MTOENX ; Enable output interrupts TCBADX: .BLKW ; Points to TCB *************** (DLCTS$\020000\Clear to send) (DLDCD$\010000\Data carrier detect) (DLRIE$\000100\Receiver interrupt enable) (DLTIE$\000100\Transmitter interupt enable) (DLRTS$\000004\Request to send) *************** the bootstrap could not find the CSR; this makes the LUN unusable.) (20\T.VEC\Contains the first interrupt vector for this terminal.) (22\T.PRI\Contains the device interrupt priority.) (24\T.JOB\Contains the job number of the job that currently *************** (5\WRWT$\This is the TT handler synchronization bit.) (6\INEXP$\Indicates that an output interrupt is expected.) (7\PAGE$\Indicates that the terminal has sent XOFF to *************** Note that a program must issue the .SCCA programmed request to inhibit CTRL/C on its console terminal. (Interrupt Service)

Terminal service in multiterminal systems is centralized in the routines *************** (Local Terminals)

RT--11's interrupt service routine for multiterminal systems contains the following data structures: (UNNUMBERED) ***************

RT--11's interrupt service is essentially simple. The bootstrap sets the input (or receiver) interrupt enable bit; the monitor leaves it set at all times. If a character is typed on a local terminal, an interrupt occurs and the monitor picks up the character. If the terminal is not attached to any job, the character is ignored. In multiterminal systems with time-out support, the monitor ensures that the interrupt enable bit for each DL is enabled once every 30 clock ticks (every half-second).

The monitor only sets the output interrupt enable bit when it is ready to print a character. It clears the bit after the output ring buffer is empty. (Remote Terminals) *************** Remote terminals are connected to RT--11 through modems (also known as data sets) and telephone lines so that someone can call up the computer and ring its data phone. When this occurs, it causes an interrupt, which the monitor recognizes. If the unit is attached, the multiterminal service routine answers the phone call and sends out carrier in response. (Carrier is a *************** available to application programs through the .TIMIO programmed request. RT--11 executes this routine once every half second. Its purpose is to periodically reenable the I/O interrupt enable bits on DL interfaces so that noise on a line or local static electricity cannot seriously affect transmissions.

The polling routine examines each DL line on the system every half second. It turns on the line's input interrupt enable bit and, if the line is remote, its modem interrupt enable bit. Then, if output is pending with no output interrupt, it turns the output interrupt enable bit off and then on, to force an output interrupt on the line. (Depending on the hardware failure that caused the loss of the output interrupt, this may occasionally cause a character to be repeated.)

***************

The DZ polling routine polls the terminals connected to the system through DZ interfaces. It is necessary because these terminals do not interrupt when their status changes.

****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560C6.SDML;22 (Old SSM Chapter 6) (Interrupt Service Routines\ISR_CHAP)

This chapter describes the ways a program (as opposed to a device handler) can transfer data between memory and a peripheral device. First it covers noninterrupt programmed I/O; next it introduces the concept of using interrupts to handle device I/O by comparing the advantages and disadvantages of in-line interrupt service routines and device handlers. After these general points have been discussed, the chapter continues with a description of the structure of an interrupt service routine, and shows in detail how to organize and write one. A skeleton example of a foreground program that contains an interrupt service routine ends this discussion of applications. The discussion is followed by a final section dealing with the considerations involved in using interrupt service routines in a single-mapped, extended memory environment. (Noninterrupt Programmed I/O)

One way to move data between memory and a peripheral device is to use noninterrupt programmed I/O. According to this method, your program operates with the device interrupts disabled and uses flags to coordinate the data transfer. Your program checks the ready bit in the status register for a particular device, moves the data when appropriate, and then either *************** for printing this error message.

In an application program, noninterrupt programmed I/O can provide the quickest response to an external event with interrupts disabled.

The following lines of code from RMON demonstrate noninterrupt programmed I/O:

*************** time, the handler first requests a read of one sector. The diskette completes the read operation, places the data in an internal silo, and issues an interrupt. The handler then disables diskette interrupts and uses programmed I/O to move data from the silo into memory. When it is ready to read another sector, the handler enables interrupts again.

The following lines of code are from a DX handler: ***************

Refer to the (PDP11_BOOK) for your computer for more information on noninterrupt programmed I/O. (Interrupt-Driven I/O)

Although programmed I/O is useful in a few situations, generally the best way to handle device I/O is through interrupt processing. According to this method, a program starts an I/O transfer but continues processing. When the transfer completes, the device issues an interrupt. An interrupt service routine then determines whether the transfer is incomplete, complete, or has encountered an error. It takes the appropriate action (restarting the transfer, returning to the program, or possibly retrying the transfer in case of error). The advantages of using interrupt-driven I/O are that it enables two or more processes to run concurrently and it does not monopolize system resources. (How an Interrupt Works)

An interrupt is a forced transfer of program execution that occurs because of some external event, such as the completion of an I/O transfer. The state of the processor prior to the interrupt is saved on the stack so that processing can continue smoothly after the return from the interrupt. The processor saves the Processor Status word, or PS, which reflects the current machine state, and the Program Counter, or PC, which indicates the ***************

Next, the processor loads new contents for the PC and PS from two preassigned locations in low memory, called an (interrupt vector). These words contain the address of the interrupt service routine and the new PS, which indicates the new processor priority. When the interrupt service routine completes, it executes an RTI instruction, which restores the old PS and PC from the stack, and execution resumes at the interrupted point in the original program. (Device and Processor Priorities)

Interrupt processing is closely related to device and processor priorities. (ISRRPS_FIG) illustrates the RT--11 priority structure. Each device on the system has a priority assigned to it and devices that must be serviced as soon as possible after they interrupt have the highest priority. Disks typically have priority 5; terminals and other character-oriented devices usually have priority 4. *************** the ordering of devices with the same priority. For these devices, the one closest to the CPU on the bus is serviced before other devices when interrupts occur simultaneously.

(RT--11 Priority Structure\ISRRPS_FIG) *************** from 0 to 7. (Some older processors are an exception; they operate at either 0 or 7.) When the CPU is operating at priority 7, no device can interrupt it with a request for service. When the CPU is operating at a lower priority, only a device with a higher priority can cause an interrupt. You can adjust the processor's priority from within an interrupt service routine by modifying the Processor Status word. In an RT--11 system, software tools are provided to do this for you, so you never directly modify the PS yourself. The tools include *************** and the .INTEN and .FORK macros.

The interrupt system allows the processor to continually compare its own priority with that of any interrupting devices and to acknowledge the device with the highest level above the processor's. This system can be nested -- that is, the servicing of one interrupt can be left in order to service an interrupt with a higher priority. Service continues for the lower priority device when the higher priority device is finished.

See the (PDP11_BOOK) for your computer for more information on priorities and interrupts. (Processor Status (PS) Word) *************** determines the priority; priority is either 0 or 7.) By changing bits, you alter the CPU's priority. You can change the priority to 7, for example, to prevent any more interrupts from occurring. When you are servicing a particular interrupt, you can change the processor priority to the priority of that device so that only devices with a higher priority will interrupt that service routine. (Specifically, the device you are servicing cannot interrupt.) In general, you need not access the PS yourself; use the macros provided in RT--11, such as .INTEN and .FORK, to change the processor priority. *************** (In-line Interrupt Service Routines Versus Device Handlers)

Because both noninterrupt programmed I/O and interrupt-driven I/O are valid processes in an RT--11 system, when you need to interface a new device to your system -- one that is not already supported by RT--11 -- your first decision must be whether to use in-line interrupt service or to write a device handler for it. Whatever your decision, both interrupt service routines and device handlers can include noninterrupt programmed I/O sections as well as interrupt-driven code. The normal RT--11 interface between the monitor and a peripheral device is a device handler, which exists as a memory image file on a mass storage device, and resides in memory when it is needed to perform device I/O (see (scm_chap)). A device handler usually includes an interrupt service routine within it.

If you choose to use an interrupt service routine, you must place the routine within your program so that your program directly changes the status and buffer registers for a specific device, and it can service the interrupts within its own code. This means, of course, that the interrupt service code must always be resident in memory.

On the other hand, if you choose to use a device handler, the interrupt service code is contained within the handler, not in your program. You issue .READ and .WRITE programmed requests from your main program, and the monitor and the handler together initiate the data transfer, service the interrupts, and notify your program when the transaction is done. In a single-job system, or for a background job in a multi-job system, *************** How you decide which method is more suitable for your new device depends largely on how you want the device to appear to system and application programs. In general, you might use in-line interrupt service for sensor or control devices, such as analog-to-digital converters. You should service devices that appear to be block-replaceable, file-structured mass *************** rests on other criteria.

The two major advantages of in-line interrupt service routines are their speed and the amount of control information they provide. Because there is no monitor overhead involved in a data transfer, an in-line routine can often handle interrupts faster than a device handler can. If the speed of servicing interrupts is crucial to your application, you may choose to write an in-line interrupt service routine even if the device is a disk.

An in-line routine has access to all the device control and status *************** the handler does not.) It can pass a lot of information to the program. This provides a great deal of flexibility in the way the program calls the interrupt service routine, and in the amount of information the routine returns to it.

*************** programs without any special modification. (In addition, a device handler for a random-access device makes the RT--11 file system available on the device at no extra cost.) In contrast, an in-line interrupt service routine makes the new device available to just one application program.

***************

(ISRIISR_FIG) highlights some differences between in-line interrupt service routines and device handlers.

(In-line Interrupt Service Routines and Device Handlers\ISRIISR_FIG) (POSTSCRIPT\ML007422B\44)

If you decide that your new device requires an in-line interrupt service routine, read the rest of this chapter to learn how to plan and write one. If you decide that a device handler is more suitable, read the rest of this *************** write, and debug a handler. (How to Plan an Interrupt Service Routine)

The most important part of writing an in-line interrupt service routine is taking the time to plan carefully. Follow these guidelines: (UNNUMBERED) Get to know your device Study the structure of an interrupt service routine Study the skeleton interrupt service routine Think about the requirements of your program Prepare a flowchart of your program *************** (Get to Know Your Device)

Getting to know your new device is crucial to writing an interrupt service routine that works correctly. If your device is a Digital peripheral, consult the hardware reference manual for that device. *************** (UNNUMBERED) What is the interrupt vector (or vectors) for the device?

Decide what the interrupt vector should be. Consider both conflicts with existing RT--11-supported devices and also conflicts with devices supported by other PDP--11 operating systems, if you use those systems. *************** Learn how to initiate the various operations by manipulating the bits in the device registers. When does the device interrupt?

Some devices interrupt for each character; others are word-oriented, block-oriented, or packet-oriented. Some devices interrupt twice for certain operations, such as seek or drive reset. Find out if your device does this, and plan now to take this information into account later. *************** (Study the Structure of an Interrupt Service Routine)

(ISRSTRUCT_SEC) describes the structure of an interrupt service routine. Read this section carefully. (Study the Skeleton Interrupt Service Routine)

(ISRSKEL_SEC) contains a skeleton outline of a foreground job with an in-line interrupt service routine. Study this outline to be sure you understand the flow of execution. (Think About the Requirements of Your Program)

Remember that the interrupt service routine is part of your program and decide where to place it in the program. Review the material in (scm_chap) *************** Many experienced programmers prepare flowcharts after all their programs are written, or they omit them entirely. However, flowcharting a system with the complexities of interrupt service can help you find loose ends and point out errors in your logic. Flowcharts are not much help, unfortunately, in pointing out potential race conditions. (A race condition *************** data structure at the same time; as a result, the data structure is corrupted and the integrity of the processes is compromised. It may be caused by a device interrupting while its interrupt service routine is running, due to improper processor priority.) When you design your program, examine every step carefully; keep in mind what would happen if an interrupt occurred at each instruction. This kind of planning can help you avoid race conditions later.

***************

If you have followed the recommended steps so far, writing the code for the interrupt service routine itself should be relatively simple. You can borrow as much code as possible from other interrupt service routines you have studied. Start with a general outline, then add details to reflect the specifics of your particular device. When you are satisfied with the code, *************** (Test and Debug the Program)

The only way to test a program with in-line interrupt service is to try executing it. If the program is operating correctly, it should be able to read or write data accurately, should not lose any data, and should handle *************** reassemble the program, and retry it as necessary. (Structure of an Interrupt Service Routine\ISRSTRUCT_SEC)

The following sections outline the general structure of an in-line interrupt service routine. Read them carefully and determine which items apply to your own situation. *************** In systems where more than one job can be running, you should use the .PROTECT programmed request to protect an interrupt vector before you move a value to it. This process makes sure that the vector does not already belong to the monitor or to another job. It gives ownership of the *************** your program needs to run in a multi-job environment. (Setting up the Interrupt Vector\isrprot_setup_sec)

Your program must take care of moving the address of your interrupt service routine to the first word of the interrupt vector. RT--11 requires all interrupts to raise the processor priority to 7, so your program must fill in the second word of the interrupt vector with 7 as the new priority. The following lines of code show a typical way for a program to set up the two-word interrupt vector. Note that a program should not set up a vector until the vector is protected. For this example, assume the device name is XX, and the interrupt vector is at 220 and 222. *************** DEVPRI = 5 ; Device priority = 5 (0-7, not 000-340) xxCSR = nnnnnn ; The device control register IENABL = 100 ; Interrupt enable bit START: .PROTECT #AREA,#xxVEC ; Protect the vector *************** ; service routine and to initialize other pointers and flags SPND: BIS #IENABL,@#xxCSR ; Enable interrupts .SPND ; Wait until there is some data *************** . ; ** INTERRUPT SERVICE ROUTINE ** ISREP: . ; The interrupt entry point . ; (priority is 7) . *************** BR SYNERR ; .SYNCH returns here on error .RSUM ; Wake up main program RET: RETURN ; Wait for another interrupt SYNBLK: .WORD 0,0,0,0,0,-1,0 ; Job number is filled in by code at START *************** The .DEVICE programmed request turns off a device (by clearing its interrupt enable bit) if its associated program is aborted or when the program exits. (See the (SML_BOOK) for the format of the *************** (Lowering Processor Priority: .INTEN)

When an interrupt occurs, control passes to your interrupt service routine entry point the address you supplied as the first word of the interrupt vector. At this point, the processor priority is 7, and all other interrupts are prohibited. If you need to do anything with all interrupts disabled, this is where the code belongs. It should be as short and efficient as possible and should not destroy the contents of any registers. *************** before issuing the .INTEN call. If the code executed at priority 7 is too long, system interrupt latency (a measure of how quickly the system can respond to an interrupt) will suffer. A good guideline is to spend no more than 50 microseconds at priority 7.

You should lower the processor priority to that of the device as soon as possible. This means that only devices with a higher priority than this one will be able to interrupt its service routine. To lower the priority, use the .INTEN programmed request. The stack pointer and general registers R0 through R5 must contain the same values when your interrupt service routine issues the .INTEN request as they did at the interrupt entry point. If your interrupt service routine is not written in Position-Independent Code (PIC), use the following format: ***************

If your interrupt service routine is written in PIC, use the .INTEN call with a second argument, (PIC). *************** Both formats cause a JSR to the monitor's INTEN routine, which lowers the processor priority and switches to system state. The monitor then calls the interrupt service routine back as a co-routine. R4 and R5 are available for use on return from the call. You must not destroy the contents of any other registers. If *************** In unmapped systems, a .INTEN causes a switch to the system stack, so you should avoid using the stack excessively once you are in your interrupt service routine. In mapped systems, the stack is switched to the kernel stack upon entering the ISR. *************** Saving values in memory locations may prevent your interrupt routine from being reentrant. If you intend to use the routine for multiple devices, be careful about reentrancy when you design it. *************** (ISRSKEL_SEC) of this chapter for an example using .INTEN. See (ISRIFSSUM_SEC) for a summary of the interrupt service routine macro calls.) (Issuing Programmed Requests: .SYNCH) *************** Its purpose is to make sure that the correct job is running when an interrupt service routine executes a programmed request. Even though the .SYNCH call has no meaning in a single-job system, it is advisable to use ***************

If you need to issue one or more RT--11 programmed requests from the interrupt service routine, you must first issue the .SYNCH call. Remember that the .INTEN call switched execution to *************** .SYNCH call itself handles the switch back to user state. Note that you should never issue programmed requests requiring the USR from within an interrupt service routine, even after using .SYNCH. You can also issue .SYNCH after .FORK, *************** .SYNCH request executes as a completion routine, in user state, at priority 0. Because of this, your program must either disable interrupts before the .SYNCH call, or it must be prepared for the device to interrupt again before the .SYNCH code executes. The synch block is available for reuse when *************** for an example using .SYNCH. See (ISRIFSSUM_SEC) for a summary of the interrupt service routine macro calls. (Running at Fork Level: .FORK\ISRFORK_SEC) *************** is a first-in, first-out list. Fork routines (all the code following a .FORK call) execute in system state at priority 0, after all interrupts have been serviced, but before the monitor switches to user state. Context switching is inhibited as well during the time fork routines are executing. *************** .INTEN call returned to you. See (ISRIFSSUM_SEC) for a summary of the interrupt service routine macro calls. Note that you cannot issue .FORK without a prior .INTEN call. *************** .FORK request. Because a .FORK routine should not be reentrant, make sure that the device cannot interrupt between the time you issue the .FORK call and the time the .FORK routine (the code following the call) ***************

Generally, .FORK is used in device handlers. To use it in an interrupt service routine, you must first set up a pointer called $FKPTR. The recommended way to do this in a main program is as follows: ***************

Then, in the interrupt service routine, you can use the normal form of the .FORK macro: ***************

Note that in your interrupt service routine, no registers are free for use before the .INTEN call. After the .INTEN, you can safely use R4 and R5. See (ISRIFSSUM_SEC) for a summary of the interrupt service routine macro calls.

The .FORK request has several applications in a real-time environment because it permits lengthy but noncritical interrupt processing to be postponed until all other interrupts are dismissed. Further, the .FORK request (unlike .SYNCH) does not cause a context switch, which is a lengthy process.

The .FORK request returns at priority 0, but only when all other interrupts have been dismissed and before control is returned to the interrupted user program. (Note that you dismiss an interrupt when you leave interrupt level, by any one of several means.) (Summary of .INTEN, .FORK, and .SYNCH Action\ISRIFSSUM_SEC) *************** describes the status of the registers for each call.

(Summary of Interrupt Service Routine Macro Calls\ISRSUMMARY_TAB) (5\8\8\8\18) (1\In mapped systems, all are kernel stack; in unmapped ***************
(Summary of Registers in Interrupt Service Routine Macro Calls\ISRREG_FIG) (POSTSCRIPT\ML007423B\30.5) ((POSTSCRIPT\S559C1ISRREG_FIG.EPS\24)) (Exiting from Interrupt Service)

The .INTEN request causes the monitor to call your interrupt service routine as a co-routine. At the end of your routine, when it is time to exit, use a RETURN instruction. This returns *************** registers that must be preserved have their original contents. (Skeleton Outline of an Interrupt Service Routine\ISRSKEL_SEC)

(SKELETONISR_FIG) shows a foreground main program that contains an in-line interrupt service routine. The foreground program performs some initialization tasks and then suspends itself. When data is available from a peripheral device, the interrupt service routine collects it. When all the data is gathered, the interrupt service routine resumes the main program, which can then process the new information before suspending itself again. The main program's processing *************** For this example, (xx )represents the device name.

(Skeleton Interrupt Service Routine\SKELETONISR_FIG) (\MULTIPAGE) *************** DEVPRI = 5 ; Device priority = 5 (0-7, not 000-340) xxCSR = nnnnnn ; The device control register IENABL = 100 ; Interrupt enable bit START: .PROTECT #AREA,#xxVEC ; Protect the vector *************** ; service routine and to initialize other pointers and flags SPND: BIS #IENABL,@#xxCSR ; Enable interrupts .SPND ; Wait until there is some data *************** . ; ** INTERRUPT SERVICE ROUTINE ** ISREP: . ; The interrupt entry point . ; (priority is 7) . *************** BR SYNERR ; .SYNCH returns here on error .RSUM ; Wake up main program RET: RETURN ; Wait for another interrupt SYNBLK: .WORD 0,0,0,0,0,-1,0 ; Job number is filled in by code at START *************** (Interrupt Service Routines in Mapped Systems\ISRXM_SEC)

If you are not planning to execute your program in a mapped environment, you ***************

Of the two kinds of jobs in a mapped environment, virtual jobs and privileged jobs, virtual jobs cannot contain in-line interrupt service routines (see (xm_chap)). Virtual jobs cannot directly access the real vectors but instead use virtual vectors.

If a job containing an in-line interrupt service routine must run in a mapped environment, it must run as a privileged job. Privileged mapping makes the low 28K words of memory and the I/O page available to the program and ***************

In order to understand the restrictions that mapping imposes on interrupt service routines, you must understand that when an interrupt occurs in a mapped system, its service routine executes with kernel, not user, mapping. This means that whether or not the program has mapped some of its virtual address space into extended memory, the interrupt service routine executes with the default kernel mapping to the low 28K words of memory plus the I/O page. It makes sense, therefore, that the first restriction demands that the mapping for your interrupt service routine plus any data it uses must be identical to kernel mapping at any time that an interrupt could occur.

*************** to the low 28K words of memory plus the I/O page. This is also the mapping scheme for a privileged job when it first begins execution. And, this is the mapping scheme that takes effect whenever an interrupt is serviced. (The shaded areas in the figure represent memory that the user job cannot access.) In (ISRKPM_FIG), the interrupt vector at 200 and 202 contains the entry point, called ISREP:, of the interrupt service routine, and the value 340, which represents the new PS. When an interrupt occurs, the system uses kernel mapping to locate the interrupt service routine. In this example, it should start at address 120000. Since privileged mapping and kernel mapping are identical in this diagram, the interrupt service routine is located in physical memory exactly where the kernel mapping points, so it can execute correctly. *************** shows a privileged job that changes the user virtual address mapping. (The shaded areas in the figure represent memory that the user job cannot access.) You can see from the example that the interrupt service routine cannot execute correctly when an interrupt occurs because the interrupt service routine is not located in physical memory where it should be. The memory area pointed to by the kernel mapping contains random data or instructions.

(Interrupt Service Routine Mapping Error\ISRIME_FIG) (postscript\MLO-007425B\26)

The second restriction for interrupt service routines relates to the way the monitor uses Page Address Register (PAR) 1 with kernel mapping. PAR1 controls the mapping for virtual addresses 20000 through 37776. When *************** system is running, the kernel virtual addresses in the PAR1 range can be mapped just about anywhere in physical memory and you have no way of controlling it. You must be sure that your interrupt service routine and any data it needs are not located in the virtual address range mapped by PAR1. (ISRP1R_FIG) illustrates this restriction. Valid locations for interrupt service routines, assuming that privileged mapping is identical to kernel mapping at the time of the interrupt, are marked on the diagram as (OK).

If your interrupt service routine needs a window into memory, it can borrow PAR1 the same way the monitor does. It must save the contents, set the value it needs, and restore the original contents before exiting. It can do ***************

(PAR1 Restriction for Interrupt Service Routines\ISRP1R_FIG) (POSTSCRIPT\ML007426B\26)

One final piece of information is important if you use .SYNCH in your interrupt service routine. The lines of code following .SYNCH execute almost like a completion routine. Completion routines in mapped environments execute with the user stack and with user mapping. But, since the code following .SYNCH is still part of an interrupt service routine, it executes in user context, but with (kernel )mapping. So, the *************** the same restriction as the main body of the service routine: its mapping must be identical to kernel mapping at any time that an interrupt could occur, or any time the completion routine could be executing. Of course, it must observe the PAR1 and PAR2 restrictions as well. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560FM.SDML;23 the data structures of a multiterminal system. Chapter 5, Interrupt Service Routines, describes the ways a program (as opposed to a device handler) can transfer data between memory ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S1782]S560IN.SDML;1 (VRUNV$bit in $JSW ) (VRUN or V job running bit) (Interrupt vectorslist) text *************** (CTRL/Fdiscussion) (CTRL/Xdiscussion) (TTOUSRused by terminal interrupt service ) (TTIUSRused by terminal interrupt service) text *************** (System stateswitching asynchronously) (INTLVLvalues) (INTLVLinterrupt level counter) (Interrupt level counterSee INTLVL) ($INTEN monitor routinediscussion) text *************** ($JSWrelationship with TCB) (Terminal control block (TCB)relationship with $JSW) (Multiterminal featureinterrupt service) (Interrupt servicefor terminals) text (.pg ! page 4-31) (Terminalsinterrupt servicelocal) (Terminalsinterrupt serviceremote) text *************** (5) (.ch Interrupt Service Routines ! page 5-1) (Interrupt service routines) (I/Owithout using interrupts) text (.pg ! page 5-2) (I/Ousing interrupts) text (.pg ! page 5-3) (Interruptsdescribed) (Prioritydevice and processordiscussion) (Interrupt prioritydiscussion) text *************** (PSWdescription) (PSSee PSW) (Device handlersinstead of in-line interrupt service) (HandlersSee Device handlers) (Processor status wordSee PSW) (Interrupt service routinesin-line instead of device handlers) (.FORK macrochanging processor priority with) (.INTEN macrochanging processor priority with) *************** (.pg ! page 5-5) (Interrupt service routinesadvantages of in-line) text (.pg ! page 5-6) (Device handlersadvantages of using) (Interrupt service routineswriting a routine) (I/Owriting a routine) text *************** (.pg ! page 5-11) (Interrupt service routinesstructure) (.PROTECT programmed requestuse in an interrupt service routine) (Interrupt service routinesuse of .PROTECT) (Interrupt vectorssetting up the values) text *************** (.pg ! page 5-13) (.DEVICE programmed requestuse in an interrupt service routine) (Interrupt service routinesuse of .DEVICE) (Interrupt prioritylowering with .INTEN) (Prioritylowering with .INTEN) (.INTEN macrouse in an interrupt service routine) (Interrupt service routinesuse of .INTEN) ($INTEN monitor routinediscussion) text (.pg ! page 5-14) (.SYNCH macrouse in an interrupt service routine) (Interrupt service routinesuse of .SYNCH) (USRwith .SYNCH macro) (.SYNCH macrowith USR) *************** (QS.CMPoffset in .SYNCH block) (.SYNCH macrohow errors returned by) (.FORK macrouse in an interrupt service routine) text (.pg ! page 5-16) (.FORK macrowith .INTEN macro) (Interrupt service routinesuse of .FORK) (Fork blockcontents) (F.BLNKoffset in fork block) *************** (F.BR4offset in fork block) ($FKPTRsetting up its value) (Interrupt service routinesuse of .FORKsetting up $FKPTR) (.FORK macrosetting up $FKPTR) text *************** (.INTEN macrosummary) (.SYNCH macrosummary) (Registers availableafter interrupt) (Registers availableafter .INTEN) (Registers availableafter .FORK) (Registers availableafter .SYNCH) (Interrupt service routinesregisters available) (.INTEN macroregisters available) (.FORK macroregisters available) (.SYNCH macroregisters available) (Interrupt service routinesexiting) (Interrupt service routinesskeleton outline) text *************** (.pg ! page 5-20) (Interrupt service routinesin mapped systems) (Mapped monitorsinterrupt service routines) (Extended memoryinterrupt service routines) (Mappingfor interrupt service routines) (Virtual jobsand interrupt service routines) text (.pg ! page 5-21) (PAR1restricted for interrupt service routines) (Interrupt service routinesrestricted in PAR1) text (.pg ! page 5-22) (PAR2restrictions for interrupt service routines) (Interrupt service routinesrestrictions in PAR2) (MQ handlerrestricted in PAR2 under XM) (MQ handlerMQH$P2 conditional) (MQH$P2restricts interrupt service routines) (.SYNCH macroexecutes with kernel mapping) (Kernel modeapplies to .SYNCH) *************** (.pg ! page B-3) (Consolesoftware simulation ofinterrupt source) (Consolesoftware simulation ofappear like DL11) (Consolesoftware simulation ofinput simulation) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S559]S559AA.SDML;14 The calculations are done; the routine can now start an operation or a retry. Before it starts, however, it arranges transfer routines for interrupt entry. To get to the ready state, force one interrupt, then return to 1$: *************** 3 .ENABL LSB 4 5 000316 012767 RXINIT: MOV #100000,RXIRTN ;SET RETURN AFTER INITIAL INTERRUPT 100000 000172 6 000324 016704 MOV RXCSA,R4 ;ENSURE THAT WE POINT TO THE CSR 000154 7 000330 000441 BR RXIENB ;GO INTERRUPT, RETURN TO 1$ LATER 8 9 000332 032700 1$: BIT #CSREAD,R0 ;READ OR WRITE FUNCTION? *************** 37 000434 052714 RXIENB: BIS #CSINT,@R4 ;SET IE TO CAUSE AN INTERRUPT WHEN DONE IS UP 000100 38 000440 000207 RETURN ;RETURN, WE'LL BE BACK WITH AN INTERRUPT 39 40 000442 016704 RXERR: MOV DXCQE,R4 ;R4 -> CURRENT QUEUE ELEMENT *************** 43 (Interrupt Service Section)

The .DRAST macro: ***************

Load registers; if the transfer is successful, this routine dispatches to the appropriate section for this interrupt. The three possibilities are: the first interrupt occurred; a read operation completed; a write operation completed. (A seek operation is treated as a zero-length read.) *************** 53 000510 005725 TST (R5)+ ;CHECK FOR ERROR, R5 -> DX REGISTER WITH ERROR 54 000512 100523 BMI RXRTRY ;ERROR, PROCESS IT 55 000514 006327 ASL (PC)+ ;NO ERROR, DISPATCH AFTER INTERRUPT 56 000516 000000 RXIRTN: .WORD 0 ;OFFSET TO INTERRUPT CONTINUATION 57 000520 103704 BCS 1$ ;FIRST INTERRUPT, START I/O 58 000522 032700 BIT #CSREAD,R0 ;READ OR WRITE? 000002 *************** 115 .ENDC ;EQ ERL$G 116 117 000724 005077 13$: CLR @RXCSA ;DISABLE FLOPPY INTERRUPTS 177554 *************** 134 MOV @R4,(R3)+ ;STORE RXCS 135 MOV @R5,(R3)+ ;STORE STATUS RXES 136 MOV #CSMAIN!CSGO,@R4 ;READ ERROR REGISTER (NO INTERRUPTS) 137 1$: BIT #CSDONE,@R4 ;WAIT FOR READ COMPLETION 138 BEQ 1$ *************** ENSURE THAT DISK IS ON TRACK BEFORE TRANSFER DLXFER - START AN I/O TRANSFER DLINT - INTERRUPT ENTRY POINT HANDLE THE ERRORS FINISH SUCCESSFUL OPERATION *************** 31 000400 CSDS0 =: 000400 ;DRIVE SELECT BIT 0 32 000200 CSCRDY =: 000200 ;CONTROLLER READY 33 000100 CSIE =: 000100 ;INTERRUPT ENABLE 34 000040 CSBA17 =: 000040 ;BUS ADDRESS BIT 17 35 000020 CSBA16 =: 000020 ;BUS ADDRESS BIT 16 *************** and returns to monitor. Request is completed and returns to interrupt entry (.DRAST). Continues down to DLEXFR to determine if we were rereading the table *************** 5 ; TRY 16 TIMES TO READ A HEADER. 6 ; IF ALL FAIL, LOG AN ERROR AND ISSUE A REVERSE SEEK (SEEK -1 TRACK) 7 ; AND A READ HEADER TO CAUSE AN INTERRUPT. 8 ; 9 ; R4 -> CSR *************** 64 001242 010044 MOV R0,-(R4) ;LOAD FUNCTION AND GO 68 001244 000207 RETURN ;WAIT FOR AN INTERRUPT 69 70 .DSABL LSB (Interrupt Service Section) 1 .SBTTL DLINT - INTERRUPT ENTRY POINT 2 3 ; INTERRUPTS ENTER THE HANDLER HERE 4 5 .ENABL LSB *************** The .DRAST macro:

When a function is completed, the device interrupts, and the handler is entered here to dismiss the interrupt and the queue element. 6 *************** 61 001540 010014 MOV R0,@R4 ;LOAD FUNCTION AND GO 65 001542 000207 RETURN ;WAIT FOR THE INTERRUPT 66 67 001544 106203 6$: ASRB R3 ;AT TIME OF FAILURE, WAS DRIVE READY? *************** 2 3 ;+ 4 ; EXECUTE A GET DRIVE STATUS OR ANY NON-INTERRUPT FUNCTION 5 ; AND WAIT FOR COMPLETION 6 ; *************** PREMTY - Prepare for multiterminal hook DRIVER RESET ENTRY OUTPUT INTERRUPT SERVICER GNXTCH - Get next output character INPUT INTERRUPT SERVICER PROCESS INPUT RECEIVED FROM INTERRUPT SERVICER XLENQ - Place Qelement on internal queue XLFIN - Internal Queue Element Completion DISINI - Disable input interrupts ENAINI - Enable input interrupts DISOUI - Disable output interrupts ENAOUI - Enable output interrupts RESBRK - Turn off BREAK SETBRK - Turn on BREAK *************** 33 ; XL$PDT is ignored if XL$PC is 1 34 ; 35 ; XL$PRI (4) interrupt priority 36 ; (5) if XL$SBC is 1 37 ; 4-7 range *************** 43 .ENDC ;NE XL$PC 44 45 .IIF NDF XL$PRI XL$PRI = 4 ;Interrupt processing level 46 47 .IF NE XL$SBC *************** 000027 000 .BYTE 0 000030 000000 .WORD 000000 78 ; interrupts to be turned off on 79 ; program exit 80 000032 .DRSPF (<)206> ;Sets/Resets DTR *************** 59 60 000205 OFFDRV = 205 ;Sets a flag which will cause 61 ; interrupts to be turned off on 62 ; program exit 63 000206 DTRDRV = 206 ;Sets/Resets DTR *************** 71 020000 RC.CTS = 020000 ;Clear to send 72 010000 RC.CD = 010000 ;Carrier detect 73 000100 RC.IE = 000100 ;Interrupt enable 74 000004 RC.RTS = 000004 ;Request to send 75 000002 RC.DTR = 000002 ;Data terminal ready 76 77 000100 XC.IE = 000100 ;Transmitter: interrupt enable 78 79 .IF NE XL$DVE *************** 91 .IF NE XL$PC 92 93 ; PRO-3xx Interrupt controller registers 94 95 IC0DR = 173200 ;Interrupt controller 0 data register 96 IC0CR = IC0DR+2 ;Interrupt controller 0 csr register 97 98 ; PRO-3xx Communications port registers *************** 109 RPT.R0 = 000 ;Write/Read register 0 110 CRC.TR = 300 ; Reset transmit underrun/end of message latch 111 CMD.RE = 020 ; Reset external/status interrupts 112 CMD.CR = 030 ; Channel reset 113 CMD.RT = 050 ; Reset transmitter interrupt pending 114 CMD.ER = 060 ; Reset error latches 115 CMD.EI = 070 ; End of interrupt 116 RPT.R1 = 001 ;Write/Read register 1 117 W1.RIE = 030 ; Receiver interrupt enable 118 ; (Int. on rec. char or special (no parity)) 119 W1.TIE = 002 ; Transmitter interrupt enable 120 RPT.R2 = 002 ;Write/Read register 2 121 RPT.R3 = 003 ;Write register 3 *************** 138 RPT.R2 = 002 ;Write/Read register 2 139 W2.REQ = 000 ; MUST be loaded with 000 140 R2.IMK = 034 ; Interrupt vector mask 141 IMK.BE = 020 ; Transmit buffer empty 142 IMK.ES = 024 ; External/Status change *************** 55 MOVB #RPT.R2,@R0 ;Select csr A, write register 2 56 MOVB #0,@R0 ; *** must be loaded with 0 *** 57 MOVB #CMD.RE,@R0 ;Reset external/status interrupts 58 59 ; Things to do through csr B *************** 68 MOVB #W1.REQ,@R0 ; *** ensure correct vector info *** 69 70 ; Now we play with the interrupt controller 71 72 MOVB #(<)30!3>,@#IC0CR ;Enable comm port interrupts 73 74 ; And finally, the modem *************** 34 ; SET XL VECTOR=octal_address 35 36 000514 010067 O.VEC: MOV R0,XL$VTB ;Save the new input interrupt vector 000142' 37 000520 062700 ADD #4,R0 000004 38 000524 010067 MOV R0,XL$VTB+6 ; and output interrupt vector 000150' 39 000530 020300 CMP R3,R0 ;Was address specified in range? *************** 25 26 .IF EQ XL$PC 27 000026 004767 CALL ENAINI ;Turn on receiver interrupts 002166 28 000032 012700 MOV #(<)RC.RTS!RC.DTR>,R0 ;Assert DTR *************** 177776 001070 31 000050 004767 CALL ENAOUI ;Enable output interrupts 002216 32 .IF NE XL$PDT *************** 35 .IFF ;EQ XL$PC 36 MOV #RPT.R1,@CSRA ;Select csr A, write register 1 37 BIS #(<)W1.RIE!W1.TIE>,SSRAW1 ;Turn on RECV and XMIT interrupts 38 MOV SSRAW1,@CSRA ; (update from software register) 39 BIS #(<)M0.DTR!M0.RTS>,@MCR0 ;Force DTR and RTS *************** 001436 52 ; read will be completed via 53 ; interrupts 54 55 000104 005267 WRITE: INC QCHG ;Set 'queue being modified' flag *************** 60 61 .IF EQ XL$PC 62 000124 004767 CALL ENAOUI ;Enable output interrupts 002142 63 .IFF ;EQ XL$PC 64 CALL GNXTCH ;Get a character for output 65 BEQ 50$ ;None available... 66 MOVB R5,@DBUF ;Now prime the interrupt pump 67 .ENDC ;EQ XL$PC 68 *************** 24 .ENDC ;NE XL$PC 25 26 ; Define the interrupt vectors 27 28 .IF EQ XL$PC 29 000142 .DRVTB XL,XL$VEC,XIINT ;Input interrupt servicer 000142 000300 .WORD XL$VEC&^C3.,XIINT-.,^o340!0,^o100000 000144 001214 000146 000340 000150 100000 30 000152 .DRVTB ,XL$VEC+4,XLINT ;Output interrupt servicer 000150 000304 .WORD XL$VEC+4&^C3.,XLINT-.,^o340!0,^o100000 000152 000750 *************** 000156 100000 31 .IFF ;EQ XL$PC 32 .DRVTB XL,XL$VEC,XLINT ;Input/Output interrupt servicer 33 .DRVTB ,XL$VEC+4,XLINT 34 .ENDC ;EQ XL$PC ***************

Special read may require post-interrupt processing, so it must be internally queued: ***************

SPFUN routines can be processed without post-interrupt processing, so they are handled without being moved to internal queue and returned to RT--11: *************** 134 135 ; Shut down driver request (OFFDRV) 136 ; Sets a flag such that when VTCOM exits, interrupts will 137 ; not be re-enabled. STATFG is used as the once-only, 138 ; interrupt startup flag. 139 140 000424 116446 100$: MOVB Q$JNUM(R4),-(SP) ;Save Q$JNUM ***************

INTERRUPT SERVICE/DISPATCHER 1 .SBTTL INTERRUPT SERVICE/DISPATCHER 2 3 ;+ 4 ; 5 ; Interrupt entry point for input and output interrupts. The interrupt 6 ; type is determined by bits (<)04:02> in RR2 of CSR B. The four defined 7 ; types of interrupts are: 8 ; 9 ; 1) Transmitter buffer empty (^B100xx) *************** 17 18 MOV #RPT.R2,@CSRB ;Select csr B, read register 2 19 MOV @CSRB,-(SP) ;Get the interrupt type 20 BIC #^C(<)R2.IMK>,@SP ;Strip the uninteresting stuff 21 ASR @SP ;Shift for word table offset *************** 23 MOV @(SP),@SP ;Get the table entry 24 ADD PC,@SP ;Convert to address 25 INTDSP: JMP @(SP)+ ;Dispatch the interrupt 26 27 ESINT: MOV #CMD.RE,@CSRA ;Reset external/status interrupts 28 IECOM: MOV #CMD.EI,@CSRA ;Declare end of interrupt 29 RETURN 30 *************** 32 JMP XIINT ; then handle as received character 33 34 INTTAB: .WORD IECOM-INTDSP ;unknown interrupt 35 .WORD IECOM-INTDSP ;unknown interrupt 36 .WORD IECOM-INTDSP ;unknown interrupt 37 .WORD IECOM-INTDSP ;unknown interrupt 38 .WORD XOINT-INTDSP ;Transmitter buffer empty 39 .WORD ESINT-INTDSP ;External/Status change 40 .WORD XIINT-INTDSP ;Received character available 41 .WORD SRINT-INTDSP ;Special receiver interrupt 42 .ENDC ;NE XL$PC 43 *************** 4 ; 5 ; XLHOOK 6 ; Entered from multiterminal input or output interrupt service. 7 ; 8 ; Call (TH.GOC): *************** 19 20 .IF EQ XL$PC 21 000624 004767 CALL DISINI ;Turn off input interrupts 001342 22 .IFF ;EQ XL$PC 23 MOV #RPT.R1,@CSRA ;Select csr A, write register 1 24 BIC #W1.RIE,SSRAW1 ;Turn off input interrupts 25 MOV SSRAW1,@CSRA ; (update from software register) 26 .ENDC ;EQ XL$PC *************** 177644 32 ; issued OFFDRV call? 33 000642 001003 BNE 5$ ;No, so interrupts should still be on 34 000644 005767 TST STATFG ;Should we turn interrupts back on? 177152 35 000650 001002 BNE 10$ ;Nope... 36 000652 5$: 37 .IF EQ XL$PC 38 000652 004767 CALL ENAINI ;Turn input interrupts back on 001342 39 .IFF ;EQ XL$PC 40 MOV #RPT.R1,@CSRA ;Select csr A, write register 1 41 BIS #W1.RIE,SSRAW1 ;Turn input interrupts back on 42 MOV SSRAW1,@CSRA ; (update from software register) 43 .ENDC ;EQ XL$PC *************** 177606 51 ;issued OFFDRV call? 52 000700 001003 BNE 15$ ;No, so interrupts should still be on 53 000702 005767 TST STATFG ;Again, interrupts back on? 177114 54 000706 001002 BNE 30$ ;Nope... 55 000710 15$: 56 .IF EQ XL$PC 57 000710 004767 CALL ENAOUI ;Turn output interrupts back on 001356 58 .IFF ;EQ XL$PC *************** 60 CALL GNXTCH ;Get a character for output 61 BEQ 20$ ;None available... 62 MOVB R5,@DBUF ;Now prime the interrupt pump 63 20$: MOV (SP)+,R5 ;Restore R5 64 .ENDC ;EQ XL$PC ***************

OUTPUT INTERRUPT SERVICER 1 .SBTTL OUTPUT INTERRUPT SERVICER 2 3 .IF EQ XL$PC ***************

Hook output interrupt entry point: 11 001130 HOINT: ;Output interrupt hook point 12 13 001130 005727 TST (PC)+ ;Is break in progress? *************** 48 001216 30$: 49 .IF EQ XL$PC 50 001216 004767 CALL DISOUI ;Turn off output interrupts 001022 51 .IFF ;EQ XL$PC 52 MOV #CMD.RT,@CSRA ;Reset transmitter interrupt pending 53 MOV #CMD.EI,@CSRA ;Declare end of interrupt 54 .ENDC ;EQ XL$PC 55 ***************

INPUT INTERRUPT SERVICER 1 .SBTTL INPUT INTERRUPT SERVICER 2 3 ; This is the input interrupt servicer. Input interrupts are always enabled 4 ; once this driver is called for the first time. Only a "RstDrv" SPFUN 5 ; request will shut off its interrupt enable. 6 7 .IF EQ XL$PC ***************

Hook input interrupt entry point: 15 001366 HIINT: ;Input interrupt hook point 16 17 001366 004767 CALL GETC ;Get an input character *************** 27 .ENDC ;NE XL$PDT 28 .IFF ;EQ XL$PC 29 MOV #CMD.EI,@CSRA ;Declare end of interrupt 30 .ENDC ;EQ XL$PC 31 *************** 86 87 .IF NE XL$PC 88 MOV #CMD.EI,@CSRA ;Declare end of interrupt 89 .ENDC ;NE XL$PC 90 ***************

PROCESS INPUT RECEIVED FROM INTERRUPT SERVICER 1 .SBTTL PROCESS INPUT RECEIVED FROM INTERRUPT SERVICER 2 3 .ENABL LSB ***************

DISINI - Disable input interrupts ENAINI - Enable input interrupts 1 .SBTTL DISINI - Disable input interrupts 2 .SBTTL ENAINI - Enable input interrupts 3 4 002172 DISINI: *************** 176312 7 002176 001404 BEQ 10$ ;Nope... 8 002200 112767 MOVB #-1,ISPND ;Disable input interrupt processing 177777 176304 *************** 10 .ENDC ;NE XL$MTY 11 12 002210 042777 10$: BIC #RC.IE,@XIS ;Turn off input interrupts 000100 175714 *************** 176264 18 002224 001403 BEQ 10$ ;Nope... 19 002226 105067 CLRB ISPND ;Enable input interrupt processing 176260 20 002232 000403 BR 20$ 21 .ENDC ;NE XL$MTY 22 23 002234 052777 10$: BIS #RC.IE,@XIS ;Turn input interrupts back on 000100 175670 ***************

DISOUI - Disable output interrupts ENAOUI - Enable output interrupts 1 .SBTTL DISOUI - Disable output interrupts 2 .SBTTL ENAOUI - Enable output interrupts 3 4 002244 DISOUI: *************** 176240 7 002250 001404 BEQ 10$ ;Nope... 8 002252 112767 MOVB #-1,OSPND ;Disable output interrupt processing 177777 176233 *************** 10 .ENDC ;NE XL$MTY 11 12 002262 042777 10$: BIC #XC.IE,@XOS ;Disable output interrupts 000100 175646 *************** 176274 18 002276 001405 BEQ 10$ ;Terminal hooks not active... 19 002300 105067 CLRB OSPND ;Enable output interrupt processing 176207 20 002304 004777 CALL @MTOENX ; and then enable output interrupts 000334 21 002310 000403 BR 20$ 22 .ENDC ;NE XL$MTY 23 24 002312 052777 10$: BIS #XC.IE,@XOS ;Enable output interrupts 000100 175616 *************** 13 ; In the case of call during multiterminal hook operation, 14 ; the character is already in R5 due to the multiterminal 15 ; input interrupt service code. 16 ; 17 ;- *************** 42 ; In the case of call during multiterminal hook operation, 43 ; the character is already in R5 due to the multiterminal 44 ; input interrupt service code. 45 ; 46 ;- *************** 8 002632 000100 XIBFRE: .WORD BUFSIZ ;Number of free bytes in buffer 9 10 ; Define areas for fork blocks used by the interrupt servicers 11 12 002634 000000 DQFBLK: .WORD 0,0,0,0 *************** 7 ; and is used 1) to verify use of the handler in the specific 8 ; configuration and, if needed, 2) to establish the required 9 ; connections between the handler and the interrupt service of 10 ; a monitor with support for multiterminal handler hooks. 11 ; *************** 3 ;+ 4 ; UNLOAD 5 ; On entry due to unload command, verifies interrupts have been 6 ; disabled unless the handler is still in use, indicated by 7 ; non-empty internal queues. 8 ; 9 ; On entry due to .RELEASE directive,disable interrupts 10 ; 11 ;- *************** 36 003330 004765 CALL (<)DISINI-XLLQE>(R5) ;Disable input 002164 37 003334 004765 CALL (<)DISOUI-XLLQE>(R5) ; and output interrupts 002236 38 003340 005000 CLR R0 ;Deassert all modem control bits *************** 46 003366 042711 BIC #RC.IE,@R1 ;Turn off input and 000100 47 003372 042761 BIC #XC.IE,4(R1) ;Output interrupts 000100 000004 *************** 49 .IFF ;EQ XL$PC 50 MOV #RPT.R1,@#XL$CSA ;Select csr A,write register 1 51 CLR @#XL$CSA ;Turn off input and output interrupts 52 BIC #(<)M0.DTR>,@#XL$MC0 ;Now turn off DTR 53 .ENDC ;EQ XL$PC ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S559]S559C1.SDML;42 Be sure to also read Chapter 5 of the (sim_book), as that chapter can help you decide whether you need to write an in-line interrupt service routine or a device handler. *************** corrupted and the integrity of the processes is compromised.) Therefore, when you design the handler, examine every step carefully and keep in mind what would happen if an interrupt occurred at each instruction. This kind of planning can help you avoid race conditions later. *************** section is able to use data structures and symbols that were defined in the previous sections and defines further handler characteristics. Interrupt service

The interrupt service section is the heart of the handler. It contains the code that processes interrupts as they are received from the device. It handles aborts and manages the handler queue. I/O completion *************** The I/O completion section contains code to inform the monitor of the success or failure of the interrupt processing and perform appropriate actions depending on success or failure. Handler termination *************** argument to (csr).) ((vec)\is the default value for the device's interrupt vector, stored in H1.VEC (offset 0 of block 1) by .DRBEG.) ((UNIT64=str)\is the number of device units to be ***************

Defines multiple vectors if the handler supports more than one interrupt vector. ***************

An RT--11 device handler can service multiple controllers where each controller has an interrupt vector. The handler can also service a device that has more than one vector.

*************** once for each vector. Each invocation creates a table with three entries. The table for each vector consists of the vector location, the interrupt entry point, and the Processor Status, or PS, value.

*************** The value must be a multiple of 4. The .DRBEG stores the value for (dd)$VEC in H1.VEC, offset 0 of block 1.) ((int)\is the symbolic name of the interrupt handling routine; it must appear elsewhere in the handler. It generally takes the form (dd)INT, where (dd )represents the *************** ((ps)\is an optional value you can use to specify the low-order four bits of the new Processor Status word in the interrupt vector. If you omit this argument, it defaults to 0.) *************** In the .DRVTB macro, only the condition code bits of the (ps) argument are significant. These can be useful if you have a common interrupt service entry point for two or more vectors and you need to determine through which vector the interrupt occurred. For example, the skeletal handler ((skel_fig)) has a single interrupt entry point for its two vectors. For the handler to determine the source of the interrupt, one is serviced with the carry bit clear and the other ((INT2)), when the carry bit is set. *************** vector device or an offset to the table of vectors for multivector devices ((dd)STRT)) (001002\H1.ABT\.DRBEG\Offset to the interrupt service entry point) (001004\H1.HLD\.DRBEG\Priority (340)) *************** CSIE = 100 ;INTERRUPT ENABLE FNWRITE = 12 ;WRITE CSGO = 1 ;GO BIT *************** . Finally, return to the interrupted program by going through the monitor first. Then when the I/O transfer finishes, the device will interrupt, and control will pass to the handler at the interrupt entry point in the interrupt service section of the handler. RTS PC ;AWAIT INTERRUPT *************** registers (UMRs) is in (psd_UB_sec). (Interrupt Service Section)

Control passes to the interrupt service section of the handler when a device interrupts, when the program requesting the I/O transfer aborts, or a .ABORT is issued for the channel. The code in this section must first determine if the data transfer had an error, if it was incomplete, or if it was complete, and then take the appropriate action. The same register usage restrictions that apply to the interrupt entry point also apply to the abort entry point. See Chapter 5 in the (sim_book) for information on interrupt service routines.

Your first step in coding the interrupt service section is to set up the interrupt entry point and the abort entry point by using the .DRAST macro. (These entry points are sometimes referred to as the asynchronous trap entry points.) The default name for the interrupt entry point is (dd)INT, where (dd )is the device name. Under normal conditions, the handler is called at the interrupt entry point when an interrupt occurs. However, under some circumstances, the handler is called at the abort entry point located at (dd)INT--2. The various situations are discussed in the following sections. *************** (.DRAST Macro)

Use the .DRAST macro to set up the interrupt entry point and the abort entry point, and to lower the processor priority. The .DRDEF and .DRVTB macros fill in the structure at bootstrap (for the *************** ((pri)\is the priority of the device, and the priority at which the interrupt service code is to execute.) ((abo)\is an optional argument that represents the label of the abort entry point. *************** a RETURN instruction at the abort entry point. Either the branch to the specified label or the RETURN instruction is the word immediately preceding the interrupt entry point (dd)INT.) *************** macro call. In the example, DYABRT is the label for the abort routine which would generate the instruction (BR DYABRT) in the word preceding the interrupt entry point DYINT. .SBTTL INTERRUPT ENTRY POINT .DRAST DY,5,DYABRT ; AST entry point *************** The next example, from the RK handler, does not have an abort routine. Notice the instruction, RETURN, in the word immediately preceding the interrupt entry point RKINT. *************** On abort, whether or not the handler is entered at all depends on two factors. The handler is always entered at the abort entry point (the word immediately before the normal interrupt entry point) if an active queue element exists and it belongs to the aborting job. In FB and XM, the handler is also entered regardless of the existence of a queue *************** XLDONE: BIC #RC.IE,@XIS ;Turn off input interrupts RTS PC ;Return to monitor ***************

The abort entry point is always located at the word previous to the interrupt entry point ((dd)INT--2). If the optional .DRAST (abo) parameter is specified, the abort entry point is a branch instruction *************** (Lowering the Priority to Device Priority)

When the interrupt occurs, the handler is entered at priority 7. As with interrupt service routines, the handler's first task is to lower the processor priority to the priority of the device, thus permitting more important devices to interrupt this service routine. Instead of using the .INTEN call, as in an interrupt service routine, use the .DRAST macro to lower the priority. (Guidelines for Coding the Interrupt Service Section)

Since the purpose of this section is to evaluate the results of the last *************** As also described in the (sim_book), the .FORK macro causes a return to the Resident Monitor, which dismisses the current interrupt. The code that follows .FORK executes at priority 0, rather than at device priority, after all other interrupts have been serviced, but before any jobs or their completion routines can execute. The code following .FORK executes, as does the main body of the interrupt service section of the handler, in system state. (This is the same state the I/O initiation section runs in.) Thus, context switching is prevented while the fork level code is executing, and any traps to 4 and 10 *************** characters or more blocks of data left to transfer. The handler should restart the device and exit with a RETURN instruction to wait for the next interrupt. (If the Transfer Was Complete\bold)

***************

The I/O completion section is an extension of the interrupt service section. Control passes from the interrupt service section to the I/O completion section when a data transfer completes, when *************** 10$: BIC #,@DYCSA ;DISABLE FLOPPY INTERRUPTS ;AND INHIBIT DRIVE RESET 11$: .DRFIN DY ;GO TO I/O COMPLETION ***************

For a block-oriented device, such as a disk or diskette, the handler simply disables interrupts and performs the jump to the monitor. The .DRFIN macro generates the code to perform the jump.

***************

You can write a device handler for a pseudodevice (one that does not interrupt, and is not a mass storage device) to take advantage of the queued I/O system and the fact that handlers can remain memory resident. Examples of handlers for pseudodevices are NL (the null device), MQ *************** .DRFIN macro call to terminate the operation and return the queue element. Since pseudodevices do not interrupt, the handler needs no interrupt service section and no .DRAST macro call. *************** RETURN (.SBTTL INTERRUPT SERVICE SECTION\bold) (.DRAST SK,4,ABORT\bold) ; Interrupt entry point BCS INT2 ; Interrupt from second vector ... RETURN INT2: ; Second interrupt vector code ... RETURN *************** A handler that implements internal queuing decides how to dispose of the current queue element based on whether processing the request requires post-interrupt activity (another interrupt). If the I/O request does not require post-interrupt activity by the handler, the handler processes the queue element immediately and returns, through .DRFIN, to the monitor. If processing *************** abort on a channel or job. (Interrupt Service for Handlers That Queue Internally)

When an operation completes, the handler is normally entered at its interrupt entry point, (dd)INT:. After this, various actions are taken depending on the circumstances. If there is more than one internal queue, the handler determines which request this interrupt involves and, therefore, which internal queue. If the operation is not complete, the handler restarts it or continues it *************** instructions.

Finally, look at the code in the interrupt service section of the handler that is modified by the routines you have just seen. Remember that the code to be modified must be located in block 1 of the handler, ***************

The device timeout feature lets a handler assign a completion routine to be executed if an interrupt does not occur within a specified time interval. Thus, the handler can perform the equivalent of a mark time operation without the need for a .SYNCH call and its attendant *************** Use the .TIMIO macro in the handler I/O initiation section to issue the timeout call. You can issue the request anywhere in the handler except at interrupt level. If you need to issue the request at interrupt level, you must issue a .FORK macro call first.

*************** the completion routine executes with kernel mapping, since it is still a part of the interrupt service routine. (See the (sim_book) for more information about interrupt service routines and the mapped monitor environment.) As usual with completion routines, R0 and R1 are available for use. When the completion ***************

Because you must go to fork level (and processor priority 0) to issue a .TIMIO or .CTIMIO request at interrupt level, your handler must disable device interrupts before issuing the .FORK, or must be carefully coded to avoid reentrancy problems. Note that you cannot reuse a timer block until *************** Execution must be in system state when you issue the call. Be sure to issue a .FORK call first if you use .CTIMIO at interrupt level.

For example, a printer handler could check for an off-line condition. When a program requests an I/O transfer, the handler's I/O initiation section forces an immediate interrupt. The handler's interrupt service section then checks the device error bit. If the bit is set, the printer is not on line and the handler prints a message, sets a 2-minute timer with .TIMIO, and returns to the monitor with a RETURN instruction to wait for another interrupt. The device should not interrupt again until the error condition has been fixed by an operator. If no interrupt occurs within two minutes, the timer completion routine prints another error message, sets another 2-minute timer, and returns again to the monitor with RETURN to wait for an interrupt. (See (LPEXAMPLE_FIG) for a printer handler example.)

In this example, when an interrupt finally occurs and the error bit is clear, the handler issues the .CTIMIO call to cancel the timed wait.

As another example, a disk handler could set a timer before it starts up a seek operation. When the interrupt occurs, the seek is complete, and the handler should then cancel the timer.

*************** job requested: a read, write, or seek operation. The handler returns to the monitor with a RETURN instruction and waits for a device interrupt.

If an interrupt occurs before the time limit expires, the handler cancels the timer and performs its normal sequence of error checking on the results of the transfer. In general, the handler either drops to fork level to *************** .DRFIN to remove the current queue element.

If an interrupt does not occur within the time limit, the timer completion routine begins to execute. Its first action should be to simulate an interrupt. This action duplicates the handler environment after a genuine interrupt and makes sure that the stack has the necessary information. Then the timer completion routine acts as though the device interrupted but the transfer was in error. The timer completion routine simply branches to the correct section of code in the interrupt service section of the device handler to finish the processing.

The timer completion routine should use the following instructions to simulate an interrupt and enter system state: MOV @SP,-(SP) ;MAKE ROOM ON THE STACK CLR 2(SP) ;FAKE INTERRUPT PS = 0 .MTPS #340 ;GO TO PRIORITY 7 .INTEN 0,PIC ;ENTER SYSTEM STATE *************** the I/O initiation section. The code in the initiation section sets another timer, restarts the transfer, and returns to the monitor with a RETURN instruction to await another interrupt.

If the handler decides that the timeout indicates a serious error, one ***************

When the handler's I/O initiation section starts up a transfer, it forces an immediate interrupt, which causes the handler's interrupt service section to check the error bit in the CSR. If there is an error, control passes to the routine OFFLIN, which issues a .SYNCH *************** error message on the console terminal, and then sets a 2-minute timer. The handler then returns to the monitor with a RETURN instruction and waits for the device to interrupt.

If the device interrupts, it means that the error condition has been corrected by an operator. The handler cancels the timer and checks the error bit once again to make sure there are no problems. If there is no error, the handler proceeds as usual. If there is an error, the handler loops back to the OFFLIN routine. If an interrupt does not occur within two minutes, the timer completion routine begins to execute. It prints an error message, sets another 2-minute timer, and returns to the monitor with a RETURN instruction to await an interrupt.

(Printer Handler Example\LPEXAMPLE_FIG) *************** BCC LPERR ;A READ REQUEST IS ILLEGAL BEQ LPDONE ;SEEKS COMPLETE IMMEDIATELY RET: BIS #100,@LPS ;CAUSE AN INTERRUPT, STARTING TRANSFER RTS PC ; INTERRUPT SERVICE SECTION .ENABL LSB .DRAST LP,4,LPDONE CLR @LPS ;DISABLE INTERRUPTS .FORK FRKBLK TST TICMPL ;IS A TIMER ELEMENT ACTIVE? *************** ; I/O COMPLETION SECTION LPDONE: CLR @LPS ;TURN OFF INTERRUPT .DRFIN LP . *************** RTS PC 2$: BIS #100,@LPS ;ENABLE INTERRUPTS RTS PC ;RETURN LATER *************** If this is a request for a special function, the handler should initiate that function and return with a RETURN instruction. In the interrupt service section the handler should, as usual, check for errors and determine whether the operation is complete. The handler returns either *************** ; bits into function MOV R3,-(R4) ;Start the operation 6$: RTS PC ;Await interrupt (The following gives you a 10 point code-example font) *************** $P1EXT(1\Because all relevant code is executed outside the PAR1 area, the interrupt service in the PAR1 area is handled in mapped monitors by a vector forwarding technique that is transparent to the handler.).

*************** the stack.

The bootstrap read routine normally is a noninterrupt routine, used to read the volume according to the parameters passed in R0 through R2. On error, the *************** that section before you read this one, as that section describes the basic monitor/handler protocol. It also describes the monitor data structures that your handler writes and accesses and the interrupt service routines your handler uses to read and write data.

*************** (hhook_hook_sec) Handler hook interrupt processing during execution of interrupt service code, (hhook_int_sec) *************** ; and is used 1) to verify use of the handler in the specific ; configuration and, if needed, 2) to establish the required ; connections between the handler and the interrupt service of ; a monitor with support for multiterminal handler hooks. ; *************** defcodexamplefonttenpointmono (Handler Hook Interrupt Processing\hhook_int_sec)

The handler hook interrupt entry point is called by the monitor whenever an interrupt occurs on the line to which the handler is attached.

When an input interrupt occurs, the monitor calls the handler hook entry point with the character in R5 and the TH.PIC function code in R0. The handler processes the character, preserving the registers, and returns.

When an output interrupt occurs, the monitor calls the handler hook entry point with the TH.GOC function code in R0. The handler returns the next output character in *************** output, it returns the PS carry bit set. All registers are preserved.

The multiterminal interrupt service controls character output. A handler cannot send output directly to an interface, but must instead indicate it has output by calling the MTOENB routine. *************** ; ; XLHOOK ; Entered from multiterminal input or output interrupt service. ; ; Call (TH.GOC): *************** BEQ 30$ ; We're not... CALL (R5) ; Disable input CALL (R5) ; and output interrupts CLR R0 ; Deassert all modem control bits CALL (R5) ; ... ***************

Set other breakpoints at various points in the handler that you want to examine during debugging. Another critical place is the interrupt entry point. You can find its location by checking the handler's MACRO--11 listing. Remember, the interrupt entry point is called (dd)INT:; you should be able to find it easily and set a breakpoint there. *************** usual to examine locations and check their values, or to modify instructions. Note that the default priority of ODT is 7; this prevents other interrupts from disturbing your debugging session. Since you are the only user on the system, ODT's high priority should cause no problem. (Note, however, that the system *************** (001000\Either the device vector or an offset to the table of vectors ((dd)STRT)) (001002\Offset to the interrupt service entry point) (001004\Priority (340)) (001006\Pointer to the last queue element ((dd)LQE)) ***************

(n\Abort entry point (from .DRAST; may be above 1777)) (n+2\Interrupt entry point (from .DRAST; may be above 1777))

(1776\High limit of area modifiable by SET code) ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S559]S559C2.SDML;25 this handler acts as a data sink. When a program calls NL, the handler returns immediately to the monitor indicating that the output is complete. The handler returns no errors and causes no interrupts. On input operations, NL returns an immediate EOF indication for all requests; no data is transferred. Hence, the contents of the input buffer are unchanged. *************** BR XBEXIT ; DRFIN because this is an example ; Handler and there are really no ; Interrupts associated with it. ; If there were, the DRFIN would be ; Issued at interrupt time when ; The DMA transfer is finished. ; This is true for the other SPFUN *************** ) (205\SF.OFF\Sets a flag that disables interrupts when the program exits. Digital recommends you issue .SPFUN SF.OFF before your program exits. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S559]S559IN.SDML;1 (Device handlerstransferring data$MPMEM routine) ($MPMEM routineillustrated) (Device handlersstructure ofinterrupt service section) (Device handlersinterrupt service section) (Device handlersinterrupt entry point) TEXT *************** (Device handlers.FORK with) (F.BADRwith handler abort) (Device handlerslowering priority after interrupt) (Device handlersinterrupt service sectioncoding guidlines) TEXT (.PG ! PAGE 1-27) (.FORK macrowith handler retries) (Device handlersinterrupt service sectionincomplete transfer) (Device handlersinterrupt service sectioncomplete transfer) text *************** (.pg ! page 1-95) (Multiterminal handler hooks supportinterrupt processing) text *************** (Communications handlersobtaining handler status) (SF.OFFfor communications handlers) (Communications handlersdisabling interrupts for) text ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S561]S561C1.SDML;101 When data is stored in contiguous blocks, I/O is more efficient. Transfers to large buffers are handled directly by the hardware for certain disks; seeks between blocks and program interrupts between blocks are eliminated. File data is processed simply and efficiently since the data is not encumbered by link words in each block. Routines to maintain the directory ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S561]S561C2.SDML;81 RMON, KMON checks each word in block 0 of the file. It does not load locations that are protected, such as location 54 and the device interrupt vectors. It loads unprotected locations into memory from the USR buffer. Next, KMON sets location 50 to the top of usable memory, or to the top of the user program, whichever is greater. ****************************** DISK$DATA:[SHOPPA.PDP11.RT.DOC56.ARCHIVE.RT-11.S878]S878.SDML;76 (CTRL/K\Inserts a vertical-tab character.) (CTRL/L\Inserts a form-feed character.) (CTRL/O\Interrupts output to your screen. To recover, type CTRL/O and CTRL/R or CTRL/W.) (CTRL/Q\Reenables output to your screen after a CTRL/S.) (CTRL/R\Restores the display after you use the HELP function or after the display is interrupted or corrupted for another reason. Also restores the operation of the keypad.) (CTRL/S\Interrupts output to your screen. To recover, type CTRL/Q.) (CTRL/U\Deletes to the preceding line terminator and stores the deletion in the line buffer. Also corrects your responses to prompts.)