/* ****************************************************************************
 *    File Name : 48FXXX.D	(Flash Memory)
 *    Last Modify Date : 91. 3. 21 
 *
 *    Device 	: SEEQ	48F512  (Vpp:12.5  Vcc:5.0  10us)
 *    Size	: 512K (FFFF)
 *    Pin num	: 32-pin	(A0..A15   D0..D7)
 *
 *    Device 	: SEEQ	48F010  (Vpp:12.5  Vcc:5.0  10us)
 *    Size	: 512K (FFFF)
 *    Pin num	: 32-pin	(A0..A16   D0..D7) 
 *****************************************************************************/
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
      Erase
      Auto      
   ;
   Manufacturers
      SEEQ
   ;
   Devices
      D48F512	
      D48F010
   ;
                   ΥΝΝΝΈΥΝΝΝΈ
  chips = Vpp, /* [³ 1   32 ³] VCC */
          A16, /* [³ 2   31 ³] WE  */
          A15, /* [³ 3   20 ³] NC2 */
          A12, /* [³ 4   29 ³] A14 */
          A7,  /* [³ 5   28 ³] A13 */
          A6,  /* [³ 6   27 ³] A8  */
          A5,  /* [³ 7   26 ³] A9  */
          A4,  /* [³ 8   25 ³] A11 */
          A3,  /* [³ 9   24 ³] OE  */
          A2,  /* [³10   23 ³] A10 */
          A1,  /* [³11   22 ³] CE  */
          A0,  /* [³12   21 ³] D7  */
          D0,  /* [³13   20 ³] D6  */
          D1,  /* [³14   19 ³] D5  */
          D2,  /* [³15   18 ³] D4  */
          GND, /* [³16   17 ³] D3  */
               /*  ΤΝΝΝΝΝΝΝΝΎ      */
	  D3, D4, D5, D6, D7, CE, A10, OE, A11, A9, A8, A13, A14, NC2, WE, 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 1, vol2;
   @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..15], @W;      /*                          */
   @Out A [16..16],@W;
   @Out CE       , @W;       /*         Of               */
   @Out OE       , @W;       /* ------------------------ */
   @Out WE	 , @W;
   @Out Vcc	 , @W;
   @Out Vpp	 , @W;
   
   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE       , @H;       /* Out  enable  is High */
   @Out WE	 , @H;
   @Out Vcc	 , @H;
   @Out Vpp	 , @H;

   @Out Vcc	 , @O;       /* Vcc Enable */
   @Delay  100 	 , @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   if (FUNCTION == Program || FUNCTION == Erase) 	init ( 12.5 , 5.0 );
   else   	     	    				init (  5.0 , 5.0 );
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row, kind)	
int	row, kind;		/* kind = 1: Erase   */
{
int  hwhb, hwlb, lwhb, lwlb;	
int  slh, sll, elh, ell, shl, ehl; 
int  tmp, tmp2;

   @Set	B_HADDR, B_LADDR;
   @Inc __B_START__;
   
   lwlb = lwhb = hwhb = hwlb = 0;
   slh = sll = elh = ell = shl = ehl = tmp = tmp2 = 0;
   @Out D [0..7], @Z;	/* Data Input  */
   
   if (FUNCTION == Read ) 
   {
      @Display 26, row, "Reading...";
      @CheckSumON;
   }
   else if (FUNCTION==Verify || kind==1)  @Display 26, row, "Verifying...";
   else if (FUNCTION == Blank_Check)	  @Display 26, row, "Blank Checking...";
   else 			          @Display 26, row, "Data Comparing...";
   
   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;
	 @Out A [16..16], hwlb;   /* Output High word address */
	 
         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_HWLB)   sll = S_LWLB;
            else                  sll = 0;
            if (lwhb == E_HWLB)   ell = E_LWLB;
            else                  ell = 0xFF;
	   
	    for ( lwlb=sll; lwlb<=ell; lwlb++)
	    {
	       @Out A [0..7], lwlb;    /* Low  byte address output */
	       @Out OE      , @L;
	       @Out CE	    , @L;
	       @In D [0..7] , tmp;
	       
	       @Out OE      , @H;
	       @Out CE	    , @H;
	       
	       if      (FUNCTION == Read)          @Load tmp;
	       else if (FUNCTION == Blank_Check)
	       {
		    if (tmp != 0xFF)  Failf(hwhb, hwlb, lwhb, lwlb, tmp);
	       }
	       else if (FUNCTION == Verify)
	       {
		   @Store tmp2;
		   if (tmp != tmp2)  
		   {
		       if (kind == 2)	return (0);	/*  2: Program   */
		       else		Failf (hwhb, hwlb, lwhb, lwlb, tmp);
		   }
	       }
	       else 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 || kind==1) @Display 26, row, "Verification OK!";
   else if (FUNCTION == Blank_Check)	 @Display 26, row, "Blank Check OK!  ";
   else 			         @Display 26, row, "Data Comparison OK!";
   
   if (kind == 2)	return (1);	/* Program Verify Success */
}

/* -----------------------------------------------------------------------
 * erase() ---> Chip Erase Routine
 * ----------------------------------------------------------------------- */
int	erase ()
{   
int	loop;

   @Display 26, 6, "Erasing...";
   @Out D [0..7], @H;
   
   for (loop = 0; loop < 30; loop++)
   {
       @Out CE	, @L;
       @Out WE	, @L;
       @Out CE	, @H;
       @Out WE	, @H;
       @Out Vpp	, @O;
       @Out CE	, @L;
       @Out WE	, @L;       
       @Out CE	, @H;
       @Out WE	, @H;
       @Delay 500  , @ms;
       @Out Vpp	, @F;
   }

   @Delay  250	, @ms;		/*  Erase Recovery Time   */
   FUNCTION = Blank_Check;
   InitProcess ();
   read (7, 1);			/*  1:Erase */
   @Display 26, 6, "Erase 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 , tmp2,  failcnt, m, ret;

   @Set B_HADDR, B_LADDR;
   @Inc	__B_START__;
   
   failcnt = tmp = tmp2 = m = ret = 0;
   lwlb = lwhb = hwhb = hwlb = 0;
   slh = elh = sll = ell = shl = ehl = 0;

   @Out	Vpp	, @O;

   @Display 26, row, "Programming...";
   
   for (m=0; m<10; m++)
   {
   	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++ )   /*  for #3 */
       	    {
	   	@Display 66, 9, hwlb;
        	@Out A [16..16], hwlb;   /* Output High word address */	   	
	   
	   	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++)	/* for #2  */
	       	{
	       	    @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++)	/*  for #1 */
	            {
		  	@Store tmp;
		  
		  	if (tmp == 0xFF)
		       	{
		      	   @Inc  SPLIT;
		      	   continue;
		  	}            
		  
	          	@Out A [0..7], lwlb;
	          	@Out D [0..7], tmp;
	          	@Out CE      , @L;
	          	@Out WE      , @L;
		  	@Out WE	     , @H;
		  	@Out CE	     , @H;
		  	@Delay 100   , @us;		  	
		  
			@Inc	SPLIT;		  
                    }	/*  for #1 : lwlb  */
	       	}       /*  for #2 : lwhb  */
       	    }   	/*  for #3 : hwlb  */
   	}		/*  for #4 : hwhb  */
   }			/*  for #5 	   */
   
   @Display 26, row, "Program OK!   ";
   if (kind == 0)	row = 7;
   else			row = 8;
   @Delay 1500,	@Us;
   
   /* ------- All Byte Verify -------- */
   FUNCTION = Verify;
   InitProcess ();
   for (m=0; m<6; m++)
   {
       ret = read (row, 2);	/*  2: Program      ret==0 : Fail  */
       if (ret != 0)	break;
   }
}
/* -----------------------------------------------------------------------
 * main () ---> Control main
 * ----------------------------------------------------------------------- */
int main ()
{
   InitProcess();
   
   if ( FUNCTION == Auto )
   {
	FUNCTION = Blank_Check;
	read (6, 0);

	FUNCTION = Program;	
        InitProcess();
	program(7, 1);
   }
   else if ( FUNCTION == Program ) program(6, 0);
   else if ( FUNCTION == Erase )   erase ();
   else 			   read (6, 0);
}   
/* ---------------------------- End of program --------------------------- */  