/*
 read bit stream from card (typically 700 bits or so);
 usage: ./readcard 1000
 reads up to 1000 (e.g. all of) the data on a typical track 1 card
 (track 1 is the track closest to the edge of the card).

 data reversed for parallel port; uncomment for isa --{mann,ben}@eyetap.org
 data also masked out for parallel port (can leave that way for isa also)
 because parallel port inputs go high by default.

 this allows use on pci only system, e.g. with pci parallel port cards:
   - SIIG Cyber Parallel PCI (both versions)
   - SIIG Cyber Parallel Dual PCI (both versions)
   - SIIG Cyber 2P1S PCI
   - SIIG Cyber I/O PCI (both versions)
   - SIIG Cyber 2S1P PCI (both versions)
   - Lava Parallel PCI
   - Lava Dual Parallel PCI
   - Lava 2SP PCI
   - LavaPort Plus
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

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

  int fd;
  long count, recv;
  unsigned char *buf,*tmp_uchptr;
  int k;
  long check = 0;
  unsigned char tmp_uchar;

  if(argc>1)
    count = strtol(argv[1],NULL,10);
  else {
    fprintf(stderr,"Use %s number_of_bits_you_want_to_read\n",argv[0]);
    fprintf(stderr,"    %s %d  # for example, reads 1000 bits\n",argv[0],1000);
    fprintf(stderr,"    usually there's approx. 700 bits read\n");
    fprintf(stderr,"    so a buffer of 1000 is more than enough\n");
    exit(0);
  }
  buf = (unsigned char *) malloc(count*sizeof(unsigned char));

  if(!buf){
    fprintf(stderr,"malloc\n");
    exit(1); 
  }

  fd = open("/dev/paraseat0", O_RDWR);
  if(fd == -1) {
    fprintf(stderr, "Error: could not open /dev/paraseat0 for reading.\n");
    exit(1);
  }

  recv = read(fd,buf,count);
  close(fd);
//  fprintf(stderr,"%lu bits requested; %lu bits read\n",count,recv);
  tmp_uchptr = buf;
  // uncomment one line below for use with isa card or para with inverter:
  for (k=0;k<recv;k++) tmp_uchptr[k] = ~tmp_uchptr[k]; // for para, no inverter
  for (k=0;k<recv;k++) tmp_uchptr[k] = tmp_uchptr[k] & 0x01; //zero other bits
  while(check<recv-6){ //number of bits received-6 (since it's 7bits per char)
          //typ recv is 700 (alloc 1000 typically); of uchar for 1 bit
    // read the 7 bit (ascii-32) values:
    // start sentinel is ascii 69-32
    tmp_uchar = (unsigned char)(        // finding start sentinel 1000101=69
                                        // start sentinel is 0x45=69
                  tmp_uchptr[6] << 6 | 
                  tmp_uchptr[5] << 5 | 
                  tmp_uchptr[4] << 4 | 
                  tmp_uchptr[3] << 3 | 
                  tmp_uchptr[2] << 2 | 
                  tmp_uchptr[1] << 1 | 
                  tmp_uchptr[0]);
    // negate if using parallel port
    // tmp_uchar = ~tmp_uchar;  // comment out this line on ISA version
    //if(tmp_uchar == 0x45){ // isa
    if(tmp_uchar == 69){ // para
      fprintf(stderr,"readcard: start sentinel found at %ld\n",check);
      break;
    }
    check++;
    tmp_uchptr++;
  }
  tmp_uchptr += 7;
  check += 7;
  while(check<recv-6){
    tmp_uchar = (unsigned char) (        // parsing actual data
                  tmp_uchptr[6] << 6 | 
                  tmp_uchptr[5] << 5 | 
                  tmp_uchptr[4] << 4 | 
                  tmp_uchptr[3] << 3 | 
                  tmp_uchptr[2] << 2 | 
                  tmp_uchptr[1] << 1 | 
                  tmp_uchptr[0]); 
    // negate if using parallel port
    // tmp_uchar = ~tmp_uchar;  // comment out this line on ISA version
    if(tmp_uchar == 31){
      fprintf(stderr,"readcard: end sentinel found\n");
      break;
    }
    printf("%c",(63&tmp_uchar)+32);
    check+=7;
    tmp_uchptr+=7;
  }

  printf("\n");
  return 0;
}


