-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprog.c
84 lines (78 loc) · 1.94 KB
/
prog.c
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
#include "as_wdc6502.h"
void prog_init(program *p)
{
p->pc = 0;
p->relocs = calloc(sizeof(relocation), 16);
p->relocs_cap = 16;
p->relocs_len = 0;
p->syms = calloc(sizeof(symbol), 16);
p->syms_cap = 16;
p->syms_len = 0;
}
void prog_add_byte(program *p, unsigned char b)
{
if (p->pc > ADDR_MAX) {
err_at("program too large");
return;
}
p->data[p->pc] = b;
p->pc++;
}
void prog_add_reloc(program *p, char *need, bool isabs, bool isrel, char *path, int line)
{
if (p->relocs_len == p->relocs_cap) {
int cap = p->relocs_cap * 2;
p->relocs = realloc(p->relocs, cap);
p->relocs_cap = cap;
}
int i = p->relocs_len;
p->relocs[i].path = path;
p->relocs[i].line = line;
p->relocs[i].need = need;
p->relocs[i].pc = p->pc;
p->relocs[i].isabs = isabs;
p->relocs[i].isrel = isrel;
p->relocs_len++;
}
void prog_add_sym(program *p, char *name, long long val, bool lab)
{
long long _;
if (prog_get_sym(p, name, lab, &_)) {
err_at("%s is already defined", name);
return;
}
if (p->syms_len == p->syms_cap) {
int cap = p->syms_cap * 2;
p->syms = realloc(p->syms, cap);
p->syms_cap = cap;
}
int i = p->syms_len;
p->syms[i].name = name;
p->syms[i].islab = lab;
p->syms[i].val = val;
p->syms_len++;
}
bool prog_get_sym(program *p, char *name, bool lab, long long *val)
{
for (int i = 0; i < p->syms_len; i++) {
symbol s = p->syms[i];
if (!strcmp(name, s.name) && s.islab == lab) {
*val = s.val;
return true;
}
}
return false;
}
void prog_write(program *p, char *path)
{
int errs = err_total();
if (errs) {
err_die("%d errors total, refusing to write output", errs);
}
FILE *out = fopen(path, "w");
if (!out) {
err_die("can't open %s", path);
}
fwrite(p->data, ADDR_MAX, 1, out);
fclose(out);
}