/* rammonitor.c -- main routine for dispatching of monitor commands
 * copyright (c) 1984  American Information Systems Corporation
 *  Dock Williams
 *  October, 1984
 *
 */

#define DEFINITIONS
#include "monitor.h"

#include "3200config.h"



rammonitor (envptr)
    INTSTACK *envptr;		/* pointer to saved environment on stack */
/*
 * rammonitor (envptr) -- main routine for monitor
 *	return:	(int)		cflags
 *
 * check all incoming status
 * return quietly in the correct cases
 * otherwise, enter debugging mode and
 * wait for commands
 * 9/4/83	dgw	created
 */
{
    register struct initsym *p;		/* pointer to initsym */
    register int i;			/* temporary counter */
    char	input[MAXINP];		/* input character buffer */
    char cmd;				/* current monitor command */
    int arg0;				/* converted argument values */

    env = envptr;			/* make environment ptr global */
    savpsr = (short*) (&env->psr);	/* point to saved psr */

    if ((env->id == MON_INIT) || (initflag == 0)) {	/* startup init */

 	/* clear counts and flags */
	ibuf = (char *)0;
	acontext = 0;
	curaddr = 0;
	cflags = 0;
	stepcnt = 0;
	procnt = 0 ;
	curbase = 'x';
	cursize = 4;

	clrbrk(0,'*');			/* clear breakpoint table */
	init_sym();			/* clear symbol table */

#ifdef AUTOP
	for(i=0;i<MAXINP;i++)		/* clear autoprint buffer */
	    autobuf[i] = '\0';
	autoptr = autobuf;		/* initialize autoprint pointer */
#endif

#ifdef MODTAB
	lastmod = (unsigned)ZERORAMEND;	/* size of mod table for disasm */
	asym("lastmod", &os_loadbase, S_HIDE|S_PHYS);
#endif


	/* add default defined symbols */
	asym("_etext", &etext, S_HIDE|S_PHYS);
	asym("_edata", &edata, S_HIDE|S_PHYS);
	asym("icu", INTCTLR, S_HIDE|S_PHYS);
	asym("rtc", TODCLK, S_HIDE|S_PHYS);
	asym("rom", ROMSTART, S_HIDE|S_PHYS);
	asym("bitmap", membitmap, S_HIDE|S_PHYS);
	asym("reset", reset_addr, S_HIDE|S_PHYS);

	initflag = -1;		/* initialization done but no copyright */

	if (env->id == MON_INIT)	/* if init only */
	    return;			/* return from initialization */
    } /*if-MON_INIT*/

    if (env->id >= 0) brkinit();	/* take out all breakpoints */
    if (initflag <= 0) {	/* Monitor initialized, but no copyright yet */
	initflag = 1;			/* do this exactly once */
	prdname(0);			/* print startup message */
    }

    switch (env->id) {
    case 0: printf("nvi"); break;
    case 1: 
	if(cflags & CF_MMUBRK) {
	    if(env->msr & MSR_ERC2) printf("mmu-brk ");
	} else printf("nmi"); break;
    case 2: printf("abt"); break;
    case 3: printf("fpu"); break;
    case 4: printf("ill"); break;
    case 5: printf("svc"); break;
    case 6: printf("dvz"); break;
    case 7: printf("flg"); break;

    case 8: 
	if ( procnt && visbrkset(env->pc) ) {
#ifdef DEBUG1
	    printf(" procnt=%x\n",procnt);
#endif
	    clrbrk(env->pc,'t');	/* clear brkpnt temporarily */
	    svbrka = (char *)env->pc;	/* save breakpoint address */
	    cflags |= (CF_BRKPRO | CF_BRKREP);	/* signify we are proceeding */
	    procnt--;			/* proceed and replace breakpnt */

	    /* if we are proceeding we can't be single stepping */
	    /* so its ok to write stepcnt */
	    stepcnt = 1;		/* step past breakpoint */
	    env->psr |= PSR_T;		/* set trace bit in psr */
	    return;			/* now 'step around' the breakpoint */
	}
	if(stepcnt > 1) printf("stepcnt=%x   ",stepcnt);
	if(tempbrk == env->pc) {
	    clrbrk(env->pc,'s');
	}
	printf("bpt");
	break;

    case 9:				 /* single step entry id */
	stepcnt--;
	if(cflags & CF_BRKREP) {
		vsetbrk(svbrka);		/* we have replaced the brk */
		cflags &= ~CF_BRKREP;	/* check if we should proceed */
		if(cflags & CF_BRKPRO) {
		    env->psr &= ~PSR_T;	/* reset the trace bit in the psr */
		    return;		/* since we have stepped through */
		}			/* the breakpoint now */
	}
	if(stepcnt > 0) {
#ifdef DEBUG1
	    printf("stepcnt=%x\n",stepcnt);
#endif
	    env->psr |= PSR_T;		/* set the trace bit in the psr */
	    return;
	}
	printf("trc");
	break;

    case 10: printf("und"); break;

    case 11: printf("(reserved)"); break;

    case MON_START:		/* direct startup */
	break;

    default:
	if ( (env->id < 16) || (env->id > 31) )
	    printf("RAM-Monitor entry: %x\n", env->id);
	else
	    printf("bad int vector: %d.\n", (env->id - 16));
	break;
    }

    if (env->id >= 0) {
	printf(": %6x   ",env->pc);
	vdisasm(env->pc, &arg0, 1);	/* display instruction */
	OUTCHR('\n');
    }

#ifdef DEBUG1
    printf("Adding stack symbols:\n");
#endif

    asym("r0",&env->r0, S_HIDE|S_SHIDE|S_PHYS);
    asym("r1",&env->r1, S_HIDE|S_SHIDE|S_PHYS);
    asym("r2",&env->r2, S_HIDE|S_SHIDE|S_PHYS);
    asym("r3",&env->r3, S_HIDE|S_SHIDE|S_PHYS);
    asym("r4",&env->r4, S_HIDE|S_SHIDE|S_PHYS);
    asym("r5",&env->r5, S_HIDE|S_SHIDE|S_PHYS);
    asym("r6",&env->r6, S_HIDE|S_SHIDE|S_PHYS);
    asym("r7",&env->r7, S_HIDE|S_SHIDE|S_PHYS);
    asym("sb",&env->sb, S_HIDE|S_SHIDE|S_PHYS);
    asym("intbase",&env->intbase, S_HIDE|S_SHIDE|S_PHYS);
    asym("sp1",&env->sp1, S_HIDE|S_SHIDE|S_PHYS);
    asym("sp0",&env->sp0, S_HIDE|S_SHIDE|S_PHYS);
    asym("sp",&env->sp0, S_HIDE|S_SHIDE|S_PHYS);
    asym("fp",&env->fp, S_HIDE|S_SHIDE|S_PHYS);
    asym("psr",&env->psr, S_HIDE|S_SHIDE|S_PHYS);
    asym("ps",&env->psr, S_HIDE|S_SHIDE|S_PHYS);
    asym("mod",&env->mod, S_HIDE|S_SHIDE|S_PHYS);
    asym("pc",&env->pc, S_HIDE|S_SHIDE|S_PHYS);
    asym("id",&env->id, S_HIDE|S_PHYS);

    for(;;){
	cflags &= ~CF_ESCHIT;

#ifdef DEBUG_MONITOR /******** DEBUG_MONITOR ***************************/
	if(recursive) OUTCHR('D');
#endif /********************** DEBUG_MONITOR ***************************/

	printf("M> ");			/* print prompt */

	cmd = getinput(input,MAXINP,0);	/* get input from console */

	if ( cmdproc( cmd, input ) )	/* execute a monitor command */
		return;			/* go execute a program */

    }
}



exec_init()
{
    brkexec();

#ifdef AUTOP
    if (cflags & CF_AUTOP) autoptr = autobuf;
#endif

}
