ELF support for RMAC.
[rmac] / debug.c
1 //
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // DEBUG.C - Debugging Messages
4 // Copyright (C) 199x Landon Dyer, 2011-2017 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
7 //
8
9 #include "debug.h"
10 #include "amode.h"
11 #include "direct.h"
12 #include "mark.h"
13 #include "sect.h"
14 #include "token.h"
15
16
17 static int siztab[4] = { 3, 5, 9, 9 };
18
19
20 //
21 // Print 'c' visibly
22 //
23 int visprt(char c)
24 {
25         if (c < 0x20 || c >= 0x7F)
26                 putchar('.');
27         else
28                 putchar(c);
29
30         return 0;
31 }
32
33
34 //
35 // Print expression, return ptr to just past the ENDEXPR
36 //
37 TOKEN * printexpr(TOKEN * tp)
38 {
39         if (tp != NULL)
40         {
41                 while (*tp != ENDEXPR)
42                 {
43                         switch ((int)*tp++)
44                         {
45                         case SYMBOL:
46                                 printf("'%s' ", symbolPtr[*tp]->sname);
47                                 tp++;
48                                 break;
49                         case CONST:
50                                 printf("$%X ", *tp++);
51                                 break;
52                         case ACONST:
53                                 printf("ACONST=($%X,$%X) ", *tp, tp[1]);
54                                 tp += 2;
55                                 break;
56                         default:
57                                 printf("%c ", (char)tp[-1]);
58                                 break;
59                         }
60                 }
61         }
62
63         return tp + 1;
64 }
65
66
67 //
68 // Dump data in a chunk (and maybe others) in the appropriate format
69 //
70 int chdump(CHUNK * ch, int format)
71 {
72         while (ch != NULL)
73         {
74                 printf("chloc=$%08X, chsize=$%X\n", ch->chloc, ch->ch_size);
75                 mdump(ch->chptr, ch->ch_size, format, ch->chloc);
76                 ch = ch->chnext;
77         }
78
79         return 0;
80 }
81
82
83 //
84 // Dump fixup records in printable format
85 //
86 int fudump(CHUNK * ch)
87 {
88         PTR p;
89
90         for(; ch!=NULL;)
91         {
92                 p.cp = ch->chptr;
93                 uint8_t * ep = ch->chptr + ch->ch_size;
94
95                 while (p.cp < ep)
96                 {
97                         uint16_t attr = *p.wp++;
98                         uint32_t loc = *p.lp++;
99                         uint16_t file = *p.wp++;
100                         uint16_t line = *p.wp++;
101
102                         printf("$%04X $%08X %d.%d: ", (int)attr, loc, (int)file, (int)line);
103
104                         if (attr & FU_EXPR)
105                         {
106                                 uint16_t esiz = *p.wp++;
107                                 printf("(%d long) ", (int)esiz);
108                                 p.tk = printexpr(p.tk);
109                         }
110                         else
111                         {
112                                 printf("`%s' ;", (*p.sy)->sname);
113                                 p.sy++;
114                         }
115
116                         if ((attr & 0x0F00) == FU_JR)
117                         {
118                                 printf(" *=$%X", *p.lp);
119                                 p.lp++;
120                         }
121
122                         printf("\n");
123                 }
124
125                 ch = ch->chnext;
126         }
127
128         return 0;
129 }
130
131
132 //
133 // Dump marks
134 //
135 int mudump(void)
136 {
137         MCHUNK * mch;
138         PTR p;
139         WORD from;
140         WORD w;
141         LONG loc;
142         SYM * symbol;
143
144         from = 0;
145
146         for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
147         {
148                 printf("mch=$%p mcptr=$%08X mcalloc=$%X mcused=$%X\n",
149                         mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
150
151                 p = mch->mcptr;
152
153                 for(;;)
154                 {
155                         w = *p.wp++;
156
157                         if (w & MCHEND)
158                                 break;
159
160                         symbol = NULL;
161                         loc = *p.lp++;
162
163                         if (w & MCHFROM)
164                                 from = *p.wp++;
165
166                         if (w & MSYMBOL)
167                                 symbol = *p.sy++;
168
169                         printf("m=$%04X to=%d loc=$%X from=%d siz=%s",
170                                         w, w & 0x00FF, loc, from, (w & MLONG) ? "long" : "word");
171
172                         if (symbol != NULL)
173                                 printf(" sym=`%s'", symbol->sname);
174
175                         printf("\n");
176                 }
177         }
178
179         return 0;
180 }
181
182
183 //
184 // Dump memory from 'start' for 'count' bytes; `flg' is the following ORed
185 // together:
186 // 0 - bytes
187 // 1 - words
188 // 2 - longwords
189 //
190 // if `base' is not -1, then print it at the start of each line, incremented
191 // accordingly.
192 //
193 int mdump(char * start, LONG count, int flg, LONG base)
194 {
195         int i, j, k;
196         j = 0;
197
198         for(i=0; i<(int)count;)
199         {
200                 if ((i & 15) == 0)
201                 {
202                         if (j < i)
203                         {
204                                 printf("  ");
205
206                                 while (j < i)
207                                 visprt(start[j++]);
208
209                                 putchar('\n');
210                         }
211
212                         j = i;
213
214                         if (base != -1)
215                                 printf("%08X  ", base);
216                 }
217
218                 switch (flg & 3)
219                 {
220                 case 0:
221                         printf("%02X ", start[i] & 0xff);
222                         i++;
223                         break;
224                 case 1:
225                         printf("%02X%02X ", start[i] & 0xff, start[i+1] & 0xff);
226                         i += 2;
227                         break;
228                 case 2:
229                         printf("%02X%02X%02X%02X ", start[i] & 0xff, start[i+1] & 0xff,
230                                 start[i+2] & 0xff, start[i+3] & 0xff);
231                         i += 4;
232                         break;
233                 case 3:
234                         break;
235                 }
236
237                 if (base != -1)
238                         base += 1 << (flg & 3);
239         }
240
241         // Print remaining bit of ASCII; the hairy expression computes the number
242         // of spaces to print to make the ASCII line up nicely.
243         if (j != i)
244         {
245                 k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
246
247                 while (k--)
248                         putchar(' ');
249
250                 printf("  ");
251
252                 while (j < i)
253                         visprt(start[j++]);
254
255                 putchar('\n');
256         }
257
258         return 0;
259 }
260
261
262 //
263 // Dump list of tokens on stdout in printable form
264 //
265 int dumptok(TOKEN * tk)
266 {
267         int flg = 0;
268
269         while (*tk != EOL)
270         {
271                 if (flg++)
272                         printf(" ");
273
274                 if (*tk >= 128)
275                 {
276                         printf("REG=%u", *tk++ - 128);
277                         continue;
278                 }
279
280                 switch ((int)*tk++)
281                 {
282                 case CONST:                                        // CONST <value>
283                         printf("CONST=%u", *tk++);
284                         break;
285                 case STRING:                                       // STRING <address>
286                         printf("STRING='%s'", string[*tk++]);
287                         break;
288                 case SYMBOL:                                       // SYMBOL <address>
289                         printf("SYMBOL='%s'", string[*tk++]);
290                         break;
291                 case EOL:                                          // End of line
292                         printf("EOL");
293                         break;
294                 case TKEOF:                                        // End of file (or macro)
295                         printf("TKEOF");
296                         break;
297                 case DEQUALS:                                      // ==
298                         printf("DEQUALS");
299                         break;
300                 case DCOLON:                                       // ::
301                         printf("DCOLON");
302                         break;
303                 case GE:                                           // >=
304                         printf("GE");
305                         break;
306                 case LE:                                           // <=
307                         printf("LE");
308                         break;
309                 case NE:                                           // <> or !=
310                         printf("NE");
311                         break;
312                 case SHR:                                          // >>
313                         printf("SHR");
314                         break;
315                 case SHL:                                          // <<
316                         printf("SHL");
317                         break;
318                 default:
319                         printf("%c", (int)tk[-1]);
320                         break;
321                 }
322         }
323
324         printf("\n");
325
326         return 0;
327 }
328
329
330 //
331 // Dump everything
332 //
333 int dump_everything(void)
334 {
335         for(int i=1; i<NSECTS; i++)
336         {
337                 if (sect[i].scattr & SUSED)
338                 {
339                         printf("Section %d sloc=$%X\n", i, sect[i].sloc);
340                         printf("Code:\n");
341                         chdump(sect[i].sfcode, 1);
342
343                         printf("Fixup:\n");
344                         fudump(sect[i].sffix);
345
346                         printf("\n");
347                 }
348         }
349
350         printf("\nMarks:\n");
351         mudump();                                                               // Dump marks
352
353         return 0;
354 }
355