/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : 1. 4. 1991.
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su       : 2689     [36 * 74 others 25]
 * -------------------------------------------------------------------------- */
declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security    
    Auto
  ;
  Manufacturers
    SIGNETICS
  ;
  Devices
    dPLC18V8Z
  ;
		/*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = VPP,  /* [³ 1     20 ³] VCC   */
          PGM,  /* [³ 2     19 ³] Y4    */
	  VFY,  /* [³ 3     18 ³] Y3    */
	   X5,  /* [³ 4     17 ³] Y2    */
	   X4,  /* [³ 5     16 ³] Y1    */
           X3,  /* [³ 6     15 ³] O3    */
	   X2,  /* [³ 7     14 ³] O2    */
	   X1,  /* [³ 8     13 ³] O1    */
	   X0,  /* [³ 9     12 ³] O0    */
	  GND,  /* [³ 10    11 ³] Y0    */
		/*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	Y0, O0, O1, O2, O3, Y1, Y2, Y3, Y4, VCC;

  $v2 = VPP;
  $v3 = VCC;
endd

int row[37]  = {19, 18, 15, 14, 21, 20, 13, 12, 23, 22, 
		11, 10, 25, 24,  9,  8, 27, 26,  7,  6, 
		29, 28,  5,  4, 31, 30,  3,  2, 33, 32,
		 1,  0, 17, 16, 35, 34, 45};

int col[20]  = { 6, 17, 16, 15, 14, 13, 12,  8,  7, 
		18,  9, 21, 11, 10, 23, 22, 20, 19}; 

int arch[6]  = { 5,  4,  1,  3,  2,  0};

int addr0[4] = { 2268, 1296,  972,    0};	/* normal array */
int addr1[4] = { 1944, 1620,  648,  324};

int ac_xor[24]={ 2614, 2608, 2606, 2600,  	/* arch array */
		 2615, 2609, 2607, 2601,
                 2599, 2596, 2595, 2592,	/* xor array */
		 2612, 2610, 2604, 2602,
                 2613, 2611, 2605, 2603,                 
		 2598, 2597, 2594, 2593};
		 
int filter;		 


  int index     = 6;
  int disp_flag = 0;
/* -----------------------------------------------------------------------
 * 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,     5.00;	/*      */
  @Vout 2,     5.00;    /* VPP  */
  @Vout 3,     5.00;    /* VCCP */
  @Out  GND,  	 @G;
  @Delay 10, @Ms;  

  @Out VCC,     @W;
  @Out VPP,     @W;
  @Out PGM,     @W;
  @Out VFY,     @W; 
  @Out X[0..5], @W;
  @Out Y[0..4], @W;
  @Out O[0..3], @Z;
  
  @Out VCC,     @H;
  @Out VPP,     @L;
  @Out PGM,     @H;
  @Out VFY,     @H; 
  @Out X[0..5], @L;
  @Out Y[0..4], @L;

  @Out VCC,     @O;
  @Delay 1, @Ms;
}
/* -----------------------------------------------------------------------
 * putdata() --> Write data to device
 * ----------------------------------------------------------------------- */
int putdata(address, shift)
int address, shift;
{
  int data;

  @Set 0, address;
  @Store data;
  data <<= shift;
  return(data);
}
/* -----------------------------------------------------------------------
 * 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;
  }	
}
/* -----------------------------------------------------------------------
 * 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 program data
 * ----------------------------------------------------------------------- */
int convert(i, j, data, arr_type, option)
int  i,       					/* Term group addressing */
     j,       					/* Input line addressing */
     data,					/* Read data    */
     arr_type,  				/* Array type   */
     option;    				/* Option       */
{
  int k;
  int pgm_d;

  pgm_d = 0;
  filter = 0x0f;

  if(arr_type == 0) {				/* NORMAL array */
    for(k=0; k<4; k++) {
      if(i < 9) pgm_d |= convert_sub(addr0[k] +  i    * 36 + j, data, k, option);
      else	pgm_d |= convert_sub(addr1[k] + (i-9) * 36 + j, data, k, option);
    }
  }
  else if(arr_type == 1) {			/* arch & xor array */
    for(k=0; k<4; k++) pgm_d |= convert_sub(ac_xor[i*4+k], data, k, option);
  }
  else if(arr_type == 2) {			/* config cell */
    pgm_d |= convert_sub(2616, data, 3, option);		
    filter = 0x08;
  }
  else {					/* preset * reset array */
    for(k=0; k<2; k++) pgm_d |= convert_sub(2617 + (k * 36) + j, data, k+1, option); 
    filter = 0x06;
  }
  return(pgm_d);
}
/* -----------------------------------------------------------------------
 * 1 bit(s) data process
 * ----------------------------------------------------------------------- */
int sub(i, j, arr_type, option)
int  i,       					/* Column addressing	*/
     j,     		  			/* Row addressing	*/
     arr_type,
     option;
{
  int pgm_d,					/* Program data     */
      read_d;					/* Read data        */
      
int tmp;      
      
  pgm_d = read_d = 0;     
  
  if(option == 'p') {				/* Programming byte conv */
    pgm_d = convert(i, j, 0, arr_type, option);
  }
         
  @Raising VPP, 5.0, 13.0, 100;

  @Out X[0..5], row[j];

  if(arr_type == 0)      @Out Y[0..4], col[i];
  else if(arr_type == 1) @Out Y[0..4], arch[i];
  else if(arr_type == 2) @Out Y[0..4], i;
  else if(arr_type == 3) @Out Y[0..4], i;  

  if(option == 'p') {				/* Program 4 bit	*/
    @Out O[0..3], @W;
    @Out O[0..3], ~pgm_d;
    @Out PGM,     @L;
    @Delay 10, @Ms;
    @Out PGM,     @H;
    @Out O[0..3], @Z;
  }

  @Out VFY,   @L; 
  @In O[0..3], read_d;
  @Out VFY,   @H;
  @Falling VPP, 13.0, 5.0, 100;
  @Out VPP,   @F;
  
  if(option == 'p') {
    if(pgm_d&filter != ~read_d&filter) @Exit;    
  }
  else convert(i, j, ~read_d, arr_type, option);
}
/* -----------------------------------------------------------------------
 * Top program
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int i, j, address;

  disp(option, 0);
  address = 0;
  init();

  for(i=0; i<18; i++) 				/* noraml array */
    for(j=0; j<36; j++)
      sub(i, j, 0, option);

  for(i=0; i<6; i++)				/* arch & xor array */
    sub(i, 36, 1, option);

  sub(24, 36, 2, option);  			/* config cell */
  
  for(j=0; j<36; j++)				/* preset * reset array */
    sub(24, j, 3, option);

  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int read_d;
  
  disp('s', 0);
  read_d = 0;

  init();
  
  @Raising VPP, 5.0, 13.0, 100;

  @Out X[0..5], 47;
  @Out Y[0..4], 25;

    @Out O[0..3], @W;
    @Out O[0..3], 7;
    @Out PGM,     @L;
    @Delay 10, @Ms;
    @Out PGM,     @H;
    @Out O[0..3], @Z;

  @Out VFY,   @L; 
  @In O[0..3], read_d;
  @Out VFY,   @H;
  @Falling VPP, 13.0, 5.0, 100;
  @Out VPP,   @F;
  
  if(read_d&0x80 != 0) @Exit;

  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Program
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;

  if     (FUNCTION == Program) {
    top('p');					/* Program device     */
    top('v');					/* Verify 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 device */
    top('p');					/* Program device     */
    top('v');					/* Verify device      */
    security_device();				/* Security device    */
  }
  else if(FUNCTION == Security) {
    security_device();				/* Security device    */
  }
}
/* ------------------------------- End of program ------------------------ */
 