#include <stdio.h>
#include <unistd.h>
#include <sys/io.h>

#include "ppar.h"

void par_port::Initialize(unsigned paddr)
{
  int err;

  addr = paddr;
  data_state = 0xff;
#ifdef __linux__
  printf("Linux - enabling ports\n");
  err = ioperm(paddr, 3, 1);
  if (err) {
    printf("Cannot IOPerm the parallel port\n");
    _exit(1);
  }
#endif
  outb(data_state, addr);
}

void par_port::Release(void)
{
#ifdef LINUX
  ioperm(addr, 3, 0);
#endif
}
  
void par_port::SetData(unsigned char data)
{
  data_state = data;
  outb(data_state, addr);
}

void par_port::SetDataBit(int bitnr, bool new_state)
{
  if (new_state) {
    data_state = data_state | (1 <<bitnr);
  } else {
    data_state = data_state & !(1 << bitnr);
  }
  outb(data_state, addr);		// No inversion for data port
}

void par_port::SetControlBit(int bitnr, bool new_state)
{
  if (new_state) {
    ctl_state = ctl_state | (1 << bitnr);
  } else {
    ctl_state = ctl_state & !(1 << bitnr);
  }
  outb((ctl_state ^ PPAR_INV_CONTROL), addr + PPAR_CONTROL);
}

bool
par_port::GetDataBit(int bitnr)
{
  return (data_state & (1 << bitnr))  != 0;
}

bool
par_port::GetControlBit(int bitnr)
{
  return (inb(addr + PPAR_CONTROL) & (1 << bitnr)) != 0;
}

bool
par_port::GetStatusBit(int bitnr)
{
  return ((inb(addr + PPAR_STATUS) ^ PPAR_INV_STATUS) & (1 << bitnr)) != 0;
}

unsigned
par_port::GetAddr(void)
{
  return addr;
}
