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 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
22 // --- Initialize Marker ---------------------------------------------------------------------------
25 void init_mark(void) {
26 firstmch = curmch = NULL;
32 // --- Wrap up marker (called after final mark is made) --------------------------------------------
37 *markptr.wp = MCHEND; // Mark end of block
38 curmch->mcused = mcused; // Update #used in mark block
43 // --- Mark a word or longword relocatable ---------------------------------------------------------
46 int rmark(int from, LONG loc, int to, int size, SYM *symbol) {
49 if((mcalloc - mcused) < MIN_MARK_MEM)
52 w = (WORD)(size | to);
58 mcused += sizeof(WORD) + sizeof(LONG);
63 *markptr.wp++ = (WORD)from;
65 mcused += sizeof(WORD);
69 *markptr.sy++ = symbol;
70 mcused += sizeof(LONG);
79 // --- Allocate another chunk of mark space --------------------------------------------------------
85 // Alloc mark block header (and data) and set it up.
86 p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
88 p->mcalloc = MARK_ALLOC_INCR;
89 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
91 if(curmch) { // Link onto previous chunk
92 *markptr.wp++ = MCHEND; // Mark end of block
93 curmch->mcused = mcused;
99 curmch = p; // Setup global vars
101 mcalloc = MARK_ALLOC_INCR;
108 // --- Make mark image for BSD .o file -------------------------------------------------------------
111 LONG bsdmarkimg(char *mp, LONG siz, LONG tsize, int reqseg) {
112 MCHUNK *mch; // Mark chunk
113 PTR p; // Source point from within mark chunk
114 WORD from; // Section fixups are currently FROM
115 WORD w; // A word (temp)
116 LONG loc; // Location (temp)
117 SYM *symbol; // Symbols (temp)
118 char *wp; // Pointer into raw relocation info
119 char *dp; // Deposit point for RELMOD info
120 LONG diff; // Difference to relocate (RELMOD)
121 LONG raddr, rflag = 0; // BSD relocation address and flags
122 LONG rsize; // Relocation size
123 int validsegment = 0; // Valid segment being processed
125 rsize = 0; // Initialise relocation size
129 for(mch = firstmch; mch != NULL; mch = mch->mcnext)
130 for(p = mch->mcptr;;) {
131 w = *p.wp++; // Next mark entry
133 if(w & MCHEND) break; // End of mark chunk
137 loc = *p.lp++; // Mark location
138 if(w & MCHFROM) { // Maybe change "from" section
140 if(obj_format == BSD) {
141 if(reqseg == TEXT) { // Requested segment is TEXT
142 if(from == TEXT) validsegment = 1;
143 else validsegment = 0;
144 } else { // Requested segment is DATA
145 if(from == DATA) validsegment = 1;
146 else validsegment = 0;
151 if(w & MSYMBOL) // Maybe includes a symbol
154 if(obj_format == BSD) {
155 raddr = loc; // Set relocation address
157 D_long(raddr); // Write relocation address
159 rflag = 0x000000A0; // PC-relative fixup
161 rflag = 0x00000040; // Absolute fixup
166 // Compute mark position in relocation information;
167 // in RELMOD mode, get address of data to fix up.
170 wp = (char *)(mp + loc);
173 // Deposit external reference
174 if(obj_format == BSD) {
175 rflag |= 0x00000010; // Set external reloc flag bit
176 rflag |= (symbol->senv << 8); // Put symbol index in flags
177 if(symbol->sattre & RISCSYM) rflag |= 0x00000001;
179 D_long(rflag); // Write relocation flags
180 rsize += 8; // Increment relocation size
186 if(obj_format == BSD) {
187 w &= TDB; // Set reloc flags to segment
189 case TEXT: rflag |= 0x00000400; break;
190 case DATA: rflag |= 0x00000600; break;
191 case BSS: rflag |= 0x00000800; break;
194 D_long(rflag); // Write relocation flags
195 rsize += 8; // Increment relocation size
200 dp = objimage + BSDHDRSIZE + loc;
201 diff = ((LONG)(*dp++ & 0xff)) << 24;
202 diff |= ((LONG)(*dp++ & 0xff)) << 16;
203 diff |= ((LONG)(*dp++ & 0xff)) << 8;
204 diff |= (LONG)(*dp & 0xff);
205 DEBUG printf("diff=%lx ==> ", diff);
207 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
208 diff += sect[TEXT].sloc;
210 diff += sect[DATA].sloc;
212 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
213 dp = objimage + BSDHDRSIZE + loc;
214 *dp++ = (char)(diff >> 24);
215 *dp++ = (char)(diff >> 16);
216 *dp++ = (char)(diff >> 8);
218 DEBUG printf("%lx\n", diff);
225 if(obj_format == BSD) // Return relocation size