/* ----------------------------------------------------------------P. S. O-
 *  FIRST UPDATE : Oct. 19. 1990
 *                 Dec.  7. 1990 all ok !
 *                   1. 15. 1991 all ok !
 *  LIB Ver      : 1.00
 * ------------------------------------------------------------------------
 *  EP600
 *  ALTERA=EP600/EP610  INTEL=5C060  TI=EP610
 *  20 inputs (16 fb), 16 outputs (OLMC), 24 pins (DIP)
 * ------------------------------------------------------------------------
 * Fuse_su		      : 6482     [40 * 162 others 2]
 * Internal Security Fuse     : 1        [Verify available]
 * ------------------------------------------------------------------------
 * SYMBOL |                            |    MIN   TYP   MAX  |  UNIT
 * -------+----------------------------+---------------------+-------------
 * VPP    | Programming supply voltage |  12.50 12.75 13.00  |   V
 * Vhh    | High-level control volotge |  12.50 12.75 13.00  |   V
 * VCC    | Operating supply voltage   |   4.70  5.00  5.20  |   V
 * VCC    | Programming supply voltage |   5.75  6.00  6.25  |   V
 * M      | Pulse limit count          |      -     -    25  |
 * N      | Pulse multlpller           |      3     -     -  |
 * P      | Retry limit                |      8     -     -  |
 * S      | Location count for retry   |      -     -    50  |
 * VPcnt  | Verify protect pluse count |     25     -     -  |
 * PPw    | Base program plse width    |   0.95   1.0  1.05  |   ms
 * T duty | Programming duty perlod    |      3     -     -  |   ms
 * T rise | Rise time for VPP          |      5     -    50  |   us
 * T fall | Fall time for VPP          |      5     -  2000  |   us
 * T ps1  | Setup time pin 1           |      -     2     -  |   us
 *----------------------------------------------------------------------*/

declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    ALTERA
    INTEL
    TI
  ;
  Devices
    dEP600	/* ALTERA */
    dEP610	/* ALTERA */
    dTIEP610	/* TI     */
    d5C060	/* INTEL  ok ! */
    d85C060     /* Intel  */
  ;
                /*  ΥΝΝΝΝΈΥΝΝΝΝΈ       */
  chips = PGM,  /* [³ 1     24 ³] VCC  */
          RA5,  /* [³ 2     23 ³] RA4  */
           D0,  /* [³ 3     12 ³] RA3  */
           D1,  /* [³ 4     21 ³] RA2  */
           D2,  /* [³ 5     20 ³] CA3  */
           D3,  /* [³ 6     19 ³] CA2  */
           D4,  /* [³ 7     18 ³] CA1  */
           D5,  /* [³ 8     17 ³] CA0  */
           D6,  /* [³ 9     16 ³] RA1  */
           D7,  /* [³ 10    15 ³] RA0  */
          RA6,  /* [³ 11    14 ³] NC   */
          GND,  /* [³ 12    13 ³] VPP  */
                /*  ΤΝΝΝΝΝΝΝΝΝΝΎ       */
	  VPP, NC, RA0, RA1, CA0, CA1, CA2, CA3, RA2, RA3, RA4, VCC;

  $v2 = PGM, VPP;
  $v3 = VCC;
endd

  int filter = 0xff;

  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(option)
int option;
{
  @Vout 1,     5.00;
  @Vout 2,     5.00;
  if(option == 'p')   @Vout 3, 6.00;
  else		      @Vout 3, 5.00;
  @Out  GND,  	 @G;
  @Delay 10, @Ms;

  @Out VCC,      @W;
  @Out NC,       @W;
  @Out CA[0..3], @W;
  @Out RA[0..6], @W;
  @Out D[0..7],  @Z;
  @Out PGM,	 @W;
  @Out VPP,      @W;

  @Out VCC,      @L;
  @Out NC,       @L;
  @Out CA[0..3], @L;
  @Out RA[0..6], @L;
  @Out PGM,      @H;
  @Out VPP,      @L;

  @Out VCC, 	 @O;
  @Delay 100, @Us;
  if(DEVICE == d85C060) @Raising VPP, 5.00, 12.50, 100;
  else 			@Raising VPP, 5.00, 12.75, 100;
  @Delay 100, @Us;
}
/* -----------------------------------------------------------------------
 * exit() ---> exit processing
 * ----------------------------------------------------------------------- */
int exit()
{
  if(DEVICE == d85C060) @Falling VPP, 12.50, 5.00, 100;
  else			@Falling VPP, 12.75, 5.00, 100;
  @Out VPP, @F;
  @Delay 100, @Us;
  @Out VCC, @F;
}
/* -----------------------------------------------------------------------
 * 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;

  @Set 0, address;
  @Store data;
  data = (data & 1) << 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);
}
/* -----------------------------------------------------------------------
 * Program data convert
 * ----------------------------------------------------------------------- */
int convert(i, j, read_d, point, arr_type, option)
int  i,       					/* Column addressing	*/
     j,       					/* Row addressing	*/
     read_d,					/* Read data    	*/
     point,
     arr_type,  	
     option;    				/* Option       	*/
{
  int k, pgm_d;

  pgm_d = 0;

  if(arr_type == 0)
    for(k=0; k<8; k++) pgm_d |= convert_sub((i*40)+(k*400)+j, read_d, k, option);
  else if(arr_type == 1)
    for(k=0; k<8; k++) pgm_d |= convert_sub(3200+(i*40)+(k*400)+j-64, read_d, k, option);
  else if(arr_type == 2)
    for(k=0; k<8; k++) pgm_d |= convert_sub(6400+(k*5)+point, read_d, k, option);
  else if(arr_type == 3)
    for(k=0; k<8; k++) pgm_d |= convert_sub(6440+(k*5)+point, read_d, k, option);
  else if(arr_type == 4) {
    pgm_d |= convert_sub(point, read_d, 0, option);
    filter = 0x01;
  }
  else if(arr_type == 5) {			/* Security bit */
    pgm_d = filter = 0x80;
  }
  return(pgm_d);
}
/* -----------------------------------------------------------------------
 * Sub program
 * ----------------------------------------------------------------------- */
int sub(ca, ra, option, point, arr_type)
int  ca,					/* Column Address */
     ra,					/* Row Address    */
     point,     				/* address point  */
     arr_type,					/* array type     */
     option;					/* Function type  */
{
  int 	i,
        pgm_d, read_d, final;

  read_d = pgm_d = final = 0;

  if(option == 'p' || option == 's') {		/* Program data convert */
    pgm_d = convert(ca, ra, 0, point, arr_type, option);
  }

  for(i=0; i<25; i++) {
    @Out CA[0..3], ca;				/* Column address 	*/
    @Out RA[0..6], ra;
    if(option == 'p' || option == 's') { 	/* Program byte 	*/
      @Out D[0..7], @W;				/* Data Out direction	*/
      @Out D[0..7], pgm_d;			/* Out data 		*/
      @Out PGM,     @L;				/* PGM enable		*/
      if(final == 1) @Delay 3*i, @Ms;		/* Final pulse 		*/
      else     	     @Delay 1, @Ms;	  	/* Program base pulse   */
      @Out PGM,     @H;				/* PGM disable 		*/
      @Out D[0..7], @Z;                         /* Data In direction 	*/
    }
    @Out PGM,     @O;				/* PGM on 		*/
    @In  D[0..7], read_d;			/* READ data 		*/
    @Out PGM,     @F;				/* PGM off 		*/

    if(option == 'p') {
      if(final == 1) break;			/* Program success 	*/
      if(i == 24)  @Exit;
      if((filter&pgm_d) == (filter&read_d)) final = 1;	/* Need final pulse */
    }
    else break;
  }

  if(option != 'p' && option != 's') convert(ca, ra, read_d, point, arr_type, option);
}
/* -----------------------------------------------------------------------
 * Top program
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int i, j;

  disp(option, 0);
  init(option);

  for(i=0;i<10;i++)
    for(j=0;j<40;j++)
      sub(i,j,option,0,0);

  for(i=0;i<10;i++)
    for(j=40;j<80;j++)
      sub(i,j+24,option,0,1);

  for(i=0;i<5;i++)
    sub(i+0x0a,0x28,option,i,2);

  for(i=0;i<5;i++)
    sub(i+0x0a,0x68,option,i,3);

  sub(0x0f,0x28,option,6480,4);
  sub(0x0f,0x68,option,6481,4);

  exit();
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security(option)
int option;
{
  disp('s', 0);
  init('p');

  sub(0x0f, 0x68, 's', 0, 5);

  exit();
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;

  if     (FUNCTION == Program) {		/* Program device     */
    top('p');					
    top('v');					
  }
  else if(FUNCTION == Security) {		/* Security device    */
    security();
  }
  else if(FUNCTION == Read) {           	/* Read device        */
    top('r');	
    @CheckSumOn;
  }
  else if(FUNCTION == Blank_Check) {		/* Blank check device */
    top('b');
  }
  else if(FUNCTION == Verify) {     		/* Verify device      */
    top('v');
  }
  else if(FUNCTION == Auto) {			/* Auto */
    top('b');
    top('p');
    top('v');
    security();
  }
}
/* ------------------------------- End of program ------------------------ */
    