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