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