/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : 2.  6. 1991 all ok!
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su		      : 2600 36
 * Internal Security Fuse     : 1
 * -------------------------------------------------------------------------- */
declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    SIGNETICS
  ;
  Devices
    dPLHS18P8A
    dPLHS18P8B
  ;
		/*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips =  C5,  /* [³ 1     20 ³] VCC   */
           C4,  /* [³ 2     19 ³] VFS   */
	   C3,  /* [³ 3     18 ³] FS    */
	   C2,  /* [³ 4     17 ³] PV    */
	   C1,  /* [³ 5     16 ³] FN    */
           C0,  /* [³ 6     15 ³] C6    */
	   R5,  /* [³ 7     14 ³] R0    */
	   R4,  /* [³ 8     13 ³] R1    */
	   R3,  /* [³ 9     12 ³] R2    */
	  GND,  /* [³ 10    11 ³] STROBE*/
		/*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	STROBE, R2, R1, R0, C6, FN, PV, FS, VFS, VCC;
	
  $v2 = FS;
  $v3 = VCC;
endd

int col[72] = { 63, 64, 65, 66, 67, 68, 69, 70, 71,
                54, 55, 56, 57, 58, 59, 60, 61, 62, 
                45, 46, 47, 48, 49, 50, 51, 52, 53, 
                36, 37, 38, 39, 40, 41, 42, 43, 44,
                27, 28, 29, 30, 31, 32, 33, 34, 35, 
                18, 19, 20, 21, 22, 23, 24, 25, 26,  
                 9, 10, 11, 12, 13, 14, 15, 16, 17,  
                 0,  1,  2,  3,  4,  5,  6,  7,  8};
                
int row[37] = {  3,  2,  1,  0,  5,  4,  9,  8, 13, 12, 
		17, 16, 21, 20, 25, 24, 29, 28, 31, 30,
		35, 34, 27, 26, 23, 22, 19, 18, 15, 14,
		11, 10,  7,  6, 33, 32, 37};

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,    17.50;
  @Vout 2,    17.50;    /* Vhh2 */
  @Vout 3,     8.75;    /* Vccp */
  @Out  GND,  	 @G;
  @Delay 10, @Ms;  

  @Out VCC,     @W;
  @Out C[0..6], @W;
  @Out R[0..5], @W; 
  @Out FS,      @W;
  @Out VFS,     @W;
  @Out STROBE,  @W;
  @Out FN,      @Z;
  @Out PV,      @W;
  
  @Out VCC,     @L;
  @Out C[0..6], @L;
  @Out R[0..5], @L; 
  @Out FS,      @L;
  @Out VFS,     @L;
  @Out STROBE,  @H;
  @Out PV,      @L;

  @Delay 1, @Ms;
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int verifyf(address, data, option)
int address, data, option;
{
  int	tmp;

  @Display 67, 9, address, @d;
  @Store tmp;

  if     (option == 'r')     @Load data;	/* Read data	   */
  else if(option == 'b') {			/* Blank check     */
    if(address > 2591) return;  
    if(data & 1 != 1)        @Exit;
  }
  else if(option == 's') {			/* Blank check     */
    if(address > 2591) return;
    if(data & 1 != 0)        @Exit;
  }
  else if(option == 'v') {			/* Verify check    */
    if ((tmp&1) != (data&1)) @Exit;
  }
  else if(option == 'p') {			/* Program verify check    */
    if ((tmp&1) != (data&1)) @Exit;
  }   
}
/* -----------------------------------------------------------------------
 * sub
 * ----------------------------------------------------------------------- */
int sub(i, j, option)
int i, j, option;
{
  int pgm_d,					/* Program data     */
      read_d;					/* Read data        */
  int tmp;

  pgm_d = read_d = 0;     
  
  if(j == 36) tmp = 2599 - (i - 72);
  else        tmp = col[i] * 36 + row[j];

  @Set 0, tmp;
  @Store pgm_d;
  
  if(j == 36) pgm_d = ~pgm_d & 1;
         
  @Out C[0..6], i;
  @Out R[0..5], j;

  @Out VCC, @O; 
  if(option == 'p' && pgm_d == 0) {
    @Out PV,    @H;
    @Out FS,    @O;
    @Out STROBE,@L;
    @Delay 10, @Us;
    @Out FS,    @F; 
    @Out STROBE,@H;
    @Out PV,    @L;
  }
  @Out STROBE, @L; 
  @In FN, read_d;
  @Out STROBE, @H;
  @Out VCC,    @F;
  
  if(j == 36) read_d = ~read_d & 1;  
  verifyf(tmp, read_d, option);
}
/* -----------------------------------------------------------------------
 * top
 * ----------------------------------------------------------------------- */
int top(option)
int option;   					/* Read, Program.. or more */
{
  int i, j;
      
  init();
  disp(option, 0);
  
  for(i=0; i<72; i++) {
    for(j=0; j<36; j++) { 
      sub(i, j, option);
    }
  }
  for(i=72; i<80; i++)
    sub(i, 36, option);
    
  disp(option, 1);  
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int read_d;
  
  disp('s', 0);

  read_d = 0;

  init();

  @Out C[0..6], 127;
  @Out R[0..5], 37;
  @Out VCC,     @O; 
  @Out PV,      @H;
  @Out VFS,     @O;
  @Out STROBE,  @L;
  @Delay 10, @Us;
  @Out VFS,     @F; 
  @Out STROBE,  @H;
  @Out PV,      @L;

  @Out C[0..6], 44;
  @Out R[0..5], 63;
  @Out STROBE,  @L; 
  @In FN, read_d;
  @Out STROBE,  @H;
  if(read_d != 1); /* @Exit; */
  @Out VCC,     @F;
  
  disp_flag = 1;
  top('s');
  disp_flag = 0;
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * MAIN Program
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;
  disp_flag = 0;

  @Set 0, 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 device */
    top('p');					/* Program device     */
    top('v');					/* Verify device      */
    security_device();	                        /* Security device    */
  }
}
/* ------------------------------- End of program ------------------------ */
  