	/*
    This code is a QC program for PCI DIO (8I8O/16I/16O) CARD

    Auther : Johnny Tseng
    Date : 1999/09/18
*/

#include <dos.h>
#include <stdio.h>
#include <conio.h>

#include "pci.c"

/* set default value for ioport */
unsigned int ioport = 0;

void dumpbits (unsigned long x, int n)
{
  int i;

  for (i = n - 1; i >= 0; i--) {
    putch ((((unsigned long)1 << i) & x)? '1' : '0');
  }
}

void test8relay8photo (void)
{
  unsigned long loop = 0L;
  unsigned int x, y, z;
  int i, step = 0;
  char c = 0;
  unsigned duration = 64;

  gotoxy (15, 22);
  cprintf (" '+','-' : speed   space : pause  ESC : exit");

  x = 1;
  for (;;) {
    outportb (ioport, x);
    delay (100);
    y = inportb (ioport);
    z = inportb (ioport + 1);
    gotoxy (20, 18);
    cprintf ("Loop: %8ld ", loop++);
    gotoxy (40, 18);
    cprintf ("Output: ");
    dumpbits (x, 8);
    gotoxy (40, 19);
    cprintf ("Input : ");
    dumpbits (y, 8);
    cprintf ("%s", (x == y)? "   OK " : (x == (~y & 0x00FF))? "   OK " : " ERROR");
    gotoxy (40, 20);
    cprintf ("Switch: ");
    dumpbits (z, 8);

    if (x == 0x0080)
      x = 1;
    else
      x <<= 1;
    delay (duration);
    if (kbhit () || step) {
      c = getch ();
      if (c == 27)
	break;
      else if (c == ' ')
	step = !step;
      else if (c == '+') {
	if (duration > 1)
	  duration >>= 1;
      }
      else if (c == '-') {
	if (duration < 512)
	  duration <<= 1;
      }
      else if (!step)
	getch ();
    }
    if (c == 27)
      break;
  } // for (;;)
  if (kbhit ())
    getch ();
}

void test4relay4photo (void)
{
  unsigned long loop = 0L;
  unsigned int x, y, z;
  int i, step = 0;
  char c = 0;
  unsigned duration = 64;

  gotoxy (5, 20);
  cprintf (" '+','-' : speed   space : pause  ESC : exit");

  x = 1;
  for (;;) {
    outportb (ioport, x);
    delay (duration);
    y = inportb (ioport) >> 4;
    z = inportb (ioport + 1);
    gotoxy (10, 18);
    cprintf("Loop: %8ld ", loop++);
    gotoxy (30, 18);
    cprintf ("Output: ");
    dumpbits (x, 4);
    cprintf ("   Input: ");
    dumpbits (y, 4);
    cprintf ("   Switch: ");
    dumpbits (z, 4);

    if (x == 0x0008)
      x = 1;
    else
      x <<= 1;
    delay (duration);
    if (kbhit () || step) {
      c = getch ();
      if (c == 27)
	break;
      else if (c == ' ')
	step = !step;
      else if (c == '+') {
	if (duration > 1)
	  duration >>= 1;
      }
      else if (c == '-') {
	if (duration < 512)
	  duration <<= 1;
      }
      else if (!step)
	getch ();
    }
    if (c == 27)
      break;
  } // for (;;)
  if (kbhit ())
    getch ();
}

void test16relay (void)
{
  unsigned long loop = 0L;
  unsigned int x;
  int i, step = 0;
  char c = 0;
  unsigned duration = 64;

  gotoxy (5, 20);
  cprintf ("1-4 : channel number   '+','-' : speed   space : pause  ESC : exit");

  x = 0x0001;
  for (;;) {
    outport (ioport, x);
    gotoxy (10, 18);
    cprintf("Loop: %8ld ", loop++);
    dumpbits (x, 16);
    if (x == 0x8000)
      x = 0x0001;
    else
      x <<= 1;
    delay (duration);
    if (kbhit () || step) {
      c = getch ();
      if (c == 27)
	break;
      else if (c == ' ')
	step = !step;
      else if (c == '+') {
	if (duration > 1)
	  duration >>= 1;
      }
      else if (c == '-') {
	if (duration < 512)
	  duration <<= 1;
      }
      else if (!step)
	getch ();
    }
    if (c == 27)
      break;
  } // for (;;)
  if (kbhit ())
    getch ();
}

void test16photo (void)
{
  unsigned long loop = 0L;
  unsigned int x;
  int i, step = 0;
  char c = 0;
  unsigned duration = 64;

  gotoxy (5, 20);
  cprintf ("1-4 : channel number   '+','-' : speed   space : pause  ESC : exit");

  for (loop = 0;;loop++) {
    x = inport (ioport);
    gotoxy (10, 18);
    cprintf("Loop: %8ld ", loop++);
    dumpbits (x, 16);
    delay (duration);
    if (kbhit () || step) {
      c = getch ();
      if (c == 27)
	break;
      else if (c == ' ')
	step = !step;
      else if (c == '+') {
	if (duration > 1)
	  duration >>= 1;
      }
      else if (c == '-') {
	if (duration < 512)
	  duration <<= 1;
      }
      else if (!step)
	getch ();
    }
    if (c == 27)
      break;
  } // for (;;)
  if (kbhit ())
    getch ();
}

void test16relay16photo (void)
{
  unsigned long loop = 0L;
  unsigned int x, y, z;
  int i, step = 0;
  char c = 0;
  unsigned duration = 64;

  gotoxy (15, 22);
  cprintf (" '+','-' : speed   space : pause  ESC : exit");

  x = 1;
  for (;;) {
    outportb (ioport, x & 0x00ff);
    outportb (ioport + 1, x >> 8);
    delay (10);
    y = inportb (ioport);
    y = (inportb (ioport + 1) << 8) | y;
    gotoxy (20, 18);
    cprintf ("Loop: %8ld ", loop++);
    gotoxy (40, 18);
    cprintf ("Output: ");
    dumpbits (x, 16);
    gotoxy (40, 19);
    cprintf ("Input : ");
    dumpbits (y, 16);
    cprintf ("%s", (x == y)? "   OK " : (x == (~y &0xffff))? "   OK " : " ERROR");
    gotoxy (40, 20);
    cprintf ("Switch: ");
    dumpbits (z, 16);

    if (x == 0x8000)
      x = 1;
    else
      x <<= 1;
    delay (duration);
    if (kbhit () || step) {
      c = getch ();
      if (c == 27)
	break;
      else if (c == ' ')
	step = !step;
      else if (c == '+') {
	if (duration > 1)
	  duration >>= 1;
      }
      else if (c == '-') {
	if (duration < 512)
	  duration <<= 1;
      }
      else if (!step)
	getch ();
    }
    if (c == 27)
      break;
  } // for (;;)
  if (kbhit ())
    getch ();
}

int main ()
{
  int r;
  int flag = 1;
  int cardid;
  char ch;
  int ioportsw = 0;
  int iosw = 0;

  cardid = 0;
  if (!GetPCICardInfo (PCI_DEVICE_ID_8_RELAY_8_PHOTO, &ioport))
    cardid = PCI_DEVICE_ID_8_RELAY_8_PHOTO;
  else if (!GetPCICardInfo (PCI_DEVICE_ID_4_RELAY_4_PHOTO, &ioport))
    cardid = PCI_DEVICE_ID_4_RELAY_4_PHOTO;
  else if (!GetPCICardInfo (PCI_DEVICE_ID_16_PHOTO, &ioport))
    cardid = PCI_DEVICE_ID_16_PHOTO;
  else if (!GetPCICardInfo (PCI_DEVICE_ID_16_RELAY, &ioport))
    cardid = PCI_DEVICE_ID_16_RELAY;
  else if (!GetPCICardInfo (PCI_DEVICE_ID_16_RELAY_16_PHOTO, &ioport))
    cardid = PCI_DEVICE_ID_16_RELAY_16_PHOTO;
  else {
    cputs ("Can not find PCI DIO card...\n\r");
    return 1;
  }

  while (flag) {
    clrscr();
    cputs ("\n\n\n\r");
    cputs ("                       PCI-DIO CARD Q.C. Program V1.1\n\r");
    cputs ("                    =====================================\n\r");
    cputs ("\n\r");
    cputs ("                       Adapter : ");
    switch (cardid) {
      case PCI_DEVICE_ID_8_RELAY_8_PHOTO:
	cputs ("PCI 8 Relay 8 Photo card\r\n");
	ioportsw = ioport + 1;
	break;
      case PCI_DEVICE_ID_4_RELAY_4_PHOTO:
	cputs ("PCI 4 Relay 4 Photo card\r\n");
	ioportsw = ioport + 1;
	break;
      case PCI_DEVICE_ID_16_PHOTO:
	cputs ("PCI 16 Photo card\r\n");
	ioportsw = ioport + 2;
	break;
      case PCI_DEVICE_ID_16_RELAY:
	cputs ("PCI 16 Relay card\r\n");
	ioportsw = ioport + 1;
	break;
      case PCI_DEVICE_ID_16_RELAY_16_PHOTO:
	cputs ("PCI 16 Photo 16 Relay card\r\n");
	ioportsw = ioport + 2;
	break;
      default:
	cputs ("Unknownm\r\n");
	ioportsw = ioport;
    }
    cprintf ("                       I/O Address: %04X\n\r", ioport);
    switch (cardid) {
      case PCI_DEVICE_ID_8_RELAY_8_PHOTO:

      case PCI_DEVICE_ID_4_RELAY_4_PHOTO:
      case PCI_DEVICE_ID_16_PHOTO:
      case PCI_DEVICE_ID_16_RELAY:
      case PCI_DEVICE_ID_16_RELAY_16_PHOTO:
      default:
	iosw = 0;
    }
    cputs ("\n\r");
    cputs ("                       (1): I/O Test\n\r");
    cputs ("\n\r");
    cputs ("                       ESC: EXIT\n\r");
    cputs ("                       Choose:");
    do {
      ch = getch();
    } while (ch != '1' && ch != 27);
    switch (ch) {
      case 27:
	flag = 0;
	break;
      case '1':
	switch (cardid) {

	  case PCI_DEVICE_ID_8_RELAY_8_PHOTO:
	    test8relay8photo ();
		iosw = inportb (ioport + 1);

	     break;
	  case PCI_DEVICE_ID_4_RELAY_4_PHOTO:
	    test4relay4photo ();
	    break;
	  case PCI_DEVICE_ID_16_PHOTO:
	    test16photo();
	    break;
	  case PCI_DEVICE_ID_16_RELAY:
	    test16relay();
	    break;
	  case PCI_DEVICE_ID_16_RELAY_16_PHOTO:
	    test16relay16photo();
	    break;
	}
	break;
    } // switch
  } //while
  return 0;
} /* end of main */
