/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd and Vincent Hayward.	    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <stdio.h>

extern short _regSave[8];

int (*onexitFxn)();
int onexitArg;

onexit (fxn, arg)
int (*fxn)();
int arg;
{
	/* tells the system to execute the specified function (with the given
	   argument whenever the program exits (because of a panic or because
	   it completes) */

	int s;
	s = spl7();
	if (onexitFxn = fxn)
	 { onexitArg = arg;
	 }
	splx(s);
}

panic(code)
int code;
{
	/* Called by the kernel whenever a panic condition arises. A panic
	   condition with generally arise because of a hardware exception
	   detected by the LSII, such as bad memory reference, power failure,
	   etc. panic() is called from the exception handling mechanism
	   located in locore.c.

	   The routine checks to see if the program has an 'onexit' function
	   set up (which is done using the onexit() call), and if so calls 
	   this function. It then prints a dump of registers (which
	   were saved by the system before panic was called) and then halts
	   the CPU.
	 */	 

	int i;

	clkast(0);
	timeout(0);

	if (onexitFxn)
	 { int (*fxn)() = onexitFxn;
	   onexitFxn = 0;
	   (*fxn)(onexitArg);
	 }
	putchar ('\n');
	printf ("PANIC -- code = %d  \n", code);
	printf ("Register dump: \n");
	putchar ('\n');
	for (i=0; i<6; i++)
	 { printf (" r%1d:  %06o  %04x  \n", i, _regSave[i], _regSave[i]);
	 }
	printf (" sp:  %06o  %04x  \n", _regSave[6], _regSave[6]);
	printf (" pc:  %06o  %04x  \n", _regSave[7], _regSave[7]); 
	halt();
}

zexit (code)
{
	/* Basic exit routine. Called either when the main program returns,
	   or when some severe failure is detected in software (as opposed
	   to panic(), which handles hardware detected failures).

	   The routine checks to see if the program has an 'onexit' function
	   set up (which is done using the onexit() call), and if so calls 
	   this function. It then prints the exit code it was called with
	   and halts the CPU.	  */

	clkast(0);
	timeout(0);

	if (onexitFxn)
	 { int (*fxn)() = onexitFxn;
	   onexitFxn = 0;
	   (*fxn)(onexitArg);
	 }
	putchar ('\n');
	printf ("exit 0x%x\n", code);
	halt ();
}
	
