/* --< 8 >---------------------------------------------------------P. S. O--
 *  FIRST UPDATE : 3. 28. 91.	All ok !
 *  LIB Ver      : 1.00
 * -------------------------------------------------------------------------
 * Fuse_su		      : 2048     [32 * 64]
 * Internal Security Fuse     : 1 	 [if Blank check OK then Security OK]
 * ==========================================================================
 * MANUFACTURER : TI
 * --------------------------------------------------------------------------
 * SYMBOL |                              |    MIN   TYP   MAX  |  UNIT
 * -------+------------------------------+---------------------+-------------
 * Vcc    | Supply voltage               |   4.50  5.00  5.50  |   V
 * Vpp    | Program voltage              |  12.50 13.00 13.50  |   V
 * Ipp    | Program current (pin 11)     |   3.2   4.0   4.8   |   V
 * Vih    | High-level input voltage     |   4.00        5.50  |   V
 * Vil    | Low_level input voltage      |               0.50  |   V
 * Tprim  | Prime program pulse duration |   0.95  1.00  1.05  |   ms
 *        | at PO                        |                     |
 * Tfinal | Final program pulse duration |   2.85       78.75  |   ms
 *        | at PO                        |                     |
 * Tvfy   | Pulse duration at PGM VERIFY |     20         400  |   us
 * Tscty  | Security pulse (pin1 and 11) |  71.25 75.00 78.75  |   ms
 * Td     | Setup and hold time          |   2.0               |   us
 * dV/dT  | Voltage ramping              |                 50  |   V/us
 *------------------------------------------------------------------------ */
declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    TI
  ;
  Devices
    dTICPAL16L8_55
    dTICPAL16R4_55
    dTICPAL16R6_55
    dTICPAL16R8_55
  ;
  chips=        
	  D7,
	  D6,
	  D5,
	  D4,
		  /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
          PGM_V,  /* [³ 1     20 ³] VCC   */
	    PA0,  /* [³ 2     19 ³] PO0   */
	    PA1,  /* [³ 3     18 ³] PO1   */
	    PA2,  /* [³ 4     17 ³] PO2   */
	    PI0,  /* [³ 5     16 ³] PO3   */
	    PI1,  /* [³ 6     15 ³] PO4	  */
	    PI2,  /* [³ 7     14 ³] PO5   */
	    PI3,  /* [³ 8     13 ³] PO6	  */
	    PI4,  /* [³ 9     12 ³] PO7	  */
	    GND,  /* [³ 10    11 ³] PGM_E */
		  /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	  PGM_E, PO7, PO6, PO5, PO4, PO3, PO2, PO1, PO0, VCC, D0, D1, D2, D3;

  $v2 = PGM_E, PGM_V;
  $v3 = VCC;
endd

  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,     12.50; /* NULL */
  @Vout 2,     12.50;				/* Vpp 13.0v set    */
  @Vout 3,      5.00;				/* Vcc  5.0v set    */
  @Out  GND, 	 @G;				/* GND on */
  @Delay 10, @Ms;

  @Out PA[0..2], @W;
  @Out PI[0..4], @W;
  @Out PO[0..7], @Z;
  @Out PGM_V,	 @W;
  @Out PGM_E,    @W;
  @Out D[0..7],  @W;

  @Out PA[0..2], @L;
  @Out PI[0..4], @L;
  @Out PGM_V,    @L;
  @Out PGM_E,    @L;
  @Out D[0..7],  @L;

  @Out  VCC, 	@O;
  @Delay 1, @Ms;
}
/* -----------------------------------------------------------------------
 * Verify function
 * ----------------------------------------------------------------------- */
int verifyf(data, option)
int data, option;
{
  int tmp;

  if     (option == 'r') @Load data;		/* Read */
  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;
  }
}
/* -----------------------------------------------------------------------
 * top
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, k, limit, flag, addr,
 	pgm_d, read_d;

  disp(option, 0);
  pgm_d = read_d = 0;
  init();

  for(i=0; i<8; i++) {
   for(j=0; j<8; j++) {
    for(k=0; k<32; k++) {
      flag = 0;
      addr = i*256 + j*32 + k;
      @Set 0, addr;				/* Address set */
      @Store pgm_d;				/* Store pgm_d from buffer */
      @Display 67, 9, addr, @d;      
      for(limit=0; limit<25; limit++) {
        @Out PA[0..2], j;			/* Product term select */
        @Out PI[0..4], k;			/* Input line select */

        if(option == 'p' && pgm_d == 1) {	/* Program              */
  	  @Out PO[0..7], @L;
	  @Out PGM_E,    @O;			/* PGM mode set     	*/
	  @Out D[i],     @H;
	  @Out PO[i],    @H;			/* Selected PO --> H	*/
	  if(flag == 0)  @Delay 1, @ms;		/* Delay 1ms 		*/
	  else           @Delay 3 * limit, @Ms;	/* Final pulse 		*/
	  @Out PO[i],    @L;			/* Selected PO --> L 	*/
	  @Out D[i],     @L;
	  @Out PGM_E,    @F;			/* PGM_E --> L 		*/
	  @Out PO[0..7], @Z;
        }
        @Out PGM_V, @O;				/* Verify mode */
        @In PO[0..7], read_d;			/* Data inport */
        @Out PGM_V, @F;
        read_d = (~read_d >> i) & 1;		/* Select PO data */

	if(option == 'p') {
	  if(flag == 1) break;
	  if(pgm_d&1 != read_d&1) {
	    if(limit == 24) @exit;		/* Program fail */
	  }
	  else 	flag = 1;
	}
	else {
	  verifyf(read_d, option);
	  break;
	}
      } /* end limit */
    }   /* end k */
   }    /* end j */
  }     /* end i */
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  init();

  disp('s', 0);
  @Out PA[0..2], 0x05;
  @Out PI[0..4], 0x14;				/* Input line select */
                    
  @Out PGM_V,   @O;				/* PGM_V --> Vpp	*/
  @Out PGM_E,   @O;
  @delay 75, @ms;
  @Out PGM_V,   @F;
  @Out PGM_E,   @F;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  if     (FUNCTION == Program) {
    top('p');					/* Program device     */
    top('v');					/* Verify device      */
  }
  else if(FUNCTION == Security) {
    security_device('s');			/* 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 ------------------------ */
 