uxn/doc/uxn.md

8.3 KiB
Raw Blame History

UXN

Reformatted from the reference document

UXN is a deterministic, non-interrupting, 8-bit instruction set and word stack machine with a 16bi address space. It interacts with the outside world via port mapped I/O devices, of which 16 are supported.

Memory model

UXN presents a linear uniform main memory with a 16bi address space. Programs may do I/O across the entire address space using the LDR2 and STR2 instructions.

The UXN address space is divided into chunks called pages, each with 8bi of addressing. The 0 page (0x00[00-FF]) is special and, for convenience, can be accessed using the LDZ and STRZ instructions.

The UXN stack machine, in keeping with the forth tradition has two stacks. These are referred to as DATA (stack 0) and RETURN (stack 1) by convention. Instructions may choose to transpose the stacks, allowing for computation on either stack. See below for more on the return flag.

The LDR and STR instructions are stack relative and allow for computed loads and stores.

Instruction set

UXN instructions are 8-bit values.

k r 2 opcode
keep return short 0 0 0 0 0

The three most significant bits of the instructions are mode flags of which we will say more. The least significant five bits select an instruction.

Effects are written using forth-style notation inputs -- outputs

Opcode Memonic Long name Data stack effect Control stack effect PC effect Memory effect
0x00 BRK Break -- --
0x01 INC Increment a -- a+1
0x02 POP Pop a --
0x03 NIP Nip b a -- a
0x04 SWP Swap b a -- a b
0x05 ROT Rotate a b c -- b c a
0x06 DUP Duplicate a -- a a
0x07 OVR Over a b -- a b a
0x08 EQU Equal b a -- (a == b)
0x09 NEQ Not equal b a -- (a != b)
0x0A GTH Greater than b a -- (b > a)
0x0B LTH Less than b a -- (b < a)
0x0C JMP Jump a -- PC+=a
0x0D JCN Conditional jump b a -- PC+=(a if b else 1)
0x0E JSR Jump stash return (call) a -- -- pc PC+=a
0x0F STH Stash a -- -- a
0x10 LDZ Load zero page a: u8 -- MEM[a]
0x11 STZ Store zero page b a: u8 -- MEM[a] = b
0x12 LDR Load a: i8 -- MEM[DATA + a]
0x13 STR Store b a: i8 -- MEM[DATA + a] = b
0x14 LDA Load absolute a: i16 -- MEM[a]
0x15 STA Store absolute b a: i16 -- MEM[a] = b
0x16 DEI Device input a: u8 -- DEV[a]
0x17 DEO Device output b a: u8 -- DEV[a] = b
0x18 ADD Add b a -- a + b
0x19 SUB Subtract b a -- a - b
0x1A MUL Multiply b a -- a * b
0x1B DIV Divide b a -- a / b
0x1C AND And b a -- a && b
0x1D ORA Or b a -- a|b
0x1E EOR Exclusive or (xor) b a -- a^b
0x1F SFT Shift b a -- b >> (a & 0x0f) << ((a & 0xf0) >> 4)

Mode bits

Note that all these instructions are listed with keep=0,return=0,short=0.

The UXN documentation refers to ADD with keep=1 as ADDk. ADD with short=1 is ADD2, and with keep=1 would be ADD2k. POP with return=1 is POPr.

Conventionally these suffixes are formatted %/2?k?r?/ as required.

Short mode

In When the short bit is set, the opcode will pop two 8bi quantities from the stack where it would only consume one in byte mode. Each b a pair so popped is considered to be the unsigned 16bi quantity a + b<<8 For instance ADDs would be a b c d - (a<<8 + b) + (c<<8+d).

Exceptions:

  • The load/store operations move two 8bi values not one. STR becomes c b a -- MEM[DATA + a] = Relative address computation is unaffected.
  • The jump opcodes become absolute rather than computed relative jumps.

Keep mode

When the keep bit is set, no values are popped from the stack. For instance ADD2k would be a b c d -- a b c d e f.

Return mode

"return mode" flips the stacks.

If STH pops from data and pushes to return, STHr pops from return and pushes to data. Likewise if ADD pops from data and pushes to data, ADDr would pop from data and push to data.

JMP2 would load b a from the data stack and branch absolutely, JMP2r would do the same from the control stack. DUP2r would a b -- a b a b the return stack.

The bytecode sequence LIT 0x01 STH JSRr BRK would load 0x1 to the data stack, pop and stash it to the return stack, perform a relative jump by +1 while pushing PC to the data stack and halt.