A whole computer — from the logic gate to the window on screen — that fits in one head. Here it boots right in the browser, on the real description of the circuit, written by Niklaus Wirth.
In the 1980s Niklaus Wirth did something nobody has repeated since: not a language, not an operating system and not a processor separately, but all of it at once — and so that one person could see the whole.
The processor core is described in 184 lines, 538 with the multiplier, divider and floating point. With all its periphery — video, mouse, keyboard, ports, SD card — 935. The system on top of it, together with its own compiler and window interface, is another 4,953. About six thousand lines from gate to window. That is a week's reading.
A modern operating system has tens of millions of lines, and nobody holds it whole in their head — not one person in the world answers for the entire chain. Oberon is a rare place where a claim about computers can be checked all the way through, without running into a single "magic happens here".
Nothing to install: the lab opens in a browser and every task checks itself.
Convince yourself there is a circuit under that window, not an imitation.
See what happens when there is none — and why it does not kill the system.
Run the rebuild and wait while it builds its own compiler.
Measure it and check against what the circuit promises.
Drive the system out of memory in the middle of work and watch what follows.
Build the compiler with the compiler, then again — and compare the results byte for byte.
Write a program in Oberon, compile it inside the system and run it.
Break compatibility between modules and watch the system catch it.
Reach the place in the compiler where processor instructions finally appear.
Make garbage, watch the heap fill, and find out why the collector only runs between commands.
Write a background task, starve it with a long command, then freeze the whole system with it.
Switch to the core with a bounds-check instruction and measure what the check costs in your own loop — with the check done by hardware, by software, and not at all.
Teach the compiler a new built-in, rebuild the compiler inside the running system, and compile a module that uses it.
Eight chapters, from "why this" to "what we measured". The labs refer to them as they go, but they can be read on their own.
Everything we claim reproduces with one command. Verilator and a C++ compiler are needed:
git clone https://github.com/tym83/paleocomputing
cd paleocomputing/impl
make deps # check the environment
make check # about eight minutes
In those eight minutes the instruction-set tests run, the system boots, a step-by-step comparison against a reference model covers 14.6 million instructions, the compiler builds itself, and the system rebuilds itself entire — 37 files byte for byte.
Two labs do not fit in a browser: they need the circuit and the compiler rebuilt. There is a container for those — you give it a change and get a verdict, with neither git nor network needed inside.
Taken ready: the RISC5 core and its periphery — Niklaus Wirth, projectoberon.net; the Project Oberon system image; the command-line compiler and the reference emulator — pdewacht.
Ours: the benches and the measuring instrumentation, a RISC5 assembler, the test sets, the browser build, the labs and the handbook. Plus 53 lines of change in the processor's description — the added bounds check instruction, for the sake of which the measurement was undertaken.
We measured what an array bounds check costs: 2.2% of the time. It matters what that does not mean.
This is Oberon, not "in general". The figure belongs to this machine and this work. What travels is the method and the conclusion about spread, not the numbers.
This processor has no cache and no branch prediction. So we measured the same loop elsewhere instead of guessing. The check takes the same two instructions everywhere — compare and branch — but its price differs: on RISC5 those two instructions are two of the loop's eleven cycles, on Apple M4 and AMD EPYC nothing measurable, a steady 2–6% on an Arm Neoverse N2 server core, where this tight loop runs out of issue width; put the check on the critical path and it costs two cycles everywhere, just as on RISC5. Modern compilers usually delete it outright when they can prove the index is in range; Wirth's never does. On CHERI the check lives inside the load and costs no instruction at all. The whole ladder, with every loop body: finding 61 and finding 63.
It was not run on a live board. But it was placed and routed on real FPGA fabric (Lattice ECP5): with wire delays counted, the core holds the design's 25 MHz with room to spare, and the bounds-check instruction does not slow it down. The cycle counts still come from the circuit model, not from a board.
This is no exposé of Wirth. The inconsistencies we found are in the distribution and the auxiliary tools, and some are explained by the history of versions.