mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
Upload
Digital Research
This commit is contained in:
530
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/ddt/ddtutil.c
Normal file
530
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/ddt/ddtutil.c
Normal file
@@ -0,0 +1,530 @@
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* DDT-68K (tm) Utility Procedures */
|
||||
/* */
|
||||
/* Copyright 1982, Digital Research */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
#include "ddtinc.h"
|
||||
#include "stdio.h"
|
||||
#include "bdosfunc.h"
|
||||
#include "disas.h"
|
||||
|
||||
|
||||
putchar(x)
|
||||
register char x;
|
||||
{
|
||||
BDOS(CONOUT, (long)x);
|
||||
if (x == '\n') BDOS(CONOUT, (long)'\r');
|
||||
}
|
||||
|
||||
|
||||
int stout(s) /* write a string */
|
||||
register char *s;
|
||||
{
|
||||
register int nc;
|
||||
|
||||
nc = 0;
|
||||
while ( *s ) { putchar( *s++ ); nc++; }
|
||||
return(nc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int gethex ( cpp, np ) /* get longest possible hex number from string */
|
||||
char **cpp; /* +*cpp, and store it in *np. return # of digits */
|
||||
long *np;
|
||||
{
|
||||
register char *cp;
|
||||
register long n;
|
||||
register short int nd;
|
||||
|
||||
for ( n=0, nd=0, cp = *cpp;
|
||||
ishex(*++cp);
|
||||
nd++, n=(n<<4)+hexval(*cp) );
|
||||
|
||||
*cpp = --cp;
|
||||
*np = n;
|
||||
return(nd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int ishex ( c )
|
||||
register char c;
|
||||
{
|
||||
return ( ( ('0'<=c) && (c<='9') ) || ( ('A'<=c) && (c<='F') ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int hexval ( c )
|
||||
register char c;
|
||||
{
|
||||
if ( ('0'<=c) && (c<='9') ) return ( c-'0');
|
||||
else return ( 10 + c - 'A' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
char hexchar(n)
|
||||
register char n;
|
||||
{
|
||||
return ( n<10 ? '0'+n : 'A'+n-10 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int puthex(n, i, zs)
|
||||
register long n;
|
||||
register int i;
|
||||
register int zs;
|
||||
{
|
||||
register char d;
|
||||
|
||||
while ( i >= 4 )
|
||||
{
|
||||
i -= 4;
|
||||
d = hexchar( (char)((n>>i) & 0xf) );
|
||||
if ( d != '0' ) zs = 0;
|
||||
if ( (! zs) || (! i) ) putchar(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int puthexl(n) /* write a long integer in hex */
|
||||
long n;
|
||||
{
|
||||
puthex(n, 32, 0);
|
||||
}
|
||||
|
||||
|
||||
int puthexw(n) /* write an integer in hex */
|
||||
short int n;
|
||||
{
|
||||
puthex((long)n, 16, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
puthexb(n) /* write a byte in hex */
|
||||
char n;
|
||||
{
|
||||
puthex((long)n, 8, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int putbyte(c) /* write an ascii byte. if not printable, write '.' */
|
||||
register char c;
|
||||
{
|
||||
char d[2];
|
||||
|
||||
d[1] = 0;
|
||||
d[0] = ( ( (c < 0x20) || (c > 0x7E) ) ? '.' : c );
|
||||
stout(d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bad()
|
||||
{
|
||||
stout("?\n");
|
||||
}
|
||||
|
||||
badram(a)
|
||||
long a;
|
||||
{
|
||||
stout("Bad or non-existent RAM at ");
|
||||
puthexl(a);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
nomore(cx)
|
||||
char *cx;
|
||||
{
|
||||
++cx;
|
||||
while (*cx)
|
||||
{
|
||||
if (*cx != ' ') return(0);
|
||||
else ++cx;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
getsep(cxp)
|
||||
register char **cxp;
|
||||
{
|
||||
register char *cx;
|
||||
|
||||
cx = (*cxp) + 1;
|
||||
if ((*cx != ' ') && (*cx != ',')) return(0);
|
||||
while ( *cx == ' ' ) ++cx;
|
||||
if ( ! *cx ) return(0);
|
||||
if ( *cx != ',' ) {*cxp = --cx; return(1);}
|
||||
++cx;
|
||||
while ( *cx == ' ' ) ++cx;
|
||||
*cxp = --cx;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
deblank(cxp)
|
||||
register char **cxp;
|
||||
{
|
||||
++*cxp;
|
||||
while ( **cxp == ' ' ) ++*cxp;
|
||||
--*cxp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
short int getform(cxp)
|
||||
register char **cxp;
|
||||
{
|
||||
register char *cx;
|
||||
register short int format;
|
||||
|
||||
cx = *cxp;
|
||||
|
||||
if ( *++cx == 'W' ) format = 2;
|
||||
else if ( *cx == 'L' ) format = 4;
|
||||
else { format = 1; cx--; }
|
||||
|
||||
*cxp = cx;
|
||||
|
||||
deblank(cxp);
|
||||
|
||||
return(format);
|
||||
}
|
||||
|
||||
|
||||
|
||||
parse(cxp, fcbp, dtp)
|
||||
register char **cxp;
|
||||
struct fcb *fcbp;
|
||||
char *dtp;
|
||||
{
|
||||
/* parse a filename into an fcb */
|
||||
|
||||
register char *cx;
|
||||
register char c;
|
||||
register int n;
|
||||
|
||||
fcbp->ex = 0;
|
||||
fcbp->cr = 0;
|
||||
|
||||
cx = *cxp;
|
||||
c = *++cx;
|
||||
|
||||
if ( ! (isalpha(c) || isdigit(c) || iswild(c))) return(0);
|
||||
if ( *(cx+1) == ':' ) {fcbp->dr = c - 'A' + 1; cx += 2; }
|
||||
else fcbp->dr = 0;
|
||||
|
||||
n = 0;
|
||||
c = *cx;
|
||||
while (isalpha(c) || isdigit(c) || iswild(c)) {
|
||||
if ( n >= 8 ) return(0);
|
||||
if(c == '*')
|
||||
{
|
||||
while(n < 8)
|
||||
fcbp->fn[n++] = '?';
|
||||
c = *++cx;
|
||||
break;
|
||||
}
|
||||
fcbp->fn[n++] = c;
|
||||
c = *++cx;
|
||||
}
|
||||
|
||||
while ( n < 8 ) fcbp->fn[n++] = ' ';
|
||||
|
||||
for (n = 0; n < 3; ++n) {
|
||||
if (*dtp) fcbp->t[n] = *dtp++;
|
||||
else fcbp->t[n] = ' ';
|
||||
}
|
||||
|
||||
if (*cx != '.') {*cxp = --cx; return(1);}
|
||||
|
||||
n = 0;
|
||||
c = *++cx;
|
||||
while ( isalpha(c) || isdigit(c) || iswild(c)) {
|
||||
if ( n >= 3 ) return(0);
|
||||
if(c == '*')
|
||||
{
|
||||
while(n < 3)
|
||||
fcbp->t[n++] = '?';
|
||||
c = *++cx;
|
||||
break;
|
||||
}
|
||||
fcbp->t[n] = c;
|
||||
++n;
|
||||
c = *++cx;
|
||||
}
|
||||
|
||||
while ( n < 3 ) fcbp->t[n++] = ' ';
|
||||
|
||||
*cxp = --cx;
|
||||
return(1);
|
||||
|
||||
} /* end of parse fcb */
|
||||
|
||||
|
||||
|
||||
int keyhit()
|
||||
{
|
||||
if ( BDOS(CONSTAT, 0L) & 0xFFFFL ) {
|
||||
BDOS(CONIN, 0L);
|
||||
return(1);
|
||||
}
|
||||
else return(0);
|
||||
}
|
||||
|
||||
|
||||
showvals(vp)
|
||||
register struct value *vp;
|
||||
{
|
||||
register int i, j;
|
||||
register long * lp;
|
||||
|
||||
switch ( vp->kind )
|
||||
{
|
||||
case 0: stout("\nERROR, no program or file loaded.\n");
|
||||
break;
|
||||
|
||||
case 1: /* do program vals */
|
||||
for ( i = 0; i < 2; ++i )
|
||||
{
|
||||
lp = &(vp->textbase);
|
||||
lp += i;
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
switch ( j )
|
||||
{
|
||||
case 0: stout("text "); break;
|
||||
case 1: stout("data "); break;
|
||||
case 2: stout("bss "); break;
|
||||
}
|
||||
switch ( i )
|
||||
{
|
||||
case 0: stout(" base "); break;
|
||||
case 1: stout(" length"); break;
|
||||
}
|
||||
stout(" = ");
|
||||
puthexl(*lp);
|
||||
lp += 2;
|
||||
stout(" ");
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
stout("base page address = ");
|
||||
puthexl(vp->bpa);
|
||||
stout(" initial stack pointer = ");
|
||||
puthexl(vp->initstk);
|
||||
break; /* end of program values */
|
||||
|
||||
case 2: /* do file values */
|
||||
stout("Start = ");
|
||||
puthexl(vp->textbase);
|
||||
stout(" End = ");
|
||||
puthexl((vp->textbase)+(vp->textlen)-1L);
|
||||
break;
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
|
||||
} /* end of showvals */
|
||||
|
||||
/**/
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* Examine/Alter CPU Registers */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
examine(cx, statep)
|
||||
char *cx;
|
||||
struct cpustate *statep;
|
||||
{
|
||||
if (nomore(cx)) showstate(statep);
|
||||
else if (*++cx == 'D') pdareg('D', cx, statep->dreg);
|
||||
else if (*cx == 'A') pdareg('A', cx, statep->areg);
|
||||
else if (cmp("PC",--cx)) pregl("PC", &(statep->pc));
|
||||
else if (cmp("USP",cx)) { if (pregl("USP",&(statep->usp)) &&
|
||||
((statep->status & SUPER) == 0 ))
|
||||
statep->areg[7] = statep->usp;
|
||||
}
|
||||
else if (cmp("SSP",cx)) { if (pregl("SSP",&(statep->ssp)) &&
|
||||
(statep->status & SUPER) )
|
||||
statep->areg[7] = statep->ssp;
|
||||
}
|
||||
else if (cmp("ST", cx)) { pregw("ST",&(statep->status) );
|
||||
if ( statep->status & SUPER) statep->areg[7] = statep->ssp;
|
||||
else statep->areg[7] = statep->usp;
|
||||
}
|
||||
else bad();
|
||||
|
||||
if ( statep->status & SUPER) statep->ssp = statep->areg[7];
|
||||
else statep->usp = statep->areg[7];
|
||||
}
|
||||
|
||||
|
||||
|
||||
showstate(statep)
|
||||
register struct cpustate *statep;
|
||||
{
|
||||
register short int status;
|
||||
|
||||
stout("PC="); puthexl(statep->pc); putchar(' ');
|
||||
stout("USP="); puthexl(statep->usp); putchar(' ');
|
||||
stout("SSP="); puthexl(statep->ssp); putchar(' ');
|
||||
stout("ST="); puthexw(status = statep->status);
|
||||
stout("=>");
|
||||
if (status & TRACE) stout("TR ");
|
||||
if (status & SUPER) stout("SUP ");
|
||||
stout("IM="); putchar(((status & INTMSK)>>8)+'0');
|
||||
if (status & EXTEND) stout(" EXT");
|
||||
if (status & NEG) stout(" NEG");
|
||||
if (status & ZERO) stout(" ZER");
|
||||
if (status & OFLOW) stout(" OFL");
|
||||
if (status & CARRY) stout(" CRY");
|
||||
putchar('\n');
|
||||
preglrow('D', statep->dreg); /* D registers */
|
||||
preglrow('A', statep->areg); /* A registers */
|
||||
dot = statep -> pc;
|
||||
pinstr(); /* disassembled instruction */
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
|
||||
pdareg(da, cx, rp) /* print data or address register contents */
|
||||
char da;
|
||||
register char *cx;
|
||||
long *rp;
|
||||
{
|
||||
|
||||
char str[3];
|
||||
|
||||
if ( ('0' <= *++cx) && (*cx <= '7') && nomore(cx) ) {
|
||||
str[0] = da;
|
||||
str[1] = *cx;
|
||||
str[2] = 0;
|
||||
pregl(str, rp + *cx - '0');
|
||||
}
|
||||
else bad();
|
||||
}
|
||||
|
||||
|
||||
pregl(rname, regp) /* print register contents as long */
|
||||
char *rname;
|
||||
long *regp;
|
||||
{
|
||||
return( preg(rname, regp, 4) );
|
||||
}
|
||||
|
||||
pregw(rname, regp) /* print register contents as word */
|
||||
char *rname;
|
||||
long *regp;
|
||||
{
|
||||
return( preg(rname, regp, 2) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
preg(rname, regp, size) /* print register contents */
|
||||
register char *rname;
|
||||
register long *regp;
|
||||
register int size;
|
||||
{
|
||||
char buf[BUFLEN];
|
||||
register short int nc;
|
||||
long int newval;
|
||||
char *bp;
|
||||
register int modify;
|
||||
|
||||
modify = 0;
|
||||
stout(rname);
|
||||
putchar('=');
|
||||
switch(size)
|
||||
{
|
||||
case 1 : puthexb(regp->memb);
|
||||
break;
|
||||
case 2 : puthexw(regp->memw);
|
||||
break;
|
||||
case 4 : puthexl(regp->meml);
|
||||
break;
|
||||
}
|
||||
putchar(' ');
|
||||
*buf = BUFLEN-2;
|
||||
BDOS(READBUF, buf);
|
||||
putchar('\n');
|
||||
if ((nc=buf[1])>0) {
|
||||
buf[nc+2]=0;
|
||||
bp = buf + 1;
|
||||
while (*++bp) *bp = toupper(*bp);
|
||||
bp = buf + 1;
|
||||
if (gethex(&bp, &newval) && nomore(bp)) {
|
||||
switch(size)
|
||||
{
|
||||
case 1 : regp->memb = (char)(newval & 0xffL);
|
||||
break;
|
||||
case 2 : regp->memw = (int)(newval & 0xffffL);
|
||||
break;
|
||||
case 4 : regp->meml = newval;
|
||||
break;
|
||||
}
|
||||
modify = 1;
|
||||
}
|
||||
else if ( ! nomore(buf+1) ) bad();
|
||||
}
|
||||
return(modify);
|
||||
}
|
||||
|
||||
|
||||
|
||||
preglrow(ch, rowp)
|
||||
char ch;
|
||||
long *rowp;
|
||||
{
|
||||
register int n;
|
||||
|
||||
putchar(ch);
|
||||
putchar(' ');
|
||||
for (n=0; n<8; n++) {
|
||||
putchar(' ');
|
||||
puthexl(*rowp++);
|
||||
if (n==3) putchar(' ');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
tryflags(cx, statep)
|
||||
register char *cx;
|
||||
register struct cpustate *statep;
|
||||
{
|
||||
bad();
|
||||
}
|
||||
|
||||
|
||||
cmp(str, ctl)
|
||||
register char *str;
|
||||
register char *ctl;
|
||||
{
|
||||
while (*str && (*str++ == *++ctl)) ;
|
||||
if ( ( ! *str) && nomore(ctl) ) return(1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
|
||||
/****************/
|
||||
|
||||
Reference in New Issue
Block a user