-- MesaNub.Mesa Edited by Sandman on September 12, 1980 8:43 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoFileDefs USING [CFA, FA], BcdOps USING [BcdBase], ControlDefs USING [ControlModule, GlobalFrameHandle, NullGlobalFrame], DisplayDefs USING [DestroyDisplay, DisplayControl], ImageDefs USING [AddFileRequest, FileRequest, ImageTime], IODefs USING [CR, SP, NewLine, WriteChar, WriteLine, WriteOctal, WriteString], LoaderOps USING [FileNotFound, Load, New, VersionMismatch], MiscDefs USING [CallDebugger], MiscOps USING [bypassExec, ReleaseDebuggerBitmap], NubOps USING [], SegmentDefs USING [FileHandle, Read, ReleaseFile, UnlockFile], StreamDefs USING [ CreateByteStream, DestroyKeyHandler, GetFA, JumpToFA, Read, StartKeyHandler, StreamHandle], StringDefs USING [AppendChar, AppendString, LowerCase], Storage USING [Node, CopyString, Free, FreeString], TimeDefs USING [AppendDayTime, DefaultTime, UnpackDT]; MesaNub: PROGRAM IMPORTS DisplayDefs, ImageDefs, IODefs, LoaderOps, MiscDefs, MiscOps, SegmentDefs, StreamDefs, StringDefs, Storage, TimeDefs EXPORTS MiscDefs, NubOps = BEGIN OPEN SegmentDefs; BadFile: SIGNAL [name: STRING] = CODE; BadVersion: SIGNAL [name: STRING] = CODE; cmFile: FileHandle ← NIL; AddComCmRequest: PUBLIC PROCEDURE = BEGIN OPEN Storage; comcmRequest ← Node[SIZE[ImageDefs.FileRequest]]; comcmRequest↑ ← [name: CopyString["Com.Cm."L], file: NIL, access: Read, link:]; ImageDefs.AddFileRequest[comcmRequest]; IF cmFile # NIL THEN {UnlockFile[cmFile]; ReleaseFile[cmFile]; cmFile ← NIL}; END; RemoveComCmRequest: PUBLIC PROCEDURE = BEGIN cmFile ← comcmRequest.file; Storage.FreeString[comcmRequest.name]; Storage.Free[comcmRequest]; END; comcmRequest: POINTER TO ImageDefs.FileRequest; Done: SIGNAL = CODE; Switches: TYPE = PACKED ARRAY CHARACTER ['a..'z] OF BOOLEAN; DefaultSwitches: Switches = [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, --'a..'i FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, --'j..'r TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE]; --'s..'z switches: Switches; postAnyway, alreadyBasic, doneHearld: BOOLEAN; ProcessSwitches: PROCEDURE [s: STRING] = BEGIN i: CARDINAL; c: CHARACTER; inverse: {this, next, no} ← no; FOR i IN [0..s.length) DO SELECT c ← StringDefs.LowerCase[s[i]] FROM IN ['a..'z] => switches[c] ← inverse # this; '- => inverse ← next; ENDCASE; inverse ← IF inverse = next THEN this ELSE no; ENDLOOP; END; GetToken: PROCEDURE [ com: StreamDefs.StreamHandle, token, ext, switches: STRING] = BEGIN s: STRING; c: CHARACTER; token.length ← ext.length ← switches.length ← 0; s ← token; WHILE ~com.endof[com] DO SELECT (c ← com.get[com]) FROM IODefs.SP, IODefs.CR => IF token.length # 0 OR ext.length # 0 OR switches.length # 0 THEN RETURN; '. => s ← ext; '/ => s ← switches; ENDCASE => StringDefs.AppendChar[s, c]; ENDLOOP; RETURN END; cfa: AltoFileDefs.CFA; CommandLineCFA: PUBLIC PROCEDURE RETURNS [POINTER TO AltoFileDefs.CFA] = BEGIN RETURN[@cfa] END; LoadSystems: PUBLIC PROCEDURE [skipImage: BOOLEAN ← FALSE] = BEGIN user: ControlDefs.ControlModule; p: PROCESS; cfa.fp ← cmFile.fp; switches ← DefaultSwitches; IF skipImage THEN SkipImage[@cfa.fa]; DO switches ← DefaultSwitches; user ← LoadUser[@cfa.fa ! Done => EXIT]; CheckSwitches[]; IF switches['s] AND user # [frame[ControlDefs.NullGlobalFrame]] THEN BEGIN p ← FORK StartModule[user]; JOIN p END; ENDLOOP; END; StartModule: PROCEDURE [f: ControlDefs.ControlModule] = BEGIN IF f.multiple OR ~f.frame.started THEN START LOOPHOLE[f, PROGRAM][ ! ABORTED => CONTINUE]; RETURN END; LoadUser: PROCEDURE [fa: POINTER TO AltoFileDefs.FA] RETURNS [user: ControlDefs.ControlModule] = BEGIN OPEN IODefs, StreamDefs; com: StreamHandle; name: STRING ← [40]; ext: STRING ← [10]; switch: STRING ← [5]; com ← CreateByteStream[cmFile, Read]; user ← [frame[ControlDefs.NullGlobalFrame]]; BEGIN StreamDefs.JumpToFA[com, fa ! ANY => GO TO finished]; GetToken[com, name, ext, switch]; IF name.length = 0 AND switch.length = 0 THEN GO TO finished; StreamDefs.GetFA[com, fa]; com.destroy[com]; ProcessSwitches[switch]; IF switches['b] THEN ConvertToBasic[]; IF name.length # 0 AND ~switches['c] THEN BEGIN IF ext.length = 0 THEN ext ← "bcd"L; IF ~alreadyBasic OR postAnyway THEN PostName[name]; StringDefs.AppendChar[name, '.]; StringDefs.AppendString[name, ext]; user ← LoadNew[name ! BadVersion => {BadVersionError[name]; RESUME}; BadFile => {BadFileError[name]; GOTO exit}]; IF ~alreadyBasic OR postAnyway THEN PostAddress[user]; END; IF switches['c] THEN ProcessSwitches[name]; EXITS exit => NULL; finished => BEGIN com.destroy[com ! ANY => CONTINUE]; SIGNAL Done; END; END; END; LoadNew: PROCEDURE [name: STRING] RETURNS [ControlDefs.ControlModule] = BEGIN OPEN LoaderOps; bcd: BcdOps.BcdBase; bcd ← Load[name ! BadFile, UNWIND => NULL; ANY => ERROR BadFile[name]]; RETURN[ New[bcd, ~switches['l], FALSE ! BadFile, BadVersion, UNWIND => NULL; VersionMismatch => {SIGNAL BadVersion[name]; RESUME}; FileNotFound => ERROR BadFile[name]; ANY => ERROR BadFile[name]]]; END; ConvertToBasic: PUBLIC PROCEDURE = BEGIN IF alreadyBasic THEN RETURN; alreadyBasic ← TRUE; DisplayDefs.DestroyDisplay[]; StreamDefs.DestroyKeyHandler[]; END; IsBasic: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN RETURN[alreadyBasic]; END; EnableOutput: PUBLIC PROCEDURE = BEGIN postAnyway ← TRUE; END; PostName: PROCEDURE [name: STRING] = BEGIN OPEN IODefs; IF ~doneHearld THEN WriteHerald[]; WriteChar['>]; WriteString[name]; END; PostAddress: PROCEDURE [user: UNSPECIFIED] = BEGIN OPEN IODefs; WriteString[" -- "]; WriteOctal[user]; WriteChar[CR]; END; BadFileError: PROCEDURE [s: STRING] = { IF alreadyBasic THEN RETURN; IF ~IODefs.NewLine[] THEN IODefs.WriteChar[IODefs.CR]; IODefs.WriteString["!File: "L]; IODefs.WriteString[s]}; BadVersionError: PROCEDURE [s: STRING] = { IF alreadyBasic THEN RETURN; IF ~IODefs.NewLine[] THEN IODefs.WriteChar[IODefs.CR]; IODefs.WriteString["!File: "L]; IODefs.WriteString[s]; IODefs.WriteString[" referenced in different versions"L]}; WriteHerald: PUBLIC PROCEDURE = BEGIN OPEN TimeDefs; h: STRING = "Alto/Mesa 6.0 of "L; time: STRING ← [18]; AppendDayTime[time, UnpackDT[ImageDefs.ImageTime[]]]; time.length ← time.length - 3; IODefs.WriteString[h]; IODefs.WriteLine[time]; time.length ← 0; AppendDayTime[time, UnpackDT[DefaultTime]]; time.length ← time.length - 3; IODefs.WriteLine[time]; doneHearld ← TRUE; END; SkipImage: PROCEDURE [fa: POINTER TO AltoFileDefs.FA] = BEGIN OPEN IODefs, StreamDefs; com: StreamHandle; name: STRING ← [40]; ext: STRING ← [10]; switch: STRING ← [5]; com ← CreateByteStream[cmFile, Read]; GetToken[com, name, ext, switch]; GetFA[com, fa]; com.destroy[com]; ProcessSwitches[switch]; CheckSwitches[]; END; CheckSwitches: PROCEDURE = BEGIN IF switches['q] THEN MiscOps.bypassExec ← TRUE; IF switches['k] THEN MiscOps.ReleaseDebuggerBitmap[]; IF switches['b] THEN ConvertToBasic[]; IF switches['d] THEN MiscDefs.CallDebugger["You Called?"L]; END; -- Main body StreamDefs.StartKeyHandler; -- Start keyboard process AddComCmRequest[]; START DisplayDefs.DisplayControl; STOP; RemoveComCmRequest[]; RESTART DisplayDefs.DisplayControl; postAnyway ← alreadyBasic ← doneHearld ← FALSE; LoadSystems[TRUE]; END...