XXIIVV

Uxambly is a programming language for the Uxn stack-machine.

The Uxn cpu understands 8-bit machine code, and that code corresponds to operations and values used in programs. The programming language that turns source code into Uxn roms, is called Uxambly, it's a unique flavor of assembly designed for this special stack-machine.

Stack machine programming might look at bit odd, as it uses a postfix notation, which means that operators are always found at the end of an operation. For instance, one would write 3 4 + instead of 3 + 4. The expression written (5 + 10) * 3 in conventional notation would be written 3 10 5 + * in reverse Polish notation.


Opcodes

There are 32 opcodes, each opcode occupies 5 bits of a byte, the remaining 3 are used to select modes of that opcode, modes are explained below.

modeopcode
nilreturn[r]short[2]0000

Opcodes using memory addresses can pop 2 bytes at once to form an absolute address, or a single one to create a relative address in the case of jump opcodes, or a the zero-page address in the case of peek/poke opcodes. For example, if [0xAB 0xCD] is present on the stack, it will be used by JMP2 to point to the memory address 0xABCD.

Stack Memory
0x00BRK Break 0x10PEK Load(zero-page)a[b]
0x01LIT Literal++ 0x11POK Save(zer-page)a [b]
0x02--- 0x12GET Load(absolute)a[b]
0x03POP Popa 0x13PUT Save(absolute)a [b]
0x04DUP Duplicateaa a 0x14JMP Jump[a]
0x05SWP Swapa bb a 0x15JNZ JumpConda [b]
0x06OVR Overa ba b a 0x16JSR JumpStash[a]rs
0x07ROT Rotatea b cb c a 0x17STH Stashars
Logic Arithmetic
0x08EQU Equala bc 0x18ADD Adda bc
0x09NEQ NotEquala bc 0x19SUB Subtracta bc
0x0aGTH GreaterThana bc 0x1aMUL Multiplya bc
0x0bLTH LesserThana bc 0x1bDIV Dividea bc
0x0cGTS GreaterSignas bsc 0x1cAND Anda bc
0x0dLTS LesserSignas bsc 0x1dORA Ora bc
0x0eDEI Device Indev[b] 0x1eEOR ExclusiveOra bc
0x0fDEO Device Outdev [b] 0x1fSFT Shifta bc

Operator modes are indicated by appending extra characters at the end of the opcode, for example, the short mode for the ADD opcode is ADD2, modes can also be combined, for example: ADD2r.

The return mode makes it possible for any operator to operate on the return-stack directly, for that reason there is no return operation. For example, the JumpStash(JSR) operator pushes the program's address onto the return stash before jumping, to return to that address, the JMPr opcode is used, where instead of using the address on the working-stack, it takes its address directly from the return-stack.

The short mode allows for each operator to do 16-bits operations by pushing and popping the necessary extra items from the stack. In the case of jump opcodes(JMP2, JSR2, and JNZ2) the short mode operation jumps to an absolute address in memory. For the getters and setters(PEK2, POK2, GET2 and PUT2) the short mode operation indicates the size of the data to read/write.

Programming

Here is an example of the assembly language that prints hello world to stdout. Uxambly has no reserved words besides the 32 opcodes, each element of the program has its own rune.

( dev/console )

%RTN { JMP2r }

( devices )

|10 @Console    [ &pad $8 &char $1 ]

( init )

|0100 ( -> )
	
	;hello-word ;print JSR2
	
BRK

@print ( addr -- )
	
	&loop
		( send ) DUP2 GET .Console/char DEO
		( incr ) #0001 ADD2
		( loop ) DUP2 GET #00 NEQ ,&loop JNZ
	POP2

RTN

@hello-word [ 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 ]

Addressing

The memory and stacks contains 8-bits values, to differentiate operations from literal numbers, the LIT opcode will push the following byte from memory onto the stack, the 16-bits mode LIT2 opcode will push the following short.

Immediate, or literal, addressing allows to directly specify a byte or short constant. Deferred addressing is a form of immediate addressing where the address of a label is put on the stack.

ByteShort
Immediate#ab#cdef
DeferredZero-pageRelativeAbsolute
.label,label;label

Uxambly allows for basic control flow, here are some of them:

ForLoopWhileLoopSwitch
#00 #0d
&loop
	( body ) 
	SWP #01 ADD SWP
	DUP2 LTH ,&loop JNZ
POP2
#00 #0d
&while
	( body )
	DUP2 EQU ,&end JNZ
	SWP #01 ADD SWP
,&while JMP &end
POP2
#02 
DUP #01 NEQ ,&b JNZ
	( a ) 
&b DUP #02 NEQ ,&c JNZ
	( b ) 
&c DUP #03 NEQ ,&default JNZ
	( c ) 
&default
POP

Library

%RTN   { JMP2r }
%STEP8 { #0033 SFT2 }
%MOD { DUP2 DIV MUL SUB }
%ABS { DUP #07 SHR #ff SWP MUL? }
%++ { #0001 ADD2 } %-- { #0001 SUB2 }
%2/ { #0001 SFT2 } %2* { #0010 SFT2 }
%8/ { #0003 SFT2 } %8* { #0030 SFT2 }
%8- { #0008 SUB2 } %8+ { #0008 ADD2 }
— Submit an edit to uxambly.htm(153 lines)

incoming(3): uxn roms noodle

Last update on 15H10, edited 16 times. +56/109fh -----|