/* ****************************************************************************
 *    File Name 	: 2864.D  (Electrical Eraser PROM)
 *    Pin num		: 28-pin	(A0..A12	D0..D7)
 *    Memory Size      	: 64K	(1FFF)
 *    Last Modify Date 	: 91. 3. 15 
 *-----------------------------------------------------------------------------
 *    Vcc	: 5.0		Erase :Vpp=12.0
 *----------------------------------------------------------------------------- 
 *    Device 	: 
 *	Dur=100us: ATMEL	28C64E	  28C64F
 *
 *      Dur=500us: ATMEL	28C64  	  28HC64  28PC64   28C64X 28HC64L
 *	Dur=1ms	 : GI		28C64A
 *
 *      Dur=5ms : EXEL		2864A	  9764		
 *		  MICROCHIPS    2864      28C64A(Spec:1ms) 28PC64
 *		  VLSI		28H64 		
 *		  XICOR		2864H	 2864HI	2864B 2864BI 
 *				2864BM (TYP=3MS 	max:5ms)
 *	Dur=10ms: AMD		2864A	 2864B
 *		  CSI		28C64A
 *		  FUJITSU	28C64
 *		  HITACHI	58064
 *		  NEC		28C64
 *		  SAMSUNG	2864AH	 28C64   2865A	2865AH	
 *				28C64A	 28C65A	 28C65
 *		  SEEQ		2864	 2864H	 28C64	28C65   	
 *		  XICOR		2864A	 2864AI  2864AM	2864AMB	2864AT   
 *		  NS		2864 
 *		 *INTEL		2864A (Spec non-exist !!!)
 * ************************************************************************** */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
   ;
   Manufacturers
      ATMEL		/*  0: 1ms   */
      GI                /*  1  */
      EXEL		/*  2: 5ms   */
      MICROCHIPS	/*  3  */
      VLSI		/*  4  */
      AMD		/*  5:10ms   */
      CSI		/*  6  */
      FUJITSU		/*  7  */
      HITACHI		/*  8  */
      NEC		/*  10  */
      SAMSUNG		/*  11  */
      SEEQ        	/*  12  */
      NS		/*  13  */
      XICOR		/* 14: except 2864H(5ms)  */
      INTEL		/*  15  */
   ;
   Devices
      D2864             /* 0 */
      D2864A		/* 1 :max=10ms*/	
      D2864AI           /* 2 */
      D2864AMB          /* 3 */
      D2864AM           /* 4 */
      D2864AT           /* 5 */
      D2864B		/* 6: 3MS   : max=5ms */
      D2864BI		/* 7 */
      D2864BM		/* 8 */
      D2864H            /* 9 */
      D2864HI           /* 10 */
      D28HC64
      D28HC64L
      D28PC64
      D9764
      D28C64
      D28C64E
      D28C64F
      D28C64X
      D2864AH
      D28C64A	      
      D28C65
      D28C65A
      D2865A
      D2865AH
      D58064
   ;      
   chips = NC1, A12, A7, A6, A5, A4, A3,  A2, A1,  A0, D0, D1,  D2, GND,
	   D3,  D4,  D5, D6, D7, CE, A10, OE, A11, A9, A8, NC2, WE, Vcc;
   $v3 = Vcc;
endd

/* -------------------------------------------------------------------------
 * Failf () ---> Fail address setting
 * ------------------------------------------------------------------------- */
int Failf (hwhb, hwlb, lwhb, lwlb, tmp)
int hwhb, hwlb, lwhb, lwlb, tmp;
{
int high, low;

   high = (hwhb << 8) | hwlb;
   low  = (lwhb << 8) | lwlb;

   @Fail high, low, tmp;
}
/* -----------------------------------------------------------------------
 * init () ---> Initial processing
 * ----------------------------------------------------------------------- */
int     init ( vol3 )
voltage  vol3;
{
   @Vout 3	 , vol3;            /* Voltage Source #3 */
   @Out GND      , @G;       /* Ground output */
   @Delay 10	 , @ms;

   @Out D [0..7] , @W;       /* ------------------------ */
   @Out A [0..7] , @W;       /*                          */
   @Out A [8..12], @W;       /*   Initial Direction      */
   @Out CE       , @W;       /*         Of               */
   @Out WE	 , @W;	     /*        Port		 */
   @Out OE       , @W;       /* ------------------------ */
   @Out __GANG__[0..3], @W;
   @Out Vcc	 , @W;

   @Out Vcc	 , @L;
   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE       , @H;       /* Out  enable  is High */
   @Out WE	 , @H;
   @Out __GANG__[0..3], @H;  
   
   @Out Vcc      , @O;       /* Vcc Enable */
   @Delay 100	 , @Ms;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   init ( 5.0 );
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row)
int	row;
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh;
int  tmp, tmp2;

   lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh = tmp = tmp2 = 0;
   
   @Set B_HADDR, B_LADDR;
   @Inc	__B_START__;
   
   @Out D [0..7], @Z;	/* Data Input  */
   
   if (FUNCTION == Read ) 
   {
      @Display 26, row, "Reading...";
      @CheckSumON;
   }
   else if (FUNCTION == Verify)		@Display 26, row, "Verifying...";
   else if (FUNCTION == Blank_Check)	@Display 26, row, "Blank Checking...";
   else 			        @Display 26, row, "Data Comparing...";
   
   for ( hwhb=0 /* S_HWHB */ ; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
      @Display 64, 9, hwhb;
      for ( hwlb=0 /* S_HWLB */; hwlb<=0 /* E_HWLB */; hwlb++ )
      {
         @Display 66, 9, hwlb;
         if (hwlb == S_HWLB) slh = S_LWHB;
         else                slh = 0;
         if (hwlb == E_HWLB) elh = E_LWHB;
         else                elh = 0xFF;
         
	 for ( lwhb=slh; lwhb<= elh; lwhb++)
         {
            @Display 68, 9, lwhb;
	    @Out A [8..12], lwhb;   /* Output High word address */
	    
	    if (lwhb == S_LWHB) sll = S_LWLB;
            else                sll = 0;
            if (lwhb == E_LWHB) ell = E_LWLB;
            else                ell = 0xFF;

	    for ( lwlb=sll; lwlb<=ell; lwlb++)
	    {
	       @Out A [0..7], lwlb;    /* Low  byte address output */
	       
	       if (GANG == 0)	@Out CE      	   , @L;
	       else		@Out __GANG__[GANG], @L;
	       
	       if (DEVICE != D2864AMB)	@Out OE      , @L;

	       @In  D [0..7], tmp;
	       if (GANG == 0)	@Out CE	    	   , @H;
	       else		@Out __GANG__[GANG], @H;
	       
	       @Out OE	    , @H;

	       if (FUNCTION == Read)          @Load tmp;
	       else if (FUNCTION == Blank_Check)
	       {
		  if (tmp != 0xFF /* Blank Char  */)
		     Failf (hwhb, hwlb, lwhb, lwlb, tmp);
	       }
	       else if (FUNCTION == Verify)
               {
                  @Store tmp2;
                  if (tmp != tmp2) Failf (hwhb, hwlb, lwhb, lwlb, tmp);
	       }
	       else if (FUNCTION == Data_Compare)
	       {
	       	    @Store	tmp2;
	       	    @Compare	tmp, tmp2;
	       }
	       @Inc SPLIT;
            }
	 }
      }
   }
   if 	   (FUNCTION == Read)		@Display 26, row, "Read OK!   ";
   else if (FUNCTION == Verify)		@Display 26, row, "Verification OK!";
   else if (FUNCTION == Blank_Check)	@Display 26, row, "Blank Check OK!  ";
   else 			        @Display 26, row, "Data Comparison OK!";
}
/* -----------------------------------------------------------------------
 * program() ---> Control main
 * ----------------------------------------------------------------------- */
int program ()
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh, Dur;
int  tmp , tmp2, failcnt;

   @Set  B_HADDR, B_LADDR;
   @Inc  __B_START__;
   
   failcnt = lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh = Dur = tmp = tmp2 = 0;

   if 	   (MFG == ATMEL)
   {
   	if (DEVICE == D28C64E || DEVICE == D28C64F)	Dur = 100;
   	else						Dur = 500;
   }	
   else	if (MFG <= 1)		Dur = 1000;
   else	if (MFG == XICOR)	
   {
   	if 	(DEVICE >= 1	&& DEVICE <= 5)	Dur = 10000;
   	else					Dur = 5000;
   }
   else if (MFG<=4 )		Dur = 5000; 
   else	    			Dur = 10000;
   
   @Display 26, 6, "Programming...";      

   @Out OE	, @L;

   for ( hwhb=0 /* S_HWHB */; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
       @Display 64, 9, hwhb;
       for ( hwlb=0 /* S_HWLB */; hwlb<=0 /* E_HWLB */; hwlb++ )
       {
	   @Display 66, 9, hwlb;
	   if (hwlb == S_HWLB) slh = S_LWHB;
           else                slh = 0;
           if (hwlb == E_HWLB) elh = E_LWHB;
           else                elh = 0xFF;
           
	   for ( lwhb=slh; lwhb<=elh; lwhb++ )	   
	   {
               @Display 68, 9, lwhb;
	       @Out A [8..12], lwhb;   /* Output High word address */
	       
	       if (lwhb == S_LWHB) sll = S_LWLB;
               else                sll = 0;
               if (lwhb == E_LWHB) ell = E_LWLB;
               else                ell = 0xFF;
            
	       for ( lwlb=sll; lwlb<=ell; lwlb++)
	       {
		  @Store tmp;
		  
	          @Out A [0..7], lwlb;
	          @Out OE      , @H;
	          if (GANG == 0)	@Out CE   	   , @L;
	          else			@Out __GANG__[GANG], @L;
	          @Out WE      , @L;	          
	          @Out D [0..7], tmp;
	          
		  if (GANG == 0)	@Out CE      	   , @H;
		  else			@Out __GANG__[GANG], @H;
		  @Out WE      , @H;
		  @Out OE      , @L;
		  @Delay Dur   , @us;
		  
		  /* -------- Verify --------- */
		  @Out D [0..7], @Z;
		  if (GANG == 0)	@Out CE            , @L;
		  else			@Out __GANG__[GANG], @L;
	          @Out OE      , @L;
	          @In  D [0..7], tmp2;
	          
	          if (GANG == 0)	@Out CE            , @H;
	          else			@Out __GANG__[GANG], @H;
	          
		  @Out D [0..7], @W;
		  
		  if (tmp != tmp2)	Failf (lwlb, lwhb, hwlb, hwhb, tmp2);
		  
		  @Inc	SPLIT; 		  
               }
	   }
       }
   }
   @Display 26, 6, "Program OK!   ";
   FUNCTION = Verify;
   read (7);		/*  Verify  */
}

/* -----------------------------------------------------------------------
 * main () ---> Control main
 * ----------------------------------------------------------------------- */
int main ()
{
   InitProcess();

   if 	   ( FUNCTION == Program ) 	program();
   else if ( FUNCTION == Read )
   {
   	if 	(GANG >= 1 && __B_START__ == 0);
   	else if (GANG == 3 && __B_START__ == 1);
   	else read (6);
   }    
   else 			read (6);
}
/* ---------------------------- End of program --------------------------- */ 