Uxn - Virtual Computer

This thread is called “virtual computer” which is a good and strange name (all computers¹ are kind of virtual), next level is the name people call PICO-8, TIC-80 etc: fantasy console.

Uxn looks cool as a thing and very cool as a project. We need news kind of computing, everyone knows it :leaves:

¹ well there are many theories but I guess mean Turing complete and maybe von Neumann architecture


I’m trying to make it explicit with this project.

Most people, including me, will at some point feel like computing is limiting or broken or static - Everyone who forget that all computing is virtual will just accept it, and won’t try to shape it in novel ways.

Building entirely personal VMs is a way to rekindle that, the Uxn code-base is only 1200 lines in size, the idea is that it can be an approachable example of DIY computing, and maybe get people to think about building their own vision of a dream machine.


This setup with a bootloader to switch between Uxn / PICO-8 / TIC-80 / etc. would be absolutely perfect (although PICO-8 is closed-source, which makes it sadly inaccessible for this type of project).


@neauoire Was wondering what might be stopping web Uxn Orca from receiving arrow key messages from my Bluetooth keyboard (RK61).

They are activated by a Fn layer on the keyboard, but unusually, the .io web version receives them fine.

P.s I’m buzzing for your set on Saturday! :honeybee:

Was wondering what might be stopping web Uxn Orca from receiving arrow key messages from my Bluetooth keyboard

They might be registering as other keycodes, does the SDL2 version of the Uxn emulator has the same issue?


1 Like

So I was talking to @neauoire in the Orca thread about possibly publishing Uxn and/or Orca on iOS and how the licensing would work, and that would be totally acceptable (as long as it were released free of charge and included the license info).

Would you mind letting me (at some point) know what you had to do to get it running on iOS? I’m thinking that the license would be fairly easy to throw in with all the other necessary iOS UI bits, and then one would just need to implement something along the lines of shim to convert the Uxn/Orca note data to CoreMIDI.

Ooh I’ve not tried building the all the SDL2 stuff, I’ll give this a go when I can and let you know! :honeybee:

1 Like

Sure! I’ve spent only a few hours on the SDL2 version and much more time trying to wrap the JS version. It really feels like making a good Uxn ROM player on iOS with some great native service integrations is the way to move forward, especially as this ecosystem evolves. I’m attaching the SDL port I started last night. Let me know if you want collab on this or fly solo. I’m kind of burnt out on mobile apps these days so I don’t think I can carry the project myself.

SDLTemplate.zip (173.0 KB)


Thanks for the ZIP of your current progress! I’ll have to play around with this in Xcode at some point soon.

To be honest, I tend to get burnt out on personal projects easier than others, but collaborating eases that problem a bit. And I totally agree - a native implementation of Uxn seems like the way to go, because then Orca and any other Uxn moms all work for the development cost of one port.

Something I’m having a harder time than I should wrapping my head around: Is there a way to enter characters into Uxn using only a controller (without a keyboard or mouse), or is the GBA port playback-only when you run Orca within Uxn?

1 Like

Since I think someone asked about OSX, building UXN on my old 2012 MBP running OSX sierra or high sierra was trivial.

on Raspberry Pi Zero W running Raspbian lite I’ve encountered the following:

  • UXNEmu can’t be directly exited (you have to pull the power plug :frowning: )
  • You can’t swap TTY with Ctrl + Alt + Fn (need to triple check this)
  • Screen will not respond to detach Ctrl + a Ctrl + d
  • I3wm, launching UXNEmu from terminal results in >1fps :sob: Not sure why this performs so badly.
Forget this

I can’t seem to run UXNEmu directly from I3 launcher (Ctrl+d) I’m completely new to i3wm and I’m not sure my install is correct? Might need to install normal Raspbian build and try install i3 from there.
Any advice on how to proceed would be appreciated, as a regular Vim and iTerm2 user i3 looks really interesting.

UPDATE Just saw your video on the ORCA thread @neauoire, very helpful to confirm that I’m doing things correctly. Looks like the Pi Zero doesn’t have the juice to run i3wm and UXNEmu :expressionless:

Are there any Android dev’s interested in UXN? Looks like there is a version of SDL2 for NDK… I’m game to try this as I have 2x unused 7in Android tablets (Samsung Galaxy Tab 3 and some generic thing). And I’ve never done anything much more than rooting devices and installing cynogenmod. I know the ecosystem is a bit fragmented, is it viable to target older Andriod tablets? Will Midi work with an OTG cable?


I, for one, would appreciate some basic button/controller support generally (such as in ORCA) for cycling through values (contextual cycling would be doubly nice for this); however, I suspect that at the very least we’ll eventually see keyboard support through the link port:


OK, it’s time to try writing an actual program in Uxntal. I’ve written a bit of assembly on microcontrollers, but it’s been a while and I’m already in over my head.

Let’s start with “pad”. I see it used to define port mappings as well as the “main” starting point for code. Could someone explain this? I’m guessing it is used to format the .rom so that the VM can jump to a constant location for these definitions.

Thanks! Super excited to get some code running, I already have ideas percolating.


@whatever defines a label whatever at a particular memory address, so |18 @whatever defines whatever at memory address 18. Uxn has memory-mapped IO, so those port mappings are just naming the memory addresses which are the places the emulator looks for I/O stuff.


Thanks, I think if I dig into the emulator code things will make a lot more sense.

1 Like

At the moment, I’m going through the various examples (uxn/projects/examples/**/*.tal) and it’s extremely enlightening.

The padding is a bit odd because the devices are overlapping the zero-page.

|00 @System     [ &vector $2 &pad      $6 &r      $2 &g     $2 &b      $2 ]
|20 @Screen     [ ... ]

|0000 ( rewind back to #0000 and start zero-page variables )

@variable $1

|0100 ( actual program )

Until the 0100 padding, everything is just about organizing references for the assembler. If you like, you could instead use constants, like

%date-day { #b3 }

That would basically be the same thing, the label date-day would be equal to the byte #b3, which is what this line does:

|b0 @DateTime   &year $2 &month $1 &day $1

After your question, I’ve decided to rewrite parts of the tutorial on the Unxtal page, I hope it’s clearer now :slight_smile: Let me know if you have any suggestions:

Official Documentation

In the following example, our program begins with a padding to the address #0018 with |18, followed by the definition of the Console/write label. From that point onward, the absolute or zero-page address of that label can be referenced by name. The zero-page is the name of the first 256 bytes in memory, the 0000-0100 range, it is typically used to store variables.

Zero-page .Console/write #18
Absolute ;Console/write #0018

Next, we pad to |0100, which is where the first page of memory ends, and where all Uxn programs begin. Our program begins by pushing to the stack, the absolute address of the label hello-world, which is defined at the end of the program and points to a series of characters. An absolute address is made of two bytes. We then assign the label &loop to this position of the program so we can return to it later.

Next, the LDAk opcode takes two bytes at the top of the stack to form an absolute address, and loads the value in memory found at that address to the top of the stack, in this case, the ascii value of the letter H. That value is sent to the Console’s port named write (#18) which prints that character to the terminal.

Next, we increment the absolute address found on top of the stack, we use #0001 and ADD2 because we know the items on the stack to be an address made of two bytes. We load the incremented value, the JCN opcode will jump to the position of label &loop as long as the item before the address is not zero. We complete the program with POP2 to remove the address on the stack, to keep the stack clean.

( dev/console )

|18 @Console/write

( init )

|0100 ( -> )

		( send ) LDAk .Console/write DEO
		( incr ) #0001 ADD2
		( loop ) LDAk ,&loop JCN

@hello-word "Hello 20 "World!

Yes! This is great. I think it helps to have a solid understanding of where “main” is coming from a C programming background. The details about the zero-page are also starting to make sense.

1 Like

I’ve not seriously written assembly before so this might be something obvious?

Am I correct in thinking that
k = keep, 2 = short (or 16bit?), r = return

Incr increment and return
Inck increment and keep
Inc2r increment 16bit (two bytes) and return
Inc2k increment 16bit and keep

Edit: had the 2* op codes wrong

1 Like

Default Mode

Notice how it adds only #45 with #67, and adds the result ac on the stack.

#1234 #4567 ADD
stack: 12  34  ac [67] 00  00  00  00

Short Mode

This adds the two shorts together, the result is 579b.

#1234 #4567 ADD2
stack: 57  9b [45] 67  00  00  00  00 

Keep Mode

This adds the two shorts together, but does not consume them, it puts the result 579b after the two shorts, still on the stack.

#1234 #4567 ADD2k
stack: 12  34  45  67  57  9b [00] 00 

Return-stack Mode

This does the ADD2r operation on the two shorts stashed in the return stack.

#1234 #4567 STH2 STH2 ADD2r STH2r
stack: 57  9b [45] 67  00  00  00  00

If you want to experiment with the uxn without the need for the audio/visual stuff, try using bin/uxncli your_project.rom --print, it will print the resulting stack.


Lots of great info here :slightly_smiling_face:
What are the file specs for the samples in drum-rack now?
Is it possible in Sox and/or ffmpeg to convert an audio sample to be compitable?