Version bump for last patch; now at v1.13.4.
[rmac] / debug.c
1 //
2 // RMAC - Reboot's Macro Assembler for all Atari computers
3 // DEBUG.C - Debugging Messages
4 // Copyright (C) 199x Landon Dyer, 2011-2018 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 "expr.h"
13 #include "mark.h"
14 #include "sect.h"
15 #include "token.h"
16
17
18 static int siztab[4] = { 3, 5, 9, 9 };
19 static PTR tp;
20
21
22 //
23 // Print 'c' visibly
24 //
25 int visprt(char c)
26 {
27         if (c < 0x20 || c >= 0x7F)
28                 putchar('.');
29         else
30                 putchar(c);
31
32         return 0;
33 }
34
35
36 //
37 // Print expression, return ptr to just past the ENDEXPR
38 //
39 TOKEN * printexpr(TOKEN * tokenptr)
40 {
41         if (tokenptr != NULL)
42         {
43                 while (*tokenptr != ENDEXPR)
44                 {
45                         switch ((int)*tokenptr++)
46                         {
47                         case SYMBOL:
48                                 printf("'%s' ", symbolPtr[*tokenptr]->sname);
49                                 tokenptr++;
50                                 break;
51                         case CONST:
52                                 tp.u32 = tokenptr;
53                                 printf("$%lX ", *tp.u64++);
54                                 tokenptr = tp.u32;
55                                 break;
56                         case ACONST:
57                                 printf("ACONST=($%X,$%X) ", *tokenptr, tokenptr[1]);
58                                 tokenptr += 2;
59                                 break;
60                         default:
61                                 printf("%c ", (char)tokenptr[-1]);
62                                 break;
63                         }
64                 }
65         }
66
67         return tokenptr + 1;
68 }
69
70
71 //
72 // Dump data in a chunk (and maybe others) in the appropriate format
73 //
74 int chdump(CHUNK * ch, int format)
75 {
76         while (ch != NULL)
77         {
78                 printf("chloc=$%08X, chsize=$%X\n", ch->chloc, ch->ch_size);
79                 mdump(ch->chptr, ch->ch_size, format, ch->chloc);
80                 ch = ch->chnext;
81         }
82
83         return 0;
84 }
85
86
87 //
88 // Dump fixup records in printable format
89 //
90 int fudump(FIXUP * fup)
91 {
92         for(; fup!=NULL;)
93         {
94                 uint32_t attr = fup->attr;
95                 uint32_t loc = fup->loc;
96                 uint16_t file = fup->fileno;
97                 uint16_t line = fup->lineno;
98
99                 printf("$%08X $%08X %d.%d: ", attr, loc, (int)file, (int)line);
100
101                 if (attr & FU_EXPR)
102                 {
103                         uint16_t esiz = ExpressionLength(fup->expr);
104                         printf("(%d long) ", (int)esiz);
105                         printexpr(fup->expr);
106                 }
107                 else
108                         printf("`%s' ;", fup->symbol->sname);
109
110                 if ((attr & FUMASKRISC) == FU_JR)
111                         printf(" *=$%X", fup->orgaddr);
112
113                 printf("\n");
114
115                 fup = fup->next;
116         }
117
118         return 0;
119 }
120
121
122 //
123 // Dump marks
124 //
125 int mudump(void)
126 {
127         MCHUNK * mch;
128         PTR p;
129         WORD from;
130         WORD w;
131         LONG loc;
132         SYM * symbol;
133
134         from = 0;
135
136         for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
137         {
138                 printf("mch=$%p mcptr=$%08X mcalloc=$%X mcused=$%X\n",
139                         mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
140
141                 p = mch->mcptr;
142
143                 for(;;)
144                 {
145                         w = *p.wp++;
146
147                         if (w & MCHEND)
148                                 break;
149
150                         symbol = NULL;
151                         loc = *p.lp++;
152
153                         if (w & MCHFROM)
154                                 from = *p.wp++;
155
156                         if (w & MSYMBOL)
157                                 symbol = *p.sy++;
158
159                         printf("m=$%04X to=%d loc=$%X from=%d siz=%s",
160                                         w, w & 0x00FF, loc, from, (w & MLONG) ? "long" : "word");
161
162                         if (symbol != NULL)
163                                 printf(" sym=`%s'", symbol->sname);
164
165                         printf("\n");
166                 }
167         }
168
169         return 0;
170 }
171
172
173 //
174 // Dump memory from 'start' for 'count' bytes; `flg' is the following ORed
175 // together:
176 // 0 - bytes
177 // 1 - words
178 // 2 - longwords
179 //
180 // if `base' is not -1, then print it at the start of each line, incremented
181 // accordingly.
182 //
183 int mdump(char * start, LONG count, int flg, LONG base)
184 {
185         int i, j, k;
186         j = 0;
187
188         for(i=0; i<(int)count;)
189         {
190                 if ((i & 15) == 0)
191                 {
192                         if (j < i)
193                         {
194                                 printf("  ");
195
196                                 while (j < i)
197                                 visprt(start[j++]);
198
199                                 putchar('\n');
200                         }
201
202                         j = i;
203
204                         if (base != -1)
205                                 printf("%08X  ", base);
206                 }
207
208                 switch (flg & 3)
209                 {
210                 case 0:
211                         printf("%02X ", start[i] & 0xFF);
212                         i++;
213                         break;
214                 case 1:
215                         printf("%02X%02X ", start[i] & 0xFF, start[i+1] & 0xFF);
216                         i += 2;
217                         break;
218                 case 2:
219                         printf("%02X%02X%02X%02X ", start[i] & 0xFF, start[i+1] & 0xFF,
220                                 start[i+2] & 0xFF, start[i+3] & 0xFF);
221                         i += 4;
222                         break;
223                 case 3:
224                         break;
225                 }
226
227                 if (base != -1)
228                         base += 1 << (flg & 3);
229         }
230
231         // Print remaining bit of ASCII; the hairy expression computes the number
232         // of spaces to print to make the ASCII line up nicely.
233         if (j != i)
234         {
235                 k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
236
237                 while (k--)
238                         putchar(' ');
239
240                 printf("  ");
241
242                 while (j < i)
243                         visprt(start[j++]);
244
245                 putchar('\n');
246         }
247
248         return 0;
249 }
250
251
252 //
253 // Dump list of tokens on stdout in printable form
254 //
255 int dumptok(TOKEN * tk)
256 {
257         int flg = 0;
258
259         while (*tk != EOL)
260         {
261                 if (flg++)
262                         printf(" ");
263
264                 if (*tk >= 128)
265                 {
266                         printf("REG=%u", *tk++ - 128);
267                         continue;
268                 }
269
270                 switch ((int)*tk++)
271                 {
272                 case CONST:                                        // CONST <value>
273                         tp.u32 = tk;
274                         printf("CONST=%lu", *tp.u64++);
275                         tk = tp.u32;
276                         break;
277                 case STRING:                                       // STRING <address>
278                         printf("STRING='%s'", string[*tk++]);
279                         break;
280                 case SYMBOL:                                       // SYMBOL <address>
281                         printf("SYMBOL='%s'", string[*tk++]);
282                         break;
283                 case EOL:                                          // End of line
284                         printf("EOL");
285                         break;
286                 case TKEOF:                                        // End of file (or macro)
287                         printf("TKEOF");
288                         break;
289                 case DEQUALS:                                      // ==
290                         printf("DEQUALS");
291                         break;
292                 case DCOLON:                                       // ::
293                         printf("DCOLON");
294                         break;
295                 case GE:                                           // >=
296                         printf("GE");
297                         break;
298                 case LE:                                           // <=
299                         printf("LE");
300                         break;
301                 case NE:                                           // <> or !=
302                         printf("NE");
303                         break;
304                 case SHR:                                          // >>
305                         printf("SHR");
306                         break;
307                 case SHL:                                          // <<
308                         printf("SHL");
309                         break;
310                 default:
311                         printf("%c", (int)tk[-1]);
312                         break;
313                 }
314         }
315
316         printf("\n");
317
318         return 0;
319 }
320
321
322 void DumpTokens(TOKEN * tokenBuffer)
323 {
324 //      printf("Tokens [%X]: ", sloc);
325
326         for(TOKEN * t=tokenBuffer; *t!=EOL; t++)
327         {
328                 if (*t == COLON)
329                         printf("[COLON]");
330                 else if (*t == CONST)
331                 {
332                         tp.u32 = t + 1;
333                         printf("[CONST: $%lX]", *tp.u64);
334                         t += 2;
335                 }
336                 else if (*t == ACONST)
337                 {
338                         printf("[ACONST: $%X, $%X]", (uint32_t)t[1], (uint32_t)t[2]);
339                         t += 2;
340                 }
341                 else if (*t == STRING)
342                 {
343                         t++;
344                         printf("[STRING:\"%s\"]", string[*t]);
345                 }
346                 else if (*t == SYMBOL)
347                 {
348                         t++;
349                         printf("[SYMBOL:\"%s\"]", string[*t]);
350                 }
351                 else if (*t == EOS)
352                         printf("[EOS]");
353                 else if (*t == TKEOF)
354                         printf("[TKEOF]");
355                 else if (*t == DEQUALS)
356                         printf("[DEQUALS]");
357                 else if (*t == SET)
358                         printf("[SET]");
359                 else if (*t == REG)
360                         printf("[REG]");
361                 else if (*t == DCOLON)
362                         printf("[DCOLON]");
363                 else if (*t == GE)
364                         printf("[GE]");
365                 else if (*t == LE)
366                         printf("[LE]");
367                 else if (*t == NE)
368                         printf("[NE]");
369                 else if (*t == SHR)
370                         printf("[SHR]");
371                 else if (*t == SHL)
372                         printf("[SHL]");
373                 else if (*t == UNMINUS)
374                         printf("[UNMINUS]");
375                 else if (*t == DOTB)
376                         printf("[DOTB]");
377                 else if (*t == DOTW)
378                         printf("[DOTW]");
379                 else if (*t == DOTL)
380                         printf("[DOTL]");
381                 else if (*t == DOTI)
382                         printf("[DOTI]");
383                 else if (*t == ENDEXPR)
384                         printf("[ENDEXPR]");
385                 else if (*t == CR_ABSCOUNT)
386                         printf("[CR_ABSCOUNT]");
387                 else if (*t == CR_DEFINED)
388                         printf("[CR_DEFINED]");
389                 else if (*t == CR_REFERENCED)
390                         printf("[CR_REFERENCED]");
391                 else if (*t == CR_STREQ)
392                         printf("[CR_STREQ]");
393                 else if (*t == CR_MACDEF)
394                         printf("[CR_MACDEF]");
395                 else if (*t == CR_TIME)
396                         printf("[CR_TIME]");
397                 else if (*t == CR_DATE)
398                         printf("[CR_DATE]");
399                 else if (*t >= 0x20 && *t <= 0x2F)
400                         printf("[%c]", (char)*t);
401                 else if (*t >= 0x3A && *t <= 0x3F)
402                         printf("[%c]", (char)*t);
403                 else if (*t >= 0x80 && *t <= 0x87)
404                         printf("[D%u]", ((uint32_t)*t) - 0x80);
405                 else if (*t >= 0x88 && *t <= 0x8F)
406                         printf("[A%u]", ((uint32_t)*t) - 0x88);
407                 else
408                         printf("[%X:%c]", (uint32_t)*t, (char)*t);
409         }
410
411         printf("[EOL]\n");
412 }
413
414
415 //
416 // Dump everything
417 //
418 int dump_everything(void)
419 {
420         for(int i=1; i<NSECTS; i++)
421         {
422                 if (sect[i].scattr & SUSED)
423                 {
424                         printf("Section %d sloc=$%X\n", i, sect[i].sloc);
425                         printf("Code:\n");
426                         chdump(sect[i].sfcode, 1);
427
428                         printf("Fixup:\n");
429                         fudump(sect[i].sffix);
430
431                         printf("\n");
432                 }
433         }
434
435         printf("\nMarks:\n");
436         mudump();                                                               // Dump marks
437
438         return 0;
439 }
440