An Introduction to Interrupts

An interrupt is an unexpected hardware initiated subroutine call or jump that temporarily suspends the running of the current program.
Interrupts occur when a peripheral device asserts an interrupt input pin of the micro-processor. Provided the interrupt is permitted, it will be acknowledged by the processor at the end of the current memory cycle. The processor then services the interrupt by branching to a special service routine written to handle that particular interrupt. Upon servicing the device, the processor is then instructed to continue with what is was doing previously (by use of a special “return from interrupt” instruction).
Interrupts fall into two major categories, maskable and non-maskable.

An interrupt may be either EDGE or LEVEL sensitive.

Edge level interrupts are recognised on the falling or rising edge of the input signal. They are generally used for high priority interrupts and are latched internally inside the processor. If this latching was not done, the processor could easily miss the falling edge (due to its short duration) and thus not respond to the interrupt request.
Level sensitive interrupts overcome the problem of latching, in that the requesting device holds the interrupt line at a specified logic state (normally logic zero) till the processor acknowledges the interrupt. This type of interrupt can be shared by other devices in a wired or configuration, thus is commonly used to support daisy chaining and other techniques.

Maskable Interrupts

The processor can inhibit certain types of interrupts by use of a special interrupt mask bit. This mask bit is part of the condition code register, or a special interrupt register. If this bit is set, and an interrupt request occurs on the Interrupt Request input, it is ignored.

Non-Maskable Interrupts

There are some interrupts which cannot be masked out or ignored by the processor. These are associated with high priority tasks which cannot be ignored (like memory parity or bus faults). In general, most processors support the Non-Maskable Interrupt (NMI). This interrupt has absolute priority, and when it occurs, the processor will finish the current memory cycle, then branch to a special routine written to handle the interrupt request.

Advantages of Interrupts

Interrupts are used to ensure adequate service response times by the processing. Sometimes, with software polling routines, service times by the processor cannot be guaranteed, and data may be lost. The use of interrupts guarantees that the processor will service the request within a specified time period, reducing the likelihood of lost data.

		Maskable	NonMaskable		Acknowledge
	68000	IPL0-IPL2	Where IPL0-IPL2 = 7	FC0-FC2 (111)

	iAPX386	INTR		NMI			M/IO=0   
				RESET			D/C=0

The 68000 uses three input lines, which are priority encoded. A level 7 cannot be masked. The interrupt lines must remain stable until the 68000 signals interrupt acknowledge.
iAPX386INTR is level sensitive, and must remain asserted until the iAPX386 generates the interrupt acknowledge signal. NMI is rising edge sensitive and must be negated for at least eight CLK2 periods, then asserted for at least eight CLK2 periods. Once NMI is accepted, no further NMI’s are processed till an IRET is executed.

The Use of Interrupts

The use of interrupts generally falls into the following categories,

  • Input/Output data transfers for peripheral devices
  • Input signals to be used for timing purposes
  • Emergency situations (power-down)
  • Real-Time-execuives/Multitasking
  • Event driven programs  I/O data transfers are more efficient when interrupt driven, because the processor is released from software polling. The device requests transfer only when there is data to be moved, so the processor does not need to continually poll the device. This releases the CPU to perform other tasks during this period.

The Basic steps involved in interrupt processing are

  1. Enable interrupts
  2. Request an interrupt
  3. Call and perform the interrupt service routine
  4. Return to the previous program

Enabling Interrupts

68000 A device requests an interrupt by presenting a priority level between 1 and 7 to the processor. The interrupt is accepted ONLY if the current processor priority level (in SR) is less than the interrupt level, OR if the request level is 7. Level 7 is equivalent to NMI.
iAPX386 INTR interrupt requests are enabled using the STI instruction (and disabled using CLI). The NMI is always enabled except where the processor is currently servicing an NMI request.

Requesting an Interrupt

When the processor has finished the current memory cycle, it will check for pending interrupts. If an interrupt is pending, and the processor is in the correct state to respond to the interrupt, the processor will begin the process of servicing the interrupt request.
68000 An interrupt is asserted by presenting a priority level of between 1 and 7 to the processor on the IPL0-IPL2 lines.
iAPX386 An INTR is performed by asserting the INTR pin high. An NMI is performed by asserting the NMI pin high.

Servicing the Interrupt

In some processors, when an interrupt request is granted, the processor acknowledges this by the use of an interrupt request acknowledge signal.
68000 The 68000 asserts FC0-FC2 high to indicate an interrupt acknowledge. The requesting device may either supply an interrupt vector number, or indicate auto-vectoring, in which case the vector numbers are 25 to 31, according to the priority level on IPL0-IPL2. The program counter and status register is saved on the stack.
The priority level in the status register is set to the level of the interrupt, which prevents further interrupts of the same or lower levels. The supervisor bit is enabled and the trace bit turned off.
iAPX386 When the INTR occurs, if the Interrupt Flag bit (IF) is enabled, the processor reads an 8-bit vector (using D0-D7) supplied by the interrupting device, which identifies the source of the interrupt. The IF bit is reset when the interrupt is being serviced, effectively disabling further interrupts. It may be set by the interrupt handler to allow nesting interrupts. When the IRET instruction is executed, the original state of the IF bit is restored.
When the NMI occurs, the processor uses an internal vector address of 2. No interrupt acknowledge signal is generated, and the processor ignores further NMI requests whilst servicing the current NMI. The IF bit is cleared on entry to the NMI service routine, which prevents furthet INTR interrupt requests.

The interrupt vector is supplied from the IDT descriptor entries when running in protected mode. The tables base address and limit is stored in IDTR, and each descriptor is eight bytes long. Which descriptor is referenced depends upon the 8 bit vector supplied by the interrupting device. The program counter and EFLAG is saved on the stack.

Returning to the main program

Once the interrupt routine is completed, the interrupt mask bit should be cleared, enabling the servicing of other future or pending interrupts, then a special Return From Interrupt instruction should be executed. This instruction restores the machine registers to the state they were in before the interrupt occurred. When the processors registers are restored to their pre-interrupt state, the program counter will be pointing to the next instruction of the program which was interrupted. The processor will then fetch that instruction, decode and execute it, ie, continue executing the program from where it was interrupted.

The 68000 uses the Return from Exception (RTE) instruction to restore the machine state to that which existed prior to the interrupt occurring. The PC and status register are restored from the supervisor stack. This is forbidden if the processor is running in user state, as the instruction sets the status register directly, which would permit a means of enabling supervisor mode.
iAPX386 The Interrupt Return (IRET) instruction restores the machine state, loading the CS, PC and EFLAGS from the stack. Other exceptions require popping off the error code before executing the IRET (8, 10-14).


  • software programming (scanning or polling)
  • interrupt controlled
  • direct memory access (DMA)

Programmed I/O or Polling

In programmed I/O, all transfers to and from devices is performed by the processor. The processor sends and requests data; all input and output operations are under the control of the program being executed. The transfers are co-ordinated by the use of a special handshake protocol.

To determine if an I/O request is pending, the processor scans each device. If the device is requesting service, it will set a special flag. The flags of the various devices are continuously checked using a scanning loop program. When the processor finds a devices flag set, it branches to the appropriate service routine, and after the service is completed, resumes the polling sequence. Such a software polling loop is shown below.

There are two basic methods used in sensing the device-request flags, the use of a simple input status port, and the use of a priority-encoder input-status port.

A Simple Input-Status Port

The various devices are connected to a decoded location, each device utilising a single bit line. By reading this location, the CPU can determine which device is requesting service.

The Priority-Encoded Input-Status Port

The decoded location is connected to the output of a priority encoder. The input of the priority encoder is connected to each device. When a device requests service, the priority encoder presents a special code combination (unique for each device) to the decoded memory location. The port thus holds the value or address associated with the highest device requesting service.

The priority encoder arranges all devices in a list, devices given a lower priority are serviced when no other higher priority devices need servicing. This simplifies the software required to determine the device, resulting in an increase in speed.

The disadvantages are

  • the extra chip required
  • resultant increases in cost
  • more board space and power consumption
  • fixed priority in hardware

Summary of Software Polled I/O

Polling is the most common and simplest method of I/O control. It requires no special hardware and all I/O transfers are controlled by the CPU program. Polling is a synchronous mechanism, by which devices are serviced in sequential order.

The polling technique, however, has limitations.

  • it is wasteful of the processors time, as it needlessly checks the status of all devices all the time.
  • it is inherently slow, as it checks the status of all I/O devices before it comes back to check any given one again.
  • when fast devices are connected to a system, polling may simply not be fast enough to satisfy the minimum service requirements.
  • priority of the device is determined by the order in the polling loop, but it is possible to change it via software

Interrupt Controlled I/O Transfers

Interrupts are an asynchronous mechanism. Each device is connected to an interrupt line. When a device needs service, it asserts the interrupt line to request the processors attention.

The processor checks for pending interrupts at the end of every memory cycle. Interrupts can be masked, or non-maskable. Once the interrupt has been recognized by the processor and accepted, the device must be serviced. This is done by forcing the processor to a specialized service routine.

The status of the program being executed must first be saved. The processors registers will be saved on the stack, or, at very least, the program counter will be saved. Preserving those registers which are not saved will be the responsibility of the interrupt service routine. Once the program counter has been saved, the processor will branch to the address of the service routine.

If more than one device is connected to the interrupt line, the processor needs to know to which device service routine it should branch to. The identification of the device requesting service can be done in either hardware or software, or a combination of both.

Software Determination of the Requesting Device

A software routine is used to identify the device requesting service. A simple polling technique is used, each device is checked to see if it was the one needing service.

Having identified the device, the processor then branches to the appropriate interrupt-handling-routine address for the given device. The order in which the devices appear in the polling sequence determines their priority.

Software/Hardware Driven Identification (Daisy Chain)

This is significantly faster than a pure software approach. A daisy chain is used to identify the device requesting service.

Daisy chaining is used for level sensitive interrupts, which act like a wired or gate. Any requesting device can take the interrupt line low, and keep it asserted low until it is

Because more than one device can assert the shared interrupt line simultaneously, some method must be employed to ensure device priority. This is done using the interrupt acknowledge signal generated by the processor is response to an interrupt request.

Each device is connected to the same interrupt request line, but the interrupt acknowledge line is passed through each device, from the highest priority device first, to the lowest priority device last.

After preserving the required registers, the microprocessor generates an interrupt acknowledge signal. This is gated through each device. If device 1 generated the interrupt, it will place its identification signal on the data bus, which is read by the
processor, and used to generate the address of the interrupt-service routine. If device 1 did not request the servicing, it will pass the interrupt acknowledge signal on to the next device in the chain. Device 2 follows the same procedure, and so on.

Hardware Identification (Vectored Interrupts)

This is the fastest system. The onus is placed on the requesting device to request the interrupt, and identify itself. The identity could be a branching address for the desired
interrupt-handling routine.

If the device just supplies an identification number, this can be used in conjunction with a lookup table to determine the address of the required service routine. Response time is best when the device requesting service also supplies a branching address.

Priority Interrupt Controller Chips (PIC’s) are hardware chips designed to make the task of a device presenting its own address to the CPU simple. The PIC also assesses the priority of the devices connected to it. Modern PIC’s can also be programmed to prevent the generation of interrupts which are lower than a desired level.


Interrupts guarantee the fastest possible response time to an I/O device requesting service. However, the servicing of the device is still accomplished using software.

This may not be fast enough, for example, to transfer raw data between disks and memory. The solution is to replace the software routines which do the transferring of data with a hardware device(s).

The software routine is replaced with a specialized hardware processor, the Direct Memory Access Controller, or DMAC for short.

Direct memory access (DMA) is a hardware technique used to transfer data between prime memory and peripheral devices. In order to perform the transfer of data, the DMAC requires access to the processors address and data buses.

DMAC options for data transfer

The DMAC has several options available for the transfer of data.
They are,

  • suspend the processor and transfer one byte (cycle steal)
  • suspend the processor and transfer many bytes (burst transfer)
  • use the buses when the processor isn’t (hidden DMA)

The simplest approach is to suspend the processor.

Bus Arbitration

Most processors use special control lines for bus arbitration, ie, controlling the use of the address and data bus,

  • an input which the DMAC uses to request the bus
  • an output(s) indicating the bus status
  • an output indicating acceptance of the DMAC’s bus request

Because the DMAC must drive the address and data buses of the processor, it is necessary for the processor to be able to tri-state these buses in response to a bus request by the DMAC.

DMAC Controller Operation

The diagram illustrates the various stages in DMA data transfer.
When the DMAC receives an interrupt from the device requesting service, it generates a special signal for the microprocessor, the HOLD signal.

The microprocessor then completes its current memory cycle, and tri-states the address and data buses. The CPU then responds with a HOLD ACKNOWLEDGE signal.

This informs the DMAC that the buses are available for use. It then places an address on the address bus which specifies the address at which the data transfer is to take place.

A read or write signal is then generated by the DMAC, and the I/O device either generates or latches the data. The DMAC effectively steals cycles from the processor in order to transfer the byte, so single byte transfer is also known as cycle stealing.

To achieve block transfers, some DMAC’s incorporate an automatic sequencing of the value presented on the address bus. A register is used as a byte count, being decremented for each byte transfer, and upon the byte count reaching zero, the DMAC will release the bus.

When the DMAC operates in burst mode, the CPU is halted for the duration of the data transfer.

Memory Considerations

The speed of memory in a micro-processor based system is the limiting factor on the DMA transfer rate. If the system RAM has a cycle time of 500ns, this means the memory has a bandwidth of 2Mhz. DMA transfers cannot exceed this rate.

Transfers can occur in single bytes, or in bursts of bytes. The type of transfer mode affects the maximum transfer rate also.

If burst mode is used, the effective transfer rate is nearly the same as that of the memory bandwidth, but for single byte transfers, the effective transfer rate is very much slower. This occurs because time is expended in requesting and granting the DMA transfer for each byte.

Hidden DMA transfers

It is possible to perform hidden DMA, which is transparent to the normal operation of the CPU. In other words, the bus is grabbed by the DMAC when the processor is not using it.

The DMAC monitors the execution of the processor, and when it recognises the processor executing an instruction which has sufficient empty clock cycles to perform a byte transfer, it waits till the processor is decoding the op code, then grabs the bus during this time.

The processor is not slowed down, but continues processing normally. Naturally, the data transfer by the DMAC must be completed before the processor starts the execute cycle of the op code.

This technique can only be performed with those processors which provide an indication of the machine cycle status.

Processors utilising cache and pipelining prohibit the use of this technique, as the processor is likely to be using the bus (pre-fetching) whilst decoding the current op-code.

DMAC’s and Operating Systems

In a multi-user system, where many users compete for limited resources such as RAM, it is common for the operating system to use either paging (Virtual memory) or  segmentation (swapping) techniques.

In paging, the users program is split up into small blocks called pages, each about 4Kbytes in size. One or more of those pages resides in prime memory, whilst the rest of the pages which make up the users program are stored on disk.

As the user program executes, it is possible for the program to make reference to a page which currently resides on disk. This is called a page fault. The operating system then takes over, locates the required page on disk, and loads it into RAM (it may also swap some other pages out to make room for the new page!) before the users program is allowed to continue.

This operation is best performed with the help of a DMAC. The operating system can load the DMAC chip with the required information, ie, track/sector(s) information, load address, and then instruct the DMAC to perform the transfer. When the transfer is complete, the DMAC will provide a signal to the processor. The processor can then check the status of the DMAC to ensure the operation was performed correctly.

In mainframes, a special device is used to perform data transfers between devices and memory. It is the IBM I/O Channel. There are two basic types, the selector and the multiplexer channel. The selector type operates in burst mode with one device at a time for maximum speed, whereas the multiplexer can work with many sub-devices simultaneously in byte or burst mode.

	   		Bus Request	Bus Grant
	68000		BR*  		BG*

Direct Memory Access (DMA) and the IBM-PC

DMA is used to transfer data between I/O devices and memory without the aid of the CPU. The DMA device takes over the processor busses and transfers the data a single byte at a time, or as a block (burst mode). In the PC, DMA is performed by the 8237. It is used primarily for dynamic RAM refresh (psuedo reads) and the floppy diskette controller.

The 8237 DMA Controller

This chip is reponsible for handling DMA transfers between various I/O devices and memory. When a device requests service, it asserts its associated request line (DRQ1 to DRQ3), signalling the DMA controller. The 8237 then asserts HOLD to the processor which responds with HLDA (Hold Acknowledge), and floats its busses. Upon receiving this acknowledge, the 8237 takes over the system bus and performs the transfer.

All DMA channels have access to 1mb memory space (20 bit registers) and have a 64k block limitation. Memory to memory transfers which use channel 0 and 1 are not supported, as channel 0 is used to refresh the system RAM.

On the PC/XT, the 8237 transfers 8 bit values between I/O and memory, and transfers must occur on evenbyte boundarys.

The PC series uses the 8237 DMA Controller Chip which is used as follows,

	 Channel  	Purpose
	 0  		Dynamic RAM Refresh
	 1  		SDLC or User programmed
	 2  		Floppy disk
	 3  		Fixed disk

	 Page registers appear at 0x80 to 0x83
	 Controller appears at 0x00 to 0x0f

When the base address is written, it is the real address divided by 2 that is written to the base register.

The method of initiating a dma transfer is,

  1. enable mask register
  2. set mode register, single, autoincrement, write, read etc
  3. determine start address
  4. program 16bits + page register with upper 4 bits
  5. set base count
  6. clear terminal count information by reading status reg
  7. unmask dma channel

Interrupt Latency and Response Time

In responding to interrupts, designers use several terms to describe specific phases of the interrupt process.

  • Interrupt Latency

    The time interval from when the interrupt is first asserted to the time the CPU recognises it. This will depend much upon whether interrupts are disabled,prioritized and what the processor is currently executing.At times, a processor might ignore requests whilst executing some indivisible instruction stream (read-write-modify cycle). The figure that matters most is the longest possible interrupt latency time. Often the real time executive is executing code which cannot be interrupted, running with interrupts disabled. In these instances, latency will vary considerably depending upon when the interrupt occurs, whether in user code or in the executive.

  • Interrupt Response Time

    The time interval between the CPU recognising the interrupt to the time when the first instruction of the interrupt service routine is executed. This is determined by the processor architecture and clock speed. The more processors required to be stacked will increase this time.



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.