-- File: TroubleAltoLocked.mesa, Last Edit: HGM March 10, 1981 4:52 AM DIRECTORY Ascii USING [CR], ControlDefs USING [StateVector, ControlLink], FrameDefs USING [MakeCodeResident, GlobalFrame], FrameOps USING [GetReturnLink], ImageDefs USING [PuntMesa], Mopcodes USING [zSTARTIO], Process USING [Detach, GetPriority, Priority, SetPriority, SetTimeout, SecondsToTicks], ProcessDefs USING [DisableInterrupts, EnableInterrupts], ProcessOps USING [CurrentPSB], PSBDefs, StreamDefs USING [StreamHandle, CleanupDiskStream], String USING [AppendChar, AppendString, AppendOctal], SDDefs USING [SD, sIOResetBits, sSwapTrap], FileSW USING [GetFile], Put USING [Line], TextSW USING [GetEOF, SetEOF], Time USING [AppendCurrent], TrapOps USING [ReadOTP], Window USING [Handle], Trouble USING [Bug]; TroubleAltoLocked: MONITOR IMPORTS FrameDefs, FrameOps, ImageDefs, Process, ProcessDefs, StreamDefs, String, Time, TrapOps, FileSW, Put, TextSW, Trouble EXPORTS Trouble SHARES ProcessDefs = -- CurrentPSB BEGIN -- This module needs to be locked in core. realTrapRoutine: PROCEDURE = SDDefs.SD[SDDefs.sSwapTrap]; okToSwap: Process.Priority ← 1; SetCodeTrap: PUBLIC PROCEDURE [new: Process.Priority] = BEGIN Process.SetPriority[Process.GetPriority[]]; -- be sure it is in Process.SetPriority[okToSwap ← new]; END; -- See <Mesa>Resident.CodeTrap TrapCodeNotIn: PROCEDURE = BEGIN -- Breakpoints in this routine won't work. state: ControlDefs.StateVector; dest: ControlDefs.ControlLink; badGuy: PROCEDURE; -- so the debugger will print it for us ProcessDefs.DisableInterrupts[]; state ← STATE; dest ← TrapOps.ReadOTP[]; -- real destination badGuy ← LOOPHOLE[dest]; state.dest ← realTrapRoutine; state.source ← FrameOps.GetReturnLink[]; -- The keyboard process runs at priority 5, Control-Swat and clock updater run at priority 6. Control-Swat will generate CodeTraps because it calls various cleanup procs on the way to the debugger if nothing else is running. IF ProcessOps.CurrentPSB.priority # okToSwap AND ProcessOps.CurrentPSB.priority # 5 AND ProcessOps.CurrentPSB.priority # 6 THEN BEGIN CheckForRecursion[]; CodeFaultFromInterruptRoutine[badGuy]; END; ProcessDefs.EnableInterrupts[]; -- This actually transfers to the real CodeTrap in Resident routine, which uses OTPreg. Since there is no way to reload OTPreg, you can't continue from here if you have generated another CodeTrap. RETURN WITH state; END; CodeFaultFromInterruptRoutine: PROCEDURE [dest: UNSPECIFIED] = BEGIN e: STRING = [100]; String.AppendString[e, "CodeTrap from Interrupt routine, dest="L]; String.AppendOctal[e, dest]; Trouble.Bug[e]; END; recursion: BOOLEAN ← FALSE; CheckForRecursion: PUBLIC PROCEDURE = BEGIN ProcessDefs.DisableInterrupts[]; IF recursion THEN BEGIN StartIO: PROCEDURE [WORD] = MACHINE CODE BEGIN Mopcodes.zSTARTIO END; StartIO[SDDefs.SD[SDDefs.sIOResetBits]]; -- Kill Ethernets turnOffSLA[]; -- Kill SLA and PR ImageDefs.PuntMesa[]; END; SDDefs.SD[SDDefs.sSwapTrap] ← realTrapRoutine; recursion ← TRUE; END; PupGlitchTrap: PUBLIC PROCEDURE [why: ERROR] = BEGIN e: STRING = [100]; CheckForRecursion[]; String.AppendString[e, "PupPackage Troubles, arg="L]; String.AppendOctal[e, why]; Trouble.Bug[e]; END; turnOffSLA: PROCEDURE ← {}; SetRamUnBooter: PUBLIC PROCEDURE [new: PROCEDURE] = BEGIN turnOffSLA ← new; END; -- This stuff lives here because it is hot and fits on the page. window: Window.Handle ← NIL; stream: StreamDefs.StreamHandle ← NIL; WrapTypescriptFile: PUBLIC PROCEDURE [wh: Window.Handle, pages: CARDINAL] = BEGIN window ← wh; stream ← FileSW.GetFile[window].s; Process.Detach[FORK Watcher[LONG[pages]*512]]; END; Watcher: ENTRY PROCEDURE [limit: LONG CARDINAL] = BEGIN pause: CONDITION; afterStartup, recent, now: LONG CARDINAL; Process.SetTimeout[@pause, Process.SecondsToTicks[15]]; THROUGH [0..3*4) DO WAIT pause; ENDLOOP; afterStartup ← TextSW.GetEOF[window]; DO -- forever WAIT pause; now ← TextSW.GetEOF[window]; IF recent = now THEN LOOP; ForceOutTypescriptFile[]; recent ← now; IF now < limit THEN LOOP; ResetTypescriptFile[afterStartup]; ENDLOOP; END; ForceOutTypescriptFile: PUBLIC PROCEDURE = BEGIN IF stream # NIL THEN StreamDefs.CleanupDiskStream[stream]; END; ResetTypescriptFile: PROCEDURE [where: LONG CARDINAL] = BEGIN text: STRING = [100]; TextSW.SetEOF[window, where]; THROUGH [0..5) DO String.AppendChar[text, Ascii.CR]; ENDLOOP; Time.AppendCurrent[text]; String.AppendString[text, " Typescript file reset."L]; Put.Line[window, text]; END; FrameDefs.MakeCodeResident[FrameDefs.GlobalFrame[TrapCodeNotIn]]; SDDefs.SD[SDDefs.sSwapTrap] ← TrapCodeNotIn; END.