/* ****************************************************************************
 *    File Name : 27513.D
 *    Pin num	: 28-pin	(A0..A13	D0..D7)
 *    Memory Size : 512K (3FFF)
 *    Last Modify Date : 91. 3. 1 
 * 
 *    Device 	: INTEL  27513     (Vpp=12.5	Vcc=6.0	  Dur=1ms)
 *			 27C513	   (Vpp=12.75   Vcc=6.25  Dur=100us)
 *		  AMD	 *27C513   
 *		  ATMEL	 27C513R   (Vpp=13.0	Vcc=6.5	  Dur=100   LOP=10)
 *			 27C513    (Vpp=12.75	Vcc=6.25  Dur=100)
 * ************************************************************************** */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
      Auto
   ;
   Manufacturers
      AMD
      ATMEL
      INTEL
   ;
   Devices
      D27513 		/*  0st : Vpp=12.5   Vcc=6.0   Dur=1ms   */
      D27C513R		/*  1   : Vpp=13.5   Vcc=6.0   Dur=100us */
      D27C513		/*  2   : Vpp=12.75  Vcc=6.25  Dur=100us */
   ;
   chips = RST, A12, A7, A6, A5, A4, A3, A2, A1, A0, D0, D1, D2, GND,
	   D3, D4, D5, D6, D7, CE, A10, OE:Vpp, A11, A9, A8, A13, 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 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 WE	 , @W;	     /*        Port		 */
   @Out OE       , @W;       /* ------------------------ */
   @Out RST	 , @W;
   @Out Vcc	 , @W;
   @Out __GANG__[0..3], @W;

   @Out CE       , @H;       /* Chip enable  is High */
   @Out OE	 , @L;
   @Out WE	 , @H;
   @Out RST	 , @H;
   @Out Vcc	 , @L;
   @Out __GANG__[0..3], @H;
   
   @Out Vcc      , @O;       /* Vcc Enable */
   @Delay 100	 , @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   if (FUNCTION != Program) init ( 5.0 , 5.0 );
   else   
   {
       if      (DEVICE == D27513)	init (12.5 , 6.0 );
       else if (DEVICE == D27C513)	init (13.0 , 6.5);
       else				init (12.75, 6.25);
   }
}
/* -----------------------------------------------------------------------
 *   SelectPage (): Page Select Operation
 * ----------------------------------------------------------------------- */
int SelectPage (page)
int page;
{	   
   page >>= 6;
   if (GANG == 0)	@Out CE     	   , @L;
   else			@Out __GANG__[GANG], @L;
	   
   @Out OE     , @H;
   @Out WE     , @L;
   @Out D[0..1], page;
   @Out WE     , @H;
	   
   if (GANG == 0)	@Out CE        	   , @H;
   else			@Out __GANG__[GANG], @H;
}
/* -----------------------------------------------------------------------
 * read () ---> read processing
 * ----------------------------------------------------------------------- */
int read (row)
int	row;
{
int  hwhb, hwlb, lwhb, lwlb;
int  tmp, tmp2, sll, ell, slh, elh;

   @Set B_HADDR, B_LADDR;
   @Inc	__B_START__;
   
   lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh = tmp = 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..7], @Z;	/* Data Input  */
   @Out OE	,@H;
   
   for ( hwhb=0 /* S_HWHB */ ; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
      @Display 64, 9, hwhb;
      
      for ( hwlb=S_HWLB ; hwlb<=E_HWLB ; 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 == 0 || lwhb == 0x40 || lwhb == 0x80 || lwhb == 0xC0)
            {
               @Out D [0..1], @W;
               SelectPage (lwhb);
               @Out D [0..1], @Z;
            }
	    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 */
	       
	       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 == Data_Compare) 
	       {
	       	    @Store   tmp2;
	       	    @Compare tmp, tmp2;
	       }
	       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;
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh;
int  tmp , tmp2, failcnt, lopnum, Dur, i;

   @Set B_HADDR, B_LADDR;
   @Inc	__B_START__;
   
   failcnt = lopnum = Dur = tmp = tmp2 = i= 0;
   lwlb = lwhb = hwhb = hwlb = sll = ell = slh = elh= 0;
   
   if (DEVICE == D27C513R) lopnum = 10;
   else			   lopnum = 25;
   if (DEVICE == D27513)   Dur = 1000;
   else			   Dur = 100;   
   
   @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;
               if (lwhb == 0 || lwhb == 0x40 || lwhb == 0x80 || lwhb == 0xC0)
               {
                  SelectPage (lwhb);
                  @Out OE, @L;
               }
                  
	       @Out A [8..13], 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;
		  
		  if (tmp == 0xFF)
		  {
		       @Inc 	SPLIT;
		       continue;
		  }

	          @Out A [0..7], lwlb;		  
		  @Out D [0..7], tmp;	          
		  @Out Vpp     , @O;
		  
 		  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;

		  @Out D [0..7], @Z;
		  @Out Vpp     , @F;
 		                    	
		  /* -------- Verify --------- */
		  if (GANG == 0)	@Out CE            , @L;
		  else			@Out __GANG__[GANG], @L;
	          @In  D [0..7], tmp2;
	          if (GANG == 0)	@Out CE            , @H;
	          else 			@Out __GANG__[GANG], @H;
		  @Out D [0..7], @W;
		  
		  if (tmp != tmp2)
                  {
		     if (failcnt > lopnum) 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 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 --------------------------- */  