#

include(`emuniv.h')

/*
 *       SCCS File Type - Emulator Source File
 *
 *       What identification string
 */
static char *_S_K34     "@(#)EM_K34.c	3.3";
	/****************************************************************
	 *
	 *      K_set_pil
	 */

/*      K_set_pil (
 *          1   new_pil   : pseudo_int_levels : int (* to change to   *)
 *          2  &old_pil   : pseudo_int_levels : int (* record old lev *)
 *                )
 */

translate(K_set_pil, Ksetpil)

# ifdef EMULATOR
int     Kpilcnt  = 0,   /* Total number of K_set_pil calls made               */
	Kgpilcnt = 0;   /* Number of "good" calls (really changing the level) */

extern t_FProcTab_index ownPindex;
extern Fstruct          F;
# endif

K_set_pil (Pnew_pil, Pold_pilP)
	pseudo_int_levels       Pnew_pil,
				*Pold_pilP;
{
	K_err_num                       ex;
	register pseudo_int_levels      opil;

	struct          /* Ksetpil_param  */
	{       pseudo_int_levels       n_pil;  /* const */
		pseudo_int_levels       vo_pil; /* var   */
	} pb;

	pb.n_pil = Pnew_pil;

#       ifdef EMULATOR
	/*
	 * Change the level we have recorded:
	 * (done here to avoid timing window)
	 */
	opil                     = F.P[ownPindex].P_cur_pil;
	F.P[ownPindex].P_cur_pil = Pnew_pil;

	/*
	 * Soon: we will want to avoid the kernel call unless it actually
	 * changes the level.  Note that a P_cur_pil value of -1 indicates
	 * that we are not currently sure of our level, implying that we
	 * should make the call regardless.  (This caters to the great
	 * difficulty we have in determining our level immediately after
	 * returning from an interrupt.)
	 */
#       endif

	ex = EMT34 (&pb);

#       ifdef EMULATOR
	/* Update statistics for this kernel call: */
	Kpilcnt++;
	if (Pnew_pil != pb.vo_pil)
	{       Kgpilcnt++;
		debug15 ( ":> %d: %d->%d]\n"
			, F.P[ownPindex].P_pid
			, pb.vo_pil
			, Pnew_pil
			);
	}

	/* Verify that we had the old level recorded properly: */
	if (opil != pb.vo_pil)
	{       warning ( "bad p.i. level recorded; thought %d, was %d"
			, opil
			, pb.vo_pil
			);
		/* Very temporary stuff follows... (spew out PIVs) */
		if (opil != -1)
			ECC_dump ();
	}
#       endif

	*Pold_pilP  = pb.vo_pil;

	return (ex);
}
