diff options
Diffstat (limited to 'wire.c')
-rw-r--r-- | wire.c | 106 |
1 files changed, 106 insertions, 0 deletions
@@ -0,0 +1,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; +} + |