#include #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; }