.\" Manpage reference for uxntal. .\" by Eiríkr Åsheim .\" Contact d_m@plastic-idolatry.com to correct errors or typos. .TH uxntal 7 "05 Aug 2024" "1.0" "Uxntal Reference Guide" .SH NAME uxntal \- assembly langauge for Varvara virtual machine .SH DESCRIPTION Uxntal is an 8-bit instruction set for programming the Varvara virtual machine. It uses the lower 5-bits to specify an opcode, and the upper 3-bits to specify optional modes. ROMs consist of a 16-bit address space of bytes. Any byte can be interpreted as either data or an instruction. A 2-byte program counter (\fIpc\fP) determines the address of the next instruction to decode and run. Instructions manipulate data using two stacks: a working stack (\fBwst\fP) and a return stack (\fBrst\fP). Each stack consists of 256 bytes, and in the case of overflow or underflow the stack pointer will wrap (the stacks are circular). There are also 256 bytes of device memory, which are used to interact with the virtual machine and its devices. Instructions deal with unsigned 8-bit values (\fIbytes\fP) and unsigned 16-bit values (\fIshorts\fP). There are no other built-in data types. .SH INSTRUCTION LAYOUT 0x01 ---- 0x02 \\ 0x04 +- \fIopcode\fP 0x08 / 0x10 ---- 0x20 ---- 2: \fIshort mode\fP 0x40 ---- r: \fIreturn mode\fP 0x80 ---- k: \fIkeep mode\fP .SH OPCODE LAYOUT There are 32 base values for opcodes: 0x00 \fBBRK*\fP 0x08 \fBEQU\fP 0x10 \fBLDZ\fP 0x18 \fBADD\fP 0x01 \fBINC\fP 0x09 \fBNEQ\fP 0x11 \fBSTZ\fP 0x19 \fBSUB\fP 0x02 \fBPOP\fP 0x0a \fBGTH\fP 0x12 \fBLDR\fP 0x1a \fBMUL\fP 0x03 \fBNIP\fP 0x0b \fBLTH\fP 0x13 \fBSTR\fP 0x1b \fBDIV\fP 0x04 \fBSWP\fP 0x0c \fBJMP\fP 0x14 \fBLDA\fP 0x1c \fBAND\fP 0x05 \fBROT\fP 0x0d \fBJCN\fP 0x15 \fBSTA\fP 0x1d \fBORA\fP 0x06 \fBDUP\fP 0x0e \fBJSR\fP 0x16 \fBDEI\fP 0x1e \fBEOR\fP 0x07 \fBOVR\fP 0x0f \fBSTH\fP 0x17 \fBDEO\fP 0x1f \fBSFT\fP The "complete" opcode's value can be derived by combining the base value with its flags. For example, \fBADD2k\fP is \fB(ADD | 2 | k)\fP = \fB(0x18 | 0x20 | 0x80)\fP = \fB0xb8\fP. Unlike other opcodes, \fB0x00\fP (\fBBRK*\fP) is contextual: its meaning depends on the \fImode\fP bits provided: 0x00 \fBBRK\fP 0x80 \fBLIT\fP 0x20 \fBJCI\fP 0xa0 \fBLIT2\fP 0x40 \fBJMI\fP 0xc0 \fBLITr\fP 0x60 \fBJSI\fP 0xe0 \fBLIT2r\fP .SH STACK EFFECTS .BR .SS NOTATION Given a stack effect \fB( a^ b^ c^ -- c^ a^ b^ )\fP here is what each symbol means: \fB(\fP and \fB)\fP are comment delimiters \fBa^\fP, \fBb^\fP, and \fBc^\fP are values on the stack \fB^\fP indicates that each value is a \fIbyte\fP (\fB*\fP would indicate \fIshort\fP) \fB--\fP separates the "before" and "after" of the stack effect The effect here is to move the top byte of the stack below the next two bytes, which could be achieved with \fBROT ROT\fP. By default stack effects describe the effect on \fBwst\fP. When \fBrst\fP is involved we use \fB[]\fP to differentiate the stacks. For example \fB( a* [b*] -- a+1* [b+1*] )\fP will increment the top short of both \fBwst\fP and \fBrst\fP. .SS EFFECTS AND MODES Regular instructions have a single stack effect which is modified in a predictable way by any additional modes. For example the generic effect for \fBADD\fP is ( x y -- x+y ). The eight combinations of modes have the following effects: .nf \fBADD\fP ( x^ y^ -- x+y^ ) sum bytes from \fBwst\fP \fBADDr\fP ( [x^ y^] -- [x+y^] ) sum bytes from \fBrst\fP \fBADD2\fP ( x* y* -- x+y* ) sum shorts from \fBwst\fP \fBADD2r\fP ( [x* y*] -- [x+y*] ) sum shorts from \fBrst\fP \fBADDk\fP ( x^ y^ -- x^ y^ x+y^ ) sum and keep bytes from \fBwst\fP \fBADDkr\fP ( [x^ y^] -- [x^ y^ x+y^] ) sum and keep bytes from \fBrst\fP \fBADD2k\fP ( x* y* -- x* y* x+y* ) sum and keep shorts from \fBwst\fP \fBADD2kr\fP ( [x* y*] -- [x* y* x+y*] ) sum and keep shorts from \fBrst\fP .fi Thus for regular instructions writing a "generic" effect (leaving sigils off values whose size depends on \fIshort mode\fP) is sufficient to describe its behavior across all eight variations. Note that some instructions always read values of a fixed size. For example the boolean condition read by \fBJCN\fP is always one byte, no matter what modes are used. In \fIreturn mode\fP the stacks are reversed. Effects on \fBwst\fP will instead affect \fBrst\fP, and effects on \fBrst\fP will instead affect \fBwst\fP. For example, \fBSTH\fP reads a byte from \fBwst\fP and writes it to \fBrst\fP, but \fBSTHr\fP reads a byte from \fBrst\fP and writes it to \fBwst\fP. In \fIkeep mode\fP all the values on the left-hand side of the stack effect will also appear on the right-hand side before the outputs. For example, \fBSWP\fP is \fB(x y -- y x)\fP but \fBSWPk\fP is \fB(x y -- x y y x)\fP. .SS TERMINOLOGY We consider the top of the stack to be the first value of the stack, and count back from there. For example, given the stack effect \fB( a b c -- )\fP we would say that \fBc\fP is the top of the stack, \fBb\fP is the second value (second from the top), and \fBa\fP is the third value (third from the top). .SH REGULAR INSTRUCTIONS .BR .SS INC ( x -- x+1 ) Increment the top value of the stack by 1. Overflow will be truncated, so \fB#ff INC\fP will evaluate to \fB0x00\fP. .SS POP ( x -- ) Remove the top value of the stack. \fBPOPk\fP is guaranteed to have no effect (it will not change the stack). .SS NIP ( x y -- y ) Remove the second value of the stack. \fBNIPk\fP is guaranteed to have no effect (it will not change the stack). .SS SWP ( x y -- y x ) Swap the top two values of the stack. .SS ROT ( x y z -- y z x ) Rotate the top three values of the stack. The lowest becomes the top and the others are each shifted down one place. .SS DUP ( x -- x x ) Place a copy of the top value of the stack on top of the stack. .SS OVR ( x y -- x y x ) Place a copy of the second value of the stack on top of the stack. .SS EQU ( x y -- x==y^ ) Test whether the top two values of the stack are equal. Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS NEQ ( x y -- x!=y^ ) Test whether the top two values of the stack are not equal. Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS GTH ( x y -- x>y^ ) Test whether the second value of the stack is greater than the top. Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS LTH ( x y -- x>l)<