π Spigot

Big Numbers

Two algorithms running simultaneously on a real Super Nintendo. The left panel streams decimal digits of π via the Rabinowitz-Wagon spigot — a carry sweep across 76 16-bit cells. The right panel throws random darts at a square and accumulates hits inside the quarter-circle to estimate π by Monte-Carlo. Written in C and compiled to a real .sfc ROM with the llvm-mos-based 65816 toolchain (+mos-a16, 16-bit accumulator mode). Runs automatically — no joypad needed.

loading core…

Self-running demo — digits tick in and darts accumulate automatically.

Click the screen to focus, then watch. Tab away and it pauses.

What it is

The π spigot (Rabinowitz & Wagon, 1995) produces decimal digits of π one at a time using only integer arithmetic — no floating point, no precomputed lookup. Each digit requires one full right-to-left pass through an array of 76 sixteen-bit cells:

x = a[i]×10 + q×i
a[i] = x mod (2i−1)
q    = x div (2i−1)

The carry q propagates left; when it reaches cell zero the algorithm resolves one output digit. The heavy operations — a 32-bit multiply and a combined 32÷32 divide+mod per cell — are what the compiler is being tested on.

Monte-Carlo

The right panel uses a simple probability argument: if you throw darts uniformly at a 1×1 square, the fraction that land inside the quarter-circle of radius 1 is exactly π/4. Each dart is a pair of xorshift16 pseudo-random 16-bit integers; the inside test is x²+y² ≤ r² (a 16×16→32 multiply, another codegen stress).

Compiler stress-test

ItemWhat it exercises
AlgorithmRabinowitz-Wagon π spigot (1995) — right-to-left carry sweep across a 76-element uint16 array with uint32 intermediates; one 32-bit divide + multiply per element per digit
Monte-CarloScatter darts uniformly in a square, count hits inside the quarter-circle; ratio × 4 ≈ π
Compiler stress__udivmodsi4 (combined 32÷32 div+mod) + __mulsi3 (32×32) called in every inner loop; rep/sep mode-switch brackets mark 16-bit sections

Both algorithms run as a portable C header (examples/65816/pi_spigot.h) linked into the SNES ROM and separately into a host oracle; the gate asserts corpus_result (a 16-bit CRC of the first digit pass + 256 MC throws) is identical on host, default 8-bit SNES, +mos-a16, and +mos-xy16 — five-way differential.

Written in C with the llvm-mos 65816 toolchain and verified against two emulators (MAME + bsnes-jg). The player above is that exact cycle-accurate core — hit Verify fidelity to reproduce the build gate's WRAM assert (gate CRC 0x7711) live in this tab. No far pointers, so the same binary is checked five ways: host == default == +mos-a16 == +mos-xy16 == bsnes-jg.