-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
153 lines (118 loc) · 3.1 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* The Game of Life
*
* Using 32x32 LED panel, picorv32 and icoboard.
*
* Original code: http://www.cs.utexas.edu/users/djimenez/utsa/cs1713-3/c/life.txt
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* dimensions of the screen */
#define BOARD_WIDTH 31
#define BOARD_HEIGHT 31
/* set pixel function */
static inline void setled(int v)
{
*(volatile uint32_t*)0x20000000 = v;
}
void set_pixel(int x, int y, uint8_t c) //uint8_t r, uint8_t g, uint8_t b)
{
if (0 <= x && x < 32 && 0 <= y && y < 32)
{
//uint32_t rgb = (r << 16) | (g << 8) | b;
uint32_t rgb = c ? 65535 : 0;
uint32_t addr = 4*x + 128*y + 0x10000000;
*(volatile uint32_t*)addr = rgb;
}
}
uint32_t i, j;
/* set everthing to random values */
void initialize(int board[][BOARD_HEIGHT])
{
for (i = 0; i < BOARD_WIDTH; i++)
for (j = 0; j < BOARD_HEIGHT; j++)
board[i][j] = !(rand() % 9);
}
/* add to a width index, wrapping around like a cylinder */
int xadd(int i, int a)
{
i += a;
while (i < 0) i += BOARD_WIDTH;
while (i >= BOARD_WIDTH) i -= BOARD_WIDTH;
return i;
}
/* add to a height index, wrapping around */
int yadd(int i, int a)
{
i += a;
while (i < 0) i += BOARD_HEIGHT;
while (i >= BOARD_HEIGHT) i -= BOARD_HEIGHT;
return i;
}
/* return the number of on cells adjacent to the i,j cell */
int adjacent_to(int board[][BOARD_HEIGHT], int i, int j)
{
int k, l, count;
count = 0;
/* go around the cell */
for (k = -1; k <= 1; k++) for (l = -1; l <= 1; l++)
/* only count if at least one of k,l isn't zero */
if (k || l)
if (board[xadd(i,k)][yadd(j,l)]) count++;
return count;
}
void play(int board[][BOARD_HEIGHT])
{
/*
(copied this from some web page, hence the English spellings...)
1.STASIS : If, for a given cell, the number of on neighbours is
exactly two, the cell maintains its status quo into the next
generation. If the cell is on, it stays on, if it is off, it stays off.
2.GROWTH : If the number of on neighbours is exactly three, the cell
will be on in the next generation. This is regardless of the cell's
current state.
3.DEATH : If the number of on neighbours is 0, 1, 4-8, the cell will
be off in the next generation.
*/
int a, newboard[BOARD_WIDTH][BOARD_HEIGHT];
/* for each cell, apply the rules of Life */
for (i = 0; i < BOARD_WIDTH; i++)
for (j = 0; j < BOARD_HEIGHT; j++)
{
a = adjacent_to(board, i, j);
if (a == 2) newboard[i][j] = board[i][j];
if (a == 3) newboard[i][j] = 1;
if (a < 2) newboard[i][j] = 0;
if (a > 3) newboard[i][j] = 0;
}
/* copy the new board back into the old board */
for (i = 0; i < BOARD_WIDTH; i++)
for (j = 0; j < BOARD_HEIGHT; j++)
board[i][j] = newboard[i][j];
}
/* print the life board */
void print(int board[][BOARD_HEIGHT])
{
for (i = 0; i < BOARD_WIDTH; i++)
for (j = 0; j < BOARD_HEIGHT; j++)
set_pixel(i, j, board[i][j]);
}
/* main program */
void main()
{
int board[BOARD_WIDTH][BOARD_HEIGHT];
for (i = 0; i < 32; i++)
for (j = 0; j < 32; j++)
set_pixel(i, j, 0);
initialize(board);
print(board);
while(1)
{
play(board);
print(board);
//for (int i = 0; i < 1000; i++)
// asm volatile ("");
}
}