/* ****************************************************************************
 *    File Name : 2716.D
 *    Pin num   : 24-pin
 *    Memory size : 8K (7FF)
 *    Last Modify Date : 91. 3. 11(if DATA is FF then skip program)
 * 
 *    Device    : **= Vcc:5.0   Vpp:25.0  Delay : 50ms =**
 *		  AMD    	2716   	9716
 * 		  CSI		27C16A
 *		  HITACHI	462716
 *		  INTEL         2716
 *		  MITSUBITCHI   2716
 *		  NEC		2716
 *		  NS 		2716	27C16	27C16Q	27C16B	27C16H  *9716
 *		  *OKI		2716	
 *		  *SGS		2716	27C16
 *		  *TI		2716	27C16
 *      *=========== Vcc:6.0   Vpp:12.5	 Delay : 5ms ==========**
 *    		  AMD		2716B		 
 * ************************************************************************* */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
      Auto      
   ;
   Manufacturers
      AMD		/* 0 */
      CSI		/* 1 */
      HITACHI           /* 2 */
      INTEL             /* 3 */
      MITSUBITHI        /* 4 */
      NEC		/* 5 */
      NS		/* 6 */
      OKI               /* 7 */
      SGS		/* 8 */
      TI		/* 9 */
   ;
   Devices
      D2716		
      D9716
      D462716
      D27C16
      D27C16A      
      D27C16B      
      D27C16Q
      D27C16H
      D2716B		
   ;
   chips = A7, A6, A5, A4, A3, A2, A1, A0, D0, D1, D2, GND,
	   D3, D4, D5, D6, D7, CE, A10, OE, Vpp, A9, A8, Vcc;
   $v2 = Vpp;
   $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 (vol2, vol3)
voltage vol2, vol3;
{
   @Vout 2, vol2;            /* Voltage Source #2 */
   @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..10], @W;       /*   Initial Direction      */
   @Out CE	 , @W;
   @Out OE	 , @W;
   @Out Vcc	 , @W;   
   @Out __GANG__[0..3], @W;   

   @Out Vcc	 , @L;   
   @Out CE       , @H;
   @Out OE       , @H;
   @Out __GANG__[0..3], @L;
   
   @Out Vcc	, @O;
   @Delay 1	, @ms;
   @Out Vpp     , @O;
   @Delay 100	, @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   if (FUNCTION != Program) init ( 5.0 , 5.0 );
   else 	 	    
   {
      if ( DEVICE == D2716B)	init (12.5 , 5.0);
      else			init (25.0 , 5.0);
   }			
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row)
int	row;
{
int  hwhb, hwlb, lwhb, lwlb;	/* eaddr : end address */
int  smask, emask, slh, elh;
int  tmp, tmp2;

   smask = emask = slh = elh = 0;
   lwlb = lwhb = hwhb = hwlb = tmp = tmp2 = 0;
   
   @Out __GANG__[0..3] , @H;
   
   @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=S_HWLB ; hwlb<=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..10], lwhb;   /* Output High word address */

            if (lwhb == S_LWHB) smask = S_LWLB;
            else                smask = 0;
            if (lwhb == E_LWHB) emask = E_LWLB;
            else                emask = 0xFF;
                                                         
	    for ( lwlb=smask ; lwlb<=emask ; lwlb++)
	    {
	       @Out A [0..7], lwlb;    /* Low  byte address output */
	       
	       if (GANG == 0)	@Out CE            , @L;
	       else		@Out __GANG__[GANG], @L;
	       @Out OE      , @L;
	       @In  D [0..7], tmp;
	       @Out OE	    , @H;
	       if (GANG == 0)	@Out CE 	    , @H;
	       else		@Out __GANG__[GANG] , @H;

	       if      (FUNCTION == Read)          @Load tmp;
	       else if (FUNCTION == Data_Compare)	
	       {	
	       	    @Store	tmp2;
	       	    @Compare	tmp	, tmp2;
	       }
	       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);
	       }
	       if (FUNCTION != Blank_Check)	@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 (row, kind)
int	row, kind;	/*  kind=0;Program	kind=1:Auto   */
{
int  hwhb, hwlb, lwhb, lwlb;
int  tmp , tmp2, Dur, smask, emask;
int  failcnt;

   smask = emask = lwlb = lwhb = hwhb = hwlb = 0;
   Dur = failcnt = tmp = tmp2 = 0;                            

   @Set B_HADDR, B_LADDR;   
   @Inc	__B_START__;
   @Display 26, row, "Programming...";
   
   if (DEVICE == D2716B)	Dur = 5;	
   else				Dur = 50;
   
   for ( hwhb=0 /* S_HWHB */; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
       @Display 64, 9, hwhb;

       for ( hwlb= S_HWLB ; hwlb<=E_HWLB ; hwlb++ )
       {
	   @Display 66, 9, hwlb;
	   for ( lwhb= S_LWHB ; lwhb<= E_LWHB ; lwhb++)
	   {
	       @Display 68, 9, lwhb;
	       @Out A [8..10], lwhb;   /* Output High word address */
	       
	       if (lwhb == S_LWHB) smask = S_LWLB;
               else                smask = 0;
               if (lwhb == E_LWHB) emask = E_LWLB;
               else                emask = 0xFF;

	       for ( lwlb= smask ; lwlb<= emask ; lwlb++)
	       {
		  @Store tmp;
		  
		  if (tmp == 0xFF)
		  {
		      @Inc  SPLIT;
		      continue;
		  }
	  
	          @Out A [0..7], lwlb;
		  @Out D [0..7], tmp;
		  
		  if (GANG == 0)	@Out CE      , @H;
		  else			@Out __GANG__[GANG], @H;
		  @Delay Dur    , @ms;	
		  if (GANG == 0) 	@Out CE      , @L;
		  else			@Out __GANG__[GANG], @L;
		  
		  @Out D [0..7], @Z;
		  @Out OE      , @L;
		  
		  @In  D [0..7], tmp2;
		  @Out OE      , @H;
		  @Out D [0..7], @W;
		  
		  /* -------- Verify ----------- */
		  if (tmp != tmp2)
		  {
		     if (failcnt > 25) Failf (hwhb, hwlb, lwhb, lwlb, tmp2);
		     else
		     {
			++ failcnt;
			lwlb--;
		     }
                  }
		  else
		  {
			failcnt = 0;
			@Inc SPLIT;
		  }
               }
	   }
       }
   }
   @Display  26, row, "Program OK!  ";
   if (kind == 0)	row = 7;
   else			row = 8;
   FUNCTION = Verify;
   @Vout 2, 5.0;
   @Vout 3, 5.0;
   read (row);		/*  Verify  */
}

/* -----------------------------------------------------------------------
 * main () ---> Control main
 * ----------------------------------------------------------------------- */
int main ()
{
   InitProcess();
      
   if ( FUNCTION == Auto )
   {
	FUNCTION = Blank_Check;
	read (6);
	
	FUNCTION = Program;
	InitProcess ();
	program(7, 1);
   }
   else if ( FUNCTION == Program ) program(6, 0);
   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 --------------------------- */
  