/* ----------------------------------------------------------------P. S. O---
 *  FIRST UPDATE : 1. 22. 91
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su		      : 2560     [40 * 64]
 * Internal Security Fuse     : 1
 * ----------------------------------------------------------------------- */
declaration
  dataunit : bit
  ;
  functions
    Program
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    AMD__MMI
    NS
  ;
  Devices
/* ---------- AMD/MMI ------------- */
    dPAL12L10		/* 00 */
    dPAL14L8            /* 01 */
    dPAL16L6            /* 02 */
    dPAL18L4            /* 03 */
    dPAL20L2            /* 04 */
    dPAL20C1            /* 05 */
    dPAL20L10           /* 06 */
    dPAL20L10A          /* 07 */
    dPAL20X10           /* 08 */
    dPAL20X10A          /* 09 */
    dPAL20X4            /* 10 */
    dPAL20X4A           /* 11 */
    dPAL20X8            /* 12 */
    dPAL20X8A           /* 13 */
    dPAL20L8_10         /* 14 */
    dPAL20L8_12         /* 15 */
    dPAL20L8A           /* 16 */
    dPAL20L8A_2         /* 17 */
    dPAL20L8B           /* 18 */
    dPAL20L8B_2         /* 19 */
    dPAL20R4_10         /* 20 */
    dPAL20R4_12         /* 21 */
    dPAL20R4A           /* 22 */
    dPAL20R4A_2         /* 23 */
    dPAL20R4B           /* 24 */
    dPAL20R4B_2         /* 25 */
    dPAL20R6_10         /* 26 */
    dPAL20R6_12         /* 27 */
    dPAL20R6A           /* 28 */
    dPAL20R6A_2         /* 29 */
    dPAL20R6B           /* 30 */
    dPAL20R6B_2         /* 31 */
    dPAL20R8_10         /* 32 */
    dPAL20R8_12         /* 33 */
    dPAL20R8A           /* 34 */
    dPAL20R8A_2         /* 35 */
    dPAL20R8B           /* 36 */
    dPAL20R8B_2         /* 37 */

    dPAL20RA10          /* 38 */

/* --------- NS ---------- */
/*  dPAL12L10            * 00 */
    dPAL12L10A          /* 39 */
/*  dPAL14L8             * 00 */
    dPAL14L8A           /* 40 */
/*  dPAL16L6             * 00 */
    dPAL16L6A           /* 41 */
/*  dPAL18L4             * 00 */
    dPAL18L4A           /* 42 */
/*  dPAL20L2             * 00 */
    dPAL20L2A           /* 43 */
/*  dPAL20C1             * 00 */
    dPAL20C1A           /* 44 */
/*  dPAL20L10            * 00 */
/*  dPAL20L10A           * 00 */
/*  dPAL20X4             * 00 */
/*  dPAL20X4A            * 00 */
/*  dPAL20X8             * 00 */
/*  dPAL20X8A            * 00 */
/*  dPAL20X10            * 00 */
/*  dPAL20X10A           * 00 */
    dPAL20L8            /* 45 */
/*  dPAL20L8A            * 00 */
/*  dPAL20L8B            * 00 */
    dPAL20R4            /* 46 */
/*  dPAL20R4A            * 00 */
/*  dPAL20R4B            * 00 */
    dPAL20R6            /* 47 */
/*  dPAL20R6A            * 00 */
/*  dPAL20R6B            * 00 */
    dPAL20R8            /* 48 */
/*  dPAL20R8A            * 00 */
/*  dPAL20R8B            * 00 */

/*  dPAL20RA10           * 00 */
  ;
			/*  ΥΝΝΝΝΈΥΝΝΝΝΈ        	*/
  chips = OD:_CLOCK,    /* [³ 1     24 ³] VCC  : VCCP 	*/
	    I0,  	/* [³ 2     23 ³] O0   : _L_R	*/
	    I1,  	/* [³ 3     22 ³] O1   : _A0  	*/
	    I2,  	/* [³ 4     21 ³] O2   : _A1  	*/
	    I3,  	/* [³ 5     20 ³] O3   : _A2  	*/
	    I4,  	/* [³ 6     19 ³] O4   : NC1 	*/
	    I5,  	/* [³ 7     18 ³] NC0  : _O0  	*/
	    I6,  	/* [³ 8     17 ³] A2   : _O1  	*/
	    I7,  	/* [³ 9     16 ³] A1   : _O2  	*/
	    I8,  	/* [³ 10    15 ³] A0   : _O3  	*/
	    I9,  	/* [³ 11    14 ³] L_R  : _O4 	*/
	    GND,  	/* [³ 12    13 ³] CLOCK: _OD 	*/
			/*  ΤΝΝΝΝΝΝΝΝΝΝΎ        	*/
	  CLOCK: _OD,
	  L_R  : _O4,
	  A0   : _O3,
	  A1   : _O2,
	  A2   : _O1,
	  NC0  : _O0,
	  O4   : NC1,
	  O3   : _A2,	  
	  O2   : _A1,
	  O1   : _A0,
	  O0   : _L_R,
	  VCC  : VCCP;


  $v1 = CLOCK, _CLOCK, VCCP;
  $v2 =  I,
         A,
         A0, A1, A2, 
         O,
         O0, O1, O2, O3, O4,
         L_R,  
         OD,
        _A,
        _A0, _A1, _A2,
        _O,
        _O0, _O1, _O2, _O3, _O4,
	_L_R,
	_OD;
  $v3 = VCC;

endd


char type[49] = {0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 
		 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 
		 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
		 5, 5, 5, 5, 5, 5, 5, 5, 6, 0, 		 
		 1, 2, 2, 3, 3, 5, 5, 5, 5};

char type_inp[35] = 
   {0x3f,0x33,0x33,0x33,0xf3,	/* 12L10                    0 */
    0xff,0x33,0x33,0x33,0xff,   /* 14L8                     1 */
    0xff,0x3f,0x33,0xf3,0xff,   /* 16L6, 18L4               2 */
    0xff,0xff,0xff,0xff,0xff,   /* 20C1, 20L2               3 */
    0xff,0xff,0xff,0xff,0xff,   /* 20L10, 20X10, 20X4, 20X8 4 */
    0xff,0xff,0xff,0xff,0xff,   /* 20L8			    5 */
    0xff,0xff,0xff,0xff,0xff};  /* 20RA10		    6 */
char type_prod[70] =
   {0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
    0x00,0x0f,0x03,0x03,0x03,0x03,0x03,0x03,0x0f,0x00,
    0x00,0x00,0x0f,0x0f,0x03,0x03,0x0f,0x0f,0x00,0x00,
    0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,
    0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
    0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};


  int LOGIC, TYPE;

  int index, disp_flag;
/* -----------------------------------------------------------------------
 * 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()

{
  voltage VIHH;

  if     (MFG == AMD__MMI) {
    if(DEVICE == dPAL20L8_12 ||
       DEVICE == dPAL20R4_12 ||
       DEVICE == dPAL20R6_12 ||
       DEVICE == dPAL20R8_12) VIHH = 10.25;
  else VIHH = 11.75;
  }
  else if(MFG == NS) {
    VIHH = 11.75;
  }

  if(DEVICE == dPAL20C1  ||
     DEVICE == dPAL20C1A)  LOGIC = 2;
  else                     LOGIC = 0;
  
  TYPE = type[DEVICE];

  @Vout 1,      VIHH;
  @Vout 2, 	VIHH;
  @Vout 3,	 5.0;
  @Out  GND, 	 @G;
  @Delay 10, @Ms;  

  @Out VCC,      @W;
  @Out I[0..9],  @W;
  @Out O[0..4],  @Z;
  @Out A[0..2],  @Z;
  @Out L_R,      @Z;
  @Out OD,       @W;
  @Out CLOCK,    @W;
  @Out _O[0..4], @Z;
  @Out _A[0..2], @Z;
  @Out _L_R,     @Z;
  @Out _OD,      @W;
  @Out _CLOCK,   @W;

  @Out VCC,      @L;                
  @Out I[0..9],  @L;
  @Out OD,       @L;
  @Out CLOCK,    @L;
  @Out _OD,      @L;
  @Out _CLOCK,   @L;

  @Out  VCC, 	 @O;
  @Delay 100, @Us;  
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int verifyf(data, option)
int data, option;
{
   int tmp;
   
   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;
   }
}
/* -----------------------------------------------------------------------
 * 
 * ----------------------------------------------------------------------- */
int sel_I_A_LR(i, j)
int i, j;
{
  int k;

  if(i<40) @Out OD,  @O;			/* PGM mode set */
  else     @Out _OD, @O;			/* PGM mode set */

  for(k=0; k<10; k++) {
    if(j/4 != k) @Out I[k], @O;
    else {
      if(j%2 == 0) @Out I[k], @L;
      else         @Out I[k], @H;
    }
  }
  
  if(i<40) {
    for(k=0; k<3; k++) {
      if(((i%8)>>k)&1 == 1) @Out A[k], @O;	/* A select */
    }
    if((j/2)%2 == 1) @Out L_R, @O;    
  }
  else {
    for(k=0; k<3; k++) {
      if(((i%8)>>k)&1 == 1) @Out _A[k], @O;	/* A select */
    }
    if((j/2)%2 == 1) @Out _L_R, @O;
  }
}  
/* -----------------------------------------------------------------------
 * 
 * ----------------------------------------------------------------------- */
int sel_O(i, addr)
int i, addr;
{
  @Out VCCP,      @O; 
  @Out VCC,       @F;
  if(i < 40) {
    @Out  O[addr], @O;
    @Delay 20, @Us;
    @Out  O[addr], @F; 
  }
  else {
    @Out _O[addr], @O;
    @Delay 20, @us;
    @Out _O[addr], @F;
  }
  @Out VCC,       @O; 
  @Out VCCP,      @F;
  @Delay 150, @us;
}
/* -----------------------------------------------------------------------
 * 
 * ----------------------------------------------------------------------- */
int read_O(i)
int i;
{
  int read_d, k;

  if(i < 40) {
    @Out CLOCK, @H; @Out CLOCK, @L;		/* Verify clock */
    @In O[0..4], read_d;
    @Out L_R,   @F;				/* Clear L_R */
    for(k=0; k<3;  k++) @Out A[k], @F;		/* Clear PA */    
    for(k=0; k<10; k++) @Out I[k], @F;		/* Clear PI */    
    @Out OD, @F;    
  }
  else {
    @Out _CLOCK, @H; @Out _CLOCK, @L;		/* Verify clock */
    @In _O[0..4], read_d;  
    @Out _L_R,   @F;				/* Clear L_R */
    for(k=0; k<3;  k++) @Out _A[k], @F;		/* Clear PA */        
    for(k=0; k<10; k++) @Out  I[k], @F;		/* Clear PI */    
    @Out _OD, @F;    
  }
  
  return(read_d);
}
/* -----------------------------------------------------------------------
 * type select
 * ----------------------------------------------------------------------- */
int type_select(i, j)
int i, j;
{
  int tmp, tmp1, itmp, jtmp;
  
  itmp = (TYPE*10) + i/8;
  jtmp = (TYPE*5) + j/8;
  
  tmp  = type_prod[itmp] >> (i%8);
  tmp1 = type_inp [jtmp] >> (j%8);

  if(tmp&1 == 1 && tmp1&1 == 1) return(1);
  else	  			return(0);
}
/* -----------------------------------------------------------------------
 * top
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, addr, tmp,
  	pgm_d, read_d;

  disp(option, 0);
  pgm_d = read_d = addr = 0;
  init();

  for(i=0; i<80; i++) {
    for(j=0; j<40; j++) {

      if(type_select(i, j) == 0) continue;

      @Set 0, addr;
      @Store pgm_d;
      @Display  67, 9, addr, @d;

      sel_I_A_LR(i, j);
      tmp = (i%40)/8;

      if(option == 'p' && pgm_d == 1) sel_O(i, tmp);
        
      read_d = ~read_O(i) >> tmp;

      if(LOGIC == 2) {
        if(i<40) read_d = ~read_d;
      }

      if(option == 'p') {
        if(read_d&1 != pgm_d&1) @Exit;
      }
      else verifyf(read_d, option);
      addr++;
    }	/* end j     */
  }	/* end i     */
  
  disp(option, 1);  
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  disp('s', 0);
  
  if(MFG == AMD__MMI) {
    @Vout 1, 19.00;
    @Vout 2, 10.00;
    @Delay 1, @MS;
    @Out OD,     @O;
    @Out _OD,    @O;
    @Delay 10, @Us;
    @Out VCCP,   @O;
    @Out VCC,    @F;
    @Delay 10, @Us;
    @Out CLOCK,  @O;
    @Out _CLOCK, @O;
    @Out OD,     @F;
    @Out _OD,    @F;
    @Delay 30, @Us;
    @Out OD,     @O;
    @Out _OD,    @O;
    @Out CLOCK,  @F;
    @Out _CLOCK, @F;
    @Delay 10, @Us;
    @Out VCC,    @O;
    @Out VCCP,   @F;
    @Delay 10, @Us;
    @Out OD,     @F;
    @Out _OD,    @F;
  }
  else {
    @Vout 2, 17.25;
    @Out OD,   @Z;
    @Out _OD,  @Z;
    @Delay 1, @Ms;

    @Out VCCP, @O;
    @Out VCC,  @F;
    @PinDelay OD, @O, @F, 40;
    @Delay 10, @Us;
    @PinDelay _OD, @O, @F, 40;
    @Delay 10, @Us;
    @Out VCC,  @O;
    @Out VCCP, @F;
  }

  disp_flag = 1;
  top('b');
  disp_flag = 0;
  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();				/* 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 ------------------------ */
  