Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/ddt/ddt1.c
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

440 lines
11 KiB
C

/****************************************************************/
/* */
/* 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) && (i<nc) ; cx++ , i++ );
return( (i==nc) ? NULL : cx );
}
clean()
{
/* restore trap vectors */
}
display(cx, dap)
char *cx;
char **dap;
{
/* display memory in hex and ascii */
short int format; /* 1=byte, 2=word, 4=long word */
char *s; /* start address */
char *f; /* end address */
char *i; /* working variable */
char *j; /* ditto */
short int c; /* column number */
/* parse command and extract parameters */
format = getform(&cx);
if ( ! gethex(&cx, &s) ) { /* get start address */
if ( nomore(cx) ) s = *dap; /* or use default */
else { bad(); return(0); } /* junk on the line */
}
if ( (format != 1) && (s & 1) ) s += 1; /* force even */
if ( GETSEP ) {if ( ! gethex(&cx, &f) ) {bad(); return;} }
else f = s + (12*16-1); /* not there, use def */
if ( ! nomore(cx) ) {bad(); return;} /* rest of line must be empty */
/* now do the display */
f = f - format + 1; /* first byte of last chunk to print */
for ( ; s <= f ; s += 16 ) { /* one line per pass */
if ( keyhit() ) return;
puthexl(s); putchar(' '); putchar(' '); c = 10;
for ( i=s, j=min(s+15,f);
i <= j;
i += format ) {
switch ( format ) {
case 1 : puthexb(i->memb);
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 */
/**/