cleaned up the mess I left behind
[fw/sdcc] / as / mcs51 / lkmain.c
index 21ae166108dd81fa62b6647da6b5a85406bbf0a4..8ea5fde7f25b69ec70309c8b3b909a66cc1301cb 100644 (file)
  *           - use a_type == 0 as "virgin area" flag: set == 1 if -b
  */
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <alloc.h>
 #include "aslink.h"
 
+/* yuck - but including unistd.h causes problems on Cygwin by redefining
+ * Addr_T.
+ */
+extern int unlink(const char *);
 
 /*)Module      lkmain.c
  *
@@ -32,7 +36,7 @@
  *             FILE *  afile(fn,ft,wf)
  *             VOID    bassav()
  *             VOID    gblsav()
-  *            VOID    link()
+  *            VOID    link_main()
  *             VOID    lkexit()
  *             VOID    main(argc,argv)
  *             VOID    map()
  *
  */
 
+/*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()*/
+               ""
+       };
+       int j;
+
+       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; }
+       }
+}
+
 /*)Function    VOID    main(argc,argv)
  *
  *             int     argc            number of command line arguments + 1
  *             int     fprintf()       c_library
  *             int     getline()       lklex.c
  *             VOID    library()       lklibr.c
- *             VOID    link()          lkmain.c
+ *             VOID    link_main()     lkmain.c
  *             VOID    lkexit()        lkmain.c
  *             VOID    lnkarea()       lkarea.c
  *             VOID    map()           lkmain.c
@@ -138,8 +176,6 @@ char *argv[];
        register char *p;
        register int c, i;
 
-       fprintf(stdout, "\n");
-
        startp = (struct lfile *) new (sizeof (struct lfile));
 
        pflag = 1;
@@ -208,7 +244,9 @@ char *argv[];
        syminit();
        
        if (dflag){
-           dfp = afile("temp", "cdb", 1);
+           //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);
        }
@@ -219,6 +257,8 @@ char *argv[];
                filep = linkp;
                hp = NULL;
                radix = 10;
+               
+               Areas51(); /*JCF: Create the default 8051 areas in the right order*/
 
                while (getline()) {
                        ip = ib;
@@ -227,7 +267,7 @@ char *argv[];
                         if ((ip[0] == ';') && (ip[1] == '!') && jfp) {
                                fprintf( jfp, "%s\n", &ip[2] );
                         }
-                       link();
+                       link_main();
                }
                if (pass == 0) {
                        /*
@@ -267,6 +307,9 @@ char *argv[];
                        if (mflag || jflag)
                                map();
 
+                       if (sflag) /*JCF: memory usage summary output*/
+                               if(summary(areap))lkexit(1);
+
                        if (iram_size)
                                iramcheck();
 
@@ -298,6 +341,9 @@ char *argv[];
                        reloc('E');
                }
        }
+       //JCF:
+       CreateAOMF51();
+
        lkexit(lkerr);
        return 0;
 }
@@ -337,20 +383,21 @@ int i;
        if (rfp != NULL) fclose(rfp);
        if (sfp != NULL) fclose(sfp);
        if (tfp != NULL) fclose(tfp);
-       if (dfp != NULL) {
+       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);
            unlink("temp.cdb");
-       }
+       }*/
        exit(i);
 }
 
-/*)Function    link()
+/*)Function    link_main()
  *
- *     The function link() evaluates the directives for each line of
+ *     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.
@@ -380,7 +427,7 @@ int i;
  */
 
 VOID
-link()
+link_main()
 {
        register int c;
 
@@ -412,7 +459,6 @@ link()
                sdp.s_area = NULL;
                sdp.s_areax = NULL;
                sdp.s_addr = 0;
-               lastExtendedAddress = -1;
                break;
 
        case 'M':
@@ -672,6 +718,11 @@ parse()
                                        ++mflag;
                                        break;
 
+                               case 'y': /*JCF: memory usage summary output*/
+                               case 'Y':
+                                       ++sflag;
+                                       break;
+
                                case 'j':
                                case 'J':
                                        jflag = 1;
@@ -739,6 +790,16 @@ parse()
                                        iramsav();
                                        return(0);
 
+                               case 'v':
+                               case 'V':
+                                       xramsav();
+                                       return(0);
+
+                               case 'w':
+                               case 'W':
+                                       codesav();
+                                       return(0);
+
                                case 'z':
                                 case 'Z':
                                        dflag = 1;                                      
@@ -839,7 +900,7 @@ bassav()
  *             int     lkerr           error flag
  *
  *      functions called:
- *             addr_t  expr()          lkeval.c
+ *             Addr_T  expr()          lkeval.c
  *             int     fprintf()       c_library
  *             VOID    getid()         lklex.c
  *             char    getnb()         lklex.c
@@ -867,14 +928,14 @@ setbas()
                        }
                        if (ap == NULL) {
                                fprintf(stderr,
-                               "No definition of area %s\n", id);
+                               "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, "No '=' in base expression");
+                       fprintf(stderr, "ASlink-Warning-No '=' in base expression");
                        lkerr++;
                }
                bsp = bsp->b_base;
@@ -948,7 +1009,7 @@ gblsav()
  *             int     lkerr           error flag
  *
  *      functions called:
- *             addr_t  expr()          lkeval.c
+ *             Addr_T  expr()          lkeval.c
  *             int     fprintf()       c_library
  *             VOID    getid()         lklex.c
  *             char    getnb()         lklex.c
@@ -1041,14 +1102,14 @@ char *ft;
        register char *p1, *p2, *p3;
        register int c;
        FILE *fp;
-       char fb[FILSPC];
+       char fb[PATH_MAX];
        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])
+               if (p2 < &fb[PATH_MAX-4])
                        *p2++ = c;
        }
        *p2++ = FSEPX;
@@ -1060,12 +1121,12 @@ char *ft;
                }
        }
        while ((c = *p3++) != 0) {
-               if (p2 < &fb[FILSPC-1])
+               if (p2 < &fb[PATH_MAX-1])
                        *p2++ = c;
        }
        *p2++ = 0;      
        if ((fp = fopen(fb, omode)) == NULL) {
-           if (strcmp(ft,"cdb")) {
+           if (strcmp(ft,"adb")) {
                fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open");
                lkerr++;
            }
@@ -1092,7 +1153,7 @@ char *ft;
  *      functions called:
  *             char    getnb()         lklex.c
  *             VOID    unget()         lklex.c
- *             addr_t  expr()          lkeval.c
+ *             Addr_T  expr()          lkeval.c
  *
  *     side effects:
  *             The iram_size may be modified.
@@ -1109,6 +1170,29 @@ iramsav()
     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
+       xram_size = rflag?0x1000000:0x10000;
+}
+
+/*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
@@ -1179,6 +1263,8 @@ char *usetxt[] = {
        "  -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",
        "End:",
        "  -e   or null line terminates input",
        0