X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=mark.c;h=1cb0f05131472f9d097dbdf5fe152ba58ef8c03e;hp=53eaf871854bb87bcd7e32f6a36e519ebcf8250f;hb=bdbf34766f4d074a5933eb1326fe4ce03d249e10;hpb=9153334781cd2e23750f4dc002e847606c07a1f0 diff --git a/mark.c b/mark.c index 53eaf87..1cb0f05 100644 --- a/mark.c +++ b/mark.c @@ -1,7 +1,7 @@ // // 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-2018 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -71,9 +71,9 @@ void StopMark(void) uint32_t MarkRelocatable(uint16_t section, uint32_t loc, uint16_t to, uint16_t flags, SYM * symbol) { #ifdef DEBUG_IMAGE_MARKING -printf("MarkRelocatable: section=%i, loc=$%X, to=$%X, flags=$%x, symbol=$%X\n", section, loc, to, flags, symbol); +printf("MarkRelocatable: section=%i, loc=$%X, to=$%X, flags=$%x, symbol=%p\n", section, loc, to, flags, symbol); if (symbol) - printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname); + printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%li, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname); #endif if ((mcalloc - mcused) < MIN_MARK_MEM) @@ -380,9 +380,13 @@ printf(" validsegment: raddr = $%08X\n", loc); // 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)) + if (!(w & (MLONG | MQUAD))) rflag |= 0x00000002; + // Tell the linker that the fixup is an OL QUAD data address + if (w & MQUAD) + rflag |= 0x00000004; + if (symbol != NULL) { // Deposit external reference @@ -415,19 +419,31 @@ printf(" validsegment(3): rflag = $%08X\n", rflag); if (w & (DATA | BSS)) { uint8_t * dp = objImage + BSDHDRSIZE + loc; + uint32_t olBitsSave = 0; // 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); +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) @@ -442,11 +458,31 @@ printf(" validsegment(4): diff = $%08X --> ", diff); // 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) + if (rflag & 0x02) // WORD relocation { SETBE16(dp, 0, diff); } - else + 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 { SETBE32(dp, 0, diff); }