DragonFly On-Line Manual Pages
PMARS(6) DragonFly Games Manual PMARS(6)
NAME
pmars - portable corewar system with ICWS'94 extensions
SYNOPSIS
pmars [ option ... ] file1 [ file(s) ]
DESCRIPTION
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.
SCORE
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)
OPTIONS
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.
-r # This options sets the number of rounds to play. The default is
1. -r 0 produces assembly output (unless -b is specified), but
does not execute the warrior(s). A maximum of 32787 rounds can
be specified.
-s # The -s option specifies the size of core memory in number of
instructions. It defaults to 8000. Maximum core size is
platform-dependent, but usually at least 65535.
-c # -c sets the maximum number of cycles per round. A cycle
consists of one execution of each warrior. A round ends when
either a single warrior remains executing or when the maximum
number of cycles has elapsed.
-p # This option sets the maximum number of processes a warrior can
run. The default is 8000.
-l # This sets the maximum length of a warrior source file in
instructions. It defaults to 100 and can be up to 500.
-d # This option specifies the minimum distance between the first
instruction of each warrior. It cannot be smaller than the
maximum length (-l option) and defaults to 100 instructions.
-S # The -S option sets the size of the P-space to # cells. The
default is 1/16th of core size if core size is evenly divisible
by sixteen, or the next larger divisible fraction. See also the
P-SPACE section below.
-f The -f option instructs the loader to use a fixed series of
addresses for positioning warriors. This is done by initializing
the pseudo random number generator with a checksum value derived
from the source of all warriors. Thus, initial placements will
still be "random" from round to round, but will be the same if
the same warriors are run again. As a consequence, the result of
battles run with the -f option will show no statistical
fluctuations. This options is useful for validating ports of
pMARS to new platforms and for providing an absolute, albeit
arbitrary performance measure for warriors.
-F # This option server two purposes. It sets the seed value of the
pseudo random number generator, and also tells the loader to
install warrior 2 at the given address # for round 1. If the
number is larger than the core size minus the minimum warrior
distance, it will be wrapped around to the range of available
starting positions. This option is useful for testing different
versions of a warrior with constant initial placement. Warrior
1 is always installed at address 0. The -F and -f options are
mutually exclusive. If neither option is specified, the pseudo
random number generator is initialized with the system time.
-P This option makes pMARS use an alternative algorithm for
positioning warriors. This algorithm uses all possible
combinations of starting order and position in a random
sequence, and will not use the same combination twice unless all
the combinations have already been used. If the -r option is not
given, the number of rounds fought will be the number of all
possible combinations. Trying to use this option with more (or
less) than two warriors causes an error.
-e If this option is specified, the cdb debugger is entered
immediately after loading warriors into core.
-b This options runs pMARS in brief output mode. -b suppresses
warrior listings after assembly.
-k With the -k option, pMARS uses the same output format as the
KotH program. This option enables pMARS to work with scripts
written for the KotH server.
-8 This options enforces strict compliance with the ICWS'88
standard and disables all ICWS'94 language extensions, which are
flagged as syntax errors by the assembler. Since ICWS'94 is a
superset of ICWS'88, this options is not necessary to run
ICWS'88 warriors.
-o When this option is given, pMARS reports scores in decreasing
order rather than in the order warriors were named on the
command line. This is mostly useful for multi-warrior play.
-V The assembler generates verbose output with this option. This is
only useful for debugging.
-v This option sets the display mode for UNIX and DOS display
versions (see APPENDIX).
-@ <fn>
pMARS continues reading options and filenames from the parameter
file <fn>. If <fn> is a - (dash) standard input is parsed.
Comments in the parameter file start with a semicolon.
-= <string>
The = (equal) option allows you to specify a custom score
formula (see SCORE). The formula may contain the standard
arithmetic and logical operators (as in the C language), as well
as the parameters W (number of warriors participating) and S
(number of warriors surviving this round). You need to enclose
the formula string with quotes if it contains spaces or
characters interpreted by the operating system.
-Q # The "query" option is intended for use in scripts that run pMARS
in batch mode. Depending on the number code following -Q, the
program returns an informative number as the exit status.
"pmars -Q 1000" e.g. will cause pMARS to exit with a code that
spells out the program version. More on -Q arguments and exit
codes can be found in the ADDENDUM.
$ The $ (dollar) parameter is not preceded by a dash and cannot be
grouped with other options. It terminates reading command line
parameters and is used in parameter files or input streams (-@
fn). The $ is necessary if you want to combine two or more of
command line parameters, warrior code and cdb commands in the
same input stream or file. Below an example of such a combined
input file:
;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
X-WINDOWS OPTIONS
The X-Windows display version of pMARS has these additional command
line options:
-display <string>
Expects a string specifying the display where the window should
appear. Following X standards, this display specification has a
format of hostname.domain:display.screen where the part before
the colon is the standard internet host specification and
display and screen are integers. The screen specification can
be omitted. For an example, consider you are working at an X
terminal named ncd13.complang.tuwien.ac.at and remotely logged
in at host stud1.tuwien.ac.at where the binary of pmars lies,
you can use the following command line
stud1$ pmars -display ncd13.complang.tuwien.ac.at:0 -b aeka.red aeka.red
and the window will appear at you local screen.
-geometry <string>
Lets you specify the initial size and position of the window.
The format is widthxheight+x+y where width, height, x, y are
integers and + may be replaced by -. Either of the two parts
(widthxheight or +x+y) may be omitted. This overrides the -v
switch concerning the window geometry. As an example, pmars
-geometry 600x400+30+100 .... will open a window of 600 by 400
pixels at the screen position (30,100). pmars -geometry
1024x768 ... creates a window of 1024x768 pixels and pmars
-geometry -20+300 ... creates a window with standard size with
its left upper corner at position (-20,300), i.e. out of the
left side of the screen.
-fn <string>
The string following this argument specifies the X font to use.
By default, a terminal font is used. If this font can't be
found, "fixed" is used for a font ("fixed" should be present at
every X installation). Use the command 'xlsfonts' to get a
listing of fonts that can be used at your X server. 'xfontsel'
provides a comfortable way to select a font. "fixed" is the
fallback if the specified font can't be found. It is strongly
recommended to use a fixed pitch font.
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).
REDCODE
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> EQU <line1>
EQU <line2>
[...]
EQU <lineN>
<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.
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>
[..]
ROF
<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:
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
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
dest01 EQU 500
dest02 EQU 1000
dest03 EQU 1500
idx FOR 3
MOV src,dest&idx
MOV src+1,dest&idx
ROF
src MOV <-1,<-1
JMP src,<-2
Using 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:
FOR MAXLENGTH-CURLINE
DAT 1,1
ROF
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 CORESIZE == 8000
<some code>
ROF
FOR CORESIZE != 8000
<other code>
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.
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
CORESIZE EQU 55440 ;current value of -s parameter
MAXPROCESSES EQU 10000 ;current value of -p parameter
[etc.]
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.
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:
;assert CORESIZE == 55440 && MAXLENGTH >= 200
;assert !(CORESIZE % 4) ; is multiple of 4
;assert 1 ; if warrior works under all settings
The run-time variable VERSION holds the current pMARS version (e.g.
"60" is v0.6.0) and is useful in ;assert expressions.
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.
P-SPACE
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:
LDP (Load P-space) loads P-space cell specified by A-value into core
at B-address.
STP (Store P-space) stores A-value into P-space cell specified by B-
value.
It is important to note that P-space cells are refered 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:
PIN (P-space Identification Number) has a single numerical argument.
If two or more participating warriors have the same PIN
argument, they share the same P-space. If the PIN pseudo-opcode
is missing from a warrior's source, its P-space is strictly
private. The PIN argument is not normalized to [0..CORESIZE-1]
before comparison. "PIN 0" and "PIN CORESIZE" are therefore not
the same.
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 DEBUGGER
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.
<Enter>
repeats the last command issued at the cdb prompt.
help displays a brief command summary.
progress
displays the status of the current game in progress.
registers
displays the current state of the simulator, including program
counters and task queues.
go runs the simulator until an instruction whose trace bit is set
is executed. If there are no traced instructions go returns to
the post-mortem debugger.
step executes the next instruction in the task queue and returns to
the cdb prompt.
continue
returns to the simulator to complete the game without
interruptions.
thread is similar to step except that only the current task thread is
traced.
skip [count]
executes the next [count] instructions in the queue silently
before returning to the cdb prompt.
execute [address]
resets the task queue of the current warrior to [address] and
executes it. This is useful in conjunction with edit.
quit aborts pMARS and returns to the OS prompt.
trace [range]
sets the trace bit of the specified address or address range.
untrace [range]
clears the trace bit of the specified address or address range.
moveable on|off
specifies whether the trace bit is copied by the MOV.I
instruction. The default is on.
list [range]
displays the specified range of core addresses, a set trace bit
is indicated by 'T'. Unmodified addresses (DAT.F 0,0) are shown
as blank.
edit [range]
allows modifying core. The specified addresses are edited by
typing in new instructions. Typing one or more spaces leaves the
core address unchanged, just hitting <return> repeats the last
input, and a syntax error aborts the edit. The full Redcode
syntax including labels and (multi-line) EQUates can be used.
Label and EQUate definitions remain in effect until the program
terminates. The edit command is useful for modifying warriors
and trying out single instructions without having to exit and
restart pMARS.
fill [range]
is similar to edit. Instructions in the specified range are
replaced by one typed in instruction. Entering DAT.F 0,0 ,e.g.
clears the address range.
search [pattern]
searches core instructions for a text pattern in the forward
direction. The next instruction matching [pattern] is displayed.
The search includes the address number and trace symbol (T), is
case- and space-insensitive and may contain wildcards: *
(asteriks) matches any number of characters; ? (question mark)
matches exactly one character. E.g. "search ," searches for the
next non-blank address; "search dat*, ?0t" searches for the next
DAT instruction that is traced and has a zero B-operand value,
regardless of modifier, A-operand and B-mode.
write [file]
opens a file for logging subsequent cdb output to. The logfile
is closed by issuing write without an argument.
echo [string]
is used mostly inside macros. [string] is echoed to the screen
followed by <newline>.
remark [string]
is ignored by cdb and can therefore be used to comment macros.
cls clears the screen. The no-display UNIX version does this by
echoing an ANSI escape sequence; if this doesn't work for you,
you need to change the CLRSCR string in config.h and recompile.
clear is a synonym for cls .
display clear|on|off|nnn
(available in display versions only) allows clearing the core
display (display clear) or changing the display mode. display
on changes the display to the default mode, display off (same as
display 0 ) suspends all display updates, and display nnn ,
where nnn is a 1 to 3-digit number, sets the display to this
mode. "nnn" is interpreted like the parameter to the -v command
line option (see APPENDIX).
switch [1|2]
(available in display versions only) makes the left (1) or right
(2) panel the current panel for cdb output. Without a number
argument switch changes to the other panel. If the right panel
doesn't exist (initially, or after close, see below), it is
created first.
close (available in display versions only) closes the right cdb panel
(if it exists) and makes the left panel fullscreen.
calc expr1[,expr2]
is a command line calculator. Since calc has no side-effects
other than echoing the result of expression 1 (and expression 2
if provided). In the context of cdb macros it is also used to
assign values to the register variables 'c' through 'z'.
macro [name][,file]
loads, executes or lists macros. A macro expands to one line of
cdb commands separated by the tilde character (~) (a so-called
command chain, see below). The command macro name executes the
macro "name"; if "name" is left out, all currently available
macros are listed. macro name,file loads macro definitions from
file "file" and executes macro "name"; again, if "name" is
missing, only a listing is produced. Macro definitions are
appended to the list of previously loaded definitions or replace
a previously loaded macro definition with the same name. If you
are trying to execute or list macros, but no macros have been
loaded yet, the default macro file "pmars.mac" is loaded
automatically. The special macro file "user" can be specified to
input macro definitions directly from the keyboard. Macro
definitions consist of a macro name, followed by the equal sign,
followed by a command (chain). The macro name can consist of
any printable character excluding <space> and comma; the equal
sign is only allowed at the end of a macro name. Individual
macro lines have a limit of 80 characters, but macro calls
inside macro expansions are allowed. Cdb can hold up to 200
macros in memory. See also the section on cdb macro programming
below.
if <expression>
controls execution of commands in macros or command chains. If
<expression> evaluates to zero, the next command block is
skipped. A command block consists of either a single command or
any number of commands bracketed by !! (loop start) and ![e]
(loop end, see section on macro programming below).
<expression> may contain C-style comparison and boolean
operators (see below). An if immediately preceeding a loop end
(![e]) can skip out of the loop.
reset is used inside macros in conjunction with if to terminate macro
execution, e.g. inside an infinite loop (...~if
A==0~reset~...~!).
pqueue [1|2|..|off]
switches cdb into "process queue mode". In this mode, list, edit
and fill operate on the process queue instead of the core array,
i.e. you can view and modify the process queue as easily as the
core array. This is especially useful for debugging complicated
multi-process warriors. pqueue without argument uses the
process queue of the current warrior. With argument 1,2,.., uses
the process queue of warrior 1,2,.., respectively. pqueue off
returns to normal mode.
wqueue [off]
stands for "warrior queue" and is similar to pqueue, except that
numbers provided as arguments for list, edit and fill now refer
to warriors: "list 0" now shows the program counter of warrior
1, "list 1" that of warrior 2 and so on. wqueue off returns to
normal "address mode".
pspace [1|2|..|off]
complements the pqueue and wqueue commands. If a number is
specified, the P-space of that warrior is selected for
viewing/editing. Without an argument, the P-space of the
currently executing warrior is selected. "pspace off" returns to
core mode.
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>.
COMMAND CHAINS AND MACRO PROGRAMMING
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.
EXAMPLE CDB COMMANDS
list ,+20
lists the next 20 instructions.
trace pc-10,pc+10
traces 21 addresses centered around the program counter of the
currently executing warrior.
untrace 0,$
clears all trace bits.
go reg l+a,+b
chains these commands: execute until the next traced address or
end of round, display the simulator status and list addresses in
the range A-number to B-number of the current instruction.
@fill0,100 dat.f 0,0
fills addresses 0 through 100 with 'dat.f 0,0', not echoing the
changed addresses to the screen.
write trace.log step !
produces a continuous execution trace by repeating step until
pMARS terminates, saving the output to logfile "trace.log".
@l x=5 !! @ed x~dat x,0 if (x=x+1)<$+1 !
This command chain could be useful for debugging a stone-type,
self-modifying warrior, which is assumed to occupy address 0
through 4 in this example. The command fills core starting at
address 5 with "dat 5,0", "dat 6,0", a.s.o., so that you can
tell where a bomb which overwrites the warrior came from. To
save some typing, you can turn this command into a macro (foo=@l
x=5~..). This is how it works, step by step: Assign 5 to
register x and make it the current address (@l x=5). Start a
loop (!!) and change address x to "dat x,0" (@ed x~dat x,0).
Increment x, if x is then smaller than the core size ($+1),
continue looping (if (x=x+1)<$+1~!). The '@' in front of the
list and edit commands suppresses screen output.
@s @4 if b<2 || b>=$-3 reset !
This command executes a warrior until the B-field of address 4
points to address 0 through 5: Step and make address 4 the
current address (@s~@4). If the B-field is less than 2 or
greater than or equal to 7996 (CORESIZE-1-3) stop execution,
else continue looping (if b<2 || b>=$-3~reset~!).
SOURCE DEBUGGING DIRECTIVES
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.
;debug [static/off]
This command enables/disables all subsequent source-embedded
commands. It is used for commenting out other source comments.
;debug static has the same effect as the command moveable off at
the cdb command prompt. ;debug is implicitly added in front of
every warrior. The last ;debug or ;debug static encountered
specifies whether the trace bit is copied by a MOV.I instruction
or not.
;trace [off]
;trace starts setting the trace bit with the next instruction
until EOF or a ;trace off command is encountered.
;break sets the trace bit of the next instruction.
FUTURE DIRECTIONS
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
BUGS
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).
AUTHORS
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.
ACKNOWLEDGMENTS
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.
APPENDIX
PMARSV
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:
0 Display nothing. This greatly speeds up execution, especially
when in graphics mode.
1 Display execution of addresses. In text mode, a black '0' on
blue background is shown for warrior 1, a black '1' on green for
warrior 2, a.s.o.. Numbers blink in white when a DAT instruction
is executed. In graphics mode, a blue square represents warrior
1, a green square warrior 2, a.s.o.. These colors are also used
for other core accesses.
2 Also display write accesses. In text mode, they appear as dots;
in graphics mode, they appear as two pixels, offset diagonally.
3 Also display decrements and increments. They are shown as '+'
and '-' in text mode and as two pixels offset vertically or
horizontally in graphics mode.
4 Also display read accesses, which appear as small dots in text
mode and as single pixels in graphics mode.
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:
0..4 selects the display level (see above).
v switches from text display to graphics display and vice versa.
> increases the display speed.
< decreases the display speed. The current speed is indicated by a
red bar in graphics mode.
d enters the cdb debugger. "Debug" on the graphics menu bar is
highlighted in red inside cdb.
<space>
(also 'r') refreshes the core display.
<escape>
(also 'q') exits to DOS.
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~continue
Function-key and other macros can also be invoked from the core
display.
CURSES 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.
MACINTOSH DISPLAY
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.
EXIT CODES
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.
-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
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.
1..W exit code is score of this warrior, 1: first in result output,
2: second, a.s.o.. If the -o option is also given, "1" gives the
score of the highest scoring warrior, etc..
101..1W
returns the number of this warrior in the result output. Usually
-Q 101 returns 1, -Q 102 returns 2 etc., so this is not very
useful. If you also specify the "-o" (order results) option, -Q
101 returns the position of the highest scoring warrior on the
command line, -Q 110 the position of the 10th highest scoring
warrior, etc..
1000 exit code is the pMARS version in the same format as the
predefined VERSION variable.
1001 returns the pMARS "variant": 0 if the program was compiled with
the SERVER option (no debugger), 1 with debugger but without
display, 2 with debugger and core display.
1002 returns a combination of version and variant:
10*variant+version.
1003 the exit code is the core address size in bytes. On a 32-bit
CPU, this is sizeof(int), usually 4. With SMALLMEM compilation,
core address size is sizeof(unsigned short), usually 2.
2000 returns how many warriors share one or more P-spaces. A value of
4, e.g. means that either four warriors share one P-space, or
that two pairs of warriors share two P-spaces.
PMARS v0.9.2 December 25, 2000 PMARS(6)