open-story-teller/docs/dev-firmware-micro-vm.md
2024-05-28 12:27:56 +02:00

6.3 KiB

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

name number type call-preserved
r0-r9 0-9 general-purpose N
t0-t9 10-19 temporary registers Y
pc 20 program counter Y
sp 21 stack pointer Y
ra 22 return address N

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

Instruction Encoding Arguments (bytes) Description Example
nop 0 0 Do nothing  
halt 1 0 Halt execution  
syscall 2 1 System call handled by user-registered function. Machine specific. Argument is the system call number, allowing up to 256 system calls.  syscall 42
lcons 3 4 Store an immediate value in a register. Can also store a variable address.  lcons r0, 0xA201d800, lcons r2, $DataInRam
mov 4 2 Copy a register in another one.  mov r0, r2
push 5 1 Push a register onto the stack.  push r0
pop 6 1 Pop the first element of the stack to a register.  pop r7
store 7 3 Copy a value from a register to a ram address located in a register with a specified size  store @r4, r1, 2 ; Copy R1 to address of R4, 2 bytes
load 8 3 Copy a value from a ram address located in a register to a register, with a specific size.  load r0, @r3, 1 ; 1 byte
add 9 2 sum and store in first reg.  add r0, r2
sub 10 2 subtract and store in first reg.   sub r0, r2
mul 11 2 multiply and store in first reg .  mul r0, r2
div 12 2 divide and store in first reg.  div r0, r2
shiftl 13 2 logical shift left.  shl r0, r1
shiftr 14 2 logical shift right.  shr r0, r1
ishiftr 15 2 arithmetic shift right (for signed values).  ishr r0, r1
and 16 2 and two registers and store result in the first one.  and r0, r1
or 17 2 or two registers and store result in the first one.  or r0, r1
xor 18 2 xor two registers and store result in the first one.  xor r0, r1
not 19 1 not a register and store result.   not r0
call 20 1 Set register RA to the next instruction and jump to subroutine, must be a label.  call .media
ret 21 0 return to the address of last callee (RA).  ret
jump 22 1 jump to address (can use label or address).  jump .my_label
jumpr 23 1 jump to address contained in a register.  jumpr t9
skipz 24 1 skip next instruction if zero.  skipz r0
skipnz 25 1 skip next instruction if not zero.  skipnz r2
eq 26 2 compare two registers for equality, result in first eq r4, r0, r1 ; equivalent to C code: r4 = (r0 == r1) ? 1 : 0
gt 27 2 compare if first register is greater than the second, result in first gt r4, r0, r1
lt 28 2 compare if first register is less than the second, result in first lt 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).

Event Bit
OK button 0
Previous button 1
Next button 2
Up button 3
Down button 4
Home button 5
Select button 6
Start button 7
Stop button 8
Pause button 9
End of audio 10

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:

Signal Number
reserved 0
Quit story 1

Assembler

Basic grammar

Example:

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

Global variables

Example:

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

Grammar:

Type First column Second column Third column Next columns
ROM constant label statring with dollar sign DC + base size (8, 16, 32) constatant value (integer or string, surrounded by double quotes) more values, separated by a coma
RAM variable label statring with dollar sign DV + base size (8, 16, 32) Size of the array (number of elements) -