/****************************************************************/
/*								*/
/* Jedec.c - enthält Routinen zum Laden und Speichern der	*/
/* GAL-Daten im Jedec-Format					*/
/*								*/
/* compilieren: cc Jedec.c					*/
/*								*/
/****************************************************************/



#include "exec/types.h"
#include "exec/memory.h"
#include <stdio.h>
#include <ctype.h>
#include <functions.h>

#include "GALer.h"


extern	int		MaxFuseAdr;
extern	int		GALType;
extern	UBYTE		GadgetSBuff[60];

struct	JedecStruct	Jedec;


int	bitnum, linenum;

UBYTE	*actptr, *buffend;




/* PutJedec:
   liest aus dem GAL die Jedec-Struktur ein und schreibt das Jedec-File 
   Aufruf: PutJedec();
	   filename: Zeiger auf Filenamen (ohne ".jed")
*/
PutJedec()
{
 if (MyRequest(ASK_REQ,(UBYTE *)"Jedec erstellen: Bitte GAL einsetzen")) {
   if (MyRequest(SAVE_REQ,(UBYTE *)"Bitte Namen für Jedec-File eingeben")) {
     ReadGALToJedec();					/*GAL einlesen*/
     WriteJedecFile();
    }
  }
}


/* WriteJedecFile:
   erstellt aus der Jedec-Struktur das Jedec-File 
   Aufruf: WriteJedecFile();
*/
WriteJedecFile()
{
UBYTE	filenamebuff[64];
FILE	*fp;
int	n, m, bitnum;

     strcpy(&filenamebuff,&GadgetSBuff);		/*.jed an Dateinamen anfügen*/
     strcat(&filenamebuff,(UBYTE *)".jed");
     if (fp=fopen(&filenamebuff,(UBYTE *)"w")) {
       bitnum = 0;
       for (m=0; m<ROW_SIZE; m++) {
	 fprintf(fp,"*L%04d ",bitnum);
         for (n=0; n<=MaxFuseAdr; n++) {
	   fprintf(fp,"%1d",Jedec.GALLogic[bitnum]);
	   bitnum++;
	  }
	 fprintf(fp,"\n");
	}

       fprintf(fp,"*L%04d ",bitnum);			/*XOR*/
       for (n=0; n<XOR_SIZE; n++) {
	 fprintf(fp,"%1d",Jedec.GALXOR[n]);
	 bitnum++;
	}
       fprintf(fp,"\n");

       fprintf(fp,"*L%04d ",bitnum);			/*Signatur*/
       for (n=0; n<SIG_SIZE; n++) {
	 fprintf(fp,"%1d",Jedec.GALSig[n]);
	 bitnum++;
        }
       fprintf(fp,"\n");

       fprintf(fp,"*L%04d ",bitnum);			/*AC1*/
       for (n=0; n<AC1_SIZE; n++) {
	 fprintf(fp,"%1d",Jedec.GALAC1[n]);
	 bitnum++;
        }
       fprintf(fp,"\n");

       fprintf(fp,"*L%04d ",bitnum);			/*Produkttermfreigabe*/
       for (n=0; n<PT_SIZE; n++) {
	 fprintf(fp,"%1d",Jedec.GALPT[n]);
	 bitnum++;
        }
       fprintf(fp,"\n");

       fprintf(fp,"*L%04d %1d\n",bitnum,Jedec.GALSYN);	/*SYN*/
       bitnum++;

       fprintf(fp,"*L%04d %1d\n",bitnum,Jedec.GALAC0);	/*AC0*/

       if (fclose(fp)==EOF) ErrorReq(8);		/*Datei läßt sich nicht schließem*/
      }
}




/* GetJedec:
   liest Jedec-File ein, wertet es aus und füllt die Jedec-Struktur
   Aufruf: error=GetJedec(filename);
	   filename: Zeiger auf Filenamen (ohne ".jed")
	   error   : Fehlernummer; 0:keine Fehler 
*/
GetJedec(filename)
UBYTE	*filename;
{
UBYTE	filenamebuff[64];
LONG	filesize;
UBYTE	*filebuff;
int	n, bit, Logic_Size;


 strcpy(&filenamebuff,&GadgetSBuff);		/*.jed an Dateinamen anfügen*/
 strcat(&filenamebuff,(UBYTE *)".jed");

 filesize=FileSize(&filenamebuff);
 switch (filesize) {
   case -1L: {
     ErrorReq(1);
     return(-1);
     break;
    }
   case -2L: {
     ErrorReq(2);
     return(-2);
     break;
    }
   case 0L: {
     ErrorReq(4);
     return(-4);
     break;
    }
  }
 if ((filebuff=(UBYTE *)AllocMem(filesize,MEMF_PUBLIC))) {
   if ((ReadFile(&filenamebuff,filesize,filebuff))) {
     PrintText((UBYTE *)"Datei ist geladen");
     actptr=filebuff;
     buffend=filebuff+filesize;
     if (GALType==GAL16V8) Logic_Size=LOGIC16_SIZE;
     else Logic_Size=LOGIC20_SIZE;

     bitnum  = 0;
     linenum = 1;
					/*Jedec-Struktur erstellen*/
     for (n=0; n<Logic_Size; n++) {		/*Logic-Matrix füllen*/
	bit=GetNextBit();
	if (bit==-1) {				/*Fehler aufgetreten?*/
	  FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
	  return(-1);				/*und Fehlercode zurückgeben*/
	 }
        Jedec.GALLogic[n]=(BYTE)bit;
       }

     for (n=0; n<XOR_SIZE; n++) {		/*XOR-Feld füllen*/
	bit=GetNextBit();
	if (bit==-1) {				/*Fehler aufgetreten?*/
	  FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
	  return(-1);				/*und Fehlercode zurückgeben*/
	 }
        Jedec.GALXOR[n]=(BYTE)bit;
       }

     for (n=0; n<SIG_SIZE; n++) {		/*Signatur-Feld füllen*/
	bit=GetNextBit();
	if (bit==-1) {				/*Fehler aufgetreten?*/
	  FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
	  return(-1);				/*und Fehlercode zurückgeben*/
	 }
        Jedec.GALSig[n]=(BYTE)bit;
       }

     for (n=0; n<AC1_SIZE; n++) {		/*AC1-Feld füllen*/
	bit=GetNextBit();
	if (bit==-1) {				/*Fehler aufgetreten?*/
	  FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
	  return(-1);				/*und Fehlercode zurückgeben*/
	 }
        Jedec.GALAC1[n]=(BYTE)bit;
       }

     for (n=0; n<PT_SIZE; n++) {		/*Produkttermfreigebe füllen*/
	bit=GetNextBit();
	if (bit==-1) {				/*Fehler aufgetreten?*/
	  FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
	  return(-1);				/*und Fehlercode zurückgeben*/
	 }
        Jedec.GALPT[n]=(BYTE)bit;
       }

     bit=GetNextBit();				/*SYN-Bit */
     if (bit==-1) {				/*Fehler aufgetreten?*/
       FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
       return(-1);				/*und Fehlercode zurückgeben*/
      }
     Jedec.GALSYN=(BYTE)bit;

     bit=GetNextBit();				/* AC0-Bit*/
     if (bit==-1) {				/*Fehler aufgetreten?*/
       FreeMem(filebuff,filesize);		/*ja, dann Speicher freigeben*/
       return(-1);				/*und Fehlercode zurückgeben*/
      }
     Jedec.GALAC0=(BYTE)bit;
					/*Jedec-Struktur fertig aufgebaut*/

     if (!(CheckFileEnd())) {			/*Dateiende erreicht?*/
       JedecError(6);				/*nein, dann Fehler*/
       return(-1);
      }

     FreeMem(filebuff,filesize);
     return(0);					/*kein Fehler aufgetreten*/
    }
   else {
     ErrorReq(3);				/*Lesefehler*/
     FreeMem(filebuff,filesize);
     return(-2);
    }
  }
 else {
   ErrorReq(2);					/*kein Speicher*/
   return(-2);
  }

}



/* GetNextBit
   gibt Wert des nächsten Bits zurück
   Aufruf: bit=GetNextBit();
   	   actptr: Zeiger auf aktuelle Textposition
	   bit: 0/1 = Bit; -1: Fehler
*/
GetNextBit()
{
int	jedec_bit;

 if (CheckFileEnd()) {					/*Dateiende vorzeitig erreicht?*/
   JedecError(7);
   return(-1);
  }

 for(;;) {
   switch (*actptr) {
     case 0x0A: {				/*LineFeed*/
       linenum++;				/*Zeilennummer erhöhen*/
       actptr++;				/*Zeiger auf nächstes Zeichen*/
       break;
      }
     case 0x09:					/*TAB*/
     case  ' ': {				/*Space*/
       actptr++;				/*Zeiger auf nächstes Zeichen*/
       break;
      }

     case  '0': {				/*Bit=0*/
       actptr++;
       bitnum++;
       return(0);
      }

     case  '1': {				/*Bit=1*/
       actptr++;
       bitnum++;
       return(1);
      }
     case  '*': {				/* * */
       actptr++;
       if (*actptr!='L') {			/*folgt L? nein, dann Syntax-Fehler*/
	 JedecError(1);
	 return(-1);
	}
       actptr++;
       if (actptr>buffend) {			/*Dateiende?, dann Fehler*/
	 JedecError(2);
	 return(-1);
	}
       while ((*actptr==' ')||(*actptr==0x09))	/*Zeiger auf nächstes Zeichen*/
	 actptr++;
       if (actptr>buffend) {			/*Dateiende?, dann Fehler*/
	 JedecError(2);
	 return(-1);
	}
       if (!(sscanf (actptr,"%d",&jedec_bit))) {
	 JedecError(3);
	 return(-1);				/*kein Zahl nach *L */       
	}
       if (jedec_bit!=bitnum) {
	 JedecError(4);
	 return(-1);				/*Jedec-Adresse ist falsch*/
	}
       while (isdigit(*actptr))
	 actptr++;
       if (actptr>buffend) {			/*Dateiende?, dann Fehler*/
	 JedecError(2);
	 return(-1);
	}
       break;
      }
     default : {
	JedecError(5);
	return(-1);				/*unerlaubtes Zeichen*/

      }

    }
  }
}


/*überprüfe, ob sich zwischen "actptr" und Dateiende noch Zeichen befinden
  Aufruf:   answer=CheckFileEnd();
	    answer: 1=Dateiende erreicht; 0=Dateiende nicht erreicht
*/
CheckFileEnd()
{
UBYTE	*ptr;
 ptr = actptr;					/*auf Dateiende testen*/
 while (isspace(*ptr))
   ptr++;
 if (ptr>=buffend)
   return(1);
 else return(0);
}



/*gibt Fehlermeldung aus*/
JedecError(errornum)
int	errornum;
{
 PrintErrorLine(linenum);
 switch (errornum) {
   case  1: { PrintText((UBYTE *)"Buchstabe 'L' erwartet");
	      break;
	    }
   case  2: { PrintText((UBYTE *)"unerwartetes Dateiende");
	      break;
	    }
   case  3: { PrintText((UBYTE *)"Zahl (Bit-Nummer) erwartet");
	      break;
	    }
   case  4: { PrintText((UBYTE *)"Bit-Nummer stimmt mit Bit-Anzahl nicht überein");
	      break;
	    }
   case  5: { PrintText((UBYTE *)"unerlaubtes Zeichen gefunden");
	      break;
	    }
   case  6: { PrintText((UBYTE *)"Datei für eingestellten GAL-Typ zu lang");
	      break;
	    }
   case  7: { PrintText((UBYTE *)"Datei für eingestellten GAL-Typ zu kurz");
	      break;
	    }
  }
 ErrorReq(5);

}




