8c2a8d96201c3eac08f0cf733313d3d034180690
[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 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 #include "debug.h"
9 #include "sect.h"
10 #include "amode.h"
11 #include "mark.h"
12
13 static int siztab[4] = {3, 5, 9, 9};
14
15 //
16 // --- Print 'c' Visibly ---------------------------------------------------------------------------
17 //
18
19 int visprt(char c) {
20    if(c < 0x20 || c >= 0x7f)
21       putchar('.');
22    else
23       putchar(c);
24
25    return(0);
26 }
27
28 //
29 // --- Print expression, return ptr to just past the ENDEXPR ---------------------------------------
30 //
31
32 TOKEN *printexpr(TOKEN *tp) {
33    if(tp != NULL)
34       while(*tp != ENDEXPR)
35          switch((int)*tp++) {
36             case SYMBOL:
37                printf("`%s' ", ((SYM *)*tp)->sname);
38                ++tp;
39                break;
40             case CONST:
41                printf("$%lx ", *tp++);
42                break;
43             case ACONST:
44                printf("ACONST=($%lx,$%lx) ", *tp, tp[1]);
45                tp += 2;
46                break;
47             default:
48                printf("%c ", (char)tp[-1]);
49                break;
50          }
51    printf(";\n");
52    return(tp + 1);
53 }
54
55 //
56 // --- Dump data in a chunk (and maybe others) in the appropriate format ---------------------------
57 //
58
59 int chdump(CHUNK *ch, int format) {
60    while(ch != NULL) {
61       printf("chloc=$%08lx, chsize=$%lx\n", ch->chloc, ch->ch_size);
62       mdump(ch->chptr, ch->ch_size, format, ch->chloc);
63       ch = ch->chnext;
64    }
65
66    return(0);
67 }
68
69 //
70 // --- Dump fixup records in printable format ------------------------------------------------------
71 //
72
73 int fudump(CHUNK *ch) {
74    PTR p;
75    char *ep;
76    WORD attr, esiz;
77    WORD line, file;
78    LONG loc;
79
80    for(; ch != NULL;) {
81       p.cp = ch->chptr;
82       ep = ch->chptr + ch->ch_size;
83       while(p.cp < ep) {
84          attr = *p.wp++;
85          loc = *p.lp++;
86          file = *p.wp++;
87          line = *p.wp++;
88
89          printf("$%04x $%08lx %d.%d: ", (int)attr, loc, (int)file, (int)line);
90
91          if(attr & FU_EXPR) {
92             esiz = *p.wp++;
93             printf("(%d long) ", (int)esiz);
94             p.tk = printexpr(p.tk);
95          } else {
96             printf("`%s' ;\n", (*p.sy)->sname);
97             ++p.lp;
98          }
99       }
100       ch = ch->chnext;
101    }
102
103    return(0);
104 }
105
106 //
107 // --- Dump marks ----------------------------------------------------------------------------------
108 //
109
110 int mudump(void) {
111    MCHUNK *mch;
112    PTR p;
113    WORD from;
114    WORD w;
115    LONG loc;
116    SYM *symbol;
117
118    from = 0;
119    for(mch = firstmch; mch != NULL; mch = mch->mcnext) {
120       printf("mch=$%08lx mcptr=$%08lx mcalloc=$%lx mcused=$%x\n",
121              mch,
122              mch->mcptr,
123              mch->mcalloc,
124              mch->mcused);
125
126       p = mch->mcptr;
127       for(;;) {
128          w = *p.wp++;
129          if(w & MCHEND)
130             break;
131
132          symbol = NULL;
133          loc = *p.lp++;
134
135          if(w & MCHFROM)
136             from = *p.wp++;
137
138          if(w & MSYMBOL)
139             symbol = *p.sy++;
140
141          printf("m=$%04x to=%d loc=$%lx from=%d siz=%s",
142                  w, w & 0x00ff, loc, from, (w & MLONG) ? "long" : "word");
143
144          if(symbol != NULL)
145             printf(" sym=`%s'", symbol->sname);
146          printf("\n");
147       }
148    }
149
150    return(0);
151 }
152
153 //
154 // -------------------------------------------------------------------------------------------------
155 // Dump memory from 'start' for 'count' bytes; `flg' is the following ORed together:
156 // 0 - bytes
157 // 1 - words
158 // 2 - longwords
159 // 
160 // if `base' is not -1, then print it at the start of each line, incremented accordingly.
161 // -------------------------------------------------------------------------------------------------
162 //
163
164 int mdump(char *start, LONG count, int flg, LONG base) {
165    int i, j, k;
166
167    j = 0;
168    for(i = 0; i < (int)count;) {
169       if((i & 15) == 0) {
170          if(j < i) {
171             printf("  ");
172             while(j < i)
173                visprt(start[j++]);
174             putchar('\n');
175          }
176          j = i;
177          if(base != -1)
178             printf("%08lx  ", base);
179       }
180
181       switch(flg & 3) {
182          case 0:
183             printf("%02x ", start[i] & 0xff);
184             ++i;
185             break;
186          case 1:
187             printf("%02x%02x ", start[i] & 0xff, start[i+1] & 0xff);
188             i += 2;
189             break;
190          case 2:
191             printf("%02x%02x%02x%02x ", start[i] & 0xff, start[i+1] & 0xff,
192                    start[i+2] & 0xff, start[i+3] & 0xff);
193             i += 4;
194             break;
195          case 3:
196             break;
197       }
198
199       if(base != -1)
200          base += 1 << (flg & 3);
201    }
202
203    // Print remaining bit of ascii; the hairy expression computes the number of
204    // spaces to print to make the ascii line up nicely.
205    if(j != i) {
206       k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
207       while(k--)
208          putchar(' ');
209       printf("  ");
210       while(j < i)
211          visprt(start[j++]);
212       putchar('\n');
213    }
214
215    return(0);
216 }
217
218 //
219 // --- Dump list of tokens on stdout in printable form ---------------------------------------------
220 //
221
222 int dumptok(TOKEN *tk) {
223    int flg = 0;
224
225    while(*tk != EOL) {
226       if(flg++)
227          printf(" ");
228
229       if(*tk >= 128) {
230          printf("REG=%ld", *tk++ - 128);
231          continue;
232       }
233
234       switch((int)*tk++) {
235          case CONST:                                        // CONST <value>
236             printf("CONST=%ld", *tk++);
237             break;
238          case STRING:                                       // STRING <address>
239             printf("STRING='%s'", *tk++);
240             break;
241          case SYMBOL:                                       // SYMBOL <address> 
242             printf("SYMBOL='%s'", *tk++);
243             break;
244          case EOL:                                          // End of line 
245             printf("EOL");
246             break;
247          case TKEOF:                                        // End of file (or macro)
248             printf("TKEOF");
249             break;
250          case DEQUALS:                                      // == 
251             printf("DEQUALS");
252             break;
253          case DCOLON:                                       // :: 
254             printf("DCOLON");
255             break;
256          case GE:                                           // >= 
257             printf("GE");
258             break;
259          case LE:                                           // <= 
260             printf("LE");
261             break;
262          case NE:                                           // <> or != 
263             printf("NE");
264             break;
265          case SHR:                                          // >> 
266             printf("SHR");
267             break;
268          case SHL:                                          // << 
269             printf("SHL");
270             break;
271          default:
272             printf("%c", tk[-1]);
273             break;
274       }
275    }
276    printf("\n");
277
278    return(0);
279 }
280
281 //
282 // --- Dump Everything -----------------------------------------------------------------------------
283 //
284
285 int dump_everything(void) {
286    int i;
287
288    for(i = 1; i < NSECTS; ++i)
289       if(sect[i].scattr & SUSED) {
290          printf("Section %d sloc=$%lx\n", i, sect[i].sloc);
291          printf("Code:\n");
292          chdump(sect[i].sfcode, 1);
293
294          printf("Fixup:\n");
295          fudump(sect[i].sffix);
296
297          printf("\n");
298       }
299
300    printf("\nMarks:\n");
301    mudump();                                                // Dump marks
302    printf("Total memory allocated=$%lx\n", amemtot);
303
304    return(0);
305 }