
                  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
                  ▓                                         ▓█
                  ▓      COREWAR PLUS 2.0 USER MANUAL       ▓█
                  ▓         1991 (c) Stefan Strack          ▓█
                  ▓                                         ▓█
                  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█
                   ███████████████████████████████████████████

                      @1 Introduction
                      @2 Implementation
                      @3 Files
                      @4 Requirements
                      @5 Setup
                      @6 Operating Core War
                        @6.0 General Remarks
                        @6.1 MARS top level
                        @6.2 The Loader
                        @6.3 The Monitor
                      @7 Bugs
                      @8 Addendum
                        @8.1 Redcode
                        @8.2 Core location modes
                        @8.3 Run control parameters
                        @8.4 Core War rules

V2.0=>  New features or changes in Version 2.0 are marked at the left margin.


-------------------
@1 INTRODUCTION

        Core War is a simulation game for computer virus battles in a small
        virtual memory space. The rules are detailed in the original article
        by the creator of Core War, A.K.Dewdney (Computer recreations column,
        Scientific American, May 84, March 85, December(?) 86).  MARS (Memory
        Array Redcode Simulator) is the Core War supervisory program that
        schedules the execution of battle programs written in the
        assembly-style language Redcode. The dialect of Redcode supported by
        this implementation of MARS, referred to as Redcode+, features the
        complete suite of opcodes including SPL (Split execution into two
        subprocesses), PCT (Protect memory location against one write
        attempt), as well as new opcodes for stack manipulation and process
        control. Recode+ is described in more detail in the addendum. A quick
        reference for Redcode+ can be found in REDCODE.HLP.


-------------------
@2 IMPLEMENTATION

        CoreWar Plus (i.e. the MARS game environment) was written in Turbo
        Prolog V1.1 and fully exploits its windowing features and management
        of dynamic memory. The memory array is represented as a collection of
        database predicates; read and write operations are implemented as
        retract/assert operations. Because all data structures are
        dynamic, the number of programs the interpreter can run is
        limited only by available memory.


-------------------
@3 FILES

        CORE.DOC    - Quick introduction
        CORE.HLP    - On-line help manual for CoreWar Plus
        REDCODE.HLP - Quick reference for Redcode Instructions
        RPP.HLP     - manual for Redcode preprocessor
        CORE.EXE    - CoreWar Plus executable
        CORE.SYS    - Init file for CORE.EXE
        RPP.EXE     - Redcode preprocessor executable
        *.RPP       - sample Redcode programs, before preprocessing
        *.RED       - sample Redcode programs, ready to run
        RUNTIM.ERR  - run-time error messages
V2.0=>  COREMUS.DEF - optional mouse driver

        CORE.EXE and RPP.EXE have been compressed using LZEXE 0.91.


-------------------
@4 REQUIREMENTS

        Core War runs on IBM compatible computers with at least 256 KByte of 
        free memory and floppy or hard disk. It runs under DOS (2.0 or 
        higher). No graphics card required, the program operates fully in 
        text mode assuming a 25 * 80 character display.  Memory requirement 
        depends on the size of the Core (specified in CORE.SYS, default 8000) 
        and on the number of Redcode programs loaded. With a Core size of 
        1000 the program will need less than 256K.  Memory requirement 
        increases by 38K for every 1000 additional Core addresses, and 510K 
        are required for the default Core size of 8000.


-------------------
@5 SETUP

        The setup file CORE.SYS contains parameters that control appearance
        and behavior of the Core War program. It consists of prolog
        predicates that are consulted upon program start. You can change the
        setup by modifying CORE.SYS with a text editor. All predicates are on
        a separate line, no blank lines are permitted. The CORE.SYS supplied
        with this release is a sample configuration for a color display;
        there you can find examples for most predicates described in the
        following.

        If CoreWar Plus cannot find CORE.SYS or predicates are omitted from
        CORE.SYS the program will initialize from defaults.

        predicate: coresize(CS)
                occurs: 0..1
                argument: CS = 0..?, default = 8000

        Coresize/1 determines the size of the virtual memory array (Core) in
        number of addresses; the original rules refer to CS=8000, but for
        Redcode debugging and test runs the Core can be much smaller.
        Coresize can be larger than 8000 and is limited only by available
        memory. The larger the Core array, the slower the execution speed and
        the longer before a battle concludes by extinction of a contestant.
        CS should be a multiple of 1000 as to prevent self-destruction of
        Redcode programs that reference beyond the boundaries of the circular
        core array.

        predicate: windowcolors(WindowName,InsideColor,FrameColor)
                occurs: 0..7
                arguments: WindowName = main ; menu ; statusline ; dialog ;
                                        dos ; editor ; error
                           InsideColor = 0..255, default = 7 (statusline 122)
                           FrameColor = 0..255, default = 15

        This predicate specifies the appearance of several windows (main,
        menu, ..) in the game environment. InsideColor and FrameColor are
        integers in the range from 0 to 255 specifying the color of the
        window inside and its frame respectively. If you have a monochrome
        monitor and the Core War display is illegible using the provided
        CORE.SYS, try color values 7 or 15. You can also delete all
        windowcolors/3 predicates, since colors default to black and white.

V2.0=>  predicate: controlmode(M1,M2,M3,M4,M5,M6,M7,M8,M9,M10)
                occurs: 0..1
                arguments: M1,M2,..M10 = on ; off
                defaults: (on,off,on,off,on,on,off,off,off,off)


        Controlmode/10 describes the initial setting of run control and run
        display parameters (see 6.3.2 Control and addendum). The order of
        arguments is the same as in the "Run control" window.

        predicate: prodisplay(ProcessNo,ExeColor,ExeChar,
                                        WriteColor,WriteChar,
                                        BreakColor,BreakChar)
                occurs: 0..?
                arguments: ProcessNo = 0..?
                           ExeColor = 0..255, default = MainWindowForeground
                           ExeChar = ASCII(32)..ASCII(255),
                                default = ASCII(48 + ProcessNo)
                           WriteColor = 0..255,
                                default = MainWindowForeground
                           WriteChar = ASCII(32)..ASCII(255),
                                default = ASCII(249) ('∙')
                           BreakColor = 0..255,
                                default = MainWindowForeground + 128,
                           BreakChar = ASCII(32)..ASCII(255),
                                default = ASCII(48 + ProcessNo)

        Prodisplay/7 controls the appearance of processes when run in "visual 
        mode" (see 6.3.2 Control and addendum). Argument ExeColor is the 
        color attribute for the display of ExeChar, the character indicating 
        the execution of process ProcessNo. When ProcessNo writes to Core, it 
        is shown by displaying WriteChar with color WriteColor. When visual
        mode is interrupted because a program faulted, a key was pressed,
        etc., the address last executed is highlighted by BreakChar displayed
        with color BreakColor.

        predicate: exclude(Opcode)
                occurs: 0..?
                argument: Opcode  = "DAT" ; "MOV" ; "ADD" ; "SUB" ; "JMP" ;
                                    "JMZ" ; "JMN" ; "JMG" ; "DJZ" ; "DJN" ;
                                    "CMP" ; "SPL" ; "PCT" ; "HLT" ; "GSB" ;
                                    "RET" ; "PSH" ; "POP" ; "RND" ; "SSP" ;
                                    "RLS" ; "EXC" ; "SSZ"

        The exclude/1 predicate forces programs to use a subset of the
        Redcode language. You might e.g. exclude the PCT (Protect)
        instruction for a faster, more offensive combat. Opcode is quoted and
        must be in all capitals.
        Since the program does not check whether Opcode is a valid 3-letter
        mnemonic, exclude/1 predicates can also be used for commenting
        CORE.SYS as in: 
                exclude("This sets the main window colors to green on red")

        predicate: editor(CommandString)
                occurs: 0..1
                argument: CommandString = DOS command string

        If you prefer your own text editor over the built-in editor, use the
        editor/1 predicate to specify a valid DOS command that invokes the
        editor. E.g. editor("c:\tools\myed /opt") starts up myed with option
        /opt when the Editor option is seleceted from the MARS menu.

        predicate: path(DosPathName)
                occurs: 0..1
                argument: DosPathName = valid drive:\pathname,
                        default = ""

        Path/1 specifies where CoreWar Plus looks for files when displaying a
        directory listing. Files that the program expects in DosPathName are:
        (a) programs (*.RED), (b) help files (*.HLP), and (c) saved game
        states (*.DMP). If the path/1 predicate is omitted, CoreWar Plus will
        look for all files in the current directory. E.g. path("b:") sets the
        directory path to drive B:. Note: you must omit the trailing
        back-slash in the directory name.


--------------------
@6 OPERATING CORE WAR

        This section explains how to run Redcode programs in the MARS
        environment and assumes you have your Redcode source files written
        with any pure ASCII editor ready on disk. How to write efficient
        battle programs, however, is an art for itself and will not be
        addressed here (but see A.K.D.'s original articles for some hints).


--------------------
@6.0 GENERAL REMARKS

        The Core War interpreter is a windowing environment driven by menus
        and dialog windows. Menu items are selected with arrow keys and the
V2.0=>  <Return> key or highlighted hot-keys; the escape key returns to the
        previous menu on top and also cancels input in dialog windows. The
        main window receives most text output (listings, run information,
        status reports etc.), the status line on the bottom of the screen
        informs if and what kind of input the program will accept. From the
        MARS menu the two central modules Loader and Monitor can be selected,
        each represented with its own submenu. Briefly, the Loader loads and
        installs Redcode programs and the Monitor executes them.

V2.0=>  You can use the function keys F1 to F7 to execute frequently used
        commands. F2, F3 and F4 start the interpreter in different
        execution/view modes by setting the switches on the control panel.

        F1      (Load) Lets you select Redcode programs from a directory
        listing until you press <Escape>. You are then prompted for one of
        three ways to install the selected programs in Core (See 6.2.2
        Install programs). This is equivalent to repeatedly selecting "Load
        program" and then "Install programs" from the Loader submenu.

        F2      (RunV) Starts the interpreter in visual mode using the
        default settings for controlmode/10.

        F3      (Step) Starts the interpreter in single-step (debugging)
        mode.

        F4      (Watch) Starts the interpreter in watch/single-step
        mode. Watchpoints are set from within the Core Editor.

        F5      (New) Clears the Core and unloads programs (= "Reset"/"Both"
        from the Loader submenu). This may take awhile if the Core is full.

        F6      (Edit) Invokes the Core Editor (= "Edit Core" from the
        Monitor submenu).

        F7      (Cls) Clears the main window.


--------------------
@6.1 MARS TOP LEVEL

        The MARS main menu provides access to the Loader and Monitor
        submenus, clears the main window (Clear window) and exits the
        environment (Quit). In addition the following commands are available
        from the main menu:

        @6.1.1 DOS. This selection suspends Core War and exits to the DOS
        prompt. "EXIT" returns to the main menu.

        @6.1.2 Editor. Invokes the editor specified in the editor/1 setup
        predicate (see 5 Setup) for editing Redcode programs etc.. If no
        external editor is specified, CoreWar Plus invokes the internal Turbo
        Prolog Editor; this editor is somewhat idiosynchratic, since you have
        to invoke "AuxEdit" to load (F8) and save (F10) files; in addition,
        you cannot create new files with the editor.  Commands resemble
        WordStar with F-keys replacing ^K and ^Q sequences.

        @6.1.3 Preprocessor. This selection calls the external Redcode
        preprocessor (RPP.EXE). RPP facilitates writing of Redcode programs
        by providing absolute addressing by labels and symbol definitions
        (see RPP.HLP for details).

        @6.1.4 View Redcode. Displays Redcode source files (*.RED or *.RPP)
        that are selected from a directory listing.

        @6.1.5 Help. Displays help files (*.HLP) selectable from a directory
        listing.


--------------------
@6.2 THE LOADER

        The Loader submenu is used to make the preparations for a Core War
        battle such as loading programs from disk, installing them in Core,
        etc.. These are the items on the menu:

        @6.2.1 Load Redcode program. Reads a Recode source file, selected 
        from a directory listing of files matching *.RED, from disk and 
        assembles a "program image" (the internal representation of Redcode) 
        line by line.  Syntax errors are reported in an error window, and the 
        assembly status is reported after completion. "Load Redcode program" 
        can be repeated ad lib.; for each successful assembly a new program 
        image is stored in memory. More on Redcode syntax can be found in the
        addendum or in REDCODE.HLP.

        @6.2.2 Install programs. After all Redcode battle contestants have
        been loaded from disk and successfully assembled into program images,
        these program images have to be installed in the circular memory
        array (Core). "Install programs" gives three choices for installing,
        offered in a submenu:

        (1) At random. Programs are installed with randomly scattered start
        addresses while maintaining a minimum distance (modifyable). (2)
        Maximum distance. As name implies, images are written into Core such
        that they keep a maximum distance from one another. (3) Manually.
        The user is prompted for the start address of each program image.
        In Core War parlance, program images have now become processes.

        @6.2.3 Load Core. The Core War simulator allows to dump the current
        state of execution (Core image, program images, process control
        blocks, process queue, stacks) to disk in order to resume with a
        battle in progress at a later time. "Load Core" lets the user select
        a core file (*.DMP) from a current directory listing and consults
        (=reads) it. Load/Install programs and Load Core are mutually
        exclusive options for preparing for execution.

        @6.2.4 Dump Core. See above item; dumps the current state of
        execution to disk (default extension .DMP). This option is also
        useful for making "back-ups" during a long-running battle.

        @6.2.5 Reset. Allows to reset (clear) Core and/or program images in
        order to start fresh. Reset (a) "Core image" sets all addresses to
        zero (actually DAT 0) and resets process control blocks, stacks, and
        the process queue, (b) "Program images" "unloads" programs, and (c)
        "Both" does both. "Install programs" will not work unless the Core is
        clear.

--------------------
@6.3 THE MONITOR

        The Monitor is the actual Core War scheduler; from the Monitor menu
        you can start execution, control execution etc.. The options are
        detailed below:

        @6.3.1 Run. This starts the round-robin scheduler executing
        instructions of Redcode processes installed in Core.  Execution can
        be restarted at any point, if it has been interrupted by the user
        pressing a key, an execution error or else. An interrupt of any kind
        displays in an interrupt window the kind of interrupt, the current
        process' program counter and the instruction interrupted.  From here,
        the supervisor is returned to the monitor menu where she may perform
        various checks before restarting the scheduler where the interrupt
        occurred.

        @6.3.2 Control. Opens the "control panel" of the scheduler. Several
        controls pertaining to execution interrupts (single step, break on
        error etc.) and representation of the running processes (visual,
        watch, verbose etc.) can be enabled or disabled by toggling on or
        off. The initial setting of the control parameters are contained in
        the setup predicate controlmode/10 (see 5 Setup). The effect of each
        control parameter on execution is detailed in the addendum.

V2.0=>  @6.3.3 Edit Core. This option starts the full-screen memory editor.
        The Core Editor allows you to scroll through the memory array and to
        modify the contents of addresses. Each address is displayed as one
        line with the format:

        Addr  Mode  Instruction
        3017  1W    CMP #513 @-12

        Addr is the address in the range from 0 to coresize-1 (since the Core
        is circular, Addr(0) and Addr(coresize-1) are adjacent); Mode is the
        3-bit write-protect-break status of this address (see addendum). A
        "W" after the Mode number means that this address is a watchpoint.
        These are the keys recognized by the Core Editor:

                Up-, Down-Arrow         scroll up or down by one address
                <PgDn>, <PgUp>          display next or previous screen (21
                                        addresses)
                <^PgDn>, <^PgUp>        (Control-PgUp, -PgDn) jump 1000
                                        addresses ahead or back
                <Home>                  go to specified address
                <F1>                    edit current (bottom) address
                <F2>                    Find contents of address
                <F3>                    Search and Replace (see below)
                <F4>                    write-protect current address
                                        (equivalent to executing PCT on this
                                        address)
                <F5>                    toggle breakpoint flag
                <F6>                    toggle watchpoint flag
                <Esc>                   exit

        All commands refer to the bottom line on screen as the current
        address. Hitting <F1> (Edit) and then <Return> will delete the
        contents of the current address and reset its Mode to zero.

        When you hit <F3> (Search and Replace), you are prompted for start
        address and stop address between which the Core is to be modified. If
        you accept the default for the following "Search instruction" prompt 
        (by hitting <Return>), every instruction in the specified range is 
        targeted. If you choose the default for the "Replace instruction" 
        prompt (Null), the targeted instructions in the specified range will 
        be deleted. E.g. to clear all instructions in the range from 0 to 
        2000:

                From address [0]: <Return>
                To address [7999]: 2000<Return>
                Search instruction [All]: <Return>
                Replace instruction [Null]: <Return>

        Since execution speed is inversely related to the number of Core
        addresses with non-zero contents, clearing "dead" Core areas this way
        can improve performance dramatically. To replace all occurrences of
        MOV 0 1 with MOV 0 2:

                From address [0]: <Return>
                To address [7999]: <Return>
                Search instruction [All]: MOV 0 1<Return>
                Replace instruction [Null]: MOV 0 2<Return>

        Writing to the Core using <F1> or <F3> follows the same rules as
        Redcode programs writing to addresses. I.e. if the targeted address
        was protected (by PCT), an edit attempt would result in the
        protect-bit being cleared, leaving the contents unchanged.

--------------------
@7 BUGS

        The program is very sensitive to improper format of the optional
        initialization file CORE.SYS, e.g. the SideKick Notepad appends a ^Z
        character to each file edited, which causes CoreWar Plus to report an
        error upon start-up.  So, be sure to use a pure ASCII-editor if you
        modify CORE.SYS. The built-in editor (see 6.1.2 Editor) works fine
        with CORE.SYS. Make sure to end the last predicate with a <Return>.

        Some operations, notably clearing the Core or Search and Replace can be
        extremely slow if most of the addresses in a large Core have been
        written to. This is a consequence of the Core implementation as logic
        predicates. You can speed up execution by using "Edit Core" to clear
        "bombs", etc..

--------------------
@8 ADDENDUM

--------------------
@8.1 REDCODE

        This section describes the present implementation of Redcode+ and the 
        syntax that the Redcode assembler accepts.

        @8.1.1 Instruction set

        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Data statement   | DAT |   B | Nonexecutable: B is data value     |
        |                  |     |     |                                    |
        ---------------------------------------------------------------------


          Store-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Move             | MOV | A B | Move contents of A to B            |
        |                  |     |     |                                    |
        ---------------------------------------------------------------------
        | Add              | ADD | A B | Add contents of A to B,            |
        |                  |     |     | store result in B                  |
        ---------------------------------------------------------------------
        | Sub              | SUB | A B | Subtract contents of A from B,     |
        |                  |     |     | store result in B                  |
        ---------------------------------------------------------------------
        | Random           | RND | A B | Generate random number (range 0..A)|
        |                  |     |     | and store it in B                  |
        ---------------------------------------------------------------------

        Remarks: Since CoreWar Plus represents Redcode instructions
        internally as predicates and not in binary or decimal encoded form,
        arithmetic operations (ADD, SUB, DJN, ..) and indirect addressing
        will fail if its arguments do not point to a data value. MARS flags
        arithmetic with a non-data statement as an execution error.


          Branch-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Jump             | JMP | A   | Transfer control to A              |
        |                  |     |     | (unconditional)                    |
        ---------------------------------------------------------------------
        | Jump if zero     | JMZ | A B | Transfer control to A if contents  |
        |                  |     |     | of B is zero                       |
        ---------------------------------------------------------------------
        | Jump if not zero | JMN | A B | Transfer control to A if contents  |
        |                  |     |     | of B is not zero                   |
        ---------------------------------------------------------------------
        | Jump if greater  | JMG | A B | Transfer control to A if contents  |
        | than zero        |     |     | of B is greater than zero          |
        ---------------------------------------------------------------------

        
          Counter-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Decrement, jump  | DJZ | A B | Subtract 1 from B and jump to A    |
        | if zero          |     |     | if contents of B is then 0         |
        ---------------------------------------------------------------------
        | Decrement, jump  | DJN | A B | Subtract 1 from B and jump to A    |
        | if not zero      |     |     | if contents of B is then not 0     |
        ---------------------------------------------------------------------


          Process-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Split            | SPL | A   | Split execution into next          |
        |                  |     |     | instruction and A                  |
        ---------------------------------------------------------------------
        | Halt             | HLT | -   | Terminate execution of             |
        |                  |     |     | (sub)process                       |
        ---------------------------------------------------------------------
V2.0=>  | Suspend          | SSP | -   | Suspend execution of all other     |
        |                  |     |     | subprocesses                       |
        ---------------------------------------------------------------------
V2.0=>  | Release          | RLS | -   | Release suspended subprocesses     |
        |                  |     |     |                                    |
        ---------------------------------------------------------------------

V2.0=>  Remarks: SSP temporarily suspends executions of all threads except
        the one executing SSP. Processes remain suspended until either a RLS
        instruction is executed or the unsuspended thread(s) terminate (i.e.
        SSP, .., RLS, HLT is equivalent to SSP, .., HLT).  SSP/RLS can
        be used to bracket a "critical segment" or to preempt low-priority
        subprocesses. SSP/RLS cannot be nested, which means that new threads
        can be SPLit after a SSP, but these threads cannot be suspended until
        after the next RLS. The interpreter flags two consecutive SSPs or
        RLSs as an execution error.


          Stack-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Gosub            | GSB | A   | Transfer control to A; push        |
        |                  |     |     | current address onto stack         |
        ---------------------------------------------------------------------
        | Return           | RET | A   | Pop return address from stack, add |
        |                  |     |     | A, and transfer control to it      |
        ---------------------------------------------------------------------
        | Push             | PSH | A   | Push contents of A onto stack      |
        |                  |     |     |                                    |
        ---------------------------------------------------------------------
        | Pop              | POP | A   | Pop address from stack and move it |
        |                  |     |     | to A                               |
        ---------------------------------------------------------------------
V2.0=>  | Stacksize        | SSZ | A   | store the number of elements       |
        |                  |     |     | currently on the stack in A        |
        ---------------------------------------------------------------------

        Remarks: Each program is allocated its own stack; a program cannot
        access the stack of another program.

        The RET (Return) instruction needs an argument because GSB (Gosub)
        pushes a PC-relative address onto the stack.  Usually, the argument
        to RET refers back to the entry point of the subroutine ("RET -10"
        for an entry point 10 addresses behind).

        PSH (Push) and POP (Pop) instructions expand or shrink the program's
        private stack. The stack can hold up to 128 instructions or data
        statements. Popping an empty stack, as well as pushing past 128
        elements is flagged with an execution error.

        A note of caution: be careful accessing the stack when multiple
        subprocesses are running (spawned of with SPL). Since all
        subprocesses of a program share the same stack, ill-timed Gosubs and
        Returns may wreak havoc on the proper flow-of-control. Use SSP/RLS
        (see above) to avoid conflicts.


          Special-Instructions
        ---------------------------------------------------------------------
        | Instruction      | Mnem| Args| Description                        |
        ---------------------------------------------------------------------
        | Protect          | PCT | A   | Write-protect address A against    |
        |                  |     |     | next write attempt                 |
        ---------------------------------------------------------------------
V2.0=>  | Execute          | EXC | A B | Execute instruction at B, update B |
        |                  |     |     | & transfer control to A if no error|
        ---------------------------------------------------------------------

V2.0=>  Remarks: The EXC instruction is a single-thread meta-interpreter. It
        provides Redcode programs with internal exception handling, since EXC
        traps errors by conditional branching: if the instruction pointed to
        by B fails or is a HLT instruction, then the next instruction
        following EXC is executed. If the instruction at B succeeds, then B
        is updated with the new "local" program counter (the address B
        transfers control to), and execution resumes at A. B is therefore
        usually an indirect address. Since only one local program counter is
        maintained in B, only one execution thread can be trapped by EXC.
        Consequently, when a SPL, SSP, or RLS instruction is executed by EXC,
        it will only affect "global" threads. The code fragment below
        demonstrates a single-instruction meta-interpreter executing a
        3-instruction program.

                exc 0 @2    ;single instruction loop
                jmp 99      ;an error was trapped
                dat 1       ;local PC
                mov #0 @3   ;"DWARF-like"
                sub #10 2
                jmp -2
                dat 4

        Since code executed by EXC is under control of the executing program,
        it is "invisible" to the interpreter: e.g. single-step mode will not
        trace the instructions under control of EXC, nor will breakpoints
        trigger an interrupt. You can still debug code under the control of 
        EXC by placing a watchpoint on the data statement that serves as the 
        local program counter.

        EXC's can be nested, i.e. an EXC instruction can execute another EXC
        instruction. The interpreter can catch EXC "loops", i.e. it will
        signal failure if an EXC tries to execute itself in an infinite loop.


        @8.1.2 Addressing modes

        ---------------------------------------------------------------------
        | Mode                |Sym| Description                             |
        ---------------------------------------------------------------------
        | immediate           | # | is data value                           |
        |                     |   |                                         |
        | direct              | $ | is effective address ($ can be omitted) |
        |                     |   |                                         |
        | data-relative:      |   |                                         |
        |       indirect      | @ | is address of effective address         |
        |                     |   | relative to data statement              |
        |       pre-increment | > | increment, is then address of effective |
        |                     |   | address relative to data statement      |
        |       pre-decrement | < | decrement, is then address of effective |
        |                     |   | address relative to data statement      |
        | PC-relative:        |   |                                         |
        |       indirect      | ^ | is address of effective address         |
        |                     |   | relative to program counter             |
        |       pre-increment | / | increment, is then address of effective |
        |                     |   | address relative to program counter     |
        |       pre-decrement | \ | decrement, is then address of effective |
        |                     |   | address relative to program counter     |
        ---------------------------------------------------------------------

V2.0=>  Two modes of indirect addressing are implemented: (a) data-relative,
        where the effective address is calculated by adding the value of the
        referenced data statement to its address, and (b) PC-relative, where
        the value of the referenced data statement is added to the address of
        the instruction that is currently executing. Data-relative indirect
        addressing is part of the original Redcode specifications introduced
        by A.K.Dewdney, whereas PC-relative addressing was mistakenly
        implemented as the only form of indirect addressing in pre-V2.0
        versions of CoreWar Plus. Both modes are supported in order to
        maintain compatibility with both programs written for earlier
        versions of CoreWar Plus, and programs that use standard
        data-relative indirect addressing.

        An example:
 .
 .
100     dat -1                                  dat -3
101     add #5 -1       is equivalent to:       add #5 -1
102     mov #0  @-2                             mov #0 ^-2
103     jmp -2                                  jmp -2
104
 .
 .

        The left program adds the value 5 to the contents of address 100, 
        yielding DAT 4 in this location. The instruction at address 102 then 
        MOVes a 0-bomb to the address specified by the data-relative indirect 
        reference "@-2". The indirect address is 102 - 2 = 100, which 
        contains DAT 4. The effective address is therefore 100 + 4 = 104,
        i.e. the bomb lands at address 104. The right program adds 5 to -3,
        resulting in DAT 2 at address 100. The MOV-statement then moves #0
        to the address specified by "^-2". The indirect address is again 102
        - 2 = 100, containing DAT 2. In PC-relative mode, the effective
        address is now 102 (address of current instruction) + 2 = 104, i.e.
        the zero-bomb falls on address 104 as before. Pre-increment and
        -decrement modes work similarly, only that the contents of the
        indirect address is incremented or decremented prior to calculation
        of the effective address.

        
        @8.1.3 Syntax conventions

        - one instruction per line, empty lines are permitted
        - comments begin with a semicolon (;) and go to the end of the line
        - mnemonics can be upper, lower or mixed case
        - mnemonics and arguments can be separated by space(s), comma(ta) or
          tab(s)
        - execution begins at the first instruction
        - each file contains exactly one program

        The Redcode preprocessor language extends basic Redcode syntax with
        labels and symbol definitions (see RPP.HLP).

--------------------
@8.2 CORE LOCATION MODES

        Each memory location has associated with it a Mode parameter in the
        range from 0 to 7. The three bits XYZ of this integer describe the
        status of this address:
        Bit X (Write): 1 if address has been written to, 0 if not
        Bit Y (Protect): 1 if address is write-protected, 0 if not
        Bit Z (Trace): 1 if address is marked as a breakpoint, 0 if not
        As a table:

        Mode          Trace   Protect Write
        -------------------------------------
        0             0       0       0
        1             0       0       1
        2             0       1       0
        3             0       1       1
        4             1       0       0
        5             1       0       1
        6             1       1       0
        7             1       1       1

        An unmodified address therefore has Mode=0 and Instruction=DAT 0 
        (neither contents nor Mode of an unmodified address are shown in the 
        Core Editor).

--------------------
@8.3 RUN CONTROL PARAMETERS

        The run control panel in the Monitor module has ten on/off switches 
        that control appearance and interrupt behavior of a Core War battle.  
        Four parameters control how the battle is represented on screen 
        (single step, visual, watch, verbose), the remaining six control 
        under what circumstances execution is paused.

        Key interrupt   ON: execution can be paused at any time by
                        pressing any key, OFF: cannot (usually ON, except
                        then "single step" is enabled)

        Single step     ON: trace mode for debugging, information for
                        each instruction executed is shown in the main window,
                        e.g.:

                [PROC=0:PC=3861], FRWE=1110, INST=ADD #5 3
                where PROC: Process number
                        PC: Program counter (=address of this instruction)
                      FRWE: Fetch-Read-Write-Execute status of instruction
                                F: Mode of instruction as fetched
                                R: Mode of address this instruction writes to
                                   before write
                                W: Mode of address this instruction writes to
                                   after write (R=W=0 if instruction does not
                                   write)
                                E: State of execution; 0: no error, 1: error,
                                   2: HLT (halt), 3: SSP (suspend) was
                                   executed
                      INST: Instruction being executed

                        Single step ON disables all other switches (except 
                        Watch), since in this mode execution is interrupted 
                        after each instruction anyway.

        Visual          ON: visual representation of Core War execution is
                        enabled. In visual mode, the Core is mapped to the
                        main window, with each address corresponding to one
                        position on the 22 * 78 character area (increasing
                        address from left to right, top to bottom). If the
                        Core size exceeds 22 * 78 = 1716 then adjacent Core
                        addresses may map to the same cursor position,
                        "condensing" the entire Core onto one screen.
                        Execution of a process is shown by writing its
                        identifying character and color to the main window at
                        coordinates corresponding to the current program
                        counter. Writing to Core addresses is indicated by a
                        different character and color (all program display
                        parameters can be customized by prodisplay/7 in
                        CORE.SYS, see 5 Setup).

V2.0=>  Watch           ON: the contents of addresses marked as watchpoints 
                        (using <F6> in the Core Editor) are displayed while 
                        programs are running. If a marked address is a data 
                        statement, then the contents of the instruction it 
                        points to as an indirect address - in both data- and
                        PC-relative mode - is also displayed on the same
                        line. Besides watchpoints, the current list of
                        program counters and the contents of the private 
                        stack are shown as well. OFF: no watch-information is 
                        displayed. "Watch" is compatible with all other 
                        execution views, although it is most commonly used 
                        together with "Single step".

        Breakpoints     ON: the scheduler pauses after an instruction at a
                        breakpoint address was executed (Address Mode =
                        4,5,6,7); OFF: although a breakpoint may have been
                        reached, execution is not interrupted. Breakpoints
                        can be marked from within the Core Editor.

        Break on error  ON: interrupt is invoked if an instruction cannot be
                        executed (e.g. a data statement), usually indicating
                        that the faulting process has been corrupted by a
                        contestant destructively modifying its code in Core.
                        OFF: execution continues through errors. The
                        scheduler terminates a faulting (sub)process;

        Break on first write
                        ON: execution is paused whenever a previously "empty"
                        (Mode = 0,2,4,6) memory location is written to.

        Break on overwrite
                        ON: execution is interrupted whenever an instruction
                        writes to a "non-empty" (Mode = 1,3,5,7) address.

        Break on protection
                        ON: an interrupt occurs if an instruction tries
                        to write to a write-protected (Mode = 2,3,6,7) memory
                        location, thereby clearing the Protect bit (New Mode
                        = Old Mode - 2).

        Verbose         ON: instructions are written to screen, along with
                        process number and Core address, as they are being
                        executed. In contrast to single step mode, there is
                        no automatic interrupt after each instruction's
                        execution. If neither single step, nor visual, nor
                        verbose mode is enabled, the execution window is
                        blank.

--------------------
@8.4 CORE WAR RULES

        The following rules are proposed guide lines for conducting a Core
        War battle and determining the winner.

        (1) Competitors are written in the same Redcode "dialect". The 
        proposed dialects are: (a) standard Redcode (Instructions 0-8), (b) 
        multi-process Redcode (standard plus SPL, HLT, SSP, RLS), (c) Protect
        Redcode (multi-process plus PCT) and (c) full Redcode+ (all
        instructions supported by MARS).  Use the exclude/1 predicate (see 5
        Setup) to enforce the dialect.

        (2) Programs are written independently of each other, i.e. without
        knowledge of the other's strategy of attack and defense.

        (3) Two programs, the contestants, are installed at random locations
        in a Core array of 8000 cells.

        (4) Execution is carried out without manipulating the Core by the
        game supervisor. Non-permissible manipulations include editing of
        "dead", though potentially executable code.

        (5) A battle ends if (a) one of the contestants is dead (survivor
        wins), (b) the contestants are found to be impervious to each other
        (draw), (c) a maximum time has elapsed (draw) or (d) MARS crashes.

        (6) A program is pronounced dead, if (a) its process number has been 
        removed from the process queue by the scheduler, (b) all of the 
        program's "central" processes (those governing attack and defense) 
        have been terminated or altered such that they no longer perform
        their intended behavior (this includes being stuck in an endless
        loop, running off in a MOV 0 1 instruction etc.). A program is
        considered damaged, if some but not all of its central processes are
        terminated or altered.

        (7) Since the start position of the contestants in Core may influence
        the outcome of the game, several battles may have to be run before
        one program can be unequivocally declared superior to the other.


Author: Stefan Strack, Dept. Biology, SUNY @ Albany, Albany, NY 12222, USA.
E-mail: ss9557@albnyvms (Bitnet)
        ss9557@leah.albany.edu (Internet)
        stst@cs.albany.edu (Internet)

        Comments and suggestions are welcome.

Implementation: July 88,
                revised April 89 (V1.6)
                November 90 (V1.7)
                March 91 (V1.8,V2.0)
Manual preparation: April 89, revised November 90, March 91
