LPT port basics

The printer port or the Geek port.... The only multi-bit, multipurpose I/O port available on a standard personal computer. Just use the processing power of the PC to control a part of the world. It's a simple port, easy to control with modest applications.

Sometimes I forget how the ports are layed out. And then I cannot find the page anymore that I always kept in ONE place. So now I put them online. So all the world can find them.

The LPT I/O ports

The LPT port consists of three I/O ports at subsequent addresses: Base, Base + 1 and Base + 2. The table below shows how they are layed out and if the bit is inverted or not. We start with the port at the Base address. A bit is True if it is not inverted by the hardware.

Base address

8 Outputs

Base + 1

5 Inputs

Base + 2

4 Outputs

Connectors and pin assignments

Old style (original) printer ports lived up to the Centronics specification. This was the port that based around the 36 pin conenctor (which is still on the back of most printers). PC's have their own connector: a 25 pin Sub-D connector.

Below is a table that shows a cross reference between pin numbers, signal names and data directions.

name IO:bb PC  LPT function DB25 Centr
/Strobe 2:0 The databus lines are stable and can be read  1  1
D0 0:0 Dataline 0  2  2
D1 0:1 Dataline 1  3  3
D2 0:2 Dataline 2  4  4
D3 0:3 Dataline 3  5  5
D4 0:4 Dataline 4  6  6
D5 0:5 Dataline 5  7  7
D6 0:6 Dataline 6  8  8
D7 0:7 Dataline 7  9  9
/ACK 1:6 Printer sends this to acknowledge receipt of data 10 10
BUSY 1:7 Printer says it cannot accept data 11 11
PEnd 1:5 Paper End: no more paper inside the printer 12 12
Seld 1:4 Selected: the printer is ON-LINE 13 13
AutoFeed 2:1 After a CR, the printer performs a linefeed 14 14
Error 1:3 Printer reports an error 15 32
Init 2:2 Force the printer to reset itself 16 31
Sel 2:3 Select: put the printer ON or OFF line 17 36
GND   Signal ground of the DATA lines 18 20
19 21
20 22
21 23
22 24
23 25
24 26
25 27
Logic ground   16
Shield (chassis) ground 17
/STROBE ground 19
/ACK ground 28
BUSY ground 29
INIT ground 30
Signal ground 33
+5 V +5 Volt output (50 mA max) 18
35
NC   No connection 15
34

The Centronics 36 pin conenctor has a high degree of redundancy in it. In the days the standard was defined, this was a bare necessity. So most all the signal lines had their own ground line (to accomodate twisted pairs inside one mother-cable).

The IBM PC connector was made many moons later when signal quality was also in order when only few ground lines were present. So they online defined 8 ground lines. Which is more than enough for modern day operation.

My experience is that you can safely combine all ground lines. It is particularly important to make sure pin 25 of the DB25 connector is grounded. Some laptops use this for identifying an external floppy diskdrive. If there is no hard ground on this pin, the laptop will not assign LPT base aIO ddresses to the port.

Finding the LPT port's base address

Tradition dictated that the I/O addresses for the LPT ports (three ports were allowed inside one PC) were either of:

This was true until separate LPT ports with a PCI interface became available. PCI ports have a more difficult addresing scheme. Which is not very important, since the addresses may change between systems...

In GOD mode (Good Old Dos), at linear address 00408h, there are three 16 bit words reserved for the maximum three LPT ports in one DOS computer. At address 00408h is the Base IO address of the first LPT port (LPT1). The base address of LPT2 is at 0040Ah and the base address for LPT3 is at 0040Ch. If either of these base addresses has the value ZERO, then the LPTx interface is not available.

I have no experience with Windows. So you would have to find out yourself how to deal with this lesser operating system.

In Linux, there is the /proc filesystem: file 'ioports' lists the base addresses of all I/O devices in the computer. Here is the result of catting the ioports to the console:

jan@beryllium:~/internet/verhoeven272/jan$ cat /proc/ioports | grep parport

0378-037a : parport0
037b-037f : parport0

jan@beryllium:~/internet/verhoeven272/jan$
   
What we are interested in, is the parport device. In this case, there is only one device in the system: parport0. I'm not sure what the second line means but it may be related to the LPT port being in a special mode of operation. What it comes down to: the base address of the LPT port in this system is 0378h.

In the mocka section is a program that finds the parport device via the list in /proc/ioports.

About the hardware

To the right you see a very simple version of the simplest form of the parallel port (aka printer port, LPT port, geekport). I left out all the unnecessary parts and signals. In this drawing is all you need to understand for becoming a geekportgeek.

In the lower left we have a 74138 '3 to 8 line decoder'. What it does is simple:

      
IF  (Enable0 = TRUE) AND (Enable1 = FALSE) AND (Enable2 = FALSE)  THEN
   DecodeAddressLines
END
   
Enable input nr 0 (zero) uses POSITIVE LOGIC so it is ACTIVE when there is a ONE signal on it.
Enable inputs 1 and 2 use NEGATIVE LOGIC and so they are ACTIVE when they experience a ZERO on them.

As usual, we start counting at ZERO, not at one.

What 'DecodeAddressLines' does is easy: if the binary pattern on the three inputs A0 .. A2 has value 'n' (in which 0 <= n <= 7) it activates the corresponding output pin. So if the A-lines see a '101', they know the 5th output (Y5) needs to be activated. So it puts a '0' on Y5 and a '1' on all other outputs. If not all enables are activated, all outputs are '1'.

In the top right we have the 74574 octal busbuffer/latch that keeps the data steady which is normally sent to (and used by) the printer. It needs to be 'latched' into place because the CPU does not have the time to keep the data on its systembusses. So it puts the value to be output on the pins in the register for a short time and then issues a WRITE signal in combination with an activated Y0 on the 138 chip.
At that moment, the value present on the system databus is 'latched' into a kind of memory inside the 574 chip and it keeps the data there until the next value is latched in place.

Something similar is valid for the 4 status inputs that are present on the IOport with address LPTbase + 2 only now, Y2 needs to be active instead of Y0. The chip involved is the one in the lower right.

The 5 status inputs are available through the center right chip. I used a 74245 chip here for easy understanding. In reality there is some other, more complicated, set of chips, but as a programmer you need not know this.
The system databus can read the values on the A-pins of the 245 by sending an address signal to the 138 saying : 'Now activate Y1' and on the next READ signal (omitted from the drawing) the values are copied from the A output lines to the Databus pins on the system bus.

The operation of the 138 is totally transparent for the user. And in fact the other chips as well.

In Modula-2 I made a library module for easy control of the IO ports. But to show how the ports are accessed I will go back to a small piece of something resembling machine language (assembler).

	Load	A, 45
	Load	DX, LPTbase
	Out	DX, A

	Add	DX, 1
	In	A, DX
   
A and DX are registers: pieces of very fast memory that 'live' inside the CPU and are some kind of notepad for storing numbers before they are processed and to keep results of these processings.

This is all there is to it. The 'hardware' inside the computer does the rest. It generates the right signals to activate the correct pins on the required chips. The programmer only needs to know what IO port number to use.

FROM	IOport		IMPORT	OutPort, InPort, IOperm;

	OutPort (port, val);
	val2 := InPort (port);
   
This is an example in Modula-2. All the 'difficult' parts are taken care of in the library module called IOport.

Page created on 5 april 2007 and

Page equipped with FroogleBuster technology