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);
97 p->mcalloc = MARK_ALLOC_INCR;
98 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
101 { // Link onto previous chunk
102 *markptr.wp++ = MCHEND; // Mark end of block
103 curmch->mcused = mcused;
110 curmch = p; // Setup global vars
112 mcalloc = MARK_ALLOC_INCR;
120 // Make mark image for BSD .o file
122 LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
124 MCHUNK * mch; // Mark chunk
125 PTR p; // Source point from within mark chunk
126 WORD from; // Section fixups are currently FROM
127 WORD w; // A word (temp)
128 LONG loc; // Location (temp)
129 SYM * symbol; // Symbols (temp)
130 char * wp; // Pointer into raw relocation info
131 char * dp; // Deposit point for RELMOD info
132 LONG diff; // Difference to relocate (RELMOD)
133 LONG raddr, rflag = 0; // BSD relocation address and flags
134 LONG rsize; // Relocation size
135 int validsegment = 0; // Valid segment being processed
137 rsize = 0; // Initialise relocation size
141 for(mch = firstmch; mch != NULL; mch = mch->mcnext)
145 w = *p.wp++; // Next mark entry
148 break; // End of mark chunk
152 loc = *p.lp++; // Mark location
155 { // Maybe change "from" section
158 if (obj_format == BSD)
161 { // Requested segment is TEXT
168 { // Requested segment is DATA
177 if (w & MSYMBOL) // Maybe includes a symbol
180 if (obj_format == BSD)
182 raddr = loc; // Set relocation address
185 D_long(raddr); // Write relocation address
188 rflag = 0x000000A0; // PC-relative fixup
190 rflag = 0x00000040; // Absolute fixup
196 // Compute mark position in relocation information;
197 // in RELMOD mode, get address of data to fix up.
201 wp = (char *)(mp + loc);
205 // Deposit external reference
206 if (obj_format == BSD)
208 rflag |= 0x00000010; // Set external reloc flag bit
209 rflag |= (symbol->senv << 8); // Put symbol index in flags
211 if (symbol->sattre & RISCSYM)
216 D_long(rflag); // Write relocation flags
217 rsize += 8; // Increment relocation size
223 if (obj_format == BSD)
225 w &= TDB; // Set reloc flags to segment
229 case TEXT: rflag |= 0x00000400; break;
230 case DATA: rflag |= 0x00000600; break;
231 case BSS: rflag |= 0x00000800; break;
236 D_long(rflag); // Write relocation flags
237 rsize += 8; // Increment relocation size
246 dp = objimage + BSDHDRSIZE + loc;
247 diff = ((LONG)(*dp++ & 0xFF)) << 24;
248 diff |= ((LONG)(*dp++ & 0xFF)) << 16;
249 diff |= ((LONG)(*dp++ & 0xFF)) << 8;
250 diff |= (LONG)(*dp & 0xFF);
251 DEBUG printf("diff=%ux ==> ", diff);
254 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
256 diff += sect[TEXT].sloc;
259 diff += sect[DATA].sloc;
262 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
264 dp = objimage + BSDHDRSIZE + loc;
265 *dp++ = (char)(diff >> 24);
266 *dp++ = (char)(diff >> 16);
267 *dp++ = (char)(diff >> 8);
269 DEBUG printf("%ux\n", diff);
277 // Return relocation size
278 if (obj_format == BSD)