/* --< 2 >---------------------------------------------------------P. S. O--
 *  FIRST UPDATE : Oct. 10. 90, 
 *                  11.  8. 90
 *                   1. 17. 91	all ok !
 *  LIB Ver      : 1.00
 * -------------------------------------------------------------------------
 * Fuse_su		      : 2560     [40 * 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
 * ======================================================================== */
declaration
  dataunit : bit 
  ;
  functions
    Program  
    Read
    Verify
    Blank_Check
    Security
    Auto
  ;
  Manufacturers
    AMD__MMI
    SAMSUNG
  ;
  Devices
    dCPL20L8
    dCPL20R4
    dCPL20R6
    dCPL20R8
    dPALC20L8Z
    dPALC20R4Z
    dPALC20R6Z
    dPALC20R8Z
    
  ;             /*  ΥΝΝΝΝΈΥΝΝΝΝΈ        */
  chips = VPP,  /* [³ 1     24 ³] VCC   */
        A0:B0,  /* [³ 2     23 ³] D0    */
        A1,     /* [³ 3     12 ³] D1    */
        A2:B1,  /* [³ 4     21 ³] D2    */
        A3:B2,  /* [³ 5     20 ³] D3    */
        A4:I0,  /* [³ 6     19 ³] D4    */
        A5:I1,  /* [³ 7     18 ³] D5    */
        A6:I2,  /* [³ 8     17 ³] D6    */
        A7:I5,  /* [³ 9     16 ³] D7    */
        A8:I3,  /* [³ 10    15 ³] D8    */
        A9:I4,  /* [³ 11    14 ³] D9    */
           GND, /* [³ 12    13 ³] PGM_OE*/
                /*  ΤΝΝΝΝΝΝΝΝΝΝΎ        */
          PGM_OE, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0, VCC;

  $v2 = VPP, PGM_OE, A1, A2, B1, B2;
  $v3 = VCC;
endd

  int index, disp_flag;
  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(option)
int option;
{
  if(MFG == SAMSUNG) {
    @Vout 1,     13.50; /* NULL */
    @Vout 2,     13.50;   
    @Vout 3, 	5.00;
  }
  else if(MFG == AMD__MMI) {
    @Vout 1,     13.50; /* NULL */
    @Vout 2,     13.50;   
    if(option == 's') @Vout 3, 	6.00;
    else	      @Vout 3, 	5.50;
  }
  @Out  GND, 	@G;
  @Delay 10, @Ms;

  @Out A[0..9], @W;
  @Out D[0..9], @Z;
  
  if(MFG == AMD__MMI) {
    @Out D0, @W;
    @Out D9, @W;
    @Out D0, @L;
    @Out D9, @L;
  }

  @Out VPP,	@W;
  @Out PGM_OE,  @W;
  @Out B[0..2], @W;
  @Out I[0..5], @W;

  @Out A[0..9], @L;
  @Out VPP,     @L;
  @Out PGM_OE,  @H;
  @Out B[0..2], @L;
  @Out I[0..5], @L;  

  @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 */
     @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 = 320*k + 40*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,
  	read_d, pgm_d, tmp,
        limit,					/* Limit of program (20)*/
        flag;					/* program Fail flag	*/

  disp(option, 0);
  init(option);
  @Out VPP,     @O;  

  for(i=0; i<8; i++) {
    for(j=0; j<40; j++) {
      flag = 0;
      if(MFG == SAMSUNG) { 
        @Out A[0..2], i;			/* Product term addressing */
        @Out A[3..9], j;			/* Input line addressing */
      }
      else if(MFG == AMD__MMI) {
        @Out B[0..2], i;			/* Product term addressing */
        @Out I[0..5], j;			/* Input line addressing */
      }
      
      for(limit=0; limit<20; limit++) {
        if(option == 'p') {        
          pgm_d = convert(i, j, 0, option);
          @Out D[1..8], @W;
          @Out D[1..8], 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[1..8], @Z;
        }
        @Out PGM_OE,  @L;
        @In  D[1..8], read_d;
        @Out PGM_OE,  @H;
        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 */
  @Out VPP,     @F;  
  disp(option, 1);
}
/* -----------------------------------------------------------------------
 * Security device
 * ----------------------------------------------------------------------- */
int security_device()
{
  int data;

  disp('s', 0);
  init('s');

  if(MFG == SAMSUNG) {  
    @Out PGM_OE, @L;
    @Out A1,  @O;
    @Out VPP, @O;
    @PinDelay PGM_OE, @O, @F, 1000;
    @Out VPP, @F;
    @Out A1,  @F;
  
    init('r');					/* Security Verify */

    @Out A1, @Z;
    @Out A2, @O;
    @In  A1, data;
    @Out A2, @F;          
    if(data&1 == 0) @Exit;
  }
  else if(MFG == AMD__MMI) {
    @Out VPP, @O;
    @Out B1,  @O;
    @Delay 50, @Ms;
    @Out B1,  @F;
    @Out VPP, @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 ------------------------ */
 