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