https://wiki.xxiivv.com/site/uxntal.html
XXIIVV
* turquoise
* secd
* chip8
* uxn
* uxntal
* varvara
* uxntal syntax
* uxntal stacks
* uxntal opcodes
* uxntal modes
* uxntal immediate
* uxntal memory
* uxntal devices
* uxntal software
Rostiger's Uxn ZineRostiger's Uxn Zine
Tal is the programming language for the Uxn virtual machine.
[uxn]
Uxn programs are written in a stack-based flavor of assembly designed
especially for this virtual machine. TAL files are human-readable
source files, ROM files are uxn-compatible binary program files;
applications that transform TAL files into ROM files are called
Assemblers.
To get started, equip yourself with an emulator and assembler for
your system.
* Download emulator & assembler, 40kb
* Introduction to Uxntal, online book
Uxntal Syntax
In concatenative programming, there are no precedence rules, the
calculations are merely performed in the sequence in which they are
presented. The order with which elements come off a stack is known as
last in, first out. In the stack a b c, the c item was the last to be
added, and will be the first to be removed.
#01 DUP ADD #03 MUL06
Example Program
The first line of our example begins with the padding token |10 which
moves the program writing location to the address 0x0010, and will
allow us to define @labels, &sublabels and $length for the various
ports of the Console device so that we can reference them in our code
by name. To learn more, see Uxntal Structs.
The following program is not the most efficient way of printing a
string, merely a length of code that covers most basic
functionalities of the language.
The second segment moves the program location to the address 0x0100,
which is where the first page of memory ends, and where all Uxn
programs begin. Next, inside parentheses, is a comment with the arrow
symbol indicating that the following operation is a vector. To learn
more, see Uxntal Notation.
The ;hello-world token pushes an absolute address, made of two bytes,
on the stack pointing to a series of letters in memory. Values pushed
to the stack in this fashion are called a literals, as opposed to
values stored in memory which are called immediates. Next, we call
the @print-text routine.
Both &while and @while are ways to define labels, but using the
ampersand rune will prefix our new label with the name of the last
parent label, creating @print-text/while.
Next, the LDAk opcode loads the byte in memory found at that address;
the ASCII letter H, to the top of the stack. The k-mode indicates
that the operation will not consume the address. That value is sent
to the device port #18, defined by our Console label and its
sublabels, with DEO which prints that character to the terminal.
We then increment the absolute address found on top of the stack with
INC2, we use the 2-mode because the address is made of two bytes. We
load the byte at the incremented value and do a conditional immediate
jump with ?&while for as long as the item on the stack is not zero.
We use POP2 to remove the address on the stack and keep the stack
clean at the end of the subroutine.
Lastly, we encounter JMP2r which jumps to the absolute address that
we left on the return stack when we entered the @print-text
subroutine.
[uxn]
To summarize, uppercased opcodes are reserved words, lowercase
hexadecimal numbers are bytes and shorts, parentheses are comments,
curlies are lambdas, and square brackets are used for organization.
Runes are special characters at the start of a word that define its
meaning, here is the full list:
+------------------------------------------------------------+
| Padding Runes | Literal Hex Rune |
|-----------------------------------+------------------------|
|||absolute |$|relative |#|literal hex |
|-----------------------------------+------------------------|
| Label Runes | Ascii Runes |
|-----------------------------------+------------------------|
|@|parent |&|child |"|raw ascii |
|-----------------------------------+------------------------|
| Addressing Runes | Pre-processor Runes |
|-----------------------------------+------------------------|
|,|literal relative |_|raw relative |%|macro-define|~|include|
|-+-----------------+-+-------------+-+------------+-+-------|
|.|literal zero-page|-|raw zero-page| | | | |
|-+-----------------+-+-------------+-+------------+-+-------|
|;|literal absolute |=|raw absolute | | | | |
|-----------------------------------+-+------------+-+-------|
| Immediate Runes | | | | |
|-----------------------------------+-+------------+-+-------|
|!|jmi |?|jci | | | | |
+------------------------------------------------------------+
Uxntal stacks
All programming in Unxtal is done by manipulating the working stack,
and return stack. Each stack contains 256 bytes, items from one stack
can be moved into the other. Here are some stack primitives and their
effect:
+------------------------------------+
|POP|a b |Discard top item. |
|---+-------+------------------------|
|NIP|a c |Discard second item. |
|---+-------+------------------------|
|SWP|a c b |Move second item to top.|
|---+-------+------------------------|
|ROT|b c a |Move third item to top. |
|---+-------+------------------------|
|DUP|a b c c|Copy top item. |
|---+-------+------------------------|
|OVR|a b c b|Copy second item to top.|
+------------------------------------+
A byte is a number between 0-255(256 values), a short is made of two
bytes, each byte in a short can be manipulated individually:
#0a #0b POP 0a
#12 #3456 NIP 12 56
#1234 DUP 12 34 34
The two stacks are circular, and so have no depths, to pop an empty
stack does not trigger an error, but merely means to set the stack
pointer to 255. There are no invalid programs, any sequence of bytes
is a potential Uxn program. To learn more about detecting unintended
stack effects, see programs validation.
Uxntal Opcodes
Uxn has 64kb of memory, 16 devices, 2 stacks of 256 bytes, 5-bits
opcodes and 3 modes. The list below show the standard opcodes and
their effect on a given stack a b c. PC: Program Counter, |: Return
Stack, [M]: Memory, [D+*]: Device Memory, a8: a byte, a16: a short.
LIT a b c [PC]
JCI a b (c8){PC+=[PC]}
JMI a b c {PC+=[PC]}
JSI a b c | PC {PC+=[PC]}
BRK a b c EQU a b==c LDZ a b [c8] ADD a b+c
INC a b c+1 NEQ a b!=c STZ a {[c8]=b} SUB a b-c
POP a b GTH a b>c LDR a b [PC+c8] MUL a b*c
NIP a c LTH a b>c8l< )
( set vector )
;on-mouse .Mouse/vector DEO2
BRK
@on-mouse ( -> )
( read state )
.Mouse/state DEI ?&on-touch
BRK
&on-touch ( -> )
( A mouse button is pressed )
BRK
For example, the address stored in the Mouse/vector ports points to a
part of the program to be evaluated when the cursor is moved, or a
button state has changed.
[varvara]
Uxntal Utilities
Here's a list of small self-hosted development tools:
* Uxnfor is a formatter that standardize the source code, this is
the formatting style used across the Uxntal documentation.
* Uxnlin is a linter and peephole optimizer that reveals
optimizations in opcode sequences, it's also a good way to
reflect about the language in novel ways.
* Uxnbal is a program validator that warns when routines do not
match their definitions.
* Uxnrea turns a rom file and its symbols file, back into a textual
source code.
* UxnUtils is a repository of varied small programs written in
Uxntal.
incoming left dexe noodle theme bifurcan catclock yufo programming
languages brainfuck gly format ufx format ulz format proquints uxn
uxntal types uxntal reference uxntal alphabet drifblim bicycle
beetbug about computer oscean arvelie
CreativeCommonsWebringMerveillesNoNazis!UxnPoweredDevine Lu Linvega (c)
2023 -- BY-NC-SA 4.0