More 24 bit flat mode support: handles "expr >> 16" relocations
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 8 Feb 2000 20:57:34 +0000 (20:57 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 8 Feb 2000 20:57:34 +0000 (20:57 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@89 4a8a32a2-be11-0410-ad9d-d568d2c75423

as/doc/format.txt
as/mcs51/asexpr.c
as/mcs51/aslink.h
as/mcs51/asm.h
as/mcs51/asout.c
as/mcs51/lkrloc.c

index fa73cfe26acf9fce4f24d509c7c2e1b6ea4fc13e..0cc625ef54d28154ed8d5ea88b0605adce953400 100644 (file)
 
         2.5.7  R Line 
 
-                R 0 0 nn nn n1 n2 xx xx ...  
+                R 0 0 nn nn n1 [n1x]  n2 xx xx ...  
 
            The R line provides the relocation information to the linker.
         The nn nn value is the current area index, i.e.  which area  the
         current  values  were  assembled.  Relocation information is en-
-        coded in groups of 4 bytes:  
+        coded in groups of 4 (possibly 5) bytes:  
 
-             1.  n1 is the relocation mode and object format 
+             1.  n1 (and optionally n1x) is the relocation mode and object
+                format:
                  1.  bit 0 word(0x00)/byte(0x01) 
                  2.  bit 1 relocatable area(0x00)/symbol(0x02) 
                  3.  bit 2 normal(0x00)/PC relative(0x04) relocation 
-                 4.  bit  3  1-byte(0x00)/2-byte(0x08) object format for
+                 4.  bit 3  1-byte(0x00)/2-byte(0x08) object format for
                      byte data 
                  5.  bit 4 signed(0x00)/unsigned(0x10) byte data 
                  6.  bit 5 normal(0x00)/page '0'(0x20) reference 
                  7.  bit 6 normal(0x00)/page 'nnn'(0x40) reference 
-                 8.  bit  7  LSB  byte(0x00)/MSB  byte(0x80) with 2-byte
-                     mode 
+                 8.  bit 7  LSB  byte(0x00)/MSB  byte(0x80) with 2-byte
+                     mode
+                9.  bit 8  1 or 2  (0x00)/3-byte (0x100) object format
+                    for byte data.
+                10. bit 9  LSB or MSB (middle byte) (0x00) or byte 3 
+                    (real MSB) (0x200) for 3-byte mode.
+
+               If the upper four bits of n1 are set (i.e. 
+               (n1 & 0xf0) == 0xf0), it is taken as an escape character, 
+               and the relocation mode will consist of the lower four bits
+               of n1 left shifted 8 bits or'ed with the value of n1x. If
+               the upper four bits of n1 are not all set, then it is not an 
+               escape character, and the n1x byte is not present.
+
+               This escape mechanism allows a 12-bit relocation mode value.
+
+               Note that in byte mode, when 3-byte mode is used (bits 0
+               and 8 are both set), the MSB bit (bit 7) really refers to 
+               the 16 bit MSB (the middle byte of the 24-bit value) while
+               the "byte 3" bit (bit 9) refers to the 24-bit MSB.
 
              2.  n2  is  a byte index into the corresponding (i.e.  pre-
                  ceeding) T line data (i.e.  a pointer to the data to be
index 1a94aa643a4823a1bc748309fef88655e75487a1..e675be354abeaa5a5f17ab0eea593a032695526b 100644 (file)
@@ -199,6 +199,23 @@ int n;
                                esp->e_rlcf |= R_MSB ;
                                break;
                            }
+                           else if (esp->e_base.e_ap && re.e_addr == 16)
+                           {
+                               if (flat24Mode)
+                               {
+                                   esp->e_rlcf |= R_HIB;
+                               }
+                               else
+                               {
+                                   warnBanner();
+                                   fprintf(stderr, 
+                                           "(expr >> 16) is only meaningful in "
+                                           ".flat24 mode.\n");
+                                   qerr();
+                               }
+                                   
+                              break;
+                           }
                            /* else continue with the normal processing */
                            abscheck(esp);
                            esp->e_addr >>= re.e_addr;
index 2fd486eaa4e9016ab8f3123d0e1e3bf795f31cc3..b0c9a969a1186d0a7eb57b5ea496337dfd633534 100644 (file)
  *         +-----+-----+-----+-----+-----+-----+-----+-----+
  */
 
-#define        R_WORD  0000            /* 16 bit */
-#define        R_BYTE  0001            /*  8 bit */
+#define        R_WORD  0x00            /* 16 bit */
+#define        R_BYTE  0x01            /*  8 bit */
 
-#define        R_AREA  0000            /* Base type */
-#define        R_SYM   0002
+#define        R_AREA  0x00            /* Base type */
+#define        R_SYM   0x02
 
-#define        R_NORM  0000            /* PC adjust */
-#define        R_PCR   0004
+#define        R_NORM  0x00            /* PC adjust */
+#define        R_PCR   0x04
 
-#define        R_BYT1  0000            /* Byte count for R_BYTE = 1 */
-#define        R_BYT2  0010            /* Byte count for R_BYTE = 2 */
+#define        R_BYT1  0x00            /* Byte count for R_BYTE = 1 */
+#define        R_BYT2  0x08            /* Byte count for R_BYTE = 2 */
 
-#define        R_SGND  0000            /* Signed value */
-#define        R_USGN  0020            /* Unsigned value */
+#define        R_SGND  0x00            /* Signed Byte */
+#define        R_USGN  0x10            /* Unsigned Byte */
 
-#define        R_NOPAG 0000            /* Page Mode */
-#define        R_PAG0  0040            /* Page '0' */
-#define        R_PAG   0100            /* Page 'nnn' */
+#define        R_NOPAG 0x00            /* Page Mode */
+#define        R_PAG0  0x20            /* Page '0' */
+#define        R_PAG   0x40            /* Page 'nnn' */
 
-/*
- * Valid for R_BYT2:
- */
-#define        R_LSB   0000            /* output low byte */
-#define        R_MSB   0200            /* output high byte */
+#define        R_LSB   0x00            /* low byte */
+#define        R_MSB   0x80            /* high byte */
+
+#define R_BYT3 0x100           /* if R_BYTE is set, this is a 
+                                * 3 byte address, of which
+                                * the linker must select one byte.
+                                */
+#define R_HIB  0x200           /* If R_BYTE & R_BYT3 are set, linker
+                                * will select byte 3 of the relocated
+                                * 24 bit address.
+                                */
 
 #define R_J11   (R_WORD|R_BYT2)        /* JLH: 11 bit JMP and CALL (8051) */
 #define R_J19   (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */
 #define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11)
 #define IS_C24(x) (((x) & R_J19_MASK) == R_C24)
 
+#define R_ESCAPE_MASK  0xf0    /* Used to escape relocation modes
+                                * greater than 0xff in the .rel
+                                * file.
+                                */
+
 /*
  * Global symbol types.
  */
@@ -685,6 +696,9 @@ extern      VOID            slew();
 extern addr_t          adb_b();
 extern addr_t          adb_hi();
 extern addr_t          adb_lo();
+extern addr_t          adb_24_hi(addr_t v, int i);
+extern addr_t          adb_24_mid(addr_t v, int i);
+extern addr_t          adb_24_lo(addr_t v, int i);
 extern addr_t          adw_w();
 extern addr_t          adw_24(addr_t, int);
 extern addr_t          adw_hi();
index 61c96daa8f91c754570f91bf8b5ccb21a183c7b3..a7a8131a0ec61e7f058eaf4814ab658475e7761d 100644 (file)
@@ -172,27 +172,36 @@ struct    area
  *     +-----+-----+-----+-----+-----+-----+-----+-----+
  */
 
-#define        R_WORD  0000            /* 16 bit */
-#define        R_BYTE  0001            /*  8 bit */
+#define        R_WORD  0x00            /* 16 bit */
+#define        R_BYTE  0x01            /*  8 bit */
 
-#define        R_AREA  0000            /* Base type */
-#define        R_SYM   0002
+#define        R_AREA  0x00            /* Base type */
+#define        R_SYM   0x02
 
-#define        R_NORM  0000            /* PC adjust */
-#define        R_PCR   0004
+#define        R_NORM  0x00            /* PC adjust */
+#define        R_PCR   0x04
 
-#define        R_BYT1  0000            /* Byte count for R_BYTE = 1 */
-#define        R_BYT2  0010            /* Byte count for R_BYTE = 2 */
+#define        R_BYT1  0x00            /* Byte count for R_BYTE = 1 */
+#define        R_BYT2  0x08            /* Byte count for R_BYTE = 2 */
 
-#define        R_SGND  0000            /* Signed Byte */
-#define        R_USGN  0020            /* Unsigned Byte */
+#define        R_SGND  0x00            /* Signed Byte */
+#define        R_USGN  0x10            /* Unsigned Byte */
 
-#define        R_NOPAG 0000            /* Page Mode */
-#define        R_PAG0  0040            /* Page '0' */
-#define        R_PAG   0100            /* Page 'nnn' */
+#define        R_NOPAG 0x00            /* Page Mode */
+#define        R_PAG0  0x20            /* Page '0' */
+#define        R_PAG   0x40            /* Page 'nnn' */
 
-#define        R_LSB   0000            /* low byte */
-#define        R_MSB   0200            /* high byte */
+#define        R_LSB   0x00            /* low byte */
+#define        R_MSB   0x80            /* high byte */
+
+#define R_BYT3 0x100           /* if R_BYTE is set, this is a 
+                                * 3 byte address, of which
+                                * the linker must select one byte.
+                                */
+#define R_HIB  0x200           /* If R_BYTE & R_BYT3 are set, linker
+                                * will select byte 3 of the relocated
+                                * 24 bit address.
+                                */
 
 #define R_J11   (R_WORD|R_BYT2)        /* JLH: 11 bit JMP and CALL (8051) */
 #define R_J19   (R_WORD|R_BYT2|R_MSB) /* 19 bit JMP/CALL (DS80C390) */
@@ -203,6 +212,11 @@ struct     area
 #define IS_R_J11(x) (((x) & R_J19_MASK) == R_J11)
 #define IS_C24(x) (((x) & R_J19_MASK) == R_C24)
 
+#define R_ESCAPE_MASK  0xf0    /* Used to escape relocation modes
+                                * greater than 0xff in the .rel
+                                * file.
+                                */
+
 /*
  * Listing Control Flags
  */
@@ -518,7 +532,7 @@ struct      expr
                struct area *e_ap;
                struct sym  *e_sp;
        } e_base;               /* Rel. base */
-       char    e_rlcf;         /* Rel. flags */
+       int     e_rlcf;         /* Rel. flags */
 };
 
 /* C Library functions */
@@ -613,7 +627,7 @@ extern      VOID            outbuf();
 extern VOID            outchk();
 extern VOID            outgsd();
 extern VOID            outrb();
-extern VOID            outrw();
+extern VOID            outrw(struct expr *, int);
 extern VOID            outr24(struct expr *, int);
 extern VOID            outsym();
 extern VOID            out_lb();
index d107854dbfb95c1576fba60cdc916ae836112c9a..90a80afafded63257e860212bda21875a3a2bea3 100644 (file)
@@ -279,6 +279,51 @@ outaw(w)
        dot.s_addr += 2;
 }
 
+/*)Function    VOID    write_rmode(r)
+ *
+ *             int     r               relocation mode
+ *
+ *     write_rmode puts the passed relocation mode into the 
+ *     output relp buffer, escaping it if necessary.
+ *
+ *     global variables:
+ *             int *   relp            pointer to rel array
+ *
+ *     functions called:
+ *             VOID    rerr()          assubr.c
+ *
+ *     side effects:
+ *             relp is incremented appropriately.
+ */
+VOID
+write_rmode(int r)
+{
+    /* We need to escape the relocation mode if it is greater
+     * than a byte, or if it happens to look like an escape.
+     * (I don't think that the latter case is legal, but
+     * better safe than sorry).
+     */
+    if ((r > 0xff) || ((r & R_ESCAPE_MASK) == R_ESCAPE_MASK))
+    {
+       /* Hack in up to an extra 4 bits of flags with escape. */
+       if (r > 0xfff)
+       {
+            /* uh-oh.. we have more than 4 extra bits. */
+            fprintf(stderr, 
+                    "Internal error: relocation mode 0x%X too big.\n", 
+                    r);
+            rerr();
+       }
+       /* printf("escaping relocation mode\n"); */
+       *relp++ = R_ESCAPE_MASK | (r >> 8);
+       *relp++ = r & 0xff;
+    }
+    else
+    {
+       *relp++ = r;
+    }
+}
+
 /*)Function    VOID    outrb(esp, r)
  *
  *             expr *  esp             pointer to expr structure
@@ -312,28 +357,43 @@ outaw(w)
  */
 
 VOID
-outrb(esp, r)
-register struct expr *esp;
-int r;
+outrb(struct expr *esp, int r)
 {
        register int n;
 
        if (pass == 2) {
                if (esp->e_flag==0 && esp->e_base.e_ap==NULL) {
+                       /* This is a constant; simply write the
+                        * const byte to the T line and don't
+                        * generate any relocation info.
+                        */
                        out_lb(lobyte(esp->e_addr),0);
                        if (oflag) {
                                outchk(1, 0);
                                *txtp++ = lobyte(esp->e_addr);
                        }
                } else {
-                       r |= R_BYTE | R_BYT2 | esp->e_rlcf;
-                       if (r & R_MSB) {
+                       /* We are generating a single byte of relocatable
+                        * info.
+                        *
+                        * In 8051 mode, we generate a 16 bit address. The 
+                        * linker will later select a single byte based on
+                        * whether R_MSB is set.
+                        *
+                        * In flat24 mode, we generate a 24 bit address. The
+                        * linker will select a single byte based on 
+                        * whether R_MSB or R_HIB is set.
+                        */
+                       if (!flat24Mode)
+                       { 
+                           r |= R_BYTE | R_BYT2 | esp->e_rlcf;
+                           if (r & R_MSB) {
                                out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
-                       } else {
+                           } else {
                                out_lb(lobyte(esp->e_addr),r|R_RELOC);
-                       }
-                       if (oflag) {
-                               outchk(2, 4);
+                           }
+                           if (oflag) {
+                               outchk(2, 5);
                                out_tw(esp->e_addr);
                                if (esp->e_flag) {
                                        n = esp->e_base.e_sp->s_ref;
@@ -341,9 +401,40 @@ int r;
                                } else {
                                        n = esp->e_base.e_ap->a_ref;
                                }
-                               *relp++ = r;
+                               write_rmode(r);
                                *relp++ = txtp - txt - 2;
                                out_rw(n);
+                           }
+                       }
+                       else
+                       {
+                           /* 24 bit mode. */
+                           r |= R_BYTE | R_BYT3 | esp->e_rlcf;
+                           if (r & R_HIB)
+                           {
+                               /* Probably should mark this differently in the
+                                * listing file.
+                                */
+                               out_lb(byte3(esp->e_addr),r|R_RELOC|R_HIGH);
+                           }
+                           else if (r & R_MSB) {
+                               out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH);
+                           } else {
+                               out_lb(lobyte(esp->e_addr),r|R_RELOC);
+                           }
+                           if (oflag) {
+                               outchk(3, 5);
+                               out_t24(esp->e_addr);
+                               if (esp->e_flag) {
+                                       n = esp->e_base.e_sp->s_ref;
+                                       r |= R_SYM;
+                               } else {
+                                       n = esp->e_base.e_ap->a_ref;
+                               }
+                               write_rmode(r);
+                               *relp++ = txtp - txt - 3;
+                               out_rw(n);                          
+                           }
                        }
                }
        }
@@ -383,9 +474,7 @@ int r;
  */
 
 VOID
-outrw(esp, r)
-register struct expr *esp;
-int r;
+outrw(struct expr *esp, int r)
 {
        register int n;
 
@@ -417,7 +506,7 @@ int r;
                                out_lw(esp->e_addr,r|R_RELOC);
                        }
                        if (oflag) {
-                               outchk(2, 4);
+                               outchk(2, 5);
                                out_tw(esp->e_addr);
                                if (esp->e_flag) {
                                        n = esp->e_base.e_sp->s_ref;
@@ -437,7 +526,7 @@ int r;
                                            "outrw()\n");
                                    rerr();
                                }
-                               *relp++ = r;
+                               write_rmode(r);
                                *relp++ = txtp - txt - 2;
                                out_rw(n);
                        }
@@ -506,7 +595,7 @@ outr24(struct expr *esp, int r)
                                out_l24(esp->e_addr,r|R_RELOC);
                        }
                        if (oflag) {
-                               outchk(3, 4);
+                               outchk(3, 5);
                                out_t24(esp->e_addr);
                                if (esp->e_flag) {
                                        n = esp->e_base.e_sp->s_ref;
@@ -529,7 +618,7 @@ outr24(struct expr *esp, int r)
                                    rerr();
                                }
                                
-                               *relp++ = r | R_C24;
+                               write_rmode(r | R_C24);
                                *relp++ = txtp - txt - 3;
                                out_rw(n);
                        }
@@ -586,7 +675,7 @@ register struct expr *esp;
                        } else {
                                n = esp->e_base.e_ap->a_ref;
                        }
-                       *relp++ = r;
+                       write_rmode(r);
                        *relp++ = txtp - txt - 2;
                        out_rw(n);
                }
@@ -693,7 +782,7 @@ outchk(nt, nr)
        if (txtp == txt) {
                out_tw(dot.s_addr);
                if ((ap = dot.s_area) != NULL) {
-                       *relp++ = R_WORD|R_AREA;
+                       write_rmode(R_WORD|R_AREA);
                        *relp++ = 0;
                        out_rw(ap->a_ref);
                }
@@ -989,19 +1078,17 @@ register struct sym *sp;
  */
 
 VOID
-out(p, n)
-register char *p;
-register int n;
+out(char *p, int n)
 {
        while (n--) {
                if (xflag == 0) {
-                       fprintf(ofp, " %02X", (*p++)&0377);
+                       fprintf(ofp, " %02X", (*p++)&0xff);
                } else
                if (xflag == 1) {
-                       fprintf(ofp, " %03o", (*p++)&0377);
+                       fprintf(ofp, " %03o", (*p++)&0xff);
                } else
                if (xflag == 2) {
-                       fprintf(ofp, " %03u", (*p++)&0377);
+                       fprintf(ofp, " %03u", (*p++)&0xff);
                }
        }
 }
@@ -1321,7 +1408,7 @@ int r;
                r |= R_WORD | esp->e_rlcf;
                 out_lw(esp->e_addr,r|R_RELOC);
                 if (oflag) {
-                        outchk(3, 4);
+                        outchk(3, 5);
                         out_tw(esp->e_addr);
                         *txtp++ = op;
 
@@ -1331,7 +1418,7 @@ int r;
                         } else {
                                 n = esp->e_base.e_ap->a_ref;
                         }
-                        *relp++ = r;
+                        write_rmode(r);
                         *relp++ = txtp - txt - 3;
                         out_rw(n);
                 }
@@ -1366,7 +1453,7 @@ outr19(struct expr * esp, int op, int r)
                r |= R_WORD | esp->e_rlcf;
                 out_l24(esp->e_addr,r|R_RELOC);
                 if (oflag) {
-                        outchk(4, 4);
+                        outchk(4, 5);
                         out_t24(esp->e_addr);
                         *txtp++ = op;
                         
@@ -1376,7 +1463,7 @@ outr19(struct expr * esp, int op, int r)
                         } else {
                                 n = esp->e_base.e_ap->a_ref;
                         }
-                        *relp++ = r;
+                        write_rmode(r);
                         *relp++ = txtp - txt - 4;
                         out_rw(n);
                 }
index 88cc143809fb18b242fb3bd1f2966fef457bf3f6..b102545d1635bb21dbffefe1bd6a6cc78bdad438 100644 (file)
@@ -306,6 +306,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 +349,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 +359,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 {
@@ -857,6 +895,143 @@ int       i;
        return (j);
 }
 
+/*)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