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



#include "exec/types.h"
#include <ctype.h>

#include "GALer.h"


extern	UBYTE	GadgetSBuff[60];
extern	int	GALType;
extern	struct	JedecStruct	Jedec;


int	MaxFuseAdr, SigAdr;


UBYTE	SignatureTxt[] = {"Signatur: $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"};


/*ProgramGAL
  liest Jedec-Datei ein, testet das GAL auf Programmierbarkeit und
  programmiert es anschließend entsprechend der Jedec-Datei
  Aufruf: ProgramGAL();
*/
ProgramGAL()
{
 if (MyRequest(LOAD_REQ,(UBYTE *)"Bitte Namen des Jedec-Files eingeben")) {
   if (!(GetJedec(&GadgetSBuff))) {
     if (MyRequest(ASK_REQ,(UBYTE *)"Bitte GAL einsetzen")) {
        ProgJedecToGAL();
        MyRequest(INFO_REQ,(UBYTE *)"GAL wurde programmiert");
      }
    }
  }
}


/* GAL kopieren
*/
CopyGAL()
{
 if (MyRequest(ASK_REQ,(UBYTE *)"Bitte Original-GAL einsetzen")) {
   ReadGALToJedec();
   if (MyRequest(ASK_REQ,(UBYTE *)"Bitte Ziel-GAL einsetzen")) {
     ProgJedecToGAL();
     MyRequest(INFO_REQ,(UBYTE *)"GAL wurde kopiert");
    }
  }
}



/* überprüfe, ob GAL leer ist*/
Leertest()
{
 if (MyRequest(ASK_REQ,(UBYTE *)"Bitte GAL zum Leertest einsetzen")) {
   if (CheckGAL())
     MyRequest(INFO_REQ,(UBYTE *)"GAL ist leer");
   else
     MyRequest(INFO_REQ,(UBYTE *)"GAL ist NICHT leer");
  }
}



/* CheckGAL
   teste ob GAL leer ist
   Aufruf:   return=CheckGAL();
   Ergebnis: return: 1=GAL ist leer; 0=GAL ist nicht leer
*/
CheckGAL()
{
int n;
 ReadGALToJedec();
 for (n=0; n<sizeof(Jedec); n++) {
   if (((GALType == GAL16V8) && ((n < LOGIC16_SIZE) || (n >= LOGIC20_SIZE))) || (GALType == GAL20V8)) {
     if (!Jedec.GALLogic[n])
       return(0);
    }
  }
 return(1);
}



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

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

 acw_num = xor_num = ac1_num =0;

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

      if (n<32) {				/*ACW0-31 eintragen*/
        PTTxt[4+acw_num]=bit+'0';
	acw_num++;
       }
      if (n>=50) {				/*ACW32-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++;
       }
     }
   InitGALer();
   EnableOutput();

   PrintText(&PTTxt);
   PrintText(&ConTxt);
   PrintText(&AC1Txt);
  }
}



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

 if (MyRequest(ASK_REQ,(UBYTE *)"Signatur lesen?")) {
   LED(ON);					/*LED anschalten*/
   EditMode(VERIFY);				/*GAL in Edit-Mode versetzen*/
   SetRow(SigAdr);				/*Signatur adressieren*/
   STRImpuls();					/*Signatur in's Schiebereg. holen*/
					     /*Signatur einlesen*/
   for (n=0; n<SIG_SIZE; n++) {
     bit=(BYTE)SDOut();				/*Bit holen und 8 Bits*/
     byte|=bit;					/*zu einem Byte zusammenfügen*/
     if (!((n+1)%8)) {				/*Text erstellen*/
       sprintf(&strn,"%02x",(int)byte);
       strncpy(&SignatureTxt[11+4*((n+1)/8-1)],&strn,2);
       if (isprint(byte))
         SignatureTxt[46+((n+1)/8-1)]=byte;
       else
         SignatureTxt[46+((n+1)/8-1)]='.';
      }
     byte<<=1;
     Clock();
    } 
   InitGALer();
   EnableOutput();

   PrintText(&SignatureTxt);
  }
}




/* ProgJedecToGAL
   schreibt die Jedec-Struktur in das GAL
   (eigentliche Programmier-Routine)
*/
ProgJedecToGAL()
{
int	n, row, bit;


 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*/
      }
    STRImpuls();				/*Row (64 Bit) programmieren*/
   }

 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*/
   }
 STRImpuls();					/*Daten programmieren*/


 SetRow(ACW_ADR);			    /*ACW schreiben*/
 for (n=0; n<ACW_SIZE; n++) {
    if (n<=31)
      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];
    SDIn((int)bit);				/*Bit an SDIn-Eingang anlegen*/
    Clock();			/*Bit in Schieberegister takten*/
   }

 STRImpuls();				/*Daten programmieren*/

 InitGALer();
 EnableOutput();
}


/* ReadGALToJedec
   liest das GAL in die Jedec-Struktur
   (MaxFuseAdr und SigAdr müssen initialisiert sein)
   Aufruf:   ReadGALToJedec()
*/
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();				/*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();
 for (n=0; n<SIG_SIZE; n++) {
    Jedec.GALSig[n]=(BYTE)SDOut();
    Clock();
   }
 

 SetRow(ACW_ADR);			    /*Architecture Control Word holen*/
 STRImpuls();					/*Bits in's Schieberegister*/
 for (n=0; n<ACW_SIZE; n++) {
    bit=(BYTE)SDOut();
    Clock();
    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;
   }

 InitGALer();					/*alle Ausgänge auf LOW*/
 EnableOutput();
}



/* Sicherungsbit setzen*/
SetSecurity()
{
 if (MyRequest(ASK_REQ,(UBYTE *)"Security-Bit setzen?")){
   LED(ON);
   EditMode(PROG);
   SetRow(SECURITY_ADR);
   SDIn(1);
   Clock();
   STRImpuls();
   InitGALer();
   EnableOutput();
   MyRequest(INFO_REQ,(UBYTE *)"Security-Bit wurde gesetzt.");
  }
}





/* GAL löschen */
Loeschen()
{
 if (MyRequest(ASK_REQ,(UBYTE *)"GAL löschen")){
   LED(ON);
   EditMode(PROG);
   SetRow(ERASE_ADR);
   SDIn(1);
   Clock();
   STRImpuls();
   InitGALer();
   EnableOutput();
   MyRequest(INFO_REQ,(UBYTE *)"GAL wurde gelöscht.");
  }
}

