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
|
#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
};
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 {
uint8_t lit;
char *label;
};
};
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 write, read;
uint8_t val;
bool attached;
};
struct tpu {
struct label_map labels;
struct tpu_port ports[4];
uint8_t acc, bak;
size_t x, y;
int last;
size_t pc;
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];
};
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_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);
bool tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst,
int op1, uint8_t op1_lit, int op2, uint8_t op2_lit);
enum tpu_status tpu_exec(struct tpu *tpu, struct tpu_inst *inst);
void 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);
|