-- File: PupTimeServerHot.mesa, Last Edit: HGM September 24, 1980 1:51 PM DIRECTORY Inline USING [LongDivMod, DIVMOD, LowHalf, HighHalf], InlineDefs USING [MesaToBcplLongNumber], Process USING [Detach], System USING [GetGreenwichMeanTime], Time USING [AppendCurrent], Clock USING [TimeParameters, GetTimeParms, TimeIsKnown], TimeServerDefs USING [ PupTimeFormat, TimeStatsEntry, timeStatsRequest, timeStatsReply, timeVersion, resetTimeRequest, resetTimeReply, lockTimeRequest, lockTimeReply, statText, statTenex, statAlto, ResetTime], StatsDefs USING [StatCounterIndex, StatIncr, StatGetCounter], PupDefs USING [ PupBuffer, MoveStringBodyToPupBuffer, ReturnPup, ReturnFreePupBuffer], PupTypes USING [PupAddress, fillInPupAddress, dateTextIs, dateTextRequest]; PupTimeServerHot: PROGRAM IMPORTS Inline, InlineDefs, Process, System, Time, Clock, TimeServerDefs, StatsDefs, PupDefs EXPORTS TimeServerDefs = BEGIN OPEN StatsDefs, PupDefs, TimeServerDefs; locked, parmsOk: PUBLIC BOOLEAN ← FALSE; correction: PUBLIC INTEGER ← 0; resetAddress: PUBLIC PupTypes.PupAddress ← PupTypes.fillInPupAddress; PupTimeServer: PUBLIC PROCEDURE [b: PupBuffer] = BEGIN IF (~Clock.TimeIsKnown[] OR locked OR ~parmsOk) AND (b.pupType = PupTypes.dateTextRequest OR b.pupType = dateTenexRequest OR b.pupType = dateAltoRequest) THEN BEGIN ReturnFreePupBuffer[b]; RETURN; END; SELECT b.pupType FROM PupTypes.dateTextRequest => BEGIN s: STRING = [30]; Time.AppendCurrent[s, TRUE]; MoveStringBodyToPupBuffer[b, s]; ReturnPup[b, PupTypes.dateTextIs, s.length]; StatIncr[statText]; END; dateTenexRequest => BEGIN OPEN Inline; now: LONG CARDINAL ← System.GetGreenwichMeanTime[]; days, seconds: LONG CARDINAL; q1, q2, r1, r2: CARDINAL; -- Q1, R1 ← AltoTime/43200, Q1 = halfDays, R1 = seconds -- Q2, R2 ← Q1/2, Q2 = days, R2 = halfDays (0 or 1) -- Days ← Q2 + 15385 -- Seconds ← R1 + R2*43200 [q1, r1] ← LongDivMod[now, 43200]; [q2, r2] ← DIVMOD[q1, 2]; days ← LOOPHOLE[LONG[q2] + LONG[15385]]; seconds ← LOOPHOLE[LONG[r1] + LONG[r2*43200]]; -- Yetch, I think this is what MAXC wants b.pupWords[0] ← HighHalf[days]*256 + LowHalf[days]/256; b.pupWords[1] ← LowHalf[days]*256 + HighHalf[seconds]; b.pupWords[2] ← LowHalf[seconds]; ReturnPup[b, dateTenexIs, 6]; StatIncr[statTenex]; END; dateAltoRequest => BEGIN parms: Clock.TimeParameters ← Clock.GetTimeParms[]; LOOPHOLE[@b.pupWords, LONG POINTER TO PupTimeFormat]↑ ← [time: InlineDefs.MesaToBcplLongNumber[System.GetGreenwichMeanTime[]], zoneS: IF parms.zone > 0 THEN west ELSE east, zoneH: ABS[parms.zone], zoneM: parms.minutes, beginDST: parms.beginDst, endDST: parms.endDst]; ReturnPup[b, dateAltoIs, 2*SIZE[PupTimeFormat]]; StatIncr[statAlto]; END; timeStatsRequest => BEGIN OPEN TimeServerDefs; tse: LONG POINTER TO TimeStatsEntry ← LOOPHOLE[@b.pupWords]; tse↑ ← [version: timeVersion, tenexRequests: InlineDefs.MesaToBcplLongNumber[ StatGetCounter[statTenex]], stringRequests: InlineDefs.MesaToBcplLongNumber[ StatGetCounter[statText]], altoRequests: InlineDefs.MesaToBcplLongNumber[ StatGetCounter[statAlto]], correction: correction, resetAddress: resetAddress]; ReturnPup[b, timeStatsReply, 2*SIZE[TimeStatsEntry]]; END; lockTimeRequest => BEGIN locked ← TRUE; ReturnPup[b, lockTimeReply, 0]; END; resetTimeRequest => BEGIN locked ← FALSE; Process.Detach[FORK ResetTime[b.address]]; ReturnPup[b, resetTimeReply, 0]; END; ENDCASE => BEGIN ReturnFreePupBuffer[b]; END; END; END.