-- JaMInterrupt.mesa
-- Written by John Warnock, April 10, 1979
-- Last changed by Doug Wyatt, June 5, 1981 3:53 PM

DIRECTORY
JaMInterruptDefs,
JaMExecDefs USING [SetWakeUp],
FrameDefs USING [GlobalFrame, MakeCodeResident, UnlockCode],
Inline USING [BITAND, BITNOT, BITOR, BITSHIFT],
KeyDefs USING [Keys],
Process USING [DisableTimeout, GetPriority, Priority, SetPriority],
ProcessDefs USING [CV, DIW, InterruptLevel];

JaMInterrupt: MONITOR
IMPORTS JaMExecDefs,FrameDefs,Inline,Process
EXPORTS JaMInterruptDefs =
BEGIN

level: ProcessDefs.InterruptLevel = 11;
mask: CARDINAL = Inline.BITSHIFT[1,level];
Keywakeup: CONDITION;
DCBHead: POINTER TO CARDINAL = LOOPHOLE[420B];
dcbChain: CARDINAL ← 0;
displayOn: BOOLEAN←TRUE;

prevwakeup: BOOLEAN←FALSE;
prevtoggle: BOOLEAN←FALSE;

stop: BOOLEAN ← FALSE;

JaMBreak: ENTRY PROCEDURE =
BEGIN
wakeup,toggle: BOOLEAN;
originalPriority: Process.Priority ← Process.GetPriority[];
Process.SetPriority[originalPriority+1];
DO
IF stop THEN EXIT;
WAIT Keywakeup;

-- RightShift-Swat means break
wakeup←(KeyDefs.Keys.Spare3=down AND KeyDefs.Keys.RightShift=down);
IF wakeup AND ~prevwakeup THEN JaMExecDefs.SetWakeUp[TRUE];
prevwakeup←wakeup;

-- RightShift-Spare2 means toggle display
toggle←(KeyDefs.Keys.Spare2=down AND KeyDefs.Keys.RightShift=down);
IF toggle AND ~prevtoggle THEN displayOn←~displayOn;
prevtoggle←toggle;

-- fix display state
IF displayOn#(dcbChain=0) THEN
BEGIN
IF dcbChain=0
THENBEGIN --turn off display
dcbChain ← DCBHead↑;
DCBHead↑ ← 0;
END
ELSEBEGIN --turn on display
DCBHead↑ ← dcbChain;
dcbChain ← 0;
END;
END
ENDLOOP;
Process.SetPriority[originalPriority];
END;

SetDisplayOn
: PUBLIC ENTRY PROCEDURE[on: BOOLEAN] =
BEGIN displayOn←on END;


breakProcess: PROCESS ← NIL;

InitJaMBreak: PUBLIC PROCEDURE =
BEGIN
FrameDefs.MakeCodeResident[FrameDefs.GlobalFrame[JaMBreak]];
Process.DisableTimeout[@Keywakeup];
ProcessDefs.CV[level] ← @Keywakeup;
ProcessDefs.DIW↑ ← Inline.BITOR[ProcessDefs.DIW↑,mask];
breakProcess ← FORK JaMBreak[];
END;

KillJaMBreak: PUBLIC PROCEDURE =
BEGIN
stop ← TRUE;
JOIN breakProcess; breakProcess ← NIL;
ProcessDefs.DIW↑ ← Inline.BITAND[ProcessDefs.DIW↑,Inline.BITNOT[mask]];
ProcessDefs.CV[level] ← NIL;
FrameDefs.UnlockCode[FrameDefs.GlobalFrame[JaMBreak]];
END;

END.

DKW March 25, 1980 1:34 PM
added SetDisplayState

DKW April 7, 1980 9:44 AM
pressing the interrupt key combination now causes just one wakeup

DKW September 29, 1980 12:00 PM
WakeUp[] changed to SetWakeUp[TRUE]

DKW December 8, 1980 5:46 PM
uses new interfaces Inline, Process

DKW June 5, 1981 3:54 PM
add KillJaMBreak