#ifndef XCPT_H
#define XCPT_H

#define MAX_NUM_XCPT			32
#define	XCPT_ERR_NOTHANDLED		0x80000000

typedef enum
{
	Int = 0, Mod = 1, TLBL = 2, TLBS = 3, AdEL = 4, AdES = 5,
	IBE = 6, DBE = 7, Syscall = 8, Bp = 9, RI = 10, CpU = 11,
	Ov = 12, TRAP = 13, VCEI = 14, FPE = 15, C2E = 16, Watch = 23, VCED = 31

} EXCEPTION_CODE;

typedef unsigned int reg_t;

typedef struct xcptcontext
{
	/* This is the exception context frame that is passed to the exception
	handlers. It gets filled in by the low-level exception handler in
	"machine.S". An assembler version of this structure can be found at the
	bottom of "machine.H".*/
	reg_t sr;					/* Status Register */
	reg_t cr;					/* Cause Register */
	reg_t epc;					/* PC at time of exception. */
	reg_t baddr;
	reg_t regs[32];				/* Copy of all general purpose registers */
	reg_t mdlo;					/* HI/LO registers (used for memory management) */
	reg_t mdhi;
	reg_t count;				/* Timer registers */
	reg_t compare;
	struct xcptcontext * prev;	/* To link exceptions. (unused for now) */
	unsigned xclass;			/* Priority class of this exception. (unused for now). */

} EXCEPTION_CONTEXT;

typedef int (*fp_xcpt_t)(struct xcptcontext * xcp);

#define PRINT_REG(tag_str, reg)			\
			sputs(tag_str);				\
			print_word(reg);			\
			sputs("   ");


#define PRINT_REG_CHG(tag_str, reg, chg_tag)			\
			sputs(tag_str);				\
			print_word(reg);			\
			sputs(chg_tag);				\
			sputs("  ");


// Public functions
void xcpt_register(int xcpt_num, fp_xcpt_t fp);

#endif // XCPT_H
