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