{
 File name:  InitDLion.mc
 Description: Mesa Emulator initialization,
 Last Edited: bj,  2-Jul-86  6:30:02
 Fiala 22-Jul-86 16:02:02 Fixed MCtl init by introducing new UMCtl register containing
 	8C02; the old U0C00 register is still needed, but only by Trident; had to eliminate
	the U0100 register used by Trident to make space for this.
  Fiala 23-Jul-86 11:04:08 commented out uIOPage ← uIOPage or cedarIOPageHigh.
  Fiala 25-Jul-86  9:45:49 removed most differences in the display initialization between
	the old InitDLion.mc and this new InitDLion.mc.  Moved the init for uSDAddr and
	uStickyReg here from StartMesa.
  Fiala 30-Jul-86 12:07:22 Added configuration switch for Trident EtherInitial variation
  	and simplified the code at OnceOnlyInit.
  Fiala  5-Sep-86 10:56:42 Commented out init for TextBlt's UtbFlags; added several more
  	Refresh calls; added init for uE3FF for 12.2 EtherDLion.mc.
  Fiala  9-Sep-86 11:01:57 Cosmetic edits.
  Fiala 19-Nov-86 11:06:33 Bummed 1 click in commented out init for 12.2 Display.mc.

	Copyright (C) 1981, 1982, 1983, 1986 by Xerox Corporation.  All rights reserved.
}

Reserve[0F6F]; Reserve[0F77]; Reserve[0F7F,0FFF];	{Kernel/Burdock}
Reserve[0F78];	{in case somebody was stupid!}

SetTask[0];

{This comment added by ERF and not guaranteed:

CoreInitial initializes map and storage, then jumps here to OnceOnlyInit.  OnceOnlyInit
initializes registers for the Cedar emulator, then jumps to DoneOnceOnlyInit in the
device specific initial microcode.  DoneOnceOnlyInit eventually jumps to exitToEmulator
in CoreInitial.mc.  Finally, exitToEmulator activates the IOP to roll in the Cedar
emulator from storage and start it executing the Germ, which is also in storage.

The different configurations which can be built are selected according
to the following values of the Config switch:
  0 = SAx000 disk boot
  1 = ?
  2 = Trident disk boot
  3 = Ether boot, SAx000 disk init
  4 = Ether boot, Trident disk init (Cedar addition)
The principal configuration dependency here is choosing between Trident and SAx000
controllers; I don't know why the peculiar value 0C is loaded into CPBootDevice, but
that value is also tested in EtherInitial.mc.

NOTE: we must use only two regisers (dY and dZ) for initialization so that
register usage will not conflict with booting.  For example, Protected.mc
uses three registers to check for Ethernet timeout.  We do Display
initialization last since the Display microcode counts on two of its
registers being initialized, and we use these two registers for all other
initialization.
}

IfEqual[Config, 4, SkipTo[SetTrident],];
IfEqual[Config, 2, SkipTo[SetTrident],];

{SAx000 init}
OnceOnlyInit:	CPBootDevice ← 0, CANCELBR[$,0F],			c1;
		Noop,							c2;
SkipTo[StartInit];

SetTrident! {Trident init}
OnceOnlyInit:	dY ← 0C, CANCELBR[$,0F],				c1;
		CPBootDevice ← dY,					c2;

StartInit!
		dZ ← 88,						c3;

		dZ ← dZ LRot8,						c1;
		dZ ← dZ or 2,						c2;
	{8000 => Map bit 8 is an address bit instead of a flag bit
	  800 => clear task 0 errors
	    2 => enable extra storage on 3.0 mb modified DLion storage boards.}
		MCtl ← dZ {8802},					c3;

		dZ ← LShift1 0FF {1FF}, SE ← 1,				c1;
		dZ ← LShift1 dZ {3FF}, SE ← 1,				c2;
{A quick glance at 12.2 EtherDLion.mc suggested that u3FF could be used instead of uE3FF,
but I didn't eliminate the duplicate definition.
}
		uE3FF ← dZ,						c3;

		u3FF ← dZ, dZ ← dZ LShift1 {7FF}, SE ← 1,		c1;
		Noop,							c2;
		Noop,							c3;

		u7FF ← dZ, dZ ← dZ LShift1 {FFF}, SE ← 1,		c1;
		dZ ← dZ LShift1 {1FFF}, SE ← 1,				c2;
		u1FFF ← dZ, dZ ← dZ LShift1 {3FFF}, SE ← 1,		c3;

		u3FFF ← dZ, Refresh,					c1;
	{***TextBlt init commented out
		dZ ← 64,						c2;
		dZ ← dZ LRot8,						c3;

		UtbFlags ← dZ, Refresh,					c1;}
		dZ ← LShift1 0F, SE ← 1,				c2;
		dZ ← dZ LRot8 {1F00}, ClrIntErr,			c3;

		dZ ← RShift1 0, SE ← 1,					c1;
		u8000 ← dZ,						c2;
  		dZ ← cedarIOPage,					c3;

		dZ ← dZ LRot8,						c1;
		rhdZ ← cedarIOPageHigh,					c2;
 		uIOPage ← dZ,						c3;

		dY ← 0F,						c1;
		dY ← dY LRot8,						c2;
		dY ← dY or 0FC,						c3;
		
		uPMask ← dY, Refresh,					c1; {0FFC}
		uPMask2 ← dY,						c2; {0FFC}
		dY ← 7,							c3;
		
		dY ← dY LRot12,						c1;
		uPPMask ← dY,						c2; {7000}
		dY ← 2,							c3;
		
		dY ← dY LRot8,						c1;
		uAVAddr {= u200} ← dY,					c2; {0200}
		dY ← dY + 40,						c3;

		uSDAddr ← dY {240'h = 1100'b}, Refresh,			c1; {0240 = 1100'b}
		dY ← uStickyReg ← 0, {floating point}			c2;
		Noop,							c3;

{clear I/O page, dY = 0}
IOPageLoop:	MAR ← [rhdZ, dZ+0],					c1;
		MDR ← dY, dZ ← dZ + 1, PgCrOvDisp,			c2; {=0}
		uPCCross ← 0, BRANCH[IOPageLoop,$,1],			c3;
		
EtherInit:	Refresh,						c1;
		dZ ← 55,						c2;
		dZ ← dZ LRot8 or dZ,					c3;

		uEPreamble ← dZ, Refresh,				c1;
		dZ ← dZ or 0C0,						c2;
		uELastPreamble ← dZ,					c3;

		dZ ← LShift1 0FF, SE ← 1,				c1; {1FF}
		dZ ← LShift1 dZ, SE ← 1,				c2; {3FF}
		uE3FF ← dZ,						c3;

MagTapeInit:	rTWc ← CTClrMEr,					c1;
		rTWc ← rTWc LRot8,					c2;
		uTMErRst ← rTWc,					c3;
	
DiskInit:
{Initialize 16 bit const used to clear memory errorflags}
		dZ ← 8C,						c1;
		dZ ← dZ LRot8,						c2;
		dZ ← dZ + 2 {8C02},					c3;

		Xbus ← CPBootDevice, XDisp,				c1;
		UMCtl ← dZ {8C02},BRANCH[SAx000Init, TridentInit, 7],	c2;


SAx000Init:	Noop,							c3;

{Form top byte of status mask; bottom byte depends on drive connected}
		dY ← CHeadMsk,						c1;
		dY ← dY LRot8,						c2;
		Xbus ← KStatus, XwdDisp,				c3;

		dZ ← CSA1MaxSectTst, BRANCH[SetSA1Const, SetSA4Const,2],	c1;
{Sector test number}
SetSA4Const:	dZ ← CSA4MaxSectTst,					c2, at[3,4,SetSA1Const];
		UMaxSectTst ← dZ,					c3;

{synchronization word and error mask}
		dZ ← dZ xor ~dZ,					c1;
		dY ← dY or CSA4ErrMsk, GOTO[SetURegs],			c2;
SetSA1Const:	UMaxSectTst ← dZ,					c2, at[2,4,SetSA4Const];
		dZ ← CAddrMkHi,						c3;

{address mark and error mask}
		dZ ← dZ LRot8,						c1;
		dY ← dY or CSA1ErrMsk,					c2;
SetURegs:	dZ ← dZ or CAddrMkLo,					c3;

{save sync word or address mark; set status mask}
		USyncAdrMk ← dZ, Refresh,				c1;
		UStatusMsk ← dY,					c2;
		GOTO[DisplayInit],					c3;


TridentInit:	Noop,							c3;

{Initialization of U0C00, a 16 bit constant}
		dZ ← 0C,						c1;
		dZ ← dZ LRot8,						c2;
		U0C00 ← dZ,						c3;

{Initialization of U0C04, a 16 bit constant used to reset Control Tag in the Command register}
		dZ ← dZ or 4,						c1;
		U0C04 ← dZ,						c2;
		dZ ← 2C,						c3;

{Initialization of U2C04, a 16 bit constant used to set the Head Tag in the Command register}
		dZ ← dZ LRot8,						c1;
		dZ ← dZ or 4,						c2;
		U2C04 ← dZ,						c3;

{Initialize U2C05 register and prepare initializing UCStatMask.}
		dZ ← dZ or 1,						c1;
		U2C05 ← dZ,						c2;
		dZ ← 4E,						c3;

{Initialize UCStatMask with 4E06.}
		dZ ← dZ LRot8,						c1;
		dZ ← dZ or 6,						c2;
		UCStatMask ← dZ,					c3;

{Initialization of UF000 and UF001, 16 bit constants used to turn on "Sequence"
for all four drives in the Control register}
		dZ ← 0F0,						c1;
		dZ ← dZ LRot8,						c2;
		UF000 ← dZ,						c3;

		dZ ← 1F,						c1;
		dZ ← dZ LRot12,						c2;
		UF001 ← dZ,						c3;

{Initialize U0400 register}
		dZ ← 4,							c1;
		dZ ← dZ LRot8,						c2;
		U0400 ← dZ,						c3;
{Initialization of U4000 and KCmd register (TestCtl = 1) and USIP with 0.}

KRegInit:	KCmd ← dZ ← dZ LRot4,					c1;
		U4000 ← dZ,						c2;
		USIP ← 0,						c3;

{Initialize KCtl with 0F000.}
		dZ ← 0F,						c1;
		KCtl ← dZ  LRot12,					c2;
		dZ ← 0FF + 1,						c3;

EndInit:	Refresh,						c1;
		Noop,							c2;
		Noop, 							c3;


DisplayInit:	rhdY ← cedarIOPageHigh, Refresh,			c1;
		dZ ← uIOPage,						c2;
		dZ ← dZ + IOPage.DCSB,					c3;

		uDCBLoc ← dZ,						c1;
		dZ ← dZ + DCSB.cursorMap,				c2;
		Noop,							c3;

		uInitCurMapAddr ← dZ, Refresh,				c1;
		dZ ← PicLenShifted,					c2;
		dY ← dZ LRot8,						c3;

		uInitCurBufAddr ← dY, Refresh,				c1;
		dZ ← LRot1 dZ,						c2;
		dZ ← LRot1 dZ, rhdZ ← 0,				c3;

		uInitPicLength ← dZ {328'x}, ClrDPRq,			c1;
		uClockBits ← 0,						c2;



{***New stuff commented out for now
{Init for 12.2 Display.mc is same as that for 8.0 FixedDisplay.mc except that
the register uDCBLoc is not initialized and new registers uInitBorder, uPatchCount,
uCopyCount, uPatchLine, and uNormalFifo are also initialized.
}
		rhdY ← cedarIOPageHigh, Refresh,			c1;
		dZ ← uIOPage,						c2;
		dZ ← dZ + IOPage.DCSB.cursorMap,			c3;

		uInitCurMapAddr ← dZ, Refresh,				c1;
		dZ ← 88,						c2;
		dZ ← dZ LRot8,						c3;

		dZ ← dZ or 22,						c1; {8822}
		uInitBorder ← dZ,					c2;
		dZ ← PicLenShifted,					c3;

		dY ← dZ LRot8,						c1;
		uInitCurBufAddr ← dY,					c2;
		dZ ← LRot1 dZ,						c3;

		dZ ← LRot1 dZ, rhdZ ← 0,				c1;
		uInitPicLength ← dZ,					c2; {328'x}
		uClockBits ← 0,						c3;

		ClrDPRq,						c1;
		dZ ← uPatchCount ← 0,					c2;
		dY ← 7,							c3;

		uCopyCount ← dY, Refresh,				c1;
		uPatchLine ← dZ xor ~dZ,				c2;
		dY ← 3F,						c3;

		dY ← dY LRot4,						c1;
		u3F0 ← dY,						c2;
		dY ← 0FC,						c3;

		dY ← dY LRot8,						c1;
		uNormalFifo ← dY,					c2;
***End of commented out code}


LsepInit:	dY ← 10,						c3;

		uDisableLSEP ← dY,					c1;
		dY ← 15,						c2;
		uEndBandScan ← dY,					c3;

		dY ← 1B,						c1;
		uStartActive ← dY,					c2;
{Must finish with dY = 1 for Display.mc}
		dY ← 1, GOTO[DoneOnceOnlyInit],				c3;

{eof...}