{InterruptsDaybreak.mc
Daybreak specific portions of Refill.mc and Process.mc
parts copied from InterruptsDicentra.mc, HGM, 18-Dec-83 9:12:35
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 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];
{Buffer refill got a MesaIntTrap}
RefillInt:
rInt ← rInt or IntStat, ClrIntErr, c3, at[addrRefillInt];
rhInt ← rhInt.Refill, Ybus ← rInt, YDisp, GOTO[IntDisp], c1;
{BLT, CHKSUM, ... or BITBLT noticed an interrupt}
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:
uIdleCountHigh ← Q, 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;
{IntReasons}
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;
{NewIntExits}
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];
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];
rhT ← T LRot0, 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;