-- IntervalTimerHeadDorado.mesa
-- Last Edited by: Taft, March 31, 1983 9:12 am
-- Last Edited by: Stewart, January 1, 1984 6:24 pm
DIRECTORY
Basics USING [LowHalf],
DeviceCleanup USING [Await, Item, Reason],
DoradoInputOutput USING [SetIntervalTimer],
IntervalTimerFace,
Loader USING [ MakeProcedureResident, MakeGlobalFrameResident ],
PrincOpsUtils USING [AllocateNakedCondition, LongNotify],
ProcessorFace USING [GetClockPulses];
IntervalTimerHeadDorado: MONITOR
IMPORTS Basics, DeviceCleanup, DoradoInputOutput, Loader, PrincOpsUtils, ProcessorFace
EXPORTS IntervalTimerFace =
BEGIN OPEN IntervalTimerFace;
csb: LONG POINTER TO IntervalTimerCSB = LOOPHOLE[LONG[177422B]];
IntervalTimerCSB: TYPE = RECORD [
wakeups: WORD];
nakedCondition: LONG POINTER TO CONDITION;
expirationTime: ClockPulses;
SetExpirationTime: PUBLIC PROCEDURE [time: ClockPulses] =
BEGIN
expirationTime ← time;
DoradoInputOutput.SetIntervalTimer[Basics.LowHalf[expirationTime]];
IF LOOPHOLE[ProcessorFace.GetClockPulses[] - expirationTime, INT] >= 0 THEN
PrincOpsUtils.LongNotify[nakedCondition];
END;
Wait: PUBLIC ENTRY PROCEDURE =
BEGIN
DO
WAIT nakedCondition;
IF LOOPHOLE[ProcessorFace.GetClockPulses[] - expirationTime, INT] >= 0 THEN EXIT;
SetExpirationTime[expirationTime];
ENDLOOP;
END;
exists: PUBLIC BOOLEAN ← TRUE;
InitializeCleanup: PROCEDURE =
BEGIN
item: DeviceCleanup.Item;
reason: DeviceCleanup.Reason;
savedCSB: IntervalTimerCSB;
DO
reason ← DeviceCleanup.Await[@item];
SELECT reason FROM
turnOff, kill =>
BEGIN
savedCSB ← csb^;
csb.wakeups ← 0;
END;
turnOn =>
BEGIN
csb^ ← savedCSB;
SetExpirationTime[expirationTime];
END;
ENDCASE
ENDLOOP
END;
Start: PROCEDURE =
BEGIN
[cv: nakedCondition, mask: csb.wakeups] ← PrincOpsUtils.AllocateNakedCondition[];
Loader.MakeProcedureResident[InitializeCleanup];
Loader.MakeGlobalFrameResident[InitializeCleanup];
InitializeCleanup[];
-- RemainingHeads.Start[];
END;
Start[];
END.
January 1, 1984 6:24 pm, Stewart, added Loader procedures on advice of Taft