{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;