summaryrefslogtreecommitdiff
path: root/spec/ability.fspec
blob: 5a695a01b8d71ad2e2884d493ac9cf6bb0bfdf3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
struct dat {
   struct asd {
      u16 index;
      u16 icon_id;
      u16 mp_cost;
      u16 unknown;
      u16 targets;
      u8 name[32] | encoding('sjis') str; // The encoding actually depends on ROM region
      u8 description[256] | encoding('sjis') str; // ^ Ditto, we can't express this (we need parser options)
      u8 padding[726] nul;
   } ability[until (false)];
};

// # Instructions
//
// Instructions are variable-length with minimum size of 16 bits and maximum size of 128 bits[1].
// They are encoded with the following schema `5:name 2:n (16 * 2^n - 7):modifiers`, where `name` specifies the
// instruction name and `n` specifies the total width of the instruction in bits with the formula `16 * 2^n`.
//
// Here's a table that shows how `n` maps to the instruction size:
// n | instruction size in bits
// 0 | 16
// 1 | 32
// 2 | 64
// 3 | 128
//
// In the list below the notation for instruction and its modifiers is `NAME<1:arg1, 1:arg2> [STACK1] (STACK2)`
// where `NAME` is the name of instruction, and inside the `<>` brackets are the modifiers for the instruction.
// The optional number before the modifier tells the modifier size in bits, if omitted rest of the bits are used.
// Inside `[]` brackets are the arguments that will be popped from the stack. `()` parenthesis are used instead,
// if the stack argument is optional.
//
// Reserved registers:
// r0: Always empty, used as NULL / empty data indicator
// r1: Field counter
//
// List of instructions:
// Name                 | Hex  | Description
// VERSION<version>     | 0x00 | Indicates the version of this bytecode.
// REG<len>             | 0x01 | Allocates a new register.
//                      *      * If `len` is not zero, the next `len` bytes will be stored in this register.
// PUSH<v>              | 0x02 | Pushes `v` to the stack.
// PUSHR<r?>            | 0x03 | Pushes the contents of register `r?` to the stack.
// POP<r?> [v]          | 0x04 | Pops `v` into register `r?`.
// INCR<r?>             | 0x05 | Increments the register `r?` by one.
// OP<op> [...]         | 0x06 | Performs operation specified by the `op`, and pushes the result to the stack.
// QUEUE<len> (...)     | 0x07 | Queues next `len` bytes for execution for the next `IO` instruction.
//                      *      * The code is executed before or after `IO` instruction, depending whether VM is packing or unpacking.
// IO<sz> (...)         | 0x08 | Unpacking: Reads data from external VM input (usually a file) to register pointed by `r1`.
//                      *      * Packing: Writes data to external VM output (usually a file) from register pointed by `r1`.
//                      *      * `sz` is the size of the element in bits.
//                      *      * Rest of the stack is the number of elements, if empty, the elements to read/write is 1.
// EXEC<r?> [r??] (...) | 0x09 | Sets `r1` to `r??` and executes instructions stored in register `r?`.
//                      *      * Rest of the stack is the number of times to execute, if empty, execution happens only once.
//                      *      * `r1` will be saved and restored during this instruction.
// CALL<r?> (...)       | 0x0A | Calls a function. The name of the function is stored in register `r?`.
// JMP<off>             | 0x0B | Jumps to the `off` (in bytes).
// JMPIF<off> [v]       | 0x0C | Performs `JMP`, if `v` is true.
// STRUCT<r?> [r??]     | 0x0D | Describes register `r?` as struct structure. register `r??` contains the name of the struct.
// SELECT<r?>           | 0x0E | Describes register `r?` as select structure.
// FIELD<r?> (...)      | 0x0F | Links field to last structure. register `r?` contains the name of the field.
//                      *      * Rest of the stack contains register indices for registers that are instances of this field.
// BSZ<s:1, v> [sz]     | 0x10 | Describes last field as a primitive field. `s` describes whether the field is signed. `v` describes how the
//                      *      * field should be represented. `sz` contains the size of field in bits.
// REF<r?>              | 0x11 | Describes field as a substructure. register `r?` contains the structure definition.
// FDIMENSION<sz>       | 0x12 | Adds fixed dimension to a field. `sz` indicates the size of the dimension.
// VDIMENSION           | 0x13 | Adds variable length dimension to a field.
// ENUM<r?>             | 0x14 | Links field to a enum
//
// List of operations for the `OP` instruction:
// Name      | Hex  | Argc | Description
// UNM       | 0x00 | 1    | Unary minus operation `-v1`.
// LNOT      | 0x01 | 1    | Logical not operation `!v1`.
// BNOT      | 0x02 | 1    | Bitwise not operation `~v1`.
// MUL       | 0x03 | 2    | Multiplication operation `v1 * v2`.
// DIV       | 0x04 | 2    | Division operation `v1 * v2`.
// MOD       | 0x05 | 2    | Modulo operation `v1 % v2`.
// ADD       | 0x06 | 2    | Addition operation `v1 + v2`.
// SUB       | 0x07 | 2    | Substraction operation `v1 - v2`.
// SHIFTL    | 0x08 | 2    | Left shift operation `v1 << v2`.
// SHIFTR    | 0x09 | 2    | Right shift operation `v1 >> v2`.
// LESS      | 0x0A | 2    | Less than operation `v1 < v2`.
// LESSEQ    | 0x0B | 2    | Less or equal operation `v1 <= v2`.
// EQ        | 0x0C | 2    | Equal operation `v1 == v2`.
// NOTEQ     | 0x0D | 2    | Not equal operation `v1 != v2`.
// BAND      | 0x0E | 2    | Bitwise and operation `v1 & v2`.
// BOR       | 0x0F | 2    | Bitwise or operation `v1 | v2`.
// BXOR      | 0x10 | 2    | Bitwise xor operation `v1 ^ v2`.
// LAND      | 0x11 | 2    | Logical and operation `v1 && v2`.
// LOR       | 0x12 | 2    | Logical or operation `v1 || v2`.
// CTERNARY  | 0x13 | 3    | Conditional ternary operation `v1 ? v2 : v3`
// SUBSCRIPT | 0x14 | 2    | Subscript operation `v1[v2]`
//
// List of visuals for the `PIO` instruction:
// Name | Hex  | Representation
// NUL  | 0x00 | None
// DEC  | 0x01 | Decimal
// HEX  | 0x02 | Hexdecimal
// STR  | 0x03 | String
// FLT  | 0x04 | Float