static char rcsid[] = "$Header: pcs.c,v 800.0 85/07/30 13:55:41 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

#
/****************************************************************************

	DEBUGGER - process control loop

****************************************************************************/
#include "defs.h"

MSG		NOBKPT;
MSG		SZBKPT;
MSG		EXBKPT;
MSG		NOPCS;
MSG		BADMOD;
MSG		BADSYN;
BKPTR		bkptr;
BKPTR		bkpthead;
INT		runpcs();
BKPTR		lbpt;
CHAR		*lp;
CHAR		*printptr;
CHAR		lastc;
REGLIST		reglist[];
L_INT		entrypt;
L_INT		expv;
L_INT		dot;
L_INT		dotinc;
INT		pid;
INT		adrflg;
L_INT		cntval;
L_INT		loopcnt;
INT		signum;

#define BSRINS	0x6100
#define JSRINS	0x4e80

subpcs(modif)
{
	INT		xarg[10];
	register INT		check, cnt = cntval;
	INT		execsig, runmode;
	STRING		comptr;
	register INT	stkptr;
	extern	char	*malloc();
	POS		inst;

	execsig = 0;
	loopcnt = cntval;

	switch(modif)
	{
	    /* delete breakpoint */
	    case 'd': case 'D':
		if (bkptr = scanbkpt(dot))
		{
			bkptr->flag = 0;
			return;
		}
		else error(NOBKPT);

	    /* set breakpoint */
	    case 'b': case 'B':
		if (bkptr = scanbkpt(dot)) bkptr->flag = 0;
		for (bkptr = bkpthead; bkptr; bkptr = bkptr->nxtbkpt)
			if (bkptr->flag == 0) break;
		if (bkptr == 0)
		{
			if ((bkptr = (BKPTR)malloc(sizeof *bkptr)) == NULL)
				error(SZBKPT);
			else
			{
				bkptr->nxtbkpt = bkpthead;
				bkpthead = bkptr;
			}	
		}
		bkptr->loc = dot;
		bkptr->initcnt = bkptr->count = cntval;
		bkptr->flag = BKPTSET;

		check = MAXCOM - 1; comptr = bkptr->comm; rdc(); lp--;
		do *comptr++ = readchar(); while (check-- && (lastc != EOR));
		*comptr = NULL; lp--;
		if (check) return; else error(EXBKPT);

	    /* exit */
	    case 'k' :case 'K':
		if (pid)
		{
			endpcs();
			return;
		}
		else error(NOPCS);

	    /* set program */
	    case 'e': case 'E':
		endpcs(); setup();
		return;
		break;

	    /* run program */
	    case 'r': case 'R':
#ifdef s32
		/*
		 * Since we are running the program locally we
		 * must make sure that usrtop is correct for our
		 * system, not the one that (may have) generated
		 * the core file.
		 */
		usrtop = mytop;
#endif s32
		endpcs();
		setup();
		runmode = CONTIN;
		break;

	    /* single step across subroutine */
	    case 'S':
		inst = get(dot, ISP);		/* fetch instruction */
		if( ( (inst & 0xFF00) == BSRINS) ||
		    ( (inst & 0xFFC0) == JSRINS) )
		{
			execsig = (expr(0) ? expv : signum);
			printins(0, ISP, inst); printptr -= charpos();
			dot += dotinc; subpcs('b'); dot -= dotinc;
			bkptr->flag = SINGLE;
			runmode = CONTIN;
			break;
		}

	    /* else, fall through to standard single step */

	    /* single step */
	    case 's':
		execsig = (expr(0) ? expv : signum);
		runmode = SINGLE;
		break;

	    /* execute subroutine */
	    case 'x': case 'X':
		if (!pid) error(NOPCS); cnt = 0; check = dot;
		while (expr(0) && (cnt < 10)) xarg[cnt++] = expv;
		if ((!cnt) || (cnt >= 10)) error(BADSYN);

		dot = entrypt;
		stkptr = getreg(pid, reglist[sp].roffs);
		subpcs('b');
			bkptr->flag = getreg(pid, reglist[pc].roffs);
			bkptr->count = check;
			bkptr->initcnt = stkptr;

		while (--cnt) ptrace(WDUSER, pid, --stkptr, xarg[cnt]);
		ptrace(WDUSER, pid, --stkptr, dot);
		putreg(pid, reglist[sp].roffs, stkptr);
		dot = xarg[0]; adrflg = TRUE;
		printf("\nexecuting subroutine:\n");
		bkptr->flag = SINGLE;
		runmode = CONTIN;
		break;

	    /* continue */
	    case 'c': case 'C': case 0:
		if( pid )
		{
		    execsig = (expr(0) ? expv : signum);
		    runmode = CONTIN;
		}
		else
		    error( NOPCS );
		break;

	    default: error(BADMOD);
	}

	if( ( loopcnt > 0 ) && runpcs( runmode, execsig ) )
	    printf("\nbreakpoint%16t");
	else
	    printf("\nstopped at%16t");

	printpc();
}

