//
// 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 0
- if ((flags & MLONG) == 0)
- error("illegal word relocatable (in .PRG mode)");
-#endif
-
if (symbol != NULL)
- errors("illegal external reference (in .PRG mode) to '%s'",
+ error("illegal external reference (in .PRG mode) to '%s'",
symbol->sname);
}
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
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);
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);
// Setup pointer for D_long/word/byte macros
chptr = buf;
+ ch_size = 0;
for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
{
// 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;
}