Fix a few minor problems with 030 mode PC relative fixups.
authorShamus Hammons <jlhamm@acm.org>
Fri, 9 Aug 2019 14:12:14 +0000 (09:12 -0500)
committerShamus Hammons <jlhamm@acm.org>
Fri, 9 Aug 2019 14:12:14 +0000 (09:12 -0500)
6502.c
eagen0.c
object.c
sect.c
sect.h

diff --git a/6502.c b/6502.c
index 4c188cfb035f8f2faadba13d7d3dccfb48c7a543..ef95a0ce128c0111b6f5fc613b36f200b281e2cf 100644 (file)
--- a/6502.c
+++ b/6502.c
@@ -667,7 +667,7 @@ void m6502obj(int ofd)
 
        // Write out mandatory $FFFF header
        header[0] = header[1] = 0xFF;
-       ssize_t unused = write(ofd, header, 2);
+       uint32_t unused = write(ofd, header, 2);
 
        for(uint16_t * l=&orgmap[0][0]; l<currentorg; l+=2)
        {
index 11e648afe845707f43b7638231acbca9d91e5e60..533dfa2e4eafadeca90506d770efbb32326ae1ee 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -9,12 +9,12 @@
 
 int eaNgen(WORD siz)
 {
-       uint32_t vbd, v = (uint32_t)aNexval;
-       WORD wbd, w = (WORD)(aNexattr & DEFINED);
-       WORD tdbbd, tdb = (WORD)(aNexattr & TDB);
-       vbd = (uint32_t)aNbdexval;
-       wbd = (WORD)(aNbdexattr & DEFINED);
-       tdbbd = (WORD)(aNbdexattr & TDB);
+       uint32_t v = (uint32_t)aNexval;
+       WORD w = (WORD)(aNexattr & DEFINED);
+       WORD tdb = (WORD)(aNexattr & TDB);
+       uint32_t vbd = (uint32_t)aNbdexval;
+       WORD wbd = (WORD)(aNbdexattr & DEFINED);
+       WORD tdbbd = (WORD)(aNbdexattr & TDB);
        uint8_t extDbl[12];
 
        switch (amN)
@@ -31,6 +31,7 @@ int eaNgen(WORD siz)
        case AM_NONE:
                // This is a performance hit, though
                break;
+
        case ADISP:
                // expr(An)
                if (w)
@@ -82,6 +83,7 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case PCDISP:
                if (w)
                {
@@ -104,6 +106,7 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case AINDEXED:
                // Compute ixreg and size+scale
                w = (WORD)((aNixreg << 12) | aNixsiz);
@@ -129,6 +132,7 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case PCINDEXED:
                // Compute ixreg and size+scale
                w = (WORD)((aNixreg << 12) | aNixsiz);
@@ -155,6 +159,7 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case IMMED:
                switch (siz)
                {
@@ -176,6 +181,7 @@ int eaNgen(WORD siz)
                        }
 
                        break;
+
                case SIZW:
                case SIZN:
                        if (w)
@@ -195,6 +201,7 @@ int eaNgen(WORD siz)
                        }
 
                        break;
+
                case SIZL:
                        if (w)
                        {
@@ -210,6 +217,7 @@ int eaNgen(WORD siz)
                        }
 
                        break;
+
                case SIZS:
                        // 68881/68882/68040 only
                        if (w)
@@ -235,6 +243,7 @@ int eaNgen(WORD siz)
                        }
 
                break;
+
                case SIZD:
                        // 68881/68882/68040 only
                        if (w)
@@ -256,6 +265,7 @@ int eaNgen(WORD siz)
                        }
 
                        break;
+
                case SIZX:
                        // 68881/68882/68040 only
                        if (w)
@@ -271,22 +281,29 @@ int eaNgen(WORD siz)
                        }
                        else
                        {
+                               // Why would this be anything other than a floating point
+                               // expression???  Even if there were an undefined symbol in
+                               // the expression, how would that be relevant?  I can't see
+                               // any use case where this would make sense.
                                AddFixup(FU_FLOATDOUB, sloc, aNexpr);
                                memset(extDbl, 0, 12);
                                D_extend(extDbl);
                        }
 
                        break;
+
                default:
                        // IMMED size problem
                        interror(1);
                }
 
                break;
+
     case SIZP:
                // 68881/68882/68040 only
                return error("Sorry, .p constant format is not implemented yet!");
                break;
+
        case ABSW:
                if (w) // Defined
                {
@@ -305,6 +322,7 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case ABSL:
                if (w) // Defined
                {
@@ -320,12 +338,15 @@ int eaNgen(WORD siz)
                }
 
                break;
+
        case DINDW:
                D_word((0x190 | (aNixreg << 12)));
                break;
+
        case DINDL:
                D_word((0x990 | (aNixreg << 12)));
                break;
+
        case ABASE:
        case MEMPOST:
        case MEMPRE:
@@ -333,6 +354,7 @@ int eaNgen(WORD siz)
        case PCMPOST:
        case PCMPRE:
                D_word(aNexten);
+
                // Deposit bd (if not suppressed)
                if ((aNexten & 0x0030) == EXT_BDSIZE0)
                {
@@ -355,7 +377,7 @@ int eaNgen(WORD siz)
                        else
                        {
                                // Arrange for fixup later on
-                               AddFixup(FU_WORD | FU_SEXT, sloc, aNbexpr);
+                               AddFixup(FU_WORD | FU_SEXT | FU_PCRELX, sloc, aNbexpr);
                                D_word(0);
                        }
                }
@@ -377,6 +399,7 @@ int eaNgen(WORD siz)
                                D_long(0);
                        }
                }
+
                // Deposit od (if not suppressed)
                if ((aNexten & 7) == EXT_IISPRE0 || (aNexten & 7) == EXT_IISPREN
                        || (aNexten & 7) == EXT_IISNOIN || (aNexten & 7) == EXT_IISPOSN)
@@ -426,6 +449,7 @@ int eaNgen(WORD siz)
 
                break;
                //return error("unsupported 68020 addressing mode");
+
        default:
                // Bad addressing mode in ea gen
                interror(3);
index 29fd8f3ce0d672e42757eed92131ccfd47b6461d..24c285ca77b2850cf1eaa192ae81a77818567079 100644 (file)
--- a/object.c
+++ b/object.c
@@ -321,7 +321,7 @@ int WriteObject(int fd)
        uint8_t * buf;                  // Scratch area
        uint8_t * p;                    // Temporary ptr
        LONG trsize, drsize;    // Size of relocations
-       long unused;                    // For supressing 'write' warnings
+       uint32_t unused;                // For supressing 'write' warnings
 
        if (verb_flag)
        {
@@ -810,7 +810,7 @@ for(int j=0; j<i; j++)
                        WriteP56();
 
                // Write all the things |o/
-               ssize_t unused = write(fd, buf, chptr - buf);
+               unused = write(fd, buf, chptr - buf);
 
                if (buf)
                        free(buf);
diff --git a/sect.c b/sect.c
index 7fcb2996bc30051a819e656b08f7ffa6db0b5e61..c7580631faa89cf9534f206bdfd34847cab5b13f 100644 (file)
--- a/sect.c
+++ b/sect.c
@@ -455,12 +455,18 @@ int ResolveFixups(int sno)
                //
                // PC-relative fixups must be DEFINED and either in the same section
                // (whereupon the subtraction takes place) or ABS (with no subtract).
-               if (dw & FU_PCREL)
+               if ((dw & FU_PCREL) || (dw & FU_PCRELX))
                {
                        if (eattr & DEFINED)
                        {
                                if (tdb == sno)
+                               {
                                        eval -= loc;
+
+                                       // In this instruction the PC is located a DWORD away
+                                       if (dw & FU_PCRELX)
+                                               eval += 2;
+                               }
                                else if (tdb)
                                {
                                        // Allow cross-section PCREL fixups in Alcyon mode
@@ -483,6 +489,10 @@ int ResolveFixups(int sno)
                                                }
 
                                                eval -= loc;
+
+                                               // In this instruction the PC is located a DWORD away
+                                               if (dw & FU_PCRELX)
+                                                       eval += 2;
                                        }
                                        else
                                        {
@@ -495,8 +505,15 @@ int ResolveFixups(int sno)
                                        warn("unoptimized short branch");
                        }
                        else if (obj_format == MWC)
+                       {
                                eval -= loc;
 
+                               // In this instruction the PC is located a DWORD away
+                               if (dw & FU_PCRELX)
+                                       eval += 2;
+                       }
+
+                       // Be sure to clear any TDB flags, since we handled it just now
                        tdb = 0;
                        eattr &= ~TDB;
                }
diff --git a/sect.h b/sect.h
index fb1db431438e5c43ae28f8ab8e41364ce066ebbf..4de4bbf78f5a4dae5f5a18acc5d0ef87c85359fa 100644 (file)
--- a/sect.h
+++ b/sect.h
@@ -84,6 +84,7 @@
 
 #define FU_SEXT      0x0010            // Ok to sign extend
 #define FU_PCREL     0x0020            // Subtract PC first
+#define FU_PCRELX    0x1000000 // 030 variant
 #define FU_EXPR      0x0040            // Expression (not symbol) follows
 
 #define FU_GLOBAL    0x0080            // Mark global symbol