Mercurial > hg-old > index.cgi
comparison src/pseudo.c @ 0:57495da01900
Initial checking of LWASM
author | lost |
---|---|
date | Fri, 03 Oct 2008 02:44:20 +0000 |
parents | |
children | 34568fab6058 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:57495da01900 |
---|---|
1 /* | |
2 * pseudo.c | |
3 * | |
4 * pseudo operations | |
5 */ | |
6 | |
7 #include <ctype.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 #include "lwasm.h" | |
11 #include "instab.h" | |
12 | |
13 #include <stdio.h> | |
14 | |
15 void pseudo_org(asmstate_t *as, sourceline_t *cl, char **optr) | |
16 { | |
17 int v1, rval; | |
18 | |
19 if (cl -> hassym) | |
20 { | |
21 register_error(as, cl, ERR_SYM); | |
22 cl -> hassym = 0; | |
23 } | |
24 rval = eval_expr(as, cl, optr, &v1); | |
25 cl -> addr = v1; | |
26 cl -> addrset = 1; | |
27 as -> addr = v1; | |
28 } | |
29 | |
30 void pseudo_include(asmstate_t *as, sourceline_t *cl, char **optr) | |
31 { | |
32 int v1; | |
33 | |
34 if (as -> passnum != 1) | |
35 return; | |
36 while (**optr && isspace(**optr)) | |
37 (*optr)++; | |
38 if (!**optr) | |
39 { | |
40 register_error(as, cl, ERR_BADFN); | |
41 return; | |
42 } | |
43 for (v1 = 0; *((*optr)+v1) && !isspace(*((*optr)+v1)); v1++) | |
44 ; | |
45 { | |
46 char *fn = malloc(v1 + 1); | |
47 strncpy(fn, *optr, v1); | |
48 fn[v1] = '\0'; | |
49 lwasm_read_file(as, fn); | |
50 } | |
51 } | |
52 | |
53 | |
54 void pseudo_rmb(asmstate_t *as, sourceline_t *cl, char **optr) | |
55 { | |
56 int rval, v1; | |
57 | |
58 rval = eval_expr(as, cl, optr, &v1); | |
59 if (rval < 0) | |
60 { | |
61 errorp1(ERR_FORWARD); | |
62 return; | |
63 } | |
64 if (v1 < 0) | |
65 { | |
66 errorp1(ERR_BADOPER); | |
67 return; | |
68 } | |
69 cl -> len = v1; | |
70 cl -> nocode = 1; | |
71 } | |
72 | |
73 void pseudo_rmd(asmstate_t *as, sourceline_t *cl, char **optr) | |
74 { | |
75 int rval, v1; | |
76 | |
77 rval = eval_expr(as, cl, optr, &v1); | |
78 if (rval < 0) | |
79 { | |
80 errorp1(ERR_FORWARD); | |
81 return; | |
82 } | |
83 if (v1 < 0) | |
84 { | |
85 errorp1(ERR_BADOPER); | |
86 return; | |
87 } | |
88 cl -> len = v1 * 2; | |
89 cl -> nocode = 1; | |
90 } | |
91 | |
92 void pseudo_rmq(asmstate_t *as, sourceline_t *cl, char **optr) | |
93 { | |
94 int rval, v1; | |
95 | |
96 rval = eval_expr(as, cl, optr, &v1); | |
97 if (rval < 0) | |
98 { | |
99 errorp1(ERR_FORWARD); | |
100 return; | |
101 } | |
102 if (v1 < 0) | |
103 { | |
104 errorp1(ERR_BADOPER); | |
105 return; | |
106 } | |
107 cl -> len = v1 * 4; | |
108 cl -> nocode = 1; | |
109 } | |
110 | |
111 void pseudo_zmb(asmstate_t *as, sourceline_t *cl, char **optr) | |
112 { | |
113 int rval, v1; | |
114 | |
115 rval = eval_expr(as, cl, optr, &v1); | |
116 if (rval < 0) | |
117 { | |
118 errorp1(ERR_FORWARD); | |
119 return; | |
120 } | |
121 if (v1 < 0) | |
122 { | |
123 errorp1(ERR_BADOPER); | |
124 return; | |
125 } | |
126 while (v1--) | |
127 emit(0); | |
128 } | |
129 | |
130 void pseudo_zmd(asmstate_t *as, sourceline_t *cl, char **optr) | |
131 { | |
132 int rval, v1; | |
133 | |
134 rval = eval_expr(as, cl, optr, &v1); | |
135 if (rval < 0) | |
136 { | |
137 errorp1(ERR_FORWARD); | |
138 return; | |
139 } | |
140 if (v1 < 0) | |
141 { | |
142 errorp1(ERR_BADOPER); | |
143 return; | |
144 } | |
145 while (v1--) | |
146 { | |
147 emit(0); | |
148 emit(0); | |
149 } | |
150 } | |
151 | |
152 void pseudo_zmq(asmstate_t *as, sourceline_t *cl, char **optr) | |
153 { | |
154 int rval, v1; | |
155 | |
156 rval = eval_expr(as, cl, optr, &v1); | |
157 if (rval < 0) | |
158 { | |
159 errorp1(ERR_FORWARD); | |
160 return; | |
161 } | |
162 if (v1 < 0) | |
163 { | |
164 errorp1(ERR_BADOPER); | |
165 return; | |
166 } | |
167 while (v1--) | |
168 { | |
169 emit(0); | |
170 emit(0); | |
171 emit(0); | |
172 emit(0); | |
173 } | |
174 } | |
175 | |
176 void pseudo_end(asmstate_t *as, sourceline_t *cl, char **optr) | |
177 { | |
178 int rval, v1; | |
179 | |
180 while (**optr && isspace(**optr)) | |
181 ; | |
182 if (**optr && **optr != '*' && **optr != ';') | |
183 { | |
184 rval = eval_expr(as, cl, optr, &v1); | |
185 if (rval < 0) | |
186 { | |
187 errorp1(ERR_FORWARD); | |
188 return; | |
189 } | |
190 } | |
191 else | |
192 { | |
193 v1 = 0; | |
194 } | |
195 if (as -> passnum == 2) | |
196 as -> execaddr = v1; | |
197 } | |
198 | |
199 void pseudo_align(asmstate_t *as, sourceline_t *cl, char **optr) | |
200 { | |
201 int rval, v1; | |
202 int cn; | |
203 | |
204 rval = eval_expr(as, cl, optr, &v1); | |
205 if (rval < 0) | |
206 { | |
207 errorp1(ERR_FORWARD); | |
208 return; | |
209 } | |
210 cn = cl -> addr % v1; | |
211 if (cn) | |
212 cn = v1 - cn; | |
213 | |
214 while (cn) | |
215 { | |
216 emit(0); | |
217 cn--; | |
218 } | |
219 } | |
220 | |
221 void pseudo_equ(asmstate_t *as, sourceline_t *cl, char **optr) | |
222 { | |
223 int rval, v1; | |
224 | |
225 if (cl -> hassym == 0) | |
226 { | |
227 errorp1(ERR_NOSYM); | |
228 return; | |
229 } | |
230 rval = eval_expr(as, cl, optr, &v1); | |
231 // eval_expr returns -1 if there was a forward ref | |
232 // or -2 if the expr was invalid | |
233 if (rval == -2) | |
234 { | |
235 // carp | |
236 errorp1(ERR_FORWARD); | |
237 } | |
238 if (rval < 0) | |
239 { | |
240 // remove symbol ref | |
241 cl -> hassym = 0; | |
242 // mark as a "comment" so it isn't processed next time | |
243 cl -> opcode = -1; | |
244 return; | |
245 } | |
246 cl -> code_symloc = v1; | |
247 cl -> isequ = 1; | |
248 cl -> symaddr = v1 & 0xFFFF; | |
249 } | |
250 | |
251 void pseudo_set(asmstate_t *as, sourceline_t *cl, char **optr) | |
252 { | |
253 int rval, v1; | |
254 | |
255 if (cl -> hassym == 0) | |
256 { | |
257 errorp1(ERR_NOSYM); | |
258 return; | |
259 } | |
260 rval = eval_expr(as, cl, optr, &v1); | |
261 // eval_expr returns -1 if there was a forward ref | |
262 // or -2 if the expr was invalid | |
263 if (rval == -2) | |
264 { | |
265 // carp | |
266 errorp1(ERR_FORWARD); | |
267 } | |
268 if (rval < 0) | |
269 { | |
270 // remove symbol ref | |
271 cl -> hassym = 0; | |
272 // mark as a "comment" so it isn't processed next time | |
273 cl -> opcode = -1; | |
274 return; | |
275 } | |
276 cl -> code_symloc = v1; | |
277 cl -> isset = 1; | |
278 cl -> isequ = 1; | |
279 cl -> symaddr = v1 & 0xFFFF; | |
280 } | |
281 | |
282 void pseudo_setdp(asmstate_t *as, sourceline_t *cl, char **optr) | |
283 { | |
284 int rval, v1; | |
285 | |
286 if (cl -> hassym) | |
287 { | |
288 register_error(as, cl, ERR_SYM); | |
289 cl -> hassym = 0; | |
290 return; | |
291 } | |
292 else | |
293 { | |
294 rval = eval_expr(as, cl, optr, &v1); | |
295 if (rval == -1) | |
296 { | |
297 errorp1(ERR_FORWARD); | |
298 } | |
299 if (rval < 0) | |
300 { | |
301 cl -> opcode = -1; | |
302 return; | |
303 } | |
304 } | |
305 // setdp needs to resolve properly on pass 2 | |
306 if (v1 > 0xff || v1 < 0) | |
307 { | |
308 errorp1(ERR_OVERFLOW); | |
309 } | |
310 as -> dpval = v1 & 0xff; | |
311 cl -> dpval = v1 & 0xff; | |
312 cl -> issetdp = 1; | |
313 cl -> numcodebytes = 0; | |
314 //printf("%s\n", "SETDP2"); | |
315 } | |
316 | |
317 void pseudo_fcc(asmstate_t *as, sourceline_t *cl, char **optr) | |
318 { | |
319 int cn = 0; | |
320 int delim = 0; | |
321 | |
322 delim = *(*optr)++; | |
323 if (!delim) | |
324 { | |
325 errorp1(ERR_BADOPER); | |
326 } | |
327 else | |
328 { | |
329 while (**optr && **optr != delim) | |
330 { | |
331 emit(**optr); | |
332 (*optr)++; | |
333 cn += 1; | |
334 } | |
335 } | |
336 cl -> len = cn; | |
337 } | |
338 | |
339 void pseudo_fcs(asmstate_t *as, sourceline_t *cl, char **optr) | |
340 { | |
341 int cn = 0; | |
342 int delim = 0; | |
343 | |
344 delim = *(*optr)++; | |
345 if (!delim) | |
346 { | |
347 errorp1(ERR_BADOPER); | |
348 } | |
349 else | |
350 { | |
351 while (**optr && **optr != delim) | |
352 { | |
353 if (!*((*optr) + 1) || *((*optr) + 1) == delim) | |
354 emit((**optr) | 0x80); | |
355 else | |
356 emit(**optr); | |
357 (*optr)++; | |
358 cn += 1; | |
359 } | |
360 } | |
361 cl -> len = cn; | |
362 } | |
363 | |
364 void pseudo_fcn(asmstate_t *as, sourceline_t *cl, char **optr) | |
365 { | |
366 int cn = 0; | |
367 int delim = 0; | |
368 | |
369 delim = *(*optr)++; | |
370 if (!delim) | |
371 { | |
372 errorp1(ERR_BADOPER); | |
373 } | |
374 else | |
375 { | |
376 while (**optr && **optr != delim) | |
377 { | |
378 emit(**optr); | |
379 (*optr)++; | |
380 cn += 1; | |
381 } | |
382 } | |
383 emit(0); | |
384 cl -> len = cn + 1; | |
385 } | |
386 | |
387 void pseudo_fcb(asmstate_t *as, sourceline_t *cl, char **optr) | |
388 { | |
389 int rval, v1; | |
390 | |
391 fcb_again: | |
392 rval = eval_expr(as, cl, optr, &v1); | |
393 if (v1 < -127 || v1 > 0xff) | |
394 errorp2(ERR_OVERFLOW); | |
395 emit(v1 & 0xff); | |
396 if (**optr == ',') | |
397 { | |
398 (*optr)++; | |
399 goto fcb_again; | |
400 } | |
401 } | |
402 | |
403 void pseudo_fdb(asmstate_t *as, sourceline_t *cl, char **optr) | |
404 { | |
405 int rval, v1; | |
406 | |
407 fdb_again: | |
408 rval = eval_expr(as, cl, optr, &v1); | |
409 emit((v1 >> 8) & 0xff); | |
410 emit(v1 & 0xff); | |
411 if (**optr == ',') | |
412 { | |
413 (*optr)++; | |
414 goto fdb_again; | |
415 } | |
416 } | |
417 | |
418 void pseudo_fqb(asmstate_t *as, sourceline_t *cl, char **optr) | |
419 { | |
420 int rval, v1; | |
421 | |
422 fqb_again: | |
423 rval = eval_expr(as, cl, optr, &v1); | |
424 emit((v1 >> 24) & 0xff); | |
425 emit((v1 >> 16) & 0xff); | |
426 emit((v1 >> 8) & 0xff); | |
427 emit(v1 & 0xff); | |
428 if (**optr == ',') | |
429 { | |
430 (*optr)++; | |
431 goto fqb_again; | |
432 } | |
433 } | |
434 | |
435 // don't need to do anything if we are executing one of these | |
436 void pseudo_endc(asmstate_t *as, sourceline_t *cl, char **optr) | |
437 { | |
438 return; | |
439 } | |
440 | |
441 // if "else" executes, we must be going into an "ignore" state | |
442 void pseudo_else(asmstate_t *as, sourceline_t *cl, char **optr) | |
443 { | |
444 as -> skipcond = 1; | |
445 as -> skipcount = 1; | |
446 } | |
447 | |
448 void pseudo_ifne(asmstate_t *as, sourceline_t *cl, char **optr) | |
449 { | |
450 int v1; | |
451 int rval; | |
452 // printf("ifne %s\n", *optr); | |
453 rval = eval_expr(as, cl, optr, &v1); | |
454 if (rval < 0) | |
455 { | |
456 errorp1(ERR_BADCOND); | |
457 } | |
458 else | |
459 { | |
460 // printf("Condition value: %d\n", v1); | |
461 if (!v1) | |
462 { | |
463 // printf("condition no match\n"); | |
464 as -> skipcond = 1; | |
465 as -> skipcount = 1; | |
466 } | |
467 } | |
468 } | |
469 void pseudo_ifeq(asmstate_t *as, sourceline_t *cl, char **optr) | |
470 { | |
471 int v1; | |
472 int rval; | |
473 | |
474 rval = eval_expr(as, cl, optr, &v1); | |
475 if (rval < 0) | |
476 { | |
477 errorp1(ERR_BADCOND); | |
478 } | |
479 else | |
480 { | |
481 if (v1) | |
482 { | |
483 as -> skipcond = 1; | |
484 as -> skipcount = 1; | |
485 } | |
486 } | |
487 } | |
488 void pseudo_iflt(asmstate_t *as, sourceline_t *cl, char **optr) | |
489 { | |
490 int v1; | |
491 int rval; | |
492 | |
493 rval = eval_expr(as, cl, optr, &v1); | |
494 if (rval < 0) | |
495 { | |
496 errorp1(ERR_BADCOND); | |
497 } | |
498 else | |
499 { | |
500 if (v1 >= 0) | |
501 { | |
502 as -> skipcond = 1; | |
503 as -> skipcount = 1; | |
504 } | |
505 } | |
506 } | |
507 void pseudo_ifle(asmstate_t *as, sourceline_t *cl, char **optr) | |
508 { | |
509 int v1; | |
510 int rval; | |
511 | |
512 rval = eval_expr(as, cl, optr, &v1); | |
513 if (rval < 0) | |
514 { | |
515 errorp1(ERR_BADCOND); | |
516 } | |
517 else | |
518 { | |
519 if (v1 > 0) | |
520 { | |
521 as -> skipcond = 1; | |
522 as -> skipcount = 1; | |
523 } | |
524 } | |
525 } | |
526 void pseudo_ifgt(asmstate_t *as, sourceline_t *cl, char **optr) | |
527 { | |
528 int v1; | |
529 int rval; | |
530 | |
531 rval = eval_expr(as, cl, optr, &v1); | |
532 if (rval < 0) | |
533 { | |
534 errorp1(ERR_BADCOND); | |
535 } | |
536 else | |
537 { | |
538 if (v1 <= 0) | |
539 { | |
540 as -> skipcond = 1; | |
541 as -> skipcount = 1; | |
542 } | |
543 } | |
544 } | |
545 void pseudo_ifge(asmstate_t *as, sourceline_t *cl, char **optr) | |
546 { | |
547 int v1; | |
548 int rval; | |
549 | |
550 rval = eval_expr(as, cl, optr, &v1); | |
551 if (rval < 0) | |
552 { | |
553 errorp1(ERR_BADCOND); | |
554 } | |
555 else | |
556 { | |
557 if (v1 < 0) | |
558 { | |
559 as -> skipcond = 1; | |
560 as -> skipcount = 1; | |
561 } | |
562 } | |
563 } | |
564 | |
565 void pseudo_error(asmstate_t *as, sourceline_t *cl, char **optr) | |
566 { | |
567 cl -> user_error = strdup(*optr); | |
568 errorp1(ERR_USER); | |
569 } |