1 ////////////////////////////////////////////////////////////////////////////////////////////////////
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
13 MCHUNK *firstmch; // First mark chunk
14 MCHUNK *curmch; // Current mark chunk
15 PTR markptr; // Deposit point in current mark chunk
16 LONG mcalloc; // #bytes alloc'd to current mark chunk
17 LONG mcused; // #bytes used in current mark chunk
18 WORD curfrom; // Current "from" section
21 // --- Initialize Marker ---------------------------------------------------------------------------
24 void init_mark(void) {
25 firstmch = curmch = NULL;
31 // --- Wrap up marker (called after final mark is made) --------------------------------------------
36 *markptr.wp = MCHEND; // Mark end of block
37 curmch->mcused = mcused; // Update #used in mark block
42 // --- Mark a word or longword relocatable ---------------------------------------------------------
45 int rmark(int from, LONG loc, int to, int size, SYM *symbol) {
48 if((mcalloc - mcused) < MIN_MARK_MEM)
51 w = (WORD)(size | to);
57 mcused += sizeof(WORD) + sizeof(LONG);
62 *markptr.wp++ = (WORD)from;
64 mcused += sizeof(WORD);
68 *markptr.sy++ = symbol;
69 mcused += sizeof(LONG);
78 // --- Allocate another chunk of mark space --------------------------------------------------------
84 // Alloc mark block header (and data) and set it up.
85 p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
87 p->mcalloc = MARK_ALLOC_INCR;
88 p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
90 if(curmch) { // Link onto previous chunk
91 *markptr.wp++ = MCHEND; // Mark end of block
92 curmch->mcused = mcused;
98 curmch = p; // Setup global vars
100 mcalloc = MARK_ALLOC_INCR;
107 // --- Make mark image for BSD .o file -------------------------------------------------------------
110 LONG bsdmarkimg(char *mp, LONG siz, LONG tsize, int reqseg) {
111 MCHUNK *mch; // Mark chunk
112 PTR p; // Source point from within mark chunk
113 WORD from; // Section fixups are currently FROM
114 WORD w; // A word (temp)
115 LONG loc; // Location (temp)
116 SYM *symbol; // Symbols (temp)
117 char *wp; // Pointer into raw relocation info
118 char *dp; // Deposit point for RELMOD info
119 LONG diff; // Difference to relocate (RELMOD)
120 LONG raddr, rflag = 0; // BSD relocation address and flags
121 LONG rsize; // Relocation size
122 int validsegment = 0; // Valid segment being processed
124 rsize = 0; // Initialise relocation size
128 for(mch = firstmch; mch != NULL; mch = mch->mcnext)
129 for(p = mch->mcptr;;) {
130 w = *p.wp++; // Next mark entry
132 if(w & MCHEND) break; // End of mark chunk
136 loc = *p.lp++; // Mark location
137 if(w & MCHFROM) { // Maybe change "from" section
139 if(obj_format == BSD) {
140 if(reqseg == TEXT) { // Requested segment is TEXT
141 if(from == TEXT) validsegment = 1;
142 else validsegment = 0;
143 } else { // Requested segment is DATA
144 if(from == DATA) validsegment = 1;
145 else validsegment = 0;
150 if(w & MSYMBOL) // Maybe includes a symbol
153 if(obj_format == BSD) {
154 raddr = loc; // Set relocation address
156 D_long(raddr); // Write relocation address
158 rflag = 0x000000A0; // PC-relative fixup
160 rflag = 0x00000040; // Absolute fixup
165 // Compute mark position in relocation information;
166 // in RELMOD mode, get address of data to fix up.
169 wp = (char *)(mp + loc);
172 // Deposit external reference
173 if(obj_format == BSD) {
174 rflag |= 0x00000010; // Set external reloc flag bit
175 rflag |= (symbol->senv << 8); // Put symbol index in flags
176 if(symbol->sattre & RISCSYM) rflag |= 0x00000001;
178 D_long(rflag); // Write relocation flags
179 rsize += 8; // Increment relocation size
185 if(obj_format == BSD) {
186 w &= TDB; // Set reloc flags to segment
188 case TEXT: rflag |= 0x00000400; break;
189 case DATA: rflag |= 0x00000600; break;
190 case BSS: rflag |= 0x00000800; break;
193 D_long(rflag); // Write relocation flags
194 rsize += 8; // Increment relocation size
199 dp = objimage + BSDHDRSIZE + loc;
200 diff = ((LONG)(*dp++ & 0xff)) << 24;
201 diff |= ((LONG)(*dp++ & 0xff)) << 16;
202 diff |= ((LONG)(*dp++ & 0xff)) << 8;
203 diff |= (LONG)(*dp & 0xff);
204 DEBUG printf("diff=%lx ==> ", diff);
206 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
207 diff += sect[TEXT].sloc;
209 diff += sect[DATA].sloc;
211 diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
212 dp = objimage + BSDHDRSIZE + loc;
213 *dp++ = (char)(diff >> 24);
214 *dp++ = (char)(diff >> 16);
215 *dp++ = (char)(diff >> 8);
217 DEBUG printf("%lx\n", diff);
224 if(obj_format == BSD) // Return relocation size