#ifndef DDTCAT	/* don't reget headers if catting when all routines internal */
#include	<pdefs.h>
#include	<ptypes.h>
#include	"mdep.h"
#include	"ddt.h"

ext PCTYP ddtpc;
ext char d_crlf[];
#endif


/* Returns 0 if instruction at addr can be trace trap executed, otherwise
 * returns the number of bytes past the current pc to set the breakpoint at.
 */
intern unst	md_isxsi(dsp, addr)
reg	ddtst	*dsp;
	unsw	addr;
{
	byte	data;
	reg	unsw	naddr;
	intf	first_arg = 1;
	retcd	d_fetch();

	naddr = addr;
	if (d_fetch(dsp, A_INST, sizeof(byte), naddr++, &data) == ERR)
		ddtbug("no pc fetch");

	if (data == 0xfb) {
again:	    if (d_fetch(dsp, A_INST, sizeof(byte), naddr++, &data) == ERR)
	      ddtbug("no pc fetch");
	    switch(data >> 4) {	/* Switch on mode bits */
	    case 4:		/* Indexed */
		goto again;
		break;
	    case 10:		/* byte displacement */
	    case 11:		/* byte disp. deferred */
		naddr++;
		break;
	    case 12:		/* word disp. */
	    case 13:		/* word disp. deferred */
		naddr += 2;
		break;
	    case 14:		/* long disp. */
	    case 15:		/* long disp. deferred */
		naddr += 4;
		break;
	    }
	    if (first_arg) {
		first_arg = 0;
		goto again;
	    }
	    return naddr - addr;
	}
	else
	  return 0;
}

/* Prints a stack backtrace. */
md_pr_stack(dsp)
ddtst *dsp;
{
    unsw *FP, *AP, *PC;
    unsw nargs;
    unsw arg;

    PC = (unsw *)ddtpc;
    md_get_sym("ap", &AP);
    d_fetch(dsp, A_DATA, sizeof(unsw), AP, &AP);
    md_get_sym("fp", &FP);
    d_fetch(dsp, A_DATA, sizeof(unsw), FP, &FP);
    while (FP) {
	dsp->d_puts(d_crlf);
	d_fetch(dsp, A_DATA, sizeof(unsw), AP, &nargs);
	nargs &= 0xff;
	d_prloc(dsp, PC);
	dsp->d_putc('(');
	while (nargs--) {
	    d_fetch(dsp, A_DATA, sizeof(unsw), ++AP, &arg);
	    d_prloc(dsp, arg);
	    if (nargs) dsp->d_puts(", ");
	}
	dsp->d_putc(')');
	d_fetch(dsp, A_DATA, sizeof(unsw), FP + 2, &AP);
	d_fetch(dsp, A_DATA, sizeof(unsw), FP + 4, &PC);
	d_fetch(dsp, A_DATA, sizeof(unsw), FP + 3, &FP);
    }
    dsp->d_putc('\t');
}
