// PupTimeInit.bcpl // Last modified March 4, 1979 2:33 AM by Boggs get "pup0.decl" get "pup1.decl" get "PupTimeServ.decl" external [ // outgoing procedures CreateTimeServ; DestroyTimeServ SetTimeCorrection; SetTimeZone; SetTimeDST // incoming procedures TimeServ; TimeServCtx Allocate; Free; Zero; MoveBlock InitializeContext; Enqueue; Unqueue // incoming statics @ts; @ms ] compileif alto then [ external [ ReadCalendar ] ] //---------------------------------------------------------------------------- let CreateTimeServ() be //---------------------------------------------------------------------------- [ ts = Allocate(ms>>MS.zone, lenTS); Zero(ts, lenTS) ts>>TS.stats.version = timeStatsVersion ts>>TS.ctx = InitializeContext(Allocate(ms>>MS.zone, 20), 20, TimeServCtx) Enqueue(ms>>MS.ctxQ, ts>>TS.ctx) compileif alto then [ ReadCalendar(lv ts>>TS.altoClk) ] ts>>TS.dontKnowTime = nova // assume Alto calendar clock is correct ] //---------------------------------------------------------------------------- and DestroyTimeServ() be //---------------------------------------------------------------------------- [ Unqueue(ms>>MS.ctxQ, ts>>TS.ctx) Free(ms>>MS.zone, ts>>TS.ctx) Free(ms>>MS.zone, ts) ] //---------------------------------------------------------------------------- and SetTimeCorrection(seconds, sign) be //---------------------------------------------------------------------------- [ ts>>TS.doCorrect = true ts>>TS.corrSign = sign MoveBlock(lv ts>>TS.correction, table [ 1; 20864 ], 2) // 86400 seconds/day Divide32x16(lv ts>>TS.correction, seconds) MoveBlock(lv ts>>TS.corrCount, lv ts>>TS.correction, 2) ts>>TS.stats.correction = sign? seconds, -seconds ] //---------------------------------------------------------------------------- and SetTimeZone(zoneS, zoneH, zoneM) be //---------------------------------------------------------------------------- [ ts>>TS.timeParams.zoneS = zoneS ts>>TS.timeParams.zoneH = zoneH ts>>TS.timeParams.zoneM = zoneM ] //---------------------------------------------------------------------------- and SetTimeDST(beginDST, endDST) be //---------------------------------------------------------------------------- [ ts>>TS.timeParams.beginDST = beginDST ts>>TS.timeParams.endDST = endDST ] //---------------------------------------------------------------------------- and Divide32x16(lvNumber, divisor) = valof //---------------------------------------------------------------------------- // Unsigned divide the 32-bit number at @lvNumber, // put the quotient back in @lvNumber, and return the remainder. [ manifest div = alto? 61021b, 73101b (table [ #55001 // sta 3 1 2 #155000 // mov 2 3 // save stack pointer #102400 // mkzero 0 0 #27404 // lda 1 @4 3 // get high dividend #31405 // lda 2 5 3 // get divisor div // div // ac0 ← remainder, ac1 ← quotient #401 // nop #47404 // sta 1 @4 3 // store high quotient #11404 // isz 4 3 #27404 // lda 1 @4 3 // get low dividend div // div // ac0 ← remainder, ac1 ← quotient #401 // nop #47404 // sta 1 @4 3 // store low quotient #171000 // mov 3 2 // restore stack pointer #35001 // lda 3 1 2 #1401 // jmp 1 3 ])() ]