[comp.misc] Core War standards

snroettg@faui09.informatik.uni-erlangen.de (Stefan Roettger) (02/12/91)

Hi friends!
Here are the Core War standards as promised.


Foreword:
In a Core War battle two programs written in the 
pseudo-assembly language REDCODE are run against each other 
on a simulation enviroment called MARS (Memory Array 
Redcode Simulator). The aim of each program is to bomb its 
opponent. Obviously the Warrior that survives and kills its 
foe first is the winner. The thrill of the game is, that 
many possible strategies such as defensive, self-repairing, 
small-but-quick and others can be programmed and of course 
it's great fun to compare your own warriors with those of 
your friends!

Disclaimer: Core War is not in the slightest way viruslike!



          The Core War Standards '88

                Proposed by
      The International Core War Society
               July 30, 1990
                  (Draft)

From the Redcode programmer's point of view, MARS is 
composed of four primary units: a read/write memory (RAM), 
a computing unit (ALU), two process cues (FIFO's), and the 
control unit (CU). There are no registers visible to the 
programmer; that is, memory is the only storage available 
for both instructions and data.

RAM: All Redcode instructions occupy exactly one memory 
location. Adressing in Redcode is relative, so it is best 
to think of memory as being composed as a circular list; an 
instructions that references memory adress zero is 
referring to itself. Every RAM location is initialised to 
the data pattern which corresponds to the instruction
'DAT 0 0' before loading any Core War Programs (elsewhere 
referred to as "warriors").

FIFO: A game of Core War is played by pitting two Redcode 
programs against eachother. Each attempts to force the 
other to fail by causing it to execute a "halt" 
instruction, (the DAT). During each machine cycle one 
instruction from each program is executed, always in the 
same order. It is thus necessary to maintain a program 
counter for each side. This is the purpose of the process 
queues. As will be seen, each side may consist of more than 
one process. This is why a FIFO and not a single register 
is necessary for each side. There are no upper or lower 
limits to the size of the FIFO's, save the minimum of one 
each, as battles cannot occur with less than two Core War 
programs.

ALU: The computing unit performs all the arithmetic and 
logical operations required by the Redcode instruction set, 
and the Control Unit, such as adding two operands or 
incrementing a program counter.

CU: As in any processor, the control unit has the 
responsibility of fetching, decoding and executing 
instructions. The control unit must also provide an 
interface to the MARS supervisor function (ZEUS). The 
supervisor may provide various support functions such as a 
Redcode debugger, graphics display, parameter control, 
etc., and is highly implementation specific.

Instruction Format:

A Redcode instruction has three fields: the opcode field 
and two operand fields, denoted as A and B. the contents of 
the opcode field specify the operation to be performed, and 
the adressing modes to be used in evaluating the operands. 
The operand fields may contain any number from zero to the 
memory size minus one. Currently, eleven Redcode 
instructions are defined. They are listed below, with a 
mnemonic and a short description for each.

DAT A B : remove executing process from process queue
MOV A B : move A to B
ADD A B : add A to B
SUB A B : subtract A from B
JMP A B : jump to A
JMZ A B : jump to A if B is zero
JMN A B : jump to A if B is not zero
CMP A B : if A equals B then skip the next instruction
SLT A B : if A is less than B then skip next instruction
DJN A B : decrement B; if B is not zero then jump to A
SPL A B : place A in the process queue

Adressing Modes:

There are currently four adressing modes defined: 
immediate, direct, indirect, and predecrement-indirect.
The default mode is direct. If no modifier symbol precedes 
an operand, the value of the operand is used as an offset 
from the memory location from which it was fetched. The 
resulting memory location is the source and/or destination 
of the data to be used by the instruction, or else is the 
destination for branching instructions.
An octothorpe (#) is used to introduce an immediate 
operand. The commemcial at sign (@) is used to introduce an 
indirect operand. The value of the operand is used as an 
offset, as it is with direct adressing. The B operand of 
the resulting memory adress is then used as an offset from 
the memory location from which it was fetched.
The less than sign (<) is used to introduce a predecrement 
indirect operand. The action is the same as with @ with the 
difference that the specified memory location is first 
decremented and then afterwards used as a pointer.

All theory is grey, here are some REDCODE examples:
(Mostly 8000 or 8192 is used as Core size and 20000-30000
as instruction maximum)

; Warrior Gnom

l: MOV p @p
   ADD #4 p
   JMP l
p: DAT p


; Warrior KISS

l:  MOV b1 <p
    MOV b2 <p
    JMN l p
    MOV #-16 p
z:  MOV k <p
    JMN z p
    MOV #-16 p
    JMP l
b1: JMP -1
b2: SPL 0
k:  DAT #0
p:  DAT #-16


; Warrior PLAGUE

   SPL k
   SPL k
l: ADD #24 p
   JMZ l @p
   MOV b @p
   MOV a <p
   ADD #1 p
   JMP l
   DAT #1
   DAT #2
   DAT #3
   DAT #4
p: DAT #5
k: MOV z <z
   JMP k
z: DAT #-16
b: JMP -1
a: SPL 0


So far for now.

If someone is interested in more detailed information about 
the 88 standards or some REDCODE programs I have collected feel
free to contact me.

MfG Stefan