Урок 6 (бонус). Munching Squares: живой узор 1962 года
В картинкахПосле этого урока на третьем экране оживёт узор из «жующих» квадратов — одна из первых компьютерных анимаций. В 1962 году её написали программой на PDP-1, мы соберём её логикой.
6.1. Идея: (x XOR y) < t
Точка горит, если (x XOR y) < t, а t растёт на 1 после каждого кадра. При маленьком t горит узкая полоса вдоль диагонали, с каждым кадром от неё отрастают квадраты, «съедают» экран — и всё начинается снова.
t— ещё одинCNT6, он считает кадры; шаг ему разрешаетcy— перенос счётчика строки на последней точке кадра;x XOR y— 6XOR;v < t— цепочка сравнения от младшего разряда к старшему: разряд говорит «меньше», если у негоv = 0, t = 1, а если разряды равны — передаёт ответ младших.
6.2. Сборка
Тот же проект: развёртка, треугольник и «игра в хаос» остаются, рядом встаёт третий экран.
История. В 1962 году в MIT на компьютере PDP-1 написали несколько строк, которые рисовали на экране узор из «жующих» квадратов — Munching Squares, одна из первых компьютерных анимаций. Правило простое: точка горит, если (x XOR y) < t, а t растёт на 1 после каждого кадра. Мы соберём то же самое без программы — одной логикой.
Как собрать.
t— ещё одинCNT6: он считает кадры. Шаг ему разрешаетcy— перенос счётчика строки, он горит на последней точке кадра.x XOR y— 6XOR, по разряду.v < t— сравнение. Сравнивают числа как в словаре: идут от старшего разряда, первый разряд, где они разные, решает. Удобнее собрать цепочку от младшего: каждый разряд говорит «меньше», если у негоv = 0, t = 1, а если разряды равны — передаёт ответ младших. Последний, старший, и выдаёт ответ.
| v | t | Сравнение по разрядам (старший слева) | v < t |
|---|---|---|---|
| 5 = 000101 | 6 = 000110 | разряд 1: v = 0, t = 1 — и старше равны | да |
| 6 = 000110 | 5 = 000101 | разряд 1: v = 1, t = 0 | нет |
| 3 = 000011 | 3 = 000011 | все равны — от младших пришло 0 | нет |
Шаг 1. CMP1 — сравнение одного разряда
| Деталь | Нога | Метка |
|---|---|---|
| Порт входа | выход | V |
| Порт входа | выход | T |
| Порт входа | выход | LI |
| NOT | I0 O0 | V nv |
| AND (здесь меньше) | I0 I1 O0 | nv T lt |
| XOR (разные?) | I0 I1 O0 | V T ne |
| NOT | I0 O0 | ne eq |
| AND (равны — решают младшие) | I0 I1 O0 | eq LI pass |
| OR | I0 I1 O0 | lt pass LO |
| Порт выхода | вход | LO |
Ctrl+G → имя CMP1. Ноги: входы V, T, LI (ответ младших); выход LO.
Шаг 2. Холст: счётчик кадров, XOR, цепочка сравнения, третий экран
| Деталь | Нога | Метка |
|---|---|---|
| CNT6 (кадры t) | CLK EN RST Q0 Q1 Q2 Q3 Q4 Q5 CO | CLK cy RST t0 t1 t2 t3 t4 t5 ct |
| XOR (разряд 0) | I0 I1 O0 | x0 y0 v0 |
| XOR (разряд 1) | I0 I1 O0 | x1 y1 v1 |
| XOR (разряд 2) | I0 I1 O0 | x2 y2 v2 |
| XOR (разряд 3) | I0 I1 O0 | x3 y3 v3 |
| XOR (разряд 4) | I0 I1 O0 | x4 y4 v4 |
| XOR (разряд 5) | I0 I1 O0 | x5 y5 v5 |
| CMP1 (разряд 0) | V T LI LO | v0 t0 GND l1 |
| CMP1 (разряд 1) | V T LI LO | v1 t1 l1 l2 |
| CMP1 (разряд 2) | V T LI LO | v2 t2 l2 l3 |
| CMP1 (разряд 3) | V T LI LO | v3 t3 l3 l4 |
| CMP1 (разряд 4) | V T LI LO | v4 t4 l4 l5 |
| CMP1 (разряд 5) | V T LI LO | v5 t5 l5 ms |
| Dot display (третий) | 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 у младшего разряда — GND: если все разряды равны, v не меньше t.
6.3. Проверка
| № | Что сделать | Что видно |
|---|---|---|
| 1 | третий экран — те же настройки (Dots, 64 × 64, 1 dot) | — |
| 2 | RST = 1, один такт, RST = 0; генератор MAX | на третьем экране из диагонали растут квадраты, «съедают» экран и начинают снова |
| 3 | генератор 4kHz | видно, как каждый кадр рисуется заново с новым t |
Если квадраты не растут — проверь EN счётчика кадров: он на cy. Если узор «рваный» — проверь цепочку CMP1: LO каждого разряда идёт на LI следующего, а V/T — разряды одного номера.
Вставка урока 6 (Cmd+I)
Нужны NOT, AND, OR, XOR, CNT6; метки x0–x5, y0–y5, cy, CLK, nCLK, RST — с урока 3.
# Урок 6 (бонус) — Munching Squares (MIT, PDP-1, 1962): точка горит, если (x XOR y) < t; t растёт на 1 каждый кадр.# Вставка: Cmd+I поверх урока 5 (нужны NOT, AND, OR, XOR, CNT6; x0–x5, y0–y5, cy, CLK, nCLK, RST — с урока 3). # --- сравнение одного разряда: v < t по этому и младшим разрядам ---# если разряды разные — решает этот разряд (v = 0, t = 1 → меньше); если равны — то, что пришло от младших (LI)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)} # --- на холст: счётчик кадров t, узор (x XOR y) < t, третий экран ---# t считает кадры: шаг — на последней точке кадра (перенос счётчика строки cy)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)Не получается? Что-то не работает →