Fixed subtle bug in expr().
[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-2012 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' ", ((SYM *)*tp)->sname);
47                                 printf("`%s' ", symbolPtr[*tp]->sname);
48                                 tp++;
49                                 break;
50                         case CONST:
51                                 printf("$%X ", *tp++);
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 //      printf(";\n");
65         return tp + 1;
66 }
67
68
69 //
70 // Dump data in a chunk (and maybe others) in the appropriate format
71 //
72 int chdump(CHUNK * ch, int format)
73 {
74         while (ch != NULL)
75         {
76                 printf("chloc=$%08X, chsize=$%X\n", ch->chloc, ch->ch_size);
77                 mdump(ch->chptr, ch->ch_size, format, ch->chloc);
78                 ch = ch->chnext;
79         }
80
81         return 0;
82 }
83
84
85 //
86 // Dump fixup records in printable format
87 //
88 int fudump(CHUNK * ch)
89 {
90         PTR p;
91         char * ep;
92         WORD attr, esiz;
93         WORD line, file;
94         LONG loc;
95
96         for(; ch!=NULL;)
97         {
98                 p.cp = ch->chptr;
99                 ep = ch->chptr + ch->ch_size;
100
101                 while (p.cp < ep)
102                 {
103                         attr = *p.wp++;
104                         loc = *p.lp++;
105                         file = *p.wp++;
106                         line = *p.wp++;
107
108                         printf("$%04X $%08X %d.%d: ", (int)attr, loc, (int)file, (int)line);
109
110                         if (attr & FU_EXPR)
111                         {
112                                 esiz = *p.wp++;
113                                 printf("(%d long) ", (int)esiz);
114                                 p.tk = printexpr(p.tk);
115                         }
116                         else
117                         {
118 //                              printf("`%s' ;\n", (*p.sy)->sname);
119                                 printf("`%s' ;", (*p.sy)->sname);
120                                 p.sy++;
121                         }
122
123                         if ((attr & 0x0F00) == FU_JR)
124                         {
125                                 printf(" *=$%X", *p.lp);
126                                 p.lp++;
127                         }
128
129                         printf("\n");
130                 }
131
132                 ch = ch->chnext;
133         }
134
135         return 0;
136 }
137
138
139 //
140 // Dump marks
141 //
142 int mudump(void)
143 {
144         MCHUNK * mch;
145         PTR p;
146         WORD from;
147         WORD w;
148         LONG loc;
149         SYM * symbol;
150
151         from = 0;
152
153         for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
154         {
155                 printf("mch=$%p mcptr=$%08X mcalloc=$%X mcused=$%X\n",
156                         mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
157
158                 p = mch->mcptr;
159                 
160                 for(;;)
161                 {
162                         w = *p.wp++;
163
164                         if (w & MCHEND)
165                                 break;
166
167                         symbol = NULL;
168                         loc = *p.lp++;
169
170                         if (w & MCHFROM)
171                                 from = *p.wp++;
172
173                         if (w & MSYMBOL)
174                                 symbol = *p.sy++;
175
176                         printf("m=$%04X to=%d loc=$%X from=%d siz=%s",
177                                         w, w & 0x00FF, loc, from, (w & MLONG) ? "long" : "word");
178
179                         if (symbol != NULL)
180                                 printf(" sym=`%s'", symbol->sname);
181
182                         printf("\n");
183                 }
184         }
185
186         return 0;
187 }
188
189
190 //
191 // Dump memory from 'start' for 'count' bytes; `flg' is the following ORed together:
192 // 0 - bytes
193 // 1 - words
194 // 2 - longwords
195 // 
196 // if `base' is not -1, then print it at the start of each line, incremented accordingly.
197 //
198 int mdump(char * start, LONG count, int flg, LONG base)
199 {
200         int i, j, k;
201         j = 0;
202
203         for(i=0; i<(int)count;)
204         {
205                 if ((i & 15) == 0)
206                 {
207                         if (j < i)
208                         {
209                                 printf("  ");
210
211                                 while(j < i)
212                                 visprt(start[j++]);
213
214                                 putchar('\n');
215                         }
216
217                         j = i;
218
219                         if (base != -1)
220                                 printf("%08X  ", base);
221                 }
222
223                 switch (flg & 3)
224                 {
225                 case 0:
226                         printf("%02X ", start[i] & 0xff);
227                         ++i;
228                         break;
229                 case 1:
230                         printf("%02X%02X ", start[i] & 0xff, start[i+1] & 0xff);
231                         i += 2;
232                         break;
233                 case 2:
234                         printf("%02X%02X%02X%02X ", start[i] & 0xff, start[i+1] & 0xff,
235                                 start[i+2] & 0xff, start[i+3] & 0xff);
236                         i += 4;
237                         break;
238                 case 3:
239                         break;
240                 }
241
242                 if (base != -1)
243                         base += 1 << (flg & 3);
244         }
245
246         // Print remaining bit of ascii; the hairy expression computes the number of
247         // spaces to print to make the ascii line up nicely.
248         if (j != i)
249         {
250                 k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
251
252                 while(k--)
253                         putchar(' ');
254
255                 printf("  ");
256
257                 while(j < i)
258                         visprt(start[j++]);
259
260                 putchar('\n');
261         }
262
263         return 0;
264 }
265
266
267 //
268 // Dump list of tokens on stdout in printable form
269 //
270 int dumptok(TOKEN * tk)
271 {
272         int flg = 0;
273
274         while (*tk != EOL)
275         {
276                 if (flg++)
277                         printf(" ");
278
279                 if (*tk >= 128)
280                 {
281                         printf("REG=%u", *tk++ - 128);
282                         continue;
283                 }
284
285                 switch ((int)*tk++)
286                 {
287                 case CONST:                                        // CONST <value>
288                         printf("CONST=%u", *tk++);
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 //
336 // Dump Everything
337 //
338 int dump_everything(void)
339 {
340         int i;
341
342         for(i=1; i<NSECTS; i++)
343         {
344                 if (sect[i].scattr & SUSED)
345                 {
346                         printf("Section %d sloc=$%X\n", i, sect[i].sloc);
347                         printf("Code:\n");
348                         chdump(sect[i].sfcode, 1);
349
350                         printf("Fixup:\n");
351                         fudump(sect[i].sffix);
352
353                         printf("\n");
354                 }
355         }
356
357         printf("\nMarks:\n");
358         mudump();                                                               // Dump marks
359 //      printf("Total memory allocated=$%X\n", amemtot);
360
361         return 0;
362 }