Each robot contains a virtual CPU that runs a program fed to it when the game is started. Each robot has its own memory and cannot touch or in any way affect the execution of the other robots programs.
The CPU has, somewhat similar to the computers of the late 70's, separate memories for program and data. There are no instructions to manipulate the program memory, therefore it is impossible to create self-modifying code.
There are no registers or status flags like the ones found in most real CPU's. Instead, every instruction has zero, one or two extension words that can be used in different ways. What these extension words are used for is determined by bits in the instruction word. Usually, however, you can use all the features of the language without having to think about the internal representation of the instructions.
There are four addessing modes, these are: immediate number, immediate symbol, dereferenced symbol and indirect symbol.
The immediate number addressing mode is the simplest. Whatever number you write in the code is the one used in the instruction. Example:
move 10,xyz
The immediate number here is the 10. This instruction results in
the value 10 being stored in the memory location pointed to by
the value of the symbol xyz
.
The immediate symbol addressing mode is similar to the immediate number. The number used is the value of a specified symbol. In the code, the symbol is preceeded by a %-sign. Example:
move %xx,yy
The immediate symbol is the %xx. This instruction stores the
value of the symbol xx
into the memory location
pointed to by yy
.
The dereferenced symbol addressing mode takes the value of the symbol and uses the value stored at that address in memory. Example:
move xx,yy
This instruction stores the contents of the memory location
pointed to by xx
in the memory location pointed to
by yy
.
The indirect symbol addressing mode takes the value of the symbol, looks up that address in memory and uses that value for another lookup in memory, that value is the one used in the operation. Example:
move &xx,yy
The indirect symbol here is &xx. This instruction does an
indirect lookup of xx
and stores the resulting
value in the memory location pointed to by yy
.
With all of the above addessing modes except immediate number, you can specify an offset that will be added to the symbol value during assembly. The offset is specified using a / followed by a number. Here is an example:
move xx/2,yy
This will look up the value stored in the memory location
pointed to by the symbol value of xx
plus 2 and
store it in the memory location pointed to by yy
.
There is no
difference between arrays and normal auto-allocated
variables. If you do not use the array
keyword to
specify the number of words of memory the symbol value will
point to, the size will be 1.
The format for the $array
keyword is:
$array symbol : size [ init-list ]
This will cause symbol to point to size number of words initialized with the contents of init-list, which is a comma separated list of integers.
If you specify an init-list then the size is optional, it will default to the number of elements in the init-list. You may not specify a size that is less than the number of elements in the init list. If you do not specify an init-list then the size parameter is mandatory.
A callback is a kind of interrupt. You set up a callback handler for a certain callback. A callback handler is set up as follows:
callback id,handler
After this command, when event id occurs, the CPU will
enter callback mode and jump to the location specified by
handler. While the CPU is in callback mode all
callbacks will be deferred until the program exists callback
mode by using the command rtc
, this command will
also return to wherever it was before the callback was called.
The handler for the callback can be removed by specifying the number -1 as the handler.
Some callbacks need to send some information to the callback
handler. This information is called the callback data
and is placed in a special location that is accessed using the
command getcb
. The format for this command is as
follows:
getcb location,destination
This instruction takes the contents of callback data location location and places it in the memory location pointed to by destination.
The assembler supports expressions wherever an integer is expected. Expressions are entered inside parentheses. For example:
move (10+2*40),var
This is the same as: move 90,var
.
Keep in mind that the unary operator -, is part of an expression, not a number. This means that if you want to enter a negative number you have to enclose it within parentheses.
The assembler allows you to define mnemonics to be used in place of an expression. The format for a define is as follows:
$define symbol = value
This will set symbol to be equal to value. After this, the symbol can be used in place of the value in any expression.
Runtime errors are errors that prevent further execution of the program, such as: jump to a location outside program memory, trying to pop a value off the user stack when there are no elements on it or specifying an illegal value for a callback id.
Whenever a runtime error occurs the CPU does the following things:
This will effectively restart the program with one important difference: the memory contents are not restored. If the program relies on certain memory contents when started, it might not be properly restarted after a runtime error.