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 WORD curfrom; // Current "from" section
28 firstmch = curmch = NULL;
35 // Wrap up marker (called after final mark is made)
41 *markptr.wp = MCHEND; // Mark end of block
42 curmch->mcused = mcused; // Update #used in mark block
48 // Mark a word or longword relocatable
50 int rmark(int from, LONG loc, int to, int size, SYM * symbol)
54 if ((mcalloc - mcused) < MIN_MARK_MEM)
57 w = (WORD)(size | to);
65 mcused += sizeof(WORD) + sizeof(LONG);
71 *markptr.wp++ = (WORD)from;
73 mcused += sizeof(WORD);
78 *markptr.sy++ = symbol;
79 mcused += sizeof(LONG);
89 // Allocate another chunk of mark space
95 // Alloc mark block header (and data) and set it up.
96 // p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
97 p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR);
99 p->mcalloc = MARK_ALLOC_INCR;
100 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
103 { // Link onto previous chunk
104 *markptr.wp++ = MCHEND; // Mark end of block
105 curmch->mcused = mcused;
112 curmch = p; // Setup global vars
114 mcalloc = MARK_ALLOC_INCR;
122 // Make mark image for BSD .o file
124 LONG bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
126 MCHUNK * mch; // Mark chunk
127 PTR p; // Source point from within mark chunk
128 WORD from; // Section fixups are currently FROM
129 WORD w; // A word (temp)
130 LONG loc; // Location (temp)
131 SYM * symbol; // Symbols (temp)
132 char * wp; // Pointer into raw relocation info
133 char * dp; // Deposit point for RELMOD info
134 LONG diff; // Difference to relocate (RELMOD)
135 LONG raddr, rflag = 0; // BSD relocation address and flags
136 LONG rsize; // Relocation size
137 int validsegment = 0; // Valid segment being processed
139 rsize = 0; // Initialise relocation size
143 for(mch = firstmch; mch != NULL; mch = mch->mcnext)
147 w = *p.wp++; // Next mark entry
150 break; // End of mark chunk
154 loc = *p.lp++; // Mark location
157 { // Maybe change "from" section
160 if (obj_format == BSD)
163 { // Requested segment is TEXT
170 { // Requested segment is DATA
179 if (w & MSYMBOL) // Maybe includes a symbol
182 if (obj_format == BSD)
184 raddr = loc; // Set relocation address
187 D_long(raddr); // Write relocation address
190 rflag = 0x000000A0; // PC-relative fixup
192 rflag = 0x00000040; // Absolute fixup
198 // Compute mark position in relocation information;
199 // in RELMOD mode, get address of data to fix up.
203 wp = (char *)(mp + loc);
207 // Deposit external reference
208 if (obj_format == BSD)
210 rflag |= 0x00000010; // Set external reloc flag bit
211 rflag |= (symbol->senv << 8); // Put symbol index in flags
213 if (symbol->sattre & RISCSYM)
218 D_long(rflag); // Write relocation flags
219 rsize += 8; // Increment relocation size
225 if (obj_format == BSD)
227 w &= TDB; // Set reloc flags to segment
231 case TEXT: rflag |= 0x00000400; break;
232 case DATA: rflag |= 0x00000600; break;
233 case BSS: rflag |= 0x00000800; break;
238 D_long(rflag); // Write relocation flags
239 rsize += 8; // Increment relocation size
248 dp = objimage + BSDHDRSIZE + loc;
249 diff = ((LONG)(*dp++ & 0xFF)) << 24;
250 diff |= ((LONG)(*dp++ & 0xFF)) << 16;
251 diff |= ((LONG)(*dp++ & 0xFF)) << 8;
252 diff |= (LONG)(*dp & 0xFF);
253 DEBUG printf("diff=%ux ==> ", diff);
256 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
258 diff += sect[TEXT].sloc;
261 diff += sect[DATA].sloc;
264 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
266 dp = objimage + BSDHDRSIZE + loc;
267 *dp++ = (char)(diff >> 24);
268 *dp++ = (char)(diff >> 16);
269 *dp++ = (char)(diff >> 8);
271 DEBUG printf("%ux\n", diff);
279 // Return relocation size
280 if (obj_format == BSD)