commit ae4a7b241a033627ed136b2ef66922034cfbeae1
parent f2ada47e6be185cc31c475c996c4ccf6735f7bb0
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 25 Dec 2023 03:08:10 +0100
Add more fixes for game compatibility
Diffstat:
5 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/asm.c b/asm.c
@@ -339,6 +339,8 @@ tis_load_asm(struct tis *tis, const char *filepath)
size_t len;
char c;
+ tis->asm_filepath = strdup(filepath);
+
tokenizer.filepath = filepath;
tokenizer.file = fopen(filepath, "r");
if (!tokenizer.file) die("load: fopen '%s':", filepath);
@@ -544,10 +546,9 @@ tis_load(struct tis *tis, const char **argv)
/* after tis_load_asm.. */
arg++;
} else {
- if (tis->asm_init)
+ if (tis->asm_filepath)
die("multiple asm files");
tis_load_asm(tis, *arg);
- tis->asm_init = true;
}
}
diff --git a/tis100-curses.c b/tis100-curses.c
@@ -452,7 +452,7 @@ reset(int ifd, int argc, const char **argv, bool watch)
tis_load(&tis, argv);
if (watch) {
- if (inotify_add_watch(ifd, argv[1], IN_MODIFY) < 0)
+ if (inotify_add_watch(ifd, tis.asm_filepath, IN_MODIFY) < 0)
die("inotify_add_watch '%s':", argv[1]);
}
diff --git a/tis100.c b/tis100.c
@@ -59,7 +59,7 @@ main(int argc, const char **argv)
printf("=== stats ===\n");
printf(" cycles: %zu\n", stats.steps);
printf(" nodes: %zu\n", stats.nodes);
- printf(" insts: %zu\n", stats.nodes);
+ printf(" insts: %zu\n", stats.insts);
printf(" idle: %2.1f%%\n", stats.idle * 100);
printf("=============\n");
}
diff --git 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
diff --git a/tpu.h b/tpu.h
@@ -73,7 +73,7 @@ struct tpu_port {
bool attached;
int in, out;
- bool avail, reading, writing;
+ bool avail, writing;
bool reset_in;
};
@@ -126,7 +126,7 @@ struct tis {
struct tpu_io_port *out_ports[TIS_MAX_IO_PORTS];
size_t steps;
bool show_stats;
- bool asm_init;
+ char *asm_filepath;
};
struct tis_stats {