summaryrefslogtreecommitdiffstats
path: root/tpu.h
blob: 79155f897e1c97de83988b7ba785930f22c2d25d (plain) (blame)
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
#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 attached, reading;
	int in, out;
};

struct tpu {
	enum tpu_status status;
	struct label_map labels;
	struct tpu_port ports[4];
	int read_port;
	uint8_t acc, bak;
	size_t x, y;
	int last;

	uint8_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);
void tpu_update_ports(struct tpu *tpu);
bool tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst,
	int op1, uint8_t op1_lit, int op2, uint8_t op2_lit);
bool tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst,
	int op1, uint8_t op1_lit, int op2, uint8_t op2_lit);
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);
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);