/*  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.
 */

#ifndef __PROGRAM_RC_H__
#define __PROGRAM_RC_H__

#include "program.h"

#define RC_MAX_FOR_COUNT 1000

#define RC_CMD_DAT	0
#define RC_CMD_MOV	1
#define RC_CMD_ADD	2
#define RC_CMD_SUB	3
#define RC_CMD_MUL	4
#define RC_CMD_DIV	5
#define RC_CMD_MOD	6
#define RC_CMD_JMP	7
#define RC_CMD_JMZ	8
#define RC_CMD_JMN	9
#define RC_CMD_DJN	10
#define RC_CMD_CMP	11
#define RC_CMD_SEQ	11
#define RC_CMD_SLT	12
#define RC_CMD_SPL	13
#define RC_CMD_SNE	14
#define RC_CMD_NOP	15
#define RC_CMD_IJZ	16
#define RC_CMD_MASK	0x1f

#define RC_MOD_NONE	(0 << 5)
#define RC_MOD_A	(1 << 5)
#define RC_MOD_B	(2 << 5)
#define RC_MOD_AB	(3 << 5)
#define RC_MOD_BA	(4 << 5)
#define RC_MOD_F	(5 << 5)
#define RC_MOD_X	(6 << 5)
#define RC_MOD_I	(7 << 5)
#define RC_MOD_MASK	(0x7 << 5)
#define RC_MOD_SHIFT	5

#define RC_AM_A_NONE		(0 << 8)
#define RC_AM_A_IMMEDIATE	(1 << 8) 
#define RC_AM_A_DIRECT		(2 << 8)
#define RC_AM_A_INDIRECT_B	(3 << 8)
#define RC_AM_A_PRE_DEC_B	(4 << 8)
#define RC_AM_A_POST_INC_B	(5 << 8)
#define RC_AM_A_PRE_DEC_A	(6 << 8)
#define RC_AM_A_POST_INC_A	(7 << 8)
#define RC_AM_A_INDIRECT_A	(8 << 8)
#define RC_AM_A_MASK		(0xf << 8)
#define RC_AM_A_SHIFT		8

#define RC_AM_B_NONE		(0 << 12)
#define RC_AM_B_IMMEDIATE	(1 << 12) 
#define RC_AM_B_DIRECT		(2 << 12)
#define RC_AM_B_INDIRECT_B	(3 << 12)
#define RC_AM_B_PRE_DEC_B	(4 << 12)
#define RC_AM_B_POST_INC_B	(5 << 12)
#define RC_AM_B_PRE_DEC_A	(6 << 12)
#define RC_AM_B_POST_INC_A	(7 << 12)
#define RC_AM_B_INDIRECT_A	(8 << 12)
#define RC_AM_B_MASK		(0xf << 12)
#define RC_AM_B_SHIFT		12

#define RC_AM_A_TO_B		(RC_AM_B_SHIFT-RC_AM_A_SHIFT)

union rc_operand {
  int number;
  struct expr* expr;
} ;

struct rc_command {
  unsigned int command;
  union rc_operand a, b;
} ;

struct cell;

void rc_dump_instruction (struct rc_command *pr);
void rc_dump_program (struct program *pr);
void rc_dump_program_internal (struct program *pr);
int rc_load_program (struct program *pr);
void rc_free_program (struct program *pr);

#endif
