VM instructions / opcodes
Jump to navigation
Jump to search
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 | |
FREQ | 0x22 | 1 | no | 3 | Not used |
TREQ | 0x23 | 1 | no | 3 | Not used |
REQSW | 0x24 | 1 | no | 3 | |
FREQSW | 0x25 | 1 | no | 3 | Not used |
TREQSW | 0x26 | 1 | no | 3 | Not used |
REQEW | 0x27 | 1 | no | 3 | |
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 | |
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 | |
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 | |
POPI1 | 0x37 | 1 | no | 0 | |
POPI2 | 0x38 | 1 | no | 0 | |
POPI3 | 0x39 | 1 | no | 0 | |
POPF0 | 0x3a | 1 | no | 0 | |
POPF1 | 0x3b | 1 | no | 0 | |
POPF2 | 0x3c | 1 | no | 0 | |
POPF3 | 0x3d | 1 | no | 0 | |
PUSHI0 | 0x3e | 1 | no | 0 | |
PUSHI1 | 0x3f | 1 | no | 0 | |
PUSHI2 | 0x40 | 1 | no | 0 | |
PUSHI3 | 0x41 | 1 | no | 0 | |
PUSHF0 | 0x42 | 1 | no | 0 | |
PUSHF1 | 0x43 | 1 | no | 0 | |
PUSHF2 | 0x44 | 1 | no | 0 | |
PUSHF3 | 0x45 | 1 | no | 0 | |
DVAR | 0x46 | 1 | no | 2 | |
LONGCODESTART | 0x47 | 1 | no | 0 | Not used |
PUSHV | 0x48 | 3 | yes | 0+dimensions | |
POPV | 0x49 | 3 | yes | 0+dimensions | |
PUSHDBG | 0x4a | 3 | yes | 0+dimensions | |
PUSHP | 0x4b | 3 | yes | 0+dimensions | |
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 | |
PUSHII | 0x4f | 3 | yes | 0 | |
PUSHF | 0x50 | 3 | yes | 0 | |
JMP | 0x51 | 3 | yes | 0 | |
POPCMPYEQJMP | 0x52 | 3 | yes | 1 | |
POPCMPYLOWJMP | 0x53 | 3 | yes | 1 | |
POPCMPYLOWEQJMP | 0x54 | 3 | yes | 1 | |
POPCMPYHIGHJMP | 0x55 | 3 | yes | 1 | |
POPCMPYHIGHEQJMP | 0x56 | 3 | yes | 1 | |
POP2CMPYBTWNJMP | 0x57 | 3 | yes | 2 | |
CALL | 0x58 | 3 | yes | 0+args | |
CALLACT | 0x59 | 3 | yes | 1+args | |
POPXJMP | 0x5a | 3 | yes | 1 | |
POPXCJMP | 0x5b | 3 | yes | 1 | |
POPXNCJMP | 0x5c | 3 | yes | 1 | |
CALLPOPA | 0x5d | 3 | yes | 0+args | |
CALLACTPOPA | 0x5e | 3 | yes | 1+args | |
REQALL | 0x5f | 3 | yes | 0 | |
JMPINTERNAL | 0x60 | 3 | yes | 0 | Not used (normal jumps cover entire script) |
REQWAITALL | 0x61 | 3 | yes | 0 | |
INCINITTAG | 0x62 | 3 | yes | 0 | |
REQIALL | 0x63 | 3 | yes | 0 |