/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : Oct.  9. 1990
 *		   Dec.  4. 1990 all ok!
 *                   1. 31. 1991 (p, r, v, b, s, e, a, v_test ok!)
 *  LIB Ver      : 1.00
 *
 *  PALCE22V10H-15 --> pin 6 & pin12(GND) 0.1uF 
 * --------------------------------------------------------------------------
 * Fuse_su		      : 5828     [44 * 132 others 20]
 * Internal Security Fuse     : 1        [Verify --> blank_check OK]
 * ------------------------------------------------------------------------ */
declaration
  dataunit : bit
  ;
  functions
    Program
    Read
    Verify
    Blank_Check
    Security
    Erase
    Auto
  ;
  Manufacturers
    AMD
  ;
  Devices
    dPALCE22V10H_15
/*  dPALCE22V10H_25
    dPALCE22V10H_15_4
    dPALCE22V10H_25_4
    dPALCE22V10Q_25
    dPALCE22V10Q_25_4
    dPALCE22V10Z_25     */
  ;
		/*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = CLK,  /* [³ 1     24 ³] VCC   */
	 SDIN,  /* [³ 2     23 ³] D9    */
	 EDIT,  /* [³ 3     12 ³] D8    */
	   VP,  /* [³ 4     21 ³] D7    */
	  CSR,  /* [³ 5     20 ³] D6    */
          RSR,  /* [³ 6     19 ³] D5    */
	   BE,  /* [³ 7     18 ³] D4    */
	  NC0,  /* [³ 8     17 ³] D3    */
	  PWP,  /* [³ 9     16 ³] D2    */
	   PV,  /* [³ 10    15 ³] D1    */
	  NC1,  /* [³ 11    14 ³] D0    */
	  GND,  /* [³ 12    13 ³] NC2   */
		/*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	NC2, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, VCC;

  $v1 = EDIT;
  $v2 = VP;
  $v3 = VCC;
endd

int addr[10]        = {5368,4884,4312,3652,2904,2156,1496, 924, 440,   0};
int lim[10]         = {  10,  11,  13,  15,  17,  17,  15,  13,  11,  10};
int inittable_r[10] = {   9,  20,  33,  48,  65,  82,  97, 110, 121, 131};
int inittable_p[10] = {   6,  14,  22,  46,  54,  70,  86, 102, 110, 126};

voltage VPP,
        VHHP,
        VHHV;

  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)
voltage vol1, vol2;
{
  @Vout 1, 	vol1;
  @Vout 2,	vol2;
  @Vout 3,	5.0;				/* Vcc 5.0 V */
  @Delay 10, @Ms;

  @Out GND,	@G;

  @Out D[0..9],	@Z;
  
  @Out VCC,     @W;
  @Out NC[0..2],@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,     @H;
  @Out NC[0..2],@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 100, @us;
  @Out EDIT,	@O;				/* EDIT VIHH on */
  @Delay 10, @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, option)
int i, option;
{
  int j;

  @Out PV,  @H;					/* Verify MODE */  
  @Out RSR, @H;					/* Input line addressing */  
  @Out CSR, @L;  

  if(i > 43)        i += 16;
  if(option == 's') i = 59;	 		/* Security addressing */
  if(option == 'i') i = 58;			/* ID addressing */

  for(j=0; j<6; j++) {
    @Out SDIN, (i >> j) & 1;
    clock();
  }  

  @Out RSR,  @L;
  @Out CSR,  @H;    
}
/* -----------------------------------------------------------------------
 * Read | Verify | Blank_check device
 * ----------------------------------------------------------------------- */
int verifyf(address, shift, data, option)
int address,
    shift,
    data,
    option;
{
  int tmp;

  @Display 67, 9, address, @d;    

  @Set 0, address;
  data >>= shift;

  if     (option == 'r') @Load data;
  else if(option == 'v') {
    @Store tmp;
    if ((tmp&1) != (data&1))  @Exit;
  }
  else if(option == 'b') {
    if((data&1) != 1)         @Exit;
  }
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, k, l,
  	data, tmp;

  disp(option, 0);
  enter(VHHV, VHHV/*NULL*/);
  
  for(i=0; i<46; i++) {
    input_addressing(i, option);   
    
    l = 0;
    for(j=0; j<132; j++) {			/* initalize verification table out */
      @Out SDIN, @L;
      if(i < 44) {
	if(j == inittable_r[l]) {
	  @Out SDIN, @H;
	  l++;
	}
      }
      clock();
      @Out SDIN, @L;
    }
    @Out PV, @L;

    if(i >= 44) {
      data = 0;
      @In D[0..9], data;			/* READ data */
      clock();
      for(j=0; j<10; j++) verifyf(5826+(i-44) - 2*j, j, data, option);
    }
    else {
      for(j=0; j<17; j++) {
        @In D[0..9], data;			/* READ data */
        clock();        
	for(k=0; k<10; k++) {
	  if(lim[k] < j+1) continue;
	  else  verifyf(addr[k] + j*44 + i, k, data, option);
	}
      }
    }
  }
  exit();
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Program data to device
 * ----------------------------------------------------------------------- */
int program_device()
{
  int 	i, j, k, l, addr,
  	tmp;

  tmp = 0;

  disp('p', 0);
  enter(VHHP, VPP);

  for(i=0; i<46; i++) {
    input_addressing(i, 'p');

    k = 0;
    for(j=0; j<132; j++) {			/* initalize verification table out */
      if(i < 44) {
        addr = 5764 - j*44 + i;
      }
      else {   
        if(j == inittable_p[k]) {
          addr =  5826 + (i-44) - 2*k;
	  k++;
        }
      }
      @Display 67, 9, addr, @d;
      @Set 0, addr;
      @Store tmp;
      @Out SDIN, tmp;
      clock();
      @Out SDIN, @L;
    }
    @Out VP,  @O;
    @Out PWP, @H;
    @Delay 40, @Ms;
    @Out PWP, @L;
    @Out VP,  @F;
  }
  disp('p', 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int i;
             
  disp('s', 0);      
  enter(VHHP, VPP);

  input_addressing(59, 's');
  @Out SDIN,@L;
  for(i=0; i<132; i++) {			/* initalize verification table out */
    clock();
  }
  @Out VP,  @O;
  @Out PWP, @H;
  @Delay 50, @Ms;
  @Out PWP, @L;
  @Out VP,  @F;
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * erase device
 * ----------------------------------------------------------------------- */
int erase_device()
{
  int i;
  
  disp('e', 0);
  enter(VHHP, VPP);
  
  @Out PV,  @H;
  @Out VP,  @O;
  @Out BE,  @H;
  @Out PWP, @H;
  @Delay 90, @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, tmp;

  data = 0;

  enter(10.00, 5.00);				/* VHH 10.00 V */

  input_addressing(58, 'i');

  for(i=0; i<132; i++) {			/* initalize verification table out */
    clock();
  }
  @Out PV, @L;

  @In D[6..9], data;				/* READ data */
						
  if     (data == 0x0f) {VPP = 13.50; VHHP = 10.50; VHHV = 10.50;} /* VPP VPP voltage */
  else if(data == 0x0c) {VPP =  9.00; VHHP =  9.00; VHHV =  8.50;} /* VHHP Program VHH */
  else if(data == 0x08) {VPP =  9.25; VHHP =  9.25; VHHV =  9.25;} /* VHHV Verify VHH */
  else if(data == 0x09) {VPP =  9.25; VHHP =  9.25; VHHV =  9.25;} 
  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 ------------------------ */
  