*****************************************************************************
*                                                                           *
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY     *
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE       *
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR     *
* PURPOSE.                                                                  *
*                                                                           *
* Copyright (C) 1993-95  Microsoft Corporation.  All Rights Reserved.       *
*                                                                           *
*****************************************************************************

The serial port

     Each serial port of a standard IBM PC connects the rest of the system
     to a type INS8250 Universal Asynchronous Receiver Transmitter (UART)
     integrated circuit (IC) chip developed by National Semiconductor
     Corporation. This chip, along with associated circuits in the port,

     1. Converts data supplied via the system data bus into a sequence of
        voltage levels on the single TXD output line that represent binary
        digits.

     2. Converts data received as a sequence of binary levels on the single
        RXD input line into bytes for the data bus.

     3. Controls the modem's actions through the DTR and RTS output lines.

     4. Provides status information to the processor; this information
        comes from the modem, via the DSR, DCD, CTS, and RI input lines,
        and from within the UART itself, which signals data available, data
        needed, or error detected.

     The word asynchronous in the name of the IC comes from the Bell
     specifications. When computer data is transmitted, each bit's
     relationship to its neighbors must be preserved; this can be done in
     either of two ways. The most obvious method is to keep the bit stream
     strictly synchronized with a clock signal of known frequency and count
     the cycles to identify the bits. Such a transmission is known as
     synchronous, often abbreviated to synch or sometimes bisync for binary
     synchronous. The second method, first used with mechanical
     teleprinters, marks the start of each bit group with a defined start
     bit and the end with one or more defined stop bits, and it defines a
     duration for each bit time. Detection of a start bit marks the
     beginning of a received group; the signal is then sampled at each bit
     time until the stop bit is encountered. This method is known as
     asynchronous (or just asynch) and is the one used by the standard
     IBM PC.

     The start bit is, by definition, exactly the same as that used to
     indicate binary zero, and the stop bit is the same as that indicating
     binary one. A zero signal is often called SPACE, and a one signal is
     called MARK, from terms used in the teleprinter industry.

     During transmission, the least significant bit of the data is sent
     first, after the start bit. A parity bit, if used, appears as the most
     significant bit in the data group, before the stop bit or bits; it
     cannot be distinguished from a databit except by its position. Once
     the first stop bit is sent, the line remains in MARK (sometimes called
     idling) condition until a new start bit indicates the beginning of
     another group.

     In most PC uses, the serial port transfers one 8-bit byte at a time,
     and the term word specifies a 16-bit quantity. In the UART world,
     however, a word is the unit of information sent by the chip in each
     chunk. The word length is part of the control information set into the
     chip during setup operations and can be 5, 6, 7, or 8 bits. This
     discussion follows UART conventions and refers to words, rather than
     to bytes.

     One special type of signal, not often used in PC-to-PC communications
     but sometimes necessary in communicating with mainframe systems, is a
     BREAK. The BREAK is an all-SPACE condition that extends for more than
     one word time, including the stop-bit time. (Many systems require the
     BREAK to last at least 150 milliseconds regardless of data rate.)
     Because it cannot be generated by any normal data character
     transmission, the BREAK is used to interrupt, or break into, normal
     operation. The IBM PC's 8250 UART can generate the BREAK  signal, but
     its duration must be determined by a program, rather than by the chip.

The 8250 UART architecture

     The 8250 UART contains four major functional areas: receiver,
     transmitter, control circuits, and status circuits. Because these
     areas are closely related, some terms used in the following
     descriptions are, of necessity, forward references to subsequent
     paragraphs.

     The major parts of the receiver are a shift register and a data
     register called the Received Data Register. The shift register
     assembles sequentially received data into word-parallel form by
     shifting the level of the RXD line into its front end at each bit time
     and, at the same time, shifting previous bits over. When the shift
     register is full, all bits in it are moved over to the data register,
     the shift register is cleared to all zeros, and the bit in the status
     circuits that indicates data ready is set. If an error is detected
     during receipt of that word, other bits in the status circuits are
     also set.

     Similarly, the major parts of the transmitter are a holding register
     called the Transmit Holding Register and a shift register. Each word
     to be transmitted is transferred from the data bus to the holding
     register. If the holding register is not empty when this is done, the
     previous contents are lost. The transmitter's shift register converts
     word-parallel data into bit-serial form for transmission by shifting
     the most significant bit out to the TXD line once each bit time, at
     the same time shifting lower bits over and shifting in an idling bit
     at the low end of the register. When the last databit has been shifted
     out, any data in the holding register is moved to the shift register,
     the holding register is filled with idling bits in case no more data
     is forthcoming, and the bit in the status circuits that indicates the
     Transmit Holding Register is empty is set to indicate that another
     word can be transferred. The parity bit, if any, and stop bits are
     added to the transmitted stream after the last databit of each word is
     shifted out.

     The control circuits establish three communications features: first,
     line control values, such as word length, whether or not (and how)
     parity is checked, and the number of stop bits; second, modem control
     values, such as the state of the DTR and RTS output lines; and third,
     the rate at which data is sent and received. These control values are
     established by two 8-bit registers and one 16-bit register, which are
     addressed as four 8-bit registers. They are the Line Control Register
     (LCR), the Modem Control Register (MCR), and the 16-bit BRG Divisor
     Latch, addressed as Baud0 and Baud1.

     The BRG Divisor Latch sets the data rate by defining the bit time
     produced by the Programmable Baud Rate Generator (PBRG), a major part
     of the control circuits. The PBRG can provide any data speed from a
     few bits per second to 38400 bps; in the BIOS of the IBM PC, PC/XT,
     and PC/AT, though, only the range 110 through 9600 bps is supported.
     How the LCR and the MCR establish their control values, how the PBRG
     is programmed, and how interrupts are enabled are discussed later.

     The fourth major area in the 8250 UART, the status circuits, records
     (in a pair of status registers) the conditions in the receive and
     transmit circuits, any errors that are detected, and any change in
     state of the RS232C input lines from the modem. When any status
     register's content changes, an interrupt request, if enabled, is
     generated to notify the rest of the PC system. This approach lets the
     PC attend to other matters without having to continually monitor the
     status of the serial port, yet it assures immediate action when
     something does occur.

The 8250 programming interface
     Not all the registers mentioned in the preceding section are
     accessible to programmers. The shift registers, for example, can be
     read from or written to only by the 8250's internal circuits. There
     are 10 registers available to the programmer, and they are accessed by
     only seven distinct addresses (shown in Table 6-2). The Received Data
     Register and the Transmit Holding Register share a single address (a
     read gets the received data; a write goes to the holding register). In
     addition, both this address and that of the Interrupt Enable Register
     (IER) are shared with the PBRG Divisor Latch. A bit in the Line
     Control Register called the Divisor Latch Access Bit (DLAB) determines
     which register is addressed at any specific time.

     In the IBM PC, the seven addresses used by the 8250 are selected by
     the low 3 bits of the port number (the higher bits select the specific
     port). Thus, each serial port occupies eight positions in the address
     space. However, only the lowest address used--the one in which the low
     3 bits are all 0--need be remembered in order to access all eight
     addresses.

     Because of this, any serial port in the PC is referred to by an
     address that, in hexadecimal notation, ends with either 0 or 8: The
     COM1 port normally uses address 03F8H, and COM2 uses 02F8H. This
     lowest port address is usually called the base port address, and each
     addressable register is then referenced as an offset from this base
     value, as shown in Table 6-2.


     Table 6-2. 8250 Port Offsets from Base Address.

     Offset      Name                   Description
     ------------------------------------------------------------------
     If DLAB bit in LCR = 0:
     00H         DATA                   Received Data Register if
                                        read from, Transmit Holding
                                        Register if written to
     01H         IER                    Interrupt Enable Register

     If DLAB bit in LCR = 1:
     00H         Baud0                  BRG Divisor Latch, low byte
     01H         Baud1                  BRG Divisor Latch, high byte

     Not affected by DLAB bit:
     02H         IID                    Interrupt Identifier Register
     03H         LCR                    Line Control Register
     04H         MCR                    Modem Control Register
     05H         LSR                    Line Status Register
     06H         MSR                    Modem Status Register

The control circuits
     The control circuits of the 8250 include the Programmable Baud Rate
     Generator (PBRG), the Line Control Register (LCR), the Modem Control
     Register (MCR), and the Interrupt Enable Register (IER).

     The PBRG establishes the bit time used for both transmitting and
     receiving data by dividing an external clock signal. To select a
     desired bit rate, the appropriate divisor is loaded into the PBRG's
     16-bit Divisor Latch by setting the Divisor Latch Access Bit (DLAB) in
     the Line Control Register to 1 (which changes the functions of
     addresses 0 and 1) and then writing the divisor into Baud0 and Baud1.
     After the bit rate is selected, DLAB is changed back to 0, to permit
     normal operation of the DATA registers and the IER.

     With the 1.8432 MHz external UART clock frequency used in standard IBM
     systems, divisor values (in decimal notation) for bit rates between
     45.5 and 38400 bps are listed in Table 6-3. These speeds are

The MS-DOS Encyclopedia
Copyright (c) 1988 by Microsoft Press.
All Rights Reserved.
     established by a crystal contained in the serial port (or internal
     modem) and are totally unrelated to the speed of the processor's
     clock.


     Table 6-3. Bit Rate Divisor Table for 8250/IBM.

     BPS          Divisor
     ------------------------------------------------------------------
        45.5      2532
        50        2304
        75        1536
       110        1047
       134.5       857
       150         768
       300         384
       600         192
      1200          96
      1800          64
      2000          58
      2400          48
      4800          24
      9600          12
     19200           6
     38400           3

     The remaining control circuits are the Line Control Register, the
     Modem Control Register, and the Interrupt Enable Register. Bits in the
     LCR control the assignment of offsets 0 and 1, transmission of the
     BREAK signal, parity generation, the number of stop bits, and the word
     length sent and received, as shown in Table 6-4.


     Table 6-4. 8250 Line Control Register Bit Values.

     Bit             Name      Binary     Meaning
     ------------------------------------------------------------------
     Address Control:
     7               DLAB      0xxxxxxx   Offset 0 refers to DATA;
                                          offset 1 refers to IER
                               1xxxxxxx   Offsets 0 and 1 refer to BRG
                                          Divisor Latch

     BREAK Control:
     6               SETBRK    x0xxxxxx   Normal UART operation
                               x1xxxxxx   Send BREAK signal

     Parity Checking:
     5,4,3           GENPAR    xxxx0xxx   No parity bit
                               xx001xxx   Parity bit is ODD
                               xx011xxx   Parity bit is EVEN
                               xx101xxx   Parity bit is 1
                               xx111xxx   Parity bit is 0

     Stop Bits:
     2               XSTOP     xxxxx0xx   Only 1 stop bit
                               xxxxx1xx   2 stop bits(1.5 if WL = 5)

     Word Length:
     1,0             WD5       xxxxxx00   Word length = 5
                     WD6       xxxxxx01   Word length = 6
                     WD7       xxxxxx10   Word length = 7
                     WD8       xxxxxx11   Word length = 8

     Two bits in the MCR (Table 6-5) control output lines DTR and RTS; two
     other MCR bits (OUT1 and OUT2) are left free by the UART to be
     assigned by the user; a fifth bit (TEST) puts the UART into a self-
     test mode of operation. The upper 3 bits have no effect on the UART.
     The MCR can be both read from and written to.

     Both of the user-assignable bits are defined in the IBM PC. OUT1 is
     used by Hayes internal modems to cause a power-on reset of their
     circuits; OUT2 controls the passage of UART-generated interrupt
     request signals to the rest of the PC. Unless OUT2 is set to 1,
     interrupt signals from the UART cannot reach the rest of the PC, even
     though all other controls are properly set. This feature is
     documented, but obscurely, in the IBM Technical Reference manuals and
     the asynchronous-adapter schematic; it is easy to overlook when
     writing an interrupt-driven program for these machines.


     Table 6-5. 8250 Modem Control Register Bit Values.

     Name    Binary      Description 
     ------------------------------------------------------------------
     TEST    xxx1xxxx    Turns on UART self-test configuration.
     OUT2    xxxx1xxx    Controls 8250 interrupt signals (User2 Output).
     OUT1    xxxxx1xx    Resets Hayes 1200b internal modem (User1 Output).
     RTS     xxxxxx1x    Sets RTS output to RS232C connector.
     DTR     xxxxxxx1    Sets DTR output to RS232C connector.

     The 8250 can generate any or all of four classes of interrupts, each
     individually enabled or disabled by setting the appropriate control
     bit in the Interrupt Enable Register (Table 6-6). Thus, setting the
     IER to 00H disables all the UART interrupts within the 8250 without
     regard to any other settings, such as OUT2, system interrupt masking,
     or the CLI/STI commands. The IER can be both read from and written to.
     Only the low 4 bits have any effect on the UART.


     Table 6-6. 8250 Interrupt Enable Register Constants.

     Binary       Action
     ------------------------------------------------------------------
     xxxx1xxx     Enable Modem Status Interrupt.
     xxxxx1xx     Enable Line Status Interrupt.
     xxxxxx1x     Enable Transmit Register Interrupt.
     xxxxxxx1     Enable Received Data Ready Interrupt.

The status circuits
     The status circuits of the 8250 include the Line Status Register
     (LSR), the Modem Status Register (MSR), the Interrupt Identifier (IID)
     Register, and the interrupt-request generation system.

     The 8250 includes circuitry that detects a received BREAK signal and
     also detects three classes of data-reception errors. Separate bits in
     the LSR (Table 6-7) are set to indicate that a BREAK has been received
     and to indicate any of the following: a parity error (if lateral
     parity is in use), a framing error (incoming bit = 0 at stop-bit
     time), or an overrun error (word not yet read from receive buffer by
     the time the next word must be moved into it).

     The remaining bits of the LSR indicate the status of the Transmit
     Shift Register, the Transmit Holding Register, and the Received Data
     Register; the most significant bit of the LSR is not used and is
     always 0. The LSR is a read-only register; writing to it has no
     effect.


     Table 6-7. 8250 Line Status Register Bit Values.

     Bit       Binary           Meaning
     ------------------------------------------------------------------
     7         0xxxxxxx         Always zero
     6         x1xxxxxx         Transmit Shift Register empty
     5         xx1xxxxx         Transmit Holding Register empty
     4         xxx1xxxx         BREAK received
     3         xxxx1xxx         Framing error
     2         xxxxx1xx         Parity error
     1         xxxxxx1x         Overrun error
     0         xxxxxxx1         Received data ready

     The MSR (Table 6-8) monitors the four RS232C lines that report modem
     status. The upper 4 bits of this register indicate the voltage level
     of the associated RS232C line; the lower 4 bits indicate that the
     voltage level has changed since the register was last read.


     Table 6-8. 8250 Modem Status Register Bit Values.

     Bit       Binary             Meaning
     ------------------------------------------------------------------
     7         1xxxxxxx           Data Carrier Detected (DCD) level
     6         x1xxxxxx           Ring Indicator (RI) level
     5         xx1xxxxx           Data Set Ready (DSR) level
     4         xxx1xxxx           Clear To Send (CTS) level
     3         xxxx1xxx           DCD change
     2         xxxxx1xx           RI change
     1         xxxxxx1x           DSR change
     0         xxxxxxx1           CTS change

     As mentioned previously, four types of interrupts are generated. The
     four types are identified by flag values in the IID Register (Table
     6-9). These flags are set as follows:

     -  Change of any bit value in the MSR sets the modem status flag.

     -  Setting of the BREAK Received bit or any of the three error bits in
        the LSR sets the line status flag.

     -  Setting of the Transmit Holding Register Empty bit in the LSR sets
        the transmit flag.

     -  Setting of the Received Data Ready bit in the LSR sets the receive
        flag.

     The IID register indicates the interrupt type, even though the IER may
     be disabling that type of interrupt from generating any request. The
     IID is a read-only register; attempts to write to it have no effect.


     Table 6-9. 8250 Interrupt Identification and Causes.

     IID content      Meaning
     ------------------------------------------------------------------
     xxxxxxx1B        No interrupt active


The MS-DOS Encyclopedia
Copyright (c) 1988 by Microsoft Press.
All Rights Reserved.
     xxxxx000B        Modem Status Interrupt; bit changed in MSR

     xxxxx010B        Transmit Register Interrupt; Transmit Holding
                      Register empty, bitset in LSR

     xxxxx100B        Received Data Ready Interrupt; Data Register full,
                      bit set in LSR

     xxxxx110B        Line Status Interrupt; BREAK or error bit set in LSR

     As shown in Table 6-9, an all-zero value (which in most of the other
     registers is a totally disabling condition) means that a Modem Status
     Interrupt condition has not yet been serviced. A modem need not be
     connected, however, for a Modem Status Interrupt condition to occur;
     all that is required is for one of the RS232C non-data input lines to
     change state, thus changing the MSR.

     Whenever a flag is set in the IID, the UART interrupt-request
     generator will, if enabled by the UART programming, generate an
     interrupt request to the processor. Two or more interrupts can be
     active at the same time; if so, more than one flag in the IID register
     is set.

     The IID flag for each interrupt type (and the LSR or MSR bits
     associated with it) clears when the corresponding register is read
     (or, in one case, written to). For example, reading the content of the
     MSR clears the modem status flag; writing a byte to the DATA register
     clears the transmit flag; reading the DATA register clears the receive
     flag; reading the LSR clears the line status flag. The LSR or MSR bit
     does not clear until it has been read; the IID flag clears with the
     LSR or MSR bit.

Programming the UART
     Each time power is applied, any serial-interface device must be
     programmed before it is used. This programming can be done by the
     computer's bootstrap sequence or as a part of the port initialization
     routines performed when a port driver is installed. Often, both
     techniques are used: The bootstrap provides default conditions, and
     these can be modified during initialization to meet the needs of each
     port driver used in a session.

     When the 8250 chip is programmed, the BRG Divisor Latch should be set
     for the proper baud rate, the LCR and MCR should be loaded, the IER
     should be set, and all internal interrupt requests and the receive
     buffer should be cleared. The sequence in which these are done is not
     especially critical, but any pending interrupt requests should be
     cleared before they are permitted to pass on to the rest of the PC.

     The following sample code performs these startup actions, setting up
     the chip in device COM1 (at port 03F8H) to operate at 1200 bps with a
     word length of 8 bits, no parity checking, and all UART interrupts
     enabled. (In practical code, all values for addresses and operating
     conditions would not be built in; these values are included in the
     example to clarify what is being done at each step.)

             MOV     DX,03FBh        ; base port COM1 (03F8) + LCR (3)
             MOV     AL,080h         ; enable Divisor Latch
             OUT     DX,AL
             MOV     DX,03F8h        ; set for Baud0
             MOV     AX,96           ; set divisor to 1200 bps
             OUT     DX,AL
             INC     DX              ; to offset 1 for Baud1
             MOV     AL,AH           ; high byte of divisor
             OUT     DX,AL
             MOV     DX,03FBh        ; back to the LCR offset
             MOV     AL,03           ; DLAB = 0, Parity = N, WL = 8
             OUT     DX,AL
             MOV     DX,03F9h        ; offset 1 for IER
             MOV     AL,0Fh          ; enable all ints in 8250
             OUT     DX,AL
             MOV     DX,03FCh        ; COM1 + MCR (4)
             MOV     AL,0Bh          ; OUT2 + RTS + DTR bits
             OUT     DX,AL 
     CLRGS:
             MOV     DX,03FDh        ; clear LSR
             IN      AL,DX
             MOV     DX,03F8h        ; clear RX reg
             IN      AL,DX
             MOV     DX,03FEh        ; clear MSR
             IN      AL,DX
             MOV     DX,03FAh        ; IID reg
             IN      AL,DX
             IN      AL,DX           ; repeat to be sure
             TEST    AL,1            ; int pending?
             JZ      CLRGS           ; yes, repeat

     Note: This code does not completely set up the IBM serial port.
     Although it fully programs the 8250 itself, additional work remains to
     be done. The system interrupt vectors must be changed to provide
     linkage to the interrupt service routine (ISR) code, and the 8259
     Priority Interrupt Controller (PIC) chip must also be programmed to
     respond to interrupt requests from the UART channels. See PROGRAMMING
     IN THE MS-DOS ENVIRONMENT: CUSTOMIZING MS-DOS: Hardware Interrupt
     Handlers.


The MS-DOS Encyclopedia
Copyright (c) 1988 by Microsoft Press.
All Rights Reserved.

