/* dumb.c

   Compile with -DDO_IOPL for Linux.

   February 2000, by H. Dietz
*/

#define	D7	0x80
#define	D6	0x40
#define	D5	0x20
#define	D4	0x10
#define	D3	0x08
#define	D2	0x04
#define	D1	0x02
#define	D0	0x01

#define	S7	0x80	/* note: NOT(S7) is on the input */
#define	S6	0x40
#define	S5	0x20
#define	S4	0x10
#define	S3	0x08

#define	C3	0x08	/* note: NOT(C3) is on the wire */
#define	C2	0x04
#define	C1	0x02	/* note: NOT(C1) is on the wire */
#define	C0	0x01	/* note: NOT(C0) is on the wire */

inline unsigned int
inb(unsigned short port)
{
  unsigned char _v;
  __asm__ __volatile__ ("inb %w1,%b0"
			:"=a" (_v)
			:"d" (port), "0" (0));
  return(_v);
}

inline void
outb(unsigned char value,
unsigned short port)
{
  __asm__ __volatile__ ("outb %b0,%w1"
			:/* no writes */
			:"a" (value), "d" (port));
}

main(int argc,
char **argv)
{
  int portbase = 0x278;	/* the default portbase... */
  int i, sbits;

  printf("Spring 2000 EE481, Support Code by H. Dietz\n"
	 "Dumb example program....\n"
	 "\n"
	 "I/O Register  Bits  Function (WRT computer)\n"
	 "portbase+0    0-7   hex counting 0 `to 255, one count per second\n"
	 "portbase+1    3-7   input read and printf'd\n"
	 "\n"
	 "Optional argument is parallel port base address\n"
	 "\n");

  /* Set portbase */
  if (argc < 2) {
    printf("Defaulting to portbase of 0x%x\n", portbase);
  } else {
    sscanf(argv[1], "%x", &portbase);
    switch (portbase) {
    case 0x278:
    case 0x378:
    case 0x3bc:
      printf("Portbase set to 0x%x\n", portbase);
      break;
    default:
      printf("0x%x is not a standard parallel port base address;\n"
	     "try a portbase of 0x278, 0x378, or 0x3bc\n", portbase);
      exit(1);
    }
  }

#ifdef	DO_IOPL
  if (iopl(3)) {
    printf("Could not get port access rights; must be root\n");
    exit(2);
  }
#endif

  /* The main loop... */
  for (i=0; i<256; ++i) {
    /* Output the bit pattern... */
    outb(i, portbase+0);
    printf("output is 0x%02x, ", i);

    /* Read and printf the input... */
    sbits = inb(portbase+1);
    printf("input is /S7=%d, S6=%d, S5=%d, S4=%d, S3=%d\n",
	   ((sbits & S7) != 0),
	   ((sbits & S6) != 0),
	   ((sbits & S5) != 0),
	   ((sbits & S4) != 0),
	   ((sbits & S3) != 0));

    /* Wait a second or so... */
    usleep(1000000);
  }
}
