Julia Set Explorer

Fractals

A Julia setz² + c iterated to escape — computed live on a Super Nintendo in Q5.10 fixed point. The constant c orbits the classic 0.7885·e path, so the fractal continuously morphs between connected blobs and scattered dust, while Mode 7 spins and zoom-breathes it and the palette cycles. Runs automatically; no joypad needed. Written in C and compiled with the llvm-mos-based 65816 toolchain (+mos-a16, 16-bit accumulator mode).

loading core…

Self-running demo — the set morphs and spins automatically. (Boot takes a few seconds to grind the first frame.)

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

What it is

A Julia set is the escape-time picture of iterating z ← z² + c for a fixed complex constant c, colouring each starting point by how fast it flies to infinity. It is the close cousin of the Mandelbrot set: Mandelbrot fixes z₀ = 0 and varies c per pixel; Julia fixes c for the whole image and lets the pixel be z₀. Slide c and the set transforms — that slide is the animation here:

z = (zr, zi) = pixel        // Q5.10 fixed point, 1.0 == 1024
for n in 0..maxiter:
    zr2 = (zr*zr) >> 10 ;  zi2 = (zi*zi) >> 10     // two __mulsi3
    if zr2 + zi2 > 4.0: break                       // escaped
    zi = 2*((zr*zi) >> 10) + ci                     // one __mulsi3
    zr =   zr2 - zi2      + cr
// escape count n = pixel colour ;  c sweeps 0.7885·e^iθ

Each frame the 65816 grinds that loop over the image and far-stores every pixel into a high-WRAM buffer at $7E2000 — memory only reachable through 24-bit addressing, the #320 far-pointer path (sta [dp]) — then far-loads it back into Mode 7 character VRAM. Because a full recompute is seconds of fixed-point multiply, the set is re-ground a row at a time in the background while the Mode 7 affine matrix spins and zoom-breathes it at 60 fps: the multiply is the morph, the hardware is the motion.

Compiler stress-test #1 — complex multiply + the far framebuffer

Every iteration issues three 32-bit multiplies and the whole image lives in far high WRAM, so this demo leans on exactly the two things +mos-a16 exists for: the __mulsi3 16×16→32 multiply in native-16 mode, and the 24-bit far store/load path.

ItemWhat it exercises
Q5.10 complex multiplyThe hot loop is z = z² + c in signed Q5.10 fixed point — three 16×16→32 multiplies per iteration (zr², zi², zr·zi), each a __mulsi3 libcall, with zr/zi held live across the loop
Far high-WRAM framebufferThe 64×56 escape image lives at $7E2000 — high WRAM reachable only by 24-bit addressing. Filling it is the #320 far-store path (sta [dp]); reading it back to VRAM is far loads (lda [dp]). a16-only
rep/sepNative 16-bit accumulator brackets under +mos-a16: the int16 values route through the Imag16 zero-page pair, entered/left with rep #$20 / sep #$20 around each native-16 op (46 in the gate object)
z₀ = pixel, c = constantThe Julia twist on the same kernel as the Mandelbrot demo: there c is per-pixel and z₀=0; here z₀ is the pixel and c is one constant per frame, swept along the 0.7885·e^{iθ} orbit so the set morphs
Grind is the morph, matrix is the motionA full 64×56 escape-time recompute is ~22 s on the 65816, so the set is re-ground one coarse row per spin frame in the background; Mode 7's hardware affine transform does the rotation/zoom at 60 fps

The Julia kernel is a portable C header (examples/65816/julia.h) linked into the SNES ROM, a host oracle, and the corpus differential slice alike. The gate folds the escape buffers of four keyframe c values into corpus_result, a 16-bit rotate-XOR CRC that must be identical on host (32-bit int) and target (16-bit int) — which holds only because every product is forced through int32_t and every narrowing is an explicit fixed-width cast.

Written in C with the llvm-mos 65816 toolchain. Hit Verify fidelity to reproduce the build gate's WRAM assert (gate CRC 0x3490) live in this tab — the same hash the host oracle and the cycle-accurate bsnes-jg core agree on. The disasm gate proves the shape: __mulsi3 = 3 (the three Q5.10 products), rep/sep = 46 — native 16-bit complex multiply.