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