'=========================================================================== ' Subject: READ/CHANGE BAUD RATE Date: Unknown Date ' Author: Douglas Lusher Code: QB, QBasic, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: MODEM.ABC '=========================================================================== ' > BTW, what's MCR??? ' Modem Control Register. ' > 'Douglas Lusher posted some code sometime back showing how ' > 'to read and change the baud rate using INP/OUT. FUNCTION UARTpresent% (CommPort%) 'returns True (-1) if a National Semiconductor UART (8250B, ' 16450, 16550, or 16550A) is present at the comm port ' specified. If communications is in progress on the port, ' it will be disrupted by running this proceedure. 'Based on Pascal code by Jeff Duntemann ' in Dr. Dobbs Journal, July 1991 ' assume False, UART not detected UARTpresent% = 0 ' a constant LoopBit% = &H10 ' get the base address for the specified port SELECT CASE CommPort% CASE 1: PortBase% = &H3F8 CASE 2: PortBase% = &H2F8 CASE 3: PortBase% = &H3E8 CASE 4: PortBase% = &H2E8 CASE ELSE: ERROR 5 END SELECT RBRPort% = PortBase% THRPort% = RBRPort% MCRPort% = RBRPort% + 4 MSRPort% = RBRPort% + 6 ' put UART into loopback test mode: ' first, save the current value of MCR HoldMCR% = INP(MCRPort%) ' turn on loopback test mode OUT MCRPort%, HoldMCR% OR LoopBit% HoldMSR% = INP(MSRPort%) ' out a specific pattern of bits OUT MCRPort%, &HA OR LoopBit% ' see if the correct pattern of bits comes back Temp% = INP(MSRPort%) AND &HF0 IF Temp% = &H90 THEN UARTpresent% = -1 ' restore the value of MSR OUT MSRPort%, HoldMSR% ' take the UART out of loopback mode and restore ' original value of MCR OUT MCRPort%, HoldMCR AND NOT LoopBit% END FUNCTION FUNCTION UARTtype% (CommPort%) 'returns the type of UART installed at the specified comm port ' 0 = error (bad UART or no UART at this comm port) ' 1 = 8250, usually (not always) found in PC or XT ' 2 = 16450, usually found in AT class machines ' 3 = 16550, found in PS/2 mod 50/60/early 80. FIFOs don't work! ' 4 = 16550A, found in later PS/2's. FIFOs fully operative. 'Based on Pascal code by Jeff Duntemann ' in Dr. Dobbs Journal, July 1991 ' get the base address for the specified port SELECT CASE CommPort% CASE 1: PortBase% = &H3F8 CASE 2: PortBase% = &H2F8 CASE 3: PortBase% = &H3E8 CASE 4: PortBase% = &H2E8 CASE ELSE: ERROR 5 END SELECT FCRport% = PortBase% + 2 IIRport% = FCRport% Scratchport% = PortBase% + 7 ' write a pattern of bits to the scratch register OUT Scratchport%, &HAA ' attempt to read it back IF INP(Scratchport%) <> &HAA THEN ' a UART w/o a scratch register is an 8250 UARTtype% = 1 ELSE ' setting bit zero of the FCR port enables FIFO buffers OUT FCRport%, &H1 ' get the FIFO status bits Temp% = INP(IIRport%) AND &HC0 SELECT CASE Temp% ' if bits 6 & 7 are set it is a 16550A CASE &HC0: UARTtype% = 4 ' if bit 7 is set and bit 6 is clear it is a 16550 CASE &H80: UARTtype% = 3 ' neither bit 6 or bit 7 set means it is a 16450 CASE &H0: UARTtype% = 2 ' error occured CASE ELSE: UARTtype% = 0 END SELECT ' disable the FIFO buffers OUT FCRport%, &H0 END IF END FUNCTION FUNCTION BaudRate& (CommPort%) 'returns the current baud rate for the specifed port BaudRate& = 0 SELECT CASE CommPort% CASE 1: BaseAddr% = &H3F8 CASE 2: BaseAddr% = &H2F8 CASE ELSE: EXIT FUNCTION END SELECT OUT BaseAddr% + 3, INP(BaseAddr% + 3) OR &H80 LSB% = INP(BaseAddr%) MSB% = INP(BaseAddr% + 1) OUT BaseAddr% + 3, INP(BaseAddr% + 3) AND &H7F Divisor& = (MSB% * &H100) + LSB% IF Divisor& THEN BaudRate& = 115200 \ Divisor& EXIT FUNCTION SUB SetBaudRate (CommPort%, NewBaudRate&) ' Dr. Dobbs Journal, May 1991, pg. 127 SELECT CASE CommPort% CASE 1: BaseAddr% = &H3F8 CASE 2: BaseAddr% = &H2F8 CASE ELSE: EXIT SUB END SELECT LCR% = BaseAddr% + 3 Divisor% = 115200 \ NewBaudRate& Temp% = INP(LCR%) OUT LCR%, Temp% OR &H80 ' OUT LCR%, INP(LCR%) OR &H80 OUT BaseAddr% + 1, Divisor% \ &H100 OUT BaseAddr%, Divisor% AND &HFF OUT LCR%, Temp% AND &H7F ' OUT LCR%, INP(LCR%) AND &H7F END SUB