-- File: TroubleAlto.mesa,  Last Edit: HGM  February 20, 1981  12:14 AM

DIRECTORY
  AltoHardware USING [BankRegisters],
  Ascii USING [CR],
  BcplOps USING [BcplJSR],
  CoreSwapDefs USING [PuntInfo],
  FrameOps USING [MyLocalFrame],
  Runtime USING [CallDebugger],
  StreamDefs USING [StreamHandle, CleanupDiskStream],
  StringDefs USING [MesaToBcplString],

  SDDefs USING [SD, sUncaughtSignal],
  String USING [AppendChar, AppendOctal, AppendString],
  Time USING [AppendCurrent],
  FileSW USING [GetFile],
  Window USING [Handle],
  StatsDefs USING [StatUpdate],
  Trouble USING [CheckForRecursion];

TroubleAlto: PROGRAM
  IMPORTS
    BcplOps, FrameOps, Runtime, StreamDefs, String, StringDefs, Time, FileSW,
    StatsDefs, Trouble
  EXPORTS Trouble =
  BEGIN

  SetUncaughtSignalTrap: PUBLIC PROCEDURE =
    BEGIN SDDefs.SD[SDDefs.sUncaughtSignal] ← Catcher; END;

  -- See DebugNub.Catcher for args and such

  Catcher: PROCEDURE [msg: UNSPECIFIED, signal: SIGNAL, frame: POINTER] =
    BEGIN
    e: STRING = [100];
    Trouble.CheckForRecursion[];
    String.AppendString[e, "Uncaught Signal, signal="L];
    String.AppendOctal[e, signal];
    String.AppendString[e, ", msg="L];
    String.AppendOctal[e, msg];
    Bug[e];
    END;

  Bug: PUBLIC PROCEDURE [e: STRING] =
    BEGIN
    text: STRING = [200];
    debugger: BOOLEAN = CoreSwapDefs.PuntInfo.pDebuggerFP # NIL;
    StatsDefs.StatUpdate[];
    String.AppendChar[text, Ascii.CR];
    Time.AppendCurrent[text];
    String.AppendString[text, "  ******  "L];
    String.AppendString[text, e];
    String.AppendChar[text, Ascii.CR];
    String.AppendChar[text, Ascii.CR];
    String.AppendString[text, "My Local frame = "L];
    String.AppendOctal[text, FrameOps.MyLocalFrame[]];
    String.AppendChar[text, Ascii.CR];
    String.AppendChar[text, Ascii.CR];
    WriteStringToTypescriptFile[text];
    String.AppendString[
      text,
      IF debugger THEN
      "
Please boot to get out of the Debugger.
Kill or Quit may clobber Swatee.
"L
      ELSE "
Please boot to get out of Swat.  ↑K or ↑P may clobber Swatee.
"L];
    String.AppendChar[text, Ascii.CR];
    IF debugger THEN Runtime.CallDebugger[text];
    CallSwat[text];
    DO ENDLOOP;
    END;

  CallSwat: PUBLIC PROCEDURE [text: STRING] =
    BEGIN
    swatText: ARRAY [0..128) OF WORD;
    break: ARRAY [0..2) OF WORD ← [77402B, 1400B];
    AltoHardware.BankRegisters[DWT] ← LOOPHOLE[0];
    StringDefs.MesaToBcplString[text, LOOPHOLE[@swatText]];
    [] ← BcplOps.BcplJSR[JSR, @break, @swatText];
    END;

  -- Since the problem is reasonably likely to include the window stuff, we try to bypass as much of it as we can, and put the bits directly on the disk.

  magic: Window.Handle ← NIL;

  SetMagicWindow: PUBLIC PROCEDURE [wh: Window.Handle] = BEGIN magic ← wh; END;

  WriteStringToTypescriptFile: PROCEDURE [s: STRING] =
    BEGIN
    stream: StreamDefs.StreamHandle;
    IF magic = NIL THEN RETURN;
    stream ← FileSW.GetFile[magic].s;
    FOR i: CARDINAL IN [0..s.length) DO stream.put[stream, s[i]]; ENDLOOP;
    StreamDefs.CleanupDiskStream[stream];
    END;

  END.