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