Lesson 6 (bonus). Munching Squares: a living pattern from 1962

In pictures

After this lesson a pattern of "munching" squares comes alive on the third screen — one of the first computer animations. In 1962 it was a program on the PDP-1; we build it from logic.


6.1. The idea: (x XOR y) < t

A dot is lit if (x XOR y) < t, and t grows by 1 after every frame. With a small t a narrow band along the diagonal is lit; with every frame squares grow from it, "eat" the screen — and it all starts again.

t = 4t = 12t = 28t = 48
Munching Squares frames: at t = 4 a band along the diagonal is lit, and with every frame bigger and bigger squares grow from it. At t = 64 the whole screen is lit, then t is 0 again.
  • t is one more CNT6, it counts frames; its step is allowed by cy — the row counter carry on the last dot of the frame;
  • x XOR y — 6 XOR gates;
  • v < t — a comparison chain from the lowest bit to the top: a bit says "less" if it has v = 0, t = 1, and if the bits are equal it passes on the answer of the lower bits.

6.2. Building

The same project: the scan, the triangle and the chaos game stay, a third screen goes next to them.

History. In 1962 at MIT a few lines on the PDP-1 drew a pattern of "munching" squares — Munching Squares, one of the first computer animations. The rule is simple: a dot is lit if (x XOR y) < t, and t grows by 1 after every frame. We build the same thing with no program — just logic.

How to build it.

  • t is one more CNT6: it counts frames. Its step is allowed by cy — the row counter carry, lit on the last dot of the frame.
  • x XOR y — 6 XOR gates, one per bit.
  • v < t — comparison. Numbers are compared like words in a dictionary: from the top bit, the first bit where they differ decides. It is easier to build a chain from the lowest bit: each bit says "less" if it has v = 0, t = 1, and if the bits are equal it passes on the answer of the lower bits. The last, top one gives the answer.
vtBit by bit (top bit on the left)v < t
5 = 0001016 = 000110bit 1: v = 0, t = 1 — and the higher bits are equalyes
6 = 0001105 = 000101bit 1: v = 1, t = 0no
3 = 0000113 = 000011all equal — 0 came from the lower bitsno

Step 1. CMP1 — comparing one bit

PartPinLabel
Input portoutV
Input portoutT
Input portoutLI
NOTI0
O0
V
nv
AND (less here)I0
I1
O0
nv
T
lt
XOR (different?)I0
I1
O0
V
T
ne
NOTI0
O0
ne
eq
AND (equal — lower bits decide)I0
I1
O0
eq
LI
pass
ORI0
I1
O0
lt
pass
LO
Output portinLO

Ctrl+G → name CMP1. Pins: inputs V, T, LI (the answer of the lower bits); output LO.

Step 2. Canvas: frame counter, XOR, comparison chain, third screen

PartPinLabel
CNT6 (frames t)CLK
EN
RST
Q0
Q1
Q2
Q3
Q4
Q5
CO
CLK
cy
RST
t0
t1
t2
t3
t4
t5
ct
XOR (bit 0)I0
I1
O0
x0
y0
v0
XOR (bit 1)I0
I1
O0
x1
y1
v1
XOR (bit 2)I0
I1
O0
x2
y2
v2
XOR (bit 3)I0
I1
O0
x3
y3
v3
XOR (bit 4)I0
I1
O0
x4
y4
v4
XOR (bit 5)I0
I1
O0
x5
y5
v5
CMP1 (bit 0)V
T
LI
LO
v0
t0
GND
l1
CMP1 (bit 1)V
T
LI
LO
v1
t1
l1
l2
CMP1 (bit 2)V
T
LI
LO
v2
t2
l2
l3
CMP1 (bit 3)V
T
LI
LO
v3
t3
l3
l4
CMP1 (bit 4)V
T
LI
LO
v4
t4
l4
l5
CMP1 (bit 5)V
T
LI
LO
v5
t5
l5
ms
Dot display (third)X0
X1
X2
X3
X4
X5
Y0
Y1
Y2
Y3
Y4
Y5
D0
WE
CLK
CLR
x0
x1
x2
x3
x4
x5
y0
y1
y2
y3
y4
y5
ms
VCC
nCLK
GND

LI of the lowest bit is GND: if all bits are equal, v is not less than t.

6.3. Check

№What to doWhat you see
1third screen — same settings (Dots, 64 × 64, 1 dot)—
2RST = 1, one clock, RST = 0; clock at MAXon the third screen squares grow from the diagonal, "eat" the screen and start again
3clock at 4kHzyou can see every frame redrawn with a new t

If the squares do not grow, check the frame counter EN: it is on cy. If the pattern is "torn", check the CMP1 chain: the LO of each bit goes to the LI of the next, and V/T are bits with the same number.


Lesson 6 paste (Cmd+I)

Needs NOT, AND, OR, XOR, CNT6; the labels x0–x5, y0–y5, cy, CLK, nCLK, RST come from lesson 3.

# Lesson 6 (bonus) — Munching Squares: (x XOR y) < t, t counts frames.chip CMP1 {  portIn(V)  portIn(T)  portIn(LI)  portOut(LO)  NOT(V, nv)  AND(nv, T, lt)  XOR(V, T, ne)  NOT(ne, eq)  AND(eq, LI, pass)  OR(lt, pass, LO)} CNT6(CLK=CLK, EN=cy, RST=RST, Q0=t0, Q1=t1, Q2=t2, Q3=t3, Q4=t4, Q5=t5, CO=ct)XOR(x0, y0, v0)XOR(x1, y1, v1)XOR(x2, y2, v2)XOR(x3, y3, v3)XOR(x4, y4, v4)XOR(x5, y5, v5)CMP1(V=v0, T=t0, LI=GND, LO=l1)CMP1(V=v1, T=t1, LI=l1, LO=l2)CMP1(V=v2, T=t2, LI=l2, LO=l3)CMP1(V=v3, T=t3, LI=l3, LO=l4)CMP1(V=v4, T=t4, LI=l4, LO=l5)CMP1(V=v5, T=t5, LI=l5, LO=ms)dotdisplay SCR3{layout=dots, w=64, h=64}(X0=x0, X1=x1, X2=x2, X3=x3, X4=x4, X5=x5, Y0=y0, Y1=y1, Y2=y2, Y3=y3, Y4=y4, Y5=y5, D0=ms, WE=VCC, CLK=nCLK, CLR=GND)

Stuck? Something doesn't work →