/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur Logique                                       */
/*    Fichier :  sl_corps.c                                                 */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) :  L. Burgun                            le : 01/08/1991     */
/*                                                                          */
/*    Modifie par :                                     le : 14/09/1992     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include MUT_H
#include LOG_H
#include BEH_H
#include "../ablorder/sl_order.h"
#include "../compil/lax_param.h"
#include "../param/sl_param.h"
#include "../synthe/sl_type.h"
#include "../synthe/sl_system.h"
#include "../compil/sl_util.h"
#include "sl_corps.h"
#include "titres.h"


/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int MENU( Titre, NbrOptions, ListOptions )

	char *Titre;
	int   NbrOptions; 
	char *ListOptions[];
	{
	char *debut = (char *) mbkalloc ( 2 * MaxString );
	char *milieu = (char *) mbkalloc ( 2 * MaxString );
	char *fin = (char *) mbkalloc ( 2 * MaxString );
	char  ListChoix[MaxString];
	char  Choix;
	int   NumOption;

	RazEcran;
        gotolc(2,2);
  printf("                      Chaine de CAO & VLSI   Alliance\n");
  printf("    ===========================================================\n");
  printf("    (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI\n");
  printf("    All right reserved\n");
  printf("    Support : e-mail cao-vlsi@masi.ibp.fr\n");
  printf("    ===========================================================\n");
  printf("    %s\n",SL_VERSION);
  printf("\n\n\n");
  printf( "\t FUNCTION :  \t%s\n\n\n", Titre );
	
  debut[0] = '\0'; milieu[0] = '\0'; fin[0] = '\0';
	for( NumOption = 0; NumOption < NbrOptions; NumOption ++ )
		{
		if( sscanf( ListOptions[NumOption], "%[^<>] <%[A-Z_]> %[^<>]",
				debut, milieu, fin ) == 1 )
			printf( "   %s\n", debut );
		else
			{
			printf( "   %s<", debut );

			if( strcmp( milieu, "SL_PARAM" ) == 0 )
			   strcpy( milieu, SL_PARAM );
			if( strcmp( milieu, "SL_FILEPAR" ) == 0 )
			   strcpy( milieu, SL_FILEPAR );
			if( strcmp( milieu, "SL_FILE" ) == 0 )
			   strcpy( milieu, SL_FILE );
			if( strcmp( milieu, "SL_OPTIM" ) == 0 )
			   {
			   milieu[0] = SL_OPTIM + 48;
			   milieu[1] = '\0';
			   };
			if( strcmp( milieu, "SL_LEVEL" ) == 0 )
			   {
			   milieu[0] = SL_LEVEL + 48;
			   milieu[1] = '\0';
			   };
			if( strcmp( milieu, "SL_AUX" ) == 0 )
			   {
			   milieu[0] = SL_AUX + 48;
			   milieu[1] = '\0';
			   };
			if( strcmp( milieu, "SL_DELAYPI" ) == 0 )
			   strcpy( milieu,
				itoa( countPtype_list( SL_DELAYPI ) )
			         );
			if( strcmp( milieu, "SL_GUARDEDAUX" ) == 0 )
			   strcpy( milieu,
				itoa( countPtype_list( SL_GUARDEDAUX ) )
			         );
			if( strcmp( milieu, "SL_OPTIMPO" ) == 0 )
			   strcpy( milieu,
				itoa( countChain_list( SL_OPTIMPO ) )
			         );
			if( strcmp( milieu, "SL_CATA_LIB" ) == 0 )
			  strcpy( milieu, SL_CATA_LIB );
			if( strcmp( milieu, "SL_CCCC_LIB" ) == 0 )
			  strcpy( milieu, SL_CCCC_LIB );
			if( strcmp( milieu, "SL_NUMTRANSN" ) == 0 )
			   strcpy( milieu, itoa( SL_NUMTRANSN ) );
			if( strcmp( milieu, "SL_NUMTRANSP" ) == 0 )
			   strcpy( milieu, itoa( SL_NUMTRANSP ) );
			printf( "%s", milieu );
			printf( "> %s\n", fin );
			};
		ListChoix[NumOption] = ListOptions[NumOption][1];
		debut[0] = '\0'; milieu[0] = '\0'; fin[0] = '\0';
		}
	ListChoix[NbrOptions] = '\0';
#if MACHINE != pc
	mbkfree( (void *) debut );
	mbkfree( (void *) milieu );
	mbkfree( (void *) fin );
#endif

	do {
 	   gotolc( 24, 5 );
	   Choix = toupper( AuVol() );
	   }
	while( strchr( ListChoix, Choix ) == NULL && Choix == 'q');
	return( Choix );
	}


/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireDelai( entree, delai, premLig )

	char *entree;
	char *delai;
	int   premLig;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *avant = (char *) mbkalloc( 4 * MaxString );
	char *delimit = (char *) mbkalloc( 4 * MaxString );
	char *apres = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	   RazEcran;
	   gotolc( 2, 21 ); presentDelai;
           printf("\n\n");
   	   displayPtype_list( SL_DELAYPI, colMax, ligMax, premLig );
           printf("\n\n");
	   gotolc( 23, 1 ); RazFinLigne;
           DemandeDelai; RazFinLigne;
	   gets( chaine );
	   if ( chaine[0] == '\0' )
	      {
              gets( chaine );
	      if( chaine[0] == '\0' ) return( 1 );
              }
	   if( sscanf( chaine, "%s %[0-9.,]", entree, delai ) < 2 )
		{
		gotolc( 23, 1 ); RazFinLigne; Beep;
		printf( "Please, respect the format !\n" ); RazFinLigne;
		Continue; 
		}
	   else	if( inChain_list( SL_DELAYPI, entree ) )
		   {
		   gotolc( 23, 1 ); RazFinLigne; Beep;
		   printf( "This input is already in the list\n" );
		   RazFinLigne; 
		   Continue; 
		   }
                   else break;
	   }

		/* on passe en pico-secondes */

	strcpy( delai, strcat( delai, "000" ) );
	if( strchr( delai, '.' ) != NULL | strchr( delai, ',' ) != NULL )
		{
		if(
		sscanf( delai, "%[0-9]%[,.]%[0-9]", avant, delimit, apres )
		  < 3 )
			{
			delai[0] = '0';
			delai[3] = '\n';
			}
		else		
			strcpy( delai, strncat( avant, apres, 2 ) );	
		};
	delimit[0] = '\0';
	apres[0] = '\0';
	avant[0] = '\0';
	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
	mbkfree( (void *) avant );
	mbkfree( (void *) delimit );
	mbkfree( (void *) apres );
#endif
	return( 0 );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireModif( entree, delai, premLig )

	char *entree;
	char *delai;
	int   premLig;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *avant = (char *) mbkalloc( 4 * MaxString );
	char *delimit = (char *) mbkalloc( 4 * MaxString );
	char *apres = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	      RazEcran;
	      gotolc( 2, 21 ); presentDelai;
   	      displayPtype_list( SL_DELAYPI, colMax, ligMax,
				premLig );
	   gotolc( 23, 1 ); RazFinLigne; DemandeModif; RazFinLigne;
	   printf( "%s : ", entree );
	   gets( chaine );
	   if( chaine[0] == '\0' ) return( 1 );
	   if( sscanf( chaine, "%[0-9.,]", delai ) < 1 )
		{
		gotolc( 23, 1 ); RazFinLigne; Beep;
		printf( "Please, respect the format !\n" ); RazFinLigne;
		Continue; 
		}
	   else	break;
	   }

	strcpy( delai, strcat( delai, "000" ) );
	if( strchr( delai, '.' ) != NULL | strchr( delai, ',' ) != NULL )
		{
		if(
		sscanf( delai, "%[0-9]%[,.]%[0-9]", avant, delimit, apres )
		  < 3 )
			{
			delai[0] = '0';
			delai[3] = '\n';
			}
		else		
			strcpy( delai, strncat( avant, apres, 2 ) );	
		};
	delimit[0] = '\0';
	apres[0] = '\0';
	avant[0] = '\0';
	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
	mbkfree( (void *) avant );
	mbkfree( (void *) delimit );
	mbkfree( (void *) apres );
#endif
	return( 0 );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireIntermediate( entree, premLig )

	char *entree;
	int   premLig;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *aux = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	   RazEcran;
	   gotolc( 2, 21 ); presentSorties;
           printf("\n\n");
   	   displayChain_list( SL_GUARDEDAUX, colMax, ligMax, premLig );
           printf("\n\n");
	   gotolc( 23, 1 ); RazFinLigne; DemandeSorties; RazFinLigne;
	   gets( chaine );
	   if ( chaine[0] == '\0' )
	      {
              gets( chaine );
	      if( chaine[0] == '\0' ) return( 1 );
              }
	   if( sscanf( chaine, "%s %s", entree, aux ) > 1 )
		{
		gotolc( 23, 1 ); RazFinLigne; Beep;
		printf( "Please, respect the format !\n" ); RazFinLigne;
		Continue; 
		}
	   else	if( inChain_list( SL_GUARDEDAUX, entree ) )
		   {
		   gotolc( 23, 1 ); RazFinLigne; Beep;
		   printf( "This output is already in the list\n" );
		   RazFinLigne; 
		   Continue; 
		   }
		   else break;
	   }

	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
#endif
	return( 0 );
	}
/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireSortie( entree, premLig )

	char *entree;
	int   premLig;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *aux = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	   RazEcran;
	   gotolc( 2, 21 ); presentSorties;
           printf("\n\n");
   	   displayChain_list( SL_OPTIMPO, colMax, ligMax, premLig );
           printf("\n\n");
	   gotolc( 23, 1 ); RazFinLigne; DemandeSorties; RazFinLigne;
	   gets( chaine );
	   if ( chaine[0] == '\0' )
	      {
              gets( chaine );
	      if( chaine[0] == '\0' ) return( 1 );
              }
	   if( sscanf( chaine, "%s %s", entree, aux ) > 1 )
		{
		gotolc( 23, 1 ); RazFinLigne; Beep;
		printf( "Please, respect the format !\n" ); RazFinLigne;
		Continue; 
		}
	   else	if( inChain_list( SL_OPTIMPO, entree ) )
		   {
		   gotolc( 23, 1 ); RazFinLigne; Beep;
		   printf( "This output is already in the list\n" );
		   RazFinLigne; 
		   Continue; 
		   }
		   else break;
	   }

	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
#endif
	return( 0 );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireMot( mot )

	char *mot;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *aux = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	   gets( chaine );
	   if( chaine[0] == '\0' ) return( 1 );
	   if( sscanf( chaine, "%s %s", mot, aux ) > 1 )
		{
		RazFinLigne; Beep;
		printf( "Please, give a simple name\n" ); RazFinLigne;
		printf( "\033[2A" ); RazFinLigne; gotolc( 10, 4 );
		}
	   else break;
	   }

	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
#endif
	return( 0 );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
int lireEntier( entier )

	char *entier;
	{
	char *chaine = (char *) mbkalloc( 4 * MaxString );
	char *aux = (char *) mbkalloc( 4 * MaxString );

	while( 1 )
	   {
	   gets( chaine );
	   if( chaine[0] == '\0' ) return( 1 );
	   if( sscanf( chaine, "%[0-9] %s", entier, aux ) > 1 )
		{
		RazFinLigne; Beep;
		printf( "Please, give a simple number\n" ); RazFinLigne;
		printf( "\033[2A" ); RazFinLigne; gotolc( 10, 4 );
		}
	   else if( entier[0] == '\0' )
		   {
		   Beep;
		   printf( "I wait for a number!\n" ); RazFinLigne;
		   printf( "\033[2A" ); RazFinLigne; gotolc( 10, 4 );
		   }
		else break;
	   }

	chaine[0] = '\0';

#if MACHINE != pc
	mbkfree( (void *) chaine );
#endif
	return( 0 );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void EDITION ()
	{
	char Action[2*MaxString];

	strcpy( Action, genNAME("vi +%d ",BVL_LINNUM));
	system( strcat( Action, SL_VHDL ) );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void OPTIM_DECOMP ()
	{
        ptype_list *delayPI;
	char *name;
        int vhb_reorder = 0; 

        RazEcran;
        gotolc(1,1);
        if (!fopen(SL_VHDL,"r"))
           {
           printf("The file %s doesn't exist ...\n",SL_VHDL);
           printf("*** Compilation aborted...\n");
           Continue;
           AuVol();
           return;
           }

 
        if (SL_MAKEORDER > 1)
           vhb_reorder = 2; 

        putenv((char *) genNAME("MBK_CATA_LIB=%s",SL_CATA_SAVE));
        mbkenv();


       	if ((SL_ORDERPI = compileVHDL(SL_VHDL,SL_ORDERPI,SL_ORDER,SL_PAR,SL_AUX,				      1,vhb_reorder,1,1,nameInt,NULL)) != NULL)
           {

           putenv((char *) genNAME("MBK_CATA_LIB=%s:%s",SL_CATA_LIB,SL_CCCC_LIB));
           mbkenv();

           SL_BEH = VHB_HEDFIG;

           verifCohBeh(SL_BEH,SL_DELAYPI,SL_OPTIMPO);


           anealingFOOD(SL_TRACE);

				/* sauvegarde du fichier */

           decompileVHDL(SL_BEH,SL_FILEOUT,1);

           resetBdd();

		/* desallocation du fichier a synthetiser */

           freechain(SL_GUARDEDAUX);
           (sl_sys->par)->intermediate = NULL;

           VHB_HEDFIG = VHB_HEDFIG->NEXT;
           AuVol();
           Continue;
           }
        else
           {
           printf("*** Compilation aborted...\n");
           AuVol();
           Continue;
           }
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void PROJECTION (mode)
char *mode;
	{
        ptype_list *delayPI;
	char *name;

        RazEcran;
        gotolc(1,1);

        if (!fopen(SL_VHDL,"r"))
           {
           printf("The file %s doesn't exist ...\n",SL_VHDL);
           printf("*** Compilation aborted...\n");
           Continue;
           AuVol();
           return;
           }


 
        putenv((char *) genNAME("MBK_CATA_LIB=%s",SL_CATA_SAVE));
        mbkenv();

       	if ((SL_ORDERPI = compileVHDL(SL_VHDL,SL_ORDERPI,SL_ORDER,SL_PAR,SL_AUX,1,1,0,1,nameInt,NULL)) != NULL)
           {

           putenv((char *) genNAME("MBK_CATA_LIB=%s:%s",SL_CATA_LIB,SL_CCCC_LIB));
           mbkenv();

           SL_BEH = VHB_HEDFIG;
           verifCohBeh(SL_BEH,SL_DELAYPI,SL_OPTIMPO);

          	/* elimination des DC */
 
           removeDCBeh(SL_BEH);
           mapCarExprBeh(SL_BEH,simplif10Expr);

           if (!strcmp(mode,"C4"))
              mappingC4();
           else
	      mappingSC();

			/* sauvegarde du fichier comportemental */

		/* desallocation du fichier a synthetiser */

           freechain(SL_GUARDEDAUX);
           (sl_sys->par)->intermediate = NULL;
           VHB_HEDFIG = VHB_HEDFIG->NEXT;
           AuVol();
	   Continue;
           }
        else
           {
           printf("*** Compilation aborted...\n");
           AuVol();
           Continue;
           }
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void SAUVERNOM ()

	{
	char Archi[MaxString];
        char file[MaxString];

	RazEcran;
	gotolc( 3, 1 );
	DemandeFic;
	scanf( "%15s1", Archi );fflush( stdin );
        if (!strcmp(Archi,"!")) return;
        file[0] = '\0';
        if (strcmp(SL_PAR_LIB,"."))
           {
           strcat( file,SL_PAR_LIB);
           strcat( file,"/");
           }
	strcat( file, Archi);
	strcat( file, ".lax" );
	saveParam(SL_PAR,file);
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void COPIER ()

	{
	char Archi[MaxString];
        char file[MaxString];

	RazEcran;
	gotolc( 3, 1 );
	listeDe(SL_PAR_LIB,"lax" );
	DemandeFic;
	scanf( "%15s1", Archi );fflush( stdin );
        if (!strcmp(Archi,"!")) return;
        file[0] = '\0';
        if (strcmp(SL_PAR_LIB,"."))
           {
           strcat( file,SL_PAR_LIB);
           strcat( file,"/");
           }
	strcat( file, Archi);
	strcat( file, ".lax" );
	saveParam(SL_PAR,file);
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void TRAVAIL_AUTRE ()
	{
	char *Archi;
        char *file;
        param *autre;

	Archi = (char *) malloc (MaxString);
	file = (char *) malloc (MaxString);

	RazEcran;
	gotolc( 3, 1 );

	do {
	listeDe(SL_PAR_LIB, "lax" );
	DemandeFic;
	scanf( "%15s1", Archi );fflush( stdin );

		/* archi = toto.lax */

        if (!strcmp(Archi,"!")) return;
        strcat(Archi,".lax");

		/* file = path/toto.lax */

        file[0] = '\0';
        if (strcmp(SL_PAR_LIB,"."))
           {
           strcat( file,SL_PAR_LIB);
           strcat( file,"/");
           }
	strcat( file, Archi);
	} while ((autre = loadParam(file)) == NULL);

        if (autre != NULL)
           {
           SL_PAR = autre; 
           SL_PARAM = file;
           SL_FILEPAR = Archi;
           }
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void SUPPRIMER ()
	{
	char Action[2*MaxString];
	char file[MaxString];

        if (strcmp(SL_PARAM,"default.lax"))
     	   {
	   strcpy( Action, "rm " );
	   system( strcat( Action, SL_PARAM ) );

           file[0] = '\0';
           if (strcmp(SL_PAR_LIB,"."))
              {
              strcat( file,SL_PAR_LIB);
              strcat( file,"/");
              }
	   strcat( file, "default.lax");

           SL_PAR = initializeParam(2,0,2,NULL,NULL,NULL,4,4);
           SL_PARAM = namealloc(file);
           SL_FILEPAR = namealloc("default.lax");
	   }
	}



/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void MODE_OPTIM ()
	{
	char Choix;

	RazEcran;
        printf("\n");
	gotolc( 5, 14 );
	printf( "Actual mode : %i\n", SL_OPTIM );
	gotolc( 9, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 10, 14 );
	printf( "-                     CODING                        -\n" );
	gotolc( 11, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 12, 14 );
	printf( "- OPTIMIZATION MODE   0      1      2      3      4 -\n" );
	gotolc( 13, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 14, 14 );
	printf( "- TIME   (%%)         0     30     50     70    100 -\n" );
	gotolc( 15, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 16, 14 );
	printf( "- AREA   (%%)       100     70     50     30      0 -\n" );
	gotolc( 17, 14 );
	printf( "-----------------------------------------------------\n" );
	do {
	gotolc( 20, 14 );
	printf( "Please, give the new mode ([0..4]) : " );
	gotolc( 21, 14 );
        printf("\n");
        printf("\n");
	   }
	while( strchr( "\n01234", Choix = AuVol() ) == NULL );
	if (Choix > 47 && Choix < 53) SL_OPTIM = Choix-48;
	}
/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void NIVEAU_OPTIM ()
	{
	char Choix;

	RazEcran;
	gotolc( 5, 14 );
	printf( "Actual level : %i\n", SL_LEVEL );
	gotolc( 9, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 10, 14 );
	printf( "-                     CODAGE                        -\n" );
	gotolc( 11, 14 );
	printf( "-----------------------------------------------------\n" );
	gotolc( 12, 14 );
	printf( "- 1           minimum optimization \n"); 
	gotolc( 13, 14 );
	printf( "- 2                    |\n\n" );
	gotolc( 15, 14 );
	printf( "- 3                    |\n\n" );
	gotolc( 17, 14 );
	printf( "- 4                    V\n\n" );
	gotolc( 19, 14 );
	printf( "- 5           maximum optimization \n"); 
	gotolc( 20, 14 );
	printf( "-----------------------------------------------------\n" );
	do {
	gotolc( 22, 14 );
	printf( "give the new level (in [1..5]) " );
	   }
	while( strchr( "\n12345", Choix = AuVol() ) == NULL );
	if (Choix > 47 && Choix < 54) SL_LEVEL = Choix-48;
	}


/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void ENTREES ()
	{
	int paragDebut,
	    paragFin,
	    largeurCol,
	    numCol,
	    reste, supr, c,
	    ligFin, colFin,
	    rang,
	    lig, 
	    col;
	char Choix;
	char *time = (char *) mbkalloc( MaxString );
	char *data = (char *) mbkalloc( MaxString );
	supr = 0;

	paragDebut = ligDepart + 3;
	rang = 1;
	numCol = colDepart;
	lig = paragDebut;
	col = colDepart;

	do {
	RazEcran;
	gotolc( 2, 21 );
	presentDelai;
        printf("\n\n");

	paragFin = countPtype_list( SL_DELAYPI );
	largeurCol = 80 / displayPtype_list( SL_DELAYPI, colMax, ligMax, paragDebut );
        printf("\n\n");
	gotolc( 23, 1 );
	emploiDelai;
	reste = paragFin % ligMax;
	if( reste == 0 )
		{ 
		  if( SL_DELAYPI == NULL )
			{
			ligFin = paragDebut;
			colFin = colDepart;
			}
		  else
			{
			ligFin =ligMax;
		  	colFin = ((paragFin / ligMax) - 1) * largeurCol + 
				colDepart;
			}
		}
	else	{ ligFin = paragDebut + reste - 1;
		  colFin = ((paragFin - reste) / ligMax) * largeurCol +
				colDepart;
		};

	if ( supr == 1 ) 
		{
		col = colDepart + ( numCol * largeurCol );
		supr = 0;
		};

	gotolc( lig, col );

		do {
		switch( Choix = toupper( AuVol() ) )
			{
		case 'M' : if( SL_DELAYPI != NULL )
			   { 
			   data = findDatat( SL_DELAYPI, rang ); 
			   if( lireModif( data, time, paragDebut ) != 1 )
			      {
			      SL_DELAYPI = delMaillont( SL_DELAYPI, data );
			      SL_DELAYPI = addptype_alpha( SL_DELAYPI, 
						data, atol( time ) );
			      time[0] = '\0'; 
			      };
			   }
			   else Beep;
			   break;
		case 'D' : if( SL_DELAYPI != NULL )
			   {
			   SL_DELAYPI = delMaillont( SL_DELAYPI, findDatat(
					SL_DELAYPI, rang ) );
			if( lig == ligFin & col == colFin )
			   if( lig != paragDebut | col != colDepart )
		 		{
			  	rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				};
			supr = 1;
			numCol = ((col - colDepart) / largeurCol) ;
			   }
			   else Beep;
		   	   break;
		case 'A' :  
			   while( lireDelai( data, time, paragDebut ) != 1 )
			   	SL_DELAYPI = addptype_alpha( SL_DELAYPI, 
					data, atol( time) );
			   col = colDepart; lig = paragDebut;		  
			   time[0] = '\0'; data[0] = '\0';
			   break;
		case 'H' : if( lig != paragDebut | col != colDepart )
				{
				rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
		   	   break;
		case 'B' : if( lig != ligFin | col != colFin )
				{
				rang ++;
				if( lig == (ligMax + paragDebut - 1) &
					col != colFin )
				  { lig = paragDebut;
				    col = col + largeurCol;
				  } 
			   	else lig ++;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
			   break;
			};
	    	}
		while( strchr( "HBADMQ", Choix ) == NULL );
	   }
	while( Choix != 'Q' );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void  INTERMEDIATE ()
	{
	int paragDebut,
	    paragFin,
	    largeurCol,
	    numCol,
	    reste, supr,
	    ligFin, colFin,
	    rang,
	    lig, 
	    col;
	char Choix;
	char *data = (char *) mbkalloc( MaxString );
	supr = 0;

	paragDebut = ligDepart + 3;
	rang = 1;
	numCol = colDepart;
	lig = paragDebut;
	col = colDepart;

	do {
	RazEcran;
	gotolc( 2, 21 );
	presentIntermediate;
        printf("\n\n");

	paragFin = countChain_list( SL_GUARDEDAUX );
	largeurCol = 80 / displayChain_list( SL_GUARDEDAUX, colMax, ligMax, paragDebut );
        printf("\n\n");
	gotolc( 23, 1 );
	emploiSorties;
	reste = paragFin % ligMax;
	if( reste == 0 )
		{ 
		  if( SL_GUARDEDAUX == NULL )
			{
			ligFin = paragDebut;
			colFin = colDepart;
			}
		  else
			{
			ligFin =ligMax;
		  	colFin = ((paragFin / ligMax) - 1) * largeurCol + 
				colDepart;
			}
		}
	else	{ ligFin = paragDebut + reste - 1;
		  colFin = ((paragFin - reste) / ligMax) * largeurCol +
				colDepart;
		};

	if ( supr == 1 ) 
		{
		col = colDepart + ( numCol * largeurCol );
		supr = 0;
		};

	gotolc( lig, col );

		do {
		switch( Choix = toupper( AuVol() ) )
			{
		case 'D' : if( SL_GUARDEDAUX != NULL )
			   {
			   SL_GUARDEDAUX = delMaillon( SL_GUARDEDAUX, findDatat(
					SL_GUARDEDAUX, rang ) );
			if( lig == ligFin & col == colFin )
			   if( lig != paragDebut | col != colDepart )
		 		{
			  	rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				};
			supr = 1;
			numCol = ((col - colDepart) / largeurCol) ;
			   }
			   else Beep;
		   	   break;
		case 'A' :  
			   while( lireIntermediate( data, paragDebut ) != 1 )
			   	SL_GUARDEDAUX = addchain_alpha( SL_GUARDEDAUX, 
					data );
			   col = colDepart; lig = paragDebut;		  
			   data[0] = '\0';
			   break;
		case 'H' : if( lig != paragDebut | col != colDepart )
				{
				rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
		   	   break;
		case 'B' : if( lig != ligFin | col != colFin )
				{
				rang ++;
				if( lig == (ligMax + paragDebut - 1) &
					col != colFin )
				  { lig = paragDebut;
				    col = col + largeurCol;
				  } 
			   	else lig ++;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
			   break;
			};
	    	}
		while( strchr( "HBADQ", Choix ) == NULL );
	   }
	while( Choix != 'Q' );
	}
/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void  SORTIES ()
	{
	int paragDebut,
	    paragFin,
	    largeurCol,
	    numCol,
	    reste, supr,
	    ligFin, colFin,
	    rang,
	    lig, 
	    col;
	char Choix;
	char *data = (char *) mbkalloc( MaxString );
	supr = 0;

	paragDebut = ligDepart + 3;
	rang = 1;
	numCol = colDepart;
	lig = paragDebut;
	col = colDepart;

	do {
	RazEcran;
	gotolc( 2, 21 );
	presentSorties;
        printf("\n\n");

	paragFin = countChain_list( SL_OPTIMPO );
	largeurCol = 80 / displayChain_list( SL_OPTIMPO, colMax, ligMax, paragDebut );
        printf("\n\n");
	gotolc( 23, 1 );
	emploiSorties;
	reste = paragFin % ligMax;
	if( reste == 0 )
		{ 
		  if( SL_OPTIMPO == NULL )
			{
			ligFin = paragDebut;
			colFin = colDepart;
			}
		  else
			{
			ligFin =ligMax;
		  	colFin = ((paragFin / ligMax) - 1) * largeurCol + 
				colDepart;
			}
		}
	else	{ ligFin = paragDebut + reste - 1;
		  colFin = ((paragFin - reste) / ligMax) * largeurCol +
				colDepart;
		};

	if ( supr == 1 ) 
		{
		col = colDepart + ( numCol * largeurCol );
		supr = 0;
		};

	gotolc( lig, col );

		do {
		switch( Choix = toupper( AuVol() ) )
			{
		case 'D' : if( SL_OPTIMPO != NULL )
			   {
			   SL_OPTIMPO = delMaillon( SL_OPTIMPO, findDatat(
					SL_OPTIMPO, rang ) );
			if( lig == ligFin & col == colFin )
			   if( lig != paragDebut | col != colDepart )
		 		{
			  	rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				};
			supr = 1;
			numCol = ((col - colDepart) / largeurCol) ;
			   }
			   else Beep;
		   	   break;
		case 'A' :  
			   while( lireSortie( data, paragDebut ) != 1 )
			   	SL_OPTIMPO = addchain_alpha( SL_OPTIMPO, 
					data );
			   col = colDepart; lig = paragDebut;		  
			   data[0] = '\0';
			   break;
		case 'H' : if( lig != paragDebut | col != colDepart )
				{
				rang --;
				if( lig == paragDebut & col != colDepart )
				  { lig = ligMax + paragDebut - 1;
				    col = col - largeurCol;
				  }
				else lig --;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
		   	   break;
		case 'B' : if( lig != ligFin | col != colFin )
				{
				rang ++;
				if( lig == (ligMax + paragDebut - 1) &
					col != colFin )
				  { lig = paragDebut;
				    col = col + largeurCol;
				  } 
			   	else lig ++;
				}
			   else
				Beep;
			   gotolc( lig, col );
			   Choix = 'X';
			   break;
			};
	    	}
		while( strchr( "HBADQ", Choix ) == NULL );
	   }
	while( Choix != 'Q' );
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void  SAUVER ()
	{
	saveParam(SL_PAR,SL_FILEPAR);
	}



/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void ARBRE_N ()
	{
	char Choix;

	RazEcran;
	gotolc( 6, 4 );
	printf("the maximum number of transistors on N-graph is : ");
	SetMode; printf( "%d\n", SL_NUMTRANSN ); ResetMode;
	gotolc( 8, 4 );
	DemandeEntier; gotolc( 10, 4 );
	while( strchr( "\n23456", Choix = AuVol() ) == NULL );
	if (Choix > 49 && Choix < 55) SL_NUMTRANSN = Choix-48;
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void ARBRE_P ()
	{
	char Choix;

	RazEcran;
	gotolc( 6, 4 );
	printf("the maximum number of transistors on P-graph is : ");
	SetMode; printf( "%d\n", SL_NUMTRANSP ); ResetMode;
	gotolc( 8, 4 );
	DemandeEntier; gotolc( 10, 4 );
	while( strchr( "\n23456", Choix = AuVol() ) == NULL );
	if (Choix > 49 && Choix < 55) SL_NUMTRANSP = Choix-48;
	}


/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void LIBRE ()
	{
	char Choix;

	do {
	   switch( Choix = MENU( TitreLibre, NbrLibre, ListLibre ) )
		{
		case '1' : ARBRE_N();
			   break;
		case '2' : ARBRE_P();
			   break;
		};
	   }
	while( Choix != '3' && Choix != 'Q'); 
	}


/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/

void MODIFIER ()

	{
	char Choix;

	do {
	   switch( Choix = MENU( TitreModif, NbrModif, ListModif ) )
		{
		case '1' : MODE_OPTIM ();
			   break;
		case '2' : NIVEAU_OPTIM ();
			   break;
		case '3' : ENTREES ();
			   break;
		case '4' : INTERMEDIATE ();
			   break;
		case '5' : SORTIES ();
			   break;
		case '6' : LIBRE ();
			   break;
		};
	   }
	while( Choix != '7' && Choix != 'Q');
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
void PARAMETRISATION ()

	{
	char Choix;

        do {
  
           if (!strcmp(SL_FILEPAR,"default.lax"))
              {
	      switch( Choix = MENU( TitreDef, NbrDef, ListDef ) )
		{
		case '1' : MODIFIER ();
			   break;
		case '2' : SAUVERNOM ();
			   break;
		case '3' : TRAVAIL_AUTRE ();
			   break;
		};
	      if ( Choix == '4') 
                 Choix = 'Q';
	      }
           else
              {
	      switch( Choix = MENU( TitreParam, NbrParam, ListParam ) )
		{
		case '1' : MODIFIER ();
			   break;
		case '2' : COPIER ();
			   break;
		case '3' : SUPPRIMER ();
			   break;
		case '4' : TRAVAIL_AUTRE ();
			   break;
		case '5' : SAUVER();
			   break;
		};
	      if ( Choix == '6') 
                 Choix = 'Q';
	     }
           }
	while (Choix != 'Q');
	}

/*---------------------------------------------------------------------------

---------------------------------------------------------------------------*/
/* Le menu principal */

void PRINCIPAL (mode)

     {
     char  Choix;

     do{
       if (mode)
          {
          switch ( Choix = MENU ( TitrePrincipal, NbrPrincipal, ListPrincipal ) )
              {
              case '1' : BVL_LINNUM = 0;
                         EDITION ();
                         break;
              case '2' : BVL_LINNUM = 0;
                         SL_AUX = 0;
                         OPTIM_DECOMP ();
                         break;
              case '3' : BVL_LINNUM = 0;
                         SL_AUX = 1;
                         OPTIM_DECOMP ();
                         break;
              case '4' : BVL_LINNUM = 0;
	                 PROJECTION ("SC");
			 break;
              case '5' : BVL_LINNUM = 0;
	                 PROJECTION ("C4");
			 break;
	      case '6' : PARAMETRISATION ();
			 break;
              };
          }
       else
          {
          switch ( Choix = MENU ( TitrePrincipalRelax, 
                                  NbrPrincipalRelax, 
                                  ListPrincipalRelax ) )
              {
              case '1' : BVL_LINNUM = 0;
                         EDITION ();
                         break;
              case '2' : BVL_LINNUM = 0;
                         SL_AUX = 0;
                         OPTIM_DECOMP ();
                         break;
              case '3' : BVL_LINNUM = 0;
                         SL_AUX = 1;
                         OPTIM_DECOMP ();
                         break;
              case '4' : BVL_LINNUM = 0;
	                 PROJECTION ("SC");
			 break;
              case '5' : BVL_LINNUM = 0;
	                 PROJECTION ("C4");
			 break;
	      case '6' : PARAMETRISATION ();
			 break;
              };
          }
       }
     while ((Choix != '7') && (Choix != 'Q'));
     RazEcran;
     gotolc(1,1);
     }
