[avida-cvs] avida CVS commits: /current/source/cpu cpu_memory.cc hardware_4stack.cc hardware_4stack.hh hardware_cpu.cc hardware_cpu.hh head.cc head.hh test_cpu.cc test_cpu.hh /current/source/event cPopulation.events cPopulation_construct_event_auto.ci cPopulation_descr.ci cPopulation_enums_auto.ci cPopulation_event_list cPopulation_name2enum_auto.ci cPopulation_process_auto.ci /current/source/main avida.cc callback_util.cc callback_util.hh config.hh organism.cc organism.hh phenotype.cc pop_interface.cc pop_interface.hh population.cc population.hh population_cell.cc population_cell.hh /current/source/tools Makefile.am /current/source/viewers Makefile.am bar_screen.cc map_screen.cc map_screen.hh symbol_util.cc text_screen.cc text_screen.hh view.cc view.hh zoom_screen.cc zoom_screen.hh

wisnelaw avida-cvs at alife.org
Thu Jul 17 03:36:56 PDT 2003


wisnelaw		Wed Jul 16 19:36:56 2003 EDT

  Modified files:              
    /avida/current/source/cpu	cpu_memory.cc hardware_4stack.cc 
                             	hardware_4stack.hh hardware_cpu.cc 
                             	hardware_cpu.hh head.cc head.hh 
                             	test_cpu.cc test_cpu.hh 
    /avida/current/source/event	cPopulation.events 
                               	cPopulation_construct_event_auto.ci 
                               	cPopulation_descr.ci 
                               	cPopulation_enums_auto.ci 
                               	cPopulation_event_list 
                               	cPopulation_name2enum_auto.ci 
                               	cPopulation_process_auto.ci 
    /avida/current/source/main	avida.cc callback_util.cc 
                              	callback_util.hh config.hh organism.cc 
                              	organism.hh phenotype.cc 
                              	pop_interface.cc pop_interface.hh 
                              	population.cc population.hh 
                              	population_cell.cc population_cell.hh 
    /avida/current/source/tools	Makefile.am 
    /avida/current/source/viewers	Makefile.am bar_screen.cc 
                                 	map_screen.cc map_screen.hh 
                                 	symbol_util.cc text_screen.cc 
                                 	text_screen.hh view.cc view.hh 
                                 	zoom_screen.cc zoom_screen.hh 
  Log:
  Additions:
  4 Stack Hardware complete.  Inject command and parasite abilities now implemented.
  Text viewer environment view mode (in progress)
  
  Fixes:
  Text viewer Zoom Screen Mini-Map fixed
  Text viewer Modified Map screen now in color
  Text viewer Thread Map screen now shows number of threads
  
  -law
  
  
  
-------------- next part --------------
Index: avida/current/source/cpu/cpu_memory.cc
diff -u avida/current/source/cpu/cpu_memory.cc:1.9 avida/current/source/cpu/cpu_memory.cc:1.10
--- avida/current/source/cpu/cpu_memory.cc:1.9	Sat May 17 02:48:07 2003
+++ avida/current/source/cpu/cpu_memory.cc	Wed Jul 16 19:36:54 2003
@@ -239,4 +239,3 @@
     genome[i + pos] = in_genome[i];
   }
 }
-
Index: avida/current/source/cpu/hardware_4stack.cc
diff -u avida/current/source/cpu/hardware_4stack.cc:1.9 avida/current/source/cpu/hardware_4stack.cc:1.10
--- avida/current/source/cpu/hardware_4stack.cc:1.9	Fri Jun 13 14:49:58 2003
+++ avida/current/source/cpu/hardware_4stack.cc	Wed Jul 16 19:36:54 2003
@@ -12,6 +12,7 @@
 #include "hardware_4stack.hh"
 
 #include "../tools/string_util.hh"
+#include "../tools/random.hh"
 
 #include "../main/config.hh"
 #include "../main/inst_set.hh"
@@ -73,7 +74,7 @@
   id = _id;
 
   for (int i = 0; i < NUM_LOCAL_STACKS; i++) local_stacks[i].Clear();
-  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
+  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(0, in_hardware);
 
   cur_head = HEAD_IP;
   input_pointer = 0;
@@ -307,98 +308,10 @@
     cInstEntry4Stack("Val-Mod",       &cHardware4Stack::Inst_Mod),
     //35
     cInstEntry4Stack("ThreadKill",   &cHardware4Stack::Inst_KillThread),
-    
-    /*
-    cInstEntry4Stack("nop-A",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-B",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-C",     &cHardware4Stack::Inst_Nop),
-
-    cInstEntry4Stack("NULL",  &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-X",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("if-equ-0",  &cHardware4Stack::Inst_If0),
-    cInstEntry4Stack("if-not-0",  &cHardware4Stack::Inst_IfNot0),
-    cInstEntry4Stack("if-n-equ",  &cHardware4Stack::Inst_IfNEqu),
-    cInstEntry4Stack("if-equ",    &cHardware4Stack::Inst_IfEqu),
-    
-    cInstEntry4Stack("if-bit-1",  &cHardware4Stack::Inst_IfBit1),
-    cInstEntry4Stack("jump-f",    &cHardware4Stack::Inst_JumpF),
-    cInstEntry4Stack("jump-b",    &cHardware4Stack::Inst_JumpB),
-    cInstEntry4Stack("jump-p",    &cHardware4Stack::Inst_JumpP),
-    cInstEntry4Stack("jump-slf",  &cHardware4Stack::Inst_JumpSelf),
-    cInstEntry4Stack("call",      &cHardware4Stack::Inst_Call),
-    cInstEntry4Stack("return",    &cHardware4Stack::Inst_Return),
-
-    cInstEntry4Stack("pop",       &cHardware4Stack::Inst_Pop),
-    cInstEntry4Stack("push",      &cHardware4Stack::Inst_Push),
-    cInstEntry4Stack("swap-stk",  &cHardware4Stack::Inst_SwitchStack),
-    cInstEntry4Stack("swap",      &cHardware4Stack::Inst_Swap),
-    cInstEntry4Stack("copy-reg",  &cHardware4Stack::Inst_CopyReg),
-
-    cInstEntry4Stack("shift-r",   &cHardware4Stack::Inst_ShiftR),
-    cInstEntry4Stack("shift-l",   &cHardware4Stack::Inst_ShiftL),
-    cInstEntry4Stack("bit-1",     &cHardware4Stack::Inst_Bit1),
-    cInstEntry4Stack("set-num",   &cHardware4Stack::Inst_SetNum),
-    cInstEntry4Stack("inc",       &cHardware4Stack::Inst_Inc),
-    cInstEntry4Stack("dec",       &cHardware4Stack::Inst_Dec),
-    cInstEntry4Stack("minus-18",  &cHardware4Stack::Inst_Minus18),
-    
-    cInstEntry4Stack("add",       &cHardware4Stack::Inst_Add),
-    cInstEntry4Stack("sub",       &cHardware4Stack::Inst_Sub),
-    cInstEntry4Stack("mult",      &cHardware4Stack::Inst_Mult),
-    cInstEntry4Stack("div",       &cHardware4Stack::Inst_Div),
-    cInstEntry4Stack("mod",       &cHardware4Stack::Inst_Mod),
-    cInstEntry4Stack("nand",      &cHardware4Stack::Inst_Nand),
-    cInstEntry4Stack("nor",       &cHardware4Stack::Inst_Nor),
-    
-    cInstEntry4Stack("copy",      &cHardware4Stack::Inst_Copy),
-    cInstEntry4Stack("read",      &cHardware4Stack::Inst_ReadInst),
-    cInstEntry4Stack("write",     &cHardware4Stack::Inst_WriteInst),
-    
-    cInstEntry4Stack("compare",   &cHardware4Stack::Inst_Compare),
-    cInstEntry4Stack("if-n-cpy",  &cHardware4Stack::Inst_IfNCpy),
-    cInstEntry4Stack("allocate",  &cHardware4Stack::Inst_Allocate),
-    cInstEntry4Stack("divide",    &cHardware4Stack::Inst_DivideOld),
-    cInstEntry4Stack("inject",    &cHardware4Stack::Inst_Inject),
-    cInstEntry4Stack("inject-r",  &cHardware4Stack::Inst_InjectRand),
-    cInstEntry4Stack("get",       &cHardware4Stack::Inst_TaskGet),
-    cInstEntry4Stack("put",       &cHardware4Stack::Inst_TaskPut),
-    cInstEntry4Stack("IO",        &cHardware4Stack::Inst_TaskIO),
-    cInstEntry4Stack("search-f",  &cHardware4Stack::Inst_SearchF),
-    cInstEntry4Stack("search-b",  &cHardware4Stack::Inst_SearchB),
-    cInstEntry4Stack("mem-size",  &cHardware4Stack::Inst_MemSize),
-
-    cInstEntry4Stack("rotate-l",  &cHardware4Stack::Inst_RotateL),
-    cInstEntry4Stack("rotate-r",  &cHardware4Stack::Inst_RotateR),
-
-    cInstEntry4Stack("set-cmut",  &cHardware4Stack::Inst_SetCopyMut),
-    cInstEntry4Stack("mod-cmut",  &cHardware4Stack::Inst_ModCopyMut),
-
-    // Threading instructions
-    cInstEntry4Stack("fork-th",   &cHardware4Stack::Inst_ForkThread),
-    cInstEntry4Stack("kill-th",   &cHardware4Stack::Inst_KillThread),
-    cInstEntry4Stack("id-th",     &cHardware4Stack::Inst_ThreadID),
-
-    // Head-based instructions
-    cInstEntry4Stack("h-alloc",   &cHardware4Stack::Inst_MaxAlloc),
-    cInstEntry4Stack("h-divide",  &cHardware4Stack::Inst_HeadDivide),
-    cInstEntry4Stack("h-read",    &cHardware4Stack::Inst_HeadRead),
-    cInstEntry4Stack("h-write",   &cHardware4Stack::Inst_HeadWrite),
-    cInstEntry4Stack("h-copy",    &cHardware4Stack::Inst_HeadCopy),
-    cInstEntry4Stack("h-search",  &cHardware4Stack::Inst_HeadSearch),
-    cInstEntry4Stack("h-push",    &cHardware4Stack::Inst_HeadPush),
-    cInstEntry4Stack("h-pop",     &cHardware4Stack::Inst_HeadPop),
-    cInstEntry4Stack("set-head",  &cHardware4Stack::Inst_SetHead),
-    cInstEntry4Stack("adv-head",  &cHardware4Stack::Inst_AdvanceHead),
-    cInstEntry4Stack("mov-head",  &cHardware4Stack::Inst_MoveHead),
-    cInstEntry4Stack("jmp-head",  &cHardware4Stack::Inst_JumpHead),
-    cInstEntry4Stack("get-head",  &cHardware4Stack::Inst_GetHead),
-    cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
-    cInstEntry4Stack("set-flow",  &cHardware4Stack::Inst_SetFlow),
-
-
-    // Placebo instructions
-    // nop-x (included with nops)
-    cInstEntry4Stack("skip",      &cHardware4Stack::Inst_Skip)*/
+    //36
+    cInstEntry4Stack("IO", &cHardware4Stack::Inst_IO),
+    //37
+    cInstEntry4Stack("Inject", &cHardware4Stack::Inst_Inject)
   };
 
   const int n_size = sizeof(s_n_array)/sizeof(cNOPEntry4Stack);
@@ -447,7 +360,16 @@
   /* FIXME:  reorganize storage of m_functions.  -- kgn */
   m_functions = s_inst_slib->GetFunctions();
   /**/
+  inst_remainder = 0;
+ 
+  for(int x=1; x<=cConfig::GetMaxCPUThreads(); x++)
+    {
+      slice_array[x] = (x-1)*cConfig::GetThreadSlicingMethod()+1;
+    }
+
   memory_array[0] = in_organism->GetGenome();  // Initialize memory...
+  memory_array[0].Resize(GetMemory(0).GetSize()+1);
+  memory_array[0][memory_array[0].GetSize()-1] = cInstruction();
   Reset();                            // Setup the rest of the hardware...
 }
 
@@ -461,6 +383,8 @@
 {
   cHardwareBase::Recycle(new_organism, in_inst_set);
   memory_array[0] = new_organism->GetGenome();
+  memory_array[0].Resize(GetMemory(0).GetSize()+1);
+  memory_array[0][memory_array[0].GetSize()-1] = cInstruction();
   Reset();
 }
 
@@ -468,12 +392,13 @@
 void cHardware4Stack::Reset()
 {
   //global_stack.Clear();
-  thread_time_used = 0;
+  //thread_time_used = 0;
 
   // Setup the memory...
   for (int i = 1; i < NUM_MEMORY_SPACES; i++) {
       memory_array[i].Resize(1);
-      GetMemory(i).Replace(0, 1, cGenome(ConvertToInstruction(i)));
+      //GetMemory(i).Replace(0, 1, cGenome(ConvertToInstruction(i)));
+      GetMemory(i)=cGenome(ConvertToInstruction(i)); 
   }
 
   // We want to reset to have a single thread.
@@ -512,17 +437,26 @@
 void cHardware4Stack::SingleProcess(ostream * trace_fp)
 {
   organism->GetPhenotype().IncTimeUsed();
-  if (GetNumThreads() > 1) thread_time_used++;
+  //if(organism->GetCellID()==46 && IP().GetMemSpace()==2)
+  // int x=0;
 
+  //if (GetNumThreads() > 1) thread_time_used++;
+  //assert((GetHead(HEAD_WRITE).GetPosition() == Stack(STACK_BX).Top() ||
+  // Stack(STACK_BX).Top()==GetMemory(IP().GetMemSpace()).GetSize()-1 || 
+  // GetHead(HEAD_WRITE).GetPosition() == Stack(STACK_BX).Top()+1) &&
+  // (GetHead(HEAD_WRITE).GetMemSpace() == IP().GetMemSpace() ||
+  //  GetHead(HEAD_WRITE).GetMemSpace() == IP().GetMemSpace()+1));
   // If we have threads turned on and we executed each thread in a single
   // timestep, adjust the number of instructions executed accordingly.
-  const int num_inst_exec = (cConfig::GetThreadSlicingMethod() == 1) ?
-    GetNumThreads() : 1;
+  //const int num_inst_exec = (cConfig::GetThreadSlicingMethod() == 1) ?
+  //  GetNumThreads() : 1;
+  const int num_inst_exec = int(slice_array[GetNumThreads()]+ inst_remainder);
+  inst_remainder = slice_array[GetNumThreads()] + inst_remainder - num_inst_exec;
   
   for (int i = 0; i < num_inst_exec; i++) {
     // Setup the hardware for the next instruction to be executed.
     NextThread();
-    advance_ip = true;
+    AdvanceIP() = true;
     IP().Adjust();
 
 #ifdef BREAKPOINTS
@@ -546,7 +480,7 @@
 
       // Some instruction (such as jump) may turn advance_ip off.  Ususally
       // we now want to move to the next instruction in the memory.
-      if (advance_ip == true) IP().Advance();
+      if (AdvanceIP() == true) IP().Advance();
     } // if exec
     
   } // Previous was executed once for each thread...
@@ -728,7 +662,7 @@
   c4StackHead search_head(inst_ptr);
   cCodeLabel & search_label = GetLabel();
 
-  // Make sure the label is of size > 0.
+  // Make sure the label is of size  > 0.
 
   if (search_label.GetSize() == 0) {
     return inst_ptr;
@@ -753,9 +687,9 @@
   }
   
   // Return the last line of the found label, if it was found.
-  if (found_pos > 0) search_head.Set(found_pos - 1);
+  if (found_pos > 0) search_head.Set(found_pos - 1, IP().GetMemSpace());
   //*** I THINK THIS MIGHT HAVE BEEN WRONG...CHANGED >= to >.  -law ***//
-
+  
   // Return the found position (still at start point if not found).
   return search_head;
 }
@@ -1031,103 +965,70 @@
 {
   // Make sure the genome will be below max size after injection.
 
-  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
-  if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
-
-  const int inject_line = FindFullLabel(in_label).GetPosition();
-
-  // Abort if no compliment is found.
-  if (inject_line == -1) return 2; // (inject fails)
-
-  // Inject the code!
-  InjectCode(injection, inject_line+1);
-
-  return 0; // (inject succeeds!)
-}
-
-int cHardware4Stack::InjectThread(const cCodeLabel & in_label, const cGenome & injection)
-{
-  // Make sure the genome will be below max size after injection.
+  int target_mem_space = 2; //TEMPORARY!!! -law
+  const int new_size = injection.GetSize() + GetMemory(target_mem_space).GetSize();
 
-  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
   if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
 
-  const int inject_line = FindFullLabel(in_label).GetPosition();
+  //ALSO TEMPORARY - we should have this match injection templates - law
+  //const int inject_line = FindFullLabel(in_label).GetPosition();
 
   // Abort if no compliment is found.
-  if (inject_line == -1) return 2; // (inject fails)
+  //if (inject_line == -1) return 2; // (inject fails)
 
-  // Inject the code!
-  InjectCodeThread(injection, inject_line+1);
+  // Inject the code! /****/ for right now the only injection point will be the
+  // first address in a memory space. -law /***/
+  InjectCode(injection, target_mem_space);//inject_line+1);
 
   return 0; // (inject succeeds!)
 }
 
-void cHardware4Stack::InjectCode(const cGenome & inject_code, const int line_num)
+void cHardware4Stack::InjectCode(const cGenome & inject_code, const int in_mem_space)
 {
-  assert(line_num >= 0);
-  assert(line_num <= memory_array[0].GetSize());
-  assert(memory_array[0].GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
-
-  // Inject the new cod.e
-  const int inject_size = inject_code.GetSize();
-  memory_array[0].Insert(line_num, inject_code);
-  
-  // Set instruction flags on the injected code
-  for (int i = line_num; i < line_num + inject_size; i++) {
-    memory_array[0].FlagInjected(i) = true;
-  }
-  organism->GetPhenotype().IsModified() = true;
+  assert(in_mem_space >=0 && in_mem_space < 4);
+  //assert(line_num >= 0);
+  //assert(line_num <= memory_array[0].GetSize());
+  assert(GetMemory(in_mem_space).GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+
+  if(ForkThread()) {
+    // Inject the new code
+    cCPUMemory oldcode = GetMemory(in_mem_space);
+    GetMemory(in_mem_space) = inject_code;
+    GetMemory(in_mem_space).Resize(inject_code.GetSize() + oldcode.GetSize());
+
+    // Is there a faster way to do this?? -law
+    for(int x=0; x<oldcode.GetSize(); x++)
+      GetMemory(in_mem_space)[inject_code.GetSize()+x] = oldcode[x];
 
-  // Adjust all of the heads to take into account the new mem size.
-
-  for (int i=0; i < NUM_HEADS; i++) {    
-    if (!GetHead(i).TestParasite() &&
-	GetHead(i).GetPosition() > line_num)
-      GetHead(i).Jump(inject_size);
-  }
-}
-
-void cHardware4Stack::InjectCodeThread(const cGenome & inject_code, const int line_num)
-{
-  assert(line_num >= 0);
-  assert(line_num <= memory_array[0].GetSize());
-  assert(memory_array[0].GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+    //const int inject_size = inject_code.GetSize();
+    //memory_array[0].Insert(line_num, inject_code);
   
-  if(ForkThread())
-    {
-      // Inject the new code.
-      const int inject_size = inject_code.GetSize();
-      memory_array[0].Insert(line_num, inject_code);
-      
-      // Set instruction flags on the injected code
-      for (int i = line_num; i < line_num + inject_size; i++) {
-	memory_array[0].FlagInjected(i) = true;
+    // Set instruction flags on the injected code
+    for (int i = 0; i < inject_code.GetSize(); i++) {
+      memory_array[in_mem_space].FlagInjected(i) = true;
+    }
+    organism->GetPhenotype().IsModified() = true;
+    
+    // Adjust all of the heads to take into account the new mem size.
+    
+    cur_thread=GetNumThreads()-1;
+    
+    for(int i=0; i<cur_thread; i++)
+      {
+	for(int j=0; j<NUM_HEADS; j++)
+	  {
+	    if(threads[i].heads[j].GetMemSpace()==in_mem_space)
+	      threads[i].heads[j].Jump(inject_code.GetSize());
+	  }
       }
-      organism->GetPhenotype().IsModified() = true;
-      organism->GetPhenotype().IsMultiThread() = true;
-      
-      // Adjust all of the heads to take into account the new mem size.
-      
-      int currthread = GetCurThread();
-      SetThread(0);
-      for (int i=0; i<GetNumThreads()-2; i++)
-	{
-	  for (int j=0; j < NUM_HEADS; j++) 
-	    {    
-	      if (!GetHead(i).TestParasite() && GetHead(i).GetPosition() > line_num)
-		GetHead(i).Jump(inject_size);
-	    }
-	  NextThread();
-	}
-      SetThread(currthread);
-          
+    
+    for (int i=0; i < NUM_HEADS; i++) {    
+      GetHead(i).Reset(in_mem_space, this);
     }
-  else
-    {
-      //Some kind of error message should go here...but what?
+    for (int i=0; i < NUM_LOCAL_STACKS; i++) {
+      Stack(i).Clear();
     }
-
+  }
 }
 
 void cHardware4Stack::Mutate(int mut_point)
@@ -1349,9 +1250,10 @@
   // Make room for the new thread.
   threads.Resize(num_threads + 1);
 
+  //IP().Advance();
+
   // Initialize the new thread to the same values as the current one.
-  threads[num_threads] = threads[cur_thread];
-  IP().Advance();
+  threads[num_threads] = threads[cur_thread]; 
 
   // Find the first free bit in thread_id_chart to determine the new
   // thread id.
@@ -1408,7 +1310,7 @@
   for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
     Stack(i).SaveState(fp);
 
-  fp << thread_time_used  << endl;
+  //fp << thread_time_used  << endl;
   fp << GetNumThreads()   << endl;
   fp << cur_thread        << endl;
 
@@ -1433,7 +1335,7 @@
     Stack(i).LoadState(fp);
 
   int num_threads;
-  fp >> thread_time_used;
+  //fp >> thread_time_used;
   fp >> num_threads;
   fp >> cur_thread;
 
@@ -1731,12 +1633,16 @@
 
 bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
 {
-  int write_head_pos = threads[cur_thread].heads[HEAD_WRITE].GetPosition();
+  int write_head_pos = GetHead(HEAD_WRITE).GetPosition();
   
   // We're going to disallow division calls from memory spaces other than zero 
   // for right now -law
   if(IP().GetMemSpace()!=0)
     return false;
+  //if(GetMemory(mem_space_used).GetSize() != GetMemory(IP().GetMemSpace()).GetSize())
+  //int q=1;
+
+  //assert(GetMemory(mem_space_used).GetSize() == GetMemory(IP().GetMemSpace()).GetSize());
 
   // Make sure this divide will produce a viable offspring.
   if(!Divide_CheckViable(GetMemory(IP().GetMemSpace()).GetSize(), 
@@ -1748,12 +1654,10 @@
   cGenome & child_genome = organism->ChildGenome();
   GetMemory(mem_space_used).Resize(write_head_pos);
   child_genome = GetMemory(mem_space_used);
-  GetMemory(mem_space_used).Resize(1);
-  GetMemory(mem_space_used)[0].SetOp(mem_space_used);
-  for(int x=0; x<NUM_HEADS; x++)
-    {
-      threads[cur_thread].heads[x].Reset(this);
-    }
+  //GetMemory(mem_space_used).Resize(1);
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
+  //GetMemory(mem_space_used)[0].SetOp(mem_space_used);
+
   // Handle Divide Mutations...
   Divide_DoMutations(mut_multiplier);
 
@@ -1770,6 +1674,45 @@
 #endif
 
   bool parent_alive = organism->ActivateDivide();
+
+  // I am still iffy about how we want to reset organisms after divide. -law
+  if(parent_alive && !(cConfig::GetDivideMethod() == DIVIDE_METHOD_OFFSPRING))
+    {
+      if(cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT)
+	{
+	  //this will wipe out all parasites on a divide.
+	  Reset();
+	  
+	}
+      else if(cConfig::GetDivideMethod() == DIVIDE_METHOD_BIRTH)
+	{
+	  //if this isn't the only thread, get rid of it!
+	  // ***this can cause a concurrency problem if we have 
+	  // multiprocessor support for single organisms...don't 
+	  // think that's happening anytime soon though -law ***
+	  if(!organism->GetPhenotype().IsModified() && GetNumThreads()>1 || 
+	     GetNumThreads()>2)
+	    {
+	      KillThread();
+	    }
+
+	  //this will reset the current thread's heads and stacks.  It will 
+	  //not touch any other threads or memory spaces (ie: parasites)
+	  else
+	    {
+	      for(int x=0; x<NUM_HEADS; x++)
+		{
+		  GetHead(x).Reset(0, this);
+		}
+	      for(int x=0; x<NUM_LOCAL_STACKS; x++)
+		{
+		  Stack(x).Clear();
+		}	  
+	    }
+	}
+      AdvanceIP()=false;
+    }
+     
   return true;
 }
 
@@ -1780,6 +1723,20 @@
   ret += c;
   return ret;
 }
+
+cString cHardware4Stack::GetActiveStackID(int stackID) const
+{
+  if(stackID==STACK_AX)
+    return "AX";
+  else if(stackID==STACK_BX)
+    return "BX";
+  else if(stackID==STACK_CX)
+    return "CX";
+  else if(stackID==STACK_DX)
+    return "DX";
+  else
+    return "";
+}
   
 
 //////////////////////////
@@ -1857,9 +1814,17 @@
 //13 
 bool cHardware4Stack::Inst_SetMemory()   // Allocate maximal more
 {
-  const int mem_space_used = FindModifiedStack(STACK_BX);
-  threads[cur_thread].heads[HEAD_FLOW].Set(0, this, mem_space_used);
+  int mem_space_used = FindModifiedStack(-1);
+  
+  if(mem_space_used==-1) {
+    mem_space_used = FindFirstEmpty();
+    if(mem_space_used==-1)
+      return false;
+  }
+  
+  GetHead(HEAD_FLOW).Set(0, mem_space_used);
   return true;
+  
   //const int cur_size = GetMemory(0).GetSize();
   //const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
   //			     MAX_CREATURE_SIZE - cur_size);
@@ -1873,11 +1838,14 @@
 bool cHardware4Stack::Inst_Divide()
 {
   //return Inst_HeadDivideMut(1);
-  int mem_space_used = FindModifiedStack(STACK_BX);
-
+  int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
+  //if(GetMemory(mem_space_used).GetSize()==GetMemory(0).GetSize()+1)
+  //  {
+  //    int x=0;
+  //  }
   int mut_multiplier = 1;
-  if(mem_space_used==0)
-    mem_space_used++;
+  //if(mem_space_used==0)
+  //  mem_space_used++;
 
   return Divide_Main(mem_space_used, mut_multiplier);
 }
@@ -2026,7 +1994,7 @@
   Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
   //if (head_used == HEAD_IP) {
   //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  //  advance_ip = false;
+  //  AdvanceIP() = false;
   //}
   return true;
 }
@@ -2035,7 +2003,8 @@
 bool cHardware4Stack::Inst_HeadPop()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(Stack(STACK_BX).Pop(), this);
+  GetHead(head_used).Set(Stack(STACK_BX).Pop(), 
+			 GetHead(head_used).GetMemSpace(), this);
   return true;
 }
 
@@ -2046,7 +2015,7 @@
   if(head_used != HEAD_FLOW)
     {
       GetHead(head_used).Set(GetHead(HEAD_FLOW));
-      if (head_used == HEAD_IP) advance_ip = false;
+      if (head_used == HEAD_IP) AdvanceIP() = false;
     }
   else
     {
@@ -2063,7 +2032,9 @@
   c4StackHead found_pos = FindLabel(0);
   if(found_pos.GetPosition()-IP().GetPosition()==0)
     {
-      GetHead(HEAD_FLOW).Set(IP().GetPosition()+1, this, IP().GetMemSpace());
+      GetHead(HEAD_FLOW).Set(IP().GetPosition()+1, IP().GetMemSpace(), this);
+      // pushing zero into STACK_AX on a missed search makes it difficult to create
+      // a self-replicating organism.  -law
       //Stack(STACK_AX).Push(0);
       Stack(STACK_BX).Push(0);
     }
@@ -2074,6 +2045,7 @@
       Stack(STACK_AX).Push(GetLabel().GetSize());
       GetHead(HEAD_FLOW).Set(found_pos);
     }  
+  
   return true; 
 }
 
@@ -2162,7 +2134,10 @@
 {
   const int stack_used = FindModifiedStack(STACK_BX);
   if (Stack(STACK_CX).Top() != 0) {
-    Stack(stack_used).Push(Stack(STACK_BX).Top() % Stack(STACK_CX).Top());
+    if(Stack(STACK_CX).Top() == -1)
+      Stack(stack_used).Push(0);
+    else
+      Stack(stack_used).Push(Stack(STACK_BX).Top() % Stack(STACK_CX).Top());
   } else {
     Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
   return false;
@@ -2174,1067 +2149,181 @@
 bool cHardware4Stack::Inst_KillThread()
 {
   if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
-  else advance_ip = false;
-  return true;
-}
-
-cString cHardware4Stack::GetActiveStackID(int stackID) const
-{
-  if(stackID==STACK_AX)
-    return "AX";
-  else if(stackID==STACK_BX)
-    return "BX";
-  else if(stackID==STACK_CX)
-    return "CX";
-  else if(stackID==STACK_DX)
-    return "DX";
-  else
-    return "";
-}
-
-/*bool cHardware4Stack::Inst_If0()          // Execute next if ?bx? ==0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) != 0)  IP().Advance();
-  return true; 
-}
-
-bool cHardware4Stack::Inst_IfNot0()       // Execute next if ?bx? != 0.
-{ 
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) == 0)  IP().Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfGr0()       // Execute next if ?bx? ! < 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) <= 0)  IP().Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfGrEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) < 0)  IP().Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfGrEqu()       // Execute next if bx > ?cx?
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int reg_used2 = FindComplementRegister(reg_used);
-  if (Register(reg_used) < Register(reg_used2)) IP().Advance();
+  else AdvanceIP() = false;
   return true;
 }
 
-bool cHardware4Stack::Inst_IfLess0()       // Execute next if ?bx? != 0.
+//36
+bool cHardware4Stack::Inst_IO()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) >= 0)  IP().Advance();
-  return true;
-}
+  const int stack_used = FindModifiedStack(STACK_BX);
 
-bool cHardware4Stack::Inst_IfLsEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) > 0) IP().Advance();
-  return true;
-}
+  // Do the "put" component
+  const int value_out = Stack(stack_used).Top();
+  DoOutput(value_out);  // Check for tasks compleated.
 
-bool cHardware4Stack::Inst_IfLsEqu()       // Execute next if bx > ?cx?
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int reg_used2 = FindComplementRegister(reg_used);
-  if (Register(reg_used) >  Register(reg_used2))  IP().Advance();
+  // Do the "get" component
+  const int value_in = organism->GetInputAt(threads[GetCurThread()].input_pointer);
+  Stack(stack_used).Push(value_in);
+  DoInput(value_in);
   return true;
 }
 
-bool cHardware4Stack::Inst_IfBit1()
+int cHardware4Stack::FindFirstEmpty()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if ((Register(reg_used) & 1) == 0)  IP().Advance();
-  return true;
-}
+  bool OK=true;
+  const int current_mem_space = IP().GetMemSpace();
 
-bool cHardware4Stack::Inst_IfANotEqB()     // Execute next if AX != BX
-{
-  if (Register(REG_AX) == Register(REG_BX) )  IP().Advance();
-  return true;
-}
+  for(int x=1; x<NUM_MEMORY_SPACES; x++)
+    {
+      OK=true;
+      
+      int index = (current_mem_space+x) % NUM_MEMORY_SPACES;
 
-bool cHardware4Stack::Inst_IfBNotEqC()     // Execute next if BX != CX
-{
-  if (Register(REG_BX) == Register(REG_CX) )  IP().Advance();
-  return true;
+      for(int y=0; y<GetMemory(index).GetSize() && OK; y++)
+	{
+	  if(GetMemory(index)[y].GetOp() >= NUM_NOPS_4STACK)
+	    OK=false; 
+	}
+      for(int y=0; y<GetNumThreads() && OK; y++)
+	{
+	  for(int z=0; z<NUM_HEADS; z++)
+	    {
+	      if(threads[y].heads[z].GetMemSpace() == index)
+		OK=false;
+	    }
+	}
+      if(OK)
+	return index;
+    }
+  return -1;
 }
 
-bool cHardware4Stack::Inst_IfANotEqC()     // Execute next if AX != BX
+bool cHardware4Stack::isEmpty(int mem_space_used)
 {
-  if (Register(REG_AX) == Register(REG_CX) )  IP().Advance();
+  for(int x=0; x<GetMemory(mem_space_used).GetSize(); x++)
+    {
+      if(GetMemory(mem_space_used)[x].GetOp() >= NUM_NOPS_4STACK)
+	return false;
+    }
   return true;
 }
 
-bool cHardware4Stack::Inst_JumpF()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    GetActiveHead().Jump(Register(REG_BX));
-    return true;
-  }
-
-  // Otherwise, try to jump to the complement label.
-  const c4StackHead jump_location(FindLabel(1));
-  if ( jump_location.GetPosition() != -1 ) {
-    GetActiveHead().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-f: No complement label");
-  return false;
-}
+// The inject instruction can be used instead of a divide command, paired
+// with an allocate.  Note that for an inject to work, one needs to have a
+// broad range for sizes allowed to be allocated.
+//
+// This command will cut out from read-head to write-head.
+// It will then look at the template that follows the command and inject it
+// into the complement template found in a neighboring organism.
 
-bool cHardware4Stack::Inst_JumpB()
+bool cHardware4Stack::Inst_Inject()
 {
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
+  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();  //FindModifiedStack(STACK_DX);
+  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
+  
+  /*AdjustHeads();
+  const int start_pos = GetHead(HEAD_READ).GetPosition();
+  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
+  const int inject_size = end_pos - start_pos;
+  */
 
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    GetActiveHead().Jump(-Register(REG_BX));
-    return true;
+  // Make sure the creature will still be above the minimum size,
+  if (end_pos <= 0) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    return false; // (inject fails)
   }
-
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location(FindLabel(-1));
-  if ( jump_location.GetPosition() != -1 ) {
-    GetActiveHead().Set(jump_location);
-    return true;
+  
+  if (end_pos < MIN_CREATURE_SIZE) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    return false; // (inject fails)
   }
 
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-b: No complement label");
-  return false;
-}
+  GetMemory(mem_space_used).Resize(end_pos);
 
-bool cHardware4Stack::Inst_JumpP()
-{
-  cOrganism * other_organism = organism->GetNeighbor();
+  /*
+  // Since its legal to cut out the injected piece, do so.
+  cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
+  GetMemory().Remove(start_pos, inject_size);
+  */
 
-  // Make sure the other organism was found and that its hardware is of the
-  // same type, or else we won't be able to be parasitic on it.
-  if (other_organism == NULL ||
-      other_organism->GetHardware().GetType() != GetType()) {
-    // Without another organism, its hard to determine if we're dealing
-    // with a parasite.  For the moment, we'll assume it is and move on.
-    // @CAO Do better!
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
+  // spin around randomly (caution: possible organism dizziness)
+  const int num_neighbors = organism->GetNeighborhoodSize();
+  for(int i=0; i<g_random.GetUInt(num_neighbors); i++)
+    organism->Rotate(1);
 
-  // Otherwise, grab the hardware from the neighbor, and use it!
-  cHardware4Stack & other_hardware = (cHardware4Stack &) other_organism->GetHardware();
+  // If we don't have a host, stop here.
+  cOrganism * host_organism = organism->GetNeighbor();
+  
+  //if (host_organism == NULL) 
+  //  {
+  //  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used));
+  //  return false;
+  //}
 
+  /*
+  // Scan for the label to match...
   ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump to line BX in creature.
-  if (GetLabel().GetSize() == 0) {
-    const int new_pos = Register(REG_BX);
-    IP().Set(new_pos, &other_hardware);
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
 
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location(other_hardware.FindFullLabel(GetLabel()));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
+  // If there is no label, abort.
+  if (GetLabel().GetSizhe() == 0) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
+    return false; // (inject fails)
   }
 
-  // If complement label was not found; record a warning (since the
-  // actual neighbors are not under the organisms control, this is not
-  // a full-scale error).
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_WARNING,
-		  "jump-p: No complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_JumpSelf()
-{
-  ReadLabel();
+  // Search for the label in the host...
   GetLabel().Rotate(2, NUM_NOPS_4STACK);
+  */
+  int inject_signal = false;
+  int target_mem_space=2;
+  //cHardware4Stack & target_hardware = (cHardware4Stack &)host_organism->GetHardware();
+  if(host_organism!=NULL && ((cHardware4Stack &)host_organism->GetHardware()).isEmpty(target_mem_space))
+    {
+      inject_signal = host_organism->GetHardware().Inject(GetLabel(), GetMemory(mem_space_used));
+    }
 
-  // If there is no label, jump to line BX in creature.
-  if (GetLabel().GetSize() == 0) {
-    IP().Set(Register(REG_BX), this);
-    return true;
-  }
-
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location( FindFullLabel(GetLabel()) );
-  if ( jump_location.GetPosition() != -1 ) {
-    IP().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-slf: no complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_Call()
-{
-  // Put the starting location onto the stack
-  const int location = IP().GetPosition();
-  StackPush(location);
+  //reset the memory space which was injected
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
 
-  // Jump to the compliment label (or by the ammount in the bx register)
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
+  for(int x=0; x<NUM_HEADS; x++)
+    {
+      GetHead(x).Reset(IP().GetMemSpace(), this);
+    }
 
-  if (GetLabel().GetSize() == 0) {
-    IP().Jump(Register(REG_BX));
-    return true;
+  for(int x=0; x<NUM_LOCAL_STACKS; x++)
+    {
+      Stack(x).Clear();
+    }
+  
+  AdvanceIP() = false;
+  /*
+  const int inject_signal =
+    host_organism->GetHardware().Inject(GetLabel(), inject_code);
+  if (inject_signal == 1) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
+    return false; // Inject failed.
   }
-
-  const c4StackHead jump_location(FindLabel(1));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    return true;
+  if (inject_signal == 2) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: target not in host.");
+    return false; // Inject failed.
   }
 
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "call: no complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_Return()
-{
-  IP().Set(StackPop());
-  return true;
+  // Set the relevent flags.
+  organism->GetPhenotype().IsModifier() = true;
+  */
+  
+  
+  return inject_signal;
 }
 
-bool cHardware4Stack::Inst_Pop()
+/*
+bool cHardware4Stack::Inst_InjectRand()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = StackPop();
+  // Rotate to a random facing and then run the normal inject instruction
+  const int num_neighbors = organism->GetNeighborhoodSize();
+  organism->Rotate(g_random.GetUInt(num_neighbors));
+  Inst_Inject();
   return true;
 }
 
-bool cHardware4Stack::Inst_Push()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  StackPush(Register(reg_used));
-  return true;
-}
-
-bool cHardware4Stack::Inst_PopA() { Register(REG_AX) = StackPop(); return true;}
-bool cHardware4Stack::Inst_PopB() { Register(REG_BX) = StackPop(); return true;}
-bool cHardware4Stack::Inst_PopC() { Register(REG_CX) = StackPop(); return true;}
-
-bool cHardware4Stack::Inst_SwitchStack() { SwitchStack(); return true;}
-bool cHardware4Stack::Inst_FlipStack()   { StackFlip(); return true;}
-
-bool cHardware4Stack::Inst_Swap()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int other_reg = FindComplementRegister(reg_used);
-  Swap(Register(reg_used), Register(other_reg));
-  return true;
-}
-
-bool cHardware4Stack::Inst_SwapAB() { Swap(Register(REG_AX), Register(REG_BX)); return true; }
-bool cHardware4Stack::Inst_SwapBC() { Swap(Register(REG_BX), Register(REG_CX)); return true; }
-bool cHardware4Stack::Inst_SwapAC() { Swap(Register(REG_AX), Register(REG_CX)); return true; }
-
-bool cHardware4Stack::Inst_CopyRegAB() { Register(REG_AX) = Register(REG_BX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegAC() { Register(REG_AX) = Register(REG_CX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegBA() { Register(REG_BX) = Register(REG_AX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegBC() { Register(REG_BX) = Register(REG_CX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegCA() { Register(REG_CX) = Register(REG_AX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegCB() { Register(REG_CX) = Register(REG_BX);   return true;
-}
-
-bool cHardware4Stack::Inst_Reset()
-{
-  Register(REG_AX) = 0;
-  Register(REG_BX) = 0;
-  Register(REG_CX) = 0;
-  StackClear();
-  return true;
-}
-
-bool cHardware4Stack::Inst_Bit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) |=  1;
-  return true;
-}
-
-bool cHardware4Stack::Inst_SetNum()
-{
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsInt();
-  return true;
-}
-
-bool cHardware4Stack::Inst_Zero()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Neg()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0-Register(reg_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Square()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(reg_used) * Register(reg_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Sqrt()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value > 1) Register(reg_used) = (int) sqrt((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Log()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value >= 1) Register(reg_used) = (int) log((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Log10()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value >= 1) Register(reg_used) = (int) log10((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Minus18()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) -= 18;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Nor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(REG_BX) | Register(REG_CX));
-  return true;
-}
-
-bool cHardware4Stack::Inst_And()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = (Register(REG_BX) & Register(REG_CX));
-  return true;
-}
-
-bool cHardware4Stack::Inst_Not()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(reg_used));
-  return true;
-}
-
-bool cHardware4Stack::Inst_Order()
-{
-  if (Register(REG_BX) > Register(REG_CX)) {
-    Swap(Register(REG_BX), Register(REG_CX));
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Xor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) ^ Register(REG_CX);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Copy()
-{
-  const c4StackHead from(this, Register(REG_BX));
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;  // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;  // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(from.GetInst());
-    to.FlagMutated() = false;  // UnMark
-    to.FlagCopyMut() = false;  // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_ReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const c4StackHead from(this, Register(REG_BX));
-
-  // Dis-allowing mutations on read, for the moment (write only...)
-  // @CAO This allows perfect error-correction...
-  Register(reg_used) = from.GetInst().GetOp();
-  return true;
-}
-
-bool cHardware4Stack::Inst_WriteInst()
-{
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = Mod(Register(reg_used), GetNumInst());
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Change value on a mutation...
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(cInstruction(value));
-    to.FlagMutated() = false;     // UnMark
-    to.FlagCopyMut() = false;     // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_StackReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  c4StackHead from(this, Register(reg_used));
-  StackPush(from.GetInst().GetOp());
-  return true;
-}
-
-bool cHardware4Stack::Inst_StackWriteInst()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  c4StackHead to(this, Register(REG_AX) + Register(reg_used));
-  const int value = Mod(StackPop(), GetNumInst());
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Change value on a mutation...
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(cInstruction(value));
-    to.FlagMutated() = false;     // UnMark
-    to.FlagCopyMut() = false;     // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Compare()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  c4StackHead from(this, Register(REG_BX));
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-
-  // Compare is dangerous -- it can cause mutations!
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-  }
-
-  Register(reg_used) = from.GetInst().GetOp() - to.GetInst().GetOp();
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfNCpy()
-{
-  const c4StackHead from(this, Register(REG_BX));
-  const c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-
-  // Allow for errors in this test...
-  if (organism->TestCopyMut()) {
-    if (from.GetInst() != to.GetInst()) IP().Advance();
-  } else {
-    if (from.GetInst() == to.GetInst()) IP().Advance();
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Allocate()   // Allocate bx more space...
-{
-  const int size = GetMemory().GetSize();
-  if( Allocate_Main(Register(REG_BX)) ) {
-    Register(REG_AX) = size;
-    return true;
-  } else return false;
-}
-
-bool cHardware4Stack::Inst_DivideOld()  
-{ 
-  return Divide_Main(Register(REG_AX));    
-}
-
-bool cHardware4Stack::Inst_CDivide() 
-{ 
-  return Divide_Main(GetMemory().GetSize() / 2);   
-}
-
-bool cHardware4Stack::Inst_CAlloc()  
-{ 
-  return Allocate_Main(GetMemory().GetSize());   
-}
-
-bool cHardware4Stack::Inst_Repro()
-{
-  // Setup child
-  cCPUMemory & child_genome = organism->ChildGenome();
-  child_genome = GetMemory();
-  organism->GetPhenotype().SetLinesCopied(GetMemory().GetSize());
-
-  int lines_executed = 0;
-  for ( int i = 0; i < GetMemory().GetSize(); i++ ) {
-    if ( GetMemory().FlagExecuted(i) == true ) lines_executed++;
-  }
-  organism->GetPhenotype().SetLinesExecuted(lines_executed);
-
-  // Perform Copy Mutations...
-  if (organism->GetCopyMutProb() > 0) { // Skip this if no mutations....
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
-      if (organism->TestCopyMut()) {
-	child_genome[i]=GetRandomInst();
-	//organism->GetPhenotype().IsMutated() = true;
-      }
-    }
-  }
-  Divide_DoMutations();
-
-  // Many tests will require us to run the offspring through a test CPU;
-  // this is, for example, to see if mutations need to be reverted or if
-  // lineages need to be updated.
-  Divide_TestFitnessMeasures();
-
-#ifdef INSTRUCTION_COSTS
-  // reset first time instruction costs
-  for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
-    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
-  }
-#endif
-
-  if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) advance_ip = false;
-
-  organism->ActivateDivide();
-
-  return true;
-}
-
-// The inject instruction can be used instead of a divide command, paired
-// with an allocate.  Note that for an inject to work, one needs to have a
-// broad range for sizes allowed to be allocated.
-//
-// This command will cut out from read-head to write-head.
-// It will then look at the template that follows the command and inject it
-// into the complement template found in a neighboring organism.
-
-bool cHardware4Stack::Inst_Inject()
-{
-  AdjustHeads();
-  const int start_pos = GetHead(HEAD_READ).GetPosition();
-  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
-  const int inject_size = end_pos - start_pos;
-
-  // Make sure the creature will still be above the minimum size,
-  if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
-    return false; // (inject fails)
-  }
-  if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
-    return false; // (inject fails)
-  }
-
-  // Since its legal to cut out the injected piece, do so.
-  cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
-  GetMemory().Remove(start_pos, inject_size);
-
-  // If we don't have a host, stop here.
-  cOrganism * host_organism = organism->GetNeighbor();
-  if (host_organism == NULL) return false;
-
-  // Scan for the label to match...
-  ReadLabel();
-
-  // If there is no label, abort.
-  if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
-    return false; // (inject fails)
-  }
-
-  // Search for the label in the host...
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  const int inject_signal =
-    host_organism->GetHardware().Inject(GetLabel(), inject_code);
-  if (inject_signal == 1) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
-    return false; // Inject failed.
-  }
-  if (inject_signal == 2) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: target not in host.");
-    return false; // Inject failed.
-  }
-
-  // Set the relevent flags.
-  organism->GetPhenotype().IsModifier() = true;
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_InjectRand()
-{
-  // Rotate to a random facing and then run the normal inject instruction
-  const int num_neighbors = organism->GetNeighborhoodSize();
-  organism->Rotate(g_random.GetUInt(num_neighbors));
-  Inst_Inject();
-  return true;
-}
-
-// The inject instruction can be used instead of a divide command, paired
-// with an allocate.  Note that for an inject to work, one needs to have a
-// broad range for sizes allowed to be allocated.
-//
-// This command will cut out from read-head to write-head.
-// It will then look at the template that follows the command and inject it
-// into the complement template found in a neighboring organism.
-
-bool cHardware4Stack::Inst_InjectThread()
-{
-  AdjustHeads();
-  const int start_pos = GetHead(HEAD_READ).GetPosition();
-  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
-  const int inject_size = end_pos - start_pos;
-
-  // Make sure the creature will still be above the minimum size,
-  if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
-    return false; // (inject fails)
-  }
-  if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
-    return false; // (inject fails)
-  }
-
-  // Since its legal to cut out the injected piece, do so.
-  cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
-  GetMemory().Remove(start_pos, inject_size);
-
-  // If we don't have a host, stop here.
-  cOrganism * host_organism = organism->GetNeighbor();
-  if (host_organism == NULL) return false;
-
-  // Scan for the label to match...
-  ReadLabel();
-
-  // If there is no label, abort.
-  if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
-    return false; // (inject fails)
-  }
-
-  // Search for the label in the host...
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  const int inject_signal =
-    host_organism->GetHardware().InjectThread(GetLabel(), inject_code);
-  if (inject_signal == 1) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
-    return false; // Inject failed.
-  }
-  if (inject_signal == 2) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: target not in host.");
-    return false; // Inject failed.
-  }
-
-  // Set the relevent flags.
-  organism->GetPhenotype().IsModifier() = true;
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskGet()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = organism->GetInput();
-  Register(reg_used) = value;
-  DoInput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskStackGet()
-{
-  const int value = organism->GetInput();
-  StackPush(value);
-  DoInput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskStackLoad()
-{
-  for (int i = 0; i < IO_SIZE; i++) StackPush( organism->GetInput() );
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskPut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  Register(reg_used) = 0;
-  DoOutput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskIO()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-
-  // Do the "put" component
-  const int value_out = Register(reg_used);
-  DoOutput(value_out);  // Check for tasks compleated.
-
-  // Do the "get" component
-  const int value_in = organism->GetInput();
-  Register(reg_used) = value_in;
-  DoInput(value_in);
-  return true;
-}
-
-bool cHardware4Stack::Inst_SearchF()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  const int search_size = FindLabel(1).GetPosition() - IP().GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardware4Stack::Inst_SearchB()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  const int search_size = IP().GetPosition() - FindLabel(-1).GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardware4Stack::Inst_MemSize()
-{
-  Register(FindModifiedRegister(REG_BX)) = GetMemory().GetSize();
-  return true;
-}
-
-
-bool cHardware4Stack::Inst_RotateL()
-{
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-   // If this organism has no neighbors, ignore rotate.
-  if (num_neighbors == 0) return false;
-
-  ReadLabel();
-
-  // Always rotate at least once.
-  organism->Rotate(-1);
-
-  // If there is no label, then the one rotation was all we want.
-  if (!GetLabel().GetSize()) return true;
-
-  // Rotate until a complement label is found (or all have been checked).
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  for (int i = 1; i < num_neighbors; i++) {
-    cOrganism * neighbor = organism->GetNeighbor();
-
-    // Assuming we have a neighbor and it is of the same hardware type,
-    // search for the label in it.
-    if (neighbor != NULL &&
-	neighbor->GetHardware().GetType() == GetType()) {
-
-      // If this facing has the full label, stop here.
-      cHardware4Stack & cur_hardware = (cHardware4Stack &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(-1);
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_RotateR()
-{
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-   // If this organism has no neighbors, ignore rotate.
-  if (num_neighbors == 0) return false;
-
-  ReadLabel();
-
-  // Always rotate at least once.
-  organism->Rotate(-1);
-
-  // If there is no label, then the one rotation was all we want.
-  if (!GetLabel().GetSize()) return true;
-
-  // Rotate until a complement label is found (or all have been checked).
-  GetLabel().Rotate(2, NUM_NOPS_4STACK)S;
-  for (int i = 1; i < num_neighbors; i++) {
-    cOrganism * neighbor = organism->GetNeighbor();
-
-    // Assuming we have a neighbor and it is of the same hardware type,
-    // search for the label in it.
-    if (neighbor != NULL &&
-	neighbor->GetHardware().GetType() == GetType()) {
-
-      // If this facing has the full label, stop here.
-      cHardware4Stack & cur_hardware = (cHardware4Stack &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(1);
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_SetCopyMut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int new_mut_rate = Max( Register(reg_used), 1 );
-  organism->SetCopyMutProb(((double) new_mut_rate) / 10000.0);
-  return true;
-}
-
-bool cHardware4Stack::Inst_ModCopyMut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const double new_mut_rate = organism->GetCopyMutProb() +
-    ((double) Register(reg_used)) / 10000.0;
-  if (new_mut_rate > 0.0) organism->SetCopyMutProb(new_mut_rate);
-  return true;
-}
-// Multi-threading.
-
-bool cHardware4Stack::Inst_ThreadID()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = GetCurThreadID();
-  return true;
-}
-
-
-// Head-based instructions
-bool cHardware4Stack::Inst_SetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  SetActiveHead(head_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_AdvanceHead()
-{
-  const int head_used = FindModifiedHead(HEAD_WRITE);
-  GetHead(head_used).Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_JumpHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Jump( Register(REG_CX) );
-  return true;
-}
-
-bool cHardware4Stack::Inst_GetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  Register(REG_CX) = GetHead(head_used).GetPosition();
-  return true;
-}
-
-bool cHardware4Stack::Inst_HeadDivideSex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(true);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardware4Stack::Inst_HeadDivideAsex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(false);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardware4Stack::Inst_HeadDivide1()  { return Inst_HeadDivideMut(1); }
-bool cHardware4Stack::Inst_HeadDivide2()  { return Inst_HeadDivideMut(2); }
-bool cHardware4Stack::Inst_HeadDivide3()  { return Inst_HeadDivideMut(3); }
-bool cHardware4Stack::Inst_HeadDivide4()  { return Inst_HeadDivideMut(4); }
-bool cHardware4Stack::Inst_HeadDivide5()  { return Inst_HeadDivideMut(5); }
-bool cHardware4Stack::Inst_HeadDivide6()  { return Inst_HeadDivideMut(6); }
-bool cHardware4Stack::Inst_HeadDivide7()  { return Inst_HeadDivideMut(7); }
-bool cHardware4Stack::Inst_HeadDivide8()  { return Inst_HeadDivideMut(8); }
-bool cHardware4Stack::Inst_HeadDivide9()  { return Inst_HeadDivideMut(9); }
-bool cHardware4Stack::Inst_HeadDivide10()  { return Inst_HeadDivideMut(10); }
-bool cHardware4Stack::Inst_HeadDivide16()  { return Inst_HeadDivideMut(16); }
-bool cHardware4Stack::Inst_HeadDivide32()  { return Inst_HeadDivideMut(32); }
-bool cHardware4Stack::Inst_HeadDivide50()  { return Inst_HeadDivideMut(50); }
-bool cHardware4Stack::Inst_HeadDivide100()  { return Inst_HeadDivideMut(100); }
-bool cHardware4Stack::Inst_HeadDivide500()  { return Inst_HeadDivideMut(500); }
-bool cHardware4Stack::Inst_HeadDivide1000()  { return Inst_HeadDivideMut(1000); }
-bool cHardware4Stack::Inst_HeadDivide5000()  { return Inst_HeadDivideMut(5000); }
-bool cHardware4Stack::Inst_HeadDivide10000()  { return Inst_HeadDivideMut(10000); }
-bool cHardware4Stack::Inst_HeadDivide50000()  { return Inst_HeadDivideMut(50000); }
-bool cHardware4Stack::Inst_HeadDivide0_5()  { return Inst_HeadDivideMut(0.5); }
-bool cHardware4Stack::Inst_HeadDivide0_1()  { return Inst_HeadDivideMut(0.1); }
-bool cHardware4Stack::Inst_HeadDivide0_05()  { return Inst_HeadDivideMut(0.05); }
-bool cHardware4Stack::Inst_HeadDivide0_01()  { return Inst_HeadDivideMut(0.01); }
-bool cHardware4Stack::Inst_HeadDivide0_001()  { return Inst_HeadDivideMut(0.001); }
-
-bool cHardware4Stack::HeadCopy_ErrorCorrect(double reduction)
-{
-  // For the moment, this cannot be nop-modified.
-  c4StackHead & read_head = GetHead(HEAD_READ);
-  c4StackHead & write_head = GetHead(HEAD_WRITE);
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  read_head.Adjust();
-  write_head.Adjust();
-
-  // Do mutations.
-  cInstruction read_inst = read_head.GetInst();
-  if ( g_random.P(organism->GetCopyMutProb() / reduction) ) {
-    read_inst = GetRandomInst();
-    cpu_stats.mut_stats.copy_mut_count++; 
-    write_head.FlagMutated() = true;
-    write_head.FlagCopyMut() = true;
-    //organism->GetPhenotype().IsMutated() = true;
-  }
-  ReadInst(read_inst.GetOp());
-
-  cpu_stats.mut_stats.copies_exec++;
-
-  write_head.SetInst(read_inst);
-  write_head.FlagCopied() = true;  // Set the copied flag...
-
-  read_head.Advance();
-  write_head.Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_HeadCopy2()  { return HeadCopy_ErrorCorrect(2); }
-bool cHardware4Stack::Inst_HeadCopy3()  { return HeadCopy_ErrorCorrect(3); }
-bool cHardware4Stack::Inst_HeadCopy4()  { return HeadCopy_ErrorCorrect(4); }
-bool cHardware4Stack::Inst_HeadCopy5()  { return HeadCopy_ErrorCorrect(5); }
-bool cHardware4Stack::Inst_HeadCopy6()  { return HeadCopy_ErrorCorrect(6); }
-bool cHardware4Stack::Inst_HeadCopy7()  { return HeadCopy_ErrorCorrect(7); }
-bool cHardware4Stack::Inst_HeadCopy8()  { return HeadCopy_ErrorCorrect(8); }
-bool cHardware4Stack::Inst_HeadCopy9()  { return HeadCopy_ErrorCorrect(9); }
-bool cHardware4Stack::Inst_HeadCopy10() { return HeadCopy_ErrorCorrect(10); }
-
-bool cHardware4Stack::Inst_SetFlow()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  GetHead(HEAD_FLOW).Set(Register(reg_used), this);
-  return true; 
-}
-
-// Direct Matching Templates
-
-bool cHardware4Stack::Inst_DMJumpF()
-{
-  ReadLabel();
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    IP().Jump(Register(REG_BX));
-    return true;
-  }
-
-  // Otherwise, jump to the label.
-  c4StackHead jump_location(FindLabel(1));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "dm-jump-f: no complement label");
-  return false;
-}
-
-//// Placebo insts ////
-bool cHardware4Stack::Inst_Skip()
-{
-  IP().Advance();
-  return true;
-}
 */
-
Index: avida/current/source/cpu/hardware_4stack.hh
diff -u avida/current/source/cpu/hardware_4stack.hh:1.5 avida/current/source/cpu/hardware_4stack.hh:1.6
--- avida/current/source/cpu/hardware_4stack.hh:1.5	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/hardware_4stack.hh	Wed Jul 16 19:36:54 2003
@@ -20,6 +20,7 @@
 #include "cpu_defs.hh"
 #include "label.hh"
 #include "head.hh"
+#include "../main/config.hh"
 
 class cInstSet;
 class cInstLibBase;
@@ -27,8 +28,8 @@
 class cMutation;
 
 //new-style constant declarations - law 
-static const int NUM_LOCAL_STACKS = 2;
-static const int NUM_GLOBAL_STACKS = 2;
+static const int NUM_LOCAL_STACKS = 3;
+static const int NUM_GLOBAL_STACKS = 1;
 static const int NUM_STACKS = NUM_LOCAL_STACKS + NUM_GLOBAL_STACKS;
 static const int STACK_AX = 0;
 static const int STACK_BX = 1;
@@ -46,12 +47,14 @@
 struct cHardware4Stack_Thread {
 private:
   int id;
+
 public:
   c4StackHead heads[NUM_HEADS];
   UCHAR cur_head;
   cCPUStack local_stacks[NUM_LOCAL_STACKS];
 
-  UCHAR input_pointer;
+  int input_pointer;
+  bool advance_ip;         // Should the IP advance after this instruction?
   tBuffer<int> input_buf;
   tBuffer<int> output_buf;
   cCodeLabel read_label;
@@ -96,7 +99,7 @@
   tArray<cCPUMemory> memory_array;          // Memory...
   //cCPUStack global_stack;     // A stack that all threads share.
   cCPUStack global_stacks[NUM_GLOBAL_STACKS];
-  int thread_time_used;
+  //int thread_time_used;
 
   tArray<cHardware4Stack_Thread> threads;
   int thread_id_chart;
@@ -104,7 +107,7 @@
 
   // Flags...
   bool mal_active;         // Has an allocate occured since last dividehe?
-  bool advance_ip;         // Should the IP advance after this instruction?
+  //bool advance_ip;         // Should the IP advance after this instruction?
 
   // Instruction costs...
 #ifdef INSTRUCTION_COSTS
@@ -112,6 +115,15 @@
   tArray<int> inst_ft_cost;
 #endif
 
+  // Thread slicing...
+
+    // Keeps track of the base thread slicing number for each possible number of threads
+  float slice_array[10]; //***HACK!  How do I do this right? -law
+                         //this wouldn't compile -> [cConfig::GetMaxCPUThreads()+1]***; 
+
+  // Keeps track of fractional instructions that carry over into next update
+  float inst_remainder; 
+
 public:
   cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set);
   ~cHardware4Stack();
@@ -167,6 +179,9 @@
     { return threads[cur_thread].heads[HEAD_IP]; }
   inline c4StackHead & IP() { return threads[cur_thread].heads[HEAD_IP]; }
 
+  inline const bool & AdvanceIP() const
+    { return threads[cur_thread].advance_ip; }
+  inline bool & AdvanceIP() { return threads[cur_thread].advance_ip; }
 
   // --------  Label Manipulation  -------
   void ReadLabel(int max_size=MAX_LABEL_SIZE);
@@ -200,7 +215,7 @@
   int TestParasite() const;
 
   // --------  Accessors  --------
-  int GetThreadTimeUsed() const { return thread_time_used; }
+  //int GetThreadTimeUsed() const { return thread_time_used; }
   int GetNumThreads() const     { return threads.GetSize(); }
   int GetCurThread() const      { return cur_thread; }
   int GetCurThreadID() const    { return threads[cur_thread].GetID(); }
@@ -222,11 +237,12 @@
 
   int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
   int Inject(const cCodeLabel & in_label, const cGenome & injection);
-  int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
+  int InjectThread(const cCodeLabel &, const cGenome &) { return -1; }
   void InjectCode(const cGenome & injection, const int line_num);
-  void InjectCodeThread(const cGenome & injection, const int line_num);
   void Mutate(const int mut_point);
   int PointMutate(const double mut_rate);
+  int FindFirstEmpty();
+  bool isEmpty(int mem_space_used);
 
   bool TriggerMutations(int trigger);
   bool TriggerMutations(int trigger, c4StackHead & cur_head);
@@ -335,212 +351,17 @@
   bool Inst_Mod();
   //35 
   bool Inst_KillThread();
-
-  /*
-  // Flow Control
-  bool Inst_If0();
-
-  bool Inst_IfNot0();
- 
-  bool Inst_IfGr0();
-  
-  bool Inst_IfGrEqu0();
-  bool Inst_IfGrEqu();
-  bool Inst_IfLess0();
- 
-  bool Inst_IfLsEqu0();
-  bool Inst_IfLsEqu();
-  bool Inst_IfBit1();
-  bool Inst_IfANotEqB();
-  bool Inst_IfBNotEqC();
-  bool Inst_IfANotEqC();
-
-  bool Inst_JumpF();
-  bool Inst_JumpB();
-  bool Inst_JumpP();
-  bool Inst_JumpSelf();
-  bool Inst_Call();
-  bool Inst_Return();
-
-  // Stack and Register Operations
-  bool Inst_Pop();
-  bool Inst_Push();
-
- 
-
-  bool Inst_PopA();
-  bool Inst_PopB();
-  bool Inst_PopC();
-
-
-  bool Inst_SwitchStack();
-  bool Inst_FlipStack();
-  bool Inst_Swap();
-  bool Inst_SwapAB();
-  bool Inst_SwapBC();
-  bool Inst_SwapAC();
-  bool Inst_CopyStack();
-  bool Inst_CopyRegAB();
-  bool Inst_CopyRegAC();
-  bool Inst_CopyRegBA();
-  bool Inst_CopyRegBC();
-  bool Inst_CopyRegCA();
-  bool Inst_CopyRegCB();
-  bool Inst_Reset();
-
-  // Single-Argument Math
-
-  bool Inst_Bit1();
-  bool Inst_SetNum();
-
-  bool Inst_Zero();
-  bool Inst_Not();
-  bool Inst_Neg();
-  bool Inst_Square();
-  bool Inst_Sqrt();
-  bool Inst_Log();
-  bool Inst_Log10();
-  bool Inst_Minus18();
-
-  // Double Argument Math
-
-  bool Inst_Nor();
-  bool Inst_And();
-  bool Inst_Order();
-  bool Inst_Xor();
-
-  // Biological
-  bool Inst_Copy();
-  bool Inst_ReadInst();
-  bool Inst_WriteInst();
-  bool Inst_StackReadInst();
-  bool Inst_StackWriteInst();
-  bool Inst_Compare();
-  bool Inst_IfNCpy();
-  bool Inst_Allocate();
-  bool Inst_DivideOld();
-  bool Inst_CAlloc();
-  bool Inst_CDivide();
-
+  //36
+  bool Inst_IO();
+  //37
   bool Inst_Inject();
+  
+  /*
   bool Inst_InjectRand();
   bool Inst_InjectThread();
   bool Inst_Repro();
-
-  // I/O and Sensory
-  bool Inst_TaskGet();
-  bool Inst_TaskStackGet();
-  bool Inst_TaskStackLoad();
-  bool Inst_TaskPut();
-  bool Inst_TaskIO();
-  bool Inst_SearchF();
-  bool Inst_SearchB();
-  bool Inst_MemSize();
-
-  // Environment
-
-  bool Inst_RotateL();
-  bool Inst_RotateR();
-  bool Inst_SetCopyMut();
-  bool Inst_ModCopyMut();
-
-  // Multi-threading...
-
-
-  bool Inst_ThreadID();
-
-  // Head-based instructions...
-
-  bool Inst_SetHead();
-  bool Inst_AdvanceHead();
-
-  bool Inst_JumpHead();
-  bool Inst_GetHead();
- 
-  bool Inst_SetFlow();
-
-  bool Inst_HeadCopy2();
-  bool Inst_HeadCopy3();
-  bool Inst_HeadCopy4();
-  bool Inst_HeadCopy5();
-  bool Inst_HeadCopy6();
-  bool Inst_HeadCopy7();
-  bool Inst_HeadCopy8();
-  bool Inst_HeadCopy9();
-  bool Inst_HeadCopy10();
-
-  bool Inst_HeadDivideSex();
-  bool Inst_HeadDivideAsex();
-
-  bool Inst_HeadDivide1();
-  bool Inst_HeadDivide2();
-  bool Inst_HeadDivide3();
-  bool Inst_HeadDivide4();
-  bool Inst_HeadDivide5();
-  bool Inst_HeadDivide6();
-  bool Inst_HeadDivide7();
-  bool Inst_HeadDivide8();
-  bool Inst_HeadDivide9();
-  bool Inst_HeadDivide10();
-  bool Inst_HeadDivide16();
-  bool Inst_HeadDivide32();
-  bool Inst_HeadDivide50();
-  bool Inst_HeadDivide100();
-  bool Inst_HeadDivide500();
-  bool Inst_HeadDivide1000();
-  bool Inst_HeadDivide5000();
-  bool Inst_HeadDivide10000();
-  bool Inst_HeadDivide50000();
-  bool Inst_HeadDivide0_5();
-  bool Inst_HeadDivide0_1();
-  bool Inst_HeadDivide0_05();
-  bool Inst_HeadDivide0_01();
-  bool Inst_HeadDivide0_001();
-
-
-  // Direct Matching Templates
-
-  bool Inst_DMJumpF();
-  bool Inst_DMJumpB();
-  bool Inst_DMCall();
-  bool Inst_DMSearchF();
-  bool Inst_DMSearchB();
-
-  // Relative Addressed Jumps
-
-  bool Inst_REJumpF();
-  bool Inst_REJumpB();
-
-  // Absoulte Addressed Jumps
-
-  bool Inst_ABSJump();
-
-
-  // Biologically inspired reproduction
-  bool Inst_BCAlloc();
-  bool Inst_BCopy();
-  bool Inst_BDivide();
-private:
-  bool Inst_BCopy_Main(double mut_prob); // Internal called by all BCopy's
-public:
-  // Bio Error Correction
-  bool Inst_BCopyDiv2();
-  bool Inst_BCopyDiv3();
-  bool Inst_BCopyDiv4();
-  bool Inst_BCopyDiv5();
-  bool Inst_BCopyDiv6();
-  bool Inst_BCopyDiv7();
-  bool Inst_BCopyDiv8();
-  bool Inst_BCopyDiv9();
-  bool Inst_BCopyDiv10();
-  bool Inst_BCopyPow2();
-  bool Inst_BIfNotCopy();
-  bool Inst_BIfCopy();
-
-
-  //// Placebo ////
-  bool Inst_Skip();
   */
+ 
 };
 
 
Index: avida/current/source/cpu/hardware_cpu.cc
diff -u avida/current/source/cpu/hardware_cpu.cc:1.52 avida/current/source/cpu/hardware_cpu.cc:1.53
--- avida/current/source/cpu/hardware_cpu.cc:1.52	Mon Jun 30 15:00:57 2003
+++ avida/current/source/cpu/hardware_cpu.cc	Wed Jul 16 19:36:54 2003
@@ -2855,7 +2855,7 @@
 bool cHardwareCPU::Inst_TaskGet()
 {
   const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = organism->GetInput();
+  const int value = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   Register(reg_used) = value;
   DoInput(value);
   return true;
@@ -2863,7 +2863,7 @@
 
 bool cHardwareCPU::Inst_TaskStackGet()
 {
-  const int value = organism->GetInput();
+  const int value = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   StackPush(value);
   DoInput(value);
   return true;
@@ -2871,7 +2871,8 @@
 
 bool cHardwareCPU::Inst_TaskStackLoad()
 {
-  for (int i = 0; i < IO_SIZE; i++) StackPush( organism->GetInput() );
+  for (int i = 0; i < IO_SIZE; i++) 
+    StackPush( organism->GetInputAt(threads[GetCurThread()].input_pointer) );
   return true;
 }
 
@@ -2893,7 +2894,7 @@
   DoOutput(value_out);  // Check for tasks compleated.
 
   // Do the "get" component
-  const int value_in = organism->GetInput();
+  const int value_in = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   Register(reg_used) = value_in;
   DoInput(value_in);
   return true;
Index: avida/current/source/cpu/hardware_cpu.hh
diff -u avida/current/source/cpu/hardware_cpu.hh:1.31 avida/current/source/cpu/hardware_cpu.hh:1.32
--- avida/current/source/cpu/hardware_cpu.hh:1.31	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/hardware_cpu.hh	Wed Jul 16 19:36:54 2003
@@ -44,7 +44,7 @@
   UCHAR cur_stack;              // 0 = local stack, 1 = global stack.
   UCHAR cur_head;
 
-  UCHAR input_pointer;
+  int input_pointer;
   tBuffer<int> input_buf;
   tBuffer<int> output_buf;
   cCodeLabel read_label;
Index: avida/current/source/cpu/head.cc
diff -u avida/current/source/cpu/head.cc:1.22 avida/current/source/cpu/head.cc:1.23
--- avida/current/source/cpu/head.cc:1.22	Sun Jun  8 19:36:08 2003
+++ avida/current/source/cpu/head.cc	Wed Jul 16 19:36:54 2003
@@ -508,15 +508,15 @@
   }
 }
 
-void c4StackHead::Reset(cHardwareBase * new_hardware)
+void c4StackHead::Reset(int in_mem_space, cHardwareBase * new_hardware)
 {
   if (new_hardware) main_hardware = new_hardware;
   cur_hardware  = new_hardware;
   position = 0;
-  mem_space = 0;
+  mem_space = in_mem_space;
 }
 
-void c4StackHead::Set(int new_pos, cHardwareBase * in_hardware, int in_mem_space)
+void c4StackHead::Set(int new_pos, int in_mem_space, cHardwareBase * in_hardware = NULL)
 {
   position = new_pos;
   if (in_hardware) cur_hardware = in_hardware;
Index: avida/current/source/cpu/head.hh
diff -u avida/current/source/cpu/head.hh:1.11 avida/current/source/cpu/head.hh:1.12
--- avida/current/source/cpu/head.hh:1.11	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/head.hh	Wed Jul 16 19:36:54 2003
@@ -125,8 +125,8 @@
   c4StackHead(const c4StackHead & in_cpu_head);
 
   void Adjust();
-  void Reset(cHardwareBase * new_hardware = NULL);
-  void Set(int new_pos, cHardwareBase * in_hardware = NULL, int in_mem_space = 0);
+  void Reset(int in_mem_space=0, cHardwareBase * new_hardware = NULL);
+  void Set(int new_pos, int in_mem_space = 0, cHardwareBase * in_hardware = NULL);
   void Set(const c4StackHead & in_head);
   void LoopJump(int jump);
   const cCPUMemory & GetMemory() const;
Index: avida/current/source/cpu/test_cpu.cc
diff -u avida/current/source/cpu/test_cpu.cc:1.42 avida/current/source/cpu/test_cpu.cc:1.43
--- avida/current/source/cpu/test_cpu.cc:1.42	Sun May 18 11:59:24 2003
+++ avida/current/source/cpu/test_cpu.cc	Wed Jul 16 19:36:54 2003
@@ -396,6 +396,12 @@
   return input_array[cur_input++];
 }
 
+int cTestCPU::GetInputAt(int & input_pointer)
+{
+  if (input_pointer >= input_array.GetSize()) input_pointer = 0;
+  return input_array[input_pointer++];
+}
+
 const tArray<double> & cTestCPU::GetResources()
 {
   assert(resource_count != NULL);
Index: avida/current/source/cpu/test_cpu.hh
diff -u avida/current/source/cpu/test_cpu.hh:1.31 avida/current/source/cpu/test_cpu.hh:1.32
--- avida/current/source/cpu/test_cpu.hh:1.31	Sat May 17 14:23:25 2003
+++ avida/current/source/cpu/test_cpu.hh	Wed Jul 16 19:36:54 2003
@@ -134,6 +134,7 @@
   static cInstSet * GetInstSet() { return inst_set; }
   static cEnvironment * GetEnvironment() { return environment; }
   static int GetInput();
+  static int GetInputAt(int & input_pointer);
   static const tArray<double> & GetResources();
   static void UpdateResources(const tArray<double> & res_change);
 };
Index: avida/current/source/event/cPopulation.events
diff -u avida/current/source/event/cPopulation.events:1.40 avida/current/source/event/cPopulation.events:1.41
--- avida/current/source/event/cPopulation.events:1.40	Tue May 20 14:07:00 2003
+++ avida/current/source/event/cPopulation.events	Wed Jul 16 19:36:54 2003
@@ -783,6 +783,111 @@
    cInstUtil::RandomGenome(length, population->GetEnvironment().GetInstSet());
 population->Inject(genome, cell_id, merit, lineage_label, neutral_metric);
 
+inject_range_parasite
+:descr:
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+:args:
+cString fname_parasite "organism.parasite"
+int start_cell 0
+int end_cell -1
+double merit -1
+int lineage_label 0
+double neutral_metric 0
+int mem_space 2
+:body:
+if (fname_parasite == "START_CREATURE") fname_parasite=cConfig::GetStartCreature();
+if (end_cell == -1) end_cell = start_cell + 1;
+if (start_cell < 0 ||
+    end_cell > population->GetSize() ||
+    start_cell >= end_cell) {
+  cout << "Warning: inject_range has invalid range!";
+}
+else {
+  cGenome genome_parasite =
+     cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+  for (int i = start_cell; i < end_cell; i++) {
+    population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+  }
+  population->SetSyncEvents(true);
+}
+
+inject_range_pair
+:descr:
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+:args:
+cString fname "START_CREATURE"
+cString fname_parasite "organism.parasite"
+int start_cell 0
+int end_cell -1
+double merit -1
+int lineage_label 0
+double neutral_metric 0
+int mem_space 2
+:body:
+if (fname == "START_CREATURE") fname=cConfig::GetStartCreature();
+if (end_cell == -1) end_cell = start_cell + 1;
+if (start_cell < 0 ||
+    end_cell > population->GetSize() ||
+    start_cell >= end_cell) {
+  cout << "Warning: inject_range has invalid range!";
+}
+else {
+  cGenome genome =
+     cInstUtil::LoadGenome(fname, population->GetEnvironment().GetInstSet());
+  cGenome genome_parasite =
+     cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+  for (int i = start_cell; i < end_cell; i++) {
+    population->Inject(genome, i, merit, lineage_label, neutral_metric);
+    population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+  }
+  population->SetSyncEvents(true);
+}
 
 ################ MUTATION RATES ###############
 zero_muts
Index: avida/current/source/event/cPopulation_construct_event_auto.ci
diff -u avida/current/source/event/cPopulation_construct_event_auto.ci:1.2 avida/current/source/event/cPopulation_construct_event_auto.ci:1.3
--- avida/current/source/event/cPopulation_construct_event_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_construct_event_auto.ci	Wed Jul 16 19:36:54 2003
@@ -130,6 +130,12 @@
     case cPopulationEventFactory::EVENT_inject_random :
       event = new cPopulationEventinject_random(arg_list);
       break;
+    case cPopulationEventFactory::EVENT_inject_range_parasite :
+      event = new cPopulationEventinject_range_parasite(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_inject_range_pair :
+      event = new cPopulationEventinject_range_pair(arg_list);
+      break;
     case cPopulationEventFactory::EVENT_zero_muts :
       event = new cPopulationEventzero_muts(arg_list);
       break;
Index: avida/current/source/event/cPopulation_descr.ci
diff -u avida/current/source/event/cPopulation_descr.ci:1.2 avida/current/source/event/cPopulation_descr.ci:1.3
--- avida/current/source/event/cPopulation_descr.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_descr.ci	Wed Jul 16 19:36:54 2003
@@ -43,6 +43,8 @@
   cEventEntry( "inject_range", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
   cEventEntry( "inject_sequence", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nsequence (string)\n  The genome sequence for this organism.  This is a mandatory argument.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range ckdfhgklsahnfsaggdsgajfg 0 10 100\n\nWill inject 10 organisms into cells 0 through 9 with a merit of 100.\n" ),
   cEventEntry( "inject_random", "Injects a randomly generated genome into the population.\n\nParameters:\nlength (integer) [required]\n  Number of instructions in the randomly generated genome.\ncell ID (integer) default: -1\n  The grid-point into which the genome should be placed.  Default is random.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n" ),
+  cEventEntry( "inject_range_parasite", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
+  cEventEntry( "inject_range_pair", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
   cEventEntry( "zero_muts", "This event will set all mutation rates to zero...\n" ),
   cEventEntry( "mod_copy_mut", "\n" ),
   cEventEntry( "mod_div_mut", "\n" ),
@@ -80,5 +82,5 @@
   cEventEntry( "inject_resource", "Inject (add) a specified amount of a specified resource.\n" ),
   cEventEntry( "set_resource", "Set the resource amount to a specific level\n" ) };
 
-const int cEventDescrs::num_of_events = 80;
+const int cEventDescrs::num_of_events = 82;
 
Index: avida/current/source/event/cPopulation_enums_auto.ci
diff -u avida/current/source/event/cPopulation_enums_auto.ci:1.2 avida/current/source/event/cPopulation_enums_auto.ci:1.3
--- avida/current/source/event/cPopulation_enums_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_enums_auto.ci	Wed Jul 16 19:36:54 2003
@@ -43,6 +43,8 @@
   EVENT_inject_range,
   EVENT_inject_sequence,
   EVENT_inject_random,
+  EVENT_inject_range_parasite,
+  EVENT_inject_range_pair,
   EVENT_zero_muts,
   EVENT_mod_copy_mut,
   EVENT_mod_div_mut,
Index: avida/current/source/event/cPopulation_event_list
diff -u avida/current/source/event/cPopulation_event_list:1.2 avida/current/source/event/cPopulation_event_list:1.3
--- avida/current/source/event/cPopulation_event_list:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_event_list	Wed Jul 16 19:36:54 2003
@@ -44,6 +44,8 @@
 inject_range  [cString fname="START_CREATURE"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
 inject_sequence  <cString seq> [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
 inject_random  <int length> [int cell_id=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
+inject_range_parasite  [cString fname_parasite="organism.parasite"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0] [int mem_space=2]
+inject_range_pair  [cString fname="START_CREATURE"] [cString fname_parasite="organism.parasite"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0] [int mem_space=2]
 zero_muts 
 mod_copy_mut  <double cmut_inc> [int cell=-1]
 mod_div_mut  <double dmut_inc> [int cell=-1]
Index: avida/current/source/event/cPopulation_name2enum_auto.ci
diff -u avida/current/source/event/cPopulation_name2enum_auto.ci:1.2 avida/current/source/event/cPopulation_name2enum_auto.ci:1.3
--- avida/current/source/event/cPopulation_name2enum_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_name2enum_auto.ci	Wed Jul 16 19:36:54 2003
@@ -89,6 +89,10 @@
     return cPopulationEventFactory::EVENT_inject_sequence;
   }else if (name == "inject_random") {
     return cPopulationEventFactory::EVENT_inject_random;
+  }else if (name == "inject_range_parasite") {
+    return cPopulationEventFactory::EVENT_inject_range_parasite;
+  }else if (name == "inject_range_pair") {
+    return cPopulationEventFactory::EVENT_inject_range_pair;
   }else if (name == "zero_muts") {
     return cPopulationEventFactory::EVENT_zero_muts;
   }else if (name == "mod_copy_mut") {
Index: avida/current/source/event/cPopulation_process_auto.ci
diff -u avida/current/source/event/cPopulation_process_auto.ci:1.2 avida/current/source/event/cPopulation_process_auto.ci:1.3
--- avida/current/source/event/cPopulation_process_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_process_auto.ci	Wed Jul 16 19:36:54 2003
@@ -1360,6 +1360,151 @@
   }
 };
 
+///// inject_range_parasite /////
+
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+
+
+class cPopulationEventinject_range_parasite : public cPopulationEvent {
+private:
+  cString fname_parasite;
+  int start_cell;
+  int end_cell;
+  double merit;
+  int lineage_label;
+  double neutral_metric;
+  int mem_space;
+public:
+  cPopulationEventinject_range_parasite(const cString & in_args):
+   cPopulationEvent("inject_range_parasite", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname_parasite="organism.parasite"; else fname_parasite=args.PopWord();
+    if (args == "") start_cell=0; else start_cell=args.PopWord().AsInt();
+    if (args == "") end_cell=-1; else end_cell=args.PopWord().AsInt();
+    if (args == "") merit=-1; else merit=args.PopWord().AsDouble();
+    if (args == "") lineage_label=0; else lineage_label=args.PopWord().AsInt();
+    if (args == "") neutral_metric=0; else neutral_metric=args.PopWord().AsDouble();
+    if (args == "") mem_space=2; else mem_space=args.PopWord().AsInt();
+  }
+///// inject_range_parasite /////
+  void Process(){
+    if (fname_parasite == "START_CREATURE") fname_parasite=cConfig::GetStartCreature();
+    if (end_cell == -1) end_cell = start_cell + 1;
+    if (start_cell < 0 ||
+        end_cell > population->GetSize() ||
+        start_cell >= end_cell) {
+      cout << "Warning: inject_range has invalid range!";
+    }
+    else {
+      cGenome genome_parasite =
+         cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+      for (int i = start_cell; i < end_cell; i++) {
+        population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+      }
+      population->SetSyncEvents(true);
+    }
+  }
+};
+
+///// inject_range_pair /////
+
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+
+
+class cPopulationEventinject_range_pair : public cPopulationEvent {
+private:
+  cString fname;
+  cString fname_parasite;
+  int start_cell;
+  int end_cell;
+  double merit;
+  int lineage_label;
+  double neutral_metric;
+  int mem_space;
+public:
+  cPopulationEventinject_range_pair(const cString & in_args):
+   cPopulationEvent("inject_range_pair", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname="START_CREATURE"; else fname=args.PopWord();
+    if (args == "") fname_parasite="organism.parasite"; else fname_parasite=args.PopWord();
+    if (args == "") start_cell=0; else start_cell=args.PopWord().AsInt();
+    if (args == "") end_cell=-1; else end_cell=args.PopWord().AsInt();
+    if (args == "") merit=-1; else merit=args.PopWord().AsDouble();
+    if (args == "") lineage_label=0; else lineage_label=args.PopWord().AsInt();
+    if (args == "") neutral_metric=0; else neutral_metric=args.PopWord().AsDouble();
+    if (args == "") mem_space=2; else mem_space=args.PopWord().AsInt();
+  }
+///// inject_range_pair /////
+  void Process(){
+    if (fname == "START_CREATURE") fname=cConfig::GetStartCreature();
+    if (end_cell == -1) end_cell = start_cell + 1;
+    if (start_cell < 0 ||
+        end_cell > population->GetSize() ||
+        start_cell >= end_cell) {
+      cout << "Warning: inject_range has invalid range!";
+    }
+    else {
+      cGenome genome =
+         cInstUtil::LoadGenome(fname, population->GetEnvironment().GetInstSet());
+      cGenome genome_parasite =
+         cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+      for (int i = start_cell; i < end_cell; i++) {
+        population->Inject(genome, i, merit, lineage_label, neutral_metric);
+        population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+      }
+      population->SetSyncEvents(true);
+    }
+  }
+};
+
 ///// zero_muts /////
 
 /**
Index: avida/current/source/main/avida.cc
diff -u avida/current/source/main/avida.cc:1.43 avida/current/source/main/avida.cc:1.44
--- avida/current/source/main/avida.cc:1.43	Fri Jun 13 14:49:59 2003
+++ avida/current/source/main/avida.cc	Wed Jul 16 19:36:54 2003
@@ -103,6 +103,7 @@
   test_interface.SetFun_Recycle(&cCallbackUtil::CB_RecycleHardware);
   test_interface.SetFun_Divide(&cCallbackUtil::CB_TestDivide);
   test_interface.SetFun_GetInput(&cCallbackUtil::CB_GetInput);
+  test_interface.SetFun_GetInputAt(&cCallbackUtil::CB_GetInputAt);
   test_interface.SetFun_GetResources(&cCallbackUtil::CB_GetResources);
   test_interface.SetFun_UpdateResources(&cCallbackUtil::CB_UpdateResources);
 
@@ -186,6 +187,7 @@
   default_interface.SetFun_Breakpoint(&cCallbackUtil::CB_Breakpoint);
   default_interface.SetFun_TestFitness(&cCallbackUtil::CB_TestFitness);
   default_interface.SetFun_GetInput(&cCallbackUtil::CB_GetInput);
+  default_interface.SetFun_GetInputAt(&cCallbackUtil::CB_GetInputAt);
   default_interface.SetFun_Debug(&cCallbackUtil::CB_Debug);
   default_interface.SetFun_GetResources(&cCallbackUtil::CB_GetResources);
   default_interface.SetFun_UpdateResources(&cCallbackUtil::CB_UpdateResources);
Index: avida/current/source/main/callback_util.cc
diff -u avida/current/source/main/callback_util.cc:1.20 avida/current/source/main/callback_util.cc:1.21
--- avida/current/source/main/callback_util.cc:1.20	Wed May 21 20:05:57 2003
+++ avida/current/source/main/callback_util.cc	Wed Jul 16 19:36:54 2003
@@ -20,7 +20,7 @@
 #include "../cpu/hardware_base.hh"
 #include "../cpu/hardware_factory.hh"
 #include "../cpu/test_cpu.hh"
-
+#include "../tools/message.hh"
 
 using namespace std;
 
@@ -141,6 +141,14 @@
   return cell.GetInput();
 }
 
+int cCallbackUtil::CB_GetInputAt(cPopulation * pop, int cell_id, int & input_pointer)
+{
+  if (pop == NULL) return cTestCPU::GetInputAt(input_pointer);
+  cPopulationCell & cell = pop->GetCell(cell_id);
+  assert(cell.IsOccupied());
+  return cell.GetInputAt(input_pointer);
+}
+
 int cCallbackUtil::CB_Debug(cPopulation * pop, int cell_id)
 {
   if (pop == NULL) return -1;
@@ -175,4 +183,15 @@
   assert(pop != NULL);
   cPopulationCell & death_cell = pop->GetCell(death_id);
   pop->KillOrganism(death_cell);
+}
+
+bool cCallbackUtil::CB_SendMessage(cPopulation * pop, int cell_id, cMessage & mess)
+{
+  mess.SetSenderID(cell_id);
+  mess.SetTime(pop->GetUpdate());
+  cPopulationCell & cell = pop->GetCell(cell_id);
+  if(cell.ConnectionList().GetFirst() == NULL)
+    return false;
+  mess.SetRecipientID(cell.ConnectionList().GetFirst()->GetID());
+  return cell.ConnectionList().GetFirst()->GetOrganism()->ReceiveMessage(mess);
 }
Index: avida/current/source/main/callback_util.hh
diff -u avida/current/source/main/callback_util.hh:1.10 avida/current/source/main/callback_util.hh:1.11
--- avida/current/source/main/callback_util.hh:1.10	Tue Apr  1 08:58:17 2003
+++ avida/current/source/main/callback_util.hh	Wed Jul 16 19:36:54 2003
@@ -15,6 +15,7 @@
 class cOrganism;
 class cPopulation;
 class cPopulationInterface;
+class cMessage;
 
 class cCallbackUtil {
 public:
@@ -32,11 +33,13 @@
   static void CB_Breakpoint();
   static double CB_TestFitness(cPopulation * pop, int cell_id);
   static int CB_GetInput(cPopulation * pop, int cell_id);
+  static int CB_GetInputAt(cPopulation * pop, int cell_id, int & input_pointer);
   static int CB_Debug(cPopulation * pop, int cell_id);
   static const tArray<double>& CB_GetResources(cPopulation * pop, int cell_id);
   static void CB_UpdateResources(cPopulation  * pop, int cell_id,
 				 const tArray<double> & res_change);
   static void CB_KillCell(cPopulation * pop, int death_id);
+  static bool CB_SendMessage(cPopulation * pop, int cell_id, cMessage & mess);
 };
 
 #endif
Index: avida/current/source/main/config.hh
diff -u avida/current/source/main/config.hh:1.51 avida/current/source/main/config.hh:1.52
--- avida/current/source/main/config.hh:1.51	Fri Jun  6 12:46:23 2003
+++ avida/current/source/main/config.hh	Wed Jul 16 19:36:54 2003
@@ -40,6 +40,7 @@
 
 #define DIVIDE_METHOD_OFFSPRING 0
 #define DIVIDE_METHOD_SPLIT     1
+#define DIVIDE_METHOD_BIRTH     2
 
 #define GENERATION_INC_OFFSPRING 0
 #define GENERATION_INC_BOTH      1
@@ -307,7 +308,7 @@
 
   static int GetNumInstructions() { return num_instructions; }
   static int GetHardwareType() { return hardware_type; }
-  static int GetMaxCPUThreads()  { return max_cpu_threads; }
+  static int GetMaxCPUThreads() { return max_cpu_threads; }
   static int GetThreadSlicingMethod() { return thread_slicing_method; }
 
   static int GetSizeMeritMethod() { return size_merit_method; }
Index: avida/current/source/main/organism.cc
diff -u avida/current/source/main/organism.cc:1.24 avida/current/source/main/organism.cc:1.25
--- avida/current/source/main/organism.cc:1.24	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/organism.cc	Wed Jul 16 19:36:55 2003
@@ -10,6 +10,7 @@
 
 #include "../tools/functions.hh"
 #include "../tools/tArray.hh"
+#include "../tools/message.hh"
 
 #include "config.hh"
 #include "inst_set.hh"
@@ -44,6 +45,8 @@
   , max_executed(-1)
   , lineage_label(-1)
   , lineage(NULL)
+    , inbox(0)
+    , sent(0)
 {
   // Initialization of structures...
   hardware = pop_interface.NewHardware(this);
@@ -95,9 +98,24 @@
   out_buf.Add(value);
   phenotype.TestOutput(in_buf, out_buf, resource_count, res_change);
   pop_interface.UpdateResources(res_change);
-  if(phenotype.GetToDie() == 1) Die();	//Final Effect Lethal Reaction
+  //if(phenotype.GetToDie() == 1) Die();	//Final Effect Lethal Reaction
 }
 
+void cOrganism::SendMessage(cMessage & mess)
+{
+  if(pop_interface.SendMessage(mess))
+    sent.Add(mess);
+  else
+    {
+      //perhaps some kind of message error buffer?
+    }
+}
+
+bool cOrganism::ReceiveMessage(cMessage & mess)
+{
+  inbox.Add(mess);
+  return true;
+}
 
 int cOrganism::OK()
 {
Index: avida/current/source/main/organism.hh
diff -u avida/current/source/main/organism.hh:1.21 avida/current/source/main/organism.hh:1.22
--- avida/current/source/main/organism.hh:1.21	Sat May 17 02:48:09 2003
+++ avida/current/source/main/organism.hh	Wed Jul 16 19:36:55 2003
@@ -12,6 +12,7 @@
 
 #include "../tools/merit.hh"
 #include "../tools/tBuffer.hh"
+#include "../tools/string.hh"
 
 #include "../defs.hh"
 
@@ -58,6 +59,9 @@
 #endif
   static int instance_count;
 
+  tBuffer<cMessage> inbox;
+  tBuffer<cMessage> sent;
+
 public:
   void PrintStatus(std::ostream & fp);
 
@@ -80,6 +84,7 @@
   void Rotate(int direction) { pop_interface.Rotate(direction); }
   void DoBreakpoint() { pop_interface.Breakpoint(); }
   int GetInput() { return pop_interface.GetInput(); }
+  int GetInputAt(int & input_pointer) { return pop_interface.GetInputAt(input_pointer); }
   void Die() { pop_interface.Die(); }
   int GetCellID() { return pop_interface.GetCellID(); }
   int GetDebugInfo() { return pop_interface.Debug(); }
@@ -88,6 +93,10 @@
   void DoInput(const int value, tBuffer<int> & in_buf, tBuffer<int> & out_buf);
   void DoOutput(const int value, tBuffer<int> & in_buf, tBuffer<int> &out_buf);
 
+  // NEW - message stuff
+  void SendMessage(cMessage & mess);
+  bool ReceiveMessage(cMessage & mess);
+
   int OK();
 
   double GetTestFitness();
@@ -147,7 +156,12 @@
   cLocalMutations & GetLocalMutations() { return mut_info; }
   const cPopulationInterface & PopInterface() const { return pop_interface; }
   cPopulationInterface & PopInterface() { return pop_interface; }
+  
+  // yes, this is a huge hack, but a lot of code uses the 
+  // original GetGenome() call - law 
+  //const tArray<cGenome> & GetGenomeArray() const;
   const cGenome & GetGenome() const { return initial_genome; }
+  //const tArray<cGenome> & GetGenome4Stack() const;
 
   int GetCurGestation() const;
   const cPhenotype & GetPhenotype() const { return phenotype; }
Index: avida/current/source/main/phenotype.cc
diff -u avida/current/source/main/phenotype.cc:1.34 avida/current/source/main/phenotype.cc:1.35
--- avida/current/source/main/phenotype.cc:1.34	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/phenotype.cc	Wed Jul 16 19:36:55 2003
@@ -401,7 +401,7 @@
 	      sensed_resources[j] = result.GetDetected(j);
 
   //Kill any cells that did lethal reactions
-  to_die = result.GetLethal();
+  //to_die = result.GetLethal();
 
   return true;
 }
Index: avida/current/source/main/pop_interface.cc
diff -u avida/current/source/main/pop_interface.cc:1.11 avida/current/source/main/pop_interface.cc:1.12
--- avida/current/source/main/pop_interface.cc:1.11	Tue Apr  1 07:06:27 2003
+++ avida/current/source/main/pop_interface.cc	Wed Jul 16 19:36:55 2003
@@ -27,10 +27,12 @@
   , fun_breakpoint(NULL)
   , fun_test_fitness(NULL)
   , fun_get_input(NULL)
+  , fun_get_input_at(NULL)
   , fun_debug(NULL)
   , fun_get_resources(NULL)
   , fun_update_resources(NULL)
   , fun_kill_cell(NULL)
+    , fun_send_message(NULL)
 {
 }
 
@@ -56,6 +58,7 @@
   fun_get_resources    = in_interface.fun_get_resources;
   fun_update_resources = in_interface.fun_update_resources;
   fun_kill_cell        = in_interface.fun_kill_cell;
+  fun_send_message     = in_interface.fun_send_message;
 }
 
 cHardwareBase * cPopulationInterface::NewHardware(cOrganism * owner)
@@ -134,6 +137,12 @@
   return (*fun_get_input)(population, cell_id);
 }
 
+int cPopulationInterface::GetInputAt(int & input_pointer)
+{
+  assert(fun_get_input_at != NULL);
+  return (*fun_get_input_at)(population, cell_id, input_pointer);
+}
+
 int cPopulationInterface::Debug()
 {
   assert(fun_debug != NULL);
@@ -157,4 +166,10 @@
 {
   if (fun_kill_cell == NULL) return;
   (*fun_kill_cell)(population, cell_id);
+}
+
+bool cPopulationInterface::SendMessage(cMessage & mess)
+{
+  if (fun_send_message == NULL) return false;
+  return (*fun_send_message)(population, cell_id, mess);
 }
Index: avida/current/source/main/pop_interface.hh
diff -u avida/current/source/main/pop_interface.hh:1.9 avida/current/source/main/pop_interface.hh:1.10
--- avida/current/source/main/pop_interface.hh:1.9	Tue Apr  1 07:06:29 2003
+++ avida/current/source/main/pop_interface.hh	Wed Jul 16 19:36:55 2003
@@ -17,6 +17,7 @@
 class cHardwareBase;
 class cOrganism;
 class cPopulation;
+class cMessage;
 
 typedef cHardwareBase * (*tFunNewHardware)(cPopulation *pop, cOrganism *owner);
 typedef void (*tFunRecycle)(cHardwareBase * out_hardware);
@@ -30,12 +31,14 @@
 typedef void (*tFunBreakpoint)();
 typedef double (*tFunTestFitness)(cPopulation * pop, int cell_id);
 typedef int (*tFunGetInput)(cPopulation * pop, int cell_id);
+typedef int (*tFunGetInputAt)(cPopulation * pop, int cell_id, int & input_pointer);
 typedef int (*tFunDebug)(cPopulation * pop, int cell_id);
 typedef const tArray<double> & (*tFunGetResources)
   (cPopulation * pop, int cell_id);
 typedef void (*tFunUpdateResources)
   (cPopulation * pop, int cell_id, const tArray<double> & res_change);
 typedef void (*tFunKillCell)(cPopulation * pop, int death_id);
+typedef bool (*tFunSendMessage)(cPopulation * pop, int cell_id, cMessage & mess);
 
 class cPopulationInterface {
 private:
@@ -53,10 +56,12 @@
   tFunBreakpoint       fun_breakpoint;
   tFunTestFitness      fun_test_fitness;
   tFunGetInput         fun_get_input;
+  tFunGetInputAt       fun_get_input_at;
   tFunDebug            fun_debug;
   tFunGetResources     fun_get_resources;
   tFunUpdateResources  fun_update_resources;
   tFunKillCell         fun_kill_cell;
+  tFunSendMessage      fun_send_message;
 public:
   cPopulationInterface();
   ~cPopulationInterface();
@@ -78,11 +83,13 @@
   void SetFun_Breakpoint(tFunBreakpoint fun) { fun_breakpoint = fun; }
   void SetFun_TestFitness(tFunTestFitness fun) { fun_test_fitness = fun; }
   void SetFun_GetInput(tFunGetInput fun) { fun_get_input = fun; }
+  void SetFun_GetInputAt(tFunGetInputAt fun) { fun_get_input_at = fun; }
   void SetFun_Debug(tFunDebug fun) { fun_debug = fun; }
   void SetFun_GetResources(tFunGetResources fun) { fun_get_resources = fun; }
   void SetFun_UpdateResources(tFunUpdateResources fun)
     { fun_update_resources = fun; }
   void SetFun_KillCell(tFunKillCell fun) { fun_kill_cell = fun; }
+  void SetFun_SendMessage(tFunSendMessage fun) { fun_send_message = fun; }
   void CopyCallbacks(cPopulationInterface & in_interface);
 
   // Activate callbacks...
@@ -97,10 +104,12 @@
   void Breakpoint();
   double TestFitness();
   int GetInput();
+  int GetInputAt(int & input_pointer);
   int Debug();
   const tArray<double> & GetResources();
   void UpdateResources(const tArray<double> & res_change);
   void Die();
+  bool SendMessage(cMessage & mess);
 };
 
 #endif
Index: avida/current/source/main/population.cc
diff -u avida/current/source/main/population.cc:1.109 avida/current/source/main/population.cc:1.110
--- avida/current/source/main/population.cc:1.109	Tue May 20 14:07:00 2003
+++ avida/current/source/main/population.cc	Wed Jul 16 19:36:55 2003
@@ -1070,8 +1070,8 @@
  * this organism.
  **/
 
-void cPopulation::Inject(const cGenome & genome, int cell_id, double merit,
-			 int lineage_label, double neutral )
+void cPopulation::Inject(const cGenome & genome, int cell_id, double merit, 
+			 int lineage_label, double neutral, int mem_space )
 {
   // If an invalid cell was given, choose a new ID for it.
   if (cell_id < 0) {
@@ -1083,14 +1083,21 @@
     }
   }
 
-  InjectGenome( cell_id, genome );
-  cPhenotype & phenotype = GetCell(cell_id).GetOrganism()->GetPhenotype();
-  phenotype.SetNeutralMetric(neutral);
-
-  if (merit > 0) phenotype.SetMerit( cMerit(merit) );
-  schedule->Adjust(cell_id, phenotype.GetMerit());
-
-  LineageSetupOrganism(GetCell(cell_id).GetOrganism(), 0, lineage_label);
+  if(mem_space==0) {
+    InjectGenome( cell_id, genome);
+    cPhenotype & phenotype = GetCell(cell_id).GetOrganism()->GetPhenotype();
+    phenotype.SetNeutralMetric(neutral);
+    
+    if (merit > 0) phenotype.SetMerit( cMerit(merit) );
+    schedule->Adjust(cell_id, phenotype.GetMerit());
+    
+    LineageSetupOrganism(GetCell(cell_id).GetOrganism(), 0, lineage_label);
+  }
+  else
+    {
+      GetCell(cell_id).GetOrganism()->GetHardware().Inject(cCodeLabel(), genome);
+    }
+      
 }
 
 
Index: avida/current/source/main/population.hh
diff -u avida/current/source/main/population.hh:1.55 avida/current/source/main/population.hh:1.56
--- avida/current/source/main/population.hh:1.55	Sat May 17 14:54:55 2003
+++ avida/current/source/main/population.hh	Wed Jul 16 19:36:55 2003
@@ -102,7 +102,7 @@
 
   // Inject and organism from the outside world.
   void Inject(const cGenome & genome, int cell_id=-1, double merit=-1,
-	      int lineage_label=0, double neutral_metric=0 );
+	      int lineage_label=0, double neutral_metric=0, int mem_space=0 );
 
   // Deactivate an organism in the population (required for deactivations)
   void KillOrganism(cPopulationCell & in_cell);
Index: avida/current/source/main/population_cell.cc
diff -u avida/current/source/main/population_cell.cc:1.8 avida/current/source/main/population_cell.cc:1.9
--- avida/current/source/main/population_cell.cc:1.8	Sat May 17 02:48:10 2003
+++ avida/current/source/main/population_cell.cc	Wed Jul 16 19:36:55 2003
@@ -82,13 +82,17 @@
   return input_array[cur_input++];
 }
 
+int cPopulationCell::GetInputAt(int & input_pointer)
+{
+  if (input_pointer >= IO_SIZE) input_pointer = 0;
+  return input_array[input_pointer++];
+}
 
 int cPopulationCell::GetInput(int id)
 {
   assert(id >= 0 && id < IO_SIZE);
   return input_array[id];
 }
-
 
 void cPopulationCell::InsertOrganism(cOrganism & new_org)
 {
Index: avida/current/source/main/population_cell.hh
diff -u avida/current/source/main/population_cell.hh:1.7 avida/current/source/main/population_cell.hh:1.8
--- avida/current/source/main/population_cell.hh:1.7	Sat May 17 02:48:10 2003
+++ avida/current/source/main/population_cell.hh	Wed Jul 16 19:36:55 2003
@@ -52,7 +52,8 @@
   const cMutationRates & MutationRates() const { return mutation_rates; }
   cMutationRates & MutationRates() { return mutation_rates; }
   int GetInput();
-  int GetInput(int id);
+  int GetInput(int);
+  int GetInputAt(int & input_pointer);
 
   int GetID() const { return cell_id; }
   int GetOrganismCount() const { return organism_count; }
Index: avida/current/source/tools/Makefile.am
diff -u avida/current/source/tools/Makefile.am:1.17 avida/current/source/tools/Makefile.am:1.18
--- avida/current/source/tools/Makefile.am:1.17	Thu May 22 11:58:54 2003
+++ avida/current/source/tools/Makefile.am	Wed Jul 16 19:36:55 2003
@@ -10,6 +10,7 @@
 		message_display.cc	message_display.hh	\
     message_display_hdrs.hh \
 		merit.cc	merit.hh	\
+		message.cc	message.hh      \
 		random.cc	random.hh	\
 		slice.cc	slice.hh	\
 		stat.cc		stat.hh         \
Index: avida/current/source/viewers/Makefile.am
diff -u avida/current/source/viewers/Makefile.am:1.15 avida/current/source/viewers/Makefile.am:1.16
--- avida/current/source/viewers/Makefile.am:1.15	Thu May 22 11:58:54 2003
+++ avida/current/source/viewers/Makefile.am	Wed Jul 16 19:36:55 2003
@@ -5,6 +5,7 @@
 
 viewer_SOURCES = ansi.cc		ansi.hh			\
 		bar_screen.cc		bar_screen.hh		\
+		environment_screen.cc	environment_screen.hh	\
 		hist_screen.cc		hist_screen.hh		\
 		map_screen.cc		map_screen.hh		\
 		menu.cc			menu.hh			\
Index: avida/current/source/viewers/bar_screen.cc
diff -u avida/current/source/viewers/bar_screen.cc:1.7 avida/current/source/viewers/bar_screen.cc:1.8
--- avida/current/source/viewers/bar_screen.cc:1.7	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/bar_screen.cc	Wed Jul 16 19:36:55 2003
@@ -7,6 +7,7 @@
 
 #include "../main/population.hh"
 #include "../main/stats.hh"
+#include "../main/environment.hh"
 
 #include "bar_screen.hh"
 
@@ -23,21 +24,39 @@
   SetBoldColor(COLOR_WHITE);
 
   Box();
-  VLine(19);
-  VLine(Width() - 14);
+  VLine(18);
+  
 
-  int offset = 7 + (prog_name.GetSize() + 1) / 2;
+  int offset = prog_name.GetSize() + 4;
+  VLine(Width() - offset - 2);
   Print(1, Width() - offset, "%s", prog_name());
 
-  Print(1, 3, "Update:");
-  Print(1, 22, "[M]ap  [S]tats  [O]ptions  [Z]oom  [Q]uit");
+  Print(1, 2, "Update:");
+
+  if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+    Print(1, 20, "[M]ap [S]tats [O]ptions [Z]oom [E]nviron [Q]uit");
+  else
+    Print(1, 20, "[M]ap  [S]tats  [O]ptions  [Z]oom  [Q]uit");
 
   SetBoldColor(COLOR_CYAN);
-  Print(1, 23, 'M');
-  Print(1, 30, 'S');
-  Print(1, 39, 'O');
-  Print(1, 50, 'Z');
-  Print(1, 58, 'Q');
+
+  if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+    {
+      Print(1, 21, 'M');
+      Print(1, 27, 'S');
+      Print(1, 35, 'O');
+      Print(1, 45, 'Z');
+      Print(1, 52, 'E');
+      Print(1, 62, 'Q');
+    }
+  else
+    {
+      Print(1, 21, 'M');
+      Print(1, 28, 'S');
+      Print(1, 37, 'O');
+      Print(1, 48, 'Z');
+      Print(1, 56, 'Q');
+    }
 
   Refresh();
 }
Index: avida/current/source/viewers/map_screen.cc
diff -u avida/current/source/viewers/map_screen.cc:1.10 avida/current/source/viewers/map_screen.cc:1.11
--- avida/current/source/viewers/map_screen.cc:1.10	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/map_screen.cc	Wed Jul 16 19:36:55 2003
@@ -24,7 +24,6 @@
 cMapScreen::cMapScreen(int _y_size, int _x_size, int _y_start,
       int _x_start, cViewInfo & in_info, cPopulation & in_pop) :
   cScreen(_y_size, _x_size, _y_start, _x_start, in_info),
-  mode(MAP_BASIC),
   x_size(in_pop.GetWorldX()),
   y_size(in_pop.GetWorldY()),
   population(in_pop)
@@ -37,6 +36,12 @@
 {
 }
 
+void cMapScreen::Draw()
+{
+  CenterActiveCPU();
+  Update();
+ 
+}
 void cMapScreen::Update()
 {
   // Get working in multiple modes!!
@@ -45,17 +50,17 @@
 
   const int name_x = Width() - 20;
   const int name_y = Height() - 1;
-  if (mode == MAP_BASIC)           Print(name_y, name_x, " Genotype View ");
-  else if (mode == MAP_SPECIES)    Print(name_y, name_x, " Species View  ");
-  else if (mode == MAP_COMBO)      Print(name_y, name_x, "  Combo View   ");
-  else if (mode == MAP_INJECT)     Print(name_y, name_x, " Modified View ");
-  else if (mode == MAP_RESOURCE)   Print(name_y, name_x, " Resource View ");
-  else if (mode == MAP_AGE)        Print(name_y, name_x, "   Age View    ");
-  else if (mode == MAP_BREED_TRUE) Print(name_y, name_x, "Breed True View");
-  else if (mode == MAP_PARASITE)   Print(name_y, name_x, " Parasite View ");
-  else if (mode == MAP_MUTATIONS)  Print(name_y, name_x, " Mutation View ");
-  else if (mode == MAP_THREAD)     Print(name_y, name_x, "  Thread View  ");
-  else if (mode == MAP_LINEAGE)    Print(name_y, name_x, " Lineage View  ");
+  if (info.GetMapMode() == MAP_BASIC)           Print(name_y, name_x, " Genotype View ");
+  else if (info.GetMapMode() == MAP_SPECIES)    Print(name_y, name_x, " Species View  ");
+  else if (info.GetMapMode() == MAP_COMBO)      Print(name_y, name_x, "  Combo View   ");
+  else if (info.GetMapMode() == MAP_INJECT)     Print(name_y, name_x, " Modified View ");
+  else if (info.GetMapMode() == MAP_RESOURCE)   Print(name_y, name_x, " Resource View ");
+  else if (info.GetMapMode() == MAP_AGE)        Print(name_y, name_x, "   Age View    ");
+  else if (info.GetMapMode() == MAP_BREED_TRUE) Print(name_y, name_x, "Breed True View");
+  else if (info.GetMapMode() == MAP_PARASITE)   Print(name_y, name_x, " Parasite View ");
+  else if (info.GetMapMode() == MAP_MUTATIONS)  Print(name_y, name_x, " Mutation View ");
+  else if (info.GetMapMode() == MAP_THREAD)     Print(name_y, name_x, "  Thread View  ");
+  else if (info.GetMapMode() == MAP_LINEAGE)    Print(name_y, name_x, " Lineage View  ");
 
 
   // Draw the [<] and [>] around the map mode....
@@ -76,7 +81,7 @@
   int virtual_x = corner_id % x_size;
   int virtual_y = corner_id / x_size;
 
-  info.SetupSymbolMaps(mode, HasColors());
+  info.SetupSymbolMaps(info.GetMapMode(), HasColors());
 
   for (int y = 0; y < Height() - 1 && y < y_size; y++) {
     Move(y, 0);
@@ -128,13 +133,15 @@
     break;
   case '>':
   case '.':
-    ++mode %= NUM_MAPS;
+    info.IncMapMode();
+    //++map_mode %= NUM_MAPS;
     Update();
     break;
   case '<':
   case ',':
-    mode += NUM_MAPS;
-    --mode %= NUM_MAPS;
+    info.DecMapMode();
+    //map_mode += NUM_MAPS;
+    //--map_mode %= NUM_MAPS;
     Update();
     break;
   }
Index: avida/current/source/viewers/map_screen.hh
diff -u avida/current/source/viewers/map_screen.hh:1.7 avida/current/source/viewers/map_screen.hh:1.8
--- avida/current/source/viewers/map_screen.hh:1.7	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/map_screen.hh	Wed Jul 16 19:36:55 2003
@@ -14,7 +14,7 @@
 
 class cMapScreen : public cScreen {
 private:
-  int mode;
+  //int mode;
 
   int x_size;
   int y_size;
@@ -33,7 +33,7 @@
   ~cMapScreen();
 
   // Virtual in base screen!
-  void Draw() { ; }
+  void Draw();
   void Update();
   void DoInput(int in_char);
 
Index: avida/current/source/viewers/symbol_util.cc
diff -u avida/current/source/viewers/symbol_util.cc:1.4 avida/current/source/viewers/symbol_util.cc:1.5
--- avida/current/source/viewers/symbol_util.cc:1.4	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/symbol_util.cc	Wed Jul 16 19:36:55 2003
@@ -13,7 +13,10 @@
 #include "../main/organism.hh"
 #include "../main/population_cell.hh"
 #include "../main/species.hh"
-
+#include "../main/config.hh"
+#include "../cpu/hardware_base.hh"
+#include "../cpu/hardware_4stack.hh"
+#include "../cpu/hardware_cpu.hh"
 
 using namespace std;
 
@@ -112,8 +115,23 @@
 //    if (thread_count < 20) return 'X';
 //    if (thread_count < 80) return 'L';
 //    if (thread_count < 200) return 'C';
-  
-  return '+';
+  //const cHardwareBase * hardware; 
+  int num_threads;
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      //const cHardwareCPU & hard_cpu= (cHardwareCPU &) cell.GetOrganism()->GetHardware();
+      //num_threads = hard_cpu.GetNumThreads();
+      num_threads = ((cHardwareCPU &) cell.GetOrganism()->GetHardware()).GetNumThreads();
+      return (char) ('0' + num_threads);
+    }
+  else
+    {
+      //const cHardware4Stack & hard_4stack= (cHardware4Stack &) cell.GetOrganism()->GetHardware();
+      //num_threads = hard_4stack.GetNumThreads();
+      num_threads = ((cHardware4Stack &) cell.GetOrganism()->GetHardware()).GetNumThreads();
+      return (char) ('0' + num_threads);
+    }
+  //return '+';
 }
 
 char cSymbolUtil::GetLineageSymbol(const cPopulationCell & cell)
Index: avida/current/source/viewers/text_screen.cc
diff -u avida/current/source/viewers/text_screen.cc:1.12 avida/current/source/viewers/text_screen.cc:1.13
--- avida/current/source/viewers/text_screen.cc:1.12	Sat May 17 14:23:26 2003
+++ avida/current/source/viewers/text_screen.cc	Wed Jul 16 19:36:55 2003
@@ -28,6 +28,7 @@
   saved_inst_set = NULL;
   thread_lock = -1;
   step_organism_id = -1;
+  map_mode=0;
 
   // Handle genotype & species managing...
 
@@ -81,7 +82,8 @@
     map_method = &cSymbolUtil::GetSpeciesSymbol;
     break;
   case MAP_INJECT:
-    map_method = &cSymbolUtil::GetModifiedSymbol;
+    if (use_color) color_method = &cSymbolUtil::GetModifiedSymbol;
+    else map_method = &cSymbolUtil::GetModifiedSymbol;
     break;
   case MAP_RESOURCE:
     map_method = &cSymbolUtil::GetResourceSymbol;
@@ -102,8 +104,8 @@
     else map_method = &cSymbolUtil::GetMutSymbol;
     break;
   case MAP_THREAD:
-    if (use_color) color_method = &cSymbolUtil::GetThreadSymbol;
-    else map_method = &cSymbolUtil::GetThreadSymbol;
+    //if (use_color) color_method = &cSymbolUtil::GetThreadSymbol;
+    map_method = &cSymbolUtil::GetThreadSymbol;
     break;
   case MAP_LINEAGE:
     if (use_color) color_method = &cSymbolUtil::GetLineageSymbol;
Index: avida/current/source/viewers/text_screen.hh
diff -u avida/current/source/viewers/text_screen.hh:1.10 avida/current/source/viewers/text_screen.hh:1.11
--- avida/current/source/viewers/text_screen.hh:1.10	Sat May 17 14:54:55 2003
+++ avida/current/source/viewers/text_screen.hh	Wed Jul 16 19:36:55 2003
@@ -59,6 +59,7 @@
   int pause_level;
   int thread_lock;
   int step_organism_id;
+  int map_mode;
 
   // Instruction Libraries.
   cInstSet const * saved_inst_set;
@@ -86,7 +87,10 @@
   tArray<char> & GetColorMap() { return color_map; }
   char & MapSymbol(int pos) { return map[pos]; }
   char & ColorSymbol(int pos) { return color_map[pos]; }
-
+  int GetMapMode() { return map_mode; }
+  void IncMapMode() { ++map_mode%=NUM_MAPS; }
+  void DecMapMode();
+    
   void EngageStepMode();
   void DisEngageStepMode();
 
@@ -144,6 +148,12 @@
 ///////////////
 //  cViewInfo
 ///////////////
+
+inline void cViewInfo::DecMapMode()
+{
+  map_mode+=NUM_MAPS; 
+  --map_mode %= NUM_MAPS; 
+}
 
 inline bool cViewInfo::InGenChart(cGenotype * in_gen)
 {
Index: avida/current/source/viewers/view.cc
diff -u avida/current/source/viewers/view.cc:1.10 avida/current/source/viewers/view.cc:1.11
--- avida/current/source/viewers/view.cc:1.10	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/view.cc	Wed Jul 16 19:36:55 2003
@@ -29,6 +29,7 @@
 #include "hist_screen.hh"
 #include "options_screen.hh"
 #include "zoom_screen.hh"
+#include "environment_screen.hh"
 
 
 using namespace std;
@@ -52,6 +53,7 @@
   hist_screen    = new cHistScreen    (0,0,3,0,info, in_population);
   options_screen = new cOptionsScreen (0,0,3,0,info);
   zoom_screen    = new cZoomScreen    (0,0,3,0,info, in_population);
+  environment_screen = new cEnvironmentScreen (0,0,3,0,info, in_population);
 
   info.SetActiveCell( &( in_population.GetCell(0) ) );
 }
@@ -63,6 +65,7 @@
   if (hist_screen) delete hist_screen;
   if (options_screen) delete options_screen;
   if (zoom_screen) delete zoom_screen;
+  if (environment_screen) delete environment_screen;
 
   EndProg(0);
 }
@@ -94,6 +97,8 @@
     cur_screen = options_screen;
   } else if (in_mode == MODE_ZOOM) {
     cur_screen = zoom_screen;
+  } else if (in_mode == MODE_ENVIRONMENT) {
+    cur_screen = environment_screen;
   }
 }
 
@@ -233,6 +238,11 @@
     case 'p':
     case 'P':
       TogglePause();
+      break;
+    case 'e':
+    case 'E':
+      if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+	ChangeCurScreen(environment_screen);
       break;
     case 's':
     case 'S':
Index: avida/current/source/viewers/view.hh
diff -u avida/current/source/viewers/view.hh:1.9 avida/current/source/viewers/view.hh:1.10
--- avida/current/source/viewers/view.hh:1.9	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/view.hh	Wed Jul 16 19:36:55 2003
@@ -15,6 +15,7 @@
 #define MODE_HIST    3
 #define MODE_OPTIONS 4
 #define MODE_ZOOM    5
+#define MODE_ENVIRONMENT 6
 
 #include "text_screen.hh"
 
@@ -25,6 +26,7 @@
 class cHistScreen;
 class cOptionsScreen;
 class cZoomScreen;
+class cEnvironmentScreen;
 
 class cView {
 private:
@@ -34,12 +36,12 @@
   static cTextWindow * base_window;
   static cScreen * cur_screen;
   static cBarScreen * bar_screen;
-
   cMapScreen * map_screen;
   cStatsScreen * stats_screen;
   cHistScreen * hist_screen;
   cOptionsScreen * options_screen;
   cZoomScreen * zoom_screen;
+  cEnvironmentScreen * environment_screen;
 
   // Window managing functions...
 
Index: avida/current/source/viewers/zoom_screen.cc
diff -u avida/current/source/viewers/zoom_screen.cc:1.25 avida/current/source/viewers/zoom_screen.cc:1.26
--- avida/current/source/viewers/zoom_screen.cc:1.25	Thu Jun  5 13:14:42 2003
+++ avida/current/source/viewers/zoom_screen.cc	Wed Jul 16 19:36:55 2003
@@ -40,7 +40,7 @@
   memory_offset = 0;
   parasite_zoom = false;
   mode = ZOOM_MODE_STATS;
-  map_mode = MAP_BASIC;
+  //map_mode = MAP_BASIC;
   inst_view_mode = true;
   active_section = ZOOM_SECTION_MEMORY;
   task_offset = 0;
@@ -49,7 +49,7 @@
   cur_mem_space=0;
   cur_view_thread=0;
 
-  map_mode = MAP_BASIC;
+  //map_mode = MAP_BASIC;
   mini_center_id = 0;
   map_x_size = population.GetWorldX();
   map_y_size = population.GetWorldY();
@@ -80,7 +80,7 @@
   if (info.GetPauseLevel()) {
     Print(OPTIONS_Y+2, OPTIONS_X+6, "P");
     Print(OPTIONS_Y+3, OPTIONS_X+3, "N");
-    Print(OPTIONS_Y+4, OPTIONS_X+3, "Space");
+    //Print(OPTIONS_Y+4, OPTIONS_X+3, "Space");
   } else {
     Print(OPTIONS_Y+2, OPTIONS_X+3, "P");
   }
@@ -1435,6 +1435,7 @@
   return cCoords(0,0);
 }
 
+/*
 cString cZoomScreen::GetSectionName(int in_section)
 {
   switch (in_section) {
@@ -1474,6 +1475,47 @@
   }
 
   return cString("Unknown!");
+}*/
+
+char* cZoomScreen::GetSectionName(int in_section)
+{
+  switch (in_section) {
+  case ZOOM_SECTION_MEMORY:
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return "Memory";
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return "Memory Space";
+      }
+    break;
+
+  case ZOOM_SECTION_REGISTERS:
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return "Registers:";
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return "Stacks:";
+      }
+    break;
+
+  case ZOOM_SECTION_STACK:
+    return "Stack ";
+    break;
+
+  case ZOOM_SECTION_INPUTS:
+    return "Inputs:";
+    break;
+
+  case ZOOM_SECTION_MAP:
+    return "Mini-Map";
+    break;
+  }
+
+  return "Unknown!";
 }
 
 void cZoomScreen::SetActiveSection(int in_section)
@@ -1483,16 +1525,16 @@
     cCoords sect_coords(GetSectionCoords(active_section));
     sect_coords.Translate(2, 1);
     SetColor(COLOR_WHITE);
-    Print(sect_coords.GetY(), sect_coords.GetX(),
-	  GetSectionName(active_section)());
+    Print(sect_coords.GetY(), sect_coords.GetX(), "%s",
+	  GetSectionName(active_section));
     active_section = in_section;
   }
 
   cCoords sect_coords(GetSectionCoords(active_section));
   sect_coords.Translate(2, 1);
   SetBoldColor(COLOR_BLUE);
-  Print(sect_coords.GetY(), sect_coords.GetX(),
-	GetSectionName(active_section)());
+  Print(sect_coords.GetY(), sect_coords.GetX(), "%s",
+	GetSectionName(active_section));
   SetColor(COLOR_WHITE);
 }
 
@@ -1646,13 +1688,12 @@
     //break;
   case '+':
   case '=':
-    ++map_mode %= NUM_MAPS;
+    info.IncMapMode();
     Update();
     break;
   case '-':
   case '_':
-    map_mode += NUM_MAPS;
-    --map_mode %= NUM_MAPS;
+    info.DecMapMode();
     Update();
     break;
   case '\n':
@@ -1748,26 +1789,27 @@
 
   // Setup the start color for the map...
   SetColor(COLOR_WHITE);
+  mini_center_id = info.GetActiveCell()->GetID();
 
   const int name_x = MINI_MAP_X + 4;
   const int name_y = MINI_MAP_Y + 11;
-  if (mode == MAP_BASIC)           Print(name_y, name_x, "Genotypes");
-  else if (mode == MAP_SPECIES)    Print(name_y, name_x, " Species ");
-  else if (mode == MAP_COMBO)      Print(name_y, name_x, "  Combo  ");
-  else if (mode == MAP_INJECT)     Print(name_y, name_x, "Modified ");
-  else if (mode == MAP_RESOURCE)   Print(name_y, name_x, "Resources");
-  else if (mode == MAP_AGE)        Print(name_y, name_x, "   Age   ");
-  else if (mode == MAP_BREED_TRUE) Print(name_y, name_x, "BreedTrue");
-  else if (mode == MAP_PARASITE)   Print(name_y, name_x, "Parasites");
-  else if (mode == MAP_MUTATIONS)  Print(name_y, name_x, "Mutations");
-  else if (mode == MAP_THREAD)     Print(name_y, name_x, " Threads ");
-  else if (mode == MAP_LINEAGE)    Print(name_y, name_x, " Lineage ");
+  if (info.GetMapMode() == MAP_BASIC)           Print(name_y, name_x, "Genotypes");
+  else if (info.GetMapMode() == MAP_SPECIES)    Print(name_y, name_x, " Species ");
+  else if (info.GetMapMode() == MAP_COMBO)      Print(name_y, name_x, "  Combo  ");
+  else if (info.GetMapMode() == MAP_INJECT)     Print(name_y, name_x, "Modified ");
+  else if (info.GetMapMode() == MAP_RESOURCE)   Print(name_y, name_x, "Resources");
+  else if (info.GetMapMode() == MAP_AGE)        Print(name_y, name_x, "   Age   ");
+  else if (info.GetMapMode() == MAP_BREED_TRUE) Print(name_y, name_x, "BreedTrue");
+  else if (info.GetMapMode() == MAP_PARASITE)   Print(name_y, name_x, "Parasites");
+  else if (info.GetMapMode() == MAP_MUTATIONS)  Print(name_y, name_x, "Mutations");
+  else if (info.GetMapMode() == MAP_THREAD)     Print(name_y, name_x, " Threads ");
+  else if (info.GetMapMode() == MAP_LINEAGE)    Print(name_y, name_x, " Lineage ");
 
 
   int virtual_x = (mini_center_id % map_x_size) + map_x_size;
   int virtual_y = (mini_center_id / map_x_size) + map_y_size;
 
-  info.SetupSymbolMaps(mode, HasColors());
+  info.SetupSymbolMaps(info.GetMapMode(), HasColors());
 
   for (int y = -3; y <= 3 && y < map_y_size - 3; y++) {
     Move(MINI_MAP_Y + 6 + y, MINI_MAP_X + 2);
Index: avida/current/source/viewers/zoom_screen.hh
diff -u avida/current/source/viewers/zoom_screen.hh:1.8 avida/current/source/viewers/zoom_screen.hh:1.9
--- avida/current/source/viewers/zoom_screen.hh:1.8	Thu Jun  5 13:14:42 2003
+++ avida/current/source/viewers/zoom_screen.hh	Wed Jul 16 19:36:55 2003
@@ -66,7 +66,7 @@
   int map_y_size;
 
   int mode;
-  int map_mode;
+  //int map_mode;
   bool inst_view_mode;
   int memory_offset;
   bool parasite_zoom; // If true, then view original parasite code, not host
@@ -102,7 +102,8 @@
   void ViewThreads();
 
   cCoords GetSectionCoords(int in_section);
-  cString GetSectionName(int in_section);
+  //cString GetSectionName(int in_section);
+  char* GetSectionName(int in_section);
   void SetActiveSection(int in_section);
 
   void DrawMiniMap();


More information about the Avida-cvs mailing list