/*  Core Wars.
 *  Copyright (C) 1999  Walter Hofmann
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as 
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkprivate.h>
#include <limits.h>

#include "main.h"
#include "main-gui.h"
#include "program.h"
#include "program-cw.h"
#include "execute.h"
#include "execute-cw.h"
#include "statistic.h"
#include "pstatistic.h"
#include "options.h"
#include "tournament.h"

#define FOLD(x) ((x)<SIZE?(x):(x)-SIZE)

void rc_execute_step ()
{
  struct process *p;
  struct thread *t, *t2;
  int remove;
  int i;
  struct rc_command IR, IRA, IRB;
  int PA, PB;
  int PIP;
  int pc;

  for (i=0; i<process_count; i++)
    {
      p = process_array+i;
      if (p->thread)
	{
	  remove = FALSE;
	  t = p->thread;
	  p->thread = t->next;
	  pc = t->pc;
	  mark_inactive (pc);

	  IR = memory[pc].content.command; 

	  switch (IR.command & RC_AM_A_MASK)
	    {
	    case RC_AM_A_IMMEDIATE:
	      PA = 0;
	      IRA = memory[pc].content.command;
	      break;
	    case RC_AM_A_DIRECT:
	      PA = IR.a.number;
	      IRA = memory[FOLD(pc+PA)].content.command;
	      break;
	    case RC_AM_A_PRE_DEC_A:
	      PA = IR.a.number;
	      if (!memory[FOLD(pc+PA)].content.command.a.number--)
		memory[FOLD(pc+PA)].content.command.a.number = SIZE-1;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PA), p);
	      mark (FOLD(pc+PA), FALSE);
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.a.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      break;
	    case RC_AM_A_PRE_DEC_B:
	      PA = IR.a.number;
	      if (!memory[FOLD(pc+PA)].content.command.b.number--)
		memory[FOLD(pc+PA)].content.command.b.number = SIZE-1;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PA), p);
	      mark (FOLD(pc+PA), FALSE);
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.b.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      break;
	    case RC_AM_A_POST_INC_A:
	      PA = IR.a.number;
	      PIP = FOLD(pc+PA);
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.a.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      if (++memory[PIP].content.command.a.number==SIZE)
		memory[PIP].content.command.a.number = 0;
	      MEMORY_CHANGE_OWNER_INDEX (PIP, p);
	      mark (PIP, FALSE);
	      break;
	    case RC_AM_A_POST_INC_B:
	      PA = IR.a.number;
	      PIP = FOLD(pc+PA);
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.b.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      if (++memory[PIP].content.command.b.number==SIZE)
		memory[PIP].content.command.b.number = 0;
	      MEMORY_CHANGE_OWNER_INDEX (PIP, p);
	      mark (PIP, FALSE);
	      break;
	    case RC_AM_A_INDIRECT_A:
	      PA = IR.a.number;
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.a.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      break;
	    case RC_AM_A_INDIRECT_B:
	      PA = IR.a.number;
	      PA = FOLD(memory[FOLD(pc+PA)].content.command.b.number+PA);
	      IRA = memory[FOLD(pc+PA)].content.command;
	      break;
	    }

	  switch (IR.command & RC_AM_B_MASK)
	    {
	    case RC_AM_B_IMMEDIATE:
	      PB = 0;
	      IRB = memory[pc].content.command;
	      break;
	    case RC_AM_B_DIRECT:
	      PB = IR.b.number;
	      IRB = memory[FOLD(pc+PB)].content.command;
	      break;
	    case RC_AM_B_PRE_DEC_A:
	      PB = IR.b.number;
	      if (!memory[FOLD(pc+PB)].content.command.a.number--)
		memory[FOLD(pc+PB)].content.command.a.number = SIZE-1;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.a.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      break;
	    case RC_AM_B_PRE_DEC_B:
	      PB = IR.b.number;
	      if (!memory[FOLD(pc+PB)].content.command.b.number--)
		memory[FOLD(pc+PB)].content.command.b.number = SIZE-1;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.b.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      break;
	    case RC_AM_B_POST_INC_A:
	      PB = IR.b.number;
	      PIP = FOLD(pc+PB);
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.a.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      if (++memory[PIP].content.command.a.number==SIZE)
		memory[PIP].content.command.a.number = 0;
	      MEMORY_CHANGE_OWNER_INDEX (PIP, p);
	      mark (PIP, FALSE);
	      break;
	    case RC_AM_B_POST_INC_B:
	      PB = IR.b.number;
	      PIP = FOLD(pc+PB);
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.b.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      if (++memory[PIP].content.command.b.number==SIZE)
		memory[PIP].content.command.b.number = 0;
	      MEMORY_CHANGE_OWNER_INDEX (PIP, p);
	      mark (PIP, FALSE);
	      break;
	    case RC_AM_B_INDIRECT_A:
	      PB = IR.b.number;
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.a.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      break;
	    case RC_AM_B_INDIRECT_B:
	      PB = IR.b.number;
	      PB = FOLD(memory[FOLD(pc+PB)].content.command.b.number+PB);
	      IRB = memory[FOLD(pc+PB)].content.command;
	      break;
	    }

	  switch (IR.command & RC_CMD_MASK)
	    {
	    case RC_CMD_DAT:
	      remove = TRUE;
	      break;
	    case RC_CMD_MOV:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		  memory[FOLD(pc+PB)].content.command.a.number = IRA.a.number;
		  break;
		case RC_MOD_B:
		  memory[FOLD(pc+PB)].content.command.b.number = IRA.b.number;
		  break;
		case RC_MOD_AB:
		  memory[FOLD(pc+PB)].content.command.b.number = IRA.a.number;
		  break;
		case RC_MOD_BA:
		  memory[FOLD(pc+PB)].content.command.a.number = IRA.b.number;
		  break;
		case RC_MOD_F:
		  memory[FOLD(pc+PB)].content.command.a.number = IRA.a.number;
		  memory[FOLD(pc+PB)].content.command.b.number = IRA.b.number;
		  break;
		case RC_MOD_X:
		  memory[FOLD(pc+PB)].content.command.b.number = IRA.a.number;
		  memory[FOLD(pc+PB)].content.command.a.number = IRA.b.number;
		  break;
		case RC_MOD_I:
		  memory[FOLD(pc+PB)].content.command = IRA;
		  memory[FOLD(pc+PB)].contains_code = 
		    (memory[FOLD(pc+PB)].content.command.command & RC_CMD_MASK)!=RC_CMD_DAT;
		  break;
		}      
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
#define ARITH(op)\
	      do switch (IR.command & RC_MOD_MASK)\
		{\
		case RC_MOD_A:\
		  memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.a.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_B:\
		  memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_AB:\
		  memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.a.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_BA:\
		  memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_F:\
		case RC_MOD_I:\
		  memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.a.number+SIZE) % SIZE;\
		  memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_X:\
		  memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.a.number+SIZE) % SIZE;\
		  memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		} while (0)
#define ARITH_DIV(op)\
	      do switch (IR.command & RC_MOD_MASK)\
		{\
		case RC_MOD_A:\
                  if (IRA.a.number)\
		    memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.a.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_B:\
                  if (IRA.b.number)\
		    memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_AB:\
                  if (IRA.a.number)\
		    memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.a.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_BA:\
                  if (IRA.b.number)\
		    memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_F:\
		case RC_MOD_I:\
                  if (IRA.a.number)\
		    memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.a.number+SIZE) % SIZE;\
                  if (IRA.b.number)\
		    memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		case RC_MOD_X:\
                  if (IRA.a.number)\
		    memory[FOLD(pc+PB)].content.command.b.number = (IRB.b.number op IRA.a.number+SIZE) % SIZE;\
                  if (IRA.b.number)\
		    memory[FOLD(pc+PB)].content.command.a.number = (IRB.a.number op IRA.b.number+SIZE) % SIZE;\
		  break;\
		} while (0)
#define ARITH_FOLD(op,of)\
	      do switch (IR.command & RC_MOD_MASK)\
		{\
		case RC_MOD_A:\
		  memory[FOLD(pc+PB)].content.command.a.number = FOLD(IRB.a.number op IRA.a.number+of);\
		  break;\
		case RC_MOD_B:\
		  memory[FOLD(pc+PB)].content.command.b.number = FOLD(IRB.b.number op IRA.b.number+of);\
		  break;\
		case RC_MOD_AB:\
		  memory[FOLD(pc+PB)].content.command.b.number = FOLD(IRB.b.number op IRA.a.number+of);\
		  break;\
		case RC_MOD_BA:\
		  memory[FOLD(pc+PB)].content.command.a.number = FOLD(IRB.a.number op IRA.b.number+of);\
		  break;\
		case RC_MOD_F:\
		case RC_MOD_I:\
		  memory[FOLD(pc+PB)].content.command.a.number = FOLD(IRB.a.number op IRA.a.number+of);\
		  memory[FOLD(pc+PB)].content.command.b.number = FOLD(IRB.b.number op IRA.b.number+of);\
		  break;\
		case RC_MOD_X:\
		  memory[FOLD(pc+PB)].content.command.b.number = FOLD(IRB.b.number op IRA.a.number+of);\
		  memory[FOLD(pc+PB)].content.command.a.number = FOLD(IRB.a.number op IRA.b.number+of);\
		  break;\
		} while (0)
#define ZEROCHECK\
	      do switch (IR.command & RC_MOD_MASK)\
		{\
		case RC_MOD_A:\
		case RC_MOD_AB:\
		  if (!IRA.a.number)\
		    remove = TRUE;\
		  break;\
		case RC_MOD_B:\
		case RC_MOD_BA:\
		  if (!IRA.b.number)\
		    remove = TRUE;\
		  break;\
		case RC_MOD_F:\
		case RC_MOD_I:\
		case RC_MOD_X:\
		  if (!IRA.a.number || !IRA.b.number)\
		    remove = TRUE;\
		  break;\
		} while (0)
	    case RC_CMD_ADD:
	      ARITH_FOLD (+, 0);
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
	    case RC_CMD_SUB:
	      ARITH_FOLD (-, SIZE);
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
	    case RC_CMD_MUL:
	      ARITH (*);
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
	    case RC_CMD_DIV:
	      ARITH_DIV (/);
	      ZEROCHECK;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
	    case RC_CMD_MOD:
	      ARITH_DIV (%);
	      ZEROCHECK;
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p);
	      mark (FOLD(pc+PB), FALSE);
	      break;
	    case RC_CMD_JMP:
	      pc += PA-1; /* will FOLD later! */
	      break;
	    case RC_CMD_JMZ:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		case RC_MOD_BA:
		  if (IRB.a.number==0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		case RC_MOD_AB:
		  if (IRB.b.number==0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		case RC_MOD_X:
		case RC_MOD_I:
		  if (IRB.a.number==0 && IRB.b.number==0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_JMN:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		case RC_MOD_BA:
		  if (IRB.a.number!=0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		case RC_MOD_AB:
		  if (IRB.b.number!=0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		case RC_MOD_X:
		case RC_MOD_I:
		  if (IRB.a.number!=0 || IRB.b.number!=0)
		    pc += PA-1; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_IJZ:
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p); /* do this first as pc can change */
	      mark (FOLD(pc+PB), FALSE);
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		case RC_MOD_BA:
		  if (++memory[FOLD(pc+PB)].content.command.a.number==SIZE)
		    memory[FOLD(pc+PB)].content.command.a.number = 0;
		  if (IRB.a.number!=-1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		case RC_MOD_AB:
		  if (++memory[FOLD(pc+PB)].content.command.b.number==SIZE)
		    memory[FOLD(pc+PB)].content.command.b.number = 0;
		  if (IRB.b.number!=-1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		case RC_MOD_X:
		case RC_MOD_I:
		  if (++memory[FOLD(pc+PB)].content.command.a.number==SIZE)
		    memory[FOLD(pc+PB)].content.command.a.number = 0;
		  if (++memory[FOLD(pc+PB)].content.command.b.number==SIZE)
		    memory[FOLD(pc+PB)].content.command.b.number = 0;
		  if (IRB.a.number!=-1 || IRB.b.number!=-1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_DJN:
	      MEMORY_CHANGE_OWNER_INDEX (FOLD(pc+PB), p); /* do this first as pc can change */
	      mark (FOLD(pc+PB), FALSE);
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		case RC_MOD_BA:
		  if (!memory[FOLD(pc+PB)].content.command.a.number--) 
		    memory[FOLD(pc+PB)].content.command.a.number = SIZE-1;
		  if (IRB.a.number!=1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		case RC_MOD_AB:
		  if (!memory[FOLD(pc+PB)].content.command.b.number--) 
		    memory[FOLD(pc+PB)].content.command.b.number = SIZE-1;
		  if (IRB.b.number!=1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		case RC_MOD_X:
		case RC_MOD_I:
		  if (!memory[FOLD(pc+PB)].content.command.a.number--) 
		    memory[FOLD(pc+PB)].content.command.a.number = SIZE-1;
		  if (!memory[FOLD(pc+PB)].content.command.b.number--) 
		    memory[FOLD(pc+PB)].content.command.b.number = SIZE-1;
		  if (IRB.a.number!=1 || IRB.b.number!=1)
		    pc += PA-1; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_SEQ:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		  if (IRA.a.number==IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		  if (IRA.b.number==IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_AB:
		  if (IRA.a.number==IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_BA:
		  if (IRA.b.number==IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		  if (IRA.a.number==IRB.a.number && IRA.b.number==IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_X:
		  if (IRA.a.number==IRB.b.number && IRA.b.number==IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_I:
		  if (IRA.command==IRB.command && IRA.a.number==IRB.a.number && IRA.b.number==IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_SNE:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		  if (IRA.a.number!=IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		  if (IRA.b.number!=IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_AB:
		  if (IRA.a.number!=IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_BA:
		  if (IRA.b.number!=IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		  if (IRA.a.number!=IRB.a.number || IRA.b.number!=IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_X:
		  if (IRA.a.number!=IRB.b.number || IRA.b.number!=IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_I:
		  if (IRA.command!=IRB.command || IRA.a.number!=IRB.a.number || IRA.b.number!=IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_SLT:
	      switch (IR.command & RC_MOD_MASK)
		{
		case RC_MOD_A:
		  if (IRA.a.number<IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_B:
		  if (IRA.b.number<IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_AB:
		  if (IRA.a.number<IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_BA:
		  if (IRA.b.number<IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_F:
		case RC_MOD_I:
		  if (IRA.a.number<IRB.a.number && IRA.b.number<IRB.b.number)
		    pc++; /* will FOLD later! */
		  break;
		case RC_MOD_X:
		  if (IRA.a.number<IRB.b.number && IRA.b.number<IRB.a.number)
		    pc++; /* will FOLD later! */
		  break;
		}      
	      break;
	    case RC_CMD_SPL:
	      if (p->thread_count<MAX_THREADS)
		{
		  t2 = malloc (sizeof (struct thread));
		  t2->next = t->next;
		  t2->prev = t;
		  t->next = t2;
		  t2->next->prev = t2;
		  t2->pc = FOLD(pc+PA);
		  p->thread_count++;
		  thread_count++;
		  mark_active (t2->pc, p);
		}
	      break;
	    case RC_CMD_NOP:
	      break;
	    }
	  if (remove)
	    {
	      p->thread_count--;
	      thread_count--;
	      if (t==t->next)
		{
		  if (memory[pc].owner && memory[pc].owner!=p)
		    memory[pc].owner->kill_count++;
		  free (t);
		  p->thread = NULL;
		  p->death_time = elapsed_time;
		  process_alive--;
		}
	      else
		{
		  t->prev->next = t->next;
		  t->next->prev = t->prev;
		  free (t); /* We assume p->thread != t here. This can only be wrong after
			       SPL, but then remove will be zero anyway.*/
		}
	    }
	  else
	    {
	      pc = FOLD(pc+1); /* We MUST use FOLD here! */
	      mark_active (pc, p);
	      t->pc = pc;
	    }
	}
    }
  elapsed_time++;
#ifndef CMD_LINE
  if (elapsed_time==MAX_CYCLES || !thread_count || (STOP_EARLY && process_alive==1 && process_count>1))
    if (tournament_running)
      tournament_finished_game ();
    else
      execute_stop();
#endif
}

void rc_create_process_cmd (struct program *p, struct process *pr, int position)
{
  int i,j;

  pr->program = p;

  pr->thread = malloc (sizeof (struct thread));
  pr->thread->next = pr->thread;
  pr->thread->prev = pr->thread;
  pr->cell_count = 0;
  pr->kill_count = 0;
  i = position;
  pr->thread->pc = (i+p->lang.rc.org+SIZE) % SIZE;
  for (j=0; j<p->lang.rc.size; j++, i = (i+1) % SIZE)
    {
      MEMORY_CHANGE_OWNER_INDEX (i, pr);
      memory[i].content.command.command = p->lang.rc.obj[j].command;
      memory[i].content.command.a.number = (p->lang.rc.obj[j].a.number % SIZE + SIZE) % SIZE;
      memory[i].content.command.b.number = (p->lang.rc.obj[j].b.number % SIZE + SIZE) % SIZE;
      memory[i].contains_code = (memory[i].content.command.command & RC_CMD_MASK)!=RC_CMD_DAT;
      mark (i, FALSE);
    }
  pr->thread_count = 1;
  pr->death_time = INT_MAX;
  mark_active (pr->thread->pc, pr);
  thread_count++;
}
