Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

614 lines
13 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************/
/* */
/* Usual filename: SID04.C */
/* Remarks: Third C module for SID68k */
/* Author: Timothy M. Benson */
/* Control: 9 MAY 83 13:59 (TMB) */
/* */
/************************************************/
#include "lgcdef.h"
#include "cputype.h"
#include "siddef.h"
#include "ddtinc.h"
#include "stdio.h"
#include "bdosfunc.h"
#include "disas.h"
/********************************************************************
* ISSPACE character
*
* Return TRUE if the character is a whitespace character
********************************************************************/
isspace(ch)
int ch;
{
return(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
}
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);
}
/************************************************/
/* Starting at byte after **cpp get longest */
/* possible hex number from string or evaluate */
/* longest possible symbol. */
/* Fill in *np with value found. Return # of */
/* digits if hex, 8 if symbol, or 0 if invalid. */
/* Leave **cpp pointing to next position after */
/* chars processed. */
/************************************************/
gethex(cpp,np)
char **cpp;
long *np;
{
/**temp** This function extensively modified for SID */
extern struct lmhedr *caput;
extern int omega;
extern int nomo;
union ambig BLOCK /* Machine dependent */
long all32;
int last16[2];
char last8[4];
UNBLOCK triad;
register char *cp;
U16 *d16; /* For '@' values */
U32 *d32; /* For '!' values */
char *deixis; /* For '=' values */
long n;
register int nd;
char px; /* . = @ ! */
register char qu;
px = *(*cpp + 1);
If px EQ '.' or px EQ '=' or px EQ '@' or px EQ '!' then BEGIN
cp = ++*cpp; /* Locate prefix */
++*cpp; /* Skip prefix */
while((qu = *++cp) and qu NE ' ' and qu NE ',' and qu NE '+'
and qu NE '-' and qu NE '/' and qu NE '*')
; /* Find char after supposed name */
If nd = 8 * (omega GE 0
and (1 EQ indica((int)(cp - *cpp),*cpp
,caput AT sump,'B',&n,&nomo))) then
If px NE '=' and px NE '.' and n AND 1L then nd = 0;
otherwise BLOCK
triad.all32 = 0;
switch (px) begin
case '.':
triad.all32 = n;
break;
case '=':
deixis = n;
triad.last8[3] = *deixis;
break;
case '@':
d16 = n;
triad.last16[1] = *d16;
break;
case '!':
d32 = n;
triad.all32 = *d32;
break;
end
n = triad.all32;
UNBLOCK
END
otherwise 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 (!isspace(*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 ( isspace(**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 (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;
}
#ifdef MC68010
else if (cmp("VBR",cx)) pregl("VBR", &(statep->vbr));
else if (cmp("SFC",cx)) pregn("SFC", &(statep->sfc));
else if (cmp("DFC",cx)) pregn("DFC", &(statep->dfc));
#endif
else if (*++cx == 'D') pdareg('D', cx, statep->dreg);
else if (*cx == 'A') pdareg('A', cx, statep->areg);
else bad();
if ( statep->status & SUPER) statep->ssp = statep->areg[7];
else statep->usp = statep->areg[7];
}
showstate(statep)
register struct cpustate *statep;
{
/**temp** Next several lines added recently */
extern int scope;
extern struct lmhedr *caput;
/**temp** End of added stuff */
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');
#ifdef MC68010
stout("VBR="); puthexl(statep->vbr); putchar(' ');
stout("SFC="); puthex(statep->sfc, 4, 0); putchar(' ');
stout("DFC="); puthex(statep->dfc, 4, 0); putchar('\n');
#endif
preglrow('D', statep->dreg); /* D registers */
preglrow('A', statep->areg); /* A registers */
dot = statep -> pc;
spell(statep AT pc,caput AT sump,scope,'m','h');
/* Label, if any */
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));
}
pregn(rname, regp)
char *rname;
long *regp;
{
return(preg(rname, regp, 0));
}
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 0 : puthex(regp->meml, 4, 0);
break;
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 0 : regp->meml = newval & 0xffL;
break;
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);
}
( ( ! *str) && nomore(ctl) ) return(1);
else return(0);
}