Mandelbrot Set

Developer(s): William J. Pedersen
Date: 1985
Type: Program
Platform(s): TS 2068

This program renders the Mandelbrot set on a character-cell display using a string of 120 characters as a lookup table to map iteration counts to display symbols. The outer loops step through a 32×22 grid of complex-plane coordinates defined by user-supplied left edge, bottom edge, and top limit values, computing the step size automatically. Each point iterates the standard Mandelbrot recurrence (z² + c) up to 119 times, terminating early when the escape radius squared exceeds 4. The iteration count drives both the character chosen from `w$` and a BRIGHT/PAPER color scheme calculated with integer division to produce alternating brightness bands across seven paper colors.


Program Structure

The program is compact at six executable lines (20–120) plus two REM lines and a SAVE. Line 20 initializes all working variables to zero in a chained LET sequence. Line 50 collects three user inputs (le, be, top) and derives the grid step w. Lines 70–110 form the nested rendering loop. Line 120 halts execution, and line 130 provides a one-line tape save.

Coordinate Grid

The outer loop (j, line 70) runs from −1 to 20, giving 22 rows; the inner loop (k, line 80) runs 0–31, giving 32 columns. The complex coordinate for each cell is:

  • Real part: a = le + k*w
  • Imaginary part: b = top - j*w

Starting j at −1 prints an extra row above the nominal top, which acts as an unlabeled header row — a minor quirk that shifts the displayed grid slightly upward.

Mandelbrot Iteration

Lines 90–100 implement the standard Mandelbrot recurrence. The squared real part is accumulated in xx to avoid recomputing it:

  • xx = x*x - y*y + a (new real part)
  • y = 2*x*y + b (new imaginary part)
  • z = xx*xx + y*y (magnitude squared, compared to 4)

If z > 4 the loop exits immediately to line 110. Otherwise n is decremented and x is updated from xx; iteration continues while n is nonzero (the IF n THEN GO TO 90 idiom). Points that never escape leave n = 0.

Character Lookup Table

The string w$ (line 40) contains 120 characters. After iteration, w$(n+1) is printed, so a point that escapes immediately (high n) prints characters near the end of the string, and a point that never escapes (n = 0) prints w$(1), which is a solid block graphic. The string progresses from dense block graphics through sparse graphics, spaces, punctuation, letters, and symbol characters, providing a visual gradient from set interior outward.

The string includes ZX81/TS1000 block graphic characters (▙, ▗, ▘, ▝, ▌, ▖, ▞, ▛) interspersed with ASCII punctuation and letters, creating a smooth perceived density gradient on a character-cell display.

Color Banding

Line 110 maps n to color attributes using integer arithmetic:

  • col = INT((119 - n) / 9) — produces values 0–13 across the 0–119 range
  • BRIGHT col - 2*INT(col/2) — extracts the low bit of col, giving alternating BRIGHT 0 / BRIGHT 1
  • PAPER 1 + INT(col/2) — steps through paper colors 1–7 (red through white), changing every two col steps

This scheme produces 14 distinct color/brightness combinations without any array or lookup table, relying entirely on arithmetic.

Key BASIC Idioms

  • Chained LET initialization in line 20 reduces line count.
  • IF n THEN GO TO 90 uses a numeric truth test (zero = false) instead of a comparison operator.
  • The INPUT statement uses the ' separator to prompt across multiple lines without separate PRINT statements.
  • NEXT k:NEXT j on the same line keeps the loop structure compact.

Notable Observations

The variable be (bottom edge) is collected in the INPUT but never used in the loop — the grid is defined entirely by top, le, and the derived step w = (top - be) / 20. The bottom edge therefore only indirectly controls the vertical scale via w. This means the user must correctly coordinate all three inputs to produce a properly proportioned view.

The REM on line 10 embeds a control-code character (character 16 followed by character 0, a color-setting token sequence) before the descriptive text, suggesting this line may have been intended for a display-formatting purpose on the original system.

Source Code

  10 REM \{16}\{0}Mandelbrot set by W.J.Pederson CTM 12/85 tape name BROTbroERr
  20 CLS :LET x=0:LET y=x:LET xx=x:LET a=x:LET b=x
  30 REM vary n and w$ for different effects
  40 LET n=119:LET w$="\::             :::::::::::::............./////////////xxxxxxxxxxxxx%%%%%%%%%%%%%#############\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.'\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:\.:??????"
  50 INPUT "left edge=";le'"bottom edge=";be'"top limits=";top:LET w=(top-be)/20
  60 PRINT "top limit ";top'"left edge ";le'"bottom edge ";be''
  70 FOR j=-1 TO 20:LET b=top-j*w
  80 FOR k=0 TO 31:LET a=le+k*w:LET x=0:LET y=x:LET n=119
  90 LET xx=x*x-y*y+a:LET y=2*x*y+b:LET z=xx*xx+y*y:IF z>4 THEN GO TO 110
 100 LET n=n-1:LET x=xx:IF n THEN GO TO 90
 110 LET col= INT ((119-n)/9):PRINT BRIGHT col-2* INT (col/2); PAPER 1+ INT (col/2);w$(n+1);:NEXT k:NEXT j
 120 STOP 
 130 SAVE "BROTbroERr" LINE 10

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.