Intel 8259 Programmable Interrupt Controller
The Intel 8259 Programmable Interrupt Controller (PIC) plays an essential role in the operation of much of the hardware of the IBM PC. The PIC can be thought of as an expansion unit to the 8088’s single INTR pin, allowing 8 separate interrupt sources to be handled in a prioritized manner.
The PIC is a surprisingly challenging chip to emulate correctly, partially due to some ambiguities in its documentation.
Overview
The 8 inputs of the PIC are called Interrupt Request lines, which are often referred to as IRQs (Interrupt reQuest).
The PIC has three main 8-bit registers. Each bit in these registers corresponds to an IRQ with the least significant bit mapping to IRQ 0 and the most significant bit mapping to IRQ 7.
- Interrupt Request Register (IRR): This register holds bits reflecting the IRQ lines that are requesting service.
- Interrupt Mask Register (IMR): A
1bit set in this register prevents the corresponding IRQ line from being serviced. - In-Service Register (ISR): A
1bit set in this register indicates that the corresponding IRQ has been acknowledged by the CPU and is now “in-service”.
The 8 IRQs of the PIC are ordered in terms of priority, with IRQ 0 being the highest priority, and IRQ 7 being the lowest priority. This means that if IRQ 0 and IRQ 1 occur simultaneously, IRQ 0 will be serviced first.
This also means that it is possible for a higher priority interrupt to be serviced while a lower priority interrupt is already in service. Normally, the 8088 clears the I flag when executing an interrupt. If a programmer desires their interrupt service routine to be reentrant, they would need to issue an STI instruction to allow this to occur.
IBM PC PIC Configuration
IRQ Assignments
The IBM PC maps devices to the 8259’s IRQ lines as follows. Some of these connections are direct traces on the motherboard, other IRQs are connected to the ISA bus. In some cases, a peripheral card may have had a jumper to allow selection of a particular IRQ.
| IRQ | Connection | Device |
|---|---|---|
| IRQ 0 | Direct | System Timer |
| IRQ 1 | Direct | Keyboard Controller |
| IRQ 2 | ISA/Direct | Vsync Interrupt (EGA) or Secondary 8259 (AT) |
| IRQ 3 | ISA | Serial Port - COM2 |
| IRQ 4 | ISA | Serial Port - COM1 |
| IRQ 5 | ISA | Hard Disk Controller or LPT2 |
| IRQ 6 | ISA | Floppy Disk Controller |
| IRQ 7 | ISA | Parallel Port - LPT1 |
I/O Ports
The 8259 has a single address pin, A0, via which one of two registers can be selected.
The two registers are decoded by the PC at the following addresses:
| PC Port | 8259 Port | RW | Description |
|---|---|---|---|
| 0x20 | 0 | RW | Command/Status Register |
| 0x21 | 1 | RW | Data/Mask Register |
The Unimportant Stuff
The 8259 was designed to be compatible not only with the 8088 and 8086, but with Intel’s earlier CPUs, the 8080 and 8085. There are various mode flag bits that control whether the 8259 should expect to be paired with an 8088 or not - obviously, on the IBM PC, you can expect these bits to be set properly, and emulation of the 8080 modes is certainly not required.
The 8259 supported daisy-chaining of additional 8259 chips to enable more interrupt sources to be handled - something that Intel called cascading. This was not used on the IBM PC, which only had a single 8259. Two 8259s were employed on the IBM 5170 AT in a primary/secondary configuration. Obviously this is something you do not need to emulate either.
The PIC can be operated in edge-triggered or level-triggered mode. The IBM PC exclusively operates in edge-triggered mode, but implementing level-triggered mode is fairly trivial to do.
There are additional features like priority rotation and special mask mode which are not used by the IBM PC.
Interrupt Processing Logic
The important thing to understand about the PIC is that it is implemented as an array of 8 priority cell circuits. The IRR, IMR, and ISR “registers” are simply latches within each priority cell. This means that a good part of the interrupt evaluation logic happens continuously, since it is simply driven by immediate state of the circuit. The PIC has no clock input, so all it can do is respond to changes of its input pins. With one exception - but we’ll talk about that later.
Let’s look at an example of interrupt logic flow:
The Simple Version
- A device raises its IRQ line connected to the PIC.
- The PIC looks to see if that IRQ is masked off in the IMR, if it is already in service, or if a higher-priority interrupt is in service, in which case the interrupt cannot be serviced at the moment.
- If the IRQ can be serviced, the PIC raises the INTR line to the CPU.
- The CPU acknowledges the interrupt and the PIC sets the corresponding bit in the ISR to indicate that the interrupt is now in service. The corresponding bit in the IRR is cleared to indicate the IRQ is no longer requesting service.
- The CPU executes the interrupt based on the 8-bit vector the PIC provides in response to the CPU’s interrupt acknowledgement.
- The interrupt service routine executes. When it is done, it sends an
End-of-Interrupt (EOI)command to the PIC. - The PIC clears the corresponding bit in the
ISRindicating that the interrupt has completed servicing.
The original IRQ line may remain high at this point, but in the PC’s standard edge-triggered mode it will not be serviced again until it transitions low and then high again.
The Detailed Version
- A device raises its IRQ line connected to the PIC.
- The low-to-high transition of the IRQ line sets the IRQ’s edge latch and sets the corresponding bit in the
IRR.- If the corresponding bit in the
IMRis set, the signal from theIRRdoes not propagate further. - If the corresponding bit in the
IMRis clear, the signal from theIRRreaches thePriority Resolver.
- If the corresponding bit in the
- The priority resolver checks to see if the corresponding bit in the
ISRis set, or if any bits lower than the corresponding bit are set, indicating a higher priority interrupt is already in service.- If any of these bits are set, nothing further happens for the moment.
- If none of these bits are set, the priority resolver will instruct the control logic to raise the PIC’s INTR pin, which is connected to the CPU.
- The CPU finishes an instruction, at which point it samples the INTR pin.
- The CPU notices INTR is high.
- If the CPU’s
Iflag is cleared, it ignores INTR being high and continues execution as normal.
- If the CPU’s
- The CPU begins to acknowledge the interrupt.
- The CPU issues one bus cycle with the
INTAbus status encoded. - The CPU bus controller decodes the
INTAbus status and asserts the physical \(\overline{INTA}\) pin.
- The CPU issues one bus cycle with the
- The PIC detects the \(\overline{INTA}\) pin going high.
- The priority resolver sets the highest-priority bit in the
ISRto indicate that the interrupt is entering service. - In edge-triggered mode, the priority resolver clears the corresponding bit in the
IRR.
- This is the only difference between edge-triggered mode and level-triggered mode.
- The control logic asserts the internal \(\overline{FREEZE}\) signal. This prevents any change to any bit in the
IRRwhile the interrupt acknowledge process is active.
- The priority resolver sets the highest-priority bit in the
- The \(\overline{INTA}\) pin goes low as the CPU completes the INTA bus cycle.
- The \(\overline{INTA}\) pin goes high again as the CPU issues a second INTA bus cycle.
- The PIC emits the 8-bit interrupt vector which the CPU reads during the second INTA bus cycle.
- The \(\overline{INTA}\) pin goes low as the CPU completes the second INTA bus cycle.
- The control logic de-asserts the \(\overline{FREEZE}\) signal, allowing the
IRRto update again. - In auto-EOI mode, the priority resolver clears the corresponding
ISRbit.
- The control logic de-asserts the \(\overline{FREEZE}\) signal, allowing the
- The CPU uses the interrupt vector received from the PIC to look up a far pointer to the correct Interrupt Service Routine from the Interrupt Vector Table.
- The CPU clears the
IandTflags, then jumps to the interrupt service routine. - At the end of the interrupt service routine, the routine sends an
EOIcommand to the PIC. - The PIC clears the appropriate bit in the
ISRto indicate that the interrupt has completed servicing.