Usage of 8250 UART in a PC

This document briefly describes the registers of an 8250, the chip found in the original IBM PC. The 16450 and 16550 (as found in newer PCs) is very simialr and the 8250 can be considered as having a subset of their full functionality.

Serial port base addresses

There are four main address that are used by the PC's UART.
Port     Address    Interrupt
-----------------------------
COM1       3F8        IRQ4
COM2       2F8        IRQ3
COM3       3E8        IRQ4*
COM4       2E8        IRQ3*
Note: COM3 and COM4 may not necessarily use the IRQ levels shown. Quite often they will use one of IRQ2, IRQ5, IRQ7 or IRQ9

8250 Registers

The 8250 has a number of registers that must be programmed before it can be used. In operation some of these registers are used to indicate status. Additionally the serial card has some extra ports that must be set up correctly. These extra registers are shown below.
            8 2 5 0   R e g i s t e r s
offset	name	Function		Use
--------------------------------------------------------------------------
  0*	DATA	Data Read/Write Reg.	Line I/O
  1*	IER	Interrupt Enable Reg.	Enable Tx, Rx, RxError, Modem int.
  2	IID	Interrupt ID Reg.	ID of highest interrupt source.
  3	LCR	Line Control Reg.	Line control parameters and Break.
  4	MCR	Modem Control Reg.	DTR, RTS, OUT1, OUT2 and loopback.
  5	LSR	Line Status Reg.	Tx and Rx status (PE, FE, OE)
  6	MSR	Modem Status Reg.	CTS, DSR, RI, RLSD & changes.

  0*	DLL	Divisor Latch LOW	LSB of Baudrate divisor
  1*	DLH	Divisor Latch HIGH	MSB ...
(*) Note: Bit 7 of the LCR controls access to the DATA/IER (=0) or Divisor latches (=1).

DATA - Data Read/Write Register

When bit 7 of the LCR is 0 the Read and Write registers are accessed.

IER - Interrupt Enable Register

When bit 7 of the LCR is 0 the IE register is accessed. There are four sources of interrupt on the 8250 that can be enabled by setting a 1 in the following bits of IER.
  0	Rx data int. enable
  1	Tx holding reg. empty int.
  2	Rx status int. enable (ie Parity, Framing, overrun and BREAK enable).
  3	Modem signal change int. enable.

IID - Interrupt ID Register

Indicates the source of the highest priority interrupt. Encoding is:
  0	Interrupt pending (0 = interrupt, 1 = none pending).
  1	Interrupt ID bit 0
  2	Interrupt ID bit 1
 3-7	0
The interrupt ID is prioritised and the ID byte is encoded as follows, the action to clear the interrupt is shown in brackets []. Note that Rx line status interrupts occur for OR, FE, PE and BREAK status:
  06	Rx line status (Highest).	[read LSR]
  04	Rx Data.			[read Rx Data]
  02	Tx Data.			[write Tx or read IIR]
  00	Modem status (Lowest).		[read MSR]

LCR - Line Control Register

Controls the output to the Line:
  0,1	Word length. (00=5, 01=6, 10=7, 11=8)
  2	Stop bits
  3,4	Parity control (00, 10=none, 01 = Odd, 11 = Even)
  5	Stick parity (0 = normal, 1 = obtuse!)
  6	Send Break.
  7	DLA, Divisor Latch Access Bit. (1 = BaudRate divisor latch access)

MCR - Modem Control Register

  0	DTR (pin 4) out
  1	RTS (pin 20) out
  2	OUT1, N/C on PC H/W.
  3	OUT2, Enable the IRQ4 signal to the PIC(s) on a PC.
  4	Loopback, test 8250 internally.
 5-7	0

LSR - Line Status Register

  0	Data ready.
  1	OE, Overrun Error.
  2	PE, Parity Error.
  3	FE, Framing Error.
  4	Break Received.
  5	Tx Holding register empty.
  6	Tx Shift register empty.
  7	0

MSR - Modem Status Register

  0	Delta CTS.
  1	Delta DSR.
  2	RI trailing-Edge detect.
  3	Delta CD.
  4	CTS (pin 5) in status.
  5	DSR (pin 6) in status.
  6	RI (pin 22) in status.
  7	CD (Pin 8) in status.