Uxntal Modes

Each opcode has 3 possible modes, which can combined:

011 00001

By default, operators consume bytes from the working stack, notice how in the following example only the last two bytes #45 and #67 are added, even if there are two shorts on the stack.

#1234 #4567 ADD12 34 ac

The short mode consumes two bytes from the stack. In the case of jump opcodes, the short-mode operation jumps to an absolute address in memory. For the memory accessing opcodes, the short mode operation indicates the size of the data to read and write.

#1234 #4567 ADD2 57 9b

The keep mode does not consume items from the stack, and pushes the result on top. The following example adds the two shorts together, but does not consume them. Under the hood, the keep mode keeps a temporary stack pointer that is decremented on POP.

#1234 #4567 ADD2k 12 34 45 67 57 9b

The return mode makes it possible for any opcode to operate on the return-stack directly. For that reason, there is no dedicated return opcode. For example, the JSR opcode pushes the program's address onto the return stack before jumping, to return to that address, the JMP2r opcode is used, where instead of using the address on the working-stack, it takes its address from the return-stack.

LITr 12 #34 STH ADDr STHr 46

To better understand how the opcode modes are used, here is a 22 bytes long implementation of the function to generate numbers in the Fibonacci sequence. Notice how only a single literal is created to perform the operation.

@fib ( num -- numfib* )
	#0001 GTH2k ?&ok
		POP2 JMP2r &ok
	SUB2k fib STH2 INC2
	SUB2 fib STH2r

Incoming: uxn devlog