summaryrefslogtreecommitdiffstats
path: root/tpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'tpu.c')
-rw-r--r--tpu.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/tpu.c b/tpu.c
index a221349..512c28d 100644
--- a/tpu.c
+++ b/tpu.c
@@ -1,6 +1,7 @@
#include "tpu.h"
#include "util.h"
+#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
#include <stddef.h>
@@ -53,7 +54,7 @@ djb_hash(const char *str)
hash = 5381;
for (c = str; *c; c++)
- hash = 33 * hash + (uint8_t) *c;
+ hash = 33 * hash + (uint8_t) tolower(*c);
return hash;
}
@@ -97,6 +98,7 @@ bool
label_map_add(struct label_map *map, const char *name, size_t pc)
{
struct label_map_link **pos, *link;
+ char *c;
pos = label_map_link_pos(map, name);
if (*pos) return false;
@@ -105,6 +107,8 @@ label_map_add(struct label_map *map, const char *name, size_t pc)
if (!link) die("malloc:");
link->label = strdup(name);
if (!link->label) die("strdup:");
+ for (c = link->label; *c; c++)
+ *c = (char) tolower(*c);
link->pc = pc;
link->next = NULL;
@@ -175,7 +179,7 @@ tpu_deinit(struct tpu *tpu)
label_map_deinit(&tpu->labels);
for (i = 0; i < TPU_MAX_INST; i++) {
if (tpu->insts[i].ops[0].type == OP_LABEL)
- free(tpu->insts[i].ops[0].label);
+ free(tpu->insts[i].ops[0].val.label);
}
}
@@ -255,7 +259,8 @@ tpu_update_ports(struct tpu *tpu)
bool
tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst_type,
- int op1, uint8_t op1_lit, int op2, uint8_t op2_lit)
+ int op1, union tpu_inst_op_val v1,
+ int op2, union tpu_inst_op_val v2)
{
struct tpu_inst *inst;
@@ -264,13 +269,13 @@ tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst_type,
if (op2 >= 0) {
inst->ops[1].type = (enum tpu_inst_op_type) op2;
- inst->ops[1].lit = op2_lit;
+ inst->ops[1].val = v1;
inst->ops[0].type = (enum tpu_inst_op_type) op1;
- inst->ops[0].lit = op1_lit;
+ inst->ops[0].val = v2;
inst->opcnt = 2;
} else if (op1 >= 0) {
inst->ops[0].type = (enum tpu_inst_op_type) op1;
- inst->ops[0].lit = op1_lit;
+ inst->ops[0].val = v1;
inst->opcnt = 1;
} else {
inst->opcnt = 0;
@@ -300,13 +305,14 @@ tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst_type,
bool
tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst_type,
- int op1, uint8_t op1_lit, int op2, uint8_t op2_lit)
+ int op1, union tpu_inst_op_val v1,
+ int op2, union tpu_inst_op_val v2)
{
- if (tpu->inst_cnt == TPU_MAX_INST)
- die("tpu_add_inst: tpu X%lu Y%lu, too many instructions",
- tpu->x, tpu->y);
- return tpu_set_inst(tpu, (uint8_t) tpu->inst_cnt++, inst_type,
- op1, op1_lit, op2, op2_lit);
+ if (tpu->inst_cnt >= TPU_MAX_INST)
+ die("tpu_add_inst: tpu X%lu Y%lu, >= max %i instructions",
+ tpu->x, tpu->y, TPU_MAX_INST);
+ return tpu_set_inst(tpu, (uint8_t) tpu->inst_cnt++,
+ inst_type, op1, v1, op2, v2);
}
/* tpu can always write to an empty port (->out), but only
@@ -385,7 +391,7 @@ tpu_exec_get(struct tpu *tpu, struct tpu_inst_op *op)
if (tpu->last < 0) return 0;
return tpu_port_read(tpu, (enum tpu_port_dir) tpu->last);
case OP_LIT:
- lit = op->lit;
+ lit = op->val.lit;
break;
case OP_LABEL:
abort();
@@ -489,34 +495,34 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
tpu->pc += 1;
return STATUS_RUN;
case INST_JMP:
- tpu_jmp_label(tpu, inst->ops[0].label);
+ tpu_jmp_label(tpu, inst->ops[0].val.label);
return STATUS_RUN;
case INST_JEZ:
if (tpu->acc == 0)
- tpu_jmp_label(tpu, inst->ops[0].label);
+ tpu_jmp_label(tpu, inst->ops[0].val.label);
else
tpu->pc += 1;
return STATUS_RUN;
case INST_JNZ:
if (tpu->acc != 0)
- tpu_jmp_label(tpu, inst->ops[0].label);
+ tpu_jmp_label(tpu, inst->ops[0].val.label);
else
tpu->pc += 1;
return STATUS_RUN;
case INST_JGZ:
if (tpu->acc > 0)
- tpu_jmp_label(tpu, inst->ops[0].label);
+ tpu_jmp_label(tpu, inst->ops[0].val.label);
else
tpu->pc += 1;
return STATUS_RUN;
case INST_JLZ:
if (tpu->acc < 0)
- tpu_jmp_label(tpu, inst->ops[0].label);
+ tpu_jmp_label(tpu, inst->ops[0].val.label);
else
tpu->pc += 1;
return STATUS_RUN;
case INST_JRO:
- tpu->pc += inst->ops[0].lit;
+ tpu->pc += inst->ops[0].val.lit;
if (tpu->pc >= tpu->inst_cnt) tpu->pc = 0;
return STATUS_RUN;
default: