/* Kompilieren mit g++ -o lpt1OutBit lpt1OutBit.cpp                   */
/* kopieren nach /usr/local/bin, dann s-bit setzen mit chmod als root */

#include <stdio.h>
#include <string.h>

#include <stdlib.h>
#include <sys/io.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#define OP_SET 1
#define OP_RES 2
#define OP_NEG 3
#define PORT1 0x378

/* Wandelt 1 Byte Integer in einen String mit Nullen und Einsen um (zB:0x63 -> "01100011") */

char* crtBitStr(unsigned char x)
{
  int i,j=0;
  static char p[7+1]="";
  for (i=0; i<8;)
  {
     if((x&1)!=0)p[i++]='1';
     else p[i++]='0';
     x>>=1;
  }
  return p;
}
int main(int argc, char* argv[])
{
  unsigned int pin;
  int operation;
  int val;
  if (argc!=3)
  {
      printf("usage: lpt1OutBit op bit\n op : set | res \n bit:0..7\n");
      exit (-1);
  }
  if (strcmp(argv[1],"set")==0) operation=OP_SET; else
  if (strcmp(argv[1],"res")==0) operation=OP_RES; else
  if (strcmp(argv[1],"neg")==0) operation=OP_NEG; else
  {
     printf("usage: lpt1OutBit op bit\n op : set | res | neg \n bit:0..7\n");
     exit (-1);
  }
  if (strcmp(argv[2],"all")==0) val=0xff;
  else val=1<<atoi(argv[2]);
  /* want to be root */
  setuid(0);
  /* ioPerm ist Linux spezifisch -> man ioperm */
  ioperm(PORT1, 1, 1); // port 0x378 und die 1 folgenden freischalten
  pin = inb(PORT1); // port lesen
  ioperm(PORT1, 1, 0); // port 0x378 und die 1 folgenden sperren
  /*printf("status:%d\n",pin);*/
  {
     printf("value:%d\n",val);
     switch (operation)
     {
     case OP_SET:pin = pin | val; break; // Eintragen 1
     case OP_RES:pin = pin & (~val);break;
     }
     ioperm(PORT1, 1, 1); // port 0x378 und die 1 folgenden freischalten
     outb(pin,PORT1);
     ioperm(PORT1, 1, 0); // port 0x378 und die 1 folgenden sperren
   }
   printf("Status:%s\n", crtBitStr(pin));
   return 0;
}