I/O Interrupts

This section is provided for those who require an understanding of the 1130 CPU interrupt scheme. Normally, application programs (used in conjunction with the facilities of IBM-supplied programming systems for the 1130) interact with the 1130 CPU interrupt scheme by means of subroutines. Subroutines are supplied by IBM for the 1130, or they may be written by the application programmer. If IBM-supplied subroutines are used, it may not be necessary for the programmer to understand how the interrupt scheme is implemented in the 1130 CPU.

General Purpose of Interrupts

The temporary stopping of the current program routine, in order to execute some higher priority I/O subroutine, is called an interrupt. The interrupt mechanism in the CPU forces a branch out of the current program routine to one of several subroutines, depending upon which level of interrupt occurs.

I/O operations are started as a result of the execution of a program instruction. Once started, the I/O device continues its operation at the same time that the job program is being executed. Eventually the I/O operation reaches a point at which a program routine that is related to the I/O operation must be executed. At that point an interrupt is requested by the I/O device involved. The interrupt action results in a forced branch to the required subroutine.

In addition to the routine needed to start an I/O operation, subroutines are required to:

  1. Transfer a data word between an I/O device and main storage (for write or read operations)
  2. Handle unusual (or check) conditions related to the I/O device
  3. Handle the ending of the I/O device operation

Note: Some I/O devices do not require program-instruction handling of data transfers to or from core storage. These devices are described in subsequent sections of this book. Their method of transferring data is called cycle steal and is not related to the interrupt program-subroutine method of handling data described in this section.

In order to understand the interrupt scheme, first examine the start of an I/O operation. Then contrast this operation with an interrupt occurrence, which in many respects is similar to the beginning of the I/O operation.

Starting an I/O Operation

Shown in the following diagram are:

  1. The job program routine (which, for this discussion, includes those program steps not used for I/O operation handling)
    I/O interrupt during program execution spawning a device operation
  2. The I/O program routine that starts an I/O device
  3. The I/O device operation (such as moving a punched card through the read feed of a card reader)

Branching from the job routine to the I/O routine occurs at point A in the diagram. This branch is a program-controlled operation that is started because the job program is at a point at which the I/O operation is required (such as the reading of a card in the card reader). Similarly, when the end of the I/O routine is reached, a program-controlled branch is made back to the job routine (point B). (Program-controlled means that the logical point at which the branch occurs is determined by the program; no forcing is performed by the CPU.)

Because the CPU can execute only one instruction at a time, the I/O routine and the job routine are not overlapped.

But the I/O device operation is overlapped with program-instruction execution because the I/O device can perform its functions without using the CPU mechanism required for execution of program instructions. In other words, the I/O device operation, once started, continues while program-instruction execution takes place in the CPU.

In summary, the important points to notice about starting the I/O operation are:

  1. Branching operations to the I/O routine and then back to the job routine are under program control.
  2. Once started, the I/O device operates at the same time as the current program routine (I/O or job) is being executed.

Interrupt Action

Assume that the I/O device in operation is the card reader (1442). The I/O device operation that has been started, then, is the moving of a card past the read station.

Card is read while program execution continues

As soon as the card is moved far enough for one card column to be read, the card reader signals the CPU. This signal to the CPU is an interrupt request. The interrupt, however, does not occur until execution of the current instruction is completed. At that time, a forced branch occurs to an interrupt-handling subroutine.

The interrupt action can be shown pictorially in the following way:

The card continues to be read as the continuing I/O is serviced

Logical requirements of the interrupt subroutine are carried out before a return to the interrupted program.

To return to the program routine that was in progress before the interrupt occurred, another branch must be provided. This, however, is a program-controlled branch and, therefore, is not forced by the CPU.

In summary,

  1. An interrupt request occurs at the time that an I/O operation, which otherwise proceeds in dependently of the program, requires program intervention.
  2. The interrupt occurs after the current instruction has been completely executed.
  3. The CPU then forces execution of a branch instruction, which causes a branch to a subroutine.
  4. At the end of the subroutine the program branches back to the program routine that was in progress when the interrupt occurred.

As discussed, the two ways of branching into an I/O routine are:

  1. Program-controlled branching
  2. CPU-forced branching

In a program-controlled branch to an I/O routine, a properly written program has address information for the branch-to location and the return address, if needed. Similarly, when a CPU-forced branch occurs, a way must be provided to branch to the proper subroutine and return (via another branch) to the interrupted program at the end of the subroutine. Therefore, the following information must be available.

  1. The core-storage address of the beginning of the interrupt subroutine
  2. The core-storage address of the next instruction to be executed in the current program (that is, the address of the place to return to after the interrupt routine is completed)

But at the time of the actual interrupt (after the current instruction is completely executed) the address of the next instruction is in the instruction-address register. (The next instruction is the one that would have been executed if the interrupt had not occurred.)

The next instruction address is stored into the first word of the interrupt-subroutine location. Storing is performed during execution of the CPU-forced branch at the time of the interrupt. The CPU-forced branch is a branch-and-store-IAR instruction (a BSI instruction). Format of this forced branch instruction is:

Format of the forced branch instruction

The beginning (first word) of the interrupt subroutine is specified by an address in the interrupt-vector location, which is the location that contains the effective address used during execution of the BSI instruction. The address field in the BSI instruction points to the interrupt vector. There are several interrupt-vector, fixed locations in core storage because there are several levels of interrupt. Interrupt levels and their associated vector locations are:

Interrupt Level   Interrupt Vector Location
(in core storage)
  Device
0   00008 (in decimal)   1442 Card Read Punch (column read, punch)
1   00009   1132 Printer, synchronous communications adapter
2   00010   Disk storage, storage access channel
3   00011   1627 Plotter, 2250 Display Unit, storage access channel, System/7
4   00012   1442 (operation complete), keyboard, console printer, 1134 Paper Tape Reader, 1055 Paper Tape Punch, 2501 Card Reader, 1403 Printer, 1231 Optical Mark Page Reader, storage access channel
5   00013   Console (program stop switch and interrupt run), storage access channel

Entering an Interrupt Subroutine

Suppose that an interrupt occurs at level 0. For this example, the address of the next instruction in the current program is 0502. This value (0502) is in the instruction-address register (IAR) when the CPU-forced branch occurs. Because the interrupt is at level 0, the CPU forces execution of the following branch instruction.

BSI instruction for enterring an I/O subroutine

Execution of this instruction stores the contents (0502) of the instruction-address register into the first word location of the interrupt subroutine. The contents are kept there until needed for branching back to the interrupted program after the interrupt has been handled.

The first word of the interrupt subroutine is at the core-storage location specified by the contents of location 0008 (the interrupt-vector location for level 0). When the program is originally loaded into the system, the appropriate subroutine addresses must be stored (via program control) into the interrupt vectors. Therefore, for this example, the contents of core-storage location 0008 are 0600. Core-storage address 0600 is the address of the first word of the interrupt subroutine for interrupt-level 0. For this example, then, execution of the branch-and-store-IAR (the CPU-forced branch) results in:

  1. The contents of the second word of the BSI instruction point to the core-storage location (0008) that contains the effective address (0600) used during execution of the BSI instruction.
    BSI instruction execution, part 1, to go to interrupt subroutine
  2. The contents (0600) of location 0008 are an address that points to the first word of the interrupt-level-0 subroutine. The value in the instruction-address register is stored at this location.
    Continuing toward the interrupt subroutine...
  3. The instruction-address register is updated to the effective address plus 1 (the effective address used during execution of the forced BSI -- for this example, 0600).
    Updating the instruction address register
  4. Because the instruction-address register now points to 0601, the first instruction of the sub routine is taken from that location. This is normal operation for the BSI instruction.

Saving Data Used by The Interrupted Program

The interrupt subroutine must save the contents of certain index and machine registers (by storing their contents into core storage) before such registers are used for data manipulation within the subroutine. Only the contents of those registers that are used by the subroutine need be saved. The data integrity of such registers must be maintained because the interrupted program may use the same registers. At the end of the interrupt subroutine, the contents of the affected registers are loaded back into the registers from core storage.

For example, the accumulator is used by all subroutines. Therefore, the contents of the accumulator must be stored into core storage before the accumulator is used by the subroutine. At the end of the subroutine, before a return to the interrupted program, the accumulator is loaded with the data that is saved.

Cause of Interrupt

In general, two methods are used to determine what condition is causing an interrupt:

  1. Examination of the device status word
  2. Examination of the interrupt-level status word

The I/O device causing an interrupt can be determined by examination (via programming) of the interrupt-level status word, when necessary. (The following discussion indicates when this is not necessary.) Then, after the device is known, the device-status word is examined to determine the condition in the device that caused the interrupt to occur.

First consider a level-O interrupt. An interrupt-level status word is not used at level 0. Only the device status word need be examined at interrupt level 0.

Either one of two conditions can cause level-0 interrupt to occur:

  1. The card reader (1442) has a data word ready for storing into core storage during a read operation.
  2. Or the card punch (1442) is ready to accept data for punching a column during a punch operation.

Because the 1442 can perform only a read or a punch operation at any one time, an interrupt at level 0 is for either a read or a punch operation. The program must determine which operation occurs. Clearly, sending a data word from core storage to the card punch during a read operation would be inappropriate.

Determination of whether the reader or the punch caused the level-0 interrupt is done in the following way: An execute I/O instruction addresses a sense-device I/O control command. Execution of this command, which specifically addresses the 1442, results in the loading of the 1442 device status word into the accumulator. Also, bit 15 in the second word of the command is on (that is, equals a value of 1). That bit, when on, causes a reset of the interrupt response. (The interrupt response is the signal, from the 1442, that originally requested the level-0 interrupt.)

Bits 0 and 1 of the 1442 device status word specify which operation (punch or read) causes the level-0 interrupt.

1442 Device Status Word

After the subroutine determines whether the interrupt is for a read or punch response, the appropriate action is taken:

  1. For a read response, an execute I/O instruction addresses a read I/O control command that moves the data word from the 1442 to core storage.
  2. For a punch response, an execute I/O instruction addresses a write I/O control command that moves the data word from core storage to the 1442 punch.

At the end of the level-0 interrupt subroutine:

  1. The saved contents of registers are loaded from core storage back into the registers.
  2. A branch (BOSC indirect) is made back to the interrupted program. (This resets the interrupt level.) The branch is carried out through use of the address stored in the first word of the subroutine. (Recall that the first word of the subroutine is loaded with the address of the instruction that would have been executed if the interrupt had not occurred.)

Interrupt-level stats words are defined for interrupt levels 1, 2, 3, 4, and 5. During execution of the subroutine, the interrupt-level status word for the level of interrupt can be put into the accumulator by an execute I/O instruction and sense-interrupt command. The contents of the interrupt level status words at the various interrupt levels are:

Interrupt level 1 status word

Interrupt level 2 status word

Interrupt level 3 status word

Interrupt level 4 status word

Interrupt level 5 status word

After an interrupt-level status word is loaded into the accumulator, the contents of that word can be inspected to determine the device causing the interrupt. For example, the procedure for level 1, for either the 1132 printer or the synchronous communications adapter, involves branching on the contents of the accumulator. If the value in the accumulator is negative (bit 0 set to a value of 1), then the interrupt is for the 1132:

Which is this level 1 interrupt for, a Synch Comm Adapter, or the 1132?

If bit 0 is not at a value of 1 during a level-1 interrupt, the interrupt must be for the synchronous communications adapter because that is the only other device that can cause an interrupt at level 1.

After the device causing the interrupt has been determined, a sense-device-status command can be executed (via an execute I/O instruction) to determine the condition within the device that caused the interrupt.

Figure 17 contains a sample interrupt-recognition routine.

Special Considerations for Level-5 Interrupt

Programming for level-5 interrupts is different from normal interrupt programming. The major difference for level 5 is the reset function in the sense-device-status-word command.


Program stop. The normally generated branch-and-store-instruction-address-register instruction (BSI) is performed with an indirect branch via storage-location OOOD (0013 in decimal). The execute I/O and sense DSW sequence is then performed to determine what caused the interrupt.

At completion of the branch-out at the end of the routine (a BOSC) another level-5 interrupt is requested, as if the program stop key were operated again. The request remains active until the start key or the reset key is operated to turn off the program-stop interrupt request.


Interrupt Run Mode. The normally generated branch-and-store-instruction-address-register instruction (BSI) is performed with an indirect branch via storage location OOOD (0013 in decimal). The execute I/O and sense DSW sequence is then performed to determine what caused the interrupt. The branch-out at the end of the routine (a BOSC) resets level-5 interrupt request and level-5 priority.

Interrupts at level 5 do not occur during other interrupt service routines. Therefore, interrupt routines cannot be traced.

 

Sample Interrupt Recognition Procedure

The notes that follow, are numbered to correspond to the reference numbers in the procedure. Each reference number cited in text is circled, e.g., circled 1, to avoid confusion with numbers necessary to the procedure, such as memory addresses.

In the registers, instructions, and data words, only the necessary 0-bits and 1-bits are shown. Op codes are shown in alphabetic symbols, and decimal numbers are used to identify memory locations. Binary notation, where used, is obvious. IAR, ACC, ond XR1 are shown only where needed for understanding of the operation.

  1. Mainline program instruction. During execution of this instruction, the 1442 initiates a card read interrupt.
  2. At the conclusion of circled 1 instruction, the CPU blocks the next program instruction and interposes a CPU-generated BSI to start the Level 0 interrupt procedure.
  3. IA of Level 0 BSI is 0008; EA at 0008 is 0600.
  4. IAR (0502) is stored at EA (0600); IAR is then loaded with EA+1 (0601).
  5. First instruction of Level 0 interrupt subroutine. Subroutine must store status of each register, all data, etc., that could be altered by execution of subroutine. Before leaving subroutine, program must restore aIl registers, data, etc., to condition that existed when interrupt occurred.
  6. Last instruction of interrupt subroutine is a BSC instruction with Bit-9 value of 1, which resets the priority status so that interrupts of equal or lower priority can be recognized. If no interrupt is waiting, return to interrupted program is effected by the IA(0600) of the BSC being equal to the EA of the CPU-generated BSI that initiated the interrupt routine, circled 1. BSC is shown as on unconditional branch (Bits 10-15 = 0); branch could have been conditional, i.e., branch executed only if no conditions specified by Bits 10-15 were true.

    NOTEs The term interrupted program is used to designate either the main program being executed or an interrupt subroutine of lower priority. For example the circled 1 instruction could be in a routine to service a console printer-keyboard, Level 4 interrupt. Thus, the mainline program can be thought of as a routine with no priority, to which the CPU returns when no interrupts are waiting.

    Interpretation sequence being explained by the text
  1. EA (0502) is the location of the next mainline program instruction and is loaded into the IAR.
  2. To illustrate an interrupt with low priority occurring while a higher priority interrupt is being serviced, we assume the console printer-keyboord initiated a Level 4 interrupt while the card read interrupt was being serviced. We assume no Level 0, I, 2, or 3 interrupts are waiting and the Level 4, CPU-generated BSI can be interposed, as in circled 1 for Level 0.
  3. IA (0012) of the BSI is the memory location assigned to Level 4 interrupts and contains the EA(1500).
  4. The IAR is stored at the EA (1500) and then loaded with EA+1 (1501).
  5. First instruction of Level 4 subroutine. See circled 1. Last housekeeping instruction takes subroutine to circled 1.
  6. XIO instruction EA (4100) is the memory location of the IOCC. IAR contents remain at 2302 because the IOCC controls an I/O device and is not a sequential program instruction.
  7. IOCC function code of 011 (Sense Interrupt) causes the ILSW for Level 4 to be loaded into the ACC.
  8. XR1 is loaded with a quantity equal to the number of response signals connected to the ILSW.
  9. SLCA instruction is terminated when the 1-bit associated with the console printer-keyboard interrupt is shifted into the high order position of the ACC. XR1 is reduced by one.
  10. BSC address is modified by XRI (+2) to form the IA (2307). A blt in the 0-position of the ILSW (paper tape reader and paper tape punch) results in an XR1 of 3 and an IA of 2308. A bit in the 2-bit position (card read-punch) results in on XR1 of 1 and on IA of 2306.
  11. An IA of 2306 has the EA 2500. which is the memory location of the first instruction of the card read-punch interrupt subroutine.
  12. An IA of 2307 has the EA 2600, which is the memory location of the first instruction of the console printer-keyboard interrupt subroutine.
  13. An IA of 2308 has the EA 2700, which is the memory location of the first instruction of the paper tape reoder and paper tape punch interrupt subroutine.
  14. First instruction of housekeeping sequence for console printer-keyboard subroutine.
  15. XIO instruction EA (4102) is the memory location of the console printer-keyboard IOCC.
  16. The IOCC Sense Device function code (111) causes the DSW of the console printer-keyboard (00001) to be loaded into the ACC. The 1-bit in position 15 causes the response to be reset. The example shows 1-bits in positions 2 and 3 of the ACC (DSW), which indicate that the operator initiated on interrupt request on the keyboard and that the console entry switches are to be read. A programmed subroutine determines the cause of the interrupt (Bit 2) and the interrupting device (Bit 3). A routine then follows that reads the data into memory, accomplishes any housekeeping required, and releases the CPU as shown in circled 1.
  17. Procedure is the same as in circled 1 and circled 1. IA (1500) of the BSC instruction is equal to EA of the CPU-generated BSI instruction that initiated the interrupt; see circled 1, circled 1, and circled 1.
  18. EA (0502), located at 1500, is loaded into IAR.
  19. The instruction at 0502 is the next one to be executed in the mainline program. See circled 1 for previous mainline instruction.

Figure 17. Sample Interrupt Recognition Program



But wait, there's MORE...