/* --< 9 >---------------------------------------------------------P. S. O--
 *  FIRST UPDATE : 3. 28. 91.	All ok !
 *  LIB Ver      : 1.00
 * -------------------------------------------------------------------------
 * Fuse_su		      : 512     [32 * 16]
 * Internal Security Fuse     : 1
 *------------------------------------------------------------------------ */
declaration
  dataunit : bit 
  ;
  functions
    Program
    Read    
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    TI
  ;
  Devices
    dTIBPAD16N8_7
  ;
		  /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = PGM_V,  /* [³ 1     20 ³] VCC/VCCP */
	    PI0,  /* [³ 2     19 ³] PO0   */
	    PI1,  /* [³ 3     18 ³] PO1   */
	    PI2,  /* [³ 4     17 ³] PO2   */
	    PI3,  /* [³ 5     16 ³] PO3   */
	    PA0,  /* [³ 6     15 ³] PO4	  */
	    PA1,  /* [³ 7     14 ³] PO5   */
	    PA2,  /* [³ 8     13 ³] PO6	  */
	  PGM_E,  /* [³ 9     12 ³] PO7	  */
	    GND,  /* [³ 10    11 ³] OE    */
		  /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	     OE, PO7, PO6, PO5, PO4, PO3, PO2, PO1, PO0, VCC:VCCP;

  $v1 = VCCP;
  $v2 = PI, PA0, PGM_E, PO;
  $v3 = VCC;
endd

int pi[128] =
  {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
   0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,
   0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,
   0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1};

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,      9.75;				/* NULL */
  @Vout 2,     10.50;				/* Vihh 10.5v set */
  @Vout 3,      5.50;				/* Vcc  5v set    */
  @Out  GND, 	 @G;				/* GND on */
  @Delay 10, @Ms;

  @Out PI[0..3], @W;
  @Out PA[0..2], @W;
  @Out PO[0..7], @Z;
  @Out PGM_V,	 @W;
  @Out PGM_E,    @W;
  @Out OE,       @W;

  @Out PI[0..3], @L;
  @Out PA[0..2], @L;
  @Out PGM_V,    @L;
  @Out PGM_E,    @L;
  @Out OE,       @L;

  @Out  VCC,     @O;
  @Delay 100, @Us;
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int verifyf(i, j, data, option)
int i, j, data, option;
{
  int k, tmp, read_d;
  
  read_d = 0;

  for(k=0; k<8; k++) {
    tmp = k*64+i*32+j;
    @Set 0, tmp;
    @Display 67, 9, tmp, @d;
    
    read_d = (data >> k) & 1;

    if     (option == 'r') @Load read_d;	/* Read data	   */
    else if(option == 'b') {			/* Blank check     */
      if(read_d != 0)      @Exit;
    }
    else if(option == 'v') {			/* Verify check    */
      @Store tmp;
      if (read_d != tmp & 1) @Exit;
    }
  }
}
/* -----------------------------------------------------------------------
 * top
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, k, limit, addr, tmp,
  	pgm_d, read_d;

  disp(option, 0);
  addr = pgm_d = read_d = 0;
  init();

  for(i=0; i<2; i++) {
   for(j=0; j<32; j++) {
    @Out PGM_E,    @O;				/* PGM mode set */
    @Out PA[0..2], i;
    for(k=0; k<4; k++) {
      tmp = k * 32 + j;
      if     (pi[tmp] == 0)   @Out PI[k], @L;
      else if(pi[tmp] == 1)   @Out PI[k], @H;
      else if(pi[tmp] == 2)   @Out PI[k], @O;
    }
        
    @Out PGM_V, @H; @Out PGM_V, @L;		/* Verify clock */
    @Delay 150, @Us;
    @In  PO[0..7], read_d;
     
    for(k=0; k<4; k++) @Out PI[k], @F;
    @Out PGM_E,    @F;

    verifyf(i, j, ~read_d, option);
   }
  }
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Program
 * ----------------------------------------------------------------------- */
int program()
{
  int 	i, j, k, limit, addr, tmp,
  	pgm_d, read_d;

  disp('p', 0);
  addr = pgm_d = read_d = 0;
  init();

  for(i=0; i<16; i++) {
   for(j=0; j<32; j++) {
    @Set 0, addr;
    @Display 67, 9, addr, @d;
    addr++;
    @Store pgm_d;
    if(pgm_d != 1) continue;
    
    for(limit=0; limit<10; limit++) {
      @Out PGM_E, @O;				/* PGM mode set */
      @Out PA[0..2], i%2;
      for(k=0; k<4; k++) {
        tmp = k * 32 + j;
        if     (pi[tmp] == 0)   @Out PI[k], @L;
        else if(pi[tmp] == 1)   @Out PI[k], @H;
        else if(pi[tmp] == 2)   @Out PI[k], @O;
      }
        
	@Out OE,      @H;			/* OE --> H 		*/
	@Out PO[i/2], @O;			/* Selected PO --> Vihh */
	@Out VCCP,    @O;
	@PinDelay VCC, @F, @O, 30;		/* 50 us pulse 		*/
	@Out VCCP,    @F;
	@Out PO[i/2], @F;
	@Out OE,      @L;			/* OE --> L 		*/

      @Out PGM_V, @H; @Out PGM_V, @L;		/* Verify clock */
      @Delay 150, @Us;
      @In  PO[0..7], read_d;
      read_d >>= i/2;
      read_d = ~read_d & 1;
      
      for(k=0; k<4; k++) @Out PI[k], @F;
      @Out PGM_E,    @F;

      if(pgm_d == read_d) break;
      if(limit == 8) @Exit;
    }	/* limit */
   }
  }
  
  disp('p', 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  disp('s', 0);
  init();

  @Out PGM_E,    @O;				/* PGM mode set */
  @Out PI[0..3], @H;
  @Out PI[2],    @O;
  @Out PA0,      @O;

	@Out OE,      @H;			/* OE --> H 		*/
	@Out VCCP,    @O;
	@PinDelay VCC, @F, @O, 50;		/* 50 us pulse 		*/
	@Out VCCP,    @F;
	@Out OE,      @L;			/* OE --> L 		*/

  @Out PA0,      @F;
  @Out PI[2],    @F;
  @Out PGM_E,    @F;

  disp_flag = 1;
  top('b');
  disp_flag = 0;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  if     (FUNCTION == Program) {
    program();					/* 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        */
    program();					/* Program device     */
    top('v');					/* Verify device      */
    top('s');		                        /* Security device    */
  }
}
/* ------------------------------- End of program ------------------------ */
 