/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : 1. 29. 1991 all ok!
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su		      : 7848   52
 * Internal Security Fuse     : 1      [Verify --> blank_check]
/* ------------------------------------------------------------------------ */
declaration
  dataunit : bit
  ;
  functions
    Program
    Read
    Verify
    Blank_Check
    Security
    Erase
    Auto
  ;
  Manufacturers
    AMD
  ;
  Devices
    PALCE26V12
  ;
/*  14 <--> 21
     7 <--> 28 */
  
		/*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = CLK,  /* [³ 1     28 ³] VCC   */
	 SDIN,  /* [³ 2     27 ³] D11   */
   EDIT:EDITH,  /* [³ 3     26 ³] D10   */
	   VP,  /* [³ 4     25 ³] D9    */
	  CSR,  /* [³ 5     24 ³] D8    */
          RSR,  /* [³ 6     23 ³] D7    */
	  NC0,  /* [³ 7     22 ³] D6    */
	   BE,  /* [³ 8     21 ³] NC4   */
	  NC1,  /* [³ 9     20 ³] D5    */
	  NC2,  /* [³ 10    19 ³] D4    */
	  PWP,  /* [³ 11    18 ³] D3    */
	   PV,  /* [³ 12    17 ³] D2    */
	  NC3,  /* [³ 13    16 ³] D1    */
	  GND,  /* [³ 14    15 ³] D0    */	  
		/*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	D0, D1, D2, D3, D4, D5, NC4, D6, D7, D8, D9, D10, D11, VCC;

  $v1 = EDIT;
  $v2 = VP, EDITH;
  $v3 = VCC;
endd

int addr[12]        = {7280,6812,6240,5564,4784,3900,3016,2236,1560, 988, 520,   0};
int lim[12]         = {  10,   9,  11,  13,  15,  17,  17,  15,  13,  11,   9,  10};
int inittable_r[12] = {   9,  18,  29,  42,  57,  74,  91, 106, 119, 130, 139, 149};
int inittable_p[12] = {   6,  14,  22,  30,  54,  70,  78,  94, 110, 126, 134, 142};

voltage VPP, VHH;

int index, disp_flag;

/* -----------------------------------------------------------------------
 * Display processing
 * ----------------------------------------------------------------------- */
int disp(option, p)
int option, p;
{
  if(disp_flag == 1) return(p);
  if(p == 0) {
    if     (option == 'p') @Display 26, index, "Programming ...";    
    else if(option == 'r') @Display 26, index, "Reading ...";      
    else if(option == 'b') @Display 26, index, "Blank checking ...";
    else if(option == 'v') @Display 26, index, "Verifying ...   ";
    else if(option == 's') @Display 26, index, "Securing ...";
    else if(option == 'e') @Display 26, index, "Eraseing ...";
  }
  else {
    if     (option == 'p') @Display 26, index, "Program OK!    ";
    else if(option == 'r') @Display 26, index, "Read OK!   ";
    else if(option == 'b') @Display 26, index, "Blank check OK!   ";
    else if(option == 'v') @Display 26, index, "Verification OK!";
    else if(option == 's') @Display 26, index, "Security OK!";
    else if(option == 'e') @Display 26, index, "Erase OK!   ";
    index ++;
  }
}
/* -----------------------------------------------------------------------
 * init() ---> inital processing
 * ----------------------------------------------------------------------- */
int enter(vol1, vol2, vol3)
voltage vol1, vol2, vol3;
{
  @Vout 1, 	vol1;
  @Vout 2,	vol2;
  @Vout 3,	vol3;				/* Vcc 5.0 V */
  @Delay 10, @Ms;

  @Out GND,	@G;

  @Out D[0..11], @Z;
  @Out VCC,      @W;
  @Out NC[0..4], @W;  
  @Out CLK,	 @W;
  @Out SDIN,	 @W;
  @Out EDIT,	 @W;
  @Out VP,	 @W;
  @Out CSR,	 @W;
  @Out RSR,	 @W;
  @Out BE,	 @W;
  @Out PWP,	 @W;
  @Out PV,	 @W;
  
  @Out VCC,      @L;
  @Out NC[0..4], @L;  
  @Out CLK,	 @L;
  @Out SDIN,	 @L;
  @Out EDIT,	 @L;
  @Out VP,	 @L;
  @Out CSR,	 @L;
  @Out RSR,	 @L;
  @Out BE,	 @L;
  @Out PWP,	 @L;
  @Out PV,	 @L;

  @Out VCC,	 @O;				/* Vcc on */
  @Delay 200, @us;
  @Out EDIT,	 @O;				/* EDIT VIHH on */
  @Delay 200, @us;
}
int exit()
{
  @Delay 200, @Us;              
  @Out EDIT, @F;
  @Delay 200, @Us;                
  @Out VCC,  @F;
}              
/* -----------------------------------------------------------------------
 * Out Clock
 * ----------------------------------------------------------------------- */
int clock()
{
  @Out CLK, @H;
  @Out CLK, @L;
}
/* -----------------------------------------------------------------------
 * Input line addressing 
 * ----------------------------------------------------------------------- */
int input_addressing(i)
int i;
{
  int j;

  @Out PV,  @H;					/* Verify MODE */
  @Out RSR, @H;					/* Input line addressing */
  @Out CSR, @L;
  for(j=0; j<6; j++) {
    if(((i>>j)&1) == 1) @Out SDIN, @H;
    else                @Out SDIN, @L;
    clock();
  }
  @Out SDIN, @L;  
}
/* -----------------------------------------------------------------------
 * Read | Verify | Blank_check device
 * ----------------------------------------------------------------------- */
int verifyf(i, j, k, data, option)
int i, j, k, data, option;
{
  int address, tmp;

  if(i < 52) {
    tmp = addr[k];
    address = tmp + j*52 + i;
  }
  else {
    address = 7800 + (i - 52) * 12 + k;
  }  
  @Display 67, 9, address, @d;    
  @Set 0, address;
  data >>= k;
  data &= 1;

  if     (option == 'r') @Load data;
  else if(option == 'v') {
    @Store tmp;
    if (tmp != data)  @Exit;
  }
  else if(option == 'b') {
    if(data != 1)     @Exit;
  }
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, k, l, m,
  	data, tmp;

  disp(option, 0);
  enter(10.5, 10.5/*null*/, 5.0);
  
  for(i=0; i<56; i++) {
    if(i < 52) m = i;
    else       m = i + 8;
    input_addressing(m);   
    @Out RSR,  @L;
    @Out CSR,  @H;
    
    l = 0;
    for(j=0; j<150; j++) {			/* initalize verification table out */
      @Out SDIN, @L;
      if((i < 52) && (j == inittable_r[l])) {
        @Out SDIN, @H;
        l++;
      }
      clock();
      @Out SDIN, @L;          
    }
    
    @Out PV, @L;

    if(i < 52) { 				/* Normal array */
      for(j=0; j<17; j++) {
        @In D[0..11], data;			/* READ data */
        clock();
	for(k=0; k<12; k++) {
	  if((j+1) > lim[k]) continue;
	  verifyf(i, j, k, data, option);
	}
      }
    }
    else {					/* ARCH array */
      @In D[0..11], data;			/* READ data */
      clock();
      for(k=0; k<12; k++) {
        verifyf(i, j, k, data, option);
      }
    }
  }

  exit();
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Program data to device
 * ----------------------------------------------------------------------- */
int program_device()
{
  int 	i, j, l, m,
  	tmp, address;

  tmp = 0;

  disp('p', 0);
  enter(10.5, 13.5, 5.0);
  
  for(i=0; i<56; i++) {
    if(i < 52) m = i;
    else       m = i + 8;
    input_addressing(m);   
    @Out RSR,  @L;
    @Out CSR,  @H;
    
    l = 0;
    for(j=0; j<150; j++) {			/* initalize verification table out */
      if(i < 52) {
        address = 7748 - j*52 + i;
      }
      else {
        if(j == inittable_p[l]) {
          address = 7800 + (i-52) * 12 + l;
          l++;
        }
      }
      @Display 67, 9, address, @d;
      @Set 0, address;
      @Store tmp;
      if(tmp == 1) @Out SDIN, @H;
      else         @Out SDIN, @L;
      clock();
      @Out SDIN, @L;
    }
    @Out EDITH,@O;
    @Out EDIT, @F;
    @Out VP,   @O;
    @Out PWP,  @H;
    @Delay 50, @Ms;
    @Out PWP,  @L;
    @Out VP,   @F;
    @Out EDIT, @O;
    @Out EDITH,@F;
  }

  exit();
  disp('p', 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int i;
             
  disp('s', 0);      
  enter(10.00, 13.5, 5.0);

  input_addressing(59);
  @Out RSR,  @L;	
  @Out CSR,  @H;
  @Out SDIN, @L;
  for(i=0; i<150; i++) {			/* initalize verification table out */
    clock();
  }
  @Out EDITH,@O;
  @Out EDIT, @F;
  @Out VP,   @O;
  @Out PWP,  @H;
  @Delay 50, @Ms;
  @Out PWP,  @L;
  @Out VP,   @F;
  @Out EDIT, @O;
  @Out EDITH,@F;
  
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('e', 1);
}
/* -----------------------------------------------------------------------
 * erase device
 * ----------------------------------------------------------------------- */
int erase_device()
{
  int i;
  
  disp('e', 0);
  enter(10.0, 14.0, 3.0);
  
/*  @Out VCC,  @O;
  @VOut 3, 3.00;
  @Delay 10, @Us;
  @Out EDIT, @O;
  @Delay 1, @Us;  */
  
  @Out EDITH,@O;
  @Out EDIT, @F;
  
  @Out PV,   @H;
  @Out RSR,  @H;
  @Out SDIN, @L;
  for(i=0; i<3; i++) clock();
  @Out SDIN, @H;
  for(i=0; i<3; i++) clock();  
  @Out SDIN, @L;
  @Out RSR,  @L;
  @Out VP,   @O;
  @Out BE,   @H;
  @Delay 990, @Ms;
  @Vout 3, 5.5;
  @Delay 3, @Us;
  @Out PWP,  @H;
  @Delay 100, @Ms;
  @Out PWP,  @L;
  @Out BE,   @L;
  @Out VP,   @F;
  @Out PV,   @L;
  exit();
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('e', 1);
}
/* -----------------------------------------------------------------------
 * ID Check
 * ----------------------------------------------------------------------- */
int ID_check()
{
  int 	i;
  int	data;

  data = 0;

  enter(10.00, 10.00/*NULL*/, 5.0);		/* VHH 10.00 V */

  input_addressing(58);
  @Out RSR,  @L;
  @Out CSR,  @H;
  @Out SDIN, @H;
  for(i=0; i<150; i++) {			/* initalize verification table out */
    clock();
  }
  @Out SDIN, @L;
  @Out PV, @L;

  @In D[8..11], data;				/* READ data */
						
  if     (data == 0x0f || data == 0) {
    VPP  = 13.50; 
    VHH  = 10.50; 
  }
  else {
    @Display 26, 6, "ID Check Fail  ";
    @Exit;
  }
  exit();
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  ID_check();					/* Check ID */

  if     (FUNCTION == Program) {
    erase_device();
    program_device();				/* Program device     */
    top('v');					/* Verify device      */
  }
  else if(FUNCTION == Security) {
    security_device();				/* Security device    */
  }
  else if(FUNCTION == Read) {   		/* Read device        */
    top('r');
    @CheckSumOn;
  }
  else if(FUNCTION == Blank_Check) top('b');	/* Blank check device */
  else if(FUNCTION == Verify)      top('v');	/* Verify device      */
  else if(FUNCTION == Auto) {
    erase_device();				/* Erase device	      */
    program_device();				/* Program device     */
    top('v');					/* Verify device      */
    security_device();	                        /* Security device    */
  }
  else if(FUNCTION == Erase) {
    erase_device();				/* Erase device       */
  }
}
/* ------------------------------- End of program ------------------------ */

  