commit 130db985e5594204897ad28d7463e7e9b5ef94c7
parent d9dd10cd6a69f6da102814ebefe1d7ad2a32a020
Author: Louis Burda <quent.burda@gmail.com>
Date: Wed, 26 Jul 2023 18:38:11 +0200
Restrict assembly input to fit game spec
Diffstat:
6 files changed, 62 insertions(+), 33 deletions(-)
diff --git a/asm.c b/asm.c
@@ -136,7 +136,7 @@ strlcat_op_name(char *buf, struct tpu_inst_op *op, size_t n)
char hhbuf[4];
if (op->type == OP_LIT) {
- snprintf(hhbuf, 4, "%hhu", op->val.lit);
+ snprintf(hhbuf, 4, "%i", op->val.lit);
return strdcat(buf, hhbuf, n);
} else if (op->type == OP_LABEL) {
return strdcat(buf, op->val.label, n);
@@ -271,7 +271,7 @@ tpu_validate(struct tpu *tpu)
&& tpu->insts[i].ops[0].type == OP_LABEL) {
dst = label_map_get(&tpu->label_map,
tpu->insts[i].ops[0].val.label);
- if (dst == TPU_MAX_INST)
+ if (dst == TPU_MAX_INST_CNT)
die("load: tpu X%i Y%i, label '%s' not defined",
tpu->x, tpu->y,
tpu->insts[i].ops[0].val.label);
@@ -284,7 +284,8 @@ tis_load(struct tis *tis, const char *filepath)
{
struct asm_tokenizer tokenizer;
struct tpu_inst_op op1, op2;
- enum tpu_inst_type inst;
+ enum tpu_inst_type inst_type;
+ struct tpu_inst *inst;
struct tpu *tpu = NULL;
struct tpu_map_link *link;
struct tpu_port *port;
@@ -292,7 +293,8 @@ tis_load(struct tis *tis, const char *filepath)
int stdin_x, stdin_y;
int stdout_x, stdout_y;
enum asm_tok tok, optok;
- size_t i;
+ char instbuf[TPU_MAX_INST_LEN+1];
+ size_t i, len;
tis_deinit(tis);
tis_init(tis);
@@ -352,13 +354,13 @@ tis_load(struct tis *tis, const char *filepath)
case TOK_JEZ: case TOK_JNZ: case TOK_JGZ: case TOK_JLZ:
case TOK_JRO:
if (!tpu) goto disallowed;
- inst = tok_to_inst(tok);
+ inst_type = tok_to_inst(tok);
optok = tok_next_in(&tokenizer, TOK_ACC,
TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (optok == TOK_NL) {
- if (!tpu_add_inst(tpu, inst, 0, op1, op2))
+ if (!tpu_add_inst(tpu, inst_type, 0, op1, op2))
die("load: line %lu, invalid instruction",
tokenizer.lineno-1);
break;
@@ -369,7 +371,7 @@ tis_load(struct tis *tis, const char *filepath)
TOK_NIL, TOK_LEFT, TOK_RIGHT, TOK_UP, TOK_DOWN,
TOK_ANY, TOK_LAST, TOK_LIT, TOK_NAME, TOK_NL, -1);
if (optok == TOK_NL) {
- if (!tpu_add_inst(tpu, inst, 1, op1, op2))
+ if (!tpu_add_inst(tpu, inst_type, 1, op1, op2))
die("load: line %lu, invalid instruction",
tokenizer.lineno-1);
break;
@@ -377,18 +379,35 @@ tis_load(struct tis *tis, const char *filepath)
op2 = tok_to_op(&tokenizer, optok);
tok_next_in(&tokenizer, TOK_NL, -1);
- if (!tpu_add_inst(tpu, inst, 2, op1, op2))
- die("load: line %lu, invalid instruction",
+
+ inst = tpu_add_inst(tpu, inst_type, 2, op1, op2);
+ if (!inst) die("load: line %lu, invalid instruction",
+ tokenizer.lineno-1);
+
+ len = asm_print_inst(instbuf, sizeof(instbuf), inst);
+ if (len >= sizeof(instbuf))
+ die("load: line %lu, inst too long",
+ tokenizer.lineno-1);
+
+ if (tpu->inst_cnt + tpu->label_cnt > TPU_MAX_INST_CNT)
+ die("load: line %lu, line does not fit",
tokenizer.lineno-1);
break;
case TOK_COMMENT:
tok_next_in(&tokenizer, TOK_NL, -1);
break;
case TOK_LABEL:
+ if (strlen(tokenizer.tokstr) > TPU_MAX_INST_LEN - 1)
+ die("load: line %lu, label too long",
+ tokenizer.lineno);
if (!label_map_add(&tpu->label_map,
tokenizer.tokstr, tpu->inst_cnt))
die("load: line %lu, duplicate label (pos)",
tokenizer.lineno);
+ tpu->label_cnt += 1;
+ if (tpu->inst_cnt + tpu->label_cnt > TPU_MAX_INST_CNT)
+ die("load: line %lu, line does not fit",
+ tokenizer.lineno);
break;
case TOK_NL:
break;
diff --git a/tis100 b/tis100
Binary files differ.
diff --git a/tis100-curses b/tis100-curses
Binary files differ.
diff --git a/tis100-curses.c b/tis100-curses.c
@@ -18,8 +18,8 @@
#define KEY_ESC 0x1b
#define KEY_CTRL(c) ((c) & ~0x60)
-#define TPU_INPUT_ROWS 14
-#define TPU_INPUT_COLS 20
+#define TPU_INPUT_ROWS 15
+#define TPU_INPUT_COLS 19
#define TPU_INFO_W 6
#define TPU_INFO_H 4
#define TPU_CNT 6
@@ -213,12 +213,14 @@ tui_draw_tpu(struct tpu *tpu)
tui_draw_box(x, y, w, h, attr,
WACS_D_TTEE, WACS_D_URCORNER, WACS_D_LTEE, WACS_D_RTEE);
tui_draw_text(x + 2, y + 1, A_BOLD, "ACC");
- tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->acc);
+ tui_draw_text(x + 1, y + 2, 0,
+ tpu->acc >= 0 ? " %03i" : "-%03i", tpu->acc);
tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE);
tui_draw_text(x + 2, y + 1, A_BOLD, "BAK");
- tui_draw_text(x + 2, y + 2, 0, "%03i", tpu->bak);
+ tui_draw_text(x + 1, y + 2, 0,
+ tpu->bak >= 0 ? " %03i" : "-%03i", tpu->bak);
tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
WACS_D_LTEE, WACS_D_RTEE, WACS_D_LTEE, WACS_D_RTEE);
@@ -240,7 +242,7 @@ tui_draw_tpu(struct tpu *tpu)
tui_draw_text(x + 2, y + 2, 0, "%s", mode_repr[tpu->status]);
tui_draw_box(x, (y += TPU_INFO_H - 1), w, h, attr,
- WACS_D_LTEE, WACS_D_RTEE, WACS_D_BTEE, WACS_D_LRCORNER);
+ WACS_D_LTEE, WACS_D_RTEE, WACS_D_BTEE, WACS_D_RTEE);
tui_draw_text(x + 2, y + 1, A_BOLD, "IDL");
if (tpu->steps > 0)
idle = (int) ((double) tpu->idle_steps * 100 / (double) tpu->steps);
@@ -248,6 +250,9 @@ tui_draw_tpu(struct tpu *tpu)
idle = 100;
tui_draw_text(x + 2, y + 2, 0, "%03i", idle);
+ tui_draw_box(x, (y += TPU_INFO_H - 1), w, 2, attr,
+ WACS_D_LTEE, WACS_D_RTEE, WACS_D_BTEE, WACS_D_LRCORNER);
+
if (tpu->ports[DIR_LEFT].attached) {
port = &tpu->ports[DIR_LEFT];
if (port->in >= 0)
diff --git a/tpu.c b/tpu.c
@@ -62,7 +62,7 @@ djb_hash(const char *str)
void
label_map_init(struct label_map *map)
{
- memset(map->labels, 0, sizeof(char *) * TPU_MAX_INST);
+ memset(map->labels, 0, sizeof(char *) * TPU_MAX_INST_CNT);
memset(map->buckets, 0, sizeof(void *) * LABEL_MAP_BUCKETS);
}
@@ -123,7 +123,7 @@ 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;
+ if (!*link) return TPU_MAX_INST_CNT;
return (*link)->pc;
}
@@ -165,6 +165,7 @@ tpu_init(struct tpu *tpu)
tpu->acc = 0;
tpu->bak = 0;
tpu->inst_cnt = 0;
+ tpu->label_cnt = 0;
label_map_init(&tpu->label_map);
tpu->last = -1;
@@ -265,7 +266,7 @@ tpu_update_ports(struct tpu *tpu)
}
bool
-tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst_type,
+tpu_set_inst(struct tpu *tpu, int pc, enum tpu_inst_type inst_type,
unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2)
{
struct tpu_inst *inst;
@@ -304,15 +305,17 @@ tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst_type,
return true;
}
-bool
+struct tpu_inst *
tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst_type,
unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2)
{
- if (tpu->inst_cnt >= TPU_MAX_INST)
+ if (tpu->inst_cnt >= TPU_MAX_INST_CNT)
die("tpu_add_inst: tpu X%i Y%i, >= max %i instructions",
- tpu->x, tpu->y, TPU_MAX_INST);
- return tpu_set_inst(tpu, (uint8_t) tpu->inst_cnt++,
- inst_type, opcnt, op1, op2);
+ tpu->x, tpu->y, TPU_MAX_INST_CNT);
+ if (!tpu_set_inst(tpu, (uint8_t) tpu->inst_cnt,
+ inst_type, opcnt, op1, op2))
+ return false;
+ return &tpu->insts[tpu->inst_cnt++];
}
/* tpu can always write to an empty port (->out), but only
@@ -354,7 +357,7 @@ 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) abort();
+ if (pc >= TPU_MAX_INST_CNT) abort();
tpu->pc = (uint8_t) pc;
}
@@ -439,7 +442,7 @@ enum tpu_status
tpu_exec(struct tpu *tpu, struct tpu_inst *inst)
{
enum tpu_status status;
- uint8_t lit;
+ int lit;
int val;
switch (inst->type) {
diff --git a/tpu.h b/tpu.h
@@ -6,7 +6,8 @@
#define TPU_MAP_BUCKETS 64
#define LABEL_MAP_BUCKETS 64
-#define TPU_MAX_INST 256
+#define TPU_MAX_INST_CNT 15
+#define TPU_MAX_INST_LEN 18
/* enum order is important ! */
@@ -35,7 +36,7 @@ enum tpu_port_type {
};
union tpu_inst_op_val {
- uint8_t lit;
+ int lit;
char *label;
};
@@ -46,7 +47,7 @@ struct label_map_link {
};
struct label_map {
- char *labels[TPU_MAX_INST]; /* borrowed from label_map_links */
+ char *labels[TPU_MAX_INST_CNT]; /* borrowed from label_map_links */
struct label_map_link *buckets[LABEL_MAP_BUCKETS];
};
@@ -82,11 +83,12 @@ struct tpu {
size_t steps;
size_t idle_steps;
- uint8_t acc, bak;
- uint8_t pc;
+ int acc, bak;
+ int pc;
+
struct label_map label_map;
- struct tpu_inst insts[TPU_MAX_INST];
- size_t inst_cnt;
+ struct tpu_inst insts[TPU_MAX_INST_CNT];
+ size_t inst_cnt, label_cnt;
};
struct tpu_map_link {
@@ -118,9 +120,9 @@ void tpu_deinit(struct tpu *tpu);
struct tpu_inst *tpu_current_inst(struct tpu *tpu);
void tpu_init_ports(struct tpu *tpu, struct tpu_map *map);
void tpu_update_ports(struct tpu *tpu);
-bool tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst,
+bool tpu_set_inst(struct tpu *tpu, int pc, enum tpu_inst_type inst,
unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2);
-bool tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst,
+struct tpu_inst *tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst,
unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2);
void tpu_clear_ports(struct tpu *tpu);
enum tpu_status tpu_exec_mov(struct tpu *tpu, struct tpu_inst *inst);