A computer made of neurons

A tiny 8-bit computer where one tick of the clock is one neural network. It runs real programs, in CSS, with 0 bytes of JavaScript.

HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT
HLTLDILDSTADDSUBADDIJMPJZJNZOUT

Printed

n =
#instructionwhat it does
0LD 0A = counter
1ADDI 1add one
2ST 0save it
3OUTprint it
4SUB 1A = counter − n
5JNZ 0not there yet? loop
6HLT
#instructionwhat it does
0LD 0A = a
1OUTprint a
2ADD 1A = a + b
3ST 2t = a + b
4LD 1
5ST 0a = b
6LD 2
7ST 1b = t
8JMP 0again
x =
y =
#instructionwhat it does
0LD 2A = total
1ADD 0add x
2ST 2save total
3LD 1A = y
4SUB 3minus one
5ST 1save y
6JNZ 0y left? loop
7LD 2
8OUTprint x × y
9HLT
n =
#instructionwhat it does
0LD 1A = total
1ADD 0add n
2ST 1save total
3LD 0A = n
4SUB 2minus one
5ST 0save n
6JNZ 0n left? loop
7LD 1
8OUTprint the sum
9HLT
#instructionwhat it does
0LD 0A = x
1OUTprint x
2ADD 0A = x + x
3ST 0x = 2x
4JNZ 0until it overflows to 0
5HLT

Tap a line to change it: pick what it does, then its number. Lines run from the top; a jump goes to any line.

0HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
1HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
2HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
3HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
4HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
5HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
6HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
7HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
8HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
9HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
10HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
11HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
12HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
13HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
14HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
15HLTLDILDSTADDSUBADDIJMPJZJNZOUTstopA = A = memory[]memory[] = AA = A + memory[]A = A − memory[]A = A + go to line if A = 0, go to line if A ≠ 0, go to line print A
do
with
mstarting memory
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]

Numbers you can pick go from 0 to 15. Memory has only 8 cells, so cell 8 is cell 0 again, 9 is 1, and so on. Sums wrap around: 255 + 1 is 0, and 0 − 1 is 255.

A
next instruction
instructions run
haltedstill running after 128 ticks

Memory

01234567

Every tick

How it works (for the curious)

The instructions

CodeDoesCodeDoes
HLTstopADDI nA = A + n
LDI nA = nJMP tgo to instruction t
LD mA = memory[m]JZ tgo to t if A is 0
ST mmemory[m] = AJNZ tgo to t if A is not 0
ADD mA = A + memory[m]OUTprint A
SUB mA = A − memory[m]numbers wrap around at 256

One tick, as ReLUs

PartHow
fetch[PC = i] for every line i, each gating that line's opcode and argument: relu(op_i − 15·(1 − [PC = i]))
decode[op = k] for each opcode, AND not halted
addressarg mod 8 = arg − 8·round(relu(2·arg − 7) / 16), one integer unit
ALUA + m, A − m, A + n, each wrapped with one comparison: s − 256·[s ≥ 256]
writethe new A is the result whose opcode is on, gated; the same for each memory cell and the printer's next slot
next PCthe jump target, PC + 1, or PC again when halted
layer 1
161
layer 2
116
layer 3
138
layer 4
139
layer 5
100
layer 6
84
layer 7
73
output
42
learnedhand-writtencarry (passes a value down a layer)

Checked in numpy against a plain Python emulator: the demo programs with every input, the editor's default, 1,000 random programs of the kind the editor can make and 3,000 random programs of any kind, all 128 ticks, every register at every tick. The browser tests run the demo programs in Chromium, Firefox and WebKit, and type programs into the editor with real clicks (random ones, and edge cases: a jump to itself, writing every memory cell, sums that wrap past 255, printing more than 16 times, stopping on line 0), comparing every tick's A and the final state with an emulator written in the test.

Writing your own

The editor is 560 radio buttons: for each of the 16 lines, one per instruction (11) and one per number (16), and 16 for each of the 8 starting memory cells. Each picked radio sets one integer on the page (.app:has(#eop3_7:checked) { --eop3: 7 }), and picking Write your own copies those integers into the program inputs of the same network every other cartridge uses. The network does not change at all: the program is just 32 more numbers it reads.

Numbers stop at 15 to keep the page small (the network itself takes any argument up to 255). Memory addresses use the number mod 8 and jumps use it mod 16, so ST 9 writes cell 1. There is no "do nothing" instruction, but ADDI 0 is one. Each line's text (LD 3, "A = memory[3]") is drawn from the same integers: the numbers with CSS counters, and the instruction name and its sentence by showing one of 11 stacked words and hiding the rest.