Difference between revisions of "VM instructions / opcodes"

From Final Fantasy XII Wiki
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.