* as/link/mcs51/lkarea.c (lnkarea2): handle absolute areas, restructured
[fw/sdcc] / as / mcs51 / asmain.c
index ef6534afef8304862812bf10800e3dc75f5b2deb..a333cceae75c6568295119f5308125a712a600c6 100644 (file)
@@ -17,6 +17,7 @@
 #include <string.h>
 
 #include "asm.h"
+#include "strcmpi.h"
 
 /*)Module      asmain.c
  *
  *             VOID    diag()          assubr.c
  *             VOID    err()           assubr.c
  *             int     fprintf()       c-library
- *             int     getline()       aslex.c
+ *             int     as_getline()    aslex.c
  *             VOID    list()          aslist.c
  *             VOID    lstsym()        aslist.c
  *             VOID    minit()         ___mch.c
@@ -288,7 +289,7 @@ char *argv[];
                dot.s_area = &dca;
                symp = &dot;
                minit();
-               while (getline()) {
+               while (as_getline()) {
                        cp = cb;
                        cpt = cbt;
                        ep = eb;
@@ -374,7 +375,7 @@ int i;
        if (i) {
          // remove output file
          printf ("removing %s\n", relFile);
-         unlink(relFile);
+         remove(relFile);
        }
        exit(i);
 }
@@ -479,9 +480,10 @@ asmbl()
        struct expr e1;
        char id[NCPS];
        char opt[NCPS];
-       char fn[FILSPC];
+       char fn[PATH_MAX];
        char *p;
        int d, n, uaf, uf;
+       static struct area *abs_ap; /* pointer to current absolute area structure */
 
        laddr = dot.s_addr;
        lmode = SLIST;
@@ -555,7 +557,7 @@ loop:
                goto loop;
        }
        /*
-        * If the first character is a letter then assume a lable,
+        * If the first character is a letter then assume a label,
         * symbol, assembler directive, or assembler mnemonic is
         * being processed.
         */
@@ -799,7 +801,7 @@ loop:
                break;
 
        case S_MODUL:
-               getst(id, -1);
+               getst(id, getnb()); // a module can start with a digit
                if (pass == 0) {
                        if (module[0]) {
                                err('m');
@@ -810,6 +812,20 @@ loop:
                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);
@@ -821,7 +837,7 @@ loop:
                break;
 
        case S_DAREA:
-               getid(id, -1);
+               getid(id, -1);
                uaf = 0;
                uf  = A_CON|A_REL;
                if ((c = getnb()) == '(') {
@@ -843,10 +859,6 @@ loop:
                if ((ap = alookup(id)) != NULL) {
                        if (uaf && uf != ap->a_flag)
                                err('m');
-                        if (ap->a_flag & A_OVR) {
-                               ap->a_size = 0; 
-                                ap->a_fuzz=0;
-                       }
                } else {
                        ap = (struct area *) new (sizeof(struct area));
                        ap->a_ap = areap;
@@ -859,17 +871,31 @@ loop:
                }
                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) {
-                       outall();
-                       laddr = dot.s_addr = absexpr();
+                       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');
                }
-               outall();
-               lmode = ALIST;
                break;
 
        case S_RADIX:
@@ -911,7 +937,7 @@ loop:
                d = getnb();
                p = fn;
                while ((c = get()) != d) {
-                       if (p < &fn[FILSPC-1]) {
+                       if (p < &fn[PATH_MAX-1]) {
                                *p++ = c;
                        } else {
                                break;
@@ -935,7 +961,7 @@ loop:
                {
                    getst(id, -1);
                    
-                   if (!strcmpi(id, "on"))
+                   if (!as_strcmpi(id, "on"))
                    {
                        /* Quick sanity check: size of 
                         * Addr_T must be at least 24 bits.
@@ -953,7 +979,7 @@ loop:
                            flat24Mode = 1;
                        }
                    }
-                   else if (!strcmpi(id, "off"))
+                   else if (!as_strcmpi(id, "off"))
                    {
                        flat24Mode = 0;
                    }
@@ -1053,8 +1079,8 @@ int wf;
        p2 = strrchr (afn, FSEPX);              // search last '.'
        if (!p2)
                p2 = afn + strlen (afn);
-       if (p2 > &afn[FILSPC-4])                // truncate filename, if it's too long
-               p2 = &afn[FILSPC-4];
+       if (p2 > &afn[PATH_MAX-4])              // truncate filename, if it's too long
+               p2 = &afn[PATH_MAX-4];
        *p2++ = FSEPX;
 
        // choose a file-extension
@@ -1067,7 +1093,7 @@ int wf;
        }
 
        while ((c = *p3++) != 0) {              // strncpy
-               if (p2 < &afn[FILSPC-1])
+               if (p2 < &afn[PATH_MAX-1])
                        *p2++ = c;
        }
        *p2++ = 0;
@@ -1114,11 +1140,35 @@ 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;
-       oap->a_size = dot.s_addr;
-       fuzz = nap->a_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;
-       dot.s_addr = nap->a_size;
        outall();
 }