--------------------------------------------------------------------
April 8, 1990
The International Core War Society is a group of individuals who
share a love of the game of Core War as first presented to a large
public by A. K. Dewdney in his March 1984 "Computer Recreations"
column of "Scientific American". The ICWS writes and maintains Core
War standards and sponsors Core War tournaments under those standards.
The two Core War standards published to date are The International
Core War Standard of 1986 (ICWS'86) and The International Core War
Standard of 1988 (ICWS'88).
The following document is NOT the official ICWS'86 or ICWS'88
standard. Those standards are available from the publisher of The
Core War Newsletter - AMRAN, 5712 Kern Drive, Huntington Beach, CA
92649-4535. The Director of The International Core War Society is
William R. Buckley and can be reached at the above address or via
Bitnet at L5USABD@CALSTATE.
I do believe that the following is an accurate and concise
restatement of both ICWS'86 and ICWS'88 and that any system conforming
to these specifications will conform as closely as possible to the
official standards. Feel free to distribute this document. Please
include this header and make no adjustments, additions, or deletions.
I am
Mark A. Durham, PO Box 301173, Houston, TX 77230-1173
Bitnet: DURHAM@RICEVM1, Internet: DUR...@RICEVM1.RICE.EDU
and I am currently editor of The Core War Newsletter. I am also
trying to build enough support to start a newsgroup devoted to Core
War, rec.games.corewar, on USENET.
INTERNATIONAL CORE WAR STANDARD OF 1986
REDCODE
Redcode is the language of Core War.
Syntax
Each Redcode program consists of one or more lines of Redcode. Each
line of Redcode consists of a string of alphanumerals and special
characters. Special characters in Redcode are the addressing mode
indicators '#', '$', '@', and '<', the operand separator (comma) ',',
the comment indicator (semicolon) ';', and the arithmetic operators
'+' and '-'. Also, spaces and tabs (referred to as "blanks") are used
as field separators.
A line may consist of an instruction, a comment, or an instruction
followed by a comment. All comments begin with a semicolon. Each
instruction consists of (in the following order) a label, an opcode,
an A-operand, a comma, and a B-operand. The label is optional. If
either operand is missing (null or blank), the comma may be omitted.
Redcode is case insensitive.
A label is any alphanumeric string one to eight characters in length
beginning with an alphabetic character other than those reserved for
opcodes and pseudo-opcodes. The label is separated from the opcode by
at least one blank. If the first character of an instruction is a
blank, then the instruction is unlabelled.
An opcode is any of the following: DAT, MOV, ADD, SUB, JMP, JMZ, JMN,
DJN, CMP, and SPL. Each operand is null or blank, contains an
address, or contains an addressing mode indicator and an address. An
address consists of any number of labels and numbers separated by
arithmetic operators. Addresses are evaluated from left to right.
Parentheses may not be used.
Pseudo-opcodes are SPACE and END. SPACE N, M instructs the assembler
to skip N lines, then keep M lines on this page when making a list
file of the assembly. END indentifies the end of assembly and takes
no operands (otherwise assembly ends at the end of the file). Some
assemblers may not support these pseudo-opcodes.
Assembly
A Redcode program is assembled into an object code (MARS) program.
Each Redcode instruction assembles into an object code instruction of
five fields: the opcode field, the A-mode field, the A-address field,
the B-mode field, and the B-address field. A missing (null or blank)
mode assembles as '$' does.
Opcodes assemble to a number between zero and ten inclusively. (See
below for mapping). Modes assemble as a number between zero and
three: # = 0, $ = 1, @ = 2, and < = 3.
The address field values are derived from the numbers, labels, and
arithmetic operators contained in the addresses. Labels are converted
to an address relative to the current instruction and the arithmetic
operations are executed from left to right to determine the final
value. Missing (null or blank) operands assemble as #0 does. If
there is one blank operand associated with a DAT or SPL instruction,
the non-blank operand is assembled into the B-address field. For all
other instructions with one blank operand, the non-blank operand is
assembled into the A-address field.
NOTE: Not all systems will have a separate assembler, per se. The
assembler may be incorporated into the loader or the executive (see
below). In the latter case, one would say that the Redcode was being
interpreted rather than assembled. This does not change the behaviour
or the outcome of the game however.
MARS
MARS stands for Memory Array Redcode Simulator. It is the operating
system of Core War.
Execution
MARS consists of a core, a loader, and an executive to execute the
object code. The core consists of a circular list of M object code
instructions, where M is the memory size. Memory size must be at
least 2048 instructions. The initial state of core is unspecified,
but core is usually initially filled with zeroes (DAT�,�).
The loader loads the object code of two specified programs, each into
a distinct contiguous area of core at a random location. All negative
field values N are converted to positive field values P&=&M&+&N. All
field values G greater than or equal to M are converted to field
values L&=&G modulo M.
The executive executes the object code of each program for a specified
number of cycles or until only one program is still executing. Each
cycle, one instruction from one task from each program is executed.
The instruction of the program loaded first executes first. The
instruction of the program loaded second executes second. For each
program, the first instruction executed is the first instruction
loaded. Subsequent execution is controlled by each program. A
program is no longer executing when it no longer has any tasks.
Each program consists of one task initially. Subsequent tasks are
added to the program's task list using the SPL instruction. Up to
sixty-four tasks are allowed for each program. A task is deleted from
the program's task list upon executing a DAT instruction.
In order to execute the object code, the executive fetches the current
instruction from the core and stores it in the instruction register.
It then extracts the following information and stores each in its
associated register: the A-term, the A-pointer, the A-instruction, the
B-term, the B-pointer, and the B-instruction. These terms, pointers,
and instructions are determined by the operands.
In the following paragraphs, all references to the A-mode (B-mode)
mean the value of the A-mode (B-mode) field of the current
instruction. References to the A-address (B-address) of a particular
instruction mean the value of the A-address (B-address) field of said
instruction. All pointers are relative to the current instruction.
All arithmetic is to be done modulo M, with negative values converted
as above (P = M + N).
If the A-mode is immediate (0 = #), the A-pointer is zero. If the A-
mode is relative (1 = $), the A-pointer is a copy of the A-address of
the current instruction. If the A-mode is indirect (@ = 2), the& A-
pointer is the sum of the A-address of the current instruction and
the B-address of the instruction pointed to by the A-address of the
current instruction. If the A-mode is auto-decrement indirect
(3&=&<), the A-pointer is one less than the sum of the A-address of
the current instruction and the B-address of the instruction pointed
to by the A-address of the current instruction.
If the B-mode is immediate (0 = #), the B-pointer is zero. If the&&
B-mode is relative (1 = $), the B-pointer is a copy of the B-address
of the current instruction. If the B-mode is indirect (@ = 2), the&
B-pointer is the sum of the B-address of the current instruction and
the B-address of the instruction pointed to by the B-address of the
current instruction. If the B-mode is auto-decrement indirect
(3&=&<), the B-pointer is one less than the sum of the B-address of
the current instruction and the B-address of the instruction pointed
to by the B-address of the current instruction.
In all modes, the A-instruction is a copy of the instruction pointed
to by the A-pointer. If the A-mode is immediate, the A-term is a copy
of the A-address of the A-instruction. In all other modes, the A-term
is a copy of the B-address of the A-instruction. In all modes, the&
B-instruction is a copy of the instruction pointed to by the B-pointer
and the B-term is a copy of the B-address of the B-instruction.
After both operands have been evaluated, if the A-mode is&&&&&&&&
auto-decrement indirect, then the B-address of the instruction (in
core) pointed to by the A-address of the current instruction (in the
instruction register) is decremented by one. If the B-mode is&&&
auto-decrement indirect, then the B-address of the instruction (in
core) pointed to by the B-address of the current instruction (in the
instruction register) is decremented by one.
The current task's pointer counter is updated such that the next
instruction to execute in the current task is the instruction after
the current instruction. The program's task pointer is updated such
that the next instruction to be executed by this program is the
current instruction of the subsequent task. The opcodes are then
evaluated as below.
Opcodes
0 = DAT
The current task is removed from the current program's task list.
1 = MOV
If either mode is immediate, the B-address of the instruction pointed
to by the B-pointer is replaced by the A-term. Otherwise, the
instruction pointed to by the B-pointer is replaced by the A-
instruction.
2 = ADD
The B-address of the instruction pointed to by the B-pointer is
replaced by the sum of the A-term and the B-term.
3 = SUB
The B-address of the instruction pointed to by the B-pointer is
replaced by the difference of the A-term and the B-term. (B - A).
4 = JMP
The next instruction to execute in the current task is the instruction
pointed to by the A-pointer.
5 = JMZ
If the B-term is zero, the next instruction to execute in the current
task is the instruction pointed to by the A-pointer.
6 = JMN
If the B-term is not zero, the next instruction to execute in the
current task is the instruction pointed to by the A-pointer.
7 = DJN
The B-address of the instruction pointed to by the B-pointer is
decremented. If the B-term minus one is zero, the next instruction to
execute in the current task is the instruction pointed to by the&&&&
A-pointer.
8 = CMP
If either mode is immediate, the A-term is compared to the B-term.
Otherwise, the A-instruction is compared to the B-instruction. If the
result of the comparison is equal, the next instruction to execute in
the current task is the instruction after the instruction after the
current instruction (i.e. skip the next instruction).
10 = SPL
The instruction pointed to by the B-pointer is inserted in the current
program's task list between the current task and the subsequent task.
This new task will execute for this program next cycle.
INTERNATIONAL CORE WAR STANDARD OF 1988
The International Core War Standard of 1988 (ICWS'88) is essentially
like that of ICWS'86 with the following changes.
1. Core War is no longer explicitly limited to two programs.
2. Redcode to machine code mappings of modes and opcodes are no longer
dictated by the standard.
3. The mode indicator $ is eliminated. Direct mode remains but is
always indicated by a space.
4. Auto-decrement indirect mode is replaced by predecrement indirect
mode. The mode indicator is the same - '<'. Whereas auto-decrement
indirect would evaluate the operands and then decrement core,
predecrement indirect decrements core and then evaluates the operands.
Note that a predecrement indirect mode in the A-operand will decrement
memory before the B-operand is evaluated. (See below).
5. Multiplication (*) and integer division (/) are supported in
operand field evaluation. Direction of evaluation is no longer
explicitly stated (but is assumed left to right). Parentheses are no
longer forbidden but are not provided for (most systems should support
them).
6. There is a new instruction - SLT (Skip if Less Than). For SLT A, B
if A is less than B then skip the next instruction. Note that nothing
is less than zero. (See below).
7. With the exceptions of ADD #a, B and SUB #a, B, ADD and SUB now add
and subtract BOTH operands. (See below).
8. A single operand for the SPL instruction now assembles into the
A-field. (See below).
9. The following instructions are now explicitly illegal. There is no
indication how to handle illegal instructions. Note that A means any
of the set {#a, a, @a, <a} and similarly for B. MOV A #b, ADD A #b,
SUB A #b, CMP A #b, SLT A #b, JMP #a B, JMN #a B, DJN #a B, SPL #a B,
and all DAT statements other than those using immediate and/or
predecrement indirect modes are all illegal.
10. The pseudo-op SPACE is no longer part of the standard.
11. There is a new pseudo-op: EQU. EQU statements usually appear as
"Label EQU String". When assembling, all occurences of Label in
operands are replaced by String before the operands are evaluated.
12. The pseudo-op END can now take an operand. The operand indicates
which statement should be the first to execute.
13. Initialization of core is explicitly stated to be DAT 0 0.
14. The task limit of 64 tasks per side is eliminated both as upper
and lower bounds.
Replace the appropriate sections in ICWS'86 with those below for
proper ICWS'88 execution.
If the A-mode is predecrement indirect '<', the B-address of the
instruction pointed to by the A-address of the current instruction is
first decremented (in core), then the A-pointer is the sum of the&&&
A-address of the current instruction and the B-address of the
instruction pointed to by the A-address of the current instruction.
If the B-mode is predecrement indirect '<', the B-address of the
instruction pointed to by the B-address of the current instruction is
first decremented (in core), then the B-pointer is the sum of the&&&
B-address of the current instruction and the B-address of the
instruction pointed to by the B-address of the current instruction.
ADD
The B-address of the instruction pointed to by the B-pointer is
replaced by the sum of the A-term and the B-term. If the A-mode is
not immediate, the A-address of the instruction pointed to by the&&&
B-pointer is also replaced by the sum of the A-address pointed to by
the A-pointer and the A-address pointed to by the B-pointer.
SUB
The B-address of the instruction pointed to by the B-pointer is
replaced by the difference of the A-term and the B-term. If the&&&&
A-mode is not immediate, the A-address of the instruction pointed to
by the B-pointer is also replaced by the difference of the A-address
pointed to by the A-pointer and the A-address pointed to by the&&&&&
B-pointer. (B&-&A).
SLT
If the A-term is less than the B-term, the next instruction to execute
in the current task is the instruction after the instruction after the
current instruction (i.e. skip the next instruction).
SPL
The instruction pointed to by the A-pointer is inserted in the current
program's task list between the current task and the subsequent task.
This new task will execute after the NEXT time the current task
executes. The subsequent task will execute next cycle.