/* --< 1 >---------------------------------------------------------P. S. O--
 *  FIRST UPDATE : Oct.  9. 90
 *                   1. 17. 91 all ok!
 *		     1. 17. 91
 *  LIB Ver      : 1.00
 * -------------------------------------------------------------------------
 * Fuse_su		      : 2048     [32 * 64]
 * Internal Security Fuse     : 1
 * ==========================================================================
 * --------------------------------------------------------------------------
 * SYMBOL |                              |    MIN   TYP   MAX  |  UNIT
 * -------+------------------------------+---------------------+-------------
 * VPP    | Programming Voltage          |  13.00 13.50 14.00  |   V
 * VCCp   | Programming supply voltage   |   4.75  5.00  5.25  |   V
 * Tpw    | PGM InitalProgram pulse Width|    0.1  1.00 10.00  |   ms
 * Ts     | Setup Time                   |    1.0              |   us
 * Th     | Hold time                    |    1.0              |   us
 * Tr, Tf | VPP Rise and Fall Time       |    1.0              |   us
 * Tvd    | Delay to Verify              |    1.0              |   us
 * Tvp    | Verify pulse width           |    2.0              |   us
 * Tdv    | Verify to Data valid         |   20.0              |   us
 * Tdz    | Verify to High Z             |                1.0  |   us
 * ========================================================================
 * group
 * SAMSUNG
 *	    CPL16L8
 *	    CPL16R4
 *	    CPL16R6
 *	    CPL16R8
 * CYPRESS
 *	    PALC16L8
 *	    PALC16R4
 *	    PALC16R6
 *	    PALC16R8
 * ADM/MMI
 *	    PALC16L8Q
 *	    PALC16R4Q
 *	    PALC16R6Q
 *	    PALC16R8Q
 *	    PALC16L8Z
 *	    PALC16R4Z
 *	    PALC16R6Z
 *	    PALC16R8Z
 * ======================================================================== */

declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    SAMSUNG
    CYPRESS
  ;
  Devices
    dCPL16L8		/* SAMSUNG */
    dCPL16R4
    dCPL16R6
    dCPL16R8

    PALC16L8Z		/* AMD/MMI */
    PALC16R4Z
    PALC16R6Z
    PALC16R8Z
  ;
                 /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips =  VPP,  /* [³ 1     20 ³] VCC   */
            A0,  /* [³ 2     19 ³] D0    */
            A1,  /* [³ 3     18 ³] D1    */
            A2,  /* [³ 4     17 ³] D2    */
            A3,  /* [³ 5     16 ³] D3    */
            A4,  /* [³ 6     15 ³] D4    */
            A5,  /* [³ 7     14 ³] D5    */
            A6,  /* [³ 8     13 ³] D6    */
            A7,  /* [³ 9     12 ³] D7    */
            GND, /* [³ 10    11 ³] PGM_OE*/
                 /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
	   PGM_OE, D7, D6, D5, D4, D3, D2, D1, D0, VCC;

  $v2 = VPP, PGM_OE, A1, A2;
  $v3 = VCC;
endd

  int index     = 6;
  int disp_flag = 0;
  int caddr     = 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,     13.50;
  if(MFG == SAMSUNG || MFG == CYPRESS)  @Vout 2,     13.50;
  else				        @Vout 2,     14.00;
  @Vout 3,	5.00;
  @Out  GND, 	@G;
  @Delay 5, @Ms;

  @Out A[0..7], @W;
  @Out D[0..7], @Z;
  @Out VPP,	@W;
  @Out PGM_OE,  @W;

  @Out A[0..7], @L;
  @Out VPP,     @L;
  @Out PGM_OE,  @H;

  @Out VCC, 	@O;
  @Delay 100, @Us;
}
/* -----------------------------------------------------------------------
 * Verify function
 * ----------------------------------------------------------------------- */
int verifyf(address, data, option)
int address, data, option;
{
  int tmp;

  @Set 0, address;

  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;
  }
}
/* -----------------------------------------------------------------------
 * convert
 * ----------------------------------------------------------------------- */
int convert(i, j, read_d, option)
int i, j, read_d, option;
{
  int k, pgm_d, tmp;

  pgm_d = 0;

  for(k=0; k<8; k++) {
    caddr = 256*k + 32*i + j;
    @Display  67, 9, caddr, @d;
    if(option == 'p') {
      @Set 0, caddr;
      @Store tmp;
      pgm_d |= (tmp & 1) << k;
    }
    else {
      verifyf(caddr, ~read_d, option);
      read_d >>= 1;          
    }
  }

  return(pgm_d);
}
/* -----------------------------------------------------------------------
 * Read data from device
 * Blank check
 * Verify
 * ----------------------------------------------------------------------- */
int top(option)
int option;
{
  int 	i, j, k,
  	pgm_d, read_d, tmp,
        limit,		/* Limit of program (20)*/  
        flag;		/* program Fail flag	*/

  disp(option, 0);
  init();

  for(i=0; i<8; i++) {
    for(j=0; j<32; j++) {
      flag = 0;
      for(limit=0; limit<20; limit++) {
        @Out A[0..2], i;			/* Product term addressing */
        @Out A[3..7], j;			/* Input line addressing */
        @Out VPP,     @O;			/* Vpp enable */
        pgm_d = tmp = 0;
        if(option == 'p') {
          pgm_d = convert(i, j, 0, option);
          @Out D[0..7], @W;
          @Out D[0..7], pgm_d;
          if(flag == 0) @PinDelay PGM_OE, @O, @F, 100;
          else {				/* final program 4*limit*100uS*/
            @Out PGM_OE, @O;
            @Delay 4*limit*100, @us;
            @Out PGM_OE, @F;
          }
          @Out D[0..7], @Z;
        }
        @Out PGM_OE,  @L;
        @In  D[0..7], read_d;
        @Out PGM_OE,  @H;
        @Out VPP,     @F;
        if(option == 'p') {
          if(flag == 1) break;
          if(pgm_d&0xff == ~read_d&0xff) flag = 1;
          if(limit == 19)  @Exit;
        }
        else {
          convert(i, j, read_d, option);
          break;
        }
      }	/* limit */
    }   /* j */
  }     /* k */
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  disp('s', 0);
  init();

  @Out A1,     @O;
  @Out VPP,    @O;
  @PinDelay PGM_OE, @O, @F, 1000;
  @Out VPP,    @F;
  @Out A1,     @F;
  security_verify();
  disp('s', 1);
}
/* -----------------------------------------------------------------------
 * Security verify
 * ----------------------------------------------------------------------- */
int security_verify()
{
  int	data;

  init();

  @Out A1, @Z;
  @Out A2, @O;
  @In  A1, data;
  @Out A2, @F;
  if(data&1 == 0) @Exit;
}
/* -----------------------------------------------------------------------
 * MAIN Porgram
 * ----------------------------------------------------------------------- */
int main()
{
  index = 6;

  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 ------------------------ */
 