-- MesaExec.Mesa Edited by Sandman on July 1, 1980 8:16 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY BcdOps USING [BcdBase], ControlDefs USING [ ControlModule, GFT, GlobalFrameHandle, NullControl, NullGlobalFrame], CoreSwapDefs USING [CantSwap], ImageDefs USING [StopMesa], IODefs USING [ CR, DEL, LineOverflow, NewLine, ReadChar, ReadID, ReadLine, ReadNumber, Rubout, SP, WriteChar, WriteOctal, WriteString], LoaderOps USING [FileNotFound, Load, New, VersionMismatch], MiscDefs USING [CallDebugger], StringDefs USING [AppendChar, InvalidNumber, LowerCase, StringBoundsFault]; MesaExec: PROGRAM IMPORTS CoreSwapDefs, ImageDefs, IODefs, LoaderOps, MiscDefs, StringDefs = BEGIN -- System Signals are converted to these to prevent NubCommand -- from catching user generated signals Delete: SIGNAL = CODE; -- nee Rubout StringTooLong: ERROR = CODE; -- nee LineOverflow BadFile: ERROR [badname: STRING] = CODE; -- nee FileNameError BadVersion: SIGNAL [badname: STRING] = CODE; -- nee VersionMismatch BadNumber: ERROR = CODE; -- nee InvalidNumber GlobalFrameHandle: TYPE = ControlDefs.GlobalFrameHandle; NullGlobalFrame: GlobalFrameHandle = ControlDefs.NullGlobalFrame; module: STRING ← [40]; defaultframe: GlobalFrameHandle ← NullGlobalFrame; DoCommand: PROCEDURE = BEGIN OPEN ControlDefs; p: PROCESS; f: GlobalFrameHandle; f ← Command[]; IF f # NullGlobalFrame THEN {p ← FORK StartModule[[frame[f]]]; JOIN p; }; RETURN END; Command: PROCEDURE RETURNS [GlobalFrameHandle] = BEGIN OPEN IODefs; nCommand: STRING = "New"L; sCommand: STRING = "Start"L; dCommand: STRING = "Debug"L; qCommand: STRING = "Quit"L; cCommand: STRING = "--"L; c: CHARACTER; f: GlobalFrameHandle; DO WriteEOL[]; WriteChar['>]; SELECT StringDefs.LowerCase[c ← ReadChar[]] FROM 'n => BEGIN WriteString[nCommand]; LoadModule[]; END; 's => BEGIN WriteString[sCommand]; f ← GetFrame[]; WriteEOL[]; RETURN[f]; END; 'd => BEGIN WriteString[dCommand]; Confirm[]; MiscDefs.CallDebugger["You called?"L]; END; 'q => BEGIN WriteString[qCommand]; Confirm[]; ImageDefs.StopMesa[]; END; '- => BEGIN WriteString[cCommand]; GetComment[]; END; CR, SP => NULL; ENDCASE => BEGIN WriteChar[c]; WriteString[" Commands are:"L]; WriteChar[' ]; WriteString[nCommand]; WriteChar[' ]; WriteString[sCommand]; WriteChar[' ]; WriteString[dCommand]; WriteChar[' ]; WriteString[qCommand]; WriteChar[' ]; WriteString[cCommand]; END; ENDLOOP; END; GetComment: PROCEDURE = BEGIN OPEN IODefs; s: STRING ← [256]; ReadLine[s ! Rubout => ERROR Delete; LineOverflow => ERROR StringTooLong]; RETURN END; LoadModule: PROCEDURE = BEGIN OPEN IODefs; i: CARDINAL ← 0; g: ControlDefs.ControlModule; frameLinks: BOOLEAN; WriteString[" Filename: "L]; ReadID[module ! Rubout => ERROR Delete; LineOverflow => ERROR StringTooLong]; frameLinks ← CheckSwitch[module]; DefaultExtension[module, ".bcd"L]; g ← LoadNew[module, frameLinks]; IF g # ControlDefs.NullControl THEN defaultframe ← g.frame; RETURN END; LoadNew: PROCEDURE [name: STRING, framelinks: BOOLEAN] RETURNS [g: ControlDefs.ControlModule] = BEGIN OPEN LoaderOps; bcd: BcdOps.BcdBase; bcd ← Load[name ! BadFile, UNWIND => NULL; ANY => ERROR BadFile[name]]; g ← New[ bcd, framelinks, FALSE ! BadFile, BadVersion, UNWIND => NULL; VersionMismatch => BEGIN SIGNAL BadVersion[name]; RESUME END; FileNotFound => ERROR BadFile[name]; ANY => ERROR BadFile[name]]; IODefs.WriteString[" -- "L]; IODefs.WriteOctal[g]; WriteEOL[]; RETURN END; StartModule: PROCEDURE [f: ControlDefs.ControlModule] = BEGIN IF f.multiple OR ~f.frame.started THEN START LOOPHOLE[f, PROGRAM][ ! ABORTED => CONTINUE] ELSE RESTART LOOPHOLE[f, PROGRAM][ ! ABORTED => CONTINUE]; RETURN END; GetFrame: PROCEDURE RETURNS [f: GlobalFrameHandle] = BEGIN OPEN IODefs; WriteString[" Global frame: "L]; f ← ReadNumber[ defaultframe, 8 ! LineOverflow => ERROR StringTooLong; Rubout => ERROR Delete; StringDefs.InvalidNumber => ERROR BadNumber]; IF ControlDefs.GFT[f.gfi].frame # f THEN BEGIN WriteString[" not a global frame!"L]; ERROR ABORTED END; defaultframe ← f; RETURN END; CheckSwitch: PROCEDURE [s: STRING] RETURNS [BOOLEAN] = BEGIN i, newLength, oldLength: CARDINAL; oldLength ← s.length; FOR i DECREASING IN [0..oldLength) DO IF s[i] = '/ THEN BEGIN newLength ← i; EXIT END; REPEAT FINISHED => RETURN[TRUE]; ENDLOOP; s.length ← newLength; FOR i IN [newLength + 1..oldLength) DO IF s[i] = 'l THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE] END; DefaultExtension: PROCEDURE [idstring: STRING, ext: STRING] = BEGIN i: CARDINAL; FOR i IN [0..idstring.length) DO IF idstring[i] = '. THEN EXIT; REPEAT FINISHED => FOR i IN [0..ext.length) DO StringDefs.AppendChar[ idstring, ext[i] ! StringDefs.StringBoundsFault => ERROR StringTooLong]; ENDLOOP; ENDLOOP; END; Confirm: PROCEDURE = BEGIN OPEN IODefs; c: STRING = " [Confirm] "L; WriteString[c]; SELECT ReadChar[] FROM CR => NULL; DEL => ERROR Delete; ENDCASE => BEGIN WriteChar['?]; DO IF ReadChar[] = DEL THEN ERROR Delete ELSE WriteChar['?]; ENDLOOP; END; WriteChar[CR]; RETURN END; WriteEOL: PROCEDURE = BEGIN OPEN IODefs; IF ~NewLine[] THEN WriteChar[CR]; RETURN END; Done: SIGNAL = CODE; ErrorName: TYPE = {XXX, file, number, toolong, nodebug, aborted, diffver}; WriteError: PROCEDURE [error: ErrorName] = BEGIN IODefs.WriteString[ SELECT error FROM file => "!File: "L, number => "!Number"L, toolong => "!String too long"L, nodebug => "External Debugger not installed, type DEL to abort "L, aborted => "...Aborted..."L, diffver => " referenced in different versions"L, ENDCASE => " XXX"L] END; StartExecutive: PROCEDURE = BEGIN OPEN IODefs; DO DoCommand[ ! Delete => BEGIN WriteError[XXX]; CONTINUE END; ABORTED => CONTINUE; BadFile --[badname: STRING]-- => BEGIN WriteEOL[]; WriteError[file]; WriteString[badname]; CONTINUE END; BadNumber => BEGIN WriteEOL[]; WriteError[number]; CONTINUE END; StringTooLong => BEGIN WriteEOL[]; WriteError[toolong]; CONTINUE END; CoreSwapDefs.CantSwap => BEGIN WriteEOL[]; WriteError[nodebug]; UNTIL ReadChar[] = DEL DO WriteChar['?] ENDLOOP; WriteError[aborted]; CONTINUE END; BadVersion --[badname: STRING]-- => BEGIN WriteEOL[]; WriteError[file]; WriteString[badname]; WriteError[diffver]; RESUME END; UNWIND => CONTINUE]; ENDLOOP; END; StartExecutive[]; END..