Buddhabrot
Fractals
The Buddhabrot — the Mandelbrot set's
ghost. Random complex points c are iterated z ← z² + c; for the ones
that escape, the entire orbit is replayed and every point it visited is tallied into a
density buffer. Where escaping orbits linger, the buffer glows — and a smoke-like figure emerges
from the noise. The 16 KiB grid lives in high WRAM, written by far scatter-stores. Runs
automatically; the cloud blooms in as samples accumulate. Written in C and compiled with the
llvm-mos-based 65816 toolchain
(+mos-a16, 16-bit accumulator mode).
Self-running demo — the density cloud blooms in over ~1–2 minutes.
Click the screen to focus, then watch. Tab away and it pauses.
What it is
The Mandelbrot set colours each pixel by how fast its orbit escapes. The Buddhabrot
turns that inside out: it forgets where each sample started and instead asks where do
escaping orbits spend their time? Sample a random c, iterate, and if the orbit
escapes within a cap, walk it again and increment a counter at every grid cell it touched. The
accumulated histogram is the Buddhabrot — the probability density of escaping trajectories,
which traces a translucent, meditating-figure silhouette around the set's boundary:
for many random c: // xorshift16 PRNG
z = 0
if iterating z = z²+c escapes within N steps:
z = 0
replay N steps, ++grid[map(z)] // far RMW in high WRAM
draw: grid hit-count → CGRAM brightness (a ghostly glow ramp) On screen the brightest regions are where many escaping orbits cross; the faint blue haze is the sparse outer density. The image is top-bottom symmetric (the set is symmetric about the real axis) — a free correctness check on the math.
Compiler stress-test #4 — PRNG + far scatter-writes
Most fractals in this gallery write each pixel once, in order. The Buddhabrot scatters writes all over a buffer too big for low WRAM — so it is the gallery's far scatter-write member, the one demo whose hot loop hammers the 24-bit far read-modify-write path the rest only touch lightly:
| Item | What it exercises |
|---|---|
| Far scatter-writes | The 128×128 hit-count grid is 16 KiB — far past the ~7.7 KiB of low WRAM — so it lives in high WRAM at $7E2000 and every visited orbit point is a far read-modify-write (lda [dp] / inc / sta [dp]) at a runtime-computed index. This is the #320 24-bit far path, only legal under +mos-a16 |
| PRNG sampling | Each complex sample c is drawn by a 16-bit xorshift generator scaled into the Mandelbrot window with an unsigned 32-bit multiply — deterministic, so host and target agree bit-for-bit |
| Complex multiply ×2 passes | Three Q5.10 16×16→32 multiplies (zr², zi², zr·zi) per iteration, run TWICE per sample: once to test escape, once to replay the orbit and deposit it. The gate object holds __mulsi3/__umulsi3 |
| rep/sep | Native 16-bit accumulator brackets under +mos-a16 — the complex iterands route through the Imag16 zero-page pair as int16; 31 rep / 34 sep across the kernel |
| 3-way bar | A far pointer is a 32-bit value, so the default 8-bit and +mos-xy16 builds cannot legalize it — the differential is host == +mos-a16 on the cycle-accurate bsnes-jg core |
The Buddhabrot logic is a portable C header (examples/65816/buddha.h) linked into
the SNES ROM and a host oracle alike — the same body compiled with 32-bit int on the
host and 16-bit int on the 65816. The gate asserts corpus_result — a
16-bit rotate-XOR hash over the whole density grid after a fixed-seed accumulation — is identical
on both.
Written in C with the llvm-mos 65816 toolchain. Hit Verify fidelity to
reproduce the build gate's WRAM assert (gate hash 0x7C31) live in this tab — the
same hash the host oracle and the cycle-accurate bsnes-jg core agree on for the
+mos-a16 far-pointer build.