1 /*******************************************************
3 * a56 - a DSP56001 assembler
5 * Written by Quinn C. Jensen
8 *******************************************************\
11 * Copyright (C) 2008 Robert Millan <rmh@aybabtu.com>
13 * This file is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published
15 * by the Free Software Foundation, either version 3 of the License,
16 * or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see
25 * <http://www.gnu.org/licenses/>.
27 * This file incorporates work covered by the following copyright and
30 * Copyright (C) 1990-1994 Quinn C. Jensen
32 * Permission to use, copy, modify, distribute, and sell this software
33 * and its documentation for any purpose is hereby granted without fee,
34 * provided that the above copyright notice appear in all copies and
35 * that both that copyright notice and this permission notice appear
36 * in supporting documentation. The author makes no representations
37 * about the suitability of this software for any purpose. It is
38 * provided "as is" without express or implied warranty.
41 static char *Copyright = "Copyright (C) 1990-1994 Quinn C. Jensen";
44 * main.c - The "main" code for the assembler.
54 extern unsigned long pc;
56 BOOL binary_listing = FALSE;
57 BOOL list_includes = FALSE;
60 BOOL list_on_next = TRUE;
70 char *output_file = "a56.out";
72 char *usage = "usage: a56 [-b] [-l] [-d] [-o output-file] input-file\n";
74 while((c = getopt(argc, argv, "bldo:")) != EOF) switch (c) {
91 input_file = argv[optind++];
92 if(input_file == NULL) fatal(usage);
93 obj = open_write(output_file);
110 printf("errors=%d\n", error);
111 printf("warnings=%d\n", warning);
112 return error ? 1 : 0;
115 struct inc inc[MAX_NEST];
122 FILE *fp = open_read(file);
125 if(inc_p >= MAX_NEST)
126 fatal("%s: include nesting too deep\n", file);
128 inc[inc_p].file = file;
133 if(inc_p > 1 && NOT list_includes)
134 list_on_next = FALSE;
136 yyin = inc[inc_p].fp;
140 static int started = 0;
154 fclose(inc[inc_p].fp);
156 list_on = list_on_next = TRUE;
158 list_on = list_on_next = FALSE;
160 yyin = inc[inc_p].fp;
168 sym_ref(sym) /* return symbol value or UNDEF if not defined yet */
171 struct sym *sp, *find_sym();
179 yyerror("%s: undefined symbol", sym);
189 #define HASH(sym) (((sym)[0] ^ sym[1]) % HASHSIZE)
191 struct sym *symtab[HASHSIZE];
193 sym_def(sym, type, seg, i, f)
200 struct sym *sp, **stop, *find_sym();
204 pass = 2; /* what a kludge */
205 yyerror("%s: multiply defined symbol", sym);
209 stop = &symtab[HASH(sym)];
210 sp = NEW(struct sym);
213 sp->name = strsave(sym);
217 sp->n.val.i = i & 0xFFFFFF;
223 fatal("internal error 304\n");
224 if(sp->n.type != type ||
225 type == INT && sp->n.val.i != (i & 0xFFFFFF) ||
226 type == FLT && sp->n.val.f != f)
227 yyerror("%s: assembler phase error", sym);
231 struct sym *find_sym(sym)
234 struct sym *sp, **stop;
236 stop = &symtab[HASH(sym)];
237 for(sp = *stop; sp; sp = sp->next)
238 if(strcmp(sp->name, sym) == 0)
247 struct sym *sp, **stop;
252 -------------------------------------\n");
254 SSSSSSSSSSSSSSSS S XXXXXX
255 SSSSSSSSSSSSSSSS S DDDDDDDDD.DDDDDDDDDD
258 for(i = 0, stop = symtab; i < HASHSIZE; i++, stop++) {
259 for(sp = *stop; sp; sp = sp->next) {
260 if(sp->n.type == INT) {
261 printf("%16s %c %06X\n", sp->name, segs[sp->n.seg], sp->n.val.i);
262 fprintf(obj, "I %06X %s\n", sp->n.val.i, sp->name);
264 printf("%16s %c %.10f\n", sp->name, segs[sp->n.seg], sp->n.val.f);
265 fprintf(obj, "F %.10f %s\n", sp->n.val.f, sp->name);
271 char *printcode(word)
274 static char list[MAX], *lp;
280 sprintf(list, "%06X<", word);
281 for(i = 0, lp = &list[7]; i < 24; i++, lp++) {
282 *lp = word & 1 << 23 - i ? '1' : '0';
284 *++lp = i % 8 == 7 ? ' ' : ',';
289 sprintf(list, "%06X", word);
294 char *spacespace[2] = {
297 /*P:XXXX_XXXXXX(XXXX_XXXX_XXXX_XXXX_XXXX_XXXX)_*/
302 return spacespace[binary_listing ? 1 : 0] + n;
307 gencode(seg, pc, word)
310 fprintf(obj, "%c %04X %06X\n", segs[seg], pc, word & 0xFFFFFF);
329 case 'b': *bp++ = '\b'; break;
330 case 'r': *bp++ = '\r'; break;
331 case 'f': *bp++ = '\f'; break;
332 case 'n': *bp++ = '\n'; break;
333 case 't': *bp++ = '\t'; break;
334 case '\\': *bp++ = '\\'; break;
337 while(*s >= '0' && *s <= '9') {
354 #define ONE 0x4000000
359 int frac = 0, div = 1;
371 frac += (*s - '0') * scale * ONE / div;
378 return frac + scale * 4 >> 3 & 0xFFFFFF;
381 /***************** psect stuff ************************/
383 struct psect *ptop = NULL, *cur_psect = NULL;
389 for(pp = ptop; pp; pp = pp->next) {
398 printf("\nSummary of psect usage\n\n");
401 section seg base last top used avail total\n\
402 -------------------------------------------------------------------------\n");
404 SSSSSSSSSSSSSSSSSSSSSSSS X FFFF FFFF FFFF 99999 100% 99999 100% 99999
407 summarize(ptop); /* do it recursively to place back in order */
419 used = pp->pc - pp->bottom;
420 avail = pp->top - pp->pc;
421 of = pp->top - pp->bottom;
425 printf("%24.24s %c %04X %04X %04X %5d %3d%% %5d %3d%% %5d\n",
426 pp->name, segs[pp->seg], pp->bottom, pp->pc, pp->top,
427 used, of ? used * 100 / of : 0, avail, of ? avail * 100 / of : 0,
431 struct psect *find_psect(name)
436 for(pp = ptop; pp; pp = pp->next)
437 if(strcmp(pp->name, name) == 0)
454 if(seg == cur_psect->seg && pc >= cur_psect->bottom &&
455 pc <= cur_psect->top) {
466 struct psect *new_psect(name, seg, bottom, top)
469 unsigned int bottom, top;
471 struct psect *pp = find_psect(name);
474 pp = (struct psect *)alloc(sizeof *pp);
477 pp->name = strsave(name);