THE REDCODE LANGUAGE
--------------------

GENERAL DESCRIPTION

The language used to write the fighting programs is similar to Assembler:
every instruction with its arguments occupies one cell of the core. There
are instructions to do mathematical operations, to transfer execution to a
distant address, to compare two objects, to move values and to start a
parallel task. The last kind of instruction allows a program to start the
independent execution of another program so that if the original one is
killed the battle is not lost. A warrior can start up to 64 parallel tasks.
They must all be killed to defeat it. If a program already has the maximum
number of tasks running and tries to start a new one, the instruction is
simply ignored by Mars. Having a lot of tasks may not be as good as it
seems at first glance: suppose there are ten red tasks and two blue ones;
when all the red ones have executed one instruction the blue ones will have
executed five!

THE REDCODE COMPILER

You can create your own warriors simply writing them as text files. You can
then drag them directly into Mars or save them to disc and drag them from
there. Below is a description of the instructions admitted. To simplify
your job you can use labels of up to 255 alphanumeric characters and give
them a value using "equ" anywhere in the program (this is not an
instruction). There is no difference between upper and lower case. Program
execution starts from the first instruction or from the label "start". You
can place comments at the beginning or at the end of a line, starting with
";". You can divide labels, instructions and operands with any number of
spaces or tabs but you can use a comma between two operands if you wish. A
line ends with a linefeed (Return). If the first line is a comment, it is
taken as the name of the warrior and is placed in the Warriors window. This
is useful if you want to give your warrior a name with more than ten
characters (the limit of the filing system), and names of up to twenty
characters are allowed. This version of the compiler does not conform to
the stricter standard so you may have problems compiling your warriors on
another Core Wars Environment (but you don't need to!).

REDCODE INSTRUCTIONS

Every instruction can have one or two arguments. Each argument can have a
different type of addressing.

The instructions are as follows:

  dat B      This instruction contains data and if executed causes the
             death of the task. In fact the only way to kill an enemy is
             to fill its code with dats hoping they will be executed.

  mov A, B   Copies the value of A to the location B.

  add A, B   Adds A to B placing the result in B.

  sub A, B   Subtracts A from B placing the result in B.

  jmp A      Jumps to A.

  jmz A, B   Jumps to A if B is zero.

  jmn A, B   Jumps to A if B is not zero.

  djn A, B   Decrease B by 1 and jumps to A if B is not zero.

  cmp A, B   If A equals B skip the next instruction.

  spl B      Starts a parallel task at the location B.

List of the addressing modes:

  #opr  Immediate: The operand is used as is. Its value is opr.

  $opr  Direct: The operand points to a location opr cells distant from
                where it is. The "$" can be omitted.

  @opr  Indirect: opr points as above to a cell where there is a direct
                  pointer to the target cell.

  <opr  Selfdecreased: This acts as above but before finding the target
                       the pointer is decremented by 1 permanently.

Now follows an attempt to explain this rather cryptic list.

CELL FIELDS

Every cell of the core is divided into five fields: the first for the
instruction, the second for the addressing of operand A, the third for
operand A itself, the fourth and the fifth for addressing and value of
operand B. "add", "sub" and "djn" only modify the fifth field of a cell.
"mov" can copy the whole cell only if A is not immediate, otherwise it only
modifies the fifth field of the target cell (B operand). You don't have to
worry about fields: only think in terms of operands.

ADDRESSING

Addressing is always relative: "mov #0,$1" does not place a zero at the
location 1 of the core, but in the B operand of the instruction that
follows. Note that "$" can be omitted. Even if you can put the addressing
you wish before an operand, some combinations may not have sense. For
example, "jmp #1" tries to jump to a number, not to a location. The
compiler does not check this and Mars acts as if it was "jmp $0" (an
endless loop) so beware! Only the "dat" operand is checked and translated
without warning into the "$" form by the compiler.

Some examples on how instructions behave:

add #5, $-1 adds 5 to the B operand of the previous location:

         before execution                 after execution

     cell ins. adr opA adr opB       cell ins. adr opA adr opB
     -------------------------       -------------------------
     1453 dat           $   1        1453 dat           $   6
  -> 1454 add   #   5   $  -1        1454 ...   .   .   .   .
     1455 ...   .   .   .   .     -> 1455 ...   .   .   .   .

add #5, @3 finds the target location using the B operand of the
           instruction three cells after it:

         before execution                 after execution

     cell ins. adr opA adr opB       cell ins. adr opA adr opB
     -------------------------       -------------------------
     1453 dat           $   1        1453 dat           $   6
  -> 1454 add   #   5   @   3        1454 ...   .   .   .   .
     1455 ...   .   .   .   .     -> 1455 ...   .   .   .   .
     1456 ...   .   .   .   .        1456 ...   .   .   .   .
     1457 dat           $  -4        1457 ...   .   .   .   .

add #5, <3 decrements the pointer before using it:

         before execution                 after execution

     cell ins. adr opA adr opB       cell ins. adr opA adr opB
     -------------------------       -------------------------
     1452 dat           $  -2        1452 dat           $   3
     1453 dat           $   1        1453 dat           $   1
  -> 1454 add   #   5   <   3        1454 ...   .   .   .   .
     1455 ...   .   .   .   .     -> 1455 ...   .   .   .   .
     1456 ...   .   .   .   .        1456 ...   .   .   .   .
     1457 dat           $  -4        1457 dat           $  -5

LABELS AND COMMENTS

The use of labels and comments considerably simplifies the programming
work. A program like this:

  mov $3,@3
  add #2,$2
  jmp $-2
  dat #4

could be written this way:

  ; Cannoniere
  ; Written by Pinco Pallino
  ;
  init      equ     4 ; Distance where to fire the first bomb.
  gap       equ     2 ; Gap between bombs.
  rosy      dat     0 ; The bomb itself.

  start     mov  $rosy     @target ; Fires a bomb.
            add  #gap      $target ; Adjusts fire.
            jmp  start             ; Go on shooting.

  target    dat  $init

The Draw file "CoreWars" contains a summary of Redcode instructions and
addressing.
