
#define  TRUE   (1)
#define  FALSE  (0)

#define VDD_WIDTH  (6L)
#define VSS_WIDTH  (8L)
#define ALU2_WIDTH (2L)
#define ALU1_WIDTH (1L)
#define POLY_WIDTH (1L)

                                                     /*   n                */
#define  rsa_exp2(n)      (1 << (n))                 /*  2                 */
                                                     /*      p             */
#define  rsa_restp(n,p)     ((n) & (rsa_mask[ p ]))  /* n = 2 + rsa_restp  */
 
#define  rsa_min(a,b)     ((a)>(b)?(b):(a))
 
int  rsa_mask[] = { 0, 1, 3, 7, 15, 31, 63, 127 } ;  /*  rsa_exp2(n)-1  pour le modulo  rsa_restp()  */
 
/*
 *     ARRAY.H
 */
 
void  DEF_ARRAY(), PLACE_ARRAY() ;
void  SET_ARRAY(), SET_SYMAR(), SET_ARSYM() ;
char  *GET_ARRAY() ;
int   GET_SYMAR() ;
 
#define  STOP  ((char  *)NULL)
#define  MORE  ((char  *)CATA_LIB)


static rsa_bit0();
static rsa_gacsa();
static rsa_sub();
static rsa_addsub();
static rsa_gae0();
static rsa_gas0();
static rsa_gaco();
static rsa_gaci();
static rsa_gapg();
static rsa_tranche();
static rsa_diag();
static rsa_inout();
static rsa_busses();
static rsa_thru();
static rsa_virtual();
static rsa_puiss();
static HSTRETCH();

/*
 *
 */

static rsa_lay(n,cin,cout,over,overn,not,csa,sub,addsub,
               deci,stretch,stretch2,name,msb0,virtual)

int  n,cin,cout,over,overn,not,
     csa,sub,addsub,
     deci,stretch,stretch2;
char *name ;
int  msb0,virtual;
{
 static  int   sym[] = { NOSYM, SYM_Y } ;
 int x,i,j,c;


   DEF_PHFIG(name) ;

   c=csa+sub+addsub;
   x=cout+c+3+rsa_puiss(n-1);     /*  Nombre de couches de logique == taille en x de la matrice  */

   DEF_ARRAY(x,n+addsub);

   rsa_bit0(n,cin|sub|addsub,c,cout,not);/*  Le bit0 est un cas particulier                                             */
   if(csa)  rsa_gacsa(n);                /*  Generation d'une couche supplementaire pour un additionneur a 3 operandes  */
   if(sub) rsa_sub(n);                   /*  Generation des nots                                                        */
   if(addsub) rsa_addsub(n,cout);        /*  Generations des xor plus le chapeau                                        */
   rsa_gae0(n,c,not);                    /*  Colonne des cellules d'entrees                                             */
   if(cout) rsa_gaco(n,c);               /*  Colonne des cellules de retenues intermediaires                            */
   rsa_gas0(n,c,cout);                   /*  Colonne des cellules de sorties                                            */
   rsa_gaci(n,c);                        /*  Dernier etage de la propagation de la retenue optimise                     */
   rsa_gapg(n,c);                        /*  Toutes les cellules de propagation                                         */


   for( i = 0 ; i < x ; i++ )           /*  Toutes cellules sur un bit slice impair subit une symetrie  SYM_Y          */

      for( j = 0 ; j < n+addsub ; j++ )   SET_SYMAR( i, j, sym[ j & 1 ] ) ;


   PLACE_ARRAY() ;

   if(virtual) DEF_AB( 0, 0, 0, 0 ) ;
   else DEF_AB(0,-7,0,7);

   rsa_inout(n,cin,csa,sub,addsub,cout,over,deci,overn) ;           /*  Remonte les connecteurs en dur  */

   if(virtual) rsa_virtual(n,cin|sub|addsub,cout,not,csa,sub,addsub,msb0);
   else rsa_busses(n,cout,csa,sub,addsub,msb0);

   rsa_thru(n,cout,csa,sub,addsub,virtual);

   if( stretch && stretch2 )   {
      fprintf(stderr,"\nThe two stretch's option are not allowed together\n");
      exit(20);
     }

	if( stretch )   { int i,slice;
      if(n&3) {
         fprintf(stderr,"\nN modulo 4 must be equal to 0\n" ) ;
         exit(5) ;
        }
      for(i=(n>>2),slice=4;i>0;i--,slice+=10)
        if(i>1)   {HSTRETCH(slice,2,0);i--;}
        else  HSTRETCH(n+((n>>2)&(-2)),1,0);
     }

   if( stretch2 )  { int i,slice;
      if(n&7) {
         fprintf(stderr,"\nN modulo 8 must be equal to 0\n" ) ;
         exit(20) ;
        }
      for(i=(n>>3),slice=8;i>0;i--,slice+=10)
          HSTRETCH(slice,2,1);
     }
}


/*
 *      traitement du bit 0
 */

static rsa_bit0( n, cin, c, cout, not )

int  n, cin, c, cout, not ;

{
 int  i ;               /*  Compteur de couche de routage  */
 int  p ;               /*  Puissance de deux de (n - 1)   */
 int  x ;               /*  Placement dans le tableau      */

 static  char carryout[][ 9 ] = { "gaco_c",  "gacoc_c"   } ;
 static  char  sorties[][ 9 ] = { "gas0f_c", "gas0c_c"   } ;
 static  char  entrees[][10 ] = { "gae0_c",  "gaec0_c",
                                  "gae03_c", "gaec03_c",
                                  "gaen0_c", "gaec0c_c",
                                  "gaen03_c","gaec03c_c" } ;
 static  char  routage[][ 8 ] = { "gaca3_c", "gaca2_c"  } ;


   x = c ;             /*  c == 0  ||  1  */

   SET_ARRAY( x++, 0, entrees[ (not << 2) + cin + (c << 1) ] ) ;

   if( ! cin )   SET_ARRAY( x++, 0, "gaca1_c" ) ;
   else
      SET_ARRAY( x++, 0, STOP ) ;


   p = rsa_puiss( n-1 ) ;

   for( i = 0 ; i < p ; i ++ )  SET_ARRAY( x++, 0, routage[ cin ] ) ;

   if( cout )   SET_ARRAY( x++, 0, carryout[ cin ] ) ;

   SET_ARRAY( x, 0, sorties[ cin ] ) ;
}


/*
 *      Placement des cellules pour une addition a 3 operandes
 */

static rsa_gacsa( n )

int  n ;

{
 int  i ;       /*  Variable balayant les bits  */

 static  char csacell[][ 9 ] = { "gacsa_c", "gacsay_c" } ;


  SET_ARRAY( 0, 0, "gacsaf_c" ) ;
  for( i = 1 ; i < n ; i++ )  SET_ARRAY( 0, i, csacell[ i & 1 ] ) ;

}


static rsa_sub(n)
int n;
{ int i;
   for(i=0;i<n;i++) SET_ARRAY(0,i,"gasub_c");
}


static rsa_addsub(n,cout)
int n,cout;
{ int i;
   for(i=0;i<n;i++) SET_ARRAY(0,i,"gaxr2_c");
   SET_ARRAY(0,n,"gaxr2b_c");
   SET_ARRAY(rsa_puiss(n-1)+3+cout,n,"gasxr2b_c");
}

/*
 *      Placement des cellules d'entrees
 */

static rsa_gae0( n, csa, not )

int   n, csa, not ;

{
 int  i ;       /*  variable balayant les differents bits  */
 int  p ;       /*  La puissance de deux superieur de i  */

 static  char entrees[][ 9 ] = { "gae0_c", "gaen0_c", "gae03_c", "gaen03_c",
                                 "gaen0_c","gae0_c" , "gaen03_c", "gae03_c"  } ;


  for( i = 1 ; i < n ; i++ )   {

     p = rsa_puiss( i ) ;
     if( rsa_restp( i, p ) != 0 )   p++ ;
     p &= 1 ;                            /*  Mise sous forme d'index  */

     if( csa )   p += 2 ;                /*  On utilise les cellule gaex03_c  */

     SET_ARRAY( csa, i, entrees[ p + (not << 2) ] ) ;
    }
}


/*
 *      Placement des cellules de sorties
 */

static rsa_gas0( n, csa, cout )

int  n, csa ;

{
 int  i ;       /*  Variable balayant les bits  */
 int  x ;       /*  Indice pour les cellules de sorties  */

 static  char sorties[][ 9 ] = { "gas0_c", "gas0y_c" } ;

  x = csa + rsa_puiss( n-1 ) + 2 + cout ;                 /*  calcul de la colonne de placement  */

  for( i = 1 ; i < n ; i++ )  SET_ARRAY( x, i, sorties[ i & 1 ] ) ;
}


/*
 *     Intermediate carry.
 */

static rsa_gaco( n, csa )

int  n, csa ;
{
 int x, y ;              /*  Coordonees de l'instance  gaci  traitee  */
 int i ;                 /*  Compteur de cellules  gaci  */

 static  char carryout[][ 9 ] = { "gacon_c", "gaco_c" } ;


  y = n - 1 ;                         /*  Coordonnees de depart  */
  x = csa + 2 + rsa_puiss( n-1 ) ;

  for( i = n-1 ; i > 0 ; i-- )   SET_ARRAY( x, y--, carryout[ rsa_puiss( i ) & 1 ] ) ;
}


/*
 *       Generation des cellules calcul de carry : gaci... + routage
 */

static rsa_gaci( n, csa )

int  n, csa ;
{
 int x, y ;              /*  Coordonees de l'instance  gaci  traitee  */
 int i ;                 /*  Compteur de cellules  gaci  */

 static  char carry[][ 9 ] = {
                               "gaci0_c", "gacin0_c",      /*  p < 2  */
                               "gaci2_c", "gacin2_c",      /*  p < 4  */
                               "gaci4_c", "gacin4_c",      /*  p < 6  */
                               "gaci8_c", "gacin8_c",      /*  p < 8  */
                               "gacid_c", "gacind_c",      /*  p < 10 */
                               "gacip_c", "gacinp_c"       /*  p > 10 */
                             } ;


  y = n-1 ;                         /*  Coordonnees de depart  */
  x = csa + 1 + rsa_puiss(n - 1) ;


  for( i = n - 1 ; i > 0 ; i-- )  {  int  p, fanout ;

     p = rsa_puiss( i ) ;

     if( (i + 1)  !=  rsa_exp2( (p + 1) ) )   fanout = 0 ;
     else
        fanout = rsa_min( (rsa_exp2( (p + 2) ) - 1), (n - 1) )  -  i ;

/*
 *    p  peut nous servir d'indice dans la table maintenant
 */

     p &= 1 ;                     /*  fanout  ==  0  */

     if( fanout > 16 )   p += 10 ;
     else
     if( fanout > 8 )  p += 8 ;
     else
     if( fanout > 4 )  p += 6 ;
     else
     if( fanout > 2 )  p += 4 ;
     else
     if( fanout > 0 )  p += 2 ;
                                                      /*  Rajoutons le routage                     */
     if( fanout != 0 )  {   int  routx, routy ;       /*  Coordonees de l'instance  gaca3 traitee  */
                            int  j            ;       /*  Compteur de cellules  gaca3  a rajouter  */

        routx = x ;
        routy = y - 1 ;

        for( j = i-1 ; j > 0 ; j-- )   SET_ARRAY( routx, routy--, "gaca3_c" ) ;

        SET_ARRAY( x--, y, STOP ) ;
       }

     SET_ARRAY( x, y--, carry[ p ] ) ;
    }
}


/*
 *    Generate - propagate
 */

static rsa_gapg( n, csa )

int  n, csa ;

{
 int  i ;           /*  Balayage des tranches                    */
 int  nbits ;       /*  Nombre de bits valides dans une tranche  */
 int  buff ;        /*  Bufferisation de la 1ere cellules        */
 int  x, y ;        /*  Coordonees de depart d'une tranche       */


  for( i = rsa_puiss( n - 1 ) ; i > 0 ; i-- )  {

     x = csa + i ;

     y = rsa_exp2( (i + 1) ) - 1 ;

     nbits = rsa_min( rsa_exp2( i ), (n - rsa_exp2( i )) ) ;       /*  tjrs > 0  */

     buff = (rsa_exp2( (i + 1) ) + 2)  <  n   ?   2  :  0 ;

     rsa_tranche( i, x, y, nbits, buff ) ;
    }

}


static rsa_tranche( num, x, y, nbits, buff )

int  num ;
int  x, y ;
int  nbits ;
int  buff ;

{
 int  i ;            /*  Balayage des tranches  */
 int  tnbits ;       /*  Nombre de bits valide dans une tranche  */
 int  tbuff ;        /*  Bufferiasation de la 1ere cellules      */
 int  tx, ty ;       /*  Coordonees de depart d'une tranche  */


  for( i = rsa_puiss( nbits - 1 ) ; i > 0 ; i-- )  {

     tx = x - num + i ;

     ty = y - rsa_exp2( num ) + rsa_exp2( (i + 1) ) ;

     tnbits = rsa_min( rsa_exp2( i ), (nbits - rsa_exp2( i )) ) ;   /*  tjrs > 0  */

     tbuff = (rsa_exp2( (i + 1) ) + 2)  <  nbits   ?   2  :  0 ;

     rsa_tranche( i, tx, ty, tnbits, tbuff ) ;
   }

  rsa_diag( num, x, y, nbits, buff ) ;

}


/*
 *    La diagonale de propagate-generate
 */


static rsa_diag( num, x, y, nbits, buff )

int  num ;
int  x, y ;
int  nbits ;
int  buff ;

{
 int  ligne ;
 int  i ;


 static  char buffer[][ 8 ] = { "gai0_c",  "gai0y_c", "gai1_c" } ;
 static  char rout[][ 8 ]   = { "gaca1_c", "gac1y_c", "gaca2_c" } ;

 static  char progen[][ 9 ] = { "gapgn0_c", "gapg0_c",
                                "gapgn2_c", "gapg2_c",
                                "gapgn4_c", "gapg4_c",
                                "gapgn8_c", "gapg8_c",
                                "gapgnd_c", "gapgd_c",
                                "gapgnp_c", "gapgp_c",

                                "gapgm0_c", "gapga0_c",
                                "gapgm2_c", "gapga2_c",
                                "gapgm4_c", "gapga4_c",
                                "gapgm8_c", "gapga8_c",
                                "gapgmd_c", "gapgad_c",
                                "gapgmp_c", "gapgap_c"  } ;

 static  int taille[]     = {  0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
                               0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2  } ;


  if( nbits == rsa_exp2( num ) )      /*  Affichable  */

    SET_ARRAY( x, y, progen[ ((num & 1) + buff) ] ) ;


  y-- ;

  ligne = 1 ;

  for( i = rsa_exp2( num ) - 2 ; i > 0 ; i-- )  {   int  p, fanout ;

     p = rsa_puiss( i ) ;

     if( (i + 1)   !=  rsa_exp2( (p + 1) ) )  fanout = 0 ;
     else
        if( i > (nbits - 1) )  fanout = 0 ;
        else
            fanout = rsa_min( (rsa_exp2( (p + 2) ) - 1), (nbits-1) ) - i ;

/*
 *     p est disponible pour nous servir d'indice dans la table
 */

     p = (++p & 1) ;        

     if( fanout > 16 ) p += 10 ;
     else
     if( fanout > 8 )  p += 8 ;         /*  Cellules sans buffers  */
     else
     if( fanout > 4 )  p += 6 ;
     else
     if( fanout > 2 )  p += 4 ;
     else
     if( fanout > 0 )  p += 2 ;

     if( fanout > 2  &&  (ligne & 1) )  p += 12 ;  

     if( (i + 1) == rsa_exp2( (rsa_puiss( i ) + 1) ) )   {   int  buffx, buffy ;
                                                         int  routx, routy ;
                                                         int  bornesup, borneinf ;
                                                         int  j, puiss2 ;
        puiss2 = rsa_exp2( rsa_puiss( i ) ) ;

        buffx = x ;
        buffy = y - taille[ p ] ;

        bornesup = (i - taille[ p ]) * (ligne & 1) ;
        borneinf = puiss2 ;

        for( j = bornesup ; j >= borneinf ; j -- )  {

            if( j < nbits )  {   int  ind ;                             /*  Il faut placer  */

               ind = (j == i  &&  nbits > (j + 1)) ? (j & 1 ) : 2 ;     /*  gai0  :  gai1  */

               SET_ARRAY( buffx, buffy, buffer[ ind ] ) ;
              }

            buffy-- ;
           }


        routx = x ;
        routy = y - ((ligne & 1)  ?  puiss2  :  taille[ p ] ) ;

        bornesup = (ligne & 1)  ?  (puiss2 - 1) : (i - taille[ p ]) ;

        for( j = bornesup ; j >= 0 ; j-- )  {

           if( j < nbits )   {   int  ind ;                             /*  Il faut placer  */

              ind = (j == i  &&  nbits > (j+1) ) ? (j & 1) : 2 ;        /*  gac1   :  gaca2  */

              SET_ARRAY( routx, routy, rout[ ind ] ) ;
             }

           routy -- ;
          }

        if( taille[ p ] > 0 )  SET_ARRAY( x, y, STOP ) ;

        x-- ;
        ligne++ ;
       }


     if( taille[ p ] == 2 )  {

         i--  ;
         SET_ARRAY( x, y--, MORE ) ;
         SET_ARRAY( x+1, y, STOP ) ;
        }


     if( nbits > i )  SET_ARRAY( x, y, progen[ p ] ) ;

     y-- ;
    }


  i = (nbits == 1) ? 2 : 0 ;

  if( ligne & 1 )  SET_ARRAY( x, y, buffer[ i ] ) ;
  else
     SET_ARRAY( x, y, rout[ i ] ) ;

}


/*
 *   Physical connectors
 */


static rsa_inout(n,cin,csa,sub,addsub,cout,over,deci,overn)
int n,cin,csa,sub,addsub,cout,over,overn,deci;
{
 int   i, j ;
 char  newname[250] ;
 char  insname[250] ;


   i=cout+csa+sub+addsub+rsa_puiss(n-1)+2;
   sprintf( newname, "vss", n ) ;
   COPY_UP_CON( 0L, "vss", "cell0_0", newname ) ;
   sprintf( insname, "cell%d_0", i ) ;
   COPY_UP_CON( 2L, "vss",  insname, newname ) ;
   COPY_UP_CON( 1L, "vss",  insname, "vss" ) ;
   COPY_UP_CON( 0L, "vdd",  insname, "vdd" ) ;
   for( j = 0 ; j < n ; j++ )  {
      if( j & 1 )   {
         sprintf( newname, "vss", n-1-j ) ;
         sprintf( insname, "cell0_%d" , j ) ;
         COPY_UP_CON( 0L, "vss", insname, newname ) ;
         sprintf( insname, "cell%d_%d", i, j ) ;
         COPY_UP_CON( 2L, "vss", insname, newname ) ;
        }
      else   {
         sprintf( newname, "vdd", n-1-j ) ;
         sprintf( insname, "cell0_%d" , j ) ;
         COPY_UP_CON(                 0L, "vdd", insname, newname ) ;
         sprintf( insname, "cell%d_%d", i, j ) ;
         COPY_UP_CON( j || (cin|sub|addsub) ? 3L : 4L, "vdd", insname, newname ) ;
        }
     }
   if(addsub) {
      THRU_CON_H(ALU2,VDD_WIDTH,"vdd",GET_CON_Y(NAME("cell0_%d",n),"vdd",0L));
      THRU_CON_H(ALU2,VSS_WIDTH,"vss",GET_CON_Y(NAME("cell0_%d",n),"vss1",0L));
      sprintf( insname, "cell%d_%d",i, n ) ;
      COPY_UP_CON( 4L, "vss",  insname, "vss" ) ;
      COPY_UP_CON( 3L, "vdd",  insname, "vdd" ) ;
     }
   else
   if(n&1) {
      sprintf( insname,"cell%d_%d",i,n-1) ;
      COPY_UP_CON( 3L, "vss",  insname, "vss" ) ;
      COPY_UP_CON( 2L, "vdd",  insname, "vdd" ) ;
     }
   else {
      sprintf( insname,"cell%d_%d",i,n-1) ;
      COPY_UP_CON( 1L, "vss",  insname, "vss" ) ;
      COPY_UP_CON( 0L, "vdd",  insname, "vdd" ) ;
     }

   sprintf( insname, "cell%d_%d", i, n-1 ) ;
   sprintf( newname, "%s%s", deci ? "deci0" : "cout", (rsa_puiss(n-1)&1) ? "" : "_n" ) ;
   COPY_UP_CON( (long)(n & 1), "g", insname, newname ) ;

   if(cin)   {
      sprintf( insname, "cell%d_%d", i, n-1+addsub ) ;
      COPY_UP_CON(addsub?2L:(long)(n & 1), "cin", insname, "cin" ) ;
     }
   else
   if(sub) {
      sprintf(insname,"cell%d_%d",i,n-1);
      PLACE_VIA_REF(insname,"cin",CONT_VIA);
      PLACE_SEG_REF(insname,"cin",ALU2,VDD_WIDTH,EAST);
     }
   else
   if(addsub) {
      sprintf(insname,"cell%d_%d",i,n);
      WIRE1(ALU1,ALU1_WIDTH,NAME("cell0_%d",n),"s",1L,insname,"cin",1L);
     }

   if( csa )   {
      sprintf( insname, "cell0_%d", n-1 ) ;
      COPY_UP_CON( 0L, "co", insname, "coc" ) ;
     }

   if(addsub) {
      sprintf(insname,"cell0_%d",n);
      COPY_UP_CON(0L,"i",insname,"sub");
     }

/* Nwell connectors */

   i=cout+csa+sub+addsub+rsa_puiss(n-1)+2;

   for( j = 0 ; j< n ; j++ )  { long  href, lref, width ;

      sprintf( insname, "cell0_%d", j ) ;
      href = GET_REF_Y( insname, "nwellh" ) ;
      lref = GET_REF_Y( insname, "nwelll" ) ;
      width = j&1 ? lref-href : href-lref ;
      sprintf( newname, "nwell%d_%d", j<<1, width ) ;
      PHREF( "ref_ref", newname, GET_REF_X( insname, "nwelll"), j&1 ? href+(width>>1) : href-(width>>1) ) ;

      sprintf( insname, "cell%d_%d", i, j ) ;
      href = GET_REF_Y( insname, "nwellh" ) ;
      lref = GET_REF_Y( insname, "nwelll" ) ;
      width = j&1 ? lref-href : href-lref ;
      sprintf( newname, "nwell%d_%d", (j<<1)+1, width ) ;
      PHREF( "ref_ref", newname, GET_REF_X( insname, "nwelll"), j&1 ? href+(width>>1) : href-(width>>1) ) ;
     }
   if(addsub) { long href,lref,ref,width;
      sprintf( insname, "cell0_%d", n ) ;
      href = GET_REF_Y( insname, "nwellh" ) ;
      lref = GET_REF_Y( insname, "nwelll" ) ;
      ref  = GET_REF_Y( insname, "nwell"  ) ;
      width =  href-ref ;
      sprintf( newname, "nwell%d_%d", n<<1, width ) ;
      PHREF( "ref_ref", newname, GET_REF_X( insname, "nwelll"), href-(width>>1) ) ;
      width =  ref-lref ;
      sprintf( newname, "nwell%d_%d", (n+1)<<1, width ) ;
      PHREF( "ref_ref", newname, GET_REF_X( insname, "nwelll"), lref+(width>>1) ) ;
     }

   if( over )  { long  xcon, ycon ;

      sprintf( newname, "over%s", (rsa_puiss( n-2 ) & 1) ? "" : "_n" ) ;
      sprintf( insname, "cell%d_%d", i, n-2 ) ;
      xcon = GET_CON_X( insname, "g", ((n-1)&1) ? 0L : 1L ) ;
      ycon = GET_CON_Y( insname, "g", ((n-1)&1) ? 0L : 1L ) ;
      PHCON( POLY, POLY_WIDTH, newname, EAST, xcon + WIDTH( "gas0_c" ), ycon ) ;
      PHSEG( POLY, POLY_WIDTH, "", xcon, ycon, xcon + WIDTH( "gas0_c" ), ycon ) ;
     }

   if( overn )  { long  xcon, ycon ;

      sprintf( newname, "over%s", (rsa_puiss( n-2 ) & 1) ? "" : "_n" ) ;
      sprintf( insname, "cell%d_%d", i, n-1 ) ;
      COPY_UP_CON( n&1 ? 1L : 0L, "co", insname, newname ) ;
     }

   if( deci )  { int  bitslice ; long  xcon, ycon ;

      bitslice = n-4 ;
      for( j = 3 ; j < n ; j+=4, bitslice-=4 )  {
         sprintf( newname, "deci%d%s", bitslice, (rsa_puiss( j ) & 1) ? "" : "_n" ) ;
         sprintf( insname, "cell%d_%d", i, j ) ;
         xcon = GET_CON_X( insname, "g", (j&1) ? 1L : 0L ) ;
         ycon = GET_CON_Y( insname, "g", (j&1) ? 1L : 0L ) ;
         PHCON( POLY, POLY_WIDTH, newname, EAST, xcon + WIDTH( "gas0_c" ), ycon ) ;
         PHSEG( POLY, POLY_WIDTH, "", xcon, ycon, xcon + WIDTH( "gas0_c" ), ycon ) ;
        }
     }
}

/*
 *
 */

static rsa_busses(n,cout,csa,sub,addsub,msb0)
int n,cout,csa,sub,addsub,msb0;
{ int y,bit,inc,i;

   i=cout+csa+sub+addsub+rsa_puiss(n-1)+2;
   bit=msb0?n-1:0;
   inc=msb0?-1:1;
   for(y=0;y<n;bit+=inc,y++) {
      THRU_CON_H(ALU2,ALU2_WIDTH,NAME("a[%d]",bit),GET_REF_Y(NAME("cell0_%d",y),"a_2"));
      PLACE_VIA_REF(NAME("cell0_%d",y),"a_2",CONT_VIA);
      THRU_CON_H(ALU2,ALU2_WIDTH,NAME("b[%d]",bit),GET_REF_Y(NAME("cell0_%d",y),"b_7"));
      PLACE_VIA_REF(NAME("cell0_%d",y),"b_7",CONT_VIA);
      THRU_CON_H(ALU2,ALU2_WIDTH,NAME("s[%d]",bit),GET_REF_Y(NAME("cell%d_%d",i,y),"s_1"));
      PLACE_VIA_REF(NAME("cell%d_%d",i,y),"s_1",CONT_VIA);
      if(cout) {
         THRU_CON_H(ALU2,ALU2_WIDTH,NAME("co[%d]",bit),GET_REF_Y(NAME("cell%d_%d",i-1,y),"co_3"));
         PLACE_VIA_REF(NAME("cell%d_%d",i-1,y),"co_3",CONT_VIA);
        }
      if(csa) {
         THRU_CON_H(ALU2,ALU2_WIDTH,NAME("c[%d]",bit),GET_REF_Y(NAME("cell0_%d",y),"c_5"));
         PLACE_VIA_REF(NAME("cell0_%d",y),"c_5",CONT_VIA);
        }
     }
}

/*
 *
 */

static rsa_thru(n,cout,csa,sub,addsub,virtual)
int n,cout,csa,sub,addsub,virtual;
{ int i,y,p,t,inc;

   i=cout+csa+sub+addsub+rsa_puiss(n-1)+2;
   for( y = 0 ; y < n ; y++ )
      for( (p=y&1?7:8),(t=y&1?0:9),(inc=y&1?1:-1);p<57;(t+=inc),(p+=5))
         if( p == (y&1 ? 27 : 33) ) {
            if(virtual) {   char  insname[100] ;

               sprintf( insname, "cell0_%d", y ) ;
               if(virtual) PLACE_SEG_REF(insname,(sub+addsub)?"b_4":"a_4",TALU2,2L,WEST);
               sprintf( insname, "cell%d_%d", csa+sub+addsub + rsa_puiss( n-1 ) + 2 + cout, y ) ;
               if(virtual) PLACE_SEG_REF( insname, "s_4", TALU2, 2L, EAST ) ;
              }
           }
         else
         if(virtual||t==0||t==6||t==8||t==9||(t==3&&!cout)||(t==5&&!csa))
            THRU_H( TALU2, 2, y*60 + p ) ;

   if(addsub)
      for(y=0;y<6;y++)
         THRU_H(TALU2,2,GET_REF_Y(NAME("cell%d_%d",i,n),NAME("tp%d",y)));
}


/*
 *   Virtual connectors
 */

static rsa_up_ref( nbref, format, xcell, ycell, bitslice )
int  nbref, xcell, ycell, bitslice ;
char  format[][7] ;
{
 int  i ;
 char form0[250], form1[250], insname[250], newname[250] ;

   for( i = 0 ; i < nbref ; i++ )  {

      sprintf( form0, format[i], "" ) ;
      sprintf( insname, "cell%d_%d", xcell, ycell ) ;
      sprintf( form1, format[i], "[%d]" ) ;
      sprintf( newname, form1, bitslice ) ;
      COPY_UP_REF( form0, insname, newname ) ;
     }
}


static rsa_virtual(n,cin,cout,not,csa,sub,addsub,msb0)
int  n,cin,cout,not,csa,sub,addsub,msb0;
{
 int  y ;
 int  p ;
 int  bit,inc;

static  char  gacsap[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_4", "a%s_5", "a%s_6", "a%s_7",
                                 "b%s_5", "b%s_6", "b%s_7", "b%s_8", "b%s_9",
                                 "c%s_1", "c%s_3", "c%s_5" } ;
static  char  gae0p[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_4", "a%s_5", "a%s_6", "a%s_7",
                                "b%s_6", "b%s_7", "b%s_8", "b%s_9" } ;
static  char  gaen0p[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_4", "a%s_5", "a%s_6", "a%s_7",
                                 "b%s_7", "b%s_8", "b%s_9" } ;
static  char  gaec0p[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_4", "a%s_6", "a%s_7",
                                 "b%s_6", "b%s_7", "b%s_8", "b%s_9" } ;
static  char  gacocp[][ 7 ] = {  "co%s_0", "co%s_1", "co%s_2", "co%s_3", "co%s_5", "co%s_7", "co%s_8", "co%s_9" } ;
static  char  gacop[][ 7 ] = {  "co%s_1", "co%s_3", "co%s_6", "co%s_7", "co%s_8" } ;
static  char  gas0p[][ 7 ] = {  "s%s_1", "s%s_3", "s%s_4", "s%s_6" , "s%s_8" } ;
static  char  gas0yp[][ 7 ] = { "s%s_1", "s%s_3", "s%s_4", "s%s_6" , "s%s_8" } ; 
static  char  gas0cp[][ 7 ] = { "s%s_1", "s%s_3", "s%s_4", "s%s_5" , "s%s_6" , "s%s_8" } ; 
static  char  gas0fp[][ 7 ] = {  "s%s_0", "s%s_1", "s%s_2", "s%s_3", "s%s_4", "s%s_5", "s%s_6", "s%s_7", "s%s_8", "s%s_9" } ;
static  char  gasub[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_5", "a%s_6", "a%s_7", "a%s_8", "a%s_9",
                                "b%s_1", "b%s_2", "b%s_3", "b%s_4", "b%s_5", "b%s_6", "b%s_7" } ;
static  char  gaxr2[][ 7 ] = {  "a%s_0", "a%s_1", "a%s_2", "a%s_3", "a%s_5", "a%s_6", "a%s_7", "a%s_8", "a%s_9",
                                "b%s_3", "b%s_4", "b%s_5", "b%s_7", "b%s_8", "b%s_9" } ;

/*
 *     Bit de poids faible.
 */

   bit=msb0?n-1:0;

   if( csa )   rsa_up_ref( 16, gacsap, 0, 0, bit) ;
   else
   if( sub )   rsa_up_ref( 16, gasub, 0, 0, bit);
   else
   if( addsub )   rsa_up_ref( 15, gaxr2, 0, 0, bit);
   else
   if( cin )   rsa_up_ref( 11, gaec0p, csa+sub+addsub, 0, bit) ;
   else
   if( not )   rsa_up_ref( 11, gaen0p, csa+sub+addsub, 0, bit) ;
   else rsa_up_ref( 12, gae0p, csa+sub+addsub, 0, bit) ;

   if( cout )
      if ( cin )   rsa_up_ref( 8, gacocp, csa+sub+addsub + rsa_puiss( n-1 ) + 2, 0, bit) ;
      else
         rsa_up_ref( 5, gacop, csa+sub+addsub+ rsa_puiss( n-1 ) + 2, 0, bit) ;

   if ( cin )   rsa_up_ref( 6, gas0cp, csa+sub+addsub + rsa_puiss( n-1 ) + 2 + cout, 0, bit) ;
   else
      rsa_up_ref( 10, gas0fp, csa+sub+addsub + rsa_puiss( n-1 ) + 2 + cout, 0, bit) ;

/*
 *     Le reste.
 */


   bit+=(inc=msb0?-1:1);

   for(y=1;y<n;(bit+=inc),y++)   {

         if(csa)
            rsa_up_ref( 16, gacsap,0 , y, bit) ;
         else if(sub)
            rsa_up_ref( 16, gasub,0 , y, bit) ;
         else if(addsub)
            rsa_up_ref( 15, gaxr2,0 , y, bit) ;
         else {
            p = rsa_puiss( y ) ;
            if( rsa_restp( y, p ) != 0 )   p++ ;

            if( p & 1 )   rsa_up_ref( not ? 12 : 11, not ? gae0p : gaen0p, 0, y , bit) ;
            else
               rsa_up_ref( not ? 11 : 12, not ? gaen0p : gae0p, 0, y, bit) ;
           }

      if( cout )
         rsa_up_ref( 5, gacop, csa+sub+addsub + rsa_puiss( n-1 ) + 2, y, bit) ;

      if( y & 1 )
         rsa_up_ref( 5, gas0yp, csa+sub+addsub + rsa_puiss( n-1 ) + 2 + cout, y, bit) ;
      else
         rsa_up_ref( 5, gas0p, csa+sub+addsub + rsa_puiss( n-1 ) + 2 + cout, y, bit) ;
     }
}


                                             /*       p          */
static int  rsa_puiss( n )                   /*  n = 2  +  rest  */
int  n ;
{
 int p = 0 ;

  if( n )    for( p = -1 ; n > 0 ; n >>= 1 )       p++ ;

  return p ;
}


/*----->
 *
 *     In Line Soft  27/09/1990   Version 1.0
 *
 *     Fonctions destinees aux generateurs. Elles permettent un placement relatif independant de la taille des cellules de  base,
 *   meme si l'algorithme de generation n'est pas regulier. Le macro-bloc est represente par une matrice ou les elements sont les
 *   noms des cellules de base composant le macro-bloc. On peut remplir la matrice dans l'ordre que l'on veut. Deux matrices sont
 *   necessaires, une pour les noms de cellules   array   , l'autre pour les symetries apportees a chaques cellules ( instances )
 *   symar  . Il est tout a fait probable que les cellules composant le macro-bloc ne soient pas toutes de memes tailles, il faut
 *   donc que la matrice, dans ce cas, ait plus d'elements que de cellules de base. Ces  elements  supplementaires  devront  etre
 *   affectes a la valeur  STOP  ou  MORE . Une colonne de la matrice est definie par la plus petite cellule. On defini ainsi une
 *   frontiere qui nous sert pour trouver la cellule la plus petite de la colonne suivante.On effectue cette action en partant de
 *   la gauche du macro-bloc. Les memes operations sont necessaires pour definir le nombre de lignes de la matrice, le  point  de
 *   depart ( la ligne 0 ) etant celle du bas du macro-bloc. Quand une cellule occupe plusieurs cases de la matrice, on place  le
 *   nom de la cellule sur la case en bas a gauche, et au Nord, sur cette colonne, de(s)  MORE. Toutes les autres cases  occupees
 *   par la cellule doivent contenir  STOP. Toutes les cases de la matrice de symetries ou se trouve cette cellule  doivent  etre
 *   initialisees.
 *
 *
 *     DEF_ARRAY( x, y )              Definir deux matrices de x*y elements : La Matrice des figures et celle des symetries.
 *
 *     SET_ARRAY( x, y, figname )     Placer la figure de nom  figname  aux coordonnees  x,y. Pas d'actions si  x,y non valides.
 *
 *     SET_SYMAR( x, y, sym )         Placer la symetrie  sym  aux coordonees  x,y. Pas d'actions si  x,y  non  valides. Si  sym
 *                                    n'est pas valide elle est remplacee par  NOSYM  avec message d'erreur.
 *
 *     SET_ARSYM( x, y, fig, sym )    Reunion des deux precedentes fonctions.
 *
 *     GET_ARRAY( x, y )              Fonction qui renvoi le nom de figure placee au coordonnee  x,y. Sauf si  x, y ne sont  pas
 *                                    valides dans ce cas  NULL. Si l'utilisateur n'a pas encore modifiee la case x,y, il y a un
 *                                    message  d'avertissement  uniquement si  MBK_FAST_MODE  sont positionnees.
 *
 *     GET_SYMAR( x, y )              Memes proprietees que la fonction precedente, mais retour de -1 si  x,y non valides.
 *
 *     PLACE_ARRAY()                  Place la matrice des figures avec les symetries associees.
 *
 *
 *     On commence donc par definir les deux dimensions de la matrice  DEF_ARRAY(), puis on utilise les fonctions d'acces, SET_xx
 *   ou  GET_xx, enfin on lance le vrai placement physique  PLACE_ARRAY(). Il y a deux  modes  de  fonctionnement,  l'un protege,
 *   l'autre beaucoup moins. Il sont actif suivant les valeurs de  MBK_FAST_MODE.
 *
 */


/*
 *     DEBUG        Version lente : verifications.
 *     MBKSIZE      Taille d'une chaine de caracteres.
 *     array_issym(sym)   TRUE si sym est une symetrie MBK.
 */

#define   MBKSIZE    80

#define   array_issym(sym)   ( ((sym) >= NOSYM)  &&  ((sym) <= SY_RP) )


#define   EXIT0(n)               {fprintf(stderr,n);exit(6);}
#define   EXIT1(n,a)           {fprintf(stderr,n,a);exit(7);}
#define   EXIT2(n,a,b)       {fprintf(stderr,n,a,b);exit(8);}
#define   EXIT3(n,a,b,c)   {fprintf(stderr,n,a,b,c);exit(9);}
#define   FPR(n)                            fprintf(stderr,n)
#define   FPR1(n,a)                       fprintf(stderr,n,a)
#define   FPR2(n,a,b)                   fprintf(stderr,n,a,b)
#define   FPR3(n,a,b,c)               fprintf(stderr,n,a,b,c)


                /*  Macros d'acces aux matrices  */

#define   ARRAY(x,y)                           (array[ x ][ y ])
#define   SYMAR(x,y)                           (symar[ x ][ y ])
#define   ARSYM(x,y,fig,sym)       ARRAY(x,y)=fig;SYMAR(x,y)=sym


#define   INITA  ((char  *)symar)        /*  Valeur d'initialisation de la matrice  array  */
#define   INITS  (99)                    /*  Valeur d'initialisation de la matrice  symar  */

#define   TRUE   (1)
#define   FALSE  (0)

                                         /*  Variables globales  */
#ifdef   DEBUG
/*   char  ***array = NULL ; */               /*  Matrice cellule de bases  */
/*   int    **symar = NULL ; */               /*  Matrice des symetries     */
#else
/*   char  ***array ; */                      /*  Initialisation inutile pour  */
/*   int    **symar ; */                      /*  une version finale  */
#endif

 char  *array[11][129] ;
 int   symar[11][129] ;

 int   arraymaxx ;                        /*  Dimensions  x  des matrices  */
 int   arraymaxy ;                        /*  Dimensions  y  des matrices  */


/*
 *     Il y a deux solutions d'implementation de tableaux dynamiques : Tableaux de pointeurs ou d'elements. La premiere solution
 *   est celle retenue pour sa rapidite malgre son encombrement memoire plus important. On commence donc par allouer la  memoire
 *   pour former les deux matrices, puis on stocke les deux dimensions afin de verifier par la suite  les  coordonnees  envoyees
 *   par l'utilisateur. Enfin si l'utilisateur le demande, initialisation complete des deux matrices afin de verifier que toutes
 *   les cases ont bien ete initialisees par l'utilisateur.
 *
 */


void  DEF_ARRAY( x, y )
int  x, y ;
{

/*
 *

 int  i ;

#ifdef   DEBUG
   if( (x < 1)  ||  (y < 1) )   EXIT2( "Dimensions in   DEF_ARRAY( %d, %d )  must be positives, > 0\n", x, y ) ; 
#endif


   array = (char ***)mbkalloc( x * sizeof( char *) ) ;
   symar = (int   **)mbkalloc( x * sizeof( char *) ) ;

   for( i = 0 ; i < x ; i++ )  {

      array[ i ] = (char **)mbkalloc( y * sizeof( char *) ) ;
      symar[ i ] = (int   *)mbkalloc( y * sizeof( int   ) ) ;
     }
*
*/
   arraymaxx = x ;
   arraymaxy = y ;

#ifdef   DEBUG
   if( FAST_MODE != 'Y' )   {  int  i, j ;

      for( i = 0 ; i < x ; i++ )
         for( j = 0 ; j < y ; j++ )   { ARRAY( i, j ) = INITA ; SYMAR( i, j ) = INITS ; }
     }
#endif
}

 
/*
 *     La verification de la matrice n'est faite que sur demande de l'utilisateur. On lit ensuite le contenu de la  matrice  des
 *   cellules de base colonne par colonne, la case 0,0 etant celle en bas a gauche. Si une case contient un  MORE  on passe a la
 *   case suivante dans la meme colonne. Si on trouve un  STOP  on fait la meme operation. Si on trouve un nom de figure et  que
 *   la case precedente etait un  MORE  ou une figure( modele ) on effectue un  PLACE_TOP()  de cette cellule. Si la case prece-
 *   dente est un  STOP  il faut rechercher a gauche de la colonne actuelle, sur la meme ligne, une case  contenant  un  nom  de
 *   figure, pour effectuer un  PLACE_RIGHT().
 *
 */


void  PLACE_ARRAY()
{
 int  i ;


#ifdef   DEBUG
   if( array == NULL )   EXIT0( "Can't do a PLACE_ARRAY()  without a  DEF_ARRAY()  before\n" ) ;

   if( FAST_MODE != 'Y' )   check_arrays() ;
#endif


   for( i = 0 ; i < arraymaxx ; i++ )  {  int  j, TOP ;

      TOP = FALSE ;                                  /*  PLACE_TOP()  Interdit en debut de colonne  */

      for( j = 0 ; j < arraymaxy ; j++ )  {  char  *figname, insname[ MBKSIZE ] ;

         figname = ARRAY( i, j ) ;

         sprintf( insname, "cell%d_%d", i, j ) ;

         if( j == 0  &&  i == 0 )  {

               PLACE( figname, insname, SYMAR( i, j ), 0, 0 ) ;
               TOP = TRUE ;
              }

         else

         if( figname == STOP )    TOP = FALSE ;

         else

         if( figname != MORE  &&  TOP )   PLACE_TOP( figname, insname, SYMAR( i, j ) ) ;

         else

         if( figname != MORE  &&  ! TOP )  {  int  ii ;  char  instmp[ MBKSIZE ] ;

            for( ii = i-1 ; ARRAY( ii, j ) == STOP ; ii-- ) ;   /*  On ne peut pas sortir de la matrice car sur la premiere
                                                                    colonne il n'y a pas de STOP  */
#ifdef   DEBUG
            if( ARRAY( ii, j )  ==  MORE )                      /*  Seule valeur connue possible  */
                           EXIT2("ARRAY NON VALID, can't do a PLACE_RIGTH() at ( %d, %d )\n", i, j );
#endif

            sprintf( instmp, "cell%d_%d", ii, j ) ;

            DEF_PHINS( instmp ) ;

            PLACE_RIGHT( figname, insname, SYMAR( i, j ) ) ;

            TOP = TRUE ;
           }
        }
    }
}



/*
 *   Fonction verifiant la coherence des matrices.
 */

#ifdef   DEBUG

check_arrays()
{
 int   FOUND ;
 int  i, j ;


   FOUND = FALSE ;

   for( i = 0 ; i < arraymaxx ; i++ )
      for( j = 0 ; j < arraymaxy ; j++ )

         if( ARRAY( i, j )  ==  INITA )   {

            FPR2( "ARRAY( %d, %d ) has not been modified\n", i, j ) ;
            FOUND = TRUE ;
           }

         else

         if( i == 0  &&  ARRAY( i, j ) == STOP )   {

               FPR1( "There is a STOP on the first column at bitslice %d\n", j ) ;
               FOUND = TRUE ;
              }

   if( FOUND )   FPR( "\n\n\n" ) ;

   for( i = 0 ; i < arraymaxx ; i++ )
      for( j = 0 ; j < arraymaxy ; j++ )

         if( SYMAR( i, j ) == INITS )   {

            FPR2( "SYMAR( %d, %d ) has not been modified\n", i, j ) ;
            FOUND = TRUE ;
           }

   if( FOUND )   FPR( "\n\n\n" ) ;


   if( ARRAY( 0, 0 )  ==  MORE  )   {

      FPR( "Error : ARRAY( 0, 0 )  is equal to MORE\n\n\n" ) ;
      FOUND = TRUE ;
     }

   if( FOUND )   exit( 10 ) ;
}



/*
 *     Fonction verifiant la valeur des coordonnees x, y d'acces a la matrice.
 */


int  check( x, y, fonction )
int        x, y ;
char  *fonction ;
{
   if( x >= arraymaxx  ||  x < 0  ||  y >= arraymaxy  ||  y < 0 )   {

      FPR3( "Coordinates in  %s( %d, %d )  are not valid\n", fonction, x, y ) ;
      return  FALSE ;
     }

   return  TRUE ;
}


/*
 *     Fonctions d'acces aux matrices.
 */


void  SET_ARRAY( x, y, fig )
int  x, y ;
char  *fig ;
{
   if( array == NULL )   EXIT0( "Can't do a  SET_ARRAY()  without a  DEF_ARRAY()  before\n" ) ;

   if( check( x, y, "SET_ARRAY" ) )   ARRAY( x, y ) = fig ;
}


void  SET_SYMAR( x, y, sym )
int  x, y ;
int  sym  ;
{
   if( array == NULL )   EXIT0( "Can't do a  SET_SYMAR()  without a  DEF_ARRAY()  before\n" ) ;

   if( check( x, y, "SET_SYMAR" ) )   {

      if( ! array_issym( sym ) )   {

         FPR2( "Symetrie value in  SET_SYMAR( %d, %d )  is non valid\n", x, y ) ;
         sym = NOSYM ;
        }

      SYMAR( x, y ) = sym ;
     }
}


void  SET_ARSYM( x, y, fig, sym )
int  x, y, sym ;
char  *fig ;
{
   if( array == NULL )   EXIT0( "Can't do a  SET_ARSYM()  without a  DEF_ARRAY()  before\n" ) ;

   if( check( x, y, "SET_ARSYM" ) )   {

      if( ! array_issym( sym ) )   {

         FPR2( "Symetrie value in  SET_ARSYM( %d, %d ) is non valid\n", x, y ) ;
         sym = NOSYM ;
        }

      ARSYM( x, y , fig, sym ) ;
     }
}


char  *GET_ARRAY( x, y )
int  x, y ;
{
   if( array == NULL )   EXIT0( "Can't do a  GET_ARRAY()  without a  DEF_ARRAY()  before\n" ) ;

   if( check( x, y, "GET_ARRAY" ) )   {

      if( FAST_MODE  !=  'Y' )
         if( ARRAY( x, y) == INITA )
            FPR2( "Warning : GET_ARRAY( %d, %d )  not yet modified\n", x, y ) ;

      return  ARRAY( x, y ) ;
     }

   else
       return  NULL ;
}


int  GET_SYMAR( x, y )
int  x, y ;
{
   if( array == NULL )   EXIT0( "Can't do a GET_SYMAR()  without a  DEF_ARRAY()  before\n" ) ;

   if( check( x, y, "GET_SYMAR" ) )   {

      if( FAST_MODE  !=  'Y' )
         if( SYMAR( x, y) == INITS )
            FPR2( "Warning : GET_SYMAR( %d, %d )  not yet modified\n", x, y ) ;

      return  SYMAR( x, y ) ;
     }

   else
       return  -1 ;
}


#else


/*
 *
 *     Les memes fonctions sans les verifications donc pour programmes surs. On pourrait remplacer ces fonctions simples par des
 *   macros C, mais dans ce cas on ne peut plus proteger les variables  array  et  symar  de l'utilisateur.
 *
 */

void  SET_ARRAY( x, y, fig )
int  x, y ;
char  *fig ;
{
   ARRAY( x, y ) = fig ;
}


void  SET_SYMAR( x, y, sym )
int  x, y ;
int  sym  ;
{
   SYMAR( x, y ) = sym ;
}


void  SET_ARSYM( x, y, fig, sym )
int  x, y, sym ;
char  *fig ;
{
   ARSYM( x, y , fig, sym ) ;
}


char  *GET_ARRAY( x, y )
int  x, y ;
{
   return  ARRAY( x, y ) ;
}


int  GET_SYMAR( x, y )
int  x, y ;
{
   return  SYMAR( x, y ) ;
}


#endif
