Port Access Libraries: Difference between revisions
m (Protected "Port Access Libraries" ([Edit=Allow only autoconfirmed users] (indefinite) [Move=Allow only autoconfirmed users] (indefinite))) |
No edit summary |
||
(9 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
==LPT Ports== | == LPT Ports == | ||
<center>'''Parallel Ports do Not Require an External LPT Device Connection to Function.'''</center> | <center>'''Parallel Ports do Not Require an External LPT Device Connection to Function.'''</center> | ||
Line 17: | Line 17: | ||
:''Example 1:'' Reading the Parallel Port Data, Status and Control register settings before and after reversing it. | :''Example 1:'' Reading the Parallel Port Data, Status and Control register settings before and after reversing it. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DECLARE DYNAMIC LIBRARY}} "inpout32" | {{Cl|DECLARE LIBRARY|DECLARE DYNAMIC LIBRARY}} "inpout32" | ||
{{Cl|FUNCTION}} Inp32% ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}) | {{Cl|FUNCTION}} Inp32% ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}) | ||
{{Cl|SUB}} Out32 ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}, {{Cl|BYVAL}} Value {{Cl|AS}} {{Cl|INTEGER}}) | {{Cl|SUB}} Out32 ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}, {{Cl|BYVAL}} Value {{Cl|AS}} {{Cl|INTEGER}}) | ||
Line 45: | Line 45: | ||
{{Cl|PRINT}} "Control:"; Inp32(address + 2) 'base + 2 read or write. 32 or over reverses port | {{Cl|PRINT}} "Control:"; Inp32(address + 2) 'base + 2 read or write. 32 or over reverses port | ||
{{Cl|PRINT}} | {{Cl|PRINT}} | ||
{{Cl|END SUB}} | {{Cl|END SUB}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
{{ | {{Small|Contributed by Ted Weissgerber}} | ||
{{OutputStart}}Data: 255 | {{OutputStart}}Data: 255 | ||
Status: 120 | Status: 120 | ||
Line 63: | Line 63: | ||
==Parallel Port Registers== | == Parallel Port Registers == | ||
<center>''Note:'' The normal LPT1 base port is '''&H378'''(888), but it could also be '''&H278'''(632) or '''&H3BC'''(956).</center> | <center>''Note:'' The normal LPT1 base port is '''&H378'''(888), but it could also be '''&H278'''(632) or '''&H3BC'''(956).</center> | ||
{{ | {{FixedStart}} __________________________________________________________ | ||
\ / | \ / | ||
\ '''13 12 11 10 9 8 7 6 5 4 3 2 1 ''' / | \ '''13 12 11 10 9 8 7 6 5 4 3 2 1 ''' / | ||
\ '''{{ | \ '''{{Text|S4 S5 S7 S6|orange}} {{Text|D7 D6 D5 D4 D3 D2 D1 D0|blue}} {{Text|C0|red}}''' / | ||
\ '''25 24 23 22 21 20 19 18 17 16 15 14 ''' / | \ '''25 24 23 22 21 20 19 18 17 16 15 14 ''' / | ||
\ '''{{ | \ '''{{Text|G7 G6 G5 G4 G3 G2 G1 G0|lime}} {{Text|C3 C2|red}} {{Text|S3|orange}} {{Text|C1|red}}''' / | ||
\______________________________________________/ | \______________________________________________/ | ||
''' DB-25 Female ''' | ''' DB-25 Female ''' | ||
10 Ack, 11 Busy, 12 PaperOut, 13 Select, 14 LFeed, 15 Error | 10 Ack, 11 Busy, 12 PaperOut, 13 Select, 14 LFeed, 15 Error | ||
{{ | {{FixedEnd}} | ||
<center>'''[https://www.google.com/search?q=LPT+pinout&biw=1209&bih=569&tbm=isch&imgil=NfwoAN_aS0iIbM%253A%253B_8oZPMerY-hDtM%253Bhttp%25253A%25252F%25252Fwww.firewall.cx%25252Fnetworking-topics%25252Fcabling-utp-fibre%25252F120-network-parallel-cable.html&source=iu&pf=m&fir=NfwoAN_aS0iIbM%253A%252C_8oZPMerY-hDtM%252C_&usg=__9NooKAtd0Kyj3aYOxNGvzhfYryk%3D&ved=0ahUKEwjYjY6JyrPLAhXMdT4KHfhNBo4QyjcIJw&ei=eRPgVpjtCczr-QH4m5nwCA#imgrc=xZhuzmkJ7DEvbM%3A Parallel Port Pinout]'''</center> | <center>'''[https://www.google.com/search?q=LPT+pinout&biw=1209&bih=569&tbm=isch&imgil=NfwoAN_aS0iIbM%253A%253B_8oZPMerY-hDtM%253Bhttp%25253A%25252F%25252Fwww.firewall.cx%25252Fnetworking-topics%25252Fcabling-utp-fibre%25252F120-network-parallel-cable.html&source=iu&pf=m&fir=NfwoAN_aS0iIbM%253A%252C_8oZPMerY-hDtM%252C_&usg=__9NooKAtd0Kyj3aYOxNGvzhfYryk%3D&ved=0ahUKEwjYjY6JyrPLAhXMdT4KHfhNBo4QyjcIJw&ei=eRPgVpjtCczr-QH4m5nwCA#imgrc=xZhuzmkJ7DEvbM%3A Parallel Port Pinout]'''</center> | ||
: '''DO NOT RUN HIGH CURRENT DEVICES with the 5 volt DC output! Use [ | : '''DO NOT RUN HIGH CURRENT DEVICES with the 5 volt DC output! Use [[Wikipedia:Opto-isolator|opto-isolators!]] with a separate power supply.''' | ||
:: '''Use appropriate grounding between devices with the 8 ground pins(green in Pinout diagram) provided!''' | :: '''Use appropriate grounding between devices with the 8 ground pins(green in Pinout diagram) provided!''' | ||
Line 85: | Line 85: | ||
<center>'''Data Register (BaseAddress)'''</center> | <center>'''Data Register (BaseAddress)'''</center> | ||
: '''Read or Write''' in normal operation. D0 to D7 data byte values from 0 to 255 can be converted to [[ASCII]] characters in a device. Setting the byte value can turn certain pins on or off to control switching devices. '''Read only''' to read input in reverse mode set by C5 bit on. | : '''Read or Write''' in normal operation. D0 to D7 data byte values from 0 to 255 can be converted to [[ASCII]] characters in a device. Setting the byte value can turn certain pins on or off to control switching devices. '''Read only''' to read input in reverse mode set by C5 bit on. | ||
<center>'''Software control in normal output mode. {{ | <center>'''Software control in normal output mode. {{Text|Data pin voltages can be set to 0 or 5 volts DC in Reverse mode only!|red}}'''</center> | ||
Line 97: | Line 97: | ||
:'''Read only!''' Register normally used to '''monitor the status of a printer or other device that is connected to the parallel port'''. Pins S3 to S6 are held high by resistors so that it will read 120(or 127) when nothing is connected to the pins. A device can manipulate the read only status port value by grounding certain pins. When 5 volts is fed to a pin, bit will stay on. S7 is inverted so that it adds 128 to the port value when it is grounded. Otherwise S7 is 0 by default. S0, the timeout bit, can be reset off by software when set by EPP mode. Bits S1 and S2 are not used. '''If the port reads 255 the parallel port is not installed.''' | :'''Read only!''' Register normally used to '''monitor the status of a printer or other device that is connected to the parallel port'''. Pins S3 to S6 are held high by resistors so that it will read 120(or 127) when nothing is connected to the pins. A device can manipulate the read only status port value by grounding certain pins. When 5 volts is fed to a pin, bit will stay on. S7 is inverted so that it adds 128 to the port value when it is grounded. Otherwise S7 is 0 by default. S0, the timeout bit, can be reset off by software when set by EPP mode. Bits S1 and S2 are not used. '''If the port reads 255 the parallel port is not installed.''' | ||
<center>'''Pin voltages can be set to 0 or 5 volts DC by chip devices or grounding switches to turn bits 3 to 6 off or bit 7 on.</center> | <center>'''Pin voltages can be set to 0 or 5 volts DC by chip devices or grounding switches to turn bits 3 to 6 off or bit 7 on.</center> | ||
::* '''{{ | ::* '''{{Text|S0|green}}''' Low can be set in EPP mode timeout only(normally off). '''INP32'''(889) [[AND]] 1 = 1 when bit is on '''(no pin)''' | ||
::* '''S3''' Low for error, offline or paper end(normally on). '''INP32'''(889) [[AND]] 8 = 8 when bit is on, pin is high | ::* '''S3''' Low for error, offline or paper end(normally on). '''INP32'''(889) [[AND]] 8 = 8 when bit is on, pin is high | ||
::* '''S4''' High for printer selected(normally on). '''INP32'''(889) [[AND]] 16 = 16 when bit is on, pin is high | ::* '''S4''' High for printer selected(normally on). '''INP32'''(889) [[AND]] 16 = 16 when bit is on, pin is high | ||
::* '''S5''' High for out of paper(normally on). '''INP32'''(889) [[AND]] 32 = 32 when bit is on, pin is high | ::* '''S5''' High for out of paper(normally on). '''INP32'''(889) [[AND]] 32 = 32 when bit is on, pin is high | ||
::* '''S6''' Low for Acknowledge(normally on). '''INP32'''(889) [[AND]] 64 = 64 when bit is on, pin is high | ::* '''S6''' Low for Acknowledge(normally on). '''INP32'''(889) [[AND]] 64 = 64 when bit is on, pin is high | ||
::* '''{{ | ::* '''{{Text|S7|red}}''' High for busy, offline, error.(normally off) '''INP32'''(889) [[AND]] 128 = 128 when bit is on, pin is pulled low | ||
<center>'''{{ | <center>'''{{Text|Bit S0 has no pin and can be set at a timeout or reset to 0 by software in EPP mode only.|green}}'''</center> | ||
<center>'''{{ | <center>'''{{Text|Pin S7 is inverted so that a low pin signal turns the bit on.|red}}'''</center> | ||
Line 113: | Line 113: | ||
<center>'''Control Register (BaseAddress + 2)'''</center> | <center>'''Control Register (BaseAddress + 2)'''</center> | ||
: '''Read or Write.''' Register is used to send messages to a printer or other device that is connected to the port. Usually the port sets itself to read 12(C2 and C3 on) after about 30 seconds. The C0, C1, and C3 pins are inverted while C2 is not. Inverted pins are set on when a bit is set low(off). C4 and C5 have no pins, but can be set internally by a program. Setting C4(16) can turn off the IRQ interrupt. When C5 is on(32) the Data port is reversed to read data sent from a device. | : '''Read or Write.''' Register is used to send messages to a printer or other device that is connected to the port. Usually the port sets itself to read 12(C2 and C3 on) after about 30 seconds. The C0, C1, and C3 pins are inverted while C2 is not. Inverted pins are set on when a bit is set low(off). C4 and C5 have no pins, but can be set internally by a program. Setting C4(16) can turn off the IRQ interrupt. When C5 is on(32) the Data port is reversed to read data sent from a device. | ||
<center>'''WARNING! Software or port hardware controls the port. {{ | <center>'''WARNING! Software or port hardware controls the port. {{Text|Do NOT attempt to change pin voltages!|red}}'''</center> | ||
::* '''{{ | ::* '''{{Text|C0|red}}''' Low(bit on) pulse strobe data sent.(normally off) '''OUT32''' 890, '''INP32'''(890) [[OR]] 1 turns bit on, pin low | ||
::* '''{{ | ::* '''{{Text|C1|red}}''' Low(bit on) linefeed or auto feed.(normally off) '''OUT32''' 890, '''INP32'''(890) [[OR]] 2 turns bit on, pin low | ||
::* '''C2''' Low(bit off) pulse Initiate.(normally on) '''OUT32''' 890, '''INP32'''(890) [[OR]] 4 turns bit on, pin high | ::* '''C2''' Low(bit off) pulse Initiate.(normally on) '''OUT32''' 890, '''INP32'''(890) [[OR]] 4 turns bit on, pin high | ||
::* '''{{ | ::* '''{{Text|C3|red}}''' Low(bit on) printer select in.(normally on) '''OUT32''' 890, '''INP32'''(890) [[OR]] 8 turns bit on, pin low | ||
::* '''{{ | ::* '''{{Text|C4|green}}''' High(bit on) IRQ interrupt off(normally off). '''OUT32''' 890, '''INP32'''(890) [[OR]] 16 turns bit on '''(no pin)''' | ||
::* '''{{ | ::* '''{{Text|C5|green}}''' High(bit on) reverse data port for input read only(normally off). '''OUT32''' 890, '''INP32'''(890) [[OR]] 32 turns bit on '''(no pin)''' | ||
<center>'''{{ | <center>'''{{Text|Red pin numbers are inverted so that bits on set corresponding output pins low and bits off set pins high.|red}}'''</center> | ||
<center>'''{{ | <center>'''{{Text|Bits C4 and C5 designate internal(no pin) software enabled control port register bits|green}}'''</center> | ||
Line 128: | Line 128: | ||
<p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | <p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | ||
==COM Ports== | |||
== COM Ports == | |||
<center>'''Serial Communication Ports Require an External Serial Device or PC COM Port Connection to function!'''</center> | <center>'''Serial Communication Ports Require an External Serial Device or PC COM Port Connection to function!'''</center> | ||
: ''Example 2:'' A 3 wire Teletype program that allows two computers to serially communicate through each keyboard: | : ''Example 2:'' A 3 wire Teletype program that allows two computers to serially communicate through each keyboard: | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DECLARE DYNAMIC LIBRARY}} "inpout32" | {{Cl|DECLARE LIBRARY|DECLARE DYNAMIC LIBRARY}} "inpout32" | ||
{{Cl|FUNCTION}} Inp32% ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}) | {{Cl|FUNCTION}} Inp32% ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}) | ||
{{Cl|SUB}} Out32 ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}, {{Cl|BYVAL}} Value {{Cl|AS}} {{Cl|INTEGER}}) | {{Cl|SUB}} Out32 ({{Cl|BYVAL}} PortAddress {{Cl|AS}} {{Cl|INTEGER}}, {{Cl|BYVAL}} Value {{Cl|AS}} {{Cl|INTEGER}}) | ||
Line 145: | Line 146: | ||
'Out32 Baseadd%, {{Cl|&H}}18 ' 4800 24 | 'Out32 Baseadd%, {{Cl|&H}}18 ' 4800 24 | ||
Out32 Baseadd%, {{Cl|&H}}C ' 9600 12 Maximum baud rate in QB! | Out32 Baseadd%, {{Cl|&H}}C ' 9600 12 Maximum baud rate in QB! | ||
Out32 Baseadd% + 1, {{Cl|&H}}0 'Write DL High Byte | Out32 Baseadd% + 1, {{Cl|&H}}0 'Write DL High Byte | ||
'Set Base and IER back to normal registers, and set Data requirements | 'Set Base and IER back to normal registers, and set Data requirements | ||
Out32 Baseadd% + 3, {{Cl|&H}}3 'set 8 bit word(bit0 + bit1=3), 1 Stop Bit(0ff), No Parity(0ff) | Out32 Baseadd% + 3, {{Cl|&H}}3 'set 8 bit word(bit0 + bit1=3), 1 Stop Bit(0ff), No Parity(0ff) | ||
Line 152: | Line 153: | ||
{{Cl|DO...LOOP|DO}}: x$ = {{Cl|INKEY$}} | {{Cl|DO...LOOP|DO}}: x$ = {{Cl|INKEY$}} | ||
{{Cl|IF...THEN|IF}} x$ = {{Cl|CHR$}}(27) {{Cl|THEN}} {{Cl|EXIT DO}} 'Escape key quits | {{Cl|IF...THEN|IF}} x$ = {{Cl|CHR$}}(27) {{Cl|THEN}} {{Cl|EXIT DO}} 'Escape key quits | ||
{{Cl|IF...THEN|IF}} x$ > "" {{Cl|THEN}} Out32 Baseadd%, {{Cl|ASC}}(x$) 'Write Transmit buffer data | {{Cl|IF...THEN|IF}} x$ > "" {{Cl|THEN}} Out32 Baseadd%, {{Cl|ASC (function)|ASC}}(x$) 'Write Transmit buffer data | ||
{{Cl|IF...THEN|IF}} (Inp32(Baseadd% + 5) {{Cl|AND (boolean)|AND}} 1) {{Cl|THEN}} 'Data ready = 1 (LSR) | {{Cl|IF...THEN|IF}} (Inp32(Baseadd% + 5) {{Cl|AND (boolean)|AND}} 1) {{Cl|THEN}} 'Data ready = 1 (LSR) | ||
{{Cl|PRINT}} {{Cl|CHR$}}(Inp32(Baseadd%)); 'Display Receive buffer data" | {{Cl|PRINT}} {{Cl|CHR$}}(Inp32(Baseadd%)); 'Display Receive buffer data" | ||
{{Cl|END IF}} | {{Cl|END IF}} | ||
{{Cl|LOOP}} | {{Cl|LOOP}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
{{ | {{Small|Adapted from code by T3SL4}} | ||
: Possible port addresses are &H3F8(1016) = COM1, &H2F8(760) = COM2, &H3E8(1000) = COM3 and &H2E8(744) = COM 4. | : Possible port addresses are &H3F8(1016) = COM1, &H2F8(760) = COM2, &H3E8(1000) = COM3 and &H2E8(744) = COM 4. | ||
: Connect each COM port transmit line to the opposing receive line on the other PC. Connect both COM grounds together. | : Connect each COM port transmit line to the opposing receive line on the other PC. Connect both COM grounds together. | ||
<center>{{ | <center>{{Text|'''Serial Communication Ports Require an External Serial Device or PC COM Port Connection to function!'''|red}}</center> | ||
<p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | <p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | ||
==Serial Communication Registers== | |||
== Serial Communication Registers == | |||
<center>Two PC's can communicate between the COM ports using a [http://www.lammertbies.nl/comm/info/RS-232_null_modem.html Null modem cable].</center> | <center>Two PC's can communicate between the COM ports using a [http://www.lammertbies.nl/comm/info/RS-232_null_modem.html Null modem cable].</center> | ||
{{ | {{FixedStart}} | ||
_______________________________ | _______________________________ | ||
\ / | \ / | ||
\ ''' 5 4 3 2 1''' / | \ ''' 5 4 3 2 1''' / | ||
\ '''GND DTR TXD RXD DCD''' / | \ '''GND DTR TXD RXD DCD''' / | ||
\''' 9 8 7 6 ''' / | \''' 9 8 7 6 ''' / | ||
\''' RI CTS RTS DSR ''' / | \''' RI CTS RTS DSR ''' / | ||
\___________________/ | \___________________/ | ||
''' RS-232 Female (DB-9) | ''' RS-232 Female (DB-9) | ||
{{ | {{FixedEnd}} | ||
<center>'''[https://www.google.com/search?q=com+port+pinout&hl=en&prmd=imvns&tbm=isch&tbo=u&source=univ&sa=X&ei=6OivT5arEcjq0gG87riHDA&sqi=2&ved=0CHwQsAQ&biw=970&bih=610 Serial Communication Port Pinouts]'''</center> | <center>'''[https://www.google.com/search?q=com+port+pinout&hl=en&prmd=imvns&tbm=isch&tbo=u&source=univ&sa=X&ei=6OivT5arEcjq0gG87riHDA&sqi=2&ved=0CHwQsAQ&biw=970&bih=610 Serial Communication Port Pinouts]'''</center> | ||
Line 190: | Line 192: | ||
<center>'''Serial Communication Ports Require an External Serial Device or PC COM Port Connection to function!'''</center> | <center>'''Serial Communication Ports Require an External Serial Device or PC COM Port Connection to function!'''</center> | ||
A Serial port can use extra Registers due to the use of a UART chip. When the Base Address is Read, the chip supplies the data from the FIFO(First In First Out) Receive Buffer. When Written to, it sends data to the FIFO Transmit Buffer. If the DLA Bit is On in the LCR register, then the UART base register accepts the Divisor Latch Low Byte data. | A Serial port can use extra Registers due to the use of a UART chip. When the Base Address is Read, the chip supplies the data from the FIFO(First In First Out) Receive Buffer. When Written to, it sends data to the FIFO Transmit Buffer. If the DLA Bit is On in the LCR register, then the UART base register accepts the Divisor Latch Low Byte data. | ||
{{ | {{FixedStart}} '''Address DLAB INP/OUT Abb. Register Name''' | ||
Base + 0 Off Write - Transmitter Hold Buffer | Base + 0 Off Write - Transmitter Hold Buffer | ||
Line 204: | Line 206: | ||
Base + 6 -- Read Only MSR Modem Status Register" | Base + 6 -- Read Only MSR Modem Status Register" | ||
Base + 7 -- Read/Write - Scratch Register (Unused)" | Base + 7 -- Read/Write - Scratch Register (Unused)" | ||
{{ | {{FixedEnd}} | ||
Also there are two Base + 1 Registers. The IER and the DL High Byte. The two Base + 2 Registers (IIR & FCR) act similar to the Base Buffers. The UART chips also use FIFO buffers to receive and send data at the same time. The most common UARTS used today are the 16550 series chips. You can add the bit values to determine the bits you want Written or Read in each register! | Also there are two Base + 1 Registers. The IER and the DL High Byte. The two Base + 2 Registers (IIR & FCR) act similar to the Base Buffers. The UART chips also use FIFO buffers to receive and send data at the same time. The most common UARTS used today are the 16550 series chips. You can add the bit values to determine the bits you want Written or Read in each register! | ||
Line 214: | Line 216: | ||
<center>'''Interrupt Enable Register (BaseAddress + 1)'''</center> | <center>'''Interrupt Enable Register (BaseAddress + 1)'''</center> | ||
This register is fairly simple to use. The only bits used are 0 to 3. You simply set a bit high to enable the appropriate Interrupt. | This register is fairly simple to use. The only bits used are 0 to 3. You simply set a bit high to enable the appropriate Interrupt. | ||
{{ | {{FixedStart}} '''Bit # Bit Value Interrupt Description''' | ||
3 8 Enable Modem Status Interrupt | 3 8 Enable Modem Status Interrupt | ||
2 4 Enable Receiver Line Status Interrupt | 2 4 Enable Receiver Line Status Interrupt | ||
1 2 Enable Transmit Hold Register Empty Interrupt | 1 2 Enable Transmit Hold Register Empty Interrupt | ||
0 1 Enable Received Data Available Interrupt | 0 1 Enable Received Data Available Interrupt | ||
{{ | {{FixedEnd}} | ||
Once the Interrupts are set, you can monitor the port Interrupts in the Read only '''IIR''' Interrupt Identification Register in a COM program routine. You just add the bit on values to use more than one Interrupt Enable and use OUT BaseAdd + 1, bitstotal. The IIR will tell if an Interrupt occurs! The IER register also can be read to find the present settings with INP. Like the Base, the IER is used in DLAB Mode for the Divisor High Byte." | Once the Interrupts are set, you can monitor the port Interrupts in the Read only '''IIR''' Interrupt Identification Register in a COM program routine. You just add the bit on values to use more than one Interrupt Enable and use OUT BaseAdd + 1, bitstotal. The IIR will tell if an Interrupt occurs! The IER register also can be read to find the present settings with INP. Like the Base, the IER is used in DLAB Mode for the Divisor High Byte." | ||
<center>'''Interrupt Identification Register (BaseAddress + 2)'''</center> | <center>'''Interrupt Identification Register (BaseAddress + 2)'''</center> | ||
This register is a '''Read Only''' Register! It monitors the FIFO status and Interrupts sent to the CPU. The Interrupts are enabled in the IER. You can use INP to read it using INP(BaseAddress + 2) AND 2 ^ bitnumber to see if a bit is on or off. The FIFO and Interrupt Status read 2 bits as below: | This register is a '''Read Only''' Register! It monitors the FIFO status and Interrupts sent to the CPU. The Interrupts are enabled in the IER. You can use INP to read it using INP(BaseAddress + 2) AND 2 ^ bitnumber to see if a bit is on or off. The FIFO and Interrupt Status read 2 bits as below: | ||
{{ | {{FixedStart}} '''Bit # INP Value Description''' | ||
7 and 6 FIFO status | 7 and 6 FIFO status | ||
1 1 192 FIFO Enabled | 1 1 192 FIFO Enabled | ||
0 1 64 FIFO Enabled but Unusable | 0 1 64 FIFO Enabled but Unusable | ||
0 0 < 64 No FIFO Available | 0 0 < 64 No FIFO Available | ||
5 32 64 Byte Fifo Enabled (16750 UART) | 5 32 64 Byte Fifo Enabled (16750 UART) | ||
4 0 Reserved (not used) | 4 0 Reserved (not used) | ||
Line 240: | Line 242: | ||
0 0 0 Modem Status Interrupt (Lowest) | 0 0 0 Modem Status Interrupt (Lowest) | ||
0 1 1 = No Interrupt Pending. 0 = Interrupt Pending | 0 1 1 = No Interrupt Pending. 0 = Interrupt Pending | ||
< denotes a byte value less than designated INP value | < denotes a byte value less than designated INP value | ||
{{ | {{FixedEnd}} | ||
For FIFO status, just compare the INP status with 192 using AND as below: | For FIFO status, just compare the INP status with 192 using AND as below: | ||
<center>{{ | <center>{{Text|IF (Inp32(BaseAdd% + 2) AND 192) THEN PRINT "FIFO Enabled"|green}}</center> | ||
<center>'''First In / First Out Control Register (BaseAddress + 2)'''</center> | <center>'''First In / First Out Control Register (BaseAddress + 2)'''</center> | ||
This Register also uses the BaseAddress + 2 address, but it is '''Write Only'''! You can NOT try to Read it! That just returns data from the '''IIR''' Register ONLY! The '''FCR''' register is just used to set Interrupt triggers and clear the data from the Recieve or Transmit buffers of 16550 or higher UARTS. | This Register also uses the BaseAddress + 2 address, but it is '''Write Only'''! You can NOT try to Read it! That just returns data from the '''IIR''' Register ONLY! The '''FCR''' register is just used to set Interrupt triggers and clear the data from the Recieve or Transmit buffers of 16550 or higher UARTS. | ||
{{ | {{FixedStart}} '''Bit # OUT Value Description ''' | ||
7 and 6 Interrupt Trigger Level | 7 and 6 Interrupt Trigger Level | ||
1 1 192 14 Byte Trigger | 1 1 192 14 Byte Trigger | ||
1 0 128 8 Byte Trigger | 1 0 128 8 Byte Trigger | ||
0 1 64 4 Byte Trigger | 0 1 64 4 Byte Trigger | ||
0 0 < 64 1 Byte Trigger | 0 0 < 64 1 Byte Trigger | ||
5 32 Enable 64 Byte FIFO (16750 UART only) | 5 32 Enable 64 Byte FIFO (16750 UART only) | ||
4 0 Reserved (not used) | 4 0 Reserved (not used) | ||
3 8 DMA Mode Select (mode 1 or 2) | 3 8 DMA Mode Select (mode 1 or 2) | ||
2 4 Clear Transmit FIFO | 2 4 Clear Transmit FIFO | ||
1 2 Clear Receive FIFO | 1 2 Clear Receive FIFO | ||
0 1 Enable FIFO's. 0 = Disabled FIFO" | 0 1 Enable FIFO's. 0 = Disabled FIFO" | ||
< denotes a byte value less than designated OUT value | < denotes a byte value less than designated OUT value | ||
{{ | {{FixedEnd}} | ||
If the trigger bytes are found in the FIFO buffer, then the Data Receive Available Interrupt in the IIR will trigger. Bits 1 and 2 clear the buffer when set hi. They will automatically reset to 0 when done. Data is lost when cleared or if bit 0 is set to 0. Be aware of this and use carefully! This register is only normally used to clear the buffers and enable them. The 0 bit must be set to 1 or both FIFO buffers are disabled! Reset it! | If the trigger bytes are found in the FIFO buffer, then the Data Receive Available Interrupt in the IIR will trigger. Bits 1 and 2 clear the buffer when set hi. They will automatically reset to 0 when done. Data is lost when cleared or if bit 0 is set to 0. Be aware of this and use carefully! This register is only normally used to clear the buffers and enable them. The 0 bit must be set to 1 or both FIFO buffers are disabled! Reset it! | ||
<center>'''Line Control Register (BaseAddress + 3)'''</center> | <center>'''Line Control Register (BaseAddress + 3)'''</center> | ||
This Register can determine the Word Length, Stop Bits, Parity and help set the Baud Rate of the Serial Port. For instance, OUT (BaseAddress + 3), 3 will set the Word Length to 8 with 1 Stop Bit and No Parity. Similar to OPEN COM, but you can also open COM ports other than COM1 or COM2 in this register. '''Be sure to Write a Register value less than 128 after the DLAB baud is set!''' | This Register can determine the Word Length, Stop Bits, Parity and help set the Baud Rate of the Serial Port. For instance, OUT (BaseAddress + 3), 3 will set the Word Length to 8 with 1 Stop Bit and No Parity. Similar to OPEN COM, but you can also open COM ports other than COM1 or COM2 in this register. '''Be sure to Write a Register value less than 128 after the DLAB baud is set!''' | ||
{{ | {{FixedStart}} '''Bit # Bit Value Description''' | ||
7 128 Divisor Latch Access Bit (set baud rate) | 7 128 Divisor Latch Access Bit (set baud rate) | ||
< 128 Access Receive & Transmit buffers & IER | < 128 Access Receive & Transmit buffers & IER | ||
6 0 Set Break Enable. 64 = Break in Receiver TD" | 6 0 Set Break Enable. 64 = Break in Receiver TD" | ||
5, 4, 3 Parity Select | 5, 4, 3 Parity Select | ||
X X 0 0 No Parity (bit 3 off only)" | X X 0 0 No Parity (bit 3 off only)" | ||
0 0 1 8 Odd Parity | 0 0 1 8 Odd Parity | ||
0 1 1 24 Even Parity | 0 1 1 24 Even Parity | ||
1 0 1 40 High Parity (Sticky) | 1 0 1 40 High Parity (Sticky) | ||
1 1 1 56 Low Parity (Sticky) | 1 1 1 56 Low Parity (Sticky) | ||
2 0 One Stop Bit (normal) | 2 0 One Stop Bit (normal) | ||
4 2 Stop bits(wordlength 6,7,8) or 1.5 (5)" | 4 2 Stop bits(wordlength 6,7,8) or 1.5 (5)" | ||
1 and 0 Set Word Length | 1 and 0 Set Word Length | ||
1 1 3 8 Bit Word (normal) | 1 1 3 8 Bit Word (normal) | ||
1 0 2 7 Bit Word | 1 0 2 7 Bit Word | ||
0 1 1 6 Bit Word | 0 1 1 6 Bit Word | ||
0 0 0 5 Bit Word | 0 0 0 5 Bit Word | ||
< denotes a byte value less than designated OUT value | < denotes a byte value less than designated OUT value | ||
{{ | {{FixedEnd}} | ||
<center>'''The Divisor Latch Access Bit and Setting the Baud Rate'''</center> | <center>'''The Divisor Latch Access Bit and Setting the Baud Rate'''</center> | ||
You can set the Baud Rate first by sending 128 to the LCR with OUT. This forces the '''Base''' and '''IER''' Registers to accept the Divisor Latch Low and High Byte values respectively. In DLAB mode both registers can be written to or read to find the current Divisor byte settings! The Divisor value is the number that 115200 must be divided by to attain the baud rate: | You can set the Baud Rate first by sending 128 to the LCR with OUT. This forces the '''Base''' and '''IER''' Registers to accept the Divisor Latch Low and High Byte values respectively. In DLAB mode both registers can be written to or read to find the current Divisor byte settings! The Divisor value is the number that 115200 must be divided by to attain the baud rate: | ||
{{ | {{FixedStart}} '''Speed (BPS) Divisor High Byte(to Base + 1) Low Byte(to Base)''' | ||
50 2304 &H9 (2304) &H0 (0) | 50 2304 &H9 (2304) &H0 (0) | ||
300 384 &H1 (256) &H80 (128) | 300 384 &H1 (256) &H80 (128) | ||
600 192 &H0 &HC0 (192) | 600 192 &H0 &HC0 (192) | ||
1200 96 &H0 &H60 (96) | 1200 96 &H0 &H60 (96) | ||
2400 48 &H0 &H30 (48) | 2400 48 &H0 &H30 (48) | ||
4800 24 &H0 &H18 (24) | 4800 24 &H0 &H18 (24) | ||
Line 303: | Line 305: | ||
19200 6 &H0 &H6 (6) | 19200 6 &H0 &H6 (6) | ||
115200 1 &H0 &H1 (1) | 115200 1 &H0 &H1 (1) | ||
{{ | {{FixedEnd}} | ||
The divisor is based on 115,200 as the maximum Baud Rate. Speeds above 300 just send 0 to the IER, but it must be sent too! Below is a routine to set up any COM port without an OPEN statement. Simply use OUT to set it up: | The divisor is based on 115,200 as the maximum Baud Rate. Speeds above 300 just send 0 to the IER, but it must be sent too! Below is a routine to set up any COM port without an OPEN statement. Simply use OUT to set it up: | ||
{{TextStart}} BaseAdd% = {{Cb|&H}}3F8 'use any valid COM base address on your PC | {{TextStart}} BaseAdd% = {{Cb|&H}}3F8 'use any valid COM base address on your PC | ||
Line 309: | Line 311: | ||
Out32 BaseAdd% + 1, {{Cb|&H}}0 'set DL High Byte on IE Register | Out32 BaseAdd% + 1, {{Cb|&H}}0 'set DL High Byte on IE Register | ||
Out32 BaseAdd%, {{Cb|&H}}60 'set DL Low Byte to 1200 baud (96) on Base Register | Out32 BaseAdd%, {{Cb|&H}}60 'set DL Low Byte to 1200 baud (96) on Base Register | ||
Out32 BaseAdd% + 3, {{Cb|&H}}3 'sets 8 bit Word, 1 Stop Bit, and No Parity (LCR) * | Out32 BaseAdd% + 3, {{Cb|&H}}3 'sets 8 bit Word, 1 Stop Bit, and No Parity (LCR) * | ||
{{TextEnd}} | {{TextEnd}} | ||
: ''Explanation:'' Setting the LCR register's value below 128 resets it from DLAB mode to normal Base Buffer and '''IER''' operations | : ''Explanation:'' Setting the LCR register's value below 128 resets it from DLAB mode to normal Base Buffer and '''IER''' operations | ||
<center>'''Modem Control Register (BaseAddress + 4)'''</center> | <center>'''Modem Control Register (BaseAddress + 4)'''</center> | ||
Like the LCR Register, it is Read and Write! Bit 4 sets Loopback Mode that sends TD data back to RD buffer. Bits 1 and 0 force RTS and DTR signals. The Auxiliary Outputs are seldom used anymore! Just set those bits to 0. | Like the LCR Register, it is Read and Write! Bit 4 sets Loopback Mode that sends TD data back to RD buffer. Bits 1 and 0 force RTS and DTR signals. The Auxiliary Outputs are seldom used anymore! Just set those bits to 0. | ||
{{ | {{FixedStart}} '''Bit # Bit Value Description''' | ||
4 16 LoopBack Mode (Test UART operation) | 4 16 LoopBack Mode (Test UART operation) | ||
3 8 Aux Output 2(control by other circuitry) | 3 8 Aux Output 2(control by other circuitry) | ||
2 4 Aux Output 1(MIDI, normally disconnected) | 2 4 Aux Output 1(MIDI, normally disconnected) | ||
1 2 Force Request to Send (RTS) | 1 2 Force Request to Send (RTS) | ||
0 1 Force Data Terminal Ready (DTR) | 0 1 Force Data Terminal Ready (DTR) | ||
{{ | {{FixedEnd}} | ||
<center>'''Line Status Register (BaseAddress + 5)'''</center> | <center>'''Line Status Register (BaseAddress + 5)'''</center> | ||
'''Read Only''' status register used to detect data buffer activity and errors. If ANY data error occurs, bit 7 will be turned on. Specific errors are also listed. Normally only Bit 0 is read, as these errors do not stop the port! Use this register to check for transfer errors. | '''Read Only''' status register used to detect data buffer activity and errors. If ANY data error occurs, bit 7 will be turned on. Specific errors are also listed. Normally only Bit 0 is read, as these errors do not stop the port! Use this register to check for transfer errors. | ||
{{ | {{FixedStart}} '''Bit # INP Value Description''' | ||
7 128 Error in Received FIFO | 7 128 Error in Received FIFO | ||
6 64 Empty Data Hold Registers(TD and RD Idle) | 6 64 Empty Data Hold Registers(TD and RD Idle) | ||
5 32 Empty Transmitter Hold Register(TD empty) | 5 32 Empty Transmitter Hold Register(TD empty) | ||
Line 336: | Line 338: | ||
1 2 Overrun Error (cannot read fast enough) | 1 2 Overrun Error (cannot read fast enough) | ||
0 1 Data Ready (Receiver ready to be read) | 0 1 Data Ready (Receiver ready to be read) | ||
{{ | {{FixedEnd}} | ||
<center>'''Modem Status Register (BaseAddress + 6)'''</center> | <center>'''Modem Status Register (BaseAddress + 6)'''</center> | ||
This '''Read Only''' register monitors each bit each time read. Delta type bits denote any changes since the last time read. Bit 2 On indicates that there was a change from low to high on the RI line since the last read. Often used in modem data transfers! | This '''Read Only''' register monitors each bit each time read. Delta type bits denote any changes since the last time read. Bit 2 On indicates that there was a change from low to high on the RI line since the last read. Often used in modem data transfers! | ||
{{ | {{FixedStart}} '''Bit # INP Value Description''' | ||
7 128 Carrier Detect (CD) | 7 128 Carrier Detect (CD) | ||
6 64 Ring Indicator (RI) | 6 64 Ring Indicator (RI) | ||
5 32 Data Set Ready (DSR) | 5 32 Data Set Ready (DSR) | ||
4 16 Clear To Send (CTS) | 4 16 Clear To Send (CTS) | ||
3 8 Delta Data Carrier Detect | 3 8 Delta Data Carrier Detect | ||
2 4 Trailing Edge Ring Indicator | 2 4 Trailing Edge Ring Indicator | ||
1 2 Delta Data Set Ready | 1 2 Delta Data Set Ready | ||
0 1 Delta Clear to Send | 0 1 Delta Clear to Send | ||
{{ | {{FixedEnd}} | ||
Line 358: | Line 360: | ||
<p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | <p style="text-align: center">([[#toc|Return to Table of Contents]])</p> | ||
{{PageSeeAlso}} | |||
* [[DECLARE | * [[DECLARE LIBRARY]] | ||
* [[INP]], [[OUT]] | * [[INP]], [[OUT]] | ||
* [[ | * [[Windows Libraries#Windows_Ports|Enumerating Windows Ports]] | ||
{{ | {{PageReferences}} |
Latest revision as of 13:21, 19 November 2024
INP and OUT are often used to access port registers, but in QB64 this capability is limited so here are some DLL Libraries:
- The following download links have the DLL and sample BAS file to show how it works with an LPT (parallel) port at &H378(888):
LPT Ports
- Example 1: Reading the Parallel Port Data, Status and Control register settings before and after reversing it.
DECLARE DYNAMIC LIBRARY "inpout32" FUNCTION Inp32% (BYVAL PortAddress AS INTEGER) SUB Out32 (BYVAL PortAddress AS INTEGER, BYVAL Value AS INTEGER) END DECLARE baseadd = 888 'base address for most LPT printers is &H378 LPTport (baseadd) _DELAY 2 Out32 baseadd + 2, 32 'set control bit 6(C5) high to reverse port to read incoming data _DELAY 2 'sets Data port to 0. may not work on all parallel ports LPTport (baseadd) _DELAY 2 Out32 baseadd + 2, 12 'control port is normally set to 12 Out32 baseadd, 227 'any ASCII code value from 0 to 255. Code 227 prints p character LPTport (baseadd) SUB LPTport (address) basedata% = Inp32(address) PRINT "Data:"; basedata%; CHR$(basedata%) 'read or write PRINT "Status:"; Inp32(address + 1) 'base + 1 read only status from device! PRINT "Control:"; Inp32(address + 2) 'base + 2 read or write. 32 or over reverses port PRINT END SUB |
Data: 255 Status: 120 Control: 12 Data: 0 Status: 120 Control: 32 Data: 227 π Status: 120 Control: 12 |
Parallel Port Registers
__________________________________________________________ \ / \ 13 12 11 10 9 8 7 6 5 4 3 2 1 / \ S4 S5 S7 S6 D7 D6 D5 D4 D3 D2 D1 D0 C0 / \ 25 24 23 22 21 20 19 18 17 16 15 14 / \ G7 G6 G5 G4 G3 G2 G1 G0 C3 C2 S3 C1 / \______________________________________________/ DB-25 Female 10 Ack, 11 Busy, 12 PaperOut, 13 Select, 14 LFeed, 15 Error |
- DO NOT RUN HIGH CURRENT DEVICES with the 5 volt DC output! Use opto-isolators! with a separate power supply.
- Use appropriate grounding between devices with the 8 ground pins(green in Pinout diagram) provided!
- Read or Write in normal operation. D0 to D7 data byte values from 0 to 255 can be converted to ASCII characters in a device. Setting the byte value can turn certain pins on or off to control switching devices. Read only to read input in reverse mode set by C5 bit on.
- Pin Bit values on: D0(+ 1), D1(+ 2), D2(+ 4), D3(+ 8), D4(+ 16), D5(+ 32), D6(+ 64), D7(+ 128)
- Read only! Register normally used to monitor the status of a printer or other device that is connected to the parallel port. Pins S3 to S6 are held high by resistors so that it will read 120(or 127) when nothing is connected to the pins. A device can manipulate the read only status port value by grounding certain pins. When 5 volts is fed to a pin, bit will stay on. S7 is inverted so that it adds 128 to the port value when it is grounded. Otherwise S7 is 0 by default. S0, the timeout bit, can be reset off by software when set by EPP mode. Bits S1 and S2 are not used. If the port reads 255 the parallel port is not installed.
- S0 Low can be set in EPP mode timeout only(normally off). INP32(889) AND 1 = 1 when bit is on (no pin)
- S3 Low for error, offline or paper end(normally on). INP32(889) AND 8 = 8 when bit is on, pin is high
- S4 High for printer selected(normally on). INP32(889) AND 16 = 16 when bit is on, pin is high
- S5 High for out of paper(normally on). INP32(889) AND 32 = 32 when bit is on, pin is high
- S6 Low for Acknowledge(normally on). INP32(889) AND 64 = 64 when bit is on, pin is high
- S7 High for busy, offline, error.(normally off) INP32(889) AND 128 = 128 when bit is on, pin is pulled low
- Read or Write. Register is used to send messages to a printer or other device that is connected to the port. Usually the port sets itself to read 12(C2 and C3 on) after about 30 seconds. The C0, C1, and C3 pins are inverted while C2 is not. Inverted pins are set on when a bit is set low(off). C4 and C5 have no pins, but can be set internally by a program. Setting C4(16) can turn off the IRQ interrupt. When C5 is on(32) the Data port is reversed to read data sent from a device.
- C0 Low(bit on) pulse strobe data sent.(normally off) OUT32 890, INP32(890) OR 1 turns bit on, pin low
- C1 Low(bit on) linefeed or auto feed.(normally off) OUT32 890, INP32(890) OR 2 turns bit on, pin low
- C2 Low(bit off) pulse Initiate.(normally on) OUT32 890, INP32(890) OR 4 turns bit on, pin high
- C3 Low(bit on) printer select in.(normally on) OUT32 890, INP32(890) OR 8 turns bit on, pin low
- C4 High(bit on) IRQ interrupt off(normally off). OUT32 890, INP32(890) OR 16 turns bit on (no pin)
- C5 High(bit on) reverse data port for input read only(normally off). OUT32 890, INP32(890) OR 32 turns bit on (no pin)
- Use OUT32 with OR to turn a bit on or XOR to change the current bit status. INP32 with AND can determine if a bit is on or off(0).
COM Ports
- Example 2: A 3 wire Teletype program that allows two computers to serially communicate through each keyboard:
DECLARE DYNAMIC LIBRARY "inpout32" FUNCTION Inp32% (BYVAL PortAddress AS INTEGER) SUB Out32 (BYVAL PortAddress AS INTEGER, BYVAL Value AS INTEGER) END DECLARE Baseadd% = &H3F8 'any valid COM port address (see the Windows Hardware COM port Properties) Out32 Baseadd% + 3, &H80 'set Divisor Latch Access Bit using 128 Hex (LCR) 'Out32 Baseadd%, &H60 ' 1200 baud 96 Write DL Low Byte 'Out32 Baseadd%, &H30 ' 2400 48 'Out32 Baseadd%, &H18 ' 4800 24 Out32 Baseadd%, &HC ' 9600 12 Maximum baud rate in QB! Out32 Baseadd% + 1, &H0 'Write DL High Byte 'Set Base and IER back to normal registers, and set Data requirements Out32 Baseadd% + 3, &H3 'set 8 bit word(bit0 + bit1=3), 1 Stop Bit(0ff), No Parity(0ff) 'COM should now be set as N, 8, 1 by the LCR. Like an OPEN statement. Out32 Baseadd% + 2, &H3 'Flush receiver FIFO buffer, enable FIFO (FCR) DO: x$ = INKEY$ IF x$ = CHR$(27) THEN EXIT DO 'Escape key quits IF x$ > "" THEN Out32 Baseadd%, ASC(x$) 'Write Transmit buffer data IF (Inp32(Baseadd% + 5) AND 1) THEN 'Data ready = 1 (LSR) PRINT CHR$(Inp32(Baseadd%)); 'Display Receive buffer data" END IF LOOP |
- Possible port addresses are &H3F8(1016) = COM1, &H2F8(760) = COM2, &H3E8(1000) = COM3 and &H2E8(744) = COM 4.
- Connect each COM port transmit line to the opposing receive line on the other PC. Connect both COM grounds together.
Serial Communication Registers
_______________________________ \ / \ 5 4 3 2 1 / \ GND DTR TXD RXD DCD / \ 9 8 7 6 / \ RI CTS RTS DSR / \___________________/ RS-232 Female (DB-9) |
A Serial port can use extra Registers due to the use of a UART chip. When the Base Address is Read, the chip supplies the data from the FIFO(First In First Out) Receive Buffer. When Written to, it sends data to the FIFO Transmit Buffer. If the DLA Bit is On in the LCR register, then the UART base register accepts the Divisor Latch Low Byte data.
Address DLAB INP/OUT Abb. Register Name Base + 0 Off Write - Transmitter Hold Buffer Off Read - Receiver Buffer On Read/Write - Divisor Latch Low Byte Base + 1 Off Read/Write IER Interrupt Enable Register On Read/Write - Divisor Latch High Byte Base + 2 -- Read Only IIR Interrupt ID Register -- Write Only FCR FIFO Control Register Base + 3 Set Read/Write LCR Line Control Register(DLAB On/Off) Base + 4 -- Read/Write MCR Modem Control Register Base + 5 -- Read Only LSR Line Status Register Base + 6 -- Read Only MSR Modem Status Register" Base + 7 -- Read/Write - Scratch Register (Unused)" |
Also there are two Base + 1 Registers. The IER and the DL High Byte. The two Base + 2 Registers (IIR & FCR) act similar to the Base Buffers. The UART chips also use FIFO buffers to receive and send data at the same time. The most common UARTS used today are the 16550 series chips. You can add the bit values to determine the bits you want Written or Read in each register!
Like the bi-directional Parallel port, the COM Base Address can send data to a device and also can receive data at the same time. It accomplishes this by using two FIFO (First In First Out) buffers. To send Data you can use PRINT # or OUT a value to the Base Address. To read data you can use INP(baseaddress) or use OPEN COM with INPUT$ (bytes, COMnumber) while LOC(COMnumber) checks for data in the receive buffer. The Base can also set the Divisor Latch Low Byte, which can also help set the baud rate of the port.
This register is fairly simple to use. The only bits used are 0 to 3. You simply set a bit high to enable the appropriate Interrupt.
Bit # Bit Value Interrupt Description 3 8 Enable Modem Status Interrupt 2 4 Enable Receiver Line Status Interrupt 1 2 Enable Transmit Hold Register Empty Interrupt 0 1 Enable Received Data Available Interrupt |
Once the Interrupts are set, you can monitor the port Interrupts in the Read only IIR Interrupt Identification Register in a COM program routine. You just add the bit on values to use more than one Interrupt Enable and use OUT BaseAdd + 1, bitstotal. The IIR will tell if an Interrupt occurs! The IER register also can be read to find the present settings with INP. Like the Base, the IER is used in DLAB Mode for the Divisor High Byte."
This register is a Read Only Register! It monitors the FIFO status and Interrupts sent to the CPU. The Interrupts are enabled in the IER. You can use INP to read it using INP(BaseAddress + 2) AND 2 ^ bitnumber to see if a bit is on or off. The FIFO and Interrupt Status read 2 bits as below:
Bit # INP Value Description 7 and 6 FIFO status 1 1 192 FIFO Enabled 0 1 64 FIFO Enabled but Unusable 0 0 < 64 No FIFO Available 5 32 64 Byte Fifo Enabled (16750 UART) 4 0 Reserved (not used) 3 0 Reserved on 8250 and 16450 UART's 8 16550 UART(or higher) Time-out Pending 2 and 1 Interrupt Status (Bit value Priority) 1 1 6 Receiver Line Status Interrupt (Highest) 1 0 4 Received Data Available Interrupt 0 1 2 Transmitter Hold Register Empty Inter. 0 0 0 Modem Status Interrupt (Lowest) 0 1 1 = No Interrupt Pending. 0 = Interrupt Pending < denotes a byte value less than designated INP value |
For FIFO status, just compare the INP status with 192 using AND as below:
This Register also uses the BaseAddress + 2 address, but it is Write Only! You can NOT try to Read it! That just returns data from the IIR Register ONLY! The FCR register is just used to set Interrupt triggers and clear the data from the Recieve or Transmit buffers of 16550 or higher UARTS.
Bit # OUT Value Description 7 and 6 Interrupt Trigger Level 1 1 192 14 Byte Trigger 1 0 128 8 Byte Trigger 0 1 64 4 Byte Trigger 0 0 < 64 1 Byte Trigger 5 32 Enable 64 Byte FIFO (16750 UART only) 4 0 Reserved (not used) 3 8 DMA Mode Select (mode 1 or 2) 2 4 Clear Transmit FIFO 1 2 Clear Receive FIFO 0 1 Enable FIFO's. 0 = Disabled FIFO" < denotes a byte value less than designated OUT value |
If the trigger bytes are found in the FIFO buffer, then the Data Receive Available Interrupt in the IIR will trigger. Bits 1 and 2 clear the buffer when set hi. They will automatically reset to 0 when done. Data is lost when cleared or if bit 0 is set to 0. Be aware of this and use carefully! This register is only normally used to clear the buffers and enable them. The 0 bit must be set to 1 or both FIFO buffers are disabled! Reset it!
This Register can determine the Word Length, Stop Bits, Parity and help set the Baud Rate of the Serial Port. For instance, OUT (BaseAddress + 3), 3 will set the Word Length to 8 with 1 Stop Bit and No Parity. Similar to OPEN COM, but you can also open COM ports other than COM1 or COM2 in this register. Be sure to Write a Register value less than 128 after the DLAB baud is set!
Bit # Bit Value Description 7 128 Divisor Latch Access Bit (set baud rate) < 128 Access Receive & Transmit buffers & IER 6 0 Set Break Enable. 64 = Break in Receiver TD" 5, 4, 3 Parity Select X X 0 0 No Parity (bit 3 off only)" 0 0 1 8 Odd Parity 0 1 1 24 Even Parity 1 0 1 40 High Parity (Sticky) 1 1 1 56 Low Parity (Sticky) 2 0 One Stop Bit (normal) 4 2 Stop bits(wordlength 6,7,8) or 1.5 (5)" 1 and 0 Set Word Length 1 1 3 8 Bit Word (normal) 1 0 2 7 Bit Word 0 1 1 6 Bit Word 0 0 0 5 Bit Word < denotes a byte value less than designated OUT value |
You can set the Baud Rate first by sending 128 to the LCR with OUT. This forces the Base and IER Registers to accept the Divisor Latch Low and High Byte values respectively. In DLAB mode both registers can be written to or read to find the current Divisor byte settings! The Divisor value is the number that 115200 must be divided by to attain the baud rate:
Speed (BPS) Divisor High Byte(to Base + 1) Low Byte(to Base) 50 2304 &H9 (2304) &H0 (0) 300 384 &H1 (256) &H80 (128) 600 192 &H0 &HC0 (192) 1200 96 &H0 &H60 (96) 2400 48 &H0 &H30 (48) 4800 24 &H0 &H18 (24) 9600 12 &H0 &HC (12) 19200 6 &H0 &H6 (6) 115200 1 &H0 &H1 (1) |
The divisor is based on 115,200 as the maximum Baud Rate. Speeds above 300 just send 0 to the IER, but it must be sent too! Below is a routine to set up any COM port without an OPEN statement. Simply use OUT to set it up:
BaseAdd% = &H3F8 'use any valid COM base address on your PC Out32 BaseAdd% + 3, &H80 'set DLAB baud rate divisor bit 7 on with 128 (LCR) Out32 BaseAdd% + 1, &H0 'set DL High Byte on IE Register Out32 BaseAdd%, &H60 'set DL Low Byte to 1200 baud (96) on Base Register Out32 BaseAdd% + 3, &H3 'sets 8 bit Word, 1 Stop Bit, and No Parity (LCR) * |
- Explanation: Setting the LCR register's value below 128 resets it from DLAB mode to normal Base Buffer and IER operations
Like the LCR Register, it is Read and Write! Bit 4 sets Loopback Mode that sends TD data back to RD buffer. Bits 1 and 0 force RTS and DTR signals. The Auxiliary Outputs are seldom used anymore! Just set those bits to 0.
Bit # Bit Value Description 4 16 LoopBack Mode (Test UART operation) 3 8 Aux Output 2(control by other circuitry) 2 4 Aux Output 1(MIDI, normally disconnected) 1 2 Force Request to Send (RTS) 0 1 Force Data Terminal Ready (DTR) |
Read Only status register used to detect data buffer activity and errors. If ANY data error occurs, bit 7 will be turned on. Specific errors are also listed. Normally only Bit 0 is read, as these errors do not stop the port! Use this register to check for transfer errors.
Bit # INP Value Description 7 128 Error in Received FIFO 6 64 Empty Data Hold Registers(TD and RD Idle) 5 32 Empty Transmitter Hold Register(TD empty) 4 16 Break Interrupt (RD Word Time Out) 3 8 Framing Error (last bit not a Stop Bit) 2 4 Parity Error 1 2 Overrun Error (cannot read fast enough) 0 1 Data Ready (Receiver ready to be read) |
This Read Only register monitors each bit each time read. Delta type bits denote any changes since the last time read. Bit 2 On indicates that there was a change from low to high on the RI line since the last read. Often used in modem data transfers!
Bit # INP Value Description 7 128 Carrier Detect (CD) 6 64 Ring Indicator (RI) 5 32 Data Set Ready (DSR) 4 16 Clear To Send (CTS) 3 8 Delta Data Carrier Detect 2 4 Trailing Edge Ring Indicator 1 2 Delta Data Set Ready 0 1 Delta Clear to Send |
This unused register can be Read and Written to. You can use it to hold data for later use. It can also be used to test for a valid COM port with a device or loopback plug on it. To test a port, Read this register and try to change it. Then Read it again. If the second reading has changed, then the COM port is accessible and ready to use with a device. Normally a Scratch Register will always read 255 if there is no device connected! COM port registers will not work if the port is not connected to a serial device!
See also