blob: e181d83725310fc12c8ef74eaf7de3585c1588c7 (
plain)
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
|
#include <string.h>
#include "wire.h"
#include "error.h"
#define WIRE_MAX 1024
#define NODE_MAX 1024
static size_t wire_count;
static size_t node_count;
static struct wire wires[WIRE_MAX];
static struct node nodes[NODE_MAX];
int
wire_count_guard(void) {
if (wire_count >= WIRE_MAX) {
emit_error("Internal: too many wires\n");
}
return 1;
}
/* check if the nodes in a wire are allowed to be joined together */
int
wire_nodes_valid(struct wire *w) {
/* FIXME needs to be more explicit if more than NODE_OUTPUT and NODE_INPUT
* out are added to node types */
if (w->b->type == w->b->type) {
emit_error("Cannot wire %sput to node of same type\n",
w->a->type == NODE_OUTPUT ? "out" : "in" );
return 1;
}
return 0;
}
int
wire_add(size_t aoffs, size_t boffs) {
struct wire w = {0};
if (wire_count_guard()) {
return 1;
}
if (aoffs >= NODE_MAX || boffs >= NODE_MAX) {
emit_error("Internal: cannot wire between node(s) outside allowable range\n");
return 1;
}
/* FIXME check that nodes are initialised? */
w.a = &nodes[aoffs];
w.b = &nodes[boffs];
if (wire_nodes_valid(&w)) {
return 1;
}
wires[wire_count++] = w;
return 0;
}
int
node_update(void) {
size_t i = 0;
struct node *na;
struct node *nb;
if (wire_count_guard()) {
return 1;
}
for (i = 0; i < wire_count; i++) {
na = wires[i].a;
nb = wires[i].b;
if (na->type == NODE_OUTPUT && nb->type == NODE_INPUT) {
nb->value = na->value;
}
if (na->type == NODE_INPUT && nb->type == NODE_OUTPUT) {
na->value = nb->value;
}
}
return 0;
}
int
tick(void) {
nodes[0].value = logic_not(nodes[0].value);
node_update();
return 0;
}
void
wire_init(void) {
wire_count = 0;
memset(wires, 0, sizeof(wires));
memset(nodes, 0, sizeof(nodes));
/* zeroth node is the clock source */
node_count = 1;
nodes[0].type = NODE_OUTPUT;
nodes[0].value = 0;
}
|