{InitDicentra.mc, HGM, 4-Nov-84 2:58:28}
Set[GermChips, 3];
Reserve[0F6F, 0FFF]; {Kernel}
SetTask[0]; StartAddress[Germ];
{If the P2 connector isn't plugged in, the hardware can't drive the 20th (word) address bit.}
Set[MaxP1Banks, 8];
Set[MaxP2Banks, 10]; {4 bit map flags}
{Blank until CPU testing finished OK}
Set[MP.CSPE, 90'd]; {Control Store Parity Error}
Set[MP.NXM, 91'd]; {XACK Timeout, or Memory Parity Error}
Set[MP.UMI, 92'd]; {Unknown Misc board Interrupt}
Set[MP.COP, 93'd]; {Cycles Out of Phase}
Set[MP.TM, 100'd]; {Testing Memory}
{101..10n is number of banks found}
Set[MP.MBM, 150'd]; {Bus Master Missing}
Set[MP.ISO, 151'd]; {Interrupt(s) Stuck On}
Set[MP.BSH, 152'd]; {(Part of) Memory Data Bus Stuck High}
Set[MP.BSL, 153'd]; {(Part of) Memory Data Bus Stuck Low}
Set[MP.XTB, 154'd]; {XAck Timeout broken (on Misc board) -- won't blink}
Set[MP.NEM, 159'd]; {Not Enough Memory (need 2 banks)}
Set[MP.MB, 160'd]; {Memory Broken}
Set[MP.XTDS, 161'd]; {XAck Timeout During Scan (parity bit broken?)}
Set[MP.CG, 170'd]; {Copying Germ}
Set[MP.BGC, 171'd]; {Bad Germ Checksum}
Set[MP.ID, 898'd]; {Unreasonable processor ID from 3Com board (set by ProcessorHeadDicentra)}
Set[MP.HWG, 899'd]; {Here We Go => About to start running Germ}
{PNIP: Put Number in MP: Expects T ← number+1, Returns T ← 0}
Set[PNIP.TM, 0];
Set[PNIP.XTB, 1];
Set[PNIP.CG, 2];
Set[PNIP.HWG, 3];
{0E used by @WRMP}
Set[PNIP.FE, 0F];
Set[Setup00, 00]; Set[Setup01, 01]; Set[Setup02, 02]; Set[Setup03, 03];
Set[Setup04, 04]; Set[Setup05, 05]; Set[Setup06, 06]; Set[Setup07, 07];
Set[Setup08, 08]; Set[Setup09, 09]; Set[Setup0A, 0A]; Set[Setup0B, 0B];
Set[Setup0C, 0C]; Set[Setup0D, 0D]; Set[Setup0E, 0E]; Set[Setup0F, 0F];
Set[Setup10, 00]; Set[Setup11, 01]; Set[Setup12, 02]; Set[Setup13, 03];
Set[Setup14, 04]; Set[Setup15, 05]; Set[Setup16, 06]; Set[Setup17, 07];
Set[Setup18, 08]; Set[Setup19, 09]; Set[Setup1A, 0A]; Set[Setup1B, 0B];
Set[Setup1C, 0C]; Set[Setup1D, 0D]; Set[Setup1E, 0E]; Set[Setup1F, 0F];
{Get here when the boot button is pushed, or somebody yanks on INIT/.}
BootTrap: {From trap dispatch in Refill.mc}
{Test the CPU???}
{Burdock starts here to run Germ. Trap handler gets here on Boot Trap.}
Germ: UvMDS ← 0, ClrIntErr, c1, at[1,4,ErrType];
Noop, c2;
ExtCtrl ← 4, {Zero, Blank, Init Incr} c3;
{At this point, UvMDS is the only register with important data.}
SetupConstants:
TT ← LShift1 0FF, SE←1, c1;
TT ← LShift1 TT, SE←1, c2;
TT ← TT LShift1, SE←1, c3;
u7FF ← TT, TT ← TT LShift1, SE←1, c1;
TT ← TT LShift1, SE←1, c2;
u1FFF ← TT, TT ← TT LShift1, SE←1, c3;
u3FFF ← TT, c1;
TT ← 01F, c2;
TT ← TT LRot8, c3;
TT ← TT or 0F8, c1;
uPMask ← TT, {1FF8} c2;
uPMask2 ← TT, c3;
TT ← RShift1 0, SE ← 1, c1;
u8000 ← TT, c2;
uPhoneFlag ← 0, c3;
TT ← 10, c1;
TT ← TT LRot8, c2;
u1000 ← TT, c3;
TT ← 90, c1;
TT ← TT LRot8, c2;
u9000 ← TT, c3;
TestMultibus:
TT ← ExtStat, XDisp, c1;
BRANCH[$, BusMasterMissing, 0B], c2;
Q ← TT and ~0FF, c3;
[] ← Q, ZeroBr, c1;
BRANCH[InterruptStuckOn, $], c2;
rhPC ← 0, PC ← 0, c3;
MAR ← [rhPC, 0+0], c1;
MDR ← 0, c2;
T ← MD, {Hack: Prom skips bus cycle} c3;
[] ← T, ZeroBr, c1;
uInts ← 0, BRANCH[BusStuckHigh, $], c2;
uWP ← 0, c3;
MAR ← [rhPC, 0+0], c1;
MDR ← T xor ~T, c2;
T ← MD, c3;
[] ← ~T, ZeroBr, c1;
Q ← 1, BRANCH[BusStuckLow, $], c2;
uWDC ← Q, L0 ← PNIP.XTB, c3;
TestXackTimeout:
T ← MP.XTB+1, CALL[PNIP2], c1;
{Section 07 of Misc Board is reserved for testing XAck Timouts.}
rhRx ← 07, c2, at[PNIP.XTB, 10, PNIPRet];
Rx ← u1000, c3;
IO ← [rhRx, Rx+0] c1;
MDR ← 0, UBrkByte ← 0, c2;
Noop, c3;
{Hang here if writes don't time out.}
IO ← [rhRx, Rx+0] c1;
Rx ← u9000, c2;
T ← MD, c3;
{Hang here if reads don't time out.}
SetupEPRomCIO:
T ← Rx + 0, L0 ← Setup00, {Master Interrupt Control} c1;
Q ← 0, rhRx ← 5, CALL[Setup0], {Reset, EProm CIO} c2;
{Reset leaves all Ports setup to Output in Bit Mode.}
T ← Rx + 1, L0 ← Setup01, {Master Config Control} c1, at[Setup00, 10, Setup0Ret];
Q ← 094, CALL[Setup0], {Enable Ports A, B, and C} c2;
T ← Rx + 0F, L0 ← Setup02, {Port C Data} c1, at[Setup01, 10, Setup0Ret];
Q ← 0, CALL[Setup0], {PromOE'} c2;
SetupTimerCio:
T ← Rx + 0, L0 ← Setup03, {Master Interrupt Control} c1, at[Setup02, 10, Setup0Ret];
Q ← 0, rhRx ← 4, CALL[Setup0], {Reset, Timers CIO} c2;
T ← Rx + 23, L0 ← Setup04, {Port A Direction} c1, at[Setup03, 10, Setup0Ret];
Q ← 0FF, CALL[Setup0] {Input} c2;
T ← Rx + 2B, L0 ← Setup05, {Port B Direction} c1, at[Setup04, 10, Setup0Ret];
Q ← 0E0, CALL[Setup0] {Out on low 5 bits: Clock and EPRom} c2;
T ← Rx + 05, L0 ← Setup06, {Port C Polarity} c1, at[Setup05, 10, Setup0Ret];
Q ← 01, CALL[Setup0] {Invert Clock Out} c2;
T ← Rx + 06, L0 ← Setup07, {Port C Direction} c1, at[Setup06, 10, Setup0Ret];
Q ← 0E, CALL[Setup0] {Low bit for Clock Out} c2;
T ← Rx + 1C, L0 ← Setup08, {Cnt 1 Mode} c1, at[Setup07, 10, Setup0Ret];
Q ← 0E0, CALL[Setup0] {Cont, Ext Out, Ext In, Pulse} c2;
T ← Rx + 1D, L0 ← Setup09, {Cnt 2 Mode} c1, at[Setup08, 10, Setup0Ret];
Q ← 080, CALL[Setup0] {Cont, Pulse} c2;
T ← Rx + 1E, L0 ← Setup0A, {Cnt 3 Mode} c1, at[Setup09, 10, Setup0Ret];
Q ← 0E4, CALL[Setup0] {Cont, Ext Out, Ext In, Retrg, Pulse} c2;
T ← Rx + 16, L0 ← Setup0B, {Cnt 1 MSB} c1, at[Setup0A, 10, Setup0Ret];
Q ← 0, CALL[Setup0], c2;
T ← Rx + 17, L0 ← Setup0C, {Cnt 1 LSB} c1, at[Setup0B, 10, Setup0Ret];
Q ← 0, CALL[Setup0], c2;
T ← Rx + 18, L0 ← Setup0D, {Cnt 2 MSB} c1, at[Setup0C, 10, Setup0Ret];
Q ← 0, CALL[Setup0], c2;
T ← Rx + 19, L0 ← Setup0E, {Cnt 2 LSB} c1, at[Setup0D, 10, Setup0Ret];
Q ← 0, CALL[Setup0], c2;
InitXACKWatcher:
T ← Rx + 02C, L0 ← Setup0F, {Port B Special IO} c1, at[Setup0E, 10, Setup0Ret];
Q ← 40, CALL[Setup0], {ONEs Catcher for TOXack} c2;
T ← Rx + 02D, L0 ← Setup10, {Port B Polarity} c1, at[Setup0F, 10, Setup0Ret];
Q ← 40, CALL[Setup1], c2;
T ← Rx + 02F, L0 ← Setup11, {Port B Mask} c1, at[Setup10, 10, Setup1Ret];
Q ← 40, CALL[Setup1], c2;
T ← Rx + 28, L0 ← Setup12, {Port B Mode} c1, at[Setup11, 10, Setup1Ret];
Q ← 4, CALL[Setup1], {Bit Port, OR Matcher} c2;
T ← Rx + 09, L0 ← Setup13, {Port B Command} c1, at[Setup12, 10, Setup1Ret];
Q ← 0C0, CALL[Setup1], {Set Interrupt Enable} c2;
T ← Rx + 0, L0 ← Setup14, {Master Control} c1, at[Setup13, 10, Setup1Ret];
Q ← 080, CALL[Setup1], {MIE} c2;
{Cnt 1 runs at 12.8 microseconds. 12800ns*2↑16 => 838ms.
3 minutes = 180 sec. 100/.838 => 214 ticks = 0D6H.}
InitWatchdogTimer:
T ← Rx + 1A, L0 ← Setup15, {Cntr 3 MSB} c1, at[Setup14, 10, Setup1Ret];
{Patch so you don't get Booted while looking for a bug...}
{ Q ← 0FF, CALL[Setup1], c2;} {←←←←←← DEBUGGING TODAY}
Q ← 000, CALL[Setup1], c2; {←←←←←← DEBUGGING TODAY}
T ← Rx + 1B, L0 ← Setup16, {Cntr 3 LSB} c1, at[Setup15, 10, Setup1Ret];
Q ← 0D6, CALL[Setup1], c2;
T ← Rx + 03, L0 ← Setup17, {Int Vec for Port B} c1, at[Setup16, 10, Setup1Ret];
Q ← 020, CALL[Setup1], {For XACK Timeout} c2;
T ← Rx + 04, L0 ← Setup18, {Int Vec for Counters} c1, at[Setup17, 10, Setup1Ret];
Q ← 011, CALL[Setup1], {For Process Timer} c2;
EnableTimerCio:
T ← Rx + 01, L0 ← Setup19, {Master Config Control} c1, at[Setup18, 10, Setup1Ret];
Q ← 0F7, CALL[Setup1], {Enables All, Link Timers} c2;
TurnOnHighResClock:
T ← Rx + 0A, L0 ← Setup1A, {Counter 1 Command} c1, at[Setup19, 10, Setup1Ret];
Q ← 06, CALL[Setup1], {Trgr, Gate on} c2;
T ← Rx + 0B, L0 ← Setup1B, {Counter 2 Command} c1, at[Setup1A, 10, Setup1Ret];
Q ← 06, CALL[Setup1], {Trgr, Gate on} c2;
TurnOnWatchdogTimer:
T ← Rx + 0C, L0 ← Setup1C, {Counter 3 Command} c1, at[Setup1B, 10, Setup1Ret];
Q ← 06, CALL[Setup1], {Trgr, Gate on} c2;
{
Setup Memory:
0 Determine if P2 Connector is being used (512K word limit = 8 banks)
1 Find number of banks, leave answer in TOS (and show it in MP)
2 Crash if can't find 128K
3 Test memory (Watch Int0 to check parity bits)
4 Set whole Map to vacant
5 Put memory into Map (skipping over memory for Map)
}
{This assumes that somebody will timeout NXMs. (and not boot us...)}
FindLastBank:
T ← MP.TM+1, L0 ← PNIP.TM, c1, at[Setup1C, 10, Setup1Ret];
rhPC ← 0, PC ← 0, CALL[PNIP], c2;
TT ← 3C, {Test Constant is 3C3C}, c2, at[PNIP.TM, 10, PNIPRet];
TT ← TT LRot8 or TT, c3;
{ If we don't have the P2 connectors wired up, only 20 bits of (byte) addresses are used.
With 4 bits of Map flags, a Dicentra can conviently generate 20 bits of word addresses.
Thus we have to poke around a bit to see if we should stop looking for more memory at 512K words, or 1024K words. This is done by storing a constant in location 0, storing something else at 512K, going back and checking location 0. If it has changed, then we don't have a P2 connector. (Maybe memory is broken, but then we are dead anyway.) }
MAR ← [rhPC, PC+0], c1;
MDR ← TT, c2;
rhL ← MaxP1Banks, L ← 0, c3;
MAR ← [rhL, L+0], c1;
MDR ← ~TT, c2;
TOS ← 0, c3;
MAR ← [rhPC, PC+0], c1;
Noop, c2;
T ← MD, c3;
[] ← T xor TT, ZeroBr, c1;
BRANCH[P2Dead, P2Ok], c2;
P2Dead: G ← MaxP1Banks, GOTO[FindLastBankScan], c3;
P2Ok: G ← MaxP2Banks, GOTO[FindLastBankScan], c3;
FindLastBankScan:
uNxmExpected ← 0, c1;
PC ← 0, c2;
FindLp: rhPC ← TOS LRot0, CANCELBR[$], c3;
MAR ← [rhPC, PC+0], c1;
MDR ← TT, c2;
L ← 0FE, {Mask for enough memory test} c3;
MAR ← [rhPC, PC+0], c1;
Q ← TOS + 1, c2;
[] ← TT xor MD, ZeroBr, c3, LOOPHOLE[stw];
PC ← PC + 1, ZeroBr, BRANCH[FoundTopBank, $], c1;
[] ← Q xor G {MaxBanks}, ZeroBr, BRANCH[FindLp, $], c2;
TOS ← TOS + 1, BRANCH[$, NoMoreBanks], c3;
ExtCtrl ← 3, c1;
ExtCtrl ← 7, GOTO[FindLp], c2;
NoMoreBanks:
ExtCtrl ← 3, c1;
FoundTopBank:
[] ← TOS and L, ZeroBr, CANCELBR[$], c2;
ExtCtrl ← 7, BRANCH[$, NotEnoughMemory], c3;
ResetXackTimeout:
T ← Rx + 0E, L0 ← Setup1D, {Port B Data} c1;
Q ← 0, CALL[Setup1], {Clear caught 1} c2;
T ← Rx + 09, L0 ← Setup1E, {Port B Command} c1, at[Setup1D, 10, Setup1Ret];
Q ← 0B0, CALL[Setup1], {Reset IP} c2;
{Yetch, have to wait for INT0 to go away, or MesaInt will get set again.}
T ← 08, c1, at[Setup1E, 10, Setup1Ret];
T ← T LRot8, c2;
u800 ← T, c3;
T ← 0E0, c1;
T ← T LRot8, c2;
uPPMask ← T, {E000} c3;
Set[TOP.C3C3, 0];
Set[TOP.Zero, 1];
Set[TOP.Ones, 2];
Set[TOP.1, 3];
Set[TOP.Last, 4];
{
Make sure each bit in memory can hold both 0 and 1.
Don't forget the parity bit.
If we ever get ECC memory, these patterns should also test the ECC bits.
Also check/update each word during a pass to catch addressing errors.
Last pass should 0 things to leave memory all 0.}
TestMemory:
T ← ~TT, L0 ← TOP.C3C3, ClrIntErr, CALL[TestOnePass], c1;
{Add patterns here to test error correcting bits.}
L0 ← TOP.Zero, c3, at[TOP.C3C3, 10, TestOnePassRet];
T ← 0, CALL[TestOnePass], c1;
L0 ← TOP.Ones, c3, at[TOP.Zero, 10, TestOnePassRet];
T ← ~TT, CALL[TestOnePass], c1;
L0 ← TOP.1, c3, at[TOP.Ones, 10, TestOnePassRet];
T ← 1, CALL[TestOnePass], {Other parity} c1;
L0 ← TOP.Last, c3, at[TOP.1, 10, TestOnePassRet];
T ← 0, CALL[TestOnePass], c1;
{TT ← old value, T ← new value; Returns TT ← T}
TestOnePass:
PC ← 0, rhPC ← 0, c2;
TestAnotherBank:
Noop, c3;
TestOnePassLoop:
MAR ← [rhPC, PC+0], CANCELBR[$], c1;
Q ← rhPC + 1, c2, LOOPHOLE[byteTiming];
[] ← MD xor TT, NZeroBr, c3, LOOPHOLE[stw];
MAR ← [rhPC, PC+0], BRANCH[$, MemBroken], c1;
MDR ← T, PC ← PC + 1, CarryBr, c2;
[] ← Q xor TOS, ZeroBr, BRANCH[TestOnePassLoop, $], c3;
L0Disp, BRANCH[$, TestOnePassExit], c1;
rhPC ← Q LRot0, CANCELBR[TestAnotherBank, 7], c2;
TestOnePassExit:
TT ← T, RET[TestOnePassRet], c2;
Set[Bank1, 0];
Set[Bank2, 1];
Set[BankTail, 2]; {Even}
SetupMap:
rhRx ← 1, Rx ← 0, MesaIntBr, c3, at[TOP.Last, 10, TestOnePassRet];
T ← 0FF + 1, BRANCH[$, XAckTimeoutDuringScan], {Pages in bank 1} c1;
TT ← 0, L0 ← Bank1, c2;
L ← 0FF + 1, CALL[AddToMap], c3;
T ← 40, c1, at[Bank1,10,AddToMapRet];
T ← T LRot8, c2;
TT ← TT + T {Skip over map}, c3;
T ← 0C0, {Rest of bank 2} c1;
L0 ← Bank2, c2;
TOS ← TOS - 2, CALL[AddToMap], c3;
T ← TOS, ZeroBr, c1, at[Bank2,10,AddToMapRet];
T ← T LRot8, L0 ← BankTail, BRANCH[$, OnlyTwoBanks], c2;
CALL[AddToMap], c3;
OnlyTwoBanks:
Noop, c3;
T ← 40, c1, at[BankTail,10,AddToMapRet];
T ← T LRot8, c2;
T ← T - Rx, c3;
Noop, c1;
Noop, c2;
TT ← 60, c3;
ClearRestOfMap:
MAR ← [rhRx, Rx+0], c1;
MDR ← TT, T ← T - 1, ZeroBr, c2;
Rx ← Rx + 1, BRANCH[ClearRestOfMap, CopyGerm], c3;
{Add a run of pages to the Map:
T has number of pages
Rx has starting virtural page number
TT has flags and physical page number (map format)
L has constant 100
Rx and TT are returned updated}
AddToMap:
MAR ← [rhRx, Rx+0], c1;
MDR ← TT, Rx ← Rx + 1, c2;
Noop, c3;
TT ← TT + L, CarryBr, c1;
T ← T - 1, ZeroBr, BRANCH[$, NewBank], c2;
BRANCH[AddToMap, MapDone], c3;
MapDone:
Noop, c1;
L0Disp, c2;
RET[AddToMapRet], c3;
NewBank:
TT ← TT + 1, BRANCH[AddToMap, MapDone], c3;
CopyGerm: {From ROM}
{ TOS holds checksum
L/rhL points to main memory
G/rhG points to EPROM
Rx/rhRx points to EPROM CIO
PC/rhPC points to Timer CIO}
TOS ← 0, L0 ← PNIP.CG, {Checksum}, c1;
L ← 0FF + 1, {Germ starts on page 1 in memory} c2;
rhL ← 0, c3;
T ← MP.CG+1, CALL[PNIP2], c1;
G ← 0C0, {2764 needs high bits on} c2, at[PNIP.CG, 10, PNIPRet];
G ← G LRot8, c3;
T ← 0FF + 1, {Germ starts on page 1 of Prom} c1;
T ← LShift1 T, {Convert to bytes} c2;
G ← G + T, rhG ← 0, {Start with the first chip} c3;
rhRx ← 5, {EProm CIO} c1;
Rx ← u9000, c2;
PC ← u9000, c3;
CopyGermLoop:
IO ← [rhRx, Rx + 0E], {Port B Data ← Low byte of addr} c1;
MDR ← G, G ← G LRot8, c2;
rhPC ← 4, {Timers CIO} c3;
IO ← [rhRx, Rx + 0D], {Port A Data ← High byte of addr} c1;
MDR ← G, G ← G LRot8, c2;
G ← G + 1, c3;
IO ← [rhPC, PC + 0E], {Port B Data ← Chip selection} c1;
MDR ← rhG, c2;
Noop, c3;
IO ← [rhPC, PC + 0D], {Port A Data} c1;
Noop, c2;
TT ← MD, c3;
IO ← [rhRx, Rx + 0E], {Port B Data ← Low byte of addr} c1;
MDR ← G, G ← G + 1, c2;
TT ← TT LRot8, c3;
IO ← [rhPC, PC + 0D], {Port A Data} c1;
T ← G LRot4, c2;
TT ← TT or MD, c3;
MAR ← [rhL, L + 0], c1;
MDR ← TT, TOS ← TOS + TT, CarryBr, c2;
L ← L + 1, BRANCH[$, CGCarry], c3;
Noop, c1;
CGRot: [] ← T and 2, {8K, 1 Bank of PROMs} ZeroBr, c2;
TOS ← LRot1 TOS, BRANCH[$, CopyGermLoop], c3;
CopyGermNextChip:
Q ← rhG + 1, c1, LOOPHOLE[byteTiming];
[] ← Q xor GermChips, ZeroBr, c2;
rhG ← Q LRot0, BRANCH[$, CopyGermDone], c3;
G ← 0C0, {2764 needs high bits on} c1;
G ← G LRot8, c2;
GOTO[CopyGermLoop], c3;
CopyGermDone:
Q ← ~TOS, ZeroBr, {0 case can't happen} c1;
BRANCH[BadGermChecksum, GoodGermChecksum], c2;
CGCarry:
TOS ← TOS + 1, GOTO[CGRot], c1;
{------------------------------------------------------------------------------------}
GoodGermChecksum:
Noop, c3;
{This section of code knows how the Map is setup.}
SetupRequest:
rhRx ← 0, c1;
Rx ← 3, {Germ's SD is .MV 200 = .MR 200} c2;
Rx ← Rx LRot8, {300, Boot.Request is on next page} c3;
T ← 7, c1;
T ← T LRot8, c2;
TT ← 0E, c3;
MAR ← [rhRx, Rx+0A0], {requestBasicVersion ← 072E} c1;
MDR ← T or 02E, CANCELBR[$, 2], LOOPHOLE[wok], c2;
Noop, c3;
MAR ← [rhRx, Rx+0A2], {location.deviceType} c1;
MDR ← 5 {anyEthernet}, CANCELBR[$, 2], LOOPHOLE[wok], c2;
T ← TT LRot8, c3;
MAR ← [rhRx, Rx+0AD], {requestExtensionVersion ← 0E53} c1;
MDR ← T or 053, CANCELBR[$, 2], LOOPHOLE[wok], c2;
Noop, c3;
HereWeGo:
rhT ← xtFC0, c1;
rhMDS ← UvMDS, c2;
uXTS ← stackP ← 0, c3;
UvG ← TOS ← 0, L0 ← PNIP.HWG, c1;
PC ← 1, {???} c2;
TT ← 0FF LShift1, SE ← 1, {1FF} c3;
T ← TT LShift1, SE ← 1, {3FF} c1;
T ← T - 7B, {383H = 899.} CALL[PNIP], c2;
T ← TT + 3{@SD[sBoot]}, c2, at[PNIP.HWG, 10, PNIPRet];
StartEmulator:
{Should activate WatchDog timer ************************************************}
uDestLo ← T, YDisp, L ← 0, GOTO[XFER], c3;
{************************************************}
Setup0: Noop, c3;
IO ← [rhRx, T + 0], c1;
MDR ← Q, L0Disp, c2;
DISP4[Setup0Ret], c3;
Setup1: Noop, c3;
IO ← [rhRx, T + 0], c1;
MDR ← Q, L0Disp, c2;
DISP4[Setup1Ret], c3;
{************************************************}
PNIP1: Noop, c1;
PNIP2: Noop, c2;
PNIP: ExtCtrl ← 4, GOTO[PNIPT], c3;
BNIP: ExtCtrl ← 3, c3;
PNIPT: T ← T - 1, ZeroBr, c1;
ExtCtrl ← 7, BRANCH[BNIP, $], c2;
L0Disp, c3;
RET[PNIPRet], c1;
{************************************************}
{Dead ends that put a number in the MP and .....}
BusMasterMissing:
T ← MP.MBM+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
InterruptStuckOn:
T ← MP.ISO+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
UnknownMiscInterrupt:
T ← MP.UMI+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
BusStuckHigh:
T ← MP.BSH+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
BusStuckLow:
T ← MP.BSL+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
NotEnoughMemory:
T ← MP.NEM+1, L0 ← PNIP.FE, CALL[PNIP2], c1;
MemBroken:
T ← MP.MB+1, L0 ← PNIP.FE, CANCELBR[PNIP, 1], c2;
XAckTimeoutDuringScan:
T ← MP.XTDS+1, L0 ← PNIP.FE, CANCELBR[PNIP, 1], c2;
BadGermChecksum:
T ← MP.BGC+1, L0 ← PNIP.FE, CALL[PNIP1], c3;
CyclesOutOfPhaseTrap:
T ← MP.COP+1, L0 ← PNIP.FE, CALL[PNIP2], c1;
CyclesOutOfPhaseInt:
T ← MP.COP+1, L0 ← PNIP.FE, CALL[PNIP2], c1;
CSParErr: {From trap dispatch in Refill.mc}
T ← MP.CSPE+1, L0 ← PNIP.FE, CALL[PNIP2], c1, at[0,4,ErrType];
NXM: T ← MP.NXM+1, L0 ← PNIP.FE, CALL[PNIP], c2;
FatalError:
Rx ← 6, {Incr high, Don't zero} c2, at[PNIP.FE, 10, PNIPRet];
{I saw some extra counts when incr was parked low. HGM 9-Dec-82}
Blink: T ← 0C, c3;
Noop, c1;
PauseB: Noop, c2;
Pause: TT ← 0, c3;
PauseA: CANCELBR[$], c1;
TT ← TT - 1, ZeroBr, c2;
[] ← T - 1, ZeroBr, BRANCH[PauseA, $], c3;
T ← T - 1, BRANCH[PauseB, $], c1;
ExtCtrl ← Rx, Rx ← Rx xor 1 {Flip visible}, GOTO[Blink], c2;