/* --< 4 >---------------------------------------------------------P. S. O---
 *  FIRST UPDATE : Oct. 10. 90
 * 	           Oct. 16. 90
 *		     1. 18. 91	
                     1. 30. 91  ti20002 (p, r, v, b, s ok !)
 *  LIB Ver      : 1.00
 * --------------------------------------------------------------------------
 * Fuse_su		      : 2048     [32 * 64]
 * Internal Security Fuse     : 1
 * -------------------------------------------------------------------------- */
declaration
  dataunit : bit
  ;
  functions
    Program
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    AMD__MMI
    NS
    TI
  ;
  Devices
/* ---------- AMD/MMI ------------- */
    dPAL10H8		/*  0 10.0V 0*/
    dPAL10H8_2          /*  1 10.0V 1*/
    dPAL10L8            /*  2 10.0V 2*/
    dPAL10L8_2          /*  3 10.0V 3*/
    dPAL12H6            /*  4 10.0V 4*/
    dPAL12H6_2          /*  5 10.0V 5*/
    dPAL12L6            /*  6 10.0V 6*/
    dPAL12L6_2          /*  7 10.0V 7*/
    dPAL14H4            /*  8 10.0V 8*/
    dPAL14H4_2          /*  9 10.0V 9*/
    dPAL14L4            /* 10 10.0V 10*/
    dPAL14L4_2          /* 11 10.0V 11*/
    dPAL16H2            /* 12 10.0V 12*/
    dPAL16H2_2          /* 13 10.0V 13*/
    dPAL16L2            /* 14 10.0V 14*/
    dPAL16L2_2          /* 15 10.0V 15*/
    dPAL16C1            /* 16 10.0V 16*/
    dPAL16C1_2          /* 17 10.0V 17*/
    dPAL16L8            /* 18 10.0V 18*/
    dPAL16L8A           /* 19 10.0V 19*/
    dPAL16L8A_2         /* 20 10.0V 20*/
    dPAL16L8A_4         /* 21 10.0V 21*/
    dPAL16R4            /* 22 10.0V 22*/
    dPAL16R4A           /* 23 10.0V 23*/
    dPAL16R4A_2         /* 24 10.0V 24*/
    dPAL16R4A_4         /* 25 10.0V 25*/
    dPAL16R6            /* 26 10.0V 26*/
    dPAL16R6A           /* 27 10.0V 27*/
    dPAL16R6A_2         /* 28 10.0V 28*/
    dPAL16R6A_4         /* 29 10.0V 29*/
    dPAL16R8            /* 30 10.0V 30*/
    dPAL16R8A           /* 31 10.0V 31*/
    dPAL16R8A_2         /* 32 10.0V 32*/
    dPAL16R8A_4         /* 33 10.0V 33*/
    dPAL16X4            /* 34 10.0V 34*/
    dPAL16L8B           /* 35 11.75V 35*/
    dPAL16L8B_2         /* 36 11.75V 36*/
    dPAL16L8B_4         /* 37 11.75V 37*/
    dPAL16L8D           /* 38 11.75V 38*/
    dPAL16L8H_15        /* 39 11.75V 39*/
    dPAL16R4B           /* 40 11.75V 40*/
    dPAL16R4B_2         /* 41 11.75V 41*/
    dPAL16R4B_4         /* 42 11.75V 42*/
    dPAL16R4D           /* 43 11.75V 43*/
    dPAL16R4H_15        /* 44 11.75V 44*/
    dPAL16R6B           /* 45 11.75V 45*/
    dPAL16R6B_2         /* 46 11.75V 46*/
    dPAL16R6B_4         /* 47 11.75V 47*/
    dPAL16R6D           /* 48 11.75V 48*/
    dPAL16R6H_15        /* 49 11.75V 49*/
    dPAL16R8B           /* 50 11.75V 50*/
    dPAL16R8B_2         /* 51 11.75V 51*/
    dPAL16R8B_4         /* 52 11.75V 52*/
    dPAL16R8D           /* 53 11.75V 53*/
    dPAL16R8H_15        /* 54 11.75V 54*/
/* --------- NS ---------- */
/*  dPAL10H8             * 55 11.75V */
    dPAL10H8A           /* 56 11.75V 55*/
    dPAL10H8A2          /* 57 11.75V 56*/
/*  dPAL10L8             * 58 11.75V */
    dPAL10L8A           /* 59 11.75V 57*/
    dPAL10L8A2          /* 60 11.75V 58*/
/*  dPAL12H6             * 61 11.75V */
    dPAL12H6A           /* 62 11.75V 59*/
    dPAL12H6A2          /* 63 11.75V 60*/
/*  dPAL12L6             * 64 11.75V */
    dPAL12L6A           /* 65 11.75V 61*/
    dPAL12L6A2          /* 66 11.75V 62*/
/*  dPAL14H4             * 67 11.75V */
    dPAL14H4A           /* 68 11.75V 63*/
    dPAL14H4A2          /* 69 11.75V 64*/
/*  dPAL14L4             * 70 11.75V */
    dPAL14L4A           /* 71 11.75V 65*/
    dPAL14L4A2          /* 72 11.75V 66*/
/*  dPAL16H2             * 73 11.75V */
    dPAL16H2A           /* 74 11.75V 67*/
    dPAL16H2A2          /* 75 11.75V 68*/
/*  dPAL16L2             * 76 11.75V */
    dPAL16L2A           /* 77 11.75V 69*/
    dPAL16L2A2          /* 78 11.75V 70*/
/*  dPAL16C1             * 79 11.75V */
    dPAL16C1A           /* 80 11.75V 71*/
    dPAL16C1A2          /* 81 11.75V 72*/
/*  dPAL16L8             * 82 11.75V */
/*  dPAL16L8A            * 83 11.75V */
    dPAL16L8A2          /* 84 11.75V 73*/
/*  dPAL16L8B            * 85 11.75V */
    dPAL16L8B2          /* 86 11.75V 74*/
/*  dPAL16R4             * 87 11.75V */
/*  dPAL16R4A            * 88 11.75V */
    dPAL16R4A2          /* 89 11.75V 75*/
/*  dPAL16R4B            * 90 11.75V */
    dPAL16R4B2          /* 91 11.75V 76*/
/*  dPAL16R6             * 92 11.75V */
/*  dPAL16R6A            * 93 11.75V */
    dPAL16R6A2          /* 94 11.75V 77*/
/*  dPAL16R6B            * 95 11.75V */
    dPAL16R6B2          /* 96 11.75V 78*/
/*  dPAL16R8             * 97 11.75V */
/*  dPAL16R8A            * 98 11.75V */
    dPAL16R8A2          /* 99 11.75V 79*/
/*  dPAL16R8B            *100 11.75V */
    dPAL16R8B2          /*101 11.75V 80*/
/* ---------- TI ---------- */
/*  dPAL16L8A		 *102 10.5V */		/* TI20001  VHH 10.5 */
/*  dPAL16R4A            *103 10.5V */
/*  dPAL16R6A            *104 10.5V */
/*  dPAL16R8A            *105 10.5V */
/*  dPAL16L8A_2          *106 10.5V */
/*  dPAL16R4A_2          *107 10.5V */
/*  dPAL16R6A_2          *108 10.5V */
/*  dPAL16R8A_2          *109 10.5V */
/*  dTIBPAL16L8_12	 *110 10.5V */		 /* TI20002  VHH 10.5 */
/*  dTIBPAL16R4_12       *111 10.5V */
/*  dTIBPAL16R6_12       *112 10.5V */
/*  dTIBPAL16R8_12       *113 10.5V */
/*  dTIBPAL16L8_15       *114 10.5V */
/*  dTIBPAL16R4_15       *115 10.5V */
/*  dTIBPAL16R6_15       *116 10.5V */
/*  dTIBPAL16R8_15       *117 10.5V */
/*  dTIBPAL16L8_25       *118 10.5V */
/*  dTIBPAL16R4_25       *119 10.5V */
/*  dTIBPAL16R6_25       *120 10.5V */
/*  dTIBPAL16R8_25       *121 10.5V */
  ;
			 /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        	*/
  chips = OD:_CLOCK,	 /* [³ 1     20 ³] VCC  : VCCP  */
	    I0,  	 /* [³ 2     19 ³] O3   : _L_R  */
	    I1,  	 /* [³ 3     18 ³] O2   : _A0   */
	    I2,  	 /* [³ 4     17 ³] O1   : _A1   */
	    I3,  	 /* [³ 5     16 ³] O0   : _A2   */
	    I4,  	 /* [³ 6     15 ³] A0   : _O3   */
	    I5,  	 /* [³ 7     14 ³] A1   : _O2   */
	    I6,  	 /* [³ 8     13 ³] A2   : _O1   */
	    I7,  	 /* [³ 9     12 ³] L_R  : _O0   */
	    GND,  	 /* [³ 10    11 ³] CLOCK: _OD   */
			 /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        	*/
	  CLOCK : _OD,
	  L_R   : _O0,
	  A2    : _O1,
	  A1    : _O2,
	  A0    : _O3,
	  O0    : _A2,
	  O1    : _A1,
	  O2    : _A0,
	  O3    : _L_R,
	  VCC   : VCCP;

  $v1 = CLOCK, _CLOCK, VCCP;
  $v2 =  I,
         A,
         A0,  A1,  A2,
         O,
         O0,  O1,  O2, O3,
         L_R,
         OD,
        _A,
        _A0, _A1, _A2,
        _O,
        _O0, _O1, _O2, _O3,
	_L_R,
	_OD;
  $v3 = VCC;

endd
	       /* 10h8, 10l8 :     0
	          12h6, 12l6 :     1
	          14h4, 14l4 :     2
	          16h2, 16l2, 16c1:3
	          else             4 */
char type[81] =  {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 
		  2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 
		  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
		  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
		  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
		  4, 4, 4, 4, 4, 0, 0, 0, 0, 1, 
		  1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 
		  3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 
		  4};

                /* L type : 0
                   H type : 1
                   C type : 2 */
char logic[81] = {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 
		  0, 0, 1, 1, 0, 0, 2, 2, 0, 0,
		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		  
		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		  
		  0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 
		  1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
		  0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 
		  1};

char type_inp[16] = {0x3f,0x33,0x33,0xf3, 			/* 0 */
		     0xff,0x33,0x33,0xff,                       /* 1 */
                     0xff,0x3f,0xf3,0xff,                       /* 2 */
                     0xff,0xff,0xff,0xff};                      /* 3 */
                     
char type_prod[32] ={0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,	/* 0 */
		     0x00,0x0f,0x03,0x03,0x03,0x03,0x0f,0x00,  	/* 1 */
		     0x00,0x00,0x0f,0x0f,0x0f,0x0f,0x00,0x00,  	/* 2 */
		     0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00}; 	/* 3 */ 

int LOGIC, TYPE;

  int index, 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()
{
  voltage VIHH;

  if     (MFG == AMD__MMI) {				/* Set VIHH */
    if(DEVICE >= 35 && DEVICE <= 54) VIHH = 10.25;
    else VIHH = 11.75;
  }
  else if(MFG == NS) {
    VIHH = 11.75;
  }
  else if(MFG == TI) {
    VIHH = 11.40; /*10.50*/
  }

  if(MFG == TI) {
    TYPE  = 4;
    LOGIC = 0;
  }
  else {
    TYPE  = type[DEVICE];
    LOGIC = logic[DEVICE];
  }

  @Vout 1,      VIHH;  /* NULL */
  @Vout 2, 	VIHH;
  @Vout 3,	 5.0;
  @Out  GND, 	 @G;
  @Delay 10, @Ms;

  @Out VCC,     @W;
  @Out I[0..7], @W;
  @Out O[0..3], @Z;
  @Out A[0..2], @Z;
  @Out L_R,     @Z;
  @Out OD,      @W;
  @Out CLOCK,   @W;
  @Out _O[0..3],@Z;
  @Out _A[0..2],@Z;
  @Out _L_R,    @Z;
  @Out _OD,     @W;
  @Out _CLOCK,  @W;

  @Out VCC,     @L;
  @Out I[0..7], @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<32) @Out  OD, @O;			/* PGM mode set */
  else     @Out _OD, @O;			/* PGM mode set */

  for(k=0; k<8; 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<32) {
    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 < 32) {
    @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 30, @Us;
}
/* -----------------------------------------------------------------------
 *
 * ----------------------------------------------------------------------- */
int read_O(i)
int i;
{
  int read_d, k;

  if(i<32) {
    @Out CLOCK, @H; @Out CLOCK, @L;		/* Verify clock */
    @Delay 5, @Us;
    @In O[0..3], read_d;
    @Out L_R,   @F;				/* Clear L_R */
    for(k=0; k<3; k++) @Out A[k], @F;		/* Clear A */
    for(k=0; k<8; k++) @Out I[k], @F;		/* Clear I */
    @Out OD, @F;
  }
  else {
    @Out _CLOCK, @H; @Out _CLOCK, @L;		/* Verify clock */
    @Delay 5, @Us;    
    @In _O[0..3], read_d;
    @Out _L_R,   @F;				/* Clear L_R */
    for(k=0; k<3; k++) @Out _A[k], @F;		/* Clear A */
    for(k=0; k<8; k++) @Out  I[k], @F;		/* Clear I */
    @Out _OD, @F;
  }
  
  return(read_d);
}
/* -----------------------------------------------------------------------
 * type select
 * ----------------------------------------------------------------------- */
int type_select(i, j)
int i, j;
{
  int tmp, tmp1, itmp, jtmp;
  
  itmp = (TYPE*8) + i/8;
  jtmp = (TYPE*4) + 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, k, tmp, addr,
  	pgm_d, read_d;

  disp(option, 0);
  pgm_d = read_d = addr = 0;
  init();

  for(i=0; i<64; i++) {
    for(j=0; j<32; j++) {

      if(TYPE != 4) {
        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 = 3-(i%32)/8;
      if(option == 'p' && pgm_d == 1) sel_O(i, tmp);

      read_d = read_O(i) >> tmp;
      
      if(LOGIC == 0) read_d = ~read_d;
      else if(LOGIC == 2) {
        if(i>=32)   read_d = ~read_d;
      }

      if(option == 'p') {
	if(pgm_d&1 != read_d&1) @Exit;
      }
      else verifyf(read_d, option);
      addr++;	
    }	/* end j     */
  }	/* end i     */

  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  disp('s', 0);
  init();

  if(MFG == TI) {
    @Vout 2, 14.00;
    @Out VCC, @F;
    @Out VCC, @G;
    @Delay 1, @Ms;
    @Out OD,  @O;
    @Out _OD, @O;
    @Delay 50, @Us;
    @Out _OD, @F;
    @Out OD,  @F;
  }
  else 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 ------------------------ */
  