+++ /dev/null
-/*******************************************************
- *
- * a56 - a DSP56001 assembler
- *
- * Written by Quinn C. Jensen
- * July 1990
- *
- *******************************************************\
-
-/*
- * Copyright (C) 2008 Robert Millan <rmh@aybabtu.com>
- * Copyright (C) 2012 Thorsten Alteholz <debian@alteholz.de>
- * Copyright (C) 2014 Arthur Marble <arthur@info9.net>
- *
- * This file is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation, either version 3 of the License,
- * or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (C) 1990-1994 Quinn C. Jensen
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. The author makes no representations
- * about the suitability of this software for any purpose. It is
- * provided "as is" without express or implied warranty.
- *
- */
-static char *Copyright = "Copyright (C) 1990-1994 Quinn C. Jensen";
-
-/*
- * main.c - The "main" code for the assembler.
- *
- */
-
-#include "a56.h"
-
-#define MAX 1024
-
-int pass;
-int error, warning;
-extern unsigned int pc;
-extern int seg;
-BOOL binary_listing = FALSE;
-BOOL list_includes = FALSE;
-FILE *obj = NULL;
-extern BOOL list_on;
-BOOL list_on_next = TRUE;
-
-main(argc,argv)
-int argc;
-char *argv[];
-{
- int i;
- extern char *optarg;
- extern int optind;
- int c;
- char *output_file = "a56.out";
- char *input_file;
- char *usage = "usage: a56 [-b] [-l] [-d] [-o output-file] input-file\n";
-
- while((c = getopt(argc, argv, "bldo:")) != EOF) switch (c) {
- case 'b':
- binary_listing++;
- break;
- case 'l':
- list_includes++;
- break;
- case 'd':
- ldebug++;
- break;
- case 'o':
- output_file = optarg;
- break;
- case '?':
- default:
- fatal(usage);
- }
- input_file = argv[optind++];
- if(input_file == NULL) fatal(usage);
- obj = open_write(output_file);
-
- pc = 0;
- seg = 0;
- pass = 1;
- reset_psects();
- include(input_file);
-
- pc = 0;
- seg = 0;
- pass = 2;
- reset_psects();
- include(input_file);
-
- psect_summary();
- dump_symtab();
- fclose(obj);
- printf("errors=%d\n", error);
- printf("warnings=%d\n", warning);
- return error ? 1 : 0;
-}
-
-struct inc inc[MAX_NEST];
-int inc_p = 0;
-FILE *yyin;
-
-include(file)
-char *file;
-{
- FILE *fp = open_read(file);
-
- inc_p++;
- if(inc_p >= MAX_NEST)
- fatal("%s: include nesting too deep\n", file);
-
- inc[inc_p].file = file;
- inc[inc_p].fp = fp;
- inc[inc_p].line = 1;
-
- list_on_next = TRUE;
- if(inc_p > 1 && NOT list_includes)
- list_on_next = FALSE;
-
- yyin = inc[inc_p].fp;
- if(inc_p == 1)
-#ifdef FLEX
- {
- static int started = 0;
- if(started)
- yyrestart(yyin);
- else
- started = 1;
- yyparse();
- }
-#else
- yyparse();
-#endif
-}
-
-yywrap()
-{
- fclose(inc[inc_p].fp);
- inc_p--;
- list_on = list_on_next = TRUE;
- if(inc_p > 1)
- list_on = list_on_next = FALSE;
- if(inc_p) {
- yyin = inc[inc_p].fp;
- return 0;
- } else {
- return 1;
- }
-}
-
-struct n
-sym_ref(sym) /* return symbol value or UNDEF if not defined yet */
-char *sym;
-{
- struct sym *sp, *find_sym();
- struct n result;
-
- result.type = UNDEF;
-
- sp = find_sym(sym);
- if(NOT sp) {
- if(pass == 2) {
- yyerror("%s: undefined symbol", sym);
- }
- return result;
- }
-
- return sp->n;
-}
-
-#define HASHSIZE 128
-
-#define HASH(sym) (((sym)[0] ^ sym[1]) % HASHSIZE)
-
-struct sym *symtab[HASHSIZE];
-
-sym_def(sym, type, seg, i, f)
-char *sym;
-int type;
-int seg;
-int i;
-double f;
-{
- struct sym *sp, **stop, *find_sym();
-
- if(pass == 1) {
- if(find_sym(sym)) {
- pass = 2; /* what a kludge */
- yyerror("%s: multiply defined symbol", sym);
- pass = 1;
- return 1;
- }
- stop = &symtab[HASH(sym)];
- sp = NEW(struct sym);
- sp->next = *stop;
- *stop = sp;
- sp->name = strsave(sym);
- sp->n.type = type;
- sp->n.seg = seg;
- if(type == INT)
- sp->n.val.i = i & 0xFFFFFF;
- else
- sp->n.val.f = f;
- } else {
- sp = find_sym(sym);
- if(NOT sp)
- fatal("internal error 304\n");
- if(sp->n.type != type ||
- type == INT && sp->n.val.i != (i & 0xFFFFFF) ||
- type == FLT && sp->n.val.f != f)
- yyerror("%s: assembler phase error", sym);
- }
-}
-
-struct sym *find_sym(sym)
-char *sym;
-{
- struct sym *sp, **stop;
-
- stop = &symtab[HASH(sym)];
- for(sp = *stop; sp; sp = sp->next)
- if(strcmp(sp->name, sym) == 0)
- return sp;
-
- return NULL;
-}
-
-extern char segs[];
-dump_symtab()
-{
- struct sym *sp, **stop;
- int i;
-
- printf("\n\
-Symbol Table\n\
--------------------------------------\n");
-/*
-SSSSSSSSSSSSSSSS S XXXXXX
-SSSSSSSSSSSSSSSS S DDDDDDDDD.DDDDDDDDDD
-*/
-
- for(i = 0, stop = symtab; i < HASHSIZE; i++, stop++) {
- for(sp = *stop; sp; sp = sp->next) {
- if(sp->n.type == INT) {
- printf("%16s %c %06X\n", sp->name, segs[sp->n.seg], sp->n.val.i);
- fprintf(obj, "I %06X %s\n", sp->n.val.i, sp->name);
- } else {
- printf("%16s %c %.10f\n", sp->name, segs[sp->n.seg], sp->n.val.f);
- fprintf(obj, "F %.10f %s\n", sp->n.val.f, sp->name);
- }
- }
- }
-}
-
-char *printcode(word)
-int word;
-{
- static char list[MAX], *lp;
- int i;
-
- word &= 0xFFFFFF;
-
- if(binary_listing) {
- sprintf(list, "%06X<", word);
- for(i = 0, lp = &list[7]; i < 24; i++, lp++) {
- *lp = word & 1 << 23 - i ? '1' : '0';
- if(i && i % 4 == 3)
- *++lp = i % 8 == 7 ? ' ' : ',';
- }
- lp[-1] = '>';
- lp[0] = '\0';
- } else {
- sprintf(list, "%06X", word);
- }
- return list;
-}
-
-char *spacespace[2] = {
-/*P:XXXX_XXXXXX_*/
- " ",
-/*P:XXXX_XXXXXX(XXXX_XXXX_XXXX_XXXX_XXXX_XXXX)_*/
- " "};
-char *spaces(n)
-int n;
-{
- return spacespace[binary_listing ? 1 : 0] + n;
-}
-
-extern char segs[];
-
-gencode(seg, pc, word)
-int seg, pc, word;
-{
- fprintf(obj, "%c %04X %06X\n", segs[seg], pc, word & 0xFFFFFF);
-}
-
-char fixbuf[1024];
-
-char *fixstring(s)
-char *s;
-{
- char *bp = fixbuf;
- int ival;
-
- while(*s) {
- switch (*s) {
- case '\'':
- case '\"':
- s++;
- break;
- case '\\':
- switch (*++s) {
- case 'b': *bp++ = '\b'; break;
- case 'r': *bp++ = '\r'; break;
- case 'f': *bp++ = '\f'; break;
- case 'n': *bp++ = '\n'; break;
- case 't': *bp++ = '\t'; break;
- case '\\': *bp++ = '\\'; break;
- case '0':
- ival = 0;
- while(*s >= '0' && *s <= '9') {
- ival <<= 3;
- ival += *s++ - '0';
- }
- *bp++ = ival;
- break;
- }
- break;
- default:
- *bp++ = *s++;
- break;
- }
- }
- *bp = '\0';
- return fixbuf;
-}
-
-#define ONE 0x4000000
-
-makefrac(s)
-char *s;
-{
- int frac = 0, div = 1;
- int scale = 1;
-
- while(*s) {
- switch(*s) {
- case '-':
- scale = -1;
- break;
- case '.':
- div = 10;
- break;
- default:
- frac += (*s - '0') * scale * ONE / div;
- div *= 10;
- break;
- }
- s++;
- }
-
- return frac + scale * 4 >> 3 & 0xFFFFFF;
-}
-
-/***************** psect stuff ************************/
-
-struct psect *ptop = NULL, *cur_psect = NULL;
-
-reset_psects()
-{
- struct psect *pp;
-
- for(pp = ptop; pp; pp = pp->next) {
- pp->pc = pp->bottom;
- }
-
- set_psect(NULL);
-}
-
-psect_summary()
-{
- printf("\nSummary of psect usage\n\n");
-
- printf("\
- section seg base last top used avail total\n\
--------------------------------------------------------------------------\n");
-/*
-SSSSSSSSSSSSSSSSSSSSSSSS X FFFF FFFF FFFF 99999 100% 99999 100% 99999
-*/
-
- summarize(ptop); /* do it recursively to place back in order */
- printf("\n");
-}
-
-summarize(pp)
-struct psect *pp;
-{
- int used, avail, of;
-
- if(pp == NULL)
- return 1;
-
- used = pp->pc - pp->bottom;
- avail = pp->top - pp->pc;
- of = pp->top - pp->bottom;
-
- summarize(pp->next);
-
- printf("%24.24s %c %04X %04X %04X %5d %3d%% %5d %3d%% %5d\n",
- pp->name, segs[pp->seg], pp->bottom, pp->pc, pp->top,
- used, of ? used * 100 / of : 0, avail, of ? avail * 100 / of : 0,
- of);
-}
-
-struct psect *find_psect(name)
-char *name;
-{
- struct psect *pp;
-
- for(pp = ptop; pp; pp = pp->next)
- if(strcmp(pp->name, name) == 0)
- return pp;
-
- return NULL;
-}
-
-set_psect(pp)
-struct psect *pp;
-{
- cur_psect = pp;
-}
-
-check_psect(seg, pc)
-int seg;
-unsigned int pc;
-{
- if(cur_psect) {
- if(seg == cur_psect->seg && pc >= cur_psect->bottom &&
- pc <= cur_psect->top) {
- cur_psect->pc = pc;
- return TRUE;
- } else {
- return FALSE;
- }
- } else {
- return TRUE;
- }
-}
-
-struct psect *new_psect(name, seg, bottom, top)
-char *name;
-int seg;
-unsigned int bottom, top;
-{
- struct psect *pp = find_psect(name);
-
- if(NOT pp) {
- pp = (struct psect *)alloc(sizeof *pp);
- pp->next = ptop;
- ptop = pp;
- pp->name = strsave(name);
- pp->seg = seg;
- pp->pc = bottom;
- }
- pp->bottom = bottom;
- pp->top = top;
-
- return pp;
-}