summaryrefslogtreecommitdiffstats
path: root/tpu.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-07-26 19:05:46 +0200
committerLouis Burda <quent.burda@gmail.com>2023-07-26 19:07:22 +0200
commit29465804bb9f3bc0eb0f538ec450e9177c0c4767 (patch)
tree25c48b99b944c1b8cfa166023643c9206126c8d7 /tpu.c
parent130db985e5594204897ad28d7463e7e9b5ef94c7 (diff)
downloadtis100-29465804bb9f3bc0eb0f538ec450e9177c0c4767.tar.gz
tis100-29465804bb9f3bc0eb0f538ec450e9177c0c4767.zip
Implement limited integer literal parsing
Diffstat (limited to 'tpu.c')
-rw-r--r--tpu.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/tpu.c b/tpu.c
index d95d8a9..55e4d53 100644
--- a/tpu.c
+++ b/tpu.c
@@ -96,7 +96,7 @@ label_map_link_pos(struct label_map *map, const char *name)
}
bool
-label_map_add(struct label_map *map, const char *name, size_t pc)
+label_map_add(struct label_map *map, const char *name, int pc)
{
struct label_map_link **pos, *link;
@@ -117,13 +117,13 @@ label_map_add(struct label_map *map, const char *name, size_t pc)
return true;
}
-size_t
+int
label_map_get(struct label_map *map, const char *name)
{
struct label_map_link **link;
link = label_map_link_pos(map, name);
- if (!*link) return TPU_MAX_INST_CNT;
+ if (!*link) return -1;
return (*link)->pc;
}
@@ -338,7 +338,7 @@ tpu_port_read(struct tpu *tpu, enum tpu_port_dir dir)
}
static bool
-tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, uint8_t lit)
+tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, int lit)
{
struct tpu_port *port;
@@ -354,11 +354,8 @@ tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, uint8_t lit)
static void
tpu_jmp_label(struct tpu *tpu, const char *label)
{
- size_t pc;
-
- pc = label_map_get(&tpu->label_map, label);
- if (pc >= TPU_MAX_INST_CNT) abort();
- tpu->pc = (uint8_t) pc;
+ tpu->pc = label_map_get(&tpu->label_map, label);
+ if (tpu->pc < 0 || tpu->pc >= tpu->inst_cnt) abort();
}
int
@@ -378,7 +375,7 @@ tpu_exec_get(struct tpu *tpu, struct tpu_inst_op *op)
v = tpu_port_read(tpu, (enum tpu_port_dir) i);
if (v >= 0) {
tpu->last = i;
- return (uint8_t) v;
+ return v;
}
}
return -1;
@@ -393,7 +390,7 @@ tpu_exec_get(struct tpu *tpu, struct tpu_inst_op *op)
}
bool
-tpu_exec_put(struct tpu *tpu, struct tpu_inst_op *op, uint8_t lit)
+tpu_exec_put(struct tpu *tpu, struct tpu_inst_op *op, int lit)
{
int i;
@@ -432,7 +429,7 @@ tpu_exec_mov(struct tpu *tpu, struct tpu_inst *inst)
lit = tpu_exec_get(tpu, &inst->ops[0]);
if (lit < 0) return STATUS_READ;
- if (!tpu_exec_put(tpu, &inst->ops[1], (uint8_t) lit))
+ if (!tpu_exec_put(tpu, &inst->ops[1], lit))
return STATUS_WRITE;
return STATUS_RUN;
@@ -467,13 +464,13 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
case INST_ADD:
val = tpu_exec_get(tpu, &inst->ops[0]);
if (val < 0) return STATUS_READ;
- tpu->acc += (uint8_t) val;
+ tpu->acc = MIN(MAX(tpu->acc + val, -999), 999);
tpu->pc += 1;
return STATUS_RUN;
case INST_SUB:
val = tpu_exec_get(tpu, &inst->ops[0]);
if (val < 0) return STATUS_READ;
- tpu->acc -= (uint8_t) val;
+ tpu->acc = MIN(MAX(tpu->acc - val, -999), 999);
tpu->pc += 1;
return STATUS_RUN;
case INST_NEG:
@@ -509,7 +506,9 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
return STATUS_RUN;
case INST_JRO:
tpu->pc += inst->ops[0].val.lit;
- if (tpu->pc >= tpu->inst_cnt) tpu->pc = 0;
+ if (tpu->pc < 0) tpu->pc = 0;
+ if (tpu->pc >= tpu->inst_cnt)
+ tpu->pc = (int) tpu->inst_cnt - 1;
return STATUS_RUN;
default:
abort();