+ // Bump the start of the section if it's DATA (& not TEXT)
+ if (from == DATA)
+ dp += tsize;
+
+ uint32_t diff = (rflag & 0x02 ? GETBE16(dp, 0) : GETBE32(dp, 0));
+
+ // Special handling for OP (data addr) relocation...
+ if (rflag & 0x04)
+ {
+ olBitsSave = diff & 0x7FF;
+ diff = (diff & 0xFFFFF800) >> 8;
+ }
+
+ DEBUG printf("diff=%uX ==> ", diff);
+#ifdef DEBUG_IMAGE_MARKING
+printf(" validsegment(4): diff = $%08X ", diff);
+#endif
+ if (rflag & 0x01)
+ diff = WORDSWAP32(diff);
+
+#ifdef DEBUG_IMAGE_MARKING
+printf("(sect[TEXT].sloc=$%X) --> ", sect[TEXT].sloc);
+#endif
+ diff += sect[TEXT].sloc;
+
+ if (w == BSS)
+ diff += sect[DATA].sloc;
+
+ if (rflag & 0x01)
+ diff = WORDSWAP32(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) // WORD relocation
+ {
+ SETBE16(dp, 0, diff);
+ }
+ else if (rflag & 0x04) // OP data address relocation
+ {
+ // We do it this way because we might have an offset
+ // that is not a multiple of 8 and thus we need this in
+ // place to prevent a bad address at link time. :-P As
+ // a consequence of this, the highest address we can
+ // have here is $1FFFF8.
+ uint32_t diffsave = diff;
+ diff = ((diff & 0x001FFFFF) << 11) | olBitsSave;
+ SETBE32(dp, 0, diff);
+ // But we need those 3 bits, otherwise we can get in
+ // trouble with things like OL data that is in the cart
+ // space, and BOOM! So the 2nd phrase of the fixup (it
+ // will *always* have a 2nd phrase) has a few spare
+ // bits, we chuck them in there.
+ uint32_t p2 = GETBE32(dp, 8);
+ p2 &= 0x1FFFFFFF;
+ p2 |= (diffsave & 0x00E00000) << 8;
+ SETBE32(dp, 8, p2);
+ }
+ else // LONG relocation