// GateConTime.bcpl -- talks to the Time server // Last modified July 2, 1983 10:26 PM by Boggs get "Pup0.decl" get "Pup1.decl" get "PupTimeServ.decl" get "AltoDefs.d" external [ // outgoing procedures CreateTimeCtx; RestartTime; Time; TimeSummary // incoming procedures OpenLevel1Socket; CloseLevel1Socket; GetBuf; ReleasePBI; CompletePup Zero; MoveBlock; ReturnFrom; Allocate; Free; Enqueue; Dequeue InitializeContext; Block; SetTimer; TimerHasExpired Ws; Wss; Puts; PutTemplate; GetString; GetPartner; Confirm; GetNumber SendCommand; MiscCmd; UNPACKDT; WRITEUDT; PrintPort TopLevel; ResetCmdMenu; CreateCmdBox; BoxProc; Noop // incoming statics dsp; sysZone; ctxQ; wheel; gcHost; oldStatsQ ] static @tu structure TU: // tu -> this 'global frame' for this module [ soc word // -> PupSoc stats word // -> Time Server Stats block timer word // update stats when this expires ] manifest lenTU = size TU/16 //---------------------------------------------------------------------------- let CreateTimeCtx() be //---------------------------------------------------------------------------- [ Enqueue(ctxQ, InitializeContext(Allocate(sysZone, 150), 150, TimeCtx)) tu = Allocate(sysZone, lenTU); Zero(tu, lenTU) tu>>TU.soc = Allocate(sysZone, lenPupSoc); OpenLevel1Socket(tu>>TU.soc) ] //---------------------------------------------------------------------------- and RestartTime() be //---------------------------------------------------------------------------- [ SetTimer(lv tu>>TU.timer, 0) if tu>>TU.stats ne 0 then [ Enqueue(oldStatsQ, tu>>TU.stats); tu>>TU.stats = 0 ] ] //---------------------------------------------------------------------------- and Time() be //---------------------------------------------------------------------------- [ ResetCmdMenu() CreateCmdBox(TopLevel, "TopLevel") CreateCmdBox(AltoTime, "Alto") CreateCmdBox(TenexTime, "Tenex") CreateCmdBox(StringTime, "String") CreateCmdBox(SurveyTime, "Survey") if gcHost ne 0 then [ CreateCmdBox(TimeStats, "TimeStats") if wheel then [ CreateCmdBox(LockServer, "Lock") CreateCmdBox(ResetTime, "Reset") ] ] // ResetCmdMenu destroyed the BoxQ which BoxProc is following. // If we just return now, BoxProc will get horribly confused. // So don't let it continue: force a return from BoxProc. ReturnFrom(BoxProc) ] //---------------------------------------------------------------------------- and TimeSummary(stream) be //---------------------------------------------------------------------------- [ if tu>>TU.stats ne 0 then PutTemplate(stream, "Time: $EUD ", lv tu>>TU.stats>>Stats.altoReqs) ] //---------------------------------------------------------------------------- and SurveyTime() be //---------------------------------------------------------------------------- [ let net = GetNumber("*NNet number: ") let soc = tu>>TU.soc let pbi = GetBuf(soc) pbi>>PBI.pup.dPort.net = net pbi>>PBI.pup.dPort.socket↑2 = psMiscServ CompletePup(pbi, ptAltoTimeRequest, pupOvBytes) let timer = nil; SetTimer(lv timer, 1000) [ Block() repeatuntil TimerHasExpired(lv timer) % soc>>PupSoc.iQ.head ne 0 if TimerHasExpired(lv timer) break let pbi = Dequeue(lv soc>>PupSoc.iQ) if pbi>>PBI.pup.type eq ptAltoTimeReply then PrintAlto(pbi) ReleasePBI(pbi) ] repeat ] //---------------------------------------------------------------------------- and TimeCtx(ctx) be //a context //---------------------------------------------------------------------------- [ Block() repeatuntil TimerHasExpired(lv tu>>TU.timer) & gcHost ne 0 SetTimer(lv tu>>TU.timer, 1000) // 10 sec let pbi = GetBuf(tu>>TU.soc) pbi>>PBI.pup.dPort.socket↑2 = psMiscServ pbi = SendCommand(pbi, ptTimeStatsRequest, pupOvBytes, (tu>>TU.stats? 1, 3)) if pbi ne 0 then [ let stats = lv pbi>>PBI.pup.words if pbi>>PBI.pup.type eq ptTimeStatsReply & stats>>Stats.version eq timeStatsVersion then [ if tu>>TU.stats then Enqueue(oldStatsQ, tu>>TU.stats) let lenStatBlock = (pbi>>PBI.pup.length-pupOvBytes+1)/2 tu>>TU.stats = Allocate(sysZone, lenStatBlock) MoveBlock(tu>>TU.stats, stats, lenStatBlock) ] ReleasePBI(pbi) ] ] repeat //---------------------------------------------------------------------------- and TimeStats() be //---------------------------------------------------------------------------- [ let oldStats = tu>>TU.stats SetTimer(lv tu>>TU.timer, 0) let timer = nil; SetTimer(lv timer, 500) // 5 sec Block() repeatuntil TimerHasExpired(lv timer) % tu>>TU.stats ne oldStats test tu>>TU.stats ne oldStats ifso Ws("*NTime Server stats:") ifnot [ Ws("*NThe Time Server doesn't answer.") if tu>>TU.stats ne 0 then Ws("*NWhen last heard from its stats were:") ] if tu>>TU.stats ne 0 then PutTemplate(dsp, "*NAlto: $EUD Tenex: $EUD String: $EUD Correction: $D Set from: $P", lv tu>>TU.stats>>Stats.altoReqs, lv tu>>TU.stats>>Stats.tenexReqs, lv tu>>TU.stats>>Stats.stringReqs, tu>>TU.stats>>Stats.correction, PrintPort, lv tu>>TU.stats>>Stats.resetPort) ] //---------------------------------------------------------------------------- and ResetTime() be //---------------------------------------------------------------------------- [ let name = vec 128; unless GetString("*NReset time from: ", name) return let port = vec lenPort unless GetPartner(name, dsp, port, 0, psMiscServ) return MiscCmd(ptResetTimeRequest, ptResetTimeReply, Noop, port, lenPort*2) ] //---------------------------------------------------------------------------- and LockServer() be if Confirm("*NLock time server") then //---------------------------------------------------------------------------- MiscCmd(ptLockTimeRequest, ptLockTimeReply, Noop) //---------------------------------------------------------------------------- and AltoTime() be MiscCmd(ptAltoTimeRequest, ptAltoTimeReply, PrintAlto) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintAlto(pbi) be //---------------------------------------------------------------------------- [ let tp = lv pbi>>PBI.pup.words↑3 let temp = vec 2; MoveBlock(temp, timeParams, 2) timeParams>>LTP.sign = tp>>TimeParams.zoneS timeParams>>LTP.zoneH = tp>>TimeParams.zoneH timeParams>>LTP.zoneM = tp>>TimeParams.zoneM timeParams>>LTP.beginDST = tp>>TimeParams.beginDST timeParams>>LTP.endDST = tp>>TimeParams.endDST let utv = vec 7; UNPACKDT(lv pbi>>PBI.pup.words, utv) MoveBlock(timeParams, temp, 2) PutTemplate(dsp, "*N$P: $P", PrintPort, lv pbi>>PBI.pup.sPort, WRITEUDT, utv) PutTemplate(dsp, ", Zone $C$D:$2F0D, DST $UD, $UD", (tp>>TimeParams.zoneS? $-, $+), tp>>TimeParams.zoneH, tp>>TimeParams.zoneM, tp>>TimeParams.beginDST, tp>>TimeParams.endDST) ] //---------------------------------------------------------------------------- and TenexTime() be MiscCmd(ptTenexTimeRequest, ptTenexTimeReply, PrintTenex) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintTenex(pbi) be //---------------------------------------------------------------------------- [ PutTemplate(dsp, "*N$P: ", PrintPort, lv pbi>>PBI.pup.sPort) for i = 1 to pbi>>PBI.pup.length-pupOvBytes do PutTemplate(dsp, "$3UF0O ", pbi>>PBI.pup.bytes↑i) ] //---------------------------------------------------------------------------- and StringTime() be MiscCmd(ptStringTimeRequest, ptStringTimeReply, PrintString) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and PrintString(pbi) be //---------------------------------------------------------------------------- [ PutTemplate(dsp, "*N$P: ", PrintPort, lv pbi>>PBI.pup.sPort) for i = 1 to pbi>>PBI.pup.length-pupOvBytes do Puts(dsp, pbi>>PBI.pup.bytes↑i) ]