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