🐫Uxn Legoptics

While having an insomnia, I came up with an idea of a ridiculous project that would be both hard to implement and of very little utility. Introducing UXN Legoptics, an optical Uxn ROM executor project. The name is a portmanteau of Uxn, Lego and optics. Such a combination cannot be boring. Read further!

NB. I'm not starting it any time soon.

The idea

Wintergatan's first Marble Machine is programmed with Lego pins. When I make my own mechanical computer, It'll be programmed with Lego pins too. It's cooler than punch cards!

The Legoptics project is not a fully mechanical computer though. I shall call the device Xunotron for the rest of the article for the ease of read.

Xunotron's architecture

  • A computer screen, connected with an HDMI to

  • Emondsfield, a single-plate computer I no longer use, connected to

  • A small camera module which was designed Raspberry π, but is probably compatible with Orange π, which is stationed to look at

  • A rotating ribbon made of Lego pieces. Each line has pins that encode ROM's bits.

  • The ribbon is lit with an LED from behind.

The Machine Word

The beet processor has 8-bit-wide bytes and machine words. But Xunotron Mark 1 has 10-bit-wide words!

  • Bit 1 is an always empty hole. Because of the LED, it's always lit and bright, so it will be easier to write the optical recognition software.

  • Bit 2 is the XUN bit.

  • If XUN bit is clear:

    • Bits 3 to 10 are regular UXN bits that are passed along to the emulator.

  • If XUN bit is set:

    • Bits 3 to 10 are reserved for some meta-operations that might alter the program flow somehow. See below.

The XUN bit is to the right, the first bit is to the left, so the ribbon has some nice margin on both sides.

The Execution

The ribbon is rotated with a gear mechanism that I hope to design well. It can be rotated with any speed, and thus the program's initial execution speed can be set as well. The camera recognizes the program and executes it.

Once the ribbon is fully read, id est it's not looped, the program is fully working. Until it's not, the program is executed on the go.

Caveat Lector

User input would only be possible after the ROM is only read, which is fine.

Also, if the program jumps to the ROM address that is not read yet, the execution will block until it's read. Programs designed with Xunotron in mind should limit the amount of such jumps to the absolute minimum.

An interesting challenge would be to design circular programs that are perfectly executed in a loop. Animations would work well this way. The cat clock, for example.

The Implementation

Is yet to start. I lack the needed Lego pieces, though. Perhaps it would actually be much more practical to go with punch cards, because of how cheap and replaceable they are. But that would never be as good as clicking your program in, right?

The Color Space

A long ribbon is problematic. Storing it, actually rotating it, doesn't sound fun! If it ends up being possible to differentiate colors with the camera, two bytes could be encoded in one line!


Byte 1 bit k

Byte 2 bit k

empty space












Such a system would make programs ~twice as small physically. If 4 more colors were possible to recognize, 3 bytes could be encoded at once.

Input optimization

Encoding the UXN bytes as is would probably ineffective. We have a 256-symbol alphabet. What's the frequency of every symbol? More common instructions should be encoded with less pieces.

Also, a visualisation that helps the operator place the pieces in place would help greatly as well.

Some Xunotron metacommands

Available with the XUN bit. I feel like something creative and compact can be done with them. They could make the programs a bit smaller. Maybe they are not needed at all.

We have the following variables:

  • A: boolean

  • B: boolean

  • C: boolean

  • IGA — Ignore A. Flip the value of A. If it's set now, ignore the next non-XUN instructions until A is clear.

  • IGB — Ignore B. Flip the value of B. If it's set now, and A is set too, ignore the next non-XUN instructions until B is clear.

  • LUV — Love. Flip both A and B.

  • LVA — Love A. Flip A only.

  • LVB — Love B. Flip B only.

  • STC — Start C. Ignore the next instructions until EDC comes.

  • EDC — End C. End the STC block. Useful for program initialization for circular programs.

  • XJP — Extra Jump. Consider the next two bytes as the ROM address to jump to, filling the space with zeroes.

  • SLW — Slow. When the ROM is finally read, execute it at the speed with which the ribbon was rotated on average.

  • MSC — Music. Play music with the instructions being notes.