cleaned up the mess I left behind
[fw/sdcc] / as / mcs51 / lkrloc.c
index 88cc143809fb18b242fb3bd1f2966fef457bf3f6..baa056496fe455baa649ef505d3340fa5d790c1e 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <alloc.h>
 #include "aslink.h"
 
 /*)Module      lkrloc.c
  *     perform the relocation calculations.
  *
  *     lkrloc.c contains the following functions:
- *             addr_t  adb_b()
- *             addr_t  adb_lo()
- *             addr_t  adb_hi()
- *             addr_t  adw_w()
- *             addr_t  adw_lo()
- *             addr_t  adw_hi()
+ *             Addr_T  adb_b()
+ *             Addr_T  adb_lo()
+ *             Addr_T  adb_hi()
+ *             Addr_T  adw_w()
+ *             Addr_T  adw_lo()
+ *             Addr_T  adw_hi()
  *             VOID    erpdmp()
  *             VOID    errdmp()
- *             addr_t  evword()
+ *             Addr_T  evword()
  *             VOID    prntval()
  *             VOID    rele()
  *             VOID    relerr()
 /* Global which holds the upper 16 bits of the last 32 bit area adress
  * output. Useful only for iHex mode.
  */
-int    lastExtendedAddress;
+int    lastExtendedAddress=-1;
+
+/* Static variable which holds the index of last processed area.
+ * Useful only for iHex mode.
+ */
+static int lastAreaIndex = -1;
 
 /*)Function    VOID    reloc(c)
  *
@@ -213,14 +217,14 @@ relt()
  *             int     lkerr           error flag
  *             int     mode            relocation mode
  *             adrr_t  paga            paging base area address
- *             addr_t  pags            paging symbol address
- *             addr_t  pc              relocated base address
- *             addr_t  r               PCR relocation value
- *             addr_t  reli            relocation initial value
- *             addr_t  relv            relocation final value
+ *             Addr_T  pags            paging symbol address
+ *             Addr_T  pc              relocated base address
+ *             Addr_T  r               PCR relocation value
+ *             Addr_T  reli            relocation initial value
+ *             Addr_T  relv            relocation final value
  *             int     rindex          symbol / area index
- *             addr_t  rtbase          base code address
- *             addr_t  rtofst          rtval[] index offset
+ *             Addr_T  rtbase          base code address
+ *             Addr_T  rtofst          rtval[] index offset
  *             int     rtp             index into T data
  *             sym     **s             pointer to array of symbol pointers
  *
@@ -230,11 +234,11 @@ relt()
  *             FILE    *stderr         standard error device
  *
  *     called functions:
- *             addr_t  adb_b()         lkrloc.c
- *             addr_t  adb_lo()        lkrloc.c
- *             addr_t  adb_hi()        lkrloc.c
- *             addr_t  adw_w()         lkrloc.c
- *             addr_t  evword()        lkrloc.c
+ *             Addr_T  adb_b()         lkrloc.c
+ *             Addr_T  adb_lo()        lkrloc.c
+ *             Addr_T  adb_hi()        lkrloc.c
+ *             Addr_T  adw_w()         lkrloc.c
+ *             Addr_T  evword()        lkrloc.c
  *             int     eval()          lkeval.c
  *             int     fprintf()       c_library
  *             VOID    ihx()           lkihx.c
@@ -255,9 +259,9 @@ VOID
 relr()
 {
        register int mode;
-       register addr_t reli, relv;
+       register Addr_T reli, relv;
        int aindex, rindex, rtp, error;
-       addr_t r, rtbase, rtofst, paga, pags, pc;
+       Addr_T r, rtbase, rtofst, paga, pags, pc;
        struct areax **a;
        struct sym **s;
 
@@ -306,6 +310,13 @@ relr()
        while (more()) {
                error = 0;
                mode = eval();
+               
+               if ((mode & R_ESCAPE_MASK) == R_ESCAPE_MASK)
+               {
+                   mode = ((mode & ~R_ESCAPE_MASK) << 8) | eval();
+                   /* printf("unescaping rmode\n"); */
+               }
+               
                rtp = eval();
                rindex = evword();
 
@@ -342,7 +353,7 @@ relr()
                /*
                 * R_PAG0 or R_PAG addressing
                 */
-               if (mode & (R_PAG0|R_PAG)) {
+               if (mode & (R_PAG0 | R_PAG)) {
                        paga  = sdp.s_area->a_addr;
                        pags  = sdp.s_addr;
                        reli -= paga + pags;
@@ -352,7 +363,38 @@ relr()
                 * R_BYTE or R_WORD operation
                 */
                if (mode & R_BYTE) {
-                       if (mode & R_BYT2) {
+                       if (mode & R_BYT3)
+                       {
+                               /* This is a three byte address, of which 
+                                * we will select one byte.
+                                */
+                               if (mode & R_HIB)
+                               {
+                                       /* printf("24 bit address selecting hi byte.\n"); */
+                                       relv = adb_24_hi(reli, rtp);
+                               }               
+                               else if (mode & R_MSB)
+                               {
+                                       /* Note that in 24 bit mode, R_MSB
+                                        * is really the middle byte, not
+                                        * the most significant byte.
+                                        *
+                                        * This is ugly and I can only apologize
+                                        * for any confusion.
+                                        */
+                                       /* printf("24 bit address selecting middle byte.\n"); */
+                                       relv = adb_24_mid(reli, rtp);                           
+                               }
+                               else
+                               {
+                                       /* printf("24 bit address selecting lo byte.\n"); */
+                                       relv = adb_24_lo(reli, rtp);                            
+                               }
+                       }
+                       else if (mode & R_BYT2) {
+                               /* This is a two byte address, of
+                                * which we will select one byte.
+                                */
                                if (mode & R_MSB) {
                                        relv = adb_hi(reli, rtp);
                                } else {
@@ -442,7 +484,7 @@ relr()
                 */
                if (mode & R_PCR && mode & R_BYTE) {
                        r = relv & ~0x7F;
-                       if (r != (addr_t) ~0x7F && r != 0)
+                       if (r != (Addr_T) ~0x7F && r != 0)
                                error = 2; 
                }
 
@@ -491,15 +533,21 @@ relr()
                 * This is another reason why we can't have areas greater
                 * than 64K yet, even in flat24 mode.
                 */
-               extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
+       //      extendedAddress += ((a[aindex]->a_size) >> 16 & 0xffff);
+       //      commented out by jr 
+               
+               if (lastAreaIndex != aindex) {
+                       lastAreaIndex = aindex;
+                       newArea();
+               }
                
                if (extendedAddress != lastExtendedAddress)
                {
                
-                   #if 0
-                   printf("output extended linear address record 0x%x\n",
-                           extendedAddress);
-                   #endif
+                   if (lastExtendedAddress!=-1) {
+                     printf("output extended linear address record 0x%x 0x%x\n",
+                            extendedAddress, lastExtendedAddress);
+                   }
                    
                    if (rflag)
                    {
@@ -559,7 +607,7 @@ char *errmsg[] = {
  *             areax   **a             pointer to array of area pointers
  *             int     aindex          area index
  *             int     mode            relocation mode
- *             addr_t  relv    relocation value
+ *             Addr_T  relv    relocation value
  *             int     rindex          symbol / area index
  *             int     rtp                     index into T data
  *             sym     **s                     pointer to array of symbol pointers
@@ -571,8 +619,8 @@ char *errmsg[] = {
  *             FILE *stderr    standard error device
  *
  *     called functions:
- *             addr_t adw_w()  lkrloc.c
- *             addr_t evword() lkrloc.c
+ *             Addr_T adw_w()  lkrloc.c
+ *             Addr_T evword() lkrloc.c
  *             int     eval()          lkeval.c
  *             int     fprintf()       c_library
  *             int     more()          lklex.c
@@ -590,7 +638,7 @@ relp()
 {
        register int aindex, rindex;
        int mode, rtp;
-       addr_t relv;
+       Addr_T relv;
        struct areax **a;
        struct sym **s;
 
@@ -699,13 +747,13 @@ rele()
        }
 }
 
-/*)Function    addr_t          evword()
+/*)Function    Addr_T          evword()
  *
  *     The function evword() combines two byte values
  *     into a single word value.
  *
  *     local variable:
- *             addr_t  v               temporary evaluation variable
+ *             Addr_T  v               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -719,10 +767,10 @@ rele()
  *
  */
 
-addr_t
+Addr_T
 evword()
 {
-       register addr_t v;
+       register Addr_T v;
 
        if (hilo) {
                v =  (eval() << 8);
@@ -734,7 +782,7 @@ evword()
        return(v);
 }
 
-/*)Function    addr_t          adb_b(v, i)
+/*)Function    Addr_T          adb_b(v, i)
  *
  *             int     v               value to add to byte
  *             int     i               rtval[] index
@@ -757,15 +805,15 @@ evword()
  *
  */
 
-addr_t
+Addr_T
 adb_b(v, i)
-register addr_t v;
+register Addr_T v;
 register int i;
 {
        return(rtval[i] += v);
 }
 
-/*)Function    addr_t          adb_lo(v, i)
+/*)Function    Addr_T          adb_lo(v, i)
  *
  *             int     v               value to add to byte
  *             int     i               rtval[] index
@@ -776,7 +824,7 @@ register int i;
  *     The MSB rtflg[] is cleared.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -792,12 +840,12 @@ register int i;
  *
  */
 
-addr_t
+Addr_T
 adb_lo(v, i)
-addr_t v;
+Addr_T v;
 int    i;
 {
-       register addr_t j;
+       register Addr_T j;
 
        j = adw_w(v, i);
        /*
@@ -811,7 +859,7 @@ int i;
        return (j);
 }
 
-/*)Function    addr_t          adb_hi(v, i)
+/*)Function    Addr_T          adb_hi(v, i)
  *
  *             int     v               value to add to byte
  *             int     i               rtval[] index
@@ -822,7 +870,7 @@ int i;
  *     The LSB rtflg[] is cleared.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -838,12 +886,12 @@ int       i;
  *
  */
 
-addr_t
+Addr_T
 adb_hi(v, i)
-addr_t v;
+Addr_T v;
 int    i;
 {
-       register addr_t j;
+       register Addr_T j;
 
        j = adw_w(v, i);
        /*
@@ -857,7 +905,144 @@ int       i;
        return (j);
 }
 
-/*)Function    addr_t          adw_w(v, i)
+/*)Function    Addr_T          adb_24_hi(v, i)
+ *
+ *             int     v               value to add to byte
+ *             int     i               rtval[] index
+ *
+ *     The function adb_24_hi() adds the value of v to the
+ *     24 bit value contained in rtval[i] - rtval[i+2].
+ *     The new value of rtval[i] / rtval[i+1] is returned.
+ *     The LSB & middle byte rtflg[] is cleared.
+ *
+ *     local variable:
+ *             Addr_T  j               temporary evaluation variable
+ *
+ *     global variables:
+ *             hilo                    byte ordering parameter
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             The value of rtval[] is changed.
+ *             The rtflg[] value corresponding to the
+ *             LSB & middle byte of the word value is cleared to
+ *             reflect the fact that the MSB is the selected byte.
+ *
+ */
+
+Addr_T
+adb_24_hi(Addr_T v, int i)
+{
+       register Addr_T j;
+
+       j = adw_24(v, i);
+
+       /* Remove the lower two bytes. */
+       if (hilo)
+       {
+           rtflg[i+2] = 0;
+       }
+       else
+       {
+           rtflg[i] = 0;
+       }
+       rtflg[i+1] = 0;
+
+       return (j);
+}
+
+/*)Function    Addr_T          adb_24_mid(v, i)
+ *
+ *             int     v               value to add to byte
+ *             int     i               rtval[] index
+ *
+ *     The function adb_24_mid() adds the value of v to the
+ *     24 bit value contained in rtval[i] - rtval[i+2].
+ *     The new value of rtval[i] / rtval[i+1] is returned.
+ *     The LSB & MSB byte rtflg[] is cleared.
+ *
+ *     local variable:
+ *             Addr_T  j               temporary evaluation variable
+ *
+ *     global variables:
+ *             hilo                    byte ordering parameter
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             The value of rtval[] is changed.
+ *             The rtflg[] value corresponding to the
+ *             LSB & MSB of the 24 bit value is cleared to reflect
+ *             the fact that the middle byte is the selected byte.
+ *
+ */
+
+Addr_T
+adb_24_mid(Addr_T v, int i)
+{
+       register Addr_T j;
+
+       j = adw_24(v, i);
+
+       /* remove the MSB & LSB. */
+       rtflg[i+2] = 0;
+       rtflg[i] = 0;
+
+       return (j);
+}
+
+/*)Function    Addr_T          adb_24_lo(v, i)
+ *
+ *             int     v               value to add to byte
+ *             int     i               rtval[] index
+ *
+ *     The function adb_24_lo() adds the value of v to the
+ *     24 bit value contained in rtval[i] - rtval[i+2].
+ *     The new value of rtval[i] / rtval[i+1] is returned.
+ *     The MSB & middle byte rtflg[] is cleared.
+ *
+ *     local variable:
+ *             Addr_T  j               temporary evaluation variable
+ *
+ *     global variables:
+ *             hilo                    byte ordering parameter
+ *
+ *     called functions:
+ *             none
+ *
+ *     side effects:
+ *             The value of rtval[] is changed.
+ *             The rtflg[] value corresponding to the
+ *             MSB & middle byte  of the word value is cleared to
+ *             reflect the fact that the LSB is the selected byte.
+ *
+ */
+
+Addr_T
+adb_24_lo(Addr_T v, int i)
+{
+       register Addr_T j;
+
+       j = adw_24(v, i);
+
+       /* Remove the upper two bytes. */
+       if (hilo)
+       {
+           rtflg[i] = 0;
+       }
+       else
+       {
+           rtflg[i+2] = 0;
+       }
+       rtflg[i+1] = 0;
+
+       return (j);
+}
+
+/*)Function    Addr_T          adw_w(v, i)
  *
  *             int     v               value to add to word
  *             int     i               rtval[] index
@@ -867,7 +1052,7 @@ int        i;
  *     The new value of rtval[i] / rtval[i+1] is returned.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -880,12 +1065,12 @@ int      i;
  *
  */
 
-addr_t
+Addr_T
 adw_w(v, i)
-register addr_t v;
+register Addr_T v;
 register int i;
 {
-       register addr_t j;
+       register Addr_T j;
 
        if (hilo) {
                j = v + (rtval[i] << 8) + (rtval[i+1] & 0xff);
@@ -899,7 +1084,7 @@ register int i;
        return(j);
 }
 
-/*)Function    addr_t          adw_24(v, i)
+/*)Function    Addr_T          adw_24(v, i)
  *
  *             int     v               value to add to word
  *             int     i               rtval[] index
@@ -909,7 +1094,7 @@ register int i;
  *     The new value of rtval[i] - rtval[i+2] is returned.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -921,10 +1106,10 @@ register int i;
  *             The word value of rtval[] is changed.
  *
  */
-addr_t
-adw_24(addr_t v, int i)
+Addr_T
+adw_24(Addr_T v, int i)
 {
-       register addr_t j;
+       register Addr_T j;
 
        if (hilo) {
                j = v + ((rtval[i] & 0xff) << 16) 
@@ -944,7 +1129,7 @@ adw_24(addr_t v, int i)
        return(j);
 }
 
-/*)Function    addr_t          adw_lo(v, i)
+/*)Function    Addr_T          adw_lo(v, i)
  *
  *             int     v               value to add to byte
  *             int     i               rtval[] index
@@ -955,7 +1140,7 @@ adw_24(addr_t v, int i)
  *     The MSB rtval[] is zeroed.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -970,12 +1155,12 @@ adw_24(addr_t v, int i)
  *
  */
 
-addr_t
+Addr_T
 adw_lo(v, i)
-addr_t v;
+Addr_T v;
 int    i;
 {
-       register addr_t j;
+       register Addr_T j;
 
        j = adw_w(v, i);
        /*
@@ -989,7 +1174,7 @@ int        i;
        return (j);
 }
 
-/*)Function    addr_t          adw_hi(v, i)
+/*)Function    Addr_T          adw_hi(v, i)
  *
  *             int     v               value to add to byte
  *             int     i               rtval[] index
@@ -1001,7 +1186,7 @@ int       i;
  *     The MSB rtval[] is zeroed.
  *
  *     local variable:
- *             addr_t  j               temporary evaluation variable
+ *             Addr_T  j               temporary evaluation variable
  *
  *     global variables:
  *             hilo                    byte ordering parameter
@@ -1016,12 +1201,12 @@ int     i;
  *
  */
 
-addr_t
+Addr_T
 adw_hi(v, i)
-addr_t v;
+Addr_T v;
 int    i;
 {
-       register addr_t j;
+       register Addr_T j;
 
        j = adw_w(v, i);
        /*
@@ -1166,7 +1351,7 @@ char *str;
 /*)Function    VOID prntval(fptr, v)
  *
  *             FILE    *fptr   output file handle
- *             addr_t  v               value to output
+ *             Addr_T  v               value to output
  *
  *     The function prntval() outputs the value v, in the
  *     currently selected radix, to the device specified
@@ -1189,7 +1374,7 @@ char *str;
 VOID
 prntval(fptr, v)
 FILE *fptr;
-addr_t v;
+Addr_T v;
 {
        if (xflag == 0) {
                fprintf(fptr, "%04X\n", v);