.\" Manpage reference for uxntal. .\" Contact d_m@plastic-idolatry.com to correct errors or typos. .TH uxntal 1 "01 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. .SH INSTRUCTION LAYOUT 0x01 ---- 0x02 \\ 0x04 +- \fIopcode\fP 0x08 / 0x10 ---- 0x20 ---- 2: \fIshort\fP mode 0x40 ---- r: \fIreturn\fP mode 0x80 ---- k: \fIkeep\fP mode .SH OPCODE LAYOUT There are 32 base values for opcodes: 0x00 \fB***\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(0x18 | 0x20 | 0x80)\fP = \fB0xb8\fP. Unlike other opcodes, \fB0x00\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 REGULAR INSTRUCTIONS 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: \fBADD\fP ( x^ y^ -- x+y^ ) sum two bytes using \fBwst\fP \fBADDr\fP ( [x^ y^] -- [x+y^] ) sum two bytes using \fBrst\fP \fBADD2\fP ( x* y* -- x+y* ) sum two shorts using \fBwst\fP \fBADD2r\fP ( [x* y*] -- [x+y*] ) sum two shorts using \fBrst\fP \fBADDk\fP ( x^ y^ -- x^ y^ x+y^ ) sum two bytes using \fBwst\fP, retain arguments \fBADDkr\fP ( [x^ y^] -- [x^ y^ x+y^] ) sum two bytes using \fBrst\fP, retain arguments \fBADD2k\fP ( x* y* -- x* y* x+y* ) sum two shorts using \fBwst\fP, retain arguments \fBADD2kr\fP ( [x* y*] -- [x* y* x+y*] ) sum two shorts using \fBrst\fP, retain arguments Thus for regular instructions writing a "generic" effect (leaving sigils off values whose size depends on \fIshort\fP mode) 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\fP mode 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\fP mode 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 INC ( x -- x+1 ) .SS POP ( x -- ) \fBPOPk\fP is guaranteed to have no effect (it will not change the stack). .SS NIP ( x y -- y ) .SS SWP ( x y -- y x ) .SS ROT ( x y z -- y z x ) .SS DUP ( x -- x x ) .SS OVR ( x y -- x y x ) .SS EQU ( x y -- x==y^ ) Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS NEQ ( x y -- x!=y^ ) Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS GTH ( x y -- x>y^ ) Result is guaranteed to be boolean (\fB0x00\fP or \fB0x01\fP). .SS LTH ( x y -- x>l)<