2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // MARK.C - A record of things that are defined relative to any of the sections
4 // Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source Utilised with the Kind Permission of Landon Dyer
15 MCHUNK * firstmch; // First mark chunk
16 MCHUNK * curmch; // Current mark chunk
17 PTR markptr; // Deposit point in current mark chunk
18 LONG mcalloc; // #bytes alloc'd to current mark chunk
19 LONG mcused; // #bytes used in current mark chunk
20 uint16_t curfrom; // Current "from" section
23 //#define DEBUG_IMAGE_MARKING
31 firstmch = curmch = NULL;
38 // Wrap up marker (called after final mark is made)
44 *markptr.wp = MCHEND; // Mark end of block
45 curmch->mcused = mcused; // Update #used in mark block
51 // Mark a word or longword relocatable
53 int rmark(uint16_t from, uint32_t loc, uint16_t to, uint16_t size, SYM * symbol)
55 #ifdef DEBUG_IMAGE_MARKING
56 printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol);
58 printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
61 if ((mcalloc - mcused) < MIN_MARK_MEM)
64 uint16_t flags = (size | to);
72 mcused += sizeof(WORD) + sizeof(LONG);
73 *markptr.wp++ = flags;
80 mcused += sizeof(WORD);
85 *markptr.sy++ = symbol;
86 mcused += sizeof(SYM *);
96 // Allocate another chunk of mark space
102 // Alloc mark block header (and data) and set it up.
103 // p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
104 MCHUNK * p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR);
106 p->mcalloc = MARK_ALLOC_INCR;
107 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
111 // Link onto previous chunk
112 *markptr.wp++ = MCHEND; // Mark end of block
113 curmch->mcused = mcused;
120 curmch = p; // Setup global vars
122 mcalloc = MARK_ALLOC_INCR;
130 // Make mark image for BSD .o file
132 uint32_t bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
134 MCHUNK * mch; // Mark chunk
135 PTR p; // Source point from within mark chunk
136 uint16_t from; // Section fixups are currently FROM
137 uint16_t w; // A word (temp)
138 uint32_t loc; // Location (temp)
139 SYM * symbol; // Symbols (temp)
140 uint8_t * wp; // Pointer into raw relocation info
141 uint8_t * dp; // Deposit point for RELMOD info
142 uint32_t diff; // Difference to relocate (RELMOD)
143 uint32_t raddr, rflag = 0; // BSD relocation address and flags
144 uint32_t rsize; // Relocation size
145 int validsegment = 0; // Valid segment being processed
147 #ifdef DEBUG_IMAGE_MARKING
148 printf("bsdmarkimg():\n");
150 // Initialise relocation size
155 for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
159 w = *p.wp++; // Next mark entry
162 break; // End of mark chunk
166 loc = *p.lp++; // Mark location
170 // Maybe change "from" section
173 if (obj_format == BSD)
177 // Requested segment is TEXT
185 // Requested segment is DATA
194 if (w & MSYMBOL) // Maybe includes a symbol
197 if (obj_format == BSD)
199 raddr = loc; // Set relocation address
202 #ifdef DEBUG_IMAGE_MARKING
204 printf(" validsegment: raddr = $%08X\n", raddr);
206 D_long(raddr); // Write relocation address
207 #ifdef DEBUG_IMAGE_MARKING
212 rflag = 0x000000A0; // PC-relative fixup
214 rflag = 0x00000040; // Absolute fixup
216 // This flag tells the linker to WORD swap the LONG when doing the fixup.
219 //printf("bsdmarkimg: ORing $01 to rflag (MMOVEI) [symbol=%s]...\n", symbol->sname);
224 // Compute mark position in relocation information;
225 // in RELMOD mode, get address of data to fix up.
229 wp = (uint8_t *)(mp + loc);
233 // Deposit external reference
234 if (obj_format == BSD)
236 rflag |= 0x00000010; // Set external reloc flag bit
237 rflag |= (symbol->senv << 8); // Put symbol index in flags
239 // Looks like this is completely unnecessary (considering it does the wrong thing!)
241 if (symbol->sattre & RISCSYM)
243 printf("bsdmarkimg: ORing $01 to rflag (RISCSYM) [symbol=%s]...\n", symbol->sname);
250 #ifdef DEBUG_IMAGE_MARKING
251 printf(" validsegment(2): rflag = $%08X\n", rflag);
253 D_long(rflag); // Write relocation flags
254 rsize += 8; // Increment relocation size
260 if (obj_format == BSD)
262 #ifdef DEBUG_IMAGE_MARKING
263 printf(" w = $%04X\n", w);
265 w &= TDB; // Set reloc flags to segment
269 case TEXT: rflag |= 0x00000400; break;
270 case DATA: rflag |= 0x00000600; break;
271 case BSS: rflag |= 0x00000800; break;
276 #ifdef DEBUG_IMAGE_MARKING
277 printf(" validsegment(3): rflag = $%08X\n", rflag);
279 D_long(rflag); // Write relocation flags
280 rsize += 8; // Increment relocation size
289 dp = objimage + BSDHDRSIZE + loc;
290 diff = ((LONG)(*dp++ & 0xFF)) << 24;
291 diff |= ((LONG)(*dp++ & 0xFF)) << 16;
292 diff |= ((LONG)(*dp++ & 0xFF)) << 8;
293 diff |= (LONG)(*dp & 0xFF);
294 DEBUG printf("diff=%ux ==> ", diff);
295 #ifdef DEBUG_IMAGE_MARKING
296 printf(" validsegment(4): diff = $%08X --> ", diff);
300 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
302 diff += sect[TEXT].sloc;
305 diff += sect[DATA].sloc;
308 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
310 dp = objimage + BSDHDRSIZE + loc;
311 *dp++ = (char)(diff >> 24);
312 *dp++ = (char)(diff >> 16);
313 *dp++ = (char)(diff >> 8);
315 DEBUG printf("%ux\n", diff);
316 #ifdef DEBUG_IMAGE_MARKING
317 printf("$%08X\n", diff);
326 // Return relocation size
327 if (obj_format == BSD)
328 #ifdef DEBUG_IMAGE_MARKING
330 printf(" rsize = $%X\n", rsize);
333 #ifdef DEBUG_IMAGE_MARKING