Difference between revisions of "VM instructions / opcodes"
Jump to navigation
Jump to search
Line 245: | Line 245: | ||
|no | |no | ||
|3 | |3 | ||
− | | | + | |Queue script for execution |
|- | |- | ||
|FREQ | |FREQ | ||
Line 266: | Line 266: | ||
|no | |no | ||
|3 | |3 | ||
− | | | + | |Queue script for asynchronous execution and wait for it to finish. |
|- | |- | ||
|FREQSW | |FREQSW | ||
Line 287: | Line 287: | ||
|no | |no | ||
|3 | |3 | ||
− | | | + | |Queue script for synchronous execution and wait for it to finish. |
|- | |- | ||
|FREQEW | |FREQEW | ||
Line 329: | Line 329: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |End function and return |
|- | |- | ||
|RETN | |RETN | ||
Line 364: | Line 364: | ||
|no | |no | ||
|2 | |2 | ||
− | | | + | |Wait for a specified queued script to finish |
|- | |- | ||
|PREQWAIT | |PREQWAIT | ||
Line 392: | Line 392: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into I0 register |
|- | |- | ||
|POPI1 | |POPI1 | ||
Line 399: | Line 399: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into I1 register |
|- | |- | ||
|POPI2 | |POPI2 | ||
Line 406: | Line 406: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into I2 register |
|- | |- | ||
|POPI3 | |POPI3 | ||
Line 413: | Line 413: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into I3 register |
|- | |- | ||
|POPF0 | |POPF0 | ||
Line 420: | Line 420: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into F0 register |
|- | |- | ||
|POPF1 | |POPF1 | ||
Line 427: | Line 427: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into F1 register |
|- | |- | ||
|POPF2 | |POPF2 | ||
Line 434: | Line 434: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into F2 register |
|- | |- | ||
|POPF3 | |POPF3 | ||
Line 441: | Line 441: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pops stack into F3 register |
|- | |- | ||
|PUSHI0 | |PUSHI0 | ||
Line 448: | Line 448: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes I0 register onto stack |
|- | |- | ||
|PUSHI1 | |PUSHI1 | ||
Line 455: | Line 455: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes I1 register onto stack |
|- | |- | ||
|PUSHI2 | |PUSHI2 | ||
Line 462: | Line 462: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes I2 register onto stack |
|- | |- | ||
|PUSHI3 | |PUSHI3 | ||
Line 469: | Line 469: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes I3 register onto stack |
|- | |- | ||
|PUSHF0 | |PUSHF0 | ||
Line 476: | Line 476: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes F0 register onto stack |
|- | |- | ||
|PUSHF1 | |PUSHF1 | ||
Line 483: | Line 483: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes F1 register onto stack |
|- | |- | ||
|PUSHF2 | |PUSHF2 | ||
Line 490: | Line 490: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes F2 register onto stack |
|- | |- | ||
|PUSHF3 | |PUSHF3 | ||
Line 497: | Line 497: | ||
|no | |no | ||
|0 | |0 | ||
− | | | + | |Pushes F3 register onto stack |
|- | |- | ||
|DVAR | |DVAR | ||
Line 504: | Line 504: | ||
|no | |no | ||
|2 | |2 | ||
− | | | + | |Pops a variable from debug stack and puts on position specified as argument |
|- | |- | ||
|LONGCODESTART | |LONGCODESTART | ||
Line 518: | Line 518: | ||
|yes | |yes | ||
|0+[[Arrays|dimensions]] | |0+[[Arrays|dimensions]] | ||
− | | | + | |Push variable value onto stack |
|- | |- | ||
|POPV | |POPV | ||
Line 525: | Line 525: | ||
|yes | |yes | ||
|0+[[Arrays|dimensions]] | |0+[[Arrays|dimensions]] | ||
− | | | + | |Pops stack into variable |
|- | |- | ||
|PUSHDBG | |PUSHDBG | ||
Line 532: | Line 532: | ||
|yes | |yes | ||
|0+[[Arrays|dimensions]] | |0+[[Arrays|dimensions]] | ||
− | | | + | |Pushes variable onto debug stack |
|- | |- | ||
|PUSHP | |PUSHP | ||
Line 539: | Line 539: | ||
|yes | |yes | ||
|0+[[Arrays|dimensions]] | |0+[[Arrays|dimensions]] | ||
− | | | + | |Pushes [[General Vritual Machine architecture#Pointers|pointer]] to a variable onto stack |
|- | |- | ||
|PUSHTAG | |PUSHTAG | ||
Line 560: | Line 560: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Pushes integer from integer table onto stack |
|- | |- | ||
|PUSHII | |PUSHII | ||
Line 567: | Line 567: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Pushes signed 16bit integer immediate onto stack |
|- | |- | ||
|PUSHF | |PUSHF | ||
Line 574: | Line 574: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Pushes float from float table onto stack |
|- | |- | ||
|JMP | |JMP | ||
Line 581: | Line 581: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Unconditionally jumps to an offset specified by an index in script's jump table |
|- | |- | ||
|POPCMPYEQJMP | |POPCMPYEQJMP | ||
Line 588: | Line 588: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack and jumps if equal to Y register |
|- | |- | ||
|POPCMPYLOWJMP | |POPCMPYLOWJMP | ||
Line 595: | Line 595: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack and jumps if less than Y register |
|- | |- | ||
|POPCMPYLOWEQJMP | |POPCMPYLOWEQJMP | ||
Line 602: | Line 602: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack and jumps if less or equal to Y register |
|- | |- | ||
|POPCMPYHIGHJMP | |POPCMPYHIGHJMP | ||
Line 609: | Line 609: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack and jumps if greater than Y register |
|- | |- | ||
|POPCMPYHIGHEQJMP | |POPCMPYHIGHEQJMP | ||
Line 616: | Line 616: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack and jumps if greater or equal to Y register |
|- | |- | ||
|POP2CMPYBTWNJMP | |POP2CMPYBTWNJMP | ||
Line 623: | Line 623: | ||
|yes | |yes | ||
|2 | |2 | ||
− | | | + | |Pops two values from stack and jumps if Y register's value is between (including) these values |
|- | |- | ||
|CALL | |CALL | ||
Line 630: | Line 630: | ||
|yes | |yes | ||
|0+[[Call arguments|args]] | |0+[[Call arguments|args]] | ||
− | | | + | |Calls external function (by specifying its number in VM's call table). Function's return value is left on stack. |
|- | |- | ||
|CALLACT | |CALLACT | ||
Line 637: | Line 637: | ||
|yes | |yes | ||
|1+args | |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 | |POPXJMP | ||
Line 644: | Line 644: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack into X register and jumps unconditionally |
|- | |- | ||
|POPXCJMP | |POPXCJMP | ||
Line 651: | Line 651: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack into X register and jumps if true |
|- | |- | ||
|POPXNCJMP | |POPXNCJMP | ||
Line 658: | Line 658: | ||
|yes | |yes | ||
|1 | |1 | ||
− | | | + | |Pops stack into X register and jumps if false |
|- | |- | ||
|CALLPOPA | |CALLPOPA | ||
Line 665: | Line 665: | ||
|yes | |yes | ||
|0+args | |0+args | ||
− | | | + | |Calls external function (by specifying its number in VM's call table). Function's return value is popped into A register. |
|- | |- | ||
|CALLACTPOPA | |CALLACTPOPA | ||
Line 672: | Line 672: | ||
|yes | |yes | ||
|1+args | |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 | |REQALL | ||
Line 679: | Line 679: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Queues all scripts within REQ table specified by an immediate for execution. |
|- | |- | ||
|JMPINTERNAL | |JMPINTERNAL | ||
Line 693: | Line 693: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Waits for all scripts within REQ table specified by an immediate to finish. |
|- | |- | ||
|INCINITTAG | |INCINITTAG | ||
Line 707: | Line 707: | ||
|yes | |yes | ||
|0 | |0 | ||
− | | | + | |Waits for all scripts within REQ table specified by an immediate to finish. |
|} | |} | ||
[[Category:Instructions]] | [[Category:Instructions]] | ||
[[Category:VM]] | [[Category:VM]] | ||
[[Category:General]] | [[Category:General]] |
Revision as of 12:34, 16 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 |
POPXNCJMP | 0x5c | 3 | yes | 1 | Pops stack into X register and jumps if false |
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. |