-- file: InitLaurel.mesa
-- edited by: Schroeder, March 14, 1981 12:47 PM.
-- edited by Brotz, January 20, 1983 1:16 PM
-- edited by Levin, May 4, 1981 12:09 PM
DIRECTORY
AltoDefs USING [PageCount, PageNumber, PageSize],
AltoFileDefs USING [FP, LD, NullFP, TIME, vDA],
Ascii USING [CR, SP],
ControlDefs USING [GlobalFrame, GlobalFrameHandle, Port],
Core USING [DMSUserBlk, InsertInFileCache, Login, LookupInFileCache],
csD: FROM "CoreStreamDefs" USING [Close, EndOfStream, OpenFromName, Read,
StreamHandle],
DiskKD USING [diskKD],
DiskKDDefs USING [CloseDiskKD],
displayCommon USING [bitmapInMDS, bitMapPtr, mcFont],
DMSTimeDefs USING [SetLaurelTime],
drD: FROM "LaurelDriverDefs" USING [ALFont, CapturePupGlitch, Catcher,
CommandLineAction, InstallError, interruptPriority, InterruptProcess, interruptWakeup],
dsD: FROM "DisplayDefs" USING [CursorBitMap, cursorBM, DCBnil, DCBorg, DCBptr,
Display, lineHeight, machineFlavor],
Editor USING [cancelCode, insertDeletionCode, nextCode],
exD: FROM "ExceptionDefs" USING [InitializeExceptions, SetUpExceptionTable, SysBug],
ForgotOps USING [disableInterrupt],
FrameDefs USING [GlobalFrame, LockCode, UnlockCode],
FrameOps USING [CodeHandle, SetReturnLink],
ImageDefs USING [AddCleanupProcedure, AddFileRequest, CleanupItem, CleanupMask,
CleanupProcedure, FileRequest],
inD: FROM "InteractorDefs" USING [maxBracketStringLength, realTimeClock,
ReportMBXState, SetTime],
Inline USING [BITOR, COPY, HighHalf],
intCommon USING [audioEnabled, cmTextNbr, dmTextNbr, editorType, gvTestingMode,
hardcopyHost, imageFileName, keystream, leafOk, mailcheckPollingInterval,
mailFileBracketsHouse, newMailTune, profileRegistry, profileRetrieve, remoteFilePath,
retrieveHandle, tocTextNbr, user, userBracketsHouse],
KeyDefs USING [ChangeKey, Keyboard],
LaurelFontDefs USING [LaurelFont],
lsD: FROM "LaurelStateDefs" USING [CreateLaurelState, InitializeSegments, PageCount,
PageNumber, ReleaseStateSegment, StateHeader, SwapInStateSegment],
MiscDefs USING [DestroyFakeModule],
NucleusOps USING [DiskKD],
OsStaticDefs USING [OsStatics],
ProcessDefs USING [Detach, DisableInterrupts, EnableInterrupts, GetPriority, Priority,
SetPriority, SetTimeout, Yield],
ProtocolDefs USING [SetTestingMode],
PupDefs USING [AdjustBufferParms, CaptureErrors, PupPackageMake],
Region USING [PageStatus],
RetrieveDefs USING [Create, NewUser, SetMTPRetrieveDefault],
SDDefs USING [SD, sUncaughtSignal],
SegmentDefs USING [CopyFileToDataSegment, DataSegmentAddress, DataSegmentHandle,
DefaultBase, DeleteFileSegment, EnumerateFileSegments, FileHandle, FileSegmentAddress,
FileSegmentHandle, HardDown, InsertFile, LockFile, MakeDataSegment, MakeSwappedIn,
memConfig, MemoryConfig, MoveFileSegment, NewFileSegment, PageNumber, Read,
ReadWriteAppend, SegmentHandle, SetFileSegmentDA, SwapIn, Unlock, UnlockFile],
Storage USING [String],
StreamDefs USING [GetCurrentKey, StartKeyHandler],
StringDefs USING [AppendChar, AppendString, BcplToMesaString, StringBoundsFault],
SwapperOps USING [FreePage, memConfig, PageStatus, Status, Update],
vmD: FROM "VirtualMgrDefs" USING [AllocateComposedMessageObject,
AllocateDisplayMessageObject, ComposedMessage, InitComposedMessage],
VMDefs USING [CantOpen, InitializeVM];
InitLaurel: PROGRAM
IMPORTS Core, csD, DiskKDDefs, disC: displayCommon, DMSTimeDefs, drD, dsD,
exD, ForgotOps, FrameDefs, FrameOps, ImageDefs, inD, Inline, intC: intCommon,
KeyDefs, LaurelFontDefs, lsD, MiscDefs, NucleusOps, ProcessDefs, ProtocolDefs,
PupDefs, RetrieveDefs, SegmentDefs, Storage, StreamDefs, StringDefs, SwapperOps,
vmD, VMDefs
EXPORTS drD, lsD
SHARES DiskKD, lsD = PUBLIC
BEGIN
OPEN drD;
-- variables and constants of the module
DisplayCleanupItem: ImageDefs.CleanupItem ←
[link: , mask: ImageDefs.CleanupMask[InLd]
+ ImageDefs.CleanupMask[OutLd]
+ ImageDefs.CleanupMask[Finish]
+ ImageDefs.CleanupMask[Abort],
proc: DisplayCleanup];
savedDCBptr: dsD.DCBptr; -- used to save DCB chain across debugger calls
vmPages: CARDINAL; -- number of pages reserved in the VM cache.
ResumeNub: PORT
[commandInCommandLine: CommandLineAction, installError: InstallError];
-- procedures of the module
DisplayCleanup: ImageDefs.CleanupProcedure =
-- ensures a readable display when going in and out of Laurel.
BEGIN
dwtBankRegister: POINTER = LOOPHOLE[177740B + 11B];
SELECT why FROM
InLd => BEGIN
dsD.DCBorg↑ ← savedDCBptr;
IF ~disC.bitmapInMDS AND dsD.machineFlavor # dmachine
THEN dwtBankRegister↑ ← Inline.HighHalf[disC.bitMapPtr] * 4;
END;
OutLd, Finish, Abort =>
BEGIN
startTime: CARDINAL ← inD.realTimeClock↑;
savedDCBptr ← dsD.DCBorg↑;
dsD.DCBorg↑ ← dsD.DCBnil;
UNTIL inD.realTimeClock↑ - startTime >= 2 DO ENDLOOP;
IF ~disC.bitmapInMDS AND dsD.machineFlavor # dmachine
THEN dwtBankRegister↑ ← 0;
END;
ENDCASE => ERROR;
END; -- of DisplayCleanup --
AdjustForExtraMemory: PROCEDURE =
BEGIN
memConfig: SegmentDefs.MemoryConfig = SegmentDefs.memConfig;
vmPages ← IF memConfig.banks = 100000B THEN 15 ELSE 50;
SELECT memConfig.AltoType FROM
AltoIIXM =>
BEGIN
IF memConfig.mesaMicrocodeVersion = 39 THEN dsD.machineFlavor ← xmesa5
ELSE dsD.machineFlavor ← alto;
IF memConfig.banks = 100000B THEN RETURN;
END;
D0, Dorado => dsD.machineFlavor ← dmachine;
ENDCASE => dsD.machineFlavor ← alto;
disC.bitmapInMDS ← TRUE;
ImageDefs.AddCleanupProcedure[@DisplayCleanupItem];
END; -- of AdjustForExtraMemory --
ScanCommandLine: PROCEDURE RETURNS [action: CommandLineAction] =
BEGIN
OPEN StringDefs;
fileName: STRING ← [inD.maxBracketStringLength];
sh: csD.StreamHandle;
char, switch: CHARACTER;
trouble, eof: BOOLEAN ← FALSE;
mailFileBracketsText: STRING = intC.mailFileBracketsHouse.text;
SkipBlanks: PROCEDURE =
BEGIN
IF eof THEN RETURN;
DO
char ← csD.Read[sh ! csD.EndOfStream => {eof ← TRUE; EXIT}];
IF char # Ascii.SP THEN RETURN;
ENDLOOP;
END; -- of SkipBlanks --
IF intC.leafOk AND intC.remoteFilePath # NIL THEN AppendString[fileName, "[]"L];
AppendString[fileName, "Active"L];
mailFileBracketsText.length ← 0;
AppendString[mailFileBracketsText, fileName];
action ← gmfOnly;
sh ← csD.OpenFromName["Com.cm"L, byte, read
! VMDefs.CantOpen => {trouble ← TRUE; CONTINUE}];
IF trouble THEN RETURN;
BEGIN -- for EXITS --
SkipBlanks[];
IF eof THEN GO TO Cleanup;
switch ← Ascii.SP;
DO
SELECT char FROM
’/ => switch ← csD.Read[sh ! csD.EndOfStream => GO TO Cleanup];
Ascii.SP, Ascii.CR => EXIT;
ENDCASE;
char ← csD.Read[sh ! csD.EndOfStream => {eof ← TRUE; EXIT}];
ENDLOOP;
SkipBlanks[];
fileName.length ← 0;
UNTIL eof DO
SELECT char FROM
Ascii.SP, Ascii.CR => EXIT;
ENDCASE =>
StringDefs.AppendChar[fileName, char ! StringDefs.StringBoundsFault => EXIT];
char ← csD.Read[sh ! csD.EndOfStream => {eof ← TRUE; EXIT}];
ENDLOOP;
SELECT switch FROM
’c, ’C => action ← checkOnly;
’n, ’N => action ← gnmAndStay;
’s, ’S => {action ← sendOnly; mailFileBracketsText.length ← 0};
’b, ’B => {action ← sendBug; mailFileBracketsText.length ← 0};
ENDCASE;
IF fileName.length = 0 THEN GO TO Cleanup;
mailFileBracketsText.length ← 0;
AppendString[mailFileBracketsText, fileName];
GO TO Cleanup;
EXITS
Cleanup => csD.Close[sh];
END; -- of EXITS block --
END; -- of ScanCommandLine
-- Pup Package Initialization
PupInitProcess: PROCEDURE =
BEGIN
IF SegmentDefs.memConfig.useXM
THEN PupDefs.AdjustBufferParms[bufferPoolSize: 18, bufferSize: 140]
ELSE PupDefs.AdjustBufferParms[bufferPoolSize: 17, bufferSize: 64];
PupDefs.PupPackageMake[];
END; -- of PupInitProcess --
-- Font Initialization
SetUpFont: PROCEDURE =
BEGIN
OPEN SegmentDefs;
font: POINTER TO drD.ALFont;
fontFS: FileSegmentHandle;
fontDS: DataSegmentHandle;
[fontFS, ] ← MiscDefs.DestroyFakeModule[LOOPHOLE[LaurelFontDefs.LaurelFont]];
fontDS ← MakeDataSegment[DefaultBase, fontFS.pages, HardDown];
CopyFileToDataSegment[fontFS, fontDS];
font ← DataSegmentAddress[fontDS];
disC.mcFont ← @font.charTable;
IF dsD.lineHeight # font.height THEN exD.SysBug[];
END; -- of SetUpFont --
-- Memory Hacking
CleanUpAfterJim: PROCEDURE =
BEGIN
OPEN ControlDefs, FrameDefs, FrameOps, SegmentDefs;
swapperFrame: GlobalFrameHandle = GlobalFrame[MakeSwappedIn];
residentSeg: FileSegmentHandle = CodeHandle[swapperFrame];
page: AltoDefs.PageNumber;
firstUnlockedSeg: SegmentHandle;
memConfigPtr: POINTER TO SegmentDefs.MemoryConfig;
CheckAndUnlock: PROCEDURE[seg: FileSegmentHandle] RETURNS [BOOLEAN] =
BEGIN
IF seg.class = code AND seg ~= residentSeg AND seg.lock > 0
THEN Unlock[seg];
RETURN[FALSE]
END; -- of CheckAndUnlock --
-- Cleanup #1
[] ← EnumerateFileSegments[CheckAndUnlock];
-- do a dance to allow us to pack the Keyboard module into the resident
LockCode[GlobalFrame[KeyDefs.Keyboard]];
StreamDefs.StartKeyHandler[];
UnlockCode[GlobalFrame[KeyDefs.Keyboard]];
-- Cleanup #2
-- you don’t want to know why this is necessary...
-- (hint: look at the first few lines of MDSRegion.Update)
BEGIN
OPEN SwapperOps;
status: PageStatus;
ProcessDefs.DisableInterrupts[];
[firstUnlockedSeg, status] ←
Status[page ← (residentSeg.VMpage + residentSeg.pages)];
IF status = inuse THEN
{Update[page, 1, FreePage, TRUE]; Update[page, 1, firstUnlockedSeg, TRUE]};
ProcessDefs.EnableInterrupts[];
END;
-- Cleanup #3
memConfigPtr ← @SwapperOps.memConfig;
memConfigPtr.banks ← Inline.BITOR[memConfigPtr.banks, 100000B];
-- Cleanup #4
LockFile[LOOPHOLE[NucleusOps.DiskKD, POINTER TO FRAME[DiskKD]].diskKD.file];
END; -- of CleanUpAfterJim --
-- Install checker
GetWrittenTime: PROCEDURE[file: SegmentDefs.FileHandle]
RETURNS [time: AltoFileDefs.TIME] =
BEGIN
OPEN SegmentDefs;
seg: FileSegmentHandle ← NewFileSegment[file, 0, 1, Read];
leader: POINTER TO AltoFileDefs.LD;
SwapIn[seg];
leader ← FileSegmentAddress[seg];
time ← leader.written;
Unlock[seg];
DeleteFileSegment[seg];
END; -- of GetWrittenTime --
FPtoFileHandle: PROCEDURE [fp: AltoFileDefs.FP] RETURNS [SegmentDefs.FileHandle] =
INLINE
{RETURN[IF fp = AltoFileDefs.NullFP THEN NIL ELSE SegmentDefs.InsertFile[@fp]]};
BringInLaurelState: PROCEDURE
[heapDS: SegmentDefs.DataSegmentHandle, believeState: BOOLEAN]
RETURNS [worked: BOOLEAN] =
BEGIN
OPEN SegmentDefs;
stateFile: FileHandle = FPtoFileHandle[Core.LookupInFileCache["Laurel.state"L]];
stateHeaderSeg: FileSegmentHandle;
stateHeader: POINTER TO lsD.StateHeader;
imageFile: FileHandle = FrameOps.CodeHandle[FrameDefs.GlobalFrame[intC]].file;
worked ← FALSE;
IF stateFile = NIL THEN IF believeState THEN exD.SysBug[] ELSE RETURN;
stateHeaderSeg ← NewFileSegment[stateFile, 1, 1, Read];
SwapIn[stateHeaderSeg];
stateHeader ← FileSegmentAddress[stateHeaderSeg];
IF imageFile.fp = stateHeader.imageFP AND
GetWrittenTime[imageFile] = stateHeader.imageTime AND
heapDS.VMpage + heapDS.pages = stateHeader.cachedHeapTop THEN
BEGIN
profileFile: FileHandle = FPtoFileHandle[Core.LookupInFileCache
[IF stateHeader.profileInUserCm THEN "User.cm"L ELSE "Laurel.profile"L]];
fontsWidthsFile: FileHandle = FPtoFileHandle[Core.LookupInFileCache["Fonts.widths"L]];
IF believeState OR
(profileFile ~= NIL AND profileFile.fp = stateHeader.profileFP AND
GetWrittenTime[profileFile] = stateHeader.profileTime AND
fontsWidthsFile ~= NIL AND fontsWidthsFile.fp = stateHeader.fontsWidthsFP AND
GetWrittenTime[fontsWidthsFile] = stateHeader.fontsWidthsTime) THEN
BEGIN
headerPages: AltoDefs.PageCount = stateHeader.firstSegmentPage-1;
BringInHeap: PROCEDURE = INLINE
BEGIN
heapFS: FileSegmentHandle =
NewFileSegment[stateFile, stateHeader.heapSegFirstPage,
stateHeader.heapSegPages, Read];
pagesToFree: AltoDefs.PageCount = heapDS.pages-heapFS.pages;
IF pagesToFree ~= 0 THEN
BEGIN
IF LOOPHOLE[pagesToFree, INTEGER] < 0 THEN exD.SysBug[];
SwapperOps.Update[heapDS.VMpage, pagesToFree, SwapperOps.FreePage,
FALSE];
heapDS.VMpage ← heapDS.VMpage+pagesToFree;
heapDS.pages ← heapFS.pages;
END;
SetFileSegmentDA[heapFS, stateHeader.heapSegDA];
CopyFileToDataSegment[heapFS, heapDS];
DeleteFileSegment[heapFS];
END;-- of BringInHeap --
FillInCodeSegmentDAs: PROCEDURE = INLINE
BEGIN
imageDAs: DESCRIPTOR FOR ARRAY [-1..0) OF AltoFileDefs.vDA =
DESCRIPTOR[lsD.SwapInStateSegment[stateHeader.imageDATableSeg],
stateHeader.imageDATableSeg.pages*AltoDefs.PageSize];
PlugHint: PROCEDURE[seg: FileSegmentHandle] RETURNS[BOOLEAN] =
BEGIN
IF seg.file = imageFile THEN
SetFileSegmentDA[seg, imageDAs[seg.base]];
RETURN[FALSE]
END; -- of PlugHint --
[] ← EnumerateFileSegments[PlugHint];
lsD.ReleaseStateSegment[stateHeader.imageDATableSeg];
END; -- of FillInCodeSegmentDAs --
worked ← TRUE;
Unlock[stateHeaderSeg];
MoveFileSegment[stateHeaderSeg, 1, headerPages];
SwapIn[stateHeaderSeg];
stateHeader ← FileSegmentAddress[stateHeaderSeg];
Inline.COPY
[to: @LOOPHOLE[intC, ControlDefs.GlobalFrameHandle].global[0],
from: stateHeader + stateHeader.intCOffset,
nwords: stateHeader.disCOffset - stateHeader.intCOffset];
Inline.COPY
[to: @LOOPHOLE[disC, ControlDefs.GlobalFrameHandle].global[0],
from: stateHeader + stateHeader.disCOffset,
nwords: stateHeader.headerFF - stateHeader.disCOffset];
BringInHeap[];
lsD.InitializeSegments[stateHeader];
FillInCodeSegmentDAs[];
[] ← Core.InsertInFileCache[intC.imageFileName, imageFile.fp, TRUE];
LockFile[imageFile];
END;
END;
Unlock[stateHeaderSeg];
IF worked THEN LockFile[stateFile];
DeleteFileSegment[stateHeaderSeg];
END; -- of BringInLaurelState --
PreStopInitialization: PROCEDURE
RETURNS [commandInCommandLine: CommandLineAction, installError: InstallError] =
BEGIN
lookupIndex: CARDINAL;
heapDS: SegmentDefs.DataSegmentHandle;
heapPages: AltoDefs.PageCount = 8; -- should include a few extra pages in case
-- of long strings in Laurel.profile.
pupInitializer: PROCESS;
hardcopyHostString: STRING;
userNameString: STRING;
userPasswordString: STRING;
userRegistryString: STRING;
bcplStringHeader: TYPE =
MACHINE DEPENDENT RECORD [length: [0 .. 255], char: CHARACTER];
bcplStringPtr: TYPE = POINTER TO bcplStringHeader;
-- Initialization cursor
--iCursor: dsD.CursorBitMap ← ALL[0];
--pCounter: CARDINAL ← 0;
--DisplayInitializationPhase: PROCEDURE =
-- BEGIN
-- iCursor[pCounter MOD 16] ← 177777B;
-- Inline.COPY[@iCursor, 16, dsD.cursorBM];
-- pCounter ← pCounter + 3;
-- RETURN;
-- END;
iCursor: dsD.CursorBitMap ←
[177777B, 177077B, 077776B, 037774B, 017770B, 007760B, 003740B, 001700B,
001100B, 002440B, 004020B, 010410B, 020004B, 040402B, 100001B, 177777B];
sandArray: ARRAY [1 .. 15) OF CARDINAL
← [11, 12, 10, 8, 6, 4, 2, 2, 3, 6, 7, 10, 11, 14];
sandUsed: CARDINAL ← 0;
tick: CARDINAL ← 13;
totalTicks: CARDINAL = 13;
grains: CARDINAL = 53;
DisplayInitializationPhase: PROCEDURE =
BEGIN
incr: INTEGER;
n, m: CARDINAL;
topSlope: CARDINAL = 3;
bottomSlope: CARDINAL = 2;
cursor: POINTER TO PACKED ARRAY [0 .. 16 * 16) OF BOOLEAN ←
LOOPHOLE[@iCursor];
IF (tick ← tick + 1) > totalTicks THEN tick ← 0
ELSE
THROUGH [sandUsed .. MIN[tick * grains / totalTicks, grains]) DO
-- take a grain out of the top non-empty row of sand, favoring the middle.
FOR n DECREASING IN [2 .. 8) DO
IF sandArray[n] >= sandArray[n - 1] + topSlope THEN EXIT;
REPEAT FINISHED => FOR n IN [1 .. 8) DO
IF sandArray[n] # 0 THEN EXIT;
ENDLOOP;
ENDLOOP;
sandArray[n] ← sandArray[n] - 1;
m ← (n * 16) + 7;
incr ← 1;
UNTIL cursor[m] DO
m ← m + incr;
incr ← -incr + (IF incr < 0 THEN 1 ELSE -1);
ENDLOOP;
cursor[m] ← FALSE;
-- put a grain in one of the top non-empty rows of sand, favoring the
-- middle, and using the slope as a determinant of the sand stacking angle.
FOR n IN [8 .. 14) DO
IF sandArray[n] >= sandArray[n + 1] + bottomSlope THEN EXIT;
REPEAT
FINISHED =>
FOR n DECREASING IN [8 .. 15) DO
IF sandArray[n] # 0 THEN EXIT;
ENDLOOP;
ENDLOOP;
sandArray[n] ← sandArray[n] - 1;
m ← (n * 16) + 7;
incr ← 1;
WHILE cursor[m] DO
m ← m + incr;
incr ← -incr + (IF incr < 0 THEN 1 ELSE -1);
ENDLOOP;
cursor[m] ← TRUE;
sandUsed ← sandUsed + 1;
ENDLOOP;
dsD.cursorBM↑ ← iCursor;
END; -- of DisplayInitializationPhase --
AddFileRequests: PROCEDURE =
BEGIN
i: CARDINAL;
FOR i IN [0 .. nLookUps) DO
ImageDefs.AddFileRequest[@fileTable[i]]
ENDLOOP;
END; -- of AddFileRequests --
-- File Cache Pre-loading
-- Note: trailing "." on file names mandatory!
fileTable: ARRAY [0 .. 15) OF ImageDefs.FileRequest ←
[
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend, name: "Laurel.state."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend, name: "DiskDescriptor."L],
[link: , file: NIL, access: SegmentDefs.Read, name: "COM.CM."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend, name: "Laurel.BugReport$."L],
[link: , file: NIL, access: SegmentDefs.Read, name: "Laurel.Profile."L],
[link: , file: NIL, access: SegmentDefs.Read, name: "User.Cm."L],
[link: , file: NIL, access: SegmentDefs.Read, name: "Fonts.widths."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend, name: "REM.CM."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "DMS-99.TMP."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "DMS-98.TMP."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "DMS-97.TMP."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "DMS-96.TMP."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "Active.mail."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend,
name: "Active.mail-dmsTOC."L],
[link: , file: NIL, access: SegmentDefs.ReadWriteAppend, name: "Swatee."L]
];
nLookUps: CARDINAL = LENGTH[fileTable];
nOpen: CARDINAL = 2;
SwitchInterruptProcesses: PROCEDURE =
BEGIN OPEN ProcessDefs;
save: Priority = GetPriority[];
START LOOPHOLE[FrameDefs.GlobalFrame[drD.InterruptProcess], PROGRAM];
SetTimeout[@drD.interruptWakeup, 1];
SetPriority[drD.interruptPriority];
Detach[FORK drD.InterruptProcess];
SetPriority[save];
ForgotOps.disableInterrupt ← TRUE;
END; -- of SwitchInterruptProcesses --
-- *** Main body of PreStopInitialization ***
-- Executed before the STOP in LaurelNub
AddFileRequests[];
DisplayInitializationPhase[]; -- 1 line in cursor
CleanUpAfterJim[];
-- Allocate state heap storage before variable length file lookups.
heapDS ← SegmentDefs.MakeDataSegment
[SegmentDefs.DefaultBase, heapPages, SegmentDefs.HardDown];
DisplayInitializationPhase[]; -- 2 lines in cursor
ResumeNub[sendBug, none];
-- Note: parameters are thrown away by LaurelNub
-- In this hiatus, Mesa will look up all files in the fileTable.
-- Executed after the STOP in LaurelNub
DisplayInitializationPhase[]; -- 3 lines in cursor
-- Set up BackStop
SDDefs.SD[SDDefs.sUncaughtSignal] ← Catcher;
PupDefs.CaptureErrors[CapturePupGlitch];
START disC;
START intC;
START dsD.Display;
DisplayInitializationPhase[]; -- 4 lines in cursor
-- Start the Pup package going, but don’t wait for it.
pupInitializer ← FORK PupInitProcess;
ProcessDefs.Yield[]; --let Pup initialization get started
DisplayInitializationPhase[]; -- 5 lines in cursor
AdjustForExtraMemory[];
VMDefs.InitializeVM[min: 10, max: vmPages, numOps: 15];
-- Now tell the file cache (actually the Alto directory cache)
-- about the files already looked-up.
FOR lookupIndex IN [0 .. nLookUps) DO
entry: POINTER TO ImageDefs.FileRequest ← @fileTable[lookupIndex];
IF entry.file = NIL THEN LOOP;
[] ← Core.InsertInFileCache[entry.name, entry.file.fp, lookupIndex < nOpen];
SegmentDefs.UnlockFile[entry.file];
ENDLOOP;
DisplayInitializationPhase[]; -- 6 lines in cursor
-- Now check if state information is current. If so, read it in. If not,
-- recompute and install it.
exD.InitializeExceptions[];
installError ← none;
IF ~BringInLaurelState[heapDS, FALSE] THEN
BEGIN
SetUpFont[];
installError ← lsD.CreateLaurelState[heapDS];
[] ← BringInLaurelState[heapDS, TRUE];
END
ELSE SetUpFont[];
exD.SetUpExceptionTable[];
SwitchInterruptProcesses[];
IF intC.editorType = modeless THEN
BEGIN
[] ← KeyDefs.ChangeKey[Spare1,
[FALSE, LOOPHOLE[Editor.cancelCode], LOOPHOLE[Editor.cancelCode]]];
[] ← KeyDefs.ChangeKey[Spare2,
[FALSE, LOOPHOLE[Editor.nextCode], LOOPHOLE[Editor.nextCode]]];
[] ← KeyDefs.ChangeKey[LF,
[FALSE, LOOPHOLE[Editor.insertDeletionCode],
LOOPHOLE[Editor.insertDeletionCode]]];
END;
DisplayInitializationPhase[]; -- 7 lines in cursor
-- Set up user name, registry, and password.
userNameString ← Storage.String
[LOOPHOLE[OsStaticDefs.OsStatics.UserName, bcplStringPtr].length];
StringDefs.BcplToMesaString[OsStaticDefs.OsStatics.UserName, userNameString];
FOR i: CARDINAL DECREASING IN [0 .. userNameString.length) DO
IF userNameString[i] = ’.
THEN BEGIN
userRegistryString ← Storage.String[userNameString.length- i-1];
FOR j: CARDINAL IN (i .. userNameString.length) DO
userRegistryString[j - i - 1] ← userNameString[j];
ENDLOOP;
userRegistryString.length ← MIN[userNameString.length - i - 1, 40];
userNameString.length ← i;
EXIT;
END;
REPEAT
FINISHED =>
BEGIN
userRegistryString ← Storage.String[intC.profileRegistry.length];
StringDefs.AppendString[userRegistryString, intC.profileRegistry];
END;
ENDLOOP;
userNameString.length
← MIN[userNameString.length, inD.maxBracketStringLength-userRegistryString.length - 1];
userPasswordString ← Storage.String
[LOOPHOLE[OsStaticDefs.OsStatics.UserPassword, bcplStringPtr].length];
StringDefs.BcplToMesaString[OsStaticDefs.OsStatics.UserPassword, userPasswordString];
intC.user ← Core.DMSUserBlk[userNameString, userRegistryString, userPasswordString];
Core.Login[@intC.user];
intC.userBracketsHouse.text.length ← 0;
StringDefs.AppendString[intC.userBracketsHouse.text, userNameString];
StringDefs.AppendChar[intC.userBracketsHouse.text, ’.];
StringDefs.AppendString[intC.userBracketsHouse.text, userRegistryString];
-- Set up hardcopy host name. To allow a variable host name, the permanent
-- name is allocated from the heap. The state string used originally for the
-- profile value is lost.
hardcopyHostString ← Storage.String[intC.hardcopyHost.length];
StringDefs.AppendString[hardcopyHostString, intC.hardcopyHost];
intC.hardcopyHost ← hardcopyHostString;
intC.keystream ← StreamDefs.GetCurrentKey[];
intC.tocTextNbr.toc ← NIL;
intC.cmTextNbr.message ← vmD.AllocateComposedMessageObject[];
vmD.InitComposedMessage[vmD.ComposedMessage[intC.cmTextNbr.message], ""L];
intC.cmTextNbr.insertionBuffer ← vmD.AllocateComposedMessageObject[];
vmD.InitComposedMessage[intC.cmTextNbr.insertionBuffer, ""L];
intC.cmTextNbr.deletionBuffer ← vmD.AllocateComposedMessageObject[];
vmD.InitComposedMessage[intC.cmTextNbr.deletionBuffer, ""L];
intC.dmTextNbr.message ← vmD.AllocateDisplayMessageObject[];
DisplayInitializationPhase[]; -- 8 lines in cursor
-- Parse the command line for switches, but don’t act on them yet.
commandInCommandLine ← ScanCommandLine[];
SELECT commandInCommandLine FROM
checkOnly, gnmAndStay => intC.audioEnabled ← FALSE;
ENDCASE => intC.audioEnabled ← (intC.newMailTune # NIL);
DisplayInitializationPhase[]; -- 9 lines in cursor
-- Now synchronize with Pup initialization
JOIN pupInitializer;
DisplayInitializationPhase[]; -- 10 lines in cursor
DMSTimeDefs.SetLaurelTime[];
IF intC.gvTestingMode THEN ProtocolDefs.SetTestingMode[];
IF intC.profileRetrieve # NIL THEN
RetrieveDefs.SetMTPRetrieveDefault[intC.profileRetrieve, intC.profileRegistry];
intC.retrieveHandle ←
RetrieveDefs.Create[intC.mailcheckPollingInterval, inD.ReportMBXState];
RetrieveDefs.NewUser[intC.retrieveHandle, intC.userBracketsHouse.text, userPasswordString];
inD.SetTime[];
DisplayInitializationPhase[]; -- 11 lines in cursor
ProcessDefs.Yield[]; -- to let EtherProbe continue
[] ← DiskKDDefs.CloseDiskKD[]; -- Blow the DiskDescriptor out
DisplayInitializationPhase[]; -- 12 lines in cursor
--dsD.SetCursor[hourGlass];
FrameOps.SetReturnLink[LOOPHOLE[ResumeNub, ControlDefs.Port].dest];
END; -- of PreStopInitialization --
END. -- of InitLaurel --