#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>

/* Copyright (c) 1999 by Tobin T. Fricke <tobin@cory.eecs.berkeley.edu>
 * Distributed under the GNU Public License.  This is pre-release software
 * and should not be distributed. */

#define DATA 16
#define CLOCK 32
#define MOTION 64
#define END 128
#define OFF  0
#define ON   1
#define ONEMORE 2

#define START 11 

void printByte(unsigned char c) {
   int i; 
   for (i=7; i!=0; i--) 
      printf("%d",(c>>i)&1);
 }

int main(int argc, char **argv) {

  int fd;
  int lrc;
  unsigned char oldfoo;
  unsigned char c;
  int i = 0;
  int state = OFF;

  fd = open("/dev/isaseat0",O_RDONLY);
  if (fd == -1) {
    printf("Error: (%s)\n",strerror(errno));
    exit(1);
  }

//  lseek(fd,0x201,SEEK_SET);
  read(fd,&oldfoo, 1);
//  oldfoo = ~oldfoo;
printf("Read 0x%02x from isaseat\n", oldfoo);

  c = 0;
  while (1) {
     unsigned char foo;
     lseek(fd, 0x201, SEEK_SET);
     read(fd, &foo, 1);
//     foo = ~foo; /* inverted */
printf("Read 0x%02x from isaseat\n", foo);
     
     if (( foo & CLOCK ) && (!(oldfoo & CLOCK))) 
       switch (state) {
	 case OFF:
           printf("%d",(foo & DATA) ? 1 : 0);
	   /* the newest bit is most-significant-bit */
           c = ( (c>>1) | ((foo & DATA) ? 16 : 0)) & 31;
	   
	   if (c == START) {
	      printf(" \\START\n");
	      state = ON;
	      lrc = c;
	      c = 0;
	      i = 0;
	     } else
            if (!(++i%8)) printf("\n");
	   break;

	case ON:
	case ONEMORE:
	   printf("%d",(foo & DATA) ? 1 : 0);
	   /* the newest bit is most-significant bit */
	   c |= ((foo & DATA) ? 1 : 0)<<(i++%5);
	   if (!(i%5)) {
	      
	      if (((!(c&1))+(!(c&2))+(!(c&4))+(!(c&8))+(!(c&16)))%2) {
		 printf(" <error>\n");
		 state = OFF;
		 break;
	      }

	      if (state == ONEMORE) {
		 printf(" LRC %s \n",
		   ((lrc ^ c)&15) == 0 ? "<passes>" : "<FAILS>" );
		 state = OFF;
		 break;
	      }

	      lrc ^= c;
              {
		 int code = c & 15;
		 if (code < 10) 
		    printf(" %d",code);
	         else
		    switch (code) {
			case 0xA: printf(" :"); break;
			case 0xB: printf(" \\START"); break;
			case 0xC: printf(" <"); break;
			case 0xD: printf(" \\FIELD"); break;
			case 0xE: printf(" >"); break;
			case 0xF: printf(" \\END"); 
				  state = ONEMORE;
				  break;
		    }
	      }
	     printf("\n"); 
             c = 0;
	   }
           break;
        default:
	   printf("Error!\n");
       } 
     oldfoo = foo;
   } 

  return(0);
  }
