Difference between revisions of "VM instructions / opcodes"
Jump to navigation
Jump to search
Line 562: | Line 562: | ||
|Pushes integer from integer table onto stack | |Pushes integer from integer table onto stack | ||
|- | |- | ||
− | |PUSHII | + | |[[PUSHII (instruction)|PUSHII]] |
|0x4f | |0x4f | ||
|3 | |3 |
Revision as of 07:56, 17 July 2019
Final Fantasy XII VM supports 100 known opcodes. There are three types of instructions. Instructions with an immediate, which are 3 bytes long, instructions without immediate, which are 1 byte long and special instructions like NOP and LABEL that have a defined size of zero and thus can't be used, because it causes the VM to loop indefinitely. These are probably used only by compiler and never put in the code itself.
Name | Opcode | Size | Immediate | Arguments | Description |
---|---|---|---|---|---|
NOP | 0x00 | 0 | no | 0 | Don't use. It causes eternal loop |
LABEL | 0x01 | 0 | no | 0 | Don't use. It causes eternal loop |
TAG | 0x02 | 0 | no | 0 | Don't use. It causes eternal loop |
SYSHALT | 0x03 | 1 | no | 0 | |
SYSTEM | 0x04 | 1 | no | 1 | |
OPLOR | 0x05 | 1 | no | 2 | Logical or |
OPLAND | 0x06 | 1 | no | 2 | Logical and |
OPOR | 0x07 | 1 | no | 2 | Binary or |
OPEOR | 0x08 | 1 | no | 2 | Binary exclusive or |
OPAND | 0x09 | 1 | no | 2 | Binary and |
OPEQ | 0x0a | 1 | no | 2 | Compares whether two values on stack are equal |
OPNE | 0x0b | 1 | no | 2 | Compares whether two values on stack are not equal |
OPGT | 0x0c | 1 | no | 2 | Compares whether second value on stack is greater than first |
OPLS | 0x0d | 1 | no | 2 | Compares whether second value on stack is less than first |
OPGTE | 0x0e | 1 | no | 2 | Compares whether second value on stack is greater or equal to first |
OPLSE | 0x0f | 1 | no | 2 | Compares whether second value on stack is less or equal to first |
OPSLL | 0x10 | 1 | no | 2 | Shift left logical |
OPSRL | 0x11 | 1 | no | 2 | Shift right logical |
OPADD | 0x12 | 1 | no | 2 | Addition |
OPSUB | 0x13 | 1 | no | 2 | Substraction |
OPMUL | 0x14 | 1 | no | 2 | Multiplication |
OPDIV | 0x15 | 1 | no | 2 | Division |
OPMOD | 0x16 | 1 | no | 2 | Modulo |
OPNOT | 0x17 | 1 | no | 1 | Logical negation |
OPBNOT | 0x18 | 1 | no | 1 | Binary negation |
OPUMINUS | 0x19 | 1 | no | 1 | Not used |
OPFIXADRS | 0x1a | 1 | no | 1 | Not used |
PUSHA | 0x1b | 1 | no | 0 | Pushes contents of A register to stack |
POPA | 0x1c | 1 | no | 0 | Pops stack into A register |
PUSHX | 0x1d | 1 | no | 0 | Pushes contents of X register to stack |
PUSHY | 0x1e | 1 | no | 0 | Pushes contents of Y register to stack |
POPX | 0x1f | 1 | no | 0 | Pops stack into X register |
POPY | 0x20 | 1 | no | 0 | Pops stack into Y register |
REQ | 0x21 | 1 | no | 3 | Queue script for execution |
FREQ | 0x22 | 1 | no | 3 | Not used |
TREQ | 0x23 | 1 | no | 3 | Not used |
REQSW | 0x24 | 1 | no | 3 | Queue script for asynchronous execution and wait for it to finish. |
FREQSW | 0x25 | 1 | no | 3 | Not used |
TREQSW | 0x26 | 1 | no | 3 | Not used |
REQEW | 0x27 | 1 | no | 3 | Queue script for synchronous execution and wait for it to finish. |
FREQEW | 0x28 | 1 | no | 3 | Not used |
TREQEW | 0x29 | 1 | no | 3 | Not used |
PREQ | 0x2a | 1 | no | 3 | Not used |
PREQSW | 0x2b | 1 | no | 3 | Not used |
PREQEW | 0x2c | 1 | no | 3 | Not used |
RET | 0x2d | 1 | no | 0 | End function and return |
RETN | 0x2e | 1 | no | 0 | |
RETT | 0x2f | 1 | no | 0 | |
RETTN | 0x30 | 1 | no | 0 | |
DRET | 0x31 | 1 | no | 0 | |
REQWAIT | 0x32 | 1 | no | 2 | Wait for a specified queued script to finish |
PREQWAIT | 0x33 | 1 | no | 2 | Not used |
REQCHG | 0x34 | 1 | no | 2 | |
REQCANCEL | 0x35 | 1 | no | 2 | Not used (see freqcancel) |
POPI0 | 0x36 | 1 | no | 0 | Pops stack into I0 register |
POPI1 | 0x37 | 1 | no | 0 | Pops stack into I1 register |
POPI2 | 0x38 | 1 | no | 0 | Pops stack into I2 register |
POPI3 | 0x39 | 1 | no | 0 | Pops stack into I3 register |
POPF0 | 0x3a | 1 | no | 0 | Pops stack into F0 register |
POPF1 | 0x3b | 1 | no | 0 | Pops stack into F1 register |
POPF2 | 0x3c | 1 | no | 0 | Pops stack into F2 register |
POPF3 | 0x3d | 1 | no | 0 | Pops stack into F3 register |
PUSHI0 | 0x3e | 1 | no | 0 | Pushes I0 register onto stack |
PUSHI1 | 0x3f | 1 | no | 0 | Pushes I1 register onto stack |
PUSHI2 | 0x40 | 1 | no | 0 | Pushes I2 register onto stack |
PUSHI3 | 0x41 | 1 | no | 0 | Pushes I3 register onto stack |
PUSHF0 | 0x42 | 1 | no | 0 | Pushes F0 register onto stack |
PUSHF1 | 0x43 | 1 | no | 0 | Pushes F1 register onto stack |
PUSHF2 | 0x44 | 1 | no | 0 | Pushes F2 register onto stack |
PUSHF3 | 0x45 | 1 | no | 0 | Pushes F3 register onto stack |
DVAR | 0x46 | 1 | no | 2 | Pops a variable from debug stack and puts on position specified as argument |
LONGCODESTART | 0x47 | 1 | no | 0 | Not used |
PUSHV | 0x48 | 3 | yes | 0+dimensions | Push variable value onto stack |
POPV | 0x49 | 3 | yes | 0+dimensions | Pops stack into variable |
PUSHDBG | 0x4a | 3 | yes | 0+dimensions | Pushes variable onto debug stack |
PUSHP | 0x4b | 3 | yes | 0+dimensions | Pushes pointer to a variable onto stack |
PUSHTAG | 0x4c | 2 | yes | 0+dimensions | Not used (pushes script number) |
PUSHACT | 0x4d | 3 | yes | 0+dimensions | Not used (pushes function number) |
PUSHI | 0x4e | 3 | yes | 0 | Pushes integer from integer table onto stack |
PUSHII | 0x4f | 3 | yes | 0 | Pushes signed 16bit integer immediate onto stack |
PUSHF | 0x50 | 3 | yes | 0 | Pushes float from float table onto stack |
JMP | 0x51 | 3 | yes | 0 | Unconditionally jumps to an offset specified by an index in script's jump table |
POPCMPYEQJMP | 0x52 | 3 | yes | 1 | Pops stack and jumps if equal to Y register |
POPCMPYLOWJMP | 0x53 | 3 | yes | 1 | Pops stack and jumps if less than Y register |
POPCMPYLOWEQJMP | 0x54 | 3 | yes | 1 | Pops stack and jumps if less or equal to Y register |
POPCMPYHIGHJMP | 0x55 | 3 | yes | 1 | Pops stack and jumps if greater than Y register |
POPCMPYHIGHEQJMP | 0x56 | 3 | yes | 1 | Pops stack and jumps if greater or equal to Y register |
POP2CMPYBTWNJMP | 0x57 | 3 | yes | 2 | Pops two values from stack and jumps if Y register's value is between (including) these values |
CALL | 0x58 | 3 | yes | 0+args | Calls external function (by specifying its number in VM's call table). Function's return value is left on stack. |
CALLACT | 0x59 | 3 | yes | 1+args | Calls external function (by specifying its number in VM's call table) in context of another script (pops its number from stack). Function's return value is left on stack. |
POPXJMP | 0x5a | 3 | yes | 1 | Pops stack into X register and jumps unconditionally |
POPXCJMP | 0x5b | 3 | yes | 1 | Pops stack into X register and jumps if true[1] |
POPXNCJMP | 0x5c | 3 | yes | 1 | Pops stack into X register and jumps if false[1] |
CALLPOPA | 0x5d | 3 | yes | 0+args | Calls external function (by specifying its number in VM's call table). Function's return value is popped into A register. |
CALLACTPOPA | 0x5e | 3 | yes | 1+args | Calls external function (by specifying its number in VM's call table) in context of another script (pops its number from stack). Function's return value is popped into A register. |
REQALL | 0x5f | 3 | yes | 0 | Queues all scripts within REQ table specified by an immediate for execution. |
JMPINTERNAL | 0x60 | 3 | yes | 0 | Not used (normal jumps cover entire script) |
REQWAITALL | 0x61 | 3 | yes | 0 | Waits for all scripts within REQ table specified by an immediate to finish. |
INCINITTAG | 0x62 | 3 | yes | 0 | |
REQIALL | 0x63 | 3 | yes | 0 | Waits for all scripts within REQ table specified by an immediate to finish. |