[Avida-cvs] [Avida2-svn] r300 - trunk/source/cpu

brysonda@myxo.css.msu.edu brysonda at myxo.css.msu.edu
Mon Aug 29 12:51:42 PDT 2005


Author: brysonda
Date: 2005-08-29 15:51:42 -0400 (Mon, 29 Aug 2005)
New Revision: 300

Added:
   trunk/source/cpu/cHardware4Stack.cc
   trunk/source/cpu/cHardware4Stack.h
   trunk/source/cpu/cHardware4Stack_Thread.cc
   trunk/source/cpu/cHardware4Stack_Thread.h
   trunk/source/cpu/cHardwareBase.cc
   trunk/source/cpu/cHardwareBase.h
   trunk/source/cpu/cHardwareCPU.cc
   trunk/source/cpu/cHardwareCPU.h
   trunk/source/cpu/cHardwareCPU_Thread.cc
   trunk/source/cpu/cHardwareCPU_Thread.h
   trunk/source/cpu/cHardwareFactory.cc
   trunk/source/cpu/cHardwareFactory.h
Removed:
   trunk/source/cpu/hardware_4stack.cc
   trunk/source/cpu/hardware_4stack.hh
   trunk/source/cpu/hardware_4stack_thread.cc
   trunk/source/cpu/hardware_4stack_thread.hh
   trunk/source/cpu/hardware_base.cc
   trunk/source/cpu/hardware_base.hh
   trunk/source/cpu/hardware_cpu.cc
   trunk/source/cpu/hardware_cpu.hh
   trunk/source/cpu/hardware_cpu_thread.cc
   trunk/source/cpu/hardware_cpu_thread.hh
   trunk/source/cpu/hardware_factory.cc
   trunk/source/cpu/hardware_factory.hh
Modified:
   trunk/source/cpu/CMakeLists.txt
   trunk/source/cpu/cpu.pri
   trunk/source/cpu/hardware_smt.h
   trunk/source/cpu/hardware_status_printer.cc
   trunk/source/cpu/hardware_util.cc
   trunk/source/cpu/head_cpu.cc
   trunk/source/cpu/head_multi_mem.cc
   trunk/source/cpu/inst_lib_cpu.hh
   trunk/source/cpu/test_cpu.cc
   trunk/source/cpu/test_util.cc
Log:
Rename cpu/cHardwareCPU,cHardware4Stack,cHardwareBase,cHardwareFactory classes to reflect new naming conventions.

Modified: trunk/source/cpu/CMakeLists.txt
===================================================================
--- trunk/source/cpu/CMakeLists.txt	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/CMakeLists.txt	2005-08-29 19:51:42 UTC (rev 300)
@@ -3,12 +3,12 @@
   cCPUMemory.cc
   cCPUStack.cc
   cCPUTestInfo.cc
-  hardware_4stack.cc
-  hardware_4stack_thread.cc
-  hardware_base.cc
-  hardware_cpu.cc
-  hardware_cpu_thread.cc
-  hardware_factory.cc
+  cHardware4Stack.cc
+  cHardware4Stack_Thread.cc
+  cHardwareBase.cc
+  cHardwareCPU.cc
+  cHardwareCPU_Thread.cc
+  cHardwareFactory.cc
   hardware_smt.cc
   hardware_smt_thread.cc
   hardware_status_printer.cc

Copied: trunk/source/cpu/cHardware4Stack.cc (from rev 299, trunk/source/cpu/hardware_4stack.cc)
===================================================================
--- trunk/source/cpu/hardware_4stack.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/cHardware4Stack.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,2306 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+#include "cHardware4Stack.h"
+
+#include "config.hh"
+#include "cCPUTestInfo.h"
+#include "functions.hh"
+#include "genome_util.hh"
+#include "inst_lib_base.hh"
+#include "inst_set.hh"
+#include "hardware_tracer.hh"
+#include "hardware_tracer_4stack.hh"
+#include "mutation.hh"
+#include "mutation_lib.hh"
+#include "mutation_macros.hh"
+#include "organism.hh"
+#include "phenotype.hh"
+#include "random.hh"
+#include "string_util.hh"
+#include "test_cpu.hh"
+
+#include <limits.h>
+
+using namespace std;
+
+
+
+
+///////////////
+//  cInstLib4Stack
+///////////////
+
+class cInstLib4Stack : public cInstLibBase {
+  const size_t m_nopmods_array_size;
+  const size_t m_function_array_size;
+  cString *m_nopmod_names;
+  cString *m_function_names;
+  const int *m_nopmods;
+  cHardware4Stack::tHardware4StackMethod *m_functions;
+  static const cInstruction inst_error;
+  static const cInstruction inst_default;
+public:
+  cInstLib4Stack(
+    size_t nopmod_array_size,
+    size_t function_array_size,
+    cString *nopmod_names,
+    cString *function_names,
+    const int *nopmods,
+    cHardware4Stack::tHardware4StackMethod *functions
+  ):m_nopmods_array_size(nopmod_array_size),
+    m_function_array_size(function_array_size),
+    m_nopmod_names(nopmod_names),
+    m_function_names(function_names),
+    m_nopmods(nopmods),
+    m_functions(functions)
+  {}
+  cHardware4Stack::tHardware4StackMethod *GetFunctions(void){ return m_functions; } 
+  const cString &GetName(const unsigned int id) {
+    assert(id < m_function_array_size);
+    return m_function_names[id];
+  }
+  const cString &GetNopName(const unsigned int id) {
+    assert(id < m_nopmods_array_size);
+    return m_nopmod_names[id];
+  }
+  int GetNopMod(const unsigned int id){
+    assert(id < m_nopmods_array_size);
+    return m_nopmods[id];
+  }
+  int GetNopMod(const cInstruction & inst){
+    return GetNopMod(inst.GetOp());
+  }
+  int GetSize(){ return m_function_array_size; }
+  int GetNumNops(){ return m_nopmods_array_size; }
+  cInstruction GetInst(const cString & in_name){
+    for (unsigned int i = 0; i < m_function_array_size; i++) {
+      if (m_function_names[i] == in_name) return cInstruction(i);
+    }
+    return cInstLib4Stack::GetInstError();
+  }
+  const cInstruction & GetInstDefault(){ return inst_default; }
+  const cInstruction & GetInstError(){ return inst_error; }
+};
+
+///////////////
+//  cHardware4Stack
+///////////////
+
+const cInstruction cInstLib4Stack::inst_error(255);
+const cInstruction cInstLib4Stack::inst_default(0);
+cInstLibBase *cHardware4Stack::GetInstLib(){ return s_inst_slib; }
+
+cInstLib4Stack *cHardware4Stack::s_inst_slib = cHardware4Stack::initInstLib();
+cInstLib4Stack *cHardware4Stack::initInstLib(void){
+  struct cNOPEntry4Stack {
+    cNOPEntry4Stack(const cString &name, int nop_mod):name(name), nop_mod(nop_mod){}
+    cString name;
+    int nop_mod;
+  };
+  static const cNOPEntry4Stack s_n_array[] = {
+    cNOPEntry4Stack("Nop-A", STACK_AX),
+    cNOPEntry4Stack("Nop-B", STACK_BX),
+    cNOPEntry4Stack("Nop-C", STACK_CX),
+    cNOPEntry4Stack("Nop-D", STACK_DX),
+    cNOPEntry4Stack("Nop-E", STACK_EX),
+    cNOPEntry4Stack("Nop-F", STACK_FX)
+  };
+
+  struct cInstEntry4Stack {
+    cInstEntry4Stack(const cString &name, tHardware4StackMethod function):name(name), function(function){}
+    cString name;
+    tHardware4StackMethod function;
+  };
+  static const cInstEntry4Stack s_f_array[] = {
+    //1 
+    cInstEntry4Stack("Nop-A",     &cHardware4Stack::Inst_Nop), 
+    //2
+    cInstEntry4Stack("Nop-B",     &cHardware4Stack::Inst_Nop), 
+    //3
+    cInstEntry4Stack("Nop-C",     &cHardware4Stack::Inst_Nop),   
+    //4 
+    cInstEntry4Stack("Nop-D",     &cHardware4Stack::Inst_Nop), 
+    //38
+    cInstEntry4Stack("Nop-E",     &cHardware4Stack::Inst_Nop),
+    //39
+    cInstEntry4Stack("Nop-F",     &cHardware4Stack::Inst_Nop),
+    //5
+    cInstEntry4Stack("Nop-X",     &cHardware4Stack::Inst_Nop),
+    //6 
+    cInstEntry4Stack("Val-Shift-R",   &cHardware4Stack::Inst_ShiftR),
+    //7
+    cInstEntry4Stack("Val-Shift-L",   &cHardware4Stack::Inst_ShiftL),
+    //8
+    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Val_Nand),
+    //9
+    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Val_Add),
+    //10
+    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Val_Sub),
+    //11
+    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Val_Mult),
+    //12
+    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Val_Div),
+    //13
+    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_SetMemory),
+    //14
+    cInstEntry4Stack("Divide",  &cHardware4Stack::Inst_Divide),
+    //15
+    cInstEntry4Stack("Inst-Read",    &cHardware4Stack::Inst_HeadRead),
+    //16
+    cInstEntry4Stack("Inst-Write",   &cHardware4Stack::Inst_HeadWrite),
+    //keeping this one for the transition period
+    //cInstEntry4Stack("Inst-Copy",    &cHardware4Stack::Inst_HeadCopy),
+    //17
+    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqual),
+    //18
+    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNotEqual),
+    //19
+    cInstEntry4Stack("If-Less",   &cHardware4Stack::Inst_IfLess),
+    //20
+    cInstEntry4Stack("If-Greater",    &cHardware4Stack::Inst_IfGreater),
+    //21
+    cInstEntry4Stack("Head-Push",    &cHardware4Stack::Inst_HeadPush),
+    //22
+    cInstEntry4Stack("Head-Pop",     &cHardware4Stack::Inst_HeadPop),
+    //23
+    cInstEntry4Stack("Head-Move",  &cHardware4Stack::Inst_HeadMove),
+    //24
+    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_Search),
+    //25
+    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushNext),
+    //26
+    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushPrevious),
+    //27
+    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushComplement),
+    //28
+    cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete),
+    //29
+    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_ValCopy),
+    //30
+    cInstEntry4Stack("ThreadFork",   &cHardware4Stack::Inst_ForkThread),
+    //31
+    //cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
+    //32
+    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Increment),
+    //33
+    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Decrement),
+    //34
+    cInstEntry4Stack("Val-Mod",       &cHardware4Stack::Inst_Mod),
+    //35
+    cInstEntry4Stack("ThreadKill",   &cHardware4Stack::Inst_KillThread),
+    //36
+    cInstEntry4Stack("IO", &cHardware4Stack::Inst_IO),
+    //37
+    cInstEntry4Stack("Inject", &cHardware4Stack::Inst_Inject)
+  };
+
+  const int n_size = sizeof(s_n_array)/sizeof(cNOPEntry4Stack);
+
+  static cString n_names[n_size];
+  static int nop_mods[n_size];
+  for (int i = 0; i < n_size; i++){
+    n_names[i] = s_n_array[i].name;
+    nop_mods[i] = s_n_array[i].nop_mod;
+  }
+
+  const int f_size = sizeof(s_f_array)/sizeof(cInstEntry4Stack);
+  static cString f_names[f_size];
+  static tHardware4StackMethod functions[f_size];
+  for (int i = 0; i < f_size; i++){
+    f_names[i] = s_f_array[i].name;
+    functions[i] = s_f_array[i].function;
+  }
+
+  cInstLib4Stack *inst_lib = new cInstLib4Stack(
+    n_size,
+    f_size,
+    n_names,
+    f_names,
+    nop_mods,
+    functions
+  );
+
+  return inst_lib;
+}
+
+cHardware4Stack::cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set)
+  : cHardwareBase(in_organism, in_inst_set)
+  , memory_array(NUM_MEMORY_SPACES)
+{
+  /* 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...
+}
+
+
+cHardware4Stack::cHardware4Stack(const cHardware4Stack &hardware_4stack)
+: cHardwareBase(hardware_4stack.organism, hardware_4stack.inst_set)
+, m_functions(hardware_4stack.m_functions)
+, memory_array(hardware_4stack.memory_array)
+, threads(hardware_4stack.threads)
+, thread_id_chart(hardware_4stack.thread_id_chart)
+, cur_thread(hardware_4stack.cur_thread)
+, mal_active(hardware_4stack.mal_active)
+, inst_cost(hardware_4stack.inst_cost)
+#ifdef INSTRUCTION_COSTS
+, inst_ft_cost(hardware_4stack.inst_ft_cost)
+, inst_remainder(hardware_4stack.inst_remainder)
+#endif
+{
+  for(int i = 0; i < NUM_GLOBAL_STACKS; i++){
+    global_stacks[i] = hardware_4stack.global_stacks[i];
+  }
+  for(int i = 0; i < sizeof(slice_array)/sizeof(float); i++){
+    slice_array[i] = hardware_4stack.slice_array[i];
+  }
+}
+
+
+void cHardware4Stack::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
+{
+  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();
+}
+
+
+void cHardware4Stack::Reset()
+{
+  //global_stack.Clear();
+  //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)=cGenome(ConvertToInstruction(i)); 
+  }
+
+  // We want to reset to have a single thread.
+  threads.Resize(1);
+
+  // Reset that single thread.
+  threads[0].Reset(this, 0);
+  thread_id_chart = 1; // Mark only the first thread as taken...
+  cur_thread = 0;
+
+  mal_active = false;
+
+  // Reset all stacks (local and global)
+  for(int i=0; i<NUM_STACKS; i++)
+    {
+      Stack(i).Clear();
+    }
+
+#ifdef INSTRUCTION_COSTS
+  // instruction cost arrays
+  const int num_inst_cost = GetNumInst();
+  inst_cost.Resize(num_inst_cost);
+  inst_ft_cost.Resize(num_inst_cost);
+
+  for (int i = 0; i < num_inst_cost; i++) {
+    inst_cost[i] = GetInstSet().GetCost(cInstruction(i));
+    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
+  }
+#endif
+
+}
+
+// This function processes the very next command in the genome, and is made
+// to be as optimized as possible.  This is the heart of avida.
+
+void cHardware4Stack::SingleProcess()
+{
+  // Mark this organism as running...
+  organism->SetRunning(true);
+
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.IncTimeUsed();
+  //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 = 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();
+    AdvanceIP() = true;
+    IP().Adjust();
+
+#ifdef BREAKPOINTS
+    if (IP().FlagBreakpoint() == true) {
+      organism->DoBreakpoint();
+    }
+#endif
+    
+    // Print the status of this CPU at each step...
+    if (m_tracer != NULL) {
+      if (cHardwareTracer_4Stack * tracer
+          = dynamic_cast<cHardwareTracer_4Stack *>(m_tracer)
+      ){
+        tracer->TraceHardware_4Stack(*this);
+      }
+    }
+    
+    // Find the instruction to be executed
+    const cInstruction & cur_inst = IP().GetInst();
+
+    // Test if costs have been paid and it is okay to execute this now...
+    const bool exec = SingleProcess_PayCosts(cur_inst);
+
+    // Now execute the instruction...
+    if (exec == true) {
+      SingleProcess_ExecuteInst(cur_inst);
+
+      // Some instruction (such as jump) may turn advance_ip off.  Ususally
+      // we now want to move to the next instruction in the memory.
+      if (AdvanceIP() == true) IP().Advance();
+    } // if exec
+    
+  } // Previous was executed once for each thread...
+
+  // Kill creatures who have reached their max num of instructions executed
+  const int max_executed = organism->GetMaxExecuted();
+  if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
+      || phenotype.GetToDie()) {
+    organism->Die();
+  }
+
+  organism->SetRunning(false);
+}
+
+// This method will test to see if all costs have been paid associated
+// with executing an instruction and only return true when that instruction
+// should proceed.
+bool cHardware4Stack::SingleProcess_PayCosts(const cInstruction & cur_inst)
+{
+#ifdef INSTRUCTION_COSTS
+  assert(cur_inst.GetOp() < inst_cost.GetSize());
+
+  // If first time cost hasn't been paid off...
+  if ( inst_ft_cost[cur_inst.GetOp()] > 0 ) {
+    inst_ft_cost[cur_inst.GetOp()]--;       // dec cost
+    return false;
+  }
+    
+  // Next, look at the per use cost
+  if ( GetInstSet().GetCost(cur_inst) > 0 ) {
+    if ( inst_cost[cur_inst.GetOp()] > 1 ){  // if isn't paid off (>1)
+      inst_cost[cur_inst.GetOp()]--;         // dec cost
+      return false;
+    } else {                                 // else, reset cost array
+      inst_cost[cur_inst.GetOp()] = GetInstSet().GetCost(cur_inst);
+    }
+  }
+    
+  // Prob of exec
+  if ( GetInstSet().GetProbFail(cur_inst) > 0.0 ){
+    return !( g_random.P(GetInstSet().GetProbFail(cur_inst)) );
+  }
+#endif
+  return true;
+}
+
+// This method will handle the actuall execution of an instruction
+// within single process, once that function has been finalized.
+bool cHardware4Stack::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
+{
+  // Copy Instruction locally to handle stochastic effects
+  cInstruction actual_inst = cur_inst;
+  
+#ifdef EXECUTION_ERRORS
+  // If there is an execution error, execute a random instruction.
+  if (organism->TestExeErr()) actual_inst = GetInstSet().GetRandomInst();
+#endif /* EXECUTION_ERRORS */
+
+  // Get a pointer to the corrisponding method...
+  int inst_idx = GetInstSet().GetLibFunctionIndex(actual_inst);
+  
+  // Mark the instruction as executed
+  IP().FlagExecuted() = true;
+	
+
+#ifdef INSTRUCTION_COUNT
+  // instruction execution count incremeneted
+  organism->GetPhenotype().IncCurInstCount(actual_inst.GetOp());
+#endif
+	
+  // And execute it.
+  const bool exec_success = (this->*(m_functions[inst_idx]))();
+	
+#ifdef INSTRUCTION_COUNT
+  // decremenet if the instruction was not executed successfully
+  if (exec_success == false) {
+    organism->GetPhenotype().DecCurInstCount(actual_inst.GetOp());
+  }
+#endif	
+
+  return exec_success;
+}
+
+
+void cHardware4Stack::ProcessBonusInst(const cInstruction & inst)
+{
+  // Mark this organism as running...
+  bool prev_run_state = organism->GetIsRunning();
+  organism->SetRunning(true);
+
+  // @CAO FIX PRINTING TO INDICATE THIS IS A BONUS
+  // Print the status of this CPU at each step...
+  if (m_tracer != NULL) {
+    if (cHardwareTracer_4Stack * tracer
+        = dynamic_cast<cHardwareTracer_4Stack *>(m_tracer)
+    ){
+      tracer->TraceHardware_4StackBonus(*this);
+    }
+  }
+    
+  SingleProcess_ExecuteInst(inst);
+
+  organism->SetRunning(prev_run_state);
+}
+
+
+void cHardware4Stack::LoadGenome(const cGenome & new_genome)
+{
+  GetMemory(0) = new_genome;
+}
+
+
+bool cHardware4Stack::OK()
+{
+  bool result = true;
+
+  for(int i = 0 ; i < NUM_MEMORY_SPACES; i++) {
+    if (!memory_array[i].OK()) result = false;
+  }
+
+  for (int i = 0; i < GetNumThreads(); i++) {
+    for(int j=0; j<NUM_LOCAL_STACKS; j++)
+    if (threads[i].local_stacks[j].OK() == false) result = false;
+    if (threads[i].next_label.OK() == false) result = false;
+  }
+
+  return result;
+}
+
+void cHardware4Stack::PrintStatus(ostream & fp)
+{
+  fp << organism->GetPhenotype().GetTimeUsed() << " "
+     << "IP:(" << IP().GetMemSpace() << ", " << IP().GetPosition() << ")    "
+
+     << "AX:" << Stack(STACK_AX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_AX).Top() << "]  " << setbase(10)
+
+     << "BX:" << Stack(STACK_BX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_BX).Top() << "]  " << setbase(10)
+
+     << "CX:" << Stack(STACK_CX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_CX).Top() << "]  " << setbase(10)
+
+     << "DX:" << Stack(STACK_DX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_DX).Top() << "]  " << setbase(10)
+
+     << endl;
+
+  fp << "  R-Head:(" << GetHead(HEAD_READ).GetMemSpace() << ", " 
+     << GetHead(HEAD_READ).GetPosition() << ")  " 
+     << "W-Head:(" << GetHead(HEAD_WRITE).GetMemSpace()  << ", "
+     << GetHead(HEAD_WRITE).GetPosition() << ")  "
+     << "F-Head:(" << GetHead(HEAD_FLOW).GetMemSpace()   << ",  "
+     << GetHead(HEAD_FLOW).GetPosition() << ")  "
+     << "RL:" << GetReadLabel().AsString() << "   "
+     << endl;
+
+  fp << "  Mem (" << GetMemory(0).GetSize() << "):"
+		  << "  " << GetMemory(0).AsString()
+		  << endl;
+  fp << "       " << GetMemory(1).GetSize() << "):"
+		  << "  " << GetMemory(1).AsString()
+		  << endl;
+  fp << "       " << GetMemory(2).GetSize() << "):"
+		  << "  " << GetMemory(2).AsString()
+		  << endl;
+  fp << "       " << GetMemory(3).GetSize() << "):"
+		  << "  " << GetMemory(3).AsString()
+		  << endl;
+  
+  
+  fp.flush();
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////
+// Method: cHardware4Stack::FindLabel(direction)
+//
+// Search in 'direction' (+ or - 1) from the instruction pointer for the
+// compliment of the label in 'next_label' and return a pointer to the
+// results.  If direction is 0, search from the beginning of the genome.
+//
+/////////////////////////////////////////////////////////////////////////
+
+cHeadMultiMem cHardware4Stack::FindLabel(int direction)
+{
+  cHeadMultiMem & inst_ptr = IP();
+
+  // Start up a search head at the position of the instruction pointer.
+  cHeadMultiMem search_head(inst_ptr);
+  cCodeLabel & search_label = GetLabel();
+
+  // Make sure the label is of size  > 0.
+
+  if (search_label.GetSize() == 0) {
+    return inst_ptr;
+  }
+
+  // Call special functions depending on if jump is forwards or backwards.
+  int found_pos = 0;
+  if( direction < 0 ) {
+    found_pos = FindLabel_Backward(search_label, inst_ptr.GetMemory(),
+			   inst_ptr.GetPosition() - search_label.GetSize());
+  }
+
+  // Jump forward.
+  else if (direction > 0) {
+    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(),
+			   inst_ptr.GetPosition());
+  }
+
+  // Jump forward from the very beginning.
+  else {
+    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(), 0);
+  }
+  
+  // Return the last line of the found label, if it was found.
+  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;
+}
+
+
+// Search forwards for search_label from _after_ position pos in the
+// memory.  Return the first line _after_ the the found label.  It is okay
+// to find search label's match inside another label.
+
+int cHardware4Stack::FindLabel_Forward(const cCodeLabel & search_label,
+				 const cGenome & search_genome, int pos)
+{
+  assert (pos < search_genome.GetSize() && pos >= 0);
+
+  int search_start = pos;
+  int label_size = search_label.GetSize();
+  bool found_label = false;
+
+  // Move off the template we are on.
+  pos += label_size;
+
+  // Search until we find the complement or exit the memory.
+  while (pos < search_genome.GetSize()) {
+
+    // If we are within a label, rewind to the beginning of it and see if
+    // it has the proper sub-label that we're looking for.
+
+    if (inst_set->IsNop(search_genome[pos])) {
+      // Find the start and end of the label we're in the middle of.
+
+      int start_pos = pos;
+      int end_pos = pos + 1;
+      while (start_pos > search_start &&
+	     inst_set->IsNop( search_genome[start_pos - 1] )) {
+	start_pos--;
+      }
+      while (end_pos < search_genome.GetSize() &&
+	     inst_set->IsNop( search_genome[end_pos] )) {
+	end_pos++;
+      }
+      int test_size = end_pos - start_pos;
+
+      // See if this label has the proper sub-label within it.
+      int max_offset = test_size - label_size + 1;
+      int offset = start_pos;
+      for (offset = start_pos; offset < start_pos + max_offset; offset++) {
+
+	// Test the number of matches for this offset.
+	int matches;
+	for (matches = 0; matches < label_size; matches++) {
+	  if (search_label[matches] !=
+	      inst_set->GetNopMod( search_genome[offset + matches] )) {
+	    break;
+	  }
+	}
+
+	// If we have found it, break out of this loop!
+	if (matches == label_size) {
+	  found_label = true;
+	  break;
+	}
+      }
+
+      // If we've found the complement label, set the position to the end of
+      // the label we found it in, and break out.
+
+      if (found_label == true) {
+	// pos = end_pos;
+	pos = label_size + offset;
+	break;
+      }
+
+      // We haven't found it; jump pos to just after the current label being
+      // checked.
+      pos = end_pos;
+    }
+
+    // Jump up a block to the next possible point to find a label,
+    pos += label_size;
+  }
+
+  // If the label was not found return a -1.
+  if (found_label == false) pos = -1;
+
+  return pos;
+}
+
+// Search backwards for search_label from _before_ position pos in the
+// memory.  Return the first line _after_ the the found label.  It is okay
+// to find search label's match inside another label.
+
+int cHardware4Stack::FindLabel_Backward(const cCodeLabel & search_label,
+				  const cGenome & search_genome, int pos)
+{
+  assert (pos < search_genome.GetSize());
+
+  int search_start = pos;
+  int label_size = search_label.GetSize();
+  bool found_label = false;
+
+  // Move off the template we are on.
+  pos -= label_size;
+
+  // Search until we find the complement or exit the memory.
+  while (pos >= 0) {
+    // If we are within a label, rewind to the beginning of it and see if
+    // it has the proper sub-label that we're looking for.
+
+    if (inst_set->IsNop( search_genome[pos] )) {
+      // Find the start and end of the label we're in the middle of.
+
+      int start_pos = pos;
+      int end_pos = pos + 1;
+      while (start_pos > 0 && inst_set->IsNop(search_genome[start_pos - 1])) {
+	start_pos--;
+      }
+      while (end_pos < search_start &&
+	     inst_set->IsNop(search_genome[end_pos])) {
+	end_pos++;
+      }
+      int test_size = end_pos - start_pos;
+
+      // See if this label has the proper sub-label within it.
+      int max_offset = test_size - label_size + 1;
+      for (int offset = start_pos; offset < start_pos + max_offset; offset++) {
+
+	// Test the number of matches for this offset.
+	int matches;
+	for (matches = 0; matches < label_size; matches++) {
+	  if (search_label[matches] !=
+	      inst_set->GetNopMod(search_genome[offset + matches])) {
+	    break;
+	  }
+	}
+
+	// If we have found it, break out of this loop!
+	if (matches == label_size) {
+	  found_label = true;
+	  break;
+	}
+      }
+
+      // If we've found the complement label, set the position to the end of
+      // the label we found it in, and break out.
+
+      if (found_label == true) {
+	pos = end_pos;
+	break;
+      }
+
+      // We haven't found it; jump pos to just before the current label
+      // being checked.
+      pos = start_pos - 1;
+    }
+
+    // Jump up a block to the next possible point to find a label,
+    pos -= label_size;
+  }
+
+  // If the label was not found return a -1.
+  if (found_label == false) pos = -1;
+
+  return pos;
+}
+
+// Search for 'in_label' anywhere in the hardware.
+cHeadMultiMem cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
+{
+  assert (in_label.GetSize() > 0);
+
+  // IDEALY:
+  // Keep making jumps (in the proper direction) equal to the label
+  // length.  If we are inside of a label, check its size, and see if
+  // any of the sub-labels match properly.
+  // FOR NOW:
+  // Get something which works, no matter how inefficient!!!
+
+  cHeadMultiMem temp_head(this);
+
+  while (temp_head.InMemory()) {
+    // IDEALY: Analyze the label we are in; see if the one we are looking
+    // for could be a sub-label of it.  Skip past it if not.
+
+    int i;
+    for (i = 0; i < in_label.GetSize(); i++) {
+      if (!inst_set->IsNop(temp_head.GetInst()) ||
+	  in_label[i] != inst_set->GetNopMod(temp_head.GetInst())) {
+	break;
+      }
+    }
+    if (i == GetLabel().GetSize()) {
+      temp_head.AbsJump(i - 1);
+      return temp_head;
+    }
+
+    temp_head.AbsJump(direction);     // IDEALY: MAKE LARGER JUMPS
+  }
+
+  temp_head.AbsSet(-1);
+  return temp_head;
+}
+
+// @CAO: direction is not currently used; should be used to indicate the
+// direction which the heads[HEAD_IP] should progress through a creature.
+cHeadMultiMem cHardware4Stack::FindFullLabel(const cCodeLabel & in_label)
+{
+  // cout << "Running FindFullLabel with " << in_label.AsString() <<
+  // endl;
+
+  assert(in_label.GetSize() > 0); // Trying to find label of 0 size!
+
+  cHeadMultiMem temp_head(this);
+
+  while (temp_head.InMemory()) {
+    // If we are not in a label, jump to the next checkpoint...
+    if (inst_set->IsNop(temp_head.GetInst())) {
+      temp_head.AbsJump(in_label.GetSize());
+      continue;
+    }
+
+    // Otherwise, rewind to the begining of this label...
+
+    while (!(temp_head.AtFront()) && inst_set->IsNop(temp_head.GetInst(-1)))
+      temp_head.AbsJump(-1);
+
+    // Calculate the size of the label being checked, and make sure they
+    // are equal.
+
+    int checked_size = 0;
+    while (inst_set->IsNop(temp_head.GetInst(checked_size))) {
+      checked_size++;
+    }
+    if (checked_size != in_label.GetSize()) {
+      temp_head.AbsJump(checked_size + 1);
+      continue;
+    }
+
+    // cout << "Testing label at line " << temp_head.GetPosition() <<
+    // endl;
+
+    // ...and do the comparison...
+
+    int j;
+    bool label_match = true;
+    for (j = 0; j < in_label.GetSize(); j++) {
+      if (!inst_set->IsNop(temp_head.GetInst(j)) ||
+	  in_label[j] != inst_set->GetNopMod(temp_head.GetInst(j))) {
+	temp_head.AbsJump(in_label.GetSize() + 1);
+	label_match = false;
+	break;
+      }
+    }
+
+    if (label_match) {
+      // If we have found the label, return the position after it.
+      temp_head.AbsJump(j - 1);
+      return temp_head;
+    }
+
+    // We have not found the label... increment i.
+
+    temp_head.AbsJump(in_label.GetSize() + 1);
+  }
+
+  // The label does not exist in this creature.
+
+  temp_head.AbsSet(-1);
+  return temp_head;
+}
+
+// This is the code run by the INFECTED organism.  Its function is to SPREAD infection.
+bool cHardware4Stack::InjectParasite(double mut_multiplier)
+{
+  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
+  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
+  
+  // Make sure the creature will still be above the minimum size,
+  // TEMPORARY!  INJECTED CODE CAN 
+  if (end_pos <= 0) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    return false; // (inject fails)
+  }
+  
+  if (end_pos < MIN_INJECT_SIZE) {
+    GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    return false; // (inject fails)
+  }
+
+  GetMemory(mem_space_used).Resize(end_pos);
+
+  cCPUMemory injected_code = GetMemory(mem_space_used);
+
+  Inject_DoMutations(mut_multiplier, injected_code);
+
+  int inject_signal = false;
+
+  if(injected_code.GetSize()>0)
+    inject_signal = organism->InjectParasite(injected_code);
+  
+  //************* CALL GOES HERE ******************//
+  // spin around randomly (caution: possible organism dizziness)
+  //const int num_neighbors = organism->GetNeighborhoodSize();
+  //for(unsigned int i=0; i<g_random.GetUInt(num_neighbors); i++)
+  //  organism->Rotate(1);
+
+  // If we don't have a host, stop here.
+  //cOrganism * host_organism = organism->GetNeighbor();
+  
+ 
+  //if(host_organism!=NULL)
+  //  {
+  //    
+  //  }
+ 
+  //************** CALL ENDS HERE ******************//
+
+  //reset the memory space which was injected
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
+
+  for(int x=0; x<NUM_HEADS; x++)
+    {
+      GetHead(x).Reset(IP().GetMemSpace(), this);
+    }
+
+  for(int x=0; x<NUM_LOCAL_STACKS; x++)
+    {
+      Stack(x).Clear();
+    }
+  
+  AdvanceIP() = false;
+  
+  return inject_signal;
+}
+
+//This is the code run by the TARGET of an injection.  This RECIEVES the infection.
+bool cHardware4Stack::InjectHost(const cCodeLabel & in_label, const cGenome & inject_code)
+{
+  // Make sure the genome will be below max size after injection.
+
+  // xxxTEMPORARYxxx - we should have this match injection templates.  For now it simply 
+  
+// FIND THE FIRST EMPTY MEMORY SPACE
+  int target_mem_space;
+  for (target_mem_space = 0; target_mem_space < NUM_MEMORY_SPACES; target_mem_space++)
+    {
+      if(isEmpty(target_mem_space))
+	{
+	  break;
+	}
+    }
+  
+  if (target_mem_space == NUM_MEMORY_SPACES)
+    {
+      return false;
+    }
+
+  assert(target_mem_space >=0 && target_mem_space < NUM_MEMORY_SPACES);
+  
+  if(ForkThread()) {
+    // Inject the new code
+    cCPUMemory oldcode = GetMemory(target_mem_space);
+    GetMemory(target_mem_space) = inject_code;
+    GetMemory(target_mem_space).Resize(inject_code.GetSize() + oldcode.GetSize());
+
+    // Copies previous instructions to the end of the injected code.
+    // Is there a faster way to do this?? -law
+    for(int x=0; x<oldcode.GetSize(); x++)
+      GetMemory(target_mem_space)[inject_code.GetSize()+x] = oldcode[x];
+  
+    // Set instruction flags on the injected code
+    for (int i = 0; i < inject_code.GetSize(); i++) {
+      memory_array[target_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()==target_mem_space)
+	  threads[i].heads[j].Jump(inject_code.GetSize());
+      }
+    }
+    
+    for (int i=0; i < NUM_HEADS; i++) {    
+      GetHead(i).Reset(target_mem_space, this);
+    }
+    for (int i=0; i < NUM_LOCAL_STACKS; i++) {
+      Stack(i).Clear();
+    }
+  }
+
+  return true; // (inject succeeds!)
+}
+
+void cHardware4Stack::Mutate(int mut_point)
+{
+  // Test if trying to mutate outside of genome...
+  assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
+
+  GetMemory(0)[mut_point] = GetRandomInst();
+  GetMemory(0).FlagMutated(mut_point) = true;
+  GetMemory(0).FlagPointMut(mut_point) = true;
+  //organism->GetPhenotype().IsMutated() = true;
+  organism->CPUStats().mut_stats.point_mut_count++;
+}
+
+int cHardware4Stack::PointMutate(const double mut_rate)
+{
+  const int num_muts =
+    g_random.GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
+
+  for (int i = 0; i < num_muts; i++) {
+    const int pos = g_random.GetUInt(GetMemory(0).GetSize());
+    Mutate(pos);
+  }
+
+  return num_muts;
+}
+
+
+// Trigger mutations of a specific type.  Outside triggers cannot specify
+// a head since hardware types are not known.
+
+bool cHardware4Stack::TriggerMutations(int trigger)
+{
+  // Only update triggers should happen from the outside!
+  assert(trigger == MUTATION_TRIGGER_UPDATE);
+
+  // Assume instruction pointer is the intended target (if one is even
+  // needed!
+
+  return TriggerMutations(trigger, IP());
+}
+
+bool cHardware4Stack::TriggerMutations(int trigger, cHeadMultiMem & cur_head)
+{
+  // Collect information about mutations from the organism.
+  cLocalMutations & mut_info = organism->GetLocalMutations();
+  const tList<cMutation> & mut_list =
+    mut_info.GetMutationLib().GetMutationList(trigger);
+
+  // If we have no mutations for this trigger, stop here.
+  if (mut_list.GetSize() == 0) return false;
+  bool has_mutation = false;
+
+  // Determine what memory this mutation will be affecting.
+  cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
+    ? organism->ChildGenome() : GetMemory(0);
+
+  // Loop through all mutations associated with this trigger and test them.
+  tConstListIterator<cMutation> mut_it(mut_list);
+
+  while (mut_it.Next() != NULL) {
+    const cMutation * cur_mut = mut_it.Get();
+    const int mut_id = cur_mut->GetID();
+    const int scope = cur_mut->GetScope();
+    const double rate = mut_info.GetRate(mut_id);
+    switch (scope) {
+    case MUTATION_SCOPE_GENOME:
+      if (TriggerMutations_ScopeGenome(cur_mut, target_mem, cur_head, rate)) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id);
+      }
+      break;
+    case MUTATION_SCOPE_LOCAL:
+    case MUTATION_SCOPE_PROP:
+      if (TriggerMutations_ScopeLocal(cur_mut, target_mem, cur_head, rate)) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id);
+      }
+      break;
+    case MUTATION_SCOPE_GLOBAL:
+    case MUTATION_SCOPE_SPREAD:
+      int num_muts =
+	TriggerMutations_ScopeGlobal(cur_mut, target_mem, cur_head, rate);
+      if (num_muts > 0) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id, num_muts);
+      }
+      break;
+    }
+  }
+
+  return has_mutation;
+}
+
+bool cHardware4Stack::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
+{
+  // The rate we have stored indicates the probability that a single
+  // mutation will occur anywhere in the genome.
+  
+  if (g_random.P(rate) == true) {
+    // We must create a temporary head and use it to randomly determine the
+    // position in the genome to be mutated.
+    cHeadMultiMem tmp_head(cur_head);
+    tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
+    TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
+    return true;
+  }
+  return false;
+}
+
+bool cHardware4Stack::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
+{
+  // The rate we have stored is the probability for a mutation at this single
+  // position in the genome.
+
+  if (g_random.P(rate) == true) {
+    TriggerMutations_Body(cur_mut->GetType(), target_memory, cur_head);
+    return true;
+  }
+  return false;
+}
+
+int cHardware4Stack::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
+{
+  // The probability we have stored is per-site, so we can pull a random
+  // number from a binomial distribution to determine the number of mutations
+  // that should occur.
+
+  const int num_mut =
+    g_random.GetRandBinomial(target_memory.GetSize(), rate);
+
+  if (num_mut > 0) {
+    for (int i = 0; i < num_mut; i++) {
+      cHeadMultiMem tmp_head(cur_head);
+      tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
+      TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
+    }
+  }
+
+  return num_mut;
+}
+
+void cHardware4Stack::TriggerMutations_Body(int type, cCPUMemory & target_memory,
+					 cHeadMultiMem & cur_head)
+{
+  const int pos = cur_head.GetPosition();
+
+  switch (type) {
+  case MUTATION_TYPE_POINT:
+    target_memory[pos] = GetRandomInst();
+    target_memory.FlagMutated(pos) = true;
+    break;
+  case MUTATION_TYPE_INSERT:
+  case MUTATION_TYPE_DELETE:
+  case MUTATION_TYPE_HEAD_INC:
+  case MUTATION_TYPE_HEAD_DEC:
+  case MUTATION_TYPE_TEMP:
+  case MUTATION_TYPE_KILL:
+  default:
+    cout << "Error: Mutation type not implemented!" << endl;
+    break;
+  };
+}
+
+void cHardware4Stack::ReadInst(const int in_inst)
+{
+  if (inst_set->IsNop( cInstruction(in_inst) )) {
+    GetReadLabel().AddNop(in_inst);
+  } else {
+    GetReadLabel().Clear();
+  }
+}
+
+
+void cHardware4Stack::AdjustHeads()
+{
+  for (int i = 0; i < GetNumThreads(); i++) {
+    for (int j = 0; j < NUM_HEADS; j++) {
+      threads[i].heads[j].Adjust();
+    }
+  }
+}
+
+
+
+// This function looks at the current position in the info of a creature,
+// and sets the next_label to be the sequence of nops which follows.  The
+// instruction pointer is left on the last line of the label found.
+
+void cHardware4Stack::ReadLabel(int max_size)
+{
+  int count = 0;
+  cHeadMultiMem * inst_ptr = &( IP() );
+
+  GetLabel().Clear();
+
+  while (inst_set->IsNop(inst_ptr->GetNextInst()) &&
+	 (count < max_size)) {
+    count++;
+    inst_ptr->Advance();
+    GetLabel().AddNop(inst_set->GetNopMod(inst_ptr->GetInst()));
+
+    // If this is the first line of the template, mark it executed.
+    if (GetLabel().GetSize() <=	cConfig::GetMaxLabelExeSize()) {
+      inst_ptr->FlagExecuted() = true;
+    }
+  }
+}
+
+
+bool cHardware4Stack::ForkThread()
+{
+  const int num_threads = GetNumThreads();
+  if (num_threads == cConfig::GetMaxCPUThreads()) return false;
+
+  // 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]; 
+
+  // Find the first free bit in thread_id_chart to determine the new
+  // thread id.
+  int new_id = 0;
+  while ( (thread_id_chart >> new_id) & 1 == 1) new_id++;
+  threads[num_threads].SetID(new_id);
+  thread_id_chart |= (1 << new_id);
+
+  return true;
+}
+
+
+int cHardware4Stack::TestParasite() const
+{
+  return IP().TestParasite();
+}
+
+
+bool cHardware4Stack::KillThread()
+{
+  // Make sure that there is always at least one thread...
+  if (GetNumThreads() == 1) return false;
+
+  // Note the current thread and set the current back one.
+  const int kill_thread = cur_thread;
+  PrevThread();
+  
+  // Turn off this bit in the thread_id_chart...
+  thread_id_chart ^= 1 << threads[kill_thread].GetID();
+
+  // Copy the last thread into the kill position
+  const int last_thread = GetNumThreads() - 1;
+  if (last_thread != kill_thread) {
+    threads[kill_thread] = threads[last_thread];
+  }
+
+  // Kill the thread!
+  threads.Resize(GetNumThreads() - 1);
+
+  if (cur_thread > kill_thread) cur_thread--;
+
+  return true;
+}
+
+
+void cHardware4Stack::SaveState(ostream & fp)
+{
+  // note, memory & child_memory handled by cpu (@CAO Not any more!)
+  assert(fp.good());
+
+  fp<<"cHardware4Stack"<<endl;
+
+  // global_stack (in inverse order so load can just push)
+  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
+    Stack(i).SaveState(fp);
+
+  //fp << thread_time_used  << endl;
+  fp << GetNumThreads()   << endl;
+  fp << cur_thread        << endl;
+
+  // Threads
+  for( int i = 0; i < GetNumThreads(); i++ ) {
+    threads[i].SaveState(fp);
+  }
+}
+
+
+void cHardware4Stack::LoadState(istream & fp)
+{
+  // note, memory & child_memory handled by cpu (@CAO Not any more!)
+  assert(fp.good());
+
+  cString foo;
+  fp>>foo;
+  assert( foo == "cHardware4Stack" );
+
+  // global_stack
+  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
+    Stack(i).LoadState(fp);
+
+  int num_threads;
+  //fp >> thread_time_used;
+  fp >> num_threads;
+  fp >> cur_thread;
+
+  // Threads
+  for( int i = 0; i < num_threads; i++ ){
+    threads[i].LoadState(fp);
+  }
+}
+
+
+////////////////////////////
+//  Instruction Helpers...
+////////////////////////////
+
+inline int cHardware4Stack::FindModifiedStack(int default_stack)
+{
+  assert(default_stack < NUM_STACKS);  // Stack ID too high.
+
+  if (GetInstSet().IsNop(IP().GetNextInst())) {
+    IP().Advance();
+    default_stack = GetInstSet().GetNopMod(IP().GetInst());
+    IP().FlagExecuted() = true;
+  }
+  return default_stack;
+}
+
+inline int cHardware4Stack::FindModifiedHead(int default_head)
+{
+  assert(default_head < NUM_HEADS); // Head ID too high.
+
+  if (GetInstSet().IsNop(IP().GetNextInst())) {
+    IP().Advance();    
+    int nop_head = GetInstSet().GetNopMod(IP().GetInst());
+    if (nop_head < NUM_HEADS) default_head = nop_head;
+    IP().FlagExecuted() = true;
+  }
+  return default_head;
+}
+
+inline int cHardware4Stack::FindComplementStack(int base_stack)
+{
+  const int comp_stack = base_stack + 2;
+  return comp_stack%NUM_STACKS;
+}
+
+inline void cHardware4Stack::Fault(int fault_loc, int fault_type, cString fault_desc)
+{
+  organism->Fault(fault_loc, fault_type, fault_desc);
+}
+
+bool cHardware4Stack::Divide_CheckViable(const int parent_size,
+				      const int child_size, const int mem_space)
+{
+  // Make sure the organism is okay with dividing now...
+  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
+
+  // Make sure that neither parent nor child will be below the minimum size.
+
+  const int genome_size = organism->GetGenome().GetSize();
+  const double size_range = cConfig::GetChildSizeRange();
+  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
+  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
+  
+  if (child_size < min_size || child_size > max_size) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
+    return false; // (divide fails)
+  }
+
+  // Count the number of lines executed in the parent, and make sure the
+  // specified fraction has been reached.
+
+  int executed_size = 0;
+  for (int i = 0; i < parent_size; i++) {
+    if (GetMemory(0).FlagExecuted(i)) executed_size++;
+  }
+
+  const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
+  if (executed_size < min_exe_lines) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Too few executed lines (%d < %d)",
+			       executed_size, min_exe_lines));
+    return false; // (divide fails)
+  }
+	
+  // Count the number of lines which were copied into the child, and make
+  // sure the specified fraction has been reached.
+
+  int copied_size = 0;
+  for (int i = 0; i < GetMemory(mem_space).GetSize(); i++) {
+    if (GetMemory(mem_space).FlagCopied(i)) copied_size++;
+   }
+
+  const int min_copied =  (int) (child_size * cConfig::GetMinCopiedLines());
+  if (copied_size < min_copied) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Too few copied commands (%d < %d)",
+			       copied_size, min_copied));
+    return false; // (divide fails)
+  }
+
+  // Save the information we collected here...
+  organism->GetPhenotype().SetLinesExecuted(executed_size);
+  organism->GetPhenotype().SetLinesCopied(copied_size);
+
+  return true; // (divide succeeds!)
+}
+
+void cHardware4Stack::Divide_DoMutations(double mut_multiplier)
+{
+  sCPUStats & cpu_stats = organism->CPUStats();
+  cCPUMemory & child_genome = organism->ChildGenome();
+  
+  organism->GetPhenotype().SetDivType(mut_multiplier);
+
+  // Divide Mutations
+  if (organism->TestDivideMut()) {
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
+    child_genome[mut_line] = GetRandomInst();
+    cpu_stats.mut_stats.divide_mut_count++;
+  }
+
+  // Divide Insertions
+  if (organism->TestDivideIns() && child_genome.GetSize() < MAX_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize() + 1);
+    child_genome.Insert(mut_line, GetRandomInst());
+    cpu_stats.mut_stats.divide_insert_mut_count++;
+  }
+
+  // Divide Deletions
+  if (organism->TestDivideDel() && child_genome.GetSize() > MIN_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
+    // if( child_genome.FlagCopied(mut_line) == true) copied_size_change--;
+    child_genome.Remove(mut_line);
+    cpu_stats.mut_stats.divide_delete_mut_count++;
+  }
+
+  // Divide Mutations (per site)
+  if(organism->GetDivMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(), 
+				   	   organism->GetDivMutProb() / mut_multiplier);
+    // If we have lines to mutate...
+    if( num_mut > 0 ){
+      for (int i = 0; i < num_mut; i++) {
+	int site = g_random.GetUInt(child_genome.GetSize());
+	child_genome[site]=GetRandomInst();
+	cpu_stats.mut_stats.div_mut_count++;
+      }
+    }
+  }
+
+
+  // Insert Mutations (per site)
+  if(organism->GetInsMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
+					   organism->GetInsMutProb());
+    // If would make creature to big, insert up to MAX_CREATURE_SIZE
+    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
+      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
+    }
+    // If we have lines to insert...
+    if( num_mut > 0 ){
+      // Build a list of the sites where mutations occured
+      static int mut_sites[MAX_CREATURE_SIZE];
+      for (int i = 0; i < num_mut; i++) {
+	mut_sites[i] = g_random.GetUInt(child_genome.GetSize() + 1);
+      }
+      // Sort the list
+      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+      // Actually do the mutations (in reverse sort order)
+      for(int i = num_mut-1; i >= 0; i--) {
+	child_genome.Insert(mut_sites[i], GetRandomInst());
+	cpu_stats.mut_stats.insert_mut_count++;
+      }
+    }
+  }
+
+
+  // Delete Mutations (per site)
+  if( organism->GetDelMutProb() > 0 ){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
+					   organism->GetDelMutProb());
+    // If would make creature too small, delete down to MIN_CREATURE_SIZE
+    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
+    }
+
+    // If we have lines to delete...
+    for (int i = 0; i < num_mut; i++) {
+      int site = g_random.GetUInt(child_genome.GetSize());
+      // if (child_genome.FlagCopied(site) == true) copied_size_change--;
+      child_genome.Remove(site);
+      cpu_stats.mut_stats.delete_mut_count++;
+    }
+  }
+
+  // Mutations in the parent's genome
+  if (organism->GetParentMutProb() > 0) {
+    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
+      if (organism->TestParentMut()) {
+	GetMemory(0)[i] = GetRandomInst();
+	cpu_stats.mut_stats.parent_mut_line_count++;
+      }
+    }
+  }
+
+
+  // Count up mutated lines
+  for(int i = 0; i < GetMemory(0).GetSize(); i++){
+    if (GetMemory(0).FlagPointMut(i) == true) {
+      cpu_stats.mut_stats.point_mut_line_count++;
+    }
+  }
+  for(int i = 0; i < child_genome.GetSize(); i++){
+    if( child_genome.FlagCopyMut(i) == true) {
+      cpu_stats.mut_stats.copy_mut_line_count++;
+    }
+  }
+}
+
+void cHardware4Stack::Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code)
+{
+  //sCPUStats & cpu_stats = organism->CPUStats();
+  //cCPUMemory & child_genome = organism->ChildGenome();
+  
+  organism->GetPhenotype().SetDivType(mut_multiplier);
+
+  // Divide Mutations
+  if (organism->TestDivideMut()) {
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
+    injected_code[mut_line] = GetRandomInst();
+    //cpu_stats.mut_stats.divide_mut_count++;
+  }
+
+  // Divide Insertions
+  if (organism->TestDivideIns() && injected_code.GetSize() < MAX_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize() + 1);
+    injected_code.Insert(mut_line, GetRandomInst());
+    //cpu_stats.mut_stats.divide_insert_mut_count++;
+  }
+
+  // Divide Deletions
+  if (organism->TestDivideDel() && injected_code.GetSize() > MIN_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
+    // if( injected_code.FlagCopied(mut_line) == true) copied_size_change--;
+    injected_code.Remove(mut_line);
+    //cpu_stats.mut_stats.divide_delete_mut_count++;
+  }
+
+  // Divide Mutations (per site)
+  if(organism->GetDivMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(), 
+				   	   organism->GetDivMutProb() / mut_multiplier);
+    // If we have lines to mutate...
+    if( num_mut > 0 ){
+      for (int i = 0; i < num_mut; i++) {
+	int site = g_random.GetUInt(injected_code.GetSize());
+	injected_code[site]=GetRandomInst();
+	//cpu_stats.mut_stats.div_mut_count++;
+      }
+    }
+  }
+
+
+  // Insert Mutations (per site)
+  if(organism->GetInsMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
+					   organism->GetInsMutProb());
+    // If would make creature to big, insert up to MAX_CREATURE_SIZE
+    if( num_mut + injected_code.GetSize() > MAX_CREATURE_SIZE ){
+      num_mut = MAX_CREATURE_SIZE - injected_code.GetSize();
+    }
+    // If we have lines to insert...
+    if( num_mut > 0 ){
+      // Build a list of the sites where mutations occured
+      static int mut_sites[MAX_CREATURE_SIZE];
+      for (int i = 0; i < num_mut; i++) {
+	mut_sites[i] = g_random.GetUInt(injected_code.GetSize() + 1);
+      }
+      // Sort the list
+      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+      // Actually do the mutations (in reverse sort order)
+      for(int i = num_mut-1; i >= 0; i--) {
+	injected_code.Insert(mut_sites[i], GetRandomInst());
+	//cpu_stats.mut_stats.insert_mut_count++;
+      }
+    }
+  }
+
+
+  // Delete Mutations (per site)
+  if( organism->GetDelMutProb() > 0 ){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
+					   organism->GetDelMutProb());
+    // If would make creature too small, delete down to MIN_CREATURE_SIZE
+    if (injected_code.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+      num_mut = injected_code.GetSize() - MIN_CREATURE_SIZE;
+    }
+
+    // If we have lines to delete...
+    for (int i = 0; i < num_mut; i++) {
+      int site = g_random.GetUInt(injected_code.GetSize());
+      // if (injected_code.FlagCopied(site) == true) copied_size_change--;
+      injected_code.Remove(site);
+      //cpu_stats.mut_stats.delete_mut_count++;
+    }
+  }
+
+  // Mutations in the parent's genome
+  if (organism->GetParentMutProb() > 0) {
+    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
+      if (organism->TestParentMut()) {
+	GetMemory(0)[i] = GetRandomInst();
+	//cpu_stats.mut_stats.parent_mut_line_count++;
+      }
+    }
+  }
+
+  /*
+  // Count up mutated lines
+  for(int i = 0; i < GetMemory(0).GetSize(); i++){
+    if (GetMemory(0).FlagPointMut(i) == true) {
+      cpu_stats.mut_stats.point_mut_line_count++;
+    }
+  }
+  for(int i = 0; i < injected_code.GetSize(); i++){
+    if( injected_code.FlagCopyMut(i) == true) {
+      cpu_stats.mut_stats.copy_mut_line_count++;
+    }
+    }*/
+}
+
+
+// test whether the offspring creature contains an advantageous mutation.
+void cHardware4Stack::Divide_TestFitnessMeasures()
+{
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
+  phenotype.ChildFertile() = true;
+
+  // Only continue if we're supposed to do a fitness test on divide...
+  if (organism->GetTestOnDivide() == false) return;
+
+  // If this was a perfect copy, then we don't need to worry about any other
+  // tests...  Theoretically, we need to worry about the parent changing,
+  // but as long as the child is always compared to the original genotype,
+  // this won't be an issue.
+  if (phenotype.CopyTrue() == true) return;
+
+  const double parent_fitness = organism->GetTestFitness();
+  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
+  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
+  
+  cCPUTestInfo test_info;
+  test_info.UseRandomInputs();
+  cTestCPU::TestGenome(test_info, organism->ChildGenome());
+  const double child_fitness = test_info.GetGenotypeFitness();
+  
+  bool revert = false;
+  bool sterilize = false;
+  
+  // If implicit mutations are turned off, make sure this won't spawn one.
+  if (organism->GetFailImplicit() == true) {
+    if (test_info.GetMaxDepth() > 0) sterilize = true;
+  }
+  
+  if (child_fitness == 0.0) {
+    // Fatal mutation... test for reversion.
+    if (g_random.P(organism->GetRevertFatal())) revert = true;
+    if (g_random.P(organism->GetSterilizeFatal())) sterilize = true;
+  } else if (child_fitness < neut_min) {
+    if (g_random.P(organism->GetRevertNeg())) revert = true;
+    if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
+  } else if (child_fitness <= neut_max) {
+    if (g_random.P(organism->GetRevertNeut())) revert = true;
+    if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
+  } else {
+    if (g_random.P(organism->GetRevertPos())) revert = true;
+    if (g_random.P(organism->GetSterilizePos())) sterilize = true;
+  }
+  
+  // Ideally, we won't have reversions and sterilizations turned on at the
+  // same time, but if we do, give revert the priority.
+  if (revert == true) {
+    organism->ChildGenome() = organism->GetGenome();
+  }
+
+  if (sterilize == true) {
+    organism->GetPhenotype().ChildFertile() = false;
+  }
+}
+
+
+bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
+{
+  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;
+
+  // Make sure this divide will produce a viable offspring.
+  if(!Divide_CheckViable(GetMemory(IP().GetMemSpace()).GetSize(), 
+	 		 write_head_pos, mem_space_used)) 
+    return false;
+  
+  // Since the divide will now succeed, set up the information to be sent
+  // to the new organism
+  cGenome & child_genome = organism->ChildGenome();
+  GetMemory(mem_space_used).Resize(write_head_pos);
+  child_genome = GetMemory(mem_space_used);
+
+  // Handle Divide Mutations...
+  Divide_DoMutations(mut_multiplier);
+
+  // 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
+
+  bool parent_alive = organism->ActivateDivide();
+
+  //reset the memory of the memory space that has been divided off
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
+
+  // 3 Division Methods:
+  // 1) DIVIDE_METHOD_OFFSPRING - Create a child, leave parent state untouched.
+  // 2) DIVIDE_METHOD_SPLIT - Create a child, completely reset state of parent.
+  // 3) DIVIDE_METHOD_BIRTH - Create a child, reset state of parent's current thread.
+  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;
+}
+
+cString cHardware4Stack::ConvertToInstruction(int mem_space_used)
+{
+  char c = mem_space_used + 97;  // 97 - ASCII for 'a'
+  cString ret;
+  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 "";
+}
+  
+
+//////////////////////////
+// And the instructions...
+//////////////////////////
+
+//6
+bool cHardware4Stack::Inst_ShiftR()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  int value = Stack(stack_used).Pop();
+  value >>= 1;
+  Stack(stack_used).Push(value);
+  return true;
+}
+
+//7
+bool cHardware4Stack::Inst_ShiftL()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  int value = Stack(stack_used).Pop();
+  value <<= 1;
+  Stack(stack_used).Push(value);
+  return true;
+}
+
+//8
+bool cHardware4Stack::Inst_Val_Nand()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Push(~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top()));
+  return true;
+}
+
+//9
+bool cHardware4Stack::Inst_Val_Add()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Push(Stack(STACK_BX).Top() + Stack(STACK_CX).Top());
+  return true;
+}
+
+//10
+bool cHardware4Stack::Inst_Val_Sub()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Push(Stack(STACK_BX).Top() - Stack(STACK_CX).Top());
+  return true;
+}
+
+//11
+bool cHardware4Stack::Inst_Val_Mult()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Push(Stack(STACK_BX).Top() * Stack(STACK_CX).Top());
+  return true;
+}
+
+//12
+bool cHardware4Stack::Inst_Val_Div()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  if (Stack(STACK_CX).Top() != 0) {
+    if (0-INT_MAX > Stack(STACK_BX).Top() && Stack(STACK_CX).Top() == -1)
+      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+    else
+      Stack(stack_used).Push(Stack(STACK_BX).Top() / Stack(STACK_CX).Top());
+  } else {
+    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+    return false;
+  }
+  return true;
+}
+
+//13 
+bool cHardware4Stack::Inst_SetMemory()   // Allocate maximal more
+{
+  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);
+  //if( Allocate_Main(alloc_size) ) {
+  //  Stack(STACK_AX).Push(cur_size);
+  //  return true;
+  //} else return false;
+}
+
+//14
+bool cHardware4Stack::Inst_Divide()
+{
+  int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
+  int mut_multiplier = 1;
+
+  return Divide_Main(mem_space_used, mut_multiplier);
+}
+
+bool cHardware4Stack::Inst_HeadDivideMut(double mut_multiplier)
+{
+  // Unused for the moment...
+  return true;
+  //AdjustHeads();
+  //const int divide_pos = GetHead(HEAD_READ).GetPosition();
+  //int child_end =  GetHead(HEAD_WRITE).GetPosition();
+  //if (child_end == 0) child_end = GetMemory(0).GetSize();
+  //const int extra_lines = GetMemory(0).GetSize() - child_end;
+  //bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
+  //// Re-adjust heads.
+  //AdjustHeads();
+  //return ret_val; 
+}
+
+//15
+bool cHardware4Stack::Inst_HeadRead()
+{
+  const int head_id = FindModifiedHead(HEAD_READ);
+  GetHead(head_id).Adjust();
+  sCPUStats & cpu_stats = organism->CPUStats();
+
+  // Mutations only occur on the read, for the moment.
+  int read_inst = 0;
+  if (organism->TestCopyMut()) {
+    read_inst = GetRandomInst().GetOp();
+    cpu_stats.mut_stats.copy_mut_count++;  // @CAO, hope this is good!
+  } else {
+    read_inst = GetHead(head_id).GetInst().GetOp();
+  }
+  Stack(STACK_AX).Push(read_inst);
+  ReadInst(read_inst);
+
+  cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
+  GetHead(head_id).Advance();
+  return true;
+}
+
+//16
+bool cHardware4Stack::Inst_HeadWrite()
+{
+  const int head_id = FindModifiedHead(HEAD_WRITE);
+  cHeadMultiMem & active_head = GetHead(head_id);
+  int mem_space_used = active_head.GetMemSpace();
+  
+  //commented out for right now...
+  if(active_head.GetPosition()>=GetMemory(mem_space_used).GetSize()-1)
+   {
+     GetMemory(mem_space_used).Resize(GetMemory(mem_space_used).GetSize()+1);
+     GetMemory(mem_space_used).Copy(GetMemory(mem_space_used).GetSize()-1, GetMemory(mem_space_used).GetSize()-2);
+   }
+
+  active_head.Adjust();
+
+  int value = Stack(STACK_AX).Pop();
+  if (value < 0 || value >= GetNumInst()) value = 0;
+
+  active_head.SetInst(cInstruction(value));
+  active_head.FlagCopied() = true;
+
+  // Advance the head after write...
+  active_head++;
+  return true;
+}
+
+//??
+bool cHardware4Stack::Inst_HeadCopy()
+{
+  // For the moment, this cannot be nop-modified.
+  cHeadMultiMem & read_head = GetHead(HEAD_READ);
+  cHeadMultiMem & write_head = GetHead(HEAD_WRITE);
+  sCPUStats & cpu_stats = organism->CPUStats();
+
+  read_head.Adjust();
+  write_head.Adjust();
+
+  // TriggerMutations(MUTATION_TRIGGER_READ, read_head);
+  
+  // Do mutations.
+  cInstruction read_inst = read_head.GetInst();
+  if (organism->TestCopyMut()) {
+    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...
+
+  // TriggerMutations(MUTATION_TRIGGER_WRITE, write_head);
+
+  read_head.Advance();
+  write_head.Advance();
+  return true;
+}
+
+//17
+bool cHardware4Stack::Inst_IfEqual()      // Execute next if bx == ?cx?
+{
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
+  if (Stack(stack_used).Top() != Stack(stack_used2).Top())  IP().Advance();
+  return true;
+}
+
+//18
+bool cHardware4Stack::Inst_IfNotEqual()     // Execute next if bx != ?cx?
+{
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
+  if (Stack(stack_used).Top() == Stack(stack_used2).Top())  IP().Advance();
+  return true;
+}
+
+//19
+bool cHardware4Stack::Inst_IfLess()       // Execute next if ?bx? < ?cx?
+{
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
+  if (Stack(stack_used).Top() >=  Stack(stack_used2).Top())  IP().Advance();
+  return true;
+}
+
+//20
+bool cHardware4Stack::Inst_IfGreater()       // Execute next if bx > ?cx?
+{
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
+  if (Stack(stack_used).Top() <= Stack(stack_used2).Top())  IP().Advance();
+  return true;
+}
+
+//21
+bool cHardware4Stack::Inst_HeadPush()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
+  //if (head_used == HEAD_IP) {
+  //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
+  //  AdvanceIP() = false;
+  //}
+  return true;
+}
+
+//22
+bool cHardware4Stack::Inst_HeadPop()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  GetHead(head_used).Set(Stack(STACK_BX).Pop(), 
+			 GetHead(head_used).GetMemSpace(), this);
+  return true;
+}
+
+//23 
+bool cHardware4Stack::Inst_HeadMove()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  if(head_used != HEAD_FLOW)
+    {
+      GetHead(head_used).Set(GetHead(HEAD_FLOW));
+      if (head_used == HEAD_IP) AdvanceIP() = false;
+    }
+  else
+    {
+      threads[cur_thread].heads[HEAD_FLOW]++;
+    }
+  return true;
+}
+
+//24
+bool cHardware4Stack::Inst_Search()
+{
+  ReadLabel();
+  GetLabel().Rotate(2, NUM_NOPS_4STACK);
+  cHeadMultiMem found_pos = FindLabel(0);
+  if(found_pos.GetPosition()-IP().GetPosition()==0)
+    {
+      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);
+    }
+  else
+    {
+      int search_size = found_pos.GetPosition() - IP().GetPosition() + GetLabel().GetSize() + 1;
+      Stack(STACK_BX).Push(search_size);
+      Stack(STACK_AX).Push(GetLabel().GetSize());
+      GetHead(HEAD_FLOW).Set(found_pos);
+    }  
+  
+  return true; 
+}
+
+//25
+bool cHardware4Stack::Inst_PushNext() 
+{
+  int stack_used = FindModifiedStack(STACK_AX);
+  int successor = (stack_used+1)%NUM_STACKS;
+  Stack(successor).Push(Stack(stack_used).Pop());
+  return true;
+}
+
+//26
+bool cHardware4Stack::Inst_PushPrevious() 
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  int predecessor = (stack_used+NUM_STACKS-1)%NUM_STACKS;
+  Stack(predecessor).Push(Stack(stack_used).Pop());
+  return true;
+}
+
+//27
+bool cHardware4Stack::Inst_PushComplement() 
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  int complement = FindComplementStack(stack_used);
+  Stack(complement).Push(Stack(stack_used).Pop());
+  return true;
+}
+
+//28
+bool cHardware4Stack::Inst_ValDelete()
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Pop();
+  return true;
+}
+
+//29
+bool cHardware4Stack::Inst_ValCopy()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Push(Stack(stack_used).Top());
+  return true;
+}
+
+//30
+bool cHardware4Stack::Inst_ForkThread()
+{
+  if (!ForkThread()) 
+    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  else
+    IP().Advance();
+  return true;
+}
+
+//31
+bool cHardware4Stack::Inst_IfLabel()
+{
+  ReadLabel();
+  GetLabel().Rotate(2, NUM_NOPS_4STACK);
+  if (GetLabel() != GetReadLabel())  IP().Advance();
+  return true;
+}
+
+//32
+bool cHardware4Stack::Inst_Increment()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(++value);
+  return true;
+}
+
+//33
+bool cHardware4Stack::Inst_Decrement()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(--value);
+  return true;
+}
+
+//34
+bool cHardware4Stack::Inst_Mod()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+  if (Stack(STACK_CX).Top() != 0) {
+    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;
+  }
+  return true;
+}
+
+//35
+bool cHardware4Stack::Inst_KillThread()
+{
+  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+  else AdvanceIP() = false;
+  return true;
+}
+
+//36
+bool cHardware4Stack::Inst_IO()
+{
+  const int stack_used = FindModifiedStack(STACK_BX);
+
+  // Do the "put" component
+  const int value_out = Stack(stack_used).Top();
+  organism->DoOutput(value_out);  // Check for tasks compleated.
+
+  // Do the "get" component
+  const int value_in = organism->GetNextInput();
+  Stack(stack_used).Push(value_in);
+  organism->DoInput(value_in);
+  return true;
+}
+
+int cHardware4Stack::FindFirstEmpty()
+{
+  bool OK=true;
+  const int current_mem_space = IP().GetMemSpace();
+
+  for(int x=1; x<NUM_MEMORY_SPACES; x++)
+    {
+      OK=true;
+      
+      int index = (current_mem_space+x) % NUM_MEMORY_SPACES;
+
+      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::isEmpty(int mem_space_used)
+{
+  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;
+}
+
+// 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()
+{
+  double mut_multiplier = 1;
+
+  return InjectParasite(mut_multiplier);
+}
+
+
+
+/*
+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;
+}
+
+*/

Copied: trunk/source/cpu/cHardware4Stack.h (from rev 299, trunk/source/cpu/hardware_4stack.hh)
===================================================================
--- trunk/source/cpu/hardware_4stack.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/cHardware4Stack.h	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,515 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef HARDWARE_4STACK_HH
+#define HARDWARE_4STACK_HH
+
+#include <iomanip>
+
+#ifndef CPU_MEMORY_HH
+#include "cCPUMemory.h"
+#endif
+#ifndef CPU_STACK_HH
+#include "cCPUStack.h"
+#endif
+#ifndef DEFS_HH
+#include "defs.hh"
+#endif
+#ifndef HEAD_MULTI_MEM_HH
+#include "head_multi_mem.hh"
+#endif
+#ifndef HARDWARE_BASE_HH
+#include "cHardwareBase.h"
+#endif
+#ifndef HARDWARE_4STACK_CONSTANTS_HH
+#include "hardware_4stack_constants.hh"
+#endif
+#ifndef HARDWARE_4STACK_THREAD_HH
+#include "cHardware4Stack_Thread.h"
+#endif
+#ifndef STRING_HH
+#include "string.hh"
+#endif
+#ifndef TARRAY_HH
+#include "tArray.hh"
+#endif
+
+class cInstSet;
+class cInstLibBase;
+class cOrganism;
+class cMutation;
+class cInjectGenotype;
+
+#ifdef SINGLE_IO_BUFFER   // For Single IOBuffer vs IOBuffer for each Thread
+# define IO_THREAD 0
+#else
+# define IO_THREAD cur_thread
+#endif
+
+/**
+ * Each organism may have a cHardware4Stack structure which keeps track of the
+ * current status of all the components of the simulated hardware.
+ *
+ * @see cHardware4Stack_Thread, cCPUStack, cCPUMemory, cInstSet
+ **/
+
+class cCodeLabel;
+class cCPUMemory;
+class cCPUStack; // aggregate
+class cHeadMultiMem; // access
+class cGenome;
+class cHardware4Stack_Thread; // access
+class cInjectGenotype;
+class cInstLib4Stack; // access
+class cInstruction;
+class cInstSet;
+class cOrganism;
+class cString; // aggregate
+template <class T> class tArray; // aggregate
+
+class cHardware4Stack : public cHardwareBase {
+public:
+  typedef bool (cHardware4Stack::*tHardware4StackMethod)();
+private:
+  static cInstLib4Stack *s_inst_slib;
+  static cInstLib4Stack *initInstLib(void);
+  tHardware4StackMethod *m_functions;
+private:
+  tArray<cCPUMemory> memory_array;          // Memory...
+  //cCPUStack global_stack;     // A stack that all threads share.
+  cCPUStack global_stacks[NUM_GLOBAL_STACKS];
+  //int thread_time_used;
+
+  tArray<cHardware4Stack_Thread> threads;
+  int thread_id_chart;
+  int cur_thread;
+
+  // Flags...
+  bool mal_active;         // Has an allocate occured since last dividehe?
+  //bool advance_ip;         // Should the IP advance after this instruction?
+
+  // Instruction costs...
+#ifdef INSTRUCTION_COSTS
+  tArray<int> inst_cost;
+  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);
+  explicit cHardware4Stack(const cHardware4Stack &);
+  ~cHardware4Stack() { ; }
+  void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
+  static cInstLibBase *GetInstLib();
+  static cString GetDefaultInstFilename() { return "inst_lib.4stack"; }
+  static void WriteDefaultInstSet() { ; }
+
+  void Reset();
+  void SingleProcess();
+  bool SingleProcess_PayCosts(const cInstruction & cur_inst);
+  bool SingleProcess_ExecuteInst(const cInstruction & cur_inst);
+  void ProcessBonusInst(const cInstruction & inst);
+  void LoadGenome(const cGenome & new_genome);
+
+  // --------  Helper methods  --------
+  bool OK();
+  void PrintStatus(std::ostream & fp);
+
+
+  // --------  Flag Accessors --------
+  bool GetMalActive() const   { return mal_active; }
+
+  // --------  Stack Manipulation...  --------
+  //void StackFlip();
+  inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
+  //inline void StackClear();
+  //inline void SwitchStack();
+  cString GetActiveStackID(int stackID) const;
+  //retrieves appropriate stack
+  inline cCPUStack & Stack(int stack_id); 
+  inline const cCPUStack & Stack(int stack_id) const;
+  inline cCPUStack & Stack(int stack_id, int in_thread);
+  inline const cCPUStack & Stack(int stack_id, int in_thread) const;
+
+  // --------  Head Manipulation (including IP)  --------
+  inline void SetActiveHead(const int new_head)
+  { threads[cur_thread].cur_head = (UCHAR) new_head; }
+
+  int GetCurHead() const { return threads[cur_thread].cur_head; }
+  
+  const cHeadMultiMem & GetHead(int head_id) const
+  { return threads[cur_thread].heads[head_id]; }
+  cHeadMultiMem & GetHead(int head_id) 
+  { return threads[cur_thread].heads[head_id];}
+  
+  const cHeadMultiMem & GetHead(int head_id, int thread) const
+  { return threads[thread].heads[head_id]; }
+  cHeadMultiMem & GetHead(int head_id, int thread) 
+  { return threads[thread].heads[head_id];}
+
+  const cHeadMultiMem & GetActiveHead() const { return GetHead(GetCurHead()); }
+  cHeadMultiMem & GetActiveHead() { return GetHead(GetCurHead()); }
+
+  void AdjustHeads();
+
+  inline const cHeadMultiMem & IP() const
+    { return threads[cur_thread].heads[HEAD_IP]; }
+  inline cHeadMultiMem & IP() { return threads[cur_thread].heads[HEAD_IP]; }
+
+  inline const cHeadMultiMem & IP(int thread) const
+  { return threads[thread].heads[HEAD_IP]; }
+  inline cHeadMultiMem & IP(int thread) 
+  { return threads[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);
+  const cCodeLabel & GetLabel() const 
+    { return threads[cur_thread].next_label; }
+  cCodeLabel & GetLabel() { return threads[cur_thread].next_label; }
+  const cCodeLabel & GetReadLabel() const
+    { return threads[cur_thread].read_label; }
+  cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
+
+
+  // --------  Register Manipulation  --------
+  //int Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
+  //int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
+
+  // --------  Memory Manipulation  --------}
+  inline cCPUMemory & GetMemory();
+  inline cCPUMemory & GetMemory(int mem_space);
+  inline const cCPUMemory & GetMemory(int mem_space) const;
+  inline const cCPUMemory & GetMemory() const;
+
+  // --------  Thread Manipulation  --------
+  bool ForkThread(); // Adds a new thread based off of cur_thread.
+  bool KillThread(); // Kill the current thread!
+  inline void PrevThread(); // Shift the current thread in use.
+  inline void NextThread();
+  inline void SetThread(int value);
+  inline cInjectGenotype * GetCurThreadOwner(); 
+  inline cInjectGenotype * GetThreadOwner(int in_thread);
+  inline void SetThreadOwner(cInjectGenotype * in_genotype);
+
+  // --------  Tests  --------
+
+  int TestParasite() const;
+
+  // --------  Accessors  --------
+  //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(); }
+
+  int GetThreadDist() const {
+    if (GetNumThreads() == 1) return 0;
+    return threads[0].heads[HEAD_IP].GetPosition() -
+      threads[1].heads[HEAD_IP].GetPosition();
+  }
+
+  // Complex label manipulation...
+  cHeadMultiMem FindLabel(int direction);
+  int FindLabel_Forward(const cCodeLabel & search_label,
+			  const cGenome & search_genome, int pos);
+  int FindLabel_Backward(const cCodeLabel & search_label,
+			  const cGenome & search_genome, int pos);
+  cHeadMultiMem FindLabel(const cCodeLabel & in_label, int direction);
+  cHeadMultiMem FindFullLabel(const cCodeLabel & in_label);
+
+  int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
+  bool InjectParasite(double mut_multiplier);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
+  int InjectThread(const cCodeLabel &, const cGenome &) { return -1; }
+  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, cHeadMultiMem & cur_head);
+  bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
+  bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
+  int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
+  void TriggerMutations_Body(int type, cCPUMemory & target_memory,
+			     cHeadMultiMem & cur_head);
+
+  void ReadInst(const int in_inst);
+
+  void SaveState(std::ostream & fp);
+  void LoadState(std::istream & fp);
+
+  //void InitInstSet(const cString & filename, cInstSet & inst_set);
+  cString ConvertToInstruction(int mem_space_used);
+
+
+private:
+ 
+ /////////---------- Instruction Helpers ------------//////////
+
+  int FindModifiedStack(int default_stack);
+  int FindModifiedHead(int default_head);
+  int FindComplementStack(int base_stack);
+
+  void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
+  bool Allocate_Necro(const int new_size);
+  bool Allocate_Random(const int old_size, const int new_size);
+  bool Allocate_Default(const int new_size);
+  bool Allocate_Main(const int allocated_size);
+
+  bool Divide_Main(const int mem_space_used, double mut_multiplier=1);
+  bool Divide_CheckViable(const int parent_size, const int child_size, const int mem_space);
+  void Divide_DoMutations(double mut_multiplier=1);
+  void Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code);
+  void Divide_TestFitnessMeasures();
+
+  bool HeadCopy_ErrorCorrect(double reduction);
+  bool Inst_HeadDivideMut(double mut_multiplier=1);
+
+public:
+  /////////---------- Instruction Library ------------//////////
+
+  //6
+  bool Inst_ShiftR();
+  //7
+  bool Inst_ShiftL();
+  //8
+  bool Inst_Val_Nand();
+  //9
+  bool Inst_Val_Add();
+  //10
+  bool Inst_Val_Sub();
+  //11
+  bool Inst_Val_Mult();
+  //12
+  bool Inst_Val_Div();
+  //13
+  bool Inst_SetMemory();
+  //14
+  bool Inst_Divide();
+  //15
+  bool Inst_HeadRead();
+  //16
+  bool Inst_HeadWrite();
+  //??
+  bool Inst_HeadCopy();
+  //17
+  bool Inst_IfEqual();
+  //18
+  bool Inst_IfNotEqual();
+  //19
+  bool Inst_IfLess();
+  //20
+  bool Inst_IfGreater();
+  //21
+  bool Inst_HeadPush();
+  //22
+  bool Inst_HeadPop();
+  //23
+  bool Inst_HeadMove();
+  //24
+  bool Inst_Search();
+  //25
+  bool Inst_PushNext();
+  //26
+  bool Inst_PushPrevious();
+  //27
+  bool Inst_PushComplement();
+  //28
+  bool Inst_ValDelete();
+  //29
+  bool Inst_ValCopy();
+  //30
+  bool Inst_ForkThread();
+  //31
+  bool Inst_IfLabel();
+  //32
+  bool Inst_Increment();
+  //33
+  bool Inst_Decrement();
+  //34
+  bool Inst_Mod();
+  //35 
+  bool Inst_KillThread();
+  //36
+  bool Inst_IO();
+  //37
+  bool Inst_Inject();
+  
+  /*
+  bool Inst_InjectRand();
+  bool Inst_InjectThread();
+  bool Inst_Repro();
+  */
+ 
+};
+
+
+//////////////////
+//  cHardware4Stack
+//////////////////
+
+//Not used, but here to satisfy the requirements of HardwareBase
+inline const cCPUMemory & cHardware4Stack::GetMemory() const
+{
+  return memory_array[0];
+}
+
+//Not used, but here to satisfy the requirements of HardwareBase 
+inline cCPUMemory & cHardware4Stack::GetMemory()
+{
+  return memory_array[0];
+}
+
+inline const cCPUMemory & cHardware4Stack::GetMemory(int mem_space) const
+{
+  if(mem_space >= NUM_MEMORY_SPACES)
+    mem_space %= NUM_MEMORY_SPACES;
+  return memory_array[mem_space];
+}
+
+inline cCPUMemory & cHardware4Stack::GetMemory(int mem_space)
+{
+ if(mem_space >= NUM_MEMORY_SPACES)
+    mem_space %= NUM_MEMORY_SPACES;
+  return memory_array[mem_space];
+}
+
+inline void cHardware4Stack::NextThread()
+{
+  cur_thread++;
+  if (cur_thread >= GetNumThreads()) cur_thread = 0;
+}
+
+inline void cHardware4Stack::PrevThread()
+{
+  if (cur_thread == 0) cur_thread = GetNumThreads() - 1;
+  else cur_thread--;
+}
+
+inline void cHardware4Stack::SetThread(int value)
+{
+  if (value>=0 && value < GetNumThreads())
+    cur_thread=value;
+}
+
+inline cInjectGenotype * cHardware4Stack::GetCurThreadOwner() 
+{ 
+  return threads[cur_thread].owner; 
+}
+
+inline cInjectGenotype * cHardware4Stack::GetThreadOwner(int thread) 
+{ 
+  return threads[thread].owner; 
+}
+
+inline void cHardware4Stack::SetThreadOwner(cInjectGenotype * in_genotype)
+{ 
+  threads[cur_thread].owner = in_genotype; 
+}
+
+/*inline void cHardware4Stack::StackFlip()
+{
+  if (threads[cur_thread].cur_stack == 0) {
+    threads[cur_thread].stack.Flip();
+  } else {
+    global_stack.Flip();
+  }
+}*/
+
+inline int cHardware4Stack::GetStack(int depth, int stack_id, int in_thread) const
+{
+  if(stack_id<0 || stack_id>NUM_STACKS) stack_id=0;
+  
+  if(in_thread==-1)
+    in_thread=cur_thread;
+  
+  return Stack(stack_id, in_thread).Get(depth);
+}
+
+//inline void cHardware4Stack::StackClear()
+//{
+  
+  //if (threads[cur_thread].cur_stack == 0) {
+  //  threads[cur_thread].stack.Clear();
+  //} else {
+  //  global_stack.Clear();
+  //}
+//}
+
+//inline void cHardware4Stack::SwitchStack()
+//{
+//  threads[cur_thread].cur_stack++;
+//  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
+//}
+
+inline cCPUStack& cHardware4Stack::Stack(int stack_id)
+{
+  if(stack_id >= NUM_STACKS)
+    {
+      stack_id=0;
+    }
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[cur_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
+inline const cCPUStack& cHardware4Stack::Stack(int stack_id) const 
+{
+  if(stack_id >= NUM_STACKS)
+    {
+      stack_id=0;
+    }
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[cur_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
+inline cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) 
+{
+  if(stack_id >= NUM_STACKS)
+      stack_id=0;
+  if(in_thread >= threads.GetSize())
+      in_thread=cur_thread;
+
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[in_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
+inline const cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) const 
+{
+  if(stack_id >= NUM_STACKS)
+      stack_id=0;
+  if(in_thread >= threads.GetSize())
+      in_thread=cur_thread;
+
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[in_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
+#endif

Copied: trunk/source/cpu/cHardware4Stack_Thread.cc (from rev 298, trunk/source/cpu/hardware_4stack_thread.cc)
===================================================================
--- trunk/source/cpu/hardware_4stack_thread.cc	2005-08-29 18:54:25 UTC (rev 298)
+++ trunk/source/cpu/cHardware4Stack_Thread.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,110 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef HARDWARE_4STACK_THREAD_HH
+#include "cHardware4Stack_Thread.h"
+#endif
+
+using namespace std;
+
+/////////////////////////
+//  cHardware4Stack_Thread
+/////////////////////////
+
+cHardware4Stack_Thread::cHardware4Stack_Thread(cHardwareBase * in_hardware, int _id)
+{
+  Reset(in_hardware, _id);
+}
+
+cHardware4Stack_Thread::cHardware4Stack_Thread(const cHardware4Stack_Thread & in_thread, int _id)
+{
+   id = _id;
+   if (id == -1) id = in_thread.id;
+   for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
+     local_stacks[i] = in_thread.local_stacks[i];
+   }
+   for (int i = 0; i < NUM_HEADS; i++) {
+     heads[i] = in_thread.heads[i];
+   }
+   owner = in_thread.owner;
+}
+
+cHardware4Stack_Thread::~cHardware4Stack_Thread() {}
+
+void cHardware4Stack_Thread::operator=(const cHardware4Stack_Thread & in_thread)
+{
+  id = in_thread.id;
+  for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
+    local_stacks[i] = in_thread.local_stacks[i];
+  }
+  for (int i = 0; i < NUM_HEADS; i++) {
+    heads[i] = in_thread.heads[i];
+  }
+  owner = in_thread.owner;
+}
+
+void cHardware4Stack_Thread::Reset(cHardwareBase * in_hardware, int _id)
+{
+  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(0, in_hardware);
+
+  cur_head = HEAD_IP;
+  read_label.Clear();
+  next_label.Clear();
+  owner = NULL;
+}
+
+void cHardware4Stack_Thread::SaveState(ostream & fp){
+  assert(fp.good());
+  fp << "cHardware4Stack_Thread" << endl;
+
+  // stacks (NOT WORKING! -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].SaveState(fp);
+  }
+
+  // heads (@TCC does not handle parasites!!!)
+  for( int i=0; i<NUM_HEADS; ++i ){
+    fp<<heads[i].GetPosition()<<endl;
+  }
+
+  fp<<"|"; // marker
+  fp<<cur_head;
+  fp<<endl;
+
+  // Code labels
+  read_label.SaveState(fp);
+  next_label.SaveState(fp);
+}
+
+void cHardware4Stack_Thread::LoadState(istream & fp){
+  assert(fp.good());
+  cString foo;
+  fp >> foo;
+  assert( foo == "cHardware4Stack_Thread");
+
+  // stacks (NOT WORKING!  -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].LoadState(fp);
+  }
+
+  // heads (@TCC does not handle parasites!!!)
+  for( int i=0; i<NUM_HEADS; ++i ){
+    int pos;
+    fp>>pos;
+    heads[i].AbsSet(pos);
+  }
+
+  char marker; fp >> marker; assert( marker == '|' );
+  /* YIKES!  data loss below: */ 
+
+  // Code labels
+  read_label.LoadState(fp);
+  next_label.LoadState(fp);
+}

Copied: trunk/source/cpu/cHardware4Stack_Thread.h (from rev 299, trunk/source/cpu/hardware_4stack_thread.hh)

Copied: trunk/source/cpu/cHardwareBase.cc (from rev 298, trunk/source/cpu/hardware_base.cc)
===================================================================
--- trunk/source/cpu/hardware_base.cc	2005-08-29 18:54:25 UTC (rev 298)
+++ trunk/source/cpu/cHardwareBase.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,61 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#include "cHardwareBase.h"
+
+#include "inst_set.hh"
+
+using namespace std;
+
+int cHardwareBase::instance_count(0);
+
+cHardwareBase::cHardwareBase(cOrganism * in_organism, cInstSet * in_inst_set)
+  : organism(in_organism)
+  , inst_set(in_inst_set)
+  , viewer_lock(-1)
+  , m_tracer(NULL)
+{
+  assert(inst_set->OK());
+  assert(organism != NULL);
+
+  instance_count++;
+}
+
+cHardwareBase::~cHardwareBase()
+{
+  instance_count--;
+}
+
+void cHardwareBase::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
+{
+  assert(inst_set->OK());
+  assert(new_organism != NULL);
+
+  organism    = new_organism;
+  inst_set    = in_inst_set;
+  viewer_lock = -1;
+}
+
+bool cHardwareBase::Inst_Nop()          // Do Nothing.
+{
+  return true;
+}
+
+
+int cHardwareBase::GetNumInst()
+{
+  assert(inst_set != NULL);
+  return inst_set->GetSize();
+}
+
+
+cInstruction cHardwareBase::GetRandomInst()
+{
+  assert(inst_set != NULL);
+  return inst_set->GetRandomInst();
+}
+

Copied: trunk/source/cpu/cHardwareBase.h (from rev 298, trunk/source/cpu/hardware_base.hh)

Copied: trunk/source/cpu/cHardwareCPU.cc (from rev 299, trunk/source/cpu/hardware_cpu.cc)
===================================================================
--- trunk/source/cpu/hardware_cpu.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/cHardwareCPU.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,3463 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2004 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#include "cHardwareCPU.h"
+
+#include "config.hh"
+#include "cCPUTestInfo.h"
+#include "functions.hh"
+#include "genome_util.hh"
+#include "genotype.hh"
+#include "hardware_tracer.hh"
+#include "hardware_tracer_cpu.hh"
+#include "inst_lib_cpu.hh"
+#include "inst_set.hh"
+#include "mutation.hh"
+#include "mutation_lib.hh"
+#include "mutation_macros.hh"
+#include "organism.hh"
+#include "phenotype.hh"
+#include "string_util.hh"
+#include "test_cpu.hh"
+
+#include <limits.h>
+#include <fstream>
+
+using namespace std;
+
+
+///////////////
+//  cHardwareCPU
+///////////////
+
+const cInstruction cInstLibCPU::inst_error(255);
+const cInstruction cInstLibCPU::inst_default(0);
+cInstLibCPU *cHardwareCPU::GetInstLib(){ return s_inst_slib; }
+
+cInstLibCPU *cHardwareCPU::s_inst_slib = cHardwareCPU::initInstLib();
+cInstLibCPU *cHardwareCPU::initInstLib(void){
+  struct cNOPEntryCPU {
+    cString name;
+    int nop_mod;
+    cNOPEntryCPU(const cString &name, int nop_mod)
+      : name(name), nop_mod(nop_mod) {}
+  };
+  static const cNOPEntryCPU s_n_array[] = {
+    cNOPEntryCPU("nop-A", REG_AX),
+    cNOPEntryCPU("nop-B", REG_BX),
+    cNOPEntryCPU("nop-C", REG_CX),
+    cNOPEntryCPU("nop-D", REG_DX)
+  };
+
+  struct cInstEntryCPU { 
+    const cString name;
+    const tHardwareCPUMethod function;
+    const bool is_default;
+    const cString desc;
+
+    cInstEntryCPU(const cString & _name, tHardwareCPUMethod _fun,
+		  bool _def=false, const cString & _desc="")
+      : name(_name), function(_fun), is_default(_def), desc(_desc) {}
+  };
+  static const cInstEntryCPU s_f_array[] = {
+    /*
+    Note: all entries of cNOPEntryCPU s_n_array must have corresponding
+    in the same order in cInstEntryCPU s_f_array, and these entries must
+    be the first elements of s_f_array.
+    */
+    cInstEntryCPU("nop-A",     &cHardwareCPU::Inst_Nop, true,
+		  "No-operation instruction; modifies other instructions"),
+    cInstEntryCPU("nop-B",     &cHardwareCPU::Inst_Nop, true,
+		  "No-operation instruction; modifies other instructions"),
+    cInstEntryCPU("nop-C",     &cHardwareCPU::Inst_Nop, true,
+		  "No-operation instruction; modifies other instructions"),
+    cInstEntryCPU("nop-D",     &cHardwareCPU::Inst_Nop, true,
+		  "No-operation instruction; modifies other instructions"),
+
+    cInstEntryCPU("NULL",      &cHardwareCPU::Inst_Nop, false,
+		  "True no-operation instruction: does nothing"),
+    cInstEntryCPU("nop-X",     &cHardwareCPU::Inst_Nop, false,
+		  "True no-operation instruction: does nothing"),
+    cInstEntryCPU("if-equ-0",  &cHardwareCPU::Inst_If0, false,
+		  "Execute next instruction if ?BX?==0, else skip it"),
+    cInstEntryCPU("if-not-0",  &cHardwareCPU::Inst_IfNot0, false,
+		  "Execute next instruction if ?BX?!=0, else skip it"),
+    cInstEntryCPU("if-n-equ",  &cHardwareCPU::Inst_IfNEqu, true,
+		  "Execute next instruction if ?BX?!=?CX?, else skip it"),
+    cInstEntryCPU("if-equ",    &cHardwareCPU::Inst_IfEqu, false,
+		  "Execute next instruction if ?BX?==?CX?, else skip it"),
+    cInstEntryCPU("if-grt-0",  &cHardwareCPU::Inst_IfGr0),
+    cInstEntryCPU("if-grt",    &cHardwareCPU::Inst_IfGr),
+    cInstEntryCPU("if->=-0",   &cHardwareCPU::Inst_IfGrEqu0),
+    cInstEntryCPU("if->=",     &cHardwareCPU::Inst_IfGrEqu),
+    cInstEntryCPU("if-les-0",  &cHardwareCPU::Inst_IfLess0),
+    cInstEntryCPU("if-less",   &cHardwareCPU::Inst_IfLess, true,
+		  "Execute next instruction if ?BX? < ?CX?, else skip it"),
+    cInstEntryCPU("if-<=-0",   &cHardwareCPU::Inst_IfLsEqu0),
+    cInstEntryCPU("if-<=",     &cHardwareCPU::Inst_IfLsEqu),
+    cInstEntryCPU("if-A!=B",   &cHardwareCPU::Inst_IfANotEqB),
+    cInstEntryCPU("if-B!=C",   &cHardwareCPU::Inst_IfBNotEqC),
+    cInstEntryCPU("if-A!=C",   &cHardwareCPU::Inst_IfANotEqC),
+    cInstEntryCPU("if-bit-1",  &cHardwareCPU::Inst_IfBit1),
+
+    cInstEntryCPU("jump-f",    &cHardwareCPU::Inst_JumpF),
+    cInstEntryCPU("jump-b",    &cHardwareCPU::Inst_JumpB),
+    cInstEntryCPU("jump-p",    &cHardwareCPU::Inst_JumpP),
+    cInstEntryCPU("jump-slf",  &cHardwareCPU::Inst_JumpSelf),
+    cInstEntryCPU("call",      &cHardwareCPU::Inst_Call),
+    cInstEntryCPU("return",    &cHardwareCPU::Inst_Return),
+
+    cInstEntryCPU("pop",       &cHardwareCPU::Inst_Pop, true,
+		  "Remove top number from stack and place into ?BX?"),
+    cInstEntryCPU("push",      &cHardwareCPU::Inst_Push, true,
+		  "Copy number from ?BX? and place it into the stack"),
+    cInstEntryCPU("swap-stk",  &cHardwareCPU::Inst_SwitchStack, true,
+		  "Toggle which stack is currently being used"),
+    cInstEntryCPU("flip-stk",  &cHardwareCPU::Inst_FlipStack),
+    cInstEntryCPU("swap",      &cHardwareCPU::Inst_Swap, true,
+		  "Swap the contents of ?BX? with ?CX?"),
+    cInstEntryCPU("swap-AB",   &cHardwareCPU::Inst_SwapAB),
+    cInstEntryCPU("swap-BC",   &cHardwareCPU::Inst_SwapBC),
+    cInstEntryCPU("swap-AC",   &cHardwareCPU::Inst_SwapAC),
+    cInstEntryCPU("copy-reg",  &cHardwareCPU::Inst_CopyReg),
+    cInstEntryCPU("set_A=B",   &cHardwareCPU::Inst_CopyRegAB),
+    cInstEntryCPU("set_A=C",   &cHardwareCPU::Inst_CopyRegAC),
+    cInstEntryCPU("set_B=A",   &cHardwareCPU::Inst_CopyRegBA),
+    cInstEntryCPU("set_B=C",   &cHardwareCPU::Inst_CopyRegBC),
+    cInstEntryCPU("set_C=A",   &cHardwareCPU::Inst_CopyRegCA),
+    cInstEntryCPU("set_C=B",   &cHardwareCPU::Inst_CopyRegCB),
+    cInstEntryCPU("reset",     &cHardwareCPU::Inst_Reset),
+
+    cInstEntryCPU("pop-A",     &cHardwareCPU::Inst_PopA),
+    cInstEntryCPU("pop-B",     &cHardwareCPU::Inst_PopB),
+    cInstEntryCPU("pop-C",     &cHardwareCPU::Inst_PopC),
+    cInstEntryCPU("push-A",    &cHardwareCPU::Inst_PushA),
+    cInstEntryCPU("push-B",    &cHardwareCPU::Inst_PushB),
+    cInstEntryCPU("push-C",    &cHardwareCPU::Inst_PushC),
+
+    cInstEntryCPU("shift-r",   &cHardwareCPU::Inst_ShiftR, true,
+		  "Shift bits in ?BX? right by one (divide by two)"),
+    cInstEntryCPU("shift-l",   &cHardwareCPU::Inst_ShiftL, true,
+		  "Shift bits in ?BX? left by one (multiply by two)"),
+    cInstEntryCPU("bit-1",     &cHardwareCPU::Inst_Bit1),
+    cInstEntryCPU("set-num",   &cHardwareCPU::Inst_SetNum),
+    cInstEntryCPU("val-grey",  &cHardwareCPU::Inst_ValGrey),
+    cInstEntryCPU("val-dir",   &cHardwareCPU::Inst_ValDir),
+    cInstEntryCPU("val-add-p", &cHardwareCPU::Inst_ValAddP),
+    cInstEntryCPU("val-fib",   &cHardwareCPU::Inst_ValFib),
+    cInstEntryCPU("val-poly-c",&cHardwareCPU::Inst_ValPolyC),
+    cInstEntryCPU("inc",       &cHardwareCPU::Inst_Inc, true,
+		  "Increment ?BX? by one"),
+    cInstEntryCPU("dec",       &cHardwareCPU::Inst_Dec, true,
+		  "Decrement ?BX? by one"),
+    cInstEntryCPU("zero",      &cHardwareCPU::Inst_Zero, false,
+		  "Set ?BX? to zero"),
+    cInstEntryCPU("neg",       &cHardwareCPU::Inst_Neg),
+    cInstEntryCPU("square",    &cHardwareCPU::Inst_Square),
+    cInstEntryCPU("sqrt",      &cHardwareCPU::Inst_Sqrt),
+    cInstEntryCPU("not",       &cHardwareCPU::Inst_Not),
+    cInstEntryCPU("minus-17",  &cHardwareCPU::Inst_Minus17),
+    
+    cInstEntryCPU("add",       &cHardwareCPU::Inst_Add, true,
+		  "Add BX to CX and place the result in ?BX?"),
+    cInstEntryCPU("sub",       &cHardwareCPU::Inst_Sub, true,
+		  "Subtract CX from BX and place the result in ?BX?"),
+    cInstEntryCPU("mult",      &cHardwareCPU::Inst_Mult, false,
+		  "Multiple BX by CX and place the result in ?BX?"),
+    cInstEntryCPU("div",       &cHardwareCPU::Inst_Div, false,
+		  "Divide BX by CX and place the result in ?BX?"),
+    cInstEntryCPU("mod",       &cHardwareCPU::Inst_Mod),
+    cInstEntryCPU("nand",      &cHardwareCPU::Inst_Nand, true,
+		  "Nand BX by CX and place the result in ?BX?"),
+    cInstEntryCPU("nor",       &cHardwareCPU::Inst_Nor),
+    cInstEntryCPU("and",       &cHardwareCPU::Inst_And),
+    cInstEntryCPU("order",     &cHardwareCPU::Inst_Order),
+    cInstEntryCPU("xor",       &cHardwareCPU::Inst_Xor),
+    
+    cInstEntryCPU("copy",      &cHardwareCPU::Inst_Copy),
+    cInstEntryCPU("read",      &cHardwareCPU::Inst_ReadInst),
+    cInstEntryCPU("write",     &cHardwareCPU::Inst_WriteInst),
+    cInstEntryCPU("stk-read",  &cHardwareCPU::Inst_StackReadInst),
+    cInstEntryCPU("stk-writ",  &cHardwareCPU::Inst_StackWriteInst),
+    
+    cInstEntryCPU("compare",   &cHardwareCPU::Inst_Compare),
+    cInstEntryCPU("if-n-cpy",  &cHardwareCPU::Inst_IfNCpy),
+    cInstEntryCPU("allocate",  &cHardwareCPU::Inst_Allocate),
+    cInstEntryCPU("divide",    &cHardwareCPU::Inst_Divide),
+    cInstEntryCPU("c-alloc",   &cHardwareCPU::Inst_CAlloc),
+    cInstEntryCPU("c-divide",  &cHardwareCPU::Inst_CDivide),
+    cInstEntryCPU("inject",    &cHardwareCPU::Inst_Inject),
+    cInstEntryCPU("inject-r",  &cHardwareCPU::Inst_InjectRand),
+    cInstEntryCPU("search-f",  &cHardwareCPU::Inst_SearchF),
+    cInstEntryCPU("search-b",  &cHardwareCPU::Inst_SearchB),
+    cInstEntryCPU("mem-size",  &cHardwareCPU::Inst_MemSize),
+
+    cInstEntryCPU("get",       &cHardwareCPU::Inst_TaskGet),
+    cInstEntryCPU("stk-get",   &cHardwareCPU::Inst_TaskStackGet),
+    cInstEntryCPU("stk-load",  &cHardwareCPU::Inst_TaskStackLoad),
+    cInstEntryCPU("put",       &cHardwareCPU::Inst_TaskPut),
+    cInstEntryCPU("IO",        &cHardwareCPU::Inst_TaskIO, true,
+		  "Output ?BX?, and input new number back into ?BX?"),
+
+    cInstEntryCPU("send",      &cHardwareCPU::Inst_Send),
+    cInstEntryCPU("receive",   &cHardwareCPU::Inst_Receive),
+    cInstEntryCPU("sense",     &cHardwareCPU::Inst_Sense),
+
+    cInstEntryCPU("donate-rnd",  &cHardwareCPU::Inst_DonateRandom),
+    cInstEntryCPU("donate-kin",  &cHardwareCPU::Inst_DonateKin),
+    cInstEntryCPU("donate-edt",  &cHardwareCPU::Inst_DonateEditDist),
+    cInstEntryCPU("donate-NUL",  &cHardwareCPU::Inst_DonateNULL),
+
+    cInstEntryCPU("rotate-l",  &cHardwareCPU::Inst_RotateL),
+    cInstEntryCPU("rotate-r",  &cHardwareCPU::Inst_RotateR),
+
+    cInstEntryCPU("set-cmut",  &cHardwareCPU::Inst_SetCopyMut),
+    cInstEntryCPU("mod-cmut",  &cHardwareCPU::Inst_ModCopyMut),
+
+    // Threading instructions
+    cInstEntryCPU("fork-th",   &cHardwareCPU::Inst_ForkThread),
+    cInstEntryCPU("kill-th",   &cHardwareCPU::Inst_KillThread),
+    cInstEntryCPU("id-th",     &cHardwareCPU::Inst_ThreadID),
+
+    // Head-based instructions
+    cInstEntryCPU("h-alloc",   &cHardwareCPU::Inst_MaxAlloc, true,
+		  "Allocate maximum allowed space"),
+    cInstEntryCPU("h-divide",  &cHardwareCPU::Inst_HeadDivide, true,
+		  "Divide code between read and write heads."),
+    cInstEntryCPU("h-read",    &cHardwareCPU::Inst_HeadRead),
+    cInstEntryCPU("h-write",   &cHardwareCPU::Inst_HeadWrite),
+    cInstEntryCPU("h-copy",    &cHardwareCPU::Inst_HeadCopy, true,
+		  "Copy from read-head to write-head; advance both"),
+    cInstEntryCPU("h-search",  &cHardwareCPU::Inst_HeadSearch, true,
+		  "Find complement template and make with flow head"),
+    cInstEntryCPU("h-push",    &cHardwareCPU::Inst_HeadPush),
+    cInstEntryCPU("h-pop",     &cHardwareCPU::Inst_HeadPop),
+    cInstEntryCPU("set-head",  &cHardwareCPU::Inst_SetHead),
+    cInstEntryCPU("adv-head",  &cHardwareCPU::Inst_AdvanceHead),
+    cInstEntryCPU("mov-head",  &cHardwareCPU::Inst_MoveHead, true,
+		  "Move head ?IP? to the flow head"),
+    cInstEntryCPU("jmp-head",  &cHardwareCPU::Inst_JumpHead, true,
+		  "Move head ?IP? by amount in CX register; CX = old pos."),
+    cInstEntryCPU("get-head",  &cHardwareCPU::Inst_GetHead, true,
+		  "Copy the position of the ?IP? head into CX"),
+    cInstEntryCPU("if-label",  &cHardwareCPU::Inst_IfLabel, true,
+		  "Execute next if we copied complement of attached label"),
+    cInstEntryCPU("if-label2",  &cHardwareCPU::Inst_IfLabel2, true,
+		  "If copied label compl., exec next inst; else SKIP W/NOPS"),
+    cInstEntryCPU("set-flow",  &cHardwareCPU::Inst_SetFlow, true,
+		  "Set flow-head to position in ?CX?"),
+
+    cInstEntryCPU("h-copy2",    &cHardwareCPU::Inst_HeadCopy2),
+    cInstEntryCPU("h-copy3",    &cHardwareCPU::Inst_HeadCopy3),
+    cInstEntryCPU("h-copy4",    &cHardwareCPU::Inst_HeadCopy4),
+    cInstEntryCPU("h-copy5",    &cHardwareCPU::Inst_HeadCopy5),
+    cInstEntryCPU("h-copy6",    &cHardwareCPU::Inst_HeadCopy6),
+    cInstEntryCPU("h-copy7",    &cHardwareCPU::Inst_HeadCopy7),
+    cInstEntryCPU("h-copy8",    &cHardwareCPU::Inst_HeadCopy8),
+    cInstEntryCPU("h-copy9",    &cHardwareCPU::Inst_HeadCopy9),
+    cInstEntryCPU("h-copy10",   &cHardwareCPU::Inst_HeadCopy10),
+
+    cInstEntryCPU("divide-sex",    &cHardwareCPU::Inst_HeadDivideSex),
+    cInstEntryCPU("divide-asex",   &cHardwareCPU::Inst_HeadDivideAsex),
+
+    cInstEntryCPU("div-sex",    &cHardwareCPU::Inst_HeadDivideSex),
+    cInstEntryCPU("div-asex",   &cHardwareCPU::Inst_HeadDivideAsex),
+    cInstEntryCPU("div-asex-w",   &cHardwareCPU::Inst_HeadDivideAsexWait),
+    cInstEntryCPU("div-sex-MS",   &cHardwareCPU::Inst_HeadDivideMateSelect),
+
+    cInstEntryCPU("h-divide1",      &cHardwareCPU::Inst_HeadDivide1),
+    cInstEntryCPU("h-divide2",      &cHardwareCPU::Inst_HeadDivide2),
+    cInstEntryCPU("h-divide3",      &cHardwareCPU::Inst_HeadDivide3),
+    cInstEntryCPU("h-divide4",      &cHardwareCPU::Inst_HeadDivide4),
+    cInstEntryCPU("h-divide5",      &cHardwareCPU::Inst_HeadDivide5),
+    cInstEntryCPU("h-divide6",      &cHardwareCPU::Inst_HeadDivide6),
+    cInstEntryCPU("h-divide7",      &cHardwareCPU::Inst_HeadDivide7),
+    cInstEntryCPU("h-divide8",      &cHardwareCPU::Inst_HeadDivide8),
+    cInstEntryCPU("h-divide9",      &cHardwareCPU::Inst_HeadDivide9),
+    cInstEntryCPU("h-divide10",     &cHardwareCPU::Inst_HeadDivide10),
+    cInstEntryCPU("h-divide16",     &cHardwareCPU::Inst_HeadDivide16),
+    cInstEntryCPU("h-divide32",     &cHardwareCPU::Inst_HeadDivide32),
+    cInstEntryCPU("h-divide50",     &cHardwareCPU::Inst_HeadDivide50),
+    cInstEntryCPU("h-divide100",    &cHardwareCPU::Inst_HeadDivide100),
+    cInstEntryCPU("h-divide500",    &cHardwareCPU::Inst_HeadDivide500),
+    cInstEntryCPU("h-divide1000",   &cHardwareCPU::Inst_HeadDivide1000),
+    cInstEntryCPU("h-divide5000",   &cHardwareCPU::Inst_HeadDivide5000),
+    cInstEntryCPU("h-divide10000",  &cHardwareCPU::Inst_HeadDivide10000),
+    cInstEntryCPU("h-divide50000",  &cHardwareCPU::Inst_HeadDivide50000),
+    cInstEntryCPU("h-divide0.5",    &cHardwareCPU::Inst_HeadDivide0_5),
+    cInstEntryCPU("h-divide0.1",    &cHardwareCPU::Inst_HeadDivide0_1),
+    cInstEntryCPU("h-divide0.05",   &cHardwareCPU::Inst_HeadDivide0_05),
+    cInstEntryCPU("h-divide0.01",   &cHardwareCPU::Inst_HeadDivide0_01),
+    cInstEntryCPU("h-divide0.001",  &cHardwareCPU::Inst_HeadDivide0_001),
+
+    // High-level instructions
+    cInstEntryCPU("repro",      &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-A",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-B",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-C",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-D",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-E",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-F",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-G",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-H",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-I",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-J",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-K",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-L",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-M",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-N",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-O",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-P",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-Q",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-R",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-S",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-T",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-U",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-V",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-W",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-X",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-Y",    &cHardwareCPU::Inst_Repro),
+    cInstEntryCPU("repro-Z",    &cHardwareCPU::Inst_Repro),
+
+    // Suicide
+    cInstEntryCPU("kazi",	&cHardwareCPU::Inst_Kazi),
+    cInstEntryCPU("die",	&cHardwareCPU::Inst_Die),
+
+
+
+    // Placebo instructions
+    // nop-x (included with nops)
+    cInstEntryCPU("skip",      &cHardwareCPU::Inst_Skip)
+  };
+
+  const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
+
+  static cString n_names[n_size];
+  static int nop_mods[n_size];
+  for (int i = 0; i < n_size; i++){
+    n_names[i] = s_n_array[i].name;
+    nop_mods[i] = s_n_array[i].nop_mod;
+  }
+
+  const int f_size = sizeof(s_f_array)/sizeof(cInstEntryCPU);
+  static cString f_names[f_size];
+  static tHardwareCPUMethod functions[f_size];
+  for (int i = 0; i < f_size; i++){
+    f_names[i] = s_f_array[i].name;
+    functions[i] = s_f_array[i].function;
+  }
+
+  cInstLibCPU *inst_lib = new cInstLibCPU(
+    n_size,
+    f_size,
+    n_names,
+    f_names,
+    nop_mods,
+    functions
+  );
+
+  return inst_lib;
+}
+
+cHardwareCPU::cHardwareCPU(cOrganism * in_organism, cInstSet * in_inst_set)
+  : cHardwareBase(in_organism, in_inst_set)
+{
+  /* FIXME:  reorganize storage of m_functions.  -- kgn */
+  m_functions = s_inst_slib->GetFunctions();
+  /**/
+  memory = in_organism->GetGenome();  // Initialize memory...
+  Reset();                            // Setup the rest of the hardware...
+}
+
+
+cHardwareCPU::cHardwareCPU(const cHardwareCPU &hardware_cpu)
+: cHardwareBase(hardware_cpu.organism, hardware_cpu.inst_set)
+, m_functions(hardware_cpu.m_functions)
+, memory(hardware_cpu.memory)
+, global_stack(hardware_cpu.global_stack)
+, thread_time_used(hardware_cpu.thread_time_used)
+, threads(hardware_cpu.threads)
+, thread_id_chart(hardware_cpu.thread_id_chart)
+, cur_thread(hardware_cpu.cur_thread)
+, mal_active(hardware_cpu.mal_active)
+, advance_ip(hardware_cpu.advance_ip)
+#ifdef INSTRUCTION_COSTS
+, inst_cost(hardware_cpu.inst_cost)
+, inst_ft_cost(hardware_cpu.inst_ft_cost)
+#endif
+{
+}
+
+
+cHardwareCPU::~cHardwareCPU()
+{
+}
+
+
+void cHardwareCPU::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
+{
+  cHardwareBase::Recycle(new_organism, in_inst_set);
+  memory = new_organism->GetGenome();
+  Reset();
+}
+
+
+void cHardwareCPU::Reset()
+{
+  global_stack.Clear();
+  thread_time_used = 0;
+
+  // We want to reset to have a single thread.
+  threads.Resize(1);
+
+  // Reset that single thread.
+  threads[0].Reset(this, 0);
+  thread_id_chart = 1; // Mark only the first thread as taken...
+  cur_thread = 0;
+
+  mal_active = false;
+
+#ifdef INSTRUCTION_COSTS
+  // instruction cost arrays
+  const int num_inst_cost = GetNumInst();
+  inst_cost.Resize(num_inst_cost);
+  inst_ft_cost.Resize(num_inst_cost);
+
+  for (int i = 0; i < num_inst_cost; i++) {
+    inst_cost[i] = GetInstSet().GetCost(cInstruction(i));
+    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
+  }
+#endif
+
+}
+
+
+// This function processes the very next command in the genome, and is made
+// to be as optimized as possible.  This is the heart of avida.
+
+void cHardwareCPU::SingleProcess()
+{
+  // Mark this organism as running...
+  organism->SetRunning(true);
+
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.IncTimeUsed();
+  const int num_threads = GetNumThreads();
+  if (num_threads > 1) thread_time_used++;
+
+  // 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) ?
+    num_threads : 1;
+  
+  for (int i = 0; i < num_inst_exec; i++) {
+    // Setup the hardware for the next instruction to be executed.
+    NextThread();
+    advance_ip = true;
+    IP().Adjust();
+
+#ifdef BREAKPOINTS
+    if (IP().FlagBreakpoint() == true) {
+      organism->DoBreakpoint();
+    }
+#endif
+    
+    // Print the status of this CPU at each step...
+    if (m_tracer != NULL) {
+      if (cHardwareTracer_CPU * tracer
+          = dynamic_cast<cHardwareTracer_CPU *>(m_tracer)
+      ){
+        tracer->TraceHardware_CPU(*this);
+      }
+    }
+    
+    // Find the instruction to be executed
+    const cInstruction & cur_inst = IP().GetInst();
+
+    // Test if costs have been paid and it is okay to execute this now...
+    const bool exec = SingleProcess_PayCosts(cur_inst);
+
+    // Now execute the instruction...
+    if (exec == true) {
+      SingleProcess_ExecuteInst(cur_inst);
+
+      // 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 exec
+    
+  } // Previous was executed once for each thread...
+
+  // Kill creatures who have reached their max num of instructions executed
+  const int max_executed = organism->GetMaxExecuted();
+  if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
+      || phenotype.GetToDie() == true) {
+    organism->Die();
+  }
+
+  organism->SetRunning(false);
+}
+
+
+// This method will test to see if all costs have been paid associated
+// with executing an instruction and only return true when that instruction
+// should proceed.
+bool cHardwareCPU::SingleProcess_PayCosts(const cInstruction & cur_inst)
+{
+#ifdef INSTRUCTION_COSTS
+  assert(cur_inst.GetOp() < inst_cost.GetSize());
+
+  // If first time cost hasn't been paid off...
+  if ( inst_ft_cost[cur_inst.GetOp()] > 0 ) {
+    inst_ft_cost[cur_inst.GetOp()]--;       // dec cost
+    return false;
+  }
+    
+  // Next, look at the per use cost
+  if ( GetInstSet().GetCost(cur_inst) > 0 ) {
+    if ( inst_cost[cur_inst.GetOp()] > 1 ){  // if isn't paid off (>1)
+      inst_cost[cur_inst.GetOp()]--;         // dec cost
+      return false;
+    } else {                                 // else, reset cost array
+      inst_cost[cur_inst.GetOp()] = GetInstSet().GetCost(cur_inst);
+    }
+  }
+    
+  // Prob of exec
+  if ( GetInstSet().GetProbFail(cur_inst) > 0.0 ){
+    return !( g_random.P(GetInstSet().GetProbFail(cur_inst)) );
+  }
+#endif
+  return true;
+}
+
+// This method will handle the actuall execution of an instruction
+// within single process, once that function has been finalized.
+bool cHardwareCPU::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
+{
+  // Copy Instruction locally to handle stochastic effects
+  cInstruction actual_inst = cur_inst;
+  
+#ifdef EXECUTION_ERRORS
+  // If there is an execution error, execute a random instruction.
+  if (organism->TestExeErr()) actual_inst = GetInstSet().GetRandomInst();
+#endif /* EXECUTION_ERRORS */
+
+  // Get a pointer to the corrisponding method...
+  int inst_idx = GetInstSet().GetLibFunctionIndex(actual_inst);
+  
+  // Mark the instruction as executed
+  IP().FlagExecuted() = true;
+	
+
+#ifdef INSTRUCTION_COUNT
+  // instruction execution count incremeneted
+  organism->GetPhenotype().IncCurInstCount(actual_inst.GetOp());
+#endif
+	
+  // And execute it.
+  const bool exec_success = (this->*(m_functions[inst_idx]))();
+	
+#ifdef INSTRUCTION_COUNT
+  // decremenet if the instruction was not executed successfully
+  if (exec_success == false) {
+    organism->GetPhenotype().DecCurInstCount(actual_inst.GetOp());
+  }
+#endif	
+
+  return exec_success;
+}
+
+
+void cHardwareCPU::ProcessBonusInst(const cInstruction & inst)
+{
+  // Mark this organism as running...
+  bool prev_run_state = organism->GetIsRunning();
+  organism->SetRunning(true);
+
+  // @CAO FIX PRINTING TO INDICATE THIS IS A BONUS
+  // Print the status of this CPU at each step...
+  if (m_tracer != NULL) {
+    if (cHardwareTracer_CPU * tracer
+        = dynamic_cast<cHardwareTracer_CPU *>(m_tracer)
+    ){
+      tracer->TraceHardware_CPUBonus(*this);
+    }
+  }
+    
+  SingleProcess_ExecuteInst(inst);
+
+  organism->SetRunning(prev_run_state);
+}
+
+
+void cHardwareCPU::LoadGenome(const cGenome & new_genome)
+{
+  GetMemory() = new_genome;
+}
+
+
+bool cHardwareCPU::OK()
+{
+  bool result = true;
+
+  if (!memory.OK()) result = false;
+
+  for (int i = 0; i < GetNumThreads(); i++) {
+    if (threads[i].stack.OK() == false) result = false;
+    if (threads[i].next_label.OK() == false) result = false;
+  }
+
+  return result;
+}
+
+void cHardwareCPU::PrintStatus(ostream & fp)
+{
+  fp << organism->GetPhenotype().GetTimeUsed() << " "
+     << "IP:" << IP().GetPosition() << "    "
+
+     << "AX:" << Register(REG_AX) << " "
+     << setbase(16) << "[0x" << Register(REG_AX) << "]  " << setbase(10)
+
+     << "BX:" << Register(REG_BX) << " "
+     << setbase(16) << "[0x" << Register(REG_BX) << "]  " << setbase(10)
+
+     << "CX:" << Register(REG_CX) << " "
+     << setbase(16) << "[0x" << Register(REG_CX) << "]" << setbase(10)
+
+     << endl;
+
+  fp << "  R-Head:" << GetHead(HEAD_READ).GetPosition() << " "
+     << "W-Head:" << GetHead(HEAD_WRITE).GetPosition()  << " "
+     << "F-Head:" << GetHead(HEAD_FLOW).GetPosition()   << "  "
+     << "RL:" << GetReadLabel().AsString() << "   "
+     << endl;
+
+  fp << "  Mem (" << GetMemory().GetSize() << "):"
+		  << "  " << GetMemory().AsString()
+		  << endl;
+  fp.flush();
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////
+// Method: cHardwareCPU::FindLabel(direction)
+//
+// Search in 'direction' (+ or - 1) from the instruction pointer for the
+// compliment of the label in 'next_label' and return a pointer to the
+// results.  If direction is 0, search from the beginning of the genome.
+//
+/////////////////////////////////////////////////////////////////////////
+
+cHeadCPU cHardwareCPU::FindLabel(int direction)
+{
+  cHeadCPU & inst_ptr = IP();
+
+  // Start up a search head at the position of the instruction pointer.
+  cHeadCPU search_head(inst_ptr);
+  cCodeLabel & search_label = GetLabel();
+
+  // Make sure the label is of size > 0.
+
+  if (search_label.GetSize() == 0) {
+    return inst_ptr;
+  }
+
+  // Call special functions depending on if jump is forwards or backwards.
+  int found_pos = 0;
+  if( direction < 0 ) {
+    found_pos = FindLabel_Backward(search_label, inst_ptr.GetMemory(),
+			   inst_ptr.GetPosition() - search_label.GetSize());
+  }
+
+  // Jump forward.
+  else if (direction > 0) {
+    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(),
+			   inst_ptr.GetPosition());
+  }
+
+  // Jump forward from the very beginning.
+  else {
+    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(), 0);
+  }
+  
+  // Return the last line of the found label, if it was found.
+  if (found_pos >= 0) search_head.Set(found_pos - 1);
+
+  // Return the found position (still at start point if not found).
+  return search_head;
+}
+
+
+// Search forwards for search_label from _after_ position pos in the
+// memory.  Return the first line _after_ the the found label.  It is okay
+// to find search label's match inside another label.
+
+int cHardwareCPU::FindLabel_Forward(const cCodeLabel & search_label,
+				 const cGenome & search_genome, int pos)
+{
+  assert (pos < search_genome.GetSize() && pos >= 0);
+
+  int search_start = pos;
+  int label_size = search_label.GetSize();
+  bool found_label = false;
+
+  // Move off the template we are on.
+  pos += label_size;
+
+  // Search until we find the complement or exit the memory.
+  while (pos < search_genome.GetSize()) {
+
+    // If we are within a label, rewind to the beginning of it and see if
+    // it has the proper sub-label that we're looking for.
+
+    if (inst_set->IsNop(search_genome[pos])) {
+      // Find the start and end of the label we're in the middle of.
+
+      int start_pos = pos;
+      int end_pos = pos + 1;
+      while (start_pos > search_start &&
+	     inst_set->IsNop( search_genome[start_pos - 1] )) {
+	start_pos--;
+      }
+      while (end_pos < search_genome.GetSize() &&
+	     inst_set->IsNop( search_genome[end_pos] )) {
+	end_pos++;
+      }
+      int test_size = end_pos - start_pos;
+
+      // See if this label has the proper sub-label within it.
+      int max_offset = test_size - label_size + 1;
+      int offset = start_pos;
+      for (offset = start_pos; offset < start_pos + max_offset; offset++) {
+
+	// Test the number of matches for this offset.
+	int matches;
+	for (matches = 0; matches < label_size; matches++) {
+	  if (search_label[matches] !=
+	      inst_set->GetNopMod( search_genome[offset + matches] )) {
+	    break;
+	  }
+	}
+
+	// If we have found it, break out of this loop!
+	if (matches == label_size) {
+	  found_label = true;
+	  break;
+	}
+      }
+
+      // If we've found the complement label, set the position to the end of
+      // the label we found it in, and break out.
+
+      if (found_label == true) {
+	// pos = end_pos;
+	pos = label_size + offset;
+	break;
+      }
+
+      // We haven't found it; jump pos to just after the current label being
+      // checked.
+      pos = end_pos;
+    }
+
+    // Jump up a block to the next possible point to find a label,
+    pos += label_size;
+  }
+
+  // If the label was not found return a -1.
+  if (found_label == false) pos = -1;
+
+  return pos;
+}
+
+// Search backwards for search_label from _before_ position pos in the
+// memory.  Return the first line _after_ the the found label.  It is okay
+// to find search label's match inside another label.
+
+int cHardwareCPU::FindLabel_Backward(const cCodeLabel & search_label,
+				  const cGenome & search_genome, int pos)
+{
+  assert (pos < search_genome.GetSize());
+
+  int search_start = pos;
+  int label_size = search_label.GetSize();
+  bool found_label = false;
+
+  // Move off the template we are on.
+  pos -= label_size;
+
+  // Search until we find the complement or exit the memory.
+  while (pos >= 0) {
+    // If we are within a label, rewind to the beginning of it and see if
+    // it has the proper sub-label that we're looking for.
+
+    if (inst_set->IsNop( search_genome[pos] )) {
+      // Find the start and end of the label we're in the middle of.
+
+      int start_pos = pos;
+      int end_pos = pos + 1;
+      while (start_pos > 0 && inst_set->IsNop(search_genome[start_pos - 1])) {
+	start_pos--;
+      }
+      while (end_pos < search_start &&
+	     inst_set->IsNop(search_genome[end_pos])) {
+	end_pos++;
+      }
+      int test_size = end_pos - start_pos;
+
+      // See if this label has the proper sub-label within it.
+      int max_offset = test_size - label_size + 1;
+      for (int offset = start_pos; offset < start_pos + max_offset; offset++) {
+
+	// Test the number of matches for this offset.
+	int matches;
+	for (matches = 0; matches < label_size; matches++) {
+	  if (search_label[matches] !=
+	      inst_set->GetNopMod(search_genome[offset + matches])) {
+	    break;
+	  }
+	}
+
+	// If we have found it, break out of this loop!
+	if (matches == label_size) {
+	  found_label = true;
+	  break;
+	}
+      }
+
+      // If we've found the complement label, set the position to the end of
+      // the label we found it in, and break out.
+
+      if (found_label == true) {
+	pos = end_pos;
+	break;
+      }
+
+      // We haven't found it; jump pos to just before the current label
+      // being checked.
+      pos = start_pos - 1;
+    }
+
+    // Jump up a block to the next possible point to find a label,
+    pos -= label_size;
+  }
+
+  // If the label was not found return a -1.
+  if (found_label == false) pos = -1;
+
+  return pos;
+}
+
+// Search for 'in_label' anywhere in the hardware.
+cHeadCPU cHardwareCPU::FindLabel(const cCodeLabel & in_label, int direction)
+{
+  assert (in_label.GetSize() > 0);
+
+  // IDEALY:
+  // Keep making jumps (in the proper direction) equal to the label
+  // length.  If we are inside of a label, check its size, and see if
+  // any of the sub-labels match properly.
+  // FOR NOW:
+  // Get something which works, no matter how inefficient!!!
+
+  cHeadCPU temp_head(this);
+
+  while (temp_head.InMemory()) {
+    // IDEALY: Analyze the label we are in; see if the one we are looking
+    // for could be a sub-label of it.  Skip past it if not.
+
+    int i;
+    for (i = 0; i < in_label.GetSize(); i++) {
+      if (!inst_set->IsNop(temp_head.GetInst()) ||
+	  in_label[i] != inst_set->GetNopMod(temp_head.GetInst())) {
+	break;
+      }
+    }
+    if (i == GetLabel().GetSize()) {
+      temp_head.AbsJump(i - 1);
+      return temp_head;
+    }
+
+    temp_head.AbsJump(direction);     // IDEALY: MAKE LARGER JUMPS
+  }
+
+  temp_head.AbsSet(-1);
+  return temp_head;
+}
+
+// @CAO: direction is not currently used; should be used to indicate the
+// direction which the heads[HEAD_IP] should progress through a creature.
+cHeadCPU cHardwareCPU::FindFullLabel(const cCodeLabel & in_label)
+{
+  // cout << "Running FindFullLabel with " << in_label.AsString() <<
+  // endl;
+
+  assert(in_label.GetSize() > 0); // Trying to find label of 0 size!
+
+  cHeadCPU temp_head(this);
+
+  while (temp_head.InMemory()) {
+    // If we are not in a label, jump to the next checkpoint...
+    if (inst_set->IsNop(temp_head.GetInst())) {
+      temp_head.AbsJump(in_label.GetSize());
+      continue;
+    }
+
+    // Otherwise, rewind to the begining of this label...
+
+    while (!(temp_head.AtFront()) && inst_set->IsNop(temp_head.GetInst(-1)))
+      temp_head.AbsJump(-1);
+
+    // Calculate the size of the label being checked, and make sure they
+    // are equal.
+
+    int checked_size = 0;
+    while (inst_set->IsNop(temp_head.GetInst(checked_size))) {
+      checked_size++;
+    }
+    if (checked_size != in_label.GetSize()) {
+      temp_head.AbsJump(checked_size + 1);
+      continue;
+    }
+
+    // cout << "Testing label at line " << temp_head.GetPosition() <<
+    // endl;
+
+    // ...and do the comparison...
+
+    int j;
+    bool label_match = true;
+    for (j = 0; j < in_label.GetSize(); j++) {
+      if (!inst_set->IsNop(temp_head.GetInst(j)) ||
+	  in_label[j] != inst_set->GetNopMod(temp_head.GetInst(j))) {
+	temp_head.AbsJump(in_label.GetSize() + 1);
+	label_match = false;
+	break;
+      }
+    }
+
+    if (label_match) {
+      // If we have found the label, return the position after it.
+      temp_head.AbsJump(j - 1);
+      return temp_head;
+    }
+
+    // We have not found the label... increment i.
+
+    temp_head.AbsJump(in_label.GetSize() + 1);
+  }
+
+  // The label does not exist in this creature.
+
+  temp_head.AbsSet(-1);
+  return temp_head;
+}
+
+
+bool cHardwareCPU::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
+{
+  // Make sure the genome will be below max size after injection.
+
+  const int new_size = injection.GetSize() + GetMemory().GetSize();
+  if (new_size > MAX_CREATURE_SIZE) return false; // (inject fails)
+
+  const int inject_line = FindFullLabel(in_label).GetPosition();
+
+  // Abort if no compliment is found.
+  if (inject_line == -1) return false; // (inject fails)
+
+  // Inject the code!
+  InjectCode(injection, inject_line+1);
+
+  return true; // (inject succeeds!)
+}
+
+int cHardwareCPU::InjectThread(const cCodeLabel & in_label, const cGenome & injection)
+{
+  // Make sure the genome will be below max size after injection.
+
+  const int new_size = injection.GetSize() + GetMemory().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!
+  InjectCodeThread(injection, inject_line+1);
+
+  return 0; // (inject succeeds!)
+}
+
+void cHardwareCPU::InjectCode(const cGenome & inject_code, const int line_num)
+{
+  assert(line_num >= 0);
+  assert(line_num <= memory.GetSize());
+  assert(memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+
+  // Inject the new code.
+  const int inject_size = inject_code.GetSize();
+  memory.Insert(line_num, inject_code);
+  
+  // Set instruction flags on the injected code
+  for (int i = line_num; i < line_num + inject_size; i++) {
+    memory.FlagInjected(i) = true;
+  }
+  organism->GetPhenotype().IsModified() = true;
+
+  // 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 cHardwareCPU::InjectCodeThread(const cGenome & inject_code, const int line_num)
+{
+  assert(line_num >= 0);
+  assert(line_num <= memory.GetSize());
+  assert(memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+  
+  if(ForkThread())
+    {
+      // Inject the new code.
+      const int inject_size = inject_code.GetSize();
+      memory.Insert(line_num, inject_code);
+      
+      // Set instruction flags on the injected code
+      for (int i = line_num; i < line_num + inject_size; i++) {
+	memory.FlagInjected(i) = true;
+      }
+      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);
+          
+    }
+  else
+    {
+      //Some kind of error message should go here...but what?
+    }
+
+}
+
+void cHardwareCPU::Mutate(int mut_point)
+{
+  // Test if trying to mutate outside of genome...
+  assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
+
+  GetMemory()[mut_point] = GetRandomInst();
+  GetMemory().FlagMutated(mut_point) = true;
+  GetMemory().FlagPointMut(mut_point) = true;
+  //organism->GetPhenotype().IsMutated() = true;
+  organism->CPUStats().mut_stats.point_mut_count++;
+}
+
+int cHardwareCPU::PointMutate(const double mut_rate)
+{
+  const int num_muts =
+    g_random.GetRandBinomial(GetMemory().GetSize(), mut_rate);
+
+  for (int i = 0; i < num_muts; i++) {
+    const int pos = g_random.GetUInt(GetMemory().GetSize());
+    Mutate(pos);
+  }
+
+  return num_muts;
+}
+
+
+// Trigger mutations of a specific type.  Outside triggers cannot specify
+// a head since hardware types are not known.
+
+bool cHardwareCPU::TriggerMutations(int trigger)
+{
+  // Only update triggers should happen from the outside!
+  assert(trigger == MUTATION_TRIGGER_UPDATE);
+
+  // Assume instruction pointer is the intended target (if one is even
+  // needed!
+
+  return TriggerMutations(trigger, IP());
+}
+
+bool cHardwareCPU::TriggerMutations(int trigger, cHeadCPU & cur_head)
+{
+  // Collect information about mutations from the organism.
+  cLocalMutations & mut_info = organism->GetLocalMutations();
+  const tList<cMutation> & mut_list =
+    mut_info.GetMutationLib().GetMutationList(trigger);
+
+  // If we have no mutations for this trigger, stop here.
+  if (mut_list.GetSize() == 0) return false;
+  bool has_mutation = false;
+
+  // Determine what memory this mutation will be affecting.
+  cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
+    ? organism->ChildGenome() : GetMemory();
+
+  // Loop through all mutations associated with this trigger and test them.
+  tConstListIterator<cMutation> mut_it(mut_list);
+
+  while (mut_it.Next() != NULL) {
+    const cMutation * cur_mut = mut_it.Get();
+    const int mut_id = cur_mut->GetID();
+    const int scope = cur_mut->GetScope();
+    const double rate = mut_info.GetRate(mut_id);
+    switch (scope) {
+    case MUTATION_SCOPE_GENOME:
+      if (TriggerMutations_ScopeGenome(cur_mut, target_mem, cur_head, rate)) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id);
+      }
+      break;
+    case MUTATION_SCOPE_LOCAL:
+    case MUTATION_SCOPE_PROP:
+      if (TriggerMutations_ScopeLocal(cur_mut, target_mem, cur_head, rate)) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id);
+      }
+      break;
+    case MUTATION_SCOPE_GLOBAL:
+    case MUTATION_SCOPE_SPREAD:
+      int num_muts =
+	TriggerMutations_ScopeGlobal(cur_mut, target_mem, cur_head, rate);
+      if (num_muts > 0) {
+	has_mutation = true;
+	mut_info.IncCount(mut_id, num_muts);
+      }
+      break;
+    }
+  }
+
+  return has_mutation;
+}
+
+bool cHardwareCPU::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
+{
+  // The rate we have stored indicates the probability that a single
+  // mutation will occur anywhere in the genome.
+  
+  if (g_random.P(rate) == true) {
+    // We must create a temporary head and use it to randomly determine the
+    // position in the genome to be mutated.
+    cHeadCPU tmp_head(cur_head);
+    tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
+    TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
+    return true;
+  }
+  return false;
+}
+
+bool cHardwareCPU::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
+{
+  // The rate we have stored is the probability for a mutation at this single
+  // position in the genome.
+
+  if (g_random.P(rate) == true) {
+    TriggerMutations_Body(cur_mut->GetType(), target_memory, cur_head);
+    return true;
+  }
+  return false;
+}
+
+int cHardwareCPU::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
+          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
+{
+  // The probability we have stored is per-site, so we can pull a random
+  // number from a binomial distribution to determine the number of mutations
+  // that should occur.
+
+  const int num_mut =
+    g_random.GetRandBinomial(target_memory.GetSize(), rate);
+
+  if (num_mut > 0) {
+    for (int i = 0; i < num_mut; i++) {
+      cHeadCPU tmp_head(cur_head);
+      tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
+      TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
+    }
+  }
+
+  return num_mut;
+}
+
+void cHardwareCPU::TriggerMutations_Body(int type, cCPUMemory & target_memory,
+					 cHeadCPU & cur_head)
+{
+  const int pos = cur_head.GetPosition();
+
+  switch (type) {
+  case MUTATION_TYPE_POINT:
+    target_memory[pos] = GetRandomInst();
+    target_memory.FlagMutated(pos) = true;
+    break;
+  case MUTATION_TYPE_INSERT:
+  case MUTATION_TYPE_DELETE:
+  case MUTATION_TYPE_HEAD_INC:
+  case MUTATION_TYPE_HEAD_DEC:
+  case MUTATION_TYPE_TEMP:
+  case MUTATION_TYPE_KILL:
+  default:
+    cout << "Error: Mutation type not implemented!" << endl;
+    break;
+  };
+}
+
+void cHardwareCPU::ReadInst(const int in_inst)
+{
+  if (inst_set->IsNop( cInstruction(in_inst) )) {
+    GetReadLabel().AddNop(in_inst);
+  } else {
+    GetReadLabel().Clear();
+  }
+}
+
+
+void cHardwareCPU::AdjustHeads()
+{
+  for (int i = 0; i < GetNumThreads(); i++) {
+    for (int j = 0; j < NUM_HEADS; j++) {
+      threads[i].heads[j].Adjust();
+    }
+  }
+}
+
+
+
+// This function looks at the current position in the info of a creature,
+// and sets the next_label to be the sequence of nops which follows.  The
+// instruction pointer is left on the last line of the label found.
+
+void cHardwareCPU::ReadLabel(int max_size)
+{
+  int count = 0;
+  cHeadCPU * inst_ptr = &( IP() );
+
+  GetLabel().Clear();
+
+  while (inst_set->IsNop(inst_ptr->GetNextInst()) &&
+	 (count < max_size)) {
+    count++;
+    inst_ptr->Advance();
+    GetLabel().AddNop(inst_set->GetNopMod(inst_ptr->GetInst()));
+
+    // If this is the first line of the template, mark it executed.
+    if (GetLabel().GetSize() <=	cConfig::GetMaxLabelExeSize()) {
+      inst_ptr->FlagExecuted() = true;
+    }
+  }
+}
+
+
+bool cHardwareCPU::ForkThread()
+{
+  const int num_threads = GetNumThreads();
+  if (num_threads == cConfig::GetMaxCPUThreads()) return false;
+
+  // Make room for the new thread.
+  threads.Resize(num_threads + 1);
+
+  // Initialize the new thread to the same values as the current one.
+  threads[num_threads] = threads[cur_thread];
+
+  // Find the first free bit in thread_id_chart to determine the new
+  // thread id.
+  int new_id = 0;
+  while ( (thread_id_chart >> new_id) & 1 == 1) new_id++;
+  threads[num_threads].SetID(new_id);
+  thread_id_chart |= (1 << new_id);
+
+  return true;
+}
+
+
+int cHardwareCPU::TestParasite() const
+{
+  return IP().TestParasite();
+}
+
+
+bool cHardwareCPU::KillThread()
+{
+  // Make sure that there is always at least one thread...
+  if (GetNumThreads() == 1) return false;
+
+  // Note the current thread and set the current back one.
+  const int kill_thread = cur_thread;
+  PrevThread();
+  
+  // Turn off this bit in the thread_id_chart...
+  thread_id_chart ^= 1 << threads[kill_thread].GetID();
+
+  // Copy the last thread into the kill position
+  const int last_thread = GetNumThreads() - 1;
+  if (last_thread != kill_thread) {
+    threads[kill_thread] = threads[last_thread];
+  }
+
+  // Kill the thread!
+  threads.Resize(GetNumThreads() - 1);
+
+  if (cur_thread > kill_thread) cur_thread--;
+
+  return true;
+}
+
+
+void cHardwareCPU::SaveState(ostream & fp)
+{
+  // note, memory & child_memory handled by cpu (@CAO Not any more!)
+  assert(fp.good());
+
+  fp<<"cHardwareCPU"<<endl;
+
+  // global_stack (in inverse order so load can just push)
+  global_stack.SaveState(fp);
+
+  fp << thread_time_used  << endl;
+  fp << GetNumThreads()   << endl;
+  fp << cur_thread        << endl;
+
+  // Threads
+  for( int i = 0; i < GetNumThreads(); i++ ) {
+    threads[i].SaveState(fp);
+  }
+}
+
+
+void cHardwareCPU::LoadState(istream & fp)
+{
+  // note, memory & child_memory handled by cpu (@CAO Not any more!)
+  assert(fp.good());
+
+  cString foo;
+  fp>>foo;
+  assert( foo == "cHardwareCPU" );
+
+  // global_stack
+  global_stack.LoadState(fp);
+
+  int num_threads;
+  fp >> thread_time_used;
+  fp >> num_threads;
+  fp >> cur_thread;
+
+  // Threads
+  for( int i = 0; i < num_threads; i++ ){
+    threads[i].LoadState(fp);
+  }
+}
+
+
+////////////////////////////
+//  Instruction Helpers...
+////////////////////////////
+
+inline int cHardwareCPU::FindModifiedRegister(int default_register)
+{
+  assert(default_register < NUM_REGISTERS);  // Reg ID too high.
+
+  if (GetInstSet().IsNop(IP().GetNextInst())) {
+    IP().Advance();
+    default_register = GetInstSet().GetNopMod(IP().GetInst());
+    IP().FlagExecuted() = true;
+  }
+  return default_register;
+}
+
+
+inline int cHardwareCPU::FindModifiedHead(int default_head)
+{
+  assert(default_head < NUM_HEADS); // Head ID too high.
+
+  if (GetInstSet().IsNop(IP().GetNextInst())) {
+    IP().Advance();
+    default_head = GetInstSet().GetNopMod(IP().GetInst());
+    IP().FlagExecuted() = true;
+  }
+  return default_head;
+}
+
+
+inline int cHardwareCPU::FindComplementRegister(int base_reg)
+{
+  const int comp_reg = base_reg + 1;
+  return (comp_reg  == NUM_REGISTERS) ? 0 : comp_reg;
+}
+
+
+inline void cHardwareCPU::Fault(int fault_loc, int fault_type, cString fault_desc)
+{
+  organism->Fault(fault_loc, fault_type, fault_desc);
+}
+
+
+bool cHardwareCPU::Allocate_Necro(const int new_size)
+{
+  GetMemory().ResizeOld(new_size);
+  return true;
+}
+
+bool cHardwareCPU::Allocate_Random(const int old_size, const int new_size)
+{
+  GetMemory().Resize(new_size);
+
+  for (int i = old_size; i < new_size; i++) {
+    GetMemory()[i] = GetInstSet().GetRandomInst();
+  }
+  return true;
+}
+
+bool cHardwareCPU::Allocate_Default(const int new_size)
+{
+  GetMemory().Resize(new_size);
+
+  // New space already defaults to default instruction...
+
+  return true;
+}
+
+bool cHardwareCPU::Allocate_Main(const int allocated_size)
+{
+  // must do divide before second allocate & must allocate positive amount...
+  if (cConfig::GetRequireAllocate() && mal_active == true) {
+    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
+    return false;
+  }
+  if (allocated_size < 1) {
+    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Allocate of %d too small", allocated_size));
+    return false;
+  }
+
+  const int old_size = GetMemory().GetSize();
+  const int new_size = old_size + allocated_size;
+
+  // Make sure that the new size is in range.
+  if (new_size > MAX_CREATURE_SIZE  ||  new_size < MIN_CREATURE_SIZE) {
+    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Invalid post-allocate size (%d)",
+			       new_size));
+    return false;
+  }
+
+  const int max_alloc_size = (int) (old_size * cConfig::GetChildSizeRange());
+  if (allocated_size > max_alloc_size) {
+    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Allocate too large (%d > %d)",
+			       allocated_size, max_alloc_size));
+    return false;
+  }
+
+  const int max_old_size =
+    (int) (allocated_size * cConfig::GetChildSizeRange());
+  if (old_size > max_old_size) {
+    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Allocate too small (%d > %d)",
+			       old_size, max_old_size));
+    return false;
+  }
+
+  switch (cConfig::GetAllocMethod()) {
+  case ALLOC_METHOD_NECRO:
+    // Only break if this succeeds -- otherwise just do random.
+    if (Allocate_Necro(new_size) == true) break;
+  case ALLOC_METHOD_RANDOM:
+    Allocate_Random(old_size, new_size);
+    break;
+  case ALLOC_METHOD_DEFAULT:
+    Allocate_Default(new_size);
+    break;
+  }
+
+  mal_active = true;
+
+  return true;
+}
+
+
+bool cHardwareCPU::Divide_CheckViable(const int child_size,
+				      const int parent_size)
+{
+  // Make sure the organism is okay with dividing now...
+  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
+
+  // If required, make sure an allocate has occured.
+  if (cConfig::GetRequireAllocate() && mal_active == false) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, "Must allocate before divide");
+    return false; //  (divide fails)
+  }
+
+  // Make sure that neither parent nor child will be below the minimum size.
+
+  const int genome_size = organism->GetGenome().GetSize();
+  const double size_range = cConfig::GetChildSizeRange();
+  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
+  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
+  
+  if (child_size < min_size || child_size > max_size) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
+    return false; // (divide fails)
+  }
+  if (parent_size < min_size || parent_size > max_size) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
+    return false; // (divide fails)
+  }
+
+  // Count the number of lines executed in the parent, and make sure the
+  // specified fraction has been reached.
+
+  int executed_size = 0;
+  for (int i = 0; i < parent_size; i++) {
+    if (GetMemory().FlagExecuted(i)) executed_size++;
+  }
+
+  const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
+  if (executed_size < min_exe_lines) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Too few executed lines (%d < %d)",
+			       executed_size, min_exe_lines));
+    return false; // (divide fails)
+  }
+	
+  // Count the number of lines which were copied into the child, and make
+  // sure the specified fraction has been reached.
+
+  int copied_size = 0;
+  for (int i = parent_size; i < parent_size + child_size; i++) {
+    if (GetMemory().FlagCopied(i)) copied_size++;
+  }
+
+  const int min_copied =  (int) (child_size * cConfig::GetMinCopiedLines());
+  if (copied_size < min_copied) {
+    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+	  cStringUtil::Stringf("Too few copied commands (%d < %d)",
+			       copied_size, min_copied));
+    return false; // (divide fails)
+  }
+
+  // Save the information we collected here...
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.SetLinesExecuted(executed_size);
+  phenotype.SetLinesCopied(copied_size);
+
+  // Determine the fitness of this organism as compared to its parent...
+  if (cConfig::GetTestSterilize() == true &&
+      phenotype.IsInjected() == false) {
+    const int merit_base =
+      cPhenotype::CalcSizeMerit(genome_size, copied_size, executed_size);
+    const double cur_fitness =
+      merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
+    const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
+
+
+    //  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
+    //  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
+  
+    bool sterilize = false;
+  
+    if (fitness_ratio < FITNESS_NEUTRAL_MIN) {
+      if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
+    } else if (fitness_ratio <= FITNESS_NEUTRAL_MAX) {
+      if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
+    } else {
+      if (g_random.P(organism->GetSterilizePos())) sterilize = true;
+    }
+  
+//     cout << "[ min(" << genome_size
+// 	 << "," << copied_size
+// 	 << "," << executed_size
+// 	 << ") * " << phenotype.GetCurBonus()
+// 	 << " / " << phenotype.GetTimeUsed()
+// 	 << "] / " << phenotype.GetLastFitness()
+// 	 << " == " << fitness_ratio;
+
+    if (sterilize == true) {
+      //Don't let this organism have this or any more children!
+      phenotype.IsFertile() = false;
+      return false;
+    }    
+  }
+
+  return true; // (divide succeeds!)
+}
+
+
+void cHardwareCPU::Divide_DoMutations(double mut_multiplier)
+{
+  sCPUStats & cpu_stats = organism->CPUStats();
+  cCPUMemory & child_genome = organism->ChildGenome();
+  
+  organism->GetPhenotype().SetDivType(mut_multiplier);
+
+  // Divide Mutations
+  if (organism->TestDivideMut()) {
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
+    child_genome[mut_line] = GetRandomInst();
+    cpu_stats.mut_stats.divide_mut_count++;
+  }
+
+  // Divide Insertions
+  if (organism->TestDivideIns() && child_genome.GetSize() < MAX_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize() + 1);
+    child_genome.Insert(mut_line, GetRandomInst());
+    cpu_stats.mut_stats.divide_insert_mut_count++;
+  }
+
+  // Divide Deletions
+  if (organism->TestDivideDel() && child_genome.GetSize() > MIN_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
+    // if( child_genome.FlagCopied(mut_line) == true) copied_size_change--;
+    child_genome.Remove(mut_line);
+    cpu_stats.mut_stats.divide_delete_mut_count++;
+  }
+
+  // Divide Mutations (per site)
+  if(organism->GetDivMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(), 
+				   	   organism->GetDivMutProb() / mut_multiplier);
+    // If we have lines to mutate...
+    if( num_mut > 0 ){
+      for (int i = 0; i < num_mut; i++) {
+	int site = g_random.GetUInt(child_genome.GetSize());
+	child_genome[site]=GetRandomInst();
+	cpu_stats.mut_stats.div_mut_count++;
+      }
+    }
+  }
+
+
+  // Insert Mutations (per site)
+  if(organism->GetInsMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
+					   organism->GetInsMutProb());
+    // If would make creature to big, insert up to MAX_CREATURE_SIZE
+    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
+      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
+    }
+    // If we have lines to insert...
+    if( num_mut > 0 ){
+      // Build a list of the sites where mutations occured
+      static int mut_sites[MAX_CREATURE_SIZE];
+      for (int i = 0; i < num_mut; i++) {
+	mut_sites[i] = g_random.GetUInt(child_genome.GetSize() + 1);
+      }
+      // Sort the list
+      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+      // Actually do the mutations (in reverse sort order)
+      for(int i = num_mut-1; i >= 0; i--) {
+	child_genome.Insert(mut_sites[i], GetRandomInst());
+	cpu_stats.mut_stats.insert_mut_count++;
+      }
+    }
+  }
+
+
+  // Delete Mutations (per site)
+  if( organism->GetDelMutProb() > 0 ){
+    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
+					   organism->GetDelMutProb());
+    // If would make creature too small, delete down to MIN_CREATURE_SIZE
+    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
+    }
+
+    // If we have lines to delete...
+    for (int i = 0; i < num_mut; i++) {
+      int site = g_random.GetUInt(child_genome.GetSize());
+      // if (child_genome.FlagCopied(site) == true) copied_size_change--;
+      child_genome.Remove(site);
+      cpu_stats.mut_stats.delete_mut_count++;
+    }
+  }
+
+  // Mutations in the parent's genome
+  if (organism->GetParentMutProb() > 0) {
+    for (int i = 0; i < GetMemory().GetSize(); i++) {
+      if (organism->TestParentMut()) {
+	GetMemory()[i] = GetRandomInst();
+	cpu_stats.mut_stats.parent_mut_line_count++;
+      }
+    }
+  }
+
+
+  // Count up mutated lines
+  for(int i = 0; i < GetMemory().GetSize(); i++){
+    if (GetMemory().FlagPointMut(i) == true) {
+      cpu_stats.mut_stats.point_mut_line_count++;
+    }
+  }
+  for(int i = 0; i < child_genome.GetSize(); i++){
+    if( child_genome.FlagCopyMut(i) == true) {
+      cpu_stats.mut_stats.copy_mut_line_count++;
+    }
+  }
+}
+
+
+// test whether the offspring creature contains an advantageous mutation.
+void cHardwareCPU::Divide_TestFitnessMeasures()
+{
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
+  phenotype.ChildFertile() = true;
+
+  // Only continue if we're supposed to do a fitness test on divide...
+  if (organism->GetTestOnDivide() == false) return;
+
+  // If this was a perfect copy, then we don't need to worry about any other
+  // tests...  Theoretically, we need to worry about the parent changing,
+  // but as long as the child is always compared to the original genotype,
+  // this won't be an issue.
+  if (phenotype.CopyTrue() == true) return;
+
+  const double parent_fitness = organism->GetTestFitness();
+  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
+  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
+  
+  cCPUTestInfo test_info;
+  test_info.UseRandomInputs();
+  cTestCPU::TestGenome(test_info, organism->ChildGenome());
+  const double child_fitness = test_info.GetGenotypeFitness();
+  
+  bool revert = false;
+  bool sterilize = false;
+  
+  // If implicit mutations are turned off, make sure this won't spawn one.
+  if (organism->GetFailImplicit() == true) {
+    if (test_info.GetMaxDepth() > 0) sterilize = true;
+  }
+  
+  if (child_fitness == 0.0) {
+    // Fatal mutation... test for reversion.
+    if (g_random.P(organism->GetRevertFatal())) revert = true;
+    if (g_random.P(organism->GetSterilizeFatal())) sterilize = true;
+  } else if (child_fitness < neut_min) {
+    if (g_random.P(organism->GetRevertNeg())) revert = true;
+    if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
+  } else if (child_fitness <= neut_max) {
+    if (g_random.P(organism->GetRevertNeut())) revert = true;
+    if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
+  } else {
+    if (g_random.P(organism->GetRevertPos())) revert = true;
+    if (g_random.P(organism->GetSterilizePos())) sterilize = true;
+  }
+  
+  // Ideally, we won't have reversions and sterilizations turned on at the
+  // same time, but if we do, give revert the priority.
+  if (revert == true) {
+    organism->ChildGenome() = organism->GetGenome();
+  }
+
+  if (sterilize == true) {
+    organism->GetPhenotype().ChildFertile() = false;
+  }
+}
+
+
+bool cHardwareCPU::Divide_Main(const int div_point, const int extra_lines, double mut_multiplier)
+{
+  const int child_size = GetMemory().GetSize() - div_point - extra_lines;
+
+  // Make sure this divide will produce a viable offspring.
+  const bool viable = Divide_CheckViable(child_size, div_point);
+  if (viable == false) return false;
+
+  // Since the divide will now succeed, set up the information to be sent
+  // to the new organism
+  cGenome & child_genome = organism->ChildGenome();
+  child_genome = cGenomeUtil::Crop(memory, div_point, div_point+child_size);
+
+  // Cut off everything in this memory past the divide point.
+  GetMemory().Resize(div_point);
+
+  // Handle Divide Mutations...
+  Divide_DoMutations(mut_multiplier);
+
+  // 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
+
+  mal_active = false;
+  if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) {
+    advance_ip = false;
+  }
+
+  // Activate the child, and do more work if the parent lives through the
+  // birth.
+  bool parent_alive = organism->ActivateDivide();
+  if (parent_alive) {
+    if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) Reset();
+  }
+
+  return true;
+}
+
+
+//////////////////////////
+// And the instructions...
+//////////////////////////
+
+bool cHardwareCPU::Inst_If0()          // Execute next if ?bx? ==0.
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) != 0)  IP().Advance();
+  return true; 
+}
+
+bool cHardwareCPU::Inst_IfNot0()       // Execute next if ?bx? != 0.
+{ 
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) == 0)  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfEqu()      // 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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfNEqu()     // 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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfGr0()       // Execute next if ?bx? ! < 0.
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) <= 0)  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfGr()       // 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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfGrEqu0()       // Execute next if ?bx? != 0.
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) < 0)  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfLess0()       // Execute next if ?bx? != 0.
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) >= 0)  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfLess()       // 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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfLsEqu0()       // Execute next if ?bx? != 0.
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(reg_used) > 0) IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::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();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfBit1()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if ((Register(reg_used) & 1) == 0)  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfANotEqB()     // Execute next if AX != BX
+{
+  if (Register(REG_AX) == Register(REG_BX) )  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfBNotEqC()     // Execute next if BX != CX
+{
+  if (Register(REG_BX) == Register(REG_CX) )  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfANotEqC()     // Execute next if AX != BX
+{
+  if (Register(REG_AX) == Register(REG_CX) )  IP().Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_JumpF()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+
+  // 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 cHeadCPU 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;
+}
+
+
+bool cHardwareCPU::Inst_JumpB()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+
+  // If there is no label, jump BX steps.
+  if (GetLabel().GetSize() == 0) {
+    GetActiveHead().Jump(-Register(REG_BX));
+    return true;
+  }
+
+  // otherwise jump to the complement label.
+  const cHeadCPU 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-b: No complement label");
+  return false;
+}
+
+bool cHardwareCPU::Inst_JumpP()
+{
+  cOrganism * other_organism = organism->GetNeighbor();
+
+  // 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;
+  }
+
+  // Otherwise, grab the hardware from the neighbor, and use it!
+  cHardwareCPU & other_hardware = (cHardwareCPU &) other_organism->GetHardware();
+
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+
+  // 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 cHeadCPU jump_location(other_hardware.FindFullLabel(GetLabel()));
+  if (jump_location.GetPosition() != -1) {
+    IP().Set(jump_location);
+    organism->GetPhenotype().IsParasite() = true;
+    return true;
+  }
+
+  // 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 cHardwareCPU::Inst_JumpSelf()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+
+  // 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 cHeadCPU 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 cHardwareCPU::Inst_Call()
+{
+  // Put the starting location onto the stack
+  const int location = IP().GetPosition();
+  StackPush(location);
+
+  // Jump to the compliment label (or by the ammount in the bx register)
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+
+  if (GetLabel().GetSize() == 0) {
+    IP().Jump(Register(REG_BX));
+    return true;
+  }
+
+  const cHeadCPU 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,
+		  "call: no complement label");
+  return false;
+}
+
+bool cHardwareCPU::Inst_Return()
+{
+  IP().Set(StackPop());
+  return true;
+}
+
+bool cHardwareCPU::Inst_Pop()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = StackPop();
+  return true;
+}
+
+bool cHardwareCPU::Inst_Push()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  StackPush(Register(reg_used));
+  return true;
+}
+
+bool cHardwareCPU::Inst_HeadPop()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  GetHead(head_used).Set(StackPop(), this);
+  return true;
+}
+
+bool cHardwareCPU::Inst_HeadPush()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  StackPush(GetHead(head_used).GetPosition());
+  if (head_used == HEAD_IP) {
+    GetHead(head_used).Set(GetHead(HEAD_FLOW));
+    advance_ip = false;
+  }
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_PopA() { Register(REG_AX) = StackPop(); return true;}
+bool cHardwareCPU::Inst_PopB() { Register(REG_BX) = StackPop(); return true;}
+bool cHardwareCPU::Inst_PopC() { Register(REG_CX) = StackPop(); return true;}
+
+bool cHardwareCPU::Inst_PushA() { StackPush(Register(REG_AX)); return true;}
+bool cHardwareCPU::Inst_PushB() { StackPush(Register(REG_BX)); return true;}
+bool cHardwareCPU::Inst_PushC() { StackPush(Register(REG_CX)); return true;}
+
+bool cHardwareCPU::Inst_SwitchStack() { SwitchStack(); return true;}
+bool cHardwareCPU::Inst_FlipStack()   { StackFlip(); return true;}
+
+bool cHardwareCPU::Inst_Swap()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  const int other_reg = FindComplementRegister(reg_used);
+//  cout << endl; 
+//  cout << "Regs 1, 2, 3 are: " << Register(1) << " " << Register(2) << " " << Register(3) << endl; 
+//  cout << "Modified reg = " << reg_used << ", Complement reg = " << other_reg << endl; 
+//  cout << "Calling Swap with " << Register(reg_used) << " and " << Register(other_reg) << endl; 
+  nFunctions::Swap(Register(reg_used), Register(other_reg));
+//  cout << "Current State is " << Register(reg_used) << " and " << Register(other_reg) << endl; 
+//  cout << "Regs 1, 2, 3 are: " << Register(1) << " " << Register(2) << " " << Register(3) << endl; 
+  return true;
+}
+
+bool cHardwareCPU::Inst_SwapAB() { nFunctions::Swap(Register(REG_AX), Register(REG_BX)); return true; }
+bool cHardwareCPU::Inst_SwapBC() { nFunctions::Swap(Register(REG_BX), Register(REG_CX)); return true; }
+bool cHardwareCPU::Inst_SwapAC() { nFunctions::Swap(Register(REG_AX), Register(REG_CX)); return true; }
+
+bool cHardwareCPU::Inst_CopyReg()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  const int other_reg = FindComplementRegister(reg_used);
+  Register(other_reg) = Register(reg_used);
+  return true;
+}
+
+bool cHardwareCPU::Inst_CopyRegAB() { Register(REG_AX) = Register(REG_BX);   return true;
+}
+bool cHardwareCPU::Inst_CopyRegAC() { Register(REG_AX) = Register(REG_CX);   return true;
+}
+bool cHardwareCPU::Inst_CopyRegBA() { Register(REG_BX) = Register(REG_AX);   return true;
+}
+bool cHardwareCPU::Inst_CopyRegBC() { Register(REG_BX) = Register(REG_CX);   return true;
+}
+bool cHardwareCPU::Inst_CopyRegCA() { Register(REG_CX) = Register(REG_AX);   return true;
+}
+bool cHardwareCPU::Inst_CopyRegCB() { Register(REG_CX) = Register(REG_BX);   return true;
+}
+
+bool cHardwareCPU::Inst_Reset()
+{
+  Register(REG_AX) = 0;
+  Register(REG_BX) = 0;
+  Register(REG_CX) = 0;
+  StackClear();
+  return true;
+}
+
+bool cHardwareCPU::Inst_ShiftR()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) >>= 1;
+  return true;
+}
+
+bool cHardwareCPU::Inst_ShiftL()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) <<= 1;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Bit1()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) |=  1;
+  return true;
+}
+
+bool cHardwareCPU::Inst_SetNum()
+{
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsInt(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_ValGrey(void) {
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsIntGreyCode(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_ValDir(void) {
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsIntDirect(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_ValAddP(void) {
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsIntAdditivePolynomial(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_ValFib(void) {
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsIntFib(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_ValPolyC(void) {
+  ReadLabel();
+  Register(REG_BX) = GetLabel().AsIntPolynomialCoefficent(NUM_NOPS);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Inc()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) += 1;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Dec()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) -= 1;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Zero()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = 0;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Neg()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = 0-Register(reg_used);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Square()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = Register(reg_used) * Register(reg_used);
+  return true;
+}
+
+bool cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::Inst_Minus17()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) -= 17;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Add()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = Register(REG_BX) + Register(REG_CX);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Sub()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = Register(REG_BX) - Register(REG_CX);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Mult()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = Register(REG_BX) * Register(REG_CX);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Div()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(REG_CX) != 0) {
+    if (0-INT_MAX > Register(REG_BX) && Register(REG_CX) == -1)
+      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+    else
+      Register(reg_used) = Register(REG_BX) / Register(REG_CX);
+  } else {
+    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+    return false;
+  }
+  return true;
+}
+
+bool cHardwareCPU::Inst_Mod()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  if (Register(REG_CX) != 0) {
+    Register(reg_used) = Register(REG_BX) % Register(REG_CX);
+  } else {
+    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+  return false;
+  }
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_Nand()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = ~(Register(REG_BX) & Register(REG_CX));
+  return true;
+}
+
+bool cHardwareCPU::Inst_Nor()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = ~(Register(REG_BX) | Register(REG_CX));
+  return true;
+}
+
+bool cHardwareCPU::Inst_And()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = (Register(REG_BX) & Register(REG_CX));
+  return true;
+}
+
+bool cHardwareCPU::Inst_Not()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = ~(Register(reg_used));
+  return true;
+}
+
+bool cHardwareCPU::Inst_Order()
+{
+  if (Register(REG_BX) > Register(REG_CX)) {
+    nFunctions::Swap(Register(REG_BX), Register(REG_CX));
+  }
+  return true;
+}
+
+bool cHardwareCPU::Inst_Xor()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = Register(REG_BX) ^ Register(REG_CX);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Copy()
+{
+  const cHeadCPU from(this, Register(REG_BX));
+  cHeadCPU 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 cHardwareCPU::Inst_ReadInst()
+{
+  const int reg_used = FindModifiedRegister(REG_CX);
+  const cHeadCPU 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 cHardwareCPU::Inst_WriteInst()
+{
+  cHeadCPU 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 cHardwareCPU::Inst_StackReadInst()
+{
+  const int reg_used = FindModifiedRegister(REG_CX);
+  cHeadCPU from(this, Register(reg_used));
+  StackPush(from.GetInst().GetOp());
+  return true;
+}
+
+bool cHardwareCPU::Inst_StackWriteInst()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  cHeadCPU 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 cHardwareCPU::Inst_Compare()
+{
+  const int reg_used = FindModifiedRegister(REG_CX);
+  cHeadCPU from(this, Register(REG_BX));
+  cHeadCPU 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 cHardwareCPU::Inst_IfNCpy()
+{
+  const cHeadCPU from(this, Register(REG_BX));
+  const cHeadCPU 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 cHardwareCPU::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 cHardwareCPU::Inst_Divide()  
+{ 
+  return Divide_Main(Register(REG_AX));    
+}
+
+bool cHardwareCPU::Inst_CDivide() 
+{ 
+  return Divide_Main(GetMemory().GetSize() / 2);   
+}
+
+bool cHardwareCPU::Inst_CAlloc()  
+{ 
+  return Allocate_Main(GetMemory().GetSize());   
+}
+
+bool cHardwareCPU::Inst_MaxAlloc()   // Allocate maximal more
+{
+  const int cur_size = GetMemory().GetSize();
+  const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
+			     MAX_CREATURE_SIZE - cur_size);
+  if( Allocate_Main(alloc_size) ) {
+    Register(REG_AX) = cur_size;
+    return true;
+  } else return false;
+}
+
+
+bool cHardwareCPU::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;
+}
+
+
+bool cHardwareCPU::Inst_Kazi()
+{
+	const int reg_used = FindModifiedRegister(REG_AX);
+	int percentProb = Register(reg_used) % 100;
+	int random = abs(rand()) % 100;
+	if (random >= percentProb)
+	{
+		return true;
+	}
+	else
+	{
+		organism->Kaboom();
+		return true;
+	}
+}
+
+bool cHardwareCPU::Inst_Die()
+{
+   const double die_prob = cConfig::GetDieProb();
+   if(g_random.GetDouble() < die_prob) { organism->Die(); }
+   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 cHardwareCPU::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(1, NUM_NOPS);
+
+  const bool inject_signal = host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
+  if (inject_signal) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
+    return false; // Inject failed.
+  }
+
+  // Set the relevent flags.
+  organism->GetPhenotype().IsModifier() = true;
+
+  return inject_signal;
+}
+
+
+bool cHardwareCPU::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 cHardwareCPU::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(1, NUM_NOPS);
+
+  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 cHardwareCPU::Inst_TaskGet()
+{
+  const int reg_used = FindModifiedRegister(REG_CX);
+  const int value = organism->GetNextInput();
+  Register(reg_used) = value;
+  organism->DoInput(value);
+  return true;
+}
+
+bool cHardwareCPU::Inst_TaskStackGet()
+{
+  const int value = organism->GetNextInput();
+  StackPush(value);
+  organism->DoInput(value);
+  return true;
+}
+
+bool cHardwareCPU::Inst_TaskStackLoad()
+{
+  for (int i = 0; i < IO_SIZE; i++) 
+    StackPush( organism->GetNextInput() );
+  return true;
+}
+
+bool cHardwareCPU::Inst_TaskPut()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  const int value = Register(reg_used);
+  Register(reg_used) = 0;
+  organism->DoOutput(value);
+  return true;
+}
+
+bool cHardwareCPU::Inst_TaskIO()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+
+  // Do the "put" component
+  const int value_out = Register(reg_used);
+  organism->DoOutput(value_out);  // Check for tasks compleated.
+
+  // Do the "get" component
+  const int value_in = organism->GetNextInput();
+  Register(reg_used) = value_in;
+  organism->DoInput(value_in);
+  return true;
+}
+
+bool cHardwareCPU::Inst_Send()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  organism->SendValue(Register(reg_used));
+  Register(reg_used) = 0;
+  return true;
+}
+
+bool cHardwareCPU::Inst_Receive()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = organism->ReceiveValue();
+  return true;
+}
+
+bool cHardwareCPU::Inst_Sense()
+{
+  const tArray<double> & res_count = organism->PopInterface().GetResources();
+  const int reg_used = FindModifiedRegister(REG_BX);
+
+  // If there are no resources to measure, this instruction fails.
+  if (res_count.GetSize() == 0) return false;
+
+  // Always get the first resource, and convert it to and int.
+  Register(reg_used) = (int) res_count[0];
+
+  // @CAO Since resources are sometimes less than one, perhaps we should
+  // multiply it by some constant?  Or perhaps taking the log would be more
+  // useful so they can easily scan across orders of magnitude?
+
+  return true;
+}
+
+void cHardwareCPU::DoDonate(cOrganism * to_org)
+{
+  assert(to_org != NULL);
+
+  const double merit_given = cConfig::GetMeritGiven();
+  const double merit_received = cConfig::GetMeritReceived();
+
+  double cur_merit = organism->GetPhenotype().GetMerit().GetDouble();
+  cur_merit -= merit_given; 
+
+  // Plug the current merit back into this organism and notify the scheduler.
+  organism->UpdateMerit(cur_merit);
+
+  // Update the merit of the organism being donated to...
+  double other_merit = to_org->GetPhenotype().GetMerit().GetDouble();
+  other_merit += merit_received;
+  to_org->UpdateMerit(other_merit);
+}
+
+bool cHardwareCPU::Inst_DonateRandom()
+{
+  organism->GetPhenotype().IncDonates();
+  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
+    return false;
+  }
+
+  // Turn to a random neighbor, get it, and turn back...
+  int neighbor_id = g_random.GetInt(organism->GetNeighborhoodSize());
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
+  cOrganism * neighbor = organism->GetNeighbor();
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
+
+  // Donate only if we have found a neighbor.
+  if (neighbor != NULL) DoDonate(neighbor);
+  
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_DonateKin()
+{
+  organism->GetPhenotype().IncDonates();
+  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
+    return false;
+  }
+
+  // Find the target as the first Kin found in the neighborhood.
+  const int num_neighbors = organism->GetNeighborhoodSize();
+
+  // Turn to face a random neighbor
+  int neighbor_id = g_random.GetInt(num_neighbors);
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
+  cOrganism * neighbor = organism->GetNeighbor();
+
+  // If there is no max distance, just take the random neighbor we're facing.
+  const int max_dist = cConfig::GetMaxDonateKinDistance();
+  if (max_dist != -1) {
+    int max_id = neighbor_id + num_neighbors;
+    bool found = false;
+    cGenotype * genotype = organism->GetGenotype();
+    while (neighbor_id < max_id) {
+      neighbor = organism->GetNeighbor();
+      if (neighbor != NULL &&
+	  genotype->GetPhyloDistance(neighbor->GetGenotype()) <= max_dist) {
+	found = true;
+	break;
+      }
+      organism->Rotate(1);
+      neighbor_id++;
+    }
+    if (found == false) neighbor = NULL;
+  }
+
+  // Put the facing back where it was.
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
+
+  // Donate only if we have found a close enough relative...
+  if (neighbor != NULL)  DoDonate(neighbor);
+
+  return true;
+}
+
+bool cHardwareCPU::Inst_DonateEditDist()
+{
+  organism->GetPhenotype().IncDonates();
+  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
+    return false;
+  }
+
+  // Find the target as the first Kin found in the neighborhood.
+  const int num_neighbors = organism->GetNeighborhoodSize();
+
+  // Turn to face a random neighbor
+  int neighbor_id = g_random.GetInt(num_neighbors);
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
+  cOrganism * neighbor = organism->GetNeighbor();
+
+  // If there is no max edit distance, take the random neighbor we're facing.
+  const int max_dist = cConfig::GetMaxDonateEditDistance();
+  if (max_dist != -1) {
+    int max_id = neighbor_id + num_neighbors;
+    bool found = false;
+    while (neighbor_id < max_id) {
+      neighbor = organism->GetNeighbor();
+      int edit_dist = max_dist + 1;
+      if (neighbor != NULL) {
+	edit_dist = cGenomeUtil::FindEditDistance(organism->GetGenome(),
+						  neighbor->GetGenome());
+      }
+      if (edit_dist <= max_dist) {
+	found = true;
+	break;
+      }
+      organism->Rotate(1);
+      neighbor_id++;
+    }
+    if (found == false) neighbor = NULL;
+  }
+
+  // Put the facing back where it was.
+  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
+
+  // Donate only if we have found a close enough relative...
+  if (neighbor != NULL)  DoDonate(neighbor);
+
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_DonateNULL()
+{
+  organism->GetPhenotype().IncDonates();
+  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
+    return false;
+  }
+
+  // This is a fake donate command that causes the organism to lose merit,
+  // but no one else to gain any.
+
+  const double merit_given = cConfig::GetMeritGiven();
+  double cur_merit = organism->GetPhenotype().GetMerit().GetDouble();
+  cur_merit -= merit_given;
+
+  // Plug the current merit back into this organism and notify the scheduler.
+  organism->UpdateMerit(cur_merit);
+
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_SearchF()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  const int search_size = FindLabel(1).GetPosition() - IP().GetPosition();
+  Register(REG_BX) = search_size;
+  Register(REG_CX) = GetLabel().GetSize();
+  return true;
+}
+
+bool cHardwareCPU::Inst_SearchB()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  const int search_size = IP().GetPosition() - FindLabel(-1).GetPosition();
+  Register(REG_BX) = search_size;
+  Register(REG_CX) = GetLabel().GetSize();
+  return true;
+}
+
+bool cHardwareCPU::Inst_MemSize()
+{
+  Register(FindModifiedRegister(REG_BX)) = GetMemory().GetSize();
+  return true;
+}
+
+
+bool cHardwareCPU::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(1, NUM_NOPS);
+  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.
+      cHardwareCPU & cur_hardware = (cHardwareCPU &) neighbor->GetHardware();
+      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
+    }
+
+    // Otherwise keep rotating...
+    organism->Rotate(-1);
+  }
+  return true;
+}
+
+bool cHardwareCPU::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(1, NUM_NOPS);
+  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.
+      cHardwareCPU & cur_hardware = (cHardwareCPU &) neighbor->GetHardware();
+      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
+    }
+
+    // Otherwise keep rotating...
+    organism->Rotate(1);
+  }
+  return true;
+}
+
+bool cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::Inst_ForkThread()
+{
+  IP().Advance();
+  if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  return true;
+}
+
+bool cHardwareCPU::Inst_KillThread()
+{
+  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+  else advance_ip = false;
+  return true;
+}
+
+bool cHardwareCPU::Inst_ThreadID()
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  Register(reg_used) = GetCurThreadID();
+  return true;
+}
+
+
+// Head-based instructions
+
+bool cHardwareCPU::Inst_SetHead()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  SetActiveHead(head_used);
+  return true;
+}
+
+bool cHardwareCPU::Inst_AdvanceHead()
+{
+  const int head_used = FindModifiedHead(HEAD_WRITE);
+  GetHead(head_used).Advance();
+  return true;
+}
+ 
+bool cHardwareCPU::Inst_MoveHead()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  GetHead(head_used).Set(GetHead(HEAD_FLOW));
+  if (head_used == HEAD_IP) advance_ip = false;
+  return true;
+}
+
+bool cHardwareCPU::Inst_JumpHead()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  GetHead(head_used).Jump( Register(REG_CX) );
+  return true;
+}
+
+bool cHardwareCPU::Inst_GetHead()
+{
+  const int head_used = FindModifiedHead(HEAD_IP);
+  Register(REG_CX) = GetHead(head_used).GetPosition();
+  return true;
+}
+
+bool cHardwareCPU::Inst_IfLabel()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  if (GetLabel() != GetReadLabel())  IP().Advance();
+  return true;
+}
+
+// This is a variation on IfLabel that will skip the next command if the "if"
+// is false, but it will also skip all nops following that command.
+bool cHardwareCPU::Inst_IfLabel2()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  if (GetLabel() != GetReadLabel()) {
+    IP().Advance();
+    if (inst_set->IsNop( IP().GetNextInst() ))  IP().Advance();
+  }
+  return true;
+}
+
+bool cHardwareCPU::Inst_HeadDivideMut(double mut_multiplier)
+{
+  AdjustHeads();
+  const int divide_pos = GetHead(HEAD_READ).GetPosition();
+  int child_end =  GetHead(HEAD_WRITE).GetPosition();
+  if (child_end == 0) child_end = GetMemory().GetSize();
+  const int extra_lines = GetMemory().GetSize() - child_end;
+  bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
+  // Re-adjust heads.
+  AdjustHeads();
+  return ret_val; 
+}
+
+bool cHardwareCPU::Inst_HeadDivide()
+{
+  return Inst_HeadDivideMut(1);
+}
+
+bool cHardwareCPU::Inst_HeadDivideSex()  
+{ 
+  organism->GetPhenotype().SetDivideSex(true);
+  organism->GetPhenotype().SetCrossNum(1);
+  return Inst_HeadDivide(); 
+}
+
+bool cHardwareCPU::Inst_HeadDivideAsex()  
+{ 
+  organism->GetPhenotype().SetDivideSex(false);
+  organism->GetPhenotype().SetCrossNum(0);
+  return Inst_HeadDivide(); 
+}
+
+bool cHardwareCPU::Inst_HeadDivideAsexWait()  
+{ 
+  organism->GetPhenotype().SetDivideSex(true);
+  organism->GetPhenotype().SetCrossNum(0);
+  return Inst_HeadDivide(); 
+}
+
+bool cHardwareCPU::Inst_HeadDivideMateSelect()  
+{ 
+  // Take the label that follows this divide and use it as the ID for which
+  // other organisms this one is willing to mate with.
+  ReadLabel();
+  organism->GetPhenotype().SetMateSelectID( GetLabel().AsInt(NUM_NOPS) );
+
+//   int mate_id = GetLabel().AsInt(NUM_NOPS);
+//   if (mate_id > 0) cout << mate_id << " "
+// 			<< GetLabel().AsString() << endl;
+
+  // Proceed as normal with the rest of mate selection.
+  organism->GetPhenotype().SetDivideSex(true);
+  organism->GetPhenotype().SetCrossNum(1);
+  return Inst_HeadDivide(); 
+}
+
+bool cHardwareCPU::Inst_HeadDivide1()  { return Inst_HeadDivideMut(1); }
+bool cHardwareCPU::Inst_HeadDivide2()  { return Inst_HeadDivideMut(2); }
+bool cHardwareCPU::Inst_HeadDivide3()  { return Inst_HeadDivideMut(3); }
+bool cHardwareCPU::Inst_HeadDivide4()  { return Inst_HeadDivideMut(4); }
+bool cHardwareCPU::Inst_HeadDivide5()  { return Inst_HeadDivideMut(5); }
+bool cHardwareCPU::Inst_HeadDivide6()  { return Inst_HeadDivideMut(6); }
+bool cHardwareCPU::Inst_HeadDivide7()  { return Inst_HeadDivideMut(7); }
+bool cHardwareCPU::Inst_HeadDivide8()  { return Inst_HeadDivideMut(8); }
+bool cHardwareCPU::Inst_HeadDivide9()  { return Inst_HeadDivideMut(9); }
+bool cHardwareCPU::Inst_HeadDivide10()  { return Inst_HeadDivideMut(10); }
+bool cHardwareCPU::Inst_HeadDivide16()  { return Inst_HeadDivideMut(16); }
+bool cHardwareCPU::Inst_HeadDivide32()  { return Inst_HeadDivideMut(32); }
+bool cHardwareCPU::Inst_HeadDivide50()  { return Inst_HeadDivideMut(50); }
+bool cHardwareCPU::Inst_HeadDivide100()  { return Inst_HeadDivideMut(100); }
+bool cHardwareCPU::Inst_HeadDivide500()  { return Inst_HeadDivideMut(500); }
+bool cHardwareCPU::Inst_HeadDivide1000()  { return Inst_HeadDivideMut(1000); }
+bool cHardwareCPU::Inst_HeadDivide5000()  { return Inst_HeadDivideMut(5000); }
+bool cHardwareCPU::Inst_HeadDivide10000()  { return Inst_HeadDivideMut(10000); }
+bool cHardwareCPU::Inst_HeadDivide50000()  { return Inst_HeadDivideMut(50000); }
+bool cHardwareCPU::Inst_HeadDivide0_5()  { return Inst_HeadDivideMut(0.5); }
+bool cHardwareCPU::Inst_HeadDivide0_1()  { return Inst_HeadDivideMut(0.1); }
+bool cHardwareCPU::Inst_HeadDivide0_05()  { return Inst_HeadDivideMut(0.05); }
+bool cHardwareCPU::Inst_HeadDivide0_01()  { return Inst_HeadDivideMut(0.01); }
+bool cHardwareCPU::Inst_HeadDivide0_001()  { return Inst_HeadDivideMut(0.001); }
+
+bool cHardwareCPU::Inst_HeadRead()
+{
+  const int head_id = FindModifiedHead(HEAD_READ);
+  GetHead(head_id).Adjust();
+  sCPUStats & cpu_stats = organism->CPUStats();
+
+  // Mutations only occur on the read, for the moment.
+  int read_inst = 0;
+  if (organism->TestCopyMut()) {
+    read_inst = GetRandomInst().GetOp();
+    cpu_stats.mut_stats.copy_mut_count++;  // @CAO, hope this is good!
+  } else {
+    read_inst = GetHead(head_id).GetInst().GetOp();
+  }
+  Register(REG_BX) = read_inst;
+  ReadInst(read_inst);
+
+  cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
+  GetHead(head_id).Advance();
+  return true;
+}
+
+bool cHardwareCPU::Inst_HeadWrite()
+{
+  const int head_id = FindModifiedHead(HEAD_WRITE);
+  cHeadCPU & active_head = GetHead(head_id);
+
+  active_head.Adjust();
+
+  int value = Register(REG_BX);
+  if (value < 0 || value >= GetNumInst()) value = 0;
+
+  active_head.SetInst(cInstruction(value));
+  active_head.FlagCopied() = true;
+
+  // Advance the head after write...
+  active_head++;
+  return true;
+}
+
+bool cHardwareCPU::Inst_HeadCopy()
+{
+  // For the moment, this cannot be nop-modified.
+  cHeadCPU & read_head = GetHead(HEAD_READ);
+  cHeadCPU & write_head = GetHead(HEAD_WRITE);
+  sCPUStats & cpu_stats = organism->CPUStats();
+
+  read_head.Adjust();
+  write_head.Adjust();
+
+  // TriggerMutations(MUTATION_TRIGGER_READ, read_head);
+  
+  // Do mutations.
+  cInstruction read_inst = read_head.GetInst();
+  ReadInst(read_inst.GetOp());
+  if (organism->TestCopyMut()) {
+    read_inst = GetRandomInst();
+    cpu_stats.mut_stats.copy_mut_count++; 
+    write_head.FlagMutated() = true;
+    write_head.FlagCopyMut() = true;
+    //organism->GetPhenotype().IsMutated() = true;
+  }
+
+  cpu_stats.mut_stats.copies_exec++;
+
+  write_head.SetInst(read_inst);
+  write_head.FlagCopied() = true;  // Set the copied flag...
+
+  // TriggerMutations(MUTATION_TRIGGER_WRITE, write_head);
+
+  read_head.Advance();
+  write_head.Advance();
+  return true;
+}
+
+bool cHardwareCPU::HeadCopy_ErrorCorrect(double reduction)
+{
+  // For the moment, this cannot be nop-modified.
+  cHeadCPU & read_head = GetHead(HEAD_READ);
+  cHeadCPU & write_head = GetHead(HEAD_WRITE);
+  sCPUStats & cpu_stats = organism->CPUStats();
+
+  read_head.Adjust();
+  write_head.Adjust();
+
+  // Do mutations.
+  cInstruction read_inst = read_head.GetInst();
+  ReadInst(read_inst.GetOp());
+  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;
+  }
+
+  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 cHardwareCPU::Inst_HeadCopy2()  { return HeadCopy_ErrorCorrect(2); }
+bool cHardwareCPU::Inst_HeadCopy3()  { return HeadCopy_ErrorCorrect(3); }
+bool cHardwareCPU::Inst_HeadCopy4()  { return HeadCopy_ErrorCorrect(4); }
+bool cHardwareCPU::Inst_HeadCopy5()  { return HeadCopy_ErrorCorrect(5); }
+bool cHardwareCPU::Inst_HeadCopy6()  { return HeadCopy_ErrorCorrect(6); }
+bool cHardwareCPU::Inst_HeadCopy7()  { return HeadCopy_ErrorCorrect(7); }
+bool cHardwareCPU::Inst_HeadCopy8()  { return HeadCopy_ErrorCorrect(8); }
+bool cHardwareCPU::Inst_HeadCopy9()  { return HeadCopy_ErrorCorrect(9); }
+bool cHardwareCPU::Inst_HeadCopy10() { return HeadCopy_ErrorCorrect(10); }
+
+bool cHardwareCPU::Inst_HeadSearch()
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  cHeadCPU found_pos = FindLabel(0);
+  const int search_size = found_pos.GetPosition() - IP().GetPosition();
+  Register(REG_BX) = search_size;
+  Register(REG_CX) = GetLabel().GetSize();
+  GetHead(HEAD_FLOW).Set(found_pos);
+  GetHead(HEAD_FLOW).Advance();
+  return true; 
+}
+
+bool cHardwareCPU::Inst_SetFlow()
+{
+  const int reg_used = FindModifiedRegister(REG_CX);
+  GetHead(HEAD_FLOW).Set(Register(reg_used), this);
+  return true; 
+}
+
+// Direct Matching Templates
+
+bool cHardwareCPU::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.
+  cHeadCPU 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 cHardwareCPU::Inst_Skip()
+{
+  IP().Advance();
+  return true;
+}
+
+

Copied: trunk/source/cpu/cHardwareCPU.h (from rev 299, trunk/source/cpu/hardware_cpu.hh)
===================================================================
--- trunk/source/cpu/hardware_cpu.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/cHardwareCPU.h	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,588 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2004 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef HARDWARE_CPU_HH
+#define HARDWARE_CPU_HH
+
+#include <iomanip>
+#include <vector>
+
+#ifndef DEFS_HH
+#include "defs.hh"
+#endif
+#ifndef CODE_LABEL_HH
+#include "cCodeLabel.h"
+#endif
+#ifndef CPU_DEFS_HH
+#include "cpu_defs.hh"
+#endif
+#ifndef HEAD_CPU_HH
+#include "head_cpu.hh"
+#endif
+#ifndef CPU_MEMORY_HH
+#include "cCPUMemory.h"
+#endif
+#ifndef CPU_STACK_HH
+#include "cCPUStack.h"
+#endif
+#ifndef HARDWARE_BASE_HH
+#include "cHardwareBase.h"
+#endif
+#ifndef HARDWARE_CPU_THREAD_HH
+#include "cHardwareCPU_Thread.h"
+#endif
+#ifndef STRING_HH
+#include "string.hh"
+#endif
+#ifndef TARRAY_HH
+#include "tArray.hh"
+#endif
+
+class cInstSet;
+class cInstLibBase;
+class cOrganism;
+class cMutation;
+class cHardwareCPU_Thread;
+
+#ifdef SINGLE_IO_BUFFER   // For Single IOBuffer vs IOBuffer for each Thread
+# define IO_THREAD 0
+#else
+# define IO_THREAD cur_thread
+#endif
+
+/**
+ * Each organism may have a cHardwareCPU structure which keeps track of the
+ * current status of all the components of the simulated hardware.
+ *
+ * @see cHardwareCPU_Thread, cCPUStack, cCPUMemory, cInstSet
+ **/
+
+class cCodeLabel; // access
+class cHeadCPU; // access
+class cCPUMemory; // aggregate
+class cCPUStack; // aggregate
+class cGenome;
+class cHardwareCPU_Thread; // access
+class cInstLibBase;
+class cInstLibCPU;
+class cInstruction;
+class cInstSet;
+class cMutation;
+class cOrganism;
+class cString; // aggregate
+template <class T> class tBuffer;
+template <class T> class tArray; // aggregate
+
+class cHardwareCPU : public cHardwareBase {
+public:
+  typedef bool (cHardwareCPU::*tHardwareCPUMethod)();
+private:
+  static cInstLibCPU *s_inst_slib;
+  static cInstLibCPU *initInstLib(void);
+  tHardwareCPUMethod *m_functions;
+private:
+  cCPUMemory memory;          // Memory...
+  cCPUStack global_stack;     // A stack that all threads share.
+  int thread_time_used;
+
+  tArray<cHardwareCPU_Thread> threads;
+  int thread_id_chart;
+  int cur_thread;
+
+  // Flags...
+  bool mal_active;         // Has an allocate occured since last divide?
+  bool advance_ip;         // Should the IP advance after this instruction?
+
+  // Instruction costs...
+#ifdef INSTRUCTION_COSTS
+  tArray<int> inst_cost;
+  tArray<int> inst_ft_cost;
+#endif
+
+public:
+  cHardwareCPU(cOrganism * in_organism, cInstSet * in_inst_set);
+  explicit cHardwareCPU(const cHardwareCPU &);
+  ~cHardwareCPU();
+  void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
+  static cInstLibCPU *GetInstLib();
+  static cString GetDefaultInstFilename() { return "inst_lib.default"; }
+  static void WriteDefaultInstSet() { ; }
+
+  void Reset();
+  void SingleProcess();
+  bool SingleProcess_PayCosts(const cInstruction & cur_inst);
+  bool SingleProcess_ExecuteInst(const cInstruction & cur_inst);
+  void ProcessBonusInst(const cInstruction & inst);
+  void LoadGenome(const cGenome & new_genome);
+
+  // --------  Helper methods  --------
+  bool OK();
+  void PrintStatus(std::ostream & fp);
+
+
+  // --------  Flag Accessors --------
+  bool GetMalActive() const   { return mal_active; }
+
+  // --------  Stack Manipulation...  --------
+  inline void StackPush(int value);
+  inline int StackPop();
+  inline void StackFlip();
+  inline int GetStack(int depth=0, int stack_id=-1) const;
+  inline void StackClear();
+  inline void SwitchStack();
+  int GetActiveStackID() const { return threads[cur_thread].cur_stack; }
+
+
+  // --------  Head Manipulation (including IP)  --------
+  inline void SetActiveHead(const int new_head)
+  { threads[cur_thread].cur_head = (UCHAR) new_head; }
+
+  int GetCurHead() const { return threads[cur_thread].cur_head; }
+  const cHeadCPU & GetHead(int head_id) const
+    { return threads[cur_thread].heads[head_id]; }
+  cHeadCPU & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
+
+  const cHeadCPU & GetActiveHead() const { return GetHead(GetCurHead()); }
+  cHeadCPU & GetActiveHead() { return GetHead(GetCurHead()); }
+
+  void AdjustHeads();
+
+  inline const cHeadCPU & IP() const
+    { return threads[cur_thread].heads[HEAD_IP]; }
+  inline cHeadCPU & IP() { return threads[cur_thread].heads[HEAD_IP]; }
+
+
+  // --------  Label Manipulation  -------
+  void ReadLabel(int max_size=MAX_LABEL_SIZE);
+  const cCodeLabel & GetLabel() const 
+    { return threads[cur_thread].next_label; }
+  cCodeLabel & GetLabel() { return threads[cur_thread].next_label; }
+  const cCodeLabel & GetReadLabel() const
+    { return threads[cur_thread].read_label; }
+  cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
+
+
+  // --------  Register Manipulation  --------
+  const int & Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
+  int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
+
+  // --------  Memory Manipulation  --------
+  inline const cCPUMemory & Memory() const { return memory; }
+  inline cCPUMemory & Memory() { return memory; }
+
+  // --------  Thread Manipulation  --------
+  bool ForkThread(); // Adds a new thread based off of cur_thread.
+  bool KillThread(); // Kill the current thread!
+  inline void PrevThread(); // Shift the current thread in use.
+  inline void NextThread();
+  inline void SetThread(int value);
+
+  // --------  Tests  --------
+
+  int TestParasite() const;
+
+  // --------  Accessors  --------
+  const cCPUMemory & GetMemory() const { return memory; }
+  cCPUMemory & GetMemory() { return memory; }
+  const cCPUMemory & GetMemory(int value) const { return memory;}
+  cCPUMemory & GetMemory(int value) { return memory; }
+
+  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(); }
+
+  int GetThreadDist() const {
+    if (GetNumThreads() == 1) return 0;
+    return threads[0].heads[HEAD_IP].GetPosition() -
+      threads[1].heads[HEAD_IP].GetPosition();
+  }
+
+  // Complex label manipulation...
+  cHeadCPU FindLabel(int direction);
+  int FindLabel_Forward(const cCodeLabel & search_label,
+			  const cGenome & search_genome, int pos);
+  int FindLabel_Backward(const cCodeLabel & search_label,
+			  const cGenome & search_genome, int pos);
+  cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
+  cHeadCPU FindFullLabel(const cCodeLabel & in_label);
+
+  int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
+  int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
+  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);
+
+  bool TriggerMutations(int trigger);
+  bool TriggerMutations(int trigger, cHeadCPU & cur_head);
+  bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
+  bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
+  int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
+        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
+  void TriggerMutations_Body(int type, cCPUMemory & target_memory,
+			     cHeadCPU & cur_head);
+
+  void ReadInst(const int in_inst);
+
+  void SaveState(std::ostream & fp);
+  void LoadState(std::istream & fp);
+
+  //void InitInstSet(const cString & filename, cInstSet & inst_set);
+
+
+private:
+ 
+ /////////---------- Instruction Helpers ------------//////////
+
+  int FindModifiedRegister(int default_register);
+  int FindModifiedHead(int default_head);
+  int FindComplementRegister(int base_reg);
+
+  void Fault(int fault_loc, int fault_type, cString fault_desc="");
+
+  bool Allocate_Necro(const int new_size);
+  bool Allocate_Random(const int old_size, const int new_size);
+  bool Allocate_Default(const int new_size);
+  bool Allocate_Main(const int allocated_size);
+
+  bool Divide_Main(const int divide_point, const int extra_lines=0, double mut_multiplier=1);
+
+  bool Divide_CheckViable(const int child_size, const int parent_size);
+  void Divide_DoMutations(double mut_multiplier=1);
+  void Divide_TestFitnessMeasures();
+
+  bool HeadCopy_ErrorCorrect(double reduction);
+  bool Inst_HeadDivideMut(double mut_multiplier=1);
+
+public:
+  /////////---------- Instruction Library ------------//////////
+
+  // Flow Control
+  bool Inst_If0();
+  bool Inst_IfEqu();
+  bool Inst_IfNot0();
+  bool Inst_IfNEqu();
+  bool Inst_IfGr0();
+  bool Inst_IfGr();
+  bool Inst_IfGrEqu0();
+  bool Inst_IfGrEqu();
+  bool Inst_IfLess0();
+  bool Inst_IfLess();
+  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_HeadPop();
+  bool Inst_HeadPush();
+
+  bool Inst_PopA();
+  bool Inst_PopB();
+  bool Inst_PopC();
+  bool Inst_PushA();
+  bool Inst_PushB();
+  bool Inst_PushC();
+
+  bool Inst_SwitchStack();
+  bool Inst_FlipStack();
+  bool Inst_Swap();
+  bool Inst_SwapAB();
+  bool Inst_SwapBC();
+  bool Inst_SwapAC();
+  bool Inst_CopyReg();
+  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_ShiftR();
+  bool Inst_ShiftL();
+  bool Inst_Bit1();
+  bool Inst_SetNum();
+  bool Inst_ValGrey();
+  bool Inst_ValDir();
+  bool Inst_ValAddP();
+  bool Inst_ValFib();
+  bool Inst_ValPolyC();
+  bool Inst_Inc();
+  bool Inst_Dec();
+  bool Inst_Zero();
+  bool Inst_Not();
+  bool Inst_Neg();
+  bool Inst_Square();
+  bool Inst_Sqrt();
+  bool Inst_Log();
+  bool Inst_Log10();
+  bool Inst_Minus17();
+
+  // Double Argument Math
+  bool Inst_Add();
+  bool Inst_Sub();
+  bool Inst_Mult();
+  bool Inst_Div();
+  bool Inst_Mod();
+  bool Inst_Nand();
+  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_Divide();
+  bool Inst_CAlloc();
+  bool Inst_CDivide();
+  bool Inst_MaxAlloc();
+  bool Inst_Inject();
+  bool Inst_InjectRand();
+  bool Inst_InjectThread();
+  bool Inst_Repro();
+  bool Inst_Kazi();
+  bool Inst_Die();
+
+  // I/O and Sensory
+  bool Inst_TaskGet();
+  bool Inst_TaskStackGet();
+  bool Inst_TaskStackLoad();
+  bool Inst_TaskPut();
+  bool Inst_TaskIO();
+  bool Inst_Send();
+  bool Inst_Receive();
+  bool Inst_Sense();
+
+  void DoDonate(cOrganism * to_org);
+  bool Inst_DonateRandom();
+  bool Inst_DonateKin();
+  bool Inst_DonateEditDist();
+  bool Inst_DonateNULL();
+
+  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_ForkThread();
+  bool Inst_KillThread();
+  bool Inst_ThreadID();
+
+  // Head-based instructions...
+
+  bool Inst_SetHead();
+  bool Inst_AdvanceHead();
+  bool Inst_MoveHead();
+  bool Inst_JumpHead();
+  bool Inst_GetHead();
+  bool Inst_IfLabel();
+  bool Inst_IfLabel2();
+  bool Inst_HeadDivide();
+  bool Inst_HeadRead();
+  bool Inst_HeadWrite();
+  bool Inst_HeadCopy();
+  bool Inst_HeadSearch();
+  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_HeadDivideAsexWait();
+  bool Inst_HeadDivideMateSelect();
+
+  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();
+};
+
+
+//////////////////
+//  cHardwareCPU
+//////////////////
+
+inline void cHardwareCPU::NextThread()
+{
+  cur_thread++;
+  if (cur_thread >= GetNumThreads()) cur_thread = 0;
+}
+
+inline void cHardwareCPU::PrevThread()
+{
+  if (cur_thread == 0) cur_thread = GetNumThreads() - 1;
+  else cur_thread--;
+}
+
+inline void cHardwareCPU::SetThread(int value)
+{
+     if (value>=0 && value < GetNumThreads())
+          cur_thread=value;
+}
+
+inline void cHardwareCPU::StackPush(int value)
+{
+  if (threads[cur_thread].cur_stack == 0) {
+    threads[cur_thread].stack.Push(value);
+  } else {
+    global_stack.Push(value);
+  }
+}
+
+inline int cHardwareCPU::StackPop()
+{
+  int pop_value;
+
+  if (threads[cur_thread].cur_stack == 0) {
+    pop_value = threads[cur_thread].stack.Pop();
+  } else {
+    pop_value = global_stack.Pop();
+  }
+
+  return pop_value;
+}
+
+inline void cHardwareCPU::StackFlip()
+{
+  if (threads[cur_thread].cur_stack == 0) {
+    threads[cur_thread].stack.Flip();
+  } else {
+    global_stack.Flip();
+  }
+}
+
+inline int cHardwareCPU::GetStack(int depth, int stack_id) const
+{
+  int value = 0;
+
+  if (stack_id == -1) stack_id = threads[cur_thread].cur_stack;
+
+  if (stack_id == 0) value = threads[cur_thread].stack.Get(depth);
+  else if (stack_id == 1) value = global_stack.Get(depth);
+
+  return value;
+}
+
+inline void cHardwareCPU::StackClear()
+{
+  if (threads[cur_thread].cur_stack == 0) {
+    threads[cur_thread].stack.Clear();
+  } else {
+    global_stack.Clear();
+  }
+}
+
+inline void cHardwareCPU::SwitchStack()
+{
+  threads[cur_thread].cur_stack++;
+  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
+}
+
+#endif

Copied: trunk/source/cpu/cHardwareCPU_Thread.cc (from rev 298, trunk/source/cpu/hardware_cpu_thread.cc)
===================================================================
--- trunk/source/cpu/hardware_cpu_thread.cc	2005-08-29 18:54:25 UTC (rev 298)
+++ trunk/source/cpu/cHardwareCPU_Thread.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,126 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef HARDWARE_CPU_THREAD_HH
+#include "cHardwareCPU_Thread.h"
+#endif
+
+using namespace std;
+
+/////////////////////////
+//  cHardwareCPU_Thread
+/////////////////////////
+
+cHardwareCPU_Thread::cHardwareCPU_Thread(cHardwareBase * in_hardware, int _id)
+{
+  Reset(in_hardware, _id);
+}
+
+cHardwareCPU_Thread::cHardwareCPU_Thread(const cHardwareCPU_Thread & in_thread, int _id)
+{
+   id = _id;
+   if (id == -1) id = in_thread.id;
+   for (int i = 0; i < NUM_REGISTERS; i++) {
+     reg[i] = in_thread.reg[i];
+   }
+   for (int i = 0; i < NUM_HEADS; i++) {
+     heads[i] = in_thread.heads[i];
+   }
+   stack = in_thread.stack;
+}
+
+cHardwareCPU_Thread::~cHardwareCPU_Thread() {}
+
+void cHardwareCPU_Thread::operator=(const cHardwareCPU_Thread & in_thread)
+{
+  id = in_thread.id;
+  for (int i = 0; i < NUM_REGISTERS; i++) {
+    reg[i] = in_thread.reg[i];
+  }
+  for (int i = 0; i < NUM_HEADS; i++) {
+    heads[i] = in_thread.heads[i];
+  }
+  stack = in_thread.stack;
+}
+
+void cHardwareCPU_Thread::Reset(cHardwareBase * in_hardware, int _id)
+{
+  id = _id;
+
+  for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
+  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
+
+  stack.Clear();
+  cur_stack = 0;
+  cur_head = HEAD_IP;
+  read_label.Clear();
+  next_label.Clear();
+}
+
+
+
+
+void cHardwareCPU_Thread::SaveState(ostream & fp){
+  assert(fp.good());
+  fp << "cHardwareCPU_Thread" << endl;
+
+  // registers
+  for( int i=0; i<NUM_REGISTERS; ++i ){
+    fp<<reg[i]<<endl;
+  }
+
+  // heads (@TCC does not handle parasites!!!)
+  for( int i=0; i<NUM_HEADS; ++i ){
+    fp<<heads[i].GetPosition()<<endl;
+  }
+
+  stack.SaveState(fp);
+
+  fp<<"|"; // marker
+  fp<<cur_stack;
+  fp<<cur_head;
+  fp<<endl;
+
+  // Code labels
+  read_label.SaveState(fp);
+  next_label.SaveState(fp);
+}
+
+
+
+void cHardwareCPU_Thread::LoadState(istream & fp){
+  assert(fp.good());
+  cString foo;
+  fp >> foo;
+  assert( foo == "cHardwareCPU_Thread");
+
+  // registers
+  for( int i=0; i<NUM_REGISTERS; ++i ){
+    fp>>reg[i];
+  }
+
+  // heads (@TCC does not handle parasites!!!)
+  for( int i=0; i<NUM_HEADS; ++i ){
+    int pos;
+    fp>>pos;
+    heads[i].AbsSet(pos);
+  }
+
+  // stack
+  stack.LoadState(fp);
+
+  char marker; fp>>marker; assert( marker == '|' );
+  /* YIKES!  data loss below: */
+  char the_cur_stack = cur_stack;
+  char the_cur_head = cur_head;
+  fp.get(the_cur_stack);
+  fp.get(the_cur_head);
+
+  // Code labels
+  read_label.LoadState(fp);
+  next_label.LoadState(fp);
+}

Copied: trunk/source/cpu/cHardwareCPU_Thread.h (from rev 299, trunk/source/cpu/hardware_cpu_thread.hh)

Copied: trunk/source/cpu/cHardwareFactory.cc (from rev 298, trunk/source/cpu/hardware_factory.cc)
===================================================================
--- trunk/source/cpu/hardware_factory.cc	2005-08-29 18:54:25 UTC (rev 298)
+++ trunk/source/cpu/cHardwareFactory.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -0,0 +1,82 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 1993 - 2003 California Institute of Technology             //
+//                                                                          //
+// Read the COPYING and README files, or contact 'avida at alife.org',         //
+// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
+//////////////////////////////////////////////////////////////////////////////
+
+#include "cHardwareFactory.h"
+
+#include "cHardwareBase.h"
+#include "cHardwareCPU.h"
+#include "cHardware4Stack.h"
+#include "hardware_smt.h"
+#include "inst_set.hh"
+#include "organism.hh"
+
+using namespace std;
+
+// Static private variables...
+tList<cHardwareBase> cHardwareFactory::hardware_cpu_list;
+int cHardwareFactory::new_count(0);
+int cHardwareFactory::recycle_count(0);
+
+cHardwareBase * cHardwareFactory::Create(cOrganism * in_org,
+					 cInstSet * inst_set, int type)
+{
+  assert(in_org != NULL);
+  assert(inst_set != NULL && inst_set->OK());
+
+  cHardwareBase * new_hardware = NULL;
+
+  // If there is nothing to recycle, just create a new one.
+  if (hardware_cpu_list.GetSize() == 0)
+  {
+    new_count++;
+    switch (type)
+    {
+      case HARDWARE_TYPE_CPU_ORIGINAL:
+        new_hardware = new cHardwareCPU(in_org, inst_set);
+        break;
+      case HARDWARE_TYPE_CPU_4STACK:
+        new_hardware = new cHardware4Stack(in_org, inst_set);
+        break;
+      case HARDWARE_TYPE_CPU_SMT:
+        new_hardware = new cHardwareSMT(in_org, inst_set);
+    }
+  }
+
+  // If we do have hardware to recycle, do so!
+  else {
+    new_hardware = hardware_cpu_list.PopRear();
+    new_hardware->Recycle(in_org, inst_set);
+    recycle_count++;
+  }
+
+  return new_hardware;
+}
+
+// Recycled hardware may be *briefly* in use, so don't delete immediately.
+void cHardwareFactory::Recycle(cHardwareBase * out_hardware)
+{
+  hardware_cpu_list.Push(out_hardware);
+}
+
+// Delete any hardware that needs it, save the rest for re-use.
+void cHardwareFactory::Update()
+{
+  int delete_count = 0;
+  while (hardware_cpu_list.GetSize() > 100) {
+    delete hardware_cpu_list.Pop();
+    delete_count++;
+  }
+
+//    cerr << "   NewHardware: " << new_count
+//         << "   Recycled: " << recycle_count
+//         << "   Deleted: " << delete_count
+//         << "   Stored: " << hardware_cpu_list.GetSize()
+//         << "   Existing: " << cHardwareBase::GetInstanceCount()
+//         << endl;
+
+  new_count = recycle_count = 0;
+}

Copied: trunk/source/cpu/cHardwareFactory.h (from rev 298, trunk/source/cpu/hardware_factory.hh)

Modified: trunk/source/cpu/cpu.pri
===================================================================
--- trunk/source/cpu/cpu.pri	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/cpu.pri	2005-08-29 19:51:42 UTC (rev 300)
@@ -6,10 +6,10 @@
              $$CPU_HH/cCPUMemory.h \
              $$CPU_HH/cCPUStack.h \
              $$CPU_HH/sCPUStats.h \
-             $$CPU_HH/hardware_4stack.hh \
-             $$CPU_HH/hardware_base.hh \
-             $$CPU_HH/hardware_cpu.hh \
-             $$CPU_HH/hardware_factory.hh \
+             $$CPU_HH/cHardware4Stack.h \
+             $$CPU_HH/cHardwareBase.h \
+             $$CPU_HH/cHardwareCPU.h \
+             $$CPU_HH/cHardwareFactory.h \
              $$CPU_HH/hardware_util.hh \
              $$CPU_HH/test_cpu.hh \
              $$CPU_HH/test_util.hh
@@ -21,12 +21,12 @@
              $$CPU_CC/cCPUMemory.cc \
              $$CPU_CC/cCPUStack.cc \
              $$CPU_CC/cCPUTestInfo.cc \
-             $$CPU_CC/hardware_4stack.cc \
-             $$CPU_CC/hardware_4stack_thread.cc \
-             $$CPU_CC/hardware_base.cc \
-             $$CPU_CC/hardware_cpu.cc \
-             $$CPU_CC/hardware_cpu_thread.cc \
-             $$CPU_CC/hardware_factory.cc \
+             $$CPU_CC/cHardware4Stack.cc \
+             $$CPU_CC/cHardware4Stack_Thread.cc \
+             $$CPU_CC/cHardwareBase.cc \
+             $$CPU_CC/cHardwareCPU.cc \
+             $$CPU_CC/cHardwareCPU_Thread.cc \
+             $$CPU_CC/cHardwareFactory.cc \
              $$CPU_CC/hardware_util.cc \
              $$CPU_CC/memory_flags.cc \
              $$CPU_CC/test_cpu.cc \

Deleted: trunk/source/cpu/hardware_4stack.cc
===================================================================
--- trunk/source/cpu/hardware_4stack.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_4stack.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,2306 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-
-
-#include "hardware_4stack.hh"
-
-#include "config.hh"
-#include "cCPUTestInfo.h"
-#include "functions.hh"
-#include "genome_util.hh"
-#include "inst_lib_base.hh"
-#include "inst_set.hh"
-#include "hardware_tracer.hh"
-#include "hardware_tracer_4stack.hh"
-#include "mutation.hh"
-#include "mutation_lib.hh"
-#include "mutation_macros.hh"
-#include "organism.hh"
-#include "phenotype.hh"
-#include "random.hh"
-#include "string_util.hh"
-#include "test_cpu.hh"
-
-#include <limits.h>
-
-using namespace std;
-
-
-
-
-///////////////
-//  cInstLib4Stack
-///////////////
-
-class cInstLib4Stack : public cInstLibBase {
-  const size_t m_nopmods_array_size;
-  const size_t m_function_array_size;
-  cString *m_nopmod_names;
-  cString *m_function_names;
-  const int *m_nopmods;
-  cHardware4Stack::tHardware4StackMethod *m_functions;
-  static const cInstruction inst_error;
-  static const cInstruction inst_default;
-public:
-  cInstLib4Stack(
-    size_t nopmod_array_size,
-    size_t function_array_size,
-    cString *nopmod_names,
-    cString *function_names,
-    const int *nopmods,
-    cHardware4Stack::tHardware4StackMethod *functions
-  ):m_nopmods_array_size(nopmod_array_size),
-    m_function_array_size(function_array_size),
-    m_nopmod_names(nopmod_names),
-    m_function_names(function_names),
-    m_nopmods(nopmods),
-    m_functions(functions)
-  {}
-  cHardware4Stack::tHardware4StackMethod *GetFunctions(void){ return m_functions; } 
-  const cString &GetName(const unsigned int id) {
-    assert(id < m_function_array_size);
-    return m_function_names[id];
-  }
-  const cString &GetNopName(const unsigned int id) {
-    assert(id < m_nopmods_array_size);
-    return m_nopmod_names[id];
-  }
-  int GetNopMod(const unsigned int id){
-    assert(id < m_nopmods_array_size);
-    return m_nopmods[id];
-  }
-  int GetNopMod(const cInstruction & inst){
-    return GetNopMod(inst.GetOp());
-  }
-  int GetSize(){ return m_function_array_size; }
-  int GetNumNops(){ return m_nopmods_array_size; }
-  cInstruction GetInst(const cString & in_name){
-    for (unsigned int i = 0; i < m_function_array_size; i++) {
-      if (m_function_names[i] == in_name) return cInstruction(i);
-    }
-    return cInstLib4Stack::GetInstError();
-  }
-  const cInstruction & GetInstDefault(){ return inst_default; }
-  const cInstruction & GetInstError(){ return inst_error; }
-};
-
-///////////////
-//  cHardware4Stack
-///////////////
-
-const cInstruction cInstLib4Stack::inst_error(255);
-const cInstruction cInstLib4Stack::inst_default(0);
-cInstLibBase *cHardware4Stack::GetInstLib(){ return s_inst_slib; }
-
-cInstLib4Stack *cHardware4Stack::s_inst_slib = cHardware4Stack::initInstLib();
-cInstLib4Stack *cHardware4Stack::initInstLib(void){
-  struct cNOPEntry4Stack {
-    cNOPEntry4Stack(const cString &name, int nop_mod):name(name), nop_mod(nop_mod){}
-    cString name;
-    int nop_mod;
-  };
-  static const cNOPEntry4Stack s_n_array[] = {
-    cNOPEntry4Stack("Nop-A", STACK_AX),
-    cNOPEntry4Stack("Nop-B", STACK_BX),
-    cNOPEntry4Stack("Nop-C", STACK_CX),
-    cNOPEntry4Stack("Nop-D", STACK_DX),
-    cNOPEntry4Stack("Nop-E", STACK_EX),
-    cNOPEntry4Stack("Nop-F", STACK_FX)
-  };
-
-  struct cInstEntry4Stack {
-    cInstEntry4Stack(const cString &name, tHardware4StackMethod function):name(name), function(function){}
-    cString name;
-    tHardware4StackMethod function;
-  };
-  static const cInstEntry4Stack s_f_array[] = {
-    //1 
-    cInstEntry4Stack("Nop-A",     &cHardware4Stack::Inst_Nop), 
-    //2
-    cInstEntry4Stack("Nop-B",     &cHardware4Stack::Inst_Nop), 
-    //3
-    cInstEntry4Stack("Nop-C",     &cHardware4Stack::Inst_Nop),   
-    //4 
-    cInstEntry4Stack("Nop-D",     &cHardware4Stack::Inst_Nop), 
-    //38
-    cInstEntry4Stack("Nop-E",     &cHardware4Stack::Inst_Nop),
-    //39
-    cInstEntry4Stack("Nop-F",     &cHardware4Stack::Inst_Nop),
-    //5
-    cInstEntry4Stack("Nop-X",     &cHardware4Stack::Inst_Nop),
-    //6 
-    cInstEntry4Stack("Val-Shift-R",   &cHardware4Stack::Inst_ShiftR),
-    //7
-    cInstEntry4Stack("Val-Shift-L",   &cHardware4Stack::Inst_ShiftL),
-    //8
-    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Val_Nand),
-    //9
-    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Val_Add),
-    //10
-    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Val_Sub),
-    //11
-    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Val_Mult),
-    //12
-    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Val_Div),
-    //13
-    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_SetMemory),
-    //14
-    cInstEntry4Stack("Divide",  &cHardware4Stack::Inst_Divide),
-    //15
-    cInstEntry4Stack("Inst-Read",    &cHardware4Stack::Inst_HeadRead),
-    //16
-    cInstEntry4Stack("Inst-Write",   &cHardware4Stack::Inst_HeadWrite),
-    //keeping this one for the transition period
-    //cInstEntry4Stack("Inst-Copy",    &cHardware4Stack::Inst_HeadCopy),
-    //17
-    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqual),
-    //18
-    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNotEqual),
-    //19
-    cInstEntry4Stack("If-Less",   &cHardware4Stack::Inst_IfLess),
-    //20
-    cInstEntry4Stack("If-Greater",    &cHardware4Stack::Inst_IfGreater),
-    //21
-    cInstEntry4Stack("Head-Push",    &cHardware4Stack::Inst_HeadPush),
-    //22
-    cInstEntry4Stack("Head-Pop",     &cHardware4Stack::Inst_HeadPop),
-    //23
-    cInstEntry4Stack("Head-Move",  &cHardware4Stack::Inst_HeadMove),
-    //24
-    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_Search),
-    //25
-    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushNext),
-    //26
-    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushPrevious),
-    //27
-    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushComplement),
-    //28
-    cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete),
-    //29
-    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_ValCopy),
-    //30
-    cInstEntry4Stack("ThreadFork",   &cHardware4Stack::Inst_ForkThread),
-    //31
-    //cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
-    //32
-    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Increment),
-    //33
-    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Decrement),
-    //34
-    cInstEntry4Stack("Val-Mod",       &cHardware4Stack::Inst_Mod),
-    //35
-    cInstEntry4Stack("ThreadKill",   &cHardware4Stack::Inst_KillThread),
-    //36
-    cInstEntry4Stack("IO", &cHardware4Stack::Inst_IO),
-    //37
-    cInstEntry4Stack("Inject", &cHardware4Stack::Inst_Inject)
-  };
-
-  const int n_size = sizeof(s_n_array)/sizeof(cNOPEntry4Stack);
-
-  static cString n_names[n_size];
-  static int nop_mods[n_size];
-  for (int i = 0; i < n_size; i++){
-    n_names[i] = s_n_array[i].name;
-    nop_mods[i] = s_n_array[i].nop_mod;
-  }
-
-  const int f_size = sizeof(s_f_array)/sizeof(cInstEntry4Stack);
-  static cString f_names[f_size];
-  static tHardware4StackMethod functions[f_size];
-  for (int i = 0; i < f_size; i++){
-    f_names[i] = s_f_array[i].name;
-    functions[i] = s_f_array[i].function;
-  }
-
-  cInstLib4Stack *inst_lib = new cInstLib4Stack(
-    n_size,
-    f_size,
-    n_names,
-    f_names,
-    nop_mods,
-    functions
-  );
-
-  return inst_lib;
-}
-
-cHardware4Stack::cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set)
-  : cHardwareBase(in_organism, in_inst_set)
-  , memory_array(NUM_MEMORY_SPACES)
-{
-  /* 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...
-}
-
-
-cHardware4Stack::cHardware4Stack(const cHardware4Stack &hardware_4stack)
-: cHardwareBase(hardware_4stack.organism, hardware_4stack.inst_set)
-, m_functions(hardware_4stack.m_functions)
-, memory_array(hardware_4stack.memory_array)
-, threads(hardware_4stack.threads)
-, thread_id_chart(hardware_4stack.thread_id_chart)
-, cur_thread(hardware_4stack.cur_thread)
-, mal_active(hardware_4stack.mal_active)
-, inst_cost(hardware_4stack.inst_cost)
-#ifdef INSTRUCTION_COSTS
-, inst_ft_cost(hardware_4stack.inst_ft_cost)
-, inst_remainder(hardware_4stack.inst_remainder)
-#endif
-{
-  for(int i = 0; i < NUM_GLOBAL_STACKS; i++){
-    global_stacks[i] = hardware_4stack.global_stacks[i];
-  }
-  for(int i = 0; i < sizeof(slice_array)/sizeof(float); i++){
-    slice_array[i] = hardware_4stack.slice_array[i];
-  }
-}
-
-
-void cHardware4Stack::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
-{
-  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();
-}
-
-
-void cHardware4Stack::Reset()
-{
-  //global_stack.Clear();
-  //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)=cGenome(ConvertToInstruction(i)); 
-  }
-
-  // We want to reset to have a single thread.
-  threads.Resize(1);
-
-  // Reset that single thread.
-  threads[0].Reset(this, 0);
-  thread_id_chart = 1; // Mark only the first thread as taken...
-  cur_thread = 0;
-
-  mal_active = false;
-
-  // Reset all stacks (local and global)
-  for(int i=0; i<NUM_STACKS; i++)
-    {
-      Stack(i).Clear();
-    }
-
-#ifdef INSTRUCTION_COSTS
-  // instruction cost arrays
-  const int num_inst_cost = GetNumInst();
-  inst_cost.Resize(num_inst_cost);
-  inst_ft_cost.Resize(num_inst_cost);
-
-  for (int i = 0; i < num_inst_cost; i++) {
-    inst_cost[i] = GetInstSet().GetCost(cInstruction(i));
-    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
-  }
-#endif
-
-}
-
-// This function processes the very next command in the genome, and is made
-// to be as optimized as possible.  This is the heart of avida.
-
-void cHardware4Stack::SingleProcess()
-{
-  // Mark this organism as running...
-  organism->SetRunning(true);
-
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.IncTimeUsed();
-  //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 = 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();
-    AdvanceIP() = true;
-    IP().Adjust();
-
-#ifdef BREAKPOINTS
-    if (IP().FlagBreakpoint() == true) {
-      organism->DoBreakpoint();
-    }
-#endif
-    
-    // Print the status of this CPU at each step...
-    if (m_tracer != NULL) {
-      if (cHardwareTracer_4Stack * tracer
-          = dynamic_cast<cHardwareTracer_4Stack *>(m_tracer)
-      ){
-        tracer->TraceHardware_4Stack(*this);
-      }
-    }
-    
-    // Find the instruction to be executed
-    const cInstruction & cur_inst = IP().GetInst();
-
-    // Test if costs have been paid and it is okay to execute this now...
-    const bool exec = SingleProcess_PayCosts(cur_inst);
-
-    // Now execute the instruction...
-    if (exec == true) {
-      SingleProcess_ExecuteInst(cur_inst);
-
-      // Some instruction (such as jump) may turn advance_ip off.  Ususally
-      // we now want to move to the next instruction in the memory.
-      if (AdvanceIP() == true) IP().Advance();
-    } // if exec
-    
-  } // Previous was executed once for each thread...
-
-  // Kill creatures who have reached their max num of instructions executed
-  const int max_executed = organism->GetMaxExecuted();
-  if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
-      || phenotype.GetToDie()) {
-    organism->Die();
-  }
-
-  organism->SetRunning(false);
-}
-
-// This method will test to see if all costs have been paid associated
-// with executing an instruction and only return true when that instruction
-// should proceed.
-bool cHardware4Stack::SingleProcess_PayCosts(const cInstruction & cur_inst)
-{
-#ifdef INSTRUCTION_COSTS
-  assert(cur_inst.GetOp() < inst_cost.GetSize());
-
-  // If first time cost hasn't been paid off...
-  if ( inst_ft_cost[cur_inst.GetOp()] > 0 ) {
-    inst_ft_cost[cur_inst.GetOp()]--;       // dec cost
-    return false;
-  }
-    
-  // Next, look at the per use cost
-  if ( GetInstSet().GetCost(cur_inst) > 0 ) {
-    if ( inst_cost[cur_inst.GetOp()] > 1 ){  // if isn't paid off (>1)
-      inst_cost[cur_inst.GetOp()]--;         // dec cost
-      return false;
-    } else {                                 // else, reset cost array
-      inst_cost[cur_inst.GetOp()] = GetInstSet().GetCost(cur_inst);
-    }
-  }
-    
-  // Prob of exec
-  if ( GetInstSet().GetProbFail(cur_inst) > 0.0 ){
-    return !( g_random.P(GetInstSet().GetProbFail(cur_inst)) );
-  }
-#endif
-  return true;
-}
-
-// This method will handle the actuall execution of an instruction
-// within single process, once that function has been finalized.
-bool cHardware4Stack::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
-{
-  // Copy Instruction locally to handle stochastic effects
-  cInstruction actual_inst = cur_inst;
-  
-#ifdef EXECUTION_ERRORS
-  // If there is an execution error, execute a random instruction.
-  if (organism->TestExeErr()) actual_inst = GetInstSet().GetRandomInst();
-#endif /* EXECUTION_ERRORS */
-
-  // Get a pointer to the corrisponding method...
-  int inst_idx = GetInstSet().GetLibFunctionIndex(actual_inst);
-  
-  // Mark the instruction as executed
-  IP().FlagExecuted() = true;
-	
-
-#ifdef INSTRUCTION_COUNT
-  // instruction execution count incremeneted
-  organism->GetPhenotype().IncCurInstCount(actual_inst.GetOp());
-#endif
-	
-  // And execute it.
-  const bool exec_success = (this->*(m_functions[inst_idx]))();
-	
-#ifdef INSTRUCTION_COUNT
-  // decremenet if the instruction was not executed successfully
-  if (exec_success == false) {
-    organism->GetPhenotype().DecCurInstCount(actual_inst.GetOp());
-  }
-#endif	
-
-  return exec_success;
-}
-
-
-void cHardware4Stack::ProcessBonusInst(const cInstruction & inst)
-{
-  // Mark this organism as running...
-  bool prev_run_state = organism->GetIsRunning();
-  organism->SetRunning(true);
-
-  // @CAO FIX PRINTING TO INDICATE THIS IS A BONUS
-  // Print the status of this CPU at each step...
-  if (m_tracer != NULL) {
-    if (cHardwareTracer_4Stack * tracer
-        = dynamic_cast<cHardwareTracer_4Stack *>(m_tracer)
-    ){
-      tracer->TraceHardware_4StackBonus(*this);
-    }
-  }
-    
-  SingleProcess_ExecuteInst(inst);
-
-  organism->SetRunning(prev_run_state);
-}
-
-
-void cHardware4Stack::LoadGenome(const cGenome & new_genome)
-{
-  GetMemory(0) = new_genome;
-}
-
-
-bool cHardware4Stack::OK()
-{
-  bool result = true;
-
-  for(int i = 0 ; i < NUM_MEMORY_SPACES; i++) {
-    if (!memory_array[i].OK()) result = false;
-  }
-
-  for (int i = 0; i < GetNumThreads(); i++) {
-    for(int j=0; j<NUM_LOCAL_STACKS; j++)
-    if (threads[i].local_stacks[j].OK() == false) result = false;
-    if (threads[i].next_label.OK() == false) result = false;
-  }
-
-  return result;
-}
-
-void cHardware4Stack::PrintStatus(ostream & fp)
-{
-  fp << organism->GetPhenotype().GetTimeUsed() << " "
-     << "IP:(" << IP().GetMemSpace() << ", " << IP().GetPosition() << ")    "
-
-     << "AX:" << Stack(STACK_AX).Top() << " "
-     << setbase(16) << "[0x" << Stack(STACK_AX).Top() << "]  " << setbase(10)
-
-     << "BX:" << Stack(STACK_BX).Top() << " "
-     << setbase(16) << "[0x" << Stack(STACK_BX).Top() << "]  " << setbase(10)
-
-     << "CX:" << Stack(STACK_CX).Top() << " "
-     << setbase(16) << "[0x" << Stack(STACK_CX).Top() << "]  " << setbase(10)
-
-     << "DX:" << Stack(STACK_DX).Top() << " "
-     << setbase(16) << "[0x" << Stack(STACK_DX).Top() << "]  " << setbase(10)
-
-     << endl;
-
-  fp << "  R-Head:(" << GetHead(HEAD_READ).GetMemSpace() << ", " 
-     << GetHead(HEAD_READ).GetPosition() << ")  " 
-     << "W-Head:(" << GetHead(HEAD_WRITE).GetMemSpace()  << ", "
-     << GetHead(HEAD_WRITE).GetPosition() << ")  "
-     << "F-Head:(" << GetHead(HEAD_FLOW).GetMemSpace()   << ",  "
-     << GetHead(HEAD_FLOW).GetPosition() << ")  "
-     << "RL:" << GetReadLabel().AsString() << "   "
-     << endl;
-
-  fp << "  Mem (" << GetMemory(0).GetSize() << "):"
-		  << "  " << GetMemory(0).AsString()
-		  << endl;
-  fp << "       " << GetMemory(1).GetSize() << "):"
-		  << "  " << GetMemory(1).AsString()
-		  << endl;
-  fp << "       " << GetMemory(2).GetSize() << "):"
-		  << "  " << GetMemory(2).AsString()
-		  << endl;
-  fp << "       " << GetMemory(3).GetSize() << "):"
-		  << "  " << GetMemory(3).AsString()
-		  << endl;
-  
-  
-  fp.flush();
-}
-
-
-
-
-/////////////////////////////////////////////////////////////////////////
-// Method: cHardware4Stack::FindLabel(direction)
-//
-// Search in 'direction' (+ or - 1) from the instruction pointer for the
-// compliment of the label in 'next_label' and return a pointer to the
-// results.  If direction is 0, search from the beginning of the genome.
-//
-/////////////////////////////////////////////////////////////////////////
-
-cHeadMultiMem cHardware4Stack::FindLabel(int direction)
-{
-  cHeadMultiMem & inst_ptr = IP();
-
-  // Start up a search head at the position of the instruction pointer.
-  cHeadMultiMem search_head(inst_ptr);
-  cCodeLabel & search_label = GetLabel();
-
-  // Make sure the label is of size  > 0.
-
-  if (search_label.GetSize() == 0) {
-    return inst_ptr;
-  }
-
-  // Call special functions depending on if jump is forwards or backwards.
-  int found_pos = 0;
-  if( direction < 0 ) {
-    found_pos = FindLabel_Backward(search_label, inst_ptr.GetMemory(),
-			   inst_ptr.GetPosition() - search_label.GetSize());
-  }
-
-  // Jump forward.
-  else if (direction > 0) {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(),
-			   inst_ptr.GetPosition());
-  }
-
-  // Jump forward from the very beginning.
-  else {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(), 0);
-  }
-  
-  // Return the last line of the found label, if it was found.
-  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;
-}
-
-
-// Search forwards for search_label from _after_ position pos in the
-// memory.  Return the first line _after_ the the found label.  It is okay
-// to find search label's match inside another label.
-
-int cHardware4Stack::FindLabel_Forward(const cCodeLabel & search_label,
-				 const cGenome & search_genome, int pos)
-{
-  assert (pos < search_genome.GetSize() && pos >= 0);
-
-  int search_start = pos;
-  int label_size = search_label.GetSize();
-  bool found_label = false;
-
-  // Move off the template we are on.
-  pos += label_size;
-
-  // Search until we find the complement or exit the memory.
-  while (pos < search_genome.GetSize()) {
-
-    // If we are within a label, rewind to the beginning of it and see if
-    // it has the proper sub-label that we're looking for.
-
-    if (inst_set->IsNop(search_genome[pos])) {
-      // Find the start and end of the label we're in the middle of.
-
-      int start_pos = pos;
-      int end_pos = pos + 1;
-      while (start_pos > search_start &&
-	     inst_set->IsNop( search_genome[start_pos - 1] )) {
-	start_pos--;
-      }
-      while (end_pos < search_genome.GetSize() &&
-	     inst_set->IsNop( search_genome[end_pos] )) {
-	end_pos++;
-      }
-      int test_size = end_pos - start_pos;
-
-      // See if this label has the proper sub-label within it.
-      int max_offset = test_size - label_size + 1;
-      int offset = start_pos;
-      for (offset = start_pos; offset < start_pos + max_offset; offset++) {
-
-	// Test the number of matches for this offset.
-	int matches;
-	for (matches = 0; matches < label_size; matches++) {
-	  if (search_label[matches] !=
-	      inst_set->GetNopMod( search_genome[offset + matches] )) {
-	    break;
-	  }
-	}
-
-	// If we have found it, break out of this loop!
-	if (matches == label_size) {
-	  found_label = true;
-	  break;
-	}
-      }
-
-      // If we've found the complement label, set the position to the end of
-      // the label we found it in, and break out.
-
-      if (found_label == true) {
-	// pos = end_pos;
-	pos = label_size + offset;
-	break;
-      }
-
-      // We haven't found it; jump pos to just after the current label being
-      // checked.
-      pos = end_pos;
-    }
-
-    // Jump up a block to the next possible point to find a label,
-    pos += label_size;
-  }
-
-  // If the label was not found return a -1.
-  if (found_label == false) pos = -1;
-
-  return pos;
-}
-
-// Search backwards for search_label from _before_ position pos in the
-// memory.  Return the first line _after_ the the found label.  It is okay
-// to find search label's match inside another label.
-
-int cHardware4Stack::FindLabel_Backward(const cCodeLabel & search_label,
-				  const cGenome & search_genome, int pos)
-{
-  assert (pos < search_genome.GetSize());
-
-  int search_start = pos;
-  int label_size = search_label.GetSize();
-  bool found_label = false;
-
-  // Move off the template we are on.
-  pos -= label_size;
-
-  // Search until we find the complement or exit the memory.
-  while (pos >= 0) {
-    // If we are within a label, rewind to the beginning of it and see if
-    // it has the proper sub-label that we're looking for.
-
-    if (inst_set->IsNop( search_genome[pos] )) {
-      // Find the start and end of the label we're in the middle of.
-
-      int start_pos = pos;
-      int end_pos = pos + 1;
-      while (start_pos > 0 && inst_set->IsNop(search_genome[start_pos - 1])) {
-	start_pos--;
-      }
-      while (end_pos < search_start &&
-	     inst_set->IsNop(search_genome[end_pos])) {
-	end_pos++;
-      }
-      int test_size = end_pos - start_pos;
-
-      // See if this label has the proper sub-label within it.
-      int max_offset = test_size - label_size + 1;
-      for (int offset = start_pos; offset < start_pos + max_offset; offset++) {
-
-	// Test the number of matches for this offset.
-	int matches;
-	for (matches = 0; matches < label_size; matches++) {
-	  if (search_label[matches] !=
-	      inst_set->GetNopMod(search_genome[offset + matches])) {
-	    break;
-	  }
-	}
-
-	// If we have found it, break out of this loop!
-	if (matches == label_size) {
-	  found_label = true;
-	  break;
-	}
-      }
-
-      // If we've found the complement label, set the position to the end of
-      // the label we found it in, and break out.
-
-      if (found_label == true) {
-	pos = end_pos;
-	break;
-      }
-
-      // We haven't found it; jump pos to just before the current label
-      // being checked.
-      pos = start_pos - 1;
-    }
-
-    // Jump up a block to the next possible point to find a label,
-    pos -= label_size;
-  }
-
-  // If the label was not found return a -1.
-  if (found_label == false) pos = -1;
-
-  return pos;
-}
-
-// Search for 'in_label' anywhere in the hardware.
-cHeadMultiMem cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
-{
-  assert (in_label.GetSize() > 0);
-
-  // IDEALY:
-  // Keep making jumps (in the proper direction) equal to the label
-  // length.  If we are inside of a label, check its size, and see if
-  // any of the sub-labels match properly.
-  // FOR NOW:
-  // Get something which works, no matter how inefficient!!!
-
-  cHeadMultiMem temp_head(this);
-
-  while (temp_head.InMemory()) {
-    // IDEALY: Analyze the label we are in; see if the one we are looking
-    // for could be a sub-label of it.  Skip past it if not.
-
-    int i;
-    for (i = 0; i < in_label.GetSize(); i++) {
-      if (!inst_set->IsNop(temp_head.GetInst()) ||
-	  in_label[i] != inst_set->GetNopMod(temp_head.GetInst())) {
-	break;
-      }
-    }
-    if (i == GetLabel().GetSize()) {
-      temp_head.AbsJump(i - 1);
-      return temp_head;
-    }
-
-    temp_head.AbsJump(direction);     // IDEALY: MAKE LARGER JUMPS
-  }
-
-  temp_head.AbsSet(-1);
-  return temp_head;
-}
-
-// @CAO: direction is not currently used; should be used to indicate the
-// direction which the heads[HEAD_IP] should progress through a creature.
-cHeadMultiMem cHardware4Stack::FindFullLabel(const cCodeLabel & in_label)
-{
-  // cout << "Running FindFullLabel with " << in_label.AsString() <<
-  // endl;
-
-  assert(in_label.GetSize() > 0); // Trying to find label of 0 size!
-
-  cHeadMultiMem temp_head(this);
-
-  while (temp_head.InMemory()) {
-    // If we are not in a label, jump to the next checkpoint...
-    if (inst_set->IsNop(temp_head.GetInst())) {
-      temp_head.AbsJump(in_label.GetSize());
-      continue;
-    }
-
-    // Otherwise, rewind to the begining of this label...
-
-    while (!(temp_head.AtFront()) && inst_set->IsNop(temp_head.GetInst(-1)))
-      temp_head.AbsJump(-1);
-
-    // Calculate the size of the label being checked, and make sure they
-    // are equal.
-
-    int checked_size = 0;
-    while (inst_set->IsNop(temp_head.GetInst(checked_size))) {
-      checked_size++;
-    }
-    if (checked_size != in_label.GetSize()) {
-      temp_head.AbsJump(checked_size + 1);
-      continue;
-    }
-
-    // cout << "Testing label at line " << temp_head.GetPosition() <<
-    // endl;
-
-    // ...and do the comparison...
-
-    int j;
-    bool label_match = true;
-    for (j = 0; j < in_label.GetSize(); j++) {
-      if (!inst_set->IsNop(temp_head.GetInst(j)) ||
-	  in_label[j] != inst_set->GetNopMod(temp_head.GetInst(j))) {
-	temp_head.AbsJump(in_label.GetSize() + 1);
-	label_match = false;
-	break;
-      }
-    }
-
-    if (label_match) {
-      // If we have found the label, return the position after it.
-      temp_head.AbsJump(j - 1);
-      return temp_head;
-    }
-
-    // We have not found the label... increment i.
-
-    temp_head.AbsJump(in_label.GetSize() + 1);
-  }
-
-  // The label does not exist in this creature.
-
-  temp_head.AbsSet(-1);
-  return temp_head;
-}
-
-// This is the code run by the INFECTED organism.  Its function is to SPREAD infection.
-bool cHardware4Stack::InjectParasite(double mut_multiplier)
-{
-  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
-  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
-  
-  // Make sure the creature will still be above the minimum size,
-  // TEMPORARY!  INJECTED CODE CAN 
-  if (end_pos <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
-    return false; // (inject fails)
-  }
-  
-  if (end_pos < MIN_INJECT_SIZE) {
-    GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
-    return false; // (inject fails)
-  }
-
-  GetMemory(mem_space_used).Resize(end_pos);
-
-  cCPUMemory injected_code = GetMemory(mem_space_used);
-
-  Inject_DoMutations(mut_multiplier, injected_code);
-
-  int inject_signal = false;
-
-  if(injected_code.GetSize()>0)
-    inject_signal = organism->InjectParasite(injected_code);
-  
-  //************* CALL GOES HERE ******************//
-  // spin around randomly (caution: possible organism dizziness)
-  //const int num_neighbors = organism->GetNeighborhoodSize();
-  //for(unsigned int i=0; i<g_random.GetUInt(num_neighbors); i++)
-  //  organism->Rotate(1);
-
-  // If we don't have a host, stop here.
-  //cOrganism * host_organism = organism->GetNeighbor();
-  
- 
-  //if(host_organism!=NULL)
-  //  {
-  //    
-  //  }
- 
-  //************** CALL ENDS HERE ******************//
-
-  //reset the memory space which was injected
-  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
-
-  for(int x=0; x<NUM_HEADS; x++)
-    {
-      GetHead(x).Reset(IP().GetMemSpace(), this);
-    }
-
-  for(int x=0; x<NUM_LOCAL_STACKS; x++)
-    {
-      Stack(x).Clear();
-    }
-  
-  AdvanceIP() = false;
-  
-  return inject_signal;
-}
-
-//This is the code run by the TARGET of an injection.  This RECIEVES the infection.
-bool cHardware4Stack::InjectHost(const cCodeLabel & in_label, const cGenome & inject_code)
-{
-  // Make sure the genome will be below max size after injection.
-
-  // xxxTEMPORARYxxx - we should have this match injection templates.  For now it simply 
-  
-// FIND THE FIRST EMPTY MEMORY SPACE
-  int target_mem_space;
-  for (target_mem_space = 0; target_mem_space < NUM_MEMORY_SPACES; target_mem_space++)
-    {
-      if(isEmpty(target_mem_space))
-	{
-	  break;
-	}
-    }
-  
-  if (target_mem_space == NUM_MEMORY_SPACES)
-    {
-      return false;
-    }
-
-  assert(target_mem_space >=0 && target_mem_space < NUM_MEMORY_SPACES);
-  
-  if(ForkThread()) {
-    // Inject the new code
-    cCPUMemory oldcode = GetMemory(target_mem_space);
-    GetMemory(target_mem_space) = inject_code;
-    GetMemory(target_mem_space).Resize(inject_code.GetSize() + oldcode.GetSize());
-
-    // Copies previous instructions to the end of the injected code.
-    // Is there a faster way to do this?? -law
-    for(int x=0; x<oldcode.GetSize(); x++)
-      GetMemory(target_mem_space)[inject_code.GetSize()+x] = oldcode[x];
-  
-    // Set instruction flags on the injected code
-    for (int i = 0; i < inject_code.GetSize(); i++) {
-      memory_array[target_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()==target_mem_space)
-	  threads[i].heads[j].Jump(inject_code.GetSize());
-      }
-    }
-    
-    for (int i=0; i < NUM_HEADS; i++) {    
-      GetHead(i).Reset(target_mem_space, this);
-    }
-    for (int i=0; i < NUM_LOCAL_STACKS; i++) {
-      Stack(i).Clear();
-    }
-  }
-
-  return true; // (inject succeeds!)
-}
-
-void cHardware4Stack::Mutate(int mut_point)
-{
-  // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
-
-  GetMemory(0)[mut_point] = GetRandomInst();
-  GetMemory(0).FlagMutated(mut_point) = true;
-  GetMemory(0).FlagPointMut(mut_point) = true;
-  //organism->GetPhenotype().IsMutated() = true;
-  organism->CPUStats().mut_stats.point_mut_count++;
-}
-
-int cHardware4Stack::PointMutate(const double mut_rate)
-{
-  const int num_muts =
-    g_random.GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
-
-  for (int i = 0; i < num_muts; i++) {
-    const int pos = g_random.GetUInt(GetMemory(0).GetSize());
-    Mutate(pos);
-  }
-
-  return num_muts;
-}
-
-
-// Trigger mutations of a specific type.  Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardware4Stack::TriggerMutations(int trigger)
-{
-  // Only update triggers should happen from the outside!
-  assert(trigger == MUTATION_TRIGGER_UPDATE);
-
-  // Assume instruction pointer is the intended target (if one is even
-  // needed!
-
-  return TriggerMutations(trigger, IP());
-}
-
-bool cHardware4Stack::TriggerMutations(int trigger, cHeadMultiMem & cur_head)
-{
-  // Collect information about mutations from the organism.
-  cLocalMutations & mut_info = organism->GetLocalMutations();
-  const tList<cMutation> & mut_list =
-    mut_info.GetMutationLib().GetMutationList(trigger);
-
-  // If we have no mutations for this trigger, stop here.
-  if (mut_list.GetSize() == 0) return false;
-  bool has_mutation = false;
-
-  // Determine what memory this mutation will be affecting.
-  cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory(0);
-
-  // Loop through all mutations associated with this trigger and test them.
-  tConstListIterator<cMutation> mut_it(mut_list);
-
-  while (mut_it.Next() != NULL) {
-    const cMutation * cur_mut = mut_it.Get();
-    const int mut_id = cur_mut->GetID();
-    const int scope = cur_mut->GetScope();
-    const double rate = mut_info.GetRate(mut_id);
-    switch (scope) {
-    case MUTATION_SCOPE_GENOME:
-      if (TriggerMutations_ScopeGenome(cur_mut, target_mem, cur_head, rate)) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id);
-      }
-      break;
-    case MUTATION_SCOPE_LOCAL:
-    case MUTATION_SCOPE_PROP:
-      if (TriggerMutations_ScopeLocal(cur_mut, target_mem, cur_head, rate)) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id);
-      }
-      break;
-    case MUTATION_SCOPE_GLOBAL:
-    case MUTATION_SCOPE_SPREAD:
-      int num_muts =
-	TriggerMutations_ScopeGlobal(cur_mut, target_mem, cur_head, rate);
-      if (num_muts > 0) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id, num_muts);
-      }
-      break;
-    }
-  }
-
-  return has_mutation;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
-{
-  // The rate we have stored indicates the probability that a single
-  // mutation will occur anywhere in the genome.
-  
-  if (g_random.P(rate) == true) {
-    // We must create a temporary head and use it to randomly determine the
-    // position in the genome to be mutated.
-    cHeadMultiMem tmp_head(cur_head);
-    tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
-    TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
-    return true;
-  }
-  return false;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
-{
-  // The rate we have stored is the probability for a mutation at this single
-  // position in the genome.
-
-  if (g_random.P(rate) == true) {
-    TriggerMutations_Body(cur_mut->GetType(), target_memory, cur_head);
-    return true;
-  }
-  return false;
-}
-
-int cHardware4Stack::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate)
-{
-  // The probability we have stored is per-site, so we can pull a random
-  // number from a binomial distribution to determine the number of mutations
-  // that should occur.
-
-  const int num_mut =
-    g_random.GetRandBinomial(target_memory.GetSize(), rate);
-
-  if (num_mut > 0) {
-    for (int i = 0; i < num_mut; i++) {
-      cHeadMultiMem tmp_head(cur_head);
-      tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
-      TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
-    }
-  }
-
-  return num_mut;
-}
-
-void cHardware4Stack::TriggerMutations_Body(int type, cCPUMemory & target_memory,
-					 cHeadMultiMem & cur_head)
-{
-  const int pos = cur_head.GetPosition();
-
-  switch (type) {
-  case MUTATION_TYPE_POINT:
-    target_memory[pos] = GetRandomInst();
-    target_memory.FlagMutated(pos) = true;
-    break;
-  case MUTATION_TYPE_INSERT:
-  case MUTATION_TYPE_DELETE:
-  case MUTATION_TYPE_HEAD_INC:
-  case MUTATION_TYPE_HEAD_DEC:
-  case MUTATION_TYPE_TEMP:
-  case MUTATION_TYPE_KILL:
-  default:
-    cout << "Error: Mutation type not implemented!" << endl;
-    break;
-  };
-}
-
-void cHardware4Stack::ReadInst(const int in_inst)
-{
-  if (inst_set->IsNop( cInstruction(in_inst) )) {
-    GetReadLabel().AddNop(in_inst);
-  } else {
-    GetReadLabel().Clear();
-  }
-}
-
-
-void cHardware4Stack::AdjustHeads()
-{
-  for (int i = 0; i < GetNumThreads(); i++) {
-    for (int j = 0; j < NUM_HEADS; j++) {
-      threads[i].heads[j].Adjust();
-    }
-  }
-}
-
-
-
-// This function looks at the current position in the info of a creature,
-// and sets the next_label to be the sequence of nops which follows.  The
-// instruction pointer is left on the last line of the label found.
-
-void cHardware4Stack::ReadLabel(int max_size)
-{
-  int count = 0;
-  cHeadMultiMem * inst_ptr = &( IP() );
-
-  GetLabel().Clear();
-
-  while (inst_set->IsNop(inst_ptr->GetNextInst()) &&
-	 (count < max_size)) {
-    count++;
-    inst_ptr->Advance();
-    GetLabel().AddNop(inst_set->GetNopMod(inst_ptr->GetInst()));
-
-    // If this is the first line of the template, mark it executed.
-    if (GetLabel().GetSize() <=	cConfig::GetMaxLabelExeSize()) {
-      inst_ptr->FlagExecuted() = true;
-    }
-  }
-}
-
-
-bool cHardware4Stack::ForkThread()
-{
-  const int num_threads = GetNumThreads();
-  if (num_threads == cConfig::GetMaxCPUThreads()) return false;
-
-  // 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]; 
-
-  // Find the first free bit in thread_id_chart to determine the new
-  // thread id.
-  int new_id = 0;
-  while ( (thread_id_chart >> new_id) & 1 == 1) new_id++;
-  threads[num_threads].SetID(new_id);
-  thread_id_chart |= (1 << new_id);
-
-  return true;
-}
-
-
-int cHardware4Stack::TestParasite() const
-{
-  return IP().TestParasite();
-}
-
-
-bool cHardware4Stack::KillThread()
-{
-  // Make sure that there is always at least one thread...
-  if (GetNumThreads() == 1) return false;
-
-  // Note the current thread and set the current back one.
-  const int kill_thread = cur_thread;
-  PrevThread();
-  
-  // Turn off this bit in the thread_id_chart...
-  thread_id_chart ^= 1 << threads[kill_thread].GetID();
-
-  // Copy the last thread into the kill position
-  const int last_thread = GetNumThreads() - 1;
-  if (last_thread != kill_thread) {
-    threads[kill_thread] = threads[last_thread];
-  }
-
-  // Kill the thread!
-  threads.Resize(GetNumThreads() - 1);
-
-  if (cur_thread > kill_thread) cur_thread--;
-
-  return true;
-}
-
-
-void cHardware4Stack::SaveState(ostream & fp)
-{
-  // note, memory & child_memory handled by cpu (@CAO Not any more!)
-  assert(fp.good());
-
-  fp<<"cHardware4Stack"<<endl;
-
-  // global_stack (in inverse order so load can just push)
-  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
-    Stack(i).SaveState(fp);
-
-  //fp << thread_time_used  << endl;
-  fp << GetNumThreads()   << endl;
-  fp << cur_thread        << endl;
-
-  // Threads
-  for( int i = 0; i < GetNumThreads(); i++ ) {
-    threads[i].SaveState(fp);
-  }
-}
-
-
-void cHardware4Stack::LoadState(istream & fp)
-{
-  // note, memory & child_memory handled by cpu (@CAO Not any more!)
-  assert(fp.good());
-
-  cString foo;
-  fp>>foo;
-  assert( foo == "cHardware4Stack" );
-
-  // global_stack
-  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
-    Stack(i).LoadState(fp);
-
-  int num_threads;
-  //fp >> thread_time_used;
-  fp >> num_threads;
-  fp >> cur_thread;
-
-  // Threads
-  for( int i = 0; i < num_threads; i++ ){
-    threads[i].LoadState(fp);
-  }
-}
-
-
-////////////////////////////
-//  Instruction Helpers...
-////////////////////////////
-
-inline int cHardware4Stack::FindModifiedStack(int default_stack)
-{
-  assert(default_stack < NUM_STACKS);  // Stack ID too high.
-
-  if (GetInstSet().IsNop(IP().GetNextInst())) {
-    IP().Advance();
-    default_stack = GetInstSet().GetNopMod(IP().GetInst());
-    IP().FlagExecuted() = true;
-  }
-  return default_stack;
-}
-
-inline int cHardware4Stack::FindModifiedHead(int default_head)
-{
-  assert(default_head < NUM_HEADS); // Head ID too high.
-
-  if (GetInstSet().IsNop(IP().GetNextInst())) {
-    IP().Advance();    
-    int nop_head = GetInstSet().GetNopMod(IP().GetInst());
-    if (nop_head < NUM_HEADS) default_head = nop_head;
-    IP().FlagExecuted() = true;
-  }
-  return default_head;
-}
-
-inline int cHardware4Stack::FindComplementStack(int base_stack)
-{
-  const int comp_stack = base_stack + 2;
-  return comp_stack%NUM_STACKS;
-}
-
-inline void cHardware4Stack::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
-  organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-bool cHardware4Stack::Divide_CheckViable(const int parent_size,
-				      const int child_size, const int mem_space)
-{
-  // Make sure the organism is okay with dividing now...
-  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
-  // Make sure that neither parent nor child will be below the minimum size.
-
-  const int genome_size = organism->GetGenome().GetSize();
-  const double size_range = cConfig::GetChildSizeRange();
-  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
-  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-  
-  if (child_size < min_size || child_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
-    return false; // (divide fails)
-  }
-
-  // Count the number of lines executed in the parent, and make sure the
-  // specified fraction has been reached.
-
-  int executed_size = 0;
-  for (int i = 0; i < parent_size; i++) {
-    if (GetMemory(0).FlagExecuted(i)) executed_size++;
-  }
-
-  const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
-  if (executed_size < min_exe_lines) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Too few executed lines (%d < %d)",
-			       executed_size, min_exe_lines));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines which were copied into the child, and make
-  // sure the specified fraction has been reached.
-
-  int copied_size = 0;
-  for (int i = 0; i < GetMemory(mem_space).GetSize(); i++) {
-    if (GetMemory(mem_space).FlagCopied(i)) copied_size++;
-   }
-
-  const int min_copied =  (int) (child_size * cConfig::GetMinCopiedLines());
-  if (copied_size < min_copied) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Too few copied commands (%d < %d)",
-			       copied_size, min_copied));
-    return false; // (divide fails)
-  }
-
-  // Save the information we collected here...
-  organism->GetPhenotype().SetLinesExecuted(executed_size);
-  organism->GetPhenotype().SetLinesCopied(copied_size);
-
-  return true; // (divide succeeds!)
-}
-
-void cHardware4Stack::Divide_DoMutations(double mut_multiplier)
-{
-  sCPUStats & cpu_stats = organism->CPUStats();
-  cCPUMemory & child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-
-  // Divide Mutations
-  if (organism->TestDivideMut()) {
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
-    child_genome[mut_line] = GetRandomInst();
-    cpu_stats.mut_stats.divide_mut_count++;
-  }
-
-  // Divide Insertions
-  if (organism->TestDivideIns() && child_genome.GetSize() < MAX_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize() + 1);
-    child_genome.Insert(mut_line, GetRandomInst());
-    cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-
-  // Divide Deletions
-  if (organism->TestDivideDel() && child_genome.GetSize() > MIN_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
-    // if( child_genome.FlagCopied(mut_line) == true) copied_size_change--;
-    child_genome.Remove(mut_line);
-    cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(), 
-				   	   organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-	int site = g_random.GetUInt(child_genome.GetSize());
-	child_genome[site]=GetRandomInst();
-	cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-
-
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
-					   organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-	mut_sites[i] = g_random.GetUInt(child_genome.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-	child_genome.Insert(mut_sites[i], GetRandomInst());
-	cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-
-
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
-					   organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
-    }
-
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = g_random.GetUInt(child_genome.GetSize());
-      // if (child_genome.FlagCopied(site) == true) copied_size_change--;
-      child_genome.Remove(site);
-      cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
-      if (organism->TestParentMut()) {
-	GetMemory(0)[i] = GetRandomInst();
-	cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-
-
-  // Count up mutated lines
-  for(int i = 0; i < GetMemory(0).GetSize(); i++){
-    if (GetMemory(0).FlagPointMut(i) == true) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < child_genome.GetSize(); i++){
-    if( child_genome.FlagCopyMut(i) == true) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-  }
-}
-
-void cHardware4Stack::Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code)
-{
-  //sCPUStats & cpu_stats = organism->CPUStats();
-  //cCPUMemory & child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-
-  // Divide Mutations
-  if (organism->TestDivideMut()) {
-    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
-    injected_code[mut_line] = GetRandomInst();
-    //cpu_stats.mut_stats.divide_mut_count++;
-  }
-
-  // Divide Insertions
-  if (organism->TestDivideIns() && injected_code.GetSize() < MAX_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(injected_code.GetSize() + 1);
-    injected_code.Insert(mut_line, GetRandomInst());
-    //cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-
-  // Divide Deletions
-  if (organism->TestDivideDel() && injected_code.GetSize() > MIN_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
-    // if( injected_code.FlagCopied(mut_line) == true) copied_size_change--;
-    injected_code.Remove(mut_line);
-    //cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(), 
-				   	   organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-	int site = g_random.GetUInt(injected_code.GetSize());
-	injected_code[site]=GetRandomInst();
-	//cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-
-
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
-					   organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + injected_code.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - injected_code.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-	mut_sites[i] = g_random.GetUInt(injected_code.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-	injected_code.Insert(mut_sites[i], GetRandomInst());
-	//cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-
-
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
-					   organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (injected_code.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = injected_code.GetSize() - MIN_CREATURE_SIZE;
-    }
-
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = g_random.GetUInt(injected_code.GetSize());
-      // if (injected_code.FlagCopied(site) == true) copied_size_change--;
-      injected_code.Remove(site);
-      //cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
-      if (organism->TestParentMut()) {
-	GetMemory(0)[i] = GetRandomInst();
-	//cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-
-  /*
-  // Count up mutated lines
-  for(int i = 0; i < GetMemory(0).GetSize(); i++){
-    if (GetMemory(0).FlagPointMut(i) == true) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < injected_code.GetSize(); i++){
-    if( injected_code.FlagCopyMut(i) == true) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-    }*/
-}
-
-
-// test whether the offspring creature contains an advantageous mutation.
-void cHardware4Stack::Divide_TestFitnessMeasures()
-{
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
-  phenotype.ChildFertile() = true;
-
-  // Only continue if we're supposed to do a fitness test on divide...
-  if (organism->GetTestOnDivide() == false) return;
-
-  // If this was a perfect copy, then we don't need to worry about any other
-  // tests...  Theoretically, we need to worry about the parent changing,
-  // but as long as the child is always compared to the original genotype,
-  // this won't be an issue.
-  if (phenotype.CopyTrue() == true) return;
-
-  const double parent_fitness = organism->GetTestFitness();
-  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
-  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
-  
-  cCPUTestInfo test_info;
-  test_info.UseRandomInputs();
-  cTestCPU::TestGenome(test_info, organism->ChildGenome());
-  const double child_fitness = test_info.GetGenotypeFitness();
-  
-  bool revert = false;
-  bool sterilize = false;
-  
-  // If implicit mutations are turned off, make sure this won't spawn one.
-  if (organism->GetFailImplicit() == true) {
-    if (test_info.GetMaxDepth() > 0) sterilize = true;
-  }
-  
-  if (child_fitness == 0.0) {
-    // Fatal mutation... test for reversion.
-    if (g_random.P(organism->GetRevertFatal())) revert = true;
-    if (g_random.P(organism->GetSterilizeFatal())) sterilize = true;
-  } else if (child_fitness < neut_min) {
-    if (g_random.P(organism->GetRevertNeg())) revert = true;
-    if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
-  } else if (child_fitness <= neut_max) {
-    if (g_random.P(organism->GetRevertNeut())) revert = true;
-    if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
-  } else {
-    if (g_random.P(organism->GetRevertPos())) revert = true;
-    if (g_random.P(organism->GetSterilizePos())) sterilize = true;
-  }
-  
-  // Ideally, we won't have reversions and sterilizations turned on at the
-  // same time, but if we do, give revert the priority.
-  if (revert == true) {
-    organism->ChildGenome() = organism->GetGenome();
-  }
-
-  if (sterilize == true) {
-    organism->GetPhenotype().ChildFertile() = false;
-  }
-}
-
-
-bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
-{
-  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;
-
-  // Make sure this divide will produce a viable offspring.
-  if(!Divide_CheckViable(GetMemory(IP().GetMemSpace()).GetSize(), 
-	 		 write_head_pos, mem_space_used)) 
-    return false;
-  
-  // Since the divide will now succeed, set up the information to be sent
-  // to the new organism
-  cGenome & child_genome = organism->ChildGenome();
-  GetMemory(mem_space_used).Resize(write_head_pos);
-  child_genome = GetMemory(mem_space_used);
-
-  // Handle Divide Mutations...
-  Divide_DoMutations(mut_multiplier);
-
-  // 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
-
-  bool parent_alive = organism->ActivateDivide();
-
-  //reset the memory of the memory space that has been divided off
-  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
-
-  // 3 Division Methods:
-  // 1) DIVIDE_METHOD_OFFSPRING - Create a child, leave parent state untouched.
-  // 2) DIVIDE_METHOD_SPLIT - Create a child, completely reset state of parent.
-  // 3) DIVIDE_METHOD_BIRTH - Create a child, reset state of parent's current thread.
-  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;
-}
-
-cString cHardware4Stack::ConvertToInstruction(int mem_space_used)
-{
-  char c = mem_space_used + 97;  // 97 - ASCII for 'a'
-  cString ret;
-  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 "";
-}
-  
-
-//////////////////////////
-// And the instructions...
-//////////////////////////
-
-//6
-bool cHardware4Stack::Inst_ShiftR()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  int value = Stack(stack_used).Pop();
-  value >>= 1;
-  Stack(stack_used).Push(value);
-  return true;
-}
-
-//7
-bool cHardware4Stack::Inst_ShiftL()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  int value = Stack(stack_used).Pop();
-  value <<= 1;
-  Stack(stack_used).Push(value);
-  return true;
-}
-
-//8
-bool cHardware4Stack::Inst_Val_Nand()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Push(~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top()));
-  return true;
-}
-
-//9
-bool cHardware4Stack::Inst_Val_Add()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Push(Stack(STACK_BX).Top() + Stack(STACK_CX).Top());
-  return true;
-}
-
-//10
-bool cHardware4Stack::Inst_Val_Sub()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Push(Stack(STACK_BX).Top() - Stack(STACK_CX).Top());
-  return true;
-}
-
-//11
-bool cHardware4Stack::Inst_Val_Mult()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Push(Stack(STACK_BX).Top() * Stack(STACK_CX).Top());
-  return true;
-}
-
-//12
-bool cHardware4Stack::Inst_Val_Div()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  if (Stack(STACK_CX).Top() != 0) {
-    if (0-INT_MAX > Stack(STACK_BX).Top() && Stack(STACK_CX).Top() == -1)
-      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
-    else
-      Stack(stack_used).Push(Stack(STACK_BX).Top() / Stack(STACK_CX).Top());
-  } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
-    return false;
-  }
-  return true;
-}
-
-//13 
-bool cHardware4Stack::Inst_SetMemory()   // Allocate maximal more
-{
-  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);
-  //if( Allocate_Main(alloc_size) ) {
-  //  Stack(STACK_AX).Push(cur_size);
-  //  return true;
-  //} else return false;
-}
-
-//14
-bool cHardware4Stack::Inst_Divide()
-{
-  int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
-  int mut_multiplier = 1;
-
-  return Divide_Main(mem_space_used, mut_multiplier);
-}
-
-bool cHardware4Stack::Inst_HeadDivideMut(double mut_multiplier)
-{
-  // Unused for the moment...
-  return true;
-  //AdjustHeads();
-  //const int divide_pos = GetHead(HEAD_READ).GetPosition();
-  //int child_end =  GetHead(HEAD_WRITE).GetPosition();
-  //if (child_end == 0) child_end = GetMemory(0).GetSize();
-  //const int extra_lines = GetMemory(0).GetSize() - child_end;
-  //bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
-  //// Re-adjust heads.
-  //AdjustHeads();
-  //return ret_val; 
-}
-
-//15
-bool cHardware4Stack::Inst_HeadRead()
-{
-  const int head_id = FindModifiedHead(HEAD_READ);
-  GetHead(head_id).Adjust();
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Mutations only occur on the read, for the moment.
-  int read_inst = 0;
-  if (organism->TestCopyMut()) {
-    read_inst = GetRandomInst().GetOp();
-    cpu_stats.mut_stats.copy_mut_count++;  // @CAO, hope this is good!
-  } else {
-    read_inst = GetHead(head_id).GetInst().GetOp();
-  }
-  Stack(STACK_AX).Push(read_inst);
-  ReadInst(read_inst);
-
-  cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
-  GetHead(head_id).Advance();
-  return true;
-}
-
-//16
-bool cHardware4Stack::Inst_HeadWrite()
-{
-  const int head_id = FindModifiedHead(HEAD_WRITE);
-  cHeadMultiMem & active_head = GetHead(head_id);
-  int mem_space_used = active_head.GetMemSpace();
-  
-  //commented out for right now...
-  if(active_head.GetPosition()>=GetMemory(mem_space_used).GetSize()-1)
-   {
-     GetMemory(mem_space_used).Resize(GetMemory(mem_space_used).GetSize()+1);
-     GetMemory(mem_space_used).Copy(GetMemory(mem_space_used).GetSize()-1, GetMemory(mem_space_used).GetSize()-2);
-   }
-
-  active_head.Adjust();
-
-  int value = Stack(STACK_AX).Pop();
-  if (value < 0 || value >= GetNumInst()) value = 0;
-
-  active_head.SetInst(cInstruction(value));
-  active_head.FlagCopied() = true;
-
-  // Advance the head after write...
-  active_head++;
-  return true;
-}
-
-//??
-bool cHardware4Stack::Inst_HeadCopy()
-{
-  // For the moment, this cannot be nop-modified.
-  cHeadMultiMem & read_head = GetHead(HEAD_READ);
-  cHeadMultiMem & write_head = GetHead(HEAD_WRITE);
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  read_head.Adjust();
-  write_head.Adjust();
-
-  // TriggerMutations(MUTATION_TRIGGER_READ, read_head);
-  
-  // Do mutations.
-  cInstruction read_inst = read_head.GetInst();
-  if (organism->TestCopyMut()) {
-    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...
-
-  // TriggerMutations(MUTATION_TRIGGER_WRITE, write_head);
-
-  read_head.Advance();
-  write_head.Advance();
-  return true;
-}
-
-//17
-bool cHardware4Stack::Inst_IfEqual()      // Execute next if bx == ?cx?
-{
-  const int stack_used = FindModifiedStack(STACK_AX);
-  const int stack_used2 = (stack_used+1)%NUM_STACKS;
-  if (Stack(stack_used).Top() != Stack(stack_used2).Top())  IP().Advance();
-  return true;
-}
-
-//18
-bool cHardware4Stack::Inst_IfNotEqual()     // Execute next if bx != ?cx?
-{
-  const int stack_used = FindModifiedStack(STACK_AX);
-  const int stack_used2 = (stack_used+1)%NUM_STACKS;
-  if (Stack(stack_used).Top() == Stack(stack_used2).Top())  IP().Advance();
-  return true;
-}
-
-//19
-bool cHardware4Stack::Inst_IfLess()       // Execute next if ?bx? < ?cx?
-{
-  const int stack_used = FindModifiedStack(STACK_AX);
-  const int stack_used2 = (stack_used+1)%NUM_STACKS;
-  if (Stack(stack_used).Top() >=  Stack(stack_used2).Top())  IP().Advance();
-  return true;
-}
-
-//20
-bool cHardware4Stack::Inst_IfGreater()       // Execute next if bx > ?cx?
-{
-  const int stack_used = FindModifiedStack(STACK_AX);
-  const int stack_used2 = (stack_used+1)%NUM_STACKS;
-  if (Stack(stack_used).Top() <= Stack(stack_used2).Top())  IP().Advance();
-  return true;
-}
-
-//21
-bool cHardware4Stack::Inst_HeadPush()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
-  //if (head_used == HEAD_IP) {
-  //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  //  AdvanceIP() = false;
-  //}
-  return true;
-}
-
-//22
-bool cHardware4Stack::Inst_HeadPop()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(Stack(STACK_BX).Pop(), 
-			 GetHead(head_used).GetMemSpace(), this);
-  return true;
-}
-
-//23 
-bool cHardware4Stack::Inst_HeadMove()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  if(head_used != HEAD_FLOW)
-    {
-      GetHead(head_used).Set(GetHead(HEAD_FLOW));
-      if (head_used == HEAD_IP) AdvanceIP() = false;
-    }
-  else
-    {
-      threads[cur_thread].heads[HEAD_FLOW]++;
-    }
-  return true;
-}
-
-//24
-bool cHardware4Stack::Inst_Search()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  cHeadMultiMem found_pos = FindLabel(0);
-  if(found_pos.GetPosition()-IP().GetPosition()==0)
-    {
-      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);
-    }
-  else
-    {
-      int search_size = found_pos.GetPosition() - IP().GetPosition() + GetLabel().GetSize() + 1;
-      Stack(STACK_BX).Push(search_size);
-      Stack(STACK_AX).Push(GetLabel().GetSize());
-      GetHead(HEAD_FLOW).Set(found_pos);
-    }  
-  
-  return true; 
-}
-
-//25
-bool cHardware4Stack::Inst_PushNext() 
-{
-  int stack_used = FindModifiedStack(STACK_AX);
-  int successor = (stack_used+1)%NUM_STACKS;
-  Stack(successor).Push(Stack(stack_used).Pop());
-  return true;
-}
-
-//26
-bool cHardware4Stack::Inst_PushPrevious() 
-{
-  int stack_used = FindModifiedStack(STACK_BX);
-  int predecessor = (stack_used+NUM_STACKS-1)%NUM_STACKS;
-  Stack(predecessor).Push(Stack(stack_used).Pop());
-  return true;
-}
-
-//27
-bool cHardware4Stack::Inst_PushComplement() 
-{
-  int stack_used = FindModifiedStack(STACK_BX);
-  int complement = FindComplementStack(stack_used);
-  Stack(complement).Push(Stack(stack_used).Pop());
-  return true;
-}
-
-//28
-bool cHardware4Stack::Inst_ValDelete()
-{
-  int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Pop();
-  return true;
-}
-
-//29
-bool cHardware4Stack::Inst_ValCopy()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Push(Stack(stack_used).Top());
-  return true;
-}
-
-//30
-bool cHardware4Stack::Inst_ForkThread()
-{
-  if (!ForkThread()) 
-    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
-  else
-    IP().Advance();
-  return true;
-}
-
-//31
-bool cHardware4Stack::Inst_IfLabel()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  if (GetLabel() != GetReadLabel())  IP().Advance();
-  return true;
-}
-
-//32
-bool cHardware4Stack::Inst_Increment()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  int value = Stack(stack_used).Pop();
-  Stack(stack_used).Push(++value);
-  return true;
-}
-
-//33
-bool cHardware4Stack::Inst_Decrement()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  int value = Stack(stack_used).Pop();
-  Stack(stack_used).Push(--value);
-  return true;
-}
-
-//34
-bool cHardware4Stack::Inst_Mod()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-  if (Stack(STACK_CX).Top() != 0) {
-    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;
-  }
-  return true;
-}
-
-//35
-bool cHardware4Stack::Inst_KillThread()
-{
-  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
-  else AdvanceIP() = false;
-  return true;
-}
-
-//36
-bool cHardware4Stack::Inst_IO()
-{
-  const int stack_used = FindModifiedStack(STACK_BX);
-
-  // Do the "put" component
-  const int value_out = Stack(stack_used).Top();
-  organism->DoOutput(value_out);  // Check for tasks compleated.
-
-  // Do the "get" component
-  const int value_in = organism->GetNextInput();
-  Stack(stack_used).Push(value_in);
-  organism->DoInput(value_in);
-  return true;
-}
-
-int cHardware4Stack::FindFirstEmpty()
-{
-  bool OK=true;
-  const int current_mem_space = IP().GetMemSpace();
-
-  for(int x=1; x<NUM_MEMORY_SPACES; x++)
-    {
-      OK=true;
-      
-      int index = (current_mem_space+x) % NUM_MEMORY_SPACES;
-
-      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::isEmpty(int mem_space_used)
-{
-  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;
-}
-
-// 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()
-{
-  double mut_multiplier = 1;
-
-  return InjectParasite(mut_multiplier);
-}
-
-
-
-/*
-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;
-}
-
-*/

Deleted: trunk/source/cpu/hardware_4stack.hh
===================================================================
--- trunk/source/cpu/hardware_4stack.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_4stack.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,515 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_4STACK_HH
-#define HARDWARE_4STACK_HH
-
-#include <iomanip>
-
-#ifndef CPU_MEMORY_HH
-#include "cCPUMemory.h"
-#endif
-#ifndef CPU_STACK_HH
-#include "cCPUStack.h"
-#endif
-#ifndef DEFS_HH
-#include "defs.hh"
-#endif
-#ifndef HEAD_MULTI_MEM_HH
-#include "head_multi_mem.hh"
-#endif
-#ifndef HARDWARE_BASE_HH
-#include "hardware_base.hh"
-#endif
-#ifndef HARDWARE_4STACK_CONSTANTS_HH
-#include "hardware_4stack_constants.hh"
-#endif
-#ifndef HARDWARE_4STACK_THREAD_HH
-#include "hardware_4stack_thread.hh"
-#endif
-#ifndef STRING_HH
-#include "string.hh"
-#endif
-#ifndef TARRAY_HH
-#include "tArray.hh"
-#endif
-
-class cInstSet;
-class cInstLibBase;
-class cOrganism;
-class cMutation;
-class cInjectGenotype;
-
-#ifdef SINGLE_IO_BUFFER   // For Single IOBuffer vs IOBuffer for each Thread
-# define IO_THREAD 0
-#else
-# define IO_THREAD cur_thread
-#endif
-
-/**
- * Each organism may have a cHardware4Stack structure which keeps track of the
- * current status of all the components of the simulated hardware.
- *
- * @see cHardware4Stack_Thread, cCPUStack, cCPUMemory, cInstSet
- **/
-
-class cCodeLabel;
-class cCPUMemory;
-class cCPUStack; // aggregate
-class cHeadMultiMem; // access
-class cGenome;
-class cHardware4Stack_Thread; // access
-class cInjectGenotype;
-class cInstLib4Stack; // access
-class cInstruction;
-class cInstSet;
-class cOrganism;
-class cString; // aggregate
-template <class T> class tArray; // aggregate
-
-class cHardware4Stack : public cHardwareBase {
-public:
-  typedef bool (cHardware4Stack::*tHardware4StackMethod)();
-private:
-  static cInstLib4Stack *s_inst_slib;
-  static cInstLib4Stack *initInstLib(void);
-  tHardware4StackMethod *m_functions;
-private:
-  tArray<cCPUMemory> memory_array;          // Memory...
-  //cCPUStack global_stack;     // A stack that all threads share.
-  cCPUStack global_stacks[NUM_GLOBAL_STACKS];
-  //int thread_time_used;
-
-  tArray<cHardware4Stack_Thread> threads;
-  int thread_id_chart;
-  int cur_thread;
-
-  // Flags...
-  bool mal_active;         // Has an allocate occured since last dividehe?
-  //bool advance_ip;         // Should the IP advance after this instruction?
-
-  // Instruction costs...
-#ifdef INSTRUCTION_COSTS
-  tArray<int> inst_cost;
-  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);
-  explicit cHardware4Stack(const cHardware4Stack &);
-  ~cHardware4Stack() { ; }
-  void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
-  static cInstLibBase *GetInstLib();
-  static cString GetDefaultInstFilename() { return "inst_lib.4stack"; }
-  static void WriteDefaultInstSet() { ; }
-
-  void Reset();
-  void SingleProcess();
-  bool SingleProcess_PayCosts(const cInstruction & cur_inst);
-  bool SingleProcess_ExecuteInst(const cInstruction & cur_inst);
-  void ProcessBonusInst(const cInstruction & inst);
-  void LoadGenome(const cGenome & new_genome);
-
-  // --------  Helper methods  --------
-  bool OK();
-  void PrintStatus(std::ostream & fp);
-
-
-  // --------  Flag Accessors --------
-  bool GetMalActive() const   { return mal_active; }
-
-  // --------  Stack Manipulation...  --------
-  //void StackFlip();
-  inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
-  //inline void StackClear();
-  //inline void SwitchStack();
-  cString GetActiveStackID(int stackID) const;
-  //retrieves appropriate stack
-  inline cCPUStack & Stack(int stack_id); 
-  inline const cCPUStack & Stack(int stack_id) const;
-  inline cCPUStack & Stack(int stack_id, int in_thread);
-  inline const cCPUStack & Stack(int stack_id, int in_thread) const;
-
-  // --------  Head Manipulation (including IP)  --------
-  inline void SetActiveHead(const int new_head)
-  { threads[cur_thread].cur_head = (UCHAR) new_head; }
-
-  int GetCurHead() const { return threads[cur_thread].cur_head; }
-  
-  const cHeadMultiMem & GetHead(int head_id) const
-  { return threads[cur_thread].heads[head_id]; }
-  cHeadMultiMem & GetHead(int head_id) 
-  { return threads[cur_thread].heads[head_id];}
-  
-  const cHeadMultiMem & GetHead(int head_id, int thread) const
-  { return threads[thread].heads[head_id]; }
-  cHeadMultiMem & GetHead(int head_id, int thread) 
-  { return threads[thread].heads[head_id];}
-
-  const cHeadMultiMem & GetActiveHead() const { return GetHead(GetCurHead()); }
-  cHeadMultiMem & GetActiveHead() { return GetHead(GetCurHead()); }
-
-  void AdjustHeads();
-
-  inline const cHeadMultiMem & IP() const
-    { return threads[cur_thread].heads[HEAD_IP]; }
-  inline cHeadMultiMem & IP() { return threads[cur_thread].heads[HEAD_IP]; }
-
-  inline const cHeadMultiMem & IP(int thread) const
-  { return threads[thread].heads[HEAD_IP]; }
-  inline cHeadMultiMem & IP(int thread) 
-  { return threads[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);
-  const cCodeLabel & GetLabel() const 
-    { return threads[cur_thread].next_label; }
-  cCodeLabel & GetLabel() { return threads[cur_thread].next_label; }
-  const cCodeLabel & GetReadLabel() const
-    { return threads[cur_thread].read_label; }
-  cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
-
-
-  // --------  Register Manipulation  --------
-  //int Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
-  //int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
-
-  // --------  Memory Manipulation  --------}
-  inline cCPUMemory & GetMemory();
-  inline cCPUMemory & GetMemory(int mem_space);
-  inline const cCPUMemory & GetMemory(int mem_space) const;
-  inline const cCPUMemory & GetMemory() const;
-
-  // --------  Thread Manipulation  --------
-  bool ForkThread(); // Adds a new thread based off of cur_thread.
-  bool KillThread(); // Kill the current thread!
-  inline void PrevThread(); // Shift the current thread in use.
-  inline void NextThread();
-  inline void SetThread(int value);
-  inline cInjectGenotype * GetCurThreadOwner(); 
-  inline cInjectGenotype * GetThreadOwner(int in_thread);
-  inline void SetThreadOwner(cInjectGenotype * in_genotype);
-
-  // --------  Tests  --------
-
-  int TestParasite() const;
-
-  // --------  Accessors  --------
-  //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(); }
-
-  int GetThreadDist() const {
-    if (GetNumThreads() == 1) return 0;
-    return threads[0].heads[HEAD_IP].GetPosition() -
-      threads[1].heads[HEAD_IP].GetPosition();
-  }
-
-  // Complex label manipulation...
-  cHeadMultiMem FindLabel(int direction);
-  int FindLabel_Forward(const cCodeLabel & search_label,
-			  const cGenome & search_genome, int pos);
-  int FindLabel_Backward(const cCodeLabel & search_label,
-			  const cGenome & search_genome, int pos);
-  cHeadMultiMem FindLabel(const cCodeLabel & in_label, int direction);
-  cHeadMultiMem FindFullLabel(const cCodeLabel & in_label);
-
-  int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
-  bool InjectParasite(double mut_multiplier);
-  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
-  int InjectThread(const cCodeLabel &, const cGenome &) { return -1; }
-  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, cHeadMultiMem & cur_head);
-  bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
-  bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
-  int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadMultiMem & cur_head, const double rate);
-  void TriggerMutations_Body(int type, cCPUMemory & target_memory,
-			     cHeadMultiMem & cur_head);
-
-  void ReadInst(const int in_inst);
-
-  void SaveState(std::ostream & fp);
-  void LoadState(std::istream & fp);
-
-  //void InitInstSet(const cString & filename, cInstSet & inst_set);
-  cString ConvertToInstruction(int mem_space_used);
-
-
-private:
- 
- /////////---------- Instruction Helpers ------------//////////
-
-  int FindModifiedStack(int default_stack);
-  int FindModifiedHead(int default_head);
-  int FindComplementStack(int base_stack);
-
-  void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
-  bool Allocate_Necro(const int new_size);
-  bool Allocate_Random(const int old_size, const int new_size);
-  bool Allocate_Default(const int new_size);
-  bool Allocate_Main(const int allocated_size);
-
-  bool Divide_Main(const int mem_space_used, double mut_multiplier=1);
-  bool Divide_CheckViable(const int parent_size, const int child_size, const int mem_space);
-  void Divide_DoMutations(double mut_multiplier=1);
-  void Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code);
-  void Divide_TestFitnessMeasures();
-
-  bool HeadCopy_ErrorCorrect(double reduction);
-  bool Inst_HeadDivideMut(double mut_multiplier=1);
-
-public:
-  /////////---------- Instruction Library ------------//////////
-
-  //6
-  bool Inst_ShiftR();
-  //7
-  bool Inst_ShiftL();
-  //8
-  bool Inst_Val_Nand();
-  //9
-  bool Inst_Val_Add();
-  //10
-  bool Inst_Val_Sub();
-  //11
-  bool Inst_Val_Mult();
-  //12
-  bool Inst_Val_Div();
-  //13
-  bool Inst_SetMemory();
-  //14
-  bool Inst_Divide();
-  //15
-  bool Inst_HeadRead();
-  //16
-  bool Inst_HeadWrite();
-  //??
-  bool Inst_HeadCopy();
-  //17
-  bool Inst_IfEqual();
-  //18
-  bool Inst_IfNotEqual();
-  //19
-  bool Inst_IfLess();
-  //20
-  bool Inst_IfGreater();
-  //21
-  bool Inst_HeadPush();
-  //22
-  bool Inst_HeadPop();
-  //23
-  bool Inst_HeadMove();
-  //24
-  bool Inst_Search();
-  //25
-  bool Inst_PushNext();
-  //26
-  bool Inst_PushPrevious();
-  //27
-  bool Inst_PushComplement();
-  //28
-  bool Inst_ValDelete();
-  //29
-  bool Inst_ValCopy();
-  //30
-  bool Inst_ForkThread();
-  //31
-  bool Inst_IfLabel();
-  //32
-  bool Inst_Increment();
-  //33
-  bool Inst_Decrement();
-  //34
-  bool Inst_Mod();
-  //35 
-  bool Inst_KillThread();
-  //36
-  bool Inst_IO();
-  //37
-  bool Inst_Inject();
-  
-  /*
-  bool Inst_InjectRand();
-  bool Inst_InjectThread();
-  bool Inst_Repro();
-  */
- 
-};
-
-
-//////////////////
-//  cHardware4Stack
-//////////////////
-
-//Not used, but here to satisfy the requirements of HardwareBase
-inline const cCPUMemory & cHardware4Stack::GetMemory() const
-{
-  return memory_array[0];
-}
-
-//Not used, but here to satisfy the requirements of HardwareBase 
-inline cCPUMemory & cHardware4Stack::GetMemory()
-{
-  return memory_array[0];
-}
-
-inline const cCPUMemory & cHardware4Stack::GetMemory(int mem_space) const
-{
-  if(mem_space >= NUM_MEMORY_SPACES)
-    mem_space %= NUM_MEMORY_SPACES;
-  return memory_array[mem_space];
-}
-
-inline cCPUMemory & cHardware4Stack::GetMemory(int mem_space)
-{
- if(mem_space >= NUM_MEMORY_SPACES)
-    mem_space %= NUM_MEMORY_SPACES;
-  return memory_array[mem_space];
-}
-
-inline void cHardware4Stack::NextThread()
-{
-  cur_thread++;
-  if (cur_thread >= GetNumThreads()) cur_thread = 0;
-}
-
-inline void cHardware4Stack::PrevThread()
-{
-  if (cur_thread == 0) cur_thread = GetNumThreads() - 1;
-  else cur_thread--;
-}
-
-inline void cHardware4Stack::SetThread(int value)
-{
-  if (value>=0 && value < GetNumThreads())
-    cur_thread=value;
-}
-
-inline cInjectGenotype * cHardware4Stack::GetCurThreadOwner() 
-{ 
-  return threads[cur_thread].owner; 
-}
-
-inline cInjectGenotype * cHardware4Stack::GetThreadOwner(int thread) 
-{ 
-  return threads[thread].owner; 
-}
-
-inline void cHardware4Stack::SetThreadOwner(cInjectGenotype * in_genotype)
-{ 
-  threads[cur_thread].owner = in_genotype; 
-}
-
-/*inline void cHardware4Stack::StackFlip()
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Flip();
-  } else {
-    global_stack.Flip();
-  }
-}*/
-
-inline int cHardware4Stack::GetStack(int depth, int stack_id, int in_thread) const
-{
-  if(stack_id<0 || stack_id>NUM_STACKS) stack_id=0;
-  
-  if(in_thread==-1)
-    in_thread=cur_thread;
-  
-  return Stack(stack_id, in_thread).Get(depth);
-}
-
-//inline void cHardware4Stack::StackClear()
-//{
-  
-  //if (threads[cur_thread].cur_stack == 0) {
-  //  threads[cur_thread].stack.Clear();
-  //} else {
-  //  global_stack.Clear();
-  //}
-//}
-
-//inline void cHardware4Stack::SwitchStack()
-//{
-//  threads[cur_thread].cur_stack++;
-//  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
-//}
-
-inline cCPUStack& cHardware4Stack::Stack(int stack_id)
-{
-  if(stack_id >= NUM_STACKS)
-    {
-      stack_id=0;
-    }
-  if(stack_id < NUM_LOCAL_STACKS)
-    return threads[cur_thread].local_stacks[stack_id];
-  else
-    return global_stacks[stack_id % NUM_LOCAL_STACKS];
-}
-
-inline const cCPUStack& cHardware4Stack::Stack(int stack_id) const 
-{
-  if(stack_id >= NUM_STACKS)
-    {
-      stack_id=0;
-    }
-  if(stack_id < NUM_LOCAL_STACKS)
-    return threads[cur_thread].local_stacks[stack_id];
-  else
-    return global_stacks[stack_id % NUM_LOCAL_STACKS];
-}
-
-inline cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) 
-{
-  if(stack_id >= NUM_STACKS)
-      stack_id=0;
-  if(in_thread >= threads.GetSize())
-      in_thread=cur_thread;
-
-  if(stack_id < NUM_LOCAL_STACKS)
-    return threads[in_thread].local_stacks[stack_id];
-  else
-    return global_stacks[stack_id % NUM_LOCAL_STACKS];
-}
-
-inline const cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) const 
-{
-  if(stack_id >= NUM_STACKS)
-      stack_id=0;
-  if(in_thread >= threads.GetSize())
-      in_thread=cur_thread;
-
-  if(stack_id < NUM_LOCAL_STACKS)
-    return threads[in_thread].local_stacks[stack_id];
-  else
-    return global_stacks[stack_id % NUM_LOCAL_STACKS];
-}
-
-#endif

Deleted: trunk/source/cpu/hardware_4stack_thread.cc
===================================================================
--- trunk/source/cpu/hardware_4stack_thread.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_4stack_thread.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,110 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_4STACK_THREAD_HH
-#include "hardware_4stack_thread.hh"
-#endif
-
-using namespace std;
-
-/////////////////////////
-//  cHardware4Stack_Thread
-/////////////////////////
-
-cHardware4Stack_Thread::cHardware4Stack_Thread(cHardwareBase * in_hardware, int _id)
-{
-  Reset(in_hardware, _id);
-}
-
-cHardware4Stack_Thread::cHardware4Stack_Thread(const cHardware4Stack_Thread & in_thread, int _id)
-{
-   id = _id;
-   if (id == -1) id = in_thread.id;
-   for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
-     local_stacks[i] = in_thread.local_stacks[i];
-   }
-   for (int i = 0; i < NUM_HEADS; i++) {
-     heads[i] = in_thread.heads[i];
-   }
-   owner = in_thread.owner;
-}
-
-cHardware4Stack_Thread::~cHardware4Stack_Thread() {}
-
-void cHardware4Stack_Thread::operator=(const cHardware4Stack_Thread & in_thread)
-{
-  id = in_thread.id;
-  for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
-    local_stacks[i] = in_thread.local_stacks[i];
-  }
-  for (int i = 0; i < NUM_HEADS; i++) {
-    heads[i] = in_thread.heads[i];
-  }
-  owner = in_thread.owner;
-}
-
-void cHardware4Stack_Thread::Reset(cHardwareBase * in_hardware, int _id)
-{
-  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(0, in_hardware);
-
-  cur_head = HEAD_IP;
-  read_label.Clear();
-  next_label.Clear();
-  owner = NULL;
-}
-
-void cHardware4Stack_Thread::SaveState(ostream & fp){
-  assert(fp.good());
-  fp << "cHardware4Stack_Thread" << endl;
-
-  // stacks (NOT WORKING! -law)
-  for( int i=0; i<NUM_STACKS; ++i ){
-    local_stacks[i].SaveState(fp);
-  }
-
-  // heads (@TCC does not handle parasites!!!)
-  for( int i=0; i<NUM_HEADS; ++i ){
-    fp<<heads[i].GetPosition()<<endl;
-  }
-
-  fp<<"|"; // marker
-  fp<<cur_head;
-  fp<<endl;
-
-  // Code labels
-  read_label.SaveState(fp);
-  next_label.SaveState(fp);
-}
-
-void cHardware4Stack_Thread::LoadState(istream & fp){
-  assert(fp.good());
-  cString foo;
-  fp >> foo;
-  assert( foo == "cHardware4Stack_Thread");
-
-  // stacks (NOT WORKING!  -law)
-  for( int i=0; i<NUM_STACKS; ++i ){
-    local_stacks[i].LoadState(fp);
-  }
-
-  // heads (@TCC does not handle parasites!!!)
-  for( int i=0; i<NUM_HEADS; ++i ){
-    int pos;
-    fp>>pos;
-    heads[i].AbsSet(pos);
-  }
-
-  char marker; fp >> marker; assert( marker == '|' );
-  /* YIKES!  data loss below: */ 
-
-  // Code labels
-  read_label.LoadState(fp);
-  next_label.LoadState(fp);
-}

Deleted: trunk/source/cpu/hardware_4stack_thread.hh
===================================================================
--- trunk/source/cpu/hardware_4stack_thread.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_4stack_thread.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,71 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_4STACK_THREAD_HH
-#define HARDWARE_4STACK_THREAD_HH
-
-#include <iostream>
-
-#ifndef CODE_LABEL_HH
-#include "cCodeLabel.h"
-#endif
-#ifndef CPU_STACK_HH
-#include "cCPUStack.h"
-#endif
-#ifndef HEAD_MULTI_MEM_HH
-#include "head_multi_mem.hh"
-#endif
-#ifndef HARDWARE_4STACK_CONSTANTS_HH
-#include "hardware_4stack_constants.hh"
-#endif
-#ifndef TBUFFER_HH
-#include "tBuffer.hh"
-#endif
-
-/**
- * This class is needed to run several threads on a single genome.
- *
- * @see cCPUStack, cHeadMultiMem, cHardware4Stack
- **/
-
-class cHeadMultiMem; // aggregate
-class cCodeLabel; // aggregate
-class cCPUStack; // aggregate
-class cHardwareBase;
-class cInjectGenotype;
-template <class T> class tBuffer; // aggregate
-
-struct cHardware4Stack_Thread {
-private:
-  int id;
-public:
-  cHeadMultiMem heads[NUM_HEADS];
-  UCHAR cur_head;
-  cCPUStack local_stacks[NUM_LOCAL_STACKS];
-
-  bool advance_ip;         // Should the IP advance after this instruction?
-  cCodeLabel read_label;
-  cCodeLabel next_label;
-  // If this thread was spawned by Inject, this will point to the genotype 
-  // of the parasite running the thread.  Otherwise, it will be NULL.
-  cInjectGenotype* owner;
-public:
-  cHardware4Stack_Thread(cHardwareBase * in_hardware=NULL, int _id=-1);
-  cHardware4Stack_Thread(const cHardware4Stack_Thread & in_thread, int _id=-1);
-  ~cHardware4Stack_Thread();
-
-  void operator=(const cHardware4Stack_Thread & in_thread);
-
-  void Reset(cHardwareBase * in_hardware, int _id);
-  int GetID() const { return id; }
-  void SetID(int _id) { id = _id; }
-
-  void SaveState(std::ostream & fp);
-  void LoadState(std::istream & fp);
-};
-
-#endif

Deleted: trunk/source/cpu/hardware_base.cc
===================================================================
--- trunk/source/cpu/hardware_base.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_base.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,61 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#include "hardware_base.hh"
-
-#include "inst_set.hh"
-
-using namespace std;
-
-int cHardwareBase::instance_count(0);
-
-cHardwareBase::cHardwareBase(cOrganism * in_organism, cInstSet * in_inst_set)
-  : organism(in_organism)
-  , inst_set(in_inst_set)
-  , viewer_lock(-1)
-  , m_tracer(NULL)
-{
-  assert(inst_set->OK());
-  assert(organism != NULL);
-
-  instance_count++;
-}
-
-cHardwareBase::~cHardwareBase()
-{
-  instance_count--;
-}
-
-void cHardwareBase::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
-{
-  assert(inst_set->OK());
-  assert(new_organism != NULL);
-
-  organism    = new_organism;
-  inst_set    = in_inst_set;
-  viewer_lock = -1;
-}
-
-bool cHardwareBase::Inst_Nop()          // Do Nothing.
-{
-  return true;
-}
-
-
-int cHardwareBase::GetNumInst()
-{
-  assert(inst_set != NULL);
-  return inst_set->GetSize();
-}
-
-
-cInstruction cHardwareBase::GetRandomInst()
-{
-  assert(inst_set != NULL);
-  return inst_set->GetRandomInst();
-}
-

Deleted: trunk/source/cpu/hardware_base.hh
===================================================================
--- trunk/source/cpu/hardware_base.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_base.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,91 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_BASE_HH
-#define HARDWARE_BASE_HH
-
-#include <iostream>
-
-#ifndef INSTRUCTION_HH
-#include "instruction.hh"
-#endif
-
-using namespace std;
-
-class cCodeLabel;
-class cCPUMemory;
-class cGenome;
-class cHardwareTracer;
-class cInstruction; // aggregate
-class cInstSet;
-class cOrganism;
-
-class cHardwareBase {
-protected:
-  cOrganism * organism;       // Organism using this hardware.
-  cInstSet * inst_set;        // Instruction set being used.
-  int viewer_lock;            // Used if the viewer should only lock onto
-                              //  one aspect of the hardware.
-
-  cHardwareTracer * m_tracer;         // Set this if you want execution traced.
-
-  static int instance_count;
-public:
-  cHardwareBase(cOrganism * in_organism, cInstSet * in_inst_set);
-  virtual ~cHardwareBase();
-  virtual void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
-
-  // --------  Organism ---------
-  cOrganism * GetOrganism() { return organism; }
-
-  // --------  Instruction Library  --------
-  const cInstSet & GetInstSet() { return *inst_set; }
-  int GetNumInst();
-  cInstruction GetRandomInst();
-  virtual void SetInstSet(cInstSet & in_inst_set) { inst_set = &in_inst_set; }
-
-  // --------  No-Operation Instruction --------
-  bool Inst_Nop();  // A no-operation instruction that does nothing! 
-
-  // --------  Interaction with Viewer --------
-  int & ViewerLock() { return viewer_lock; }
-
-  // --------  Core Functionality  --------
-  virtual void Reset() = 0;
-  virtual void SingleProcess() = 0;
-  virtual void ProcessBonusInst(const cInstruction & inst) = 0;
-  virtual void LoadGenome(const cGenome & new_genome) = 0;
-  virtual bool OK() = 0;
-
-  // --------  Other Virtual Tools --------
-  virtual int GetType() const = 0;
-  virtual bool InjectHost(const cCodeLabel & in_label,
-		      const cGenome & injection) = 0;
-  virtual int InjectThread(const cCodeLabel & in_label,
-			   const cGenome & injection) = 0;
-
-  // --------  Input and Output --------
-  virtual void PrintStatus(std::ostream & fp) = 0;
-  virtual void SaveState(std::ostream & fp) = 0;
-  virtual void LoadState(std::istream & fp) = 0;
-
-  void SetTrace(cHardwareTracer * tracer) { m_tracer = tracer; }
-
-
-  // --------  Mutations (Must be Virtual)  --------
-  virtual int PointMutate(const double mut_rate) = 0;
-  virtual bool TriggerMutations(int trigger) = 0;
-
-  // --------  @CAO Should be rethought?  --------
-  virtual cCPUMemory & GetMemory() = 0;
-  virtual cCPUMemory & GetMemory(int) = 0;
-
-  // --------  DEBUG ---------
-  static int GetInstanceCount() { return instance_count; }
-};
-
-#endif

Deleted: trunk/source/cpu/hardware_cpu.cc
===================================================================
--- trunk/source/cpu/hardware_cpu.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_cpu.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,3463 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2004 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#include "hardware_cpu.hh"
-
-#include "config.hh"
-#include "cCPUTestInfo.h"
-#include "functions.hh"
-#include "genome_util.hh"
-#include "genotype.hh"
-#include "hardware_tracer.hh"
-#include "hardware_tracer_cpu.hh"
-#include "inst_lib_cpu.hh"
-#include "inst_set.hh"
-#include "mutation.hh"
-#include "mutation_lib.hh"
-#include "mutation_macros.hh"
-#include "organism.hh"
-#include "phenotype.hh"
-#include "string_util.hh"
-#include "test_cpu.hh"
-
-#include <limits.h>
-#include <fstream>
-
-using namespace std;
-
-
-///////////////
-//  cHardwareCPU
-///////////////
-
-const cInstruction cInstLibCPU::inst_error(255);
-const cInstruction cInstLibCPU::inst_default(0);
-cInstLibCPU *cHardwareCPU::GetInstLib(){ return s_inst_slib; }
-
-cInstLibCPU *cHardwareCPU::s_inst_slib = cHardwareCPU::initInstLib();
-cInstLibCPU *cHardwareCPU::initInstLib(void){
-  struct cNOPEntryCPU {
-    cString name;
-    int nop_mod;
-    cNOPEntryCPU(const cString &name, int nop_mod)
-      : name(name), nop_mod(nop_mod) {}
-  };
-  static const cNOPEntryCPU s_n_array[] = {
-    cNOPEntryCPU("nop-A", REG_AX),
-    cNOPEntryCPU("nop-B", REG_BX),
-    cNOPEntryCPU("nop-C", REG_CX),
-    cNOPEntryCPU("nop-D", REG_DX)
-  };
-
-  struct cInstEntryCPU { 
-    const cString name;
-    const tHardwareCPUMethod function;
-    const bool is_default;
-    const cString desc;
-
-    cInstEntryCPU(const cString & _name, tHardwareCPUMethod _fun,
-		  bool _def=false, const cString & _desc="")
-      : name(_name), function(_fun), is_default(_def), desc(_desc) {}
-  };
-  static const cInstEntryCPU s_f_array[] = {
-    /*
-    Note: all entries of cNOPEntryCPU s_n_array must have corresponding
-    in the same order in cInstEntryCPU s_f_array, and these entries must
-    be the first elements of s_f_array.
-    */
-    cInstEntryCPU("nop-A",     &cHardwareCPU::Inst_Nop, true,
-		  "No-operation instruction; modifies other instructions"),
-    cInstEntryCPU("nop-B",     &cHardwareCPU::Inst_Nop, true,
-		  "No-operation instruction; modifies other instructions"),
-    cInstEntryCPU("nop-C",     &cHardwareCPU::Inst_Nop, true,
-		  "No-operation instruction; modifies other instructions"),
-    cInstEntryCPU("nop-D",     &cHardwareCPU::Inst_Nop, true,
-		  "No-operation instruction; modifies other instructions"),
-
-    cInstEntryCPU("NULL",      &cHardwareCPU::Inst_Nop, false,
-		  "True no-operation instruction: does nothing"),
-    cInstEntryCPU("nop-X",     &cHardwareCPU::Inst_Nop, false,
-		  "True no-operation instruction: does nothing"),
-    cInstEntryCPU("if-equ-0",  &cHardwareCPU::Inst_If0, false,
-		  "Execute next instruction if ?BX?==0, else skip it"),
-    cInstEntryCPU("if-not-0",  &cHardwareCPU::Inst_IfNot0, false,
-		  "Execute next instruction if ?BX?!=0, else skip it"),
-    cInstEntryCPU("if-n-equ",  &cHardwareCPU::Inst_IfNEqu, true,
-		  "Execute next instruction if ?BX?!=?CX?, else skip it"),
-    cInstEntryCPU("if-equ",    &cHardwareCPU::Inst_IfEqu, false,
-		  "Execute next instruction if ?BX?==?CX?, else skip it"),
-    cInstEntryCPU("if-grt-0",  &cHardwareCPU::Inst_IfGr0),
-    cInstEntryCPU("if-grt",    &cHardwareCPU::Inst_IfGr),
-    cInstEntryCPU("if->=-0",   &cHardwareCPU::Inst_IfGrEqu0),
-    cInstEntryCPU("if->=",     &cHardwareCPU::Inst_IfGrEqu),
-    cInstEntryCPU("if-les-0",  &cHardwareCPU::Inst_IfLess0),
-    cInstEntryCPU("if-less",   &cHardwareCPU::Inst_IfLess, true,
-		  "Execute next instruction if ?BX? < ?CX?, else skip it"),
-    cInstEntryCPU("if-<=-0",   &cHardwareCPU::Inst_IfLsEqu0),
-    cInstEntryCPU("if-<=",     &cHardwareCPU::Inst_IfLsEqu),
-    cInstEntryCPU("if-A!=B",   &cHardwareCPU::Inst_IfANotEqB),
-    cInstEntryCPU("if-B!=C",   &cHardwareCPU::Inst_IfBNotEqC),
-    cInstEntryCPU("if-A!=C",   &cHardwareCPU::Inst_IfANotEqC),
-    cInstEntryCPU("if-bit-1",  &cHardwareCPU::Inst_IfBit1),
-
-    cInstEntryCPU("jump-f",    &cHardwareCPU::Inst_JumpF),
-    cInstEntryCPU("jump-b",    &cHardwareCPU::Inst_JumpB),
-    cInstEntryCPU("jump-p",    &cHardwareCPU::Inst_JumpP),
-    cInstEntryCPU("jump-slf",  &cHardwareCPU::Inst_JumpSelf),
-    cInstEntryCPU("call",      &cHardwareCPU::Inst_Call),
-    cInstEntryCPU("return",    &cHardwareCPU::Inst_Return),
-
-    cInstEntryCPU("pop",       &cHardwareCPU::Inst_Pop, true,
-		  "Remove top number from stack and place into ?BX?"),
-    cInstEntryCPU("push",      &cHardwareCPU::Inst_Push, true,
-		  "Copy number from ?BX? and place it into the stack"),
-    cInstEntryCPU("swap-stk",  &cHardwareCPU::Inst_SwitchStack, true,
-		  "Toggle which stack is currently being used"),
-    cInstEntryCPU("flip-stk",  &cHardwareCPU::Inst_FlipStack),
-    cInstEntryCPU("swap",      &cHardwareCPU::Inst_Swap, true,
-		  "Swap the contents of ?BX? with ?CX?"),
-    cInstEntryCPU("swap-AB",   &cHardwareCPU::Inst_SwapAB),
-    cInstEntryCPU("swap-BC",   &cHardwareCPU::Inst_SwapBC),
-    cInstEntryCPU("swap-AC",   &cHardwareCPU::Inst_SwapAC),
-    cInstEntryCPU("copy-reg",  &cHardwareCPU::Inst_CopyReg),
-    cInstEntryCPU("set_A=B",   &cHardwareCPU::Inst_CopyRegAB),
-    cInstEntryCPU("set_A=C",   &cHardwareCPU::Inst_CopyRegAC),
-    cInstEntryCPU("set_B=A",   &cHardwareCPU::Inst_CopyRegBA),
-    cInstEntryCPU("set_B=C",   &cHardwareCPU::Inst_CopyRegBC),
-    cInstEntryCPU("set_C=A",   &cHardwareCPU::Inst_CopyRegCA),
-    cInstEntryCPU("set_C=B",   &cHardwareCPU::Inst_CopyRegCB),
-    cInstEntryCPU("reset",     &cHardwareCPU::Inst_Reset),
-
-    cInstEntryCPU("pop-A",     &cHardwareCPU::Inst_PopA),
-    cInstEntryCPU("pop-B",     &cHardwareCPU::Inst_PopB),
-    cInstEntryCPU("pop-C",     &cHardwareCPU::Inst_PopC),
-    cInstEntryCPU("push-A",    &cHardwareCPU::Inst_PushA),
-    cInstEntryCPU("push-B",    &cHardwareCPU::Inst_PushB),
-    cInstEntryCPU("push-C",    &cHardwareCPU::Inst_PushC),
-
-    cInstEntryCPU("shift-r",   &cHardwareCPU::Inst_ShiftR, true,
-		  "Shift bits in ?BX? right by one (divide by two)"),
-    cInstEntryCPU("shift-l",   &cHardwareCPU::Inst_ShiftL, true,
-		  "Shift bits in ?BX? left by one (multiply by two)"),
-    cInstEntryCPU("bit-1",     &cHardwareCPU::Inst_Bit1),
-    cInstEntryCPU("set-num",   &cHardwareCPU::Inst_SetNum),
-    cInstEntryCPU("val-grey",  &cHardwareCPU::Inst_ValGrey),
-    cInstEntryCPU("val-dir",   &cHardwareCPU::Inst_ValDir),
-    cInstEntryCPU("val-add-p", &cHardwareCPU::Inst_ValAddP),
-    cInstEntryCPU("val-fib",   &cHardwareCPU::Inst_ValFib),
-    cInstEntryCPU("val-poly-c",&cHardwareCPU::Inst_ValPolyC),
-    cInstEntryCPU("inc",       &cHardwareCPU::Inst_Inc, true,
-		  "Increment ?BX? by one"),
-    cInstEntryCPU("dec",       &cHardwareCPU::Inst_Dec, true,
-		  "Decrement ?BX? by one"),
-    cInstEntryCPU("zero",      &cHardwareCPU::Inst_Zero, false,
-		  "Set ?BX? to zero"),
-    cInstEntryCPU("neg",       &cHardwareCPU::Inst_Neg),
-    cInstEntryCPU("square",    &cHardwareCPU::Inst_Square),
-    cInstEntryCPU("sqrt",      &cHardwareCPU::Inst_Sqrt),
-    cInstEntryCPU("not",       &cHardwareCPU::Inst_Not),
-    cInstEntryCPU("minus-17",  &cHardwareCPU::Inst_Minus17),
-    
-    cInstEntryCPU("add",       &cHardwareCPU::Inst_Add, true,
-		  "Add BX to CX and place the result in ?BX?"),
-    cInstEntryCPU("sub",       &cHardwareCPU::Inst_Sub, true,
-		  "Subtract CX from BX and place the result in ?BX?"),
-    cInstEntryCPU("mult",      &cHardwareCPU::Inst_Mult, false,
-		  "Multiple BX by CX and place the result in ?BX?"),
-    cInstEntryCPU("div",       &cHardwareCPU::Inst_Div, false,
-		  "Divide BX by CX and place the result in ?BX?"),
-    cInstEntryCPU("mod",       &cHardwareCPU::Inst_Mod),
-    cInstEntryCPU("nand",      &cHardwareCPU::Inst_Nand, true,
-		  "Nand BX by CX and place the result in ?BX?"),
-    cInstEntryCPU("nor",       &cHardwareCPU::Inst_Nor),
-    cInstEntryCPU("and",       &cHardwareCPU::Inst_And),
-    cInstEntryCPU("order",     &cHardwareCPU::Inst_Order),
-    cInstEntryCPU("xor",       &cHardwareCPU::Inst_Xor),
-    
-    cInstEntryCPU("copy",      &cHardwareCPU::Inst_Copy),
-    cInstEntryCPU("read",      &cHardwareCPU::Inst_ReadInst),
-    cInstEntryCPU("write",     &cHardwareCPU::Inst_WriteInst),
-    cInstEntryCPU("stk-read",  &cHardwareCPU::Inst_StackReadInst),
-    cInstEntryCPU("stk-writ",  &cHardwareCPU::Inst_StackWriteInst),
-    
-    cInstEntryCPU("compare",   &cHardwareCPU::Inst_Compare),
-    cInstEntryCPU("if-n-cpy",  &cHardwareCPU::Inst_IfNCpy),
-    cInstEntryCPU("allocate",  &cHardwareCPU::Inst_Allocate),
-    cInstEntryCPU("divide",    &cHardwareCPU::Inst_Divide),
-    cInstEntryCPU("c-alloc",   &cHardwareCPU::Inst_CAlloc),
-    cInstEntryCPU("c-divide",  &cHardwareCPU::Inst_CDivide),
-    cInstEntryCPU("inject",    &cHardwareCPU::Inst_Inject),
-    cInstEntryCPU("inject-r",  &cHardwareCPU::Inst_InjectRand),
-    cInstEntryCPU("search-f",  &cHardwareCPU::Inst_SearchF),
-    cInstEntryCPU("search-b",  &cHardwareCPU::Inst_SearchB),
-    cInstEntryCPU("mem-size",  &cHardwareCPU::Inst_MemSize),
-
-    cInstEntryCPU("get",       &cHardwareCPU::Inst_TaskGet),
-    cInstEntryCPU("stk-get",   &cHardwareCPU::Inst_TaskStackGet),
-    cInstEntryCPU("stk-load",  &cHardwareCPU::Inst_TaskStackLoad),
-    cInstEntryCPU("put",       &cHardwareCPU::Inst_TaskPut),
-    cInstEntryCPU("IO",        &cHardwareCPU::Inst_TaskIO, true,
-		  "Output ?BX?, and input new number back into ?BX?"),
-
-    cInstEntryCPU("send",      &cHardwareCPU::Inst_Send),
-    cInstEntryCPU("receive",   &cHardwareCPU::Inst_Receive),
-    cInstEntryCPU("sense",     &cHardwareCPU::Inst_Sense),
-
-    cInstEntryCPU("donate-rnd",  &cHardwareCPU::Inst_DonateRandom),
-    cInstEntryCPU("donate-kin",  &cHardwareCPU::Inst_DonateKin),
-    cInstEntryCPU("donate-edt",  &cHardwareCPU::Inst_DonateEditDist),
-    cInstEntryCPU("donate-NUL",  &cHardwareCPU::Inst_DonateNULL),
-
-    cInstEntryCPU("rotate-l",  &cHardwareCPU::Inst_RotateL),
-    cInstEntryCPU("rotate-r",  &cHardwareCPU::Inst_RotateR),
-
-    cInstEntryCPU("set-cmut",  &cHardwareCPU::Inst_SetCopyMut),
-    cInstEntryCPU("mod-cmut",  &cHardwareCPU::Inst_ModCopyMut),
-
-    // Threading instructions
-    cInstEntryCPU("fork-th",   &cHardwareCPU::Inst_ForkThread),
-    cInstEntryCPU("kill-th",   &cHardwareCPU::Inst_KillThread),
-    cInstEntryCPU("id-th",     &cHardwareCPU::Inst_ThreadID),
-
-    // Head-based instructions
-    cInstEntryCPU("h-alloc",   &cHardwareCPU::Inst_MaxAlloc, true,
-		  "Allocate maximum allowed space"),
-    cInstEntryCPU("h-divide",  &cHardwareCPU::Inst_HeadDivide, true,
-		  "Divide code between read and write heads."),
-    cInstEntryCPU("h-read",    &cHardwareCPU::Inst_HeadRead),
-    cInstEntryCPU("h-write",   &cHardwareCPU::Inst_HeadWrite),
-    cInstEntryCPU("h-copy",    &cHardwareCPU::Inst_HeadCopy, true,
-		  "Copy from read-head to write-head; advance both"),
-    cInstEntryCPU("h-search",  &cHardwareCPU::Inst_HeadSearch, true,
-		  "Find complement template and make with flow head"),
-    cInstEntryCPU("h-push",    &cHardwareCPU::Inst_HeadPush),
-    cInstEntryCPU("h-pop",     &cHardwareCPU::Inst_HeadPop),
-    cInstEntryCPU("set-head",  &cHardwareCPU::Inst_SetHead),
-    cInstEntryCPU("adv-head",  &cHardwareCPU::Inst_AdvanceHead),
-    cInstEntryCPU("mov-head",  &cHardwareCPU::Inst_MoveHead, true,
-		  "Move head ?IP? to the flow head"),
-    cInstEntryCPU("jmp-head",  &cHardwareCPU::Inst_JumpHead, true,
-		  "Move head ?IP? by amount in CX register; CX = old pos."),
-    cInstEntryCPU("get-head",  &cHardwareCPU::Inst_GetHead, true,
-		  "Copy the position of the ?IP? head into CX"),
-    cInstEntryCPU("if-label",  &cHardwareCPU::Inst_IfLabel, true,
-		  "Execute next if we copied complement of attached label"),
-    cInstEntryCPU("if-label2",  &cHardwareCPU::Inst_IfLabel2, true,
-		  "If copied label compl., exec next inst; else SKIP W/NOPS"),
-    cInstEntryCPU("set-flow",  &cHardwareCPU::Inst_SetFlow, true,
-		  "Set flow-head to position in ?CX?"),
-
-    cInstEntryCPU("h-copy2",    &cHardwareCPU::Inst_HeadCopy2),
-    cInstEntryCPU("h-copy3",    &cHardwareCPU::Inst_HeadCopy3),
-    cInstEntryCPU("h-copy4",    &cHardwareCPU::Inst_HeadCopy4),
-    cInstEntryCPU("h-copy5",    &cHardwareCPU::Inst_HeadCopy5),
-    cInstEntryCPU("h-copy6",    &cHardwareCPU::Inst_HeadCopy6),
-    cInstEntryCPU("h-copy7",    &cHardwareCPU::Inst_HeadCopy7),
-    cInstEntryCPU("h-copy8",    &cHardwareCPU::Inst_HeadCopy8),
-    cInstEntryCPU("h-copy9",    &cHardwareCPU::Inst_HeadCopy9),
-    cInstEntryCPU("h-copy10",   &cHardwareCPU::Inst_HeadCopy10),
-
-    cInstEntryCPU("divide-sex",    &cHardwareCPU::Inst_HeadDivideSex),
-    cInstEntryCPU("divide-asex",   &cHardwareCPU::Inst_HeadDivideAsex),
-
-    cInstEntryCPU("div-sex",    &cHardwareCPU::Inst_HeadDivideSex),
-    cInstEntryCPU("div-asex",   &cHardwareCPU::Inst_HeadDivideAsex),
-    cInstEntryCPU("div-asex-w",   &cHardwareCPU::Inst_HeadDivideAsexWait),
-    cInstEntryCPU("div-sex-MS",   &cHardwareCPU::Inst_HeadDivideMateSelect),
-
-    cInstEntryCPU("h-divide1",      &cHardwareCPU::Inst_HeadDivide1),
-    cInstEntryCPU("h-divide2",      &cHardwareCPU::Inst_HeadDivide2),
-    cInstEntryCPU("h-divide3",      &cHardwareCPU::Inst_HeadDivide3),
-    cInstEntryCPU("h-divide4",      &cHardwareCPU::Inst_HeadDivide4),
-    cInstEntryCPU("h-divide5",      &cHardwareCPU::Inst_HeadDivide5),
-    cInstEntryCPU("h-divide6",      &cHardwareCPU::Inst_HeadDivide6),
-    cInstEntryCPU("h-divide7",      &cHardwareCPU::Inst_HeadDivide7),
-    cInstEntryCPU("h-divide8",      &cHardwareCPU::Inst_HeadDivide8),
-    cInstEntryCPU("h-divide9",      &cHardwareCPU::Inst_HeadDivide9),
-    cInstEntryCPU("h-divide10",     &cHardwareCPU::Inst_HeadDivide10),
-    cInstEntryCPU("h-divide16",     &cHardwareCPU::Inst_HeadDivide16),
-    cInstEntryCPU("h-divide32",     &cHardwareCPU::Inst_HeadDivide32),
-    cInstEntryCPU("h-divide50",     &cHardwareCPU::Inst_HeadDivide50),
-    cInstEntryCPU("h-divide100",    &cHardwareCPU::Inst_HeadDivide100),
-    cInstEntryCPU("h-divide500",    &cHardwareCPU::Inst_HeadDivide500),
-    cInstEntryCPU("h-divide1000",   &cHardwareCPU::Inst_HeadDivide1000),
-    cInstEntryCPU("h-divide5000",   &cHardwareCPU::Inst_HeadDivide5000),
-    cInstEntryCPU("h-divide10000",  &cHardwareCPU::Inst_HeadDivide10000),
-    cInstEntryCPU("h-divide50000",  &cHardwareCPU::Inst_HeadDivide50000),
-    cInstEntryCPU("h-divide0.5",    &cHardwareCPU::Inst_HeadDivide0_5),
-    cInstEntryCPU("h-divide0.1",    &cHardwareCPU::Inst_HeadDivide0_1),
-    cInstEntryCPU("h-divide0.05",   &cHardwareCPU::Inst_HeadDivide0_05),
-    cInstEntryCPU("h-divide0.01",   &cHardwareCPU::Inst_HeadDivide0_01),
-    cInstEntryCPU("h-divide0.001",  &cHardwareCPU::Inst_HeadDivide0_001),
-
-    // High-level instructions
-    cInstEntryCPU("repro",      &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-A",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-B",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-C",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-D",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-E",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-F",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-G",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-H",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-I",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-J",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-K",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-L",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-M",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-N",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-O",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-P",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-Q",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-R",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-S",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-T",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-U",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-V",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-W",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-X",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-Y",    &cHardwareCPU::Inst_Repro),
-    cInstEntryCPU("repro-Z",    &cHardwareCPU::Inst_Repro),
-
-    // Suicide
-    cInstEntryCPU("kazi",	&cHardwareCPU::Inst_Kazi),
-    cInstEntryCPU("die",	&cHardwareCPU::Inst_Die),
-
-
-
-    // Placebo instructions
-    // nop-x (included with nops)
-    cInstEntryCPU("skip",      &cHardwareCPU::Inst_Skip)
-  };
-
-  const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
-
-  static cString n_names[n_size];
-  static int nop_mods[n_size];
-  for (int i = 0; i < n_size; i++){
-    n_names[i] = s_n_array[i].name;
-    nop_mods[i] = s_n_array[i].nop_mod;
-  }
-
-  const int f_size = sizeof(s_f_array)/sizeof(cInstEntryCPU);
-  static cString f_names[f_size];
-  static tHardwareCPUMethod functions[f_size];
-  for (int i = 0; i < f_size; i++){
-    f_names[i] = s_f_array[i].name;
-    functions[i] = s_f_array[i].function;
-  }
-
-  cInstLibCPU *inst_lib = new cInstLibCPU(
-    n_size,
-    f_size,
-    n_names,
-    f_names,
-    nop_mods,
-    functions
-  );
-
-  return inst_lib;
-}
-
-cHardwareCPU::cHardwareCPU(cOrganism * in_organism, cInstSet * in_inst_set)
-  : cHardwareBase(in_organism, in_inst_set)
-{
-  /* FIXME:  reorganize storage of m_functions.  -- kgn */
-  m_functions = s_inst_slib->GetFunctions();
-  /**/
-  memory = in_organism->GetGenome();  // Initialize memory...
-  Reset();                            // Setup the rest of the hardware...
-}
-
-
-cHardwareCPU::cHardwareCPU(const cHardwareCPU &hardware_cpu)
-: cHardwareBase(hardware_cpu.organism, hardware_cpu.inst_set)
-, m_functions(hardware_cpu.m_functions)
-, memory(hardware_cpu.memory)
-, global_stack(hardware_cpu.global_stack)
-, thread_time_used(hardware_cpu.thread_time_used)
-, threads(hardware_cpu.threads)
-, thread_id_chart(hardware_cpu.thread_id_chart)
-, cur_thread(hardware_cpu.cur_thread)
-, mal_active(hardware_cpu.mal_active)
-, advance_ip(hardware_cpu.advance_ip)
-#ifdef INSTRUCTION_COSTS
-, inst_cost(hardware_cpu.inst_cost)
-, inst_ft_cost(hardware_cpu.inst_ft_cost)
-#endif
-{
-}
-
-
-cHardwareCPU::~cHardwareCPU()
-{
-}
-
-
-void cHardwareCPU::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
-{
-  cHardwareBase::Recycle(new_organism, in_inst_set);
-  memory = new_organism->GetGenome();
-  Reset();
-}
-
-
-void cHardwareCPU::Reset()
-{
-  global_stack.Clear();
-  thread_time_used = 0;
-
-  // We want to reset to have a single thread.
-  threads.Resize(1);
-
-  // Reset that single thread.
-  threads[0].Reset(this, 0);
-  thread_id_chart = 1; // Mark only the first thread as taken...
-  cur_thread = 0;
-
-  mal_active = false;
-
-#ifdef INSTRUCTION_COSTS
-  // instruction cost arrays
-  const int num_inst_cost = GetNumInst();
-  inst_cost.Resize(num_inst_cost);
-  inst_ft_cost.Resize(num_inst_cost);
-
-  for (int i = 0; i < num_inst_cost; i++) {
-    inst_cost[i] = GetInstSet().GetCost(cInstruction(i));
-    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
-  }
-#endif
-
-}
-
-
-// This function processes the very next command in the genome, and is made
-// to be as optimized as possible.  This is the heart of avida.
-
-void cHardwareCPU::SingleProcess()
-{
-  // Mark this organism as running...
-  organism->SetRunning(true);
-
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.IncTimeUsed();
-  const int num_threads = GetNumThreads();
-  if (num_threads > 1) thread_time_used++;
-
-  // 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) ?
-    num_threads : 1;
-  
-  for (int i = 0; i < num_inst_exec; i++) {
-    // Setup the hardware for the next instruction to be executed.
-    NextThread();
-    advance_ip = true;
-    IP().Adjust();
-
-#ifdef BREAKPOINTS
-    if (IP().FlagBreakpoint() == true) {
-      organism->DoBreakpoint();
-    }
-#endif
-    
-    // Print the status of this CPU at each step...
-    if (m_tracer != NULL) {
-      if (cHardwareTracer_CPU * tracer
-          = dynamic_cast<cHardwareTracer_CPU *>(m_tracer)
-      ){
-        tracer->TraceHardware_CPU(*this);
-      }
-    }
-    
-    // Find the instruction to be executed
-    const cInstruction & cur_inst = IP().GetInst();
-
-    // Test if costs have been paid and it is okay to execute this now...
-    const bool exec = SingleProcess_PayCosts(cur_inst);
-
-    // Now execute the instruction...
-    if (exec == true) {
-      SingleProcess_ExecuteInst(cur_inst);
-
-      // 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 exec
-    
-  } // Previous was executed once for each thread...
-
-  // Kill creatures who have reached their max num of instructions executed
-  const int max_executed = organism->GetMaxExecuted();
-  if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
-      || phenotype.GetToDie() == true) {
-    organism->Die();
-  }
-
-  organism->SetRunning(false);
-}
-
-
-// This method will test to see if all costs have been paid associated
-// with executing an instruction and only return true when that instruction
-// should proceed.
-bool cHardwareCPU::SingleProcess_PayCosts(const cInstruction & cur_inst)
-{
-#ifdef INSTRUCTION_COSTS
-  assert(cur_inst.GetOp() < inst_cost.GetSize());
-
-  // If first time cost hasn't been paid off...
-  if ( inst_ft_cost[cur_inst.GetOp()] > 0 ) {
-    inst_ft_cost[cur_inst.GetOp()]--;       // dec cost
-    return false;
-  }
-    
-  // Next, look at the per use cost
-  if ( GetInstSet().GetCost(cur_inst) > 0 ) {
-    if ( inst_cost[cur_inst.GetOp()] > 1 ){  // if isn't paid off (>1)
-      inst_cost[cur_inst.GetOp()]--;         // dec cost
-      return false;
-    } else {                                 // else, reset cost array
-      inst_cost[cur_inst.GetOp()] = GetInstSet().GetCost(cur_inst);
-    }
-  }
-    
-  // Prob of exec
-  if ( GetInstSet().GetProbFail(cur_inst) > 0.0 ){
-    return !( g_random.P(GetInstSet().GetProbFail(cur_inst)) );
-  }
-#endif
-  return true;
-}
-
-// This method will handle the actuall execution of an instruction
-// within single process, once that function has been finalized.
-bool cHardwareCPU::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
-{
-  // Copy Instruction locally to handle stochastic effects
-  cInstruction actual_inst = cur_inst;
-  
-#ifdef EXECUTION_ERRORS
-  // If there is an execution error, execute a random instruction.
-  if (organism->TestExeErr()) actual_inst = GetInstSet().GetRandomInst();
-#endif /* EXECUTION_ERRORS */
-
-  // Get a pointer to the corrisponding method...
-  int inst_idx = GetInstSet().GetLibFunctionIndex(actual_inst);
-  
-  // Mark the instruction as executed
-  IP().FlagExecuted() = true;
-	
-
-#ifdef INSTRUCTION_COUNT
-  // instruction execution count incremeneted
-  organism->GetPhenotype().IncCurInstCount(actual_inst.GetOp());
-#endif
-	
-  // And execute it.
-  const bool exec_success = (this->*(m_functions[inst_idx]))();
-	
-#ifdef INSTRUCTION_COUNT
-  // decremenet if the instruction was not executed successfully
-  if (exec_success == false) {
-    organism->GetPhenotype().DecCurInstCount(actual_inst.GetOp());
-  }
-#endif	
-
-  return exec_success;
-}
-
-
-void cHardwareCPU::ProcessBonusInst(const cInstruction & inst)
-{
-  // Mark this organism as running...
-  bool prev_run_state = organism->GetIsRunning();
-  organism->SetRunning(true);
-
-  // @CAO FIX PRINTING TO INDICATE THIS IS A BONUS
-  // Print the status of this CPU at each step...
-  if (m_tracer != NULL) {
-    if (cHardwareTracer_CPU * tracer
-        = dynamic_cast<cHardwareTracer_CPU *>(m_tracer)
-    ){
-      tracer->TraceHardware_CPUBonus(*this);
-    }
-  }
-    
-  SingleProcess_ExecuteInst(inst);
-
-  organism->SetRunning(prev_run_state);
-}
-
-
-void cHardwareCPU::LoadGenome(const cGenome & new_genome)
-{
-  GetMemory() = new_genome;
-}
-
-
-bool cHardwareCPU::OK()
-{
-  bool result = true;
-
-  if (!memory.OK()) result = false;
-
-  for (int i = 0; i < GetNumThreads(); i++) {
-    if (threads[i].stack.OK() == false) result = false;
-    if (threads[i].next_label.OK() == false) result = false;
-  }
-
-  return result;
-}
-
-void cHardwareCPU::PrintStatus(ostream & fp)
-{
-  fp << organism->GetPhenotype().GetTimeUsed() << " "
-     << "IP:" << IP().GetPosition() << "    "
-
-     << "AX:" << Register(REG_AX) << " "
-     << setbase(16) << "[0x" << Register(REG_AX) << "]  " << setbase(10)
-
-     << "BX:" << Register(REG_BX) << " "
-     << setbase(16) << "[0x" << Register(REG_BX) << "]  " << setbase(10)
-
-     << "CX:" << Register(REG_CX) << " "
-     << setbase(16) << "[0x" << Register(REG_CX) << "]" << setbase(10)
-
-     << endl;
-
-  fp << "  R-Head:" << GetHead(HEAD_READ).GetPosition() << " "
-     << "W-Head:" << GetHead(HEAD_WRITE).GetPosition()  << " "
-     << "F-Head:" << GetHead(HEAD_FLOW).GetPosition()   << "  "
-     << "RL:" << GetReadLabel().AsString() << "   "
-     << endl;
-
-  fp << "  Mem (" << GetMemory().GetSize() << "):"
-		  << "  " << GetMemory().AsString()
-		  << endl;
-  fp.flush();
-}
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////////
-// Method: cHardwareCPU::FindLabel(direction)
-//
-// Search in 'direction' (+ or - 1) from the instruction pointer for the
-// compliment of the label in 'next_label' and return a pointer to the
-// results.  If direction is 0, search from the beginning of the genome.
-//
-/////////////////////////////////////////////////////////////////////////
-
-cHeadCPU cHardwareCPU::FindLabel(int direction)
-{
-  cHeadCPU & inst_ptr = IP();
-
-  // Start up a search head at the position of the instruction pointer.
-  cHeadCPU search_head(inst_ptr);
-  cCodeLabel & search_label = GetLabel();
-
-  // Make sure the label is of size > 0.
-
-  if (search_label.GetSize() == 0) {
-    return inst_ptr;
-  }
-
-  // Call special functions depending on if jump is forwards or backwards.
-  int found_pos = 0;
-  if( direction < 0 ) {
-    found_pos = FindLabel_Backward(search_label, inst_ptr.GetMemory(),
-			   inst_ptr.GetPosition() - search_label.GetSize());
-  }
-
-  // Jump forward.
-  else if (direction > 0) {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(),
-			   inst_ptr.GetPosition());
-  }
-
-  // Jump forward from the very beginning.
-  else {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(), 0);
-  }
-  
-  // Return the last line of the found label, if it was found.
-  if (found_pos >= 0) search_head.Set(found_pos - 1);
-
-  // Return the found position (still at start point if not found).
-  return search_head;
-}
-
-
-// Search forwards for search_label from _after_ position pos in the
-// memory.  Return the first line _after_ the the found label.  It is okay
-// to find search label's match inside another label.
-
-int cHardwareCPU::FindLabel_Forward(const cCodeLabel & search_label,
-				 const cGenome & search_genome, int pos)
-{
-  assert (pos < search_genome.GetSize() && pos >= 0);
-
-  int search_start = pos;
-  int label_size = search_label.GetSize();
-  bool found_label = false;
-
-  // Move off the template we are on.
-  pos += label_size;
-
-  // Search until we find the complement or exit the memory.
-  while (pos < search_genome.GetSize()) {
-
-    // If we are within a label, rewind to the beginning of it and see if
-    // it has the proper sub-label that we're looking for.
-
-    if (inst_set->IsNop(search_genome[pos])) {
-      // Find the start and end of the label we're in the middle of.
-
-      int start_pos = pos;
-      int end_pos = pos + 1;
-      while (start_pos > search_start &&
-	     inst_set->IsNop( search_genome[start_pos - 1] )) {
-	start_pos--;
-      }
-      while (end_pos < search_genome.GetSize() &&
-	     inst_set->IsNop( search_genome[end_pos] )) {
-	end_pos++;
-      }
-      int test_size = end_pos - start_pos;
-
-      // See if this label has the proper sub-label within it.
-      int max_offset = test_size - label_size + 1;
-      int offset = start_pos;
-      for (offset = start_pos; offset < start_pos + max_offset; offset++) {
-
-	// Test the number of matches for this offset.
-	int matches;
-	for (matches = 0; matches < label_size; matches++) {
-	  if (search_label[matches] !=
-	      inst_set->GetNopMod( search_genome[offset + matches] )) {
-	    break;
-	  }
-	}
-
-	// If we have found it, break out of this loop!
-	if (matches == label_size) {
-	  found_label = true;
-	  break;
-	}
-      }
-
-      // If we've found the complement label, set the position to the end of
-      // the label we found it in, and break out.
-
-      if (found_label == true) {
-	// pos = end_pos;
-	pos = label_size + offset;
-	break;
-      }
-
-      // We haven't found it; jump pos to just after the current label being
-      // checked.
-      pos = end_pos;
-    }
-
-    // Jump up a block to the next possible point to find a label,
-    pos += label_size;
-  }
-
-  // If the label was not found return a -1.
-  if (found_label == false) pos = -1;
-
-  return pos;
-}
-
-// Search backwards for search_label from _before_ position pos in the
-// memory.  Return the first line _after_ the the found label.  It is okay
-// to find search label's match inside another label.
-
-int cHardwareCPU::FindLabel_Backward(const cCodeLabel & search_label,
-				  const cGenome & search_genome, int pos)
-{
-  assert (pos < search_genome.GetSize());
-
-  int search_start = pos;
-  int label_size = search_label.GetSize();
-  bool found_label = false;
-
-  // Move off the template we are on.
-  pos -= label_size;
-
-  // Search until we find the complement or exit the memory.
-  while (pos >= 0) {
-    // If we are within a label, rewind to the beginning of it and see if
-    // it has the proper sub-label that we're looking for.
-
-    if (inst_set->IsNop( search_genome[pos] )) {
-      // Find the start and end of the label we're in the middle of.
-
-      int start_pos = pos;
-      int end_pos = pos + 1;
-      while (start_pos > 0 && inst_set->IsNop(search_genome[start_pos - 1])) {
-	start_pos--;
-      }
-      while (end_pos < search_start &&
-	     inst_set->IsNop(search_genome[end_pos])) {
-	end_pos++;
-      }
-      int test_size = end_pos - start_pos;
-
-      // See if this label has the proper sub-label within it.
-      int max_offset = test_size - label_size + 1;
-      for (int offset = start_pos; offset < start_pos + max_offset; offset++) {
-
-	// Test the number of matches for this offset.
-	int matches;
-	for (matches = 0; matches < label_size; matches++) {
-	  if (search_label[matches] !=
-	      inst_set->GetNopMod(search_genome[offset + matches])) {
-	    break;
-	  }
-	}
-
-	// If we have found it, break out of this loop!
-	if (matches == label_size) {
-	  found_label = true;
-	  break;
-	}
-      }
-
-      // If we've found the complement label, set the position to the end of
-      // the label we found it in, and break out.
-
-      if (found_label == true) {
-	pos = end_pos;
-	break;
-      }
-
-      // We haven't found it; jump pos to just before the current label
-      // being checked.
-      pos = start_pos - 1;
-    }
-
-    // Jump up a block to the next possible point to find a label,
-    pos -= label_size;
-  }
-
-  // If the label was not found return a -1.
-  if (found_label == false) pos = -1;
-
-  return pos;
-}
-
-// Search for 'in_label' anywhere in the hardware.
-cHeadCPU cHardwareCPU::FindLabel(const cCodeLabel & in_label, int direction)
-{
-  assert (in_label.GetSize() > 0);
-
-  // IDEALY:
-  // Keep making jumps (in the proper direction) equal to the label
-  // length.  If we are inside of a label, check its size, and see if
-  // any of the sub-labels match properly.
-  // FOR NOW:
-  // Get something which works, no matter how inefficient!!!
-
-  cHeadCPU temp_head(this);
-
-  while (temp_head.InMemory()) {
-    // IDEALY: Analyze the label we are in; see if the one we are looking
-    // for could be a sub-label of it.  Skip past it if not.
-
-    int i;
-    for (i = 0; i < in_label.GetSize(); i++) {
-      if (!inst_set->IsNop(temp_head.GetInst()) ||
-	  in_label[i] != inst_set->GetNopMod(temp_head.GetInst())) {
-	break;
-      }
-    }
-    if (i == GetLabel().GetSize()) {
-      temp_head.AbsJump(i - 1);
-      return temp_head;
-    }
-
-    temp_head.AbsJump(direction);     // IDEALY: MAKE LARGER JUMPS
-  }
-
-  temp_head.AbsSet(-1);
-  return temp_head;
-}
-
-// @CAO: direction is not currently used; should be used to indicate the
-// direction which the heads[HEAD_IP] should progress through a creature.
-cHeadCPU cHardwareCPU::FindFullLabel(const cCodeLabel & in_label)
-{
-  // cout << "Running FindFullLabel with " << in_label.AsString() <<
-  // endl;
-
-  assert(in_label.GetSize() > 0); // Trying to find label of 0 size!
-
-  cHeadCPU temp_head(this);
-
-  while (temp_head.InMemory()) {
-    // If we are not in a label, jump to the next checkpoint...
-    if (inst_set->IsNop(temp_head.GetInst())) {
-      temp_head.AbsJump(in_label.GetSize());
-      continue;
-    }
-
-    // Otherwise, rewind to the begining of this label...
-
-    while (!(temp_head.AtFront()) && inst_set->IsNop(temp_head.GetInst(-1)))
-      temp_head.AbsJump(-1);
-
-    // Calculate the size of the label being checked, and make sure they
-    // are equal.
-
-    int checked_size = 0;
-    while (inst_set->IsNop(temp_head.GetInst(checked_size))) {
-      checked_size++;
-    }
-    if (checked_size != in_label.GetSize()) {
-      temp_head.AbsJump(checked_size + 1);
-      continue;
-    }
-
-    // cout << "Testing label at line " << temp_head.GetPosition() <<
-    // endl;
-
-    // ...and do the comparison...
-
-    int j;
-    bool label_match = true;
-    for (j = 0; j < in_label.GetSize(); j++) {
-      if (!inst_set->IsNop(temp_head.GetInst(j)) ||
-	  in_label[j] != inst_set->GetNopMod(temp_head.GetInst(j))) {
-	temp_head.AbsJump(in_label.GetSize() + 1);
-	label_match = false;
-	break;
-      }
-    }
-
-    if (label_match) {
-      // If we have found the label, return the position after it.
-      temp_head.AbsJump(j - 1);
-      return temp_head;
-    }
-
-    // We have not found the label... increment i.
-
-    temp_head.AbsJump(in_label.GetSize() + 1);
-  }
-
-  // The label does not exist in this creature.
-
-  temp_head.AbsSet(-1);
-  return temp_head;
-}
-
-
-bool cHardwareCPU::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
-{
-  // Make sure the genome will be below max size after injection.
-
-  const int new_size = injection.GetSize() + GetMemory().GetSize();
-  if (new_size > MAX_CREATURE_SIZE) return false; // (inject fails)
-
-  const int inject_line = FindFullLabel(in_label).GetPosition();
-
-  // Abort if no compliment is found.
-  if (inject_line == -1) return false; // (inject fails)
-
-  // Inject the code!
-  InjectCode(injection, inject_line+1);
-
-  return true; // (inject succeeds!)
-}
-
-int cHardwareCPU::InjectThread(const cCodeLabel & in_label, const cGenome & injection)
-{
-  // Make sure the genome will be below max size after injection.
-
-  const int new_size = injection.GetSize() + GetMemory().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!
-  InjectCodeThread(injection, inject_line+1);
-
-  return 0; // (inject succeeds!)
-}
-
-void cHardwareCPU::InjectCode(const cGenome & inject_code, const int line_num)
-{
-  assert(line_num >= 0);
-  assert(line_num <= memory.GetSize());
-  assert(memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
-
-  // Inject the new code.
-  const int inject_size = inject_code.GetSize();
-  memory.Insert(line_num, inject_code);
-  
-  // Set instruction flags on the injected code
-  for (int i = line_num; i < line_num + inject_size; i++) {
-    memory.FlagInjected(i) = true;
-  }
-  organism->GetPhenotype().IsModified() = true;
-
-  // 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 cHardwareCPU::InjectCodeThread(const cGenome & inject_code, const int line_num)
-{
-  assert(line_num >= 0);
-  assert(line_num <= memory.GetSize());
-  assert(memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
-  
-  if(ForkThread())
-    {
-      // Inject the new code.
-      const int inject_size = inject_code.GetSize();
-      memory.Insert(line_num, inject_code);
-      
-      // Set instruction flags on the injected code
-      for (int i = line_num; i < line_num + inject_size; i++) {
-	memory.FlagInjected(i) = true;
-      }
-      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);
-          
-    }
-  else
-    {
-      //Some kind of error message should go here...but what?
-    }
-
-}
-
-void cHardwareCPU::Mutate(int mut_point)
-{
-  // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
-
-  GetMemory()[mut_point] = GetRandomInst();
-  GetMemory().FlagMutated(mut_point) = true;
-  GetMemory().FlagPointMut(mut_point) = true;
-  //organism->GetPhenotype().IsMutated() = true;
-  organism->CPUStats().mut_stats.point_mut_count++;
-}
-
-int cHardwareCPU::PointMutate(const double mut_rate)
-{
-  const int num_muts =
-    g_random.GetRandBinomial(GetMemory().GetSize(), mut_rate);
-
-  for (int i = 0; i < num_muts; i++) {
-    const int pos = g_random.GetUInt(GetMemory().GetSize());
-    Mutate(pos);
-  }
-
-  return num_muts;
-}
-
-
-// Trigger mutations of a specific type.  Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardwareCPU::TriggerMutations(int trigger)
-{
-  // Only update triggers should happen from the outside!
-  assert(trigger == MUTATION_TRIGGER_UPDATE);
-
-  // Assume instruction pointer is the intended target (if one is even
-  // needed!
-
-  return TriggerMutations(trigger, IP());
-}
-
-bool cHardwareCPU::TriggerMutations(int trigger, cHeadCPU & cur_head)
-{
-  // Collect information about mutations from the organism.
-  cLocalMutations & mut_info = organism->GetLocalMutations();
-  const tList<cMutation> & mut_list =
-    mut_info.GetMutationLib().GetMutationList(trigger);
-
-  // If we have no mutations for this trigger, stop here.
-  if (mut_list.GetSize() == 0) return false;
-  bool has_mutation = false;
-
-  // Determine what memory this mutation will be affecting.
-  cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory();
-
-  // Loop through all mutations associated with this trigger and test them.
-  tConstListIterator<cMutation> mut_it(mut_list);
-
-  while (mut_it.Next() != NULL) {
-    const cMutation * cur_mut = mut_it.Get();
-    const int mut_id = cur_mut->GetID();
-    const int scope = cur_mut->GetScope();
-    const double rate = mut_info.GetRate(mut_id);
-    switch (scope) {
-    case MUTATION_SCOPE_GENOME:
-      if (TriggerMutations_ScopeGenome(cur_mut, target_mem, cur_head, rate)) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id);
-      }
-      break;
-    case MUTATION_SCOPE_LOCAL:
-    case MUTATION_SCOPE_PROP:
-      if (TriggerMutations_ScopeLocal(cur_mut, target_mem, cur_head, rate)) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id);
-      }
-      break;
-    case MUTATION_SCOPE_GLOBAL:
-    case MUTATION_SCOPE_SPREAD:
-      int num_muts =
-	TriggerMutations_ScopeGlobal(cur_mut, target_mem, cur_head, rate);
-      if (num_muts > 0) {
-	has_mutation = true;
-	mut_info.IncCount(mut_id, num_muts);
-      }
-      break;
-    }
-  }
-
-  return has_mutation;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
-{
-  // The rate we have stored indicates the probability that a single
-  // mutation will occur anywhere in the genome.
-  
-  if (g_random.P(rate) == true) {
-    // We must create a temporary head and use it to randomly determine the
-    // position in the genome to be mutated.
-    cHeadCPU tmp_head(cur_head);
-    tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
-    TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
-    return true;
-  }
-  return false;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
-{
-  // The rate we have stored is the probability for a mutation at this single
-  // position in the genome.
-
-  if (g_random.P(rate) == true) {
-    TriggerMutations_Body(cur_mut->GetType(), target_memory, cur_head);
-    return true;
-  }
-  return false;
-}
-
-int cHardwareCPU::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate)
-{
-  // The probability we have stored is per-site, so we can pull a random
-  // number from a binomial distribution to determine the number of mutations
-  // that should occur.
-
-  const int num_mut =
-    g_random.GetRandBinomial(target_memory.GetSize(), rate);
-
-  if (num_mut > 0) {
-    for (int i = 0; i < num_mut; i++) {
-      cHeadCPU tmp_head(cur_head);
-      tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
-      TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
-    }
-  }
-
-  return num_mut;
-}
-
-void cHardwareCPU::TriggerMutations_Body(int type, cCPUMemory & target_memory,
-					 cHeadCPU & cur_head)
-{
-  const int pos = cur_head.GetPosition();
-
-  switch (type) {
-  case MUTATION_TYPE_POINT:
-    target_memory[pos] = GetRandomInst();
-    target_memory.FlagMutated(pos) = true;
-    break;
-  case MUTATION_TYPE_INSERT:
-  case MUTATION_TYPE_DELETE:
-  case MUTATION_TYPE_HEAD_INC:
-  case MUTATION_TYPE_HEAD_DEC:
-  case MUTATION_TYPE_TEMP:
-  case MUTATION_TYPE_KILL:
-  default:
-    cout << "Error: Mutation type not implemented!" << endl;
-    break;
-  };
-}
-
-void cHardwareCPU::ReadInst(const int in_inst)
-{
-  if (inst_set->IsNop( cInstruction(in_inst) )) {
-    GetReadLabel().AddNop(in_inst);
-  } else {
-    GetReadLabel().Clear();
-  }
-}
-
-
-void cHardwareCPU::AdjustHeads()
-{
-  for (int i = 0; i < GetNumThreads(); i++) {
-    for (int j = 0; j < NUM_HEADS; j++) {
-      threads[i].heads[j].Adjust();
-    }
-  }
-}
-
-
-
-// This function looks at the current position in the info of a creature,
-// and sets the next_label to be the sequence of nops which follows.  The
-// instruction pointer is left on the last line of the label found.
-
-void cHardwareCPU::ReadLabel(int max_size)
-{
-  int count = 0;
-  cHeadCPU * inst_ptr = &( IP() );
-
-  GetLabel().Clear();
-
-  while (inst_set->IsNop(inst_ptr->GetNextInst()) &&
-	 (count < max_size)) {
-    count++;
-    inst_ptr->Advance();
-    GetLabel().AddNop(inst_set->GetNopMod(inst_ptr->GetInst()));
-
-    // If this is the first line of the template, mark it executed.
-    if (GetLabel().GetSize() <=	cConfig::GetMaxLabelExeSize()) {
-      inst_ptr->FlagExecuted() = true;
-    }
-  }
-}
-
-
-bool cHardwareCPU::ForkThread()
-{
-  const int num_threads = GetNumThreads();
-  if (num_threads == cConfig::GetMaxCPUThreads()) return false;
-
-  // Make room for the new thread.
-  threads.Resize(num_threads + 1);
-
-  // Initialize the new thread to the same values as the current one.
-  threads[num_threads] = threads[cur_thread];
-
-  // Find the first free bit in thread_id_chart to determine the new
-  // thread id.
-  int new_id = 0;
-  while ( (thread_id_chart >> new_id) & 1 == 1) new_id++;
-  threads[num_threads].SetID(new_id);
-  thread_id_chart |= (1 << new_id);
-
-  return true;
-}
-
-
-int cHardwareCPU::TestParasite() const
-{
-  return IP().TestParasite();
-}
-
-
-bool cHardwareCPU::KillThread()
-{
-  // Make sure that there is always at least one thread...
-  if (GetNumThreads() == 1) return false;
-
-  // Note the current thread and set the current back one.
-  const int kill_thread = cur_thread;
-  PrevThread();
-  
-  // Turn off this bit in the thread_id_chart...
-  thread_id_chart ^= 1 << threads[kill_thread].GetID();
-
-  // Copy the last thread into the kill position
-  const int last_thread = GetNumThreads() - 1;
-  if (last_thread != kill_thread) {
-    threads[kill_thread] = threads[last_thread];
-  }
-
-  // Kill the thread!
-  threads.Resize(GetNumThreads() - 1);
-
-  if (cur_thread > kill_thread) cur_thread--;
-
-  return true;
-}
-
-
-void cHardwareCPU::SaveState(ostream & fp)
-{
-  // note, memory & child_memory handled by cpu (@CAO Not any more!)
-  assert(fp.good());
-
-  fp<<"cHardwareCPU"<<endl;
-
-  // global_stack (in inverse order so load can just push)
-  global_stack.SaveState(fp);
-
-  fp << thread_time_used  << endl;
-  fp << GetNumThreads()   << endl;
-  fp << cur_thread        << endl;
-
-  // Threads
-  for( int i = 0; i < GetNumThreads(); i++ ) {
-    threads[i].SaveState(fp);
-  }
-}
-
-
-void cHardwareCPU::LoadState(istream & fp)
-{
-  // note, memory & child_memory handled by cpu (@CAO Not any more!)
-  assert(fp.good());
-
-  cString foo;
-  fp>>foo;
-  assert( foo == "cHardwareCPU" );
-
-  // global_stack
-  global_stack.LoadState(fp);
-
-  int num_threads;
-  fp >> thread_time_used;
-  fp >> num_threads;
-  fp >> cur_thread;
-
-  // Threads
-  for( int i = 0; i < num_threads; i++ ){
-    threads[i].LoadState(fp);
-  }
-}
-
-
-////////////////////////////
-//  Instruction Helpers...
-////////////////////////////
-
-inline int cHardwareCPU::FindModifiedRegister(int default_register)
-{
-  assert(default_register < NUM_REGISTERS);  // Reg ID too high.
-
-  if (GetInstSet().IsNop(IP().GetNextInst())) {
-    IP().Advance();
-    default_register = GetInstSet().GetNopMod(IP().GetInst());
-    IP().FlagExecuted() = true;
-  }
-  return default_register;
-}
-
-
-inline int cHardwareCPU::FindModifiedHead(int default_head)
-{
-  assert(default_head < NUM_HEADS); // Head ID too high.
-
-  if (GetInstSet().IsNop(IP().GetNextInst())) {
-    IP().Advance();
-    default_head = GetInstSet().GetNopMod(IP().GetInst());
-    IP().FlagExecuted() = true;
-  }
-  return default_head;
-}
-
-
-inline int cHardwareCPU::FindComplementRegister(int base_reg)
-{
-  const int comp_reg = base_reg + 1;
-  return (comp_reg  == NUM_REGISTERS) ? 0 : comp_reg;
-}
-
-
-inline void cHardwareCPU::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
-  organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-
-bool cHardwareCPU::Allocate_Necro(const int new_size)
-{
-  GetMemory().ResizeOld(new_size);
-  return true;
-}
-
-bool cHardwareCPU::Allocate_Random(const int old_size, const int new_size)
-{
-  GetMemory().Resize(new_size);
-
-  for (int i = old_size; i < new_size; i++) {
-    GetMemory()[i] = GetInstSet().GetRandomInst();
-  }
-  return true;
-}
-
-bool cHardwareCPU::Allocate_Default(const int new_size)
-{
-  GetMemory().Resize(new_size);
-
-  // New space already defaults to default instruction...
-
-  return true;
-}
-
-bool cHardwareCPU::Allocate_Main(const int allocated_size)
-{
-  // must do divide before second allocate & must allocate positive amount...
-  if (cConfig::GetRequireAllocate() && mal_active == true) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
-    return false;
-  }
-  if (allocated_size < 1) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate of %d too small", allocated_size));
-    return false;
-  }
-
-  const int old_size = GetMemory().GetSize();
-  const int new_size = old_size + allocated_size;
-
-  // Make sure that the new size is in range.
-  if (new_size > MAX_CREATURE_SIZE  ||  new_size < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Invalid post-allocate size (%d)",
-			       new_size));
-    return false;
-  }
-
-  const int max_alloc_size = (int) (old_size * cConfig::GetChildSizeRange());
-  if (allocated_size > max_alloc_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate too large (%d > %d)",
-			       allocated_size, max_alloc_size));
-    return false;
-  }
-
-  const int max_old_size =
-    (int) (allocated_size * cConfig::GetChildSizeRange());
-  if (old_size > max_old_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate too small (%d > %d)",
-			       old_size, max_old_size));
-    return false;
-  }
-
-  switch (cConfig::GetAllocMethod()) {
-  case ALLOC_METHOD_NECRO:
-    // Only break if this succeeds -- otherwise just do random.
-    if (Allocate_Necro(new_size) == true) break;
-  case ALLOC_METHOD_RANDOM:
-    Allocate_Random(old_size, new_size);
-    break;
-  case ALLOC_METHOD_DEFAULT:
-    Allocate_Default(new_size);
-    break;
-  }
-
-  mal_active = true;
-
-  return true;
-}
-
-
-bool cHardwareCPU::Divide_CheckViable(const int child_size,
-				      const int parent_size)
-{
-  // Make sure the organism is okay with dividing now...
-  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
-  // If required, make sure an allocate has occured.
-  if (cConfig::GetRequireAllocate() && mal_active == false) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, "Must allocate before divide");
-    return false; //  (divide fails)
-  }
-
-  // Make sure that neither parent nor child will be below the minimum size.
-
-  const int genome_size = organism->GetGenome().GetSize();
-  const double size_range = cConfig::GetChildSizeRange();
-  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
-  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-  
-  if (child_size < min_size || child_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
-    return false; // (divide fails)
-  }
-  if (parent_size < min_size || parent_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
-    return false; // (divide fails)
-  }
-
-  // Count the number of lines executed in the parent, and make sure the
-  // specified fraction has been reached.
-
-  int executed_size = 0;
-  for (int i = 0; i < parent_size; i++) {
-    if (GetMemory().FlagExecuted(i)) executed_size++;
-  }
-
-  const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
-  if (executed_size < min_exe_lines) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Too few executed lines (%d < %d)",
-			       executed_size, min_exe_lines));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines which were copied into the child, and make
-  // sure the specified fraction has been reached.
-
-  int copied_size = 0;
-  for (int i = parent_size; i < parent_size + child_size; i++) {
-    if (GetMemory().FlagCopied(i)) copied_size++;
-  }
-
-  const int min_copied =  (int) (child_size * cConfig::GetMinCopiedLines());
-  if (copied_size < min_copied) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Too few copied commands (%d < %d)",
-			       copied_size, min_copied));
-    return false; // (divide fails)
-  }
-
-  // Save the information we collected here...
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.SetLinesExecuted(executed_size);
-  phenotype.SetLinesCopied(copied_size);
-
-  // Determine the fitness of this organism as compared to its parent...
-  if (cConfig::GetTestSterilize() == true &&
-      phenotype.IsInjected() == false) {
-    const int merit_base =
-      cPhenotype::CalcSizeMerit(genome_size, copied_size, executed_size);
-    const double cur_fitness =
-      merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
-    const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
-
-
-    //  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
-    //  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
-  
-    bool sterilize = false;
-  
-    if (fitness_ratio < FITNESS_NEUTRAL_MIN) {
-      if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
-    } else if (fitness_ratio <= FITNESS_NEUTRAL_MAX) {
-      if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
-    } else {
-      if (g_random.P(organism->GetSterilizePos())) sterilize = true;
-    }
-  
-//     cout << "[ min(" << genome_size
-// 	 << "," << copied_size
-// 	 << "," << executed_size
-// 	 << ") * " << phenotype.GetCurBonus()
-// 	 << " / " << phenotype.GetTimeUsed()
-// 	 << "] / " << phenotype.GetLastFitness()
-// 	 << " == " << fitness_ratio;
-
-    if (sterilize == true) {
-      //Don't let this organism have this or any more children!
-      phenotype.IsFertile() = false;
-      return false;
-    }    
-  }
-
-  return true; // (divide succeeds!)
-}
-
-
-void cHardwareCPU::Divide_DoMutations(double mut_multiplier)
-{
-  sCPUStats & cpu_stats = organism->CPUStats();
-  cCPUMemory & child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-
-  // Divide Mutations
-  if (organism->TestDivideMut()) {
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
-    child_genome[mut_line] = GetRandomInst();
-    cpu_stats.mut_stats.divide_mut_count++;
-  }
-
-  // Divide Insertions
-  if (organism->TestDivideIns() && child_genome.GetSize() < MAX_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize() + 1);
-    child_genome.Insert(mut_line, GetRandomInst());
-    cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-
-  // Divide Deletions
-  if (organism->TestDivideDel() && child_genome.GetSize() > MIN_CREATURE_SIZE){
-    const UINT mut_line = g_random.GetUInt(child_genome.GetSize());
-    // if( child_genome.FlagCopied(mut_line) == true) copied_size_change--;
-    child_genome.Remove(mut_line);
-    cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(), 
-				   	   organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-	int site = g_random.GetUInt(child_genome.GetSize());
-	child_genome[site]=GetRandomInst();
-	cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-
-
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
-					   organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-	mut_sites[i] = g_random.GetUInt(child_genome.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-	child_genome.Insert(mut_sites[i], GetRandomInst());
-	cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-
-
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = g_random.GetRandBinomial(child_genome.GetSize(),
-					   organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
-    }
-
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = g_random.GetUInt(child_genome.GetSize());
-      // if (child_genome.FlagCopied(site) == true) copied_size_change--;
-      child_genome.Remove(site);
-      cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
-      if (organism->TestParentMut()) {
-	GetMemory()[i] = GetRandomInst();
-	cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-
-
-  // Count up mutated lines
-  for(int i = 0; i < GetMemory().GetSize(); i++){
-    if (GetMemory().FlagPointMut(i) == true) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < child_genome.GetSize(); i++){
-    if( child_genome.FlagCopyMut(i) == true) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-  }
-}
-
-
-// test whether the offspring creature contains an advantageous mutation.
-void cHardwareCPU::Divide_TestFitnessMeasures()
-{
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
-  phenotype.ChildFertile() = true;
-
-  // Only continue if we're supposed to do a fitness test on divide...
-  if (organism->GetTestOnDivide() == false) return;
-
-  // If this was a perfect copy, then we don't need to worry about any other
-  // tests...  Theoretically, we need to worry about the parent changing,
-  // but as long as the child is always compared to the original genotype,
-  // this won't be an issue.
-  if (phenotype.CopyTrue() == true) return;
-
-  const double parent_fitness = organism->GetTestFitness();
-  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
-  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
-  
-  cCPUTestInfo test_info;
-  test_info.UseRandomInputs();
-  cTestCPU::TestGenome(test_info, organism->ChildGenome());
-  const double child_fitness = test_info.GetGenotypeFitness();
-  
-  bool revert = false;
-  bool sterilize = false;
-  
-  // If implicit mutations are turned off, make sure this won't spawn one.
-  if (organism->GetFailImplicit() == true) {
-    if (test_info.GetMaxDepth() > 0) sterilize = true;
-  }
-  
-  if (child_fitness == 0.0) {
-    // Fatal mutation... test for reversion.
-    if (g_random.P(organism->GetRevertFatal())) revert = true;
-    if (g_random.P(organism->GetSterilizeFatal())) sterilize = true;
-  } else if (child_fitness < neut_min) {
-    if (g_random.P(organism->GetRevertNeg())) revert = true;
-    if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
-  } else if (child_fitness <= neut_max) {
-    if (g_random.P(organism->GetRevertNeut())) revert = true;
-    if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
-  } else {
-    if (g_random.P(organism->GetRevertPos())) revert = true;
-    if (g_random.P(organism->GetSterilizePos())) sterilize = true;
-  }
-  
-  // Ideally, we won't have reversions and sterilizations turned on at the
-  // same time, but if we do, give revert the priority.
-  if (revert == true) {
-    organism->ChildGenome() = organism->GetGenome();
-  }
-
-  if (sterilize == true) {
-    organism->GetPhenotype().ChildFertile() = false;
-  }
-}
-
-
-bool cHardwareCPU::Divide_Main(const int div_point, const int extra_lines, double mut_multiplier)
-{
-  const int child_size = GetMemory().GetSize() - div_point - extra_lines;
-
-  // Make sure this divide will produce a viable offspring.
-  const bool viable = Divide_CheckViable(child_size, div_point);
-  if (viable == false) return false;
-
-  // Since the divide will now succeed, set up the information to be sent
-  // to the new organism
-  cGenome & child_genome = organism->ChildGenome();
-  child_genome = cGenomeUtil::Crop(memory, div_point, div_point+child_size);
-
-  // Cut off everything in this memory past the divide point.
-  GetMemory().Resize(div_point);
-
-  // Handle Divide Mutations...
-  Divide_DoMutations(mut_multiplier);
-
-  // 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
-
-  mal_active = false;
-  if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) {
-    advance_ip = false;
-  }
-
-  // Activate the child, and do more work if the parent lives through the
-  // birth.
-  bool parent_alive = organism->ActivateDivide();
-  if (parent_alive) {
-    if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) Reset();
-  }
-
-  return true;
-}
-
-
-//////////////////////////
-// And the instructions...
-//////////////////////////
-
-bool cHardwareCPU::Inst_If0()          // Execute next if ?bx? ==0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) != 0)  IP().Advance();
-  return true; 
-}
-
-bool cHardwareCPU::Inst_IfNot0()       // Execute next if ?bx? != 0.
-{ 
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) == 0)  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfEqu()      // 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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfNEqu()     // 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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfGr0()       // Execute next if ?bx? ! < 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) <= 0)  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfGr()       // 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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfGrEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) < 0)  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfLess0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) >= 0)  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfLess()       // 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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfLsEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) > 0) IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::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();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfBit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if ((Register(reg_used) & 1) == 0)  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfANotEqB()     // Execute next if AX != BX
-{
-  if (Register(REG_AX) == Register(REG_BX) )  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfBNotEqC()     // Execute next if BX != CX
-{
-  if (Register(REG_BX) == Register(REG_CX) )  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfANotEqC()     // Execute next if AX != BX
-{
-  if (Register(REG_AX) == Register(REG_CX) )  IP().Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_JumpF()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-
-  // 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 cHeadCPU 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;
-}
-
-
-bool cHardwareCPU::Inst_JumpB()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    GetActiveHead().Jump(-Register(REG_BX));
-    return true;
-  }
-
-  // otherwise jump to the complement label.
-  const cHeadCPU 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-b: No complement label");
-  return false;
-}
-
-bool cHardwareCPU::Inst_JumpP()
-{
-  cOrganism * other_organism = organism->GetNeighbor();
-
-  // 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;
-  }
-
-  // Otherwise, grab the hardware from the neighbor, and use it!
-  cHardwareCPU & other_hardware = (cHardwareCPU &) other_organism->GetHardware();
-
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-
-  // 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 cHeadCPU jump_location(other_hardware.FindFullLabel(GetLabel()));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
-
-  // 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 cHardwareCPU::Inst_JumpSelf()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-
-  // 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 cHeadCPU 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 cHardwareCPU::Inst_Call()
-{
-  // Put the starting location onto the stack
-  const int location = IP().GetPosition();
-  StackPush(location);
-
-  // Jump to the compliment label (or by the ammount in the bx register)
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-
-  if (GetLabel().GetSize() == 0) {
-    IP().Jump(Register(REG_BX));
-    return true;
-  }
-
-  const cHeadCPU 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,
-		  "call: no complement label");
-  return false;
-}
-
-bool cHardwareCPU::Inst_Return()
-{
-  IP().Set(StackPop());
-  return true;
-}
-
-bool cHardwareCPU::Inst_Pop()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = StackPop();
-  return true;
-}
-
-bool cHardwareCPU::Inst_Push()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  StackPush(Register(reg_used));
-  return true;
-}
-
-bool cHardwareCPU::Inst_HeadPop()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(StackPop(), this);
-  return true;
-}
-
-bool cHardwareCPU::Inst_HeadPush()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  StackPush(GetHead(head_used).GetPosition());
-  if (head_used == HEAD_IP) {
-    GetHead(head_used).Set(GetHead(HEAD_FLOW));
-    advance_ip = false;
-  }
-  return true;
-}
-
-
-bool cHardwareCPU::Inst_PopA() { Register(REG_AX) = StackPop(); return true;}
-bool cHardwareCPU::Inst_PopB() { Register(REG_BX) = StackPop(); return true;}
-bool cHardwareCPU::Inst_PopC() { Register(REG_CX) = StackPop(); return true;}
-
-bool cHardwareCPU::Inst_PushA() { StackPush(Register(REG_AX)); return true;}
-bool cHardwareCPU::Inst_PushB() { StackPush(Register(REG_BX)); return true;}
-bool cHardwareCPU::Inst_PushC() { StackPush(Register(REG_CX)); return true;}
-
-bool cHardwareCPU::Inst_SwitchStack() { SwitchStack(); return true;}
-bool cHardwareCPU::Inst_FlipStack()   { StackFlip(); return true;}
-
-bool cHardwareCPU::Inst_Swap()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int other_reg = FindComplementRegister(reg_used);
-//  cout << endl; 
-//  cout << "Regs 1, 2, 3 are: " << Register(1) << " " << Register(2) << " " << Register(3) << endl; 
-//  cout << "Modified reg = " << reg_used << ", Complement reg = " << other_reg << endl; 
-//  cout << "Calling Swap with " << Register(reg_used) << " and " << Register(other_reg) << endl; 
-  nFunctions::Swap(Register(reg_used), Register(other_reg));
-//  cout << "Current State is " << Register(reg_used) << " and " << Register(other_reg) << endl; 
-//  cout << "Regs 1, 2, 3 are: " << Register(1) << " " << Register(2) << " " << Register(3) << endl; 
-  return true;
-}
-
-bool cHardwareCPU::Inst_SwapAB() { nFunctions::Swap(Register(REG_AX), Register(REG_BX)); return true; }
-bool cHardwareCPU::Inst_SwapBC() { nFunctions::Swap(Register(REG_BX), Register(REG_CX)); return true; }
-bool cHardwareCPU::Inst_SwapAC() { nFunctions::Swap(Register(REG_AX), Register(REG_CX)); return true; }
-
-bool cHardwareCPU::Inst_CopyReg()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int other_reg = FindComplementRegister(reg_used);
-  Register(other_reg) = Register(reg_used);
-  return true;
-}
-
-bool cHardwareCPU::Inst_CopyRegAB() { Register(REG_AX) = Register(REG_BX);   return true;
-}
-bool cHardwareCPU::Inst_CopyRegAC() { Register(REG_AX) = Register(REG_CX);   return true;
-}
-bool cHardwareCPU::Inst_CopyRegBA() { Register(REG_BX) = Register(REG_AX);   return true;
-}
-bool cHardwareCPU::Inst_CopyRegBC() { Register(REG_BX) = Register(REG_CX);   return true;
-}
-bool cHardwareCPU::Inst_CopyRegCA() { Register(REG_CX) = Register(REG_AX);   return true;
-}
-bool cHardwareCPU::Inst_CopyRegCB() { Register(REG_CX) = Register(REG_BX);   return true;
-}
-
-bool cHardwareCPU::Inst_Reset()
-{
-  Register(REG_AX) = 0;
-  Register(REG_BX) = 0;
-  Register(REG_CX) = 0;
-  StackClear();
-  return true;
-}
-
-bool cHardwareCPU::Inst_ShiftR()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) >>= 1;
-  return true;
-}
-
-bool cHardwareCPU::Inst_ShiftL()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) <<= 1;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Bit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) |=  1;
-  return true;
-}
-
-bool cHardwareCPU::Inst_SetNum()
-{
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsInt(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_ValGrey(void) {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsIntGreyCode(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_ValDir(void) {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsIntDirect(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_ValAddP(void) {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsIntAdditivePolynomial(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_ValFib(void) {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsIntFib(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_ValPolyC(void) {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsIntPolynomialCoefficent(NUM_NOPS);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Inc()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) += 1;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Dec()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) -= 1;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Zero()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Neg()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0-Register(reg_used);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Square()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(reg_used) * Register(reg_used);
-  return true;
-}
-
-bool cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::Inst_Minus17()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) -= 17;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Add()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) + Register(REG_CX);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Sub()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) - Register(REG_CX);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Mult()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) * Register(REG_CX);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Div()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(REG_CX) != 0) {
-    if (0-INT_MAX > Register(REG_BX) && Register(REG_CX) == -1)
-      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
-    else
-      Register(reg_used) = Register(REG_BX) / Register(REG_CX);
-  } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
-    return false;
-  }
-  return true;
-}
-
-bool cHardwareCPU::Inst_Mod()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(REG_CX) != 0) {
-    Register(reg_used) = Register(REG_BX) % Register(REG_CX);
-  } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
-  return false;
-  }
-  return true;
-}
-
-
-bool cHardwareCPU::Inst_Nand()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(REG_BX) & Register(REG_CX));
-  return true;
-}
-
-bool cHardwareCPU::Inst_Nor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(REG_BX) | Register(REG_CX));
-  return true;
-}
-
-bool cHardwareCPU::Inst_And()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = (Register(REG_BX) & Register(REG_CX));
-  return true;
-}
-
-bool cHardwareCPU::Inst_Not()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(reg_used));
-  return true;
-}
-
-bool cHardwareCPU::Inst_Order()
-{
-  if (Register(REG_BX) > Register(REG_CX)) {
-    nFunctions::Swap(Register(REG_BX), Register(REG_CX));
-  }
-  return true;
-}
-
-bool cHardwareCPU::Inst_Xor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) ^ Register(REG_CX);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Copy()
-{
-  const cHeadCPU from(this, Register(REG_BX));
-  cHeadCPU 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 cHardwareCPU::Inst_ReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const cHeadCPU 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 cHardwareCPU::Inst_WriteInst()
-{
-  cHeadCPU 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 cHardwareCPU::Inst_StackReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  cHeadCPU from(this, Register(reg_used));
-  StackPush(from.GetInst().GetOp());
-  return true;
-}
-
-bool cHardwareCPU::Inst_StackWriteInst()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  cHeadCPU 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 cHardwareCPU::Inst_Compare()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  cHeadCPU from(this, Register(REG_BX));
-  cHeadCPU 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 cHardwareCPU::Inst_IfNCpy()
-{
-  const cHeadCPU from(this, Register(REG_BX));
-  const cHeadCPU 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 cHardwareCPU::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 cHardwareCPU::Inst_Divide()  
-{ 
-  return Divide_Main(Register(REG_AX));    
-}
-
-bool cHardwareCPU::Inst_CDivide() 
-{ 
-  return Divide_Main(GetMemory().GetSize() / 2);   
-}
-
-bool cHardwareCPU::Inst_CAlloc()  
-{ 
-  return Allocate_Main(GetMemory().GetSize());   
-}
-
-bool cHardwareCPU::Inst_MaxAlloc()   // Allocate maximal more
-{
-  const int cur_size = GetMemory().GetSize();
-  const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
-			     MAX_CREATURE_SIZE - cur_size);
-  if( Allocate_Main(alloc_size) ) {
-    Register(REG_AX) = cur_size;
-    return true;
-  } else return false;
-}
-
-
-bool cHardwareCPU::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;
-}
-
-
-bool cHardwareCPU::Inst_Kazi()
-{
-	const int reg_used = FindModifiedRegister(REG_AX);
-	int percentProb = Register(reg_used) % 100;
-	int random = abs(rand()) % 100;
-	if (random >= percentProb)
-	{
-		return true;
-	}
-	else
-	{
-		organism->Kaboom();
-		return true;
-	}
-}
-
-bool cHardwareCPU::Inst_Die()
-{
-   const double die_prob = cConfig::GetDieProb();
-   if(g_random.GetDouble() < die_prob) { organism->Die(); }
-   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 cHardwareCPU::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(1, NUM_NOPS);
-
-  const bool inject_signal = host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
-  if (inject_signal) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
-    return false; // Inject failed.
-  }
-
-  // Set the relevent flags.
-  organism->GetPhenotype().IsModifier() = true;
-
-  return inject_signal;
-}
-
-
-bool cHardwareCPU::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 cHardwareCPU::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(1, NUM_NOPS);
-
-  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 cHardwareCPU::Inst_TaskGet()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = organism->GetNextInput();
-  Register(reg_used) = value;
-  organism->DoInput(value);
-  return true;
-}
-
-bool cHardwareCPU::Inst_TaskStackGet()
-{
-  const int value = organism->GetNextInput();
-  StackPush(value);
-  organism->DoInput(value);
-  return true;
-}
-
-bool cHardwareCPU::Inst_TaskStackLoad()
-{
-  for (int i = 0; i < IO_SIZE; i++) 
-    StackPush( organism->GetNextInput() );
-  return true;
-}
-
-bool cHardwareCPU::Inst_TaskPut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  Register(reg_used) = 0;
-  organism->DoOutput(value);
-  return true;
-}
-
-bool cHardwareCPU::Inst_TaskIO()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-
-  // Do the "put" component
-  const int value_out = Register(reg_used);
-  organism->DoOutput(value_out);  // Check for tasks compleated.
-
-  // Do the "get" component
-  const int value_in = organism->GetNextInput();
-  Register(reg_used) = value_in;
-  organism->DoInput(value_in);
-  return true;
-}
-
-bool cHardwareCPU::Inst_Send()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  organism->SendValue(Register(reg_used));
-  Register(reg_used) = 0;
-  return true;
-}
-
-bool cHardwareCPU::Inst_Receive()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = organism->ReceiveValue();
-  return true;
-}
-
-bool cHardwareCPU::Inst_Sense()
-{
-  const tArray<double> & res_count = organism->PopInterface().GetResources();
-  const int reg_used = FindModifiedRegister(REG_BX);
-
-  // If there are no resources to measure, this instruction fails.
-  if (res_count.GetSize() == 0) return false;
-
-  // Always get the first resource, and convert it to and int.
-  Register(reg_used) = (int) res_count[0];
-
-  // @CAO Since resources are sometimes less than one, perhaps we should
-  // multiply it by some constant?  Or perhaps taking the log would be more
-  // useful so they can easily scan across orders of magnitude?
-
-  return true;
-}
-
-void cHardwareCPU::DoDonate(cOrganism * to_org)
-{
-  assert(to_org != NULL);
-
-  const double merit_given = cConfig::GetMeritGiven();
-  const double merit_received = cConfig::GetMeritReceived();
-
-  double cur_merit = organism->GetPhenotype().GetMerit().GetDouble();
-  cur_merit -= merit_given; 
-
-  // Plug the current merit back into this organism and notify the scheduler.
-  organism->UpdateMerit(cur_merit);
-
-  // Update the merit of the organism being donated to...
-  double other_merit = to_org->GetPhenotype().GetMerit().GetDouble();
-  other_merit += merit_received;
-  to_org->UpdateMerit(other_merit);
-}
-
-bool cHardwareCPU::Inst_DonateRandom()
-{
-  organism->GetPhenotype().IncDonates();
-  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
-    return false;
-  }
-
-  // Turn to a random neighbor, get it, and turn back...
-  int neighbor_id = g_random.GetInt(organism->GetNeighborhoodSize());
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
-  cOrganism * neighbor = organism->GetNeighbor();
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
-
-  // Donate only if we have found a neighbor.
-  if (neighbor != NULL) DoDonate(neighbor);
-  
-  return true;
-}
-
-
-bool cHardwareCPU::Inst_DonateKin()
-{
-  organism->GetPhenotype().IncDonates();
-  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
-    return false;
-  }
-
-  // Find the target as the first Kin found in the neighborhood.
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-  // Turn to face a random neighbor
-  int neighbor_id = g_random.GetInt(num_neighbors);
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
-  cOrganism * neighbor = organism->GetNeighbor();
-
-  // If there is no max distance, just take the random neighbor we're facing.
-  const int max_dist = cConfig::GetMaxDonateKinDistance();
-  if (max_dist != -1) {
-    int max_id = neighbor_id + num_neighbors;
-    bool found = false;
-    cGenotype * genotype = organism->GetGenotype();
-    while (neighbor_id < max_id) {
-      neighbor = organism->GetNeighbor();
-      if (neighbor != NULL &&
-	  genotype->GetPhyloDistance(neighbor->GetGenotype()) <= max_dist) {
-	found = true;
-	break;
-      }
-      organism->Rotate(1);
-      neighbor_id++;
-    }
-    if (found == false) neighbor = NULL;
-  }
-
-  // Put the facing back where it was.
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
-
-  // Donate only if we have found a close enough relative...
-  if (neighbor != NULL)  DoDonate(neighbor);
-
-  return true;
-}
-
-bool cHardwareCPU::Inst_DonateEditDist()
-{
-  organism->GetPhenotype().IncDonates();
-  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
-    return false;
-  }
-
-  // Find the target as the first Kin found in the neighborhood.
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-  // Turn to face a random neighbor
-  int neighbor_id = g_random.GetInt(num_neighbors);
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(1);
-  cOrganism * neighbor = organism->GetNeighbor();
-
-  // If there is no max edit distance, take the random neighbor we're facing.
-  const int max_dist = cConfig::GetMaxDonateEditDistance();
-  if (max_dist != -1) {
-    int max_id = neighbor_id + num_neighbors;
-    bool found = false;
-    while (neighbor_id < max_id) {
-      neighbor = organism->GetNeighbor();
-      int edit_dist = max_dist + 1;
-      if (neighbor != NULL) {
-	edit_dist = cGenomeUtil::FindEditDistance(organism->GetGenome(),
-						  neighbor->GetGenome());
-      }
-      if (edit_dist <= max_dist) {
-	found = true;
-	break;
-      }
-      organism->Rotate(1);
-      neighbor_id++;
-    }
-    if (found == false) neighbor = NULL;
-  }
-
-  // Put the facing back where it was.
-  for (int i = 0; i < neighbor_id; i++) organism->Rotate(-1);
-
-  // Donate only if we have found a close enough relative...
-  if (neighbor != NULL)  DoDonate(neighbor);
-
-  return true;
-}
-
-
-bool cHardwareCPU::Inst_DonateNULL()
-{
-  organism->GetPhenotype().IncDonates();
-  if (organism->GetPhenotype().GetCurNumDonates() > cConfig::GetMaxDonates()) {
-    return false;
-  }
-
-  // This is a fake donate command that causes the organism to lose merit,
-  // but no one else to gain any.
-
-  const double merit_given = cConfig::GetMeritGiven();
-  double cur_merit = organism->GetPhenotype().GetMerit().GetDouble();
-  cur_merit -= merit_given;
-
-  // Plug the current merit back into this organism and notify the scheduler.
-  organism->UpdateMerit(cur_merit);
-
-  return true;
-}
-
-
-bool cHardwareCPU::Inst_SearchF()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  const int search_size = FindLabel(1).GetPosition() - IP().GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardwareCPU::Inst_SearchB()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  const int search_size = IP().GetPosition() - FindLabel(-1).GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardwareCPU::Inst_MemSize()
-{
-  Register(FindModifiedRegister(REG_BX)) = GetMemory().GetSize();
-  return true;
-}
-
-
-bool cHardwareCPU::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(1, NUM_NOPS);
-  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.
-      cHardwareCPU & cur_hardware = (cHardwareCPU &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(-1);
-  }
-  return true;
-}
-
-bool cHardwareCPU::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(1, NUM_NOPS);
-  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.
-      cHardwareCPU & cur_hardware = (cHardwareCPU &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(1);
-  }
-  return true;
-}
-
-bool cHardwareCPU::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 cHardwareCPU::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 cHardwareCPU::Inst_ForkThread()
-{
-  IP().Advance();
-  if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
-  return true;
-}
-
-bool cHardwareCPU::Inst_KillThread()
-{
-  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
-  else advance_ip = false;
-  return true;
-}
-
-bool cHardwareCPU::Inst_ThreadID()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = GetCurThreadID();
-  return true;
-}
-
-
-// Head-based instructions
-
-bool cHardwareCPU::Inst_SetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  SetActiveHead(head_used);
-  return true;
-}
-
-bool cHardwareCPU::Inst_AdvanceHead()
-{
-  const int head_used = FindModifiedHead(HEAD_WRITE);
-  GetHead(head_used).Advance();
-  return true;
-}
- 
-bool cHardwareCPU::Inst_MoveHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  if (head_used == HEAD_IP) advance_ip = false;
-  return true;
-}
-
-bool cHardwareCPU::Inst_JumpHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Jump( Register(REG_CX) );
-  return true;
-}
-
-bool cHardwareCPU::Inst_GetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  Register(REG_CX) = GetHead(head_used).GetPosition();
-  return true;
-}
-
-bool cHardwareCPU::Inst_IfLabel()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  if (GetLabel() != GetReadLabel())  IP().Advance();
-  return true;
-}
-
-// This is a variation on IfLabel that will skip the next command if the "if"
-// is false, but it will also skip all nops following that command.
-bool cHardwareCPU::Inst_IfLabel2()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  if (GetLabel() != GetReadLabel()) {
-    IP().Advance();
-    if (inst_set->IsNop( IP().GetNextInst() ))  IP().Advance();
-  }
-  return true;
-}
-
-bool cHardwareCPU::Inst_HeadDivideMut(double mut_multiplier)
-{
-  AdjustHeads();
-  const int divide_pos = GetHead(HEAD_READ).GetPosition();
-  int child_end =  GetHead(HEAD_WRITE).GetPosition();
-  if (child_end == 0) child_end = GetMemory().GetSize();
-  const int extra_lines = GetMemory().GetSize() - child_end;
-  bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
-  // Re-adjust heads.
-  AdjustHeads();
-  return ret_val; 
-}
-
-bool cHardwareCPU::Inst_HeadDivide()
-{
-  return Inst_HeadDivideMut(1);
-}
-
-bool cHardwareCPU::Inst_HeadDivideSex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(true);
-  organism->GetPhenotype().SetCrossNum(1);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardwareCPU::Inst_HeadDivideAsex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(false);
-  organism->GetPhenotype().SetCrossNum(0);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardwareCPU::Inst_HeadDivideAsexWait()  
-{ 
-  organism->GetPhenotype().SetDivideSex(true);
-  organism->GetPhenotype().SetCrossNum(0);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardwareCPU::Inst_HeadDivideMateSelect()  
-{ 
-  // Take the label that follows this divide and use it as the ID for which
-  // other organisms this one is willing to mate with.
-  ReadLabel();
-  organism->GetPhenotype().SetMateSelectID( GetLabel().AsInt(NUM_NOPS) );
-
-//   int mate_id = GetLabel().AsInt(NUM_NOPS);
-//   if (mate_id > 0) cout << mate_id << " "
-// 			<< GetLabel().AsString() << endl;
-
-  // Proceed as normal with the rest of mate selection.
-  organism->GetPhenotype().SetDivideSex(true);
-  organism->GetPhenotype().SetCrossNum(1);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardwareCPU::Inst_HeadDivide1()  { return Inst_HeadDivideMut(1); }
-bool cHardwareCPU::Inst_HeadDivide2()  { return Inst_HeadDivideMut(2); }
-bool cHardwareCPU::Inst_HeadDivide3()  { return Inst_HeadDivideMut(3); }
-bool cHardwareCPU::Inst_HeadDivide4()  { return Inst_HeadDivideMut(4); }
-bool cHardwareCPU::Inst_HeadDivide5()  { return Inst_HeadDivideMut(5); }
-bool cHardwareCPU::Inst_HeadDivide6()  { return Inst_HeadDivideMut(6); }
-bool cHardwareCPU::Inst_HeadDivide7()  { return Inst_HeadDivideMut(7); }
-bool cHardwareCPU::Inst_HeadDivide8()  { return Inst_HeadDivideMut(8); }
-bool cHardwareCPU::Inst_HeadDivide9()  { return Inst_HeadDivideMut(9); }
-bool cHardwareCPU::Inst_HeadDivide10()  { return Inst_HeadDivideMut(10); }
-bool cHardwareCPU::Inst_HeadDivide16()  { return Inst_HeadDivideMut(16); }
-bool cHardwareCPU::Inst_HeadDivide32()  { return Inst_HeadDivideMut(32); }
-bool cHardwareCPU::Inst_HeadDivide50()  { return Inst_HeadDivideMut(50); }
-bool cHardwareCPU::Inst_HeadDivide100()  { return Inst_HeadDivideMut(100); }
-bool cHardwareCPU::Inst_HeadDivide500()  { return Inst_HeadDivideMut(500); }
-bool cHardwareCPU::Inst_HeadDivide1000()  { return Inst_HeadDivideMut(1000); }
-bool cHardwareCPU::Inst_HeadDivide5000()  { return Inst_HeadDivideMut(5000); }
-bool cHardwareCPU::Inst_HeadDivide10000()  { return Inst_HeadDivideMut(10000); }
-bool cHardwareCPU::Inst_HeadDivide50000()  { return Inst_HeadDivideMut(50000); }
-bool cHardwareCPU::Inst_HeadDivide0_5()  { return Inst_HeadDivideMut(0.5); }
-bool cHardwareCPU::Inst_HeadDivide0_1()  { return Inst_HeadDivideMut(0.1); }
-bool cHardwareCPU::Inst_HeadDivide0_05()  { return Inst_HeadDivideMut(0.05); }
-bool cHardwareCPU::Inst_HeadDivide0_01()  { return Inst_HeadDivideMut(0.01); }
-bool cHardwareCPU::Inst_HeadDivide0_001()  { return Inst_HeadDivideMut(0.001); }
-
-bool cHardwareCPU::Inst_HeadRead()
-{
-  const int head_id = FindModifiedHead(HEAD_READ);
-  GetHead(head_id).Adjust();
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Mutations only occur on the read, for the moment.
-  int read_inst = 0;
-  if (organism->TestCopyMut()) {
-    read_inst = GetRandomInst().GetOp();
-    cpu_stats.mut_stats.copy_mut_count++;  // @CAO, hope this is good!
-  } else {
-    read_inst = GetHead(head_id).GetInst().GetOp();
-  }
-  Register(REG_BX) = read_inst;
-  ReadInst(read_inst);
-
-  cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
-  GetHead(head_id).Advance();
-  return true;
-}
-
-bool cHardwareCPU::Inst_HeadWrite()
-{
-  const int head_id = FindModifiedHead(HEAD_WRITE);
-  cHeadCPU & active_head = GetHead(head_id);
-
-  active_head.Adjust();
-
-  int value = Register(REG_BX);
-  if (value < 0 || value >= GetNumInst()) value = 0;
-
-  active_head.SetInst(cInstruction(value));
-  active_head.FlagCopied() = true;
-
-  // Advance the head after write...
-  active_head++;
-  return true;
-}
-
-bool cHardwareCPU::Inst_HeadCopy()
-{
-  // For the moment, this cannot be nop-modified.
-  cHeadCPU & read_head = GetHead(HEAD_READ);
-  cHeadCPU & write_head = GetHead(HEAD_WRITE);
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  read_head.Adjust();
-  write_head.Adjust();
-
-  // TriggerMutations(MUTATION_TRIGGER_READ, read_head);
-  
-  // Do mutations.
-  cInstruction read_inst = read_head.GetInst();
-  ReadInst(read_inst.GetOp());
-  if (organism->TestCopyMut()) {
-    read_inst = GetRandomInst();
-    cpu_stats.mut_stats.copy_mut_count++; 
-    write_head.FlagMutated() = true;
-    write_head.FlagCopyMut() = true;
-    //organism->GetPhenotype().IsMutated() = true;
-  }
-
-  cpu_stats.mut_stats.copies_exec++;
-
-  write_head.SetInst(read_inst);
-  write_head.FlagCopied() = true;  // Set the copied flag...
-
-  // TriggerMutations(MUTATION_TRIGGER_WRITE, write_head);
-
-  read_head.Advance();
-  write_head.Advance();
-  return true;
-}
-
-bool cHardwareCPU::HeadCopy_ErrorCorrect(double reduction)
-{
-  // For the moment, this cannot be nop-modified.
-  cHeadCPU & read_head = GetHead(HEAD_READ);
-  cHeadCPU & write_head = GetHead(HEAD_WRITE);
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  read_head.Adjust();
-  write_head.Adjust();
-
-  // Do mutations.
-  cInstruction read_inst = read_head.GetInst();
-  ReadInst(read_inst.GetOp());
-  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;
-  }
-
-  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 cHardwareCPU::Inst_HeadCopy2()  { return HeadCopy_ErrorCorrect(2); }
-bool cHardwareCPU::Inst_HeadCopy3()  { return HeadCopy_ErrorCorrect(3); }
-bool cHardwareCPU::Inst_HeadCopy4()  { return HeadCopy_ErrorCorrect(4); }
-bool cHardwareCPU::Inst_HeadCopy5()  { return HeadCopy_ErrorCorrect(5); }
-bool cHardwareCPU::Inst_HeadCopy6()  { return HeadCopy_ErrorCorrect(6); }
-bool cHardwareCPU::Inst_HeadCopy7()  { return HeadCopy_ErrorCorrect(7); }
-bool cHardwareCPU::Inst_HeadCopy8()  { return HeadCopy_ErrorCorrect(8); }
-bool cHardwareCPU::Inst_HeadCopy9()  { return HeadCopy_ErrorCorrect(9); }
-bool cHardwareCPU::Inst_HeadCopy10() { return HeadCopy_ErrorCorrect(10); }
-
-bool cHardwareCPU::Inst_HeadSearch()
-{
-  ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  cHeadCPU found_pos = FindLabel(0);
-  const int search_size = found_pos.GetPosition() - IP().GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  GetHead(HEAD_FLOW).Set(found_pos);
-  GetHead(HEAD_FLOW).Advance();
-  return true; 
-}
-
-bool cHardwareCPU::Inst_SetFlow()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  GetHead(HEAD_FLOW).Set(Register(reg_used), this);
-  return true; 
-}
-
-// Direct Matching Templates
-
-bool cHardwareCPU::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.
-  cHeadCPU 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 cHardwareCPU::Inst_Skip()
-{
-  IP().Advance();
-  return true;
-}
-
-

Deleted: trunk/source/cpu/hardware_cpu.hh
===================================================================
--- trunk/source/cpu/hardware_cpu.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_cpu.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,588 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2004 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_CPU_HH
-#define HARDWARE_CPU_HH
-
-#include <iomanip>
-#include <vector>
-
-#ifndef DEFS_HH
-#include "defs.hh"
-#endif
-#ifndef CODE_LABEL_HH
-#include "cCodeLabel.h"
-#endif
-#ifndef CPU_DEFS_HH
-#include "cpu_defs.hh"
-#endif
-#ifndef HEAD_CPU_HH
-#include "head_cpu.hh"
-#endif
-#ifndef CPU_MEMORY_HH
-#include "cCPUMemory.h"
-#endif
-#ifndef CPU_STACK_HH
-#include "cCPUStack.h"
-#endif
-#ifndef HARDWARE_BASE_HH
-#include "hardware_base.hh"
-#endif
-#ifndef HARDWARE_CPU_THREAD_HH
-#include "hardware_cpu_thread.hh"
-#endif
-#ifndef STRING_HH
-#include "string.hh"
-#endif
-#ifndef TARRAY_HH
-#include "tArray.hh"
-#endif
-
-class cInstSet;
-class cInstLibBase;
-class cOrganism;
-class cMutation;
-class cHardwareCPU_Thread;
-
-#ifdef SINGLE_IO_BUFFER   // For Single IOBuffer vs IOBuffer for each Thread
-# define IO_THREAD 0
-#else
-# define IO_THREAD cur_thread
-#endif
-
-/**
- * Each organism may have a cHardwareCPU structure which keeps track of the
- * current status of all the components of the simulated hardware.
- *
- * @see cHardwareCPU_Thread, cCPUStack, cCPUMemory, cInstSet
- **/
-
-class cCodeLabel; // access
-class cHeadCPU; // access
-class cCPUMemory; // aggregate
-class cCPUStack; // aggregate
-class cGenome;
-class cHardwareCPU_Thread; // access
-class cInstLibBase;
-class cInstLibCPU;
-class cInstruction;
-class cInstSet;
-class cMutation;
-class cOrganism;
-class cString; // aggregate
-template <class T> class tBuffer;
-template <class T> class tArray; // aggregate
-
-class cHardwareCPU : public cHardwareBase {
-public:
-  typedef bool (cHardwareCPU::*tHardwareCPUMethod)();
-private:
-  static cInstLibCPU *s_inst_slib;
-  static cInstLibCPU *initInstLib(void);
-  tHardwareCPUMethod *m_functions;
-private:
-  cCPUMemory memory;          // Memory...
-  cCPUStack global_stack;     // A stack that all threads share.
-  int thread_time_used;
-
-  tArray<cHardwareCPU_Thread> threads;
-  int thread_id_chart;
-  int cur_thread;
-
-  // Flags...
-  bool mal_active;         // Has an allocate occured since last divide?
-  bool advance_ip;         // Should the IP advance after this instruction?
-
-  // Instruction costs...
-#ifdef INSTRUCTION_COSTS
-  tArray<int> inst_cost;
-  tArray<int> inst_ft_cost;
-#endif
-
-public:
-  cHardwareCPU(cOrganism * in_organism, cInstSet * in_inst_set);
-  explicit cHardwareCPU(const cHardwareCPU &);
-  ~cHardwareCPU();
-  void Recycle(cOrganism * new_organism, cInstSet * in_inst_set);
-  static cInstLibCPU *GetInstLib();
-  static cString GetDefaultInstFilename() { return "inst_lib.default"; }
-  static void WriteDefaultInstSet() { ; }
-
-  void Reset();
-  void SingleProcess();
-  bool SingleProcess_PayCosts(const cInstruction & cur_inst);
-  bool SingleProcess_ExecuteInst(const cInstruction & cur_inst);
-  void ProcessBonusInst(const cInstruction & inst);
-  void LoadGenome(const cGenome & new_genome);
-
-  // --------  Helper methods  --------
-  bool OK();
-  void PrintStatus(std::ostream & fp);
-
-
-  // --------  Flag Accessors --------
-  bool GetMalActive() const   { return mal_active; }
-
-  // --------  Stack Manipulation...  --------
-  inline void StackPush(int value);
-  inline int StackPop();
-  inline void StackFlip();
-  inline int GetStack(int depth=0, int stack_id=-1) const;
-  inline void StackClear();
-  inline void SwitchStack();
-  int GetActiveStackID() const { return threads[cur_thread].cur_stack; }
-
-
-  // --------  Head Manipulation (including IP)  --------
-  inline void SetActiveHead(const int new_head)
-  { threads[cur_thread].cur_head = (UCHAR) new_head; }
-
-  int GetCurHead() const { return threads[cur_thread].cur_head; }
-  const cHeadCPU & GetHead(int head_id) const
-    { return threads[cur_thread].heads[head_id]; }
-  cHeadCPU & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
-
-  const cHeadCPU & GetActiveHead() const { return GetHead(GetCurHead()); }
-  cHeadCPU & GetActiveHead() { return GetHead(GetCurHead()); }
-
-  void AdjustHeads();
-
-  inline const cHeadCPU & IP() const
-    { return threads[cur_thread].heads[HEAD_IP]; }
-  inline cHeadCPU & IP() { return threads[cur_thread].heads[HEAD_IP]; }
-
-
-  // --------  Label Manipulation  -------
-  void ReadLabel(int max_size=MAX_LABEL_SIZE);
-  const cCodeLabel & GetLabel() const 
-    { return threads[cur_thread].next_label; }
-  cCodeLabel & GetLabel() { return threads[cur_thread].next_label; }
-  const cCodeLabel & GetReadLabel() const
-    { return threads[cur_thread].read_label; }
-  cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
-
-
-  // --------  Register Manipulation  --------
-  const int & Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
-  int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
-
-  // --------  Memory Manipulation  --------
-  inline const cCPUMemory & Memory() const { return memory; }
-  inline cCPUMemory & Memory() { return memory; }
-
-  // --------  Thread Manipulation  --------
-  bool ForkThread(); // Adds a new thread based off of cur_thread.
-  bool KillThread(); // Kill the current thread!
-  inline void PrevThread(); // Shift the current thread in use.
-  inline void NextThread();
-  inline void SetThread(int value);
-
-  // --------  Tests  --------
-
-  int TestParasite() const;
-
-  // --------  Accessors  --------
-  const cCPUMemory & GetMemory() const { return memory; }
-  cCPUMemory & GetMemory() { return memory; }
-  const cCPUMemory & GetMemory(int value) const { return memory;}
-  cCPUMemory & GetMemory(int value) { return memory; }
-
-  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(); }
-
-  int GetThreadDist() const {
-    if (GetNumThreads() == 1) return 0;
-    return threads[0].heads[HEAD_IP].GetPosition() -
-      threads[1].heads[HEAD_IP].GetPosition();
-  }
-
-  // Complex label manipulation...
-  cHeadCPU FindLabel(int direction);
-  int FindLabel_Forward(const cCodeLabel & search_label,
-			  const cGenome & search_genome, int pos);
-  int FindLabel_Backward(const cCodeLabel & search_label,
-			  const cGenome & search_genome, int pos);
-  cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
-  cHeadCPU FindFullLabel(const cCodeLabel & in_label);
-
-  int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
-  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
-  int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
-  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);
-
-  bool TriggerMutations(int trigger);
-  bool TriggerMutations(int trigger, cHeadCPU & cur_head);
-  bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
-  bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
-  int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cHeadCPU & cur_head, const double rate);
-  void TriggerMutations_Body(int type, cCPUMemory & target_memory,
-			     cHeadCPU & cur_head);
-
-  void ReadInst(const int in_inst);
-
-  void SaveState(std::ostream & fp);
-  void LoadState(std::istream & fp);
-
-  //void InitInstSet(const cString & filename, cInstSet & inst_set);
-
-
-private:
- 
- /////////---------- Instruction Helpers ------------//////////
-
-  int FindModifiedRegister(int default_register);
-  int FindModifiedHead(int default_head);
-  int FindComplementRegister(int base_reg);
-
-  void Fault(int fault_loc, int fault_type, cString fault_desc="");
-
-  bool Allocate_Necro(const int new_size);
-  bool Allocate_Random(const int old_size, const int new_size);
-  bool Allocate_Default(const int new_size);
-  bool Allocate_Main(const int allocated_size);
-
-  bool Divide_Main(const int divide_point, const int extra_lines=0, double mut_multiplier=1);
-
-  bool Divide_CheckViable(const int child_size, const int parent_size);
-  void Divide_DoMutations(double mut_multiplier=1);
-  void Divide_TestFitnessMeasures();
-
-  bool HeadCopy_ErrorCorrect(double reduction);
-  bool Inst_HeadDivideMut(double mut_multiplier=1);
-
-public:
-  /////////---------- Instruction Library ------------//////////
-
-  // Flow Control
-  bool Inst_If0();
-  bool Inst_IfEqu();
-  bool Inst_IfNot0();
-  bool Inst_IfNEqu();
-  bool Inst_IfGr0();
-  bool Inst_IfGr();
-  bool Inst_IfGrEqu0();
-  bool Inst_IfGrEqu();
-  bool Inst_IfLess0();
-  bool Inst_IfLess();
-  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_HeadPop();
-  bool Inst_HeadPush();
-
-  bool Inst_PopA();
-  bool Inst_PopB();
-  bool Inst_PopC();
-  bool Inst_PushA();
-  bool Inst_PushB();
-  bool Inst_PushC();
-
-  bool Inst_SwitchStack();
-  bool Inst_FlipStack();
-  bool Inst_Swap();
-  bool Inst_SwapAB();
-  bool Inst_SwapBC();
-  bool Inst_SwapAC();
-  bool Inst_CopyReg();
-  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_ShiftR();
-  bool Inst_ShiftL();
-  bool Inst_Bit1();
-  bool Inst_SetNum();
-  bool Inst_ValGrey();
-  bool Inst_ValDir();
-  bool Inst_ValAddP();
-  bool Inst_ValFib();
-  bool Inst_ValPolyC();
-  bool Inst_Inc();
-  bool Inst_Dec();
-  bool Inst_Zero();
-  bool Inst_Not();
-  bool Inst_Neg();
-  bool Inst_Square();
-  bool Inst_Sqrt();
-  bool Inst_Log();
-  bool Inst_Log10();
-  bool Inst_Minus17();
-
-  // Double Argument Math
-  bool Inst_Add();
-  bool Inst_Sub();
-  bool Inst_Mult();
-  bool Inst_Div();
-  bool Inst_Mod();
-  bool Inst_Nand();
-  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_Divide();
-  bool Inst_CAlloc();
-  bool Inst_CDivide();
-  bool Inst_MaxAlloc();
-  bool Inst_Inject();
-  bool Inst_InjectRand();
-  bool Inst_InjectThread();
-  bool Inst_Repro();
-  bool Inst_Kazi();
-  bool Inst_Die();
-
-  // I/O and Sensory
-  bool Inst_TaskGet();
-  bool Inst_TaskStackGet();
-  bool Inst_TaskStackLoad();
-  bool Inst_TaskPut();
-  bool Inst_TaskIO();
-  bool Inst_Send();
-  bool Inst_Receive();
-  bool Inst_Sense();
-
-  void DoDonate(cOrganism * to_org);
-  bool Inst_DonateRandom();
-  bool Inst_DonateKin();
-  bool Inst_DonateEditDist();
-  bool Inst_DonateNULL();
-
-  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_ForkThread();
-  bool Inst_KillThread();
-  bool Inst_ThreadID();
-
-  // Head-based instructions...
-
-  bool Inst_SetHead();
-  bool Inst_AdvanceHead();
-  bool Inst_MoveHead();
-  bool Inst_JumpHead();
-  bool Inst_GetHead();
-  bool Inst_IfLabel();
-  bool Inst_IfLabel2();
-  bool Inst_HeadDivide();
-  bool Inst_HeadRead();
-  bool Inst_HeadWrite();
-  bool Inst_HeadCopy();
-  bool Inst_HeadSearch();
-  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_HeadDivideAsexWait();
-  bool Inst_HeadDivideMateSelect();
-
-  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();
-};
-
-
-//////////////////
-//  cHardwareCPU
-//////////////////
-
-inline void cHardwareCPU::NextThread()
-{
-  cur_thread++;
-  if (cur_thread >= GetNumThreads()) cur_thread = 0;
-}
-
-inline void cHardwareCPU::PrevThread()
-{
-  if (cur_thread == 0) cur_thread = GetNumThreads() - 1;
-  else cur_thread--;
-}
-
-inline void cHardwareCPU::SetThread(int value)
-{
-     if (value>=0 && value < GetNumThreads())
-          cur_thread=value;
-}
-
-inline void cHardwareCPU::StackPush(int value)
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Push(value);
-  } else {
-    global_stack.Push(value);
-  }
-}
-
-inline int cHardwareCPU::StackPop()
-{
-  int pop_value;
-
-  if (threads[cur_thread].cur_stack == 0) {
-    pop_value = threads[cur_thread].stack.Pop();
-  } else {
-    pop_value = global_stack.Pop();
-  }
-
-  return pop_value;
-}
-
-inline void cHardwareCPU::StackFlip()
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Flip();
-  } else {
-    global_stack.Flip();
-  }
-}
-
-inline int cHardwareCPU::GetStack(int depth, int stack_id) const
-{
-  int value = 0;
-
-  if (stack_id == -1) stack_id = threads[cur_thread].cur_stack;
-
-  if (stack_id == 0) value = threads[cur_thread].stack.Get(depth);
-  else if (stack_id == 1) value = global_stack.Get(depth);
-
-  return value;
-}
-
-inline void cHardwareCPU::StackClear()
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Clear();
-  } else {
-    global_stack.Clear();
-  }
-}
-
-inline void cHardwareCPU::SwitchStack()
-{
-  threads[cur_thread].cur_stack++;
-  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
-}
-
-#endif

Deleted: trunk/source/cpu/hardware_cpu_thread.cc
===================================================================
--- trunk/source/cpu/hardware_cpu_thread.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_cpu_thread.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,126 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_CPU_THREAD_HH
-#include "hardware_cpu_thread.hh"
-#endif
-
-using namespace std;
-
-/////////////////////////
-//  cHardwareCPU_Thread
-/////////////////////////
-
-cHardwareCPU_Thread::cHardwareCPU_Thread(cHardwareBase * in_hardware, int _id)
-{
-  Reset(in_hardware, _id);
-}
-
-cHardwareCPU_Thread::cHardwareCPU_Thread(const cHardwareCPU_Thread & in_thread, int _id)
-{
-   id = _id;
-   if (id == -1) id = in_thread.id;
-   for (int i = 0; i < NUM_REGISTERS; i++) {
-     reg[i] = in_thread.reg[i];
-   }
-   for (int i = 0; i < NUM_HEADS; i++) {
-     heads[i] = in_thread.heads[i];
-   }
-   stack = in_thread.stack;
-}
-
-cHardwareCPU_Thread::~cHardwareCPU_Thread() {}
-
-void cHardwareCPU_Thread::operator=(const cHardwareCPU_Thread & in_thread)
-{
-  id = in_thread.id;
-  for (int i = 0; i < NUM_REGISTERS; i++) {
-    reg[i] = in_thread.reg[i];
-  }
-  for (int i = 0; i < NUM_HEADS; i++) {
-    heads[i] = in_thread.heads[i];
-  }
-  stack = in_thread.stack;
-}
-
-void cHardwareCPU_Thread::Reset(cHardwareBase * in_hardware, int _id)
-{
-  id = _id;
-
-  for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
-  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
-
-  stack.Clear();
-  cur_stack = 0;
-  cur_head = HEAD_IP;
-  read_label.Clear();
-  next_label.Clear();
-}
-
-
-
-
-void cHardwareCPU_Thread::SaveState(ostream & fp){
-  assert(fp.good());
-  fp << "cHardwareCPU_Thread" << endl;
-
-  // registers
-  for( int i=0; i<NUM_REGISTERS; ++i ){
-    fp<<reg[i]<<endl;
-  }
-
-  // heads (@TCC does not handle parasites!!!)
-  for( int i=0; i<NUM_HEADS; ++i ){
-    fp<<heads[i].GetPosition()<<endl;
-  }
-
-  stack.SaveState(fp);
-
-  fp<<"|"; // marker
-  fp<<cur_stack;
-  fp<<cur_head;
-  fp<<endl;
-
-  // Code labels
-  read_label.SaveState(fp);
-  next_label.SaveState(fp);
-}
-
-
-
-void cHardwareCPU_Thread::LoadState(istream & fp){
-  assert(fp.good());
-  cString foo;
-  fp >> foo;
-  assert( foo == "cHardwareCPU_Thread");
-
-  // registers
-  for( int i=0; i<NUM_REGISTERS; ++i ){
-    fp>>reg[i];
-  }
-
-  // heads (@TCC does not handle parasites!!!)
-  for( int i=0; i<NUM_HEADS; ++i ){
-    int pos;
-    fp>>pos;
-    heads[i].AbsSet(pos);
-  }
-
-  // stack
-  stack.LoadState(fp);
-
-  char marker; fp>>marker; assert( marker == '|' );
-  /* YIKES!  data loss below: */
-  char the_cur_stack = cur_stack;
-  char the_cur_head = cur_head;
-  fp.get(the_cur_stack);
-  fp.get(the_cur_head);
-
-  // Code labels
-  read_label.LoadState(fp);
-  next_label.LoadState(fp);
-}

Deleted: trunk/source/cpu/hardware_cpu_thread.hh
===================================================================
--- trunk/source/cpu/hardware_cpu_thread.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_cpu_thread.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,68 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_CPU_THREAD_HH
-#define HARDWARE_CPU_THREAD_HH
-
-#include <iostream>
-
-#ifndef CODE_LABEL_HH
-#include "cCodeLabel.h"
-#endif
-#ifndef CPU_DEFS_HH
-#include "cpu_defs.hh"
-#endif
-#ifndef HEAD_CPU_HH
-#include "head_cpu.hh"
-#endif
-#ifndef CPU_STACK_HH
-#include "cCPUStack.h"
-#endif
-#ifndef TBUFFER_HH
-#include "tBuffer.hh"
-#endif
-
-/**
- * This class is needed to run several threads on a single genome.
- *
- * @see cCPUStack, cHeadCPU, cHardwareCPU
- **/
-
-class cCodeLabel; // aggregate;
-class cHeadCPU; // aggregate
-class cCPUStack; // aggregate
-class cHardwareBase;
-template <class T> class tBuffer; // aggregate
-
-struct cHardwareCPU_Thread {
-private:
-  int id;
-public:
-  int reg[NUM_REGISTERS];
-  cHeadCPU heads[NUM_HEADS];
-  cCPUStack stack;
-  UCHAR cur_stack;              // 0 = local stack, 1 = global stack.
-  UCHAR cur_head;
-
-  cCodeLabel read_label;
-  cCodeLabel next_label;
-public:
-  cHardwareCPU_Thread(cHardwareBase * in_hardware=NULL, int _id=-1);
-  cHardwareCPU_Thread(const cHardwareCPU_Thread & in_thread, int _id=-1);
-  ~cHardwareCPU_Thread();
-
-  void operator=(const cHardwareCPU_Thread & in_thread);
-
-  void Reset(cHardwareBase * in_hardware, int _id);
-  int GetID() const { return id; }
-  void SetID(int _id) { id = _id; }
-
-  void SaveState(std::ostream & fp);
-  void LoadState(std::istream & fp);
-};
-
-#endif

Deleted: trunk/source/cpu/hardware_factory.cc
===================================================================
--- trunk/source/cpu/hardware_factory.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_factory.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,82 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2003 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#include "hardware_factory.hh"
-
-#include "hardware_base.hh"
-#include "hardware_cpu.hh"
-#include "hardware_4stack.hh"
-#include "hardware_smt.h"
-#include "inst_set.hh"
-#include "organism.hh"
-
-using namespace std;
-
-// Static private variables...
-tList<cHardwareBase> cHardwareFactory::hardware_cpu_list;
-int cHardwareFactory::new_count(0);
-int cHardwareFactory::recycle_count(0);
-
-cHardwareBase * cHardwareFactory::Create(cOrganism * in_org,
-					 cInstSet * inst_set, int type)
-{
-  assert(in_org != NULL);
-  assert(inst_set != NULL && inst_set->OK());
-
-  cHardwareBase * new_hardware = NULL;
-
-  // If there is nothing to recycle, just create a new one.
-  if (hardware_cpu_list.GetSize() == 0)
-  {
-    new_count++;
-    switch (type)
-    {
-      case HARDWARE_TYPE_CPU_ORIGINAL:
-        new_hardware = new cHardwareCPU(in_org, inst_set);
-        break;
-      case HARDWARE_TYPE_CPU_4STACK:
-        new_hardware = new cHardware4Stack(in_org, inst_set);
-        break;
-      case HARDWARE_TYPE_CPU_SMT:
-        new_hardware = new cHardwareSMT(in_org, inst_set);
-    }
-  }
-
-  // If we do have hardware to recycle, do so!
-  else {
-    new_hardware = hardware_cpu_list.PopRear();
-    new_hardware->Recycle(in_org, inst_set);
-    recycle_count++;
-  }
-
-  return new_hardware;
-}
-
-// Recycled hardware may be *briefly* in use, so don't delete immediately.
-void cHardwareFactory::Recycle(cHardwareBase * out_hardware)
-{
-  hardware_cpu_list.Push(out_hardware);
-}
-
-// Delete any hardware that needs it, save the rest for re-use.
-void cHardwareFactory::Update()
-{
-  int delete_count = 0;
-  while (hardware_cpu_list.GetSize() > 100) {
-    delete hardware_cpu_list.Pop();
-    delete_count++;
-  }
-
-//    cerr << "   NewHardware: " << new_count
-//         << "   Recycled: " << recycle_count
-//         << "   Deleted: " << delete_count
-//         << "   Stored: " << hardware_cpu_list.GetSize()
-//         << "   Existing: " << cHardwareBase::GetInstanceCount()
-//         << endl;
-
-  new_count = recycle_count = 0;
-}

Deleted: trunk/source/cpu/hardware_factory.hh
===================================================================
--- trunk/source/cpu/hardware_factory.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_factory.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -1,32 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 1993 - 2001 California Institute of Technology             //
-//                                                                          //
-// Read the COPYING and README files, or contact 'avida at alife.org',         //
-// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef HARDWARE_FACTORY_HH
-#define HARDWARE_FACTORY_HH
-
-#ifndef TLIST_HH
-#include "tList.hh"
-#endif
-
-class cHardwareBase;
-class cOrganism;
-class cInstSet;
-
-class cHardwareFactory {
-private:
-  // A static list for each hardware type.
-  static tList<cHardwareBase> hardware_cpu_list;
-  static int new_count;
-  static int recycle_count;
-public:
-  static cHardwareBase * Create(cOrganism * in_org, cInstSet * inst_set,
-				int type=0);
-  static void Recycle(cHardwareBase * out_hardware);
-  static void Update();
-};
-
-#endif

Modified: trunk/source/cpu/hardware_smt.h
===================================================================
--- trunk/source/cpu/hardware_smt.h	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_smt.h	2005-08-29 19:51:42 UTC (rev 300)
@@ -25,7 +25,7 @@
 #include "head_multi_mem.hh"
 #endif
 #ifndef HARDWARE_BASE_HH
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #endif
 #ifndef HARDWARE_SMT_CONSTANTS_H
 #include "hardware_smt_constants.h"

Modified: trunk/source/cpu/hardware_status_printer.cc
===================================================================
--- trunk/source/cpu/hardware_status_printer.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_status_printer.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -6,9 +6,9 @@
 //////////////////////////////////////////////////////////////////////////////
 
 #include "head_cpu.hh"
-#include "hardware_4stack.hh"
-#include "hardware_base.hh"
-#include "hardware_cpu.hh"
+#include "cHardware4Stack.h"
+#include "cHardwareBase.h"
+#include "cHardwareCPU.h"
 #include "hardware_status_printer.hh"
 #include "inst_set.hh"
 #include "organism.hh"

Modified: trunk/source/cpu/hardware_util.cc
===================================================================
--- trunk/source/cpu/hardware_util.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/hardware_util.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -13,13 +13,13 @@
 #include "config.hh"
 #endif
 #ifndef HARDWARE_UTIL_HH
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #endif
 #ifndef HARDWARE_CPU_HH
-#include "hardware_cpu.hh"
+#include "cHardwareCPU.h"
 #endif
 #ifndef HARDWARE_4STACK_HH
-#include "hardware_4stack.hh"
+#include "cHardware4Stack.h"
 #endif
 #ifndef HARDWARE_SMT_H
 #include "hardware_smt.h"

Modified: trunk/source/cpu/head_cpu.cc
===================================================================
--- trunk/source/cpu/head_cpu.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/head_cpu.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -19,7 +19,7 @@
 #include "genome.hh"
 #endif
 #ifndef HARDWARE_BASE_HH
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #endif
 #ifndef INST_SET_HH
 #include "inst_set.hh"

Modified: trunk/source/cpu/head_multi_mem.cc
===================================================================
--- trunk/source/cpu/head_multi_mem.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/head_multi_mem.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -13,7 +13,7 @@
 #include "cCPUMemory.h"
 #endif
 #ifndef HARDWARE_BASE_HH
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #endif
 #ifndef INST_SET_HH
 #include "inst_set.hh"

Modified: trunk/source/cpu/inst_lib_cpu.hh
===================================================================
--- trunk/source/cpu/inst_lib_cpu.hh	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/inst_lib_cpu.hh	2005-08-29 19:51:42 UTC (rev 300)
@@ -7,7 +7,7 @@
 #endif
 
 #ifndef HARDWARE_CPU_HH
-#include "hardware_cpu.hh"
+#include "cHardwareCPU.h"
 #endif
 #ifndef INSTRUCTION_HH
 #include "instruction.hh"

Modified: trunk/source/cpu/test_cpu.cc
===================================================================
--- trunk/source/cpu/test_cpu.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/test_cpu.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -11,7 +11,7 @@
 #include "config.hh"
 #include "environment.hh"
 #include "functions.hh"
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #include "hardware_status_printer.hh"
 #include "inst_set.hh"
 #include "inst_util.hh"

Modified: trunk/source/cpu/test_util.cc
===================================================================
--- trunk/source/cpu/test_util.cc	2005-08-29 19:15:32 UTC (rev 299)
+++ trunk/source/cpu/test_util.cc	2005-08-29 19:51:42 UTC (rev 300)
@@ -11,7 +11,7 @@
 #include "environment.hh"
 #include "genome.hh"
 #include "genotype.hh"
-#include "hardware_base.hh"
+#include "cHardwareBase.h"
 #include "inject_genotype.hh"
 #include "inst_util.hh"
 #include "organism.hh"




More information about the Avida-cvs mailing list