/* ****************************************************************************
 *    File Name : 27256.D
 *    Pin num	: 28    (A0..A14	D0..D7)
 *    Memory Size : 256K (7FFF)
 *    Last Modify Date : 91. 3. 15 
 *
 * +--------------------------------------------------------------------------
 *    Vpp:12.5  	Vcc:6.0  	Dur:1000 us
 * +-------------------------------------------------------------------------- 
 *    Device 	: 
 *		  AMD		27256(13.0, 6.0)    27256AP 
 * 		  ATMEL	  	27HC256	27C256	  27256  27HC256L
 *		  CSI		27256(OTP) 
 *		  FUJITSU	27256	27C256H	  27C256A  *27C256(21.0 6.0,1ms)
 *		  HITACHI	27256	27C256	  27C256H  27C256A
 *		  MITSUBICHI    27256		27C256	   27C256A 	 
 *		  NEC		27256C	27256D	  27C256C  27C256D  27C256AD
 *		  		27256	27256A	27256AD	   27256AC  27C256A	  
 *		  RICHO		27C256 
 *		  SEEQ		27C256	27256
 *		  SIGNETICS	27C256F	27C256 (Test result:Quick.NOTsupported!)
 *		  SGS		27256A	27256	27C256 
 *		  TOSHIBA	24256	24256A	24256B	24256AP	27256	27256A
 *				27256B 	57256A	57256D	27256D	27256AD	27256ADI
 *			 	TC57256D        TC57256AD	TC54256P(OTP)	  
 *			 	TC54256AP 	TC54256AF
 *		  VLSI		27C256 (13.0)
 * +--------------------------------------------------------------------------
 *    Vpp:13.0  	Vcc:6.5  	Dur:1000 us
 * +--------------------------------------------------------------------------  
 *		  ATMEL		27C256R
 * +--------------------------------------------------------------------------
 *    Vpp:12.75  	Vcc:6.25  	Dur:100us 
 * +--------------------------------------------------------------------------  
 *		  AMD		27C256  
 *		  CSI		27256P-17	  27HC256
 *		  INTEL		27C256		  P27C256    87C256		
 *				27256		  P27256 	
 *		  NS		27C256	27C256Q	  27CP256 (Spec:13.0 6.0 500us)
 * 				27C256B	27C256BQ  27C256BQE  27C256BQM (SAME)	
 *				27C256BN	
 *		  MICROCHIP	27C256	27HC256(Express Algo:13.0 6.5 LOP=10)
 *		  OKI		27256	27C256	27256A	27C256A	 27C256H	 
 *		  SGS		*27C256B(?)
 *		  TI		27C256	  27PC256 
 * +--------------------------------------------------------------------------
 *    Vpp=21.0  	Vcc=6.0  	Dur=10ms 
 * +--------------------------------------------------------------------------   
 *		  AMD		27256F	 27256PC    27C256F	27C256PC
 * +--------------------------------------------------------------------------
 *    Vpp=12.5  	Vcc=5.5  	Dur=3ms 
 * +--------------------------------------------------------------------------    
 *		  WSI		27C256F	   57C256F	
 * +--------------------------------------------------------------------------
 *    Vpp=12.75  	Vcc=5.8  	Dur=3ms 
 * +--------------------------------------------------------------------------    
 *		  WSI		27C256L  
 * ************************************************************************* */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
      Auto      
   ;
   Manufacturers
      AMD		/* 0 */
      ATMEL		/* 1 */	
      CSI		/* 2 */
      FUJITSU		/* 3 */
      HITACHI		/* 4 */
      INTEL		/* 5 */
      MITSUBICHI	/* 6 */
      MICROCHIP		/* 7 */
      NEC		/* 8 */
      NS		/* 9 */
      OKI		/* 10 */
      RICHO		/* 11 */
      SEEQ		/* 12 */
      SIGNETICS		/* 13 */
      SGS		/* 14 */
      TI		/* 15 */
      TOSHIBA		/* 16 */
      VLSI		/* 17 */
      WSI		/* 18 */
   ;
   Devices
      D24256
      D24256A
      D24256B
      D27256B
      D57256A
      D57256D
      D27256AD
      D27256ADI
      D27256D	
      D27256P_17
      DTC57256D
      DTC57256AD
      DTC54256P
      DTC54256AP
      DTC54256AF
      D27256C
      D27C256B
      D27C256BQ
      D27C256BQE
      D27C256BQM
      D27C256BN
      D27C256C
      D27C256D
      D27C256R
      D27256            
      D27256AP
      D27HC256
      D27HC256L
      D27C256
      D27C256H
      D27C256A
      D27C256L
      D27256AC
      D27C256F
      D27C256Q
      D27CP256
      D57C256F
      DP27C256
      DP27256
      D87C256
   ;
   chips = Vpp, A12, A7, A6, A5, A4, A3, A2, A1, A0, D0, D1, D2, GND,
	   D3, D4, D5, D6, D7, CE, A10, OE, A11, A9, A8, A13, A14, Vcc;
   $v2 = Vpp;
   $v3 = Vcc;
endd

int durstat [] = { 3 , 3, 3, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 3, 0, 1, 1, 3 };
int volstat [] = { 3 , 3, 3, 0, 0, 1, 0, 2, 0, 1, 1, 0, 0, 0, 3, 1, 0, 0, 3 };
int durtbl  [] = { 100, 1000 };

voltage vpptbl [] = { 12.5,  12.75, 13.0 };
voltage vcctbl [] = {  6.0,   6.25, 6.5 };

/* -----------------------------------------------------------------------
 * 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..14], @W;       /*   Initial Direction      */
   @Out CE       , @W;       /*         Of               */
   @Out OE       , @W;	     /*        Port		 */
   @Out Vcc	 , @W; 	     /* ------------------------ */
   @Out __GANG__[0..3] , @W;

   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE       , @H;       /* Out  enable  is High */
   @Out Vcc	 , @H;
   @Out __GANG__[0..3] , @H;

   @Out Vcc      , @O;       /* Vcc Enable */
   @Delay  100   , @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
int	stat, dur;

   if (MFG == MICROCHIP)	LOP=10;
   else				LOP=25;
   
   if (FUNCTION != Program) init ( 5.0 , 5.0 );
   else	
   {
      stat = volstat [MFG];
      if (stat != 3) 
      {
         init (vpptbl [stat], vcctbl [stat]);
         stat = durstat [MFG];
         dur = durtbl [stat];
      }
      else
      {
         if (MFG == AMD)
         {
            if (DEVICE == D27256 || DEVICE == D27256AP) 
            {
               init (13.0 , 6.0);
               dur = 1000;
            }
            else if (DEVICE == D27C256)
            {
               init (12.75, 6.25);
               dur = 100;
            }
            else 
            {
               init (21.0, 6.0);
               dur = 10000;
            }
         }		/* end if: (MFG == AMD)  */
         else if (MFG == ATMEL)
         {
            if (DEVICE == D27C256R) 
            {
               init (13.0, 6.5);
               dur = 1000;
            }
            else 
            {
               init (12.5 , 6.0 );
               dur = 1000;
            }
         }		/*  end if : (MFG == ATMEL) */
         else if (MFG == CSI)
         {
             if (DEVICE == D27256)
             {
             	init (12.5 , 6.0);
             	dur = 1000;
             }
             else 
             {
             	init (12.75 , 6.25 );
		dur = 100;             	
             } 
         }		/*  end if : (MFG == CSI) */
         else if (MFG == SGS)
         {
             if (DEVICE == D27C256B)
             {
		init ( 12.75 , 6.25 );      
		dur = 100;		
             }
             else 
             {
		init (12.5 , 6.0 );
		dur = 1000;             	             	
             }
         }   		/*  end if : (MFG == SGS)  */
         else if (MFG == WSI)
         {
	     if (DEVICE == D27C256L)
	     {
	     	init ( 12.75, 5.8 );
	     	dur = 3000;
	     }             
	     else 
	     {
	     	init ( 12.5, 5.5);
	     	dur = 3000;
	     }
         }   		/*  end if : (MFG == WSI)  */
      }			/*  end else : stat == 2   */         
   }			/*  end if : (FUNCTION != Program) */
   
   return (dur);
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row)
int	row;
{
int  hwhb, hwlb, lwhb, lwlb;
int  slh, elh, smask, emask;
int  tmp, tmp2;

   @Set	B_HADDR, B_LADDR;   
   @Inc	__B_START__;
   
   lwlb = lwhb = hwhb = hwlb = 0;
   slh = elh = smask = emask = tmp = tmp2 = 0;
   
   @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..14], 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;

	       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);
	       }
	       if (FUNCTION == Data_Compare)
	       {
	          @Store tmp2;
	          @Compare tmp, tmp2;
	       }	       
	       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, Dur)
int	row, kind, Dur;
{
int  hwhb, hwlb, lwhb, lwlb;
int  slh, elh, smask, emask;
int  tmp , tmp2, failcnt;

   @Set	B_HADDR, B_LADDR;
   @Inc	__B_START__;
   
   slh = elh = smask = emask = failcnt = tmp = tmp2 = 0;
   lwlb = lwhb = hwhb = hwlb = 0;
   
   @Out Vpp ,  @H;
   @Display 26, row, "Programming...";   
   
   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..14], 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 Vpp     , @O;
		  @Out D [0..7], @W; 		  
	       
		  @Store tmp;
		  
		  if (tmp == 0xFF)
		  {
		      @Inc  SPLIT;
		      continue;
		  }
		  
	          @Out A [0..7], lwlb;
	          @Out D [0..7], tmp;
	          
		  if (GANG == 0)    	@Out CE      	   , @L;
		  else			@Out __GANG__[GANG], @L;
		  
		  @Delay Dur     , @us;
		  
		  if (GANG == 0) 	@Out CE		   , @H;
		  else			@Out __GANG__[GANG], @H;
		  
		  /* -------- Verify --------- */
		  @Out Vpp     , @F;
		  @Out D [0..7], @Z;
		  if (GANG == 0)    	@Out CE      	   , @L;
		  else			@Out __GANG__[GANG], @L;
	          @Out OE      , @L;
	          @In  D [0..7], tmp2;
		  @Out OE      , @H;
		  if (GANG == 0) 	@Out CE		   , @H;
		  else			@Out __GANG__[GANG], @H;
		  
		  if (tmp != tmp2)
                  {
		     if (failcnt > LOP )   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);
}

/* -----------------------------------------------------------------------
 * main () ---> Control main
 * ----------------------------------------------------------------------- */
int main ()
{
int	dur;

   dur = InitProcess();

   if ( FUNCTION == Auto )
   {
	FUNCTION = Blank_Check;
	read (6);
	
	FUNCTION = Program;
	dur = InitProcess ();
	program(7, 1, dur);
   }
   else if ( FUNCTION == Program ) program(6, 0, dur);
   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 --------------------------- */ 