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