summaryrefslogtreecommitdiffstats
path: root/tpu.c
diff options
context:
space:
mode:
authorLouis Burda <quent.burda@gmail.com>2023-12-25 03:08:10 +0100
committerLouis Burda <quent.burda@gmail.com>2023-12-25 03:08:10 +0100
commitae4a7b241a033627ed136b2ef66922034cfbeae1 (patch)
treee8f045d51a36c2f9c24b63d962bcf84baebdc3c9 /tpu.c
parentf2ada47e6be185cc31c475c996c4ccf6735f7bb0 (diff)
downloadtis100-ae4a7b241a033627ed136b2ef66922034cfbeae1.tar.gz
tis100-ae4a7b241a033627ed136b2ef66922034cfbeae1.zip
Add more fixes for game compatibility
Diffstat (limited to 'tpu.c')
-rw-r--r--tpu.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/tpu.c b/tpu.c
index 2736e1c..aac59ed 100644
--- a/tpu.c
+++ b/tpu.c
@@ -137,7 +137,6 @@ tpu_port_init(struct tpu_port *port, struct tpu *tpu)
port->dst_port = NULL;
port->type = PORT_BIDI;
port->reset_in = false;
- port->reading = false;
port->writing = false;
port->avail = false;
port->in = -1;
@@ -166,13 +165,14 @@ tpu_port_update(struct tpu_port *port)
if (port->reset_in && (!port->tpu || !port->tpu->idle)) {
port->avail = false;
port->dst_port->writing = false;
- port->reset_in = false;
if ((tpu = port->dst_port->tpu)) {
- /* hacky: only allow mode to be RUN after receive */
+ /* hacky: switch mode to RUN after receive */
+ assert(tpu->mode == MODE_WRITE);
tpu->mode = MODE_RUN;
tpu->idle = false;
if (++tpu->pc >= tpu->inst_cnt) tpu->pc = 0;
}
+ port->reset_in = false;
}
}
@@ -352,18 +352,16 @@ tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst_type,
return &tpu->insts[tpu->inst_cnt++];
}
-/* tpu can only read values if there is a writer attached and offering a
- * value (->dst_port->out) -- which is cleared on successful read */
+/* tpu can only read values if there is a writer attached and offering
+ * a value -- this value is cleared on successful read */
static bool
tpu_port_read(struct tpu *tpu, enum tpu_port_dir dir, int *lit)
{
struct tpu_port *port = &tpu->ports[dir];
- if (!port->avail) {
- port->reading = true;
+ if (!port->avail)
return false;
- }
*lit = port->in;
port->reset_in = true;
@@ -371,23 +369,20 @@ tpu_port_read(struct tpu *tpu, enum tpu_port_dir dir, int *lit)
return true;
}
-/* tpu can always write values (->out) but only finish writing once the
- * written value is read and cleared by the reader (->dst_port->in) */
+/* tpu can write value to ->out immediately but only finish the instruction
+ * once the written value is read and cleared by the reader */
static bool
tpu_port_write(struct tpu *tpu, enum tpu_port_dir dir, int lit)
{
struct tpu_port *port = &tpu->ports[dir];
- if (port->writing) {
+ if (port->writing)
return false;
- }
port->writing = true;
port->out = lit;
- /* port writing never succeeds right away, only after
- * value was read in tpu_update is tpu->idle/mode fixed up */
return true;
}
@@ -473,16 +468,21 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
tpu->pc += 1;
return MODE_RUN;
case INST_MOV:
- if (tpu->mode != MODE_WRITE) {
- if (!tpu_exec_get(tpu, &inst->ops[0], &lit)) {
- tpu->idle = true;
- return MODE_READ;
- }
+ if (tpu->mode == MODE_WRITE) {
+ tpu->idle = true;
+ return MODE_WRITE;
+ }
+ if (!tpu_exec_get(tpu, &inst->ops[0], &lit)) {
+ tpu->idle = true;
+ return MODE_READ;
}
if (!tpu_exec_put(tpu, &inst->ops[1], lit)) {
tpu->idle = true;
return MODE_WRITE;
}
+ /* if MOV to port, set WRITE tentatively and fix on reset_in */
+ if (inst->ops[1].type != OP_ACC && inst->ops[1].type != OP_NIL)
+ return MODE_WRITE;
tpu->pc += 1;
return MODE_RUN;
case INST_SWP:
@@ -504,8 +504,10 @@ tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
tpu->pc += 1;
return MODE_RUN;
case INST_SUB:
- if (!tpu_exec_get(tpu, &inst->ops[0], &val))
+ if (!tpu_exec_get(tpu, &inst->ops[0], &val)) {
+ tpu->idle = true;
return MODE_READ;
+ }
tpu->acc = MIN(MAX(tpu->acc - val, -999), 999);
tpu->pc += 1;
return MODE_RUN;
@@ -640,7 +642,7 @@ tis_init(struct tis *tis)
memset(&tis->out_ports, 0, TIS_MAX_IO_PORTS * sizeof(void *));
tis->steps = 0;
tis->show_stats = false;
- tis->asm_init = false;
+ tis->asm_filepath = NULL;
}
void
@@ -659,6 +661,7 @@ tis_deinit(struct tis *tis)
free(tis->out_ports[i]);
}
}
+ free(tis->asm_filepath);
}
bool