Ports 20H-21H are decoded by the PC's 8259A Interrupt Controller chip.
This controller is initialized by the BIOS and there is rarely any need to
perform I/O to these ports in application programs.

The only common exception is seen when a program intercepts an IRQ
interrupt (INT 08H-0fH) and does not pass control on to the normal INT
handler.  For instance, when a TSR traps a keystroke via INT 09H, you may
need to send an "End-of-Interrupt" to the 8259.  In most cases, it is wise
to simply pass control down the line to the original interrupt handler and
let it handle such housekeeping chores.

In the following, the ICWs are Initialization Control Words.  These are
output in a particular order during system startup by the BIOS.  The OCWs
are Operation Control Words which may be output by IRQ handlers.

Port  Description
20H  ICW1  First control word initialization sequence
 7 6 5 4 3 2 1 0 
 0 0 0 1         
                  bits mask
             0:  01H (IC4) 1=init sequences will include ICW4
             1:  02H (SNGL) 0=cascaded ctrlrs; 1=single ctrlr
             2:  04H (ADI) not used; set to 0 on PC
             3:  08H (LTIM) 0=edge-triggered; 1=level-triggered
             4:  10H must be 1 (indicates this is ICW1)

21H  ICW2 Second control word in initialization sequence
 7 6 5 4 3 2 1 0 
           0 0 0 
                  bits mask
             3-7: f8H  high-order bits of interrupt table addr

21H  ICW3 Third control word in initialization sequence; not actually
used since bit 4 is set in ICW1.

21H  ICW4  Fourth control word initialization sequence (actually 3rd in PC)
 7 6 5 4 3 2 1 0 
 0 0 0 1         
                  bits mask
             0:  01H (uPM)  1=PC/8088 mode
             1:  02H (AEIO) 1=automatic EOI
                             0=must send EOI at end of int
             2:  04H (M/S)  0=master mode; 1=slave/cascade mode
             3:  08H (BUF)  1=this is a buffered bus
             4:  10H (SFNM) 1=ctrlrs are nested in this system
21H  OCW1  Read/Write: Get/Set Interrupt Mask
Each bit corresponds to an IRQ; a 1-enables that IRQ and a
0 masks it.

20H  OCW2  Write: Change IRQ priority; set EOI mode
 7 6 5 4 3 2 1 0 
  cmd  0 0 level 
                  bits mask
                   0:  07H specifies level (0-7) to be acted upon
                         by command in bits 5-7
                 4:  e0H one of the commands:
000 = rotate in automatic EOI (clear)
001 = non-specific End Of Interrupt
010 = no operation
011 = specific End Of Interrupt
100 = rotate in automatic EOI (set)
101 = rotate on non-specific EOI
110 = set priority
111 = rotate on specific EOI command
Note: The command most commonly sent is 20H to port 20H (that is, the
non-specific End of Interrupt command).  You would use this
after assuming control of an IRQ such as INT 09H (kybd int).

20H  OCW3  Write: Select Status Read Mode
 7 6 5 4 3 2 1 0 
 0     0 1   rmd 
                  bits mask
                0-1:  03H selects register read mode:
                         00=nop; 01=nop
                         10=read IR register on next read cmd
                         11=read IS register on next read cmd
                 2:  04H 1=poll command; 0=no poll command
               5-6:  60H special mask mode:
00=nop; 01=nop
10=reset special mask
11=set special mask

20H or
21H Read: A read of either of these ports returns the status of the

See Also: I/O Port Map
- -

Interrupt Controller Ports