#include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ help() { printf("debugger commands are:\n"); printf(" b[reak] [fn] [sn [count]]\n"); printf(" clear all breakpoints\n"); printf(" , d[ump] p[rint] contents of memory\n"); printf(" g[o]\n"); printf(" l[ist]\n"); printf(" l[ist] a[rgs]\n"); printf(" l[ist] b[reaks]\n"); printf(" l[ist] g[lobals]\n"); printf(" l[ist] l[ocals]\n"); printf(" l[ist] m[ap]\n"); printf(" l[ist] t[raceback]\n"); printf(" quit exit to CP/M\n"); printf(" r[eset] [fn] [sn] a breakpoint\n"); printf(" run start execution, debugger off\n"); printf(" s[et] var val [c] a variable\n"); printf(" t[race] [num] execute num statements, displaying sn's\n"); printf(" u[ntrace] [num] execute num statements, silently\n"); } printasn(n) unsigned n; { /* print a statement number. If 4 high order bits are on, then * use decimal format (low order 12 bits . high order 4). */ if (n==0xffff) printf("-1"); else { printf("%d",n&0x0fff); if (n&0xf000) printf(".%d",n>>12); } } listbreaks () { int i; for (i=0; ifntname); printasn(breaktab[i].bsn); if (breaktab[i].bcount!=1) printf(" (%d)\n",breaktab[i].bcount); else putchar('\n'); } } listit(l) char *l; { /* process a list command */ char subcmd[10], *garbage; get_token(&l, subcmd, garbage); switch (tolower(*subcmd)) { case 0: printf("current location: %s ",curfnt->fntname); printasn(cursn); putchar('\n'); break; case 'a': if (curfnt->fntst!=NIL) printargs(); else if (curargs == NIL) printf("can't list args to %s because it has called a function\n", curfnt->fntname); else { printf("first argument address is %04x\n",curargs); printf("[1] = %04x = %d, [2] = %04x = %d, [3] = %04x = %d\n", *curargs, *curargs, *(curargs+1), *(curargs+1), *(curargs+2), *(curargs+2) ); printf("[4] = %04x = %d, [5] = %04x = %d, [6] = %04x = %d\n", *(curargs+3), *(curargs+3), *(curargs+4), *(curargs+4), *(curargs+5), *(curargs+5) ); } break; case 'g': printlg(globalp); break; case 'l': if (curfnt->fntst!=NIL) printlg(curfnt->fntst); else printf("local symbols not available\n"); break; case 'm': map(); break; case 't': trace(); break; case 'b': listbreaks(); break; default: printf("illegal list subcommand\n"); } } trace () { int i; for (i=1; ifntname); printasn(tracetab[i].tsn); printf(" called\n"); } else printf("%s called\n", addr2fnt(tracetab[i].taddr)->fntname); printf("%s\n",curfnt->fntname ); } compare(s, pat) char *s, *pat; { while (*pat && tolower(*s++) == tolower(*pat)) pat++; return !*pat; } breakargs(l, fnt, sn) char **l; struct fntentry **fnt; unsigned *sn; { /* Process arguments to break and reset commands. Determines * function (and sets fnt) and statement number (sets sn). * l is pointer to pointer to input line * * syntax: * [function name] [line[.statement within line]] * if function name is ommitted, current function assumed. * if line ommitted, zero (i.e., function entry) assumed. */ char name[10], class; int high; if (0 == (class = get_token(l, name, sn))) { printf("arguments missing\n"); return ERROR; } else if (class==INTEGER) *fnt = curfnt; else { if (ERROR == (*fnt = name2fnt(name))) { printf("%s does not exist\n",name); return ERROR; } if (INTEGER != get_token(l, name, sn)) *sn = 0; } if ('.' == **l) { (*l)++; if (INTEGER != get_token(l, name, &high)) { printf("invalid statement number %d.%s\n",*sn,name); return ERROR; } *sn |= high<<12; } } setbreak(l) char *l; { unsigned sn, count; struct fntentry *fnt; char name[20]; if (ERROR!=breakargs(&l,&fnt,&sn)) { if (INTEGER != get_token(&l, name, &count)) count = 1; insertbreak(fnt,sn,count); } } resetbreak(l) char *l; { unsigned sn; struct fntentry *fnt; if (ERROR!=breakargs(&l,&fnt,&sn)) deletebreak(fnt,sn); } map() { /* print a load module map of the target program. */ struct fntentry *q; int i; for (i = 0, q = fntab-1; (q-1) > fntabend; q--, i++) { if (!(i&3)) putchar('\n'); printf("%-8s %04x ", q->fntname, q->fntaddr); } putchar('\n'); } command() { /* get and process commands. */ char *l, line[128], cmd[10]; int garbage; walkcount = trace_display = 0; while (1) { cancel_char = 0; putchar('>'); l = gets(line); get_token(&l, cmd, &garbage); switch (tolower(*cmd)) { case 'b': setbreak(l); break; case 'c': if (compare(cmd,"clear")) clearbreaks(); else goto wrong; break; case 'l': listit(l); break; case 'q': if (compare(cmd,"quit")) exit(); else goto wrong; break; case 'r': if (!compare(cmd,"run")) { resetbreak(l); break; } movmem("\341\043\043\351",8*RST_NUM,4); /* POP H INX H x2 PCHL */ zapbreaks(); /* fall through */ case 'g': return; break; case 't': trace_display = 1; /* fall through */ case 'w': case 'u': if (INTEGER!=get_token(&l, cmd, &walkcount)) walkcount = 1; return; break; case 's': set(l); break; case '?': case 'h': help(); break; case ',': case 'd': case 'p': print(l); break; #ifdef DEBUG case 'z': debug = !debug; printf("debug %s\n", debug ? "on" : "off"); break; #endif wrong: default: printf("illegal command\n"); } } }