PMARS(6) | Games Manual | PMARS(6) |
pmars - portable corewar system with ICWS'94 extensions
pmars [ option ... ] file1 [ file(s) ]
pMARS (portable Memory Array Redcode Simulator) is a corewar interpreter with multi-platform support. pMARS currently runs on UNIX systems, PC/DOS, VMS, Amiga (AmigaDOS command line), and the Mac. pMARS implements the ICWS'94 draft standard, but can also be used in ICWS'88 mode. The base system includes a graphical core display for UNIX (curses, X-windows), PC/linux (svgalib), PC/DOS and the Mac (see APPENDIX). A line-oriented debugger is included to help in writing warriors for the ICWS'94 draft standard.
pMARS runs one or more warriors written in Redcode that are provided as file(s) on the command line. Running a single warrior is supported for debugging. Two warriors are pitted against each other for standard play, but up to 36 warriors can be named for "multi-warrior" core war. If the warrior(s) assemble without error they are loaded into the core array and executed in round-robin mode starting with the first warrior. Warrior 1 is loaded starting at core position 0, warrior 2, 3, etc., at either a random or fixed position. For fairness the starting order is rotated after each round.
The score is reported after all rounds have been played. A round ends when either a single surviving warrior remains or when a maximum number of cycles has elapsed. For each round, every surviving warrior is awarded points calculated from a score formula (F). By default, this is (W*W-1)/S, where W is the total number of warriors participating, S is the number of of survivors, and "/" is integer division. Alternative score formulas can be specified with the = option (see below).
When two warriors battle, the results are reported as wins1, wins2, and ties, where wins1 and wins2 are the numbers of rounds that each warrior won, and ties are the number of rounds in which both warriors lasted until time-out. The score is then:
warrior 1: points = wins1 * F + ties * F
warrior 2: points = wins2 * F + ties * F
F is a score formula containing the W and S parameters. When more than two warriors (W) participate in a game, results are reported as wins[1], wins[2], .., wins[W], losses for each warrior, where the index indicates the number of warriors that survived until the end (S parameter in the score formula). The total number of points for each warrior is then calculated as:
points = sum (S=1..W) (wins[S] * F)
A few alternative score formulas:
10
(W+1)/S
(x=W-S+1)*(x+1)/2
(S==3)*5 + (S==2)*3 + (S==1)
(S == 1)*W + (S != 1)
Command line options may occur anywhere on the command line. Single-letter options without a parameter can be combined as in -fbe. The special argument - (dash) stands for standard input (stdin). It can be combined with the -@ option (see below) to signify reading options from stdin, or the - can take the place of a warrior filename, in which case warrior code starting with a ;redcode line and ending with an END statement is extracted from stdin. The END statement can be omitted if the next ;redcode line immediately follows the last instruction. Several warriors, each specified by a separate dash on the command line and bracketed by ;redcode/END can be piped into pMARS. #- (where # is a positive number) is a shorthand for writing this number of dashes on the command line.
;Below the command line parameters:
-r 10 -beF 1000 2- $
;redcode
;name Imp 1
;assert 1
mov 0,1
end
;redcode
;name Imp 2
;assert 1
mov 0,2
mov 0,2
end
!! cdb commands follow:
sk 1000
reg
quit
The X-Windows display version of pMARS has these additional command line options:
stud1$ pmars -display ncd13.complang.tuwien.ac.at:0 -b aeka.red aeka.red
The argument of the -v display option has an additional fourth digit in the X-Windows version: 0 (the default) enables the color display, 1 the grayscale, and 2 the black and white display (e.g. -v 1033 for the grayscale display).
pMARS implements an extension of the proposed ICWS'94 standard. The new instruction modifiers .A,.B,.AB,.F,.X, and .I, the arithmetic instructions MUL, DIV and MOD, as well as post-increment indirect (>) are supported. pMARS currently does not implement read/write ranges, although they may be added in future versions.
Version 0.5 of pMARS adds support for three experimental opcodes that are currently not included in the ICWS'94 draft:
SEQ (Skip if EQual): this is a synonym for CMP and is included mainly for clarity (future versions of pMARS may implement SEQ as a "predefined EQU" rather than a true opcode).
SNE (Skip if Not Equal): the opposite of SEQ.
NOP (No OPerations): do nothing.
Version 0.6 adds three new indirect addressing modes that use the A-field instead of the B-field as the pointer for indirection:
* - indirect using A-field
{ - predrecement indirect using A-field
} - postincrement indirect using A-field
The new P-space instructions of version 0.8 are discussed under separate heading below.
The assembler also supports multi-line EQU statements, a feature not included in the current ICWS'94 draft. The format for multi-line EQUates is
<label> in the warrior source is replaced by <line1> <newline> <line2> <newline> [....] lineN. In contrast to KotH, pmars EQUs substitute arbitrary text, and not just expressions. EQU expressions are not implicitly parenthesized.
<label> EQU <line1>
EQU <line2>
[...]
EQU <lineN>
pMARS features the non-standard FOR text-repetition macro. This macro repeats the text between FOR and ROF a specified number of times:
<labels> <counter> FOR <times><times> is an expression specifying the number of expansions; it may contain EQUates and labels as long as they have been defined before the FOR/ROF block. <counter> is the last label before the FOR word, but not necessarily on the same line. It is expanded to 01, 02, .., <times> in each repetition. The optional <labels> label the first instruction after FOR expansion. An example:
[..]
ROF
The symbol & concatenates 'a' and 01, 02 to form a valid label. EQU expansion and FOR/ROF processing is done in the same pass. It is therefore possible to write
ORG start start sp FOR 2 a&sp SPL a&sp
JMP a&sp
ROF becomes after expansion start a01 SPL a01
JMP a01 a02 SPL a02
JMP a02
dest01 EQU 500 dest02 EQU 1000 dest03 EQU 1500 idx FOR 3Using predefined EQUates (see below) it is possible to define adaptive FOR/ROF blocks. The next example fills the remainder of the warrior (up to MAXLENGTH lines) with decoy instructions:
MOV src,dest&idx
MOV src+1,dest&idx
ROF src MOV <-1,<-1
JMP src,<-2
Since true logical expressions have a value of "1" and false expressions a value of "0", you can write conditionally assembled code enclosed by FOR/ROF:
FOR MAXLENGTH-CURLINE
DAT 1,1
ROF
pMARS uses KotH-style ;name and ;author comments to describe warriors. If a line starting with ;redcode is present, all text preceding it is ignored. This makes it possible to run posted warriors without removing mail headers and descriptive text. The ;version, ;strategy and other comments mentioned in the ICWS'94 draft are currently not used.
FOR CORESIZE == 8000
<some code>
ROF
FOR CORESIZE != 8000
<other code>
ROF
As another "non-standard" extension, the assembler predefines the following run-time variables: CORESIZE, MAXPROCESSES, MAXCYCLES, MAXLENGTH, MINDISTANCE, ROUNDS, and PSPACESIZE. They can be used in your Redcode as though they were defined by EQUs like
The run-time variable CURLINE holds the current instruction number offset from the first instruction. WARRIORS is initialized with the number of warriors specified on the command line.
CORESIZE EQU 55440 ;current value of -s parameter
MAXPROCESSES EQU 10000 ;current value of -p parameter
[etc.]
pMARS supports the ;assert directive as a way of checking whether a warrior is run under the parameters it was designed for. If the expression following ;assert evaluates to "0" (false), assembly is aborted with an error message. If an ;assert is missing, a warning is issued. Examples:
The run-time variable VERSION holds the current pMARS version (e.g. "60" is v0.6.0) and is useful in ;assert expressions.
;assert CORESIZE == 55440 && MAXLENGTH >= 200
;assert !(CORESIZE % 4) ; is multiple of 4
;assert 1 ; if warrior works under all settings
With the -8 option, pMARS is fully ICWS'88 compatible, except that a comma is required between operands. Extensions like predefined and multi-line EQUs and FOR/ROF are supported even in ICWS'88 mode.
A full treatment of corewar and ICWS'94 in particular is beyond the scope of this document. General information about corewar as well as the ICWS'94 draft is available by anonymous FTP from soda.berkeley.edu in pub/corewar.
Originating from discussions on rec.games.corewar, P-space is an attempt at making warriors more "intelligent" by giving them a memory. P-space, short for "private", "permanent" or "priviledged" space is a memory area separate from core whose contents is not cleared between rounds. Every warrior has its own P-space for gathering information about the opposing warrior, but there is a provision for sharing P-space in team play (see below).
P-space cells contain values in the range 0..CORESIZE-1. The number of P-space cells can be adjusted with the -S command line option; by default, P-space size is 1/16th of CORESIZE. This number is available to warriors as the predefined variable PSPACESIZE. pMARS updates P-space cell 0 at the beginning of each round with the result of the previous round: 0 signifies a loss in the previous round, a number larger than zero means that the warrior survived until the end of the round, the value indicating the number of surviving warriors. That is, a value of "1" means that the warrior survived by itself (a "win" in a two-warrior battle), a value of "2" that two warriors lasted until the end (a "tie" in a two warrior battle), etc.. In the first round, P-cell 0 is set to -1 (actually CORESIZE-1) to indicate that there is no previous result.
There are two new instructions for accessing P-space:
It is important to note that P-space cells are referred to by A/B-values as opposed to A/B-addresses. As an example, "STP #9,#1" stores number 9 in P-cell 1.
Since all P-space access is only via these two instructions, it takes too much time and space to use P-space for working variables where they would be safe from the opposing warrior. P-space was made deliberately hard to access, unlike a set of general purpose registers.
P-space can also be used for communication between warriors belonging to a team in multi-warrior core war. To allow communication, P-space has to be declared as "shared". You do this by including the PIN pseudo-opcode in your source:
P-cell #0 holding the result of the last round is exempt from sharing, i.e. every warrior has its own last round cell even though the rest of its P-space may be shared.
Cdb is a line-oriented debugger. It is invoked either by specifying the -e option (enter cdb immediately), by including debugging commands in the warrior source, or by hitting Ctrl-C during the simulation. The debugger is also entered whenever a warrior terminates ("post-mortem") if execution was started with the go command. cdb is very powerful and has an overwhelming number of commands. You may want to start with only the most often used commands: step (single step execution), go (execute until breakpoint), list (look at core), trace and untrace (set and remove breakpoints), and go on to more complex ones later.
The following commands are available at the cdb prompt; commands can be abbreviated to the first unambiguous substring.
go, step, continue and thread may have a single address argument. The program counter of the current warrior is set to this address before execution continues.
The range argument of the list, trace, etc. commands has the format <start>,<stop>. Addresses <start> and <stop> are numbers, special symbols or C-style expressions including special symbols. If either <start> or <stop> is omitted, it defaults to the current address. If both are omitted, the range of the last cdb command is used. A single address (without the comma) acts on only that address. Addresses starting with a + or - are interpreted relative to the current address.
Expressions may contain the arithmetic operators -,+,*,/,% (modulo), the comparison operators ==, !=, <=, >=, and the boolean operators && (AND), || (OR), and ! (negation). Expressions may also include register variables C through Z and the assignment operator =. Operator precedence is like that of the C-language and may be overridden by parentheses. Assignment, comparison and boolean operations are mostly used with calc and if commands in macros, but can also be used in Redcode operands.
Special address symbols used in cdb commands:
. (dot) is the current address (displayed last).
$ (dollar) is the last core address.
A is the A value of the current instruction.
B is the B value of the current instruction.
PC is the program counter of the currently executing warrior.
PC1 is the program counter of warrior 1.
PC2 is the program counter of warrior 2.
LINES is the number of lines available to the cdb display
CYCLE is the current execution cycle (counted down)
In process queue (pq), warrior queue (wq) or pspace (ps) mode (see pqueue, wqueue, pspace), most of these symbols have a different meaning:
. (dot) is the current process number (pq),
warrior (wq), or P-space cell (ps) which was displayed last.
$ (dollar) is the last process in the process queue (pq),
the last warrior (wq), or the last P-space cell (ps).
A is the A value of the instruction of the current process (pq),
the next executing process of the current warrior (wq), or
the P-space selector (ps, same as warrior number if unshared).
B is the B value of the instruction of the current process (pq),
the next executing process of the current warrior (wq), or
the P-space selector (ps).
PC is 0.
PC1.. are 0
Preceding a command with the character '@' (ampersand) will suppress its screen output, but not output to a logfile. Preceding a command with '&' will suppress both screen and logfile output, which is useful if you are only interested in the "side-effects" of a command. Starting a command with a <Space> character suppresses saving it to the "last-command" buffer that is recalled by <Enter>.
Several commands can be issued on one line when separated by the tilde character ( ). These "command chains" are useful for repeating long command sequences, since <Enter> recalls the entire chain (see the examples below). Commands requiring user intervaention (list, edit, fill) also read their input from the chain.
The "empty command" (two consecutive tildes or a tilde at the end of the chain) repeats the last command in the chain. A command consisting of <Space> is a null command and is used to simulate pressing <Enter> in list, edit and fill.
The exclamation mark (!) character is a special "chain repetitor" command. The optional expression following '!' specifies how many times the command chain starting at the beginning of the line or the last ´!' is executed. '!' without an expression repeats until the program terminates.
The symbol '!!' is used for nested loops and marks the start of a command block to be repeated. The command block is closed by '![expression]' and may contain other command blocks. A command block immediately following an if command is executed only if the condition is true.
With loops, subroutines (macros calling macros), variables (C..Z), expressions involving comparisons and boolean operations, and conditional execution (if), the cdb command language can be used to construct complicated macros for e.g. executing a warrior until a certain core address has changed, controlling the 2-panel display, automatically finding the right constants for a warrior, etc. See the file "pmars.mac" for examples.
Trace bits can also be set by including debugging commands in the warrior source. A comment format is used to retain compatibility with simulators that do not support source-embedded debugging commands.
We will be glad to assist in porting pMARS to other, currently unsupported platforms. This program is still under development and we will continue to enhance functionality and speed, as well as adapt to changes in the proposed ICWS'94 standard. If there is demand, future versions of pMARS will also implement read/write ranges
None whatsoever (right). Contact for bug reports and suggestions is Stefan Strack (stst@vuse.vanderbilt.edu). Please be detailed and include a logfile of the cdb session if applicable. Bug reports and suggestions concerning the Macintosh display and interface should also be directed to Alex MacAulay (macaulay@mundil.cs.mu.oz.au).
The portable MARS project was initiated after discussing the ICWS'94 draft on the rec.games.corewar newsgroup. We realized that we needed a portable system to try out the proposed standard and to accept, modify or reject it. The people who started portable MARS and are responsible for the base code as well as the DOS and UNIX displays are:
Albert Ma (ama@athena.mit.edu) Nandor Sieben (nandor.sieben@asu.edu) Stefan Strack (stst@vuse.vanderbilt.edu) Mintardjo Wangsaw (wangsawm@csos.orst.edu)
Alex MacAulay (macaulay@mundil.cs.mu.oz.au) wrote the Macintosh display version. Martin Maierhofer (m.maierhofer@ieee.org) contributed the linux SVGA and X windows display. Nathan Summers (00ncsummers@bsuvc.bsu.edu) did the port to VMS.
We thank Planar (Damien.Doligez@inria.fr) for expert help with debugging and porting pMARS to different UNIX machines. We also appreciate the help of Chris Lindensmith (lind0014@student.tc.umn.edu) and Pierre Baillargeon (dak@info.polymtl.ca) with the initial Mac and Amiga ports respectively. Mark Durham (durham@ricevm.rice.edu) spearheaded development of the ICWS'94 draft and we thank him for writing the sample interpreter code included with the draft.
pMARSv is a DOS version of pMARS with a graphical core display. You can chose between EGA/VGA graphics or text mode with the -v command line options or by pressing 'v' during the game. The -v option takes a three digit argument 'xyz'. Digit 'x' specifies the initial display speed and ranges from 0 (fastest) to 7 (slowest). 'y' is the initial display mode: 0 for text mode, 1 for standard VGA graphics, 2 and 3 for SVGA, 4 and 5 for EGA, and 6 for CGA graphics.
The display level 'z' specifies how much is displayed:
The more is displayed, the slower runs the simulation. The argument for -v defaults to 103, i.e. speed=1, mode=text, level=3.
The text mode display is very fast, but contains less on-screen information than the graphics display. The core display and the cdb debugger run full-screen on separate display pages.
In graphics mode, core and debugger share the same screen. The mouse can be used to navigate around core when debugging is enabled: clicking a mouse button on any core location lists addresses starting there. The mouse cursor follows the current program counter when in single step mode.
In both graphics and text mode, the cdb display can be divided into two side-by-side panels. You can switch between panels with the switch command (or the <Tab> macro) and close the right panel with close (or the <Shft-Tab> macro). Extended (function keys, arrow/page keys, ALT keys, etc.) and control keys generate macro calls at the cdb prompt; some of these "hot key macros" have been defined in "pmars.mac"; you can easily change them or add more with a text editor. E.g. <PgDn> and <PgUp> keys currently invoke macros that scroll through core one screen at a time.
A white line at the top of the display, called the time meter, indicates the time required to finish the current simulation. The amount of time depends on the number of warriors still alive in the arena. After a warrior dies it no longer needs simulation time so the required time to finish the simulation becomes less. On the time meter this is indicated by a discontinuity. One can count the number of dead warriors in the arena by counting the number of discontinuities on the time meter.
Just below, the length of "process meters" in the color of the warriors they represent show how many processes each warrior has running.
The following keys are available at the core display screen:
You can define additional keys and commands associated with them by defining "key-x" macros ("x" is any printable character). E.g.:
key-p= progress~registers~continueFunction-key and other macros can also be invoked from the core display.
The curses display is very similar to the DOS text mode display. There are separate pages for core and debugger. There is a status bar at the bottom of the core display:
Rave [0]: 1 Lucky 3 [1]: 3702 Cycle: 72967 R: 2/5 (0 0 1)
The display symbol that indicates execution is shown in brackets after the warrior name. The number after the colon shows the number of processes active. The "2/5 (0 0 1)" means that this is round 2 of 5; the result so far is one tie. Only cycle and round information is shown if more than two warriors are run.
There is no "hot key" user interface during the core display, but you can enter the debugger by hitting Ctrl-C and clearing the display, changing the display mode, etc. from within cdb. Only the first and third digit of the -v option and display command argument, namely the display speed and level, have an effect (see PMARSV above). The display speed setting (0=fastest, 7=slowest) adjusts the screen refresh rate; depending on the size of your display, movement in core may appear "jerky" at fast speeds. Control keys at the cdb prompt generate a macro call like in the DOS versions.
If you redirect standard input (by supplying a '-' filename or parameter file), all interactive input is disabled.
MacpMARS is a Macintosh version of pMARS with a graphical core display and standard Macintosh user interface. It has two windows, the Core window and Text window. The display of the core uses four patterns for each warrior (black and white backgrounds respectively) to show what is happening in the core:
´/' when the core location is written to (including incrementing and decrementing);
´\' when a process has died at the core location;
´-' when a process has executed at the core location;
´|' when a process is waiting to execute at the core location.
If you click on a core location in the Core window while a battle is being run, the contents will be displayed in the Text window.
Two warriors can be in memory at any one time. To assemble a warrior choose "Choose Warrior n..." from the File menu. To remove the warrior from memory choose "Remove Warrior n...". You can modify the settings used by choosing "Preferences..." (this can only be done when no battle is being run). Alternatively, you can type in a command line in the same way as if you were typing from a unix prompt (if you're used to that sort of thing) by choosing "Command Line...". The Edit menu is just the normal Macintosh Edit menu and can be used to cut and paste text in the Text window and dialogs. The items in the Play menu are fairly self-explanatory: "Go" starts (or continues) a battle; "Step" executes one instruction and enters the debugger; "Halt" halts the battle and enters the debugger; "Abort" aborts the battle. The Window menu is used to show and bring either of the two windows to the front of the screen.
The cdb commands display, switch and close are not available in MacpMARS.
Note: to use very large core sizes (up to about 65000) and process limits you may need to increase the memory partition for MacpMARS. To do this, choose "Get Info" from the File menu in the Finder and set the preferred memory size to about 1200K.
The following is mainly useful for people who write scripts or batch files for pMARS. Upon normal exit, the program returns 0. Below is a listing of what the abnormal exit codes mean. Your operating system may not support negative exit codes; in this case you have to convert the value to its unsigned counterpart.
The exit codes of the VMS version conform to the VMS standard. The -Q (Query) command line option (see OPTIONS) allows you to customize the pMARS exit code. E.g. "pmars -Q 1000" returns the current pMARS version. Below the -Q arguments and what the resulting exit codes mean.
-4 graphics error
-3 trying to execute 80386 code on a lesser processor
-2 memory allocation error
-1 serious program logic error, contact developers
1 file not found
2 command line error
3 assembly error
4 user aborted program
December 25, 2000 | PMARS v0.9.2 |