#pragma once #include #include #include #define TPU_MAP_BUCKETS 64 #define LABEL_MAP_BUCKETS 64 #define TPU_MAX_INST 256 /* enum order is important ! */ enum tpu_status { STATUS_IDLE, STATUS_RUN, STATUS_READ, STATUS_WRITE }; enum tpu_inst_type { INST_NOP, INST_MOV, INST_SWP, INST_SAV, INST_ADD, INST_SUB, INST_NEG, INST_JMP, INST_JEZ, INST_JNZ, INST_JGZ, INST_JLZ, INST_JRO }; enum tpu_inst_op_type { OP_ACC, OP_BAK, OP_NIL, OP_LEFT, OP_RIGHT, OP_UP, OP_DOWN, OP_ANY, OP_LAST, OP_LIT, OP_LABEL }; enum tpu_port_dir { DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN }; enum tpu_port_type { PORT_IN = 0b01, PORT_OUT = 0b10, PORT_BIDI = 0b11 }; union tpu_inst_op_val { uint8_t lit; char *label; }; struct label_map_link { char *label; size_t pc; struct label_map_link *next; }; struct label_map { char *labels[TPU_MAX_INST]; /* borrowed from label_map_links */ struct label_map_link *buckets[LABEL_MAP_BUCKETS]; }; struct tpu_inst_op { enum tpu_inst_op_type type; union tpu_inst_op_val val; }; struct tpu_inst { enum tpu_inst_type type; struct tpu_inst_op ops[2]; uint8_t opcnt; }; struct tpu_port { struct tpu *dst_tpu; enum tpu_port_type type; struct tpu_port *dst_port; bool clr_post_run; bool reading, writing; bool attached; int in, out; }; struct tpu { enum tpu_status status; size_t x, y; struct tpu_port ports[4]; int io_port; int last; size_t steps; size_t idle_steps; uint8_t acc, bak; uint8_t pc; struct label_map label_map; struct tpu_inst insts[TPU_MAX_INST]; size_t inst_cnt; }; struct tpu_map_link { size_t x, y; struct tpu *tpu; struct tpu_map_link *next; }; struct tpu_map { struct tpu_map_link *buckets[TPU_MAP_BUCKETS]; }; struct tis { struct tpu_map tpu_map; struct tpu_port stdin_port; struct tpu_port stdout_port; }; void label_map_init(struct label_map *map); void label_map_deinit(struct label_map *map); bool label_map_add(struct label_map *map, const char *name, size_t pc); size_t label_map_get(struct label_map *map, const char *name); void tpu_port_init(struct tpu_port *port); void tpu_port_deinit(struct tpu_port *port); void tpu_init(struct tpu *tpu); 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, int op1, union tpu_inst_op_val v1, int op2, union tpu_inst_op_val v2); bool tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst, int op1, union tpu_inst_op_val v1, int op2, union tpu_inst_op_val v2); void tpu_clear_ports(struct tpu *tpu); enum tpu_status tpu_exec_mov(struct tpu *tpu, struct tpu_inst *inst); enum tpu_status tpu_exec(struct tpu *tpu, struct tpu_inst *inst); enum tpu_status tpu_step(struct tpu *tpu); void tpu_map_init(struct tpu_map *map); void tpu_map_deinit(struct tpu_map *map); void tpu_map_add(struct tpu_map *map, struct tpu *tpu); struct tpu *tpu_map_get(struct tpu_map *map, size_t x, size_t y); void tis_init(struct tis *tis); void tis_deinit(struct tis *tis); bool tis_step(struct tis *tis); extern const char *dir_reprs[]; extern const char *status_reprs[]; extern const char *inst_reprs[]; extern const char *op_reprs[];