/* File Transfer Program for Oric Software */
/* UNIX Version by Boris GRANVEAUD 1994 */

/* Adapted to Amiga by JF FABRE */

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

#include <dos/dos.h>
#include <proto/dos.h>
#include <pragmas/dos_pragmas.h>

FILE *f1,*f2;

void FinFichier(void)
{
  printf("** End of file encountered !\n");
  fclose(f2);
  exit(0);
}

void Attend1Zero(FILE *f)
{
  int c1,c2;

  c1=127;
  for (;;)
  {
    c2=fgetc(f);

    if (feof(f))
      FinFichier();
      
    if (((c1>127) && (c2<=127)) || ((c1<127) && (c2>=127)))
      return;
    c1=c2;
  }
}

void Attend8Zeros(FILE *f)
{
  int zeros,c1,c2;

  zeros=0; c1=127;
  do
  {
    c2=fgetc(f);

    if (feof(f))
      FinFichier();
      
    if (((c1>127) && (c2<=127)) || ((c1<127) && (c2>=127)))
      zeros++;
    c1=c2;
  }
  while (zeros<8);
}

int LectureBit300(FILE *f,int seuil,int aff)
{
  long pos1,pos2,nb_oct;

  pos1=ftell(f);
  Attend8Zeros(f);
  pos2=ftell(f);

  nb_oct=pos2-pos1;

  if (nb_oct>seuil)
  {
    if (aff)    printf("0");
    return 0;
  }

  Attend8Zeros(f);

  if (aff)  printf("1");

  return 1;
}

int LectureBit2400(FILE *f,int seuil,int aff)
{
  long pos1,pos2,nb_oct;

  pos1=ftell(f);
  Attend1Zero(f);
  Attend1Zero(f);
  pos2=ftell(f);

  nb_oct=pos2-pos1;

  if (nb_oct>seuil)
  {
 
    return 0;
  }



  return 1;
}

int AmorceValide(int b[13])
{
  int i;
  char ch[20];
  
  ch[0]=0;
  for (i=0;i<13;i++)
    sprintf(ch,"%s%d",ch,b[i]);
    
  return (!strcmp(ch,"0011010000111"));
}

void Synchronisation(FILE *f1,int mode,int seuil)
{
  int b[13],i;
  
  printf("Searching...\n");
  
  for (i=0;i<13;i++)
    if (mode)
      b[i]=LectureBit2400(f1,seuil,0);
    else
      b[i]=LectureBit300(f1,seuil,0);
     
  while (!AmorceValide(b))
  {
    for (i=0;i<12;i++)
      b[i]=b[i+1];
      
    if (mode)
      b[12]=LectureBit2400(f1,seuil,0);
    else
      b[12]=LectureBit300(f1,seuil,0);
  }
}

int Lecture1Octet(FILE *f1,int mode,int seuil,int aff)
{
  int octet,nb_1,i,b,stop[3],erreur;
  long pos,offset;
    
  pos=ftell(f1);
  
  octet=0; nb_1=0; erreur=0;

  do
  {
    if (mode)
      b=LectureBit2400(f1,seuil,aff);
    else
      b=LectureBit300(f1,seuil,aff);
    if (b)
      erreur=1;
  }
  while (b);
  
 /* if (aff) printf(" ");*/
  
  for (i=0;i<9;i++)
  {
    if (mode)
      b=LectureBit2400(f1,seuil,aff);
    else
      b=LectureBit300(f1,seuil,aff);

    if ((i<=7) && (b))
    {
      octet+=b<<i; nb_1++;
    }
    if ((i==8) && (b))
      nb_1++;
  }

  if (!(nb_1 & 1))
    erreur=1;
      
  for (i=0;i<3;i++)
  {
    if (mode)
      stop[i]=LectureBit2400(f1,seuil,aff);
    else
      stop[i]=LectureBit300(f1,seuil,aff);
  }
  
  while ((!stop[0]) || (!stop[1]) || (!stop[2]))
  {
    erreur=1;
    
    stop[0]=stop[1]; stop[1]=stop[2];
    if (mode)
      stop[2]=LectureBit2400(f1,seuil,aff);
    else
      stop[2]=LectureBit300(f1,seuil,aff);
  }
  
  Attend1Zero(f1);


  if ((erreur) && (aff))
  {
    printf(" %2x ",octet);
    
    if ((octet>=32) && (octet<=127))
      printf(" %c",octet);
    else
      printf("  ");

    printf(" longueur %ld ",ftell(f1)-pos);

    printf("** Error found\nEnter new value :");fflush(stdout);fflush(stdin);
    scanf("%x",&octet);fflush(stdin);
    printf("offset:");fflush(stdout);fflush(stdin);
    scanf("%ld",&offset);fflush(stdin);
    fseek(f1,offset,SEEK_CUR);
  }     

     
  return octet;
}

main(argc,argv)

unsigned int argc;
char **argv;

{

  int c,i,j,nb_oct,frequence,periode,seuil,mode,octet,magic_number,octet1,octet2,octet3,octet4;
  
  if (argc<3)
  {
    printf("Usage : transf infile outfile\n");
    exit(0);
  }

  f1=fopen(*(argv+1),"rb");
  if (!f1)
  {
    printf("Cannot open %s for reading\n",*(argv+1));
    exit(0);
  }

  f2=fopen(*(argv+2),"wb");
  if (!f2)
  {
    printf("Cannot open %s for writing\n",*(argv+2));
    exit(0);
  }

  do
  {
    c=fgetc(f1);
  }
  while (c<130);

  do
  {
    c=fgetc(f1);
  }
  while (c>=127);


  mode=1; /* mettre a 0 pour lent */
  
  printf("Sample rate :");
  scanf("%d",&frequence);

  magic_number=(int)(56*frequence/44100);
  if (argc==4) magic_number=0; 
  printf("Magic number : %d\n",magic_number);
  
  if (mode)
  {
    periode=208*frequence/1000000;
    seuil=periode*5/2;
  }
  else
  {
    periode=3328*frequence/1000000;
    seuil=periode*3/4;
  }
  
  printf("period: %d bytes  thresold: %d bytes\n",periode,seuil);
  
  Synchronisation(f1,mode,seuil);
  Synchronisation(f1,mode,seuil);

  while (Lecture1Octet(f1,mode,seuil,0)!=0x24);

  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x16,f2);
  fputc(0x24,f2);

  printf("Header...\n");
    
  for (i=0;i<4;i++)
  {
    octet=Lecture1Octet(f1,mode,seuil,0);
    fputc(octet,f2);
  }
  
  octet1=Lecture1Octet(f1,mode,seuil,0);
  fputc(octet1,f2);
  octet2=Lecture1Octet(f1,mode,seuil,0);
  fputc(octet2,f2);
  octet3=Lecture1Octet(f1,mode,seuil,0);
  fputc(octet3,f2);
  octet4=Lecture1Octet(f1,mode,seuil,0);
  fputc(octet4,f2);
  octet=Lecture1Octet(f1,mode,seuil,0);
  fputc(octet,f2);
  
  printf("Start address :\011%4x\n",octet3*256+octet4);
  printf("Ending address :\011%4x\n",octet1*256+octet2);
  
  nb_oct=octet1*256+octet2-(octet3*256+octet4);
  printf("Data length :\011%4x\n",nb_oct);
  
  printf("Loading... ");
  
  while ((octet=Lecture1Octet(f1,mode,seuil,0)))
  {
    fputc(octet,f2);
    printf("%c",octet);
  }
  fputc(0,f2);
  
  printf("\n");
  
  if (magic_number) fseek(f1,magic_number,SEEK_CUR);
  
  printf("Data...\n");
  
  for (j=0;j<nb_oct;j++)
  {
    /*printf("octet %4x ",j);*/
    
    octet=Lecture1Octet(f1,mode,seuil,1);
    
    fputc(octet,f2);
  }

  fclose(f1);
  fclose(f2);

  return 0;
}
