From a6551d1af637d1361480af20440919d01fb65e00 Mon Sep 17 00:00:00 2001 From: d_m Date: Thu, 1 Aug 2024 23:28:16 -0400 Subject: [PATCH] uxntal manpage --- uxntal.1 | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 uxntal.1 diff --git a/uxntal.1 b/uxntal.1 new file mode 100644 index 0000000..c03ab70 --- /dev/null +++ b/uxntal.1 @@ -0,0 +1,115 @@ +.\" 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 instruction pointer 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). + +.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.) + +.SS INC +( x -- x+1 ) + +.SS POP +( x -- ) + +.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 ) + +.SH SPECIAL INSTRUCTIONS + +.SS BRK + +The break instruction is used to end a vector call and return control to the virtual machine. + +.SS JCI, JMI, and JSI + +The "immediate jump" instructions are produced by the assembler. They interpret the next 2 bytes of the ROM as a relative address (\fIaddr\fP) and have the following effects: + + \fBJMI\fP ( -- ) jump to \fIaddr\fP unconditionally + \fBJCI\fP ( bool^ -- ) jump to \fIaddr\fP if \fIbool\fP is non-zero + \fBJSI\fP ( -- [cur] ) jump to \fIaddr\fP saving the current address (\fIcur\fP) on the return stack + +(The instruction pointer will be moved forward 2 bytes, past the relative address.) + +.SS LIT, LIT2, LITr, and LIT2r + +The "literal" instructions are used to push new data onto the stacks. They interpret the next 1-2 bytes of the ROM (\fIwx\fP, \fIwxyz\fP) as data and push it onto the corresponding stack: + + \fBLIT\fP ( -- wx^ ) push literal byte \fIwx\fP onto the \fBwst\fP + \fBLITr\fP ( -- [wx^] ) push literal byte \fIwx\fP onto the \fBrst\fP + \fBLIT2\fP ( -- wxyz* ) push literal short \fIwxyz\fP (2 bytes) onto the \fBwst\fP + \fBLIT2r\fP ( -- [wxyz*] ) push literal short \fIwxyz\fP (2 bytes) onto the \fBrst\fP + +(The instruction pointer will be moved forward 1-2 bytes, past the literal data.) +