X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=as%2Fmcs51%2Flkmain.c;h=43392b83b1999a489a7058a5d22171b96ade93eb;hb=0b169912b0393d64149a308c4e9f1cb994a620a2;hp=96f48736b380e0c6e988044ea081429cc809bcd7;hpb=f93eb1eafde8985b8634d476b01641de63124b9e;p=fw%2Fsdcc diff --git a/as/mcs51/lkmain.c b/as/mcs51/lkmain.c index 96f48736..43392b83 100644 --- a/as/mcs51/lkmain.c +++ b/as/mcs51/lkmain.c @@ -10,1100 +10,1267 @@ * * 31-Oct-97 JLH: * - add jflag and jfp to control NoICE output file genration - * 3-Nov-97 JLH: + * 3-Nov-97 JLH: * - use a_type == 0 as "virgin area" flag: set == 1 if -b */ +#include #include #include -#if defined(_MSC_VER) -#include -#else -#include -#endif #include "aslink.h" -/* yuck - but including unistd.h causes problems on Cygwin by redefining - * addr_t. - */ -extern int unlink(const char *); - -/*)Module lkmain.c - * - * The module lkmain.c contains the functions which - * (1) input the linker options, parameters, and specifications - * (2) perform a two pass link - * (3) produce the appropriate linked data output and/or - * link map file and/or relocated listing files. - * - * lkmain.c contains the following functions: - * FILE * afile(fn,ft,wf) - * VOID bassav() - * VOID gblsav() - * VOID link_main() - * VOID lkexit() - * VOID main(argc,argv) - * VOID map() - * int parse() - * VOID setbas() - * VOID setgbl() - * VOID usage() - * - * lkmain.c contains the following local variables: - * char * usetext[] array of pointers to the - * command option tect lines +#ifdef WIN32T +#include + +void Timer(int action, char * message) +{ + static double start, end, total=0.0; + static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; + + if(action==0) start=clock()*secs_per_tick; + else if(action==1) + { + end=clock() * secs_per_tick; + printf("%s \t%f seconds.\n", message, (end-start)); + total+=end-start; + } + else + { + printf("Total time: \t%f seconds.\n", total); + total=0.0; + } +} +#endif + +/*)Module lkmain.c + * + * The module lkmain.c contains the functions which + * (1) input the linker options, parameters, and specifications + * (2) perform a two pass link + * (3) produce the appropriate linked data output and/or + * link map file and/or relocated listing files. + * + * lkmain.c contains the following functions: + * FILE * afile(fn,ft,wf) + * VOID bassav() + * VOID gblsav() + * VOID link_main() + * VOID lkexit() + * VOID main(argc,argv) + * VOID map() + * int parse() + * VOID setbas() + * VOID setgbl() + * VOID usage() + * + * lkmain.c contains the following local variables: + * char * usetext[] array of pointers to the + * command option tect lines * */ -/*)Function VOID main(argc,argv) - * - * int argc number of command line arguments + 1 - * char * argv[] array of pointers to the command line - * arguments - * - * The function main() evaluates the command line arguments to - * determine if the linker parameters are to input through 'stdin' - * or read from a command file. The functiond getline() and parse() - * are to input and evaluate the linker parameters. The linking process - * proceeds by making the first pass through each .rel file in the order - * presented to the linker. At the end of the first pass the setbase(), - * lnkarea(), setgbl(), and symdef() functions are called to evaluate - * the base address terms, link all areas, define global variables, - * and look for undefined symbols. Following these routines a linker - * map file may be produced and the linker output files may be opened. - * The second pass through the .rel files will output the linked data - * in one of the four supported formats. - * - * local variables: - * char * p pointer to an argument string - * int c character from argument string - * int i loop counter - * - * global variables: - * text line in ib[] - * lfile *cfp The pointer *cfp points to the - * current lfile structure - * char ctype[] array of character types, one per - * ASCII character - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * head *hp Pointer to the current - * head structure - * char ib[NINPUT] .rel file text line - * char *ip pointer into the .rel file - * lfile *linkp pointer to first lfile structure - * containing an input .rel file - * specification - * int lkerr error flag - * int mflag Map output flag - * int oflag Output file type flag - * FILE *ofp Output file handle - * for word formats - * FILE *ofph Output file handle - * for high byte format - * FILE *ofpl Output file handle - * for low byte format - * int pass linker pass number - * int pflag print linker command file flag - * int radix current number conversion radix - * FILE *sfp The file handle sfp points to the - * currently open file - * lfile *startp asmlnk startup file structure - * FILE * stdin c_library - * FILE * stdout c_library - * - * functions called: - * FILE * afile() lkmain.c - * int fclose() c_library - * int fprintf() c_library - * int getline() lklex.c - * VOID library() lklibr.c - * VOID link_main() lkmain.c - * VOID lkexit() lkmain.c - * VOID lnkarea() lkarea.c - * VOID map() lkmain.c - * VOID new() lksym.c - * int parse() lkmain.c - * VOID reloc() lkreloc.c - * VOID search() lklibr.c - * VOID setbas() lkmain.c - * VOID setgbl() lkmain.c - * VOID symdef() lksym.c - * VOID usage() lkmain.c - * - * side effects: - * Completion of main() completes the linking process - * and may produce a map file (.map) and/or a linked - * data files (.ihx or .s19) and/or one or more - * relocated listing files (.rst). +/*JCF: Creates some of the default areas so they are allocated in the right order.*/ +void Areas51 (void) +{ + char * rel[]={ + "XH", + "H 7 areas 0 global symbols", + "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ + "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ + "A REG_BANK_1 size 0 flags 4", + "A REG_BANK_2 size 0 flags 4", + "A REG_BANK_3 size 0 flags 4", + "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ + "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ + "" + }; + + char * rel2[]={ + "XH", + "H C areas 0 global symbols", + "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ + "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ + "A REG_BANK_1 size 0 flags 4", + "A REG_BANK_2 size 0 flags 4", + "A REG_BANK_3 size 0 flags 4", + "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ + "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ + "A BIT_BANK size 0 flags 4", /*Bit register bank is overlayable*/ + "A DSEG size 0 flags 0", + "A OSEG size 0 flags 4", + "A ISEG size 0 flags 0", + "A SSEG size 0 flags 4", + "" + }; + int j; + struct sym * sp; + + if(packflag) + { + for (j=0; rel2[j][0]!=0; j++) + { + ip=rel2[j]; + link_main(); + } + } + else + { + for (j=0; rel[j][0]!=0; j++) + { + ip=rel[j]; + link_main(); + } + } + + /*Set the start address of the default areas:*/ + for(ap=areap; ap; ap=ap->a_ap) + { + /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; } + else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; } + else if (!strcmp(ap->a_id, "SSEG")) + { + if(stacksize) ap->a_axp->a_size=stacksize; + } + } + + sp = lkpsym("l_IRAM", 1); + sp->s_addr = ((iram_size>0) && (iram_size<=0x100)) ? iram_size : 0x0100; + sp->s_axp = NULL; + sp->s_type |= S_DEF; +} + +/*)Function VOID main(argc,argv) + * + * int argc number of command line arguments + 1 + * char * argv[] array of pointers to the command line + * arguments + * + * The function main() evaluates the command line arguments to + * determine if the linker parameters are to input through 'stdin' + * or read from a command file. The functions as_getline() and parse() + * are to input and evaluate the linker parameters. The linking process + * proceeds by making the first pass through each .rel file in the order + * presented to the linker. At the end of the first pass the setbase(), + * lnkarea(), setgbl(), and symdef() functions are called to evaluate + * the base address terms, link all areas, define global variables, + * and look for undefined symbols. Following these routines a linker + * map file may be produced and the linker output files may be opened. + * The second pass through the .rel files will output the linked data + * in one of the four supported formats. + * + * local variables: + * char * p pointer to an argument string + * int c character from argument string + * int i loop counter + * + * global variables: + * text line in ib[] + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * char ctype[] array of character types, one per + * ASCII character + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * head *hp Pointer to the current + * head structure + * char ib[NINPUT] .rel file text line + * char *ip pointer into the .rel file + * lfile *linkp pointer to first lfile structure + * containing an input .rel file + * specification + * int lkerr error flag + * int mflag Map output flag + * int oflag Output file type flag + * FILE *ofp Output file handle + * for word formats + * FILE *ofph Output file handle + * for high byte format + * FILE *ofpl Output file handle + * for low byte format + * int pass linker pass number + * int pflag print linker command file flag + * int radix current number conversion radix + * FILE *sfp The file handle sfp points to the + * currently open file + * lfile *startp asmlnk startup file structure + * FILE * stdin c_library + * FILE * stdout c_library + * + * functions called: + * FILE * afile() lkmain.c + * int fclose() c_library + * int fprintf() c_library + * int as_getline() lklex.c + * VOID library() lklibr.c + * VOID link_main() lkmain.c + * VOID lkexit() lkmain.c + * VOID lnkarea() lkarea.c + * VOID map() lkmain.c + * VOID new() lksym.c + * int parse() lkmain.c + * VOID reloc() lkreloc.c + * VOID search() lklibr.c + * VOID setbas() lkmain.c + * VOID setgbl() lkmain.c + * VOID symdef() lksym.c + * VOID usage() lkmain.c + * + * side effects: + * Completion of main() completes the linking process + * and may produce a map file (.map) and/or a linked + * data files (.ihx or .s19) and/or one or more + * relocated listing files (.rst). */ int -main(argc, argv) -char *argv[]; +main(int argc, char *argv[]) { - register char *p; - register int c, i; - - fprintf(stdout, "\n"); - - startp = (struct lfile *) new (sizeof (struct lfile)); - - pflag = 1; - for (i=1; if_type = F_STD; - break; - - case 'f': - case 'F': - startp->f_type = F_LNK; - break; - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - default: - usage(); - } - } - } else { - if (startp->f_type == F_LNK) { - startp->f_idp = p; - } - } - } - if (startp->f_type == 0) - usage(); - if (startp->f_type == F_LNK && startp->f_idp == NULL) - usage(); - - cfp = NULL; - sfp = NULL; - filep = startp; - while (1) { - ip = ib; - if (getline() == 0) - break; - if (pflag && sfp != stdin) - fprintf(stdout, "%s\n", ip); + register char *p; + register int c, i; + +#ifdef WIN32T + Timer(0, ""); +#endif + + startp = (struct lfile *) new (sizeof (struct lfile)); + + pflag = 1; + for (i=1; if_type = F_STD; + break; + + case 'f': + case 'F': + startp->f_type = F_LNK; + break; + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + default: + usage(); + } + } + } else { + if (startp->f_type == F_LNK) { + startp->f_idp = p; + } + } + } + if (startp->f_type == 0) + usage(); + if (startp->f_type == F_LNK && startp->f_idp == NULL) + usage(); + + cfp = NULL; + sfp = NULL; + filep = startp; + while (1) { + ip = ib; + if (as_getline() == 0) + break; + if (pflag && sfp != stdin) + fprintf(stdout, "%s\n", ip); if (*ip == '\0' || parse()) - break; - } - - if (sfp) { - fclose(sfp); - sfp = NULL; - } - - if (linkp == NULL) - usage(); - - syminit(); - - if (dflag){ - dfp = afile("temp", "cdb", 1); - if (dfp == NULL) - lkexit(1); - } - - for (pass=0; pass<2; ++pass) { - cfp = NULL; - sfp = NULL; - filep = linkp; - hp = NULL; - radix = 10; - - while (getline()) { - ip = ib; - - /* pass any "magic comments" to NoICE output */ - if ((ip[0] == ';') && (ip[1] == '!') && jfp) { - fprintf( jfp, "%s\n", &ip[2] ); - } - link_main(); - } - if (pass == 0) { - /* - * Search libraries for global symbols - */ - search(); - /* - * Set area base addresses. - */ - setbas(); - /* - * Link all area addresses. - */ - lnkarea(); - /* - * Process global definitions. - */ - setgbl(); - /* - * Check for undefined globals. - */ - symdef(stderr); - - /* Open NoICE output file if requested */ - if (jflag) { - jfp = afile(linkp->f_idp, "NOI", 1); - if (jfp == NULL) { - lkexit(1); - } - } - - /* - * Output Link Map if requested, - * or if NoICE output requested (since NoICE - * file is generated in part by map() processing) - */ - if (mflag || jflag) - map(); - - if (iram_size) - iramcheck(); - - /* - * Open output file - */ - if (oflag == 1) { - ofp = afile(linkp->f_idp, "ihx", 1); - if (ofp == NULL) { - lkexit(1); - } - /* include NoICE command to load hex file */ - if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp ); - - } else - if (oflag == 2) { - ofp = afile(linkp->f_idp, "S19", 1); - if (ofp == NULL) { - lkexit(1); - } - /* include NoICE command to load hex file */ - if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp ); - } - } else { - /* - * Link in library files - */ - library(); - reloc('E'); - } - } - lkexit(lkerr); - return 0; + break; + } + + if (sfp) { + fclose(sfp); + sfp = NULL; + } + + if (linkp == NULL) + usage(); + + syminit(); + + if (dflag){ + //dfp = afile("temp", "cdb", 1); + SaveLinkedFilePath(linkp->f_idp); //Must be the first one... + dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002 + if (dfp == NULL) + lkexit(1); + } + + for (pass=0; pass<2; ++pass) { + cfp = NULL; + sfp = NULL; + filep = linkp; + hp = NULL; + radix = 10; + + Areas51(); /*JCF: Create the default 8051 areas in the right order*/ + + while (as_getline()) { + ip = ib; + + /* pass any "magic comments" to NoICE output */ + if ((ip[0] == ';') && (ip[1] == '!') && jfp) { + fprintf( jfp, "%s\n", &ip[2] ); + } + link_main(); + } + if (pass == 0) { + /* + * Search libraries for global symbols + */ + search(); + /* + * Set area base addresses. + */ + setbas(); + /* + * Link all area addresses. + */ + if(!packflag) + lnkarea(); + else + lnkarea2(); + /* + * Process global definitions. + */ + setgbl(); + /* + * Check for undefined globals. + */ + symdef(stderr); + + /* Open NoICE output file if requested */ + if (jflag) { + jfp = afile(linkp->f_idp, "NOI", 1); + if (jfp == NULL) { + lkexit(1); + } + } + + /* + * Output Link Map if requested, + * or if NoICE output requested (since NoICE + * file is generated in part by map() processing) + */ + if (mflag || jflag) + map(); + + if (sflag) /*JCF: memory usage summary output*/ + { + if(!packflag) + { + if(summary(areap)) lkexit(1); + } + else + { + if(summary2(areap)) lkexit(1); + } + } + + if ((iram_size) && (!packflag)) + iramcheck(); + + /* + * Open output file + */ + if (oflag == 1) { + ofp = afile(linkp->f_idp, "ihx", 1); + if (ofp == NULL) { + lkexit(1); + } + /* include NoICE command to load hex file */ + if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp ); + + } else + if (oflag == 2) { + ofp = afile(linkp->f_idp, "S19", 1); + if (ofp == NULL) { + lkexit(1); + } + /* include NoICE command to load hex file */ + if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp ); + } + } else { + /* + * Link in library files + */ + library(); + reloc('E'); + } + } + //JCF: + CreateAOMF51(); + +#ifdef WIN32T + Timer(1, "Linker execution time"); +#endif + + lkexit(lkerr); + return 0; } -/*)Function VOID lkexit(i) +/*)Function VOID lkexit(i) * - * int i exit code + * int i exit code * - * The function lkexit() explicitly closes all open - * files and then terminates the program. + * The function lkexit() explicitly closes all open + * files and then terminates the program. * - * local variables: - * none + * local variables: + * none * - * global variables: - * FILE * mfp file handle for .map - * FILE * ofp file handle for .ihx/.s19 - * FILE * rfp file hanlde for .rst - * FILE * sfp file handle for .rel - * FILE * tfp file handle for .lst + * global variables: + * FILE * mfp file handle for .map + * FILE * ofp file handle for .ihx/.s19 + * FILE * rfp file hanlde for .rst + * FILE * sfp file handle for .rel + * FILE * tfp file handle for .lst * - * 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 -lkexit(i) -int i; +lkexit(int i) { - if (mfp != NULL) fclose(mfp); - if (jfp != NULL) fclose(jfp); - if (ofp != NULL) fclose(ofp); - if (rfp != NULL) fclose(rfp); - if (sfp != NULL) fclose(sfp); - if (tfp != NULL) fclose(tfp); - if (dfp != NULL) { - FILE *xfp = afile(linkp->f_idp,"cdb",1); - dfp = freopen("temp.cdb","r",dfp); - copyfile(xfp,dfp); - fclose(xfp); - fclose(dfp); - unlink("temp.cdb"); - } - exit(i); + if (mfp != NULL) fclose(mfp); + if (jfp != NULL) fclose(jfp); + if (ofp != NULL) fclose(ofp); + if (rfp != NULL) fclose(rfp); + if (sfp != NULL) fclose(sfp); + if (tfp != NULL) fclose(tfp); + if (dfp != NULL) fclose(dfp); + /*if (dfp != NULL) + FILE *xfp = afile(linkp->f_idp,"cdb",1); + dfp = freopen("temp.cdb","r",dfp); + copyfile(xfp,dfp); + fclose(xfp); + fclose(dfp); + remove("temp.cdb"); + }*/ + exit(i); } -/*)Function link_main() - * - * The function link_main() evaluates the directives for each line of - * text read from the .rel file(s). The valid directives processed - * are: - * X, D, Q, H, M, A, S, T, R, and P. - * - * local variables: - * int c first non blank character of a line - * - * global variables: - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * int pass linker pass number - * int radix current number conversion radix - * - * functions called: - * char endline() lklex.c - * VOID module() lkhead.c - * VOID newarea() lkarea.c - * VOID newhead() lkhead.c - * sym * newsym() lksym.c - * VOID reloc() lkreloc.c - * - * side effects: - * Head, area, and symbol structures are created and - * the radix is set as the .rel file(s) are read. +/*)Function link_main() + * + * The function link_main() evaluates the directives for each line of + * text read from the .rel file(s). The valid directives processed + * are: + * X, D, Q, H, M, A, S, T, R, and P. + * + * local variables: + * int c first non blank character of a line + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * int pass linker pass number + * int radix current number conversion radix + * + * functions called: + * char endline() lklex.c + * VOID module() lkhead.c + * VOID newarea() lkarea.c + * VOID newhead() lkhead.c + * sym * newsym() lksym.c + * VOID reloc() lkreloc.c + * + * side effects: + * Head, area, and symbol structures are created and + * the radix is set as the .rel file(s) are read. */ VOID link_main() { - register int c; - - if ((c=endline()) == 0) { return; } - switch (c) { - - case 'X': - radix = 16; - break; - - case 'D': - radix = 10; - break; - - case 'Q': - radix = 8; - break; - - case 'H': - if (pass == 0) { - newhead(); - } else { - if (hp == 0) { - hp = headp; - } else { - hp = hp->h_hp; - } - } - sdp.s_area = NULL; - sdp.s_areax = NULL; - sdp.s_addr = 0; - lastExtendedAddress = -1; - break; - - case 'M': - if (pass == 0) - module(); - break; - - case 'A': - if (pass == 0) - newarea(); - if (sdp.s_area == NULL) { - sdp.s_area = areap; - sdp.s_areax = areap->a_axp; - sdp.s_addr = 0; - } - break; - - case 'S': - if (pass == 0) - newsym(); - break; - - case 'T': - case 'R': - case 'P': - if (pass == 0) - break; - reloc(c); - break; - - default: - break; - } - if (c == 'X' || c == 'D' || c == 'Q') { - if ((c = get()) == 'H') { - hilo = 1; - } else - if (c == 'L') { - hilo = 0; - } - } + register char c; + + if ((c=endline()) == 0) { return; } + switch (c) { + + case 'O': /*For some important sdcc options*/ + if (pass == 0) + { + if(strlen(sdccopt)==0) + { + strcpy(sdccopt, &ip[1]); + strcpy(sdccopt_module, curr_module); + } + else + { + if(strcmp(sdccopt, &ip[1])!=0) + { + fprintf(stderr, + "?ASlink-Warning-Conflicting sdcc options:\n" + " \"%s\" in module \"%s\" and\n" + " \"%s\" in module \"%s\".\n", + sdccopt, sdccopt_module, &ip[1], curr_module); + lkerr++; + } + } + } + break; + + case 'X': + radix = 16; + break; + + case 'D': + radix = 10; + break; + + case 'Q': + radix = 8; + break; + + case 'H': + if (pass == 0) { + newhead(); + } else { + if (hp == 0) { + hp = headp; + } else { + hp = hp->h_hp; + } + } + sdp.s_area = NULL; + sdp.s_areax = NULL; + sdp.s_addr = 0; + break; + + case 'M': + if (pass == 0) + { + strcpy(curr_module, &ip[1]); + module(); + } + break; + + case 'A': + if (pass == 0) + newarea(); + if (sdp.s_area == NULL) { + sdp.s_area = areap; + sdp.s_areax = areap->a_axp; + sdp.s_addr = 0; + } + break; + + case 'S': + if (pass == 0) + newsym(); + break; + + case 'T': + case 'R': + case 'P': + if (pass == 0) + break; + reloc(c); + break; + + default: + break; + } + if (c == 'X' || c == 'D' || c == 'Q') { + if ((c = get()) == 'H') { + hilo = 1; + } else + if (c == 'L') { + hilo = 0; + } + } } -/*)Function VOID map() - * - * The function map() opens the output map file and calls the various - * routines to - * (1) output the variables in each area, - * (2) list the files processed with module names, - * (3) list the libraries file processed, - * (4) list base address definitions, - * (5) list global variable definitions, and - * (6) list any undefined variables. - * - * local variables: - * int i counter - * head * hdp pointer to head structure - * lbfile *lbfh pointer to library file structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * head *headp The pointer to the first - * head structure of a linked list - * lbfile *lbfhead The pointer to the first - * lbfile structure of a linked list - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int lop current line number on page - * FILE *mfp Map output file handle - * int page current page number - * - * functions called: - * FILE * afile() lkmain.c - * int fprintf() c_library - * VOID lkexit() lkmain.c - * VOID lstarea() lklist.c - * VOID newpag() lklist.c - * VOID symdef() lksym.c - * - * side effects: - * The map file is created. +/*)Function VOID map() + * + * The function map() opens the output map file and calls the various + * routines to + * (1) output the variables in each area, + * (2) list the files processed with module names, + * (3) list the libraries file processed, + * (4) list base address definitions, + * (5) list global variable definitions, and + * (6) list any undefined variables. + * + * local variables: + * int i counter + * head * hdp pointer to head structure + * lbfile *lbfh pointer to library file structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * head *headp The pointer to the first + * head structure of a linked list + * lbfile *lbfhead The pointer to the first + * lbfile structure of a linked list + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int lop current line number on page + * FILE *mfp Map output file handle + * int page current page number + * + * functions called: + * FILE * afile() lkmain.c + * int fprintf() c_library + * VOID lkexit() lkmain.c + * VOID lstarea() lklist.c + * VOID newpag() lklist.c + * VOID symdef() lksym.c + * + * side effects: + * The map file is created. */ VOID map() { - register int i; - register struct head *hdp; - register struct lbfile *lbfh; - - /* - * Open Map File - */ - mfp = afile(linkp->f_idp, "map", 1); - if (mfp == NULL) { - lkexit(1); - } - - /* - * Output Map Area Lists - */ - page = 0; - lop = NLPP; - ap = areap; - while (ap) { - lstarea(ap); - ap = ap->a_ap; - } - /* - * List Linked Files - */ - newpag(mfp); - fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); - hdp = headp; - filep = linkp; - while (filep) { - fprintf(mfp, "%-16s", filep->f_idp); - i = 0; - while ((hdp != NULL) && (hdp->h_lfile == filep)) { - if (i % 5) { - fprintf(mfp, ", %8.8s", hdp->m_id); - } else { - if (i) { - fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); - } else { - fprintf(mfp, " [ %8.8s", hdp->m_id); - } - } - hdp = hdp->h_hp; - i++; - } - if (i) - fprintf(mfp, " ]"); - fprintf(mfp, "\n"); - filep = filep->f_flp; - } - /* - * List Linked Libraries - */ - if (lbfhead != NULL) { - fprintf(mfp, - "\nLibraries Linked [ object file ]\n\n"); - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { - fprintf(mfp, "%-32s [ %16.16s ]\n", - lbfh->libspc, lbfh->relfil); - } - fprintf(mfp, "\n"); - } - /* - * List Base Address Definitions - */ - if (basep) { - newpag(mfp); - fprintf(mfp, "\nUser Base Address Definitions\n\n"); - bsp = basep; - while (bsp) { - fprintf(mfp, "%s\n", bsp->b_strp); - bsp = bsp->b_base; - } - } - /* - * List Global Definitions - */ - if (globlp) { - newpag(mfp); - fprintf(mfp, "\nUser Global Definitions\n\n"); - gsp = globlp; - while (gsp) { - fprintf(mfp, "%s\n", gsp->g_strp); - gsp = gsp->g_globl; - } - } - fprintf(mfp, "\n\f"); - symdef(mfp); + register int i; + register struct head *hdp; + register struct lbfile *lbfh; + + /* + * Open Map File + */ + mfp = afile(linkp->f_idp, "map", 1); + if (mfp == NULL) { + lkexit(1); + } + + /* + * Output Map Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstarea(ap); + ap = ap->a_ap; + } + /* + * List Linked Files + */ + newpag(mfp); + fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); + hdp = headp; + filep = linkp; + while (filep) { + fprintf(mfp, "%-16s", filep->f_idp); + i = 0; + while ((hdp != NULL) && (hdp->h_lfile == filep)) { + if (i % 5) { + fprintf(mfp, ", %8.8s", hdp->m_id); + } else { + if (i) { + fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); + } else { + fprintf(mfp, " [ %8.8s", hdp->m_id); + } + } + hdp = hdp->h_hp; + i++; + } + if (i) + fprintf(mfp, " ]"); + fprintf(mfp, "\n"); + filep = filep->f_flp; + } + /* + * List Linked Libraries + */ + if (lbfhead != NULL) { + fprintf(mfp, + "\nLibraries Linked [ object file ]\n\n"); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + fprintf(mfp, "%-32s [ %16.16s ]\n", + lbfh->libspc, lbfh->relfil); + } + fprintf(mfp, "\n"); + } + /* + * List Base Address Definitions + */ + if (basep) { + newpag(mfp); + fprintf(mfp, "\nUser Base Address Definitions\n\n"); + bsp = basep; + while (bsp) { + fprintf(mfp, "%s\n", bsp->b_strp); + bsp = bsp->b_base; + } + } + /* + * List Global Definitions + */ + if (globlp) { + newpag(mfp); + fprintf(mfp, "\nUser Global Definitions\n\n"); + gsp = globlp; + while (gsp) { + fprintf(mfp, "%s\n", gsp->g_strp); + gsp = gsp->g_globl; + } + } + fprintf(mfp, "\n\f"); + symdef(mfp); } -/*)Function int parse() - * - * The function parse() evaluates all command line or file input - * linker directives and updates the appropriate variables. - * - * local variables: - * int c character value - * char fid[] file id string - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * lfile *lfp pointer to current lfile structure - * being processed by parse() - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int mflag Map output flag - * int oflag Output file type flag - * int pflag print linker command file flag - * FILE * stderr c_library - * int uflag Relocated listing flag - * int xflag Map file radix type flag - * - * Functions called: - * VOID addlib() lklibr.c - * VOID addpath() lklibr.c - * VOID bassav() lkmain.c - * int fprintf() c_library - * VOID gblsav() lkmain.c - * VOID getfid() lklex.c - * char getnb() lklex.c - * VOID lkexit() lkmain.c - * char * strcpy() c_library - * int strlen() c_library - * - * side effects: - * Various linker flags are updated and the linked - * structure lfile is created. +/*)Function int parse() + * + * The function parse() evaluates all command line or file input + * linker directives and updates the appropriate variables. + * + * local variables: + * int c character value + * char fid[] file id string + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * lfile *lfp pointer to current lfile structure + * being processed by parse() + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int mflag Map output flag + * int oflag Output file type flag + * int pflag print linker command file flag + * FILE * stderr c_library + * int uflag Relocated listing flag + * int xflag Map file radix type flag + * + * Functions called: + * VOID addlib() lklibr.c + * VOID addpath() lklibr.c + * VOID bassav() lkmain.c + * int fprintf() c_library + * VOID gblsav() lkmain.c + * VOID getfid() lklex.c + * char getnb() lklex.c + * VOID lkexit() lkmain.c + * char * strcpy() c_library + * int strlen() c_library + * + * side effects: + * Various linker flags are updated and the linked + * structure lfile is created. */ int parse() { - register int c; - char fid[NINPUT]; - - while ((c = getnb()) != 0) { - if ( c == '-') { - while (ctype[c=get()] & LETTER) { - switch(c) { - - case 'i': - case 'I': - oflag = 1; - break; - - case 's': - case 'S': - oflag = 2; - break; - - case 'm': - case 'M': - ++mflag; - break; - - case 'j': - case 'J': - jflag = 1; - break; - - case 'u': - case 'U': - uflag = 1; - break; - case 'r': - case 'R': - rflag = 1; - break; - case 'x': - case 'X': - xflag = 0; - break; - - case 'q': - case 'Q': - xflag = 1; - break; - - case 'd': - case 'D': - xflag = 2; - break; - - case 'e': - case 'E': - return(1); - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - case 'b': - case 'B': - bassav(); - return(0); - - case 'g': - case 'G': - gblsav(); - return(0); - - case 'k': - case 'K': - addpath(); - return(0); - - case 'l': - case 'L': - addlib(); - return(0); - - case 'a': - case 'A': - iramsav(); - return(0); - - case 'z': - case 'Z': - dflag = 1; - return(0); - default: - fprintf(stderr, "Invalid option\n"); - lkexit(1); - } - } - } else + register int c; + char fid[NINPUT]; + + while ((c = getnb()) != 0) { + if ( c == ';') + return(0); + if ( c == '-') { + while (ctype[c=get()] & LETTER) { + switch(c) { + + case 'i': + case 'I': + oflag = 1; + break; + + case 's': + case 'S': + oflag = 2; + break; + + case 'm': + case 'M': + ++mflag; + break; + + case 'y': /*JCF: memory usage summary output*/ + ++sflag; + break; + + case 'Y': + unget(getnb()); + packflag=1; + break; + + case 'A': + unget(getnb()); + if (ip && *ip) + { + stacksize=expr(0); + if(stacksize>256) stacksize=256; + else if(stacksize<0) stacksize=0; + } + return(0); + + case 'j': + case 'J': + jflag = 1; + break; + + case 'u': + case 'U': + uflag = 1; + break; + case 'r': + case 'R': + rflag = 1; + break; + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'e': + case 'E': + return(1); + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + case 'b': + case 'B': + bassav(); + return(0); + + case 'g': + case 'G': + gblsav(); + return(0); + + case 'k': + case 'K': + addpath(); + return(0); + + case 'l': + case 'L': + addlib(); + return(0); + + case 'a': + iramsav(); + return(0); + + case 'v': + case 'V': + xramsav(); + return(0); + + case 'w': + case 'W': + codesav(); + return(0); + + case 'z': + case 'Z': + dflag = 1; + return(0); + default: + fprintf(stderr, "Invalid option\n"); + lkexit(1); + } + } + if ( c == ';') + return(0); + } else if (ctype[c] & ILL) { fprintf(stderr, "Invalid input"); lkexit(1); } else { - if (linkp == NULL) { - linkp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = linkp; - } else { - lfp->f_flp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = lfp->f_flp; - } - getfid(fid, c); - lfp->f_idp = (char *) new (strlen(fid)+1); - strcpy(lfp->f_idp, fid); - lfp->f_type = F_REL; - } - } - return(0); + if (linkp == NULL) { + linkp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = linkp; + } else { + lfp->f_flp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = lfp->f_flp; + } + getfid(fid, c); + lfp->f_idp = (char *) new (strlen(fid)+1); + strcpy(lfp->f_idp, fid); + lfp->f_type = F_REL; + } + } + return(0); } -/*)Function VOID bassav() +/*)Function VOID bassav() * - * The function bassav() creates a linked structure containing - * the base address strings input to the linker. + * The function bassav() creates a linked structure containing + * the base address strings input to the linker. * - * local variables: - * none + * local variables: + * none * - * global variables: - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] + * global variables: + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The basep structure is created. + * side effects: + * The basep structure is created. */ VOID bassav() { - if (basep == NULL) { - basep = (struct base *) - new (sizeof (struct base)); - bsp = basep; - } else { - bsp->b_base = (struct base *) - new (sizeof (struct base)); - bsp = bsp->b_base; - } - unget(getnb()); - bsp->b_strp = (char *) new (strlen(ip)+1); - strcpy(bsp->b_strp, ip); + if (basep == NULL) { + basep = (struct base *) + new (sizeof (struct base)); + bsp = basep; + } else { + bsp->b_base = (struct base *) + new (sizeof (struct base)); + bsp = bsp->b_base; + } + unget(getnb()); + bsp->b_strp = (char *) new (strlen(ip)+1); + strcpy(bsp->b_strp, ip); } -/*)Function VOID setbas() - * - * The function setbas() scans the base address lines in hte - * basep structure, evaluates the arguments, and sets beginning - * address of the specified areas. - * - * local variables: - * int v expression value - * char id[] base id string - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag - * - * functions called: - * addr_t expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * int symeq() lksym.c - * - * side effects: - * The base address of an area is set. +/*)Function VOID setbas() + * + * The function setbas() scans the base address lines in the + * basep structure, evaluates the arguments, and sets beginning + * address of the specified areas. + * + * local variables: + * int v expression value + * char id[] base id string + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * int symeq() lksym.c + * + * side effects: + * The base address of an area is set. */ VOID setbas() { - register int v; - char id[NCPS]; - - bsp = basep; - while (bsp) { - ip = bsp->b_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - for (ap = areap; ap != NULL; ap = ap->a_ap) { - if (symeq(id, ap->a_id)) - break; - } - if (ap == NULL) { - fprintf(stderr, - "No definition of area %s\n", id); - lkerr++; - } else { - ap->a_addr = v; - ap->a_type = 1; /* JLH: value set */ - } - } else { - fprintf(stderr, "No '=' in base expression"); - lkerr++; - } - bsp = bsp->b_base; - } + register int v; + char id[NCPS]; + + bsp = basep; + while (bsp) { + ip = bsp->b_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + for (ap = areap; ap != NULL; ap = ap->a_ap) { + if (symeq(id, ap->a_id)) + break; + } + if (ap == NULL) { + fprintf(stderr, + "ASlink-Warning-No definition of area %s\n", id); + lkerr++; + } else { + ap->a_addr = v; + ap->a_type = 1; /* JLH: value set */ + } + } else { + fprintf(stderr, "ASlink-Warning-No '=' in base expression"); + lkerr++; + } + bsp = bsp->b_base; + } } -/*)Function VOID gblsav() +/*)Function VOID gblsav() * - * The function gblsav() creates a linked structure containing - * the global variable strings input to the linker. + * The function gblsav() creates a linked structure containing + * the global variable strings input to the linker. * - * local variable: - * none + * local variable: + * none * - * global variables: - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag + * global variables: + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The globlp structure is created. + * side effects: + * The globlp structure is created. */ VOID gblsav() { - if (globlp == NULL) { - globlp = (struct globl *) - new (sizeof (struct globl)); - gsp = globlp; - } else { - gsp->g_globl = (struct globl *) - new (sizeof (struct globl)); - gsp = gsp->g_globl; - } - unget(getnb()); - gsp->g_strp = (char *) new (strlen(ip)+1); - strcpy(gsp->g_strp, ip); + if (globlp == NULL) { + globlp = (struct globl *) + new (sizeof (struct globl)); + gsp = globlp; + } else { + gsp->g_globl = (struct globl *) + new (sizeof (struct globl)); + gsp = gsp->g_globl; + } + unget(getnb()); + gsp->g_strp = (char *) new (strlen(ip)+1); + strcpy(gsp->g_strp, ip); } - -/*)Function VOID setgbl() - * - * The function setgbl() scans the global variable lines in hte - * globlp structure, evaluates the arguments, and sets a variable - * to this value. - * - * local variables: - * int v expression value - * char id[] base id string - * sym * sp pointer to a symbol structure - * - * global variables: - * char *ip pointer into the REL file - * text line in ib[] - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * FILE * stderr c_library - * int lkerr error flag - * - * functions called: - * addr_t expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * sym * lkpsym() lksym.c - * - * side effects: - * The value of a variable is set. + +/*)Function VOID setgbl() + * + * The function setgbl() scans the global variable lines in the + * globlp structure, evaluates the arguments, and sets a variable + * to this value. + * + * local variables: + * int v expression value + * char id[] base id string + * sym * sp pointer to a symbol structure + * + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * FILE * stderr c_library + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * sym * lkpsym() lksym.c + * + * side effects: + * The value of a variable is set. */ VOID setgbl() { - register int v; - register struct sym *sp; - char id[NCPS]; - - gsp = globlp; - while (gsp) { - ip = gsp->g_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - sp = lkpsym(id, 0); - if (sp == NULL) { - fprintf(stderr, - "No definition of symbol %s\n", id); - lkerr++; - } else { - if (sp->s_flag & S_DEF) { - fprintf(stderr, - "Redefinition of symbol %s\n", id); - lkerr++; - sp->s_axp = NULL; - } - sp->s_addr = v; - sp->s_type |= S_DEF; - } - } else { - fprintf(stderr, "No '=' in global expression"); - lkerr++; - } - gsp = gsp->g_globl; - } + register int v; + register struct sym *sp; + char id[NCPS]; + + gsp = globlp; + while (gsp) { + ip = gsp->g_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + sp = lkpsym(id, 0); + if (sp == NULL) { + fprintf(stderr, + "No definition of symbol %s\n", id); + lkerr++; + } else { + if (sp->s_flag & S_DEF) { + fprintf(stderr, + "Redefinition of symbol %s\n", id); + lkerr++; + sp->s_axp = NULL; + } + sp->s_addr = v; + sp->s_type |= S_DEF; + } + } else { + fprintf(stderr, "No '=' in global expression"); + lkerr++; + } + gsp = gsp->g_globl; + } } -/*)Function FILE * afile(fn,, ft, wf) - * - * 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 .rel file - * type is appended to the file specification. - * - * afile() returns a file handle for the opened file or aborts - * the assembler on an open error. - * - * local variables: - * int c character value - * char fb[] constructed file specification string - * 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: - * int lkerr error flag - * - * functions called: - * FILE * fopen() c_library - * int fprintf() c_library - * - * side effects: - * File is opened for read or write. +/*)Function FILE * afile(fn,, ft, wf) + * + * 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 .rel file + * type is appended to the file specification. + * + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. + * + * local variables: + * char fb[] constructed file specification string + * FILE * fp filehandle for opened file + * + * global variables: + * int lkerr error flag + * + * functions called: + * FILE * fopen() c_library + * int fprintf() c_library + * + * side effects: + * File is opened for read or write. */ FILE * -afile(fn, ft, wf) -char *fn; -char *ft; +afile(char *fn, char *ft, int wf) { - register char *p1, *p2, *p3; - register int c; - FILE *fp; - char fb[FILSPC]; - char *omode = (wf ? (wf == 2 ? "a" : "w") : "r"); - - p1 = fn; - p2 = fb; - p3 = ft; - while ((c = *p1++) != 0 && c != FSEPX) { - if (p2 < &fb[FILSPC-4]) - *p2++ = c; - } - *p2++ = FSEPX; - if (*p3 == 0) { - if (c == FSEPX) { - p3 = p1; - } else { - p3 = "rel"; - } - } - while ((c = *p3++) != 0) { - if (p2 < &fb[FILSPC-1]) - *p2++ = c; - } - *p2++ = 0; - if ((fp = fopen(fb, omode)) == NULL) { - if (strcmp(ft,"cdb")) { - fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); - lkerr++; - } - } - return (fp); + FILE *fp; + char fb[PATH_MAX]; + char *omode = (wf ? (wf == 2 ? "a" : "w") : "r"); + int i; + + /*Look backward the name path and get rid of the extension, if any*/ + i=strlen(fn); + for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--); + if( (fn[i]=='.') && strcmp(ft, "lnk") ) + { + strncpy(fb, fn, i); + fb[i]=0; + } + else + { + strcpy(fb, fn); + } + + /*Add the extension*/ + if (fb[i] != '.') + { + strcat(fb, "."); + strcat(fb, strlen(ft)?ft:"rel"); + } + + fp = fopen(fb, omode); + if (fp==NULL) + { + if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/ + { + fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); + lkerr++; + } + } + return (fp); } -/*)Function VOID iramsav() +/*)Function VOID iramsav() * - * The function iramsav() stores the size of the chip's internal RAM. - * This is used after linking to check that variable assignment to this - * dataspace didn't overflow into adjoining segments. Variables in the - * DSEG, OSEG, and ISEG are assigned to this dataspace. + * The function iramsav() stores the size of the chip's internal RAM. + * This is used after linking to check that variable assignment to this + * dataspace didn't overflow into adjoining segments. Variables in the + * DSEG, OSEG, and ISEG are assigned to this dataspace. * - * local variables: - * none + * local variables: + * none * - * global variables: - * char *ip pointer into the REL file - * text line in ib[] - * unsigned int size of chip's internal - * iram_size RAM segment + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * unsigned int size of chip's internal + * iram_size RAM segment * - * functions called: - * char getnb() lklex.c - * VOID unget() lklex.c - * addr_t expr() lkeval.c + * functions called: + * char getnb() lklex.c + * VOID unget() lklex.c + * Addr_T expr() lkeval.c * - * side effects: - * The iram_size may be modified. + * side effects: + * The iram_size may be modified. */ VOID @@ -1111,31 +1278,55 @@ iramsav() { unget(getnb()); if (ip && *ip) - //iram_size = atoi(ip); - iram_size = expr(0); /* evaluate size expression */ + iram_size = expr(0); /* evaluate size expression */ + else + iram_size = 128; /* Default is 128 (0x80) bytes */ + if ((iram_size<=0) || (iram_size>256)) + iram_size = 128; /* Default is 128 (0x80) bytes */ +} + +/*Similar to iramsav but for xram memory*/ +VOID +xramsav() +{ + unget(getnb()); + if (ip && *ip) + xram_size = expr(0); /* evaluate size expression */ else - iram_size = 128; /* Default is 128 (0x80) bytes */ + xram_size = rflag?0x1000000:0x10000; } -/*)Function VOID iramcheck() +/*Similar to iramsav but for code memory*/ +VOID +codesav() +{ + unget(getnb()); + if (ip && *ip) + code_size = expr(0); /* evaluate size expression */ + else + code_size = rflag?0x1000000:0x10000; +} + + +/*)Function VOID iramcheck() * - * The function iramcheck() is used at the end of linking to check that - * the internal RAM area wasn't overflowed by too many variable - * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to - * the chip's internal RAM. + * The function iramcheck() is used at the end of linking to check that + * the internal RAM area wasn't overflowed by too many variable + * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to + * the chip's internal RAM. * - * local variables: - * none + * local variables: + * none * - * global variables: - * unsigned int size of chip's internal - * iram_size RAM segment - * struct area linked list of memory - * *areap areas + * global variables: + * unsigned int size of chip's internal + * iram_size RAM segment + * struct area linked list of memory + * *areap areas * - * functions called: + * functions called: * - * side effects: + * side effects: */ VOID @@ -1154,95 +1345,100 @@ iramcheck() { last_addr = ap->a_addr + ap->a_size - 1; if (last_addr >= iram_size) - fprintf(stderr, - "\nWARNING! Segment %s extends past the end\n" - " of internal RAM. Check map file.\n", - ap->a_id); + fprintf(stderr, + "\nWARNING! Segment %s extends past the end\n" + " of internal RAM. Check map file.\n", + ap->a_id); } } } char *usetxt[] = { - "Startup:", - " -c Command line input", - " -f file[LNK] File input", - " -p Prompt and echo of file[LNK] to stdout (default)", - " -n No echo of file[LNK] to stdout", -/* "Usage: [-Options] file [file ...]", */ - "Libraries:", - " -k Library path specification, one per -k", - " -l Library file specification, one per -l", - "Relocation:", - " -b area base address = expression", - " -g global symbol = expression", - "Map format:", - " -m Map output generated as file[MAP]", - " -x Hexadecimal (default), -d Decimal, -q Octal", - "Output:", - " -i Intel Hex as file[IHX]", - " -s Motorola S19 as file[S19]", - " -j Produce NoICE debug as file[NOI]", - " -z Produce SDCdb debug as file[cdb]", -/* "List:", */ - " -u Update listing file(s) with link data as file(s)[.RST]", - "Miscellaneous:\n" - " -a [iram-size] Check for internal RAM overflow", - "End:", - " -e or null line terminates input", - 0 + "Startup:", + " -c Command line input", + " -f file[LNK] File input", + " -p Prompt and echo of file[LNK] to stdout (default)", + " -n No echo of file[LNK] to stdout", +/* "Usage: [-Options] file [file ...]", */ + "Libraries:", + " -k Library path specification, one per -k", + " -l Library file specification, one per -l", + "Relocation:", + " -b area base address = expression", + " -g global symbol = expression", + "Map format:", + " -m Map output generated as file[MAP]", + " -x Hexadecimal (default), -d Decimal, -q Octal", + "Output:", + " -i Intel Hex as file[IHX]", + " -s Motorola S19 as file[S19]", + " -j Produce NoICE debug as file[NOI]", + " -z Produce SDCdb debug as file[cdb]", +/* "List:", */ + " -u Update listing file(s) with link data as file(s)[.RST]", + "Miscellaneous:\n" + " -a [iram-size] Check for internal RAM overflow", + " -v [xram-size] Check for external RAM overflow", + " -w [code-size] Check for code overflow", + " -y Generate memory usage summary file[mem]", + " -Y Pack internal ram", + " -A [stack-size] Allocate space for stack", + "End:", + " -e or null line terminates input", + 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: - * FILE * stderr c_library + * global variables: + * FILE * stderr c_library * - * functions called: - * int fprintf() c_library + * functions called: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none */ VOID usage() { - register char **dp; + register char **dp; - fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); - for (dp = usetxt; *dp; dp++) - fprintf(stderr, "%s\n", *dp); - lkexit(1); + fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + lkexit(1); } -/*)Function VOID copyfile() - * - * FILE *dest destination file - * FILE *src source file +/*)Function VOID copyfile() + * + * FILE *dest destination file + * FILE *src source file * * function will copy source file to destination file * * - * functions called: - * int fgetc() c_library - * int fputc() c_library + * functions called: + * int fgetc() c_library + * int fputc() c_library * - * side effects: - * none + * side effects: + * none */ VOID copyfile (dest,src) FILE *src,*dest ; -{ +{ int ch; while ((ch = fgetc(src)) != EOF) { - fputc(ch,dest); + fputc(ch,dest); } }