-- file: LaurelInterrupt
-- derived from Resident.mesa of September 2, 1980 7:53 AM;
-- edited by Sandman on September 2, 1980 7:53 AM
-- edited by Levin on January 16, 1981 3:19 PM

DIRECTORY
AltoFileDefs,
BcplOps,
ControlDefs,
CoreSwapDefs,
DiskDefs,
drD: FROM "LaurelDriverDefs",
ImageDefs,
InlineDefs,
KeyDefs,
Mopcodes,
OsStaticDefs,
ProcessDefs,
ProcessOps,
SDDefs;

LaurelInterrupt: MONITOR
IMPORTS ImageDefs, InlineDefs, BcplOps, ProcessDefs
EXPORTS drD =
BEGIN

interruptWakeup: PUBLIC CONDITION;

GetDebugger: PROCEDURE = MACHINE CODE {Mopcodes.zKFCB, SDDefs.sInterrupt};

TimeData: POINTER TO TimeDataRecord = LOOPHOLE[572B];
TimeDataRecord: TYPE = MACHINE DEPENDENT RECORD [
timeOfDay: InlineDefs.BcplLongNumber,
milliSeconds: InlineDefs.BcplLongNumber,
timeBase: InlineDefs.BcplLongNumber];

InterruptProcess: PUBLIC ENTRY PROCEDURE =
BEGIN
keys: POINTER TO KeyDefs.KeyBits ← KeyDefs.Keys;
interruptState: KeyDefs.updown ← up;
pp: ProcessDefs.Priority;
SV: POINTER TO ARRAY ProcessDefs.Priority OF ControlDefs.StateVector =
LOOPHOLE[ProcessOps.FirstStateVector↑];
timeData: POINTER TO TimeDataRecord ← TimeData;
RealTimeClock: POINTER TO CARDINAL = LOOPHOLE[430B];
clockSecond: POINTER TO InlineDefs.BcplLongNumber;
DO
WAIT interruptWakeup;
clockSecond ← OsStaticDefs.OsStatics.ClockSecond;
IF RealTimeClock↑ - timeData.timeBase.highbits > clockSecond.highbits THEN
BEGIN OPEN InlineDefs;
timeData.timeOfDay ← MesaToBcplLongNumber[
BcplToMesaLongNumber[timeData.timeOfDay] + 1];
timeData.milliSeconds ← MesaToBcplLongNumber[
BcplToMesaLongNumber[timeData.milliSeconds] + 1000];
timeData.timeBase ← MesaToBcplLongNumber[
BcplToMesaLongNumber[timeData.timeBase] +
BcplToMesaLongNumber[clockSecond↑]];
END;
IF keys.LeftShift = down AND keys.Spare2 = down AND keys.Spare3 = down THEN
BEGIN
ProcessDefs.DisableInterrupts[];
UNTIL DiskDefs.NextDiskCommand↑ = DiskDefs.CBNil DO ENDLOOP;
IF keys.Ctrl = down THEN
BEGIN
code: ARRAY [0..2) OF WORD ← [77410B, 1400B];
[] ← BcplOps.BcplJSR[code: JSR, address: @code, arg: NIL];
ProcessDefs.EnableInterrupts[];
END
ELSE
BEGIN
SwatVector: POINTER TO POINTER TO RECORD [
fill: ARRAY [0..4) OF WORD, swatee: AltoFileDefs.CFP] =
LOOPHOLE[567B];
[] ← BcplOps.BcplOutLd[code: OutLd, file: @SwatVector.swatee, message: NIL];
ProcessDefs.EnableInterrupts[];
ImageDefs.AbortMesa[];
END;
END
ELSE
IF keys.Ctrl = down AND (keys.Spare3 = down OR keys.FR5 = down) THEN
BEGIN
IF interruptState = up AND CoreSwapDefs.PuntInfo↑ # LOOPHOLE[0]
AND CoreSwapDefs.PuntInfo.pDebuggerFP ~= NIL THEN
BEGIN
interruptState ← down;
FOR pp IN [0..drD.interruptPriority) DO
SV[pp].instbyte ← Mopcodes.zBRK;
WAIT interruptWakeup;
IF SV[pp].instbyte = 0 THEN EXIT ELSE SV[pp].instbyte ← 0;
REPEAT FINISHED => GetDebugger[ ! ABORTED => CONTINUE];
ENDLOOP;
END;
END
ELSE interruptState ← up;
ENDLOOP;
END;


END.