/* ****************************************************************************
 *    File Name : MEGAWORD.D (1M WORD-wide EPROM:  GANG is NOT Supported !!)
 *    Last Modify Date : 91. 3. 11 
 *
 *    Pin num : 40-pin   (A0..A15     D0..D15) 
 *    Size    : 1M  (FFFF * 2 = 1FFFF)
 *    Vpp     : 12.75		Vcc : 6.25		Dur:100us
 *    Device  : AMD		27C1024
 *		ATMEL		27HC1024	27C1024		27C1024L
 *		CSI	 	27C210	27C210D(/-15/5/20/25/17)
 *		INTEL 		27C210  27210
 *		NEC	 	27C1024
 *		NS		27C1024
 *		OKI		27C1024 		
 *		HITACHI		27C1024	27C1024-PG
 *		*SGS		27C1024
 *		TI	  	27C210
 *		TOSHIBA		571024	
 *		WSI		27C210L	(Dur =2000us)
 *----Vpp---- : 12.5-----------Vcc=6.0-------------Dur=500us-------------------
 *		FUJITSU	 	27C1024     	27C1024-PG
 *		MITSUBISHI	27C102	(200us)	 27C102-PG
 *    Vpp     : 13.0		Vcc : 6.5		Dur:100us 
 *		ATMEL		27C1024		27C1024L
 * ************************************************************************** */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
      Auto
   ;
   Manufacturers
      AMD
      ATMEL
      CSI  	
      INTEL
      NEC
      NS
      OKI
      HITACHI
      SGS
      TI
      TOSHIBA
      WSI
      FUJITSU		/*  12  */
      MITSUBISHI
   ;
   Devices
      D27C1024
      D27C1024L      
      D27HC1024
      D27C210
      D27210
      D27C210D
      D571024
      D57H1024
      D27C210L
      D27C102_PG
   ;
   chips = Vpp,   CE,  D15,D14, D13, D12, D11, D10, D9, D8, 
   	   GND1_, D7 , D6, D5 , D4 , D3 , D2 , D1 , D0, OE,
	   A0, 	  A1 , A2, A3 , A4 , A5 , A6 , A7 , A8, GND2_,
	   A9,    A10, A11,A12, A13, A14, A15, NC , PGM,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 GND1_   , @G;     /* Ground output */
   @Out GND2_	, @G;
   @Delay 10	, @ms;

   @Out A [0..7]  , @W;
   @Out A [8..15] , @W;
   @Out D [0..7 ] , @W; 
   @Out D [8..15] , @W;

   @Out CE        , @W;       
   @Out OE        , @W;       
   @Out PGM	  , @W;
   @Out Vcc	  , @W;

   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE       , @H;       /* Out  enable  is High */
   @Out PGM	 , @H;
   @Out Vcc	 , @L;

   @Out Vcc	 , @O;       /* Vcc Enable */
   @Out Vpp	 , @O;       /* Vpp Enable */
   @Delay 100	 , @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   if (FUNCTION != Program) 	init ( 5.0 , 5.0 );
   else
   {
    	if (MFG ==ATMEL && DEVICE !=D27HC1024 )	init (13.0 , 6.5 );
    	else if (MFG >= 12)			init (12.5 , 6.0 );
    	else					init (12.75, 6.25);
   } 		    
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row)
int	row;
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh, shl, ehl;
int  tmp, tmp1, tmp2, incval;

   @Set B_HADDR, B_LADDR;
   @Inc	__B_START__;

   if (SPLIT == 1) incval = 1;
   else            
   {
      incval = SPLIT + 1;
      @Inc __B_START__;
   }
   
   hwhb = hwlb = lwlb = lwhb = 0;
   sll = ell = slh = elh = shl = ehl = 0;
   tmp = tmp1 = tmp2 = 0;

   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...";   
   
   @Out D [0..15] , @Z;	/* Data Input  */
   
   for ( hwhb=0 /* S_HWHB */ ; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
      @Display 64, 9, hwhb;
      if (hwhb == S_HWHB) shl = S_HWLB;
      else                shl = 0;
      if (hwhb == E_HWHB) ehl = E_HWLB;
      else                ehl = 0xFF;
      
      for ( hwlb=shl; hwlb<=ehl; 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..15], 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 */
	       
	       @Out CE       , @L;
	       @Out OE       , @L;
	       @In  D [0..15] , tmp;
	       @Out CE       , @H;	       
	       @Out OE       , @H;

	       if (FUNCTION == Read)         
	       {
	          @Load tmp;	/*  Load	Low-byte  */
	          @Inc 1;
	          tmp >>= 8;	/*  Load	High-Byte   */
	          @Load tmp;
	       }
	       else if (FUNCTION == Blank_Check)   /* Blank_Char */
	       {
		    if (tmp != 0xFFFF)	Failf(hwhb, hwlb, lwhb, lwlb, tmp);
	       }
	       else if (FUNCTION == Verify)
	       {
		   @Store tmp1;		/*  Low Byte */
		   @Inc	1;
		   @Store tmp2;		/*  High Byte */
		   tmp1 |= tmp2<<8;
		   if (tmp != tmp1)  Failf (hwhb, hwlb, lwhb, lwlb, tmp);
	       }
	       else if (FUNCTION == Data_Compare) 	   
	       {
	       	    @Store      tmp1;
		    @Inc        1;	
	       	    @Store	tmp2;
	       	    tmp1 |= tmp2<<8;
	       	    @Compare	tmp, tmp1;
	       }	       
	       @Inc incval;
            }
	 }
      }
   }
   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;
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh, shl, ehl;
int  tmp , tmp1, tmp2, failcnt, Dur, incval;

   @Set  B_HADDR, B_LADDR;
   @Inc  __B_START__;
   
   if (SPLIT == 1) incval = 1;
   else            
   {
      incval = SPLIT + 1;
      @Inc __B_START__;
   }
   
   Dur = failcnt = tmp = tmp1 = tmp2 = 0;
   lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh = shl = ehl = 0;
   
   @Display 26, row, "Programming...";      

   if      (MFG == FUJITSU || MFG == MITSUBISHI)	Dur = 500;
   else if (MFG == WSI)					Dur = 300;
   else							Dur = 100;

   for ( hwhb=0 ; hwhb<=0; hwhb++ )
   {
       @Display 64, 9, hwhb;
       if (hwhb == S_HWHB) shl = S_HWLB;
       else                shl = 0;
       if (hwhb == E_HWHB) ehl = E_HWLB;
       else                ehl = 0xFF;

       for ( hwlb=shl; hwlb<=ehl; 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..15], 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;	/* Low Byte  */
		  @Inc	1;
		  @store tmp1;	/* High Byte */
		  tmp |= tmp1<<8;
		  
		  if (tmp == 0xFFFF)
		  {
		      @Inc incval;
		      continue;
		  }
		  
	          @Out A [0..7], lwlb;
		  @Out D [0..15], tmp;
		  @Out CE	, @L;
		  
		  @Out    PGM	, @L;				  
		  @Delay  Dur	, @us;
		  @Out    PGM	, @H;
		  
		  /* -------- One word Verify ----------- */
		  @Out D [0..15] , @Z;
		  @Out OE	, @L;
		  @In  D [0..15], tmp2;
		  
		  @Out D [0..15] , @W;
		  @Out OE       , @H;
		  
		  @Delay 100, @Us;	/*  assign OE Raising time  */	  
		  
		  if (tmp != tmp2)
                  {
		     if (failcnt > 25 ) Failf (hwhb, hwlb, lwhb, lwlb, tmp2);
		     else
		     {
			++ failcnt;
			lwlb--;
			@Dec	1;
		     }
                  }
		  else
		  {
			failcnt = 0;
			@Inc incval;
		  }
               }
	   }
       }
   }
   @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 			   read (6);
}
/* ---------------------------- End of program --------------------------- */ 