²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² ² ²Û ² 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=> 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 . 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 , display next or previous screen (21 addresses) <^PgDn>, <^PgUp> (Control-PgUp, -PgDn) jump 1000 addresses ahead or back go to specified address edit current (bottom) address Find contents of address Search and Replace (see below) write-protect current address (equivalent to executing PCT on this address) toggle breakpoint flag toggle watchpoint flag exit All commands refer to the bottom line on screen as the current address. Hitting (Edit) and then will delete the contents of the current address and reset its Mode to zero. When you hit (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 ), 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]: To address [7999]: 2000 Search instruction [All]: Replace instruction [Null]: 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]: To address [7999]: Search instruction [All]: MOV 0 1 Replace instruction [Null]: MOV 0 2 Writing to the Core using or 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 . 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 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