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
14 MCHUNK * firstmch; // First mark chunk
15 MCHUNK * curmch; // Current mark chunk
16 PTR markptr; // Deposit point in current mark chunk
17 LONG mcalloc; // #bytes alloc'd to current mark chunk
18 LONG mcused; // #bytes used in current mark chunk
19 WORD curfrom; // Current "from" section
27 firstmch = curmch = NULL;
34 // Wrap up marker (called after final mark is made)
40 *markptr.wp = MCHEND; // Mark end of block
41 curmch->mcused = mcused; // Update #used in mark block
47 // Mark a word or longword relocatable
49 int rmark(int from, LONG loc, int to, int size, SYM * symbol)
53 if ((mcalloc - mcused) < MIN_MARK_MEM)
56 w = (WORD)(size | to);
64 mcused += sizeof(WORD) + sizeof(LONG);
70 *markptr.wp++ = (WORD)from;
72 mcused += sizeof(WORD);
77 *markptr.sy++ = symbol;
78 mcused += sizeof(LONG);
88 // Allocate another chunk of mark space
94 // Alloc mark block header (and data) and set it up.
95 // p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
96 p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR);
98 p->mcalloc = MARK_ALLOC_INCR;
99 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
102 { // Link onto previous chunk
103 *markptr.wp++ = MCHEND; // Mark end of block
104 curmch->mcused = mcused;
111 curmch = p; // Setup global vars
113 mcalloc = MARK_ALLOC_INCR;
121 // Make mark image for BSD .o file
123 LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
125 MCHUNK * mch; // Mark chunk
126 PTR p; // Source point from within mark chunk
127 WORD from; // Section fixups are currently FROM
128 WORD w; // A word (temp)
129 LONG loc; // Location (temp)
130 SYM * symbol; // Symbols (temp)
131 char * wp; // Pointer into raw relocation info
132 char * dp; // Deposit point for RELMOD info
133 LONG diff; // Difference to relocate (RELMOD)
134 LONG raddr, rflag = 0; // BSD relocation address and flags
135 LONG rsize; // Relocation size
136 int validsegment = 0; // Valid segment being processed
138 rsize = 0; // Initialise relocation size
142 for(mch = firstmch; mch != NULL; mch = mch->mcnext)
146 w = *p.wp++; // Next mark entry
149 break; // End of mark chunk
153 loc = *p.lp++; // Mark location
156 { // Maybe change "from" section
159 if (obj_format == BSD)
162 { // Requested segment is TEXT
169 { // Requested segment is DATA
178 if (w & MSYMBOL) // Maybe includes a symbol
181 if (obj_format == BSD)
183 raddr = loc; // Set relocation address
186 D_long(raddr); // Write relocation address
189 rflag = 0x000000A0; // PC-relative fixup
191 rflag = 0x00000040; // Absolute fixup
197 // Compute mark position in relocation information;
198 // in RELMOD mode, get address of data to fix up.
202 wp = (char *)(mp + loc);
206 // Deposit external reference
207 if (obj_format == BSD)
209 rflag |= 0x00000010; // Set external reloc flag bit
210 rflag |= (symbol->senv << 8); // Put symbol index in flags
212 if (symbol->sattre & RISCSYM)
217 D_long(rflag); // Write relocation flags
218 rsize += 8; // Increment relocation size
224 if (obj_format == BSD)
226 w &= TDB; // Set reloc flags to segment
230 case TEXT: rflag |= 0x00000400; break;
231 case DATA: rflag |= 0x00000600; break;
232 case BSS: rflag |= 0x00000800; break;
237 D_long(rflag); // Write relocation flags
238 rsize += 8; // Increment relocation size
247 dp = objimage + BSDHDRSIZE + loc;
248 diff = ((LONG)(*dp++ & 0xFF)) << 24;
249 diff |= ((LONG)(*dp++ & 0xFF)) << 16;
250 diff |= ((LONG)(*dp++ & 0xFF)) << 8;
251 diff |= (LONG)(*dp & 0xFF);
252 DEBUG printf("diff=%ux ==> ", diff);
255 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
257 diff += sect[TEXT].sloc;
260 diff += sect[DATA].sloc;
263 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
265 dp = objimage + BSDHDRSIZE + loc;
266 *dp++ = (char)(diff >> 24);
267 *dp++ = (char)(diff >> 16);
268 *dp++ = (char)(diff >> 8);
270 DEBUG printf("%ux\n", diff);
278 // Return relocation size
279 if (obj_format == BSD)