/*
 * System Control Block (SCB)
 */

/* This is an INTERIM solution, sufficient to allow clock interrupts! */

	.set	SCBB,0x11	/* System Control Block Base Register */
	.set	IPL,0x12	/* Interrupt Priority Level Register */
	.set	ICCS,0x18	/* Interval Clock Control/Status Register */

	.set	ISTK,1		/* use the interrupt stack */
	.set	HALT,3		/* halt if this happens */

#define	PUSHALL	pushr	$0x7fff	/* push all regs except PC */
#define	POPALL	popr	$0x7fff	/*  pop all regs except PC */

#define	STRAYVV(off)	.long	_Xstray_/**/off+ISTK
#define	STRAY	.long _Xstray+ISTK
#define	STRAY8	STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY
#define	STRAY15	STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY8
#define	KS(a)	.long	_X/**/a+ISTK	/* TEMP */
#define	IS(a)	.long	_X/**/a+ISTK
#define	STOP(a)	.long	_X/**/a+HALT

#define SCBVECTOR(name)		.align 2; .globl _X/**/name; _X/**/name
#define SCBVECTOR2(name,off)	.align 2; .globl _X/**/name; _X/**/name:\
		nop;nop; \
		pushl r0;pushl r1; \
		pushl r0;pushl r1; \
		pushl	$/**/off;jmp common

#define STVEC(offset)	.align 2; \
		.globl _Xstray_/**/offset; _Xstray_/**/offset: \
		nop;nop; \
		pushl r0;pushl r1; \
		pushl	r0;pushl	r1; \
		pushl	$/**/offset;jmp	common


	.set	ISTK,1	/* handle this interrupt on the interrupt stack */
	.set	HALT,3	/* halt if this interrupt occurs */

	.data
	.globl	SCB_scb
.align 2
SCB_scb:

/* 000 */	STRAYVV(0x0);	IS(machcheck);	IS(kspnotval);	STOP(powfail);
/* 010 */	KS(privinflt);	KS(xfcflt);	KS(resopflt);	KS(resadflt);
/* 020 */	KS(protflt);	KS(transflt);	KS(tracep);	KS(bptflt);
/* 030 */	KS(compatflt);	KS(arithtrap);	STRAYVV(0x38);	STRAYVV(0x3c);
/* 040 */	KS(chmktrap);	KS(chmetrap);	KS(chmstrap);	KS(chmutrap);
/* 050 */	STRAYVV(0x50);	IS(cmrd);	STRAYVV(0x58);	STRAYVV(0x5c);
/* 060 */	IS(wtime);	STRAYVV(0x64);	STRAYVV(0x68);	STRAYVV(0x6c);
/* 070 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 080 */	STRAY;		STRAY;		KS(astflt);	STRAY;
/* 090 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0a0 */	IS(softclock);	STRAY;		STRAY;		STRAY;
/* 0b0 */	IS(netintr);	STRAY;		STRAY;		STRAY;
/* 0c0 */	IS(interval);	STRAY;		STRAY;		STRAY;
/* 0d0 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0e0 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0f0 */	IS(consdin);	IS(consdout);	IS(cnrint);	IS(cnxint);
/* 100 */	IS(nexzvec); STRAY15;		/* ipl 0x14, nexus 0-15 */
/* 140 */	IS(nexzvec); STRAY15;		/* ipl 0x15, nexus 0-15 */
/* 180 */	IS(nexzvec); STRAY15;		/* ipl 0x16, nexus 0-15 */
/* 1c0 */	IS(nexzvec); STRAY15;		/* ipl 0x17, nexus 0-15 */


#ifdef NOTYET
/* 000 */	STRAY;		IS(machcheck);	IS(kspnotval);	STOP(powfail);
/* 010 */	KS(privinflt);	KS(xfcflt);	KS(resopflt);	KS(resadflt);
/* 020 */	KS(protflt);	KS(transflt);	KS(tracep);	KS(bptflt);
/* 030 */	KS(compatflt);	KS(arithtrap);	STRAY;		STRAY;
/* 040 */	KS(chmktrap);	KS(chmetrap);	KS(chmstrap);	KS(chmutrap);
/* 050 */	STRAY;		IS(cmrd);	STRAY;		STRAY;
/* 060 */	IS(wtime);	STRAY;		STRAY;		STRAY;
/* 070 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 080 */	STRAY;		STRAY;		KS(astflt);	STRAY;
/* 090 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0a0 */	IS(softclock);	STRAY;		STRAY;		STRAY;
/* 0b0 */	IS(netintr);	STRAY;		STRAY;		STRAY;
/* 0c0 */	IS(interval);	STRAY;		STRAY;		STRAY;
/* 0d0 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0e0 */	STRAY;		STRAY;		STRAY;		STRAY;
/* 0f0 */	IS(consdin);	IS(consdout);	IS(cnrint);	IS(cnxint);
/* 100 */	IS(nexzvec); STRAY15;		/* ipl 0x14, nexus 0-15 */
/* 140 */	IS(nexzvec); STRAY15;		/* ipl 0x15, nexus 0-15 */
/* 180 */	IS(nexzvec); STRAY15;		/* ipl 0x16, nexus 0-15 */
/* 1c0 */	IS(nexzvec); STRAY15;		/* ipl 0x17, nexus 0-15 */
#endif /* NOTYEt */



	.text
/* The actual interrupt handlers: */

STVEC(0x0);STVEC(0x38);STVEC(0x3c);STVEC(0x50);
STVEC(0x58);STVEC(0x5c);STVEC(0x64);STVEC(0x68);
STVEC(0x6c);



SCBVECTOR2(machcheck,0x1)		/* Machine Check */
SCBVECTOR2(kspnotval,0x08)	/* Kernel Stack Pointer Not Valid */
SCBVECTOR2(powfail,0x0c)	/* Power Failure */
SCBVECTOR2(privinflt,0x10)		/* Privileged Instruction Fault */
SCBVECTOR2(xfcflt,0x014)		/* Extended Function Code Fault */
SCBVECTOR2(resopflt,0x18)		/* Reserved Operand Fault */
SCBVECTOR2(resadflt,0x1c)		/* Reserved Addressing Mode Fault? */
SCBVECTOR2(protflt,0x20)		/* Protection Fault (Access Mode Violation) */
SCBVECTOR2(transflt,0x24)		/* Address Translation Fault */
SCBVECTOR2(tracep,0x28)		/* Trace Point Fault?? */
SCBVECTOR2(bptflt,0x2c)		/* Breakpoint Fault */
SCBVECTOR2(compatflt,0x30)		/* Compatability Mode Fault */
SCBVECTOR2(arithtrap,0x34)		/* Arithmetic Exception Trap */
SCBVECTOR2(chmktrap,0x40)		/* Change Mode To Kernel */
SCBVECTOR2(chmetrap,0x44)		/* Change Mode to Executive */
SCBVECTOR2(chmstrap,0x48)		/* Change Mode to Supervisor */
SCBVECTOR2(chmutrap,0x4c)		/* Change Mode to User */
SCBVECTOR2(cmrd,0x54)		/* Corrected Memory Read Data */
SCBVECTOR2(wtime,0x60)		/* Memory Write Timeout */
SCBVECTOR2(astflt,0x88)		/* Asynchronous System Trap Fault */
SCBVECTOR2(softclock,0xa0)		/* Software Level 8 - software clock? */
SCBVECTOR2(netintr,0xb0)		/* Software Level 0xC - Network?? */

SCBVECTOR2(consdin,0xf0)		/* Console Device Interrupt */
SCBVECTOR2(consdout,0xf4)		/* Console Device Interrupt */
SCBVECTOR2(cnrint,0xf8)		/* Console Receiver Interrupt */
SCBVECTOR2(cnxint,0xfc)		/* Console Transmitter Interrupt */


SCBVECTOR(nexzvec):		/* Nexus Vector */
SCBVECTOR(stray):		/* Stray Interrupts - Default Handler */
	PUSHALL
	pushl	$0
     	calls	$1, _dummyHandler
	POPALL
	rei	/* a default handler */


SCBVECTOR(interval):		/* Interval Timer - IPL=0x18, 0 params */
	rei
	PUSHALL
	mtpr  $0x800000c1,$ICCS
	calls $0,_dummyHandler
	POPALL
	rei

	.globl common
common:	nop;nop;		/* entry mask for adb */
/* at this point:
		PSL	:(SP)+24 \_ saved by HW (restored by REI below)
		PC	:(SP)+20 /
		r0	:(SP)+16 \_ saved for the running program
		r1	:(SP)+12 /	(restored below)
		r0	:(SP)+8	\
		r1	:(SP)+4	 +-	the arguments to the handler
		offset	:(SP)	/	(cleaned off stack by handler' s RET)
*/
	.globl INTTTT
INTTTT:	halt
	pushl	24(sp);pushl	24(sp)	/* push pc,psl */
	calls	$3, _dummyHandler
	movl	(sp)+,r1	/* restore r1,r0 */
	movl	(sp)+,r0
	rei
      


/* END OF HANDLERS */

/* Entry point to PROCEDURE _initSCB */

	.globl _initSCB
_initSCB:
	.word 0
	mtpr	$0x1f,$IPL	/* go to highest IPL before changing SCBB */
	mtpr	$SCB_scb,$SCBB
	mfpr	$SCBB,r0	/* set up return value */
	mtpr	$0,$IPL /* LOWER IT AGAIN */
	ret
