/****************************************************************/
/*								*/
/* GAL.c - enthält Routinen zum Beschreiben und zum Lesen	*/
/* von GALs							*/
/*								*/
/* compilieren: cc GAL.c					*/
/*								*/
/****************************************************************/



#include <exec/types.h>
#include <intuition/intuition.h>
#include <ctype.h>
#include <stdio.h>

#include "GALer.h"


extern	char	path[];
extern	int	GALType, JedecSecurity, JedecGALType;
extern	struct	JedecStruct	Jedec;
extern	struct	Configuration	Config;
extern	struct	Gadget		SGadget20;
extern	struct	Gadget		SGadget21;
extern	struct	Gadget		SGadget22;
extern	struct	Gadget		SGadget23;
extern	struct	IntuiText	SIText19, ITextW;
extern	struct	Requester	req;


int	MaxFuseAdr, SigAdr;

extern	long	prog_time;

struct	JedecStruct	Jedec2;


UBYTE	SignatureTxt[] = "Signature:$00 $00 $00 $00 $00 $00 $00 $00  :  XXXXXXXX";
UBYTE	PTTxt[]        = "PT: 0000000000000000000000000000000000000000000000000000000000000000";
UBYTE	ConTxt[]       = "XOR(n): 00000000    SYN: 0    AC0: 0";
UBYTE	AC1Txt[]       = "AC1(n): 00000000";


struct IntuiText CmpIText5 = { 2,0,JAM1,23,30,NULL,
			       (UBYTE *)"       Compare once more?",NULL};

struct IntuiText CmpIText4 = { 2,0,JAM1,67,10,NULL,
			       (UBYTE *)"Cancel comparison.",&CmpIText5};

struct IntuiText CmpIText3 = { 2,0,JAM1,47,10,NULL,
			       (UBYTE *)"   Signature not equal!",&CmpIText5 };

struct IntuiText CmpIText2 = { 2,0,JAM1,91,10,NULL,
			       (UBYTE *)"   NOT equal!",&CmpIText5 };

struct IntuiText CmpIText1 = { 2,0,JAM1,87,10,NULL,
			       (UBYTE *)"     Equal!",&CmpIText5 };




/*ProgramGAL
  liest Jedec-Datei ein und programmiert anschließend das GAL
  Aufruf: ProgramGAL();
*/
void ProgramGAL()
{
 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Program a GAL?")) {
   if (MyFileReq((char *)"Load JEDEC file", (char *)".jed",YES)) {
     if (!(GetJedec(&path[0]))) {
       if (GALType != JedecGALType) {		/*überprüfen, ob der einge-*/
	 JedecError(25,NO);			/*stellte GAL-Typ zum Jedec-*/
	 return;				/*File paßt*/
	}
       if (ReadGALParameter(YES))		/*GAL-Parameter holen*/
	 return;				/*bei Fehler return*/
       if (!ProgJedecToGAL(PROGGAL)) {
	 if (JedecSecurity)			/*war im Jedec-File das Sec.*/
	   SetSecurity(NO);			/*gesetzt? */ 
	 MyRequest(INFO_REQ,(UBYTE *)"GAL programmed.");
	}
       else
	 return;
      }
    }
  }
}


/* GAL kopieren
*/
void CopyGAL()
{
int	flag;
BYTE	atype;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Copy GAL?")) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   PrintText((UBYTE *)"reading GAL...",1);
   ReadGALToJedec();
   PrintText((UBYTE *)" o.k.",0);

   flag = 0;
   for (;;) {
     if (flag)
       if (!MyRequest(CONT_REQ,(UBYTE *)"Copy the GAL once more?"))
         break;
     flag = 1;

     if (Config.AutoAType) {
       MyRequest(INFO_REQ,(UBYTE *)"Please insert dest. GAL.");
       if (!ReadGALParameter(YES))		/*GAL-Parameter holen*/
         ProgJedecToGAL(COPYGAL);		/*kein Fehler, dann prog.*/
      }
     else {
       atype = Config.AType;
       Config.AType = MyRequest(ATYPE_REQ,(UBYTE *)"Please insert dest. GAL.");
       if (!ReadGALParameter(YES))		/*GAL-Parameter holen*/
         ProgJedecToGAL(COPYGAL);		/*kein Fehler, dann prog.*/
       Config.AType = atype;
      }
    }
  }
}



/* überprüfe, ob GAL leer ist*/
void Leertest()
{
int result;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Blank test?")) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   PrintText((UBYTE *)"executing blank test...",1);
   result = CheckGAL();
   PrintText((UBYTE *)" ready",0);

   if (result)
     MyRequest(INFO_REQ,(UBYTE *)"GAL is blank!");
   else
     MyRequest(INFO_REQ,(UBYTE *)"GAL is NOT blank!");
  }
}



/* CheckGAL:   teste ob GAL leer ist
   Vor dem Aufruf von dieser Routine sollten mit ReadGALParameter(YES) die
   GAL-Parameter erfolgreich gelesen worden sein.
   Aufruf:   return=CheckGAL();
   Ergebnis: return = 0 : GAL ist leer
		      1 : Logik-Matrix ist nicht leer
		      2 : Logik-Matrix ist leer, aber Rest nicht
*/
int CheckGAL()
{
int	n, row;


 LED(ON);
 EditMode(VERIFY);				/*GAL in Verify-Mode*/

 for (row=0; row<=MaxFuseAdr; row++) {	    /*Logik-Matrix lesen*/
   SetRow(row);				/*Adresse anlegen*/
   STRImpuls(VERIFY_TIME);		/*Bits in's Schieberegister holen*/
   for (n=0; n<ROW_SIZE; n++) {		/*seriell auslesen*/
     if (!SDOut()) {				/*SDOut-Ausgang lesen*/
       ExitEditMode();
       return(1);
      }
     Clock();					/*nächstes Bit an SDOut holen*/
    }
  }

 SetRow(SigAdr);	 		    /*Signatur auslesesn*/
 STRImpuls(VERIFY_TIME);
 for (n=0; n<SIG_SIZE; n++) {
    if (!SDOut()) {
      ExitEditMode();
      return(2);
     }
    Clock();
   }
 
 SetRow(ACW_ADR);			    /*Architecture Control Word holen*/
 STRImpuls(VERIFY_TIME);			/*Bits in's Schieberegister*/
 for (n=0; n<ACW_SIZE; n++) {
   if (!SDOut()) {
     ExitEditMode();
     return(2);
    }
   Clock();
  }

 ExitEditMode();
 return(0);					/*GAL ist leer*/
}




/*testen, ob Sicherungsbit gesetzt ist
  Das geht so (hoffe ich zumindest): Die Funktion CheckGAL gibt eine 0
  zurück wenn das GAL leer ist, eine 1 wenn in der Logik-Matrix eine
  0 vorkommt und eine 2 wenn erst im ACW oder in der Signatur eine 0 vor-
  kommt. Wenn in der Logik-Matrix eine 0 vorkommt, kann das Security-Bit
  nicht gesetzt sein. Wenn in der Logik-Matrix nur 1 vorkommt und der Rest
  (Signatur...), der ja auch bei gesetztem Bit ausgelesen werden kann,
  eine 0 enthält, folgt daraus, daß das Secruity-Bit gesetzt ist.
*/
void TestSecurity()
{
int result;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Test security bit?")) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   result = CheckGAL();
   if (result == 2)
     MyRequest(INFO_REQ,(UBYTE *)"Security bit is set!");
   else
     if (result == 1)
       MyRequest(INFO_REQ,(UBYTE *)"Security bit is NOT set!");
     else
       MyRequest(INFO_REQ,(UBYTE *)"GAL is blank!");
  }
}







/* Compare:  führt Vergleich durch zwischen GAL-GAL, GAL-Jedec, Jedec-GAL
   Aufruf:	 Compare();
   Ergebnis:	 ---
*/
void Compare()
{
int	n, row, cmptype, result, execute;
int	logic, acw, signature;
BYTE	atype;
UBYTE	*old_txt;


 if (!(cmptype = CompareRequester()))			/*Abbruch?*/
   return;

 if (cmptype == 1)					/*GAL mit GAL*/
   if (!MyRequest(GALTYPE_REQ,(UBYTE *)"Compare GAL with GAL."))
     return;
 if (cmptype == 2)					/*GAL mit Jedec*/
   if (!MyRequest(GALTYPE_REQ,(UBYTE *)"Compare GAL with JEDEC file."))
     return;
 if ((cmptype == 3) && (Config.GALTypeReq)) {
   old_txt = SIText19.IText;
   SIText19.IText = (UBYTE *)" GAL which you want to compare with a JEDEC file.";
   result = MyRequest(GALTYPE_REQ,(UBYTE *)"Compare JEDEC file with GAL. Please select type of");
   SIText19.IText = old_txt;

   if (!result)
     return;
  }


 if ((cmptype == 1) || (cmptype == 2)) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   PrintText((UBYTE *)"reading GAL...",1);
   ReadGALToJedec();				/*Jedec-Struktur erstellen*/
   PrintText((UBYTE *)" o.k.",0);
  }
 if (cmptype == 3) {
   if (MyFileReq((char *)"Load JEDEC file", (char *)".jed",YES)) {
     if (GetJedec(&path[0]))			/*Jedec-File in Struktur*/
       return;
     if (GALType != JedecGALType) {		/*überprüfen, ob der einge-*/
       JedecError(25,NO);			/*stellte GAL-Typ zum Jedec-*/
       return;					/*File paßt*/
      }
    }
   else
     return;
  }


 for (n=0; n<sizeof(Jedec2); n++)		/*Jedec-Struktur sichern*/
   Jedec2.GALLogic[n] = Jedec.GALLogic[n];


 for (;;) {
   execute = 1;
   if ((cmptype == 1) || (cmptype == 3)) {
     if (Config.AutoAType) {
       MyRequest(INFO_REQ,(UBYTE *)"Please insert GAL too compare.");
       if (!ReadGALParameter(YES)) {		/*GAL-Parameter holen*/
	 PrintText((UBYTE *)"reading GAL...",1); /*o.k.? dann weiter*/
	 ReadGALToJedec();
	 PrintText((UBYTE *)" o.k.",0);
	}
       else
	 execute = 0;
      }
     else {
       atype = Config.AType;		/*GAL-Typ sichern*/
       Config.AType = MyRequest(ATYPE_REQ,(UBYTE *)"Please insert GAL too compare.");
       if (!ReadGALParameter(YES)) {		/*GAL-Parameter holen*/
	 PrintText((UBYTE *)"reading GAL...",1);
	 ReadGALToJedec();
	 PrintText((UBYTE *)" o.k.",0);
	 Config.AType = atype;		/*GAL-Typ wieder herstellen*/
	}
       else
	 execute = 0;
      }
    }


   if (cmptype == 2) {
     if (MyFileReq((char *)"Load JEDEC file", (char *)".jed",YES)) {
       if (GetJedec(&path[0]))			/*Jedec-File in Struktur*/
	 execute = 0;
       if (GALType != JedecGALType) {		/*überprüfen, ob der einge-*/
	 JedecError(25,NO);			/*stellte GAL-Typ zum Jedec-*/
	 execute = 0;
	}
      }
     else
       execute = 0;
    }

  if (execute) {
    logic = acw = signature = 1;

    for (row=0; row<=MaxFuseAdr; row++) {	/*Logik-Matrizen vergleichen*/
      for (n=0; n<ROW_SIZE; n++) {
        if (Jedec.GALLogic[row+(MaxFuseAdr+1)*n] != Jedec2.GALLogic[row+(MaxFuseAdr+1)*n]) {
	  logic = 0;
         }
        if (!logic) break;
       }
      if (!logic) break;
     }

    for (n=LOGIC20_SIZE; n<sizeof(Jedec2); n++) {	/*ACW, Signatur*/
      if (Jedec.GALLogic[n] != Jedec2.GALLogic[n])
        if ((n < SIG20) || (n >= SIG20+SIG_SIZE))
          acw = 0;
        else
	  signature = 0;
     }


    if (logic && acw && signature)		/*völlig identisch?*/
      req.ReqText = &CmpIText1;
    if (!logic || !acw)				/*NICHT identisch?*/
      req.ReqText = &CmpIText2;
    if (logic && acw && !signature)		/*bis auf Sig. identisch?*/
      req.ReqText = &CmpIText3;
   }
  else
    req.ReqText = &CmpIText4;			/*Vergleich abgebrochen*/


  result = MyRequest(CONT_REQ,NULL);

  req.ReqText = &ITextW;
  if (!result)
    return;					
 
 }
}




/****************************************************************/
/* Die nachfolgenden Routinen greifen direkt über das Modul	*/
/* "port.asm" auf das GAL zu.					*/
/****************************************************************/

/* PrintACW
   gibt das Architecture Control Word aus
   Aufruf: PrintACW
*/
void PrintACW()
{
BYTE	bit;
int	n, acw_num, xor_num, ac1_num ;

 acw_num = xor_num = ac1_num =0;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Read ACW?")) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   LED(ON);					/*LED anschalten*/
   EditMode(VERIFY);				/*GAL in Edit-Mode versetzen*/
   SetRow(ACW_ADR);				/*ACW adressieren*/
   STRImpuls(VERIFY_TIME);			/*ACW in's Schiebereg. holen*/
   for (n=0; n<ACW_SIZE; n++) {			/*ACW einlesen*/
      bit=(BYTE)SDOut();
      Clock();

					/*Standard-Typ (kein A-Typ)*/
      if ((!Config.AutoAType && !Config.AType) || (Config.AutoAType && !GALAType())) {
        if (n < 32) {				/*PT0-31 eintragen*/
          PTTxt[4+acw_num]=bit+'0';
	  acw_num++;
         }
        if (n >= 50) {				/*PT32-63 eintragen*/
          PTTxt[4+acw_num]=bit+'0';
	  acw_num++;
         }
        if (n == 36) 				/*AC0-Bit*/
          ConTxt[35]=bit+'0';
        if (n == 45) 				/*SYN-Bit*/
          ConTxt[25]=bit+'0';
        if ((n >= 32) && (n <= 35)) { 		/*4 XOR-Bits*/
          ConTxt[8+xor_num]=bit+'0';
          xor_num++;
         }
        if ((n >= 46) && (n <= 49)) { 		/*4 XOR-Bits*/
          ConTxt[8+xor_num]=bit+'0';
          xor_num++;
         }
        if ((n >= 37) && (n <= 44)) {		/*AC1-Bits*/
	  AC1Txt[8+ac1_num]=bit+'0';
	  ac1_num++;
         }
       }
      else {				/*A-Typ*/
        if ((n >= 9) && (n <= 72)) {		/*PT0-63 eintragen*/
          PTTxt[4+acw_num]=bit+'0';
	  acw_num++;
         }
        if (n == 36) 				/*AC0-Bit*/
          ConTxt[35]=bit+'0';
        if (n == 77) 				/*SYN-Bit*/
          ConTxt[25]=bit+'0';
        if (n <= 3) { 				/*XOR-Bits*/
          ConTxt[8+xor_num]=bit+'0';
          xor_num++;
         }
        if (n >= 78) {	 			/*XOR-Bits*/
          ConTxt[8+xor_num]=bit+'0';
          xor_num++;
         }
        if ((n >= 5) && (n <= 8)) {		/*AC1-Bits*/
	  AC1Txt[8+ac1_num]=bit+'0';
	  ac1_num++;
         }
        if ((n >= 73) && (n <= 76)) {		/*AC1-Bits*/
	  AC1Txt[8+ac1_num]=bit+'0';
	  ac1_num++;
         }
       }
     }
   ExitEditMode();

   PrintText(&PTTxt[0],1);
   PrintText(&ConTxt[0],1);
   PrintText(&AC1Txt[0],1);
  }
}



/* PrintSignature
   gibt Signatur im Textfeld aus
   Aufruf: PrintSignature();
*/
void PrintSignature()
{
UBYTE	strn[6];
BYTE	byte;
int	n;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Read signature?")) {
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   LED(ON);					/*LED anschalten*/
   EditMode(VERIFY);				/*GAL in Edit-Mode versetzen*/
   SetRow(SigAdr);				/*Signatur adressieren*/
   STRImpuls(VERIFY_TIME);			/*Signatur in's Schiebereg. holen*/
					     /*Signatur einlesen*/
   byte = 0;
   for (n=0; n<SIG_SIZE; n++) {
     byte |= (BYTE)SDOut();			/*acht Bits zu einem Byte*/
     if (!((n+1)%8)) {				/*Text erstellen*/
       sprintf(&strn[0],"%02x",(int)byte);
       strncpy(&SignatureTxt[11+4*((n+1)/8-1)],&strn[0],2);
       if (isprint(byte))
         SignatureTxt[46+((n+1)/8-1)]=byte;
       else
         SignatureTxt[46+((n+1)/8-1)]='.';
       byte = 0;
      }
     byte<<=1;
     Clock();
    } 
   ExitEditMode();

   PrintText(&SignatureTxt[0],1);
  }
}




/* ProgJedecToGAL
   schreibt die Jedec-Struktur in das GAL
   (eigentliche Programmier-Routine)
   Aufruf:    result = ProgJedecToGAL(mode);
   Parameter: mode = COPYGAL: Aufruf erfolgt von GAL-Copy-Routine
		   = PROGGAL: Aufruf erfolgt von GAL-Programmier-Routine

   Ergebnis: 0: GAL erfolgreich programmiert
	     1: GAL wurde nicht programmiert, da es nicht leer ist
	     2: Verify ist fehlgeschlagen
*/
int ProgJedecToGAL(mode)
int mode;
{
int	n, i, row, bit;

					/*Leertest durchführen*/
 if (((mode == COPYGAL) && Config.CopyEmptyTest) || ((mode == PROGGAL) && Config.ProgEmptyTest)) {
   PrintText((UBYTE *)"executing blank test...",1);
   if (CheckGAL()) {
     PrintText((UBYTE *)" GAL is NOT empty",0);
     if (MyRequest(ERASE_REQ,(UBYTE *)"GAL is NOT empty! Clear it?"))
       EraseIt();
     else
       return(1);
    }
   else
     PrintText((UBYTE *)" o.k.",0);

  }

 PrintText((UBYTE *)"programming GAL...",1);

 LED(ON);
 EditMode(PROG);

 for (row=0; row<=MaxFuseAdr; row++) {	     /*Logik-Matrix schreiben*/
    SetRow(row);
    for (n=0; n<ROW_SIZE; n++) {
       SDIn((int)Jedec.GALLogic[row+(MaxFuseAdr+1)*n]); /*Bit an SDIn-Eingang anlegen*/
       Clock();			/*Bit in Schieberegister takten*/
      }
    SetPV(PROG);			/*P/V auf "programmieren"*/
    STRImpuls(prog_time);		/*Row (64 Bit) programmieren*/
    SetPV(VERIFY);			/*P/V wieder auf "lesen"*/
   }

 SetRow(SigAdr);			     /*Signatur schreiben*/
 for (n=0; n<SIG_SIZE; n++) {
    SDIn((int)Jedec.GALSig[n]);			/*Bit an SDIn-Eingang anlegen*/
    Clock();			/*Bit in Schieberegister takten*/
   }
 SetPV(PROG);					/*P/V auf "programmieren"*/
 STRImpuls(prog_time);				/*Daten programmieren*/
 SetPV(VERIFY);					/*P/V auf "lesen"*/


 SetRow(ACW_ADR);			    /*ACW schreiben*/
 for (n=0; n<ACW_SIZE; n++) {
					/*Standard-Typ (kein A-Typ)*/
    if ((!Config.AutoAType && !Config.AType) || (Config.AutoAType && !GALAType())) {
      if (n <= 31)				/*PT0-PT31*/
	bit = Jedec.GALPT[n];
      if ((n >= 32) && (n <= 35))		/*4 XOR-Bits*/
	bit = Jedec.GALXOR[n-32];
      if (n == 36)				/*AC0-Bit*/
	bit = Jedec.GALAC0;
      if ((n >= 37) && (n <= 44)) 		/*AC1-Bits*/
	bit = Jedec.GALAC1[n-37];
      if (n == 45) 				/*SYN-Bit*/
	bit = Jedec.GALSYN;
      if ((n >= 46) && (n <= 49))		/*4 XOR-Bits*/
	bit = Jedec.GALXOR[n-42];
      if ((n >= 50) && (n <= 81))		/*PT32-PT63*/
	bit = Jedec.GALPT[n-18];
     }
    else {				/* A-Typ */
      if (n <= 3)				/*4 XOR-Bits*/
	bit = Jedec.GALXOR[n];
      if (n == 4)				/*AC0-Bit*/
	bit = Jedec.GALAC0;
      if ((n >= 5) && (n <= 8))			/*AC1-Bits*/
	bit = Jedec.GALAC1[n-5];
      if ((n >= 9) && (n <= 72))		/*PT0-PT63*/
	bit = Jedec.GALPT[n-9];
      if ((n >= 73) && (n <= 76))		/*AC1-Bits*/
	bit = Jedec.GALAC1[n-69];
      if (n == 77)				/*SYN-Bit*/
	bit = Jedec.GALSYN;
      if (n >= 78)				/*XOR-Bits*/
	bit = Jedec.GALXOR[n-74];
     }
    SDIn((int)bit);			/*Bit an SDIn-Eingang anlegen*/
    Clock();				/*Bit in Schieberegister takten*/
   }


 SetPV(PROG);				/*P/V auf "programmieren"*/
 STRImpuls(prog_time);			/*Daten programmieren*/
 SetPV(VERIFY);				/*P/V auf "lesen"*/

 ExitEditMode();

 PrintText((UBYTE *)" o.k.",0);


						/*Verify durchführen*/
 if (((mode == COPYGAL) && Config.CopyVerify) || ((mode == PROGGAL) && Config.ProgVerify)) {
   PrintText((UBYTE *)"verifying...",1);

   for (i=0; i<sizeof(Jedec2); i++)		/*Jedec-Struktur sichern*/
     Jedec2.GALLogic[i] = Jedec.GALLogic[i];

   ReadGALToJedec();			/*GAL nach Programmierung einlesen*/

   for (row=0; row<=MaxFuseAdr; row++) {	/*Logik-Matrizen vergleichen*/
     for (n=0; n<ROW_SIZE; n++) {
       if (Jedec.GALLogic[row+(MaxFuseAdr+1)*n] != Jedec2.GALLogic[row+(MaxFuseAdr+1)*n]) {
         MyRequest(ERR_REQ,(UBYTE *)"Verify not successful!!!");
         PrintText((UBYTE *)" failed",0);
	 for (i=0; i<sizeof(Jedec2); i++)	/*Jedec-Struktur restaurieren*/
	   Jedec.GALLogic[i] = Jedec2.GALLogic[i];
	 return(2);
        }
      }
    }

   for (n=LOGIC20_SIZE; n<sizeof(Jedec2); n++)	/*ACW, Signatur,...*/
     if (Jedec.GALLogic[n] != Jedec2.GALLogic[n]) {
       MyRequest(ERR_REQ,(UBYTE *)"Verify not successful!!!");
       PrintText((UBYTE *)" failed",0);
       for (i=0; i<sizeof(Jedec2); i++)		/*Jedec-Struktur restaurieren*/
	 Jedec.GALLogic[i] = Jedec2.GALLogic[i];
       return(2);
      }

   for (i=0; i<sizeof(Jedec2); i++)	/*Jedec-Struktur restaurieren*/
      Jedec.GALLogic[i] = Jedec2.GALLogic[i];	/*wurde durch Verify überschrieben*/
   PrintText((UBYTE *)" o.k.",0);
  }

 return(0);
}



/* ReadGALToJedec
   liest das GAL in die Jedec-Struktur
   (MaxFuseAdr und SigAdr müssen initialisiert sein)
   Aufruf:  ReadGALToJedec()
*/
void ReadGALToJedec()
{
int	n, row;
BYTE	bit;

 LED(ON);
 EditMode(VERIFY);				/*GAL in Verify-Mode*/

 for (row=0; row<=MaxFuseAdr; row++) {	    /*Logik-Matrix lesen*/
    SetRow(row);				/*Adresse anlegen*/
    STRImpuls(VERIFY_TIME);		/*Bits in's Schieberegister holen*/
    for (n=0; n<ROW_SIZE; n++) {		/*seriell auslesen*/
       Jedec.GALLogic[row+(MaxFuseAdr+1)*n]=(BYTE)SDOut();	/*SDOut-Ausgang lesen*/
       Clock();					/*nächstes Bit an SDOut holen*/
      }
   }


 SetRow(SigAdr);	 		    /*Signatur auslesesn*/
 STRImpuls(VERIFY_TIME);
 for (n=0; n<SIG_SIZE; n++) {
    Jedec.GALSig[n]=(BYTE)SDOut();
    Clock();
   }
 

 SetRow(ACW_ADR);			    /*Architecture Control Word holen*/
 STRImpuls(VERIFY_TIME);			/*Bits in's Schieberegister*/
 for (n=0; n<ACW_SIZE; n++) {
    bit=(BYTE)SDOut();
    Clock();				   	/*kein A-Typ*/
    if ((!Config.AutoAType && !Config.AType) || (Config.AutoAType && !GALAType())) {
      if (n <= 31)
	Jedec.GALPT[n] = bit;
      if ((n >= 32) && (n <= 35))		/*4 XOR-Bits*/
	Jedec.GALXOR[n-32] = bit;
      if (n == 36)				/*AC0-Bit*/
	Jedec.GALAC0 = bit;
      if ((n >= 37) && (n <= 44))		/*AC1-Bits*/
	Jedec.GALAC1[n-37] = bit;
      if (n == 45) 				/*SYN-Bit*/
	Jedec.GALSYN=bit;
      if ((n >= 46) && (n <= 49))		/*4 XOR-Bits*/
	Jedec.GALXOR[n-42] = bit;
      if ((n >= 50) && (n <= 81))		/*PT32-PT63*/
	Jedec.GALPT[n-18] = bit;
     }
    else {				/* A-Typ */
      if (n <= 3)				/*4 XOR-Bits 19-16*/
	Jedec.GALXOR[n] = bit;
      if (n == 4)				/*AC0-Bit*/
	Jedec.GALAC0 = bit;
      if ((n >= 5) && (n <= 8))			/*AC1-Bits*/
	Jedec.GALAC1[n-5] = bit;
      if ((n >= 9) && (n <= 72))		/*PT0-PT63*/
	Jedec.GALPT[n-9] = bit;
      if (n == 77)				/*SYN-Bit*/
	Jedec.GALSYN = bit;
      if ((n >= 73) && (n <= 76))		/*AC1-Bits*/
	Jedec.GALAC1[n-69] = bit;
      if (n >= 78)				/*XOR-Bits*/
	Jedec.GALXOR[n-74] = bit;
     }
   }

 ExitEditMode();
}



/* Sicherungsbit setzen
    flag = 0: Aufruf von der ProgramGAL-Routine aufgrund eines
	      gesetzten "JedecSecurity"-Flags
    flag = 1: Aufruf von einer anderen Routine als der ProgramGAL-Routine
*/
void SetSecurity(flag)
int  flag;
{
int result;

 if (flag)
   result = MyRequest(GALTYPE_REQ,(UBYTE *)"Set security bit?");
 else
   result = MyRequest(CONT_REQ,(UBYTE *)"Set security bit?");

 if (result) {
   if (flag)
     if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
       return;					/*bei Fehler return*/
   LED(ON);
   EditMode(PROG);
   SetRow(SECURITY_ADR);
   SDIn(1);
   SetPV(PROG);				/*P/V-Pin auf "programmieren*/
   STRImpuls(prog_time);		/*STR-Impuls geben*/
   SetPV(VERIFY);			/*P/V wieder auf "lesen*/
   ExitEditMode();
   if (flag)
     MyRequest(INFO_REQ,(UBYTE *)"Security bit is set.");
  }
}





/* GAL löschen */
void Loeschen()
{
int result;

 if (MyRequest(GALTYPE_REQ,(UBYTE *)"Erase GAL?")){
   if (ReadGALParameter(YES))			/*GAL-Parameter holen*/
     return;					/*bei Fehler return*/
   EraseIt();
   if (Config.EraseEmptyTest) {
     PrintText("GAL is erased",1);
     PrintText("executing blank test...",1);
     result = CheckGAL();
     PrintText(" ready",0);
     if (result) {
       MyRequest(ERR_REQ,(UBYTE *)"Couldn't erase GAL!");
       return;
      }
    }
   MyRequest(INFO_REQ,(UBYTE *)"GAL is erased.");
  }
}


/*GAL löschen.
  Vor dem Aufruf sollten die GAL-Parameter eingelesen worden sein (mit
  ReadGALParameter(YES);)
*/
void EraseIt()
{
   LED(ON);
   EditMode(PROG);
   SetRow(ERASE_ADR);
   SDIn(1);
   SetPV(PROG);				/*P/V-Pin auf "programmieren"*/
   STRImpuls(BULK_TIME);		/*STR-Imputs geben*/
   SetPV(VERIFY);			/*und P/V wieder auf "lesen"*/
   ExitEditMode();
}

