1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#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 {
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 labels;
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[];
|