]> Shamusworld >> Repos - rmac/blobdiff - mark.c
Added floating point support to expression evaluator, introduced FLOAT token, fixup...
[rmac] / mark.c
diff --git a/mark.c b/mark.c
index 70f90fde4ab4e3fd26fdb2134fd22e645bb191e5..7378c8a6916aee2d8804c39901c042e39908e93b 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1,7 +1,7 @@
 //
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Reboot's Macro Assembler for all Atari computers
 // MARK.C - A record of things that are defined relative to any of the sections
-// Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -90,16 +90,13 @@ if (symbol)
 
        //
        // Complain about some things are not allowed in '-p' (PRG) mode:
-       //  o Marks that aren't to LONGs
-       //  o External references
+       //  o  Marks that aren't to LONGs
+       //  o  External references
        //
        if (prg_flag)
        {
-               if ((flags & MLONG) == 0)
-                       error("illegal word relocatable (in .PRG mode)");
-
                if (symbol != NULL)
-                       errors("illegal external reference (in .PRG mode) to '%s'",
+                       error("illegal external reference (in .PRG mode) to '%s'",
                                symbol->sname);
        }
 
@@ -380,6 +377,12 @@ printf(" validsegment: raddr = $%08X\n", loc);
                        if (w & MMOVEI)
                                rflag |= 0x00000001;
 
+                       // This tells the linker to do a WORD relocation (otherwise it
+                       // defaults to doing a LONG, throwing things off for WORD sized
+                       // fixups)
+                       if (!(w & MLONG))
+                               rflag |= 0x00000002;
+
                        if (symbol != NULL)
                        {
                                // Deposit external reference
@@ -417,7 +420,7 @@ printf("  validsegment(3): rflag = $%08X\n", rflag);
                                        if (from == DATA)
                                                dp += tsize;
 
-                                       uint32_t diff = GETBE32(dp, 0);
+                                       uint32_t diff = (rflag & 0x02 ? GETBE16(dp, 0) : GETBE32(dp, 0));
                                        DEBUG printf("diff=%uX ==> ", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(4): diff = $%08X --> ", diff);
@@ -433,7 +436,21 @@ printf("  validsegment(4): diff = $%08X --> ", diff);
                                        if (rflag & 0x01)
                                                diff = WORDSWAP32(diff);
 
-                                       SETBE32(dp, 0, diff);
+                                       // Make sure to deposit the correct size payload
+                                       // N.B.: The braces around the SETBExx macros are needed
+                                       //       because the macro supplies its own set of braces,
+                                       //       thus leaving a naked semicolon afterwards to
+                                       //       screw up the if/else structure. This is the price
+                                       //       you pay when using macros pretending to be code.
+                                       if (rflag & 0x02)
+                                       {
+                                               SETBE16(dp, 0, diff);
+                                       }
+                                       else
+                                       {
+                                               SETBE32(dp, 0, diff);
+                                       }
+
                                        DEBUG printf("%uX\n", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("$%08X\n", diff);
@@ -466,6 +483,7 @@ uint32_t CreateELFRelocationRecord(uint8_t * buf, uint8_t * secBuf, uint16_t sec
 
        // Setup pointer for D_long/word/byte macros
        chptr = buf;
+       ch_size = 0;
 
        for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
        {
@@ -531,7 +549,7 @@ uint32_t CreateELFRelocationRecord(uint8_t * buf, uint8_t * secBuf, uint16_t sec
 
                                // Deposit the relocation record
                                D_long(r_offset);
-                               D_long((r_sym << 8) | r_type);
+                               D_long(((r_sym << 8) | r_type));
                                D_long(r_addend);
                                rsize += 0x0C;
                        }