How to Change COM1 or COM2 Parameters While Port Is Open

Retired KB Content Disclaimer

This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.

Summary

When using the communications ports in Basic, once the COM port is OPENed (with an OPEN "COM1:..." or OPEN "COM2:..." statement), the port's configuration normally cannot be changed by any Basic statement without closing and then reopening the COM port. However, the parameters to the COM port (the baud rate, parity, stop bits, data bits, etc.) can be changed by directly communicating with the UART using Basic's OUT and INP statements. The UART (Universal Asynchronous Receiver Transmitter) in the IBM PC is the 8250 Asynchronous Communications Element, a dedicated microprocessor chip.


This article contains advanced programmer's information, and should be used only by advanced programmers who are very familiar with the operations of the communications ports. This information applies to Microsoft QuickBasic versions 4.00, 4.00b, and 4.50; to Microsoft Basic Compiler versions 6.00 and 6.00b for MS-DOS; and to Microsoft Basic Professional Development System (PDS) versions 7.00 and 7.10 for MS-DOS.

More Information

To change the communications parameters for a COM port, you must first disable communications interrupts. You can do this by setting bit 4 (for COM1) or bit 3 (for COM2) of the Interrupt Mask Register (IMR, I/O port &H21) (where bits are numbered starting at bit zero; that is, 0, 1, 2, etc.). Note that when this is done, the other bits of this register should remain unchanged, so you should "OR" the current value with the bit value needed, and place the new value back into the register. For example, the following disables COM1:

   OUT &H21, INP(&H21) OR 16
The following disables COM2:

   OUT &H21, INP(&H21) OR 8
Once the COM interrupt is disabled, you can alter the communications parameters. The first of the parameters that you may change is the baud rate. To do this, you must first set the line-control register to allow a change in the baud rate by sending a &H80 to port &H3FB, the line-control register for COM1, or to port &H2FB, the line-control register for COM2. Then, send the appropriate least-significant byte (LSB) and most-significant byte (MSB) of the desired baud rate to ports &H3F8 and &H3F9, respectively, for COM1, or to ports &H2F8 and &H2F9, respectively, for COM2. The LSB and MSB bytes for the baud rates are shown in the following table:


Baud Rate MSB LSB
--------- --- ---

300 01H 80H
600 00H C0H
1200 00H 60H
2400 00H 30H
3600 00H 20H
4800 00H 18H
9600 00H 0CH
Now that the baud rate has been changed, the other parameters must be set (for example, parity type, stop bits, data bits, etc.). These parameters are set by sending the appropriate byte to the line-control register (port &H3FB for COM1, or port &H2FB for COM2). The byte to send is established by setting the appropriate bits according to the following diagram:

THE LINE-CONTROL REGISTER

|-----|-----|-----|-----|-----|-----|-----|-----|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|-----|-----|-----|-----|-----|-----|-----|-----|
| \ | | | | | | Character
| \ | | | | | | length
I/O Addressing < \ | | | | 0 + 0 = 5 bits
0 = Normal value \__| | | | 0 + 1 = 6 bits
1 = To address baud | | | | 1 + 0 = 7 bits
rate divisor | | | | 1 + 1 = 8 bits
registers | | | |
| | | > Stop bits
Set these bits to 0 < | | 0 = 1 stop bit
| | 1 = 1.5 stop bits if 5-bit
| | character length
| | 1 = 2 if 6-, 7-, or 8-bit
| | character length
Parity type < > Parity
0 = even 0 = No parity bit generated
1 = odd 1 = Parity bit generated
(This table is taken from page 180 of "8088 Assembler Language Programming: The IBM PC, Second Edition" by Willen and Krantz [Howard W. Sams & Company, Inc., 1988]. Please read Chapter 7, "Serial Communications," for more technical details.)


After setting these other parameters, the COM interrupt can be reenabled by setting the bit for the COM port back to 0 in the IMR. As before, you must be careful not to disrupt any of the other bits in this register, so to mask the particular bit to 0, logically "AND" the current value of the register with 255 minus the bit value. For example:
   OUT &H21, INP(&H21) AND 239    'enables COM1 (255 - 16 = 239)
OUT &H21, INP(&H21) AND 247 'enables COM2 (255 - 8 = 247)
Once this step is done, communication can resume at the new communication settings. Below is a code example listing that changes the baud rate and parameters of COM1 to 9600,N,8,1.


The following book contains more information about hardware addresses:
"The Programmer's PC Sourcebook," by Thom Hogan (Microsoft Press, 1988)
The following is a code example:
     x% = INP(&H21)                    'disable COM1...
x% = x% OR 16
OUT &H21, x%
OUT &H3FB, &H80 'set for BAUD change
REM OUT &H3F8, &H60 'BAUD-rate-divisor register; &H60 sets 1200 baud
OUT &H3F8, &H0C 'BAUD-rate-divisor register; &H0C sets 9600 baud
OUT &H3F9, &H0 'High byte of BAUD-rate-divisor register
OUT &H3FB, &H3 'N,8,1
x% = INP(&H21) 'reenable COM1...
x% = x% AND 239
OUT &H21, x% 'all done!
Properties

Article ID: 39255 - Last Review: 21/11/2006 - Revision: 1

Feedback