/****************************************************************/ /* */ /* DDT-68K (tm) */ /* */ /* Copyright 1982, Digital Research */ /* */ /****************************************************************/ #include "ddtinc.h" #include "stdio.h" #include "bdosfunc.h" #include "disas.h" char *copyrt="CP/M-68K(tm), Version 1.1, Copyright (c) 1983, Digital Research"; char *serial = "XXXX-0000-654321"; main(bpptr) struct basepage *bpptr; { char combuf[BUFLEN]; char *cx; char *dispaddr; /* current display address */ char *listaddr; /* current disassembly addr*/ struct cpustate state; /* state of user program registers */ struct value curvals; /* values relating to current file or pgm */ register int i; /* workhorse integer */ /* phony machine state initialization */ for (i=0; i<8; i++) {state.dreg[i]=0L; state.areg[i]=0L;} state.pc = 0x0; state.usp = 0x00001000L; state.areg[7]=state.usp; state.ssp = GETSSP(); state.status = 0x0000; dispaddr = 0; listaddr = 0; curvals.kind = 0; /* no current file or program */ init(bpptr, &state, &curvals, &dispaddr, &listaddr, &bpptr); while ( 1 ) { while ( ! (cx = readcom(combuf)) ); switch ( *cx ) { /* one case for each possible command */ case 'D' : display(cx, &dispaddr); break; case 'E' : ecmd(cx, bpptr, &state, &curvals, &dispaddr, &listaddr, &bpptr); break; case 'F' : fillmem(cx); break; case 'G' : gocmd(cx, &state); break; case 'H' : hexmath(cx); break; case 'I' : incomtl(cx, &curvals); break; case 'L' : disasm(cx, &listaddr); break; case 'M' : movemem(cx); break; case 'R' : readfl(cx, bpptr, &curvals, &dispaddr); break; case 'S' : setmem(cx); break; case 'T' : trace(cx, &state, &listaddr, (int)1); break; case 'U' : trace(cx, &state, &listaddr, (int)0); break; case 'V' : vcmd(cx, &curvals); break; case 'W' : wrtfile(cx, &curvals); break; case 'X' : examine(cx, &state); break; default : stout("Unknown Command\n\n"); break; }; /* end of switch on comx */ }; /* end of while loop */ } /* end of function main */ init(basep, statep, valuep, dap, lap, bppa) struct basepage *basep; struct cpustate *statep; struct value *valuep; char **dap; char **lap; long *bppa; { /* if program file argument, then load it */ /* set up trap vectors */ /* initialize tables */ stout("\nDDT-68K\nCopyright 1982, Digital Research\n\n"); if (basep->fcb1.fn[0] != ' ') loadpgm(&(basep->fcb1), basep, statep, valuep, dap, lap, bppa); } char *readcom(buf) /* read one command line, return command type */ register char *buf; { register char *cx; register short int i,nc; do { stout("\r\r-"); /* prompt */ *buf = BUFLEN-3; BDOS(READBUF, buf); /* get command line */ putchar('\n'); } while ( ( nc=buf[1]) == 0 ); buf[2+nc] = 0; for ( cx = &buf[2]; *cx; *cx=toupper(*cx), cx++); for ( cx= &buf[2], i=0 ; iswhite(*cx) && (imemb); break; case 2 : puthexw(i->memw); break; case 4 : puthexl(i->meml); break; } /* end of switch */ putchar(' '); c += (2*format+1); } /* end of loop across line */ while ( c++ < 60 ) putchar(' '); for ( i=s, j=min(s+15,f); i<=j ; i++ ) putbyte(*i); putchar('\n'); } /* end of loop through lines */ *dap = f + format; } /* end display */ ecmd(cx, basep, statep, valuep, dap, lap, bppa) char *cx; struct basepage *basep; struct cpustate *statep; struct value *valuep; char **dap; char **lap; long *bppa; { /* Load the program named in the command */ struct fcb pgmfcb; deblank(&cx); if (parse(&cx, &pgmfcb, "68K") && nomore(cx)) loadpgm ( &pgmfcb, basep, statep, valuep, dap, lap, bppa); else bad(); } loadpgm(fcbp, basep, statep, valuep, dap, lap, bppa) struct fcb *fcbp; struct basepage *basep; struct cpustate *statep; struct value *valuep; char **dap; char **lap; long *bppa; { /* load a program for execution */ struct lpb pgmlpb; int loaderr; struct basepage *newbp; long *stkptr; int i; /* open program file */ while(1) { if ( (BDOS(OPEN, fcbp) & 0xffL) == 0x0FFL ) { if(fcbp->t[0] != ' ') { /* open failed */ stout("Cannot open program file\n"); return; } else { fcbp->t[0] = '6'; fcbp->t[1] = '8'; fcbp->t[2] = 'K'; } } else break; } /* set up lpb */ pgmlpb.fcbaddr = fcbp; pgmlpb.tpabase = basep->lowtpa; pgmlpb.tpatop = basep; pgmlpb.flags = 0; /* now do program load */ loaderr = (int)(BDOS(PGMLOAD, &pgmlpb) & 0x0FFFFL); switch ( loaderr ) { case 0: { /* successful */ newbp = pgmlpb.bpaddr; valuep->kind = 1; valuep->textbase = newbp->csstart; valuep->textlen = newbp->cslen; valuep->database = newbp->dsstart; valuep->datalen = newbp->dslen; valuep->bssbase = newbp->bsstart; valuep->bsslen = newbp->bslen; valuep->bpa = newbp; valuep->initstk = pgmlpb.stkinit; statep->pc = newbp->csstart; stkptr = pgmlpb.stkinit; (*--stkptr) = newbp; (*--stkptr) = *--bppa; statep->usp = stkptr; statep->areg[7]= stkptr; statep->status = 0; *dap = newbp->csstart; *lap = newbp->csstart; newbp->fcb1.dr = 0; newbp->fcb2.dr = 0; for ( i = 0; i < 11; ++i) { newbp->fcb1.fn[i] = ' '; newbp->fcb2.fn[i] = ' '; } newbp->fcb1.cr = 0; newbp->fcb2.cr = 0; newbp->fcb1.ex = 0; newbp->fcb2.ex = 0; } break; /* end case 0 -- success */ case 1: { stout("Insufficient memory or bad file header\n"); return; } break; case 2: { stout("Read error\n"); return; } break; case 3: { stout("Bad relocation bits\n"); return; } break; default: { stout("Unknown program load error\n"); return; } break; } /* end switch */ showvals(valuep); } /* end loadpgm */ fillmem(cx) char *cx; { /* fill memory with constant */ register short int format; /* 1=byte, 2=word, 4=long word */ char *s; /* start address */ char *f; /* end address */ long v; /* value to stuff into memory */ /* parse command and extract parameters */ format = getform(&cx); if ( gethex(&cx, &s) ); /* get start address */ else {bad(); return(0);} /* not there, error */ if ( (format != 1) && (s & 1) ) /* must be even address, error */ {bad(); return(0);} if ( GETSEP && gethex(&cx, &f) ); /* get end address */ else { bad(); return(0); } /* not there, error */ if ( GETSEP && gethex(&cx, &v) ); /* get value to stuff */ else { bad(); return(0); } if ( ! nomore(cx) ) {bad(); return;} /* rest of line must be empty */ if ((s>f) || /* test for junk or nonsense */ ( (format == 1) && ((v > 255L) || (v < 0)) ) || ( (format == 2) && ((v > 65535L) || (v < 0)) ) ) { bad(); return(0); } /* now do the stuffing */ for ( ; (s+format) <= (f+1); s += format ) { switch ( format ) { case 1 : s->memb = (char)v; if ((s->memb ^ (char)v) & 0xFF) badram(s); break; case 2 : s->memw = (short int)v ; if ((s->memw ^ (short int)v) & 0xFFFF) badram(s); break; case 4 : s->meml = (long)v ; if ( s->meml != v ) badram(s); break; } /* end of switch */ } /* end of for */ } /* end of fillmem */ /**/