{ 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...}