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