]> Shamusworld >> Repos - rmac/blobdiff - sect.c
Version bump for last patch; now at v1.13.4.
[rmac] / sect.c
diff --git a/sect.c b/sect.c
index f4ce7889e1f6a65a6ee5b11f28d8e01488c803f7..59f7977160b11dee3d3057e050f166f426bc74ea 100644 (file)
--- a/sect.c
+++ b/sect.c
@@ -177,26 +177,26 @@ int fixtest(int sno, uint32_t loc)
 
 //
 // Check that there are at least 'amt' bytes left in the current chunk. If
 
 //
 // Check that there are at least 'amt' bytes left in the current chunk. If
-// there are not, allocate another chunk of at least 'amt' bytes (and probably
-// more).
+// there are not, allocate another chunk of at least CH_CODE_SIZE bytes or
+// 'amt', whichever is larger.
 //
 // If 'amt' is zero, ensure there are at least CH_THRESHOLD bytes, likewise.
 //
 //
 // If 'amt' is zero, ensure there are at least CH_THRESHOLD bytes, likewise.
 //
-int chcheck(uint32_t amt)
+void chcheck(uint32_t amt)
 {
        DEBUG { printf("chcheck(%u)\n", amt); }
 
        // If in BSS section, no allocation required
        if (scattr & SBSS)
 {
        DEBUG { printf("chcheck(%u)\n", amt); }
 
        // If in BSS section, no allocation required
        if (scattr & SBSS)
-               return 0;
+               return;
 
 
-       if (!amt)
+       if (amt == 0)
                amt = CH_THRESHOLD;
 
                amt = CH_THRESHOLD;
 
-       DEBUG { printf("    challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc-ch_size); }
+       DEBUG { printf("    challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc - ch_size); }
 
        if ((int)(challoc - ch_size) >= (int)amt)
 
        if ((int)(challoc - ch_size) >= (int)amt)
-               return 0;
+               return;
 
        if (amt < CH_CODE_SIZE)
                amt = CH_CODE_SIZE;
 
        if (amt < CH_CODE_SIZE)
                amt = CH_CODE_SIZE;
@@ -216,7 +216,7 @@ int chcheck(uint32_t amt)
        {
                cp->chprev = scode;
                scode->chnext = cp;
        {
                cp->chprev = scode;
                scode->chnext = cp;
-               scode->ch_size = ch_size;                       // Save old chunk's globals
+               scode->ch_size = ch_size;       // Save old chunk's globals
        }
 
        // Setup chunk and global vars
        }
 
        // Setup chunk and global vars
@@ -227,7 +227,7 @@ int chcheck(uint32_t amt)
        chptr = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK);
        scode = p->scode = cp;
 
        chptr = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK);
        scode = p->scode = cp;
 
-       return 0;
+       return;
 }
 
 
 }
 
 
@@ -290,7 +290,7 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr)
 
        DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr);
                if (symbol != NULL)
 
        DEBUG { printf("AddFixup: sno=%u, l#=%u, attr=$%X, loc=$%X, expr=%p, sym=%p, org=$%X\n", cursect, fixup->lineno, fixup->attr, fixup->loc, (void *)fixup->expr, (void *)fixup->symbol, fixup->orgaddr);
                if (symbol != NULL)
-                       printf("          name: %s, value: $lX\n", symbol->sname, symbol->svalue);
+                       printf("          name: %s, value: $%lX\n", symbol->sname, symbol->svalue);
        }
 
        return 0;
        }
 
        return 0;
@@ -298,14 +298,10 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr)
 
 
 //
 
 
 //
-// Resolve fixups in a section
+// Resolve fixups in the passed in section
 //
 int ResolveFixups(int sno)
 {
 //
 int ResolveFixups(int sno)
 {
-       uint64_t eval;                  // Expression value
-       int reg2;
-       uint16_t flags;
-
        SECT * sc = &sect[sno];
 
        // "Cache" first chunk
        SECT * sc = &sect[sno];
 
        // "Cache" first chunk
@@ -328,7 +324,7 @@ int ResolveFixups(int sno)
                FIXUP * fup = fixup;
                fixup = fixup->next;
 
                FIXUP * fup = fixup;
                fixup = fixup->next;
 
-               uint32_t w = fup->attr;         // Fixup long (type+modes+flags)
+               uint32_t w = fup->attr;         // Fixup long (type + modes + flags)
                uint32_t loc = fup->loc;        // Location to fixup
                cfileno = fup->fileno;
                curlineno = fup->lineno;
                uint32_t loc = fup->loc;        // Location to fixup
                cfileno = fup->fileno;
                curlineno = fup->lineno;
@@ -365,8 +361,11 @@ int ResolveFixups(int sno)
                // subtract the chunk's starting location from loc to get the offset
                // into the current chunk.
                uint8_t * locp = cch->chptr + (loc - cch->chloc);
                // subtract the chunk's starting location from loc to get the offset
                // into the current chunk.
                uint8_t * locp = cch->chptr + (loc - cch->chloc);
+
                uint16_t eattr = 0;                     // Expression attrib
                SYM * esym = NULL;                      // External symbol involved in expr
                uint16_t eattr = 0;                     // Expression attrib
                SYM * esym = NULL;                      // External symbol involved in expr
+               uint64_t eval;                          // Expression value
+               uint16_t flags;                         // Mark flags
 
                // Compute expression/symbol value and attributes
 
 
                // Compute expression/symbol value and attributes
 
@@ -404,17 +403,15 @@ int ResolveFixups(int sno)
 
                // Do the fixup
                //
 
                // Do the fixup
                //
-               // If a PC-relative fixup is undefined, its value is *not*
-               // subtracted from the location (that will happen in the linker
-               // when the external reference is resolved).
+               // If a PC-relative fixup is undefined, its value is *not* subtracted
+               // from the location (that will happen in the linker when the external
+               // reference is resolved).
                //
                //
-               // MWC expects PC-relative things to have the LOC subtracted from
-               // the value, if the value is external (that is, undefined at this
-               // point).
+               // MWC expects PC-relative things to have the LOC subtracted from the
+               // value, if the value is external (that is, undefined at this point).
                //
                //
-               // PC-relative fixups must be DEFINED and either in the same
-               // section (whereupon the subtraction takes place) or ABS (with no
-               // subtract).
+               // PC-relative fixups must be DEFINED and either in the same section
+               // (whereupon the subtraction takes place) or ABS (with no subtract).
                if (w & FU_PCREL)
                {
                        if (eattr & DEFINED)
                if (w & FU_PCREL)
                {
                        if (eattr & DEFINED)
@@ -537,7 +534,7 @@ int ResolveFixups(int sno)
                                continue;
                        }
 
                                continue;
                        }
 
-                       *locp = (uint8_t)((eval >> 8) & 0xFF);
+                       *locp = (uint8_t)(eval >> 8);
                        break;
 
                case FU_BYTEL:
                        break;
 
                case FU_BYTEL:
@@ -547,61 +544,63 @@ int ResolveFixups(int sno)
                                continue;
                        }
 
                                continue;
                        }
 
-                       *locp = (uint8_t)(eval & 0xFF);
+                       *locp = (uint8_t)eval;
                        break;
 
                        break;
 
-               // Fixup WORD forward references; the word could be unaligned in
-               // the section buffer, so we have to be careful.
+               // Fixup WORD forward references; the word could be unaligned in the
+               // section buffer, so we have to be careful.
                case FU_WORD:
                        if ((w & FUMASKRISC) == FU_JR)
                        {
                case FU_WORD:
                        if ((w & FUMASKRISC) == FU_JR)
                        {
+                               int reg;
+
                                if (fup->orgaddr)
                                if (fup->orgaddr)
-                                       reg2 = (signed)((eval - (fup->orgaddr + 2)) / 2);
+                                       reg = (signed)((eval - (fup->orgaddr + 2)) / 2);
                                else
                                else
-                                       reg2 = (signed)((eval - (loc + 2)) / 2);
+                                       reg = (signed)((eval - (loc + 2)) / 2);
 
 
-                               if ((reg2 < -16) || (reg2 > 15))
+                               if ((reg < -16) || (reg > 15))
                                {
                                        error("relative jump out of range");
                                        break;
                                }
 
                                {
                                        error("relative jump out of range");
                                        break;
                                }
 
-                               *locp = (uint8_t)(*locp | ((reg2 >> 3) & 0x03));
+                               *locp |= ((uint8_t)reg >> 3) & 0x03;
                                locp++;
                                locp++;
-                               *locp = (uint8_t)(*locp | ((reg2 & 0x07) << 5));
+                               *locp |= ((uint8_t)reg & 0x07) << 5;
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM15)
                        {
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM15)
                        {
-                               if (eval < -16 || eval > 15)
+                               if (((int)eval < -16) || ((int)eval > 15))
                                {
                                {
-                                       error("constant out of range");
+                                       error("constant out of range (-16 - +15)");
                                        break;
                                }
 
                                        break;
                                }
 
-                               *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
+                               *locp |= ((uint8_t)eval >> 3) & 0x03;
                                locp++;
                                locp++;
-                               *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
+                               *locp |= ((uint8_t)eval & 0x07) << 5;
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM31)
                        {
                                if (eval > 31)
                                {
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM31)
                        {
                                if (eval > 31)
                                {
-                                       error("constant out of range");
+                                       error("constant out of range (0-31)");
                                        break;
                                }
 
                                        break;
                                }
 
-                               *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
+                               *locp |= ((uint8_t)eval >> 3) & 0x03;
                                locp++;
                                locp++;
-                               *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
+                               *locp |= ((uint8_t)eval & 0x07) << 5;
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM32)
                        {
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_NUM32)
                        {
-                               if (eval < 1 || eval > 32)
+                               if ((eval < 1) || (eval > 32))
                                {
                                {
-                                       error("constant out of range");
+                                       error("constant out of range (1-32)");
                                        break;
                                }
 
                                        break;
                                }
 
@@ -609,34 +608,34 @@ int ResolveFixups(int sno)
                                        eval = (32 - eval);
 
                                eval = (eval == 32) ? 0 : eval;
                                        eval = (32 - eval);
 
                                eval = (eval == 32) ? 0 : eval;
-                               *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
+                               *locp |= ((uint8_t)eval >> 3) & 0x03;
                                locp++;
                                locp++;
-                               *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
+                               *locp |= ((uint8_t)eval & 0x07) << 5;
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_REGONE)
                        {
                                if (eval > 31)
                                {
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_REGONE)
                        {
                                if (eval > 31)
                                {
-                                       error("register value out of range");
+                                       error("register one value out of range");
                                        break;
                                }
 
                                        break;
                                }
 
-                               *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
+                               *locp |= ((uint8_t)eval >> 3) & 0x03;
                                locp++;
                                locp++;
-                               *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
+                               *locp |= ((uint8_t)eval & 0x07) << 5;
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_REGTWO)
                        {
                                if (eval > 31)
                                {
                                break;
                        }
                        else if ((w & FUMASKRISC) == FU_REGTWO)
                        {
                                if (eval > 31)
                                {
-                                       error("register value out of range");
+                                       error("register two value out of range");
                                        break;
                                }
 
                                locp++;
                                        break;
                                }
 
                                locp++;
-                               *locp = (uint8_t)(*locp | (eval & 0x1F));
+                               *locp |= (uint8_t)eval & 0x1F;
                                break;
                        }
 
                                break;
                        }
 
@@ -680,9 +679,8 @@ int ResolveFixups(int sno)
 
                        break;
 
 
                        break;
 
-               // Fixup LONG forward references;
-               // the long could be unaligned in the section buffer, so be careful
-               // (again).
+               // Fixup LONG forward references; the long could be unaligned in the
+               // section buffer, so be careful (again).
                case FU_LONG:
                        flags = MLONG;
 
                case FU_LONG:
                        flags = MLONG;
 
@@ -703,6 +701,38 @@ int ResolveFixups(int sno)
                        SETBE32(locp, 0, eval);
                        break;
 
                        SETBE32(locp, 0, eval);
                        break;
 
+               // Fixup QUAD forward references (mainly used by the OP assembler)
+               case FU_QUAD:
+                       if (w & FU_OBJLINK)
+                       {
+                               uint64_t quad = GETBE64(locp, 0);
+                               uint64_t addr = eval;
+
+                               if (fup->orgaddr)
+                                       addr = fup->orgaddr;
+
+
+                               eval = (quad & 0xFFFFFC0000FFFFFFLL) | ((addr & 0x3FFFF8) << 21);
+                       }
+                       else if (w & FU_OBJDATA)
+                       {
+                               // If it's in a TEXT or DATA section, be sure to mark for a
+                               // fixup later
+                               if (tdb)
+                                       MarkRelocatable(sno, loc, tdb, MQUAD, NULL);
+
+                               uint64_t quad = GETBE64(locp, 0);
+                               uint64_t addr = eval;
+
+                               if (fup->orgaddr)
+                                       addr = fup->orgaddr;
+
+                               eval = (quad & 0x000007FFFFFFFFFFLL) | ((addr & 0xFFFFF8) << 40);
+                       }
+
+                       SETBE64(locp, 0, eval);
+                       break;
+
                // Fixup a 3-bit "QUICK" reference in bits 9..1
                // (range of 1..8) in a word. [Really bits 1..3 in a byte.]
                case FU_QUICK:
                // Fixup a 3-bit "QUICK" reference in bits 9..1
                // (range of 1..8) in a word. [Really bits 1..3 in a byte.]
                case FU_QUICK:
@@ -728,6 +758,21 @@ int ResolveFixups(int sno)
                        *locp = (uint8_t)eval;
                        break;
 
                        *locp = (uint8_t)eval;
                        break;
 
+               // Fixup a 4-byte float
+               case FU_FLOATSING:
+                       warn("FU_FLOATSING missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\"");
+                       break;
+
+               // Fixup a 8-byte float
+               case FU_FLOATDOUB:
+                       warn("FU_FLOATDOUB missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\"");
+                       break;
+
+               // Fixup a 12-byte float
+               case FU_FLOATEXT:
+                       warn("FU_FLOATEXT missing implementation\n%s", "And you may ask yourself, \"Self, how did I get here?\"");
+                       break;
+
                default:
                        // Bad fixup type--this should *never* happen!
                        // Once we call this function, it winds down immediately; it
                default:
                        // Bad fixup type--this should *never* happen!
                        // Once we call this function, it winds down immediately; it