/* ***************************************************************************
 *    File Name : 27128.D
 *    Pin num	: 28
 *    Memory Size : 128K (3FFF)
 *    Last Modify Date : 91. 3. 11 
 *
 * +--------------------------------------------------------------------------
 *    Vpp:12.75  	Vcc:6.25  	Dur:100us 
 * +-------------------------------------------------------------------------- 
 *		  AMD		27C128
 *		  ATMEL		27C128 
 *		  INTEL		27128A	P27128A	27C128
 *		  MICROCHIP	27C128  27C128A
 *		  NS		27C128	27C128B	27C128BN  27C128AN
 *		  OKI		27128	27128A	27C128 
 *		  SIGNETICS	27C128
 *		  TI		27C128		
 *		  VLSI		27C128  
 * +--------------------------------------------------------------------------
 *    Vpp:21.0  	Vcc:6.0  	Dur:1ms 
 * +-------------------------------------------------------------------------- 
 *    Device 	: AMD	  	27128		27128DC
 *		  FUJITSU	27128		27C128
 *		  HITACHI	4827128		4827128G			
 *		  MITSUBISHI    27128		27C128
 *		  NEC		27128	27128C	27128D
 *		  TOSHIBA	27128
 *		  SEEQ		27128
 *		  TI		27128
 * +--------------------------------------------------------------------------
 *    Vpp:12.5  	Vcc:6.0  	Dur:1ms 
 * +-------------------------------------------------------------------------- 
 *		  HITACHI	27128A	4827128P	
 *		  CSI		27128AP-15	27128A
 *		  SGS		27128A
 *		  SIGNETICS	27128A
 *		  TI		27PC128		27128A
 *		  TOSHIBA	24128	24128A	24128AP	27128ADI  
 *				27128A	27128AP
 * +--------------------------------------------------------------------------
 *    Vpp:13.5  	Vcc:5.5  	Dur:3ms 
 * +--------------------------------------------------------------------------  
 *		  WSI		27C128F(5ms)	27C128L(5.8,12.75, 2ms)
 *				57C128F		57C128
 * +--------------------------------------------------------------------------
 *    Vpp:13.0  	Vcc:6.0  	Dur:1ms 
 * +-------------------------------------------------------------------------- 
 *		  AMD		27128A 
 * +--------------------------------------------------------------------------
 *    Vpp:21.0  	Vcc:5.0  	Dur:10ms 
 * +-------------------------------------------------------------------------- 
 *		  AMD		27128AF		27128APC			 
 * ************************************************************************* */
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 */
      MICROCHIP         /* 6 */
      MITSUBISHI        /* 7 */
      NEC		/* 8 */
      NS         	/* 9 */
      OKI		/* 10 */
      SEEQ		/* 11 */
      SIGNETICS		/* 12 */
      SGS      	        /* 13 */
      TI		/* 14 */
      TOSHIBA 		/* 15 */
      VLSI      	/* 16 */
      WSI		/* 17 */
   ;
   Devices
      D27128		/* 0 */
      D27128DC		/* 1 */
      D4827128          /* 2 */
      D4827128G         /* 3 */
      D27128C           /* 4 */
      D27128D           /* 5 */
      D4827128P		/* 6 */
      D27128AP          /* 7 : TOSHIBA : Vpp=12.5   Vcc=6.0  Dur=1000us */
      D27128A           /* 8 */
      D24128            /* 9 */
      D24128A           /* 10 */
      D24128AP          /* 11 */
      D27128ADI         /* 12 : TOSHIBA end ..*/
      D27C128F          /* 13 */
      D27C128L          /* 14 */
      D27128AF          /* 15 */
      D27128APC		/* 16 */
      DP27128A		/* 17 */
      D27C128A          /* 18 */
      D27C128AN         /* 19 */
      D27C128B          /* 20 */
      D27C128BN         /* 21 */
      D27128AP_15       /* 22 */
      D27C128		/* 23 */
      D27PC128          /* 24 */ 
      D57C128           /* 25 */
      D57C128F          /* 26 */
   ;
   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, PGM, Vcc;
   $v2 = Vpp;
   $v3 = Vcc;
endd

int durstat [] = { 6 , 0, 1, 1, 6, 0, 0, 1, 1, 0, 0, 1, 6, 1, 6, 6, 0, 6 };
int volstat [] = { 6 , 4, 1, 0, 6, 4, 5, 0, 0, 4, 4, 0, 6, 1, 6, 6, 4, 6 };
int durtbl  [] = { 100, 1000, 3000, 10000};

voltage vpptbl [] = { 21.0, 12.5, 13.0, 21.0, 12.75, 13.0 };
voltage vcctbl [] = {  6.0,  6.0,  6.0 , 5.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..13], @W;       /*   Initial Direction      */
   @Out CE       , @W;       /*         Of               */
   @Out PGM	 , @W;	     /*        Port		 */
   @Out OE       , @W;       /* ------------------------ */
   @Out Vcc	 , @W;
   @Out __GANG__[0..3] , @W;

   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE       , @H;       /* Out  enable  is High */
   @Out PGM	 , @H;
   @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 != 6) 
      {
         init (vpptbl [stat], vcctbl [stat]);
         stat = durstat [MFG];
         dur = durtbl [stat];
      }
      else
      {
         if (MFG == AMD)
         {
            if (DEVICE == D27128 || DEVICE == D27128DC) 
            {
               init (21.0 , 6.0);
               dur = 1000;
            }
            else if (DEVICE == D27128A)
            {
               init (13.0, 6.0);
               dur = 1000;
            }
            else if (DEVICE == D27128AF || DEVICE == D27128APC)
            {
               init (21.0, 5.0);
               dur = 10000;
            }
            else 
            {
            	init (12.75, 6.25);
            	dur = 100;
            }
         }		/* end if: (MFG == AMD)  */
         else if (MFG == HITACHI)
         {
            if (DEVICE == D4827128 || DEVICE == D4827128G) 
            {
               init (21.0, 6.0);
               dur = 1000;
            }
            else if (DEVICE == D27128A || DEVICE == D4827128P)
            {
               init (12.5 , 6.0 );
               dur = 1000;
            }
         }		/*  end if : (MFG == HITACHI) */
         else if (MFG == TOSHIBA)
         {
             if (DEVICE == D27128)
             {
             	init (21.0 , 6.0);
             	dur = 1000;
             }
             else if (DEVICE >= 7 && DEVICE <= 12)
             {
             	init (12.5 , 6.0 );
		dur = 1000;             	
             } 
         }		/*  end if : (MFG == TOSHIBA) */
         else if (MFG == TI)
         {
             if (DEVICE == D27128)
             {
		init ( 21.0 , 6.0 );      
		dur = 1000;		
             }
             else if (DEVICE == D27PC128 || DEVICE == D27128A)
             {
		init (12.5 , 6.0 );
		dur = 1000;             	             	
             }
             else if (DEVICE == D27C128)
             {
             	init ( 12.75, 6.25 );
             	dur = 100;
             }
         }   		/*  end if : (MFG == TI)  */
         else if (MFG == SIGNETICS)
         {
	     if (DEVICE == D27128A)
	     {
	     	init ( 12.5, 6.0 );
	     	dur = 1000;
	     }             
	     else 
	     {
	     	init ( 12.75, 6.25);
	     	dur = 100;
	     }
         }   		/*  end if : (MFG == SIGNETICS)  */
         else if (MFG == WSI)
         {
             if (DEVICE == D27C128F || DEVICE == D27C128L)
      	     {
      	     	init (12.5, 6.0);
      	     	dur = 1000;
      	     }	
      	     else 
      	     {
	     	init ( 13.5 , 5.5 );
	     	dur = 3000;      	     
      	     }
         }		/*  end if : (MFG == WSI)	*/
      }			/*  end else : stat == 6	*/         
   }			/*  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;

   lwlb = lwhb = hwhb = hwlb = 0;
   tmp = tmp2 = slh = elh = smask = emask = 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; hwlb<=0; 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..13], 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 ,  @O;
   @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..13], 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      	   , @L;
		  else			@Out __GANG__[GANG], @L;

		  @Out   PGM   , @L;	/*  Assign Delay time  */
		  @Delay Dur   , @us;
		  @Out   PGM   , @H;

		  /* -------- Verify --------- */
		  @Out D [0..7], @Z;
	          @Out OE      , @L;
	          @In  D [0..7], tmp2;
		  @Out OE      , @H;
		  
		  if (GANG == 0) 	@Out CE		   , @H;
		  else			@Out __GANG__[GANG], @H;
		  
		  @Out D [0..7], @W;

		  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;
   if (MFG == AMD && DEVICE == D27C128)
   {
      @Vout  2,	5.25;
      @Vout  3,	5.25;
   }
   else
   {
      @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 --------------------------- */ 