[avida-cvs] avida CVS commits: /current configure.in /current/source/cpu cpu_stack.hh hardware_4stack.cc hardware_4stack.hh hardware_base.hh hardware_cpu.hh head.cc head.hh /current/source/main inst_util.cc /current/source/viewers zoom_screen.cc zoom_screen.hh

wisnelaw avida-cvs at alife.org
Thu Jun 5 21:14:43 PDT 2003


wisnelaw		Thu Jun  5 13:14:43 2003 EDT

  Modified files:              
    /avida/current	configure.in 
    /avida/current/source/cpu	cpu_stack.hh hardware_4stack.cc 
                             	hardware_4stack.hh hardware_base.hh 
                             	hardware_cpu.hh head.cc head.hh 
    /avida/current/source/main	inst_util.cc 
    /avida/current/source/viewers	zoom_screen.cc zoom_screen.hh 
  Log:
  This update includes the implementation of the new 4 stack hardware.  It is now fully functional with 35 commands, and is compatible with primitive mode and the ncurses viewer.  Note that running qt-viewer with hardware type 1 set in genesis will cause qt-viewer to crash.  No funcionality associated with the original hardware has been changed.
  
  -law
  
  
  
-------------- next part --------------
Index: avida/current/configure.in
diff -u avida/current/configure.in:1.28 avida/current/configure.in:1.29
--- avida/current/configure.in:1.28	Fri May 30 15:09:54 2003
+++ avida/current/configure.in	Thu Jun  5 13:14:38 2003
@@ -51,7 +51,7 @@
 dnl debugging/profiling
 AC_ARG_ENABLE(debug,
   [  --enable-debug: Compile with debugging symbols],
-  [CPPFLAGS="-g -DDEBUG"; qmake_debug="debug"],
+  [CPPFLAGS="-g -Wall -pedantic -DDEBUG"; qmake_debug="debug"],
   [CPPFLAGS="-O3 -ffast-math"; qmake_debug="release"])
 
 AC_ARG_ENABLE(gnu-debug,
Index: avida/current/source/cpu/cpu_stack.hh
diff -u avida/current/source/cpu/cpu_stack.hh:1.4 avida/current/source/cpu/cpu_stack.hh:1.5
--- avida/current/source/cpu/cpu_stack.hh:1.4	Tue May 27 18:08:18 2003
+++ avida/current/source/cpu/cpu_stack.hh	Thu Jun  5 13:14:39 2003
@@ -35,7 +35,7 @@
   inline int Pop();
   inline int Get(int depth=0) const;
   inline void Clear();
-  inline int& Top();
+  inline int Top();
   void Flip();
 
   bool OK();
@@ -74,7 +74,7 @@
   stack_pointer = 0;
 }
 
-inline int& cCPUStack::Top()
+inline int cCPUStack::Top()
 {
   return stack[stack_pointer];
 }
Index: avida/current/source/cpu/hardware_4stack.cc
diff -u avida/current/source/cpu/hardware_4stack.cc:1.7 avida/current/source/cpu/hardware_4stack.cc:1.8
--- avida/current/source/cpu/hardware_4stack.cc:1.7	Fri May 30 14:39:49 2003
+++ avida/current/source/cpu/hardware_4stack.cc	Thu Jun  5 13:14:40 2003
@@ -1,4 +1,3 @@
-
 //////////////////////////////////////////////////////////////////////////////
 // Copyright (C) 1993 - 2003 California Institute of Technology             //
 //                                                                          //
@@ -6,6 +5,7 @@
 // before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
 //////////////////////////////////////////////////////////////////////////////
 
+
 #include <iomanip>
 
 #include "hardware_method.hh"
@@ -43,13 +43,12 @@
 {
    id = _id;
    if (id == -1) id = in_thread.id;
-   for (int i = 0; i < NUM_REG_4STACK; i++) {
-     reg[i] = in_thread.reg[i];
+   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];
    }
-   stack = in_thread.stack;
    input_pointer = in_thread.input_pointer;
 }
 
@@ -58,13 +57,12 @@
 void cHardware4Stack_Thread::operator=(const cHardware4Stack_Thread & in_thread)
 {
   id = in_thread.id;
-  for (int i = 0; i < NUM_REG_4STACK; i++) {
-    reg[i] = in_thread.reg[i];
+  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];
   }
-  stack = in_thread.stack;
   input_pointer = in_thread.input_pointer;
   input_buf = in_thread.input_buf;
   output_buf = in_thread.output_buf;
@@ -74,11 +72,9 @@
 {
   id = _id;
 
-  for (int i = 0; i < NUM_REG_4STACK; i++) reg[i] = 0;
+  for (int i = 0; i < NUM_LOCAL_STACKS; i++) local_stacks[i].Clear();
   for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
 
-  stack.Clear();
-  cur_stack = 0;
   cur_head = HEAD_IP;
   input_pointer = 0;
   input_buf.Clear();
@@ -94,9 +90,9 @@
   assert(fp.good());
   fp << "cHardware4Stack_Thread" << endl;
 
-  // registers
-  for( int i=0; i<NUM_REG_4STACK; ++i ){
-    fp<<reg[i]<<endl;
+  // stacks (NOT WORKING! -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].SaveState(fp);
   }
 
   // heads (@TCC does not handle parasites!!!)
@@ -104,10 +100,7 @@
     fp<<heads[i].GetPosition()<<endl;
   }
 
-  stack.SaveState(fp);
-
   fp<<"|"; // marker
-  fp<<cur_stack;
   fp<<cur_head;
   fp<<input_pointer;
   fp<<endl;
@@ -129,9 +122,9 @@
   fp >> foo;
   assert( foo == "cHardware4Stack_Thread");
 
-  // registers
-  for( int i=0; i<NUM_REG_4STACK; ++i ){
-    fp>>reg[i];
+  // stacks (NOT WORKING!  -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].LoadState(fp);
   }
 
   // heads (@TCC does not handle parasites!!!)
@@ -141,20 +134,14 @@
     heads[i].AbsSet(pos);
   }
 
-  // stack
-  stack.LoadState(fp);
-
   char marker; fp>>marker; assert( marker == '|' );
-  /* YIKES!  data loss below: */
+  /* YIKES!  data loss below: */ 
 #ifdef USE_INST_SET_CODE
-  char the_cur_stack = cur_stack;
   char the_cur_head = cur_head;
   char the_input_pointer = input_pointer;
-  fp.get(the_cur_stack);
   fp.get(the_cur_head);
   fp.get(the_input_pointer);
 #else /* USE_INST_SET_CODE */
-  fp.get((char)cur_stack);
   fp.get((char)cur_head);
   fp.get((char)input_pointer);
 #endif /* USE_INST_SET_CODE */
@@ -244,10 +231,10 @@
     int nop_mod;
   };
   static const cNOPEntry4Stack s_n_array[] = {
-    cNOPEntry4Stack("Nop-A", REG_AX),
-    cNOPEntry4Stack("Nop-B", REG_BX),
-    cNOPEntry4Stack("Nop-C", REG_CX),
-    cNOPEntry4Stack("Nop-D", REG_DX),
+    cNOPEntry4Stack("Nop-A", STACK_AX),
+    cNOPEntry4Stack("Nop-B", STACK_BX),
+    cNOPEntry4Stack("Nop-C", STACK_CX),
+    cNOPEntry4Stack("Nop-D", STACK_DX),
   };
 
   struct cInstEntry4Stack {
@@ -262,7 +249,7 @@
     cInstEntry4Stack("Nop-B",     &cHardware4Stack::Inst_Nop), 
     //3
     cInstEntry4Stack("Nop-C",     &cHardware4Stack::Inst_Nop),   
-    //4 - not implemented yet...
+    //4 
     cInstEntry4Stack("Nop-D",     &cHardware4Stack::Inst_Nop), 
     //5
     cInstEntry4Stack("Nop-X",     &cHardware4Stack::Inst_Nop),
@@ -271,59 +258,59 @@
     //7
     cInstEntry4Stack("Val-Shift-L",   &cHardware4Stack::Inst_ShiftL),
     //8
-    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Nand),
+    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Val_Nand),
     //9
-    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Add),
+    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Val_Add),
     //10
-    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Sub),
+    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Val_Sub),
     //11
-    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Mult),
+    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Val_Mult),
     //12
-    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Div),
+    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Val_Div),
     //13
-    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_MaxAlloc),
+    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_SetMemory),
     //14
-    cInstEntry4Stack("Divide",  &cHardware4Stack::Inst_HeadDivide),
+    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),
+    //cInstEntry4Stack("Inst-Copy",    &cHardware4Stack::Inst_HeadCopy),
     //17
-    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqu),
+    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqual),
     //18
-    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNEqu),
+    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNotEqual),
     //19
     cInstEntry4Stack("If-Less",   &cHardware4Stack::Inst_IfLess),
     //20
-    cInstEntry4Stack("If-Greater",    &cHardware4Stack::Inst_IfGr),
+    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_MoveHead),
+    cInstEntry4Stack("Head-Move",  &cHardware4Stack::Inst_HeadMove),
     //24
-    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_HeadSearch),
+    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_Search),
     //25
-    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushA),
+    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushNext),
     //26
-    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushB),
+    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushPrevious),
     //27
-    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushC),
-    //28 - Not implemented yet...
-    //cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete
+    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushComplement),
+    //28
+    cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete),
     //29
-    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_CopyStack),
+    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_ValCopy),
     //30
     cInstEntry4Stack("ThreadFork",   &cHardware4Stack::Inst_ForkThread),
     //31
-    cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
+    //cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
     //32
-    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Inc),
+    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Increment),
     //33
-    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Dec),
+    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Decrement),
     //34
     cInstEntry4Stack("Val-Mod",       &cHardware4Stack::Inst_Mod),
     //35
@@ -378,7 +365,7 @@
     cInstEntry4Stack("compare",   &cHardware4Stack::Inst_Compare),
     cInstEntry4Stack("if-n-cpy",  &cHardware4Stack::Inst_IfNCpy),
     cInstEntry4Stack("allocate",  &cHardware4Stack::Inst_Allocate),
-    cInstEntry4Stack("divide",    &cHardware4Stack::Inst_Divide),
+    cInstEntry4Stack("divide",    &cHardware4Stack::Inst_DivideOld),
     cInstEntry4Stack("inject",    &cHardware4Stack::Inst_Inject),
     cInstEntry4Stack("inject-r",  &cHardware4Stack::Inst_InjectRand),
     cInstEntry4Stack("get",       &cHardware4Stack::Inst_TaskGet),
@@ -464,13 +451,14 @@
 
 cHardware4Stack::cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set)
   : cHardwareBase(in_organism, in_inst_set)
+  , memory_array(NUM_MEMORY_SPACES)
 {
 #ifdef USE_INST_SET_CODE
   /* FIXME:  reorganize storage of m_functions.  -- kgn */
   m_functions = s_inst_slib->GetFunctions();
   /**/
 #endif /* USE_INST_SET_CODE */
-  memory = in_organism->GetGenome();  // Initialize memory...
+  memory_array[0] = in_organism->GetGenome();  // Initialize memory...
   Reset();                            // Setup the rest of the hardware...
 }
 
@@ -483,16 +471,22 @@
 void cHardware4Stack::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
 {
   cHardwareBase::Recycle(new_organism, in_inst_set);
-  memory = new_organism->GetGenome();
+  memory_array[0] = new_organism->GetGenome();
   Reset();
 }
 
 
 void cHardware4Stack::Reset()
 {
-  global_stack.Clear();
+  //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)));
+  }
+
   // We want to reset to have a single thread.
   threads.Resize(1);
 
@@ -503,6 +497,12 @@
 
   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();
@@ -517,7 +517,6 @@
 
 }
 
-
 // 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.
 
@@ -571,7 +570,6 @@
   }
 }
 
-
 // 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.
@@ -659,7 +657,7 @@
 
 void cHardware4Stack::LoadGenome(const cGenome & new_genome)
 {
-  GetMemory() = new_genome;
+  GetMemory(0) = new_genome;
 }
 
 
@@ -667,12 +665,15 @@
 {
   bool result = true;
 
-  if (!memory.OK()) result = false;
+  for(int i = 0 ; i < NUM_MEMORY_SPACES; i++) {
+    if (!memory_array[i].OK()) result = false;
+  }
 
   for (int i = 0; i < GetNumThreads(); i++) {
     assert (threads[i].input_pointer < IO_SIZE);
 
-    if (threads[i].stack.OK() == false) result = false;
+    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;
   }
 
@@ -682,32 +683,46 @@
 void cHardware4Stack::PrintStatus(ostream & fp)
 {
   fp << organism->GetPhenotype().GetTimeUsed() << " "
-     << "IP:" << IP().GetPosition() << "    "
+     << "IP:(" << IP().GetMemSpace() << ", " << IP().GetPosition() << ")    "
 
-     << "AX:" << Register(REG_AX) << " "
-     << setbase(16) << "[0x" << Register(REG_AX) << "]  " << setbase(10)
+     << "AX:" << Stack(STACK_AX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_AX).Top() << "]  " << setbase(10)
 
-     << "BX:" << Register(REG_BX) << " "
-     << setbase(16) << "[0x" << Register(REG_BX) << "]  " << setbase(10)
+     << "BX:" << Stack(STACK_BX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_BX).Top() << "]  " << setbase(10)
 
-     << "CX:" << Register(REG_CX) << " "
-     << setbase(16) << "[0x" << Register(REG_CX) << "]" << setbase(10)
+     << "CX:" << Stack(STACK_CX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_CX).Top() << "]  " << setbase(10)
 
-     << "DX:" << Register(REG_DX) << " "
-     << setbase(16) << "[0x" << Register(REG_DX) << "]" << setbase(10)
+     << "DX:" << Stack(STACK_DX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_DX).Top() << "]  " << setbase(10)
 
      << endl;
 
-  fp << "  R-Head:" << GetHead(HEAD_READ).GetPosition() << " "
-     << "W-Head:" << GetHead(HEAD_WRITE).GetPosition()  << " "
-     << "F-Head:" << GetHead(HEAD_FLOW).GetPosition()   << "  "
+  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() << "   "
      << "NEXT: >> " << inst_set->GetName(IP().GetInst())() << " <<"
      << endl;
 
-  fp << "  Mem (" << GetMemory().GetSize() << "):"
-		  << "  " << GetMemory().AsString()
+  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();
 }
 
@@ -734,12 +749,12 @@
 //
 /////////////////////////////////////////////////////////////////////////
 
-cCPUHead cHardware4Stack::FindLabel(int direction)
+c4StackHead cHardware4Stack::FindLabel(int direction)
 {
-  cCPUHead & inst_ptr = IP();
+  c4StackHead & inst_ptr = IP();
 
   // Start up a search head at the position of the instruction pointer.
-  cCPUHead search_head(inst_ptr);
+  c4StackHead search_head(inst_ptr);
   cCodeLabel & search_label = GetLabel();
 
   // Make sure the label is of size > 0.
@@ -767,7 +782,8 @@
   }
   
   // Return the last line of the found label, if it was found.
-  if (found_pos >= 0) search_head.Set(found_pos - 1);
+  if (found_pos > 0) search_head.Set(found_pos - 1);
+  //*** I THINK THIS MIGHT HAVE BEEN WRONG...CHANGED >= to >.  -law ***//
 
   // Return the found position (still at start point if not found).
   return search_head;
@@ -935,7 +951,7 @@
 }
 
 // Search for 'in_label' anywhere in the hardware.
-cCPUHead cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
+c4StackHead cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
 {
   assert (in_label.GetSize() > 0);
 
@@ -946,7 +962,7 @@
   // FOR NOW:
   // Get something which works, no matter how inefficient!!!
 
-  cCPUHead temp_head(this);
+  c4StackHead temp_head(this);
 
   while (temp_head.InMemory()) {
     // IDEALY: Analyze the label we are in; see if the one we are looking
@@ -973,14 +989,14 @@
 
 // @CAO: direction is not currently used; should be used to indicate the
 // direction which the heads[HEAD_IP] should progress through a creature.
-cCPUHead cHardware4Stack::FindFullLabel(const cCodeLabel & in_label)
+c4StackHead 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!
 
-  cCPUHead temp_head(this);
+  c4StackHead temp_head(this);
 
   while (temp_head.InMemory()) {
     // If we are not in a label, jump to the next checkpoint...
@@ -1044,7 +1060,7 @@
 {
   // Make sure the genome will be below max size after injection.
 
-  const int new_size = injection.GetSize() + GetMemory().GetSize();
+  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
   if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
 
   const int inject_line = FindFullLabel(in_label).GetPosition();
@@ -1062,7 +1078,7 @@
 {
   // Make sure the genome will be below max size after injection.
 
-  const int new_size = injection.GetSize() + GetMemory().GetSize();
+  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
   if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
 
   const int inject_line = FindFullLabel(in_label).GetPosition();
@@ -1079,16 +1095,16 @@
 void cHardware4Stack::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);
+  assert(line_num <= memory_array[0].GetSize());
+  assert(memory_array[0].GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
 
-  // Inject the new code.
+  // Inject the new cod.e
   const int inject_size = inject_code.GetSize();
-  memory.Insert(line_num, inject_code);
+  memory_array[0].Insert(line_num, inject_code);
   
   // Set instruction flags on the injected code
   for (int i = line_num; i < line_num + inject_size; i++) {
-    memory.FlagInjected(i) = true;
+    memory_array[0].FlagInjected(i) = true;
   }
   organism->GetPhenotype().IsModified() = true;
 
@@ -1104,18 +1120,18 @@
 void cHardware4Stack::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);
+  assert(line_num <= memory_array[0].GetSize());
+  assert(memory_array[0].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);
+      memory_array[0].Insert(line_num, inject_code);
       
       // Set instruction flags on the injected code
       for (int i = line_num; i < line_num + inject_size; i++) {
-	memory.FlagInjected(i) = true;
+	memory_array[0].FlagInjected(i) = true;
       }
       organism->GetPhenotype().IsModified() = true;
       organism->GetPhenotype().IsMultiThread() = true;
@@ -1146,11 +1162,11 @@
 void cHardware4Stack::Mutate(int mut_point)
 {
   // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
+  assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
 
-  GetMemory()[mut_point] = GetRandomInst();
-  GetMemory().FlagMutated(mut_point) = true;
-  GetMemory().FlagPointMut(mut_point) = true;
+  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++;
 }
@@ -1158,10 +1174,10 @@
 int cHardware4Stack::PointMutate(const double mut_rate)
 {
   const int num_muts =
-    g_random.GetRandBinomial(GetMemory().GetSize(), mut_rate);
+    g_random.GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
 
   for (int i = 0; i < num_muts; i++) {
-    const int pos = g_random.GetUInt(GetMemory().GetSize());
+    const int pos = g_random.GetUInt(GetMemory(0).GetSize());
     Mutate(pos);
   }
 
@@ -1183,7 +1199,7 @@
   return TriggerMutations(trigger, IP());
 }
 
-bool cHardware4Stack::TriggerMutations(int trigger, cCPUHead & cur_head)
+bool cHardware4Stack::TriggerMutations(int trigger, c4StackHead & cur_head)
 {
   // Collect information about mutations from the organism.
   cLocalMutations & mut_info = organism->GetLocalMutations();
@@ -1196,7 +1212,7 @@
 
   // Determine what memory this mutation will be affecting.
   cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory();
+    ? organism->ChildGenome() : GetMemory(0);
 
   // Loop through all mutations associated with this trigger and test them.
   tConstListIterator<cMutation> mut_it(mut_list);
@@ -1236,7 +1252,7 @@
 }
 
 bool cHardware4Stack::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & cur_head, const double rate)
 {
   // The rate we have stored indicates the probability that a single
   // mutation will occur anywhere in the genome.
@@ -1244,7 +1260,7 @@
   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.
-    cCPUHead tmp_head(cur_head);
+    c4StackHead tmp_head(cur_head);
     tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
     TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
     return true;
@@ -1253,7 +1269,7 @@
 }
 
 bool cHardware4Stack::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & cur_head, const double rate)
 {
   // The rate we have stored is the probability for a mutation at this single
   // position in the genome.
@@ -1266,7 +1282,7 @@
 }
 
 int cHardware4Stack::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & 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
@@ -1277,7 +1293,7 @@
 
   if (num_mut > 0) {
     for (int i = 0; i < num_mut; i++) {
-      cCPUHead tmp_head(cur_head);
+      c4StackHead tmp_head(cur_head);
       tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
       TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
     }
@@ -1287,7 +1303,7 @@
 }
 
 void cHardware4Stack::TriggerMutations_Body(int type, cCPUMemory & target_memory,
-					 cCPUHead & cur_head)
+					 c4StackHead & cur_head)
 {
   const int pos = cur_head.GetPosition();
 
@@ -1336,7 +1352,7 @@
 void cHardware4Stack::ReadLabel(int max_size)
 {
   int count = 0;
-  cCPUHead * inst_ptr = &( IP() );
+  c4StackHead * inst_ptr = &( IP() );
 
   GetLabel().Clear();
 
@@ -1364,6 +1380,7 @@
 
   // Initialize the new thread to the same values as the current one.
   threads[num_threads] = threads[cur_thread];
+  IP().Advance();
 
   // Find the first free bit in thread_id_chart to determine the new
   // thread id.
@@ -1417,7 +1434,8 @@
   fp<<"cHardware4Stack"<<endl;
 
   // global_stack (in inverse order so load can just push)
-  global_stack.SaveState(fp);
+  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
+    Stack(i).SaveState(fp);
 
   fp << thread_time_used  << endl;
   fp << GetNumThreads()   << endl;
@@ -1440,7 +1458,8 @@
   assert( foo == "cHardware4Stack" );
 
   // global_stack
-  global_stack.LoadState(fp);
+  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
+    Stack(i).LoadState(fp);
 
   int num_threads;
   fp >> thread_time_used;
@@ -1458,18 +1477,6 @@
 //  Instruction Helpers...
 ////////////////////////////
 
-inline int cHardware4Stack::FindModifiedRegister(int default_register)
-{
-  assert(default_register < NUM_REG_4STACK);  // 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 cHardware4Stack::FindModifiedStack(int default_stack)
 {
   assert(default_stack < NUM_STACKS);  // Stack ID too high.
@@ -1482,7 +1489,6 @@
   return default_stack;
 }
 
-
 inline int cHardware4Stack::FindModifiedHead(int default_head)
 {
   assert(default_head < NUM_HEADS); // Head ID too high.
@@ -1495,13 +1501,6 @@
   return default_head;
 }
 
-
-inline int cHardware4Stack::FindComplementRegister(int base_reg)
-{
-  const int comp_reg = base_reg + 2;
-  return comp_reg%NUM_REG_4STACK;
-}
-
 inline int cHardware4Stack::FindComplementStack(int base_stack)
 {
   const int comp_stack = base_stack + 2;
@@ -1513,102 +1512,19 @@
   organism->Fault(fault_loc, fault_type, fault_desc);
 }
 
-
-bool cHardware4Stack::Allocate_Necro(const int new_size)
-{
-  GetMemory().ResizeOld(new_size);
-  return true;
-}
-
-bool cHardware4Stack::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 cHardware4Stack::Allocate_Default(const int new_size)
-{
-  GetMemory().Resize(new_size);
-
-  // New space already defaults to default instruction...
-
-  return true;
-}
-
-bool cHardware4Stack::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 cHardware4Stack::Divide_CheckViable(const int child_size,
-				      const int parent_size)
+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)
 
+  //mal_active=true;
+
   // 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)
-  }
+  //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.
 
@@ -1622,18 +1538,20 @@
 	  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)
-  }
+
+  //This is unneccesary...Parent size cannot change
+  //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++;
+    if (GetMemory(0).FlagExecuted(i)) executed_size++;
   }
 
   const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
@@ -1648,9 +1566,9 @@
   // 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++;
-  }
+  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) {
@@ -1757,9 +1675,9 @@
 
   // Mutations in the parent's genome
   if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
+    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
       if (organism->TestParentMut()) {
-	GetMemory()[i] = GetRandomInst();
+	GetMemory(0)[i] = GetRandomInst();
 	cpu_stats.mut_stats.parent_mut_line_count++;
       }
     }
@@ -1767,8 +1685,8 @@
 
 
   // Count up mutated lines
-  for(int i = 0; i < GetMemory().GetSize(); i++){
-    if (GetMemory().FlagPointMut(i) == true) {
+  for(int i = 0; i < GetMemory(0).GetSize(); i++){
+    if (GetMemory(0).FlagPointMut(i) == true) {
       cpu_stats.mut_stats.point_mut_line_count++;
     }
   }
@@ -1840,22 +1758,31 @@
 }
 
 
-bool cHardware4Stack::Divide_Main(const int div_point, const int extra_lines, double mut_multiplier)
+bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
 {
-  const int child_size = GetMemory().GetSize() - div_point - extra_lines;
+  int write_head_pos = threads[cur_thread].heads[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.
-  const bool viable = Divide_CheckViable(child_size, div_point);
-  if (viable == false) return false;
-
+  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();
-  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);
-
+  GetMemory(mem_space_used).Resize(write_head_pos);
+  child_genome = GetMemory(mem_space_used);
+  GetMemory(mem_space_used).Resize(1);
+  GetMemory(mem_space_used)[0].SetOp(mem_space_used);
+  for(int x=0; x<NUM_HEADS; x++)
+    {
+      threads[cur_thread].heads[x].Reset(this);
+    }
   // Handle Divide Mutations...
   Divide_DoMutations(mut_multiplier);
 
@@ -1871,21 +1798,18 @@
   }
 #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;
 }
 
+cString cHardware4Stack::ConvertToInstruction(int mem_space_used)
+{
+  char c = mem_space_used + 97;
+  cString ret;
+  ret += c;
+  return ret;
+}
+  
 
 //////////////////////////
 // And the instructions...
@@ -1895,7 +1819,9 @@
 bool cHardware4Stack::Inst_ShiftR()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() >>= 1;
+  int value = Stack(stack_used).Pop();
+  value >>= 1;
+  Stack(stack_used).Push(value);
   return true;
 }
 
@@ -1903,51 +1829,53 @@
 bool cHardware4Stack::Inst_ShiftL()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() <<= 1;
+  int value = Stack(stack_used).Pop();
+  value <<= 1;
+  Stack(stack_used).Push(value);
   return true;
 }
 
 //8
-bool cHardware4Stack::Inst_Nand()
+bool cHardware4Stack::Inst_Val_Nand()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = ~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top());
+  Stack(stack_used).Push(~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top()));
   return true;
 }
 
 //9
-bool cHardware4Stack::Inst_Add()
+bool cHardware4Stack::Inst_Val_Add()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() + Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() + Stack(STACK_CX).Top());
   return true;
 }
 
 //10
-bool cHardware4Stack::Inst_Sub()
+bool cHardware4Stack::Inst_Val_Sub()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() - Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() - Stack(STACK_CX).Top());
   return true;
 }
 
 //11
-bool cHardware4Stack::Inst_Mult()
+bool cHardware4Stack::Inst_Val_Mult()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() * Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() * Stack(STACK_CX).Top());
   return true;
 }
 
 //12
-bool cHardware4Stack::Inst_Div()
+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).Top() = Stack(STACK_BX).Top() / Stack(STACK_CX).Top();
+      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;
@@ -1956,34 +1884,46 @@
 }
 
 //13 
-bool cHardware4Stack::Inst_MaxAlloc()   // Allocate maximal more
+bool cHardware4Stack::Inst_SetMemory()   // 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) ) {
-    Stack(STACK_AX).Top() = cur_size;
-    return true;
-  } else return false;
+  const int mem_space_used = FindModifiedStack(STACK_BX);
+  threads[cur_thread].heads[HEAD_FLOW].Set(0, this, 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_HeadDivide()
+bool cHardware4Stack::Inst_Divide()
 {
-  return Inst_HeadDivideMut(1);
+  //return Inst_HeadDivideMut(1);
+  int mem_space_used = FindModifiedStack(STACK_BX);
+
+  int mut_multiplier = 1;
+  if(mem_space_used==0)
+    mem_space_used++;
+
+  return Divide_Main(mem_space_used, mut_multiplier);
 }
 
 bool cHardware4Stack::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; 
+  // 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
@@ -2001,7 +1941,7 @@
   } else {
     read_inst = GetHead(head_id).GetInst().GetOp();
   }
-  Stack(STACK_BX).Top() = read_inst;
+  Stack(STACK_AX).Push(read_inst);
   ReadInst(read_inst);
 
   cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
@@ -2013,11 +1953,19 @@
 bool cHardware4Stack::Inst_HeadWrite()
 {
   const int head_id = FindModifiedHead(HEAD_WRITE);
-  cCPUHead & active_head = GetHead(head_id);
+  c4StackHead & 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_BX).Top();
+  int value = Stack(STACK_AX).Pop();
   if (value < 0 || value >= GetNumInst()) value = 0;
 
   active_head.SetInst(cInstruction(value));
@@ -2032,8 +1980,8 @@
 bool cHardware4Stack::Inst_HeadCopy()
 {
   // For the moment, this cannot be nop-modified.
-  cCPUHead & read_head = GetHead(HEAD_READ);
-  cCPUHead & write_head = GetHead(HEAD_WRITE);
+  c4StackHead & read_head = GetHead(HEAD_READ);
+  c4StackHead & write_head = GetHead(HEAD_WRITE);
   sCPUStats & cpu_stats = organism->CPUStats();
 
   read_head.Adjust();
@@ -2065,19 +2013,19 @@
 }
 
 //17
-bool cHardware4Stack::Inst_IfEqu()      // Execute next if bx == ?cx?
+bool cHardware4Stack::Inst_IfEqual()      // Execute next if bx == ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  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_IfNEqu()     // Execute next if bx != ?cx?
+bool cHardware4Stack::Inst_IfNotEqual()     // Execute next if bx != ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  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;
 }
@@ -2085,17 +2033,17 @@
 //19
 bool cHardware4Stack::Inst_IfLess()       // Execute next if ?bx? < ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  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_IfGr()       // Execute next if bx > ?cx?
+bool cHardware4Stack::Inst_IfGreater()       // Execute next if bx > ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  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;
 }
@@ -2104,11 +2052,11 @@
 bool cHardware4Stack::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;
-  }
+  Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
+  //if (head_used == HEAD_IP) {
+  //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
+  //  advance_ip = false;
+  //}
   return true;
 }
 
@@ -2116,58 +2064,98 @@
 bool cHardware4Stack::Inst_HeadPop()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(StackPop(), this);
+  GetHead(head_used).Set(Stack(STACK_BX).Pop(), this);
   return true;
 }
 
 //23 
-bool cHardware4Stack::Inst_MoveHead()
+bool cHardware4Stack::Inst_HeadMove()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  if (head_used == HEAD_IP) advance_ip = false;
+  if(head_used != HEAD_FLOW)
+    {
+      GetHead(head_used).Set(GetHead(HEAD_FLOW));
+      if (head_used == HEAD_IP) advance_ip = false;
+    }
+  else
+    {
+      threads[cur_thread].heads[HEAD_FLOW]++;
+    }
   return true;
 }
 
 //24
-bool cHardware4Stack::Inst_HeadSearch()
+bool cHardware4Stack::Inst_Search()
 {
   ReadLabel();
   GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  cCPUHead found_pos = FindLabel(0);
-  const int search_size = found_pos.GetPosition() - IP().GetPosition();
-  Stack(STACK_BX).Top() = search_size;
-  Stack(STACK_CX).Top() = GetLabel().GetSize();
-  GetHead(HEAD_FLOW).Set(found_pos);
-  GetHead(HEAD_FLOW).Advance();
+  c4StackHead found_pos = FindLabel(0);
+  if(found_pos.GetPosition()-IP().GetPosition()==0)
+    {
+      GetHead(HEAD_FLOW).Set(IP().GetPosition()+1, this, IP().GetMemSpace());
+      //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_PushA() { StackPush(Stack(STACK_AX).Top()); return true;}
+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_PushB() { StackPush(Stack(STACK_AX).Top()); return true;}
+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_PushC() { StackPush(Stack(STACK_AX).Top()); return true;}
+bool cHardware4Stack::Inst_PushComplement() 
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  int complement = FindComplementStack(stack_used);
+  Stack(complement).Push(Stack(stack_used).Pop());
+  return true;
+}
 
-//INSTRUCTION 28 - "ValDelete" GOES HERE - law
+//28
+bool cHardware4Stack::Inst_ValDelete()
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Pop();
+  return true;
+}
 
 //29
-bool cHardware4Stack::Inst_CopyStack()
+bool cHardware4Stack::Inst_ValCopy()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  const int other_stack = FindComplementStack(stack_used);
-  Stack(other_stack).Top() = Stack(stack_used).Top();
+  Stack(stack_used).Push(Stack(stack_used).Top());
   return true;
 }
 
 //30
 bool cHardware4Stack::Inst_ForkThread()
 {
-  IP().Advance();
-  if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  if (!ForkThread()) 
+    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  else
+    IP().Advance();
   return true;
 }
 
@@ -2181,18 +2169,20 @@
 }
 
 //32
-bool cHardware4Stack::Inst_Inc()
+bool cHardware4Stack::Inst_Increment()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() += 1;
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(++value);
   return true;
 }
 
 //33
-bool cHardware4Stack::Inst_Dec()
+bool cHardware4Stack::Inst_Decrement()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() -= 1;
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(--value);
   return true;
 }
 
@@ -2201,7 +2191,7 @@
 {
   const int stack_used = FindModifiedStack(STACK_BX);
   if (Stack(STACK_CX).Top() != 0) {
-    Stack(stack_used).Top() = Stack(STACK_BX).Top() % Stack(STACK_CX).Top();
+    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;
@@ -2217,6 +2207,20 @@
   return true;
 }
 
+cString cHardware4Stack::GetActiveStackID(int stackID) const
+{
+  if(stackID==STACK_AX)
+    return "AX";
+  else if(stackID==STACK_BX)
+    return "BX";
+  else if(stackID==STACK_CX)
+    return "CX";
+  else if(stackID==STACK_DX)
+    return "DX";
+  else
+    return "";
+}
+
 /*bool cHardware4Stack::Inst_If0()          // Execute next if ?bx? ==0.
 {
   const int reg_used = FindModifiedRegister(REG_BX);
@@ -2312,7 +2316,7 @@
   }
 
   // Otherwise, try to jump to the complement label.
-  const cCPUHead jump_location(FindLabel(1));
+  const c4StackHead jump_location(FindLabel(1));
   if ( jump_location.GetPosition() != -1 ) {
     GetActiveHead().Set(jump_location);
     return true;
@@ -2336,7 +2340,7 @@
   }
 
   // otherwise jump to the complement label.
-  const cCPUHead jump_location(FindLabel(-1));
+  const c4StackHead jump_location(FindLabel(-1));
   if ( jump_location.GetPosition() != -1 ) {
     GetActiveHead().Set(jump_location);
     return true;
@@ -2378,7 +2382,7 @@
   }
 
   // otherwise jump to the complement label.
-  const cCPUHead jump_location(other_hardware.FindFullLabel(GetLabel()));
+  const c4StackHead jump_location(other_hardware.FindFullLabel(GetLabel()));
   if (jump_location.GetPosition() != -1) {
     IP().Set(jump_location);
     organism->GetPhenotype().IsParasite() = true;
@@ -2405,7 +2409,7 @@
   }
 
   // otherwise jump to the complement label.
-  const cCPUHead jump_location( FindFullLabel(GetLabel()) );
+  const c4StackHead jump_location( FindFullLabel(GetLabel()) );
   if ( jump_location.GetPosition() != -1 ) {
     IP().Set(jump_location);
     return true;
@@ -2432,7 +2436,7 @@
     return true;
   }
 
-  const cCPUHead jump_location(FindLabel(1));
+  const c4StackHead jump_location(FindLabel(1));
   if (jump_location.GetPosition() != -1) {
     IP().Set(jump_location);
     return true;
@@ -2621,8 +2625,8 @@
 
 bool cHardware4Stack::Inst_Copy()
 {
-  const cCPUHead from(this, Register(REG_BX));
-  cCPUHead to(this, Register(REG_AX) + Register(REG_BX));
+  const c4StackHead from(this, Register(REG_BX));
+  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
   sCPUStats & cpu_stats = organism->CPUStats();
 
   if (organism->TestCopyMut()) {
@@ -2645,7 +2649,7 @@
 bool cHardware4Stack::Inst_ReadInst()
 {
   const int reg_used = FindModifiedRegister(REG_CX);
-  const cCPUHead from(this, Register(REG_BX));
+  const c4StackHead from(this, Register(REG_BX));
 
   // Dis-allowing mutations on read, for the moment (write only...)
   // @CAO This allows perfect error-correction...
@@ -2655,7 +2659,7 @@
 
 bool cHardware4Stack::Inst_WriteInst()
 {
-  cCPUHead to(this, Register(REG_AX) + Register(REG_BX));
+  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
   const int reg_used = FindModifiedRegister(REG_CX);
   const int value = Mod(Register(reg_used), GetNumInst());
   sCPUStats & cpu_stats = organism->CPUStats();
@@ -2681,7 +2685,7 @@
 bool cHardware4Stack::Inst_StackReadInst()
 {
   const int reg_used = FindModifiedRegister(REG_CX);
-  cCPUHead from(this, Register(reg_used));
+  c4StackHead from(this, Register(reg_used));
   StackPush(from.GetInst().GetOp());
   return true;
 }
@@ -2689,7 +2693,7 @@
 bool cHardware4Stack::Inst_StackWriteInst()
 {
   const int reg_used = FindModifiedRegister(REG_BX);
-  cCPUHead to(this, Register(REG_AX) + Register(reg_used));
+  c4StackHead to(this, Register(REG_AX) + Register(reg_used));
   const int value = Mod(StackPop(), GetNumInst());
   sCPUStats & cpu_stats = organism->CPUStats();
 
@@ -2714,8 +2718,8 @@
 bool cHardware4Stack::Inst_Compare()
 {
   const int reg_used = FindModifiedRegister(REG_CX);
-  cCPUHead from(this, Register(REG_BX));
-  cCPUHead to(this, Register(REG_AX) + Register(REG_BX));
+  c4StackHead from(this, Register(REG_BX));
+  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
 
   // Compare is dangerous -- it can cause mutations!
   if (organism->TestCopyMut()) {
@@ -2732,8 +2736,8 @@
 
 bool cHardware4Stack::Inst_IfNCpy()
 {
-  const cCPUHead from(this, Register(REG_BX));
-  const cCPUHead to(this, Register(REG_AX) + Register(REG_BX));
+  const c4StackHead from(this, Register(REG_BX));
+  const c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
 
   // Allow for errors in this test...
   if (organism->TestCopyMut()) {
@@ -2753,7 +2757,7 @@
   } else return false;
 }
 
-bool cHardware4Stack::Inst_Divide()  
+bool cHardware4Stack::Inst_DivideOld()  
 { 
   return Divide_Main(Register(REG_AX));    
 }
@@ -3185,8 +3189,8 @@
 bool cHardware4Stack::HeadCopy_ErrorCorrect(double reduction)
 {
   // For the moment, this cannot be nop-modified.
-  cCPUHead & read_head = GetHead(HEAD_READ);
-  cCPUHead & write_head = GetHead(HEAD_WRITE);
+  c4StackHead & read_head = GetHead(HEAD_READ);
+  c4StackHead & write_head = GetHead(HEAD_WRITE);
   sCPUStats & cpu_stats = organism->CPUStats();
 
   read_head.Adjust();
@@ -3243,7 +3247,7 @@
   }
 
   // Otherwise, jump to the label.
-  cCPUHead jump_location(FindLabel(1));
+  c4StackHead jump_location(FindLabel(1));
   if (jump_location.GetPosition() != -1) {
     IP().Set(jump_location);
     return true;
Index: avida/current/source/cpu/hardware_4stack.hh
diff -u avida/current/source/cpu/hardware_4stack.hh:1.4 avida/current/source/cpu/hardware_4stack.hh:1.5
--- avida/current/source/cpu/hardware_4stack.hh:1.4	Tue May 27 18:08:18 2003
+++ avida/current/source/cpu/hardware_4stack.hh	Thu Jun  5 13:14:40 2003
@@ -35,21 +35,19 @@
 static const int STACK_CX = 2;
 static const int STACK_DX = 3;
 static const int NUM_NOPS_4STACK = 4;
+static const int NUM_MEMORY_SPACES = 4; 
 
 /**
  * This class is needed to run several threads on a single genome.
  *
- * @see cCPUStack, cCPUHead, cHardware4Stack
+ * @see cCPUStack, c4StackHead, cHardware4Stack
  **/
 
 struct cHardware4Stack_Thread {
 private:
   int id;
 public:
-  int reg[NUM_REG_4STACK];
-  cCPUHead heads[NUM_HEADS];
-  cCPUStack stack;
-  UCHAR cur_stack;              // 0 = local stack, 1 = global stack.
+  c4StackHead heads[NUM_HEADS];
   UCHAR cur_head;
   cCPUStack local_stacks[NUM_LOCAL_STACKS];
 
@@ -95,8 +93,8 @@
   static cInstLib4Stack *initInstLib(void);
   tHardware4StackMethod *m_functions;
 private:
-  cCPUMemory memory;          // Memory...
-  cCPUStack global_stack;     // A stack that all threads share.
+  tArray<cCPUMemory> memory_array;          // Memory...
+  //cCPUStack global_stack;     // A stack that all threads share.
   cCPUStack global_stacks[NUM_GLOBAL_STACKS];
   int thread_time_used;
 
@@ -105,7 +103,7 @@
   int cur_thread;
 
   // Flags...
-  bool mal_active;         // Has an allocate occured since last divide?
+  bool mal_active;         // Has an allocate occured since last dividehe?
   bool advance_ip;         // Should the IP advance after this instruction?
 
   // Instruction costs...
@@ -137,15 +135,13 @@
   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; }
-  //NEW STUFF
+  cString GetActiveStackID(int stackID) const;
   inline cCPUStack & Stack(int stack_id); //retrieves appropriate stack
+  inline const cCPUStack & Stack(int stack_id) const;
 
   // --------  Tasks & IO  --------
   tBuffer<int> & GetInputBuffer() { return threads[cur_thread].input_buf; }
@@ -158,18 +154,18 @@
   { threads[cur_thread].cur_head = (UCHAR) new_head; }
 
   int GetCurHead() const { return threads[cur_thread].cur_head; }
-  const cCPUHead & GetHead(int head_id) const
+  const c4StackHead & GetHead(int head_id) const
     { return threads[cur_thread].heads[head_id]; }
-  cCPUHead & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
+  c4StackHead & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
 
-  const cCPUHead & GetActiveHead() const { return GetHead(GetCurHead()); }
-  cCPUHead & GetActiveHead() { return GetHead(GetCurHead()); }
+  const c4StackHead & GetActiveHead() const { return GetHead(GetCurHead()); }
+  c4StackHead & GetActiveHead() { return GetHead(GetCurHead()); }
 
   void AdjustHeads();
 
-  inline const cCPUHead & IP() const
+  inline const c4StackHead & IP() const
     { return threads[cur_thread].heads[HEAD_IP]; }
-  inline cCPUHead & IP() { return threads[cur_thread].heads[HEAD_IP]; }
+  inline c4StackHead & IP() { return threads[cur_thread].heads[HEAD_IP]; }
 
 
   // --------  Label Manipulation  -------
@@ -183,12 +179,14 @@
 
 
   // --------  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]; }
+  //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; }
+  // --------  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.
@@ -202,9 +200,6 @@
   int TestParasite() const;
 
   // --------  Accessors  --------
-  const cCPUMemory & GetMemory() const { return memory; }
-  cCPUMemory & GetMemory() { return memory; }
-
   int GetThreadTimeUsed() const { return thread_time_used; }
   int GetNumThreads() const     { return threads.GetSize(); }
   int GetCurThread() const      { return cur_thread; }
@@ -217,13 +212,13 @@
   }
 
   // Complex label manipulation...
-  cCPUHead FindLabel(int direction);
+  c4StackHead 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);
-  cCPUHead FindLabel(const cCodeLabel & in_label, int direction);
-  cCPUHead FindFullLabel(const cCodeLabel & in_label);
+  c4StackHead FindLabel(const cCodeLabel & in_label, int direction);
+  c4StackHead FindFullLabel(const cCodeLabel & in_label);
 
   int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
   int Inject(const cCodeLabel & in_label, const cGenome & injection);
@@ -234,15 +229,15 @@
   int PointMutate(const double mut_rate);
 
   bool TriggerMutations(int trigger);
-  bool TriggerMutations(int trigger, cCPUHead & cur_head);
+  bool TriggerMutations(int trigger, c4StackHead & cur_head);
   bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   void TriggerMutations_Body(int type, cCPUMemory & target_memory,
-			     cCPUHead & cur_head);
+			     c4StackHead & cur_head);
 
   void ReadInst(const int in_inst);
 
@@ -250,16 +245,15 @@
   void LoadState(std::istream & fp);
 
   void InitInstSet(const cString & filename, cInstSet & inst_set);
+  cString ConvertToInstruction(int mem_space_used);
 
 
 private:
  
  /////////---------- Instruction Helpers ------------//////////
 
-  int FindModifiedRegister(int default_register);
   int FindModifiedStack(int default_stack);
   int FindModifiedHead(int default_head);
-  int FindComplementRegister(int base_reg);
   int FindComplementStack(int base_stack);
 
   void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
@@ -268,9 +262,8 @@
   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);
+  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 Divide_TestFitnessMeasures();
 
@@ -280,17 +273,81 @@
 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();
+
+  /*
   // 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();
@@ -308,15 +365,13 @@
   // 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();
@@ -334,12 +389,10 @@
   bool Inst_Reset();
 
   // Single-Argument Math
-  bool Inst_ShiftR();
-  bool Inst_ShiftL();
+
   bool Inst_Bit1();
   bool Inst_SetNum();
-  bool Inst_Inc();
-  bool Inst_Dec();
+
   bool Inst_Zero();
   bool Inst_Not();
   bool Inst_Neg();
@@ -350,12 +403,7 @@
   bool Inst_Minus18();
 
   // 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();
@@ -370,10 +418,10 @@
   bool Inst_Compare();
   bool Inst_IfNCpy();
   bool Inst_Allocate();
-  bool Inst_Divide();
+  bool Inst_DivideOld();
   bool Inst_CAlloc();
   bool Inst_CDivide();
-  bool Inst_MaxAlloc();
+
   bool Inst_Inject();
   bool Inst_InjectRand();
   bool Inst_InjectThread();
@@ -398,23 +446,17 @@
 
   // 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_HeadDivide();
-  bool Inst_HeadRead();
-  bool Inst_HeadWrite();
-  bool Inst_HeadCopy();
-  bool Inst_HeadSearch();
+ 
   bool Inst_SetFlow();
 
   bool Inst_HeadCopy2();
@@ -498,6 +540,7 @@
 
   //// Placebo ////
   bool Inst_Skip();
+  */
 };
 
 
@@ -505,6 +548,32 @@
 //  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++;
@@ -523,65 +592,57 @@
           cur_thread=value;
 }
 
-inline void cHardware4Stack::StackPush(int value)
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Push(value);
-  } else {
-    global_stack.Push(value);
-  }
-}
-
-inline int cHardware4Stack::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 cHardware4Stack::StackFlip()
+/*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) const
 {
-  int value = 0;
+  //int value = 0;
 
-  if (stack_id == -1) stack_id = threads[cur_thread].cur_stack;
+  if(stack_id<0 || stack_id>NUM_STACKS) stack_id=0;
 
-  if (stack_id == 0) value = threads[cur_thread].stack.Get(depth);
-  else if (stack_id == 1) value = global_stack.Get(depth);
+  int value = Stack(stack_id).Get(depth);
+  return value; //Stack(stack_id).Get(depth);
+  //threads[cur_thread].Stack(stack_id).Get(depth);
 
-  return value;
+  //return value;
 }
 
-inline void cHardware4Stack::StackClear()
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Clear();
-  } else {
-    global_stack.Clear();
-  }
-}
+//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 void cHardware4Stack::SwitchStack()
+inline cCPUStack& cHardware4Stack::Stack(int stack_id)
 {
-  threads[cur_thread].cur_stack++;
-  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
+  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)
+inline const cCPUStack& cHardware4Stack::Stack(int stack_id) const 
 {
   if(stack_id >= NUM_STACKS)
     {
@@ -592,5 +653,4 @@
   else
     return global_stacks[stack_id % NUM_LOCAL_STACKS];
 }
-
 #endif
Index: avida/current/source/cpu/hardware_base.hh
diff -u avida/current/source/cpu/hardware_base.hh:1.17 avida/current/source/cpu/hardware_base.hh:1.18
--- avida/current/source/cpu/hardware_base.hh:1.17	Sun May 18 21:15:21 2003
+++ avida/current/source/cpu/hardware_base.hh	Thu Jun  5 13:14:40 2003
@@ -69,6 +69,7 @@
 
   // --------  @CAO Should be rethought?  --------
   virtual cCPUMemory & GetMemory() = 0;
+  virtual cCPUMemory & GetMemory(int) = 0;
 
   // --------  DEBUG ---------
   static int GetInstanceCount() { return instance_count; }
Index: avida/current/source/cpu/hardware_cpu.hh
diff -u avida/current/source/cpu/hardware_cpu.hh:1.30 avida/current/source/cpu/hardware_cpu.hh:1.31
--- avida/current/source/cpu/hardware_cpu.hh:1.30	Tue May 27 18:08:18 2003
+++ avida/current/source/cpu/hardware_cpu.hh	Thu Jun  5 13:14:40 2003
@@ -192,6 +192,8 @@
   // --------  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(); }
Index: avida/current/source/cpu/head.cc
diff -u avida/current/source/cpu/head.cc:1.20 avida/current/source/cpu/head.cc:1.21
--- avida/current/source/cpu/head.cc:1.20	Sat May 17 14:54:54 2003
+++ avida/current/source/cpu/head.cc	Thu Jun  5 13:14:40 2003
@@ -256,8 +256,6 @@
   return cur_hardware->GetMemory().FlagCopyMut(position);    
 }
 
-
-
 cCPUHead & cCPUHead::operator=(const cCPUHead & in_cpu_head)
 {
   main_hardware = in_cpu_head.main_hardware;
@@ -452,6 +450,10 @@
   return pos;
 }
 
+bool cCPUHead::operator==(const cCPUHead & in_cpu_head) const {
+  return (cur_hardware == in_cpu_head.cur_hardware) &&
+    (position == in_cpu_head.position);
+}
 
 bool cCPUHead::AtEnd() const
 {
@@ -467,4 +469,202 @@
 {
   // If CPU has a head in another creature, mark it as a parasite.
   return (cur_hardware != main_hardware);
+}
+
+c4StackHead::c4StackHead() : cCPUHead() { mem_space=0; }
+
+c4StackHead::c4StackHead(cHardwareBase * in_hardware, int in_pos = 0, int in_mem_space = 0) 
+  : cCPUHead(in_hardware, in_pos) { mem_space = in_mem_space; }
+
+c4StackHead::c4StackHead(const c4StackHead & in_head) : cCPUHead(in_head) 
+{ 
+  mem_space = in_head.mem_space; 
+}
+
+void c4StackHead::Adjust()
+{
+  assert(cur_hardware != NULL);
+  assert(main_hardware != NULL);
+
+  const int mem_size = GetMemory().GetSize();
+
+  // If we are still in range, stop here!
+  if (position >= 0 && position < mem_size) return;
+
+  // If the memory is gone, just stick it at the begining of its parent.
+  if (mem_size == 0) {
+    cur_hardware = main_hardware;
+    position = 0;
+  }
+  else if (position <= 0) { position = 0; }
+  else if (position >= mem_size) {
+    // Always loop into the begining of the owner hardware.
+    cur_hardware = main_hardware;
+    position -= mem_size;
+    while (position >= GetMemory().GetSize()) {
+      // position back at the begining of the creature.
+      position %= GetMemory().GetSize();
+    }
+  }
+}
+
+void c4StackHead::Reset(cHardwareBase * new_hardware)
+{
+  if (new_hardware) main_hardware = new_hardware;
+  cur_hardware  = new_hardware;
+  position = 0;
+  mem_space = 0;
+}
+
+void c4StackHead::Set(int new_pos, cHardwareBase * in_hardware = NULL, int in_mem_space)
+{
+  position = new_pos;
+  if (in_hardware) cur_hardware = in_hardware;
+  mem_space = in_mem_space;
+  Adjust();
+}
+
+void c4StackHead::Set(const c4StackHead & in_head)
+{
+  position = in_head.position;
+  cur_hardware = in_head.cur_hardware;
+  mem_space = in_head.mem_space;
+  Adjust();
+}
+
+void c4StackHead::LoopJump(int jump)
+{
+  position += jump;
+
+  // If we are out of range, bring back in.
+  if (position < 0 || position >= GetMemory().GetSize()) {
+    position %= GetMemory().GetSize();
+    if (position <= 0) position += GetMemory().GetSize();
+  }
+}
+
+const cCPUMemory & c4StackHead::GetMemory() const
+{
+  assert(cur_hardware != NULL);
+  return cur_hardware->GetMemory(mem_space);
+}
+
+cCPUMemory & c4StackHead::GetMemory()
+{
+  assert(cur_hardware != NULL);
+  return cur_hardware->GetMemory(mem_space);
+}
+
+const cInstruction & c4StackHead::GetInst() const
+{
+  assert(position >= 0);
+  assert(position < GetMemory().GetSize());
+  return GetMemory()[position];
+}
+
+const cInstruction & c4StackHead::GetInst(int offset) const 
+{
+  int new_pos = position + offset;
+  return GetMemory()[new_pos];
+}
+
+
+void c4StackHead::SetInst(const cInstruction & value)
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory()[position] = value;
+#else
+  GetMemory()[position] = value;
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+void c4StackHead::InsertInst(const cInstruction & value)
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory().Insert(position, value);
+#else
+  GetMemory().Insert(position, value);
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+void c4StackHead::RemoveInst()
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory().Remove(position);
+#else
+  GetMemory().Remove(position);
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+const cInstruction & c4StackHead::GetNextInst()
+{
+  return (AtEnd()) ? cInstSet::GetInstError() : GetMemory()[position+1];
+}
+
+bool & c4StackHead::FlagCopied()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagCopied(position);     
+}
+
+bool & c4StackHead::FlagMutated()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagMutated(position);    
+}
+
+bool & c4StackHead::FlagExecuted()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagExecuted(position);   
+}
+
+bool & c4StackHead::FlagBreakpoint()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagBreakpoint(position); 
+}
+
+bool & c4StackHead::FlagPointMut()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagPointMut(position);   
+}
+
+bool & c4StackHead::FlagCopyMut()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagCopyMut(position);    
+}
+
+c4StackHead & c4StackHead::operator=(const c4StackHead & in_cpu_head)
+{
+  main_hardware = in_cpu_head.main_hardware;
+  cur_hardware  = in_cpu_head.cur_hardware;
+  position = in_cpu_head.position;
+  mem_space = in_cpu_head.mem_space;
+  return *this;
+}
+
+bool c4StackHead::operator==(const c4StackHead & in_cpu_head) const 
+{
+  return (cur_hardware == in_cpu_head.cur_hardware) && 
+    (position == in_cpu_head.position) &&
+    (mem_space == in_cpu_head.mem_space);
+}
+  
+bool c4StackHead::AtEnd() const
+{
+  return (position + 1 == GetMemory().GetSize());
+}
+
+bool c4StackHead::InMemory() const
+{
+  return (position >= 0 && position < GetMemory().GetSize());
 }
Index: avida/current/source/cpu/head.hh
diff -u avida/current/source/cpu/head.hh:1.10 avida/current/source/cpu/head.hh:1.11
--- avida/current/source/cpu/head.hh:1.10	Thu Mar 28 04:21:14 2002
+++ avida/current/source/cpu/head.hh	Thu Jun  5 13:14:40 2003
@@ -22,7 +22,7 @@
  **/
 
 class cCPUHead {
-private:
+protected:
   cHardwareBase * main_hardware;
   cHardwareBase * cur_hardware;
   int position;
@@ -35,22 +35,24 @@
   cCPUHead();
   cCPUHead(cHardwareBase * in_hardware, int in_pos = 0);
   cCPUHead(const cCPUHead & in_cpu_head);
-  ~cCPUHead() { ; }
-
-  void Reset(cHardwareBase * new_hardware = NULL);
+  virtual ~cCPUHead() { ; }
   
   /**
    * This function keeps the position within the range of the current memory.
    **/
-  void Adjust();
+  virtual void Adjust();
+
+  virtual void Reset(cHardwareBase * new_hardware = NULL);
   
   /**
    * Set the new position of the head (and adjust it into range in Set()).
    **/
 
-  void Set(int new_pos, cHardwareBase * in_hardware = NULL);
+  virtual void Set(int new_pos, cHardwareBase * in_hardware = NULL);
+  
   void AbsSet(int new_pos) { position = new_pos; }
-  void Set(const cCPUHead & in_head) {
+  
+  virtual void Set(const cCPUHead & in_head) {
     position = in_head.position;
     cur_hardware  = in_head.cur_hardware;
   }
@@ -60,7 +62,7 @@
    **/
 
   void Jump(int jump);
-  void LoopJump(int jump);
+  virtual void LoopJump(int jump);
   void AbsJump(int jump);
   
   // Other manipulation functions.
@@ -70,27 +72,27 @@
 
   // Accessors.
   int GetPosition() const { return position; }
-  const cCPUMemory & GetMemory() const;
+  virtual const cCPUMemory & GetMemory() const;
   cHardwareBase * GetCurHardware() const { return cur_hardware; }
   cHardwareBase * GetMainHardware() const { return main_hardware; }
-  const cInstruction & GetInst() const;
-  const cInstruction & GetInst(int offset) const;
+  virtual const cInstruction & GetInst() const;
+  virtual const cInstruction & GetInst(int offset) const;
   // int GetFlag(int id) const;
 
-  void SetInst(const cInstruction & value);
-  void InsertInst(const cInstruction & in_char);
-  void RemoveInst();
-  const cInstruction & GetNextInst();
-
-  bool & FlagCopied();
-  bool & FlagMutated();
-  bool & FlagExecuted();
-  bool & FlagBreakpoint();
-  bool & FlagPointMut();
-  bool & FlagCopyMut();
+  virtual void SetInst(const cInstruction & value);
+  virtual void InsertInst(const cInstruction & in_char);
+  virtual void RemoveInst();
+  virtual const cInstruction & GetNextInst();
+
+  virtual bool & FlagCopied();
+  virtual bool & FlagMutated();
+  virtual bool & FlagExecuted();
+  virtual bool & FlagBreakpoint();
+  virtual bool & FlagPointMut();
+  virtual bool & FlagCopyMut();
 
   // Operator Overloading...
-  cCPUHead & operator=(const cCPUHead & in_cpu_head);
+  virtual cCPUHead & operator=(const cCPUHead & in_cpu_head);
   cCPUHead & operator++();
   cCPUHead & operator--();
   cCPUHead & operator++(int);
@@ -100,19 +102,59 @@
     if (cur_hardware != in_cpu_head.cur_hardware) return 0;
     else return position - in_cpu_head.position;
   }
-  inline int operator==(const cCPUHead & in_cpu_head) const {
-    return (cur_hardware == in_cpu_head.cur_hardware) &&
-      (position == in_cpu_head.position);
-  }
+  virtual bool operator==(const cCPUHead & in_cpu_head) const;
 
   // Bool Tests...
   inline bool AtFront() const { return (position == 0); }
-  bool AtEnd() const;
-  bool InMemory() const;
+  virtual bool AtEnd() const;
+  virtual bool InMemory() const;
 
   // Test functions...
   int TestParasite() const;
 };
 
+class c4StackHead : public cCPUHead
+{
+private:
+  int mem_space;
+
+public:
+
+  c4StackHead();
+  c4StackHead(cHardwareBase * in_hardware, int in_pos = 0, int mem_space = 0);
+  c4StackHead(const c4StackHead & in_cpu_head);
+
+  void Adjust();
+  void Reset(cHardwareBase * new_hardware = NULL);
+  void Set(int new_pos, cHardwareBase * in_hardware = NULL, int in_mem_space = 0);
+  void Set(const c4StackHead & in_head);
+  void LoopJump(int jump);
+  const cCPUMemory & GetMemory() const;
+  cCPUMemory & GetMemory();
+  const cInstruction & GetInst() const;
+  const cInstruction & GetInst(int offset) const;
+
+  int GetMemSpace() const { return mem_space; }
+
+  void SetInst(const cInstruction & value);
+  void InsertInst(const cInstruction & in_char);
+  void RemoveInst();
+  const cInstruction & GetNextInst();
+
+  bool & FlagCopied();
+  bool & FlagMutated();
+  bool & FlagExecuted();
+  bool & FlagBreakpoint();
+  bool & FlagPointMut();
+  bool & FlagCopyMut();
+
+  // Operator Overloading...
+  c4StackHead & operator=(const c4StackHead & in_cpu_head);
+  bool operator==(const c4StackHead & in_cpu_head) const; 
+  bool AtEnd() const;
+  bool InMemory() const;
+};
 #endif
+
+
 
Index: avida/current/source/main/inst_util.cc
diff -u avida/current/source/main/inst_util.cc:1.13 avida/current/source/main/inst_util.cc:1.14
--- avida/current/source/main/inst_util.cc:1.13	Sun May 18 19:07:58 2003
+++ avida/current/source/main/inst_util.cc	Thu Jun  5 13:14:41 2003
@@ -21,7 +21,7 @@
 cGenome cInstUtil::LoadGenome(const cString & filename,
 			      const cInstSet & inst_set)
 {
-  cInitFile input_file(filename);
+    cInitFile input_file(filename);
   if (!input_file.IsOpen()) {
     cerr << "Cannot open file: " << filename << endl;
     return cGenome(1);
@@ -46,6 +46,9 @@
       exit(1);
     }
   }
+
+  if(new_genome.GetSize()==0)
+    cerr << "WARNING: Genome size is 0!" << endl;
 
   return new_genome;
 }
Index: avida/current/source/viewers/zoom_screen.cc
diff -u avida/current/source/viewers/zoom_screen.cc:1.24 avida/current/source/viewers/zoom_screen.cc:1.25
--- avida/current/source/viewers/zoom_screen.cc:1.24	Sat May 17 14:23:26 2003
+++ avida/current/source/viewers/zoom_screen.cc	Thu Jun  5 13:14:42 2003
@@ -18,6 +18,7 @@
 #include "../main/tasks.hh"
 
 #include "../cpu/hardware_cpu.hh"
+#include "../cpu/hardware_4stack.hh"
 
 #include "zoom_screen.hh"
 
@@ -43,6 +44,10 @@
   inst_view_mode = true;
   active_section = ZOOM_SECTION_MEMORY;
   task_offset = 0;
+  //hardware_type = info.GetActiveCell()->GetOrganism()->GetHardware().GetType();
+  cur_stack=0;
+  cur_mem_space=0;
+  cur_view_thread=0;
 
   map_mode = MAP_BASIC;
   mini_center_id = 0;
@@ -82,7 +87,13 @@
 
   // Redirect to the proper Draw() method.
 
-  if (mode == ZOOM_MODE_CPU) DrawCPU();
+  if (mode == ZOOM_MODE_CPU)
+    {
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL) 
+	DrawCPU_Original();
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK) 
+	DrawCPU_4Stack();
+    }
   else if (mode == ZOOM_MODE_STATS) DrawStats();
   else if (mode == ZOOM_MODE_GENOTYPE) DrawGenotype();
 
@@ -118,11 +129,23 @@
 
   Print(10, 27, "Thread:");
   Print(11, 27, "IP....:");
-  Print(12, 27, "AX....:");
-  Print(13, 27, "BX....:");
-  Print(14, 27, "CX....:");
-  Print(15, 27, "Stack.:");
-  Print(16, 27, "---- Memory ----");
+
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      Print(12, 27, "AX....:");
+      Print(13, 27, "BX....:");
+      Print(14, 27, "CX....:");
+      Print(15, 27, "Stack.:");
+      Print(16, 27, "---- Memory ----");
+    }
+  else if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+    {
+      Print(12, 27, "Stack AX:");
+      Print(13, 27, "Stack BX:");
+      Print(14, 27, "Stack CX:");
+      Print(15, 27, "Stack DX:");
+      Print(16, 27, "---- Memory ----");
+    }
 
   Print(CPU_FLAGS_Y, CPU_FLAGS_X, "---- Flags ----");
 
@@ -159,11 +182,9 @@
     Print(Height()-1, Width() - 21, "<-");
     Print(Height()-1, Width() - 11, "->");
   }
-
-
 }
 
-void cZoomScreen::DrawCPU()
+void cZoomScreen::DrawCPU_Original()
 {
   SetColor(COLOR_WHITE);
 
@@ -211,9 +232,8 @@
 
   Print(OPTIONS_Y+6, OPTIONS_X+2, "[E]dit Component");
   Print(OPTIONS_Y+7, OPTIONS_X+2, "[V]iew Component");
-#ifdef THREADS
-  Print(OPTIONS_Y+8, OPTIONS_X+2, "[T]hread Options");
-#endif
+  if(cConfig::GetMaxCPUThreads() >1)
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "Next [T]hread");
   Print(OPTIONS_Y+9, OPTIONS_X+2, "[TAB] Shift Active");
 
   if (info.GetPauseLevel()) {
@@ -226,9 +246,8 @@
   SetBoldColor(COLOR_CYAN);
   Print(OPTIONS_Y+6, OPTIONS_X+3, "E");
   Print(OPTIONS_Y+7, OPTIONS_X+3, "V");
-#ifdef THREADS
-  Print(OPTIONS_Y+8, OPTIONS_X+3, "T");
-#endif
+  if(cConfig::GetMaxCPUThreads() >1)
+    Print(OPTIONS_Y+8, OPTIONS_X+8, "T");
   Print(OPTIONS_Y+9, OPTIONS_X+3, "TAB");
 
   if (info.GetPauseLevel()) {
@@ -261,6 +280,109 @@
   Print(19, 52, "Thread.......:");
 }
 
+void cZoomScreen::DrawCPU_4Stack()
+{
+  SetColor(COLOR_WHITE);
+
+  // --== Registers ==--
+  Box(REG_X, REG_Y-1, 19, 8);
+  Print(REG_Y, REG_X + 2, "Stacks:");
+  HLine(REG_Y + 1, REG_X, 19);
+
+  SetBoldColor(COLOR_WHITE);
+  Print(REG_Y + 2, REG_X + 2, "AX:");
+  Print(REG_Y + 3, REG_X + 2, "BX:");
+  Print(REG_Y + 4, REG_X + 2, "CX:");
+  Print(REG_Y + 5, REG_X + 2, "DX:");
+  SetColor(COLOR_WHITE);
+
+  // --== Inputs ==--
+  Box(INPUT_X, INPUT_Y-1, 16, 8);
+  Print(INPUT_Y, INPUT_X + 2, "Inputs:");
+  HLine(INPUT_Y+1, INPUT_X, 16);
+
+  // --== Mini-Map ==--
+  Box(MINI_MAP_X, MINI_MAP_Y, 17, 3);
+  Print(MINI_MAP_Y + 1, MINI_MAP_X + 2, "Mini-Map");
+  //HLine(MINI_MAP_Y + 2, MINI_MAP_X, 19);
+
+  SetBoldColor(COLOR_WHITE);
+  Print(MINI_MAP_Y + 11, MINI_MAP_X,  "[ ]           [ ]");
+  SetBoldColor(COLOR_CYAN);
+  Print(MINI_MAP_Y + 11, MINI_MAP_X + 1,  '-');
+  Print(MINI_MAP_Y + 11, MINI_MAP_X + 15, '+');
+  SetColor(COLOR_WHITE);
+
+  // --== Memory ==--
+  Box(MEMORY_X, MEMORY_Y, 36, 5 + MEMORY_PRE_SIZE + MEMORY_POST_SIZE);
+  Print(MEMORY_Y + 1, MEMORY_X + 2,  "Memory Space");
+  HLine(MEMORY_Y + 2, MEMORY_X, 36);
+
+  // --== Stack ==--
+  Box(STACK_X, STACK_Y-1, 15, 8);
+  HLine(STACK_Y + 1, STACK_X, 15);
+
+  // --== Options ==--
+  SetBoldColor(COLOR_YELLOW);
+  Print(OPTIONS_Y, OPTIONS_X+4,    "Component Zoom");
+  SetBoldColor(COLOR_WHITE);
+
+  //Print(OPTIONS_Y+6, OPTIONS_X+2, "[E]dit Component");
+  //Print(OPTIONS_Y+7, OPTIONS_X+2, "[V]iew Component");
+  Print(OPTIONS_Y+5, OPTIONS_X+2, "Next Stac[K]");
+  if(cConfig::GetMaxCPUThreads() >1)
+  Print(OPTIONS_Y+6, OPTIONS_X+2, "Next [T]hread");
+  //Print(OPTIONS_Y+9, OPTIONS_X+2, "[TAB] Shift Active");
+
+  if (info.GetPauseLevel()) {
+    Print(OPTIONS_Y+7, OPTIONS_X+2, "[UP, DOWN]");
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "Scroll Instruction");
+    Print(OPTIONS_Y+9, OPTIONS_X+2, "[LEFT, RIGHT]");
+    Print(OPTIONS_Y+10, OPTIONS_X+2, "Change Mem Space");
+  } else {
+    Print(OPTIONS_Y+7, OPTIONS_X+2, "               ");
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "                  ");
+    Print(OPTIONS_Y+9, OPTIONS_X+2, "               ");
+    Print(OPTIONS_Y+10, OPTIONS_X+2, "                 ");
+  }
+
+
+  SetBoldColor(COLOR_CYAN);
+  Print(OPTIONS_Y+5, OPTIONS_X+12, "K");
+  if(cConfig::GetMaxCPUThreads() >1)
+  Print(OPTIONS_Y+6, OPTIONS_X+8, "T");
+
+  if (info.GetPauseLevel()) {
+    Print(OPTIONS_Y+7, OPTIONS_X+3, "UP, DOWN");
+    Print(OPTIONS_Y+9, OPTIONS_X+3, "LEFT, RIGHT");
+  }
+
+  // Highlight the active section...
+  SetActiveSection(active_section);
+
+  // Add on a bunch of special characters to smooth the view out...
+  Print(INPUT_Y - 1, INPUT_X, CHAR_TTEE);
+  Print(INPUT_Y + 1, INPUT_X, CHAR_PLUS);
+  Print(INPUT_Y + 6, INPUT_X, CHAR_BTEE);
+
+  Print(STACK_Y - 1, STACK_X, CHAR_TTEE);
+  Print(STACK_Y + 1, STACK_X, CHAR_PLUS);
+  Print(STACK_Y + 6, STACK_X, CHAR_BTEE);
+
+
+  // A few stats on this screen...
+
+  SetBoldColor(COLOR_WHITE);
+
+  Print(13, 52, "Location.....:");
+  Print(14, 52, "Genotype ID..:");
+  Print(15, 52, "Genotype Name:");
+
+  Print(17, 52, "Faults.......:");
+  Print(18, 52, "Offspring....:");
+  Print(19, 52, "Thread.......:");
+}
+
 void cZoomScreen::DrawGenotype()
 {
   SetBoldColor(COLOR_YELLOW);
@@ -306,16 +428,15 @@
 
 void cZoomScreen::Update()
 {
-  if (mode == ZOOM_MODE_CPU){
-    UpdateCPU();
-  }
-  else if (mode == ZOOM_MODE_STATS) UpdateStats();
+  cHardwareBase & hardware = info.GetActiveCell()->GetOrganism()->GetHardware();
+  if(mode == ZOOM_MODE_CPU) UpdateCPU(hardware);
+  else if (mode == ZOOM_MODE_STATS) UpdateStats(hardware);
   else if (mode == ZOOM_MODE_GENOTYPE) UpdateGenotype();
 
   Refresh();
 }
 
-void cZoomScreen::UpdateStats()
+void cZoomScreen::UpdateStats(cHardwareBase & hardware)
 {
   if (info.GetActiveCell() == NULL ||
       info.GetActiveCell()->IsOccupied() == false) return;
@@ -323,8 +444,8 @@
   cGenotype * genotype = info.GetActiveGenotype();
   cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
 
-  cHardwareCPU & hardware =
-    (cHardwareCPU &) info.GetActiveCell()->GetOrganism()->GetHardware();
+  //cHardwareBase & hardware =
+  //  info.GetActiveCell()->GetOrganism()->GetHardware();
 
   SetBoldColor(COLOR_CYAN);
 
@@ -354,34 +475,14 @@
   Print(7, 39, "%9d ", phenotype.GetGestationStart());
   Print(8, 39, "%9d ", phenotype.GetNumDivides());
 
-
   if (info.GetThreadLock() != -1) Print(10, 36, "LOCKED");
   else Print(10, 36, "      ");
-  Print(10, 43, "%2d/%2d", hardware.GetCurThread() + 1,
-	hardware.GetNumThreads());
-  Print(12, 34, "%14d", hardware.Register(0));
-  Print(13, 34, "%14d", hardware.Register(1));
-  Print(14, 34, "%14d", hardware.Register(2));
-  Print(15, 34, "%14d", hardware.GetStack(0));
-
-  cCPUHead inst_ptr(hardware.IP());
-  const cInstSet & inst_set = hardware.GetInstSet();
-
-  for (int pos = 0; pos < 3; pos++) {
-    // Clear the line
-    Print(17+pos, 29, "                    ");
-    if (inst_ptr.InMemory() == false) continue;
-    if (pos == 1) SetColor(COLOR_CYAN);
-
-    // Draw the current instruction.
-      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
-    inst_ptr.Advance();
-  }
+  
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    UpdateStats_CPU(hardware);
 
-  // Flags...
-  if (hardware.GetMalActive()) SetBoldColor(COLOR_CYAN);
-  else SetColor(COLOR_CYAN);
-  Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+    UpdateStats_4Stack(hardware);
 
   if (phenotype.ParentTrue()) SetBoldColor(COLOR_CYAN);
   else SetColor(COLOR_CYAN);
@@ -450,27 +551,157 @@
   Print(2, 40, "[%2d, %2d] ",
 	id % population.GetWorldX(), id / population.GetWorldY());
 
-  // And print the IP.
+  
+
+}
+
+void cZoomScreen::UpdateStats_CPU(cHardwareBase & hardware)
+{
+  cHardwareCPU & hardwareCPU = (cHardwareCPU &) hardware;
+
+  Print(10, 43, "%2d/%2d", hardwareCPU.GetCurThread() + 1,
+	hardwareCPU.GetNumThreads());
 
-  const cCPUHead & active_inst_ptr = hardware.IP();
+  Print(12, 34, "%14d", hardwareCPU.Register(0));
+  Print(13, 34, "%14d", hardwareCPU.Register(1));
+  Print(14, 34, "%14d", hardwareCPU.Register(2));
+  Print(15, 34, "%14d", hardwareCPU.GetStack(0));
+
+  cCPUHead inst_ptr(hardwareCPU.IP());
+   const cInstSet & inst_set = hardwareCPU.GetInstSet();
+  
+  for (int pos = 0; pos < 3; pos++) {
+    // Clear the line
+    Print(17+pos, 29, "                    ");
+    if (inst_ptr.InMemory() == false) continue;
+    if (pos == 1) SetColor(COLOR_CYAN);
+
+    // Draw the current instruction.
+      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
+    inst_ptr.Advance();
+  }
+
+  // Flags...
+  if (hardwareCPU.GetMalActive()) SetBoldColor(COLOR_CYAN);
+  else SetColor(COLOR_CYAN);
+  Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+ 
+  // And print the IP.
+  const cCPUHead & active_inst_ptr = hardwareCPU.IP();
   // @CAO assume no parasites for now.
   int cur_id = info.GetActiveCell()->GetID();
   //active_inst_ptr.GetCurHardware()->GetOrganism()->GetEnvironment()->GetID();
   Print(11, 36, "%12s", cStringUtil::Stringf("[%2d,%2d] : %2d",
 	cur_id % population.GetWorldX(), cur_id / population.GetWorldX(),
 	active_inst_ptr.GetPosition())() );
+}
+
+void cZoomScreen::UpdateStats_4Stack(cHardwareBase & hardware)
+{
+  cHardware4Stack & hardware4Stack = (cHardware4Stack &) hardware;
+
+  Print(10, 43, "%2d/%2d", hardware4Stack.GetCurThread() + 1,
+	hardware4Stack.GetNumThreads());
+
+  Print(12, 34, "%14d", hardware4Stack.Stack(0).Top());
+  Print(13, 34, "%14d", hardware4Stack.Stack(1).Top());
+  Print(14, 34, "%14d", hardware4Stack.Stack(2).Top());
+  Print(15, 34, "%14d", hardware4Stack.Stack(3).Top());
+
+  c4StackHead inst_ptr(hardware4Stack.IP());
+   const cInstSet & inst_set = hardware4Stack.GetInstSet();
+  
+  for (int pos = 0; pos < 3; pos++) {
+    // Clear the line
+    Print(17+pos, 29, "                    ");
+    if (inst_ptr.InMemory() == false) continue;
+    if (pos == 1) SetColor(COLOR_CYAN);
+
+    // Draw the current instruction.
+      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
+    inst_ptr.Advance();
+  }
 
+  // Flags...
+  //if (hardwareCPU.GetMalActive()) SetBoldColor(COLOR_CYAN);
+  //else SetColor(COLOR_CYAN);
+  //Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+ 
+  // And print the IP.
+  const c4StackHead & active_inst_ptr = hardware4Stack.IP();
+  // @CAO assume no parasites for now.
+  //int cur_id = info.GetActiveCell()->GetID();
+  //active_inst_ptr.GetCurHardware()->GetOrganism()->GetEnvironment()->GetID();
+  Print(11, 36, "%12s", cStringUtil::Stringf("(%2d, %2d)",
+	active_inst_ptr.GetMemSpace(),
+	active_inst_ptr.GetPosition())() );
 }
 
-void cZoomScreen::UpdateCPU()
+void cZoomScreen::UpdateCPU(cHardwareBase & hardware)
 {
-  cHardwareCPU & hardware =
-    (cHardwareCPU &) info.GetActiveCell()->GetOrganism()->GetHardware();
+  // Place the visible section of the current memory onto the screen.
+
+  SetBoldColor(COLOR_WHITE);
+  if (info.GetPauseLevel() == PAUSE_OFF) {
+    // If not paused, then set user desired offset to zero AND always show
+    // the code that is executing (ie. do not show original Parasite code if
+    // host is executing)
+    memory_offset = 0;
+    parasite_zoom = false;
+  }
+
+  Print(14, 69, "%10d", info.GetActiveGenotypeID());
+  Print(15, 69, "%10s", info.GetActiveName()());
+
+  cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
+  Print(17, 69, "%10d", phenotype.GetCurNumErrors());
+  Print(18, 69, "%10d", phenotype.GetNumDivides());
+  if (info.GetThreadLock() != -1) Print(19, 67, "LOCKED");
+  else Print(19, 67, "      ");
+
+  if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+    UpdateCPU_Original(hardware);
+  else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+    UpdateCPU_4Stack(hardware);
+
+  // Place the input buffer on the screen.
+
+  SetBoldColor(COLOR_CYAN);
+  Print(INPUT_Y+3, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(0));
+
+  SetColor(COLOR_CYAN);
+  for (int i = 1; i < IO_SIZE; i++) {
+    Print(INPUT_Y+3+i, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(i));
+  }
+
+  const cString & cur_fault = phenotype.GetFault();
+  if (cur_fault.GetSize() > 0) {
+    SetBoldColor(COLOR_RED);
+    Print(FAULT_Y, FAULT_X, "Fault:");
+    SetBoldColor(COLOR_CYAN);
+    Print(FAULT_Y, FAULT_X + 7, cur_fault());
+  } else {
+    Print(FAULT_Y, FAULT_X, "                                        ");
+  }
+
+  SetBoldColor(COLOR_WHITE);
+
+  Print(13, 70, "[%3d,%3d] ",
+	info.GetActiveID() % population.GetWorldX(),
+	info.GetActiveID() / population.GetWorldY());
+
+  SetBoldColor(COLOR_CYAN);
+  Refresh();
+}
+
+void cZoomScreen::UpdateCPU_Original(cHardwareBase & hardware)
+{
+  cHardwareCPU & hardwareCPU = (cHardwareCPU &) hardware;
 
   // Place the registers onto the screen.
   SetBoldColor(COLOR_CYAN);
   for (int i = 0; i < NUM_REGISTERS; i++) {
-    Print(REG_Y+3 + i, REG_X+6, "%11d", hardware.Register(i));
+    Print(REG_Y+3 + i, REG_X+6, "%11d", hardwareCPU.Register(i));
   }
 
   // Place the active stack onto the screen.
@@ -478,14 +709,14 @@
   // Stack A
   // SetBoldColor(COLOR_CYAN);   // -Redundant
   SetColor(COLOR_WHITE);
-  char stack_letter = 'A' + hardware.GetActiveStackID();
+  char stack_letter = 'A' + hardwareCPU.GetActiveStackID();
   Print(STACK_Y + 1, STACK_X + 2, "Stack %c", stack_letter);
 
   SetBoldColor(COLOR_CYAN);
-  Print(STACK_Y+3, STACK_X + 2, "%11d", hardware.GetStack(0));
+  Print(STACK_Y+3, STACK_X + 2, "%11d", hardwareCPU.GetStack(0));
   SetColor(COLOR_CYAN);
   for (int i = 1; i <= 2; i++) {
-    Print(STACK_Y+3 + i, STACK_X+2, "%11d", hardware.GetStack(i));
+    Print(STACK_Y+3 + i, STACK_X+2, "%11d", hardwareCPU.GetStack(i));
   }
 
   // Place the input buffer on the screen.
@@ -498,38 +729,20 @@
     Print(INPUT_Y+3+i, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(i));
   }
 
-  // Place the visible section of the current memory onto the screen.
-
-  SetBoldColor(COLOR_WHITE);
-  if (info.GetPauseLevel() == PAUSE_OFF) {
-    // If not paused, then set user desired offset to zero AND always show
-    // the code that is executing (ie. do not show original Parasite code if
-    // host is executing)
-    memory_offset = 0;
-    parasite_zoom = false;
-  }
-
-  Print(14, 69, "%10d", info.GetActiveGenotypeID());
-  Print(15, 69, "%10s", info.GetActiveName()());
-
-  cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
-  Print(17, 69, "%10d", phenotype.GetCurNumErrors());
-  Print(18, 69, "%10d", phenotype.GetNumDivides());
-  if (info.GetThreadLock() != -1) Print(19, 67, "LOCKED");
-  else Print(19, 67, "      ");
-  Print(19, 74, "%2d/%2d", hardware.GetCurThread() + 1,
-	hardware.GetNumThreads());
-
+  Print(19, 74, "%2d/%2d", hardwareCPU.GetCurThread() + 1,
+	hardwareCPU.GetNumThreads());
+  
   // This line gets the creature that is currently executing. Usually the
   // creature we are viewing, but can also be a different one (if this is a
   // parasite).
-
+  
   const cCPUMemory & memory = (parasite_zoom) ?
-    hardware.GetMemory() : hardware.IP().GetMemory();
+    hardware.GetMemory() : hardwareCPU.IP().GetMemory();
   SetColor(COLOR_WHITE);
   Print(MEMORY_Y + 1, MEMORY_X + 9, "%4d", memory.GetSize());
-
-
+  
+  
+  
   // Nothing past this point gets executed for empty creatures....
   if (memory.GetSize() == 0) {
     for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
@@ -537,12 +750,12 @@
     }
     return;
   }
-
+  
   int adj_inst_ptr = 0;
-  int base_inst_ptr = hardware.IP().GetPosition();
+  int base_inst_ptr = hardwareCPU.IP().GetPosition();
   if (base_inst_ptr < 0 || parasite_zoom == true) base_inst_ptr = 0;
 
-  const cInstSet & inst_set = hardware.GetInstSet();
+  const cInstSet & inst_set = hardwareCPU.GetInstSet();
 
   // Determine the center (must be between 0 and size - 1)
   int center_pos = (base_inst_ptr + memory_offset) % memory.GetSize();
@@ -601,40 +814,156 @@
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 27, "Bp");
       }
 
-      if (adj_inst_ptr == hardware.GetHead(HEAD_READ).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_READ).GetPosition()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 30, "R");
       }
-      if (adj_inst_ptr == hardware.GetHead(HEAD_WRITE).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_WRITE).GetPosition()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 31, "W");
       }
-      if (adj_inst_ptr == hardware.GetHead(HEAD_FLOW).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_FLOW).GetPosition()) {
 	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 32, "F");
       }
     }
-
     SetColor(COLOR_WHITE);
   }
 
   DrawMiniMap();
+}
 
-  const cString & cur_fault = phenotype.GetFault();
-  if (cur_fault.GetSize() > 0) {
-    SetBoldColor(COLOR_RED);
-    Print(FAULT_Y, FAULT_X, "Fault:");
-    SetBoldColor(COLOR_CYAN);
-    Print(FAULT_Y, FAULT_X + 7, cur_fault());
-  } else {
-    Print(FAULT_Y, FAULT_X, "                                        ");
+void cZoomScreen::UpdateCPU_4Stack(cHardwareBase & hardware)
+{
+  cHardware4Stack & hardware4Stack = (cHardware4Stack &) hardware;
+  hardware4Stack.SetThread(cur_view_thread);
+
+  // Place the registers onto the screen.
+  SetBoldColor(COLOR_CYAN);
+  for (int i = 0; i < 4; i++) {
+    Print(REG_Y+2 + i, REG_X+6, "%11d", hardware4Stack.Stack(i).Top());
   }
 
-  SetBoldColor(COLOR_WHITE);
+  // Place the active stack onto the screen.
 
-  Print(13, 70, "[%3d,%3d] ",
-	info.GetActiveID() % population.GetWorldX(),
-	info.GetActiveID() / population.GetWorldY());
+  // Stack AX
+  //SetBoldColor(COLOR_CYAN);   // -Redundant
+  SetColor(COLOR_WHITE);
+  
+  Print(STACK_Y, STACK_X + 2, "Stack   :");
+  Print(STACK_Y, STACK_X + 8, "%s" , hardware4Stack.GetActiveStackID(cur_stack)());
 
-  SetBoldColor(COLOR_CYAN);
-  Refresh();
+  //SetBoldColor(COLOR_CYAN);
+  Print(STACK_Y+2, STACK_X + 2, "%11d", hardware4Stack.GetStack(0, cur_stack));
+  SetColor(COLOR_CYAN);
+  for (int i = 1; i <= 3; i++) {
+    Print(STACK_Y+2 + i, STACK_X+2, "%11d", hardware4Stack.GetStack(i, cur_stack));
+   }
+
+  Print(19, 74, "%2d/%2d", hardware4Stack.GetCurThread() + 1,
+	hardware4Stack.GetNumThreads());
+  
+  // This line gets the creature that is currently executing. Usually the
+  // creature we are viewing, but can also be a different one (if this is a
+  // parasite).
+  
+  const cCPUMemory & memory = hardware4Stack.GetMemory(cur_mem_space);
+  SetBoldColor(COLOR_BLUE);
+  Print(MEMORY_Y + 1, MEMORY_X + 8, " Space ");	
+  SetColor(COLOR_WHITE);
+  Print(MEMORY_Y + 1, MEMORY_X + 15, "%2d", cur_mem_space);
+  
+  Print(MEMORY_Y + 1, MEMORY_X + 17, ":");	
+  Print(MEMORY_Y + 1, MEMORY_X + 18, "%4d", memory.GetSize());
+  
+  
+  
+  // Nothing past this point gets executed for empty creatures....
+  if (memory.GetSize() == 0) {
+    for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
+      HLine(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, 36);
+    }
+    return;
+  }
+  
+  int adj_inst_ptr = 0;
+  int base_inst_ptr = hardware4Stack.IP().GetPosition();
+  if (base_inst_ptr < 0 || parasite_zoom == true) base_inst_ptr = 0;
+
+  const cInstSet & inst_set = hardware4Stack.GetInstSet();
+
+  // Determine the center (must be between 0 and size - 1)
+  int center_pos = (base_inst_ptr + memory_offset) % memory.GetSize();
+  if (center_pos < 0) center_pos += memory.GetSize();
+
+  for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
+    adj_inst_ptr = (center_pos + i) % (memory.GetSize() + 1);
+    if (adj_inst_ptr < 0) adj_inst_ptr += memory.GetSize() + 1;
+
+    if (adj_inst_ptr == memory.GetSize()) {
+      HLine(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, 36);
+    } else {
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, CHAR_VLINE);
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 35, CHAR_VLINE);
+
+      // If we are on the instruction about to be executed by the CPU,
+      // hilight it...
+      if (adj_inst_ptr == base_inst_ptr && 
+	  hardware4Stack.IP().GetMemSpace() == cur_mem_space) {
+	SetBoldColor(COLOR_WHITE);
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 1, "%3d: ",
+		  adj_inst_ptr);
+	SetBoldColor(COLOR_CYAN);
+      } else {
+	if (i == 0) SetBoldColor(COLOR_YELLOW);
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 1, "%3d: ",
+		  adj_inst_ptr);
+	// If we are scrolling through memory, make the current position
+	// yellow.
+	if (i == 0) SetColor(COLOR_YELLOW);
+	else SetColor(COLOR_CYAN);
+      }
+
+      // Print the instruction...
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 6, "%8s ",
+	    inst_set.GetName( memory[adj_inst_ptr] )());
+
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 15,
+         "                    ");
+
+      // Only list the "Cpy" flag or the "Inj" flag...
+      if (memory.FlagCopied(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 16, "Cpy");
+      }
+      if (memory.FlagInjected(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 16, "Inj");
+      }
+
+      // Other flags we're interested in...
+      if (memory.FlagMutated(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 20, "Mut");
+	}
+      if (memory.FlagExecuted(adj_inst_ptr) == true) {
+	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 24, "Exe");
+      }
+      if (memory.FlagBreakpoint(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 28, "Bp");
+      }
+
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_READ).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_READ).GetMemSpace()) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 31, "R");
+      }
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_WRITE).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_WRITE).GetMemSpace()) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 32, "W");
+      }
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_FLOW).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_FLOW).GetMemSpace()) {
+	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 33, "F");
+      }
+    }
+    SetColor(COLOR_WHITE);
+  }
+
+  DrawMiniMap();
 }
 
 void cZoomScreen::UpdateGenotype()
@@ -1064,15 +1393,40 @@
   case ZOOM_SECTION_MEMORY:
     return cCoords(MEMORY_X, MEMORY_Y);
     break;
+
   case ZOOM_SECTION_REGISTERS:
-    return cCoords(REG_X, REG_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      return cCoords(REG_X, REG_Y);
+    }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(REG_X, REG_Y-1);
+      }
     break;
+    
   case ZOOM_SECTION_STACK:
-    return cCoords(STACK_X, STACK_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	return cCoords(STACK_X, STACK_Y);
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(STACK_X, STACK_Y-1);
+      }
     break;
+
   case ZOOM_SECTION_INPUTS:
-    return cCoords(INPUT_X, INPUT_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	return cCoords(INPUT_X, INPUT_Y);
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(INPUT_X, INPUT_Y-1);
+      }
     break;
+    
   case ZOOM_SECTION_MAP:
     return cCoords(MINI_MAP_X, MINI_MAP_Y);
     break;
@@ -1085,17 +1439,35 @@
 {
   switch (in_section) {
   case ZOOM_SECTION_MEMORY:
-    return cString("Memory");
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return cString("Memory");
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cString("Memory Space");
+      }
     break;
+
   case ZOOM_SECTION_REGISTERS:
-    return cString("Registers");
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return cString("Registers:");
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cString("Stacks:");
+      }
     break;
+
   case ZOOM_SECTION_STACK:
-    return cString("Stack");
+    return cString("Stack ");
     break;
+
   case ZOOM_SECTION_INPUTS:
-    return cString("Inputs");
+    return cString("Inputs:");
     break;
+
   case ZOOM_SECTION_MAP:
     return cString("Mini-Map");
     break;
@@ -1132,10 +1504,15 @@
   if (mode == ZOOM_MODE_STATS    && DoInputStats(in_char)) return;
   if (mode == ZOOM_MODE_GENOTYPE && DoInputGenotype(in_char)) return;
 
+  cHardware4Stack & hardware4Stack = 
+      (cHardware4Stack &) info.GetActiveCell()->GetOrganism()->GetHardware();
+
   switch(in_char) {
   case 't':
   case 'T':
-    ThreadOptions();
+    cur_view_thread=(cur_view_thread+1)%hardware4Stack.GetNumThreads();
+    //ThreadOptions();
+    Update();
     break;
 
   /*
@@ -1214,15 +1591,23 @@
     break;
   case '6':
   case KEY_RIGHT:
-    if (active_section == ZOOM_SECTION_MAP) {
-      mini_center_id++;
-      if (mini_center_id == population.GetSize()) mini_center_id = 0;
-      if (population.GetCell(mini_center_id).IsOccupied()) {
-	memory_offset = 0;
-	info.SetActiveCell( &(population.GetCell(mini_center_id)));
+    if (active_section == ZOOM_SECTION_MAP) 
+      {
+	mini_center_id++;
+	if (mini_center_id == population.GetSize()) mini_center_id = 0;
+	if (population.GetCell(mini_center_id).IsOccupied()) {
+	  memory_offset = 0;
+	  info.SetActiveCell( &(population.GetCell(mini_center_id)));
+	}
       }
-      Update();
-    }
+    else if (active_section == ZOOM_SECTION_MEMORY)
+      {
+	if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+	  {
+	    cur_mem_space=(cur_mem_space+1)%4;
+	  }
+      }
+    Update(); 
     break;
   case '4':
   case KEY_LEFT:
@@ -1233,9 +1618,32 @@
 	memory_offset = 0;
 	info.SetActiveCell( &(population.GetCell(mini_center_id)));
       }
-      Update();
     }
+    else if (active_section == ZOOM_SECTION_MEMORY) {
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+	{
+	  cur_mem_space--;
+	  if(cur_mem_space<0)
+	    cur_mem_space=3;
+	}
+    }
+    Update();
+    break;
+  case 'K':
+  case 'k':
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK) {
+      cur_stack=(cur_stack+1)%4;
+    }
+    Update();
     break;
+    //case '<':
+    // if(hardware_type==HARDWARE_TYPE_CPU_4STACK)
+    //  {
+    //cur_stack=(cur_stack-1);
+    //if(cur_stack<0) cur_stack=3;
+    //}
+    //Update();
+    //break;
   case '+':
   case '=':
     ++map_mode %= NUM_MAPS;
Index: avida/current/source/viewers/zoom_screen.hh
diff -u avida/current/source/viewers/zoom_screen.hh:1.7 avida/current/source/viewers/zoom_screen.hh:1.8
--- avida/current/source/viewers/zoom_screen.hh:1.7	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/zoom_screen.hh	Thu Jun  5 13:14:42 2003
@@ -72,13 +72,22 @@
   bool parasite_zoom; // If true, then view original parasite code, not host
   int active_section;
   int task_offset;
+  //int hardware_type;
+  int cur_stack;
+  int cur_mem_space;
+  int cur_view_thread;
 
 private:
-  void DrawCPU();
+  void DrawCPU_Original();
+  void DrawCPU_4Stack();
   void DrawStats();
   void DrawGenotype();
-  void UpdateCPU();
-  void UpdateStats();
+  void UpdateCPU(cHardwareBase & hardware);
+  void UpdateCPU_Original(cHardwareBase & hardware);
+  void UpdateCPU_4Stack(cHardwareBase & hardware);
+  void UpdateStats(cHardwareBase & hardware);
+  void UpdateStats_CPU(cHardwareBase & hardware);
+  void UpdateStats_4Stack(cHardwareBase & hardware);
   void UpdateGenotype();
 
   void EditMemory();


More information about the Avida-cvs mailing list