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.