/*********************************************************************
   SIGNETICS       : 82HS321
   Fuse enable pin : CE_
   Vccp            = 5 V
   Data out volt   = 12.75 V
   Delay time      = 100 Us
   Date		   : 12. 19. 1990
   Last Modify date:  2. 26. 1991
   Author	   : E. Y. Lee
**********************************************************************/
declaration
  dataunit : byte;
  functions
    Program
    Read
    Verify
    Blank_check
    Data_compare
    Auto
    Encryption
    Security
  ;
  Manufacturers
    SIGNETICS
  ;
  Devices
    D87C751
  ;
  chips = Vpp, NC0, A7, A6, A5, A4, A3, 
          A2:A10,
          A1:A9,
          A0:A8,
          Q0, Q1, Q2, GND,
          Q3, Q4, Q5, Q6, Q7, ASEL, NC1, NC2, NC3, NC4, NC5, NC6, PGM, Vcc
  ;
  $v2 = Vpp;
  $v3 = Vcc;
endd
char  ExternArray [16];

/* ----------------------------------------------------------------------  */
int  init( vol1, vol2, vol3 )
voltage vol1, vol2, vol3;
{
  @Vout  1, vol1;
  @Vout  2, vol2;
  @Vout  3, vol3;
  @Out  GND,  @G;
  @Delay 10,  @Ms;

  @Out  Q[0..7], @Z;
  @Out  A[0..7], @W;
  @Out  NC[0..6],@W;
  @Out  ASEL,	 @W;
  @Out  PGM,	 @W;
  @Out  Vpp,	 @W;
  @Out  Vcc,	 @W;
  
  @Out	Vpp,	 @H;
  @Out  ASEL,	 @L;
  @Out  A[0..7], @L;
  @Out  NC[0..6],@L;
  @Out  PGM,     @H;
  @Out  Vcc,	 @L;
  @Out  Vcc,     @O;
  @Delay 100,	 @Us;
}
/* ---------------------------------------------------------------------- */
int  Failf ( hwhb, hwlb, lwhb, lwlb, data )
int  hwhb, hwlb, lwhb, lwlb, data;
{
  int  high, low;

  high = ( hwhb << 8) | hwlb;
  low  = ( lwhb << 8) | lwlb;
  @Fail  high, low, data;
}
/* ---------------------------------------------------------------------- */
int  read(option)
int  option;
{
  int  i, j;
  int  tmp, tmp2, tmp3;
  int  saddr, eaddr, Modep;

  if( ExternMode == 1)  {
     for( i=0; i<16;i++)   {
       @ExtStore  tmp;
       ExternArray [ i] = tmp;
       @ExtInc 1;
     }
  }
    
  @Set  B_HADDR,  B_LADDR;
  init(5.0, 5.0, 5.0);
  tmp = tmp2 = 0;
  
  @Out   Vpp,  @H;
  @Out   PGM,  @H;
  @Out   ASEL, @L;
  @Delay 50,   @Ms;
  @Out   A0,   @H;
  @Out   A1,   @H;
  @Out   A2,   @L;
  @Out   Vpp,  @L;
  @Delay 50,   @Ms;
  @Out   Vpp,  @H;
  @Delay 100,  @Ms;
/*  @Out   A0,   @L;
  @Out   A1,   @L;  */

  for(i=S_LWHB;i<=E_LWHB;i++)
  {
    @Display  68, 9,   i;
    if( i == S_LWHB )  saddr = S_LWLB;
    else		saddr = 0;
    if( i == E_LWHB )  eaddr = E_LWLB;
    else		eaddr = 0xff;    
    for(j=saddr; j<=eaddr;j++)
    {
    @Out      ASEL,     @H;
    @Out      A[0..2],  i;

    @Out      ASEL,     @L;

       @Out  A[0..7],   j;
       @In   Q[0..7], tmp;
       
       if( ExternMode == 1 )   {
           tmp = tmp !^ ExternArray [ Modep ];
           if( Modep >= 16 )  Modep = 0;
           else		      ++Modep;
       }
       
       if( option == 1 )      @Load tmp;
       else if(option == 4)   {
           @Store  tmp2;
           @Compare tmp, tmp2;
       }
       else if(option == 3)
       {
	   if( tmp != 0xff)      Failf(0, 0, i, j, tmp );
       }
       else if(option == 2 )
       {
	   @Store  tmp2;
	   if( tmp != tmp2 )     Failf( 0, 0, i, j, tmp );
       }
       @Inc  SPLIT;
    }
  }
}
/* ---------------------------------------------------------------------- */
int  program()
{
  int   i, j, k;
  int   tmp, tmp2, failcnt;
  int   saddr, eaddr;

  failcnt = 0;
  tmp = tmp2 = 0;
  @Set  B_HADDR, B_LADDR;
  init( 5.0, 12.75, 5.0 );
  
  @Out  Vpp,   @H;
  @Out  PGM,   @H;
  @Out  ASEL,  @L;
  @Delay 50,   @Ms;
  @Out  A0,    @H;
  @Out  A1,    @H;
  @Out  A2,    @L;
  @Out  Vpp,   @L;
  @Delay 50,   @Ms;
  @Out  Vpp,   @H;
  @Delay 100,  @Ms;
  @Out  A0,    @L;
  @Out  A1,    @L;
  
  for(i=S_LWHB;i<=E_LWHB;i++)
  {
       @Display  68, 9, i;
       @Out  A[8..10],   i;
       @Out  ASEL,      @H;       
       @Out  ASEL,	@L;
       @Out  A0,	@L;
       @Out  A1,	@L;
       @Out  A2,	@L;
       if( i == S_LWHB )  saddr = S_LWLB;
       else		saddr = 0;
       if( i == E_LWHB )  eaddr = E_LWLB;
       else		eaddr = 0xff;       
       
       for(j=saddr;j<=eaddr;j++)
       {
	  @Out  A[0..7],    j;
	  
	  @Out  Q[0..7],   @W;
	  @Store  tmp;
	  @Out  Q[0..7],   tmp;
	  
	  @Out  Vpp,       @O;
	  for(k=0;k<25;k++)
	  {
	      @Out  PGM,   @L;
	      @Delay 100,  @Us;
	      @Out  PGM,   @H;
	      @Delay  10,  @Us;
	  }
	  @Out  Vpp,	   @F;
	  	  
	  @Out  Q[0..7],  @Z;
	  @In   Q[0..7],  tmp2;
	  if( tmp != tmp2 )
	  {
	      if( failcnt > LOP )	Failf( 0, 0, i, j, tmp2);
	      else			failcnt ++;
	      j -= 1;
	  }
	  else	  
	  {   failcnt = 0;
	      @Inc  SPLIT;
	  }
       }  /* for j */
     }  /* for i */
}
/* --------------------------------------------------------------------- */ 
int  encryp()
{
  int i, j, failcnt;
  int tmp, tmp2;
  
  failcnt = 0;
  tmp = tmp2 = 0;
  @Set  B_HADDR, B_LADDR;
  init( 5.0, 12.75, 5.0 );
  
  @Out  Vpp,	@H;
  @Out  PGM,	@H;
  @Out  ASEL,	@L;
  @Delay 50,    @Ms;
  @Out   A0,	@H;
  @Out   A1,    @L;
  @Out   A2,	@L;
  @Out   Vpp,	@L;
  @Delay 50,	@Ms;
  @Out   Vpp,	@H;
  @Delay 100,	@Ms;
  
  for(i=0;i<16;i++)
  {
     @Display 70, 9, i;                     
     @Out  A[0..2],@L;
     @Out  ASEL,@H;
     @Out  ASEL,@L;    

     @Out  A[0..7], i;

     @Out  Q[0..7], @W;
     @ExtStore  tmp;		
     @Out  Q[0..7], tmp;
     @Out  Vpp,	@O;
     for(j=0;j<25;j++)
     {
       @Out  PGM,  @L;
       @Delay 100, @Us;
       @Out  PGM,  @H;
       @Delay 10,  @Us;
     }
     @Out  Vpp,	@F;
/*     
     @Out  Q[0..7], @Z;
     @In   Q[0..7], tmp2;
     if( tmp != tmp2)     
     {
         if( failcnt > 25)	Failf( 0, 0, 0, i, tmp2);
         else		        failcnt ++;
         i -= 1;
     }
*/     
     @ExtInc  SPLIT;	
  }
}
/* --------------------------------------------------------------------- */           
int  securi()
{
  int  i;
  
  init( 5.0, 12.75, 5.0 );
  @Out  PGM,	@H;
  @Out  ASEL,	@L;
  @Delay 50,	@Ms;
  @Out 	A0,	@L;
  @Out  A1,	@L;
  @Out  A2,	@H;
  @Out  Vpp,	@L;
  @Delay 50,	@Ms;
  @Out  Vpp,	@H;
  @Delay 100,	@Ms;
  @Out  A2,	@L;
  @Out  Vpp,	@O;
  for(i=0;i<25;i++)
  {
    @Out PGM,	@L;
    @Delay 100, @Us;
    @Out PGM,	@H;
    @Delay 10,	@Us;
  }
  @Out Vpp,	@F;
  
  @Delay 10, 	@Us;
  read(3);
}  
/* --------------------------------------------------------------------- */
int  main()
{

  if( FUNCTION == Read)	     {
  	@Display 26, 6, "Reading...";
  	read(1);
  	@Display 26, 6, "Read OK!  ";
  	@CheckSumOn;
  }
  else if( FUNCTION == Program)	 {
  	@Display 26, 6, "Programming...";
  	program();
  	@Display 26, 6, "Program OK!   ";
  	@Display 26, 7, "Verifying...";
  	read(2);
  	@Display 26, 7, "Verification OK!";
  }  	
  else if( FUNCTION == Verify)	 {
  	@Display 26, 6, "Verifying...";
  	read(2);
  	@Display 26, 6, "Verification OK!";
  }
  else if( FUNCTION == Blank_check)  {
  	@Display 26, 6, "Blank checking...";
  	read(3);
  	@Display 26, 6, "Blank check OK!  ";
  }
  else if( FUNCTION == Data_compare)  {
  	@Display 26, 6, "Data comparing...";
  	read(4);
  	@Display 26, 6, "Data comparison OK!";
  }
  else if( FUNCTION == Auto)     {
	@Display 26, 6, "Blank checking...";  
  	read(3);
  	@Display 26, 6, "Blank check OK!  ";
  	@Display 26, 7, "Programming...";
  	program();
  	@Display 26, 7, "Program OK!   ";
  	@Display 26, 8, "Verifying...";
  	read(2);
  	@Display 26, 8, "Verification OK!";
  }
  else if( FUNCTION == Encryption)   {
        @Display 26, 6, "Encryption...";
        encryp();
        @Display 26, 6, "Encryption OK!";
  }
  else if( FUNCTION == Security )     {
        @Display 26, 6, "Security...";
        securi();
        @Display 26, 6, "Security OK!";
        @Display 26, 7, "Verifying...";
        read(3);
        @Display 26, 7, "Verification OK!";        
  }
} 
/* --------------------------------------------------------------------- */