XXIIVV — uxntal
Tal is the programming language for the Uxn digital machine.
Uxn applications are written in a stack-based taste of meeting designed
particularly for this digital machine. TAL information are human-readable supply information,
ROM information are uxn-compatible binary program information; functions that rework
TAL information into ROM information are known as Assemblers.
To get began, equip your self with an emulator and assembler on your
system.
Uxntal Syntax
In concatenative programming, there are not any priority guidelines,
the calculations are merely carried out within the sequence during which they’re
offered. The order with which parts come off a stack is named final
in, first out. Within the stack a b c, the c merchandise was the final to
be added, and would be the first to be eliminated.
#01 DUP ADD #03 MUL06
Instance Program
The primary line of our instance begins with the padding
token |10 which strikes this system writing location to the tackle
0x0010, and can enable us to outline @labels, &sublabels
and $size for the assorted ports of the Console device in order that we are able to reference them in
our code by title. To be taught extra, see Uxntal
Structs.
The next program is not probably the most environment friendly manner of printing a
string, merely a size of code that covers most simple functionalities of the
language.
The second phase strikes this system location to the tackle 0x0100, which is
the place the primary web page of reminiscence ends, and where all
Uxn programs begin. Subsequent, inside parentheses, is a remark with the
arrow image indicating that the next operation is a vector. To be taught extra, see Uxntal Notation.
The ;hello-world token pushes an absolute tackle, manufactured from
two bytes, on the stack pointing to a collection of letters in reminiscence. Values
pushed to the stack on this style are known as a literals, versus
values saved in reminiscence that are known as immediates. Subsequent, we name the
@print-text routine.
Each &whereas and @whereas are methods to outline labels,
however utilizing the ampersand rune will prefix our new label with the title of the
final mum or dad label, creating @print-text/whereas.
Subsequent, the LDAk opcode hundreds
the byte in reminiscence discovered at that tackle; the ASCII
letter H, to the highest of the stack. The k-mode
signifies that the operation won’t eat the tackle. That worth is distributed
to the device port #18, outlined by our
Console label and its sublabels, with DEO which prints that character
to the terminal.
We then increment absolutely the tackle discovered on prime of the stack with INC2, we use the 2-mode as a result of the tackle is manufactured from two bytes.
We load the byte on the incremented worth and do a conditional fast bounce
with ?&whereas for so long as the merchandise on the stack just isn’t zero. We
use POP2 to take away the tackle
on the stack and hold the stack clear on the finish of the subroutine.
Lastly, we encounter JMP2r
which jumps to absolutely the tackle that we left on the return stack once we
entered the @print-text subroutine.
To summarize, uppercased opcodes are reserved phrases, lowercase hexadecimal
numbers are bytes and shorts, parentheses are comments, curlies are lambdas, and sq. brackets are used for
group. Runes are particular characters initially of a phrase that outline
its which means, right here is the total listing:
Padding Runes | Literal Hex Rune | ||||||
---|---|---|---|---|---|---|---|
| |
absolute | $ |
relative | # |
literal hex | ||
Label Runes | Ascii Runes | ||||||
@ |
mum or dad | & |
baby | " |
uncooked ascii | ||
Addressing Runes | Pre-processor Runes | ||||||
, |
literal relative | _ |
uncooked relative | % |
macro-define | ~ |
embrace |
. |
literal zero-page | - |
uncooked zero-page | ||||
; |
literal absolute | = |
uncooked absolute | ||||
Instant Runes | |||||||
! |
jmi | ? |
jci |
Uxntal stacks
All programming in Unxtal is finished by manipulating the working stack,
and return stack. Every stack accommodates 256 bytes, gadgets from one stack
could be moved into the opposite. Listed here are some stack primitives and their impact:
POP | a b | Discard prime merchandise. |
---|---|---|
NIP | a c | Discard second merchandise. |
SWP | a c b | Transfer second merchandise to prime. |
ROT | b c a | Transfer third merchandise to prime. |
DUP | a b c c | Copy prime merchandise. |
OVR | a b c b | Copy second merchandise to prime. |
A byte is a quantity between 0-255(256 values), a brief is manufactured from two bytes,
every byte in a brief could be manipulated individually:
#0a #0b POP 0a #12 #3456 NIP 12 56 #1234 DUP 12 34 34
The 2 stacks are circular, and so don’t have any depths, to pop an empty stack does
not set off an error, however merely means to set the stack pointer to 255. There
are not any invalid applications, any sequence of bytes is a possible Uxn program. To
be taught extra about detecting unintended stack results, see programs validation.
Uxntal Opcodes
Uxn has 64kb of reminiscence, 16 gadgets, 2 stacks of 256 bytes, 5-bits opcodes and
3 modes. The listing beneath present the usual opcodes and their impact on a given
stack a b c. PC: Program Counter, |: Return Stack,
[M]: Reminiscence, [D+*]: System Reminiscence, a8: a byte, a16:
a brief.
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<c STR a {[PC+c8]=b} DIV a b/c SWP a c b JMP a b {PC+=c} LDA a b [c16] AND a b&c ROT b c a JCN a (b8){PC+=c} STA a {[c16]=b} ORA a b|c DUP a b c c JSR a b | PC {PC+=c} DEI a b [D+c8] EOR a b^c OVR a b c b STH a b | c DEO a {[D+c8]=b} SFT a b>>c8l<<c8h
To be taught extra about every opcode, see the Opcode Reference.
Uxntal Modes
Every opcode has 3 attainable modes, which may mixed:
- The brief mode 2 operates on shorts, as an alternative of bytes.
- The hold mode okay operates with out consuming gadgets.
- The return mode r operates on the return stack.
INC2r | |||||||
---|---|---|---|---|---|---|---|
okay | r | 2 | opcode | ||||
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
By default, operators eat bytes from the working stack, discover how within the following instance solely the final two bytes #45
and #67
are added, even when there are two shorts on the stack.
#1234 #4567 ADD12 34 ac
The brief mode consumes two bytes from the stack. Within the case of bounce opcodes, the short-mode operation jumps to an absolute tackle in reminiscence. For the reminiscence accessing opcodes, the brief mode operation signifies the dimensions of the info to learn and write.
#1234 #4567 ADD2 57 9b
The hold mode doesn’t eat gadgets from the stack, and pushes the end result on prime. The next instance provides the 2 shorts collectively, however doesn’t eat them. Below the hood, the hold mode retains a short lived stack pointer that’s decremented on POP
.
#1234 #4567 ADD2k 12 34 45 67 57 9b
The return mode makes it attainable for any opcode to function on the return-stack straight. For that purpose, there is no such thing as a devoted return opcode. For instance, the JSR
opcode pushes this system’s tackle onto the return stack earlier than leaping, to return to that tackle, the JMP2r
opcode is used, the place as an alternative of utilizing the tackle on the working-stack, it takes its tackle from the return-stack.
LITr 12 #34 STH ADDr STHr 46
To higher perceive how the opcode modes are used, here’s a 22 bytes lengthy implementation of the operate to generate numbers within the Fibonacci sequence. Discover how solely a single literal is created to carry out the operation.
@fib ( num* -: numfib* ) #0001 GTH2k ?{ POP2 JMP2r } SUB2k fib STH2 INC2 SUB2 fib STH2r ADD2 JMP2r
Instant opcodes
Instant opcodes are operations which don’t take gadgets from the stack, however
learn values saved instantly after the opcode in this system’s reminiscence.
Uxntal has 4 fast opcodes:
- The literal LIT.
- The bounce !routine, fast of JMP.
- The conditional ?routine, fast of JCN.
- The subroutine routine, fast of JSR.
The fast bounce opcodes are barely sooner than their customary opcode
counterparts, however should not have modes and can’t be used to do pointer
arithmetic. The tackle worth of the fast opcodes are saved in reminiscence as
relative shorts, enabling routines making use of those opcodes to be moved
round in this system’s reminiscence.
@truth ( n* -: res* ) ORAk ?{ POP2 #0001 JMP2r } DUP2 #0001 SUB2 truth MUL2 JMP2r
Quoting is the act of deferring an operation, for instance, by holding the tackle
to a routine on the stack and utilizing it later, by unquoting it, with the
JMP2 or JSR2 opcodes. To be taught extra about pointer
arithmetic, see lambdas.
Uxntal Reminiscence
There are 64kb of addressable reminiscence. Roms are loaded at 0x0100, which
is the tackle of the reset vector. As soon as in
reminiscence, a Uxn program can write over itself, it’s not unusual for a uxntal
program to store values in its own runtime.
Reminiscence is big-endian, when writing or studying a brief from reminiscence, the
place is that of the high-byte. The low-byte of a brief written at 0xffff
wraps to 0x0000.
#12 #0200 STA 0x0200=12 #3456 #0400 STA2 0x0400=34, 0x0401=56 #0400 LDA 34
The zero-page is the reminiscence positioned beneath 0x0100, its
function is to retailer variables that will likely be accessed usually, or must be
preserved throughout a soft-reboot. It’s sligthly sooner to learn and write from
the zero-page utilizing the LDZ and STZ opcodes as they use solely a single byte
as an alternative of a brief. This reminiscence area can’t be pre-filled within the rom previous to
initialization. The low-byte of a brief written at 0xff wraps to 0x00.
#1234 #80 STZ2 0x0080=12, 0x0081=34 #81 LDZ 34
Throughout boot, the stacks, machine and addressable recollections are zeroed, whether it is
a soft-reboot, the content material of the zero-page is preserved.
Uxntal Units
Uxn is non-interruptible, vectors are areas in applications which might be
evaluated when sure occasions happen. A vector is evaluated till a BRK opcode
is encountered. Uxn can talk with a most of 16 gadgets, every machine
has 16 ports, every port handles a selected I/O message. Ports are mapped to the
gadgets reminiscence web page, which is positioned exterior of the principle addressable
reminiscence.
All applications start by executing the reset vector positioned at
0x100
. The content material of the stacks are preserved between vectors,
however it’s discouraged to make use of the stacks to go data between vectors.
@on-reset ( -> ) ( set vector ) ;on-mouse .Mouse/vector DEO2 BRK @on-mouse ( -> ) ( learn state ) .Mouse/state DEI ?&on-touch BRK &on-touch ( -> ) ( A mouse button is pressed ) BRK
For instance, the tackle saved within the Mouse/vector ports factors to part of the
program to be evaluated when the cursor is moved, or a button state has
modified.
Uxntal Utilities
This is a listing of small self-hosted growth instruments:
- Uxnfor is a
formatter that standardize the supply code, that is the formatting model used
throughout the Uxntal documentation. - Uxnlin is a linter and
peephole optimizer that reveals optimizations in opcode sequences, it is also a
good option to mirror in regards to the language in novel methods. - Uxnbal is a
program validator that warns when routines don’t match their definitions. - Uxnrea turns
a rom file and its symbols file, again right into a textual supply code. - UxnUtils is
a repository of various small applications 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