{InterruptsDicentra.mc, HGM,  4-Nov-84  2:58:45

Dicentra specific Portions of Refill.mc and Process.mc, HGM, 13-Oct-82 20:20:20}

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


{Buffer refill got a MessIntTrap}
RefillInt:
	rhInt ← rhInt.Refill, GOTO[CheckInterrupts],			c3;

{BLT, CHKSUM, ... or BITBLT noticed an interrupt}
BlockInt:
	rhInt ← rhInt.Block, GOTO[CheckInterrupts],			c3, at[restore.int,10,RestoreCallers];
	
{Idle loop noticed a MesaInt}
IdleInt:
	rhInt ← rhInt.Idle, GOTO[CheckInterrupts3],			c2;

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

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

{Reschedule noticed an interrupt}
RescheduleInt:
	rhInt ← rhInt.Reschedule, CANCELBR[CheckInterrupts2, 3],	c1;

{Enqueue noticed an interrupt}
EnqueueInt:
	rhInt ← rhInt.Enqueue, GOTO[CheckInterrupts3],			c2;

CheckInterrupts2:
	Noop,								c2;
CheckInterrupts3:
	Noop,								c3;
	
CheckInterrupts:
	T ← uInts, ClrIntErr,						c1;
	TT ← ExtStat, XC2npcDisp,					c2;
	uInts ← TT, BRANCH[CyclesOutOfPhaseInt, $, 0D],			c3;
	
	TT ← TT and ~0FF, {Discard trash}				c1;
	TT ← TT and ~T {New hardware interrupts}, NZeroBr,		c2;
	BRANCH[$, NewHardwareInterrupts],				c3;
	
NoMoreInts:
	[] ← uInts, NegBr,						c1;
	[] ← uWDC, NZeroBr, BRANCH[$, MiscBoardStillInterrupting],	c2;
	[] ← uWP, ZeroBr, BRANCH[$, IntsDisabled],			c3;

IntsEnabled:
	Xbus ← rhInt, XDisp, BRANCH[ProcessPendingWakeups, NoIntExit],	c1;
	
IntsDisabled:
	Xbus ← rhInt, XDisp, CANCELBR[$],				c1;
NoIntExit:
	DISP3[NoIntExits],						c2;
	
NoWakeups: {Hook used by Block.mc}
	GOTO[IgnoreInt {in Refill}],					c3, at[rhInt.Refill, 8, NoIntExits];
	Rx ← pInt, push, GOTO[BlockInterrupt],				c3, at[rhInt.Block, 8, NoIntExits];
	T ← 77{pIdle}, GOTO[IdleLoopBranch] {in Process},		c3, at[rhInt.Idle, 8, NoIntExits];
	GOTO[LoadProcess] {in Process},					c3, at[rhInt.LP, 8, NoIntExits];
	PC ← PC + 1, GOTO[IOCopyFalseInt] {in IOCopy},			c3, at[rhInt.IOCopy, 8, NoIntExits];
	Q ← PC + PC, GOTO[TSd] {in Process},				c3, at[rhInt.Scan, 8, NoIntExits];
	L3Disp, GOTO[SaveProcess {in Process}],				c3, at[rhInt.Reschedule, 8, NoIntExits];
	GOTO[Enqueue {in Process}],					c3, at[rhInt.Enqueue, 8, NoIntExits];


NewHardwareInterrupts: {
TT has new hardware interrupts
Rx holds index/counter
Bit 0 of uWP is reserved for Process timeouts}

	[] ← uPhoneFlag, ZeroBr,					c1;
	Xbus ← ~TT LRot8, XDisp, BRANCH[$, NoPhoneCSB], {Int4}		c2;
	SCCh ← SCC ← u1000, BRANCH[PhoneInterrupt, NoPhoneInterrupt, 07], c3;

NoPhoneCSB:
	CANCELBR[$, 0F],						c3;
NoPhoneInterrupt:
	Q ← uWP,							c1;
	TT ← TT LShift1, NegBr,						c2;
	Rx ← 8, BRANCH[MoreHardwareInterrupts, MiscBoardInterrupt],	c3;

MiscBoardInterrupt: {8000 in ExtStat => INT0}
	Rio ← u9000,							c1;
	rhRio ← 5, {EProms CIO: Process timer}				c2;
	T ← Rio + 01F,							c3;
	
	IO ← [rhRio, T + 0], {Current Vector}				c1;
	uTickCount ← 0, {Avoid divide by 4}				c2;
	T ← MD,								c3;

{Int Vec initialized to 00.
  00 => 1 Tick.
  06 => Error = 2+ ticks. (Happens during Breakpoints.)
  FF => No Interrupt.}
	Noop,								c1;
	Xbus ← T LRot0, XLDisp,						c2;
	BRANCH[MiscProcessInterrupt, NextMiscInterrupt, 02],		c3;

MiscProcessInterrupt:
    	IO ← [rhRio, Rio + 0C], {Counter 3 Cntrl}			c1;
	MDR ← 0B4, {Reset IP, GCB}					c2;
	Q ← Q or u8000,							c3;

MoreHardwareInterrupts:
	Noop,								c1;
	GOTO[MoreInterruptsTest],					c2;
	
SkipThisBit:
	Rx ← Rx + 1, BRANCH[$, NoMoreInterrupts],			c1;
	TT ← TT LShift1, NegBr,						c2;
MoreInterruptsTest:
	[] ← TT, ZeroBr, BRANCH[SkipThisBit, $],			c3;
	
TakeThisBit:
 	Ybus ← Rx, AltUaddr, CANCELBR[$]				c1;
	Q ← Q or uInterruptMasks, GOTO[MoreInterruptsTest],		c2;

	
NoMoreInterrupts:
	uWP ← Q, CANCELBR[CheckInterrupts3],				c2;

	

ProcessPendingWakeups:
	DISP3[NewIntExits],						c2;

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

RefillInterrupt:
	STK ← TOS, pop,	GOTO[SaveRegs] {in Process},			c1;

BlockInterrupt:
	TOS ← STK, pop,	GOTO[SaveRegs] {in Process},			c1;

{This can actually happen if NXMs are allowed, and the process clock ticks while we are ignoring a NXM.}
MiscBoardStillInterrupting:
	uInts ← 0, CANCELBR[CheckInterrupts, 1],			c3;

NextMiscInterrupt:
	Noop,								c1;
	rhRio ← 4, {Timer CIO: ONEs Catcher on TOXACK}			c2;
	T ← Rio + 01F,							c3;
		
	IO ← [rhRio, T + 0], {Current Vector}				c1;
	Noop,								c2;
	T ← MD,								c3;

{Int Vec initialized to 0.  FF => No Interupt Pending}
	Xbus ← T LRot0, XLDisp,						c1;
	BRANCH[$, UnknownMiscInterrupt, 02],				c2;
	Noop,								c3;
	
XACKTimeout:
	IO ← [rhRio, Rio + 0E], {Port B Data}				c1;
	MDR ← 000, {Clear caught 1}					c2;
	Xbus ← uNxmExpected, XDisp,					c3;

	IO ← [rhRio, Rio + 09], BRANCH[NXM, $], {Port B Command}	c1;
	MDR ← 0B0, GOTO[MoreInterruptsTest], {Reset IP}			c2;