#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;asm/io.h&gt;

#define DATA 0x378	 /* Adresse du bus de données (c.a.d du port imprimante) */
#define STATUS 0x379


/* Une série de définitions pour simplifier la programmation */
// #define SET_E outb(inb(CONTROL) &amp; 0xFE,CONTROL) /* E=1 (Strobe) */
// #define RAZ_E outb(inb(CONTROL) | 0x01,CONTROL) /* E=0 (Strobe) */
// #define SET_RS outb(inb(CONTROL) &amp; 0xF7,CONTROL) /* RS=1, la donnée est un caractère */
// #define RAZ_RS outb(inb(CONTROL) | 0x08,CONTROL) /* RS=0, la donnée est une instruction */


// Pour lire un octet sur un port, appelez inb(port); qui retourne l'octet correspondant.
// Pour écrire un octet, appelez outb(value, port);

// Le port parallèle (BASE = 0x3bc pour /dev/lp0, 0x378 pour /dev/lp1 et 0x278 pour /dev/lp2)~: 
// {source~: IBM PS/2 model 50/60 Technical Reference, et quelques expériences}

// Vérifier qu on est en EPP dans le BIOS, et que les modules parport sont déchargés.


void printfb (int x);
void SDAH(void);
void SDAB(void);
void SCLH(void);
void SCLB(void);
void start(void);
void stop(void);
void ackin(void); //   Lecture d'une condition d'acquittement, retour dans Z ; entrée SCL bas
void ackout(void); //  Envoi d'une condition d'acquittement ; entrée SCL bas
void nackout(void); // Envoi d'une condition de non acquittement ; entrée SCL bas
void pcf_read(void);
void pcf_write(void);




int main(void)
{

  ioperm(DATA,3,1); // donne les permissions sur le port 378h et 37Ah

//clrscr();
  printf("************************************************\n");
  printf("* Lecture d'une valeur sur le bus de donnees\n");
  printf("*             du port parallele\n");
  printf("* Samir Saidani saidani@info.unicaen.fr\n");
  printf("* Vincent Regnard vincent.regnard@libertysurf.fr\n");
  printf("************************************************\n\n\n");
  Init_SMEC();
  Lire_SMEC();
  Ecrire_SMEC();
}

void Init_SMEC (void)
  
{

}

void LigneLibre (void)
{

  while (!(inb(STATUS) &amp; 1))
    {
      printf(" La ligne est occupée : ");
      printfb(inb(STATUS) &amp; 1);
      sleep(0.5);
    }
  printf(" La ligne est libre : ");
  printfb(inb(STATUS) &amp; 1);
}

void Lire_SMEC (void)
   {
unsigned char Valeur, Controle;
Valeur = inb(DATA); // On lit le registre de données
Controle = inb(STATUS); // On lit le registre de controle
 LigneLibre();
 printf("Valeur lue (Données) : %x\n", Valeur);
 printfb(Valeur);
 printf("Valeur lue (Controle) : %x\n", Controle);
 printfb(Controle);
   }


void Ecrire_SMEC (void)

{
  unsigned char Controle, Valeur, Adresse;
  int t;
  Controle = inb(STATUS); // On lit le registre de controle

  LigneLibre();
  printf("Entrez l'adresse du SMEC (0-255):\n");
  scanf("%d",&amp;Adresse);
  outb(Adresse &amp;&amp; 254,DATA);
  outb(0xC5,STATUS);

  // Attente ACK
  for (t=200; t || !(inb(STATUS) &amp; 128); t--,printf("Le Status &amp; 128 :%d\n", (inb(STATUS) &amp; 128)),printfb((inb(STATUS) &amp; 128)),sleep(1));
   if (!t) {printf("Dépassement de délais t=%d\n", t);} 
  else {
    if ((inb(STATUS) &amp; 8)==8) {printf("Pas d'acquittement après envoi adresse\n");}
    else { 
      printf("Entrez la donnée du SMEC (0-255):\n");
      scanf("%d",&amp;Valeur);
      outb(Valeur, DATA);
      do {
	printf("Attente ACK\n");}
      while (!(inb(STATUS) &amp; 128));
      if ((inb(STATUS) &amp; 8)==8) {printf ("Pas d'acquittement après envoi de données\n");}
    }
  }
  exit(0);
}

void printfb(int x)

{
   int n;
   for(n=0; n&lt;8; n++)
   {
      if((x &amp; 0x80) !=0)
      {
         printf("1");
      }
      else
      {
         printf("0");
      }
      if (n==3)
      {
         printf(" "); /* insert a space between nybbles */
      }
      x = x&lt;&lt;1;
   }
   printf("\n");
}

void Dn (void)
{
  printf ("Données : ");
  printfb(inb(DATA));
}

void Ctrl (void)
{
  printf ("Status  : ");
  printfb(inb(STATUS));
}

