summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-06-20 21:04:43 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-06-20 21:04:43 +0200
commitb6f87dacd8c141940a0061c7c8af32ce1d9e2963 (patch)
treefa7e34a117099d5872967f89b7d349eef3c3c491
Add docs
-rw-r--r--doc/cwg.txt548
-rw-r--r--doc/icws88.txt387
-rw-r--r--doc/icws94.html32
-rw-r--r--doc/icws94.txt2343
-rw-r--r--doc/tutorial.txt473
5 files changed, 3783 insertions, 0 deletions
diff --git a/doc/cwg.txt b/doc/cwg.txt
new file mode 100644
index 0000000..733ecef
--- /dev/null
+++ b/doc/cwg.txt
@@ -0,0 +1,548 @@
+
+
+
+
+
+
+ [Note: This is a reproduction of the Core War Guidelines
+ originally produced by Jones and Dewdney in March of 1984]
+
+
+
+ CORE WAR GUIDELINES
+
+ D. G. Jones and A. K. Dewdney
+
+ Department of Computer Science
+ The University of Western Ontario
+
+ March, 1984
+
+
+
+
+ These guidelines suggest ways of implementing a simple version
+ of Core War, the game described in the "Computer Recreations"
+ department of Scientific American in May, 1984.
+
+ Programming examples are given in a style similar to that of the
+ Pascal and C languages. Readers unfamiliar with constructs of
+ these languages, such as the CASE statement, may want to consult
+ a Pascal manual.
+
+
+ The Redcode Instruction Set
+
+ Core War programs are written in an assembly-type language
+ called Redcode. The eight instructions included in the version
+ of the language presented here are by no means the only ones
+ possible; indeed, the original implementation of Core War, done
+ on a minicomputer, had a larger instruction set. If there are
+ many kinds of instructions, however, the encoded form of each
+ instruction takes up more space, and so the area of memory
+ needed for CORE must be larger. Mars, the program that inter-
+ prets Redcode programs, also grows as the size of the instruc-
+ tion set increases. The complexity of your Core War implementa-
+ tion may be constrained by the amount of memory available in
+ your computer.
+
+
+
+
+
+
+ CORE WAR GUIDELINES 2.
+
+ If you choose to a create your own Redcode instruction set, two
+ points should be kept in mind. First, each Redcode instruction
+ must occupy a single location in CORE. In many assembly lan-
+ guages an instruction can extend over multiple addresses, but
+ not in Redcode. Second, there are no registers available for
+ Redcode programs; all data are kept in CORE and manipulated
+ there.
+
+ Here is a simple Redcode instruction set:
+
+ Encoded Mnemonic Argum ent Action
+ Form Symbol
+ ------- --------- ----- ----- ----------------------------------
+ 0 DAT B Initialize location to value B.
+
+ 1 MOV A B Move A into location B.
+
+ 2 ADD A B Add operand A to contents of
+ location B and store result in
+ location B.
+
+ 3 SUB A B Subtract operand A from contents
+ of location B and store result in
+ location B.
+
+ 4 JMP B Jump to location B.
+
+ 5 JMZ A B If operand A is 0, jump to loca-
+ tion B; otherwise continue with
+ next instruction.
+
+ 6 DJZ A B Decrement contents of location A
+ by 1. If location A now holds 0,
+ jump to location B; otherwise
+ continue with next instruction.
+
+ 7 CMP A B Compare operand A with operand B.
+ If they are not equal, skip next
+ instruction; otherwise continue
+ with next instruction.
+
+
+ Addressing Modes
+
+ There are various ways of specifying memory addresses in an
+ assembly-language program. In order to make the execution of a
+ Redcode program independent of its position in memory, a special
+ form of relative addressing is used. Again, your version of Red-
+ code may have different addressing modes or additional ones, al-
+
+
+
+
+
+
+ CORE WAR GUIDELINES 3.
+
+ though you should be aware when you choose modes that Mars will
+ load your Redcode program at an address in CORE that cannot be
+ predicted in advance.
+
+ The three addressing modes in our version of Redcode are identi-
+ fied by symbols placed before the argument:
+
+ Encoded Mnemonic Name Meaning
+ Form Symbol
+ ------- --------- ----------- ----------------------------------
+ 0 # Immediate The number following this symbol
+ is the operand.
+
+ 1 <none> Relative The number specifies an offset
+ from the current instruction. Mars
+ adds the offset to the address of
+ the current instruction; the num-
+ ber stored at the location reached
+ in this way is the operand.
+
+ 2 @ Indirect The number following this symbol
+ specifies an offset from the cur-
+ rent instruction to a location
+ where the relative address of the
+ operand is found. Mars adds the
+ offset to the address of the cur-
+ rent instruction and retrieves the
+ number stored at the specified lo-
+ cation; this number is then inter-
+ preted as an offset from its own
+ address. The number found at this
+ second location is the operand.
+
+ All address arithmetic is done modulo the size of CORE. The MOD
+ operator is the remainder after division, and so 5096 MOD 4096
+ is 1000. Thus if your CORE array has 4096 locations, a reference
+ to location 5096 is taken as a reference to location 1000.
+
+ Because a program can never refer to an absolute address, some
+ addressing modes for some operands do not make sense. For ex-
+ ample, in the instruction MOV #5 #0 the operand to be moved is
+ the immediate value 5, but the argument indicating where it is
+ to be moved is not an address but the immediate value 0, which
+ has no clear interpretation. The allowed modes can be stored in
+ a two-dimensional table that is consulted by Mars when it inter-
+ prets the instructions.
+
+ The example below should illustrate how the instructions and the
+ addressing modes work. The code is taken from a battle program
+
+
+
+
+
+
+ CORE WAR GUIDELINES 4.
+
+ called Dwarf, which was described in the Scientific American
+ article. Here, however, it has been altered to work in a CORE
+ array of 4096 locations instead of one with 8000 locations.
+
+ Location Inst ruc tion Action
+ -------- ---- --- ------ ---------------------------------------
+ 0: DAT 0 This location initially holds 0.
+
+ 1: ADD #4 -1 Operand A is 4. The address of operand
+ B is 1+(-1)=0; hence operand B is the
+ content of this location in CORE. Add
+ the two operands and store the result
+ in location 0.
+
+ 2: MOV #0 @-2 Operand A is 0. The address of operand
+ B is the number stored at location
+ 2+(-2)=0, and so operand A is stored at
+ the location given by 0+(content of lo-
+ cation 0).
+
+ 3: JMP -2 Continue execution with the instruction
+ at location 3+(-2)=1.
+
+
+ Translating a Redcode Program into an Encoded Format
+
+ CORE is typically implemented as and array of integers. Suppose
+ the array has 4096 (or 2^12) elements; then exactly 12 bits are
+ required for each operand field in an instruction. There are
+ three addressing modes, and so for each mode field two bits suf-
+ fice. If four bits are alloted to the instruction itself, each
+ instruction can be stored in 32 bits, or four bytes.
+
+ Each element of the array might have the following format:
+
+ number of bits: 4 2 2 12 12
+ fields: type mode for A mode for B A B
+
+ The example below suggests one way of encoding an instruction in
+ a 32-bit binary integer. (A somewhat different scheme, based on
+ decimal integers, was given in the Scientific American artice.)
+
+ Instruction Fields Encoded Integer
+ ----------------------------------------------------------------
+ MOV #5 @20 type = 1 1 * 2^28 = 268435456
+ mode for A = 0 0 * 2^26 = 0
+ mode for B = 2 2 * 2^24 = 33554432
+ A = 5 5 * 2^12 = 20480
+ B = 20 20 * 2^0 = 20
+ ---------
+ 302010388
+
+
+
+
+
+
+ CORE WAR GUIDELINES 5.
+
+ The experience programmer will probably want to automate the
+ conversion of mnemonic instructions into integers by writing a
+ Redcode assembler to do the translation.
+
+
+ Rules of Core War
+
+ The rules of Core War are few and simple. The simpler the rules
+ are, the simpler the referee program needs to be. Here are the
+ rules we have been using:
+
+ 1. Two battle programs are loaded into CORE at randomly cho-
+ sen starting locations, subject to the constraint that
+ the programs cannot overlap.
+
+ 2. The battle proceeds as Mars executes one instruction from
+ program X, one instruction from program Y, one from X,
+ one from Y, and so on, until one of two events happens:
+
+ i) A previously specified number of instructions has
+ been executed and both programs are still running.
+ The battle is then declared a draw and ended.
+
+ ii) An instruction is encountered that cannot be inter-
+ preted by Mars and hence cannot be executed. The
+ program with the faulty instruction is the loser.
+
+ One problem with these rules is that they reward small but un-
+ interesting programs such as:
+
+ JMP 0 /execute this instruction over and over.
+
+ This program is completely unaggressive, and yet it is hard to
+ destroy simply because of its size. A program such as Dwarf, on
+ the other hand, is so destructive that it is hard to write lar-
+ ger, more complicated Redcode programs that can compete against
+ it. The larger program has too little time to launch its attack
+ before a "zero bomb" from Dwarf strikes somewhere in its
+ instructions. Other rules might be able to alleviate these prob-
+ lems, but remember that the referee program must be able to im-
+ plement the rules.
+
+
+ The Mars Program
+
+ In addition to serving as the referee in a Core War battle, Mars
+ is responsible for executing the battle programs. Mars first
+ loads two battle programs X and Y into the CORE array, putting
+ them at arbitrary positions but taking care that one program is
+ not written over the other. For each program Mars also needs to
+ know the address where execution is to start; this information
+ can be put into a file with the encoded Redcode program.
+
+
+
+
+
+ CORE WAR GUIDELINES 6.
+
+ During execution Mars must continually keep track of the current
+ instruction pointer for each program. If CORE is implemented as
+ an array of integers, the instruction pointer is simply an index
+ into the array. Mars then executes a simple loop:
+
+ LOOP: IF X's next instruction can be executed, THEN execute it
+ ELSE declare X the loser, Y the winner; GOTO ABORT
+ IF Y's next instruction can be executed, THEN execute it
+ ELSE declare Y the loser, X the winner; GOTO ABORT
+ count = count + 1
+ IF count < limit THEN GOTO LOOP
+ ELSE GOTO ABORT
+
+ The counter is kept in case neither program is able to defeat
+ the other. Without it Mars could be trapped in an endless loop.
+
+
+ Executing An Instruction
+
+ The following pseudocode for a part of Mars illustrates how a
+ Redcode instruction can be interpreted and executed. (Note tat
+ the operator DIV gives the integer result of division, that is,
+ 100 DIV 30 yields a result of 3.) In the example we assume it is
+ program X's turn to execute its next instruction, which is spec-
+ ified by the variable X-index.
+
+ Integer variables used:
+
+ instruction /current instruction (encoded as 32-bit integer)
+ type /the instruction type (encoded)
+ mode-A /the addressing mode for operand A (encoded)
+ mode-B /the addressing mode for operand B (encoded)
+ field-A /the encoded number in field A
+ field-B /the encoded number in field B
+ address-A /address of operand A (unless immediate)
+ address-B /address of operand B (unless immediate)
+ pointer /variable used in calculating indirect addresses
+ operand-A /value of operand A
+ operand-B /value of operand B
+ answer /result calculated by the instruction
+
+ Program statements:
+
+ instruction = CORE[X-index] /get instruction
+ type = instruction DIV 2^28 /get first 4 bits
+ mode-A = (instruction DIV 2^26) MOD 2^2 /get next 2 bits
+ mode-B = (instruction DIV 2^24) MOD 2^2 /get next 2 bits
+ field-A = (instruction DIV 2^12) MOD 2^12 /get next 12 bits
+ field-B = instruction MOD 2^12 /get last 12 bits
+
+
+
+
+
+
+ CORE WAR GUIDELINES 7.
+
+ CASE mode-A OF
+
+ 0: operand-A = field-A
+ /immediate mode; operand given in the field itself
+
+ 1: address-A = (X-index + field-A) MOD 4096
+ operand-A = CORE[address-A]
+ /relative mode; address of operand A is index + field A;
+ /operand A is the content of CORE at this address
+
+ 2: pointer = (X-index + field-A) MOD 4096
+ address-A = (pointer + CORE[pointer]) MOD 4096
+ operand-A = CORE[address-A]
+ /indirect mode; pointer to the address of operand A is
+ /index + field A; address of operand A is the the value
+ /of the pointer + the content of the location it points
+ /to; operand A is the content of CORE at this address.
+
+ OTHERWISE: GOTO ABORT
+
+ At this point in the program a similar CASE statement, based on
+ the variable B-mode, is employed to assign a value to operand B.
+ An error-checking routine can be invoked to make certain that
+ the mode of each operand is allowable for an instruction of the
+ kind specified by the variable type. If no errors have been en-
+ countered, Mars continues with the following code:
+
+ X-index = X-index + 1 /increment the instruction
+ /index in preparation for
+ /program X's next turn; the
+ /index may subsequently be
+ /altered by a JMP, JMZ, DJZ
+ /or CMP instruction
+
+ CASE type OF
+
+ 0: GOTO ABORT /DAT statement; cannot
+ /be executed
+
+ 1: CORE[address-B] = operand-A /MOV instruction
+
+ 2: answer = operand-B + operand-A /ADD instruction
+ CORE[address-B] = answer
+
+ 3: answer = operand-B - operand-A /SUB instruction
+ CORE[address-B] = answer
+
+ 4: X-index = operand-B /JMP instruction; the
+ /next instruction is at
+ /the location specified
+ /by operand B
+
+
+
+
+
+
+ CORE WAR GUIDELINES 8.
+
+ 5: IF operand-A = 0 THEN /JMZ instruction; if
+ X-index = operand-B /operand A is zero, jump
+
+ 6: answer = operand-A - 1 /DJZ instruction; dec-
+ CORE[address-A] = answer /rement operand A and
+ IF answer = 0 THEN /store result; if it is
+ X-index = operand-B /zero, jump
+
+ 7: IF operand-A = operand-B /CMP instruction; if
+ X-index = X-index + 1 /the operands are equal,
+ /skip next instruction
+
+ OTHERWISE: GOTO ABORT
+
+ END /An instruction of program X has been interpreted
+ /and executed successfully; Mars now goes on to
+ /execute the next instruction of program Y.
+
+ ABORT: /This label is reached only if the current in-
+ /struction of program X could not be interpreted
+ /and executed. Program X is declared the loser
+ /and program Y the winner.
+
+
+ Displaying a Battle
+
+ The author of a Redcode program would become frustrated if his
+ creation were loaded into the darkest regions of CORE and then,
+ after a short battle, pronounced dead by the referee Mars with-
+ out any indication of what went wrong. Was the opposing program
+ superior, or was there merely a bug in the program? Some trace
+ of the events in a battle is needed.
+
+ The simplest display of an ongoing Core War battle is a listing
+ of both programs' execution on a split screen. The address of
+ each instruction and its mnemonic symbol ought to be given. A
+ typical display might look something like this:
+
+ 1135: MOV 0 1 202: ADD #4 -1
+ 1136: MOV 0 1 203: MOV #0 @-2
+ 1137: MOV 0 1 204: JMP -2
+ 1138: MOV 0 1 205: ADD #4 -1
+ 1139: MOV 0 1 206: MOV #0 @-2
+ 1140: MOV 0 1 207: JMP -2
+ 1141: MOV 0 1 208: ADD #4 -1
+ 1142: MOV 0 1 209: MOV #0 @-2
+ 1143: MOV 0 1 210: JMP -2
+ 1144: MOV 0 1 211: ADD #4 -1
+ 1145: MOV 0 1 212: MOV #0 @-2
+ PROGRAM X PROGRAM Y
+
+
+
+
+
+
+ CORE WAR GUIDELINES 9.
+
+ The instruction currently being executed would always be dis-
+ played at the bottom of the screen, along with the preceeding 23
+ instructions (on a 24-line screen). The information for the dis-
+ play might be generated as each instruction is interpreted and
+ the values of the various fields are determined. A subroutine
+ would output the mnemonic or the numerical value corresponding
+ to each encoded field. It must be recognized, however, that this
+ output will slow th execution of Mars. In a battle lasting
+ several thousand steps you may want to suppress the output.
+
+ Although the display described above is useful for debugging
+ programs by stepping through their instructions, it gives no
+ clear idea of the overall action. It is rather like seeing only
+ two televised close-ups of the gladiators' feet in the Roman
+ arena.
+
+ Another method we intend to try creates a circular display on a
+ graphics terminal. Two large concentric circles represent the
+ CORE array, and symbols within the annulus formed by the circles
+ represent the two battle programs.
+
+ The extreme right-hand point of the circles can be taken as
+ address 0. The symbols could be any simple but distinguishable
+ shapes (say a dot and a line). Additional information could be
+ displayed, such as the elapsed time or a key identifying the
+ programs corresponding to the symbols. One could even have a
+ momentary flash (an asterisk?) appear at addresses altered by
+ MOV commands; the flashes would be interpreted either as artil-
+ lery or relocation. Of course the more complicated the display
+ is, the slower the battle will proceed.
+
+
+
+
+
+
+ CORE WAR GUIDELINES 10.
+
+ The position of each symbol in the circular display can be cal-
+ culated from the instruction index for the corresponding pro-
+ gram. Suppose a program is executing at location I in a CORE
+ array with 4096 elements and its position is to be shown on a
+ screen that has 1000 distinguishable points vertically and hori-
+ zontally. The coordinates on the display screen are then given
+ by the expressions 400 * cos(2piI/4096) and 400 *
+ sin(2piI/4096).
+
+ With a lower-resolution graphics system the circular display
+ might not be feasible, but the CORE array could still be repre-
+ sented as a rectangle. Again symbols would indicate the location
+ of each program, although they might appear to jump or flicker
+ slightly even tough execution moved "continuously" from address
+ to address. A crude version of such a display might even be im-
+ plemented on a purely character-oriented screen.
+
+ Extensions to Redcode and Mars
+
+ The version of Mars presented here is easy to implement, and
+ many of you may want to see how you can expand the Core War sys-
+ tem. For example, in this version of Mars only two battle pro-
+ grams can be run at once. Would it be hard to let more programs
+ execute? How about a new Redcode instruction that allows a run-
+ ning program to start up another program it has copied into a
+ free area of CORE, and thereby increase the chance that at least
+ one program from its "team" will survive the Core War battle?
+
+ The Redcode instruction set given here is a simple one. Those
+ of you with access to a larger computer may want to experiment
+ with new instruction sets and addressing modes, possibly making
+ Redcode more like a real assembly language. Instructions that
+ protect a larger program from a small, hard-to-defeat one would
+ help to elevate Core War to a higher, more interesting level.
+
+ We would welcome documentation and listings of Core War systems
+ and Redcode battle programs from anyone who thinks he has come
+ up with a particularly interesting or innovative idea. Send
+ correspondence to:
+
+ D. G. Jones or A. K. Dewdney
+ Department of Computer Science
+ The University of Western Ontario
+ London, Ontario
+ Canada
+ N6A 5B7
+
+
+
diff --git a/doc/icws88.txt b/doc/icws88.txt
new file mode 100644
index 0000000..2e8ebbb
--- /dev/null
+++ b/doc/icws88.txt
@@ -0,0 +1,387 @@
+The Redcode ICWS-88 standard
+----------------------------
+
+[Note: This text is reproduced from the article "Core War '88 - A Proposed
+Standard" by Thomas Gettys which appeared in the Summer 1988 edition of The Core
+War Newsletter, Copyright (c) 1988 by AMRAN. It appears here by the permission
+of AMRAN and the International Core War Society, both of which retain the
+aforementioned copyright. Although the original appears in several different
+proportional fonts, every effort has been made to maintain pagination, columns,
+and paragraphs as in the original document. Therefore, references to either
+document should be the same. Additional information is available by contacting
+the ICWS at 5712 Kern Drive, Huntington Beach, CA 92649-4535. A $1.00 donation
+for this document is requested.]
+
+URL: ftp://ftp.csua.berkeley.edu/pub/corewar/documents/standards/redcode-icws-88.Z
+
+
+ The Text of the Proposal
+
+ MARS Functional Units.
+
+ From the Redcode programmer's point of
+ view, MARS is composed of four primary
+ functional units: a read/write memory
+ (RAM), a computing unit (ALU), two
+ process queues (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.
+ Addressing in Redcode is relative, so
+ it is best to think of memory as being
+ organised as a circular list; an
+ instruction that references memory
+ location zero is referring to itself.
+ Every RAM location is initialised to
+ the data pattern which corresponds to
+ the instruct DAT 0 0 before loading
+ any Core War programs, (elsewhere
+ refered to as "warriors").
+
+ FIFO: A game of Core War is played by
+ pitting two Redcode programs against
+ each other. 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 tow operands or incrementing a
+ program counter.
+ Page 4
+
+
+
+
+
+
+CU: As in any processor, the control Addressing Modes
+unit has the responsibility of
+fetching, decoding and executing There are currently four addressing
+instructions. Details about the fetch modes defined: immediate, direct,
+and decode phase will be delayed until indirect, and predecrement-indirect.
+the instruction set has been introduced
+and defined, (see the section on The default mode is direct. If no
+Effective Address Calculation). The modifier symbol precedes an operand,
+control unit must also provide an the value of the operand is used as an
+interface to the MARS supervisor offset from the memory locations from
+function (ZEUS). The supervisor may which it was fetched. The resulting
+provide various support functions such memory location is the source and/or
+as a Redcode debugger, graphics destination of the data to be used by
+display, parameter control, etc. and is the instruction, or else is the
+highly implementation specific. destination for branching
+ instructions.
+Instruction Format
+ An octothorpe (#) is used to introduce
+A Redcode instruction has three fields: an immediate operand. The value of the
+the opcode field and two operand operand is not an address but rather
+field, denoted as A and B. The contents the data to be used by the
+of the opcode field specify the instruction; the data is "immediately"
+operation to be performed, and the available.
+addressing modes to be used in
+evaluating the operands. For pragmatic The commercial at sign (@) is used to
+purposes it is useful to divide the introduce an indirect operand. The
+opcode into three sub-fields: the value of the operand is used as an
+operation and the two operand offset, as it is with direct
+modifiers, but this is not strictly addressing. The B operand of the
+necessary. The operand fields may resulting memory location is then used
+contain any number from zero to the as an offset from the memory location
+memory size minus one. Currently, from which it was fetched. The
+eleven Redcode instructions are resulting memory location is the
+defined. They are listed in figure 1 source and/or destination of the data
+below, with a mnemonic and short to be used by the instruction, of else
+operational description for each. is the destination for branching
+ instructions.
+ DAT A B: remove executing process
+ from process queue The less than sign (<) is used to
+ introduce a pre-decrement indirect
+ MOV A B: move A to B operand. The value of the operand is
+ used as an offset, as it is with
+ ADD A B: add A to B direct addressing. The B operand of
+ the resulting memory location is
+ SUB A B: subtract A from B fetched, decremented, and then
+ restored. It is then used as an offset
+ JMP A B: jump to A from the memory location from which it
+ was fetched. The resulting memory
+ JMZ A B: jump to A if B is zero location is the source and/or
+ destination for the data to be used by
+ JMN A B: jump to A if B is not the instruction, or else is the
+ zero destination for branching
+ instructions.
+ CMP A B: if A equals B, then skip
+ the next instruction The Redcode Instruction Set
+
+ SLT A B: if A is less than B then For the most part, the Redcode
+ skip next instruction instruction set presents no unusual
+ problems, and the implementation is
+ DJN A B: decrement B; if B is not straight-forward. Some additional
+ zero then jump to A definition and clarification is
+ required however to insure that it is
+ SPL A B: place A in the process implemented correctly.
+ queue
+ DAT A B : This instruction actually
+ Figure 1. Instruction set ofthe serves two functions, one utilitarian,
+ proposed Core War Standard of 1988. and the other quite destructive. On
+ the one hand, it is used for the
+ storage of data to be used as a
+ counter, pointer, etc. If executed
+ however, the process is halted! This,
+ then, is the mechanism by which one
+ obtains victory in a Core War: cause
+ every process associated with the
+ opponent's program to execute a DAT
+ instruction.
+
+ Continued on page 8c.
+ Page 5
+
+
+
+
+
+
+ MOV A B : If the A operand is
+ immediate it is placed in the B-field
+ of the memory location specified by
+ the B operand, otherwise the contents
+ of the entire memory location
+ specified by the A operand is moved to
+ the memory location specified by the B
+ operand.
+
+ ADD A B : If the A operand is
+ immediate it is added to the B-field
+ of the B operand. If the A operand is
+ not immediate both the A-field and B-
+ field of the A operand are added
+ respectively to the A-field and B-
+ field of the B operand.
+
+ SUB A B : If the A operand is
+ immediate it is subtracted from the B-
+ field of the B operand. If the A
+ operand is not immediate both the A-
+ field and B-field of the A operand are
+ subtracted respectively from the A-
+ field and B-field of the B operand.
+
+ JMP A B : The address of the memory
+ location specified by the A operand is
+ placed at the back of the process
+ queue associated with the executing
+ program. The B operand does not
+ necessarily participate in the
+ execution of the instruction.
+
+ JMZ A B : If the B-field of the B
+ operand is zero then the address of
+ the memory location specified by the A
+ operand is placed at the back of the
+ process queue associated with the
+ executing program.
+
+ JMN A B : If the B-field of the B
+ operand is not zero then the address
+ of the memory location specifiec by
+ the A operand is placed at the back of
+ the process queue associated with the
+ executing program.
+
+ CMP A B : If the A operand is
+ immediate it is compared to the B-
+ field of the memory location specified
+ by the B operand, otherwise the
+ contents of the entire memory location
+ specified by the A operand is compared
+ to the contents of the memory location
+ specified by the B operand. If the
+ compared values are equal, the next
+ instruction is skipped (the program
+ counter is incremented).
+
+ SLT A B : If the A operand is not
+ immediate, the B-field ot the memory
+ location specified by the A operand is
+ compared to the B-field of the B
+ operand, otherwise the A operand
+ itself is used in the comparison. If
+ the A value is less than the B value,
+ the next instruction is skipped (the
+ program counter is incremented).
+
+ DJN A B : If the B operand is not
+ immediate, the B-field of the memory
+ location specified by the B operand is
+ fetched, decremented, and then
+ restored, otherwise the B-field of the
+ current instruction is used. If the
+ value is not zero, the address of the
+ memory
+
+ Page 8
+
+
+
+
+
+
+location specified by the A operand is Blank lines are used solely for
+placed at the back of the process queue cosmetic purposes in the source and
+associated with the executing program. listing files. Blank lines enhance
+ readability by allowing groups of
+SPL A B : After a process has caused an related instructions to be easily
+SPL instruction to be fetched, the separated.
+program counter is incremented and
+placed at the back of its process All comments are introduced by a
+queue. The address ot the spawned semicolon, (;). Comments may be placed
+process is then placed at the back of anywhere within the source file. All
+the same queue, providing the queue is characters following the semicolon are
+not full. The B operand does not ignored.
+necessarily participate in the
+execution of this instruction. A Redcode instruction consists of five
+ components (fields) : an optional
+Effective Address Calculations. label, the instruction mnemonic, the
+ A and B operands, and an optional
+The fetch-decode phase of Redcode comment. Fields are separated by one
+instruction execution is complicated or more space and/or tab characters.
+somewhat by the predecrement-indirect
+addressing mode. After the instruction Labels begin in the first column and
+to be executed has been fetched, the are composed of alpha-numeric
+operands must be "normalised" before characters. Only the first eight
+the opcode is processed. That is, the characters of a label are significant.
+operands are processed so as to remove If a label is present, it will take
+any indirection. Because this may the current value of the program
+involve the modification of memory, the counter.
+order of evaluation must be specified
+exactly. An operand consists of the addressing
+ mode symbol followed by an expression
+First the A addressing mode is that is composed of labels, number,
+examined. If immediate, we are done. and operator symbols. The valid
+Otherwise, the program counter is added operators are addition (+),
+to the value in the A-field, yielding subtraction (-), multiplication (*),
+an absolute address. If direct, we are and integer division (/).
+done. Otherwise, the B-field of this
+direct memory location is read into the A pseudo-instruction is adirective to
+A-field. If predecrement is indicated, the assembler; object code is not
+the value just read is decremented and generated by a pseudo instruction. The
+written back to the memory location mnemonic and definition of each pseudo
+from whence it came. Finally, the instruction follows.
+program counter is added to the value
+in the A-field. EQU : The EQU pseudo-instruction must
+ be preceded by a label, and foloowed
+At this point the A-field either by an expression which is consistent
+contains immediate data or else it with the rules governing operand
+contains the absolute address of the A expressions. The value of the
+operand. The same procedure is now expression is the value associated
+performed to normalise the B operand. with the label. The expression may
+With bother operands now normalised, contain such other labels as a priorly
+the operation code is examined and the defined.
+specified operation performed.
+ END : The END pseudo-instruction
+One final aspect of instruction follows the last line to be assembled.
+execution remains to be resolved. All lines following the END statement
+Because of the process queue FIFO's are ignored. Additionally, if an
+implied by the SPL instruction, the operand is provided, it will be used
+updating of the program counter as the program entry point. If no
+associated with the current process operand appears, the entry point is
+must be delayed until the opcode is assumed to be the first instruction
+processed. If the instruction does not line in the file.
+require a branch to be taken and the
+instruction is not a DAT, the program Appendix A
+counter is incremented and placed at
+the back ot the process queue The following is a complete list of
+associated with the executing program all legal Redcode instructions under
+before the instruction is executed. this proposed standard.
+
+Source Code Syntax Appendix A continued on page 13a.
+
+The source code file consists of lines
+as generated by a typical ASCII editor.
+A line may be classified as either a
+blank line, a comment line, a Redcode
+instruction, or as a pseudo-
+instruction.
+
+ Page 9
+
+
+
+
+
+
+MOV # A B SLT # A B DJN A # B SPL A # B
+MOV # A @ B SLT # A @ B DJN A B SPL A B
+MOV # A < B SLT # A < B DJN A @ B SPL A @ B
+MOV A B SLT A B DJN A < B SPL A < B
+MOV A @ B SLT A @ B DJN @ A # B SPL @ A # B
+MOV A < B SLT A < B DJN @ A B SPL @ A B
+MOV @ A B SLT @ A B DJN @ A @ B SPL @ A @ B
+MOV @ A @ B SLT @ A @ B DJN @ A < B SPL @ A < B
+MOV @ A < B SLT @ A < B DJN < A # B SPL < A # B
+MOV < A B SLT < A B DJN < A B SPL < A B
+MOV < A @ B SLT < A @ B DJN < A @ B SPL < A @ B
+MOV < A < B SLT < A < B DJN < A < B SPL < A < B
+
+ADD # A B JMP A # B
+ADD # A @ B JMP A B DAT # A # B
+ADD # A < B JMP A @ B DAT # A < B
+ADD A B JMP A < B DAT < A # B
+ADD A @ B JMP @ A # B DAT < A < B
+ADD A < B JMP @ A B
+ADD @ A B JMP @ A @ B
+ADD @ A @ B JMP @ A < B
+ADD @ A < B JMP < A # B
+ADD < A B JMP < A B
+ADD < A @ B JMP < A @ B
+ADD < A < B JMP < A < B
+
+SUB # A B JMZ A # B
+SUB # A @ B JMZ A B
+SUB # A < B JMZ A @ B
+SUB A B JMZ A < B
+SUB A @ B JMZ @ A # B
+SUB A < B JMZ @ A B
+SUB @ A B JMZ @ A @ B
+SUB @ A @ B JMZ @ A < B
+SUB @ A < B JMZ < A # B
+SUB < A B JMZ < A B
+SUB < A @ B JMZ < A @ B
+SUB < A < B JMZ < A < B
+
+CMP # A B JMN A # B
+CMP # A @ B JMN A B
+CMP # A < B JMN A @ B
+CMP A B JMN A < B
+CMP A @ B JMN @ A # B
+CMP A < B JMN @ A B
+CMP @ A B JMN @ A @ B
+CMP @ A @ B JMN @ A < B
+CMP @ A < B JMN < A # B
+CMP < A B JMN < A B
+CMP < A @ B JMN < A @ B
+CMP < A < B JMN < A < B
+
+
+ Page 13
diff --git a/doc/icws94.html b/doc/icws94.html
new file mode 100644
index 0000000..c988e1d
--- /dev/null
+++ b/doc/icws94.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>404: Not Found</title>
+<meta name="title" content="404: Not Found">
+<style>
+body {
+background: whitesmoke;
+height: 100%;
+}
+p {
+font-size:500%;
+font-family:"Bitstream Vera Sans Mono","DejaVu Sans Mono", "Lucida Console", Monaco, monospace;
+position:absolute;
+top:0;
+bottom:0;
+left:0;
+right:0;
+margin:auto;
+text-align:center;
+height:4ex;
+}
+code {
+font-family:inherit;
+background:white;
+padding:8px;
+border:3px gainsboro solid;
+}
+</style>
+</head>
+<body>
+<p><code class="redcode"><span style="color:crimson">jmz.f</span> notfound, <span style="color:dodgerblue">404</span></code></p>
+</body></html>
diff --git a/doc/icws94.txt b/doc/icws94.txt
new file mode 100644
index 0000000..3643e3e
--- /dev/null
+++ b/doc/icws94.txt
@@ -0,0 +1,2343 @@
+Annotated Draft of the Proposed 1994 Core War Standard.
+
+Version 3.3
+Annotated Draft Last Modified: November 8, 1995
+Last modified by: Damien Doligez
+Base draft by: Mark Durham
+
+[Planar's intro to ver. 3.3]
+
+This is a list of what I've changed from version 3.2:
+
++ Changed "pointer counter" to "program counter" in Mark's intro.
++ Changed "A-pointer" and "B-pointer" to "A-number" and "B-number" in
+ Mark's intro
++ Added A-number indirect, A-number predecrement, and A-number
+ postincrement to the description of addressing modes. Changed
+ "indirect", "predecrement", and "postincrement" to "B-number indirect",
+ etc.
++ Clarified the fact that newlines are not considered whitespace.
++ Added the SEQ, SNE, and NOP opcodes
++ Changed a reference to "load file" into "assembly file" in section 2.3
++ Simplified the grammar entries for label_list and newline.
++ Removed the grammar entries for list, simplified those for files.
++ Stop parsing (not simply assembling) after the END.
++ Added predefined labels.
++ Added ";assert" comment convention.
++ Specified the behaviour of {DIV,MOD}.{I,F,X} when a component of the
+ A-value is 0.
++ Fixed a discrepancy between the text and the sample code on the
+ behavior of JMN and DJN, >>>BY CHANGING THE TEXT<<<. The old version
+ would not jump (for JMN.F and DJN.F) if either field of the target
+ was zero.
++ Added SEQ as a synonym to CMP (in description and code)
++ Added SNE (in description and code)
++ Added NOP (in description and code)
++ Specified the behavior of SLT.F
++ Fixed the bug with label "noqueue" in the ARITH_DIV macro.
++ Updated the conversion tables.
++ Updated the list of new opcodes and addressing modes.
+
+This is a list of things to do:
+
++ Decide on whether to remove read/write distance.
++ Add ROUNDS and PSPACE and LDP and STP.
++ Define "battle" and "rounds" in the glossary.
++ The assembler and run-time environment must agree on the value of
+ predefined labels. Make this fact explicit.
++ Add CURLINE and VERSION.
++ Decide which one takes precedence if the description and code
+ disagree and write this decision explicitely in the standard.
++ Add the comparison and logical operators to the description and
+ to the grammar of expressions.
++ Specify the operator precedence for expressions (if only by saying
+ it's the same as in the C language).
++ Add multi-line EQUs and FOR/ROF macros.
+
+[Stefan's intro to ver. 3.2]
+
+The sample simulator was rewritten extensively based on suggestions by Damien
+Doligez ("Planar") and on our experience implemementing the pMARS, the first
+ICWS'94 simulator. Thanks to Planar and also Steven Morrell for pointing out
+many omission and ambiguities in the previous revision. Other readers of
+rec.games.corewar have also provided many helpful comments.
+
+Changes incorporated since last revision:
+ Text:
+ - corrected various typos
+ - clarified behaviour of JMN, JMZ and DJN with .F modifier
+ - defined behavior for division by zero
+ - incorporated EOF in grammar, eliminated "empty" expression
+ - limited definition of whitespace to <space> and <tab>
+ - labels are case sensitive
+ - "pointer counter" -> "program counter"
+ - added default modifier rules (A.2.1.1-2)
+ Sample code:
+ - macro'ized ADD/SUB/MUL/DIV code
+ - test for division by zero
+ - .AB in JMZ, JMN, DJN works now like .B; .BA like .A
+ - fixed DJN.F, JMN.F
+
+To do for next revision:
+ - fix formal grammar (still flaky)
+ - exclude/redefine read/write limits, add jump limit?
+
+[Mark's intro to ver. 3.1]
+
+The information presented here is not part of the Draft proper. The Draft
+proper immediately follows these annotations, beginning with the line
+"0001 Draft of Proposed 1994 Core War Standard". The content lines of the
+Draft proper are numbered for easy reference. The numbers may or may not
+be included in the final Draft.
+
+Internal annotations were removed to clean-up the draft for presentation to
+the ICWS for comment. These annotations which precede the draft take their
+place.
+
+Open-ended references were removed to clean-up the draft for presentation
+to the ICWS for comment. The question of the inclusion or exclusion of
+various opcodes, modes, etc. has not been closed as of yet. Such additions
+or deletions should be finalized by the next draft however.
+
+Previously speculative references were either included or removed to
+clean-up the draft for presentation to the ICWS for comment. See above.
+
+The Load File section was rewritten to aid in the readability of load
+files. It was deemed best that Load Files be a subset of Assembly Files;
+therefore Load Files should logically follow the Assembly File section.
+For that reason, the two sections have been swapped.
+
+Example MARS code is now included. Other parts of the standard, such as
+validation, remain incomplete. The remaining incomplete sections do not
+impact on the other sections of the standard and so can be completed even
+after consideration of the rest of the draft by the ICWS. Alternatively,
+they could be issued as separate documents.
+
+The MARS code is specifically designed to mirror the draft as closely as
+possible. There is a multitude of optimizations which could have been
+made but were not in order that the example code could serve as a
+possible clarification of obscure parts of the draft. Do not suggest
+changes to the example code which speed up processing at the expense of
+mirroring the draft.
+
+Several changes have been made with the goal of expanding the flexibility
+of Core War without compromising backwards compatibility and without
+seriously altering the nature of the game. In that vein:
+
+The modulus '%' operator was added to the Assembly File section.
+
+Read and Write limitations with folding have been clarified. These limits
+allow the possibility of warriors essentially running in a mini-core inside
+core, folding out-of-bounds access attempts back into accessible memory.
+The main advantages to folding are: old-style bombers like Dwarf do not
+unfairly and unknowingly spend cycles doing nothing, and movement to seek
+and destroy enemy warriors is still encouraged by the limits. The main
+disadvantage is that limits which are not factors of the size of core lead
+to unexpected results. Example: a reference to address location -1 is
+adjusted to M-1 when loaded into core and will not fold to R-1 and/or W-1
+if R or W are not factors of M (M is size of core, R is the read limit, and
+W is the write limit). Of course, if R = W = M, then play is equivalent
+to ICWS'88 without limits.
+
+
+In the 5.MARS section of the draft, many of the terms such as A-operand
+were used both as containers ("Writes to the A-operand") and the contents
+of those containers ("Compare the A-operand to ..."). Such ambiguous terms
+and references have hopefully been eradicated.
+
+Although such eradication eliminates ambiguity, it encourages obfuscation
+and/or the proliferation of terms. A delicate balance has, perhaps, been
+struck between the two.
+
+The following are terms which are new or may be used differently than in
+the past. All terms are contents (not containers).
+
+opcode modifier : Removes mode-specific behaviour from opcodes by
+ explicitly stating whether an instruction uses just one number,
+ two numbers, or a whole instruction.
+A-number : Replaces A-field/A-value/A-term, etc. A general term, not tied
+ to any specific instruction.
+B-number : Replaces B-field/B-value/B-term, etc. A general term, not tied
+ to any specific instruction.
+current instruction : Specifically means the instruction in the instruction
+ register. Does NOT mean the instruction in core pointed to by the
+ program counter. (That instruction may have changed since the
+ current instruction was copied from there).
+A-instruction : Specifically means the copy of the instruction in core (at
+ the time of A-operand evaluation) pointed to by the A-number.
+B-instruction : Specifically means the copy of the instruction in core (at
+ the time of B-operand evaluation) pointed to by the B-number.
+A-value : Now refers to the object(s) (A/B-number(s) of the A-instruction
+ or the A-instruction) referenced by the A-operand (as selected by
+ the opcode modifier).
+B-value : Now refers to the object(s) (A/B-number(s) of the B-instruction
+ or the B-instruction) referenced by the B-operand (as selected by
+ the opcode modifier).
+B-target: The object(s) (A/B-number(s) of the instruction in core [at the
+ time of opcode execution] or the instruction) pointed to by the
+ B-number.
+
+
+Six opcode modifiers have been added to the Draft. Modifiers are appended
+to the opcodes with a dot. Example: "MOV.A". The modifiers are:
+
+.A Instructions use and write A-numbers.
+.B Instructions use and write B-numbers.
+.AB Instructions use the A-numbers of the A-instructions and the
+ B-numbers of the B-instructions and write B-numbers.
+.BA Instructions use the B-numbers of the A-instructions and the
+ A-numbers of the B-instructions and write A-numbers.
+.F Instructions use both the A-numbers and the B-numbers, using and
+ writing A-to-A, B-to-B.
+.X Instructions use both the A-numbers and the B-numbers, using and
+ writing A-to-B, B-to-A.
+.I Instructions use and write entire instructions.
+
+See Section 5.4 for more information (especially the examples).
+
+There could be modifiers (other than .I) which take the modes into account,
+but their utility may not warrant their inclusion.
+
+The advantages of opcode modifiers include: greatly expanding the function
+of opcodes without greatly expanding the number of opcodes, separating
+opcode evaluation from operand evaluation (i.e. the behaviours of the
+opcodes no longer depend on the modes), rendering moot questions about
+whether ADD, SUB, etc. should use one or two fields (and if one field,
+whether to use the A-field or the B-field), adding versatility to the order
+of task splitting, and providing a "Skip if greater than" equivalent to
+SLT.
+
+In addition, backwards compatibility with ICWS'88 (and even ICWS'86) is
+easily accomplished at the assembly level. Any instructions with opcodes
+without modifiers would be translated to the appropriate opcode.modifier
+pair. Examples:
+
+"MOV #a, B", which only moves the A-field of the current instruction to the
+B-field of the instruction pointed to by B, would be translated to
+"MOV.AB #a, B". Similarly, "MOV a, b", which moves an entire instruction
+from A to B, becomes "MOV.I a, b". Instructions which were previously
+impossible, such as moving a B-field to an A-field, are now very
+simple and intuitive with "MOV.BA A, B". Another example,
+"MOV.X target, target" takes the place of "XCH target", exchanging fields.
+Finally, "ADD a, b" would translate to "ADD.F a, b" for ICWS'88 and
+"ADD.B a, b" for ICWS'86.
+
+There is one negative to one opcode modifier. ".I" only really makes sense
+for MOV and CMP. It would be possible to define results for arithmetic
+manipulation and ordinal comparison of opcodes and modes, but it would be
+very artificial. As an alternative, .I falls back to .F functionality (for
+opcodes other than MOV and CMP) in this document.
+
+
+Things which absolutely must be done before final consideration for
+adoption by the ICWS:
+
+ 1. Complete incomplete sections or remove references to them
+ 2. Add typographic distinctions to grammars
+
+To aid in completion of the draft, all suggested revisions of the draft
+should consist of explicit remarks such as:
+
+ Delete lines xxxx to yyyy
+ Add the following after line zzzz ....
+ Replace lines vvvv to wwww with ....
+
+Please individually explain why each revision is necessary.
+
+
+The maximal verbosity of the draft is intentional. Each sentence either
+presents a new item, a clarification of an item, or an old item in a new
+context. The goal is that no two reasonable people could arrive at
+two different interpretations of the draft.
+
+\start numbering
+0001 Draft of Proposed 1994 Core War Standard
+
+0002 Version 3.3
+0003 Draft Last Modified: November 8, 1995
+0004 Last modified by: Damien Doligez
+0005 Base draft by: Mark Durham
+
+
+0006 i. Contents
+
+0007 1. Introduction
+0008 1. Purpose
+0009 2. Overview
+0010 3. Acknowledgements
+0011 2. Redcode Assembly File Format
+0012 1. Purpose
+0013 2. Description
+0014 3. Grammar
+0015 4. Assembly To Object Code Conversion
+0016 5. Pseudo-instructions
+0017 6. Comment Conventions
+0018 7. Example Assembly File
+0019 3. Load File Format
+0020 1. Purpose
+0021 2. Description
+0022 3. Grammar
+0023 4. Comment Conventions
+0024 5. Example Load File
+0025 4. Run-time Variables
+0026 1. Purpose
+0027 2. Predefined Labels
+0028 3. Variables
+0029 4. Standard Variable Sets
+0030 5. MARS
+0031 1. Purpose
+0032 2. Description
+0033 3. Address Modes
+0034 1. Immediate
+0035 2. Direct
+0036 3. A-number Indirect
+0037 4. B-number Indirect
+0038 5. A-number Predecrement Indirect
+0039 6. B-number Predecrement Indirect
+0040 7. A-number Postincrement Indirect
+0041 8. B-number Postincrement Indirect
+0042 4. Modifiers
+0043 1. A
+0044 2. B
+0045 3. AB
+0046 4. BA
+0047 5. F
+0048 6. X
+0049 7. I
+0050 5. Instruction Set
+0051 1. DAT
+0052 2. MOV
+0053 3. ADD
+0054 4. SUB
+0055 5. MUL
+0056 6. DIV
+0057 7. MOD
+0058 8. JMP
+0059 9. JMZ
+0060 10. JMN
+0061 11. DJN
+0062 12. SEQ and CMP
+0063 13. SNE
+0064 14. SLT
+0065 15. SPL
+0066 16. NOP
+0067 6. Example MARS interpreter
+0068 6. Validation Suite
+0069 1. Purpose and Requirements
+0070 2. Tests
+0071 1. Assembly to Load File Test
+0072 2. MARS Tests
+0073 1. DAT Tests
+0074 2. MOV Tests
+0075 3. ADD Tests
+0076 4. SUB Tests
+0077 5. MUL Tests
+0078 6. DIV Tests
+0079 7. MOD Tests
+0080 8. JMP Tests
+0081 9. JMZ Tests
+0082 10. JMN Tests
+0083 11. DJN Tests
+0084 12. SEQ/CMP Tests
+0085 13. SNE Tests
+0086 14. SLT Tests
+0087 15. SPL Tests
+0088 16. NOP Tests
+0089 7. Glossary and Index
+
+0090 A. Differences Between Standards
+0091 1. Purpose
+0092 2. Changes
+0093 1. Assembly Files
+0094 1. ICWS'88 conversion
+0095 2. ICWS'86 conversion
+0096 2. Load Files
+0097 3. MARS
+
+
+0098 1. Introduction
+
+0099 1.1 Purpose
+0100 This standard seeks to fully define and describe the game of Core War.
+
+0101 1.2 Overview
+0102 Core War is a game in which programs compete for control of a computer
+0103 called MARS (for Memory Array Redcode Simulator). Redcode is the name
+0104 of the assembly language in which Core War programs, called warriors,
+0105 are written.
+
+0106 In order to play Core Wars, access to a Core War system is required.
+0107 A Core War system at a minimum must have a MARS executive function
+0108 (interpreter) and a way to load warriors into core (the MARS memory).
+0109 Most systems include a Redcode assembler, either separately or as part
+0110 of the loader. Also, many systems include a graphical interface and
+0111 code debugging features. Some systems have the ability to run
+0112 automated tournaments.
+
+0113 1.3 Acknowledgements
+0114 This document is the fourth standard for Core War, the first three
+0115 being "Core War Guidelines" (March 1984) by D. G. Jones and
+0116 A. K. Dewdney, the International Core War Society standard of 1986 -
+0117 "Core Wars" (May 1986), principally authored by Graeme McRae and the
+0118 "Core Wars Standard of 1988" (Summer 1988), principally authored by
+0119 Thomas Gettys. The latter two standards are often referred to as
+0120 ICWS'86 and ICWS'88, respectively.
+
+0121 People who contributed to this document (in alphabetical order):
+0122 Scott W. Adkins
+0123 Mark A. Durham
+0124 Anders Ivner
+0125 Morten Due Joergensen
+0126 Paul Kline
+0127 Scott Nelson
+0128 Jon Newman
+0129 John Perry
+0130 Andy Pierce
+0131 Planar
+0132 Wayne Sheppard
+0133 William Shubert
+0134 Nandor Sieben
+0135 Stefan Strack
+0136 Mintardjo Wangsaw
+0137 Kevin Whyte
+
+
+0138 2. Redcode Assembly File Format
+
+0139 2.1 Purpose
+0140 A Redcode assembly file consists of the information necessary for a
+0141 Redcode assembler to produce a load file. A standard assembly file
+0142 format allows programmers to exchange warriors in a more meaningful
+0143 format than load files. An assembly file, through the use of labels,
+0144 arithmetic expressions, and macros can also greatly reduce the work
+0145 necessary to produce a particular warrior while enhancing code
+0146 readability.
+
+0147 2.2 Description
+0148 Each Redcode warrior consists of one or more lines of Redcode. Each
+0149 line of Redcode consists of a string of alphanumerals and special
+0150 characters. Special characters in Redcode are the addressing mode
+0151 indicators for immediate '#', direct '$', A-number indirect '*',
+0152 B-number indirect '@', A-number predecrement indirect '{', B-number
+0153 predecrement indirect '<', A-number postincrement indirect '}', and
+0154 B-number postincrement indirect '>' modes, the field separator
+0155 (comma) ',', the comment indicator (semicolon) ';', the arithmetic
+0156 operators for addition '+', subtraction '-', multiplication '*',
+0157 division '/', and modulus '%', and opening '(' and closing ')'
+0158 parentheses for precedence grouping.
+
+0159 A line may be blank or consist of an instruction, a
+0160 pseudo-instruction, a comment, or an instruction or
+0161 pseudo-instruction followed by a comment. Each line is terminated
+0162 with a newline. All comments begin with a semicolon. Each
+0163 instruction consists of these elements in the following order: a
+0164 label, an opcode, an A-operand, a comma, and a B-operand. Each
+0165 element may be preceded and/or followed by whitespace (newline is
+0166 not considered whitespace). The label is optional. If either
+0167 operand is blank, the comma may be omitted. The operands may not
+0168 be both blank.
+
+0169 Pseudo-instructions appear just like instructions but are directives
+0170 to the assembler and do not result in object code as an instruction
+0171 would. Each pseudo-instruction has a pseudo-opcode which appears
+0172 where an opcode would appear in an instruction. The format of the
+0173 remainder of the pseudo-instruction depends on which pseudo-opcode is
+0174 used. For the remainder of this section (2.2) and the next (2.3),
+0175 references to "opcode" include "pseudo-opcode" assembler directives.
+
+0176 A label is any alphanumeric string other than those reserved for
+0177 opcodes. Labels are case sensitive, i.e. "start" is different from
+0178 "Start". An opcode is any of the following: DAT, MOV, ADD, SUB, MUL,
+0179 DIV, MOD, JMP, JMZ, JMN, DJN, CMP, SEQ, SNE, SLT, SPL, and NOP.
+0180 Opcodes may be in upper or lower case or any combination. An opcode
+0181 may be followed by a modifier. A modifier always begins with a dot.
+0182 A modifier is any of the following: .A, .B, .AB, .BA, .F, .X, or .I.
+0183 Modifiers may be in upper or lower case or any combination.
+
+0184 Each operand is blank, contains an address, or contains an addressing
+0185 mode indicator and an address. An address consists of any number of
+0186 labels and numbers separated by arithmetic operators and possibly
+0187 grouped with parentheses. All elements of an address may be separated
+0188 by whitespace.
+
+0189 2.3 Grammar
+0190 Tokens are separated by whitespace (space and tab) exclusive of
+0191 newline characters, which are used for line termination. End-of-file
+0192 should occur only where newline could logically occur, otherwise the
+0193 assembly file is invalid.
+
+0194 In the following, 'e' is the "empty" element, meaning the token may be
+0195 omitted, a caret '^' means NOT, an asterisk '*' immediately adjacent
+0196 means zero or more occurrences of the previous token, and a plus '+'
+0197 immediately adjacent means one or more occurrences of the previous
+0198 token. The vertical bar '|' means OR.
+
+0199 assembly_file:
+0200 line+ EOF
+0201 line:
+0202 comment | instruction
+0203 comment:
+0204 ; v* newline | newline
+0205 instruction:
+0206 label_list operation mode expr comment |
+0207 label_list operation mode expr , mode expr comment
+0208 label_list:
+0209 label newline* label_list | e
+0210 label:
+0211 alpha alphanumeral*
+0212 operation:
+0213 opcode | opcode.modifier
+0214 opcode:
+0215 DAT | MOV | ADD | SUB | MUL | DIV | MOD |
+0216 JMP | JMZ | JMN | DJN | CMP | SEQ | SNE |
+0217 SLT | SPL | NOP | ORG | EQU | END
+0218 modifier:
+0219 A | B | AB | BA | F | X | I
+0220 mode:
+0221 # | $ | * | @ | { | < | } | > | e
+0222 expr:
+0223 term |
+0224 term + expr | term - expr |
+0225 term * expr | term / expr |
+0226 term % expr
+0227 term:
+0228 label | number | ( expression )
+0229 number:
+0230 whole_number | signed_integer
+0231 signed_integer:
+0232 +whole_number | -whole_number
+0233 whole_number:
+0234 numeral+
+0235 alpha:
+0236 A-Z | a-z | _
+0237 numeral:
+0238 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+0239 alphanumeral:
+0240 alpha | numeral
+0241 v:
+0242 ^newline
+0243 newline:
+0244 LF | CR | LF CR | CR LF
+0245 e:
+
+
+0246 2.4 Assembly To Load File Conversion
+0247 A Redcode program can be assembled into a list of MARS instructions.
+0248 (When assembled to a file instead of directly to core, the list is
+0249 called a load file. See Section 3). Each Redcode instruction
+0250 assembles into a MARS instruction of five fields: an opcode.modifier
+0251 field, the A-mode field, the A-address field, the B-mode field, and
+0252 the B-address field. A missing (null or blank) mode assembles as '$'
+0253 does.
+
+0254 If no modifier is present in the assembly instruction, the appropriate
+0255 modifier is appended to the opcode. The appropriate modifier depends
+0256 upon the opcode, the modes, and which standard (ICWS'86 or ICWS'88) to
+0257 consider (ICWS'88 by default). See Appendix A for the appropriate
+0258 translations.
+
+0259 The address field values are derived from the numbers, labels, and
+0260 arithmetic operators contained in the addresses. Labels are
+0261 converted to an address relative to the current instruction. Then
+0262 the arithmetic operations are carried out according to the
+0263 appropriate operator and parenthetical precedence to determine the
+0264 final value. If there is only one operand associated with a DAT
+0265 instruction, this operand is assembled into the B-mode and B-address
+0266 fields, while #0 is assembled into the A-mode and A-address fields.
+0267 For all other instructions with only one operand, this operand is
+0268 assembled into the A-mode and A-address fields and #0 is assembled
+0269 into the B-mode and B-address fields.
+
+0270 2.5 Pseudo-instructions
+0271 Pseudo-opcodes are "ORG", "EQU", and "END".
+
+0272 "ORG" ("ORiGin") is a way for the assembly file to indicate the
+0273 logical origin of the warrior. The A-operand contains an offset to
+0274 the logical first instruction. Thus "ORG 0" means execution should
+0275 start with the first instruction (the default) whereas "ORG 6" means
+0276 execution should start with the seventh instruction. Although multiple
+0277 ORG instructions are of no additional benefit to the programmer, they
+0278 are allowed. When there is more than one ORG instruction in a file,
+0279 the last ORG instruction encountered will be the one that takes
+0280 effect.
+
+0281 "EQU" ("EQUate") is a simple text substitution utility. Instructions
+0282 of the form "label EQU text" will replace all occurrences of "label"
+0283 with the (probably longer and more complicated) "text" before any
+0284 actual assembly takes place on the file. Some labels are predefined
+0285 with the value of run-time variables as if they were defined with
+0286 EQU at the start of the program (see section 4.2 for the list of
+0287 predefined labels).
+
+0288 "END" indicates the logical end of the assembly file. If END has an
+0289 A-operand, then the A-operand indicates the logical origin of the
+0290 warrior in the same manner as ORG does. The rest of the file (after
+0291 the end of the line containing END) is ignored.
+
+
+0292 2.6 Comment Conventions
+0293 ";redcode<switch>" as a first line identifies the file as a Redcode
+0294 assembly file. The "<switch>" is optional and implementation
+0295 dependent.
+
+0296 ";strategy <text>" indicates a comment for "public" consumption.
+
+0297 ";name <program name>", ";author <name of author(s)>",
+0298 ";version <version number>", and ";date <date of last revision>"
+0299 offer uniform ways of presenting this information.
+
+0300 ";kill <program name>" is for removing warriors from ongoing
+0301 tournaments. If no <program name> is supplied, all of the author's
+0302 previous submissions will be removed.
+
+0303 ";assert <expression>" will evaluate the expression and trigger
+0304 an error if it is 0. In conjunction with predefined labels (see
+0305 section 4.2), this provides a way of specifying the conditions under
+0306 which a warrior is supposed to run.
+
+
+0307 2.7 Example Assembly File
+
+0308 ;redcode
+
+0309 ;name Dwarf
+0310 ;author A. K. Dewdney
+0311 ;version 94.1
+0312 ;date April 29, 1993
+
+0313 ;strategy Bombs every fourth instruction.
+0314 ;assert CORESIZE % 4 == 0
+
+0315 ORG start ; Indicates the instruction with
+0316 ; the label "start" should be the
+0317 ; first to execute.
+
+0318 step EQU 4 ; Replaces all occurrences of "step"
+0319 ; with the character "4".
+
+0320 target DAT.F #0, #0 ; Pointer to target instruction.
+0321 start ADD.AB #step, target ; Increments pointer by step.
+0322 MOV.AB #0, @target ; Bombs target instruction.
+0323 JMP.A start ; Same as JMP.A -2. Loops back to
+0324 ; the instruction labelled "start".
+0325 END
+
+
+0326 3. Load File Format
+
+0327 3.1 Purpose
+0328 A load file represents the minimum amount of information necessary for
+0329 a warrior to execute properly and is presented in a very simple format
+0330 which is a subset of the assembly file format presented in Section 2.
+0331 A standard load file format allows programmers to choose assemblers
+0332 and MARS programs separately and to verify assembler performance and
+0333 MARS performance separately. Not all Core War systems will necessarily
+0334 write load files (for example, those which assemble directly to core),
+0335 but all systems should support reading load files.
+
+0336 3.2 Description
+
+0337 Each load file will consist of one or more lines of MARS
+0338 instructions or comments. Each line is terminated with a newline.
+0339 All comments start with with a semicolon. Each MARS instruction
+0340 consists of five fields: an opcode.modifier pair, an A-mode, an
+0341 A-field, a B-mode, and a B-field. The A-mode is separated from the
+0342 opcode.modifier pair by whitespace and the B-mode is separated from
+0343 the A-field by a comma and additional whitespace. Each MARS
+0344 instruction may be followed by extraneous information, which is
+0345 ignored. Note that the instruction format for load files is more
+0346 rigid than for assembly files to simplify parsing. No blank modes or
+0347 operands are allowed.
+
+
+0348 3.3 Grammar
+0349 Tokens are separated by whitespace (non-marking characters such as
+0350 SPACE and TAB) exclusive of newline characters, which are used for
+0351 line termination. End-of-file should occur only where newline could
+0352 logically occur, otherwise the load file is invalid.
+
+0353 load_file:
+0354 line+ EOF
+0355 line:
+0356 comment | instruction
+0357 comment:
+0358 ; v* newline | newline
+0359 instruction:
+0360 opcode.modifier mode number , mode number comment
+0361 opcode:
+0362 DAT | MOV | ADD | SUB | MUL | DIV | MOD |
+0363 JMP | JMZ | JMN | DJN | CMP | SEQ | SNE |
+0364 SLT | SPL | NOP | ORG
+0365 modifier:
+0366 A | B | AB | BA | F | X | I
+0367 mode:
+0368 # | $ | @ | * | < | { | > | }
+0369 number:
+0370 whole_number | signed_integer
+0371 signed_integer:
+0372 +whole_number | -whole_number
+0373 whole_number:
+0374 numeral+
+0375 numeral:
+0376 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+0377 v:
+0378 ^newline
+0379 newline:
+0380 LF | CR | LF CR | CR LF
+
+
+0381 3.4 Comment Conventions
+0382 Comment conventions for load files are the same as for assembly files.
+0383 Of particular note are the "; name <program name>" and "; author
+0384 <author(s)>" comments. These comments provide a more suitable
+0385 identification of programs to the MARS than "Warrior #1", "Warrior #2",
+0386 etc. It also allows for less cryptic identification than by filename.
+
+
+0387 3.5 Example Load File
+0388 ;redcode
+
+0389 ;name Dwarf
+0390 ;author A. K. Dewdney
+0391 ;version 94.1
+0392 ;date April 29, 1993
+
+0393 ;strategy Bombs every fourth instruction.
+0394 ;assert CORESIZE % 4 == 0
+
+0395 ORG 1 ; Indicates execution begins with the second
+0396 ; instruction (ORG is not actually loaded, and is
+0397 ; therefore not counted as an instruction).
+
+0398 DAT.F #0, #0 ; Pointer to target instruction.
+0399 ADD.AB #4, $-1 ; Increments pointer by step.
+0400 MOV.AB #0, @-2 ; Bombs target instruction.
+0401 JMP.A $-2, #0 ; Loops back two instructions.
+
+
+0402 4. Run-time Variables
+
+0403 4.1 Purpose
+0404 This section describes those variables which are determined just prior
+0405 to running a battle by the person running the battle. It also
+0406 enumerates some of the standardized sets of variables used for
+0407 tournaments.
+
+0408 4.2 Predefined Labels
+0409 Most of the run-time variables are available to the programmer as
+0410 predefined labels. The purpose of these labels is twofold: first,
+0411 to parameterize the warriors with the characteristics of their
+0412 run-time environment; second, to check (with the ";assert" comment)
+0413 that the warrior is run in an environment that makes sense for it.
+
+0414 The next section gives a list of the run-time variables. When
+0415 a predefined label takes the value of the variable, the label is
+0416 given between parentheses after the name of the variable.
+
+0417 4.2 Variables
+0418 Run-time variables consist of the following:
+
+0419 Core Size: (CORESIZE)
+0420 Core size is the number of instructions which make up core
+0421 during the battle.
+
+0422 Cycles Before Tie: (MAXCYCLES)
+0423 In each cycle, one instruction from each warrior is executed.
+0424 This variable determines how many cycles without a winner
+0425 should be executed before declaring a tie.
+
+0426 Initial Instruction:
+0427 The initial instruction is that instruction which is preloaded
+0428 into core prior to loading warriors. In addition to loading
+0429 an instruction such as "DAT #0, #0" into all of core, the
+0430 initial instruction could be set to "NONE", meaning core should
+0431 not be cleared between battles, or "RANDOM", meaning core
+0432 instructions are filled with randomly generated instructions.
+
+0433 Instruction Limit: (MAXLENGTH)
+0434 The maximum number of instructions allowed per load file.
+
+0435 Maximum Number of Tasks: (MAXPROCESSES)
+0436 Each warrior can spawn multiple additional tasks. This
+0437 variable sets the maximum number of tasks allowed per warrior.
+0438 In other words, this is the size of each warrior's task queue.
+
+0439 Minimum Separation: (MINDISTANCE)
+0440 The minimum number of instructions from the first instruction
+0441 of one warrior to the first instruction of the next warrior.
+
+0442 Read Distance:
+0443 This is the range available for warriors to read information
+0444 from core. Attempts to read outside the limits of this range
+0445 result in reading within the local readable range. The range
+0446 is centered on the current instruction. Thus, a range of
+0447 500 limits reading to offsets of (-249 -> +250) from the
+0448 currently executing instruction. The read limit can therefore
+0449 be considered a mini-core within core. An attempt to read
+0450 location PC+251 reads location PC-249 instead. An attempt to
+0451 read location PC+500 reads location PC instead.
+
+0452 Read distance must be a factor of core size, otherwise the
+0453 above defined behaviour is not guaranteed.
+
+0454 Separation:
+0455 The number of instructions from the first instruction of one
+0456 warrior to the first instruction of the next warrior.
+0457 Separation can be set to "RANDOM", meaning separations will be
+0458 chosen randomly from those larger than the minimum separation.
+
+0459 Warriors:
+0460 The initial number of warriors to battle simultaneously in
+0461 core.
+
+0462 Write Distance:
+0463 This is the range available for warriors to write information
+0464 to core. Attempts to write outside the limits of this range
+0465 result in writing within the local writable range. The range
+0466 is centered on the current instruction. Thus, a range of 500
+0467 limits writing to offsets of (-249 -> +250) from the
+0468 currently executing instruction. The write limit can
+0469 therefore be considered a mini-core within core. An attempt
+0470 to write location PC+251 writes to location PC-249 instead.
+0471 An attempt to write to location PC+500 writes to location PC
+0472 instead.
+
+0473 Write distance must be a factor of core size, otherwise the
+0474 above defined behaviour is not guaranteed.
+
+
+0475 4.3 Standard Variable Sets
+0476 ICWS86:
+0477 Core Size: 8192
+0478 Cycles Before Tie: 100000
+0479 Initial Instruction: DAT.F #0, #0
+0480 Instruction Limit: 300
+0481 Maximum Number of Tasks: 64
+0482 Minimum Separation: 300
+0483 Read Distance: 8192
+0484 Separation: RANDOM
+0485 Warriors: 2
+0486 Write Distance: 8192
+
+0487 KOTH:
+0488 Core Size: 8000
+0489 Cycles Before Tie: 80000
+0490 Initial Instruction: DAT.F $0, $0
+0491 Instruction Limit: 100
+0492 Maximum Number of Tasks: 8000
+0493 Minimum Separation: 100
+0494 Read Distance: 8000
+0495 Separation: RANDOM
+0496 Warriors: 2
+0497 Write Distance: 8000
+
+
+0498 5. MARS
+
+0499 5.1 Purpose
+0500 The Memory Array Redcode Simulator (MARS) is the computer in which
+0501 Core War warriors do combat.
+
+0502 5.2 Description
+0503 A minimally-complete MARS consists of a core, a loader, task queues,
+0504 the MARS executive function, and a way to present the final results of
+0505 a battle. Additionally, many MARS provide a "real-time" battle
+0506 display and various debugging tools.
+
+0507 The core consists of a cyclic list (0, 1, 2, ..., M-2, M-1, 0, 1, ...)
+0508 of M MARS instructions. The integer M is referred to as "core size".
+0509 All operations are performed modulo M. Core initialization (the
+0510 initial instructions placed in core before loading warriors) is a
+0511 run-time variable (see Section 4).
+
+0512 The loader loads warriors into core, converting each negative field
+0513 value N to the positive field value P such that 0 <= P < M and P = kM
+0514 + N where k is a positive integer (P = N modulo M). Each field value
+0515 G greater than or equal to M is converted to the field values L such
+0516 that 0 <= L < M and L = kM + G where k is a negative integer (L = G
+0517 modulo M). The loader also initializes each warrior's task queue with
+0518 the appropriate task pointer.
+
+0519 There is a task queue for each warrior loaded into core. Each task
+0520 queue can hold a limited number of task pointers. The "task limit"
+0521 (number of tasks an individual warrior's task queue can hold) is a
+0522 run-time variable. The task queues are FIFOs (First In, First Out).
+
+0523 Each warrior consists of one task initially. Subsequent tasks are
+0524 added to the warrior's task queue using the SPL instruction. Attempted
+0525 execution of a DAT instruction by a task effectively removes that task
+0526 from the warrior's task queue.
+
+0527 Warriors execute for a specified number of cycles ("time limit", see
+0528 Section 4) or until only one warrior is still executing, whichever
+0529 occurs first. Each cycle, one instruction from each warrior is
+0530 executed. The instruction to execute is the instruction pointed to by
+0531 the next task pointer in the warrior's task queue. A warrior is no
+0532 longer executing when its task queue is empty.
+
+0533 The following expressions are used in describing the MARS executive
+0534 function's operation.
+
+0535 General Definitions:
+0536 An instruction consists of an opcode, a modifier, an A-operand,
+0537 and a B-operand.
+0538 An A-operand consists of an A-mode and an A-number.
+0539 An A-mode is the addressing mode of an A-operand.
+0540 An A-number is an integer between 0 and M-1, inclusive.
+0541 A B-operand consists of a B-mode and a B-number.
+0542 A B-mode is the addressing mode of a B-operand.
+0543 A B-number is an integer between 0 and M-1, inclusive.
+
+0544 Specific Definitions:
+0545 The program counter (PC) is the pointer to the location in core of
+0546 the instruction fetched from core to execute.
+0547 The current instruction is the instruction in the instruction
+0548 register, as copied (prior to execution) from the PC
+0549 location of core.
+0550 The A-pointer points to the instruction the A-operand of the
+0551 current instruction references in core.
+0552 The A-instruction is a copy of the instruction the A-pointer
+0553 points to in core (as it was during operand evaluation).
+0554 The A-value is the A-number and/or the B-number of the
+0555 A-instruction or the A-instruction itself, whichever are/is
+0556 selected by the opcode modifier.
+0557 The B-pointer points to the instruction the B-operand of the
+0558 current instruction references in core.
+0559 The B-instruction is a copy of the instruction the B-pointer
+0560 points to in core (as it was during operand evaluation).
+0561 The B-value is the A-number and/or the B-number of the
+0562 B-instruction or the B-instruction itself, whichever are/is
+0563 selected by the opcode modifier.
+0564 The B-target is the A-number and/or the B-number of the instruction
+0565 pointed to by the B-pointer or the instruction itself,
+0566 whichever are/is selected by the opcode modifier.
+
+0567 All MARS instructions are executed following the same procedure:
+0568 1. The currently executing warrior's current task pointer is
+0569 extracted from the warrior's task queue and assigned to the
+0570 program counter.
+0571 2. The corresponding instruction is fetched from core and stored in
+0572 the instruction register as the current instruction.
+0573 3. The A-operand of the current instruction is evaluated.
+0574 4. The results of A-operand evaluation, the A-pointer and the
+0575 A-instruction, are stored in the appropriate registers.
+0576 5. The B-operand of the current instruction is evaluated.
+0577 6. The results of B-operand evaluation, the B-pointer and the
+0578 B-instruction, are stored in the appropriate registers.
+0579 7. Operations appropriate to the opcode.modifier pair in the
+0580 instruction register are executed. With the exception of DAT
+0581 instructions, all operations queue an updated task pointer.
+0582 (How the task pointer is updated and when it is queued depend on
+0583 instruction execution).
+
+0584 All pointers are PC-relative, indicating the offset from the source of
+0585 the current instruction to the desired location. All arithmetic is to
+0586 be done modulo M, with negative values converted in the same manner as
+0587 during loading as discussed above (P = M + N). Additionally, all
+0588 reads of core are done modulo the read limit (R) and all writes of
+0589 core are done modulo the write limit (W). Read offsets O greater than
+0590 R/2 from the current instruction are converted to backwards offsets of
+0591 O = O - R. A comparable conversion occurs for write offsets greater
+0592 than W/2.
+
+
+0593 5.3 Address Modes
+
+0594 5.3.1 Immediate
+0595 An immediate mode operand merely serves as storage for data. An
+0596 immediate A/B-mode in the current instruction sets the A/B-pointer to
+0597 zero.
+
+0598 5.3.2 Direct
+0599 A direct mode operand indicates the offset from the program counter.
+0600 A direct A/B-mode in the current instruction means the A/B-pointer is
+0601 a copy of the offset, the A/B-number of the current instruction.
+
+0602 5.3.3 A-number Indirect
+0603 An A-number indirect mode operand indicates the primary offset
+0604 (relative to the program counter) to the secondary offset (relative to
+0605 the location of the instruction in which the secondary offset is
+0606 contained). An A-number indirect A/B-mode indicates that the
+0607 A/B-pointer is the sum of the A/B-number of the current instruction
+0608 (the primary offset) and the A-number of the instruction pointed to by
+0609 the A/B-number of the current instruction (the secondary offset).
+
+0610 5.3.4 B-number Indirect
+0611 A B-number indirect mode operand indicates the primary offset
+0612 (relative to the program counter) to the secondary offset (relative to
+0613 the location of the instruction in which the secondary offset is
+0614 contained). A B-number indirect A/B-mode indicates that the
+0615 A/B-pointer is the sum of the A/B-number of the current instruction
+0616 (the primary offset) and the B-number of the instruction pointed to by
+0617 the A/B-number of the current instruction (the secondary offset).
+
+0618 5.3.5 A-number Predecrement Indirect
+0619 An A-number predecrement indirect mode operand indicates the primary
+0620 offset (relative to the program counter) to the secondary offset
+0621 (relative to the location of the instruction in which the secondary
+0622 offset is contained) which is decremented prior to use. An A-number
+0623 predecrement indirect A/B-mode indicates that the A/B-pointer is the
+0624 sum of the A/B-number of the current instruction (the primary offset)
+0625 and the decremented A-number of the instruction pointed to by the
+0626 A/B-number of the current instruction (the secondary offset).
+
+0627 5.3.6 B-number Predecrement Indirect
+0628 A B-number predecrement indirect mode operand indicates the primary
+0629 offset (relative to the program counter) to the secondary offset
+0630 (relative to the location of the instruction in which the secondary
+0631 offset is contained) which is decremented prior to use. A B-number
+0632 predecrement indirect A/B-mode indicates that the A/B-pointer is the
+0633 sum of the A/B-number of the current instruction (the primary offset)
+0634 and the decremented B-number of the instruction pointed to by the
+0635 A/B-number of the current instruction (the secondary offset).
+
+0636 5.3.7 A-number Postincrement Indirect
+0637 An A-number postincrement indirect mode operand indicates the primary
+0638 offset (relative to the program counter) to the secondary offset
+0639 (relative to the location of the instruction in which the secondary
+0640 offset is contained) which is incremented after the results of the
+0641 operand evaluation are stored. An A-number postincrement indirect
+0642 A/B-mode indicates that the A/B-pointer is the sum of the A/B-number of
+0643 the current instruction (the primary offset) and the A-number of the
+0644 instruction pointed to by the A/B-number of the current instruction
+0645 (the secondary offset). The A-number of the instruction pointed to by
+0646 the A/B-number of the current instruction is incremented after the
+0647 A/B-instruction is stored, but before the B-operand is evaluated (for
+0648 A-number postincrement indirect A-mode), or the operation is executed
+0649 (for A-number postincrement indirect B-mode).
+
+0650 5.3.8 B-number Postincrement Indirect
+0651 A B-number postincrement indirect mode operand indicates the primary
+0652 offset (relative to the program counter) to the secondary offset
+0653 (relative to the location of the instruction in which the secondary
+0654 offset is contained) which is incremented after the results of the
+0655 operand evaluation are stored. A B-number postincrement indirect
+0656 A/B-mode indicates that the A/B-pointer is the sum of the A/B-number of
+0657 the current instruction (the primary offset) and the B-number of the
+0658 instruction pointed to by the A/B-number of the current instruction
+0659 (the secondary offset). The B-number of the instruction pointed to by
+0660 the A/B-number of the current instruction is incremented after the
+0661 A/B-instruction is stored, but before the B-operand is evaluated (for
+0662 B-number postincrement indirect A-mode), or the operation is executed
+0663 (for B-number postincrement indirect B-mode).
+
+
+0664 5.4 Modifiers
+
+0665 5.4.1 A
+0666 Instruction execution proceeds with the A-value set to the A-number of
+0667 the A-instruction and the B-value set to the A-number of the
+0668 B-instruction. A write to core replaces the A-number of the
+0669 instruction pointed to by the B-pointer.
+
+0670 For example, a CMP.A instruction would compare the A-number of the
+0671 A-instruction with the A-number of the B-instruction. A MOV.A
+0672 instruction would replace the A-number of the instruction pointed to
+0673 by the B-pointer with the A-number of the A-instruction.
+
+0674 5.4.2 B
+0675 Instruction execution proceeds with the A-value set to the B-number of
+0676 the A-instruction and the B-value set to the B-number of the
+0677 B-instruction. A write to core replaces the B-number of the
+0678 instruction pointed to by the B-pointer.
+
+0679 For example, a CMP.B instruction would compare the B-number of the
+0680 A-instruction with the B-number of the B-instruction. A MOV.B
+0681 instruction would replace the B-number of the instruction pointed to
+0682 by the B-pointer with the B-number of the A-instruction.
+
+0683 5.4.3 AB
+0684 Instruction execution proceeds with the A-value set to the A-number of
+0685 the A-instruction and the B-value set to the B-number of the
+0686 B-instruction. A write to core replaces the B-number of the
+0687 instruction pointed to by the B-pointer.
+
+0688 For example, a CMP.AB instruction would compare the A-number of the
+0689 A-instruction with the B-number of the B-instruction. A MOV.AB
+0690 instruction would replace the B-number of the instruction pointed to
+0691 by the B-pointer with the A-number of the A-instruction.
+
+0692 5.4.4 BA
+0693 Instruction execution proceeds with the A-value set to the B-number of
+0694 the A-instruction and the B-value set to the A-number of the
+0695 B-instruction. A write to core replaces the A-number of the
+0696 instruction pointed to by the B-pointer.
+
+0697 For example, a CMP.BA instruction would compare the B-number of the
+0698 A-instruction with the A-number of the B-instruction. A MOV.BA
+0699 instruction would replace the A-number of the instruction pointed to
+0700 by the B-pointer with the B-number of the A-instruction.
+
+0701 5.4.5 F
+0702 Instruction execution proceeds with the A-value set to both the
+0703 A-number and B-number of the A-instruction (in that order) and the
+0704 B-value set to both the A-number and B-number of the B-instruction
+0705 (also in that order). A write to core replaces both the A-number and
+0706 the B-number of the instruction pointed to by the B-pointer (in that
+0707 order).
+
+0708 For example, a CMP.F instruction would compare the A-number of the
+0709 A-instruction to the A-number of the B-instruction and the B-number of
+0710 the A-instruction to B-number of the B-instruction. A MOV.F
+0711 instruction would replace the A-number of the instruction pointed to by
+0712 the B-pointer with the A-number of the A-instruction and would also
+0713 replace the B-number of the instruction pointed to by the B-pointer
+0714 with the B-number of the A-instruction.
+
+0715 5.4.6 X
+0716 Instruction execution proceeds with the A-value set to both the
+0717 A-number and B-number of the A-instruction (in that order) and the
+0718 B-value set to both the B-number and A-number of the B-instruction
+0719 (in that order). A write to to core replaces both the B-number and
+0720 the A-number of the instruction pointed to by the B-pointer (in that
+0721 order).
+
+0722 For example, a CMP.X instruction would compare the A-number of the
+0723 A-instruction to the B-number of the B-instruction and the B-number of the
+0724 A-instruction to A-number of the B-instruction. A MOV.X instruction
+0725 would replace the B-number of the instruction pointed to by the
+0726 B-pointer with the A-number of the A-instruction and would also replace
+0727 the A-number of the instruction pointed to by the B-pointer with the
+0728 B-number of the A-instruction.
+
+0729 5.4.7 I
+0730 Instruction execution proceeds with the A-value set to the
+0731 A-instruction and the B-value set to the B-instruction. A write to
+0732 core replaces the entire instruction pointed to by the B-pointer.
+
+0733 For example, a CMP.I instruction would compare the A-instruction to
+0734 the B-instruction. A MOV.I instruction would replace the instruction
+0735 pointed to by the B-pointer with the A-instruction.
+
+
+0736 5.5 Instruction Set
+
+0737 5.5.1 DAT
+0738 No additional processing takes place. This effectively removes the
+0739 current task from the current warrior's task queue.
+
+0740 5.5.2 MOV
+0741 Move replaces the B-target with the A-value and queues the next
+0742 instruction (PC + 1).
+
+0743 5.5.3 ADD
+0744 ADD replaces the B-target with the sum of the A-value and the B-value
+0745 (A-value + B-value) and queues the next instruction (PC + 1). ADD.I
+0746 functions as ADD.F would.
+
+0747 5.5.4 SUB
+0748 SUB replaces the B-target with the difference of the B-value and the
+0749 A-value (B-value - A-value) and queues the next instruction (PC + 1).
+0750 SUB.I functions as SUB.F would.
+
+0751 5.5.5 MUL
+0752 MUL replaces the B-target with the product of the A-value and the
+0753 B-value (A-value * B-value) and queues the next instruction (PC + 1).
+0754 MUL.I functions as MUL.F would.
+
+0755 5.5.6 DIV
+0756 DIV replaces the B-target with the integral result of dividing the
+0757 B-value by the A-value (B-value / A-value) and queues the next
+0758 instruction (PC + 1). DIV.I functions as DIV.F would. If the
+0759 A-value is zero, the B-value is unchanged and the current task is
+0760 removed from the warrior's task queue. DIV.I, DIV.F, and DIV.X
+0761 operate on pairs of operands. If either component of the A-value
+0762 is zero, the corresponding component of the B-value is unchanged
+0763 (the other component is divided normally), and the current task is
+0764 removed from the warrior queue.
+
+0765 5.5.7 MOD
+0766 MOD replaces the B-target with the integral remainder of dividing the
+0767 B-value by the A-value (B-value % A-value) and queues the next
+0768 instruction (PC + 1). MOD.I functions as MOD.F would. If the
+0769 A-value is zero, the B-value is unchanged and the current task is
+0770 removed from the warrior's task queue. MOD.I, MOD.F, and MOD.X
+0771 operate on pairs of operands. If either component of the A-value
+0772 is zero, the corresponding component of the B-value is unchanged
+0773 (the other component is divided normally), and the current task is
+0774 removed from the warrior queue.
+
+0775 5.5.8 JMP
+0776 JMP queues the sum of the program counter and the A-pointer.
+
+0777 5.5.9 JMZ
+0778 JMZ tests the B-value to determine if it is zero. If the B-value is
+0779 zero, the sum of the program counter and the A-pointer is queued.
+0780 Otherwise, the next instruction is queued (PC + 1). JMZ.I functions
+0781 as JMZ.F would, i.e. it jumps if both the A-number and the B-number
+0782 of the B-instruction are zero.
+
+0783 5.5.10 JMN
+0784 JMN tests the B-value to determine if it is zero. If the B-value is
+0785 not zero, the sum of the program counter and the A-pointer is queued.
+0786 Otherwise, the next instruction is queued (PC + 1). JMN.I functions
+0787 as JMN.F would, i.e. it jumps if the A-number or the B-number of the
+0788 B-instruction (or both) is non-zero. This is the negation of the
+0789 condition for JMZ.F.
+
+0790 5.5.11 DJN
+0791 DJN decrements the B-value and the B-target, then tests the B-value
+0792 to determine if it is zero. If the decremented B-value is not zero,
+0793 the sum of the program counter and the A-pointer is queued.
+0794 Otherwise, the next instruction is queued (PC + 1). DJN.I functions
+0795 as DJN.F would, i.e. it decrements both both A/B-numbers of the B-value
+0796 and the B-target, and jumps if one (or both) of the A/B-numbers of the
+0797 B-value is non-zero.
+
+0798 5.5.12 SEQ and CMP
+0799 SEQ and CMP are synonymous opcodes. SEQ is provided as an
+0800 easy-to-remember mnemonic, and CMP is provided for backward
+0801 compatibility. They are completely equivalent. SEQ (or CMP) compares
+0802 the A-value to the B-value. If the result of the comparison is equal,
+0803 the instruction after the next instruction (PC + 2) is queued (skipping
+0804 the next instruction). Otherwise, the next instruction is queued
+0805 (PC + 1).
+
+0806 5.5.13 SNE
+0807 SNE compares the A-value to the B-value. If the result of the
+0808 comparison is not equal, the instruction after the next instruction
+0809 (PC + 2) is queued (skipping the next instruction). Otherwise, the
+0810 next instruction is queued (PC + 1).
+
+0811 5.5.14 SLT
+0812 SLT compares the A-value to the B-value. If the A-value is less than
+0813 the B-value, the instruction after the next instruction (PC + 2) is
+0814 queued (skipping the next instruction). Otherwise, the next
+0815 instruction is queued (PC + 1). SLT.I functions as SLT.F would, i.e.
+0816 the next instruction is skipped only if each of the A/B-numbers of the
+0817 A-value is less than its B-value counterpart.
+
+0818 5.5.15 SPL
+0819 SPL queues the next instruction (PC + 1) and then queues the sum of
+0820 the program counter and the A-pointer. If the queue is full, only the
+0821 next instruction is queued.
+
+0822 5.5.16 NOP
+0823 NOP queues the next instruction (PC + 1).
+
+
+0824 5.6 Example MARS Interpreter
+
+0825 /************************************/
+0826 /* */
+0827 /* EMI94.c */
+0828 /* */
+0829 /* Execute MARS Instruction ala */
+0830 /* ICWS'94 Draft Standard. */
+0831 /* */
+0832 /* Last Update: November 8, 1995 */
+0833 /* */
+0834 /************************************/
+
+0835 /* This ANSI C function is the benchmark MARS instruction */
+0836 /* interpreter for the ICWS'94 Draft Standard. */
+
+
+0837 /* The design philosophy of this function is to mirror the */
+0838 /* standard as closely as possible, illuminate the meaning */
+0839 /* of the standard, and provide the definitive answers to */
+0840 /* questions of the "well, does the standard mean this or */
+0841 /* that?" variety. Although other, different implemen- */
+0842 /* tations are definitely possible and encouraged; those */
+0843 /* implementations should produce the same results as this */
+0844 /* one does. */
+
+
+0845 /* The function returns the state of the system. What the */
+0846 /* main program does with this information is not defined */
+0847 /* by the standard. */
+
+0848 enum SystemState {
+0849 UNDEFINED,
+0850 SUCCESS
+0851 };
+
+
+0852 /* Any number of warriors may be executing in core at one */
+0853 /* time, depending on the run-time variable set and how */
+0854 /* many warriors have failed during execution. For this */
+0855 /* implementation, warriors are identified by the order in */
+0856 /* which they were loaded into core. */
+
+0857 typedef unsigned int Warrior;
+
+
+0858 /* An Address in Core War can be any number from 0 to the */
+0859 /* size of core minus one, relative to the current */
+0860 /* instruction. In this implementation, core is an array */
+0861 /* of instructions; therefore any variable types which */
+0862 /* contain an Address can be considered to be of type */
+0863 /* unsigned int. One caveat: for the purposes of this */
+0864 /* standard, unsigned int must be considered to have no */
+0865 /* upper limit. Depending on the size of core, it may be */
+0866 /* necessary to take precautions against overflow. */
+
+0867 typedef unsigned int Address;
+
+
+0868 /* The FIFO task queues and supporting functions are not */
+0869 /* presented. The function Queue() attempts to add a task */
+0870 /* pointer to the back of the currently executing warrior's */
+0871 /* task queue. No special actions are to be taken if */
+0872 /* Queue() is unsuccessful, which it will be if the warrior */
+0873 /* has already reached the task limit (maximum allowable */
+0874 /* number of tasks). */
+
+0875 extern void Queue(
+0876 Warrior W,
+0877 Address TaskPointer
+0878 );
+
+
+0879 /* There is one support function used to limit the range of */
+0880 /* reading from Core and writing to Core relative to the */
+0881 /* current instruction. Behaviour is as expected (a small */
+0882 /* core within Core) only if the limits are factors of the */
+0883 /* size of Core. */
+
+0884 static Address Fold(
+0885 Address pointer, /* The pointer to fold into the desired range. */
+0886 Address limit, /* The range limit. */
+0887 Address M /* The size of Core. */
+0888 ) {
+0889 Address result;
+
+0890 result = pointer % limit;
+0891 if ( result > (limit/2) ) {
+0892 result += M - limit;
+0893 };
+0894 return(result);
+0895 }
+
+
+0896 /* Instructions are the principle data type. Core is an */
+0897 /* array of instructions, and there are three instruction */
+0898 /* registers used by the MARS executive. */
+
+0899 enum Opcode {
+0900 DAT,
+0901 MOV,
+0902 ADD,
+0903 SUB,
+0904 MUL,
+0905 DIV,
+0906 MOD,
+0907 JMP,
+0908 JMZ,
+0909 JMN,
+0910 DJN,
+0911 CMP, /* aka SEQ */
+0912 SNE,
+0913 SLT,
+0914 SPL,
+0915 NOP,
+0916 };
+
+0917 enum Modifier {
+0918 A,
+0919 B,
+0920 AB,
+0921 BA,
+0922 F,
+0923 X,
+0924 I
+0925 };
+
+0926 enum Mode {
+0927 IMMEDIATE,
+0928 DIRECT,
+0929 A_INDIRECT,
+0930 B_INDIRECT,
+0931 A_DECREMENT,
+0932 B_DECREMENT,
+0933 A_INCREMENT,
+0934 B_INCREMENT,
+0935 };
+
+0936 typedef struct Instruction {
+0937 enum Opcode Opcode;
+0938 enum Modifier Modifier;
+0939 enum Mode AMode;
+0940 Address ANumber;
+0941 enum Mode BMode;
+0942 Address BNumber;
+0943 } Instruction;
+
+
+0944 /* The function is passed which warrior is currently */
+0945 /* executing, the address of the warrior's current task's */
+0946 /* current instruction, a pointer to the Core, the size of */
+0947 /* the Core, and the read and write limits. It returns the */
+0948 /* system's state after attempting instruction execution. */
+
+0949 enum SystemState EMI94(
+
+0950 /* W indicates which warrior's code is executing. */
+
+0951 Warrior W,
+
+0952 /* PC is the address of this warrior's current task's */
+0953 /* current instruction. */
+
+0954 Address PC,
+
+0955 /* Core is just an array of Instructions. Core has been */
+0956 /* initialized and the warriors have been loaded before */
+0957 /* calling this function. */
+
+0958 Instruction Core[],
+
+0959 /* M is the size of Core. */
+
+0960 Address M,
+
+0961 /* ReadLimit is the limitation on read distances. */
+
+0962 Address ReadLimit,
+
+0963 /* WriteLimit is the limitation on write distances. */
+
+0964 Address WriteLimit
+
+
+0965 ) {
+
+
+0966 /* This MARS stores the currently executing instruction in */
+0967 /* the instruction register IR. */
+
+0968 Instruction IR;
+
+0969 /* This MARS stores the instruction referenced by the */
+0970 /* A-operand in the instruction register IRA. */
+
+0971 Instruction IRA;
+
+0972 /* This MARS stores the instruction referenced by the */
+0973 /* B-operand in the instruction Register IRB. */
+
+0974 Instruction IRB;
+
+0975 /* All four of the following pointers are PC-relative */
+0976 /* (relative to the Program Counter). Actual access of */
+0977 /* core must add-in the Program Counter (mod core size). */
+
+0978 /* The offset to the instruction referred to by the */
+0979 /* A-operand for reading is Read Pointer A (RPA). */
+
+0980 Address RPA;
+
+0981 /* The offset to the instruction referred to by the */
+0982 /* A-operand for writing is Write Pointer A (WPA). */
+
+0983 Address WPA;
+
+0984 /* The offset to the instruction referred to by the */
+0985 /* B-operand for reading is Read Pointer B (RPB). */
+
+0986 Address RPB;
+
+0987 /* The offset to the instruction referred to by the */
+0988 /* A-operand for writing is Write Pointer B (WPB). */
+
+0989 Address WPB;
+
+0990 /* Post-increment operands need to keep track of which */
+0991 /* instruction to increment. */
+
+0992 Address PIP;
+
+0993 /* Before execution begins, the current instruction is */
+0994 /* copied into the Instruction Register. */
+
+0995 IR = Core[PC];
+
+
+0996 /* Next, the A-operand is completely evaluated. */
+
+0997 /* For instructions with an Immediate A-mode, the Pointer A */
+0998 /* points to the source of the current instruction. */
+
+0999 if (IR.AMode == IMMEDIATE) {
+1000 RPA = WPA = 0;
+1001 } else {
+
+1002 /* For instructions with a Direct A-mode, the Pointer A */
+1003 /* points to the instruction IR.ANumber away, relative to */
+1004 /* the Program Counter. */
+1005 /* Note that implementing Core as an array necessitates */
+1006 /* doing all Address arithmetic modulus the size of Core. */
+
+1007 RPA = Fold(IR.ANumber, ReadLimit, M);
+1008 WPA = Fold(IR.ANumber, WriteLimit, M);
+
+1009 /* For instructions with A-indirection in the A-operand */
+1010 /* (A-number Indirect, A-number Predecrement, */
+1011 /* and A-number Postincrement A-modes): */
+
+1012 if (IR.AMode == A_INDIRECT
+1013 || IR.AMode == A_DECREMENT
+1014 || IR.AMode == A_INCREMENT) {
+
+1015 /* For instructions with Predecrement A-mode, the A-Field */
+1016 /* of the instruction in Core currently pointed to by the */
+1017 /* Pointer A is decremented (M - 1 is added). */
+
+1018 if (IR.AMode == A_DECREMENT) {
+1019 Core[((PC + WPA) % M)].ANumber =
+1020 (Core[((PC + WPA) % M)].ANumber + M - 1) % M;
+1021 };
+
+1022 /* For instructions with Postincrement A-mode, the A-Field */
+1023 /* of the instruction in Core currently pointed to by the */
+1024 /* Pointer A will be incremented. */
+
+1025 if (IR.AMode == A_INCREMENT) {
+1026 PIP = (PC + WPA) % M;
+1027 };
+
+1028 /* For instructions with A-indirection in the A-operand, */
+1029 /* Pointer A ultimately points to the instruction */
+1030 /* Core[((PC + PCA) % M)].ANumber away, relative to the */
+1031 /* instruction pointed to by Pointer A. */
+
+1032 RPA = Fold(
+1033 (RPA + Core[((PC + RPA) % M)].ANumber), ReadLimit, M
+1034 );
+1035 WPA = Fold(
+1036 (WPA + Core[((PC + WPA) % M)].ANumber), WriteLimit, M
+1037 );
+
+1038 };
+
+1039 /* For instructions with B-indirection in the A-operand */
+1040 /* (B-number Indirect, B-number Predecrement, */
+1041 /* and B-number Postincrement A-modes): */
+
+1042 if (IR.AMode == B_INDIRECT
+1043 || IR.AMode == B_DECREMENT
+1044 || IR.AMode == B_INCREMENT) {
+
+1045 /* For instructions with Predecrement A-mode, the B-Field */
+1046 /* of the instruction in Core currently pointed to by the */
+1047 /* Pointer A is decremented (M - 1 is added). */
+
+1048 if (IR.AMode == DECREMENT) {
+1049 Core[((PC + WPA) % M)].BNumber =
+1050 (Core[((PC + WPA) % M)].BNumber + M - 1) % M;
+1051 };
+
+1052 /* For instructions with Postincrement A-mode, the B-Field */
+1053 /* of the instruction in Core currently pointed to by the */
+1054 /* Pointer A will be incremented. */
+
+1055 if (IR.AMode == INCREMENT) {
+1056 PIP = (PC + WPA) % M;
+1057 };
+
+1058 /* For instructions with B-indirection in the A-operand, */
+1059 /* Pointer A ultimately points to the instruction */
+1060 /* Core[((PC + PCA) % M)].BNumber away, relative to the */
+1061 /* instruction pointed to by Pointer A. */
+
+1062 RPA = Fold(
+1063 (RPA + Core[((PC + RPA) % M)].BNumber), ReadLimit, M
+1064 );
+1065 WPA = Fold(
+1066 (WPA + Core[((PC + WPA) % M)].BNumber), WriteLimit, M
+1067 );
+
+1068 };
+1069 };
+
+1070 /* The Instruction Register A is a copy of the instruction */
+1071 /* pointed to by Pointer A. */
+
+1072 IRA = Core[((PC + RPA) % M)];
+
+1073 /* If the A-mode was post-increment, now is the time to */
+1074 /* increment the instruction in core. */
+
+1075 if (IR.AMode == A_INCREMENT) {
+1076 Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
+1077 }
+1078 else if (IR.AMode == B_INCREMENT) {
+1079 Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
+1080 };
+
+1081 /* The Pointer B and the Instruction Register B are */
+1082 /* evaluated in the same manner as their A counterparts. */
+
+1083 if (IR.BMode == IMMEDIATE) {
+1084 RPB = WPB = 0;
+1085 } else {
+1086 RPB = Fold(IR.BNumber, ReadLimit, M);
+1087 WPB = Fold(IR.BNumber, WriteLimit, M);
+1088 if (IR.BMode == A_INDIRECT
+1089 || IR.BMode == A_DECREMENT
+1090 || IR.BMode == A_INCREMENT) {
+1091 if (IR.BMode == A_DECREMENT) {
+1092 Core[((PC + WPB) % M)].ANumber =
+1093 (Core[((PC + WPB) % M)].ANumber + M - 1) % M
+1094 ;
+1095 } else if (IR.BMode == A_INCREMENT) {
+1096 PIP = (PC + WPB) % M;
+1097 };
+1098 RPB = Fold(
+1099 (RPB + Core[((PC + RPB) % M)].ANumber), ReadLimit, M
+1100 );
+1101 WPB = Fold(
+1102 (WPB + Core[((PC + WPB) % M)].ANumber), WriteLimit, M
+1103 );
+1104 };
+1105 if (IR.BMode == B_INDIRECT
+1106 || IR.BMode == B_DECREMENT
+1107 || IR.BMode == B_INCREMENT) {
+1108 if (IR.BMode == B_DECREMENT) {
+1109 Core[((PC + WPB) % M)].BNumber =
+1110 (Core[((PC + WPB) % M)].BNumber + M - 1) % M
+1111 ;
+1112 } else if (IR.BMode == B_INCREMENT) {
+1113 PIP = (PC + WPB) % M;
+1114 };
+1115 RPB = Fold(
+1116 (RPB + Core[((PC + RPB) % M)].BNumber), ReadLimit, M
+1117 );
+1118 WPB = Fold(
+1119 (WPB + Core[((PC + WPB) % M)].BNumber), WriteLimit, M
+1120 );
+1121 };
+1122 };
+1123 IRB = Core[((PC + RPB) % M)];
+
+1124 if (IR.BMode == A_INCREMENT) {
+1125 Core[PIP].ANumber = (Core[PIP].ANumber + 1) % M;
+1126 }
+1127 else if (IR.BMode == INCREMENT) {
+1128 Core[PIP].BNumber = (Core[PIP].BNumber + 1) % M;
+1129 };
+
+1130 /* Execution of the instruction can now proceed. */
+
+1131 switch (IR.Opcode) {
+
+1132 /* Instructions with a DAT opcode have no further function. */
+1133 /* The current task's Program Counter is not updated and is */
+1134 /* not returned to the task queue, effectively removing the */
+1135 /* task. */
+
+1136 case DAT: noqueue:
+1137 break;
+
+
+1138 /* MOV replaces the B-target with the A-value and queues */
+1139 /* the next instruction. */
+
+1140 case MOV:
+1141 switch (IR.Modifier) {
+
+1142 /* Replaces A-number with A-number. */
+
+1143 case A:
+1144 Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
+1145 break;
+
+1146 /* Replaces B-number with B-number. */
+
+1147 case B:
+1148 Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
+1149 break;
+
+1150 /* Replaces B-number with A-number. */
+
+1151 case AB:
+1152 Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
+1153 break;
+
+1154 /* Replaces A-number with B-number. */
+
+1155 case BA:
+1156 Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
+1157 break;
+
+1158 /* Replaces A-number with A-number and B-number with */
+1159 /* B-number. */
+
+1160 case F:
+1161 Core[((PC + WPB) % M)].ANumber = IRA.ANumber;
+1162 Core[((PC + WPB) % M)].BNumber = IRA.BNumber;
+1163 break;
+
+1164 /* Replaces B-number with A-number and A-number with */
+1165 /* B-number. */
+
+1166 case X:
+1167 Core[((PC + WPB) % M)].BNumber = IRA.ANumber;
+1168 Core[((PC + WPB) % M)].ANumber = IRA.BNumber;
+1169 break;
+
+1170 /* Copies entire instruction. */
+
+1171 case I:
+1172 Core[((PC + WPB) % M)] = IRA;
+1173 break;
+
+1174 default:
+1175 return(UNDEFINED);
+1176 break;
+1177 };
+
+1178 /* Queue up next instruction. */
+1179 Queue(W, ((PC + 1) % M));
+1180 break;
+
+1181 /* Arithmetic instructions replace the B-target with the */
+1182 /* "op" of the A-value and B-value, and queue the next */
+1183 /* instruction. "op" can be the sum, the difference, or */
+1184 /* the product. */
+
+1185 #define ARITH(op) \
+1186 switch (IR.Modifier) { \
+1187 case A: \
+1188 Core[((PC + WPB) % M)].ANumber = \
+1189 (IRB.ANumber op IRA.ANumber) % M \
+1190 ; \
+1191 break; \
+1192 case B: \
+1193 Core[((PC + WPB) % M)].BNumber = \
+1194 (IRB.BNumber op IRA.BNumber) % M \
+1195 ; \
+1196 break; \
+1197 case AB: \
+1198 Core[((PC + WPB) % M)].BNumber = \
+1199 (IRB.ANumber op IRA.BNumber) % M \
+1200 ; \
+1201 break; \
+1202 case BA: \
+1203 Core[((PC + WPB) % M)].ANumber = \
+1204 (IRB.BNumber op IRA.ANumber) % M \
+1205 ; \
+1206 break; \
+1207 case F: \
+1208 case I: \
+1209 Core[((PC + WPB) % M)].ANumber = \
+1210 (IRB.ANumber op IRA.ANumber) % M \
+1211 ; \
+1212 Core[((PC + WPB) % M)].BNumber = \
+1213 (IRB.BNumber op IRA.BNumber) % M \
+1214 ; \
+1215 break; \
+1216 case X: \
+1217 Core[((PC + WPB) % M)].BNumber = \
+1218 (IRB.ANumber op IRA.BNumber) % M \
+1219 ; \
+1220 Core[((PC + WPB) % M)].ANumber = \
+1221 (IRB.BNumber op IRA.ANumber) % M \
+1222 ; \
+1223 break; \
+1224 default: \
+1225 return(UNDEFINED); \
+1226 break; \
+1227 }; \
+1228 Queue(W, ((PC + 1) % M)); \
+1229 break;
+
+1230 case ADD: ARITH(+)
+1231 case SUB: ARITH(+ M -)
+1232 case MUL: ARITH(*)
+
+1233 /* DIV and MOD replace the B-target with the integral */
+1234 /* quotient (for DIV) or remainder (for MOD) of the B-value */
+1235 /* by the A-value, and queues the next instruction. */
+1236 /* Process is removed from task queue if A-value is zero. */
+
+1237 #define ARITH_DIV(op) \
+1238 switch (IR.Modifier) { \
+1239 case A: \
+1240 if (IRA.ANumber != 0) \
+1241 Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
+1242 break; \
+1243 case B: \
+1244 if (IRA.BNumber != 0) \
+1245 Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
+1246 else goto noqueue; \
+1247 break; \
+1248 case AB: \
+1249 if (IRA.ANumber != 0) \
+1250 Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
+1251 else goto noqueue; \
+1252 break; \
+1253 case BA: \
+1254 if (IRA.BNumber != 0) \
+1255 Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
+1256 else goto noqueue; \
+1257 break; \
+1258 case F: \
+1259 case I: \
+1260 if (IRA.ANumber != 0) \
+1261 Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.ANumber; \
+1262 if (IRA.BNumber != 0) \
+1263 Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.BNumber; \
+1264 if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
+1265 goto noqueue; \
+1266 break; \
+1267 case X: \
+1268 if (IRA.ANumber != 0) \
+1269 Core[((PC + WPB) % M)].BNumber = IRB.BNumber op IRA.ANumber; \
+1270 if (IRA.BNumber != 0) \
+1271 Core[((PC + WPB) % M)].ANumber = IRB.ANumber op IRA.BNumber; \
+1272 if ((IRA.ANumber == 0) || (IRA.BNumber == 0)) \
+1273 goto noqueue; \
+1274 break; \
+1275 default: \
+1276 return(UNDEFINED); \
+1277 break; \
+1278 }; \
+1279 Queue(W, ((PC + 1) % M)); \
+1280 break;
+
+1281 case DIV: ARITH_DIV(/)
+1282 case MOD: ARITH_DIV(%)
+
+1283 /* JMP queues the sum of the Program Counter and the */
+1284 /* A-pointer. */
+
+1285 case JMP:
+1286 Queue(W, RPA);
+1287 break;
+
+
+1288 /* JMZ queues the sum of the Program Counter and Pointer A */
+1289 /* if the B-value is zero. Otherwise, it queues the next */
+1290 /* instruction. */
+
+1291 case JMZ:
+1292 switch (IR.Modifier) {
+1293 case A:
+1294 case BA:
+1295 if (IRB.ANumber == 0) {
+1296 Queue(W, RPA);
+1297 } else {
+1298 Queue(W, ((PC + 1) % M));
+1299 };
+1300 break;
+1301 case B:
+1302 case AB:
+1303 if (IRB.BNumber == 0) {
+1304 Queue(W, RPA);
+1305 } else {
+1306 Queue(W, ((PC + 1) % M));
+1307 };
+1308 break;
+1309 case F:
+1310 case X:
+1311 case I:
+1312 if ( (IRB.ANumber == 0) && (IRB.BNumber == 0) ) {
+1313 Queue(W, RPA);
+1314 } else {
+1315 Queue(W, ((PC + 1) % M));
+1316 };
+1317 break;
+1318 default:
+1319 return(UNDEFINED);
+1320 break;
+1321 };
+1322 break;
+
+
+1323 /* JMN queues the sum of the Program Counter and Pointer A */
+1324 /* if the B-value is not zero. Otherwise, it queues the */
+1325 /* next instruction. */
+
+1326 case JMN:
+1327 switch (IR.Modifier) {
+1328 case A:
+1329 case BA:
+1330 if (IRB.ANumber != 0) {
+1331 Queue(W, RPA);
+1332 } else {
+1333 Queue(W, ((PC + 1) % M));
+1334 };
+1335 break;
+1336 case B:
+1337 case AB:
+1338 if (IRB.BNumber != 0) {
+1339 Queue(W, RPA);
+1340 } else {
+1341 Queue(W, ((PC + 1) % M));
+1342 };
+1343 break;
+1344 case F:
+1345 case X:
+1346 case I:
+1347 if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
+1348 Queue(W, RPA);
+1349 } else {
+1350 Queue(W, ((PC + 1) % M));
+1351 };
+1352 break;
+1353 default:
+1354 return(UNDEFINED);
+1355 break;
+1356 };
+1357 break;
+
+
+1358 /* DJN (Decrement Jump if Not zero) decrements the B-value */
+1359 /* and the B-target, then tests if the B-value is zero. If */
+1360 /* the result is not zero, the sum of the Program Counter */
+1361 /* and Pointer A is queued. Otherwise, the next */
+1362 /* instruction is queued. */
+
+1363 case DJN:
+1364 switch (IR.Modifier) {
+1365 case A:
+1366 case BA:
+1367 Core[((PC + WPB) % M)].ANumber =
+1368 (Core[((PC + WPB) % M)].ANumber + M - 1) % M
+1369 ;
+1370 IRB.ANumber -= 1;
+1371 if (IRB.ANumber != 0) {
+1372 Queue(W, RPA);
+1373 } else {
+1374 Queue(W, ((PC + 1) % M));
+1375 };
+1376 break;
+1377 case B:
+1378 case AB:
+1379 Core[((PC + WPB) % M)].BNumber =
+1380 (Core[((PC + WPB) % M)].BNumber + M - 1) % M
+1381 ;
+1382 IRB.BNumber -= 1;
+1383 if (IRB.BNumber != 0) {
+1384 Queue(W, RPA);
+1385 } else {
+1386 Queue(W, ((PC + 1) % M));
+1387 };
+1388 break;
+1389 case F:
+1390 case X:
+1391 case I:
+1392 Core[((PC + WPB) % M)].ANumber =
+1393 (Core[((PC + WPB) % M)].ANumber + M - 1) % M
+1394 ;
+1395 IRB.ANumber -= 1;
+1396 Core[((PC + WPB) % M)].BNumber =
+1397 (Core[((PC + WPB) % M)].BNumber + M - 1) % M
+1398 ;
+1399 IRB.BNumber -= 1;
+1400 if ( (IRB.ANumber != 0) || (IRB.BNumber != 0) ) {
+1401 Queue(W, RPA);
+1402 } else {
+1403 Queue(W, ((PC + 1) % M));
+1404 };
+1405 break;
+1406 default:
+1407 return(UNDEFINED);
+1408 break;
+1409 };
+1410 break;
+
+
+1411 /* SEQ/CMP compares the A-value and the B-value. If there */
+1412 /* are no differences, then the instruction after the next */
+1413 /* instruction is queued. Otherwise, the next instrution */
+1414 /* is queued. */
+
+1415 case CMP:
+1416 switch (IR.Modifier) {
+1417 case A:
+1418 if (IRA.ANumber == IRB.ANumber) {
+1419 Queue(W, ((PC + 2) % M));
+1420 } else {
+1421 Queue(W, ((PC + 1) % M));
+1422 };
+1423 break;
+1424 case B:
+1425 if (IRA.BNumber == IRB.BNumber) {
+1426 Queue(W, ((PC + 2) % M));
+1427 } else {
+1428 Queue(W, ((PC + 1) % M));
+1429 };
+1430 break;
+1431 case AB:
+1432 if (IRA.ANumber == IRB.BNumber) {
+1433 Queue(W, ((PC + 2) % M));
+1434 } else {
+1435 Queue(W, ((PC + 1) % M));
+1436 };
+1437 break;
+1438 case BA:
+1439 if (IRA.BNumber == IRB.ANumber) {
+1440 Queue(W, ((PC + 2) % M));
+1441 } else {
+1442 Queue(W, ((PC + 1) % M));
+1443 };
+1444 break;
+1445 case F:
+1446 if ( (IRA.ANumber == IRB.ANumber) &&
+1447 (IRA.BNumber == IRB.BNumber)
+1448 ) {
+1449 Queue(W, ((PC + 2) % M));
+1450 } else {
+1451 Queue(W, ((PC + 1) % M));
+1452 };
+1453 break;
+1454 case X:
+1455 if ( (IRA.ANumber == IRB.BNumber) &&
+1456 (IRA.BNumber == IRB.ANumber)
+1457 ) {
+1458 Queue(W, ((PC + 2) % M));
+1459 } else {
+1460 Queue(W, ((PC + 1) % M));
+1461 };
+1462 break;
+1463 case I:
+1464 if ( (IRA.Opcode == IRB.Opcode) &&
+1465 (IRA.Modifier == IRB.Modifier) &&
+1466 (IRA.AMode == IRB.AMode) &&
+1467 (IRA.ANumber == IRB.ANumber) &&
+1468 (IRA.BMode == IRB.BMode) &&
+1469 (IRA.BNumber == IRB.BNumber)
+1470 ) {
+1471 Queue(W, ((PC + 2) % M));
+1472 } else {
+1473 Queue(W, ((PC + 1) % M));
+1474 };
+1475 break;
+1476 default:
+1477 return(UNDEFINED);
+1478 break;
+1479 };
+1480 break;
+
+
+1481 /* SNE compares the A-value and the B-value. If there */
+1482 /* is a difference, then the instruction after the next */
+1483 /* instruction is queued. Otherwise, the next instrution */
+1484 /* is queued. */
+
+1485 case SNE:
+1486 switch (IR.Modifier) {
+1487 case A:
+1488 if (IRA.ANumber != IRB.ANumber) {
+1489 Queue(W, ((PC + 2) % M));
+1490 } else {
+1491 Queue(W, ((PC + 1) % M));
+1492 };
+1493 break;
+1494 case B:
+1495 if (IRA.BNumber != IRB.BNumber) {
+1496 Queue(W, ((PC + 2) % M));
+1497 } else {
+1498 Queue(W, ((PC + 1) % M));
+1499 };
+1500 break;
+1501 case AB:
+1502 if (IRA.ANumber != IRB.BNumber) {
+1503 Queue(W, ((PC + 2) % M));
+1504 } else {
+1505 Queue(W, ((PC + 1) % M));
+1506 };
+1507 break;
+1508 case BA:
+1509 if (IRA.BNumber != IRB.ANumber) {
+1510 Queue(W, ((PC + 2) % M));
+1511 } else {
+1512 Queue(W, ((PC + 1) % M));
+1513 };
+1514 break;
+1515 case F:
+1516 if ( (IRA.ANumber != IRB.ANumber) ||
+1517 (IRA.BNumber != IRB.BNumber)
+1518 ) {
+1519 Queue(W, ((PC + 2) % M));
+1520 } else {
+1521 Queue(W, ((PC + 1) % M));
+1522 };
+1523 break;
+1524 case X:
+1525 if ( (IRA.ANumber != IRB.BNumber) ||
+1526 (IRA.BNumber != IRB.ANumber)
+1527 ) {
+1528 Queue(W, ((PC + 2) % M));
+1529 } else {
+1530 Queue(W, ((PC + 1) % M));
+1531 };
+1532 break;
+1533 case I:
+1534 if ( (IRA.Opcode != IRB.Opcode) ||
+1535 (IRA.Modifier != IRB.Modifier) ||
+1536 (IRA.AMode != IRB.AMode) ||
+1537 (IRA.ANumber != IRB.ANumber) ||
+1538 (IRA.BMode != IRB.BMode) ||
+1539 (IRA.BNumber != IRB.BNumber)
+1540 ) {
+1541 Queue(W, ((PC + 2) % M));
+1542 } else {
+1543 Queue(W, ((PC + 1) % M));
+1544 };
+1545 break;
+1546 default:
+1547 return(UNDEFINED);
+1548 break;
+1549 };
+1550 break;
+
+
+1551 /* SLT (Skip if Less Than) queues the instruction after the */
+1552 /* next instruction if A-value is less than B-value. */
+1553 /* Otherwise, the next instruction is queued. Note that no */
+1554 /* value is less than zero because only positive values can */
+1555 /* be represented in core. */
+
+1556 case SLT :
+1557 switch (IR.Modifier) {
+1558 case A:
+1559 if (IRA.ANumber < IRB.ANumber) {
+1560 Queue(W, ((PC + 2) % M));
+1561 } else {
+1562 Queue(W, ((PC + 1) % M));
+1563 };
+1564 break;
+1565 case B:
+1566 if (IRA.BNumber < IRB.BNumber) {
+1567 Queue(W, ((PC + 2) % M));
+1568 } else {
+1569 Queue(W, ((PC + 1) % M));
+1570 };
+1571 break;
+1572 case AB:
+1573 if (IRA.ANumber < IRB.BNumber) {
+1574 Queue(W, ((PC + 2) % M));
+1575 } else {
+1576 Queue(W, ((PC + 1) % M));
+1577 };
+1578 break;
+1579 case BA:
+1580 if (IRA.BNumber < IRB.ANumber) {
+1581 Queue(W, ((PC + 2) % M));
+1582 } else {
+1583 Queue(W, ((PC + 1) % M));
+1584 };
+1585 break;
+1586 case F:
+1587 case I:
+1588 if ( (IRA.ANumber < IRB.ANumber) &&
+1589 (IRA.BNumber < IRB.BNumber)
+1590 ) {
+1591 Queue(W, ((PC + 2) % M));
+1592 } else {
+1593 Queue(W, ((PC + 1) % M));
+1594 };
+1595 break;
+1596 case X:
+1597 if ( (IRA.ANumber < IRB.BNumber) &&
+1598 (IRA.BNumber < IRB.ANumber)
+1599 ) {
+1600 Queue(W, ((PC + 2) % M));
+1601 } else {
+1602 Queue(W, ((PC + 1) % M));
+1603 };
+1604 break;
+1605 default:
+1606 return(UNDEFINED);
+1607 break;
+1608 };
+1609 break;
+
+
+1610 /* SPL queues the next instruction and also queues the sum */
+1611 /* of the Program Counter and Pointer A. */
+
+1612 case SPL:
+1613 Queue(W, ((PC + 1) % M));
+1614 Queue(W, RPA);
+1615 break;
+
+
+1616 /* NOP queues the next instruction. */
+
+1617 case NOP:
+1618 Queue(W, ((PC + 1) % M));
+1619 break;
+
+
+1620 /* Any other opcode is undefined. */
+
+1621 default:
+1622 return(UNDEFINED);
+1623 };
+
+
+1624 /* We are finished. */
+
+1625 return(SUCCESS);
+1626 }
+
+1627 6. Validation Suite
+
+1628 6.1 Purpose and Requirements
+1629 This validation suite exists to help developers test the compatibility
+1630 of their Core War systems with the requirements set up in this
+1631 standard.
+
+1632 6.2 Assembly To Load File Test
+
+1633 6.3 MARS tests
+
+1634 6.3.1 DAT Tests
+1635 6.3.2 MOV Tests
+1636 6.3.3 ADD Tests
+1637 6.3.4 SUB Tests
+1638 6.3.5 MUL Tests
+1639 6.3.6 DIV Tests
+1640 6.3.7 MOD Tests
+1641 6.3.8 JMP Tests
+1642 6.3.9 JMZ Tests
+1643 6.3.10 JMN Tests
+1644 6.3.11 DJN Tests
+1645 6.3.12 SEQ/CMP Tests
+1646 6.3.13 SNE Tests
+1647 6.3.14 SLT Tests
+1648 6.3.15 SPL Tests
+1649 6.3.16 NOP Tests
+
+
+1650 7. Glossary and Index
+1651 alphanumeric Any of the characters A-Za-z0-9 and the underscore.
+
+1652 assembly file A file containing Redcode instructions.
+
+1653 battle A contest between two or more warriors.
+
+1654 core size See section 4.2
+
+1655 Core War A game in which programs compete for control of a
+1656 computer called a Memory Array Redcode Simulator.
+
+1657 Core Wars More than one game of Core War.
+
+1658 cycle See section 4.2
+
+1659 Dwarf See sections 2.7 and 3.6
+
+1660 initial instruction
+1661 See section 4.2
+
+1662 instruction A line of Redcode or object code indicating an action
+1663 for MARS to execute.
+
+1664 instruction limit
+1665 See section 4.2
+
+1666 loader A program or that part of a program which loads
+1667 warriors into a MARS.
+
+1668 load file A file containing a warrior's instructions in an
+1669 assembled format. Any MARS program can be used with
+1670 any and all Redcode assemblers which produce load
+1671 files, allowing customized Core War systems.
+
+1672 MARS An acronym for Memory Array Redcode Simulator. The
+1673 computer in which Core War warriors run.
+
+1674 newline A linefeed, carriage-return, or combination of linefeed
+1675 and carriage-return. Whichever newline is native to
+1676 the host operating system.
+
+1677 object code The internal representation of a MARS instruction.
+
+1678 read distance See section 4.2
+
+1679 Redcode The assembly language of Core War.
+
+1680 tournament A series of battles in which points, based upon the
+1681 degree of success, are awarded for each battle and
+1682 accumulated by each warrior (or programmer, depending
+1683 upon the type of tournament).
+
+1684 warrior A Redcode program.
+
+1685 whitespace The space and tab characters.
+
+1686 write distance See section 4.2
+
+
+1687 A. Differences Between Standards
+
+1688 A.1 Purpose
+1689 This appendix lists some of the major differences between this standard
+1690 and those standards which preceded it. The purpose is to help those
+1691 who are familiar with a previous standard or standards to quickly
+1692 understand those items which are new or have changed.
+
+
+1693 A.2 Changes
+
+1694 A.2.1 Assembly Files
+1695 A comma is required for operand separation.
+
+1696 Parenthetical expressions are allowed.
+
+1697 There is a new pseudo-opcode, ORG, for specifying the first logical
+1698 instruction.
+
+1699 There is a new operator, modulus '%', for determining the remainder
+1700 of integer division.
+
+1701 A.2.1.1 ICWS'86 to ICWS'94 Conversion
+1702 If a modifier is missing, it is assembled according to conversion
+1703 rules that depend on whether the ICWS'86 or '88 standard is emulated.
+1704 By default, a MARS should use the ICWS'88 conversion rules. Emulation
+1705 of ICWS'86 is optional.
+
+1706 Opcode A-mode B-mode modifier
+1707 ---------------------------------------------------------
+1708 DAT #$@<>*{} #$@<>*{} F
+1709 MOV,CMP,SEQ,SNE # #$@<>*{} AB
+1710 $@<>*{} # B
+1711 $@<>*{} $@<>*{} I
+1712 ADD,SUB,MUL,DIV,MOD # #$@<>*{} AB
+1713 $@<>*{} #$@<>*{} B
+1714 SLT # #$@<>*{} AB
+1715 $@<>*{} #$@<>*{} B
+1716 JMP,JMZ,JMN,DJN,SPL,NOP #$@<>*{} #$@<>*{} B
+1717 ---------------------------------------------------------
+
+1718 A.2.1.2 ICWS'88 to ICWS'94 Conversion
+1719 The default modifier for ICWS'88 emulation is determined according
+1720 to the table below.
+
+1721 Opcode A-mode B-mode modifier
+1722 ---------------------------------------------------------
+1723 DAT #$@<>*{} #$@<>*{} F
+1724 MOV,CMP,SEQ,SNE # #$@<>*{} AB
+1725 $@<>*{} # B
+1726 $@<>*{} $@<>*{} I
+1727 ADD,SUB,MUL,DIV,MOD # #$@<>*{} AB
+1728 $@<>*{} # B
+1729 $@<>*{} $@<>*{} F
+1730 SLT # #$@<>*{} AB
+1731 $@<>*{} #$@<>*{} B
+1732 JMP,JMZ,JMN,DJN,SPL,NOP #$@<>*{} #$@<>*{} B
+1733 ---------------------------------------------------------
+
+1734 A.2.2 Load Files
+1735 A load file format is specified for the first time. (An object code
+1736 did exist for ICWS'86).
+
+
+1737 A.2.3 MARS
+1738 There are no illegal instructions.
+
+1739 The following addressing modes have been added:
+1740 A-number indirect, A-number predecrement, A-number postincrement,
+1741 and B-number postincrement.
+
+1742 MUL, DIV, MOD, SNE, and NOP have been added.
+1743 SEQ is an alias for CMP.
+
+1744 Opcode modifiers have been added.
+
+1745 Read and Write distance limitations have been imposed.
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
new file mode 100644
index 0000000..e9198af
--- /dev/null
+++ b/doc/tutorial.txt
@@ -0,0 +1,473 @@
+Newsgroups: rec.games.corewar
+From: DURHAM@ricevm1.rice.edu (Mark A. Durham)
+Subject: Intro to Redcode Part I
+Organization: Rice University, Houston, TX
+Date: Thu, 14 Nov 1991 09:41:37 GMT
+
+Introduction to Redcode
+-----------------------
+
+ I. Preface - Reader Beware! { Part I }
+
+ II. Notation { Part I }
+
+III. MARS Peculiarities { Part I }
+
+ IV. Address Modes { Part II }
+
+ V. Instruction Set { Part II }
+
+----------------------------------------------------------------------
+
+I. Preface - Reader Beware!
+
+ The name "Core War" arguably can be claimed as public domain.
+Thus, any program can pass itself off as an implementation of Core
+War. Ideally, one would like to write a Redcode program on one system
+and know that it will run in exactly the same manner on every other
+system. Alas, this is not the case.
+ Basically, Core War systems fall under one of four catagories:
+Non-ICWS, ICWS'86, ICWS'88, or Extended. Non-ICWS systems are usually
+a variant of Core War as described by A. K. Dewdney in his "Computer
+Recreations" articles appearing in Scientific American. ICWS'86 and
+ICWS'88 systems conform to the standards set out by the International
+Core War Society in their standards of 1986 and 1988, respectively.
+Extended systems generally support ICWS'86, ICWS'88, and proprietary
+extensions to those standards. I will discuss frequently common
+extensions as if they were available on all Extended systems (which
+they most certainly are not).
+ I will not describe Non-ICWS systems in this article. Most Non-
+ICWS systems will be easily understood if you understand the systems
+described in this article however. Although called "standards",
+ICWS'86 and ICWS'88 (to a lesser extent) both suffer from ambiguities
+and extra-standard issues which I will try to address.
+ This is where the reader should beware. Because almost any
+interpretation of the standard(s) is as valid as any other, I
+naturally prefer MY interpretation. I will try to point out other
+common interpretations when ambiguities arise though, and I will
+clearly indicate what is interpretation (mine or otherwise) as such.
+You have been warned!
+
+----------------------------------------------------------------------
+
+II. Notation
+
+ "86:" will indicate an ICWS'86 feature. "88:" will indicate an
+ICWS'88 feature. "X:" will indicate an Extended feature. "Durham:"
+will indicate my biased interpretation. "Other:" will indicate
+interpretations adhered to by others. "Commentary:" is me explaining
+what I am doing and why. "Editorial:" is me railing for or against
+certain usages. Items without colon-suffixed prefaces can be
+considered universal.
+
+ Redcode consists of assembly language instructions of the form
+
+<label> <opcode> <A-mode><A-field>, <B-mode><B-field> <comment>
+
+An example Recode program:
+
+; Imp
+; by A. K. Dewdney
+;
+imp MOV imp, imp+1 ; This program copies itself ahead one
+ END ; instruction and moves through memory.
+
+The <label> is optional.
+86: <label> begins in the first column, is one to eight characters
+ long, beginning with an alphabetic character and consisting
+ entirely of alphanumerals. Case is ignored ("abc" is equivalent
+ to "ABC").
+88: <label> as above, except length is not limited and case is not
+ addressed. Only the first eight characters are considered
+ significant.
+X: <label> can be preceded by any amount of whitespace (spaces, tabs,
+ and newlines), consists of any number of significant alphanumerals
+ but must start with an alphabetic, and case is significant ("abc"
+ is different from "ABC").
+Commentary: I will always use lowercase letters for labels to
+ distinguish labels from opcodes and family operands.
+
+The <opcode> is separated from the <label> (if there is one) by
+ whitespace. Opcodes may be entered in either uppercase or
+ lowercase. The case does not alter the instruction. DAT, MOV,
+ ADD, SUB, JMP, JMZ, JMN, DJN, CMP, SPL, and END are acceptable
+ opcodes.
+86: SPACE is also recognized as an opcode.
+88: SLT and EQU are recognized as opcodes. SPACE is not.
+X: All of the above are recognized as opcodes as well as XCH and PCT,
+ plus countless other extensions.
+Commentary: END, SPACE, and EQU are known as pseudo-ops because they
+ really indicate instructions to the assembler and do not produce
+ executable code. I will always capitalize opcodes and pseudo-ops
+ to distinguish them from labels and text.
+
+The <A-mode> and <A-field> taken together are referred to as the
+ A-operand. Similarly, the <B-mode><B-field> combination is known
+ as the B-operand. The A-operand is optional for some opcodes.
+ The B-operand is optional for some opcodes. Only END can go
+ without at least one operand.
+86: Operands are separated by a comma.
+88: Operands are separated by whitespace.
+X: Operands are separated by whitespace and/or a comma. Lack of a
+ comma can lead to unexpected behaviour for ambiguous constructs.
+Commentary: The '88 standard forces you to write an operand without
+ whitespace, reserving whitespace to separate the operands. I like
+ whitespace in my expressions, therefore I prefer to separate my
+ operands with a comma and will do so here for clarity.
+
+<mode> is # (Immediate Addressing), @ (Indirect Addressing), or <
+ (86: Auto-Decrement Indirect, 88: Pre-Decrement Indirect). A
+ missing mode indicates Direct Addressing.
+86: $ is an acceptable mode, also indicating Direct Addressing.
+88: $ is not an acceptable mode.
+X: $ is an acceptable mode as in 86:.
+Commentary: The distinction between Auto-Decrement Indirect Addressing
+ and Pre-Decrement Indirect Addressing is semantic, not syntactic.
+
+<field> is any combination of labels and integers separated by the
+ arithmetic operators + (addition) and - (subtraction).
+86: Parentheses are explicitly forbidden. "*" is defined as a special
+ label symbol meaning the current statement.
+88: Arithmetic operators * (multiplication) and / (integer division)
+ are added. "*" is NOT allowed as a special label as in 86:.
+X: Parentheses and whitespace are permitted in expressions.
+Commentary: The use of "*" as meaning the current statement may be
+ useful in some real assemblers, but is completely superfluous in a
+ Redcode assembler. The current statement can always be referred
+ to as 0 in Redcode.
+
+<comment> begins with a ; (semicolon), ends with a newline, and can
+ have any number of intervening characters. A comment may appear
+ on a line by itself with no instruction preceding it.
+88: Blank lines are explicitly allowed.
+
+ I will often use "A" to mean any A-operand and "B" to mean any
+B-operand (capitalization is important). I use "a" to mean any A-
+field and "b" to mean any B-field. For this reason, I never use "a"
+or "b" as an actual label.
+ I enclose sets of operands or instructions in curly braces. Thus
+"A" is equivalent to "{ a, #a, @a, <a }". I use "???" to mean any
+opcode and "x" or "label" as an arbitrary label. Thus, the complete
+family of acceptable Redcode statements can be represented as
+
+x ??? A, B ; This represents all possible Redcode statements.
+
+"???" is rarely used as most often we wish to discuss the behaviour of
+a specific opcode. I will often use labels such as "x-1" (despite its
+illegality) for the instruction before the instruction labelled "x",
+for the logically obvious reason. "M" always stands for the integer
+with the same value as the MARS memory size.
+
+----------------------------------------------------------------------
+
+III. MARS Peculiarities
+
+ There are two things about MARS which make Redcode different from
+any other assembly language. The first of these is that there are no
+absolute addresses in MARS. The second is that memory is circular.
+ Because there are no absolute addresses, all Redcode is written
+using relative addressing. In relative addressing, all addresses are
+interpreted as offsets from the currently executing instruction.
+Address 0 is the currently executing instruction. Address -1 was the
+previously executed instruction (assuming no jumps or branches).
+Address +1 is the next instruction to execute (again assuming no jumps
+or branches).
+ Because memory is circular, each instruction has an infinite number
+of addresses. Assuming a memory size of M, the current instruction
+has the addresses { ..., -2M, -M, 0, M, 2M, ... }. The previous
+instruction is { ..., -1-2M, -1-M, -1, M-1, 2M-1, ... }. The next
+instruction is { ..., 1-2M, 1-M, 1, M+1, 2M+1, ... }.
+
+Commentary: MARS systems have historically been made to operate on
+ object code which takes advantage of this circularity by insisting
+ that fields be normalized to positive integers between 0 and M-1,
+ inclusive. Since memory size is often not known at the time of
+ assembly, a loader in the MARS system (which does know the memory
+ size) takes care of field normalization in addition to its normal
+ operations of code placement and task pointer initialization.
+
+Commentary: Redcode programmers often want to know what the memory
+ size of the MARS is ahead of time. This is not always possible.
+ Since normalized fields can only represent integers between 0 and
+ M-1 inclusive, we can not represent M in a normalized field. The
+ next best thing? M-1. But how can we write M-1 when we do not
+ know the memory size? Recall from above that -1 is equivalent to
+ M-1. Final word of caution: -1/2 is assembled as 0 (not as M/2)
+ since the expression is evaluated within the assembler as -0.5 and
+ then truncated.
+
+86: Only two assembled-Redcode programs (warriors) are loaded into
+ MARS memory (core).
+88: Core is initialized to (filled with) DAT 0, 0 before loading any
+ warriors. Any number of warriors may be loaded into core.
+
+Commentary: Tournaments almost always pit warrior versus warrior with
+ only two warriors in core.
+
+ MARS is a multi-tasking system. Warriors start as just one task,
+but can "split" off additional tasks. When all of a warriors tasks
+have been killed, the warrior is declared dead. When there is a sole
+warrior still executing in core, that warrior is declared the winner.
+86: Tasks are limited to a maximum of 64 for each warrior.
+88: The task limit is not set by the standard.
+
+----------------------------------------------------------------------
+IV. Address Modes
+
+ Addressing modes subtly (sometimes not-so-subtly) alter the
+behaviour of instructions. A somewhat brief description of their
+general properties is given here. Specifics will be left to the
+instruction set section.
+ An octothorpe (#) is used to indicate an operand with an Immediate
+Address Mode. Immediate mode data is contained in the current
+instruction's field. If the A-mode is immediate, the data is in the
+A-field. If the B-mode is immediate, the data is in the B-field.
+ If no mode indicator is present (86: or the US dollar sign '$' is
+present), Direct Address Mode is used. Direct addresses refer to
+instructions relative to the current instruction. Address 0 refers to
+the current instruction. Direct address -1 refers to the (physically)
+previous instruction. Direct address +1 refers to the (physically)
+next instruction.
+ The commercial-at (@) is used to indicate Indirect Address Mode.
+In indirect addressing, the indirect address points to an instruction
+as in direct addressing, except the target is not the instruction to
+which the indirect address points but rather the instruction pointed
+to by the B-field of the instruct pointed to by the indirect address.
+Example:
+
+x-2 DAT #0, #0 ; Target instruction.
+x-1 DAT #0, #-1 ; Pointer instruction.
+x MOV 0, @-1 ; Copies this instruction to location x-2.
+
+ The less-than (<) is used to indicate (86: Auto-, 88: Pre-)
+Decrement Indirect Address Mode. Its behaviour is just like that of
+Indirect Address Mode, except the pointer is decremented before use.
+Example:
+
+x-2 DAT #0, #0 ; Target instruction
+x-1 DAT #0, #0 ; Pointer instruction. Compare to @ example.
+x MOV 0, <-1 ; Copies this instruction to location x-2.
+
+Commentary: Although Decrement Indirect addressing appears to be a
+ simple extension of Indirect addressing, it is really very tricky
+ at times - especially when combined with DJN. There are sematic
+ differences between the '86 and '88 standards, thus the change in
+ name from Auto-Decrement to Pre-Decrement. These differences are
+ discussed below. This discussion is non-essential for the average
+ Redcode programmer. I suggesting skipping to the next section for
+ the weak-stomached.
+
+86: Durham: Instructions are fetched from memory into an instruction
+ register. Each operand is evaluated, storing a location (into an
+ address register) and an instruction (into a value register) for
+ each operand. After the operands have been evaluated, the
+ instruction is executed.
+ Operand Evaluation: If the mode is immediate, the address register
+ is loaded with 0 (the current instruction's address) and the value
+ register is loaded with the current instruction. If the mode is
+ direct, the address register is loaded with the field value and
+ the value register is loaded with the instruction pointed to by
+ the address register. If the mode is indirect, the address
+ register is loaded with the sum of the field value and the B-field
+ value of the instruction pointed to by the field value and the
+ value register is loaded with the instruction pointed to by the
+ address register. If the mode is auto-decrement, the address
+ register is loaded with a value one less than the sum of the field
+ value and the B-field value of the instruction pointed to by the
+ field value and the value register is loaded with the instruction
+ pointed to by the address register. AFTER the operands have been
+ evaluated (but before instruction execution), if either mode was
+ auto-decrement, the appropriate memory location is decremented.
+ If both modes were auto-decrement and both fields pointed to the
+ same pointer, that memory location is decremented twice. Note
+ that this instruction in memory then points to a different
+ instruction than either operand and also differs from any copies
+ of it in registers.
+86: Other: As above, except there are no registers. Everything is
+ done in memory.
+Commentary: ICWS'86 clearly states the use of an instruction register,
+ but the other operand address and value registers are only
+ implied. Ambiguities and lack of strong statements delineating
+ what takes place in memory and what takes place in registers
+ condemned ICWS'86 to eternal confusion and gave birth to ICWS'88.
+88: As above except everything is done in memory and Pre-Decrement
+ Indirect replaces Auto-Decrement Indirect. Pre-Decrement Indirect
+ decrements memory as it is evaluating the operands rather than
+ after. It evaluates operand A before evaluating operand B.
+
+----------------------------------------------------------------------
+
+V. Instruction Set
+
+DAT A, B
+ The DAT (data) instruction serves two purposes. First, it allows
+you to store data for use as pointers, offsets, etc. Second, any task
+which executes a DAT instruction is removed from the task queue. When
+all of warrior's tasks have been removed from the queue, that warrior
+has lost.
+86: DAT allows only one operand - the B-operand. The A-field is left
+ undefined (the example shows #0), but comparisons of DAT
+ instructions with identical B-operands must yield equality.
+88: DAT allows two operands but only two modes - immediate and
+ pre-decrement.
+X: DAT takes one or two operands and accepts all modes. If only one
+ operand is present, that operand is considered to be the B-operand
+ and the A-operand defaults to #0.
+Commentary: It is important to note that any decrement(s) WILL occur
+ before the task is removed from the queue since the instruction
+ executes only after the operand evaluation.
+
+MOV A, B
+ The MOV (move) instruction either copies a field value (if either
+mode is immediate) or an entire instruction (if neither mode is
+immediate) to another location in core (from A to B).
+86: Durham: MOV #a, #b changes itself to MOV #a, #a.
+Commentary: There is a clear typographical error in ICWS'86 which
+ changes the interpretation of MOV #a, B to something non-sensical.
+ For those with a copy of ICWS'86, delete the term "B-field" from
+ the next-to-last line of the second column on page 4.
+88: No immediate B-modes are allowed.
+X: Immediate B-modes are allowed and have the same effect as a
+ B-operand of 0. (See 86: Durham: above).
+
+ADD A, B
+86: The ADD instruction adds the value at the A-location to the value
+ at the B-location, replacing the B-location's old contents.
+88: If the A-mode is immediate, ADD is interpreted as above. If the
+ A-mode is not immediate, both the A-field and the B-field of the
+ instruction pointed to by the A-operand are added to the A-field
+ and B-field of the instruction pointed to by the B-operand,
+ respectively. The B-mode can not be immediate.
+X: Immediate B-modes are allowed and have the same effect as in 86:.
+ Example: ADD #2, #3 becomes ADD #2, #5 when executed once.
+
+SUB A, B
+ The SUB (subtract) instruction is interpreted as above for all
+three cases, except A is subtracted from B.
+
+JMP A, B
+ The JMP (jump) instruction changes the instruction pointer to point
+to the instruction pointed to by the A-operand.
+86: JMP allows only one operand - the A-operand. The B-operand is
+ shown as #0.
+88: JMP allows both operands, but the A-mode can not be immediate.
+X: JMP allows both operands and the A-mode can be immediate. An
+ immediate A-mode operand is treated just like JMP 0, B when
+ executed.
+
+JMZ A, B
+ The JMZ (jump if zero) instruction jumps to the instruction pointed
+to by the A-operand only if the B-field of the instruction pointed to
+by the B-operand is zero.
+88: Immediate A-modes are not allowed.
+
+JMN A, B
+ The JMN (jump if non-zero) instruction jumps to the instruction
+pointed to by the A-operand only if the B-field of the instruction
+pointed to by the B-operand is non-zero.
+88: Immediate A-modes are not allowed.
+
+DJN A, B
+ The DJN (decrement and jump if non-zero) instruction causes the
+B-field of the instruction pointed to by the B-operand to be
+decremented. If the decremented values is non-zero, a jump to the
+instruction pointed to by the A-operand is taken.
+88: Immediate A-modes are not allowed.
+
+CMP A, B
+ The CMP (compare, skip if equal) instruction compares two fields
+(if either mode is immediate) or two entire instructions (if neither
+mode is immediate) and skips the next instruction if the two are
+equivalent.
+Commentary: There is a clear typographical error in ICWS'86 which
+ changes the interpretation of CMP #a, B to something non-sensical.
+ For those with a copy of ICWS'86, delete the term "B-field" from
+ the fifth line from the bottom of the second column on page 5.
+ Also, the comments to the example on page 6 have been switched
+ (equal is not equal and vice versa). The labels are correct
+ though.
+88: Immediate B-modes are not allowed.
+
+SPL A, B
+ The SPL (split) instruction splits the execution between this
+warrior's currently running tasks and a new task. Example: A battle
+between two warriors, 1 and 2, where warrior 1 has two tasks (1 and
+1') and warrior 2 has only one task would look like this: 1, 2, 1', 2,
+1, 2, 1', 2, etc.
+86: SPL allows only one operand - the B-operand. The A-operand is
+ shown as #0. After executing the SPL, the next instruction to
+ execute for this warrior is that of the newly added task (the new
+ task is placed at the front of the task queue). A maximum of 64
+ tasks is allowed for each warrior.
+88: SPL splits the A-operand, not the B-operand. After executing the
+ SPL, the next instruction to execute for this warrior is the same
+ instruction which would have executed had another task not been
+ added (the new task is placed at the back of the task queue).
+ There is no explicit task limit on warriors. Immediate A-operands
+ are not allowed.
+X: Immediate A-operands are allowed and behave as SPL 0, B when
+ executed.
+
+88: SLT A, B: The SLT (skip if less than) instruction skips the next
+ instruction if A is less than B. No Immediate B-modes are
+ allowed.
+X: Immediate B-modes are allowed.
+
+X: XCH A, B: The XCH (exchange) instructions exchanges the A-field and
+ the B-field of the instruction pointed to by the A-operand.
+
+X: PCT A, B: The PCT (protect) instruction protects the instruction
+ pointed to by the A-operand until the protection is removed by an
+ instruction attempting to copy over the protected instruction.
+
+Pseudo-Ops: Instructions to the Assembler
+-----------------------------------------
+
+END
+ The END pseudo-op indicates the end of the Redcode source program.
+86: END takes no operands.
+88: If END is followed by a label, the first instruction to be
+ executed is that with the label following END.
+X: ORG A (origin) takes over this initial instruction function from
+ END.
+Commentary: If no initial instruction is identified, the first
+ instruction of your program will be the initial instruction. You
+ can accomplish the same effect as "END start" or "ORG start" by
+ merely starting your program with the instruction "JMP start".
+
+86: SPACE A, B: The SPACE pseudo-op helps pretty-up Redcode source
+ listings. SPACE A, B means to skip A lines, then keep B lines on
+ the next page. Some assemblers do not support SPACE, but will
+ treat it as a comment.
+
+88: label EQU A: The EQU (equate) pseudo-op gives the programmer a
+ macro-like facility by replacing every subsequent occurrence of
+ the label "label" with the string "A".
+Commentary: A normal label is a relative thing. Example:
+
+x DAT #0, #x ; Here x is used in the B-field
+x+1 DAT #0, #x ; Each instruction's B-field gives
+x+2 DAT #0, #x ; the offset to x.
+
+is the same as
+
+x DAT #0, #0 ; Offset of zero
+x+1 DAT #0, #-1 ; one
+x+2 DAT #0, #-2 ; two
+
+but
+
+x! EQU 0 ; Equate label like #define x! 0
+ DAT #0, #x! ; Exclamation points can be used
+ DAT #0, #x! ; in labels (in Extended systems)
+ DAT #0, #x! ; I use them exclusively to indicate
+ ; immediate equate labels.
+
+is the same as
+
+ DAT #0, #0 ; A direct text replacement
+ DAT #0, #0 ; appears the same on every
+ DAT #0, #0 ; line it is used.
+
+----------------------------------------------------------------------
+