-- IntervalTimerHeadDorado.mesa -- Last Edited by: Taft, March 31, 1983 9:12 am DIRECTORY DeviceCleanup USING [Await, Item, Reason], DoradoInputOutput USING [SetIntervalTimer], HeadStartChain USING [Start], Inline USING [LowHalf], IntervalTimerFace, ProcessInternal USING [AllocateNakedCondition], ProcessOperations USING [LongNotify], ProcessorFace USING [GetClockPulses]; IntervalTimerHeadDorado: MONITOR IMPORTS DeviceCleanup, DoradoInputOutput, RemainingHeads: HeadStartChain, Inline, ProcessInternal, ProcessOperations, ProcessorFace EXPORTS HeadStartChain, 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[Inline.LowHalf[expirationTime]]; IF LOOPHOLE[ProcessorFace.GetClockPulses[] - expirationTime, INT] >= 0 THEN ProcessOperations.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: PUBLIC PROCEDURE = BEGIN [cv: nakedCondition, mask: csb.wakeups] ← ProcessInternal.AllocateNakedCondition[]; InitializeCleanup[]; RemainingHeads.Start[]; END; END.