At 06:43 PM 1/18/99 +0000, you wrote:
> <byte> signed 8-bit value
> <word> signed 16-bit value, LSB-first
Add that signed numbers are stored in two's complement format.
> The machine has two stacks. One for calculations and parameter passing
> (a-stack) and one for storing return addresses for CALL instructions
> (c-stack).
Have you looked yet at the possibility of integrating the two stacks?
> The env status register array contains info on the direct environment
> of the robot. This status register array always reflects the current
> situation. The robot itself is placed at env[0][0]; env[-2][-2],
> env[-2][2], env[2][-2] and env[2][2] will always contain blank data
> (0 filled).
What about defining an "out of range" code? Every square out of scanner
range will have that property when scanned.
Advantages:
- you know what to return when for example env[3][3] is requested
- rules like "damaged robots will have reduced scanner range" can easily be
added later
> env[][].contents - (byte) 0 = empty
> 1 = robot
> 2 = energy supply
> env[][].data - (byte) When the contents field indicates a robot at
> this position, this field contains the ID of that
> robot. When the contents field indicates a power
> supply, this field contains the size of the supply.
After a robot drops energy, it's possible for a robot and an energy supply
to occupy the same square. Maybe it's better to make an env[][].robot,
which contains a robot ID if there is a robot, or -1 otherwise and an
env[][].energy which contains the amount of energy on the square (0 for none).
> The scan status register contains the information obtained via the SCAN
> instruction. The robot will have to perform a SCAN to fill these. The scan
> status register fields are updated just before the robot wakes up for the
> next turn so all information will then be up to date.
>
> scan.n_robots - (byte)
> scan.n_supplies - (byte)
Maybe it's better to report the amount of energy (sum) instead of the
number of supplies?
> Executing an action instruction (SCAN, MOVE etc) will decreae the value
> of the energy status register.
Typo: "decrease" (first line)
> I.e. after the exeuction of one of these instructions, the robots sends its
> public status register set and wait for its next turn.
Typo: "waits" (second line)
> [META: Apart from the instructions (mnemonics, actually), a byte code must
> be defined. A byte code is faster to interpret than plain ascii text]
Good point.
But a bit outdated since you already designed the byte code...
> The lower 2 bits of stacktop indicate in which direction the SCAN should be
> performed. Scanning reaches till the borders of the playing field.
I think the scanner should have limited range, although it should be a lot
larger than the range of the env variable.
> [META: Would it be more fun to define a scanner that only scans in a line?
> so: scanning e.g east would be defined as:
> . . . . . .
> . . . . . .
> . X + + + +
> . . . . . .
> . . . . . .
> ]
No, that would make the scanner too limited.
> Syntax: SKIP <flag>
> Opcode: %0001ifpz
>
> ...
>
> mask | name
> I F P Z |
> ----------------+-------
> 0 0 0 0 | - (not used - will never jump)
This is the "NOP" for the abstract robot machine!
(Don't say "not used", let people decide what they want to use and what not.)
...I just noticed that you mentioned using this as a NOP at the bottom of
the document.
> 1 0 0 0 | - (not used - will always jump)
This is a useful instruction: it allows you to jump over the next
instruction. Since a SKIP requires less bytes than a JUMP, the compiler can
use it to optimize the code.
What if you changed "negative/positive" into "sign/no sign (S/NS)"?
In that case, you could make "SKIP" mean "skip always" and "SKIP N" mean
"skip never (NOP)".
By the way, I really like the idea of "opcode made of truth table".
> Syntax: JP <address>
> Opcode: $20 ll hh
>
> where <address> = (hh AND $3F)*256+ll
I'm not sure whether the "AND $3F" is actually useful.
Maybe you should simply let the robot break down when the address is out of
range.
I even think that we should have the "robot EXE format" tell which part of
the RAM will be used for code and which part for data. Executing data or
reading/writing code should be illegal.
The reason for this is that it makes debugging much simpler. If the robot
bytecode interpreter reports "robot shut down: writing to code area at
$1420", you can easily spot the error in your program or compiler. However,
if the write is allowed, you will probably see the robot do very strange
things without having a clue what's wrong.
> Syntax: PSHB <byte>
> Opcode: $34 nn
>
> Syntax: PSHB (address>)
> Opcode: $35 ll hh
>
> where <address> = (hh AND $3F)*256+ll
>
> Pushes <byte> or the byte at <address> in memory on top of the a-stack
> as word. The byte is set as low-byte of the word, the hi-byte is filled
> using sign extension.
Maybe you can better describe it as "byte is fetched, then sign extended,
resulting word is pushed to the stack".
> [META: Now I've dropped the unsigned <byte> and <word>, sign extension
> makes more sense than 0 fill...]
I agree.
> Syntax: PSHE
> Opcode: $37
>
> Push a byte from the environment on top of the stack.
>
> [META: How do I define this?]
Suggestion:
Syntax: PSHE <index>
Opcode: $37 nn
where <index> = nn
Pops two words from the a-stack.
The topmost is called <y> and the other one <x>.
Depending on <index>, a byte specified by one of the following environment
items is pushed to the a-stack:
<index> = 0 env[<x>][<y>].contents
<index> = 1 env[<x>][<y>].data
<index> = 2 env[<x>][<y>].alive
<index> = 3 env[<x>][<y>].action
Other values for <index> will cause the machine to abort with an error.
Note: you also need an instruction to push the other status registers to
the a-stack. For example the scan registers.
>the result is pushed back on the a-stack.
With some operations you mention "the result is pushed back", with others
you don't. Since you mention the result being pushed back in the beginning
of the paragraph, I don't really care whether you mention it or not, as
long as it's consistent.
> The bitwise operations take the two topmost elements of the a-stack
> (or only the stack top, for NOT), perform the operation and push the
> result on the a-stack again.
>
> The Z flag will be set when the result is 0, P and F flag are reset.
Why reset the P and F flags? You could also leave them untouched.
> [META: Open questions till now:
> - What to do when an illegal instruction is met? Should I define
> interrupts for that? If so, what action will be taken?
I think the only appropriate action that can be taken is to abort the
running of the machine with an error message. The result would be that the
robot doesn't take any actions anymore (same as continuous PASS).
Maybe an instruction is needed: one that pops an address off the a-stack
and pushes back the word found in memory at that address. The current
instructions only allow reading of fixed addresses.
Ofcourse there would have to be a complementary write instruction: one that
pops two values: one address and one word.
To shevek: forget about ZIP files, this robots thing is much more fun!
Bye,
Maarten
****
MSX Mailinglist. To unsubscribe, send an email to [EMAIL PROTECTED] and put
in the body (not subject) "unsubscribe msx [EMAIL PROTECTED]" (without the
quotes :-) Problems? contact [EMAIL PROTECTED] (www.stack.nl/~wiebe/mailinglist/)
****