12.7 Serial Data Communication using IN and OUT

A more detailed knowledge of the Asynchronous Communication Adapter is needed touse it directly via OUT and IN instructions. A simplified logic diagram of the Adapter is shown in Figure 12-4.

The National Semiconductor INS8250 chip is an Asynchronous Communication Element (ACE), also called a Universal Asynchronous Receiver-Transmitter (UART), a "smart peripheral" chip that can be programmed to perform full-duplex conversion of character data between parallel and serial formats at various baud rates, for different character formats, including the insertion and removal of start, stop, and parity bits, control of modem functions, and monitoring of modem status signals. Machines today use a different UART chip than the INS8250, but it is compatible with the 8250, so the following discussions are still valid.

In the PC, I/O ports 3F8h to 3FEh and interrupt request line IRQ4 are assigned to the primary (COM1) adapter, I/O ports 2F8h to 2FEh and interrupt request line IRQ3 to the secondary (COM2) adapter; a jumper on the Adapter card is used to configure it as COM1 or COM2. COM1 and COM3 share IRQ4, and COM2 and COM4 share IRQ3, but each COM port uses a different set of I/O ports.

The internal registers of the 8250 ACE that are accessible via I/O port addresses are shown in Table 12-5. All registers are 8 bits wide. The TRANSMIT HOLDING and RECEIVE BUFFER Registers are padded with 0s on the left for characters with fewer than 8 information bits.

Figure 12-4. Simplified logic diagram of the Asynchronous Communications Adapter

Table 12-5. Accessible registers in the IN8250 ACE

Register Address
Divisor Latch (Low Byte) ComBase+0 and DLAB=1
Divisor Latch (High Byte) ComBase+1 and DLAB=1
Transmit Holding Register ComBase+0 and DLAB=0 and OUT
Receive Buffer Register ComBase+0 and DLAB=0 and IN
Interrupt Enable Register ComBase+1 and DLAB=0
Interrupt ID Register ComBase+2
Line Control Register ComBase+3
Modem Control Register ComBase+4
Line Status Register ComBase+5
Modem Status Register ComBase+6
DLAB=bit 7 of Line Control Register
ComBase=port 03F8h for COM1, port 02F8h for COM2

12.7.1 Selecting Baud Rate and Character Format

Before the 8250 ACE can be used, it must be programmed with baud rate, character format, and interrupt source selections. For standard baud rates and character formats and polled operation the BIOS initialization function described in a previous section is preferable. Otherwise, the 8250 ACE must be programmed by setting the control registers shown in Section 12.7.5.

The baud rate is selected by writing a two-byte divisor value into the DIVISOR LATCHES. An internal clock signal equal to 16 times the baud rate is obtained by dividing this divisor into the oscillator frequency. Several divisor values are shown below for an oscillator frequency of 1.8432 MHz:

Desired Baud Rate Decimal Divisor Hexadecimal Divisor
50 2304 0900
300 384 0180
1200 96 0060
9600 12 000C

The Divisor Latches are accessed by first setting DLAB, the Divisor Latch Access Bit (bit 7 of the Line Control Register); after the divisor bytes are loaded, DLAB must be cleared for normal register addressing. E.g., to select 50 baud, write 80h to the Line Control Register to set DLAB, write 09h to the high-byte Divisor Latch, and 00h to the low-byte Divisor Latch. If the character format is programmed next, DLAB can be cleared then.

The character format is selected by programming the LINE CONTROL Register. E.g., to specify character having 7 information bits, a parity bit forced to 0, and 1 stop bit, write 00111010 to the Line Control Register.

12.7.2 Modem Control and Device Handshaking

The RS-232C interface signals Data Terminal Ready (DTR) and Request to Send (RTS) may be controlled via bits 0 and 1 of the MODEM CONTROL Register; Clear to Send (CTS), Data Set Ready (DSR), Ring Indicator (RI), and Received Line Signal Detect (RLSD)--also Carrier Detect (CD)--may be sensed as bits 4, 5, 6, and 7 of the MODEM STATUS register, and changes in CTS, DSR, RI, and RLSD since the last time the Modem Status Register was read as bits 0, 1, 2, and 3.

12.7.3 Transmit and Receive in the 8250 ACE

The 8250's transmitter uses a Transmit Shift Register (TSR), not accessible to the programmer, together with the Transmit Holding Register (THR) for double-buffered operation: a new character may be written into the THR while the previous character is being shifted out of the TSR on the Serial Out (SOUT) line. The character in THR (and the computed parity bit, if used) is automatically moved to TSR as soon as TSR is empty and serial transmission of the information bits preceded by a start bit and followed by the selected number of stop bits is started. The THR Empty (THRE) Flag indicates when THR can be loaded again; the TSR Empty (TSRE) Flag indicates similarly that TSR is empty (and that a character sent to THR would be immediately moved to TSR, so that a second character may be sent to THR without checking for THRE). The THRE and TSRE flags are found in the LINE STATUS Register; they are set initially by Master Reset. THRE is cleared when a character is loaded into THR.

The 8250's receiver similarly uses a Receive Shift Register (RSR), not accessible to the programmer, together with the Receive Buffer Register (RBR) for double-buffered operation: a character is held in RBR while the bits of the next character frame are being shifted into RSR on the Serial In (SIN) line. When the complete frame has been received, the start and stop bits are deleted, the parity check, if used, is computed, the character is automatically moved from RSR to RBR, and the Received Data Available (RDA) Flag is set. Also the Parity Error Flag is set if the parity check was used but failed, the Framing Error Flag is set if the line was not at the MARK level when the first stop bit was expected, and the Overrun Error Flag is set if the previous character in RBR had not been removed and was overwritten when the new character was moved into RBR from RSR. In addition, the Break Detected Flag is set if the line was in the SPACE condition for more than a character frame time ("long space"). These five flags are found in the LINE STATUS Register; they are cleared initially by Master Reset. RDA is also cleared whenever a character is read from RBR.

12.7.4 Input/Output without Interrupts

If no interrupts are used the INTERRUPT ENABLE Register should be cleared (initialization via BIOS does that) and OUT2 (bit 3 of the MODEM CONTROL Register) should be cleared. The polling routine should check THRE (bit 5 of the Line Status Register) and RDA (bit 0 of the Line Status Register); a new character can be sent to the Transmit Holding Register when THRE = 1; a new character can be read from the Receive Buffer Register when RDA = 1.

12.7.5 Bit Interpretation of Control and Status Registers

Table 12-6. Serial Interrupt Enable Register (@ ComBase+1, with DLAB=0)

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 0 0 0 Enable Modem Status Change (bits 0-3) Interrupt Enable Receive Line Status (bits 1-4) Interrupt Enable Transmit Holding Register Empty (THRE) Interrupt Enable Received Data Available (RDA) Interrupt

Table 12-7. Serial Line Control Register (@ ComBase+3)

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bits 1, 0
Divisor Latch Access Bit (DLAB) Set Break SOUT → 0; Long Space Stick Parity (force parity to ~bit 4) Even parity select Parity Enable

# Stop bits:

0: 1 stop bit
1: 2 stop bits (1.5 if 3 info)

# Info bits:

00: 5 info bits
01: 6 info bits
10: 7 info bits
11: 8 info bits

Table 12-8. Modem Control Register (@ ComBase+4)

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 0 0 Loop (for diagnostics) OUT2 (enables interrupts) OUT1 (n.c.) Request to Send (RTS) Data Terminal Ready (DTR)

Table 12-9. Serial Line Status Register (@ ComBase+5)

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
0 TSR Empty THR Empty Break Detected Framing Error Parity Error Overrun Error Received Data Available (RDA)
  Write to THR Read Line Status Register Read RBR

Table 12-10. Modem Status Register (@ ComBase+6)

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
Received Line Signal Detected (RLSD) Ring Indicator (RI) Data Set Ready (DSR) Clear to Send (CTS) Change in RLSD Trailing Edge RI Change in DSR Change in CTS

12.7.6 Interrupt-Driven Input/Output

The following steps are necessary to allow interrupt-driven operation of the 8250 ACE (the discussion assumes the use of COM1):

  1. Select the 8250 ACE interrupt sources by programming the INTERRUPT ENABLE Register

  2. Set OUT2 in the MODEM CONTROL Register so that the interrupt signal from the 8250 ACE is passed to the IRQ4 Interrupt Request Line

  3. Unmask IRQ4 at the 8259 Programmable Interrupt Controller by clearing bit 4 of the 8259's Mask Register (at port address 21h)

  4. Enable interrupts in the CPU, 8250 ACE interrupts will cause an interrupt 0Ch in the CPU.

The interrupt 0Ch service routine can determine the source of the interrupt by examining the INTERRUPT ID Register and take the appropriate action. The interrupt condition in the 8250 ACE is typically reset automatically, as indicated in the description of the Interrupt ID Register. However, the 8259 Interrupt Controller must also be reset, by sending an End-of-Interrupt command byte (20h) to port 20h before returning from the interrupt service routine.

Unfortunately, the behavior of some versions of the UART is less than ideal. The following anomalies were described in an obscure application note: