Little Roomba Friends
roobma,
The Roomba VM
A roomba is equipped with:
- 16 punchcard slots containing up to 16 instructions each
- 4 registers, A, B, C, and D, plus a pseudo-register for the instruction pointer
- 4 ports for peripherals
- Automatic item vacuum and inventory
Roombas will automatically pick up any items they move over, and try to deposit all the items in their inventory into blocks they bump into.
Roombas also face a given direction, measured in degrees. 0 degrees is south (not north!), and positive degrees increase counter-clockwise.
Execution
A roomba's instruction pointer (IP) starts at card #0, index #0. At each execution step, it executes the command pointed
to by the IP and increments the IP. Once it reaches the end of a card, it goes back to the top of that card.
(To switch cards, use the CRD
opcode.)
Empty lines will be skipped during execution.
Registers
The roomba's four registers each can contain an integer value between -999 and 999. Each of the registers has a special purpose:
A
ccumulator is the most "general-purpose" register, and is used for arithmetic calculations.B
ackup is used as a second argument/destination for calculations and peripherals.C
onditional is used for conditional execution.D
evice is used as a primary argument for peripherals.
Attempting to store a value outside of -999 through 999 in a register will saturate at the bounds.
LDA 600
ADD 600
; A now contains 999, not 1200
Opcodes
There are 16 opcodes. Each opcode takes an argument and an optional conditional flag. The argument can be a literal
integer between -999 and 999, one of the four registers, or a label. The conditional flag can be +
, -
, or =
.
An opcode marked with the +
conditional flag will be skipped unless the C
register is greater than 0. Similarly,
the -
flag requires the C
register to be less than 0, and the =
flag requires it to be equal.
Labels
Labels can come before opcodes. They're simply any string followed by a colon, and can be used as arguments.
When compiling a program, labels used as arguments are syntactic sugar for integers; they represent the line they're
written on, or if they're on a line by themself, the next line with an opcode on it. This can help with writing JMP
instructions.
Comments
Any characters following a ;
character are comments, and are ignored.
So, an example program that moves the roomba across a 16x16 block rectangle:
LDA 16
LOOP:MOV 240 ; Sweep out a 2x15 rectangle
ROT 90
MOV 16
ROT 90
MOV 240
SUB 1
+ROT -90
+MOV 16
+ROT -90
+JMP LOOP
MOV 16
ROT 90
MOV 256
ROT 90
Opcode Reference
Here, the letter X
will refer to the argument of the opcode.
Opcodes are notated as their 3-letter representation in code, a mnemonic to remember the opcode by, and what it does.
Arithmetic
ADD
: AddX
to the value inA
, and store the result inA
.SUB
: SubtractX
from the value inA
, and store the result inA
MUL
: MultiplyX
and the value inA
, and store the result inA
.DVM
: Div Mod. Divide the value inA
byX
. Put the quotient inA
and the remainder inB
.
Jumping
JMP
: Jump to lineX
in the given card, so that lineX
will be the next line executed.JBY
: Jump By. Offset the instruction pointer by the given amount. Positive numbers will jump forward, negative numbers will jump backwards, and 0 will enter an infinite loop.
The IP will wrap at the boundaries, so executingJBY 10
at line 8 will move the IP to line 2.CRD
: Card. Move the instruction pointer to instruction 0 of the given card index.
Note that the IP automatically wraps around at the end of any given card, so there's no need to end cards withCRD <the current card index>
.
Also note that if the roomba tries to go to a card that doesn't exist, it will instead jump to card 0 (which must exist).CRJ
: Card Jump. Move the instruction pointer to the given card index, but keep the current line index. If aCRJ
instruction is executed on line 8, then the next instruction executed will be line 8 on whatever card it is.
Register Manipulation
LDA
: Load A. CopyX
intoA
.RLB
,RLC
,RLD
: Roll throughB
/C
/D
. CopyX
intoA
, then copy the old value ofA
intoB
,C
, orD
depending on the opcode. This can be used to implement both a "copy" operation and a "swap" operation.RLB A
will copy the value ofA
toB
, andRLB B
will exchange the values inA
andB
.
Roomba Manipulation
MOV
: Move the roomba forwardX
pixels, where 1 pixel is 1/16th of a block. Execution hangs until the roomba has moved that many pixels forward or bumped into a wall.ROT
: Rotate the roomba byX
degrees.ROT 90
makes the roomba face orthogonally right, andROT -90
makes the roomba face orthogonally left.PHL
: Peripheral. Interact with the peripheral in slotX
(0-indexed). Peripherals all do different things, but they usually do some kind of operation with theD
and/orA
registers.
Trying to interact with a peripheral slot that isn't inserted, or that is out of bounds, just does nothing.SLP
: Sleep for the given number of ticks, where 1 tick is 1/20 of a second. Execution hangs for that long, and the roomba will pick up at the next argument once it is through.