| ... | ... |
@@ -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 |