/***********************************************************************
 *
 * peek.c
 * Tom Kelliher
 * Jan. 20, 2000
 *
 * Copyright (C) 2000 Thomas P. Kelliher, Goucher College
 *
 * Peek a byte value from the data register of a parallel port in Linux.
 * By default, the parallel port at 0x378 is used.  This program should
 * be used with ports in PS/2 (bidirectional) modes.  Results with ports
 * in EPP or ECP modes are undefined.  SPP (unidirectional) mode ports
 * are not capable of reading data from the port.
 *
 * This program leaves the host with data line drivers disabled.
 *
 * WARNING: IT IS YOUR RESPONSIBILITY TO ENSURE THAT HOST DATA LINE
 * DRIVERS AND PERIPHERAL DATA LINE DRIVERS ARE NOT SIMULTANEOUSLY
 * ENABLED.  Ignoring this warning may result in damage to the host,
 * the peripheral, and your wallet.
 *
 * Compiling note: You must use gcc's "-O" switch.
 *
 * Running notes: 
 *    This program must run with root privileges.
 *
 ***********************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>


/* base of the parallel port.  this is the location of the data */
/* register.                                                    */

#define BASE 0x378

/* offset of the control register */

#define CONTROL 2


/* function prototypes */

void error(char *s);


/***********************************************************************
 *
 * main()
 *
 ***********************************************************************/

int main()
{
   unsigned char data;       /* value of the data register */
   unsigned char control;    /* value of the control register */

   if (iopl(3))
      error("Could't get the port addresses\n");

   /* disable data register output by bringing bit 5 of control */
   /* register high                                             */

   control = inb(BASE + CONTROL);
   outb(control | 0x20, BASE + CONTROL);

   /* read and print the value */

   printf("Port 0x%x reads 0x%x\n", BASE, inb(BASE));

   return 0;
}


/***********************************************************************
 *
 * error()
 *
 * Print an error message and terminate with an error code of 1.
 *
 * The error message to print is passed in as s.
 *
 ***********************************************************************/

void error(char *s)
{
   printf("%s", s);
   exit(1);
}
