/* ****************************************************************************
 *    File Name : 2816.D  (Electrical Eraser PROM)
 *    Pin num   : 24-pin        (A0..A10        D0..D7)
 *    Memory Size : 16K (7FF)
 *    Last Modify Date : 91. 3. 15
 *
 *    |---------- Vpp:0  Vcc:5.0  Dur:10ms ---------------|
 *    Device    :*CSI           28C16A-20(28C16AI)      28C16A
 *                EXEL          2816A
 *               *INTEL         2816A   2816
 *                OKI           28C16A	2816A
 *                XICOR         2816A
 *                SAMSUNG       *2816A  28C16
 *    |---------- Vpp:0  Vcc:5.0  Dur:5ms ---------------|
 *                SEEQ          5516A   2816A (max:10ms)  2816AH
 *                XICOR         2816B   2816BMB
 *    |---------- Vpp:0  Vcc:5.0  Dur: 500us ---------------------------------|
 *                ATMEL         28HC16  28HC16L       28C16
 *               *GI            28C16A
 *                MICROCHIPS    28C16A   *2816                   
 *                HITACHI      *48016
 *		  NS		*2816	  9816A
 *    |------------------------- Vpp:0  Vcc:5.0  Dur: 100us ------------------|
 *                ATMEL         28C16E	28C16F 
 * ************************************************************************** */
declaration
   dataunit : byte;
   functions
      Program
      Read
      Verify
      Blank_Check
      Data_Compare
   ;
   Manufacturers
      CSI               /* 0: 10ms  */
      EXEL		/* 1 */
      INTEL		/* 2 */
      OKI		/* 3 */
      XICOR		/* 4 */
      SAMSUNG           /* 5 */
      SEEQ		/* 6 */
      ATMEL             /* 7: 500us */
      GI    
      MICROCHIP      
      HITACHI
      NS
   ;
   Devices
      D2816
      D2816A
      D28C16
      D28C16E
      D28C16F
      D28C16A
      D28C16A_20
      D5516A
      D2816AH
      D2816B            /*  7: 5ms  */
      D2816BMB
      D28HC16           /*  9:500us */
      D48016
      D9816A
   ;
   chips = A7, A6, A5, A4, A3, A2, A1, A0, D0, D1, D2, GND,
           D3, D4, D5, D6, D7, CE, A10, OE, WE, A9, A8, Vcc;
   $v2 = OE;
   $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 (vol3)
voltage vol3;
{
   @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..10], @W;       /*   Initial Direction      */
   @Out CE       , @W;       /*         Of               */
   @Out WE       , @W;       /*        Port              */
   @Out OE       , @W;       /* ------------------------ */
   @Out Vcc      , @W;
   @Out __GANG__[0..3], @W;

   @Out CE       , @H;
   @Out OE       , @H;
   @Out WE       , @H;
   @Out __GANG__[0..3], @H;
   
   @Out Vcc      , @O;       /* Vcc Enable */
   @Delay 100    , @us;
}
/* -----------------------------------------------------------------------
 * InitProcess () ---> Initial Buffer | Voltage source
 * ----------------------------------------------------------------------- */
int InitProcess ()
{
   init ( 5.0 );
}
/* ---------------------------------------------------------------------
 * read () ---> read processing
 * --------------------------------------------------------------------- */
int read (row)
int     row;
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh;
int  tmp, tmp2;

   lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh = 0;
   tmp = tmp2 = 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 /* S_HWLB */; hwlb<=0 /* 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..10], 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 */
               
               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);
               }
               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)         @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 ()
{
int  hwhb, hwlb, lwhb, lwlb;
int  sll, ell, slh, elh;
int  tmp , tmp2, Dur;

   @Set  B_HADDR, B_LADDR;
   @Inc  __B_START__; 
   
   tmp = tmp2 = 0;   
   lwlb = lwhb = hwhb = hwlb = 0;
   sll = ell = slh = elh =  Dur = 0;
   
   if 	   (MFG == ATMEL)	
   {
   	if (DEVICE == D28C16E || DEVICE == D28C16F)	Dur = 100;
   	else						Dur = 500;
   }	   
   else	if (MFG == SEEQ)	Dur = 5000;
   else if (MFG == XICOR)
   {
   	if (DEVICE == D2816A)	Dur = 10000;
   	else 			Dur = 5000;
   }
   else if (MFG <= 6)   	Dur = 10000;
   else                 	Dur = 500;
        
   @Display 26, 6, "Programming...";      

/* -------- Initial Process to Program device   --------- */
   @Out OE        , @L; 
   
   for ( hwhb=0 /* S_HWHB */; hwhb<=0 /* E_HWHB */; hwhb++ )
   {
       @Display 64, 9, hwhb;
       for ( hwlb=0 /* S_HWLB */; hwlb<=0 /* 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..10], 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;
                  
                  @Out A [0..7], lwlb;
                  @Out OE      , @H;
                  if (GANG == 0)        @Out CE            , @L;
                  else                  @Out __GANG__[GANG], @L;
                  @Out WE      , @L;
                  @Out D [0..7], tmp;                             
                  
                  if (GANG == 0)        @Out CE            , @H;
                  else                  @Out __GANG__[GANG], @H;
                  @Out WE      , @H;
                  @Out OE      , @L;
                  
                  @Delay  Dur  , @us;   /*  write cycle time delay */
                  
                  /* -------- Verify --------- */
                  @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 (tmp != tmp2)      Failf (hwhb, hwlb, lwhb, lwlb, tmp2);       
                  
                  if (GANG == 0)        @Out CE            , @H;
                  else                  @Out __GANG__[GANG], @H;
                  
                  @Out D [0..7], @W;
                  
                  @Inc SPLIT;             
               }
           }
       }
   }
   @Display 26, 6, "Program OK!   ";
   FUNCTION = Verify;
   read (7);            /*  Verify  */
}

/* -----------------------------------------------------------------------
 * main () ---> Control main
 * ----------------------------------------------------------------------- */
int main ()
{
   InitProcess();

   if ( FUNCTION == Program )   program();
   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 --------------------------- */ 
 