Skip to content

Micro VM

The stories created through the official Story Editor using graphical nodes are compiled into a binary executable. This binary is then interpreted by a micro virtual machine embedded in the OpenStory firmware.

Here is a description of that VM.

Registers

namenumbertypecall-preserved
r0-r90-9general-purposeN
t0-t910-19temporary registersY
pc20program counterY
sp21stack pointerY
ra22return addressN

Registers that are preserved means that the VM will store them on the stack before the call operation. Then, after the return (ret), theses registers are restored.

Registers that are not preserved must be saved manually (by writing code) by the user before using them.

Instructions

InstructionEncodingArguments (bytes)DescriptionExample
nop00Do nothing
halt10Halt execution
syscall21System call handled by user-registered function. Machine specific. Argument is the system call number, allowing up to 256 system calls.syscall 42
lcons34Store an immediate value in a register. Can also store a variable address.lcons r0, 0xA201d800, lcons r2, $DataInRam
mov42Copy a register in another one.mov r0, r2
push51Push a register onto the stack.push r0
pop61Pop the first element of the stack to a register.pop r7
store73Copy a value from a register to a ram address located in a register with a specified sizestore @r4, r1, 2 ; Copy R1 to address of R4, 2 bytes
load83Copy a value from a ram address located in a register to a register, with a specific size.load r0, @r3, 1 ; 1 byte
add92sum and store in first reg.add r0, r2
sub102subtract and store in first reg. sub r0, r2
mul112multiply and store in first reg .mul r0, r2
div122divide and store in first reg.div r0, r2
shiftl132logical shift left.shl r0, r1
shiftr142logical shift right.shr r0, r1
ishiftr152arithmetic shift right (for signed values).ishr r0, r1
and162and two registers and store result in the first one.and r0, r1
or172or two registers and store result in the first one.or r0, r1
xor182xor two registers and store result in the first one.xor r0, r1
not191not a register and store result. not r0
call201Set register RA to the next instruction and jump to subroutine, must be a label.call .media
ret210return to the address of last callee (RA).ret
jump221jump to address (can use label or address).jump .my_label
jumpr231jump to address contained in a register.jumpr t9
skipz241skip next instruction if zero.skipz r0
skipnz251skip next instruction if not zero.skipnz r2
eq262compare two registers for equality, result in firsteq r4, r0, r1 ; equivalent to C code: r4 = (r0 == r1) ? 1 : 0
gt272compare if first register is greater than the second, result in firstgt r4, r0, r1
lt282compare if first register is less than the second, result in firstlt r4, r0, r1

System calls

The story player machine supports the following system calls:

SYSCALL 1 (Play media)

This system call is used to play media. Use R0 and R1 to pass arguments:

  • R0 is for the image:

    • if zero, clear the screen
    • Otherwise pass the address in ROM or RAM where is stored the image filename
  • R1 is for the sound:

    • if zero, do not play anything
    • Otherwise pass the address in ROM or RAM where is stored the sound filename

The file must be stored in the /assets subdirectory of the current story.

The syscall do not blocks. User must wait for end of sound event if necessary.

SYSCALL 2 (wait event)

This system call is used to wait for machine events. Use R0 to mask events to wait for (events not selected are ignored).

EventBit
OK button0
Previous button1
Next button2
Up button3
Down button4
Home button5
Select button6
Start button7
Stop button8
Pause button9
End of audio10

Example:

    mov r0, 0b1000
    syscall 2

SYSCALL 3 (Send signal)

Send a specific signal event to the machine. Use R0 register to pass the signal argument.

    mov r0, 42
    syscall 3

Supported signals:

SignalNumber
reserved0
Quit story1

Assembler

Basic grammar

Example:

asm
; ---------------------------- Base node Type: Transition
.mediaEntry0004:
    lcons r0, $fairy
    lcons r1, $la_fee_luminelle
    syscall 1
    lcons r0, .mediaEntry0006
    ret

Global variables

Example:

asm
$yourLabel  DC8 "a string", 5, 4, 8  ; Déclaration de constantes
$MaVar      DV32    14      ; Variable en RAM : 14 emplacements de taille 32-bits

Grammar:

TypeFirst columnSecond columnThird columnNext columns
ROM constantlabel statring with dollar signDC + base size (8, 16, 32)constatant value (integer or string, surrounded by double quotes)more values, separated by a coma
RAM variablelabel statring with dollar signDV + base size (8, 16, 32)Size of the array (number of elements)-

Source code under the MIT License, art under the CC0 License.