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).

loading core…

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:

ItemWhat it exercises
Far scatter-writesThe 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 samplingEach 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 passesThree 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/sepNative 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 barA 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.