-- file: BackStop.Mesa -- edited by Levin, March 13, 1981 4:44 PM -- edited by Schroeder, March 15, 1981 2:45 PM -- edited by Brotz, November 13, 1981 9:27 AM DIRECTORY Ascii USING [CR], ControlDefs USING [ControlLink, FrameHandle, NullFrame], csD: FROM "CoreStreamDefs" USING [Close, OpenFromName, StreamHandle, Write], drD: FROM "LaurelDriverDefs" USING [], dsD: FROM "DisplayDefs" USING [DCBorg, SetCursor], Editor USING [RefreshSoThatFirstCharStartsLine], exD: FROM "exceptionDefs" USING [AppendExceptionString, autoErrorReport, cannotProceed, ClearExceptionsRegion, DisplayException, DisplayExceptionLine, DisplayExceptionStringOnLine, FlashExceptionsRegion, GetExceptionString, maxExceptionStringLength, mustEndSession, noBugReportFile, recursiveTrouble, SysBugSignal, systemError, tryToContinue], FrameOps USING [MyLocalFrame], ImageDefs USING [StopMesa], inD: FROM "InteractorDefs" USING [CharIndex, MessageTextNbrPtr, SetCaretBlinking, StopBlinkingCaret, TextSelection], Inline USING [BITAND, DIVMOD], intCommon USING [bugReportee, cmTextNbr, editorType, imageFileName, newTargetSelection, pendingDeleteSetByControl, target, timeMayBeBogus, versionHouse], ModuleName USING [ControlLinkToModuleName], opD: FROM "OperationsDefs" USING [FileError], PupDefs USING [GetPupAddress, PupAddress], SegmentDefs USING [memConfig], String USING [AppendString], TrapDefs USING [ParityError, PhantomParityError], vmD: FROM "VirtualMgrDefs" USING [CharIndex, ComposedMessage, ComposedMessagePtr, GetMessageChar, GetMessageSize, InsertFileInMessage], VMDefs USING [CantReadBackingStore, CantWriteBackingStore, Error]; BackStop: PROGRAM IMPORTS csD, dsD, Editor, exD, FrameOps, ImageDefs, Inline, intC: intCommon, inD, ModuleName, opD, PupDefs, SegmentDefs, String, TrapDefs, vmD, VMDefs EXPORTS drD = BEGIN OPEN inD; recursionDepth: INTEGER _ -1; oldSignalMessage: STRING _ "Signal lost."; PupTrouble: ERROR[why: UNSPECIFIED] = CODE; -- ProcessBugReport is called during initialization if a /b switch is encountered. ProcessBugReport: PUBLIC PROCEDURE = BEGIN state: {initial, firstCR, endOfHeader, secondCR} _ initial; selectionStart, selectionEnd: CARDINAL; mnp: inD.MessageTextNbrPtr = intC.cmTextNbr; message: vmD.ComposedMessagePtr = vmD.ComposedMessage[mnp.message]; modelessEditor: BOOLEAN = (intC.editorType = modeless); i: CharIndex; char: CHARACTER; vmD.InsertFileInMessage [0, message, "Laurel.BugReport$"L ! opD.FileError => GO TO MalFormedMessage]; FOR i IN [0 .. vmD.GetMessageSize[message]) DO char _ vmD.GetMessageChar[message, i]; SELECT state FROM initial => IF char = Ascii.CR THEN state _ firstCR; firstCR => IF char = Ascii.CR THEN {state _ endOfHeader; selectionStart _ i+1} ELSE state _ initial; endOfHeader => IF char = Ascii.CR THEN state _ secondCR; secondCR => IF char = Ascii.CR THEN {selectionEnd _ i-1; EXIT} ELSE state _ endOfHeader; ENDCASE; REPEAT FINISHED => GO TO MalFormedMessage; ENDLOOP; intC.target _ inD.TextSelection [mnp: mnp, start: selectionStart, end: selectionEnd, point: selectionStart, key: 0, mode: char, pendingDelete: intC.editorType = modeless]; intC.newTargetSelection _ TRUE; intC.pendingDeleteSetByControl _ FALSE; message.formatStart _ message.formatEnd _ 0; mnp.haveMessage _ TRUE; IF modelessEditor THEN inD.StopBlinkingCaret[]; Editor.RefreshSoThatFirstCharStartsLine[firstChar: 0, firstLine: mnp.lines, mnp: mnp]; IF modelessEditor THEN inD.SetCaretBlinking[selectionStart, mnp]; EXITS MalFormedMessage => exD.DisplayException[exception: exD.noBugReportFile]; END; -- of ProcessBugReport -- CapturePupGlitch: PUBLIC PROCEDURE [why: UNSPECIFIED -- DriverDefs.GlitchType --] = BEGIN ERROR PupTrouble[why]; END; -- of CapturePupGlitch -- out: csD.StreamHandle _ NIL; WriteString: PROCEDURE [s: STRING] = BEGIN FOR i: CARDINAL IN [0 .. s.length) DO csD.Write[out, s[i]]; ENDLOOP; END; -- of WriteString -- -- Message Formatting Procedures StuffOctal: PROCEDURE [value: UNSPECIFIED, s: STRING, start: CARDINAL, places: CARDINAL _ 6] = BEGIN FOR i: CARDINAL DECREASING IN [start..start+places) DO digit: CARDINAL; [value, digit] _ Inline.DIVMOD[value, 8]; s[i] _ LOOPHOLE[digit + 60B, CHARACTER]; ENDLOOP; END; -- of StuffOctal -- DumpCallStack: PROCEDURE = BEGIN OPEN ControlDefs; moduleName: STRING _ [20]; pcTemplate: STRING _ ", xxxxxx "L; localFrame: ControlLink _ FrameOps.MyLocalFrame[].returnlink; THROUGH [0..100) DO SELECT localFrame.tag FROM frame => BEGIN OPEN f:localFrame.frame; IF @f = NullFrame THEN EXIT; ModuleName.ControlLinkToModuleName[localFrame, moduleName]; WriteString[moduleName]; StuffOctal[IF f.pc < 0 THEN (-f.pc) * 2 + 1 ELSE f.pc * 2, pcTemplate, 2]; WriteString[pcTemplate]; localFrame _ f.returnlink; END; ENDCASE => BEGIN WriteString["Stack end "L]; ModuleName.ControlLinkToModuleName[localFrame, moduleName]; WriteString[moduleName]; csD.Write[out, Ascii.CR]; EXIT; END; ENDLOOP; csD.Write[out, Ascii.CR]; END; -- of DumpCallStack -- WriteGoryDetails: PROCEDURE = BEGIN OPEN SegmentDefs; s: STRING _ " (nnn#nnn#) with "L; rest: STRING _ "MDS: nn Banks: nnnnnn"L; ucode: STRING _ " code: nnnnnn"L; me: PupDefs.PupAddress; WriteString[" "L]; WriteString[ SELECT memConfig.AltoType FROM AltoI => "Alto I"L, AltoII => "Alto II"L, AltoIIXM => "Alto II XM"L, D0 => "Dolphin"L, Dorado => "Dorado"L, ENDCASE => "IBM 360/15"L]; PupDefs.GetPupAddress[@me, "ME"L]; StuffOctal[me.net, s, 2, 3]; StuffOctal[me.host, s, 6, 3]; WriteString[s]; IF memConfig.AltoType < D0 THEN WriteString[SELECT memConfig.controlStore FROM Ram0 => "Ram only "L, RamandRom => "2K Rom "L, Ram3k => "3K Ram "L, ENDCASE => "Paper tape "L]; IF memConfig.xmMicroCode THEN WriteString["XMcode "L]; IF memConfig.useXM THEN WriteString["using XM "L]; StuffOctal[memConfig.mdsBank, rest, 5, 2]; StuffOctal[memConfig.banks, rest, 15]; WriteString[rest]; IF memConfig.AltoType < D0 THEN {StuffOctal[memConfig.mesaMicrocodeVersion, ucode, 8]; WriteString[ucode]}; END; -- of WriteGoryDetails -- Oops: PROCEDURE = BEGIN exD.FlashExceptionsRegion[]; UNTIL UserWants[] = terminate DO ENDLOOP; -- Die[]; END; -- of Oops -- Die: PROCEDURE = BEGIN dsD.DCBorg^ _ LOOPHOLE[0]; -- keep display tidy ImageDefs.StopMesa[]; END; -- of Die -- UserWants: PROCEDURE RETURNS[{tryIt,terminate}] = BEGIN mouseButton: POINTER TO UNSPECIFIED = LOOPHOLE[177030B]; redBlue: UNSPECIFIED = 4+2; yellow: UNSPECIFIED = 1; UNTIL Inline.BITAND[mouseButton^,yellow] = 0 DO IF Inline.BITAND[mouseButton^,redBlue] = 0 THEN RETURN[terminate]; ENDLOOP; RETURN[tryIt]; END; -- of UserWants -- Catcher: PUBLIC PROCEDURE [msg: UNSPECIFIED, signal: SIGNAL[UNSPECIFIED], frame: ControlDefs.FrameHandle] = BEGIN i: CARDINAL; savedCursor: ARRAY [0 .. 15] OF CARDINAL; pCursor: POINTER TO ARRAY [0 .. 15] OF CARDINAL = LOOPHOLE[431B]; errorCursor: ARRAY [0 .. 15] OF CARDINAL = [34034B, 42042B, 101102B, 101202B, 101204B, 42210B, 34160B, 0, 176174B, 101202B, 101200B, 176174B, 100002B, 100202B, 100174B, 0]; moduleName: STRING _ [20]; twoCRs: STRING _ " "L; headerPart: STRING _ "Subject: Error Report To: "L; bodyPart: STRING _ "Please replace this paragraph with a brief description of what you were doing when Laurel broke, then ""Deliver"" this message. (Be sure to include the last command you invoked.) After the message is delivered, you can continue to use Laurel as usual."L; parityErrorMessage: STRING _ "Parity error at ??????."L; -- 28 spaces required after msg^ signalMessage: STRING _ "Signal xxxxxx in "L; msgMessage: STRING _ "msg xxxxxx, msg^ "L; SELECT (recursionDepth _ recursionDepth+1) FROM 0 => NULL; 1 => BEGIN exceptionString: STRING _ [exD.maxExceptionStringLength]; pCursor^ _ errorCursor; exD.GetExceptionString[exD.recursiveTrouble, exceptionString]; String.AppendString[exceptionString, intC.bugReportee]; exD.AppendExceptionString[exD.mustEndSession, exceptionString]; exD.DisplayExceptionStringOnLine[exceptionString, 1]; exD.DisplayExceptionStringOnLine[oldSignalMessage, 2]; Oops[]; END; ENDCASE => DO ENDLOOP; savedCursor _ pCursor^; pCursor^ _ errorCursor; SELECT signal FROM LOOPHOLE[TrapDefs.PhantomParityError, SIGNAL[UNSPECIFIED]], TrapDefs.ParityError => BEGIN IF signal = TrapDefs.ParityError THEN StuffOctal[msg, parityErrorMessage, 16]; exD.DisplayExceptionStringOnLine[parityErrorMessage, 1]; exD.DisplayExceptionLine[exD.tryToContinue, 2]; exD.FlashExceptionsRegion[]; IF UserWants[] = terminate THEN Die[]; pCursor^ _ savedCursor; recursionDepth _ -1; exD.ClearExceptionsRegion[]; intC.timeMayBeBogus _ TRUE; RETURN; --resume the parity error END; exD.SysBugSignal => IF ~LOOPHOLE[msg, BOOLEAN] THEN Oops[]; LOOPHOLE[VMDefs.CantReadBackingStore, SIGNAL [UNSPECIFIED] ], LOOPHOLE[VMDefs.CantWriteBackingStore, SIGNAL [UNSPECIFIED] ], LOOPHOLE[VMDefs.Error, SIGNAL [UNSPECIFIED] ] => BEGIN exD.DisplayExceptionStringOnLine["Disk error"L, 1]; exD.DisplayExceptionLine[exD.cannotProceed, 2]; Oops[]; END; ENDCASE; --remember this instance of signalMessage for possible recursive error oldSignalMessage _ signalMessage; --prepare signal message StuffOctal[signal, signalMessage, 7]; ModuleName.ControlLinkToModuleName[LOOPHOLE[signal], moduleName]; StuffOctal[msg, msgMessage, 4]; IF LOOPHOLE[msg, CARDINAL] > 1400B THEN FOR i _ 17, i + 7 WHILE i < 39 DO StuffOctal[LOOPHOLE[msg + (i - 17) / 7, POINTER]^, msgMessage, i]; ENDLOOP; exD.DisplayExceptionLine[exD.systemError, 1]; exD.DisplayExceptionLine[exD.autoErrorReport, 2]; exD.FlashExceptionsRegion[]; IF UserWants[] = terminate THEN Die[]; dsD.SetCursor[hourGlass]; out _ csD.OpenFromName["Laurel.BugReport$"L, byte, overwrite]; WriteString[headerPart]; WriteString[intC.bugReportee]; WriteString[twoCRs]; WriteString[bodyPart]; WriteString[twoCRs]; WriteString[intC.versionHouse.text]; WriteGoryDetails[]; WriteString[twoCRs]; WriteString[signalMessage]; WriteString[moduleName]; csD.Write[out, Ascii.CR]; WriteString[msgMessage]; WriteString[twoCRs]; DumpCallStack[]; csD.Close[out]; IF intC.imageFileName # NIL THEN BEGIN out _ csD.OpenFromName["Rem.cm"L, byte, overwrite]; WriteString[intC.imageFileName]; WriteString["/b"L]; csD.Write[out, Ascii.CR]; csD.Close[out]; END; Die[]; END; -- of Catcher -- END. -- of BackStop --z20461q(529)\f1