From: MaartenBrock Date: Fri, 20 Apr 2007 18:36:38 +0000 (+0000) Subject: * as/mcs51/asmain.c (search_path_append, search_path_fopen): new, added, X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=f1be544d8fcb3ff37000939b9739e427f65f3a91;hp=ac3b73ef0556ed8a71ff7c5ce6702ba32f9b8ce1;p=fw%2Fsdcc * as/mcs51/asmain.c (search_path_append, search_path_fopen): new, added, (main): added option -i, (asmbl, case S_INCL): use search_path_fopen, mostly from patch 1579668 by Peter Miller, thanks * src/z80/main.c: fixed typo --callee-saves-bc * device/include/mcs51/compiler.h: added sfrword for Tasking git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4760 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 1ecf5e45..c102ac52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-04-20 Maarten Brock + + * as/mcs51/asmain.c (search_path_append, search_path_fopen): new, added, + (main): added option -i, + (asmbl, case S_INCL): use search_path_fopen, + mostly from patch 1579668 by Peter Miller, thanks + * src/z80/main.c: fixed typo --callee-saves-bc + * device/include/mcs51/compiler.h: added sfrword for Tasking + 2007-04-20 Borut Razem * src/z80/main.c: replaced reserved keyword asm with asmblr diff --git a/as/mcs51/asmain.c b/as/mcs51/asmain.c index 1a506fbf..9e4b3890 100644 --- a/as/mcs51/asmain.c +++ b/as/mcs51/asmain.c @@ -11,6 +11,7 @@ * 29-Oct-97 JLH pass ";!" comments to output file */ +#include #include #include #include @@ -18,133 +19,194 @@ #include "asm.h" -/*)Module asmain.c +/*)Module asmain.c * - * The module asmain.c includes the command argument parser, - * the three pass sequencer, and the machine independent - * assembler parsing code. + * The module asmain.c includes the command argument parser, + * the three pass sequencer, and the machine independent + * assembler parsing code. * - * asmain.c contains the following functions: - * VOID main(argc, argv) - * VOID asexit() - * VOID asmbl() - * FILE * afile(fn, ft, wf) - * VOID newdot(nap) - * VOID phase(ap, a) - * VOID usage() + * asmain.c contains the following functions: + * VOID main(argc, argv) + * VOID asexit() + * VOID asmbl() + * FILE * afile(fn, ft, wf) + * VOID newdot(nap) + * VOID phase(ap, a) + * VOID usage() * - * asmain.c contains the array char *usetxt[] which - * references the usage text strings printed by usage(). + * asmain.c contains the array char *usetxt[] which + * references the usage text strings printed by usage(). */ -/*)Function VOID main(argc, argv) +static const char *search_path[100]; +static int search_path_length; + +/** + * The search_path_append is used to append another directory to the end + * of the include file search path. * - * int argc argument count - * char * argv array of pointers to argument strings + * @param dir + * The directory to be added to the path. + */ +void +search_path_append(const char *dir) +{ + if (search_path_length < sizeof(search_path)/sizeof(char*)) + { + search_path[search_path_length++] = dir; + } +} + +/** + * The search_path_fopen function is used to open the named file. If + * the file isn't in the current directory, the search path is then used + * to build a series of possible file names, and attempts to open them. + * The first found is used. * - * The function main() is the entry point to the assembler. - * The purpose of main() is to (1) parse the command line - * arguments for options and source file specifications and - * (2) to process the source files through the 3 pass assembler. - * Before each assembler pass various variables are initialized - * and source files are rewound to their beginning. During each - * assembler pass each assembler-source text line is processed. - * After each assembler pass the assembler information is flushed - * to any opened output files and the if-else-endif processing - * is checked for proper termination. + * @param filename + * The name of the file to be opened. + * @param mode + * The mode of the file to be opened. + * @returns + * what the fopen function would return on success, or NULL if the + * file is not anywhere in the search path. + */ +static FILE * +search_path_fopen(const char *filename, const char *mode) +{ + FILE *fp; + int j; + + fp = fopen(filename, mode); + if (fp != NULL || filename[0] == '/' || filename[0] == '\\') + return fp; + for (j = 0; j < search_path_length; ++j) + { + char path[2000]; + + strncpy(path, search_path[j], sizeof(path)); + if ((path[strlen(path) - 1] != '/') && + (path[strlen(path) - 1] != DIR_SEPARATOR_CHAR)) + { + strncat(path, DIR_SEPARATOR_STRING, sizeof(path)); + } + strncat(path, filename, sizeof(path)); + fp = fopen(path, mode); + if (fp != NULL) + return fp; + } + errno = ENOENT; + return NULL; +} + +/*)Function VOID main(argc, argv) + * + * int argc argument count + * char * argv array of pointers to argument strings + * + * The function main() is the entry point to the assembler. + * The purpose of main() is to (1) parse the command line + * arguments for options and source file specifications and + * (2) to process the source files through the 3 pass assembler. + * Before each assembler pass various variables are initialized + * and source files are rewound to their beginning. During each + * assembler pass each assembler-source text line is processed. + * After each assembler pass the assembler information is flushed + * to any opened output files and the if-else-endif processing + * is checked for proper termination. * - * The function main() is also responsible for opening all - * output files (REL, LST, and SYM), sequencing the global (-g) - * and all-global (-a) variable definitions, and dumping the - * REL file header information. + * The function main() is also responsible for opening all + * output files (REL, LST, and SYM), sequencing the global (-g) + * and all-global (-a) variable definitions, and dumping the + * REL file header information. * - * local variables: - * char * p pointer to argument string - * int c character from argument string - * int i argument loop counter - * area * ap pointer to area structure + * local variables: + * char * p pointer to argument string + * int c character from argument string + * int i argument loop counter + * area * ap pointer to area structure * - * global variables: - * int aflag -a, make all symbols global flag - * char afn[] afile() constructed filespec - * area * areap pointer to an area structure - * int cb[] array of assembler output values - * int cbt[] array of assembler relocation types - * describing the data in cb[] - * int cfile current file handle index - * of input assembly files - * int * cp pointer to assembler output array cb[] - * int * cpt pointer to assembler relocation type - * output array cbt[] - * char eb[] array of generated error codes - * char * ep pointer into error list array eb[] - * int fflag -f(f), relocations flagged flag - * int flevel IF-ELSE-ENDIF flag will be non - * zero for false conditional case - * Addr_T fuzz tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats - * int gflag -g, make undefined symbols global flag - * char ib[] assembler-source text line - * int inpfil count of assembler - * input files specified - * int ifcnd[] array of IF statement condition - * values (0 = FALSE) indexed by tlevel - * int iflvl[] array of IF-ELSE-ENDIF flevel - * values indexed by tlevel - * int incfil current file handle index - * for include files - * char * ip pointer into the assembler-source - * text line in ib[] - * jmp_buf jump_env compiler dependent structure - * used by setjmp() and longjmp() - * int lflag -l, generate listing flag - * int line current assembler source - * line number - * int lop current line number on page - * int oflag -o, generate relocatable output flag - * int jflag -j, generate debug info flag - * int page current page number - * int pflag enable listing pagination - * int pass assembler pass number - * int radix current number conversion radix: - * 2 (binary), 8 (octal), 10 (decimal), - * 16 (hexadecimal) - * int sflag -s, generate symbol table flag - * char srcfn[][] array of source file names - * int srcline[] current source file line - * char stb[] Subtitle string buffer - * sym * symp pointer to a symbol structure - * int tlevel current conditional level - * int xflag -x, listing radix flag - * FILE * lfp list output file handle - * FILE * ofp relocation output file handle - * FILE * tfp symbol table output file handle - * FILE * sfp[] array of assembler-source file handles + * global variables: + * int aflag -a, make all symbols global flag + * char afn[] afile() constructed filespec + * area * areap pointer to an area structure + * int cb[] array of assembler output values + * int cbt[] array of assembler relocation types + * describing the data in cb[] + * int cfile current file handle index + * of input assembly files + * int * cp pointer to assembler output array cb[] + * int * cpt pointer to assembler relocation type + * output array cbt[] + * char eb[] array of generated error codes + * char * ep pointer into error list array eb[] + * int fflag -f(f), relocations flagged flag + * int flevel IF-ELSE-ENDIF flag will be non + * zero for false conditional case + * Addr_T fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + * int gflag -g, make undefined symbols global flag + * char ib[] assembler-source text line + * int inpfil count of assembler + * input files specified + * int ifcnd[] array of IF statement condition + * values (0 = FALSE) indexed by tlevel + * int iflvl[] array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + * int incfil current file handle index + * for include files + * char * ip pointer into the assembler-source + * text line in ib[] + * jmp_buf jump_env compiler dependent structure + * used by setjmp() and longjmp() + * int lflag -l, generate listing flag + * int line current assembler source + * line number + * int lop current line number on page + * int oflag -o, generate relocatable output flag + * int jflag -j, generate debug info flag + * int page current page number + * int pflag enable listing pagination + * int pass assembler pass number + * int radix current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + * int sflag -s, generate symbol table flag + * char srcfn[][] array of source file names + * int srcline[] current source file line + * char stb[] Subtitle string buffer + * sym * symp pointer to a symbol structure + * int tlevel current conditional level + * int xflag -x, listing radix flag + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles * - * called functions: - * FILE * afile() asmain.c - * VOID allglob() assym.c - * VOID asexit() asmain.c - * VOID diag() assubr.c - * VOID err() assubr.c - * int fprintf() c-library - * int as_getline() aslex.c - * VOID list() aslist.c - * VOID lstsym() aslist.c - * VOID minit() ___mch.c - * VOID newdot() asmain.c - * VOID outchk() asout.c - * VOID outgsd() asout.c - * int rewind() c-library - * int setjmp() c-library - * VOID symglob() assym.c - * VOID syminit() assym.c - * VOID usage() asmain.c + * called functions: + * FILE * afile() asmain.c + * VOID allglob() assym.c + * VOID asexit() asmain.c + * VOID diag() assubr.c + * VOID err() assubr.c + * int fprintf() c-library + * int as_getline() aslex.c + * VOID list() aslist.c + * VOID lstsym() aslist.c + * VOID minit() ___mch.c + * VOID newdot() asmain.c + * VOID outchk() asout.c + * VOID outgsd() asout.c + * int rewind() c-library + * int setjmp() c-library + * VOID symglob() assym.c + * VOID syminit() assym.c + * VOID usage() asmain.c * - * side effects: - * Completion of main() completes the assembly process. - * REL, LST, and/or SYM files may be generated. + * side effects: + * Completion of main() completes the assembly process. + * REL, LST, and/or SYM files may be generated. */ int fatalErrors=0; @@ -154,145 +216,152 @@ int main(argc, argv) char *argv[]; { - register char *p; - register int c, i; - struct area *ap; - - /*fprintf(stdout, "\n");*/ - inpfil = -1; - pflag = 1; - for (i=1; i= 0) - usage(); - ++p; - while ((c = *p++) != 0) - switch(c) { - - case 'a': - case 'A': - ++aflag; - break; - - case 'c': - case 'C': - ++cflag; - break; - - case 'g': - case 'G': - ++gflag; - break; - - case 'j': /* JLH: debug info */ - case 'J': - ++jflag; - ++oflag; /* force object */ - break; - - case 'l': - case 'L': - ++lflag; - break; - - case 'o': - case 'O': - ++oflag; - break; - - case 's': - case 'S': - ++sflag; - break; - - case 'p': - case 'P': - pflag = 0; - break; - - case 'x': - case 'X': - xflag = 0; - break; - - case 'q': - case 'Q': - xflag = 1; - break; - - case 'd': - case 'D': - xflag = 2; - break; - - case 'f': - case 'F': - ++fflag; - break; - - default: - usage(); - } - } else { - if (++inpfil == MAXFIL) { - fprintf(stderr, "too many input files\n"); - asexit(1); - } - sfp[inpfil] = afile(p, "", 0); - strcpy(srcfn[inpfil],afn); - if (inpfil == 0) { - if (lflag) - lfp = afile(p, "lst", 1); - if (oflag) { - ofp = afile(p, "rel", 1); - // save the file name if we have to delete it on error - strcpy(relFile,afn); - } - if (sflag) - tfp = afile(p, "sym", 1); - } - } - } - if (inpfil < 0) - usage(); - syminit(); - for (pass=0; pass<3; ++pass) { - if (gflag && pass == 1) - symglob(); - if (aflag && pass == 1) - allglob(); - if (oflag && pass == 2) - outgsd(); - flevel = 0; - tlevel = 0; - ifcnd[0] = 0; - iflvl[0] = 0; - radix = 10; - srcline[0] = 0; - page = 0; - stb[0] = 0; - lop = NLPP; - cfile = 0; - incfil = -1; - for (i = 0; i <= inpfil; i++) - rewind(sfp[i]); - ap = areap; - while (ap) { - ap->a_fuzz = 0; - ap->a_size = 0; - ap = ap->a_ap; - } - fuzz = 0; - dot.s_addr = 0; - dot.s_area = &dca; - symp = ˙ - minit(); - while (as_getline()) { - cp = cb; - cpt = cbt; - ep = eb; - ip = ib; + register char *p; + register int c, i; + struct area *ap; + + /*fprintf(stdout, "\n");*/ + inpfil = -1; + pflag = 1; + for (i=1; i= 0) + usage(); + ++p; + while ((c = *p++) != 0) + switch(c) { + + case 'a': + case 'A': + ++aflag; + break; + + case 'c': + case 'C': + ++cflag; + break; + + case 'g': + case 'G': + ++gflag; + break; + + case 'i': + case 'I': + search_path_append(p); + while (*p) + ++p; + break; + + case 'j': /* JLH: debug info */ + case 'J': + ++jflag; + ++oflag; /* force object */ + break; + + case 'l': + case 'L': + ++lflag; + break; + + case 'o': + case 'O': + ++oflag; + break; + + case 's': + case 'S': + ++sflag; + break; + + case 'p': + case 'P': + pflag = 0; + break; + + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'f': + case 'F': + ++fflag; + break; + + default: + usage(); + } + } else { + if (++inpfil == MAXFIL) { + fprintf(stderr, "too many input files\n"); + asexit(1); + } + sfp[inpfil] = afile(p, "", 0); + strcpy(srcfn[inpfil],afn); + if (inpfil == 0) { + if (lflag) + lfp = afile(p, "lst", 1); + if (oflag) { + ofp = afile(p, "rel", 1); + // save the file name if we have to delete it on error + strcpy(relFile,afn); + } + if (sflag) + tfp = afile(p, "sym", 1); + } + } + } + if (inpfil < 0) + usage(); + syminit(); + for (pass=0; pass<3; ++pass) { + if (gflag && pass == 1) + symglob(); + if (aflag && pass == 1) + allglob(); + if (oflag && pass == 2) + outgsd(); + flevel = 0; + tlevel = 0; + ifcnd[0] = 0; + iflvl[0] = 0; + radix = 10; + srcline[0] = 0; + page = 0; + stb[0] = 0; + lop = NLPP; + cfile = 0; + incfil = -1; + for (i = 0; i <= inpfil; i++) + rewind(sfp[i]); + ap = areap; + while (ap) { + ap->a_fuzz = 0; + ap->a_size = 0; + ap = ap->a_ap; + } + fuzz = 0; + dot.s_addr = 0; + dot.s_area = &dca; + symp = ˙ + minit(); + while (as_getline()) { + cp = cb; + cpt = cbt; + ep = eb; + ip = ib; /* JLH: if line begins with ";!", then * pass this comment on to the output file @@ -300,715 +369,715 @@ char *argv[]; if (oflag && (pass == 1) && (ip[0] == ';') && (ip[1] == '!')) { - fprintf(ofp, "%s\n", ip ); + fprintf(ofp, "%s\n", ip ); } - - if (setjmp(jump_env) == 0) - asmbl(); - - if (pass == 2) { - diag(); - list(); - } - } - newdot(dot.s_area); /* Flush area info */ - if (flevel || tlevel) - err('i'); - } - if (oflag) - outchk(HUGE, HUGE); /* Flush */ - if (sflag) { - lstsym(tfp); - } else - if (lflag) { - lstsym(lfp); - } - //printf ("aserr: %d\n", aserr); - //printf ("fatalErrors: %d\n", fatalErrors); - asexit(fatalErrors); - return 0; // hush the compiler + + if (setjmp(jump_env) == 0) + asmbl(); + + if (pass == 2) { + diag(); + list(); + } + } + newdot(dot.s_area); /* Flush area info */ + if (flevel || tlevel) + err('i'); + } + if (oflag) + outchk(HUGE, HUGE); /* Flush */ + if (sflag) { + lstsym(tfp); + } else + if (lflag) { + lstsym(lfp); + } + //printf ("aserr: %d\n", aserr); + //printf ("fatalErrors: %d\n", fatalErrors); + asexit(fatalErrors); + return 0; // hush the compiler } -/*)Function VOID asexit(i) +/*)Function VOID asexit(i) * - * int i exit code + * int i exit code * - * The function asexit() explicitly closes all open - * files and then terminates the program. + * The function asexit() explicitly closes all open + * files and then terminates the program. * - * local variables: - * int j loop counter + * local variables: + * int j loop counter * - * global variables: - * FILE * ifp[] array of include-file file handles - * FILE * lfp list output file handle - * FILE * ofp relocation output file handle - * FILE * tfp symbol table output file handle - * FILE * sfp[] array of assembler-source file handles + * global variables: + * FILE * ifp[] array of include-file file handles + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles * - * functions called: - * int fclose() c-library - * VOID exit() c-library + * functions called: + * int fclose() c-library + * VOID exit() c-library * - * side effects: - * All files closed. Program terminates. + * side effects: + * All files closed. Program terminates. */ VOID asexit(i) int i; { - int j; - - if (lfp != NULL) fclose(lfp); - if (ofp != NULL) fclose(ofp); - if (tfp != NULL) fclose(tfp); - - for (j=0; j= 0) { - n = 10*n + d; - c = get(); - } - if (c != '$' || get() != ':') - qerr(); - tp = symp->s_tsym; - if (pass == 0) { - while (tp) { - if (n == tp->t_num) { - tp->t_flg |= S_MDF; - break; - } - tp = tp->t_lnk; - } - if (tp == NULL) { - tp=(struct tsym *) new (sizeof(struct tsym)); - tp->t_lnk = symp->s_tsym; - tp->t_num = n; - tp->t_flg = 0; - tp->t_area = dot.s_area; - tp->t_addr = dot.s_addr; - symp->s_tsym = tp; - } - } else { - while (tp) { - if (n == tp->t_num) { - break; - } - tp = tp->t_lnk; - } - if (tp) { - if (pass == 1) { - fuzz = tp->t_addr - dot.s_addr; - tp->t_area = dot.s_area; - tp->t_addr = dot.s_addr; - } else { - phase(tp->t_area, tp->t_addr); - if (tp->t_flg & S_MDF) - err('m'); - } - } else { - err('u'); - } - } - lmode = ALIST; - goto loop; - } - /* - * If the first character is a letter then assume a label, - * symbol, assembler directive, or assembler mnemonic is - * being processed. - */ - if ((ctype[c] & LETTER) == 0) { - if (flevel) { - return; - } else { - qerr(); - } - } - getid(id, c); - c = getnb(); - /* - * If the next character is a : then a label is being processed. - * A double :: defines a global label. If this is new label - * then create a symbol structure. - * pass 0: - * Flag multiply defined labels. - * pass 1: - * Load area, address, and fuzz values - * into structure symp. - * pass 2: - * Check for assembler phase error and - * multiply defined error. - */ - if (c == ':') { - if (flevel) - return; - if ((c = get()) != ':') { - unget(c); - c = 0; - } - symp = lookup(id); - if (symp == &dot) - err('.'); - if (pass == 0) - if ((symp->s_type != S_NEW) && - ((symp->s_flag & S_ASG) == 0)) - symp->s_flag |= S_MDF; - if (pass != 2) { - fuzz = symp->s_addr - dot.s_addr; - symp->s_type = S_USER; - symp->s_area = dot.s_area; - symp->s_addr = dot.s_addr; - } else { - if (symp->s_flag & S_MDF) - err('m'); - phase(symp->s_area, symp->s_addr); - } - if (c) { - symp->s_flag |= S_GBL; - } - lmode = ALIST; - goto loop; - } - /* - * If the next character is a = then an equate is being processed. - * A double == defines a global equate. If this is new variable - * then create a symbol structure. - */ - if (c == '=') { - if (flevel) - return; - if ((c = get()) != '=') { - unget(c); - c = 0; - } - clrexpr(&e1); - expr(&e1, 0); - sp = lookup(id); - if (sp == &dot) { - outall(); - if (e1.e_flag || e1.e_base.e_ap != dot.s_area) - err('.'); - } else - if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { - err('m'); - } - sp->s_type = S_USER; - sp->s_area = e1.e_base.e_ap; - sp->s_addr = laddr = e1.e_addr; - sp->s_flag |= S_ASG; - if (c) { - sp->s_flag |= S_GBL; - } - lmode = ELIST; - goto loop; - } - unget(c); - lmode = flevel ? SLIST : CLIST; - if ((mp = mlookup(id)) == NULL) { - if (!flevel) - err('o'); - return; - } - /* - * If we have gotten this far then we have found an - * assembler directive or an assembler mnemonic. - * - * Check for .if, .else, .endif, and .page directives - * which are not controlled by the conditional flags - */ - switch (mp->m_type) { - - case S_IF: - n = absexpr(); - if (tlevel < MAXIF) { - ++tlevel; - ifcnd[tlevel] = n; - iflvl[tlevel] = flevel; - if (n == 0) { - ++flevel; - } - } else { - err('i'); - } - lmode = ELIST; - laddr = n; - return; - - case S_ELSE: - if (ifcnd[tlevel]) { - if (++flevel > (iflvl[tlevel]+1)) { - err('i'); - } - } else { - if (--flevel < iflvl[tlevel]) { - err('i'); - } - } - lmode = SLIST; - return; - - case S_ENDIF: - if (tlevel) { - flevel = iflvl[tlevel--]; - } else { - err('i'); - } - lmode = SLIST; - return; - - case S_PAGE: - lop = NLPP; - lmode = NLIST; - return; - - default: - break; - } - if (flevel) - return; - /* - * If we are not in a false state for .if/.else then - * process the assembler directives here. - */ - switch (mp->m_type) { - - case S_EVEN: - outall(); - laddr = dot.s_addr = (dot.s_addr + 1) & ~1; - lmode = ALIST; - break; - - case S_ODD: - outall(); - laddr = dot.s_addr |= 1; - lmode = ALIST; - break; - - case S_BYTE: - case S_WORD: - do { - clrexpr(&e1); - expr(&e1, 0); - if (mp->m_type == S_BYTE) { - outrb(&e1, R_NORM); - } else { - outrw(&e1, R_NORM); - } - } while ((c = getnb()) == ','); - unget(c); - break; - - case S_ASCII: - case S_ASCIZ: - if ((d = getnb()) == '\0') - qerr(); - while ((c = getmap(d)) >= 0) - outab(c); - if (mp->m_type == S_ASCIZ) - outab(0); - break; - - case S_ASCIS: - if ((d = getnb()) == '\0') - qerr(); - c = getmap(d); - while (c >= 0) { - if ((n = getmap(d)) >= 0) { - outab(c); - } else { - outab(c | 0x80); - } - c = n; - } - break; - - case S_BLK: - clrexpr(&e1); - expr(&e1, 0); - outchk(HUGE,HUGE); - dot.s_addr += e1.e_addr*mp->m_valu; - lmode = BLIST; - break; - - case S_TITLE: - p = tb; - if ((c = getnb()) != 0) { - do { - if (p < &tb[NTITL-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; - break; - - case S_SBTL: - p = stb; - if ((c = getnb()) != 0) { - do { - if (p < &stb[NSBTL-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; - break; - - case S_MODUL: - getst(id, getnb()); // a module can start with a digit - if (pass == 0) { - if (module[0]) { - err('m'); - } else { - strncpy(module, id, NCPS); - } - } - lmode = SLIST; - break; - - case S_OPTSDCC: - p = optsdcc; - if ((c = getnb()) != 0) { - do { - if (p < &optsdcc[NINPUT-1]) - *p++ = c; - } while ((c = get()) != 0); - } - *p = 0; - unget(c); - lmode = SLIST; + if ((c=endline()) == 0) { return; } + /* + * If the first character is a digit then assume + * a local symbol is being specified. The symbol + * must end with $: to be valid. + * pass 0: + * Construct a tsym structure at the first + * occurance of the symbol. Flag the symbol + * as multiply defined if not the first occurance. + * pass 1: + * Load area, address, and fuzz values + * into structure tsym. + * pass 2: + * Check for assembler phase error and + * multiply defined error. + */ + if (ctype[c] & DIGIT) { + if (flevel) + return; + n = 0; + while ((d = digit(c, 10)) >= 0) { + n = 10*n + d; + c = get(); + } + if (c != '$' || get() != ':') + qerr(); + tp = symp->s_tsym; + if (pass == 0) { + while (tp) { + if (n == tp->t_num) { + tp->t_flg |= S_MDF; + break; + } + tp = tp->t_lnk; + } + if (tp == NULL) { + tp=(struct tsym *) new (sizeof(struct tsym)); + tp->t_lnk = symp->s_tsym; + tp->t_num = n; + tp->t_flg = 0; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + symp->s_tsym = tp; + } + } else { + while (tp) { + if (n == tp->t_num) { + break; + } + tp = tp->t_lnk; + } + if (tp) { + if (pass == 1) { + fuzz = tp->t_addr - dot.s_addr; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + } else { + phase(tp->t_area, tp->t_addr); + if (tp->t_flg & S_MDF) + err('m'); + } + } else { + err('u'); + } + } + lmode = ALIST; + goto loop; + } + /* + * If the first character is a letter then assume a label, + * symbol, assembler directive, or assembler mnemonic is + * being processed. + */ + if ((ctype[c] & LETTER) == 0) { + if (flevel) { + return; + } else { + qerr(); + } + } + getid(id, c); + c = getnb(); + /* + * If the next character is a : then a label is being processed. + * A double :: defines a global label. If this is new label + * then create a symbol structure. + * pass 0: + * Flag multiply defined labels. + * pass 1: + * Load area, address, and fuzz values + * into structure symp. + * pass 2: + * Check for assembler phase error and + * multiply defined error. + */ + if (c == ':') { + if (flevel) + return; + if ((c = get()) != ':') { + unget(c); + c = 0; + } + symp = lookup(id); + if (symp == &dot) + err('.'); + if (pass == 0) + if ((symp->s_type != S_NEW) && + ((symp->s_flag & S_ASG) == 0)) + symp->s_flag |= S_MDF; + if (pass != 2) { + fuzz = symp->s_addr - dot.s_addr; + symp->s_type = S_USER; + symp->s_area = dot.s_area; + symp->s_addr = dot.s_addr; + } else { + if (symp->s_flag & S_MDF) + err('m'); + phase(symp->s_area, symp->s_addr); + } + if (c) { + symp->s_flag |= S_GBL; + } + lmode = ALIST; + goto loop; + } + /* + * If the next character is a = then an equate is being processed. + * A double == defines a global equate. If this is new variable + * then create a symbol structure. + */ + if (c == '=') { + if (flevel) + return; + if ((c = get()) != '=') { + unget(c); + c = 0; + } + clrexpr(&e1); + expr(&e1, 0); + sp = lookup(id); + if (sp == &dot) { + outall(); + if (e1.e_flag || e1.e_base.e_ap != dot.s_area) + err('.'); + } else + if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { + err('m'); + } + sp->s_type = S_USER; + sp->s_area = e1.e_base.e_ap; + sp->s_addr = laddr = e1.e_addr; + sp->s_flag |= S_ASG; + if (c) { + sp->s_flag |= S_GBL; + } + lmode = ELIST; + goto loop; + } + unget(c); + lmode = flevel ? SLIST : CLIST; + if ((mp = mlookup(id)) == NULL) { + if (!flevel) + err('o'); + return; + } + /* + * If we have gotten this far then we have found an + * assembler directive or an assembler mnemonic. + * + * Check for .if, .else, .endif, and .page directives + * which are not controlled by the conditional flags + */ + switch (mp->m_type) { + + case S_IF: + n = absexpr(); + if (tlevel < MAXIF) { + ++tlevel; + ifcnd[tlevel] = n; + iflvl[tlevel] = flevel; + if (n == 0) { + ++flevel; + } + } else { + err('i'); + } + lmode = ELIST; + laddr = n; + return; + + case S_ELSE: + if (ifcnd[tlevel]) { + if (++flevel > (iflvl[tlevel]+1)) { + err('i'); + } + } else { + if (--flevel < iflvl[tlevel]) { + err('i'); + } + } + lmode = SLIST; + return; + + case S_ENDIF: + if (tlevel) { + flevel = iflvl[tlevel--]; + } else { + err('i'); + } + lmode = SLIST; + return; + + case S_PAGE: + lop = NLPP; + lmode = NLIST; + return; + + default: + break; + } + if (flevel) + return; + /* + * If we are not in a false state for .if/.else then + * process the assembler directives here. + */ + switch (mp->m_type) { + + case S_EVEN: + outall(); + laddr = dot.s_addr = (dot.s_addr + 1) & ~1; + lmode = ALIST; + break; + + case S_ODD: + outall(); + laddr = dot.s_addr |= 1; + lmode = ALIST; + break; + + case S_BYTE: + case S_WORD: + do { + clrexpr(&e1); + expr(&e1, 0); + if (mp->m_type == S_BYTE) { + outrb(&e1, R_NORM); + } else { + outrw(&e1, R_NORM); + } + } while ((c = getnb()) == ','); + unget(c); + break; + + case S_ASCII: + case S_ASCIZ: + if ((d = getnb()) == '\0') + qerr(); + while ((c = getmap(d)) >= 0) + outab(c); + if (mp->m_type == S_ASCIZ) + outab(0); + break; + + case S_ASCIS: + if ((d = getnb()) == '\0') + qerr(); + c = getmap(d); + while (c >= 0) { + if ((n = getmap(d)) >= 0) { + outab(c); + } else { + outab(c | 0x80); + } + c = n; + } + break; + + case S_BLK: + clrexpr(&e1); + expr(&e1, 0); + outchk(HUGE,HUGE); + dot.s_addr += e1.e_addr*mp->m_valu; + lmode = BLIST; + break; + + case S_TITLE: + p = tb; + if ((c = getnb()) != 0) { + do { + if (p < &tb[NTITL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_SBTL: + p = stb; + if ((c = getnb()) != 0) { + do { + if (p < &stb[NSBTL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_MODUL: + getst(id, getnb()); // a module can start with a digit + if (pass == 0) { + if (module[0]) { + err('m'); + } else { + strncpy(module, id, NCPS); + } + } + lmode = SLIST; + break; + + case S_OPTSDCC: + p = optsdcc; + if ((c = getnb()) != 0) { + do { + if (p < &optsdcc[NINPUT-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; /*if (pass == 0) printf("optsdcc=%s\n", optsdcc);*/ break; - case S_GLOBL: - do { - getid(id, -1); - sp = lookup(id); - sp->s_flag |= S_GBL; - } while ((c = getnb()) == ','); - unget(c); - lmode = SLIST; - break; - - case S_DAREA: - getid(id, -1); - uaf = 0; - uf = A_CON|A_REL; - if ((c = getnb()) == '(') { - do { - getid(opt, -1); - mp = mlookup(opt); - if (mp && mp->m_type == S_ATYP) { - ++uaf; - uf |= mp->m_valu; - } else { - err('u'); - } - } while ((c = getnb()) == ','); - if (c != ')') - qerr(); - } else { - unget(c); - } - if ((ap = alookup(id)) != NULL) { - if (uaf && uf != ap->a_flag) - err('m'); - } else { - ap = (struct area *) new (sizeof(struct area)); - ap->a_ap = areap; - strncpy(ap->a_id, id, NCPS); - ap->a_ref = areap->a_ref + 1; - ap->a_size = 0; - ap->a_fuzz = 0; - ap->a_flag = uaf ? uf : (A_CON|A_REL); - areap = ap; - } - newdot(ap); - lmode = SLIST; - if (dot.s_area->a_flag & A_ABS) - abs_ap = ap; - break; - - case S_ORG: - if (dot.s_area->a_flag & A_ABS) { - char buf[NCPS]; - laddr = absexpr(); - sprintf(buf, "%s%x", abs_ap->a_id, laddr); - if ((ap = alookup(buf)) == NULL) { - ap = (struct area *) new (sizeof(struct area)); - *ap = *areap; - ap->a_ap = areap; - strncpy(ap->a_id, buf, NCPS); - ap->a_ref = areap->a_ref + 1; - ap->a_size = 0; - ap->a_fuzz = 0; - areap = ap; - } - newdot(ap); - lmode = ALIST; - dot.s_addr = dot.s_org = laddr; - } else { - err('o'); - } - break; - - case S_RADIX: - if (more()) { - switch (getnb()) { - case 'b': - case 'B': - radix = 2; - break; - case '@': - case 'o': - case 'O': - case 'q': - case 'Q': - radix = 8; - break; - case 'd': - case 'D': - radix = 10; - break; - case 'h': - case 'H': - case 'x': - case 'X': - radix = 16; - break; - default: - radix = 10; - qerr(); - break; - } - } else { - radix = 10; - } - lmode = SLIST; - break; - - case S_INCL: - d = getnb(); - p = fn; - while ((c = get()) != d) { - if (p < &fn[PATH_MAX-1]) { - *p++ = c; - } else { - break; - } - } - *p = 0; - if ((++incfil == MAXINC) || - (ifp[incfil] = fopen(fn, "r")) == NULL) { - --incfil; - err('i'); - } else { - lop = NLPP; - incline[incfil] = 0; - strcpy(incfn[incfil],fn); - } - lmode = SLIST; - break; - - case S_FLAT24: - if (more()) - { - getst(id, -1); - - if (!as_strcmpi(id, "on")) - { - /* Quick sanity check: size of - * Addr_T must be at least 24 bits. - */ - if (sizeof(Addr_T) < 3) - { - warnBanner(); - fprintf(stderr, - "Cannot enable Flat24 mode: " - "host system must have 24 bit " - "or greater integers.\n"); - } - else - { - flat24Mode = 1; - } - } - else if (!as_strcmpi(id, "off")) - { - flat24Mode = 0; - } - else - { - qerr(); - } - } - else - { - qerr(); - } - lmode = SLIST; - #if 0 - printf("as8051: ds390 flat mode %sabled.\n", - flat24Mode ? "en" : "dis"); - #endif - break; - - - /* - * If not an assembler directive then go to - * the machine dependent function which handles - * all the assembler mnemonics. - */ - default: - machine(mp); - /* if cdb information the generate the line info */ - if (cflag && (pass == 1)) - DefineCDB_Line(); + case S_GLOBL: + do { + getid(id, -1); + sp = lookup(id); + sp->s_flag |= S_GBL; + } while ((c = getnb()) == ','); + unget(c); + lmode = SLIST; + break; + + case S_DAREA: + getid(id, -1); + uaf = 0; + uf = A_CON|A_REL; + if ((c = getnb()) == '(') { + do { + getid(opt, -1); + mp = mlookup(opt); + if (mp && mp->m_type == S_ATYP) { + ++uaf; + uf |= mp->m_valu; + } else { + err('u'); + } + } while ((c = getnb()) == ','); + if (c != ')') + qerr(); + } else { + unget(c); + } + if ((ap = alookup(id)) != NULL) { + if (uaf && uf != ap->a_flag) + err('m'); + } else { + ap = (struct area *) new (sizeof(struct area)); + ap->a_ap = areap; + strncpy(ap->a_id, id, NCPS); + ap->a_ref = areap->a_ref + 1; + ap->a_size = 0; + ap->a_fuzz = 0; + ap->a_flag = uaf ? uf : (A_CON|A_REL); + areap = ap; + } + newdot(ap); + lmode = SLIST; + if (dot.s_area->a_flag & A_ABS) + abs_ap = ap; + break; + + case S_ORG: + if (dot.s_area->a_flag & A_ABS) { + char buf[NCPS]; + laddr = absexpr(); + sprintf(buf, "%s%x", abs_ap->a_id, laddr); + if ((ap = alookup(buf)) == NULL) { + ap = (struct area *) new (sizeof(struct area)); + *ap = *areap; + ap->a_ap = areap; + strncpy(ap->a_id, buf, NCPS); + ap->a_ref = areap->a_ref + 1; + ap->a_size = 0; + ap->a_fuzz = 0; + areap = ap; + } + newdot(ap); + lmode = ALIST; + dot.s_addr = dot.s_org = laddr; + } else { + err('o'); + } + break; + + case S_RADIX: + if (more()) { + switch (getnb()) { + case 'b': + case 'B': + radix = 2; + break; + case '@': + case 'o': + case 'O': + case 'q': + case 'Q': + radix = 8; + break; + case 'd': + case 'D': + radix = 10; + break; + case 'h': + case 'H': + case 'x': + case 'X': + radix = 16; + break; + default: + radix = 10; + qerr(); + break; + } + } else { + radix = 10; + } + lmode = SLIST; + break; + + case S_INCL: + d = getnb(); + p = fn; + while ((c = get()) != d) { + if (p < &fn[PATH_MAX-1]) { + *p++ = c; + } else { + break; + } + } + *p = 0; + if ((++incfil == MAXINC) || + (ifp[incfil] = search_path_fopen(fn, "r")) == NULL) { + --incfil; + err('i'); + } else { + lop = NLPP; + incline[incfil] = 0; + strcpy(incfn[incfil],fn); + } + lmode = SLIST; + break; + + case S_FLAT24: + if (more()) + { + getst(id, -1); + + if (!as_strcmpi(id, "on")) + { + /* Quick sanity check: size of + * Addr_T must be at least 24 bits. + */ + if (sizeof(Addr_T) < 3) + { + warnBanner(); + fprintf(stderr, + "Cannot enable Flat24 mode: " + "host system must have 24 bit " + "or greater integers.\n"); + } + else + { + flat24Mode = 1; + } + } + else if (!as_strcmpi(id, "off")) + { + flat24Mode = 0; + } + else + { + qerr(); + } + } + else + { + qerr(); + } + lmode = SLIST; + #if 0 + printf("as8051: ds390 flat mode %sabled.\n", + flat24Mode ? "en" : "dis"); + #endif + break; + + + /* + * If not an assembler directive then go to + * the machine dependent function which handles + * all the assembler mnemonics. + */ + default: + machine(mp); + /* if cdb information then generate the line info */ + if (cflag && (pass == 1)) + DefineCDB_Line(); /* JLH: if -j, generate a line number symbol */ if (jflag && (pass == 1)) @@ -1016,49 +1085,49 @@ loop: DefineNoICE_Line(); } - } - goto loop; + } + goto loop; } -/*)Function FILE * afile(fn, ft, wf) +/*)Function FILE * afile(fn, ft, wf) * - * char * fn file specification string - * char * ft file type string - * int wf read(0)/write(1) flag + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag * - * The function afile() opens a file for reading or writing. - * (1) If the file type specification string ft - * is not NULL then a file specification is - * constructed with the file path\name in fn - * and the extension in ft. - * (2) If the file type specification string ft - * is NULL then the file specification is - * constructed from fn. If fn does not have - * a file type then the default source file - * type dsft is appended to the file specification. + * The function afile() opens a file for reading or writing. + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default source file + * type dsft is appended to the file specification. * - * afile() returns a file handle for the opened file or aborts - * the assembler on an open error. + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. * - * local variables: - * int c character value - * FILE * fp filehandle for opened file - * char * p1 pointer to filespec string fn - * char * p2 pointer to filespec string fb - * char * p3 pointer to filetype string ft + * local variables: + * int c character value + * FILE * fp filehandle for opened file + * char * p1 pointer to filespec string fn + * char * p2 pointer to filespec string fb + * char * p3 pointer to filetype string ft * - * global variables: - * char afn[] afile() constructed filespec - * char dsft[] default assembler file type string - * char afn[] constructed file specification string + * global variables: + * char afn[] afile() constructed filespec + * char dsft[] default assembler file type string + * char afn[] constructed file specification string * - * functions called: - * VOID asexit() asmain.c - * FILE * fopen() c_library - * int fprintf() c_library + * functions called: + * VOID asexit() asmain.c + * FILE * fopen() c_library + * int fprintf() c_library * - * side effects: - * File is opened for read or write. + * side effects: + * File is opened for read or write. */ FILE * @@ -1067,132 +1136,132 @@ char *fn; char *ft; int wf; { - register char *p2, *p3; - register int c; - FILE *fp; - - p2 = afn; - p3 = ft; - - strcpy (afn, fn); - p2 = strrchr (afn, FSEPX); // search last '.' - if (!p2) - p2 = afn + strlen (afn); - if (p2 > &afn[PATH_MAX-4]) // truncate filename, if it's too long - p2 = &afn[PATH_MAX-4]; - *p2++ = FSEPX; - - // choose a file-extension - if (*p3 == 0) { // extension supplied? - p3 = strrchr (fn, FSEPX); // no: extension in fn? - if (p3) - ++p3; - else - p3 = dsft; // no: default extension - } - - while ((c = *p3++) != 0) { // strncpy - if (p2 < &afn[PATH_MAX-1]) - *p2++ = c; - } - *p2++ = 0; - - if ((fp = fopen(afn, wf?"w":"r")) == NULL) { - fprintf(stderr, "%s: cannot %s.\n", afn, wf?"create":"open"); - asexit(1); - } - return (fp); + register char *p2, *p3; + register int c; + FILE *fp; + + p2 = afn; + p3 = ft; + + strcpy (afn, fn); + p2 = strrchr (afn, FSEPX); // search last '.' + if (!p2) + p2 = afn + strlen (afn); + if (p2 > &afn[PATH_MAX-4]) // truncate filename, if it's too long + p2 = &afn[PATH_MAX-4]; + *p2++ = FSEPX; + + // choose a file-extension + if (*p3 == 0) { // extension supplied? + p3 = strrchr (fn, FSEPX); // no: extension in fn? + if (p3) + ++p3; + else + p3 = dsft; // no: default extension + } + + while ((c = *p3++) != 0) { // strncpy + if (p2 < &afn[PATH_MAX-1]) + *p2++ = c; + } + *p2++ = 0; + + if ((fp = fopen(afn, wf?"w":"r")) == NULL) { + fprintf(stderr, "%s: cannot %s.\n", afn, wf?"create":"open"); + asexit(1); + } + return (fp); } -/*)Function VOID newdot(nap) +/*)Function VOID newdot(nap) * - * area * nap pointer to the new area structure + * area * nap pointer to the new area structure * - * The function newdot(): - * (1) copies the current values of fuzz and the last - * address into the current area referenced by dot - * (2) loads dot with the pointer to the new area and - * loads the fuzz and last address parameters - * (3) outall() is called to flush any remaining - * bufferred code from the old area to the output + * The function newdot(): + * (1) copies the current values of fuzz and the last + * address into the current area referenced by dot + * (2) loads dot with the pointer to the new area and + * loads the fuzz and last address parameters + * (3) outall() is called to flush any remaining + * bufferred code from the old area to the output * - * local variables: - * area * oap pointer to old area + * local variables: + * area * oap pointer to old area * - * global variables: - * sym dot defined as sym[0] - * Addr_T fuzz tracks pass to pass changes in the - * address of symbols caused by - * variable length instruction formats + * global variables: + * sym dot defined as sym[0] + * Addr_T fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats * - * functions called: - * none + * functions called: + * none * - * side effects: - * Current area saved, new area loaded, buffers flushed. + * side effects: + * Current area saved, new area loaded, buffers flushed. */ VOID newdot(nap) register struct area *nap; { - register struct area *oap; - - oap = dot.s_area; - /* fprintf (stderr, "%s dot.s_area->a_size: %d dot.s_addr: %d\n", - oap->a_id, dot.s_area->a_size, dot.s_addr); */ - oap->a_fuzz = fuzz; - if (oap->a_flag & A_OVR) { - // the size of an overlay is the biggest size encountered - if (oap->a_size < dot.s_addr) { - oap->a_size = dot.s_addr; - } - } else if (oap->a_flag & A_ABS) { - oap->a_addr = dot.s_org; - oap->a_size += dot.s_addr - dot.s_org; - dot.s_addr = dot.s_org = 0; - } else { - oap->a_addr = 0; - oap->a_size = dot.s_addr; - } - if (nap->a_flag & A_OVR) { - // a new overlay starts at 0, no fuzz - dot.s_addr = 0; - fuzz = 0; - } else if (nap->a_flag & A_ABS) { - // a new absolute starts at org, no fuzz - dot.s_addr = dot.s_org; - fuzz = 0; - } else { - dot.s_addr = nap->a_size; - fuzz = nap->a_fuzz; - } - dot.s_area = nap; - outall(); + register struct area *oap; + + oap = dot.s_area; + /* fprintf (stderr, "%s dot.s_area->a_size: %d dot.s_addr: %d\n", + oap->a_id, dot.s_area->a_size, dot.s_addr); */ + oap->a_fuzz = fuzz; + if (oap->a_flag & A_OVR) { + // the size of an overlay is the biggest size encountered + if (oap->a_size < dot.s_addr) { + oap->a_size = dot.s_addr; + } + } else if (oap->a_flag & A_ABS) { + oap->a_addr = dot.s_org; + oap->a_size += dot.s_addr - dot.s_org; + dot.s_addr = dot.s_org = 0; + } else { + oap->a_addr = 0; + oap->a_size = dot.s_addr; + } + if (nap->a_flag & A_OVR) { + // a new overlay starts at 0, no fuzz + dot.s_addr = 0; + fuzz = 0; + } else if (nap->a_flag & A_ABS) { + // a new absolute starts at org, no fuzz + dot.s_addr = dot.s_org; + fuzz = 0; + } else { + dot.s_addr = nap->a_size; + fuzz = nap->a_fuzz; + } + dot.s_area = nap; + outall(); } -/*)Function VOID phase(ap, a) +/*)Function VOID phase(ap, a) * - * area * ap pointer to area - * Addr_T a address in area + * area * ap pointer to area + * Addr_T a address in area * - * Function phase() compares the area ap and address a - * with the current area dot.s_area and address dot.s_addr - * to determine if the position of the symbol has changed - * between assembler passes. + * Function phase() compares the area ap and address a + * with the current area dot.s_area and address dot.s_addr + * to determine if the position of the symbol has changed + * between assembler passes. * - * local variables: - * none + * local variables: + * none * - * global varaibles: - * sym * dot defined as sym[0] + * global varaibles: + * sym * dot defined as sym[0] * - * functions called: - * none + * functions called: + * none * - * side effects: - * The p error is invoked if the area and/or address - * has changed. + * side effects: + * The p error is invoked if the area and/or address + * has changed. */ VOID @@ -1200,56 +1269,59 @@ phase(ap, a) struct area *ap; Addr_T a; { - if (ap != dot.s_area || a != dot.s_addr) - err('p'); + if (ap != dot.s_area || a != dot.s_addr) + err('p'); } char *usetxt[] = { - "Usage: [-dqxjgalopsf] file1 [file2 file3 ...]", - " d decimal listing", - " q octal listing", - " x hex listing (default)", - " j add line number and debug information to file", /* JLH */ - " g undefined symbols made global", - " a all user symbols made global", - " l create list output file1[LST]", - " o create object output file1[REL]", - " s create symbol output file1[SYM]", - " p disable listing pagination", - " f flag relocatable references by ` in listing file", - " ff flag relocatable references by mode in listing file", - "", - 0 + "Usage: [-dqxjgalopsf][ -I ] file1 [file2 file3 ...]", + " d decimal listing", + " q octal listing", + " x hex listing (default)", + " j add line number and debug information to file", /* JLH */ + " g undefined symbols made global", + " a all user symbols made global", + " l create list output file1[LST]", + " o create object output file1[REL]", + " s create symbol output file1[SYM]", + " p disable listing pagination", + " f flag relocatable references by ` in listing file", + " ff flag relocatable references by mode in listing file", + "-I Add the named directory to the include file", + " search path. This option may be used more than once.", + " Directories are searched in the order given.", + "", + 0 }; -/*)Function VOID usage() +/*)Function VOID usage() * - * The function usage() outputs to the stderr device the - * assembler name and version and a list of valid assembler options. + * The function usage() outputs to the stderr device the + * assembler name and version and a list of valid assembler options. * - * local variables: - * char ** dp pointer to an array of - * text string pointers. + * local variables: + * char ** dp pointer to an array of + * text string pointers. * - * global variables: - * char cpu[] assembler type string - * char * usetxt[] array of string pointers + * global variables: + * char cpu[] assembler type string + * char * usetxt[] array of string pointers * - * functions called: - * VOID asexit() asmain.c - * int fprintf() c_library + * functions called: + * VOID asexit() asmain.c + * int fprintf() c_library * - * side effects: - * program is terminated + * side effects: + * program is terminated */ VOID usage() { - register char **dp; + register char **dp; - fprintf(stderr, "\nASxxxx Assembler %s (%s)\n\n", VERSION, cpu); - for (dp = usetxt; *dp; dp++) - fprintf(stderr, "%s\n", *dp); - asexit(1); + fprintf(stderr, "\nASxxxx Assembler %s (%s)\n\n", VERSION, cpu); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + asexit(1); } diff --git a/device/include/mcs51/compiler.h b/device/include/mcs51/compiler.h index cc8f6a32..e8bdc283 100644 --- a/device/include/mcs51/compiler.h +++ b/device/include/mcs51/compiler.h @@ -114,7 +114,11 @@ # define SBIT(name, addr, bit) _sfrbit name _at(addr+bit) # define SFR(name, addr) _sfrbyte name _at(addr) # define SFRX(name, addr) _xdat volatile unsigned char name _at(addr) +#if _CC51 > 71 +# define SFR16(name, addr) _sfrword _little name _at(addr) +#else # define SFR16(name, addr) /* not supported */ +#endif # define SFR16E(name, fulladdr) /* not supported */ # define SFR32(name, fulladdr) /* not supported */ # define SFR32E(name, fulladdr) /* not supported */ diff --git a/src/z80/main.c b/src/z80/main.c index 446db99c..64984af6 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -30,13 +30,13 @@ #include "SDCCargs.h" #include "dbuf_string.h" -#define OPTION_BO "-bo" -#define OPTION_BA "-ba" -#define OPTION_CODE_SEG "--codeseg" -#define OPTION_CONST_SEG "--constseg" -#define OPTION_CALLE_SAVES_BC "--calle-saves-bc" -#define OPTION_PORTMODE "--portmode=" -#define OPTION_ASM "--asm=" +#define OPTION_BO "-bo" +#define OPTION_BA "-ba" +#define OPTION_CODE_SEG "--codeseg" +#define OPTION_CONST_SEG "--constseg" +#define OPTION_CALLEE_SAVES_BC "--callee-saves-bc" +#define OPTION_PORTMODE "--portmode=" +#define OPTION_ASM "--asm=" static char _z80_defaultRules[] = @@ -55,21 +55,21 @@ Z80_OPTS z80_opts; static OPTION _z80_options[] = { - { 0, OPTION_CALLE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC" }, - { 0, OPTION_PORTMODE, NULL, "Determine PORT I/O mode (z80/z180)" }, - { 0, OPTION_ASM, NULL, "Define assembler name (rgbds/asxxxx/isas/z80asm)" }, - { 0, OPTION_CODE_SEG, NULL, " use this name for the code segment" }, - { 0, OPTION_CONST_SEG, NULL, " use this name for the const segment" }, + { 0, OPTION_CALLEE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC" }, + { 0, OPTION_PORTMODE, NULL, "Determine PORT I/O mode (z80/z180)" }, + { 0, OPTION_ASM, NULL, "Define assembler name (rgbds/asxxxx/isas/z80asm)" }, + { 0, OPTION_CODE_SEG, NULL, " use this name for the code segment" }, + { 0, OPTION_CONST_SEG, NULL, " use this name for the const segment" }, { 0, NULL } }; static OPTION _gbz80_options[] = { - { 0, OPTION_BO, NULL, " use code bank " }, - { 0, OPTION_BA, NULL, " use data bank " }, - { 0, OPTION_CALLE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC" }, - { 0, OPTION_CODE_SEG, NULL, " use this name for the code segment" }, - { 0, OPTION_CONST_SEG, NULL, " use this name for the const segment" }, + { 0, OPTION_BO, NULL, " use code bank " }, + { 0, OPTION_BA, NULL, " use data bank " }, + { 0, OPTION_CALLEE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC" }, + { 0, OPTION_CODE_SEG, NULL, " use this name for the code segment" }, + { 0, OPTION_CONST_SEG, NULL, " use this name for the const segment" }, { 0, NULL } };