Using a Printer Port for Simple GPIB/IEEE-488 Operation All programs and documentation, Copyright 1990 by Sydex P.O. Box 5700 Eugene, OR 97405 Voice: (503) 683-6033 FAX: (503) 683-1622 Data: (503) 683-1385 All Rights Reserved. INTRODUCTION A while back (quite a while, actually) we had a need for the use of a color plotter for some 1-2-3 spreadsheet graphs that we were doing. A friend offered us the use of his HP 7470--but there was a catch. It seems that the thing had the HPIB/GPIB/IEEE-488 interface, not a straight serial or parallel connection. This posed a problem. A GPIB card for a PC would set us back about $350--and there was no guarantee that 1-2-3 could even talk to the thing. I recalled that the old Commodore Pet, as well as the Victor 9000 and the Osborne I could do a limited amount of GPIB interfacing with their parallel ports--so why not a PC? I even had an extra port that I wasn't using. After looking at the IBM Tech Reference manual, I discovered that there's a problem with this. Although the IBM Parallel Printer adapter bills itself as being bi-directional (input and output), it's hard-wired for output mode only! Now, I probably could drive the plotter with an output-only port, but this was aesthetically unsatisfying. How could the parallel port be wired to be REALLY bi-directional? The offending item appeared to be the 74LS374 IC used as the data output latch--the Output Enable (OE*) pin was grounded (wired active). However, there was a spare bit (bit 5) available on the 74LS174 6-bit latch used to control the printer handshaking lines. The solution was obvious--wire the unused bit to Output Enable on the LS374--viola! Incidentally, if you're using an IBM PS/2, ignore the next section, IBM finally came to its senses and implemented the same change when it brought the PS/2 out--you can use the software that accompanies this documentation will operate with no changes. ALTERING A PARALLEL ADAPTER Once again, note that this applies to PC XT- and AT- type computers (ISA bus) only. If you've got a PS/2, your changed parallel port is standard equipment. I'll discuss what has to be done to the simple $15.00 born-in- Taiwan parallel adapter, but note that these changes can be made to most other parallel adapters that use generic LSTTL IC's. This category also includes a number of monochrome display adapters. You should know one end of a soldering iron from another; a short length of wire-wrap or other small-gauge wire and an X-acto or other hobbyist utility knife is useful. The change is simple and will take you about 15 minutes (assuming your iron is hot). Most inexpensive parallel-only adapters come from the same basic design--12 SSI IC's on a half-slot card. First, locate the 74LS374 IC adjacent to the printer connector on the rear of the board. Note that one end of the IC has a recessed notch on one end. Also locate the 74LS174 just above it. Note the pin numbering: 74LS374 74LS174 +-U-+ +-U-+ Pin 1 [| |] Pin 20 Pin 1 [| |] Pin 16 Pin 2 [| |] Pin 19 Pin 2 [| |] Pin 15 Pin 3 [| |] Pin 18 Pin 3 [| |] Pin 14 Pin 4 [| |] Pin 17 Pin 4 [| |] Pin 13 Pin 5 [| |] Pin 16 Pin 5 [| |] Pin 12 Pin 6 [| |] Pin 15 Pin 6 [| |] Pin 11 Pin 7 [| |] Pin 14 Pin 7 [| |] Pin 10 Pin 8 [| |] Pin 13 Pin 8 [| |] Pin 9 Pin 9 [| |] Pin 12 +---+ Pin 10 [| |] Pin 11 +---+ Remembering that the pin numbering becomes "mirrored", turn the board over and locate pin 1 of the 74LS374. Note that it is connected by an enlargement of the solder pad to the wide ground trace above it. Being careful not to sever the wide ground trace, take your knife and separate the pin 1 pad from the ground trace. Check your work with a continuity tester. Next, locate pin 7 on the 74LS174. Take a short piece of wire and connect pin 1 on the 74LS374 to this pin. Be neat and check your work. That's it! Your card will still function normally as a printer adapter, but now has a true bi-directional mode of operation. BUILDING A CABLE The next task is to build a cable from the 25-pin parallel printer connection to a 24-pin male GPIB connector. Unfortunately, some "criss-crossing" of connections is necessary between the two, so you can either solder up a multiconductor cable between a male solder-cup DB25P connector and a 24 pin "Blue Ribbon" connector, or you can do what I did. I took a length of 24-conductor ribbon cable and crimped a male DP25P IDC connector on one end and a male 24 pin "centronics" connector (Scotch No. 3548, for example) on the other end. I then took an inexpensive solder-type DB25 "breakout box" (cost: about $7.50) and performed my "wire weaving" in it. In any case, you'll have to make sure the wiring works out this way: GPIB Pin Signal Name DB-25 ======== =========== ===== 1 -DATA 1 2 2 -DATA 2 3 3 -DATA 3 4 4 -DATA 4 5 5 -EOI 13 6 -DAV 1 7 -NRFD 16 8 -NDAC 17 9 -IFC 10 10 -SRQ 15 11 -ATN 14 12 GND 18 13 -DATA 5 6 14 -DATA 6 7 15 -DATA 7 8 16 -DATA 8 9 17 -REN 12 18 GND 19 19 GND 20 20 GND 21 21 GND 22 22 GND 23 23 GND 24 24 GND 25 Check your work for accuracy! THE SOFTWARE We've supplied the source and object for a set of "C"-callable routines to manage the GPIB interface. We use Microsoft "C" and Microsoft MASM, though there should be no reason why this wouldn't also work with Borland's Turbo "C" and TASM. Note that we make use of the "small" memory model--you could alter this to use the huge, large or compact models by making sure that full segment-offset addresses are handled and the necessary segment register juggling is done. Similarly, there's no reason that the package couldn't be modifed to work with BASIC or FORTRAN with appropriate changes. The source file is the file "GPIB_C.ASM" and is written in 8086 assembly language. These are the routines that are included in it: int GPIB_Init( int io_port, int our_address) Initializes the GPIB interface. "io_port" is the address of the printer adapter being used--usually 0x378 for the first and 0x278 for the second. If your adapter is part of a monochrome display adapter, its address is 0x3bc. "Our_address" is the GPIB talker/listener address that the PC is to consider to be its own. The interface is initialized; if no response can be had, a status of -1 is returned; a return of 0 signifies no error. int GPIB_Send( int listen, char what) This routine sends a single character to the GPIB device addressed by "listen". If this function returns -1, there's a problem, otherwise the return value is 0. int GPIB_PutStr( int listen, char *string, int count) This routine sends a string of bytes to the GPIB device addressed by "listen". "count" bytes are sent. Returns are -1 for failure, 0 for success. int GPIB_Stat(void); Simply returns the value of the GPIB status lines. These are encoded in the lower 8 bits of the return value as: IFC REN EOI SRQ NDAC NRFD ATN DAV int GPIB_Get( int listen) Reads a character from the GPIB device addressed by "listen". Returns the character or -1 if error. int GPIB_GetStr( int listen, char *buf) Reads a string of data from the device addressed by "listen". Returns the number of bytes read into "buf" or -1 if error. int GPIB_SerPoll( int listen) Executes a Serial Poll on the device at "listen". Returns the serial poll status in the lower 8 bits of the return value or -1 if error. int GPIB_PutAdd( char what) GPIB primitive. Puts the value "what" out as an address byte. Returns 0 if success or -1 if failure. int GPIB_PutData( char what) GPIB primitive. Puts the value "what" out as a data byte. Returns 0 if success or -1 if failure. int GPIB_GetData(void); GPIB primitive. Reads the value on the GPIB bus as a data value and returns it or -1 if failure. As an example of usage, a terminate-and-stay-resident program, LPPLOT, is included to talk to an HP 7470 plotter disguised as LPT3. It works--but note that the GPIB version of the 7470 lacks arc and circle-drawing HPGL extensions. MISCELLANY Clearly, this scheme represents a way to get by on the cheap. This method will not support all GPIB functions, nor is it likely to be able to drive more than one GPIB device at a time--the output current drive capability just isn't there. If I had it to do over again, I'd change the way I wired the cable and wire the ATN signal to pin 10 on the DB25 so that I could use the interrupt capability on the printer card to service asynchronous requests such as Parallel Poll. But the thing does work--and with a little work, 2 PC's could be coupled to do full 8-bit transfers in either direction. Current printer port data transfer schemes "nibble" the data, rather than use the full data bus width. USAGE AND LICENSING License is hereby granted by Sydex for single-use non-commercial application of this code. Contact Sydex for commercial use and system-integration licensing rights. Any other use of this code or documentation is hereby prohibited without explicit written permission from Sydex. Text and programs by Chuck Guzis Certain products and terms referred to in this document are property of the following firms: Hewlett-Packard Corporation, International Business Machines, Microsoft Corporation, Borland International, Centronics, ITT-Cannon, 3M Corporation.