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;
17 my ($addrA, $imm, $addrC) = @_;
19 xor_
$addrA, 42, $addrC;
23 my ($addrA, $imm, $addrC) = @_;
25 and_
$addrA, 42, $addrC;
28 # we want everyone to have
30 # own quadrant at mem[0]
31 # east quadrant at mem[11]
32 # south quadrant at mem[12]
33 # SE quadrant at mem[13]
39 chip_select
4, sub { storei
0, 0x247 }; # glider
40 chip_select
$_, sub { ledi
$_ } for 1, 2, 4, 8;
45 chip_select
1, sub { route
0, 11 };
46 chip_select
2, sub { route
11, 12 };
47 chip_select
4, sub { route
12, 13 };
49 chip_select
2, sub { route
0, 13 };
50 chip_select
4, sub { route
13, 12 };
51 chip_select
8, sub { route
12, 11 };
53 chip_select
4, sub { route
0, 11 };
54 chip_select
8, sub { route
11, 12 };
55 chip_select
1, sub { route
12, 13 };
57 chip_select
8, sub { route
0, 13 };
58 chip_select
1, sub { route
13, 12 };
59 chip_select
2, sub { route
12, 11 };
64 alu3 alu_zero
, alu_select_f
, 0, 0, $mem, flag_news
($dir), flag_zero
67 my $and_AB = alu_of_function
{ $a & $b };
69 sub compute_neighbour
{
70 my ($dest, $dir, $mask, $other) = @_;
72 alu3
$and_AB, $and_AB, 0, $dest, $dest, flag_zero
, flag_zero
;
73 news_to_mem
$dir, $dest;
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
81 compute_neighbour
1, 0, 0x0FFF, $q_south;
83 compute_neighbour
2, 1, 0xEEEE, $q_east;
85 compute_neighbour
3, 2, 0xFFF0, $q_south;
87 compute_neighbour
4, 3, 0x7777, $q_east;
89 sub 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;
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
;
106 compute_diagonal_neighbour
5, 4, 0x0777, 0x0888, 0x7000, 0x8000;
109 compute_diagonal_neighbour
6, 5, 0x0EEE, 0x0111, 0xE000, 0x1000;
112 compute_diagonal_neighbour
7, 6, 0xEEE0, 0x1110, 0x000E, 0x0001;
114 # SW neighbour (DODGY)
115 compute_diagonal_neighbour
8, 7, 0x7770, 0x8880, 0x0007, 0x0008;
119 my ($address, $flag) = @_;
120 alu3 alu_zero
, alu_select_f
, 0, 0, $address, $flag, flag_zero
;
123 # now we add bits mem[1] .. mem[8]
124 # result should be mem[1] .. mem[3] (we don't distinguish 8 from 0)
127 # add 1 and 2, 3 and 4, 5 and 6, 7 and 8
128 for my $x (1, 3, 5, 7) {
129 add
$x, $x + 1, $x, $F;
130 flag_to_memory
$x + 1, $F;
133 # add 12 and 34, 56 and 78
135 add
$x, $x + 2, $x, $F;
136 addC
$x + 1, $x + 3, $x + 1, $F;
137 flag_to_memory
$x + 2, $F;
144 alu3 alu_or
, alu_select_a
, 3, 7, 3, $F, $F;
146 # should a new cell be born here? (do we have 3 neighbours?)
147 sub alu_birth
{ alu_of_function
{; $a && $b && !$_ } }
149 # should a living cell survive here? (do we have 2 or 3 neighbours?)
150 sub alu_survival
{ alu_of_function
{; $a && !$_ } }
152 # compute the state of this cell at the next tick
153 sub alu_step
{ alu_of_function
{; $_ & ($a | $b) } }
155 # read from memory 1, and with memory 2 and not F, write into memory 1 (= birth-p)
156 alu3 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)
158 alu3 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
160 alu3 alu_zero
, alu_step
, 0, 1, 0, $F, $F; # also zeroes out flag F