#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 5 (of 7)."
# Contents:  bookeep.c tierra.c tierra.h
# Wrapped by ray@life on Mon Nov  4 22:56:33 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'bookeep.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bookeep.c'\"
else
echo shar: Extracting \"'bookeep.c'\" \(16574 characters\)
sed "s/^X//" >'bookeep.c' <<'END_OF_FILE'
X/* bookeep.c  4-10-91  bookeeping functions for the Tierra simulator */
X/** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
X
X#include "license.h"
X
X#ifndef lint
Xstatic char     sccsid[] = "@(#)bookeep.c	2.7 10/6/91";
X#endif
X
X#include "tierra.h"
X#include "extern.h"
X
Xvoid DivideBookeep(ci, ni)
X    I32s  ci, ni;
X{
X    Pcells  nc = cells + ni;
X    Pcells  ce = cells + ci;
X    Pgl     tgl, tcgl;
X    float   max;
X    I8s     same = 0;
X
X    LastDiv = InstExe;
X    if (!ce->d.fecundity && !ce->d.mut && !ce->d.flaw) {
X	ce->d.d1.flags = ce->d.flags; /* record metabolic data 1st replicat */
X        ce->d.d1.inst  = ce->d.inst + 1;
X        ce->d.d1.mov_daught = ce->d.mov_daught;
X    }
X    ce->d.fecundity++;
X    nc->d.gen.size = nc->mm.s;
X    if (GeneBnker) {
X	if (ce->mm.s == nc->mm.s &&    /* if cell breeds true */
X           IsSameGen(nc->mm.s, soup + nc->mm.p, soup + ce->mm.p)) {
X	    if (ce->d.fecundity == 1)
X                nc->d.d1.BreedTrue = ce->d.d1.BreedTrue = 1;
X            nc->d.parent = ce->d.parent;
X            nc->d.gen = ce->d.gen;
X            nc->d.gli = ce->d.gli;
X            same = 1;
X        }
X        else {  /* if daughter is a new genotype (same = 0) */
X	    nc->d.parent = ce->d.gen;
X            CheckGenotype(ni,&nc->d.gli); /* this will assign a gen.label */
X        }
X        tgl = (sl + nc->d.gli.si)->g + nc->d.gli.gi;  /* new cell g_list */
X        tcgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi; /* mother cell g_list */
X        if (ce->d.fecundity == 1 && !ce->d.mut && !ce->d.flaw)
X            tcgl->d1 = ce->d.d1;
X        else if (ce->d.fecundity == 2 && !ce->d.mut && !ce->d.flaw) {
X	    tcgl->d2.inst = ce->d.inst + 1 - ce->d.d1.inst;
X            tcgl->d2.flags = ce->d.flags - ce->d.d1.flags;
X            tcgl->d2.mov_daught = ce->d.mov_daught;
X            if (same) tcgl->d2.BreedTrue = same;
X        }
X        tgl->pop++;
X/* this might be a good place to keep track of multiple parental genotypes. */
X        if (reaped) {
X	    max = (float) tgl->pop / (float) NumCells;
X            if (max > tgl->MaxPropPop) tgl->MaxPropPop = max;
X            max = (float) tgl->pop * nc->d.gen.size / (float) SoupSize;
X            if (max > tgl->MaxPropInst) tgl->MaxPropInst = max;
X        }
X        /* criteria for saving genotype to disk */
X        if (reaped && !IsBit(tgl->bits,0) && tgl->pop > 3 &&
X           (tgl->MaxPropPop > SavThrPop || tgl->MaxPropInst > SavThrMem * .5))
X	{   if (!(sl + nc->d.gli.si)->num_s) NumSiz++;
X            SetBit(&tgl->bits, 0, 1); SetBit(&tgl->bits, 1, 1);
X            extract(ni);
X            (sl + nc->d.gli.si)->num_s++;
X            num_gen++;
X        }
X    }
X    ce->d.mov_daught = ce->d.mut = 0;
X    OutDisk('b',nc);
X}
X
Xvoid OutDisk(bd, nc)
X    I8s   bd;
X    Pcells  nc;
X{
X    I32s  ttime;
X    I8s   path[80], label[4];
X
X    if(DiskOut)
X    {
X    if (FirstOutDisk) {
X	FirstOutDisk = 0; BrkupCum = 0; BrkupCou = 1;
X#ifdef IBM3090
X        if (BrkupSiz) sprintf(path,"break.1.d");
X        else sprintf(path,"tierra.run.d");
X        oufr = fopen(path,"w");
X#else
X        if (BrkupSiz) sprintf(path,"%sbreak.1", OutPath);
X        else sprintf(path,"%stierra.run", OutPath);
X        oufr = fopen(path,"w");
X#endif
X        if (oufr == NULL)
X	{   sprintf(mes[0],"OutDisk 1: file %s not opened, exiting", path);
X            FEMessage(1);
X            while (hangup) ;
X            exit(0);
X        }
X        sprintf(label,nc->d.gen.label);
X#ifdef IBM3090
X        Ascii2Ebcdic(label);
X#endif
X        BrkupCum += fprintf(oufr,"%lx %c %ld", InstExe.i, bd,
X            nc->d.gen.size);
X        if (GeneBnker) BrkupCum += 1 + fprintf(oufr," %s\n", label);
X        else BrkupCum += 1 + fprintf(oufr,"\n");
X    }
X    else {
X	ttime = InstExe.i - lo.time;
X        if (ttime < 0) ttime += 1000000L;
X        BrkupCum += fprintf(oufr,"%lx", ttime);
X        if (lo.bd != bd) BrkupCum += fprintf(oufr," %c", bd);
X        if (lo.size != nc->d.gen.size)
X	    BrkupCum += fprintf(oufr," %ld", nc->d.gen.size);
X        if (GeneBnker && strcmp(lo.label,nc->d.gen.label)) {
X            sprintf(label,nc->d.gen.label);
X#ifdef IBM3090
X            Ascii2Ebcdic(label);
X#endif
X            BrkupCum += fprintf(oufr," %s", label);
X        }
X        BrkupCum += 1 + fprintf(oufr,"\n");
X        if (BrkupSiz && BrkupCum > BrkupSiz * 1024L) {
X	    fclose(oufr); BrkupCum = 0; BrkupCou++;
X#ifdef IBM3090
X            sprintf(path,"break.%ld.d", BrkupCou);
X            oufr = fopen(path,"w");
X#else
X            sprintf(path,"%sbreak.%ld", OutPath, BrkupCou);
X            oufr = fopen(path,"w");
X#endif
X            if (oufr == NULL)
X            {   sprintf(mes[0],"OutDisk 2: file %s not opened, exiting", path);
X                if (!hangup)
X                    FEMessage(1);
X                else
X                {   sprintf(mes[1],"system being saved to disk");
X                    FEMessage(2);
X                }
X                while (hangup) ;
X                WriteSoup(1);
X                exit(0);
X            }
X        }
X    }
X    }
X    else
X    {   if(FirstOutDisk) FirstOutDisk = 0;
X        else
X        {   ttime = InstExe.i - lo.time;
X            if(ttime < 0) ttime += 1000000L;
X        }
X    }
X    lo.bd = bd; lo.size = nc->d.gen.size; lo.time = InstExe.i;
X    strcpy(lo.label,nc->d.gen.label);
X    TimePop += (double) ttime * (double) NumCells;
X    if (bd == 'b') TimeBirth++;
X    else TimeDeath++;
X}
X
Xvoid ReapBookeep(ci)
X    I32s  ci;
X{
X    Pgl  tgl;
X    Pcells  ce = cells + ci;
X
X    OutDisk('d',ce);
X    if (GeneBnker) {
X	tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
X        tgl->pop--;
X/* don't do this any more? -tom
X        if (tgl->pop <= 0 && IsBit(tgl->bits,1) && !IsBit(tgl->bits,0))
X            DelGenFile(tgl);
X*/
X    }
X    InitCell(ci);
X    NumCells--;
X    reaped = 1;
X}
X
Xvoid MutBookeep(i)
X    Ind  i;
X{
X    I32s  ci;
X    I8s   md;
X    Pcells  ce;
X    Pgl     tgl;
X
X    if (!GeneBnker || IsFree(i)) return ;
X    WhichCell(i, &ci, &md);
X    if (md == 'm') {
X	ce = cells + ci;
X        ((sl + ce->d.gli.si)->g + ce->d.gli.gi)->pop--;
X        OutDisk('d',ce);
X        ce->d.parent = ce->d.gen;		/* assign new genotype */
X        CheckGenotype(ci,&ce->d.gli);
X        tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
X        tgl->pop++;
X        OutDisk('b',ce);
X        ce->d.d1.flags = ce->d.d1.mov_daught = 0L;
X        ce->d.fecundity = ce->d.flags = 0L;
X        ce->d.d1.inst = ce->d.inst = 0L;
X        ce->d.mut++;
X    }
X}
X
Xvoid plan()
X{   I32s  i, n = 0L, upper_cell = 0L, indiv_gen_time, pop_gen_time;
X    I32s  MaxPop = 0L, MaxMem = 0L, pop = 0L, mem = 0L;
X    struct genotype  MaxGenPop, MaxGenMem;
X    double  prob_of_hit;
X    Pcells  ce;
X    I8s     buf[80];
X
X    AverageSize = 0L;
X    for (i = 2; i < CellsSize; i++)
X    {   ce = cells + i;
X        if (ce->ld)
X        {   n++;
X            AverageSize += ce->d.gen.size;
X            upper_cell = i;
X            if (GeneBnker && InstExe.m)
X            {   pop = ((sl + ce->d.gli.si)->g + ce->d.gli.gi)->pop; 
X                mem = pop * ce->d.gen.size;
X                if (pop > MaxPop)
X                {   MaxPop = pop;
X                    MaxGenPop = ce->d.gen;
X                }
X                if (mem > MaxMem)
X                {   MaxMem = mem;
X                    MaxGenMem = ce->d.gen;
X                }
X            }
X        }
X    }
X#ifdef ERROR
X    if (n != NumCells)
X    {   sprintf(mes[0],"ERROR: NumCells = %ld  count of cells = %ld",
X            NumCells, n);
X        FEMessage(1);
X    }
X#endif
X    if (((double) CellsSize > 1.8 * (double) (upper_cell + 1)) && reaped &&
X        DistFreq < 0)
X    {   sprintf(mes[0],"lbookeep: realloc, NumCells = %ld  upper_cell = %ld",
X            NumCells, upper_cell);
X        sprintf(buf,"    old CellsSize = %ld  ", CellsSize);
X        CellsSize = (I32s) (1.2 * (double) (upper_cell + 1));
X        if (CellsSize < upper_cell) CellsSize = upper_cell + 10;
X        if (CellsSize < NumCells + 2) CellsSize = NumCells + 12;
X        cells = (Pcells) threalloc((I8s Fp) cells,
X                (I32u) CellsSize * sizeof(struct cell));
X        sprintf(mes[1],"%s new CellsSize = %ld", buf, CellsSize);
X        FEMessage(2);
X    }
X    AverageSize /= n;
X    if (GenPerMovMut) RateMovMut = (I32s) 2L * GenPerMovMut * AverageSize;
X    indiv_gen_time = 10L * AverageSize;
X    if (InstExe.m) pop_gen_time = NumCells * indiv_gen_time;
X    else pop_gen_time = indiv_gen_time * (SoupSize / (4L * AverageSize));
X    prob_of_hit = (double) AverageSize / (double) SoupSize;
X    if(GenPerBkgMut) RateMut=(I32s)(pop_gen_time*2L*GenPerBkgMut*prob_of_hit);
X    if (GenPerFlaw) RateFlaw = (I32s) indiv_gen_time * GenPerFlaw * 2L;
X    DropDead = 1L + AverageSize / 80L;
X    Search_limit = SearchLimit * (I32s) AverageSize;
X    if (InstExe.m) {
X	TimePop /= 1000000.;
X        Generations += (double) (TimeBirth + TimeDeath) / (2. * TimePop);
X    }
X    FEPlan(MaxPop, MaxMem, &MaxGenPop, &MaxGenMem);
X    TimePop = 0.;  TimeBirth = TimeDeath = 0L;
X}
X
Xvoid GenExTemp(adrt, ci, tsize)
X    Ind   adrt; /* address of beginning of template */
X    I32s  ci, tsize;   /* ci = index of cell executing instruction */
X{
X    I32s  i, ti;
X    I32u  who; /* 0 same cell; 1 daughter cell; 2 other cell; */
X               /* 3 free memory; 4 daughter of other cell */
X    Ind   dist;
X    Pgl   tgl, ogl;
X    Pcells  ce = cells + ci, ct;
X
X    tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
X    for (i = 0; i < tsize; i++)
X    {   ti = ci;
X        who = WhoIs(&ti, ad(ce->c.ip + 1 + i)); /* who has template pattern */
X        if (who < 4) tgl->bits |= (I32u) (ONE << (I32u) (12 + who));
X        else tgl->bits |= (I32u) (ONE << (I32u) (12 + 2));
X        if (!who) {
X	    dist = ad(ce->c.ip + 1 + i) - ce->mm.p;
X            dist = ad(dist);
X#ifdef ERROR
X            if (tgl->genome == NULL || dist < 0 || dist >= tgl->gen.size)
X            {   sprintf(mes[0],"GenExTemp error 0");
X                if(!hangup)
X                    FEMessage(1);
X                else
X                {   sprintf(mes[1],"core being saved");
X                    FEMessage(2);
X                }
X                while (hangup) ;
X                WriteSoup(1);
X                exit(0);
X            }
X#endif
X         /* *(tgl->genome + dist) |= (1 << 5); */
X            tgl->gbits[dist][ce->c.tr] |= 1;
X        }
X        if (who == 2) {
X	    ct = cells + ti;
X            ogl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X            if (IsBit(ogl->bits,0)) {
X		ogl->bits |= (I32u) (ONE << (I32u) (12 + 4));
X                dist = ad(ce->c.ip + 1 + i) - ct->mm.p;
X                dist = ad(dist);
X#ifdef ERROR
X                if (ogl->genome == NULL || dist < 0 || dist >= ogl->gen.size)
X                {   sprintf(mes[0],"GenExTemp error 1");
X                    if (!hangup)
X                        FEMessage(1);
X                    else
X                    {   sprintf(mes[1],"core being saved");
X                        FEMessage(2);
X                    }
X                    while (hangup) ;
X                    WriteSoup(1);
X                    exit(0);
X                }
X#endif
X             /* *(ogl->genome + dist) |= (1 << 6); */
X                ogl->gbits[dist][ce->c.tr] |= (1 << 1);
X            }
X        }
X        ti = ci;
X        who = WhoIs(&ti, ad(adrt + i)); /* who has complementary template */
X        if (who < 4) tgl->bits |= (I32u) (ONE << (I32u) (7 + who));
X        else tgl->bits |= (I32u) (ONE << (I32u) (7 + 2));
X        if (!who) {
X	    dist = ad(adrt + i) - ce->mm.p;
X            dist = ad(dist);
X#ifdef ERROR
X            if (tgl->genome == NULL || dist < 0 || dist >= tgl->gen.size)
X            {   sprintf(mes[0],"GenExTemp error 2");
X                if (!hangup)
X                    FEMessage(1);
X                else
X                {   sprintf(mes[1],"core being saved");
X                    FEMessage(2);
X                }
X                while (hangup) ;
X                WriteSoup(1);
X                exit(0);
X            }
X#endif
X         /* *(tgl->genome + dist) |= (1 << 5); */
X            tgl->gbits[dist][ce->c.tr] |= 1;
X        }
X        if (who == 2)
X        {   ct = cells + ti;
X            ogl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X            if (IsBit(ogl->bits,0))
X            {   ogl->bits |= (I32u) (ONE << (I32u) (7 + 4));
X                dist = ad(adrt + i) - ct->mm.p;
X                dist = ad(dist);
X#ifdef ERROR
X                if (ogl->genome == NULL || dist < 0 || dist >= ogl->gen.size)
X                {   sprintf(mes[0],"GenExTemp error 3");
X                    if (!hangup)
X                        FEMessage(1);
X                    else
X                    {   sprintf(mes[1],"core being saved");
X                        FEMessage(2);
X                    }
X                    while (hangup) ;
X                    WriteSoup(1);
X                    exit(0);
X                }
X#endif
X             /* *(ogl->genome + dist) |= (1 << 6); */
X                ogl->gbits[dist][ce->c.tr] |= (1 << 1);
X            }
X        }
X    }
X}
X
Xvoid GenExMov(ci, to, from)
XI32s  ci, to, from;
X{   Pcells  ce = (cells + ci), ct;
X    Pgl     tgl, ogl;
X    I32s    ti;
X    I32u  who; /* 0 same cell; 1 daughter cell; 2 other cell; */
X               /* 3 free memory; 4 daughter of other cell */
X
X    tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
X    if(ce->d.flaw || ce->d.mut || !IsBit(tgl->bits,0))
X        return;
X    if(ce->mm.p <= ce->c.ip && ce->c.ip < (ce->mm.p + ce->mm.s))
X        /* the mov instruction being executed is within your own genome */
X    {   ti = ci;
X        who = WhoIs(&ti, from); /* who is it moved from */
X        if(who < 4) tgl->bits |= (I32u) (ONE << (I32u) (17 + who));
X        else tgl->bits |= (I32u) (ONE << (I32u) (17 + 2));
X        if(who == 2)
X        {   ct = cells + ti;
X            ogl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X            if(IsBit(ogl->bits,0))
X                ogl->bits |= (I32u) (ONE << (I32u) (17 + 4));
X        }
X        ti = ci;
X        who = WhoIs(&ti, to); /* who is it moved to */
X        if(who < 4) tgl->bits |= (I32u) (ONE << (I32u) (22 + who));
X        else tgl->bits |= (I32u) (ONE << (I32u) (22 + 2));
X        if(who == 2)
X        {   ct = cells + ti;
X            ogl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X            if(IsBit(ogl->bits,0))
X                ogl->bits |= (I32u) (ONE << (I32u) (22 + 4));
X        }
X    }
X    else /* these are moved from while executing instructions that */
X    {   ti = ci;      /* are not your own */
X        who = WhoIs(&ti, from); /* who is it moved from */
X        if(who < 4) tgl->bits |= (I32u) (ONE << (I32u) (27 + who));
X        else tgl->bits |= (I32u) (ONE << (I32u) (27 + 2));
X        if(who == 2)
X        {   ct = cells + ti; /* index of cell from which inst is moved */
X            ogl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X            if(IsBit(ogl->bits,0))
X                ogl->bits |= (I32u) (ONE << (I32u) (27 + 4));
X        }
X    }
X}
X
Xvoid GenExExe(ci, adrt)
XI32s  ci;
XInd   adrt;
X{   Pcells  ce = cells + ci, ct;
X    I32u    dist;
X    I32u    who; /* 0 same cell; 1 daughter cell; 2 other cell; */
X                 /* 3 free memory; 4 daughter of other cell */
X    Pgl     tgl;
X    I32s    ti = ci;
X
X    tgl = (sl + ce->d.gli.si)->g + ce->d.gli.gi;
X    if(ce->d.flaw || ce->d.mut || !IsBit(tgl->bits,0))
X        return;
X    who = WhoIs(&ti, adrt);
X    if(who < 4) tgl->bits |= (I32u) (ONE << (I32u) (2 + who));
X    else tgl->bits |= (I32u) (ONE << (I32u) (2 + 2));
X    if(!who) /* who == 0 == same cell */
X    {   dist = adrt - ce->mm.p;
X#ifdef ERROR
X        if(tgl->gbits == NULL || dist < 0 || dist >= tgl->gen.size)
X        {   sprintf(mes[0],"decode GenExExe error 0");
X            if (!hangup)
X                FEMessage(1);
X            else
X            {   sprintf(mes[1],"core being saved");
X                FEMessage(2);
X            }
X            while(hangup) ;
X            WriteSoup(1);
X            exit(0);
X        }
X#endif
X        tgl->gbits[dist][ce->c.tr] |= 1;
X    }
X    if(who == 2) /* is other cell */
X    {   ct = cells + ti;
X        tgl = (sl + ct->d.gli.si)->g + ct->d.gli.gi;
X        if(IsBit(tgl->bits,0))
X        {   tgl->bits |= (1 << (2 + 4));
X            dist = adrt - ct->mm.p;
X#ifdef ERROR
X            if(tgl->gbits == NULL || dist < 0 || dist >= tgl->gen.size)
X            {   sprintf(mes[0],"decode GenExExe error 1");
X                if (!hangup)
X                    FEMessage(1);
X                else
X                {   sprintf(mes[1],"core being saved");
X                    FEMessage(2);
X                }
X                while(hangup) ;
X                WriteSoup(1);
X                exit(0);
X            }
X#endif
X            tgl->gbits[dist][ce->c.tr] |= (1 << 1);
X        }
X    }
X}
END_OF_FILE
if test 16574 -ne `wc -c <'bookeep.c'`; then
    echo shar: \"'bookeep.c'\" unpacked with wrong size!
fi
# end of 'bookeep.c'
fi
if test -f 'tierra.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tierra.c'\"
else
echo shar: Extracting \"'tierra.c'\" \(15942 characters\)
sed "s/^X//" >'tierra.c' <<'END_OF_FILE'
X/* tierra.c  28-10-91  main module of Tierra Synthetic Life Simulator */
X/** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
X
X#include "license.h"
X
X#ifndef lint
Xstatic char     sccsid[] = "%W% %G%";
X#endif
X
X#include "tierra.h"
X#include "declare.h"
X#include "soup_in.h"
X#include <sys/types.h>
X#include <fcntl.h>
X#include <signal.h>
X#ifdef unix
X#include <unistd.h>
X#endif
X
XI32s          FindCell;
XI32s          itime, mtime;
Xstruct event  FindTime;
Xint           run_flag;	/* NEW GLOBAL */
X
X#define	_DBGMainModule
X#include "debug.h"		/* some useful debugging stuff */
X#undef	_DBGMainModule
X
X#ifdef SOCKETS
X
X#include "alreques.h"		/* request constants, ids, etc. */
X#include "allayer.h"		/* public header for AL Layer */
X#include "tlayer.h"		/* public header for T layer */
X#include "tlayerp.h"
X
Xstatic void	_t_memory_stats P_(( unsigned char which, void *indata,
X		    int inlen, void **outdata, int *outdatalen ));
Xstatic void	_t_sim_runcontrol P_(( unsigned char which, void *data,
X		    int datalen ));
X
Xstatic void	_t_init_birthdeath P_(( ALtCLink *clink ));
X
Xstatic TtMonInitRoutine         _t_myinitroutines[] = {
X  { ALrdBirthDeath, _t_init_birthdeath }
X};
X
Xstatic void _t_init_birthdeath( clink )
X    ALtCLink  *clink;
X{
X  Pcells                ce;
X  I32s                  i;
X
X  TRepBirthDeathInit( clink, 1 );
X  for ( i = 0; i < CellsSize; i++ ) {
X    ce = cells + i;
X    if ( ce->ld ) {
X      if ( ce->mm.s )
X        TRepBirthDirect( clink, ce->mm.p, ce->mm.s );
X      if ( ce->md.s )
X        TRepBirthDirect( clink, ce->md.p, ce->md.s );
X    }
X  }
X  TRepBirthDeathInit( clink, 0 );
X}
X
Xstatic void _t_memory_stats( which, indata, inlen, outdata, outdatalen )
X  u_char	which;
X  void		*indata;
X  int		inlen;
X  void		**outdata;
X  int		*outdatalen;
X{   ALrtMemStats  *ms;
X
X    if (( ms = (ALrtMemStats *)ALMalloc(sizeof(ALrtMemStats))) ==
X        (ALrtMemStats *)NULL)
X    {   sprintf(mes[0], "_t_memory_stats: can't malloc");
X        FEError(1);
X        exit(1);
X    }
X    ms->memsize = SoupSize;
X    *outdata = ms;
X    *outdatalen = sizeof(ALrtMemStats);
X}
X/*-----------------------------------------------------------------------*/
Xstatic void
X_t_query_org( which, indata, inlen, outdata, outdatalen )
X  u_char        which;
X  void          *indata;
X  int           inlen;
X  void          **outdata;
X  int           *outdatalen;
X{
X  ALrtQueryOrg          *qo;
X  ALrtOrgInfo           *oi;
X
X  FILE *dan_fp;
X  I32s  tpci;
X  I8s   tmd;
X  I8s tstr[200];
X  Pgl g;
X  I32s  tl=1;
X  I32s dan_fd, tsz;
X
X  qo = (ALrtQueryOrg *)indata;
X  fprintf( stderr, "QueryOrg: received query for [ %d : %d ]\n",
X           qo->start, qo->length );
X
X  if ((IsFree(ad(qo->start))))
X     {
X       if (( oi = (ALrtOrgInfo *)ALMalloc( 1 )
X           ) == (ALrtOrgInfo *)NULL ) {
X         fprintf( stderr, "_t_query_org: can't malloc\n" );
X         exit( 1 );
X      }
X      *oi = '@';
X      *outdata = oi;
X      *outdatalen = 1;
X     }
X else {
X    WhichCell(ad(qo->start),&tpci,&tmd);
X    if (tmd == 'm')
X    {
X    extract(tpci);
X    sprintf(tstr,"arg x %s%4.4d.gen %s\n",GenebankPath,
X            (cells+tpci)->d.gen.size, (cells+tpci)->d.gen.label);
X    system(tstr);
X
X    sprintf(tstr,"%4.4d%s",(cells+tpci)->d.gen.size, 
X	   (cells+tpci)->d.gen.label);
X    
X    dan_fd = open(tstr,O_RDONLY);
X    if( dan_fd < 0 ) {
X       fprintf(stderr,"temp gene file can't read");
X        perror("moo");
X       exit(-666);
X       }
X     tsz = (int)lseek(dan_fd,0L,SEEK_END); 
X     lseek(dan_fd,0L,SEEK_SET); 
X     if (( oi = (ALrtOrgInfo *)ALMalloc( (tsz ) + 20)  
X        ) == (ALrtOrgInfo *)NULL ) {
X      fprintf( stderr, "_t_query_org: can't malloc\n" );
X      exit( 1 );
X    }
X    *oi = ' ';
X    tl = read(dan_fd,oi,tsz) ;
X    if (tl < 0){
X       fprintf(stderr,"temp gene file can't read");
X        perror("moo");
X       exit(-666);
X       }
X    close(dan_fd);   
X    sprintf(tstr,"rm %4.4d%s\n",(cells+tpci)->d.gen.size, 
X	   (cells+tpci)->d.gen.label);
X    system(tstr); 
X    *outdata = oi;
X    *outdatalen = tsz +1; 
X    }
X    else
X    {
X     if (( oi = (ALrtOrgInfo *)ALMalloc(100)  
X        ) == (ALrtOrgInfo *)NULL ) {
X      fprintf( stderr, "_t_query_org: can't malloc\n" );
X      exit( 1 );
X      }
X    sprintf(oi,"\nchild data: yet yet able to display\n\n");
X    *outdata = oi;
X    *outdatalen = 100;
X    }
X
X}
X}
X
X
X
X/*-----------------------------------------------------------------------*/
X/* this routine is nto finished, but helps in monitoring runs
X   till the tty version of ov is ready  */
Xstatic void
X_t_query_size(size_class)
XI32s size_class;
X{
XI32s top_buf,tc,tl,c,t,thit;
Xtypedef struct size_buf {
X   I32s count;
X   I8s *gene;
X   I32s moves;
X   I32s flags;
X   I32s bits;
X   } bf;
X   bf buf[10];
X
Xif((size_class < 1) || (size_class > 20000)) return;
X
Xthit = 0;
Xtop_buf = -1;
X
Xfor(t=0; t< 10; t++)
X   {
X   buf[t].count=0;
X   buf[t].moves=0;
X   buf[t].gene=NULL;
X   buf[t].bits=0;
X   buf[t].flags=0;
X   }
X
Xfor(c = 2; c < CellsSize; c++)
X   {
X   if (
X      ((cells+c)->ld) &&
X      ((cells+c)->mm.s == size_class)) 
X      {
X      for(t = 0; t < 10; t++)
X	 {
X	 if (buf[t].gene == NULL ) { thit = 0; t = 500; break;}
X         if (strcmp((cells+c)->d.gen.label,buf[t].gene)== 0 )
X	    {
X	    thit = 1;
X            buf[t].count++;
X	    buf[t].flags += (cells+c)->d.flags - (cells+c)->d.d1.flags;
X	    buf[t].moves += (cells+c)->d.mov_daught;
X            /* buf[t].bits |= (cells+c)->d.bits; */
X	    t = 500;
X
X	    }
X  	 }
X      if (thit== 0)
X            {
X	    thit =1;
X	    top_buf += (top_buf < 11) ? 1 : 0;
X	    if (top_buf > 10) break;
X            buf[top_buf].gene = (cells+c)->d.gen.label;
X            buf[top_buf].count++;
X            /* buf[top_buf].bits |= (cells+c)->d.bits;  */
X            buf[top_buf].flags += (cells+c)->d.flags - (cells+c)->d.d1.flags;
X            buf[top_buf].moves += (cells+c)->d.mov_daught;
X            }
X
X      }
X   }
X sprintf(mes[0],"==========================================================");
X sprintf(mes[1],"TIERRA: Size Class %d (first 10)",size_class);
X sprintf(mes[2],"==========================================================");
X sprintf(mes[3],"Gene:\t#\t%% Mem\tErrs\tMove\tBits");
X FEError(4);
X
X   for(t= 0; t < 10; t++)
X      {
X      if (buf[t].count < 1) break;
X      sprintf(mes[0],"%3.3s\t%d\t%d\t%d\t%d\t%d",
X	buf[t].gene,
X	buf[t].count,
X	(int) (100.0 * buf[t].count * size_class / SoupSize),
X	(int) (buf[t].flags / buf[t].count),
X	(int) (buf[t].moves / buf[t].count),
X	buf[t].bits
X	);
X      FEError(1); 
X      }
X    }
X/*-----------------------------------------------------------------------*/
X
Xstatic void _t_sim_runcontrol( which, data, datalen )
X  u_char	which;
X  void		*data;
X  int		datalen;
X{   switch (which)
X    {   case ALrsPauseSim:  run_flag = 0; break;
X        case ALrsResumeSim: run_flag = 1; break;
X        default:
X        {   sprintf(mes[0], "_t_sim_runcontrol: unknown state request: %d",
X                which);
X            FEError(1);
X        }
X        break;
X    }
X}
X
X#endif	/* SOCKETS */
X
X/* THE CODE IN SHUTD IS NOT IS NOT FINISHED ,
X   when I get acces to a pc, i will fully test it out ... */
X
Xvoid shutd(sig,code,scp,addr)
X    I32s  sig,code;
X    /* struct sigcontext *scp; */
X    I32s *scp; /* DO NOT USE !!!!! */
X    I8s  *addr;
X{
X   I8s  answer;
X   I32s tsz;
X   I8s  data[85];
X
X   sprintf(mes[0],"\tTIERRA: trapped a signal! # %d @ %d",sig, InstExe.i);
X   FEMessage(1);
X#ifdef SOCKETS
X   sprintf(mes[0],"\tTIERRA: port %d",TS.port);
X   FEMessage(1);
X#endif
X   sprintf(mes[0],"\tTIERRA: trapped a signal! # %d @ %d",sig, InstExe.i);
X   FEError(1);
X#ifdef SOCKETS
X   sprintf(mes[0],"\tTIERRA: port %d",TS.port);
X   FEError(1);
X#endif
X   sprintf(mes[0],"Variable | siZe info | Save soup | save & Quit | ");
X   sprintf(mes[1],"Exit     | Continue  | {v,z,s,q,e,c}");
X   FEError(2);
X   fgets(data,84,stdin);
X   sscanf(data,"%c", &answer);
X   if (answer == 'e') exit(-666);
X   if (answer == 'v') 
X   {
X      sprintf(mes[0],"To alter any global variable from soup_in, type\n");
X      sprintf(mes[1],"the variable name (using proper case), a space,\n");
X      sprintf(mes[2],"an equal sign, a space, and the new value.\n");
X      sprintf(mes[3],"Use no space at start of line.  Some examples:\n");
X      sprintf(mes[4],"alive = 0");
X      sprintf(mes[5],"DistProp = .6");
X      sprintf(mes[6],"GenebankPath = newpath/");
X      FEError(7);
X      fgets(data,84,stdin);
X      if (!GetAVar(data))
X      {   sprintf(mes[0],"Not a valid soup_in variable: %s", data);
X          FEError(1);
X      }
X   }
X
X   if (answer == 'z')
X      {
X      sprintf(mes[0],"Enter a size class ( eg: 80 ) to examine ");
X      FEError(1);
X      fgets(data,84,stdin);
X      sscanf(data,"%d", &tsz);
X/*    _t_query_size(tsz); */
X      }
X
X   if (answer == 's')
X   {  WriteSoup(1);
X      sprintf(mes[0],"TIERRA Soup Written ...");
X      FEError(1);
X   }
X   if (answer == 'q')
X   {  WriteSoup(1);
X      sprintf(mes[0],"TIERRA Soup Written ...");
X      FEError(1);
X      exit(-333);
X   }
X   sprintf(mes[0],"Continuing from interupt...");
X   FEError(1);
X}
X
Xint main(argc,argv)
X    int   argc;
X    char  *argv[];
X{
X
X    signal(SIGINT, shutd);
X
X    if (argc > 1) 
X    {   sprintf(soup_fn,"%s", argv[1]);
X    }
X    else
X    {
X#ifdef IBM3090
X        strcpy(soup_fn,"soup_in.io.d");
X#else
X        strcpy(soup_fn,"soup_in");
X#endif
X    }
X#ifdef SOCKETS
X    setpgrp( 0, getpid() );	/* SHOULD BE DONE AS PART OF SV!!! */
X
X    TInitialise( _t_myinitroutines, 1, argc, argv );
X
X    TRegisterQueryhandler( ALrqMemStats, _t_memory_stats );
X    TRegisterQueryhandler( ALrqQueryOrg, _t_query_org );
X    /* TRegisterQueryhandler( ALrqQueryOrg, _t_query_size ); */
X
X    TRegisterStatehandler( ALrsPauseSim, _t_sim_runcontrol );
X    TRegisterStatehandler( ALrsResumeSim, _t_sim_runcontrol );
X
X#endif
X
X    run_flag = 1;
X    GetSoup(); 
X    life();
X    WriteSoup(1);
X    return 0;
X}
X
Xvoid life() /* doles out time slices and death */
X{   while(InstExe.m < alive)
X    {   if ( run_flag == 1 )
X        {   (*slicer)();
X            ReapCheck();
X        }
X        else
X            sleep( 1 );
X#ifdef SOCKETS
X        TCheckRequestQueue();
X#endif
X    }
X}
X
Xvoid TimeSlice(ci, size_slice)
XI32s  ci, size_slice;
X{   Pcells  ce = cells + ci;
X    I16s          di;  /* decoded instruction */
X
X    ce->d.ib += size_slice;
X    for(is.ts = ce->d.ib; is.ts > 0; )
X    {   di = FetchDecode(ci);
X        (*id[di].execute)(ci);
X        ce = cells + ci;
X        IncrementIp(ci);
X        SystemWork(ci);
X    }
X}
X
XI16s FetchDecode(ci)
XI32s  ci;
X{   Pcells  ce = cells + ci;
X    I16s    di;
X
X    di = soup[ce->c.ip][ce->c.tr].inst;
X    is.oip = ce->c.ip;
X    (*id[di].parse)(ci);
X    return di;
X}
X
Xvoid IncrementIp(ci)
XI32s  ci;
X{   Pcells  ce = cells + ci;
X
X    ce->c.ip += is.iip;
X    ce->c.ip = ad(ce->c.ip);
X    ce->d.ib -= is.dib;
X    is.ts -= is.dib;
X    if (WatchExe)
X        GenExExe(ci, is.oip);
X}
X
Xvoid SystemWork(ci)
XI32s  ci;
X{ 
X    (cells + ci)->d.inst++;
X    if((cells + ci)->c.fl)
X    {   (cells + ci)->d.flags++;
X	if(!(cells + ci)->d.dm)
X            UpRprIf(ci);
X    }
X    CountMutRate++;
X    if(CountMutRate >= RateMut && RateMut)
X    {   mutate();
X        TotMut++;
X        CountMutRate = tlrand() % RateMut;
X    }
X    if(isolate) extract(extr);
X    InstExe.i++;
X    if(InstExe.i > 1000000L)
X    {   InstExe.i %= 1000000L; InstExe.m++;
X        if(DropDead && (InstExe.m > LastDiv.m + DropDead))
X        {   sprintf(mes[0],
X                "SystemWork: soup has died, saving system to disk");
X            FEMessage(1);
X            WriteSoup(1);
X            exit(0);
X        }
X        if(!(InstExe.m % SaveFreq)) WriteSoup(0);
X        plan();
X    }
X}
X
Xvoid mutate()
X{   Ind   i;
X
X    i = tlrand() % SoupSize;
X    mut_site(soup + i, tcrand() % 2);
X    MutBookeep(i);
X}
X
Xvoid mut_site(s, t)
XHpInst  s;
XI8s     t;
X{   s[0][t].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); }
X
Xvoid ReapCheck() /* kill some cells if necessary */
X{   I32s  i, t, dtime;
X    struct event  result;
X
X    if(DistFreq < 0 || !reaped || (!DistNext.m && !DistNext.i)) return;
X    dtime = SubEvent(&InstExe, &DistNext, &result);
X    if(dtime > 0)
X    {   Disturb = InstExe;
X        DistNext.m = DistNext.i = 0L;
X        t = (I32s) (DistProp * (float) NumCells);
X        if(t == NumCells)
X            t--;
X        for(i = 0; i < t; i++)
X            reaper(0);
X    }
X}
X
Xvoid reaper(ex)
XI8s  ex;  /* is a creature executing now ? */
X{   Pcells  ce; /* cell to be reaped */
X    I32s    l_top, rtime; /* local TopReap */
X    struct event  result;
X    Pcells  nc; /* daughter of cell to be reaped */
X    FpInst  in;
X    I32s    i, j;
X
X    if(ex && TopReap == ThisSlice)
X        DownReaper(TopReap);
X    if(ex && DistFreq > 0 && !DistNext.m && !DistNext.i)
X    {   rtime = SubEvent(&InstExe, &Disturb, &result);
X        rtime = (I32s) (DistFreq * (float) rtime);
X        DistNext = Disturb = InstExe;
X        DistNext.m += rtime / 1000000L;
X        DistNext.i += rtime % 1000000L;
X        DistNext.m += DistNext.i / 1000000L;
X        DistNext.i %= 1000000L;
X    }
X    if(NumCells == 1)
X    {   sprintf(mes[0],
X            "Tierra reaper error 0, attempt to reap last creature");
X        if (!hangup)
X            FEMessage(1);
X        else
X        {   sprintf(mes[1],"core being saved");
X            FEMessage(2);
X        }
X        while(hangup) ;
X        WriteSoup(1);
X        exit(0);
X    }
X    ce = cells + TopReap; l_top = TopReap;
X#ifdef ERROR
X    if(!ce->ld || !NumCells || (!ce->mm.s && !ce->md.s))
X    {   sprintf(mes[0],
X            "Tierra reaper error 1, attempt to reap non-existant cell");
X        if (!hangup)
X            FEMessage(1);
X        else
X        {   sprintf(mes[1],"core being saved");
X            FEMessage(2);
X        }
X        while(hangup) ;
X        WriteSoup(1);
X        exit(0);
X    }
X#endif
X    if(ce->mm.s)
X    {
X#ifdef ERROR
X        if(ce->mm.p < 0 || ce->mm.p >= SoupSize)
X        {   sprintf(mes[0],
X    "Tierra reaper error 2: attemp to deallocate main memory not in soup");
X            if (!hangup)
X                FEMessage(1);
X            else
X            {   sprintf(mes[1],"core being saved");
X                FEMessage(2);
X            }
X            while(hangup) ;
X            WriteSoup(1);
X            exit(0);
X        }
X#endif
X        for(i = 0; i < ce->mm.s; i++)
X        {   in = soup + ad(ce->mm.p + i);
X            for (j = 0; j < PLOIDY; j++)
X                in[0][j].write = in[0][j].read = in[0][j].exec = 0;
X        }
X        MemDealloc(ce->mm.p,ce->mm.s);
X    }
X    if(ce->md.s)
X    {
X#ifdef ERROR
X        if(ce->md.p < 0 || ce->md.p >= SoupSize)
X        {   sprintf(mes[0],"Tierra reaper error 3: attemp to deallocate \
X                daughter memory not in soup");
X            if (!hangup)
X                FEMessage(1);
X            else
X            {   sprintf(mes[1],"core being saved");
X                FEMessage(2);
X            }
X            while(hangup) ;
X            WriteSoup(1);
X            exit(0);
X        }
X#endif
X        for(i = 0; i < ce->mm.s; i++)
X        {   in = soup + ad(ce->mm.p + i);
X            for (j = 0; j < PLOIDY; j++)
X                in[0][j].write = in[0][j].read = in[0][j].exec = 0;
X        }
X        if(ce->d.ni > -1) /* cleanup daughter cpu */
X        {   nc = cells + ce->d.ni;
X            if(nc->d.is) /* cleanup daughter instruction pointer */
X                RmvFrmSlicer(ce->d.ni);
X            NumCells--;
X            InitCell(ce->d.ni);
X        }
X        MemDealloc(ce->md.p,ce->md.s);
X    }
X    RmvFrmSlicer(l_top);
X    RmvFrmReaper(l_top);
X    ReapBookeep(l_top);
X/*  InitCell(ci); done in ReapBookeep(ci); */
X}
X
XI32s SubEvent(event1, event2, result) /* subtract e2 from e1 */
Xstruct event  *event1, *event2, *result;
X{   result->m =  event1->m - event2->m;
X    result->m += (event1->i - event2->i) / 1000000L;
X    result->i =  (event1->i - event2->i) % 1000000L;
X    if(result->m <= 0)
X        return result->i + (result->m * 1000000L);
X    if(result->i < 0)
X    {   --result->m;
X        result->i += 1000000L;
X    }
X    return result->i + (result->m * 1000000L);
X}
END_OF_FILE
if test 15942 -ne `wc -c <'tierra.c'`; then
    echo shar: \"'tierra.c'\" unpacked with wrong size!
fi
# end of 'tierra.c'
fi
if test -f 'tierra.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tierra.h'\"
else
echo shar: Extracting \"'tierra.h'\" \(11435 characters\)
sed "s/^X//" >'tierra.h' <<'END_OF_FILE'
X/* tierra.h 19-8-91 */
X/* type, structure and function definitions for the Tierra simulator */
X/** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
X
X#include "license.h"
X
X/*
Xtierra_h_sccsid: @(#)tierra.h	2.9	10/6/91
X*/
X
X#ifndef LTIERRA_H
X#define LTIERRA_H 
X
X#include <stdio.h>
X#include <math.h>
X#include <string.h>
X#include <time.h>
X#include "configur.h"
X#include "portable.h"
X
X#define IsBit(seed, bit) (((seed) & (1 << (bit))) ? 1 : 0)
X#define ad(A) ((A) >=0 ? ((A)%SoupSize):((SoupSize-(-(A)%SoupSize))%SoupSize))
X#define mo(A,B) ((A) >=0 ? ((A)%(B)) : (((B)-(-(A)%(B)))%(B)))
X
X#if INSTBITNUM == 5
X
X#ifdef __TURBOC__
Xstruct Inst {
X    unsigned int  inst:5;
X    unsigned int  exec:1;
X    unsigned int write:1;
X    unsigned int  read:1;
X    } ;
X#else
Xstruct Inst {
X    unsigned char  inst:5;
X    unsigned char  exec:1;
X    unsigned char write:1;
X    unsigned char  read:1;
X    } ;
X#endif
X
X#endif
X
Xtypedef struct Inst  Instruction[PLOIDY];
X
Xtypedef Instruction Hp  HpInst;
Xtypedef Instruction Fp  FpInst;
Xtypedef Instruction Np  NpInst;
Xtypedef struct Inst Fp  FpIns;
X
Xtypedef I8s GenBits[PLOIDY];
X
Xtypedef GenBits Hp  HpGenB;
X
Xtypedef struct cell Hp  Pcells;
Xtypedef struct s_list  Hp Psl;
Xtypedef struct g_list  Hp Pgl;
Xtypedef struct mem_fr  Hp Pmf;
Xtypedef I32s  Ind;   /* index for addressing instructions in soup */
Xtypedef I32s  Num;   /* type for use in numerical CPU registers */
Xtypedef I32s  Reg;   /* type for use in CPU registers */
Xtypedef Reg  *Preg; 
X
Xstruct InstDef { /* structure for instruction set definitions */
X    I8s   op; /* op code */
X    I8s   mn[9]; /* assembler mnemonic */
X    void  (*execute) P_((I32s)); /* pointer to execute function */
X    void  (*parse) P_((I32s)); /* pointer to parse function */
X    } ;
X
Xstruct ArgInstDef { /* structure for instruction set definitions */
X    I8s   op; /* op code */
X    I8s   mn[9]; /* assembler mnemonic */
X    } ;
X
Xstruct inst { /* struct for passing arguments from parse to execute */
X    Preg   dreg; /* pointer to destination register */
X    I32s   dval; /* original destination value */
X    FpIns  dins; /* pointer to destination instruction */
X    I8s    dtra; /* destination track */
X    I32s   dmod; /* destination modulused positive this size */
X    I32s   dran; /* destination kept in signed range of this value */
X
X    Preg   dreg2; /* pointer to 2nd destination register */
X    I32s   dval2; /* original destination value */
X    FpIns  dins2; /* pointer to 2nd destination instruction */
X    I8s    dtra2; /* 2nd destination track */
X    I32s   dmod2; /* 2nd dest modulused positive this size */
X    I32s   dran2; /* 2nd dest kept in signed range of this value */
X
X    Preg   sreg; /* pointer to source register */
X    FpIns  sins; /* pointer to source instruction */
X    I32s   sval; /* source value */
X    I8s    stra; /* source track */
X
X    Preg   sreg2; /* pointer to 2nd source register */
X    FpIns  sins2; /* pointer to 2nd source instruction */
X    I32s   sval2; /* 2nd source value */
X    I8s    stra2; /* 2nd source track */
X
X    I8s    mode;    /* mode of instruction */
X    I8s    mode2;   /* 2nd mode of instruction */
X    Ind    oip;     /* address of instruction being executed: ce->c.ip */
X    I8s    iip;     /* amount to increment instruction pointer */
X    I8s    dib;     /* amount to decrement instruction bank */
X    I16s   ts;      /* size of time slice, used to control central loop */
X    } ;
X
Xstruct event {  /* structure for time measured in executed instructions */
X    I32s  m;   /* count of millions of instructions */
X    I32s  i;   /* count of instructions */
X    } ;
X
Xstruct genotype {
X    I32s  size;      /* size class (~species) */
X    I8s   label[4];  /* genotype label */
X    } ;
X
Xstruct gl_index {
X    I32s  si;  /* size index */
X    I32s  gi;  /* genotype index */
X    } ;
X
Xstruct metabolism {  /* structure for metabolic data */
X    I32s  inst;       /* count of instructions executed */
X    I32s  flags;      /* count of flags (error conditions) set */
X    I32s  mov_daught; /* count of number of instructions moved to daughter */
X    I8s   BreedTrue; /* 0=not, 1 = this daughter genetically same as parent */
X    } ;
X
Xstruct dem {  /* structure for demographic data */
X    struct genotype  gen; /* size and genotype name of cell */
X    I32s  fecundity;   /* count of number of daughter cells produced */
X    I32s  flags;       /* count of flags (error conditions) set */
X    I32s  mov_daught;  /* count of number of instructions moved to daughter */
X    I32s  inst;        /* count of instructions executed */
X    I32s  mut;        /* 0 = no somatic mutations, >= 1 = somatic mutations */
X    I32s  flaw;        /* 0 = no flaws, >= 1 = flaws */
X    struct metabolism  d1;    /* metabolic data for first daughter */
X    struct genotype  parent;  /* size and genotype name of parent */
X    struct gl_index  gli;  /* index to this genotype in the sl-gl arrays */
X    I16s  ib;  /* instruction bank */
X    I32s  ni;  /* index to cells array of daughter cell */
X    I8s   is;  /* 1 = this cpu is active, in the slicer; 0 = not active */
X    I8s   dm;  /* 0 = mother, 1 = daughter */
X    I8s   ploidy; /* how many tracks */
X    } ;
X
Xstruct que {  /* pointers to previous and next cells in queues */
X    I32s  n_time; /* index of next cell in slicer queue */
X    I32s  p_time; /* index of previous cell in slicer queue */
X    I32s  n_reap; /* index of next cell in reaper queue */
X    I32s  p_reap; /* index of previous cell in reaper queue */
X    } ;
X
Xstruct mem {  /* structure for allocated memory block of cell */
X    Ind   p;  /* location of start of cell memory */
X    I32s  s;  /* size of cell memory */
X    } ;
X
Xstruct cpu {  /* structure for registers of virtual cpu */
X    Reg   re[NUM_REGS];  /* array of registers */
X    Reg   sp;  /* stack pointer */
X    Reg   st[STACK_SIZE];  /* stack */
X    Reg   ip;  /* instruction pointer */
X    I8s   fl;  /* flag */
X    I8s   tr; /* which track currently being executed */
X    } ;
X
Xstruct cell {  /* structure for cell of organisms */
X    struct dem  d;   /* fecundity and times and dates of birth and death */
X    struct que  q;   /* pointers to previous and next cells in queues */
X    struct mem  mm;  /* main cell memory */
X    struct mem  md;  /* daughter cell memory */
X    struct cpu  c;   /* virtual cpu */
X    I8s         ld;  /* 0 = dead, 1 = alive */
X    } ;  /* sizeof(struct cell) = XX */
X
Xstruct mem_fr { /* structure for free memory list */
X    Ind   p;  /* location in soup of free block */
X    Ind   s;  /* size of free block */
X    I32s  n;  /* index of next free block in FreeMem array */
X    I8s   o;  /* 1 = element in use, 0 = element open for use */
X    } ;  /* sizeof(struct mem_fr) = X */
X
Xstruct s_list { /* structure for size list */
X    I32s  size;  /* genotype size */
X    I32s  num;   /* number of genotypes of this size */
X    I32s  num_s; /* number of genotypes of this size saved to disk */
X    I32s  num_q; /* number of genotypes of this size in gen_queue */
X    I32s  num_e; /* number of genotypes saved to disk or extant */
X    I32s  a_num; /* allocated size of *g array */
X    Pgl   g;    /* array of g_list structures */
X    } ;
X
Xstruct g_list {  /* structure for genotype list */
X    I32s   pop;        /* current number of adults of this genotype in soup */
X    struct genotype  gen;  /* genotype of creature */
X    struct genotype  parent;    /* genotype of parent genotype (ancestor) */
X    I32u   bits;           /* see below */
X    struct metabolism  d1; /* metabolic data for first daughter */
X    struct metabolism  d2; /* metabolic data for second daughter */
X    struct event  originI;  /* time of origin, in instruction time */
X    I32s   originC;  /* time of first origin of genotype, in clock time */
X    float  MaxPropPop;  /* max. propor. of NumCells reached by this gen. */
X    float  MaxPropInst; /* max. propor. of SoupSize reached by this gen. */
X    I8s    Fp comments;  /* pointer to string containing comments */
X    I8s    ploidy; /* how many tracks */
X    I8s    track; /* which track are we on now ... */
X    HpInst genome;       /* pointer to genome itself */
X    HpGenB gbits;        /* pointer to genome itself */
X    struct gl_index  b;  /* next (below) in queue */
X    struct gl_index  a;  /* previous (above) in queue */
X    } ;
X
X/* definitions of bits:
X    bit  0  permanent genotype name
X    bit  1  saved to disk
X    bit  2  EXs = executes own instructions (self)
X    bit  3  EXd = executes daughter's instructions
X    bit  4  EXo = executes other cell's instructions
X    bit  5  EXf = executes instructions in free memory
X    bit  6  EXh = own instructions are executed by other creature (host)
X    bit  7  TCs = matches template complement of self
X    bit  8  TCd = matches template complement of daughter
X    bit  9  TCo = matches template complement of other
X    bit 10  TCf = matches template complement of free memory
X    bit 11  TCh = own template complement is matched by other creature (host)
X    bit 12  TPs = uses template pattern of self
X    bit 13  TPd = uses template pattern of daughter
X    bit 14  TPo = uses template pattern of other
X    bit 15  TPf = uses template pattern of free memory
X    bit 16  TPh = own template pattern is used by other creature (host)
X    bit 17  MFs = moves instruction from self
X    bit 18  MFd = moves instruction from daughter
X    bit 19  MFo = moves instruction from other cell
X    bit 20  MFf = moves instruction from free memory
X    bit 21  MFh = own instructions are moved by other creature (host)
X    bit 22  MTs = moves instruction to self
X    bit 23  MTd = moves instruction to daughter
X    bit 24  MTo = moves instruction to other cell
X    bit 25  MTf = moves instruction to free memory
X    bit 26  MTh = is written on by another creature (host)
X    bit 27  MBs = executing other creatures code, moves inst from self
X    bit 28  MBd = executing other creatures code, moves inst from daughter
X    bit 29  MBo = executing other creatures code, moves inst from other cell
X    bit 30  MBf = executing other creatures code, moves inst from free memory
X    bit 31  MBh = other creature uses another cpu to move your instructions
X*/
X
Xstruct LastOut { /* record of last data output to disk */
X    I32s  time;  /* elapsed time */
X    I32s  ctime; /* millions of instructions */
X    I8s   bd;    /* b = birth, d = death */
X    I32s  size;  /* size of creature */
X    I8s   label[4];  /* genotype name of creature, e.g., aaa */
X    } ;
X
Xstruct SizList { /* use for output of size list */
X    I32s  size;  /* genome size */
X    I32s  pos;   /* position is sl */
X    I32s  ext;   /* number of saved or extant genotypes of this size */
X    I8s   dir;   /* does a directory for this size exist */
X    } ;
X
Xtypedef struct {
X    I8s   magic[4];
X    I32s  g_off;
X    I16s  size, n, n_alloc;
X} head_t;
X
Xtypedef struct {
X    I8s   gen[3];
X    I8s   pgen[3];
X    I16s  psize;
X    I32u  bits;
X    I32s  originC;
X    I16s  mpp, mpi;
X    I32s  ptr;		/* reserved for future versions */
X    struct event originI;
X    struct metabolism d1, d2;
X    I8s pt;  /* ploidy and track */
X} indx_t;
X
X#ifdef SOCKETS
X/*** new structure for global data *************************************/
X
X#ifndef MAXHOSTNAMELEN
X#include <sys/param.h>
X#endif
X
X#ifndef u_long
X#include <sys/types.h>
X#endif
X
Xextern char * ALRealloc P_((char  *ptr; u_int  size));
X
X/***********************************************************************/
X#endif
X
X#include "prototyp.h"
X
X#endif
END_OF_FILE
if test 11435 -ne `wc -c <'tierra.h'`; then
    echo shar: \"'tierra.h'\" unpacked with wrong size!
fi
# end of 'tierra.h'
fi
echo shar: End of archive 5 \(of 7\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    echo "Please see the README file(s) 
    for detailed instructions"
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
