Uxn Ecosystem

Published

July 13, 2022

Modified

July 13, 2022

Uxn

uxn …virtual machine…

  • …simple architecture…
    • …comprehensible for a single human
    • …postfix notation
      • …aka reverse polish notation
      • …operators follow their operands (from left to right)
  • …programmable in assembly language called uxntal
  • …core of the varvara virtual computer

Elements of data encoding and manipulation…

  • binary words of 8-bits (1 byte)
  • binary words of 16-bits (2 bytes) … known as shorts
  • numbers …hexadecimal system (base 16) …nibble 0-9,a-f
  • byte 1f two hex, digits …short four 1f2e

Virtual hardware…

  • CPU…
    • …stack-based machine
    • 32 instructions…
      • …three different mode flags 2, r, k
      • …encoded in a single word of 8-bits
      • …operate with elements in the stack
    • …instruction cycle
      • …program counter …16bits …next byte to read
      • …reads one byte at a time from the main memory
      • …decode instruction
      • …execute instruction
  • Memory …four separate spaces
    • main …64kbit
      • …16bit addresses …random access
      • …first 256bits …zero page
      • …program starts at 257th byte …adress 0100
    • i/o .. 256bit in 16 sections (or devices) of 16 bytes …8bit addresses
    • working stack …256bit
    • return stack …256bit

Varvara

Virtual computer …cf. reference

  • …run locally with emulator
    • emulator list on GitHub
    • Linux (bundled with a selection of roms)
      • unxemu …emulator
      • unxcli …console-based emulator
      • unxasm …uxntal assembler
    • source code
  • Controls…
    • F1 cycle resolution
    • F2 toggle debugger
    • F3 screenshot
    • F4 ..reload launcher.rom (current directory)
    • Enter …start a rom (F4 to return)
  • TinyBASIC article, code

Uxntal

Uxn assembly language

Simple “Hello World” on the emulator…

# simple hello world
>>> cat > hello.tal <<EOF
( hello.tal )
|0100 LIT 68 LIT 18 DEO ( h )
      LIT 65 LIT 18 DEO ( e )
      LIT 6c LIT 18 DEO ( l )
      LIT 6c LIT 18 DEO ( l )
      LIT 6f LIT 18 DEO ( o )
      LIT 0a LIT 18 DEO ( newline )
EOF

# ...assemble the program
>>> unxasm hello.tal hello.rom

# ...run the program
>>> unxemu hello.rom
  • syntax
    • …opcodes …reserved words
    • …hexadecimal values …lower-case
    • ( ... ) comments …spaces required
    • [ ] ignored …for readability

Opcode & Modes

36 opcodes

LIT a b c M[PC]   EQU a b?c             LDZ a b M[c8]      ADD a b+c
INC a b c+1       NEQ a b!c             STZ a {M[c8]=b}    SUB a b-c
POP a b           GTH a b>c             LDR a b M[PC+c8]   MUL a b*c
NIP a c           LTH a b<c             STR a {M[PC+c8]=b} DIV a b/c
SWP a c b         JMP a b {PC+=c}       LDA a b M[c16]     AND a b&c
ROT b c a         JCN a {(b8)PC+=c}     STA a {M[c16]=b}   ORA a b|c
DUP a b c c       JSR a b {rs.PC PC+=c} DEI a b D[c8]      EOR a b^c
OVR a b c b       STH a b {rs.c}        DEO a {D[c8]=b}    SFT a b>>c8l<<c8h

JMI PC=M[PC]      JCI (a8)PC=M[PC]      JSI {rs.PC} M[PC]
--2 a16 b16+c16   --r a b c {rs.b+rs.c} --k a b c b+c

By default instructions consume bytes …3 possible modes

  • 2 …short mode
    • …consumes two bytes from the stack
    • …jumps to an absolute address in memory
    • …indicates the size of the data to read and write
  • k …keep mode …does not consume items from the stack
  • r …return mode …operate on the return stack

Cf. uxn tutorial (day 2)

Runes, Labels & Macros

Runes …pre-processing for the assembler

  • | …absolute pad …write to address in memory
    • 1 byte …i/o memory address
    • 2 bytes …main memory address
  • $ …relative pad
  • # …literal hex rune …short for LIT
  • " …raw character rune
( hello.tal )
|0100 LIT "h #18 DEO
      LIT "e #18 DEO
      LIT "l #18 DEO
      LIT "l #18 DEO
      LIT "o #18 DEO
      #0a #18 DEO ( newline )

Labels …rune @ …sub-labels &

  • …address in memory followed by label
  • …sub-labels use $ relative pads
  • . rune …literal address
  • / rune …refer to one of its sub-labels
( hello.tal )

( devices )
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]

( main program )
|0100 LIT "h .Console/write DEO
      LIT "e .Console/write DEO
      LIT "l .Console/write DEO
      LIT "l .Console/write DEO
      LIT "o .Console/write DEO
      #0a .Console/write DEO ( newline )

Define our own “words” as macros

  • …recursively replaced during assembly
  • % rune
    • { ... } curly brackets for the definition
    • …spaces mandatory
( hello.tal )
( devices )
|10 @Console [ &vector $2 &read $1 &pad $5 &write $1 &error $1 ]

( macros )
( print a character to standard output )
%EMIT { .Console/write DEO } ( character -- )
( print a newline )
%NL { #0a EMIT } ( -- )

( main program )
|0100 LIT "h EMIT
      LIT "e EMIT
      LIT "l EMIT
      LIT "l EMIT
      LIT "o EMIT
      NL