Microsoft KB Archive/39255

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 14:14, 21 July 2020 by X010 (talk | contribs) (Text replacement - "&" to "&")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Knowledge Base


How to Change COM1 or COM2 Parameters While Port Is Open

Article ID: 39255

Article Last Modified on 11/21/2006



APPLIES TO

  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft BASIC Professional Development System 7.1



This article was previously published under Q39255

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!
                


Additional query words: QuickBas BasicCom

Keywords: KB39255