mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
4.3 KiB
4.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 |
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 |
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) | - |