MODULE LIB_pom(IDENT='V04-000',ADDRESSING_MODE(EXTERNAL=GENERAL)) =
BEGIN
LIBRARY 'SYS$LIBRARY:starlet';
GLOBAL ROUTINE LIB_pom(time,phase_code,age) =
!
PHASE_OF_MOON.B32 - Phase of the Moon routine LIB_pom
! status.wlc.v = LIB_pom(time.rq.r,phase_code.wbu.r,age.wbu.r)
! Arguments:
! TIME - optional time for computation; address 0 = now.
! PHASE_CODE - code for the phase:
! 0 = new, 1 = waxing crescent, 2 = first quarter
! 3 = waxing gibbous, 4 = full, 5 = waning gibbous,
! 6 = last quarter, 7 = waning crescent.
! AGE - days since new moon.
! All arguments are optional.
!Times: The moon's period is taken as 2551440 seconds (29d 12h44m).
! The phases are New: 0 sec, FQ: 638100 sec, Full: 1276127 sec, LQ: 1913785.
! Each of these primary phases is held to last 12 hours (43200 sec) to each
! side of the given value. Computations are made in 10 second units to avoid
! EDIV overflow.
BEGIN
! EXTERNAL LITERAL
! LIB__early;
LITERAL
period = 255144;
LITERAL
LIB__early = 0;
LOCAL
timadr : VECTOR[2],
basetime : VECTOR[2] INITIAL(%X'85E8A000',%X'86C199'), !28-JAN-79 0120
seconds,
phase_table : VECTOR[9] INITIAL(4320,59466,68106,123252,131892,
187038,195678,250824,255144);
BUILTIN
EDIV, SUBM,
actualcount,
nullparameter;
MACRO test(val) = (LOCAL sts; IF NOT (sts = (val)) THEN RETURN .sts)%;
IF nullparameter(1) THEN test($gettim(TIMADR=timadr))
ELSE IF actualcount() EQL 1 THEN RETURN 1
ELSE
(CH$move(8,.time,timadr);
IF (.timadr[1] EQL 0) AND (.timadr[0] EQL 0)
THEN test($gettim(TIMADR=timadr))
);
SUBM(2,basetime,timadr,timadr); IF .timadr[1] LEQ 0 THEN RETURN LIB__early;
EDIV(%REF(100000000),timadr,seconds,basetime);
seconds = .seconds MOD period;
IF NOT nullparameter(2) THEN
(.phase_code)<0,8,0> = (INCR i FROM 0 TO 8 DO
IF .seconds LSS .phase_table[.i] THEN EXITLOOP .i) MOD 8;
IF NOT nullparameter(3) THEN
(.age)<0,8,0> = .seconds/(24*360);
1
END;
END
ELUDOM