//Instance file di spp.h : spp.c
//Libreria per gestione porta parallela spp
//Andrea Cipriani Ago 2004
//a71cip@tiscali.it
//Status register e control register invertono alcuni bit, per cui i risultati
//delle operazioni di i/o che coinvolgono questi registri vanno messi in Xor con : 
//^ 0x80 per Status register
//^ 0x0b per Control register

# include <conio.h>

void DataOut    (unsigned int addr, char v) //Data Output
{
 _outp(addr,v);
}

char DataIn     (unsigned int addr) //Data Input
{
 return _inp(addr);
}

char StatusIn   (unsigned int addr) //Status Input
{
 return (_inp(addr)^0x80);
}

void ControlOut (unsigned int addr, char v) //Control Output
{
 _outp(addr,(v^0x0b));
}

char ControlIn  (unsigned int addr) //Control Input
{
 return _inp(addr);
}

void DataSetBit (unsigned int add, char position)
// Setta il bit in posizione position (0..7) sulla data port
{
 char last;
 last = DataIn(add);
 switch (position)
  {
   case 0:
    DataOut(add,(last|0x01));
    break;

   case 1:
    DataOut(add,(last|0x02));
    break;

   case 2:
    DataOut(add,(last|0x04));
    break;

   case 3:
    DataOut(add,(last|0x08));
    break;

   case 4:
    DataOut(add,(last|0x10));
    break;

   case 5:
    DataOut(add,(last|0x20));
    break;

   case 6:
    DataOut(add,(last|0x40));
    break;

   case 7:
    DataOut(add,(last|0x80));
    break;
  }
}

void DataClearBit (unsigned int add, char position)
// Resetta il bit in posizione position (0..7) sulla data port
{
 char last;
 last = DataIn(add);
 switch (position)
  {
   case 0:
    DataOut(add,(last&0xfe));
    break;

   case 1:
    DataOut(add,(last&0xfd));
    break;

   case 2:
    DataOut(add,(last&0xfb));
    break;

   case 3:
    DataOut(add,(last&0xf7));
    break;

   case 4:
    DataOut(add,(last&0xef));
    break;

   case 5:
    DataOut(add,(last&0xdf));
    break;

   case 6:
    DataOut(add,(last&0xbf));
    break;

   case 7:
    DataOut(add,(last&0x7f));
    break;
  }
}

//*****************************************************************************
//void StatusSetBit (unsigned int,char);
//Set bit        : unsigned int=STATUS address, unsigned char=numero bit (0..7)
//void StatusClearBit (unsigned int,char);
//Clear bit      : unsigned int=STATUS address, unsigned char=numero bit (0..7)
//*****************************************************************************


void ControlSetBit (unsigned int add, char position)
// Setta il bit in posizione position (0..3) sulla control port
{
 char last;
 last = ControlIn(add);
 switch (position)
  {
   case 0:
    ControlOut(add,(last|0x01));
    break;

   case 1:
    ControlOut(add,(last|0x02));
    break;

   case 2:
    ControlOut(add,(last|0x04));
    break;

   case 3:
    ControlOut(add,(last|0x08));
    break;
  }
}


void ControlClearBit (unsigned int add, char position)
// Resetta il bit in posizione position (0..3) sulla control port
{
 char last;
 last = ControlIn(add);
 switch (position)
  {
   case 0:
    ControlOut(add,(last&0xfe));
    break;

   case 1:
    ControlOut(add,(last&0xfd));
    break;

   case 2:
    ControlOut(add,(last&0xfb));
    break;

   case 3:
    ControlOut(add,(last&0xf7));
    break;
  }
}
