/* ----------------------------------------------------------------P. S. O--
 *  FIRST UPDATE : 1. 10. 1991
 *                 1. 20. 1991     20ra10 vtest fail
                                   20g10  Vtest OK
 *  LIB Ver      : 1.00
 * -------------------------------------------------------------------------
 * Fuse_su       : 20G10  3990     [44 * 90 others 30]
 		   20RA10 3210     [40 * 80 others 10] 
 * ------------------------------------------------------------------------- */    
declaration
  dataunit : bit
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    CYPRESS
  ;
  Devices
    dPLDC20G10
    dPLDC20G10B
    dPLDC20RA10
  ;
                /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = VPP,  /* [³ 1     24 ³] VCC   */
           A0,  /* [³ 2     23 ³] D0    */
           A1,  /* [³ 3     12 ³] D1    */
           A2,  /* [³ 4     21 ³] D2    */
           A3,  /* [³ 5     20 ³] D3    */
           A4,  /* [³ 6     19 ³] D4    */
           A5,  /* [³ 7     18 ³] D5    */
           A6,  /* [³ 8     17 ³] D6    */
           A7,  /* [³ 9     16 ³] D7    */
           A8,  /* [³ 10    15 ³] D8    */
           A9,  /* [³ 11    14 ³] D9    */
           GND, /* [³ 12    13 ³] PGM_VF*/
                /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
       PGM_VF, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0, VCC;
       
  $v2 = VPP, PGM_VF, A9, A1, A2;
  $v3 = VCC;
endd

int d20ra10[40] = 
    {0x04, 0x05, 0x02, 0x03, 0x08, 0x09, 0x06, 0x07, 0x0c, 0x0d,
     0x0a, 0x0b, 0x10, 0x11, 0x0e, 0x0f, 0x14, 0x15, 0x12, 0x13, 
     0x18, 0x19, 0x16, 0x17, 0x1c, 0x1d, 0x1a, 0x1b, 0x20, 0x21, 
     0x1e, 0x1f, 0x24, 0x25, 0x22, 0x23, 0x28, 0x29, 0x26, 0x27};

int disp_flag, index;
/* -----------------------------------------------------------------------
 * 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 == '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!";
    index ++;
  }
}
/* -----------------------------------------------------------------------
 * init() ---> inital processing
 * ----------------------------------------------------------------------- */
int init()
{
  @Vout 1,     12.50;	/* NULL */
  @Vout 2,     12.50;	
  @Vout 3, 	5.00;
  @Delay 10, @Ms;

  @Out  GND, 	@G;

  @Out A[0..9], @W;
  @Out D[0..9], @Z;
  @Out VPP,     @W;
  @Out PGM_VF,  @W;

  @Out A[0..9], @L;
  @Out VPP,     @L;
  @Out PGM_VF,  @H;
  
  @Out  VCC, 	@O;
  @Delay 1, @Ms;  
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int verifyf(address, data, shift, option)
int address, data, shift, option;
{
  int tmp;

  @Set 0, address;
  data >>= shift;
  
  if     (option == 'r') @Load data;		/* Read data	   */
  else if(option == 'b') {			/* Blank check     */
    if(data&1 != 0)      @Exit;
  }
  else if(option == 'v') {			/* Verify check    */
    @Store tmp;
    if (tmp&1 != data&1) @Exit;
  }
}
/* -----------------------------------------------------------------------
 * putdata() --> Write data to device
 * ----------------------------------------------------------------------- */
int putdata(address, shift)
int address, shift;
{
  int data;

  data = 0;
  
  @Set 0, address;
  @Store data;
  data <<= shift;
  return(data);
}
/* -----------------------------------------------------------------------
 * convert sub program function
 * ----------------------------------------------------------------------- */
int convert_sub(address, data, shift, option)
int  address,
     data,					/* Read data    */
     shift,
     option;    				/* Option       */
{
  int pgm_d;

  @Display 67, 9, address, @d;

  if(option == 'p')  pgm_d = putdata(address, shift);
  else               verifyf(address, data, shift, option);
  return(pgm_d);
}
/* -----------------------------------------------------------------------
 * convert read
 * ----------------------------------------------------------------------- */
int convert(i, j, data, arr_type, option)
int  i, j,					/* Column & Row */
     data,					/* Read data    */
     arr_type,  				/* Array type   */
     option;    				/* Option       */
{
  int k, pgm_d;
  
  pgm_d = 0;

  if(DEVICE == dPLDC20RA10) {
    if(arr_type == 0) {				/* AND array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub(280+(k*320)-(i*40)+j, data, k, option);
    }
    else if(arr_type == 1) {			/* OE array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub((k*320)+j, data, k, option);
    }
    else if(arr_type == 2) {			/* ARCH array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub(3200+k, data, k, option);
    }
  }
  else {
    if(arr_type == 0) {				/* AND array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub((k*396)+(i*44)+44+j, data, k, option);
    }
    else if(arr_type == 1) {			/* OE array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub(k*396+j, data, k, option);
    }
    else if(arr_type == 2) {			/* ARCH array */
      for(k=0; k<10; k++) 
        pgm_d |= convert_sub(3960+k*3+(i>>1), data, k, option);
    }
  }
  
  return(pgm_d);
}
/* -----------------------------------------------------------------------
 * 10 bit data process
 * ----------------------------------------------------------------------- */
int sub(i, j, arr_type, option)
int  i, j, arr_type, option;
{
  int 	k, 
        flag, limit, 
  	read_d, pgm_d;

  read_d = flag = 0;

  if(option == 'p') {				/* Programming byte conv */
    pgm_d = convert(i, j, 0, arr_type, option);
  }

  for(limit=0; limit<5; limit++) {
    @Out A[6..9], i;				/* Product term addressing */
    if(DEVICE == dPLDC20RA10) @Out A[0..5], d20ra10[j];  /* Input line addressing */
    else                      @Out A[0..5], j;	
    if(arr_type != 0) @Out A9, @O;
    @Out VPP,     @O;    
    if(option == 'p') { 
      @Out D[0..9], @W;
      @Out D[0..9], pgm_d;
      if(flag == 0) @PinDelay PGM_VF, @O, @F, 400;
      else {
        @Out PGM_VF, @O;
        @Delay 400 * limit, @Us;		/* final program y*0.4*x ms */
        @Out PGM_VF, @F;
      }
      @Out D[0..9], @Z;
    }
    @Out PGM_VF, @L;
    @In D[0..9], read_d;

    @Out PGM_VF, @H;
    @Out VPP,    @F;
    @Out A9,     @F;
    if(option == 'p') {
      if(flag == 1) break;
      if(~read_d&0x03ff == pgm_d&0x03ff) flag = 1;
      if(limit == 4)  @Exit;			/* program fail */    
    }
    else {
      convert(i, j, ~read_d, arr_type, option);
      break;
    }
  }
}
/* -----------------------------------------------------------------------
 * Top program
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int i, j;

  disp(option, 0); 
  init();

  if(DEVICE == dPLDC20RA10) {
    for(i=0; i<7; i++)           		/* AND array */
      for(j=0; j<40; j++)
        sub(i, j, 0, option);
 
    for(j=0; j<40; j++)    			/* OE array */
      sub(0x0f, j, 1, option);

      sub(0, 0x3f, 2, option);			/* XOR array */
  }
  else {
    for(i=0; i<8; i++)           		/* AND array */
      for(j=0; j<44; j++)
        sub(i, j, 0, option);
  
    for(j=0; j<44; j++)    			/* OE array */
      sub(0x0f, j, 1, option);

    for(i=0; i<5; i+=2)    			/* ARCH array */
      sub(i, 0x3f, 2, option);
  }
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  disp('s', 0);
  init();
  
  @Out D[0..9], @W;
  @Out D[0..9], @L;
  @Out VPP,    @O;
  @Out A1,     @O;
  @Out PGM_VF, @O; 
  @Delay 50, @ms;
  @Out PGM_VF, @F;
  @Out A1,     @F;
  @Out VPP,    @F;
  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * Security verify
 * ----------------------------------------------------------------------- */
int security_verify()
{
  int data;

  init();
  @Out A1, @Z;
  @Out A2, @O;
  @In  A1, data;
  @Out A2, @F;
  
  if(data&1 != 0) @Exit;
}
/* -----------------------------------------------------------------------
 * MAIN Program
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  if     (FUNCTION == Program) {
    top('p');					/* 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) {
    top('b');					/* Blank check 		*/
    top('p');					/* Program device 	*/
    top('v');					/* Verify device	*/
    security_device();                          /* Security device 	*/
  }
}
/* ------------------------------- end of program ------------------------ */
  