h14822
s 00083/00055/00294
d D 1.6 85/06/03 18:26:42 dock 6 5
c allow more than one temporary breakpoint 
c removed redundant options 
c move '+' '#' 'l' into a single 's' command with options
e
s 00034/00002/00315
d D 1.5 85/02/13 00:24:23 dock 5 4
c added stack tracing
e
s 00009/00002/00308
d D 1.4 84/11/30 22:20:22 dock 4 3
c added MMUBRK ifdef to turn on or off mmu-type breakpointing
e
s 00003/00000/00307
d D 1.3 84/11/12 22:26:30 dock 3 2
c fixed bug in '=' command
e
s 00003/00014/00304
d D 1.2 84/11/12 18:52:21 dock 2 1
c simplified 'g' command of monitor
e
s 00318/00000/00000
d D 1.1 84/11/09 05:38:21 dock 1 0
c date and time created 84/11/09 05:38:21 by dock
e
u
U
t
T
I 1

/*
I 6
 * %M%: version %I% of %H%
 *
E 6
 * cmdproc.c -- command processor for dispatching of monitor commands
 * copyright (c) 1984  American Information Systems Corporation
D 6
 *  Dock Williams
 *  October, 1984
E 6
I 6
 *  Dock Williams  October, 1984
E 6
 *
 */

#include "monitor.h"

#define TOCMD 0
#define TOEXEC 1

/*
 * cmdproc returns TOEXEC (1) for return to execution
 * and TOCMD (0) for get another command 
 */

cmdproc( cmd, input )
register char cmd;
register char *input;
{
	register int	argc;		/* argument count for command */
	register char	*cp;		/* character pointer */
	register int	i;		/* temporary counter */
	int	val;			/* value for a symbol */
	int arg0,arg1,arg2,arg3;	/* converted argument values */
	char	*argv[MAXARG];		/* argument vectors */


#ifdef AUTOP
D 6
	 /* if this is not an autoprint string call mkargv */
E 6
I 6
	 /* if this is not an autoprint string, call mkargv */
E 6
	 /* otherwise pass a raw string for autoprinting */
	if (*input != ';')  
#endif
	    argc = mkargv(input,argv);	/* count arguments */
					/* form vectors  */

	switch(cmd) {
I 6

E 6
	case '\0':			/* exceptional cases? */
	    break;
I 5

E 5
D 6
	case '#':			/* delete a symbol */
	    dsym(argv[0]);
	    break;
I 5

E 5
	case '+':			/* add a symbol */
	    if ( !conv(argv[1],&val) ) break;
	    asym(argv[0],val,0);	/* don't hide it */
	    break;
I 5

E 6
E 5
	case '$':			/* change open base */
	    switch (*argv[0]) {
I 6
		case 'b':
		case 'c':
E 6
		case 'd':
		case 'o':
D 6
		case 'x':
		case 'h':
		case 'c':
E 6
		case 'u':
I 6
		case 'x':
E 6
		    curbase = *argv[0];
		    break;
		default:
		    goto argcerr;
	    }
	    OUTCHR('\n');
	    break;
I 5

E 5
	case '/':			/* display and change double */
	case '\\':			/* display and change word */
	case '\`':			/* display and change byte */
	    setcursize(cmd);
	    open(argv);
	    break;
I 5

I 6
	case 024:			/* ^T, time of day routines */
	    switch (argv[0][0]) {
	    case 's':	setrtc(); break;
	    case 'l':	looptime(); break;
	    default:	printtod(); printf("\n"); break;
	    }
	    break;

E 6
E 5
	case '=':
		if (argc != 1) goto argcerr;
		else {
		    if( !conv(argv[0],&val) ) break;
I 3
		    i = mapping;		/* save current mapping */
		    mapping = PHYS;		/* val is always physical */
E 3
		    dprint(&val, curbase, cursize);
I 3
		    mapping = i;		/* restore mapping */
E 3
		    OUTCHR('\n');
		}
		break;
I 5

E 5
	case '?':			/* print command synopsis */
	    if (argc > 1) synop(argv);
	    else {
		argv[0][0]= '?';
		argv[0][1] = '\0';
		synop(argv);
	    }
	    break;
I 5

E 5
#ifdef AUTOP
	case 'a':
	    if (*input == ';') {	/* set autoprint string */
		for(i=1;(input[i] != ';') && (i<MAXINP);i++)
		    autobuf[i-1] = input[i];
		autobuf[i-1] = '\0';
		autoptr = &autobuf[i-1];
		cflags |= CF_AUTOP;
	    } else if (argc==1) {	/* print current autoprint string */
		for(i=0; autobuf[i] != '\0'; i++) prtsee(autobuf[i]);
		OUTCHR('\n');
	    } else if (argc==2) {
		if (*argv[0] == 'e') autoptr = autobuf;
	    } else goto argcerr;
	    break;
#endif
I 5

E 5
	case 'b':			/* breakpoints */
	    brkpnt(argc,argv);
	    break;
I 5

E 5
	case 'c':			/* compare blocks of memory */
	    if (argc != 4) goto argcerr;
	    if ( conv(argv[0],&arg0) &&
		 conv(argv[1],&arg1) &&
		 conv(argv[2],&arg2) ) compare(arg0,arg1,arg2);
	    break;
I 5

E 5
	case 'd':			/* display chunks */
	    if (argc != 3) goto argcerr;
	    if ( conv(argv[0],&arg0) &&
		 conv(argv[1],&arg1) ) display(arg0,arg1);
	    break;
I 5

E 5
	case 'e':			/* enable bits in cflags */
	    cp = argv[0];
	    while(*cp) {
		switch (*cp++) {
		case 'u': debug_user_state = '\001';break;
		case 'p': cflags |= CF_PHYS;break;
		case 's': cflags |= CF_SYMP;break;
		case 'h': cflags |= CF_PHIDE;break;
D 4
		case 'm': cflags |= CF_MMUBRK;break;
E 4
I 4

#ifdef MMUBRK
		case 'm': 
		    cflags |= CF_MMUBRK;
		    break;
#endif MMUBRK

E 4
#ifdef AUTOP
		case 'a': 
		    for(i=0;(i<MAXINP && autobuf[i] != '\0');i++);
		    autoptr = &autobuf[i];
		    cflags |= CF_AUTOP;
		    break;
D 4
#endif
E 4
I 4
#endif AUTOP

E 4
		case '-':
		    while(*cp) {
			switch (*cp++) {	
			case 'u': debug_user_state = '\0';break;
			case 'p': cflags &= ~CF_PHYS;break;
			case 's': cflags &= ~CF_SYMP;break;
			case 'h': cflags &= ~CF_PHIDE;break;
			case 't': cflags &= ~CF_TRACE;break;
#ifdef AUTOP
			case 'a': cflags &= ~CF_AUTOP; break;
#endif
			case 'm': cflags &= ~CF_MMUBRK;break;
			case '*': cflags = 0;break;
			}
		    }
		}
	    }
	    break;
I 5

E 5
	case 'g':			/* go */
	    if(argc == 1) {
#ifdef DEBUG1
		printf("current pc = %x",env->pc);
#endif
	    } else {
D 2
		if ( !conv(argv[0],&env->pc) ) break;
E 2
I 2
		if ( !conv(argv[0],&(env->pc)) ) break;
E 2
#ifdef DEBUG1
		printf("new pc = %x",env->pc);
#endif
	    }
D 2
	    env->psr &= ~(PSR_I | PSR_P);	/* reset pending trace & ints */
	    env->msr = 0;		/* disable mapping */
	    if(visbrkset(env->pc)) {	/* check for a breakpoint */
		svbrka = (char *)env->pc;	/* set at the current address */
		clrbrk(env->pc,'t');	/* step around it, if there */
	    	cflags |= (CF_BRKREP | CF_BRKPRO);  /* replace and proceed */
		env->psr |= PSR_T;
		stepcnt = 1;
	    } else env->psr &= ~PSR_T;
	    if (vmembyte(env->pc) == BRKCODE) env->pc++;
	    cflags &= ~CF_SSTEP;	/* reset single step flag */
	    stepcnt = procnt = 0;
	    return(TOEXEC);
E 2
I 2
	    jump_reset(env->pc);	/* take off and don't come back */

E 2
D 6
	case 'l':			/* list symbols */
	    if (argc != 2) goto argcerr;
	    else lsym(argv[0]);
	    break;
I 5

E 6
E 5
	case 'm':			/* move a block of memory */
	    if (argc != 4) goto argcerr;
	    if ( conv(argv[0],&arg0) &&
		 conv(argv[1],&arg1) &&
		 conv(argv[2],&arg2) ) move(arg0,arg1,arg2);
	    break;
I 5

E 5
	case 'i':			/* image loader */
	    dload();
	    break;
I 5

I 6

E 6
E 5
	case 'p':			/* proceed through breakpoints */
	    if(argc > 2) goto argcerr;
	    env->psr &= ~PSR_P;		/* reset trace trap pending */
D 6
	    if(visbrkset(env->pc)) {	/* check for a breakpoint */
E 6
I 6
	    if( visbrkset(env->pc, B_NORM) ) {	/* check for a breakpoint */
E 6
		svbrka = (char *)env->pc;	/* set at the current address */
D 6
		clrbrk(env->pc,'t');	/* step around it, if there */
E 6
I 6
		clrbrk(env->pc,B_REPL);		/* step around it, if there */
E 6
	    	cflags |= (CF_BRKREP | CF_BRKPRO);  /* replace and proceed */
		env->psr |= PSR_T;
		stepcnt = 1;
	    } else env->psr &= ~PSR_T;	
	    if (vmembyte(env->pc) == BRKCODE) env->pc++;
	    cflags &= ~CF_SSTEP;	/* reset single step flag */
	    if (argc == 1) {	
		procnt = 0;
		return(TOEXEC);
	    } else if (argc == 2) {
		if ( !conv(argv[0],&procnt) ) break;
		return(TOEXEC);	
	    } else goto argcerr;
I 5

I 6

E 6
E 5
	case 'x':
	    ramless_monitor();
	    break;
I 5

E 5
	case 'r':			/* print registers */
D 6
	    if(argc == 1) rcpu();
	    else if (argc == 2) 
		switch(*argv[0]) {
		case 'c':	rcpu(); break;
		case 'm':	rmmu(); break;
		case 'f':	rfpu(); break;
		default:	break;
		}
E 6
I 6
	    switch(*argv[0]) {
	    case 'a':	rcpu(); rmmu(); break;	/* both cpu and mmu registers */
	    case 'c':	rcpu(); break;		/* cpu registers */
	    case 'm':	rmmu(); break;		/* mmu registers */
	    case 'f':	rfpu(); break;		/* fpu registers */
	    default:	rcpu(); break;
	    }
E 6
	    break;
I 5

E 5
D 6
	case 's':
E 6
I 6

	case 's':			/* symbol manipulations */
	    if ( (argc<2) || (argc>4) ) goto argcerr;
	    switch(*argv[argc-2]) {
	    case 'a':			/* add a symbol */
		if ( !conv(argv[1],&val) ) break;
		asym(argv[0],val,0);	/* don't hide it */
		break;
	    case 'd':			/* delete a symbol */
		dsym(argv[0]);
		break;
	    case 'l':			/* list symbols */
		if (argc == 2)
			lsym("*");
		else
			lsym(argv[0]);
		break;
	    }
	    break;


E 6
	case ',':			/* single step */
	case '<':			/* step over calls */
I 6
	case '>':  /* step into calls but possible proceed to return address */
E 6
	    if(argc>2) goto argcerr;
	    cflags |= CF_SSTEP;		/* set single step flag */
D 6
	    if(visbrkset(env->pc)) {	/* check for a breakpoint */
		svbrka = (char *)env->pc;	/* set at the current address */
		clrbrk(env->pc,'t');	/* step around it, if there */
E 6
I 6
	    /* check for a breakpoint */
	    /* BUG: a temporary brkpnt is turned into a normal one here */
	    if( visbrkset(env->pc, B_NORM|B_TEMP) ) {
		svbrka = (char *)env->pc;  /* set at the current address */
		clrbrk(env->pc,B_REPL);	/* step around it, if there */
E 6
		cflags |= CF_BRKREP;	/* replace breakpoint */
		cflags &= ~CF_BRKPRO;	/* but dont proceed */
	    }

	    if (vmembyte(env->pc) == BRKCODE) env->pc++;

D 6
	    if (    (vmembyte(env->pc) == CXPCODE)
		 || (vmembyte(env->pc) == BSRCODE)
		 || ((vmembyte(env->pc) == JSRCODE)
		     && ((vmembyte((env->pc)+1) & 0x07) == JSR2CODE) )
	       && (cmd == '<') ) {
			vdisasm(env->pc, &val, 0);
			tempbrk = env->pc + val;
			printf("<.."); 
			if (visbrkset(env->pc)) {
				env->psr |= PSR_T;
				cflags |= CF_BRKPRO;
				stepcnt = 1;
			} 
			if (visbrkset(tempbrk)) {
				tempbrk = 0;
			} else 
				vsetbrk(tempbrk);
			env->psr &= ~(PSR_P|PSR_T);
			return(TOEXEC);
E 6
I 6
	    if ( ((cmd=='<')||(cmd=='>')) &&
	         (  (vmembyte(env->pc) == CXPCODE) ||
		    (vmembyte(env->pc) == BSRCODE) ||
		    ( (vmembyte(env->pc) == JSRCODE) &&
		      ((vmembyte((env->pc)+1) & 0x07) == JSR2CODE) )
		 )  ) {

			    val = vdisasm(env->pc, 0);
			    i = env->pc + val;

			    if (visbrkset(env->pc,B_NORM)) {
				    env->psr |= PSR_T;
				    if(cmd=='<') cflags |= CF_BRKPRO;
				    stepcnt = 1;
			    } 

			    if ( !visbrkset(i, B_NORM|B_TEMP) ) {
				    vsetbrk(i,"",B_TEMP);
			    }

			    if (cmd=='<')
				    env->psr &= ~(PSR_P|PSR_T);
			    else {
				    stepcnt = 1;
				    env->psr |= PSR_T;
			    }
			    return(TOEXEC);
E 6
	    } else {
		env->psr |= PSR_T;	/* set the trace bit in the psr */
D 6
		if(cmd == '<') printf("<.");
E 6
		if (argc == 1) {
		    stepcnt = 1;
		    return(TOEXEC);
		} else {
		    if ( !conv(argv[0], &stepcnt) ) break;
		    return(TOEXEC);
		} 
	    }
D 5
	case 'u':
E 5
I 5

I 6

E 6
#ifdef STRACE
	case 't':			/* do a stack trace */
	    if (argc != 1) {
		goto argcerr;
	    } else 
		tracestack(env->fp,env->pc);
	    break;
#endif STRACE

	case 'u':			/* unassemble instructions */
E 5
	    if( (argc < 2) || (argc > 3) ) goto argcerr;
	    if( !conv(argv[0],&arg0) ) goto argcerr;
	    arg1 = 2;			/* default count to unassemble */
	    if(argc == 3) {
		if( !conv(argv[1],&arg1) ) goto argcerr;
	    } 
	    for(i=0;i<arg1;i++) {
	    psym(arg0);
D 6
	    disasm(arg0,&arg2,1);
E 6
I 6
	    arg2 = disasm(arg0,1);
E 6
	    arg0 += arg2;
	    OUTCHR('\n');
	    if(quitchk()) break;
	    }
	    break;
I 5

E 5
	case 'f':		/* fill a block of memory with a constant */
	    if (argc != 4) goto argcerr;
	    if ( conv(argv[0],&arg0) &&
		 conv(argv[1],&arg1) &&
		 conv(argv[2],&arg2) ) fill(arg0,arg1,arg2);
	    break;
I 5

E 5
#ifdef MONJSR
	case 'j':
	    if(argc < 2) goto argcerr;
	    brkexec();			/* write breakpnts for execution */
	    if ( conv(argv[0],&arg0) ) {	/* must supply an address */
		conv(argv[1],&arg1);
		conv(argv[2],&arg2);
		conv(argv[3],&arg3);
	    	xcall(arg0,arg1,arg2,arg3);
	    }
	    break;
D 5
#endif
E 5
I 5
#endif MONJSR

E 5
	case 'z':		/* write a location of memory */
		if (argc != 4) goto argcerr;
		if ((conv(argv[0],&arg0)) &&
		    (conv(argv[1],&arg1))) {
			switch(*argv[2]) {
			case 'b': arg2 = 1; break;
			case 'w': arg2 = 2; break;
			case 'd': arg2 = 4; break;
			}
			zap(arg0,arg1,arg2);
		}
	    break;
I 5

E 5
	default:
	    printf("unknown cmd\n");
	    break;
	}

	return(TOCMD);

	argcerr:
	    printf("arg count?\n");
}
E 1
