... | ... |
@@ -22,14 +22,15 @@ typedef struct { |
22 | 22 |
} Program; |
23 | 23 |
|
24 | 24 |
typedef struct { |
25 |
- char name[64], keys[16][64]; |
|
26 |
- Uint8 len, lens[16]; |
|
25 |
+ char name[64], params[16][64]; |
|
26 |
+ Uint8 len, length[16], size; |
|
27 | 27 |
} Macro; |
28 | 28 |
|
29 | 29 |
typedef struct { |
30 |
- Uint8 len; |
|
30 |
+ Uint8 len, offset; |
|
31 | 31 |
Uint16 addr; |
32 | 32 |
char name[64]; |
33 |
+ Macro *macro; |
|
33 | 34 |
} Label; |
34 | 35 |
|
35 | 36 |
int macroslen; |
... | ... |
@@ -49,10 +50,11 @@ char ops[][4] = { |
49 | 50 |
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" |
50 | 51 |
}; |
51 | 52 |
|
52 |
-int scmp(char *a, char *b) { int i = 0; while(a[i] == b[i]) if(!a[i++]) return 1; return 0; } /* string compare */ |
|
53 |
-int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */ |
|
54 |
-int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */ |
|
55 |
-int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */ |
|
53 |
+int scin(char *s, char c) { int i = 0; while(s[i]) if(s[i++] == c) return i - 1; return -1; } /* string char index */ |
|
54 |
+int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i] && i < len) if(!a[i++]) return 1; return 0; } /* string compare */ |
|
55 |
+int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */ |
|
56 |
+int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */ |
|
57 |
+int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */ |
|
56 | 58 |
char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */ |
57 | 59 |
|
58 | 60 |
#pragma mark - Helpers |
... | ... |
@@ -83,21 +85,53 @@ findmacro(char *s) |
83 | 85 |
{ |
84 | 86 |
int i; |
85 | 87 |
for(i = 0; i < macroslen; ++i) |
86 |
- if(scmp(macros[i].name, s)) |
|
88 |
+ if(scmp(macros[i].name, s, 64)) |
|
87 | 89 |
return ¯os[i]; |
88 | 90 |
return NULL; |
89 | 91 |
} |
90 | 92 |
|
91 | 93 |
Label * |
92 |
-findlabel(char *s) |
|
94 |
+findlabelplain(char *s) |
|
93 | 95 |
{ |
94 | 96 |
int i; |
95 | 97 |
for(i = 0; i < labelslen; ++i) |
96 |
- if(scmp(labels[i].name, s)) |
|
98 |
+ if(scmp(labels[i].name, s, 64)) |
|
97 | 99 |
return &labels[i]; |
98 | 100 |
return NULL; |
99 | 101 |
} |
100 | 102 |
|
103 |
+Label * |
|
104 |
+findlabelmacro(char *s) |
|
105 |
+{ |
|
106 |
+ int i, o = 0, pti = scin(s, '.'); |
|
107 |
+ char name[64], param[64]; |
|
108 |
+ Label *l; |
|
109 |
+ if(pti > 0) { |
|
110 |
+ scpy(s, name, pti + 1); |
|
111 |
+ scpy(s + pti + 1, param, 64); |
|
112 |
+ } else |
|
113 |
+ scpy(s, name, 64); |
|
114 |
+ if(!(l = findlabelplain(name)) || !l->macro) |
|
115 |
+ return NULL; |
|
116 |
+ /* find macro offset */ |
|
117 |
+ for(i = 0; i < l->macro->len; ++i) { |
|
118 |
+ if(scmp(l->macro->params[i], param, 64)) { |
|
119 |
+ l->offset = o; |
|
120 |
+ break; |
|
121 |
+ } |
|
122 |
+ o += l->macro->length[i]; |
|
123 |
+ } |
|
124 |
+ return l; |
|
125 |
+} |
|
126 |
+ |
|
127 |
+Label * |
|
128 |
+findlabel(char *s) |
|
129 |
+{ |
|
130 |
+ if(scin(s, '.') > 0) |
|
131 |
+ return findlabelmacro(s); |
|
132 |
+ return findlabelplain(s); |
|
133 |
+} |
|
134 |
+ |
|
101 | 135 |
Uint8 |
102 | 136 |
findopcode(char *s) |
103 | 137 |
{ |
... | ... |
@@ -140,25 +174,27 @@ makemacro(char *name, FILE *f) |
140 | 174 |
if(findopcode(name)) |
141 | 175 |
return error("Macro name is invalid", name); |
142 | 176 |
m = ¯os[macroslen++]; |
177 |
+ scpy(name, m->name, 64); |
|
143 | 178 |
while(fscanf(f, "%s", wv)) { |
144 | 179 |
if(wv[0] == '{') |
145 | 180 |
continue; |
146 | 181 |
if(wv[0] == '}') |
147 | 182 |
break; |
148 | 183 |
if(mode == 0) |
149 |
- scpy(wv, m->keys[m->len], 64); |
|
184 |
+ scpy(wv, m->params[m->len], 64); |
|
150 | 185 |
else { |
151 |
- m->lens[m->len] = shex(wv); |
|
186 |
+ m->length[m->len] = shex(wv); |
|
187 |
+ m->size += m->length[m->len]; |
|
152 | 188 |
m->len++; |
153 | 189 |
} |
154 | 190 |
mode = !mode; |
155 | 191 |
} |
156 |
- printf("New macro: %s[%d items]\n", name, m->len); |
|
192 |
+ printf("New macro: %s[%d:%d]\n", name, m->len, m->size); |
|
157 | 193 |
return 1; |
158 | 194 |
} |
159 | 195 |
|
160 | 196 |
int |
161 |
-makelabel(char *name, Uint16 addr, Uint8 len) |
|
197 |
+makelabel(char *name, Uint16 addr, Uint8 len, Macro *m) |
|
162 | 198 |
{ |
163 | 199 |
Label *l; |
164 | 200 |
if(findlabel(name)) |
... | ... |
@@ -171,6 +207,8 @@ makelabel(char *name, Uint16 addr, Uint8 len) |
171 | 207 |
l->addr = addr; |
172 | 208 |
l->len = len; |
173 | 209 |
scpy(name, l->name, 64); |
210 |
+ if(m) |
|
211 |
+ l->macro = m; |
|
174 | 212 |
printf("New label: %s, at 0x%02x[%d]\n", l->name, l->addr, l->len); |
175 | 213 |
return 1; |
176 | 214 |
} |
... | ... |
@@ -180,18 +218,23 @@ makeconst(char *id, FILE *f) |
180 | 218 |
{ |
181 | 219 |
char wv[64]; |
182 | 220 |
fscanf(f, "%s", wv); |
183 |
- return makelabel(id, shex(wv), 1); |
|
221 |
+ return makelabel(id, shex(wv), 1, 0); |
|
184 | 222 |
} |
185 | 223 |
|
186 | 224 |
int |
187 | 225 |
makevariable(char *id, Uint16 *addr, FILE *f) |
188 | 226 |
{ |
189 | 227 |
char wv[64]; |
190 |
- Uint8 origin; |
|
228 |
+ Uint8 origin, len; |
|
229 |
+ Macro *m = NULL; |
|
191 | 230 |
fscanf(f, "%s", wv); |
192 | 231 |
origin = *addr; |
193 |
- *addr += shex(wv); |
|
194 |
- return makelabel(id, origin, shex(wv)); |
|
232 |
+ if((m = findmacro(wv))) |
|
233 |
+ len = m->size; |
|
234 |
+ else |
|
235 |
+ len = shex(wv); |
|
236 |
+ *addr += len; |
|
237 |
+ return makelabel(id, origin, len, m); |
|
195 | 238 |
} |
196 | 239 |
|
197 | 240 |
int |
... | ... |
@@ -247,13 +290,14 @@ pass1(FILE *f) |
247 | 290 |
int ccmnt = 0, cstrg = 0, cbits = 0; |
248 | 291 |
Uint16 addr = 0; |
249 | 292 |
char w[64]; |
293 |
+ printf("Pass 1\n"); |
|
250 | 294 |
while(fscanf(f, "%s", w) == 1) { |
251 | 295 |
if(skipblock(w, &ccmnt, '(', ')')) continue; |
252 | 296 |
if(skipstring(w, &cstrg, &addr)) continue; |
253 | 297 |
if(skipblock(w, &cbits, '[', ']')) |
254 | 298 |
addr += w[0] != '[' && w[0] != ']' ? 2 : 0; |
255 | 299 |
else if(w[0] == '@') { |
256 |
- if(!makelabel(w + 1, addr, 0)) |
|
300 |
+ if(!makelabel(w + 1, addr, 0, NULL)) |
|
257 | 301 |
return error("Pass1 failed", w); |
258 | 302 |
} else if(w[0] == ';') { |
259 | 303 |
if(!makevariable(w + 1, &addr, f)) |
... | ... |
@@ -264,7 +308,7 @@ pass1(FILE *f) |
264 | 308 |
} else if(w[0] == ':') { |
265 | 309 |
if(!makeconst(w + 1, f)) |
266 | 310 |
return error("Pass1 failed", w); |
267 |
- } else if(findopcode(w) || scmp(w, "BRK")) |
|
311 |
+ } else if(findopcode(w) || scmp(w, "BRK", 4)) |
|
268 | 312 |
addr += 1; |
269 | 313 |
else { |
270 | 314 |
switch(w[0]) { |
... | ... |
@@ -289,6 +333,7 @@ pass2(FILE *f) |
289 | 333 |
{ |
290 | 334 |
int ccmnt = 0, cstrg = 0, cbits = 0, cmacro = 0; |
291 | 335 |
char w[64]; |
336 |
+ printf("Pass 2\n"); |
|
292 | 337 |
while(fscanf(f, "%s", w) == 1) { |
293 | 338 |
Uint8 op = 0; |
294 | 339 |
Label *l; |
... | ... |
@@ -300,7 +345,7 @@ pass2(FILE *f) |
300 | 345 |
/* clang-format off */ |
301 | 346 |
if(skipblock(w, &cbits, '[', ']')) { if(w[0] != '[' && w[0] != ']') { pushshort(shex(w), 0); } } |
302 | 347 |
else if(w[0] == '|') p.ptr = shex(w + 1); |
303 |
- else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0); |
|
348 |
+ else if((op = findopcode(w)) || scmp(w, "BRK", 4)) pushbyte(op, 0); |
|
304 | 349 |
else if(w[0] == ':') fscanf(f, "%s", w); |
305 | 350 |
else if(w[0] == ';') fscanf(f, "%s", w); |
306 | 351 |
else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 0); |
... | ... |
@@ -311,10 +356,12 @@ pass2(FILE *f) |
311 | 356 |
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1); |
312 | 357 |
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1); |
313 | 358 |
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1); |
314 |
- else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); } |
|
315 |
- else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); } |
|
316 |
- else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ','); |
|
317 |
- else return error("Unknown label in second pass", w); |
|
359 |
+ else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr + l->offset, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); } |
|
360 |
+ else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr + l->offset, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); } |
|
361 |
+ else if((l = findlabel(w + 1))) pushshort(l->addr + l->offset, w[0] == ','); |
|
362 |
+ else { |
|
363 |
+ return error("Unknown label in second pass", w); |
|
364 |
+ } |
|
318 | 365 |
/* clang-format on */ |
319 | 366 |
} |
320 | 367 |
return 1; |
... | ... |
@@ -3,28 +3,22 @@ |
3 | 3 |
:dev/r fff8 ( std read port ) |
4 | 4 |
:dev/w fff9 ( std write port ) |
5 | 5 |
|
6 |
-&point2d { x 2 y 2 } |
|
7 |
-&point3d { x 2 y 2 z 2 } |
|
6 |
+&Rect2d { x 2 y 2 width 2 height 2 } |
|
8 | 7 |
|
9 |
-;position point2d |
|
10 |
-;vertex point3d |
|
8 |
+;rc1 Rect2d |
|
11 | 9 |
|
12 | 10 |
( TODO ) |
13 | 11 |
|
14 | 12 |
|0100 @RESET |
15 |
- |
|
16 |
- ,position:x #0002 STR2 |
|
17 |
- |
|
18 |
- ~position:x |
|
19 |
- |
|
20 |
- #02 =position:x |
|
21 |
- |
|
22 |
- #abcd =vertex:x |
|
13 |
+ |
|
14 |
+ #abcd ,rc1.height STR2 |
|
15 |
+ ,rc1.height LDR2 |
|
16 |
+ ,rc1.height LDR2 |
|
23 | 17 |
|
24 | 18 |
BRK |
25 | 19 |
|
26 | 20 |
|c000 @FRAME BRK |
27 | 21 |
|d000 @ERROR BRK |
28 | 22 |
|
29 |
-|FFF0 [ f2ac 35bb 2b53 ] ( palette ) |
|
23 |
+|FFF0 [ 0f32 0f32 0f32 ] ( palette ) |
|
30 | 24 |
|FFFA .RESET .FRAME .ERROR |