#!/usr/local/bin/perl -w
#
# runpram
#
# release 0 version 1
# (based on PRAMOS release 4 version 1)
#
# (C) 1997 by Jochen Rhrig
#

$RUNPRAM_VERSION      = "0v1";
$RUNPRAM_VERSION_LONG = "runpram $RUNPRAM_VERSION (C) 1997 by Michael Bosch & Jochen Rhrig";
$PRAMOS_VERSION       = "4v1";
$HOST_VERSION         = "4v1";

$PRAM_HOME    = "/home/pram/";
$PRAM_BIN_DIR = $PRAM_HOME."bin/";
$PRAM_ETC_DIR = $PRAM_HOME."etc/";
$PRAM_LIB_DIR = $PRAM_HOME."lib/";

print "This is $RUNPRAM_VERSION_LONG\n";

$HOST_ETC_PATH = $PRAM_ETC_DIR."/host/$HOST_VERSION/";
$HOST_MODULE_PATH = $HOST_ETC_PATH;

$GTODUS_PROG  = $PRAM_LIB_DIR."/runpram/gettimeofday_usec";
                  # this program splits up the current value of gettimeofday()
                  # into two 32bit values that represent a 64bit microsecond
                  # value

$WRITE_STDIN_PROG = $PRAM_LIB_DIR."/runpram/write_stdin";
$ENV{WRITE_STDIN_PROG} = $WRITE_STDIN_PROG; # writes to the stdin-buffer of
                                            # the connected terminal

$TMPDIR = ($ENV{'TMPDIR'} ? $ENV{'TMPDIR'}
          : $ENV{'TMP'} ? $ENV{'TMP'}
          : $ENV{'TEMPDIR'} ? $ENV{'TEMPDIR'}
          : "/tmp")."/";

#$log_file = "$libdir/pramsim.log";

#print "start: $user $HOST $$ ">> $log_file;
#date >> $log_file;

#
# PRAM Simulator
# 

$PRAMSIM = $PRAM_BIN_DIR."pramsim";
$TIME    = "/usr/5bin/time";

$PRAMSIM_OPT = "";
$PRAMSIM_OUTFILE_DEFAULT = "/dev/null";
$PRAMSIM_OUTFILE = $PRAMSIM_OUTFILE_DEFAULT;

#
# Grenzwerte
#

$MAX_PHYSNUM = 64;
$MAX_VIRTNUM = 31; # maximal stehen dem Benutzer 31 von 32 vPen zur Verfgung
                   # da ein vP pro pP als Serviceprozessor reserviert ist
$MAX_IOCPNUM = $MAX_VIRTNUM-1;  # maximale Zahl der io-copy-Prozessoren pro pP


#
# Default-Werte
#

$lddata = 11;           # Size of .lddata-segment
$sheap  = 8000000;      # shared Heap
$pstack = 8192;         # lokaler Stack
$pheap  = 2048;         # lokaler Heap
$pargs  = 1000;         # Dummer default.

$PHYSNUM   = 3;	     # Zahl der pPen
$VIRTNUM_USER   = 1; # Zahl der vPen pro pP (ohne Serviceprozessor)
$IOCPNUM=0;          # Zahl der io-copy-Prozessoren pro pP


$TRACE_OUTPUT     = "";

$STRACE = "";

$NONINTERACTIVE = 0; # if set to 1 noninteractive mode is activated

# Pfade Simulator und Hostprogramm

$PRAMOS_FILE     = $PRAM_LIB_DIR."pramos/".$PRAMOS_VERSION."/pramos_pram";
$PRAMOS_COD_FILE = $PRAMOS_FILE.".cod";

$PRAMOS_KSHBRK_SIZE_BASE = 512*1024; # gemessen: 88071
$PRAMOS_KSHBRK_SIZE_VP   =   2*1024; # gemessen:  1098
$PRAMOS_KSHBRK_SIZE_PP   =  10*1024; # gemessen:   112

$PRAMOS_KSHBRK_SIZE_LOCATION = 0xe; # adress in global PRAM memory where the 
				    # size of the global kernel kshbrk is      
				    # stored for PRAMOS

$PRAMOS_IOCPNUM_LOCATION = 0xf;    # adress in global PRAM memory where the 
				    # number of io-copy-processors is stored
				    # for PRAMOS

#$GLOBAL_MEMSIZE        = 0x1200000; this is calculated now
$GLOBAL_MEMSIZE_LOCATION = 0xd; # adress in global PRAM memory where the
                                # size of the global PRAM memory is
                                # stored for PRAMOS                      
$LOCAL_MEMSIZE   = 0x20000;     # 128 kWord local memory  
$PROGRAM_MEMSIZE = 0x80000;     # 512 kWord program memory
$PROGRAM_MEMSIZE_LOCATION = 0x13; # adress in global PRAM memory where the
                                # size of the PRAM program memory is
                                # stored for PRAMOS                      


$PRAMOS_GETTIMEOFDAY_HI_LOCATION = 17; # adress in global PRAM memory where the
$PRAMOS_GETTIMEOFDAY_LO_LOCATION = 18; # 64 bit microsecond offset for the
                                       # calculation of the gettimeofday()
                                       # value is stored for PRAMOS

$DEVICE_PREFIX = $TMPDIR."runpram-".$$."/";
mkdir $DEVICE_PREFIX, 0755;

$PRAM_DEVICE = $DEVICE_PREFIX."glmem";
$PROG_DEVICE = $DEVICE_PREFIX."prgmem";
$INTS_DEVICE = $DEVICE_PREFIX."extint";

$ACCESS_CFG = $DEVICE_PREFIX."access.cfg";
$HOST_LOADERRC = $DEVICE_PREFIX."ldrc";

#
# Usage- and Help-Functions
#

sub usage
{
    print "$_[0]\7\n";
    print "help with $0 -help\n";
    exit 1;
}

sub help
{
    printf("usage: $0 [options] coff-file args-for-pram-program\n");
    printf("  -sheap    %10-d\t\t".
	   "shared heap used by shmalloc()\n", $sheap);
    printf("  -pstack   %10-d\t\t".
	   "private stack\n", $pstack);
    printf("  -pheap    %10-d\t\t".
	   "private heap used by malloc()\n", $pheap);
    printf("  -physnum  %10-d\t\t".
           "number of physical processors (pPs) (1..$MAX_PHYSNUM)\n", $PHYSNUM);
    printf("  -virtnum  %10-d\t\t".
	   "number of virtual processors per pP (1..$MAX_VIRTNUM) \n".
	   "                      \t\t(without serviceprocessor)\n",
	   $VIRTNUM_USER);
    printf("  -procs    %3-d %2-d    \t\t".
	   "-physnum and -virtnum combined\n", $PHYSNUM, $VIRTNUM_USER);
    printf("  -iocpnum  %10-d\t\t".
	   "number of io-copy-processors per pP (1..$MAX_IOCPNUM) \n",
	   $IOCPNUM);
    printf("  -pramsim  <pramsim-file>\t".
	   "path of PRAM-simulator\n".
	   "\t\t\t\t(currently set to $PRAMSIM)\n");
    printf("  -pramosfile <pramos-file>\t".
	   "path of PRAMOS-File\n".
	   "\t\t\t\t(currently set to $PRAMOS_FILE)\n");
    printf("  -host_etc_path <path>\t".
	   "etc/-path for host\n".
	   "\t\t\t\t(currently set to $HOST_ETC_PATH)\n");
    printf("  -host_module_path <path>\t".
	   "location of host modules\n".
	   "\t\t\t\t(currently set to $HOST_MODULE_PATH)\n");
    printf("  -simopt  \"%-10s\"\t".
	   "simulator options (MUST BE QUOTED!)\n",
	   $PRAMSIM_OPT ? "$PRAMSIM_OPT" : "<pramsim options>");
    printf("  -simoutfile <simout-file>\t".
	   "file to which simulator output is redirected\n".
	   "\t\t\t\tin noninteractive mode\n".
	   "\t\t\t\t(currently set to $PRAMSIM_OUTFILE)\n");
    printf("  -trace   <filename prefix>\t".
	   "output trace-files %s\n",
	   $TRACE_OUTPUT ? "to $TRACE_OUTPUT.*" : "(not specified)");
    printf("  -tmpdir  <filename>\t\t".
	   "directory for temporary files\n".
	   "\t\t\t\t(currently set to $TMPDIR)\n");
    printf("  -renice  <niceinc>\t\t".
	   "increment nice level of simulation by <niceinc>\n".
	   "\t\t\t\t(niceinc %s)\n",
	   defined($nicelevel)?"set to $nicelevel":"not set");
    printf("  -str           \t\t".
	   "strace simulator (switched %s)\n", $STRACE ? "on" : "off");
    printf("  -noninteractive\t\tstart in non-interactive mode\n");
    printf("  -verbose\t\t\tshow some additional output\n");
    printf("  -version\t\t\t$RUNPRAM_VERSION_LONG\n");
    printf("  -help\t\t\t\tshow this message\n");
    printf("The shown values are default values possibly changed by your options\n");
    exit 0;
}

#
# Signal Handler for proper Cleanup
#

sub cleanup
{
    if($NONINTERACTIVE)
    {
        kill -2, $bgproc_pid; # kill host process directly
    }
    else
    {
        kill 9, $bgproc_pid; # kill xterm in which the host process is running
    }

    unlink $PRAM_DEVICE, $PROG_DEVICE, $INTS_DEVICE;
    unlink $ACCESS_CFG, $HOST_LOADERRC, $OBJFILE_TMP;
    rmdir $DEVICE_PREFIX;
}

$SIG{'INT'} = 'cleanup';

#
# Process command-line arguments
#

$all_args_processed = 0;
 PROCESS_ARGS:
    while($#ARGV >= 0 && !$all_args_processed)
    {
	if($ARGV[0] eq "-sheap")
	{shift; $sheap = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-pstack")
	{shift; $pstack = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-pheap")
	{shift; $pheap = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-physnum")
	{shift; $PHYSNUM = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-virtnum")
	{shift; $VIRTNUM_USER = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-procs")
	{shift; $PHYSNUM = shift; $VIRTNUM_USER = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-iocpnum")
	{shift; $IOCPNUM = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-pramsim")
	{shift; $PRAMSIM = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-pramosfile")
	{shift; $PRAMOS_FILE = shift; $PRAMOS_COD_FILE = $PRAMOS_FILE.".cod";
	 next PROCESS_ARGS;}
	if($ARGV[0] eq "-host_etc_path")
	{shift; $HOST_ETC_PATH = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-host_module_path")
	{shift; $HOST_MODULE_PATH = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-trace")
	{shift; $TRACE_OUTPUT=shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-str")
	{shift; $STRACE="truss"; next PROCESS_ARGS;}
	if($ARGV[0] eq "-simopt")
	{shift; $PRAMSIM_OPT=" ".shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-simoutfile")
	{shift; $PRAMSIM_OUTFILE = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-tmpdir")
	{shift; $TMPDIR = shift; next PROCESS_ARGS;}
	if($ARGV[0] eq "-renice")
	{
	    shift; $nicelevel = shift;
	    $run="/usr/ucb/renice +$nicelevel $$ 2>1 1> /dev/null";
	    if($VERBOSE){print "$$ $run"};
	    system $run;
	    next PROCESS_ARGS;
	}
	if($ARGV[0] eq "-noninteractive")
	{shift; $NONINTERACTIVE=1; next PROCESS_ARGS;}
	if($ARGV[0] eq "-verbose")
	{shift; $VERBOSE=1; next PROCESS_ARGS;}
	if($ARGV[0] eq "-version")
	{print "$RUNPRAM_VERSION_LONG\n"; exit 0;}
	if($ARGV[0] eq "-help")
	{&help;}
	if($ARGV[0] =~ /-.*/)
	{&usage("Unknown option $ARGV[0]");shift;}
	$all_args_processed = 1;
    }

if($#ARGV < 0)
{
    &usage("You could at least specify a coff-file");
}

if(!$NONINTERACTIVE && $PRAMSIM_OUTFILE ne $PRAMSIM_OUTFILE_DEFAULT)
{
    printf("Option \"-simoutfile\" has no effect in interactive mode".
	    " - ignoring option\7\n");
    $PRAMSIM_OUTFILE = $PRAMSIM_OUTFILE_DEFAULT;
}
	     
if($PHYSNUM > $MAX_PHYSNUM || $PHYSNUM < 1)
{
    &usage("physnum out of range (1..$MAX_PHYSNUM)");
}

if($VIRTNUM_USER > $MAX_VIRTNUM || $VIRTNUM_USER < 1)
{
    &usage("virtnum out of range (1..$MAX_VIRTNUM)");
}

if($IOCPNUM > $MAX_IOCPNUM || $IOCPNUM < 0)
{
    &usage("iocpnum out of range (0..$MAX_IOCPNUM)");
}

if($VIRTNUM_USER+$IOCPNUM > $MAX_VIRTNUM)
{
    &usage("virtnum + iocpnum must not exceed $MAX_VIRTNUM");
}

$VIRTNUM_TOTAL = $VIRTNUM_USER    # total number of vP per pP - we need one
                 + $IOCPNUM       # more than the user (for the PRAMOS
                 + 1;             # service-processor)


exit(1);


$OBJFILE=$ARGV[0];
if(!-e $OBJFILE){ die "File $OBJFILE doesn't exist\7\n"};

$OBJFILE_TMP = "$TMPDIR/runpram_".$$."_obj";

if($OBJFILE =~ /.*\.gz/)
{
    if($VERBOSE){printf("unzipping $OBJFILE\n")};
    system "gunzip --to-stdout $OBJFILE >$OBJFILE_TMP";
    $OBJFILE=$OBJFILE_TMP;
}

if($VERBOSE){print "Using $TMPDIR as \"device\"-file directory\n"};

#
# Calculate the size of the total amount of global (shared) memory
#

# Determine data segment sizes of the program that is to be simulated
    
open(OBJDUMP, "$PRAM_BIN_DIR/objdump --header $OBJFILE|");

 SECTION_SIZES:
    while(<OBJDUMP>)
    {
	if(/\.gpbss/)
	{
	    ($d1, $d2, $pbss) = split;
	    next SECTION_SIZES;
	}
	if(/\.gpdata/)
	{
	    ($d1, $d2, $pdata) = split;
	    next SECTION_SIZES;
	}
	if(/\.gsbss/)
	{
	    ($d1, $d2, $sbss) = split;
	    next SECTION_SIZES;
	}
	if(/\.gsdata/)
	{
	    ($d1, $d2, $sdata) = split;
	    next SECTION_SIZES;
	}
    }
close(OBJDUMP);

$pbss  = (hex $pbss )/4;
$pdata = (hex $pdata)/4;
$sbss  = (hex $sbss )/4;
$sdata = (hex $sdata)/4;

if($VERBOSE){printf "gpbss length  = %d word\n", $pbss };
if($VERBOSE){printf "gpdata length = %d word\n", $pdata};
if($VERBOSE){printf "gsbss length  = %d word\n", $sbss };
if($VERBOSE){printf "gsdata length = %d word\n", $sdata};

$private = $pheap + $pstack + $pdata + $pbss + $pargs;
$shared  = $sdata + $sbss + $sheap + $lddata;

$procnum = $PHYSNUM * $VIRTNUM_USER;

$GLOBAL_MEMSIZE = $private * $procnum + $shared;

if($VERBOSE){print "section private shared\n"};
if($VERBOSE){print "lddata	$lddata\n"};
if($VERBOSE){print "stack	$pstack\n"};
if($VERBOSE){print "heap	$pheap	$sheap\n"};
if($VERBOSE){print "data	$pdata	$sdata\n"};
if($VERBOSE){print "bss	$pbss	$sbss\n"};
if($VERBOSE){print "args	$pargs\n"};
if($VERBOSE){print "       ----------------\n"};
if($VERBOSE){print "$procnum *	$private +	"
		     ."$shared = $GLOBAL_MEMSIZE Words\n"};
    
if($procnum == 1)
{
    # If we run the program on one vP an additional amount of memory is
    # needed to ensure correct copying of the private segments at program
    # startup

    $additional = $pdata + $pbss + $pargs;
    $GLOBAL_MEMSIZE += $additional;

    if($VERBOSE)
    {
	print "Using only one processor. Additional $additional bytes.\n";
    }
    
    print "\n";
}

#
# Determine data segment sizes of PRAMOS
#

open(OBJDUMP, "$PRAM_BIN_DIR/objdump --header $PRAMOS_FILE|");

 SECTION_SIZES:
    while(<OBJDUMP>)
    {
	if(/\.gpbss/)
	{
	    ($d1, $d2, $pramos_pbss) = split;
	    next SECTION_SIZES;
	}
	if(/\.gpdata/)
	{
	    ($d1, $d2, $pramos_pdata) = split;
	    next SECTION_SIZES;
	}
	if(/\.gsbss/)
	{
	    ($d1, $d2, $pramos_sbss) = split;
	    next SECTION_SIZES;
	}
	if(/\.gsdata/)
	{
	    ($d1, $d2, $pramos_sdata) = split;
	    next SECTION_SIZES;
	}
	if(/\.pbsdat/)
	{
	    ($d1, $d2, $pramos_pbsdat) = split;
	    next SECTION_SIZES;
	}
    }

close(OBJDUMP);

$pramos_pbss   = (hex $pramos_pbss )/4; # THIS SHOULD ALWAYS BE 0
$pramos_pdata  = (hex $pramos_pdata)/4; # THIS SHOULD ALWAYS BE 0
$pramos_sbss   = (hex $pramos_sbss )/4;
$pramos_sdata  = (hex $pramos_sdata)/4;
$pramos_pbsdat = (hex $pramos_pbsdat)/4;

$pramos_kshbrk_size = $PRAMOS_KSHBRK_SIZE_BASE
    + $PHYSNUM * ($PRAMOS_KSHBRK_SIZE_PP
		  + $VIRTNUM_TOTAL * $PRAMOS_KSHBRK_SIZE_VP);

if($VERBOSE){printf "PRAMOS-gpbss length  = %d\n", $pramos_pbss};
if($VERBOSE){printf "PRAMOS-gpdata length = %d\n", $pramos_pdata};
if($VERBOSE){printf "PRAMOS-gsbss length  = %d\n", $pramos_sbss};
if($VERBOSE){printf "PRAMOS-gsdata length = %d\n", $pramos_sdata};
if($VERBOSE){printf "PRAMOS-pbsdat length = %d\n", $pramos_pbsdat};
if($VERBOSE){printf "PRAMOS-kshbrk length = %d\n", $pramos_kshbrk_size};

$GLOBAL_MEMSIZE += $pramos_pbss + $pramos_pdata
                + $pramos_sbss + $pramos_sdata
                + $pramos_pbsdat
                + $pramos_kshbrk_size;

# Round the size of the global memory to a 64K border

if($GLOBAL_MEMSIZE & 0xffff != 0)
{
    $GLOBAL_MEMSIZE = ($GLOBAL_MEMSIZE & 0xffff0000) + 0x10000;
}

#
# Generate config file for access-lib
#

if($VERBOSE){printf("Generating access.cfg file $ACCESS_CFG")};

$ENV{'PRAM_DEV_PREFIX'} = $DEVICE_PREFIX;
$ENV{'PRAM_CFG_FILE'} = $ACCESS_CFG;

open(AC, ">$ACCESS_CFG") || die "couldn't create file $ACCESS_CFG";
printf AC
    "rng global glmem 0 $GLOBAL_MEMSIZE 0 0 0\n".
    "rng program prgmem 0 $PROGRAM_MEMSIZE 0 0 0\n".
    "set num_of_pp $PHYSNUM\n".
    "set version new\n";
close AC;    

#
# Set up variables etc. for Host-Program Startup
#

if($VERBOSE){printf("Generating loaderc-file ...\n")};

if(-e $HOST_LOADERRC)
{
    die "File $HOST_LOADERRC exists - please remove or rename it\7\n";
}

open(HLDR, ">$HOST_LOADERRC") || die "Couldn't create file $HOST_LOADERRC";

printf HLDR "sctdata          \n";
printf HLDR "{                \n";
printf HLDR "  org *          \n"; 
printf HLDR "  .lddata     S  \n"; 
printf HLDR "  .gsdata     S  \n"; 
printf HLDR "  .gsbss      S  \n"; 
printf HLDR "  org 0xc0000000 \n"; 
printf HLDR "  .gpdata     P  \n"; 
printf HLDR "  .gpbss      P  \n"; 
printf HLDR "  .args       P  \n"; 
printf HLDR "}                \n"; 
printf HLDR "lddata           \n"; 
printf HLDR "{                \n"; 
printf HLDR "  procs    %8d N \n", $VIRTNUM_USER*$PHYSNUM; 
printf HLDR "  textlen  %8d T \n", 0; 
printf HLDR "  pstack   %8d P \n", $pstack; 
printf HLDR "  pheap    %8d P \n", $pheap; 
printf HLDR "  sheap    %8d S \n", $sheap; 
printf HLDR "}                     \n"; 
    
close HLDR;

$HOST             = $HOST_MODULE_PATH."pramos_host";
$START_HOST       = $PRAM_LIB_DIR."runpram/".$RUNPRAM_VERSION."/runpram_host";

$ENV{'HOST'} = $HOST;
$ENV{'HOST_LOADERRC'}  = $HOST_LOADERRC;
$ENV{'GLOBAL_MEMSIZE'} = $GLOBAL_MEMSIZE;

$ENV{'PRAM_DEVICE'} = $PRAM_DEVICE;
$ENV{'PROG_DEVICE'} = $PROG_DEVICE;
$ENV{'INTS_DEVICE'} = $INTS_DEVICE;

$ENV{'PROGRAM'} = join(" ", @ARGV);

$ENV{'SBP_HOSTETCPATH'}    = $HOST_ETC_PATH;
$ENV{'SBP_HOSTMODULEPATH'} = $HOST_MODULE_PATH;
$ENV{'SBP_HOSTRC'}         = $HOST_ETC_PATH."hostrc";
$ENV{'SBP_HOSTMODULEFILE'} = $HOST_ETC_PATH."host_modules";
$ENV{'SBP_LOADER'}         = "host-loader";
$ENV{'SBP_PRAMOS_ISSUE'}   = $HOST_ETC_PATH."issue";
$ENV{'SBP_PRAMOS_MOTD'}    = $HOST_ETC_PATH."motd";
$ENV{'SBP_HOSTRC'}         = ".hostrc.dummy";

#
# Set up variables etc. for Host-Program Startup
#

($GTODUS_HI, $GTODUS_LO) =  split(/ /, `$GTODUS_PROG`);

if($VERBOSE){print("gettimofday_offset_hi = $GTODUS_HI\n".
		   "gettimofday_offset_lo = $GTODUS_LO\n");};

$pramsim_run = "$TIME $STRACE $PRAMSIM ".
       "--no-rc-file           ".
       "--net-datatest         ".
       "--net-op-test	       ".
       "-M $GLOBAL_MEMSIZE     ".
       "-P $PROGRAM_MEMSIZE    ".
       "-L $LOCAL_MEMSIZE      ".
       "-p $PHYSNUM            ".
       "-v $VIRTNUM_TOTAL      ".
       "-l 1		       ".
       "-i		       ".
       "--set global-devname $PRAM_DEVICE ".
       "--set   prog-devname $PROG_DEVICE ".
       "--set   ints-devname $INTS_DEVICE ".
       "--set file $OBJFILE   ".
       "--set pramos-file $PRAMOS_FILE ".
       "--init-string \"f $GLOBAL_MEMSIZE_LOCATION $GLOBAL_MEMSIZE, ".
                       "f $PROGRAM_MEMSIZE_LOCATION $PROGRAM_MEMSIZE, ".
       		       "f $PRAMOS_KSHBRK_SIZE_LOCATION $pramos_kshbrk_size, ".
       		       "f $PRAMOS_IOCPNUM_LOCATION $IOCPNUM, ".
       		       "f $PRAMOS_GETTIMEOFDAY_HI_LOCATION $GTODUS_HI, ".
       		       "f $PRAMOS_GETTIMEOFDAY_LO_LOCATION $GTODUS_LO, ".
       		       "g".
                       "\"".
       ($TRACE_OUTPUT?" --trace $TRACE_OUTPUT":"").
       "$PRAMSIM_OPT".
       " $PRAMOS_COD_FILE";

if($VERBOSE) {print($pramsim_run);};

#
# Start the whole thing up
#

    $ENV{NONINTERACTIVE} = $NONINTERACTIVE;

    print "Starting up Host ...\n";

    unless($bgproc_pid = fork)
    {
	if($VERBOSE){print "bgproc_pid = $bgproc_pid\n"}
	setpgrp; # to assure that all children of the host process are killed
                 # at termination

	$title = $OBJFILE."-Host";

	if($VERBOSE){print "HOST       = $HOST\n"};
	if($VERBOSE){print "START_HOST = $START_HOST\n"};

	if($NONINTERACTIVE)
	{
	    exec "$START_HOST";
	}
	else
	{
	    exec "xterm -title $title -name runpram_host -e $START_HOST";
	}
    }

    print "Starting up Simulator ...\n";
    if($VERBOSE){print "$pramsim_run\n";};

#    printf "%s", "]2;".$OBJFILE."-Simulator";
                                    # This sets the title in the xterm
    if($NONINTERACTIVE)
    {
	close(STDIN); # to stop the simulator after having executed the program
	open(STDOUT, ">".$PRAMSIM_OUTFILE)
	    || die "Couldn't open file $PRAMSIM_OUTFILE";;
        open(STDERR, ">&STDOUT");
    }

    system $pramsim_run;

#
# Termination
#

&cleanup;

exit 0;
