/****************************************************************/
/*								*/
/* 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 <libraries/dos.h>
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#include <functions.h>

#include "GALer.h"



extern	int		MaxFuseAdr;
extern	int		GALType;
extern	char		path;

extern	struct	Configuration Config;

struct	JedecStruct	Jedec;


int	linenum, JedecSecurity, JedecGALType;

UBYTE	*actptr, *buffend;




/* PutJedec:
   liest aus dem GAL die Jedec-Struktur ein und schreibt das Jedec-File 
   Aufruf: PutJedec();
*/
void PutJedec()
{
 if (MyRequest(GALTYPE_REQ,(UBYTE *)"read GAL and make JEDEC file?")) {
     if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
       return;					/*bei Fehler return*/
     PrintText((UBYTE *)"reading GAL...",1);
     ReadGALToJedec();					/*GAL einlesen*/
     PrintText((UBYTE *)" o.k.",0);

     if (MyFileReq((UBYTE *)"save JEDEC file",(UBYTE *)".jed",YES))
       WriteJedecFile();

  }
}






/* FileChecksum: berechnet die Checksumme über das Jedec-File
		 Enfang und Ende MUß mit <STX> und <ETX> gekennzeichnet sein!
   Aufruf: checksum = FileChecksum(buff);
	     buff: ActBuffer-Struktur des File-Puffers
   Ergebnis: checksum: 16-Bit Checksumme der Jedec-Struktur
*/
int FileChecksum(buff)
struct	ActBuffer buff;
{
int checksum;

 checksum = 0;

 while (*buff.Entry != 0x2)			/* <STX> suchen */
   IncPointer(&buff);

 while (*buff.Entry != 0x3) {			/* <ETX> suchen und alle*/
   checksum += *buff.Entry;			/* Zeichen aufaddieren*/
   IncPointer(&buff);
  }

 checksum += 0x3;				/* <ETX> noch dazuaddieren*/

 return(checksum);				/* fertig */
}



/* FuseChecksum: berechnet aus der Jedec-Struktur die Fuse-Checksumme 
   Aufruf: checksum = FuseChecksum(gal_type);
	   gal_type muß den GAL-Typ enthalten
   Ergebnis: checksum: 16-Bit Checksumme der Jedec-Struktur
*/
int FuseChecksum(gal_type)
int gal_type;
{
int	checksum, byte, fuses;
int	n;
BYTE	*ptr;

 if (gal_type == GAL16V8)
   fuses = NUMOFFUSES16;
 else
   fuses = NUMOFFUSES20;

 ptr = &Jedec.GALLogic[0];
 checksum = byte = 0;
 for (n=9; n<fuses+9; n++) {
   byte |= (*ptr << (n-1) % 8);
   if (!(n % 8)) {
     checksum += byte;
     byte = 0;
    }
 if (n == 2039)
   n=n;
   
   if ((gal_type == GAL16V8) && (ptr == &Jedec.GALLogic[0]+(long)XOR16-1L))
     ptr = &Jedec.GALXOR[0];
   else
     ptr++;
  }
 checksum += byte;

 return(checksum); 
}



/* MakeJedecBuff: wertet Jedec-Struktur aus und legt das Jedec-File
		  im Speicher ab
   Aufruf:   result = MakeJedecBuff(buff);
   	     buff:    ActBuffer-Struktur für Speicherblock in dem
		      das Jedec-File abgelegt werden soll
   Ergebnis: result:  0: alles o.k.
		     -1: nicht genug freier Speicher
*/
int MakeJedecBuff(buff)
struct	ActBuffer buff;
{
int	n, m, bitnum, bitnum2, flag;
UBYTE	mystrng[8];
struct	ActBuffer buff2;

 buff2 = buff;

 if (Config.JedecFileChk)
   if (AddString(&buff, "\2\n"))			/*<STX>*/
     return(-1);

 if (AddString(&buff, "Used Program:   GALer V1.4\n"))
   return(-1);
 if (AddString(&buff, "GAL-Assembler:  GALer V1.4\n"))
   return(-1);
 if (GALType == GAL16V8) {
   if (AddString(&buff, "Device:         GAL16V8\n\n"))
     return(-1);
  }
 else
   if (AddString(&buff, "Device:         GAL20V8\n\n"))
     return(-1);


 if (AddString(&buff, "*F0\n"))			/*Default-Wert für Fuses*/
   return(-1);

 if (Config.JedecSecBit) {			/*Security-Bit*/
   if (AddString(&buff, "*G1\n"))
     return(-1);
  }
 else
   if (AddString(&buff, "*G0\n"))
     return(-1);

 if (GALType == GAL16V8) {			/*Anzahl der Sicherungen*/
   if (AddString(&buff, "*QF2194\n"))		/*im File*/
     return(-1);
  }
 else
   if (AddString(&buff, "*QF2706\n"))
     return(-1);
      
						/*Fuse-Matrix erstellen*/
 bitnum = 0;
 for (m=0; m<ROW_SIZE; m++) {
   flag = 0;
   bitnum2 = bitnum;
   for (n=0; n<=MaxFuseAdr; n++) {
     if (Jedec.GALLogic[bitnum2]) {
       flag = 1;
       break;
      }
     bitnum2++;
    }

   if (flag) {
     sprintf(&mystrng[0],"*L%04d \0",bitnum);
     if (AddString(&buff, &mystrng[0]))
       return(-1);
     for (n=0; n<=MaxFuseAdr; n++) {
       if (AddByte(&buff, Jedec.GALLogic[bitnum] + '0'))
         return(-1);
       bitnum++;
      }
     if (AddByte(&buff, '\n'))
       return(-1);
    }
   else
     bitnum = bitnum2;
  }
 if (!flag)
   bitnum = bitnum2;


						/*XOR-Bits*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 for (n=0; n<XOR_SIZE; n++) {
   if (AddByte(&buff, Jedec.GALXOR[n] + '0'))
     return(-1);
   bitnum++;
  }
 if (AddByte(&buff, '\n'))
   return(-1);

						/*Signatur*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 for (n=0; n<SIG_SIZE; n++) {
   if (AddByte(&buff, Jedec.GALSig[n] + '0'))
     return(-1);
   bitnum++;
  }
 if (AddByte(&buff, '\n'))
   return(-1);

						/*AC1-Bits*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 for (n=0; n<AC1_SIZE; n++) {
   if (AddByte(&buff, Jedec.GALAC1[n] + '0'))
     return(-1);
   bitnum++;
  }
 if (AddByte(&buff, '\n'))
   return(-1);

						/*PT-Bits*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 for (n=0; n<PT_SIZE; n++) {
   if (AddByte(&buff, Jedec.GALPT[n] + '0'))
     return(-1);
   bitnum++;
  }
 if (AddByte(&buff, '\n'))
   return(-1);

						/*SYN-Bit*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 if (AddByte(&buff, Jedec.GALSYN + '0'))
   return(-1);
 if (AddByte(&buff, '\n'))
   return(-1);
 bitnum++;
						/*AC0-Bit*/
 sprintf(&mystrng[0],"*L%04d \0",bitnum);
 if (AddString(&buff, &mystrng[0]))
   return(-1);
 if (AddByte(&buff, Jedec.GALAC0 + '0'))
   return(-1);
 if (AddByte(&buff, '\n'))
   return(-1);

 if (Config.JedecFuseChk) {			/*Checksumme der Sicherungen*/
   sprintf(&mystrng[0],"*C%04x\n\0", FuseChecksum(GALType));
   if (AddString(&buff, &mystrng[0]))
     return(-1);
  }

 if (AddString(&buff, "*\n"))			/*abschließendes '*' */
   return(-1);

 if (Config.JedecFileChk) {
   if (AddByte(&buff, 0x3))			/* <ETX> */
     return(-1);
   sprintf(&mystrng[0],"%04x\n\0", FileChecksum(buff2));
   if (AddString(&buff, &mystrng[0]))
     return(-1);
  }

 return(0);
}




/* WriteJedecFile:
   erstellt aus der Jedec-Struktur das Jedec-File 
   Aufruf: WriteJedecFile();
   	   die globale Variable "GALType" muß den GAL-Typ enthalten
*/
void WriteJedecFile()
{
struct	ActBuffer	mybuff;
struct	Buffer		*first_buff;
struct	FileHandle	*fh;
extern	char	path;
UBYTE	*filebuffer, *filebuffer2;
long	result;


 if (!(first_buff = (struct Buffer *)AllocMem((long)sizeof(struct Buffer),MEMF_PUBLIC|MEMF_CLEAR))) {
   ErrorReq(2);			/*kein Speicher mehr->Fehlermeldung*/
   return;
  }

 mybuff.ThisBuff = first_buff;
 mybuff.Entry    = (UBYTE *)(&first_buff->Entries[0]);
 mybuff.BuffEnd  = (UBYTE *)first_buff + (long)sizeof(struct Buffer);



 if (MakeJedecBuff(mybuff)) {			/*Jedec in Puffer ablegen*/
   FreeBuffer(first_buff);			/*Fehler?, dann Abbruch*/
   ErrorReq(2);
   return;
  }

 PrintText((UBYTE *)"saving JEDEC file...",1);
 if ((fh = Open(&path, (long)MODE_NEWFILE))) {
   for (;;) {
     filebuffer = filebuffer2 = mybuff.Entry;

     while (filebuffer2 < mybuff.BuffEnd) {	/*Größe des Puffers bestimmen*/
       if (!*filebuffer2) 
	 break;
       filebuffer2++;
      }
						/*Puffer schreiben*/
     result = Write(fh, filebuffer, (long)(filebuffer2-filebuffer));
     if (result == -1L) {			/*Fehler beim Schreiben?*/
       Close(fh);				/*ja, dann Ende*/
       FreeBuffer(first_buff);
       PrintText((UBYTE *)" Error! ",0);
       ErrorReq(13);
       return;
      }

     if (!mybuff.ThisBuff->Next)		/*noch ein Puffer da?*/
       break;					/*nein, dann for(;;)-Ende*/
     mybuff.ThisBuff = mybuff.ThisBuff->Next;
     mybuff.Entry    = (UBYTE *)(&mybuff.ThisBuff->Entries[0]);
     mybuff.BuffEnd  = (UBYTE *)mybuff.ThisBuff + (long)sizeof(struct Buffer);
    }
   Close(fh);
  }
 else {
   FreeBuffer(first_buff);			/*Fehler?, dann Abbruch*/
   PrintText((UBYTE *)" Error! ",0);
   ErrorReq(13);			/*Datei läßt sich nicht öffnen*/
   return;
  }
 PrintText((UBYTE *)" o.k.",0);
 FreeBuffer(first_buff);
}





/* SearchNextChar: stellt Zeiger auf nächstes Zeichen, das kein TAB
		   SPACE, CR ist - sucht von actptr + 1 ab
   Aufruf:   result = SearchNextChar();
   Ergebnis: result = 0: noch ein Zeichen gefunden
		    =-1: kein Zeichen mehr da (Fileende)
*/
int SearchNextChar()
{
 actptr++;
 while (*actptr) {
   switch (*actptr) {
     case  ' ':
     case 0x09:	break;
     case 0x0A: linenum++;
		break;
     default  : return(0);
    }
   actptr++;
  } 
 return(-1);
}


/* SearchNextAsterix: (hat nichts mit dem bekannten Gallier zu tun)
		      sucht bis zum Fileende das '*'-Zeichen - sucht von
		      actptr ab
   Aufruf:   result = SearchNextAsterix();
   Ergebnis: result = 0: Zeichen gefunden
		    =-1: kein Zeichen mehr da (Fileende)
*/
int SearchNextAsterix()
{
  while (*actptr) {
    if (*actptr == '*')
      return(0);
    if (*actptr == 0x0A)
      linenum++;
    actptr++;
   }
  return(-1);
}



/* GetJedec:
   liest Jedec-File ein, wertet es aus und füllt die Jedec-Struktur
   Aufruf: error=GetJedec(jedecfile);
	   jedecfile  : Zeiger auf Filenamen (mit ".jed")
	   error      : Fehlernummer; 0:keine Fehler 
*/
int GetJedec(jedecfile)
UBYTE	*jedecfile;
{
extern	char	path;
LONG	filesize;
UBYTE	*filebuff, *ptr, *jedbuff, *jedptr;
int	n;
int	QFflag, QPflag, Fflag, Gflag, Cflag;
int	Lflag, STXflag, ETXflag, FCHKflag;
int	errornum, fuse_chk, file_chk;
unsigned int	num, fuse;
unsigned int	QF, QP, F;


 JedecGALType = NOT_SPECIFIED;

 filesize = FileSize(jedecfile);
 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+2L,MEMF_PUBLIC|MEMF_CLEAR))) {
   if ((ReadFile(jedecfile,filesize,filebuff))) {
     PrintText((UBYTE *)"file loaded",1);
     actptr = filebuff;				/*Variablen initialisieren*/
     linenum  = 1;
     errornum = 0;
     fuse     = 0;
     QFflag = QPflag = Fflag = Gflag = Cflag = Lflag = STXflag = ETXflag = 0;
     FCHKflag = 0;

     if (!(jedbuff=(UBYTE *)AllocMem((long)NUMOFFUSES20,MEMF_PUBLIC|MEMF_CLEAR))) {
       FreeMem(filebuff,filesize);
       ErrorReq(2);					/*kein Speicher*/
       return(-2);
      }
     jedptr = jedbuff;


     if (SearchNextAsterix()) {			/*Zeiger auf ersten Befehl*/
       FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
       FreeMem(filebuff,filesize);
       JedecError(1,YES);			/*unerwartetes Dateiende*/
       return(1);
      }

     for (;;) {
       if (SearchNextChar())			/*kein Zeichen mehr da?*/
	 break;					/*dann for-Schleife beenden*/

       switch (*actptr) {
	 case 'Q':			/*Befehle, die mit Q beginnen*/
	   actptr++;
	   if (*actptr == 'F') {	/*Anzahl der Fuses*/
	     if (QFflag) {			/*Befehl darf innerhalb des*/
	       errornum = 7;			/*Jedec-Files nur einmal*/
	       break;				/*vorkommen*/
	      }
	     actptr++;
	     if (!isdigit(*actptr)) {		/*Zahl vorhanden?*/
	       errornum = 4;			/*nein, dann Fehler*/
	       break;
	      }
	     if (!sscanf(actptr,"%d",&QF)) {
	       errornum = 3;
	       break;
	      }
	     while (isdigit(*actptr))		/*eingelesene Zahl über-*/
	       actptr++;			/*springen*/
	     QFflag = 1;

	     if ((QF != 2194) && (QF != 2706)) {
	       errornum = 22;			/*ungültiges QF, dann Fehler*/
	       break;
	      }

	     if (QF == 2194)			/*aus *QF GAL-Typ bestimmen*/
	       JedecGALType = GAL16V8;
	     if (QF == 2706)
	       JedecGALType = GAL20V8;

	     break;
	    }

	   if (*actptr == 'P') {	/*Anzahl der Pins für Testvek.*/
	     if (QPflag) {			/*Befehl darf innerhalb des*/
	       errornum = 8;			/*Jedec-Files nur einmal*/
	       break;				/*vorkommen*/
	      }
	     actptr++;
	     if (!isdigit(*actptr)) {		/*Zahl vorhanden?*/
	       errornum = 4;			/*nein, dann Fehler*/
	       break;
	      }
	     if (!sscanf(actptr,"%d",&QP)) {
	       errornum = 3;
	       break;
	      }
	     while (isdigit(*actptr))		/*eingelesene Zahl über-*/
	       actptr++;			/*springen*/
	     QPflag = 1;
	     break;
	    }
	   errornum = 2;			/*kein QF,QP, dann Fehler*/
	   break;


	 case 'F':			/*Fuse-Default*/
	   actptr++;
	   if (*actptr == '0')
	     F = 0;
	   else
	     if (*actptr == '1')
	       F = 1;
	     else {				/*weder 0 noch 1 nach F*/
	       errornum = 5;			/*dann Fehler*/
	       break;
	      }
	   for (n=fuse; n<sizeof(Jedec); n++)	/*Default-Wert setzen*/
	     *(jedbuff + (long)n) = F;
	   Fflag = 1;
	   break;


	 case 'P':			/*Pins für Testvektoren*/
	 case 'V':			/*Testvektoren*/
	 case 'N':			/*Kommentar*/
	   break;				/*nichts machen*/


	 case 'C':			/*Fuse-Checksumme*/
	   if (Cflag) {				/*nur eine Checksumme*/
	     errornum = 24;			/*erlaubt*/
	     break;
	    }
	   actptr++;
	   if (!isxdigit(*actptr)) {		/*Hex-Zahl vorhanden?*/
	     errornum = 4;			/*nein, dann Fehler*/
	     break;
	    }
	   if (!sscanf(actptr,"%x",&fuse_chk)) {
	     errornum = 3;
	     break;
	    }
	   while (isxdigit(*actptr))		/*eingelesene Hex-Zahl über-*/
	     actptr++;				/*springen*/
	   Cflag = 1;
	   break;


	 case 'L':			/*Fuse-Adresse*/
	   if (Cflag) {			/*nach *C kein *L mehr*/
	     errornum = 10;
	     break;
	    }
	   actptr++;
	   if (!isdigit(*actptr)) {		/*Dez-Zahl vorhanden?*/
	     errornum = 4;			/*nein, dann Fehler*/
	     break;
	    }
	   if (!sscanf(actptr,"%d",&num)) {
	     errornum = 3;
	     break;
	    }
	   while (isdigit(*actptr))		/*eingelesene Zahl über-*/
	     actptr++;				/*springen*/
	   if (num < fuse) {			/* Fuse-Adresse zu klein?*/
	     errornum = 17;
	     break;
	    }
	   if ((num > fuse) && !Fflag) {	/*Fuse-Adresse übersprungen*/
	     errornum = 18;			/*aber kein *F vorhanden?*/
	     break;
	    }
	   if (SearchNextChar()) {		/*kein Zeichen mehr da?*/
	     errornum = 1;			/*dann unerwartetes Ende*/
	     break;
	    }
	   fuse = num;
	   for (;;) {				/*Fuses auswerten*/
	     if ((*actptr == '1') || (*actptr == '0')) {
	       *(jedbuff + (long)fuse) = *actptr - '0';
	      }
	     else {
	       if (*actptr == '*')		/*nächste Anweisung?*/
		 break;				/*ja, dann fertig*/
	       else {				/*nein, dann Fehler*/
		 errornum = 19;			/* '*' erwartet*/
		 break;
		}
	      }
	     if (SearchNextChar()) {		/*kein Zeichen mehr da?*/
	       errornum = 1;			/*dann unerwartetes Ende*/
	       break;
	      }
	     fuse++;
	    }
	   Lflag = 1;
	   break;


	 case 'G':			/*Security*/
	   if (QPflag) {			/*Befehl darf innerhalb des*/
	     errornum = 8;			/*Jedec-Files nur einmal*/
	     break;				/*vorkommen*/
	    }
	   actptr++;
	   if (*actptr == '0')
	     JedecSecurity = 0;
	   else
	     if (*actptr == '1')
	       JedecSecurity = 1;
	     else {				/*weder 0 noch 1 nach G*/
	       errornum = 5;			/*dann Fehler*/
	       break;
	      }
	   Gflag = 1;
	   break;


	 case 0x02:			/* <STX> */
	   break;


	 case 0x03:			/* <ETX> gefolgt von File-Checksumme*/
	   ptr = filebuff;
	   file_chk = 0;
	   while (*ptr) {
	     if (*ptr == 0x02) {			/* <STX> */
	       if (STXflag) {				/*mehrfach vorhanden*/
		 errornum = 12;
		 break;
		}
	       if (ETXflag) {				/* STX vor ETX? */
		 errornum = 14;
		 break;
		}
	       STXflag = 1;
	      }
	     if (*ptr == 0x03) {			/* <ETX> */
	       if (ETXflag) {				/*mehrfach vorhanden*/
		 errornum = 13;
		 break;
		}
	       if (!STXflag) {				/* STX vor ETX? */
		 errornum = 14;
		 break;
		}
	       ETXflag = 1;
	      }
	     if (STXflag && !ETXflag)			/*Summe bilden*/
	       file_chk += *ptr;
	     ptr++;
	    }
	   file_chk += 0x03;				/*ETX dazuaddieren*/
	   actptr++;
	   if (!isxdigit(*actptr)) {		/*Hex-Zahl vorhanden?*/
	     errornum = 4;			/*nein, dann Fehler*/
	     break;
	    }
	   if (!sscanf(actptr,"%x",&num)) {
	     errornum = 3;
	     break;
	    }
	   while (isxdigit(*actptr))		    /*Hex-Zahl überspringen*/
	     actptr++;
	   if (file_chk != num) {
	     if (!MyRequest(CONT_REQ, (UBYTE *)"Bad file checksum: continue?")) {
	       errornum = 16;
	       break;
	      }
	    }
	   FCHKflag = 1;
	   break;
        }


       if (errornum) {			/*Fehler aufgetreten? dann Ende*/
         FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
	 FreeMem(filebuff,filesize);		/*Puffer für Jedec-File*/
	 JedecError(errornum,YES);
	 return(errornum);
	}

       if (FCHKflag)				/*File-Checksumme?*/
	 break;					/*dann for-Schleife beenden*/

       if (SearchNextAsterix()) 		/*abschließendes '*' suchen*/
	 errornum = 9;

      }


     if (!Lflag && !Fflag) {			/*keine Fuses angegeben?*/
       FreeMem(filebuff,filesize);		/*dann Fehler*/
       FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
       JedecError(21,NO);
       return(21);
      }

     if (QFflag) {			/*Diskrepanz zwischen *QF und *L..?*/
       if (((fuse != QF) && !Fflag) || (fuse > QF)) {
	 FreeMem(filebuff,filesize);		/*dann Fehler*/
         FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
	 JedecError(20,NO);
	 return(20);
	}
       }
     else {
       if (Fflag) {
	 if ((fuse > 2194) && (fuse <= 2706))
	   JedecGALType = GAL20V8;
	 if (fuse <= 2194)
	   JedecGALType = GAL16V8;
	 if (fuse > 2706) {
           FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
	   FreeMem(filebuff,filesize);
	   JedecError(6,NO);
	   return(23);
	  }
	}
       else {
         if ((fuse != 2194) && (fuse != 2706)) {
           FreeMem(jedbuff,(long)NUMOFFUSES20); /*Puffer für Jedec-Struktur*/
	   FreeMem(filebuff,filesize);
	   JedecError(6,NO);
	   return(6);
	  }
         if (fuse == 2194)
	   JedecGALType = GAL16V8;
         if (fuse == 2706)
	   JedecGALType = GAL20V8;
	}
      }

     if (FCHKflag)				/*File-Checksumme?*/
       if (!SearchNextChar()) {			/*noch Zeichen vorhanden?*/
	 FreeMem(filebuff,filesize);		/*dann Fehler*/
         FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
	 JedecError(15,YES);
	 return(15);
	}

     for (n=0; n<sizeof(Jedec); n++) {		/*Jedec-Struktur init.*/
       if (JedecGALType == GAL16V8) {
	 if ((n > 2047) && (n < 2560))
	   Jedec.GALLogic[n] = 0;
	 else {
 	   Jedec.GALLogic[n] = *jedptr;
	   jedptr++;
	  }
        }
       if (JedecGALType == GAL20V8) {
  	 Jedec.GALLogic[n] = *jedptr;
         jedptr++;
	}
      }

     if (Cflag) {
       if (fuse_chk != FuseChecksum(JedecGALType)) {
         if (!MyRequest(CONT_REQ, (UBYTE *)"Bad fuse checksum: continue?")) {
	   FreeMem(filebuff,filesize);		/*dann Fehler*/
           FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
	   JedecError(11,NO);
	   return(11);
	  }
        }
      }

     FreeMem(jedbuff,(long)NUMOFFUSES20);	/*Puffer für Jedec-Struktur*/
     FreeMem(filebuff,filesize);		/*Puffer für Jedec-File*/
     return(0);					/*kein Fehler aufgetreten*/
    }
   else {
     ErrorReq(3);				/*Lesefehler*/
     FreeMem(filebuff,filesize);
     return(-2);
    }
  }
 else {
   ErrorReq(2);					/*kein Speicher*/
   return(-2);
  }

}







/*gibt Fehlermeldung aus
  flag gibt an, ob mit oder ohne Zeilenangabe
*/
void JedecError(errornum, flag)
int	errornum, flag;
{
 if (flag)
   PrintErrorLine(linenum);

 switch (errornum) {
   case  1: { PrintText((UBYTE *)"unexpected end of file",1);
	      break;
	    }
   case  2: { PrintText((UBYTE *)"unknown command found",1);
	      break;
	    }
   case  3: { PrintText((UBYTE *)"bad format of number",1);
	      break;
	    }
   case  4: { PrintText((UBYTE *)"number expected after command",1);
	      break;
	    }
   case  5: { PrintText((UBYTE *)"0 or 1 expected",1);
	      break;
	    }
   case  6: { PrintText((UBYTE *)"can't find out type of GAL",1);
	      break;
	    }
   case  7: { PrintText((UBYTE *)"QF multible found",1);
	      break;
	    }
   case  8: { PrintText((UBYTE *)"QP multible found",1);
	      break;
	    }
   case  9: { PrintText((UBYTE *)"ending '*' expected",1);
	      break;
	    }
   case 10: { PrintText((UBYTE *)"after 'C' command no 'L' command allowed",1);
	      break;
	    }
   case 11: { PrintText((UBYTE *)"bad fuse checksum",1);
	      break;
	    }
   case 12: { PrintText((UBYTE *)"too many <STX> (= CTRL-B, 0x02) found",1);
	      break;
	    }
   case 13: { PrintText((UBYTE *)"too many <ETX> (= CTRL-C, 0x03) found",1);
	      break;
	    }
   case 14: { PrintText((UBYTE *)"bad sequence of <STX>, <ETX>",1);
	      break;
	    }
   case 15: { PrintText((UBYTE *)"after file checksum end of file expected",1);
	      break;
	    }
   case 16: { PrintText((UBYTE *)"bad file checksum",1);
	      break;
	    }
   case 17: { PrintText((UBYTE *)"bad fuse address (L... too short)",1);
	      break;
	    }
   case 18: { PrintText((UBYTE *)"addresses skiped but no default value (F0/1) defined",1);
	      break;
	    }
   case 19: { PrintText((UBYTE *)"'*' expected",1);
	      break;
	    }
   case 20: { PrintText((UBYTE *)"QF... and last fuse address (L...) are not equal",1);
	      break;
	    }
   case 21: { PrintText((UBYTE *)"no values for the fuses found (no F0/1, L...)",1);
	      break;
	    }
   case 22: { PrintText((UBYTE *)"only QF2194 * (GAL16V8) and QF2706 * (GAL20V8) allowed",1);
	      break;
	    }
   case 23: { PrintText((UBYTE *)"too many fuses found (>2706)",1);
	      break;
	    }
   case 24: { PrintText((UBYTE *)"found several fuse checksumms",1);
	      break;
	    }
   case 25: { PrintText((UBYTE *)"selected type of GAL fits not to JEDEC file",1);
	      break;
	    }
  }
 ErrorReq(5);

}




