Add diagrams and pictures
[clump.git] / bigone.pl
CommitLineData
46a95fd3
MG
1#!/usr/bin/perl
2use v5.14;
3use warnings;
4use lib '.';
5
6use asm;
7
8sub update_leds {
9 my ($x) = @_;
10 route $x + 0, $x + 1, 4;
11 route $x + 1, $x + 2, 3;
12 route $x + 2, $x + 3, 2;
13 route $x + 3, $x + 4, 1;
14}
15
16sub xori {
17 my ($addrA, $imm, $addrC) = @_;
18 storei 42, $imm;
19 xor_ $addrA, 42, $addrC;
20}
21
22sub andi {
23 my ($addrA, $imm, $addrC) = @_;
24 storei 42, $imm;
25 and_ $addrA, 42, $addrC;
26}
27
28# we want everyone to have
29#
30# own quadrant at mem[0]
31# east quadrant at mem[11]
32# south quadrant at mem[12]
33# SE quadrant at mem[13]
34
35my $q_east = 11;
36my $q_south = 12;
37my $q_SE = 13;
38
39chip_select 4, sub { storei 0, 0x247 }; # glider
40chip_select $_, sub { ledi $_ } for 1, 2, 4, 8;
41
42
43update_leds 0;
44
45chip_select 1, sub { route 0, 11 };
46chip_select 2, sub { route 11, 12 };
47chip_select 4, sub { route 12, 13 };
48
49chip_select 2, sub { route 0, 13 };
50chip_select 4, sub { route 13, 12 };
51chip_select 8, sub { route 12, 11 };
52
53chip_select 4, sub { route 0, 11 };
54chip_select 8, sub { route 11, 12 };
55chip_select 1, sub { route 12, 13 };
56
57chip_select 8, sub { route 0, 13 };
58chip_select 1, sub { route 13, 12 };
59chip_select 2, sub { route 12, 11 };
60
61
62sub news_to_mem {
63 my ($dir, $mem) = @_;
64 alu3 alu_zero, alu_select_f, 0, 0, $mem, flag_news($dir), flag_zero
65}
66
67my $and_AB = alu_of_function { $a & $b };
68
69sub compute_neighbour {
70 my ($dest, $dir, $mask, $other) = @_;
71 storei $dest, $mask;
72 alu3 $and_AB, $and_AB, 0, $dest, $dest, flag_zero, flag_zero;
73 news_to_mem $dir, $dest;
74
75 storei $dest + 1, 0xFFFF - $mask;
76 alu3 $and_AB, $and_AB, $other, $dest + 1, $dest + 1, flag_zero, flag_zero;
77 alu3 alu_zero, alus_addAF, $dest, 0, $dest, flag_news($dir), flag_zero
78}
79
80# N neighbour
81compute_neighbour 1, 0, 0x0FFF, $q_south;
82# E neighbour
83compute_neighbour 2, 1, 0xEEEE, $q_east;
84# S neighbour
85compute_neighbour 3, 2, 0xFFF0, $q_south;
86# W neighbour
87compute_neighbour 4, 3, 0x7777, $q_east;
88
89sub compute_diagonal_neighbour {
90 my ($dest, $dir, @masks) = @_;
91 die 'expected exactly 4 @masks' unless @masks == 4;
92 storei $dest, $masks[0];
93 alu3 $and_AB, alu_select_a, 0, $dest, 0, flag_zero, flag_zero;
94 news_to_mem $dir, $dest;
95
96 for my $quad (1 .. 3) {
97 storei $dest + 1, $masks[$quad];
98 alu3 $and_AB, alu_select_a, 10 + $quad, $dest + 1, 10 + $quad, flag_zero, flag_zero;
99 alu3 alu_zero, alus_addAF, $dest, 0, $dest, flag_news($dir), flag_zero;
100 }
101}
102
103#update_leds $q_SE;
104
105# NW neighbour
106compute_diagonal_neighbour 5, 4, 0x0777, 0x0888, 0x7000, 0x8000;
107#update_leds 5;
108# NE neighbour
109compute_diagonal_neighbour 6, 5, 0x0EEE, 0x0111, 0xE000, 0x1000;
110#update_leds 6;
111# SE neighbour
112compute_diagonal_neighbour 7, 6, 0xEEE0, 0x1110, 0x000E, 0x0001;
113#update_leds 7;
114# SW neighbour (DODGY)
115compute_diagonal_neighbour 8, 7, 0x7770, 0x8880, 0x0007, 0x0008;
116#update_leds 8;
117
118sub flag_to_memory {
119 my ($address, $flag) = @_;
120 alu3 alu_zero, alu_select_f, 0, 0, $address, $flag, flag_zero;
121}
122
123# now we add bits mem[1] .. mem[8]
124# result should be mem[1] .. mem[3] (we don't distinguish 8 from 0)
125my $F = 1;
126
127# add 1 and 2, 3 and 4, 5 and 6, 7 and 8
128for my $x (1, 3, 5, 7) {
129 add $x, $x + 1, $x, $F;
130 flag_to_memory $x + 1, $F;
131}
132
133# add 12 and 34, 56 and 78
134for my $x (1, 5) {
135 add $x, $x + 2, $x, $F;
136 addC $x + 1, $x + 3, $x + 1, $F;
137 flag_to_memory $x + 2, $F;
138}
139
140# add 12 and 56
141add 1, 5, 1, $F;
142addC 2, 6, 2, $F;
143# F = F | 3 | 7
144alu3 alu_or, alu_select_a, 3, 7, 3, $F, $F;
145
146# should a new cell be born here? (do we have 3 neighbours?)
147sub alu_birth { alu_of_function {; $a && $b && !$_ } }
148
149# should a living cell survive here? (do we have 2 or 3 neighbours?)
150sub alu_survival { alu_of_function {; $a && !$_ } }
151
152# compute the state of this cell at the next tick
153sub alu_step { alu_of_function {; $_ & ($a | $b) } }
154
155# read from memory 1, and with memory 2 and not F, write into memory 1 (= birth-p)
156alu3 alu_zero, alu_birth, 1, 2, 1, $F, flag_zero;
157# read from memory 2, and with flag not F, write into flag F (= survive-p)
158alu3 alu_survival, alu_select_a, 2, 0, 2, $F, $F;
159# read from memory 0, memory 1, and flag F, write F and (mem0 or mem1) into memory 0
160alu3 alu_zero, alu_step, 0, 1, 0, $F, $F; # also zeroes out flag F
This page took 0.018692 seconds and 4 git commands to generate.