{InterruptsDaybreak.mc

Daybreak specific portions of Refill.mc and Process.mc
parts copied from InterruptsDicentra.mc, HGM, 18-Dec-83 9:12:35
Trow	 9-Nov-87 20:55:16 Fix RescheduleInt for Cedar.
Trow	 5-Nov-87  0:25:00 Fix IdleInt for Cedar.
Trow	28-Oct-87 22:16:24 Fix RefillInt for Cedar.
Last Revised by JPM, 14-Nov-86 13:03:17, Store uIdleCountHigh at IdleInt
Last Revised by JPM, 11-Jul-86 9:46:03, Hard-wire address of RefillInt
Last Revised by JPM, 1-Aug-85 10:35:30, Bug fix in block interrupt
Last Revised by JPM, 3-Jul-85 13:32:15, Opie redesign conversion
Last Revised by JPM, 8-May-85 9:43:26, do software locking
Last Revised by JPM, 16-Oct-84 17:29:19, fix branch masks at IntDisp
Last Revised by JPM, 9-Oct-84 10:18:26, mask timer bit from IOP bits (because Daisy uCode needs timing from the IOP and Daybreak doesn't)
Last Revised by JPM, 3-Oct-84 11:31:34, made RefillInt and BlockInt more efficient
Last Revised by JPM, 1-Oct-84 8:45:59, changed cycle for ClrLOCK
Last Revised by JPM, 28-Sep-84 9:17:04, simplified interrupt processing}

{ 	Copyright (C) 1984, 1985, 1986, 1987 by Xerox Corporation.  All rights reserved.}


Set[rhInt.Refill,	0];
Set[rhInt.Block,	1];
Set[rhInt.Idle,		2];
Set[rhInt.LP,		3];
Set[rhInt.Scan,		4];
Set[rhInt.Reschedule,	5];
Set[rhInt.Enqueue,	6];

Set[L3.Interrupt,	1];

{Buffer refill got a MesaIntTrap}
RefillInt:
	rInt ← rInt or IntStat, ClrIntErr,					c1, at[addrRefillInt];
	Noop,									c2;
	Noop,									c3;

	rhInt ← rhInt.Refill, Ybus ← rInt, YDisp, GOTO[IntDisp],		c1;


{BLT, CHKSUM, ... or BITBLT noticed an interrupt}
{remove till reconciled with Cedar code
BlockInt:
	rInt ← rInt or IntStat, ClrIntErr,					c3, at[restore.int,10,RestoreCallers];

	rhInt ← rhInt.Block, Ybus ← rInt, YDisp, GOTO[IntDisp],			c1;}


{Idle loop noticed a MesaInt}
IdleInt:
	CANCELBR[$,1],								c2;
	rInt ← rInt or IntStat, ClrIntErr,					c3;

	rhInt ← rhInt.Idle, Ybus ← rInt, YDisp, GOTO[IntDisp],			c1;


{LoadProcess noticed a MesaInt}
LoadProcessInt:
	rhInt ← rhInt.LP, GOTO[CheckInterrupts],				c2;


{Process timeout Scan noticed an interrupt}
ScanInt:
	rhInt ← rhInt.Scan, CANCELBR[CheckInterrupts,1],			c2;


{Reschedule noticed an interrupt}
RescheduleInt:
	rhInt ← rhInt.Reschedule, CANCELBR[$,3],				c1;
	GOTO[CheckInterrupts],							c2;


{Enqueue noticed an interrupt}
EnqueueInt:
	rhInt ← rhInt.Enqueue,							c2;
	rInt ← rInt or IntStat, ClrIntErr,					c3;

	T ← rhT, Ybus ← rInt, YDisp, GOTO[IntDisp],				c1;


CheckInterrupts:
	rInt ← rInt or IntStat, ClrIntErr,					c3;

{rInt holds interrupt reason(s): bits 13 for MesaInt, 14 for IOP interrupt, 15 for timer
new flags from IOP are at fixed location (rhIOP, rIOP + 1)
Bit 0 of uWP is reserved for Process timeouts: u8000 holds that bit}

	Ybus ← rInt, YDisp,							c1;
IntDisp:
	Q ← uWP, DISP4[IntReasons,0C],						c2;

	GOTO[IntReturns], 				{neither IOP nor timer}	c3, at[0C,10,IntReasons];
	Q ← Q or u8000, GOTO[IntReturns], 		{timer only}		c3, at[0D,10,IntReasons];
	GOTO[ReadAndClearIOPBits], 			{IOP only}		c3, at[0E,10,IntReasons];
	Q ← Q or u8000, GOTO[ReadAndClearIOPBits],	{both IOP and timer}	c3, at[0F,10,IntReasons];


ReadAndClearIOPBits:
	TT ← uMesaProc,								c1;
	rhTT ← uIORgnHigh,							c2;
	uTemp ← TOS, L4 ← SoftwareLockRets.Interrupt,				c3;

	MAR ← [rhTT, TT + notifiersLockMask],					c1;
	TT ← TT + upNotifyBits, CANCELBR[$,0],					c2;
	TOS ← MD, uT ← T,							c3;

	MAR ← [rhIORgn, rIORgn + iopRequestsLock],				c1;
	T ← 0, rhT ← lock.xchg, CANCELBR[SoftwareLockSideDoor,0],		c2;

	MDR ← T {0}, T ← uT, CANCELBR[$,0],					c2, at[SoftwareLockRets.Interrupt,10,SoftwareLockRets];
	TT ← u8000,								c3;

	TOS ← TOS and ~TT {mask off the timer bit},				c1;
	Q ← Q or TOS,								c2;
	TOS ← uTemp,								c3;

IntReturns:
	rInt ← 0, Xbus ← rhInt, XDisp,						c1;
	uWP ← Q, DISP3[NewIntExits],						c2;

	TT ← uWP, GOTO[RefillInterrupt],					c3, at[rhInt.Refill,8,NewIntExits];
	Rx ← pInt, push, GOTO[BlockInterrupt], 					c3, at[rhInt.Block,8,NewIntExits];
	GOTO[IdleInterrupt],							c3, at[rhInt.Idle,8,NewIntExits];
	MesaIntRq, GOTO[LoadProcess] {in Process},				c3, at[rhInt.LP,8,NewIntExits];
	Q ← PC + PC, GOTO[TSd {in Process}],					c3, at[rhInt.Scan,8,NewIntExits];
{db}	{L3Disp}, MesaIntRq, GOTO[SaveProcess {in Process}],			c3, at[rhInt.Reschedule,8,NewIntExits];
	rhT ← T LRot0, MesaIntRq, GOTO[Enqueue {in Process}],			c3, at[rhInt.Enqueue,8,NewIntExits];


TSd:	{temp, see dbProcess.mc}
BlockInterrupt:
	TOS ← STK, pop,	GOTO[SaveRegs] {in Process},				c1;


RefillInterrupt:
	[] ← TT, ZeroBr,							c1;
	BRANCH[Wakeups, NoWakeups],						c2;

IdleInterrupt:
	Rx ← uWP,								c1;
	uWP ← 0, L3←L3.Interrupt, GOTO[CVLoop] {in Process},			c2;