[comp.sys.handhelds] A Sun Clock for the HP 48sx

elliott@veronica.cs.wisc.edu (James Elliott) (04/28/91)

I've had my HP 48sx for a month now, and it seemed like time to write
a sizable program for it, just to achieve a sense of proper ownership.
Actually, a better explanation for my motivation involves the fact
that I have a lot of icky class projects coming due and I need better
and better distractions from that ugly realization...

One of my all-time favorite UNIX workstation programs is called
"sunclock", and it shows the regions of the Earth which are in
daylight by drawing the sunlight on a Mercator projection map of the
globe. It seemed to me that it was a moral imperative that my
calculator should be able to do this too. So, Wednesday night I set
about re-writing the program in RPL. On Thursday night I had a working
version; since then I've come up with a set of improvements to make it
need less room, update faster, and generally work well in its new HP
handheld environment.

So here is an HP version of sunclock! I'm posting both an ASCII
version, and a uuencoded binary version. The ASCII one has been
commented, the binary is faster to download.

SunClk is a directory which contains all the programs and variables
needed to implement the program. When you go into the directory,
you'll see a menu with "NOW", "THEN", "HELP", "ABOUT" and "TZ" as the
first five entries. The first thing you should do is set TZ to the
difference between your current time zone and UTC. For example, I am
presently in CDT, U.S. Central Daylight savings Time. That's five
hours west of Greenwich, so I store -5 in TZ.

HELP gives you brief help about the package, ABOUT gives credits for
various aspects of its design and implementation.

Pressing "NOW" will draw the state of the Earth as it is the moment
you press the button. This will take about a minute the first time,
since it will probably have to compute the daylight widths from
scratch. However, subsequent runs will be a lot faster, until the
sun's declination changes enough to force a recomputation. Once the
first map display is complete, it will be updated roughly once every
ten seconds (taking longer if changes need to be made).

To end the program, hit any key other than ON/ATTN. In a few seconds
it will notice the keypress, stop whatever it is doing, and clean up
after itself before exiting (so you don't get garbage in your variable
menu). If you accidentally hit ON, you can manually purge the
variables that are before "NOW" in the menu. Or, they'll be cleaned up
on the next run.

Pressing "THEN" will let you specify a particular date and time for
which you'd like to see the daylight pattern. It has an interface that
is very similar to the setting of an alarm; you edit the date and time
presented by entering numbers and hitting ">DATE", ">TIME" or "A/PM".
Partial dates are defaulted to the displayed day/year. Once you've
entered the time you'd like to see, press "GO", and the map will be
displayed. This is probably going to take about a minute, since the
sun will likely be in a very different place from the last computation
performed. Once the map is drawn, the program will terminate. (There
is no updating to do, since you've requested just one time to view.)

Again, if you want to interrupt the program before it draws or
finishes the map, you can press any key other than ON/ATTN and it will
stop shortly.

Of particular viewing interest this year are March 20 and September 23
(the first days of spring and of autumn, respectively).

If you have the ticking clock display enabled (system flag -40, or
"CLK" on the second page of the "MODES" menu) the current date and
time will be drawn at the bottom of the map on each update. Around the
transitions between summer and winter, it will probably be difficult
to read, because the terminator boundaries will fall right in the
middle of the text.

Anyway, I think it's a lot of fun, I hope other people enjoy it too.
Let me know if you like it!

Here's the ASCII version:

--------------->8--------Cut here--------8<-----------------
%%HP: T(3)A(R)F(.);
@ Directory: SunClk
@ Checksum: # 40750d  Bytes: 8805.5
DIR
  Now
@ Put the current date and time into TM and DT, convert to Julian
@ date/time, and call SunClk, the driver program.
    \<< DATE TIME
'TM' STO 'DT' STO
GTime 1 'STAT' STO
SunClk
    \>>
  Then
@ Create a temporary menu that allows specification of an arbitrary
@ date and time, and display the current settings. Trap errors in case
@ an invalid date or time is entered, so garbage isn't left on the
@ stack.
    \<< { { ">DATE"
@ Menu key for setting the date to view.
      \<< \-> i
        \<< DT \-> d
          \<< i
            IF DUP
DUP IP ==
@ If only the month was entered, default the rest from the previous
@ setting.
            THEN d
FP +
            ELSE
              IF
DUP FP 100 * DUP IP
==
@ Similarly, if the year is missing, provide the default.
              THEN
d 100 * FP 100 / +
              END
            END
'DT' STO
@ Update the date to reflect their changes, fixing things if there is
@ an error.
            IFERR
ShwTm
            THEN
ERRM 3 DISP 2 WAIT
DROP DROP d 'DT'
STO ShwTm
            END
          \>>
        \>>
      \>> } { ">TIME"
@ Menu key for setting the time to view. Very similar to above.
      \<< \-> i
        \<< TM \-> t
          \<< i 'TM'
STO
            IFERR
ShwTm
            THEN
ERRM 3 DISP 2 WAIT
DROP DROP t 'TM'
STO ShwTm
            END
          \>>
        \>>
      \>> } { "A/PM"
@ Toggle AM vs. PM
      \<< TM 12 - DUP
        IF 0 <
        THEN 24 +
        END 'TM'
STO ShwTm
      \>> } { } { } {
"Go"
@ Use the specified time; convert it to Julian time and call SunClk,
@ the driver program, restoring the normal menu.
      \<< 0 MENU
GTime 0 'STAT' STO
SunClk
      \>> } } TMENU
@ Okay, the temporary menu is built; now show what the default time
@ and date are (these are the ones used for the last display.)
ShwTm
    \>>


@ Provide brief instructions. Blank the menu while waiting for
@ keypresses between screens.
  Help
    \<< CLLCD { }
TMENU
"Press NOW for current"
1 DISP
"daylight map, or THEN"
2 DISP
"to pick a day & time."
3 DISP
"Set TZ to your time"
5 DISP
"zone (eg. CDT = -5)."
6 DISP -1 WAIT DROP
CLLCD
"To interrupt, press"
1 DISP
"any key other than"
2 DISP
"ON/ATTN, and it will"
3 DISP
"stop in a few seconds"
4 DISP
"and clean up." 5
DISP 0 WAIT DROP
CLLCD
"'NOW' updates the map"
1 DISP
"continually until you"
2 DISP
"interrupt it, 'THEN'"
3 DISP
"draws a map and ends."
4 DISP 0 MENU 3
FREEZE
    \>>


@ Provide brief credits. Blank the menu while waiting for
@ keypresses between screens.
  About
    \<< CLLCD { }
TMENU
"HP 48SX implementation"
1 DISP
"by James J. Elliott"
2 DISP
"<elliott@cs.wisc.edu>"
3 DISP
"Public domain; share"
5 DISP "and enjoy!"
6 DISP -1 WAIT DROP
CLLCD
"Based on a SunView"
1 DISP
"program by:" 2
DISP "John Walker"
4 DISP
"<kelvin@acad.uu.net>"
5 DISP 0 WAIT DROP
CLLCD
"Algorithms found in"
1 DISP
"'Astronomical Formulae"
2 DISP
"for Calculators' by"
3 DISP
"Jean Meeus, Third"
4 DISP
"Edition, 1985." 5
DISP 3 FREEZE 0
MENU
    \>>


@ This variable contains your current time zone. My default is Central
@ Daylight savings Time, or 5 hours earlier than UTC.
  TZ -5

@ This variable determines how detailed (and therefore slow) the
@ computation of the daylight bands' width is. In projecting the
@ sunlight region over the daylight hemisphere, this many different
@ bands are computed, and linear interpolation is used between them up
@ to the resolution of the graphics display. Note that it does not
@ make sense to set this higher than 62, since only 62 values are
@ stored! The lower the number, the chunkier the display, but the
@ faster arbitrary dates can be displayed. It doesn't really affect
@ the speed of ongoing updates, since this computation is only done
@ when the sun's declination drifts beyond a threshold from its
@ current value.
  Res 40

@ This is the threshold referred to above.
  Thres .5

@ This is just a band of black used in drawing the sunlight (with
@ GXOR). It's much faster than using LINE.
  STRIP
GROB 131 1 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0

@ Here's the world map.
  World
GROB 126 64 FFFFFFF30000008FFFFFFEFFFFFFFFF3FFFFFF1000CFF18F10F00CF30FFFFFF3FFFF7000008FF7EF18FF38F30CF1EFF3FFFF70000E3FF1EFFFFF002840018FF3E30E1000007CF07EF0CF010FF5000892C8F00000004C78FF340000CF9FFF910208FF744000CC038F1008F30FFFFFFF72389FF0C000E0E3C7800EFFFFFFFFF132F000E18971E1FFF0000FFFFFFFF70083F3C3C72324CFFFF8004FFFFF9FF1F0F370FF8F7E0D1FFF700CF3FFCF1EF1E8F30EFF0F74270FFF70FFF9FFDF3FF7ECF3FFFF3E17020EFFF9FF7D7EFFFFF36EF3FFFF7F73014EFFFB0F03270FFFF10FF3FFFF7F7F00EFFF7006122FCFFF74CFF3FFFF7FFF88FFFE73002






4CFFFF703FFF3FFFF7EFFFEFFF8700184EFFFF701FFF3FFFFF8FF3EFFFF7883BFFFFFF720FFF3FFFFF3F78FFFFF4F3083FFFFF76EFFF3FFFFF3E09FFFFF1FFF93CFFFFFEFFFF3FFFFF3CE3FFFFF9FFF170CFFF7EFFFF3F7FFFF8E0FFFFFCFFF0F81F870EFFFF3F7EFFFB000FFFFCFFF3E93727EEFFFF3FFFFFF3040EFFFDFFF7EC73766EFFFF3FFFFFFF1CFFFFFCF3F70E7A346CFFFF3FFFFFFEFC0CFFF9F3FF1FF8B06CFFBD3FFFFFFEF008FFFBBFFF7FF8B078FFBD3FFFFFFFF3F3EFF30CFB3FF93019FFFF3FFFFFFFF7FFCFFFFCF89FFF7001FFFF3FFFFFFF33FF0FFFFCE8CFFF7820AFF73FFFFFFFB3FF4CFFFDE4EFFFF00002F73FFFFFFFFBFFF9FFF9F






6FFFFF10E90EF3FFFBFFFF3FFFBF9FB76FFFFF708388F3FFFBFFFF7EFF9FFFBF64FFFFF7448FF3FFFFFFFFFAFFDFFFBFC0FFFFFF15EFE3FFFDFFFFF8FFDFFC3300FFFFFFC1CFC3FFFDFFFFFBFFCFFF3BB1DFFFF3EF97C3FFFFFFFFFBF3EFFF3FB9DFFFF9FF3FE3FFFFFFFFFBF9FFFF7F99FFFFF9FF7FF3FFFFFFFFF9F9FFFF7ECFFFFFF1E17FF3FFFFFFFFFDFCFFFFF6EFFFFFF3107FF3FFFFFFFFFD3EFFFFF0FFFFFFF3C93F33FFFFFFFFFD3FFFFFFFFFFFFFFFF18F32FFFFFFFFFD8FFFFFFFFFFFFFFFFFCF32FFFFFFFFFCEFFFFFFFFFFFFFFFFFCF03FFFFFFFFF4EFFFFFFFFFFFFFFFFFFF83FFFFFFFFF4FFFFFFFFFFFFFFFFFFFFE3FFFFFFFFF09FFFFFF






FFFFFFFFFFFFFF3FFFFFFFFF0EF9FFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFF9FFFFFFFFFFFFFFFFFFFF3FFFFFFFFF7CFFFFFFFFF0E300000EFF3FFFFFFFF70CFFFFF7F00E18FFFFF08F3FFFFFF7040DFFF7000EFFFFFFFFFF3C3FFF1000C08CFF30FFFFFFFFFFFFFF3C3F70C9FFFF70E38FFFFFFFFFFFFFFF3E3F90FFFFFFFF1CFFFFFFFFFFFFFFFF1E3F7EFFFFFFFFFFFFFFFFFFFFFFFFFF1028F9FFFFFFFFFFFFFFFFFFFFFFFFFF7C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFF






FFFFFFFFFFFFFFF3


@ This reverses the pixels of a region of the line being built up,
@ starting at the pixel in level 2, and ending at the pixel in level
@ 1. It's called by XSpan, below.
  XLine
    \<< \-> s f
      \<< STRIP f 1 +
s - R\->B # 0d 2
\->LIST STRIP GXOR s
2 + R\->B # 0d 2
\->LIST SWAP GXOR
      \>>
    \>>

@ Reverse a region of the line, centered on the pixel in level 1, and
@ twice the length specified in level 2. Handles wrapping off the left
@ edge if needed.
  XSpan
    \<< \-> l n
      \<< l 126 MOD
'l' STO
        IF l n +
126 >
        THEN l 125
XLine 0 l n + 127 -
XLine
        ELSE l l n
+ 1 - XLine
        END
      \>>
    \>>


@ Draw the time at the bottom of the map.
  XTime
    \<< \-> s
      \<< s 1 \->GROB
DUP SIZE DROP \-> o w
        \<< PICT 131
w - 2 / # 59d 2
\->LIST o GXOR
        \>>
      \>>
    \>>


@ Update the sunlit region display if necessary, and the time display
@ if appropriate. Takes the pixel location of noon in level 1.
  Draw
    \<< \-> n
      \<< 0 255 \-> w o
        \<<
@ Is this an update, or the first display? If an update, set flag 6,
@ so that the old lines will be taken into account.
          IF 'OTAB'
VTYPE 0 \>=
          THEN 6 SF
@ Has the sun moved, as far as the resolution of the map is concerned?
@ If so, set flag 7.
            IF n
ONOON \=/
            THEN 7
SF
            ELSE 7
CF
            END
          ELSE 6 CF
7 CF
          END 1 64
@ Loop over the whole map, one horizontal band at a time.
          FOR i
            IF 6
FS?
@ If it's an update, determine what the width was last time.
            THEN
OTAB i DUP SUB NUM
'o' STO
            END
@ Figure out the width of sunlight at this latitude, by looking it up
@ in the width table built by PrjIll.
WTAB i DUP SUB NUM
'w' STO
@ If the sun has moved or the width has changed, we need to update
@ this band.
            IF o w
\=/ 7 FS? OR
            THEN
@ Create a blank line in which the regions which need to change will
@ be marked.
# 131d # 1d BLANK
@ If there was an old sunlit band, we'll erase it.
              IF o
255 <
              THEN
ONOON o - 126 + 126
MOD o 2 * XSpan
              END
@ If there is a new sunlit band, draw it.
              IF w
255 <
              THEN
n w - 126 + 126 MOD
w 2 * XSpan
              END
@ Take the net result of the above two operations and apply it to the
@ actual map in one fast GXOR, so there's no flicker.
PICT SWAP # 0d i 1
- R\->B 2 \->LIST SWAP
GXOR
            END
@ If the user wants to stop, record that fact and abort the loop.
            IF KEY
            THEN
DROP -1 'STAT' STO
63 'i' STO
            END
          NEXT
        \>>
      \>>
@ If the clock display is enabled, draw the time at the bottom of the
@ map (erasing the old time first, since GXOR is being used.)
      IF -40 FS?
      THEN OSTR
XTime DT TM TSTR
DUP 'OSTR' STO
XTime
      END
    \>>


@ Main driver program: Compute the relevant astronomical variables and
@ then draw the map.
  SunClk
@ First make sure the right mathematical modes are in effect.
    \<< RCLF -19 CF
-15 CF -16 CF -17
SF -18 CF CLLCD
@ Display an explanatory screen during the initial computation.
"       SunClock" 1
DISP
"  Figuring widths of"
3 DISP
"  daylight bands."
4 DISP
"[Preliminaries]" 7
DISP PICT PURGE
@ Put the completely dark map into PICT.
PICT { # 2d # 0d }
World REPL ""
@ Note that no time string has yet been displayed.
'OSTR' STO
@ This is the animation loop; if "NOW" was pressed, it will be
@ executed multiple times.
      DO JTime 0 0
0 0 \-> jt gt ra dec
xl
        \<< jt DUP
GMST 'gt' STO 0
@ Figure out the location of the sun at the specified instant.
SunPos DROP DROP
'dec' STO 'ra' STO
@ We only care about the angular information.
          IF dec
@ If the declination has changed more than the threshold value, or if
@ it has changed sign, recompute the table of daylight widths.
OldDec - ABS Thres
\>= dec SIGN OldDec
SIGN \=/ OR
          THEN dec
PrjIll
          END
@ Unless the user has already hit a key (requesting termination), draw
@ the resulting map.
          IF STAT 0
\>=
          THEN {
# 0d # 0d } PVIEW
@ Figure out the longitude of noon.
ra gt 15 * - 180 +
FixAng 126 * 360 /
@ Draw the current map.
FLOOR DUP Draw
@ Keep track of the last location of noon.
'ONOON' STO
          END
        \>>
@ If the user has hit a key, end the animation loop if it was active.
        IF KEY
        THEN DROP
-1 'STAT' STO
        END
@ If we're animating, update the date and time and record the old
@ widths table so they can be erased properly on the next update.
        IF STAT 0 >
        THEN DATE
TIME 'TM' STO 'DT'
STO GTime WTAB
'OTAB' STO
        END
@ If we're animating, loop back and recompute/redraw.
      UNTIL STAT 0
\<=
@ Get rid of extraneous variables.
      END STAT {
OTAB ONOON OSTR
PPAR STAT } PURGE
@ If the user hasn't hit a key but we're ending because "THEN" was the
@ calling program (one-shot date display), freeze the screen so the
@ user can enjoy their map.
      IF 0 \>=
      THEN 7 FREEZE
      END STOF
    \>>


@ Figure out what widths of sunlight fall on the latitude bands of the
@ map. Given the sun's declination in level 1.
  PrjIll
    \<< \-> dec
      \<< 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 \->
i ilon ilat lilon
lilat xt m x y z th
lon lat s c
@ Initialize the width table to "darkness". This was originally an
@ array, but 64 real numbers took too much space, so I changed it to a
@ string. 255 means no light, other numbers are 1/2 the width to
@ illuminate.
        \<< "" 1 64
          FOR c 255
CHR +
          NEXT
@ Flag 6 is set the first time through, so interpolation isn't attempted.
'WTAB' STO 6 SF dec
@ Build the transformation for the declination.
D\->R NEG SIN 's' STO
dec D\->R NEG COS 'c'
STO \pi \->NUM 2 / NEG
'th' STO
@ Increment over a semicircle of illumination.
          DO s NEG
@ Transform the point through the declination rotation.
th SIN * 'x' STO th
COS 'y' STO c th
SIN * 'z' STO y x
@ Transform the resulting coordinate through the map projection to
@ obtain screen coordiantes.
ATAN2 R\->D 'lon' STO
z ASIN R\->D 'lat'
STO 62 lat 90 +
.344444444444 * -
IP 'ilat' STO lon
.35 * IP 'ilon' STO
            IF 6
FS?C
            THEN
@ First time through; just record the previous coordinates.
ilon 'lilon' STO
ilat 'lilat' STO
            ELSE
@ Interpolate between the current and previous points if we've jumped
@ more than one map line down.
              IF
lilat ilat ==
              THEN
WTAB 62 ilat - ilon
1 MAX CHR REPL
'WTAB' STO
              ELSE
ilon lilon - ilat
lilat - / 'm' STO
lilat 'i' STO
WHILE i ilat \=/
REPEAT lilon i
lilat - m * .5 +
FLOOR + 'xt' STO
WTAB 62 i - xt 1
MAX CHR REPL 'WTAB'
STO ilat lilat -
SIGN 'i' STO+
END
              END
ilon 'lilon' STO
ilat 'lilat' STO
            END \pi
@ Back at the outer loop; give the user feedback about how the
@ computation is progressing.
\->NUM Res / 'th'
STO+ "[" th \pi \->NUM
2 / + \pi \->NUM / 100
* 100 MIN FLOOR
\->STR + "%]" + 7
DISP
@ If the user wishes to terminate this computation, record the fact
@ and abort the loop.
            IF KEY
            THEN
DROP 3 'th' STO -1
'STAT' STO 1000
'OldDec' STO
            END
@ Keep computing until the full semicircle is done.
          UNTIL th
\pi \->NUM 2 / .001 + >
          END
@ One edge of the map is fully illuminated, but may have been missed
@ in the above loop, so tweak the widths at that end.
          IF dec 0
<
@ South pole in daylight
          THEN -1
64
          ELSE 1 1
@ North pole in daylight.
          END
'ilat' STO 'lilat'
STO
@ Don't bother if the user's already aborting.
          IF STAT 0
\>=
@ Loop from the edge of the map until a non-dark line is found,
@ illuminating as you go.
          THEN ilat
31
            FOR j
              IF
WTAB j DUP SUB NUM
255 \=/
              THEN
DO WTAB j 63 CHR
REPL 'WTAB' STO
  IF j ilat ==
  THEN lilat 'j'
STO
  END lilat NEG 'j'
STO+
UNTIL j 0 ==
END 31 'j' STO
              END
lilat
            STEP
@ All done; keep track of the declination value used in this
@ computation, so it can be avoided next time if the current
@ declination is close enough.
dec 'OldDec' STO
          END
        \>>
      \>>
    \>>


@ Calculate the position of the sun. Level 2 contains the Julian time
@ of the instant for which the position is desired, and level 1 should
@ be nonzero if the apparent position (corrected for nutation and
@ aberration) is desired.
@ The Sun's longitudinal position (in degrees) is returned in level 4;
@ divide by 15 to get hours. The declination is returned in level 3.
@ The radius vector (in astronomical units) is returned in level 2,
@ and the Sun's longitude (true or apparent, as desired) is returned
@ as degrees in level 1.
  SunPos
    \<< \-> jd ap
      \<< 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 \->
t t2 t3 l m e ea v
th om eps ra dec rv
slong
        \<< jd
2415020 - 36525 /
@ Convert time to Julian centuries of 36525 ephemeris days, measured
@ from the epoch 1900 January 0.5 ET.
DUP 't' STO DUP DUP
* DUP 't2' STO *
't3' STO 279.69668
36000.76892 t * +
.0003025 t2 * +
FixAng 'l' STO
@ 'l' gets the geometric mean longitude of the Sun, referred to the
@ mean equinox of the date. Now compute the sun's mean anomaly.
358.47583
35999.04975 t * +
.00015 t2 * -
.0000033 t3 * -
FixAng 'm' STO
@ Now take the eccentricity of the Earth's orbit into account.
.01675104 .0000418
t * - .000000126 t2
* - 'e' STO m e
@ Compute the eccentric anomaly.
Kepler 'ea' STO 1 e
@ Compute the true anomaly.
+ 1 e - / \v/ ea 2 /
TAN * ATAN R\->D 2 *
FixAng 'v' STO l v
@ Compute the sun's true longitude.
+ m - 'th' STO
@ Obliquity of the ecliptic:
23.452294 .0130125
t * - .00000164 t2
* - .000000503 t3 *
+ 'eps' STO
          IF ap
@ Corrections for sun's apparent longitude, if desired.
          THEN
259.18 1934.142 t *
- FixAng 'om' STO
.00569 .00479 om
D\->R SIN * - NEG
'th' STO+ .00256 om
D\->R COS * 'eps'
STO+
          END th
@ Record sun's longitude and radius vector, then compute coordinates.
'slong' STO
1.0000002 1 e e * -
* 1 e v D\->R COS * +
/ 'rv' STO eps D\->R
COS th D\->R SIN * th
D\->R COS ATAN2 R\->D
FixAng 'ra' STO eps
D\->R SIN th D\->R SIN
* ASIN R\->D 'dec'
STO ra dec rv slong
        \>>
      \>>
    \>>


@ Solve the equation of Kepler.
  Kepler
    \<< \-> m ecc
      \<< 0 0 \-> e d
        \<< m D\->R DUP
'm' STO 'e' STO
          DO e e
SIN ecc * - m - 'd'
STO d 1 e COS ecc *
- / NEG 'e' STO+
          UNTIL d
ABS .000001 \<=
          END e
        \>>
      \>>
    \>>

@ Compute arctan(y/x), with y in level 2 and x in level 1. Returns
@ appropriate quadrant treating y and x as rectangular coordinates
@ being converted to polar coordinates.
  ATAN2
    \<< SWAP \->V2 -16
SF V\-> -16 CF SWAP
DROP
    \>>

@ Translate a big angle back in to the range 0-360 degrees.
  FixAng
    \<< DUP 360 /
FLOOR 360 * -
    \>>

@ Show the currently chosen date and time and prompt the user for
@ their next action (used by the "THEN" submenu).
  ShwTm
    \<< CLLCD DT TM
TSTR 4 DISP
"Choose time, push GO"
3 DISP 2 FREEZE
    \>>
  GMST
    \<< \-> jd
      \<< jd .5 +
FLOOR .5 - 2415020
- 36525 / 0 \-> t th0
        \<< 6.6460656
2400.051262 t * +
.00002581 t t * * +
'th0' STO jd .5 +
DUP FLOOR - 24 *
1.002737908 * th0 +
DUP 24 / FLOOR 24 *
-
        \>>
      \>>
    \>>

@ Convert the chosen date and time to Greenwich time.
  GTime
    \<< RCLF -42 CF
DT 'GD' STO TM TZ -
DUP
      IF 24 \>=
      THEN 24 - GD
1 DATE+ 'GD' STO
      END 'GT' STO
STOF
    \>>

@ Compute the chosen Julian time, as a date and day fraction.
  JTime
    \<< JDate .5 - GT
HMS\-> 24 / +
    \>>

@ Compute the Julian date for the chosen date.
  JDate
    \<< GD DUP IP
SWAP FP 100 * DUP
IP SWAP FP 10000 *
0 \-> m d y c
      \<<
        IF 'm>2'
        THEN -3 'm'
STO+
        ELSE 9 'm'
STO+ -1 'y' STO+
        END y 100 /
IP DUP 'c' STO 100
* NEG 'y' STO+ d c
146097 * 4 / IP + y
1461 * 4 / IP + m
153 * 2 + 5 / IP +
1721119 +
      \>>
    \>>

@ Holds the currently chosen time:
  TM 22.3138814208

@ Holds the currently chosen date:
  DT 11.151991

@ Greenwich time and date for above values:
  GT 3.3138814208
  GD 11.161991

@ Stores the declination for the last computed daylight width table.
  OldDec
-18.5917760031

@ The most recently computed width table, as a string for space
@ reasons (about 70 bytes instead of 500, and there are two of these
@ around while animation is active.)
  WTAB
C$ 64 \255\255\255\255\255\255   !!!"""##$$$%&'')*+,/5?????????
END
--------------->8--------Cut here--------8<-----------------



And here's the uuencoded binary version:

begin 644 SunClk
M2%!(4#0X+466*O!_"T0    $5U1!0@0L*E ( /_______P0,#Q(3%!47&!@9
M&AH:&QP<'!T='1X>'A\@(" A(2$B(B(C(R0D)"4F)R<I*BLL+S4_/S\_/S\_
M/S^6 &#PQ$9&5#9F,)," 1 #8'>1A9$E "!P1"0PDP(!   0F6$1 1T ('!$
M)3"3 @  "$*!.#$#'0 @0$0E,)," 0  $)E1$0$= "! U20PDP(!@" 4B!,C
M AT 4*!$%$975M#9 AXV@N0" D=$A_O1MAN]^S&Z&S,I(        !#@WAJ'
M^]&V&[W[,;H;,RE         $.#>&K2B$DPC;2X0T-;F @%D;2X0D-?F @%C
M'C8R["*X*M#F @%MWJ+2Q1XK,:#O(ITM #LJ5#;2Y@(!;7DVLD0@*S%0^R*=
M+1 W*E0VTN8" 6UY-K)$((:C0F4C;2X0D)=G(TL$LA(#U2_2Y@(!>3,I(   
M     !!0\!IMNW&X'U0VTN8" 6-Y-M+,(#,I(        !#@WAJ5J4%E(VTN
M$)"79R-+!-+F @%D;2X0,#:3 @4   !P"48![JV!,"H%K]&V&V>KT>8" 7DS
M*3       &$4X-X:"*-2\!IMNW&V&FTN$- VDP("      !3 >ZMX2TJ9ZO1
M,2H%K]&V&V>K,9,"!@   !D1<@%GJ^%?(SDVLA(#JP)0H$25UE96T-D"'C:"
MY (%2D1A=&4S*9"9      !0D- :2"X@<$3E\QLS*1         D4/ :9ZN1
M8R,K,< '  5'5&EM906=+>!A(QG&,9," 0      ()35PH'D @)$5%0V@N0"
M D=$>3;2S"!(+B! U83D @)46@FM<;@?PRXRDP(!      !  IOMH>\BG2TP
MDP(!      !  @FM@>0" D=$R:(BG1E4-H+D @)'1'DVTLP@*S%0_2)4-H+D
M @)'5'DVTLP@?\:18R,K,1 2  1'35-4!)TMX&$CP332Y@(":F0>-M+F @)J
M9#,ID)D      %!PMAK9NS&3 ID)       %":TQDP(&    (%!! @FM,9,"
M!      E90,%KT$K*L$TTN8" 71M+C! AP;C82,S*0    !6!D9F,)," P @
M)E$ 0 )M+A! Y]X:9ZLQDP*5"0   !!8 FTN$$#7Y@(!=.ZMX=X:9ZM!92-M
M+C! AP:39R/-#-+F @)J9#,ID)D      %!PMAJ'^Y&]&PFM,9," 0      
M0 +NK3&3 @  @) W)P ![JW1Y@(#=&@P9ZMQN!\S*1         D4/ :V;LQ
MDP(!      !  NZMD= :_C7B7R,Y-K(2 R@"4#"%=D?55M#9 AXV@H4:2"X@
M0$2%Y ("5$V2F8$P*H2EP:("+0 PA/;V-E<&0I?65L8" E<WAP9R]#0O*H2E
MX2TJI*618R,K,2 )  9&:7A!;F<&G2W@82.'^S&3 @(      & #!:^1O1LS
M*2         VX-X:":V18R,K,7 &  5!5$%.,@6=+>!A([W[8>8=,RD0    
M    %DDG' ;=,9," 0      8)'5PM&[']C[D6,C*S'P!@ &2V5P;&5R!ITM
MX&$CP332Y@(!;6TN,% V-N9A([2B0BLJP332Y@(!96TN$$#F82-M+A#0ANP;
MA_M!92-M+A#0EF<CS0Q"92-M+A!0EF<CS0PR#"-M+A!0UN8" 66LM-'F @-E
M8V/NK9'0&FTN$-"6T!I4-M+F @%D>3;2S"!M+A! EBPJ;2X04%90&VTN,% V
M-N;>&@FM4? :E:E!92-M+A!0EF<C2P32#B-M+A! ]J$:,RE F0      $,#/
M'KDVTN8" 67^->)?(SDVLA(#H %@,%7G!O4V9]#9 AXV$DPC;2X@H$;6Y@("
M87 >-D(K*K2B0BLJM*)"*RJTHD(K*K2B0BLJM*)"*RJTHD(K*K2B0BLJP332
MY@(!=&TN($ GT^8" G0S;2X0P-;F @%M;2X04-;F @)E86TN$&#7Y@("=&AM
M+B#PUM;F @-E<'-M+B @%];F @-D96-M+B @9]?F @5S;&]N9QXVTN8" FID
M,RE@      (5))#0&C,I0     !04C90\!J'^T%E(VTN$$"79R/-#'*X'X?[
MX=X:A_M!92-M+B! )Y-G(\T,XMX:5#;2Y@("=#-Y-M+,(#,I(    &B6EB<P
MDP($ "")=@!@ VTN$$#GWAIGJS&3 I8)    4 (#;2X@0"?CWAIGJX'D @9&
M:7A!;F=4-M+F @%L>3;2S" S*2    "#=80U,),"! !0EP2960-M+A! Y]X:
M9ZLQDP*6"0    !0 6TN($ GX]X:":TQDP*4"0     P VTN($ WX]X:":V!
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
M)5UGJW$T*H2E,>PB<ZBA[R*=+8"]'_.B0F4C;2X@0(>69R/-#&(X*E0V@N0"
M!%-4051Y-M+,(#,I,        !! 92-(+F#PQ$9&5#:69R/-#+(2 ]4OT@XC
M;2X@0(?6JQKDI>$M*@6O,9,"EPD       %GJ]'%'KDV,NPB;2XP0%8V1BLJ
MONNA[R*=+6 X*C,I$        &2P$@.U+]+9 LFBDBPJ*S%0_2)4-M+F @1I
M;&%T>3;2S"!4-M+F @5L:6QA='DVTLP@PRZ"Y ($4U1!5+2BLMD>^B[2V0)M
M+D"0QA9&-Y," 0      $ .@,=+F @%JPRZ"Y ($5U1!0FTN$*!VN!]<R&&T
M'#,I(       4"70J1[Z+M+9 L,P@N0"!%=404)M+A"@-I," 0      , 9F
MRZ&.'%0V@N0"!%=404)Y-M+,(,,NTN8" 6IM+D"0QA9&)Y<>^B[2V0)M+E# 
MEL861D=E(VTN$*"69R/-#+(2 ]4OTN8"!6QI;&%TE:E!92-M+A"@EF<C2P32
M#B-M+A"@1BLJ<NF1:R,S*1         Q0&4C;2X0H)9G(\T,LA(#U2_2Y@(%
M;&EL872 ,]+F @-D96-4-H+D @9/;&1$96-Y-M+,("LQ4/TB_C7B7R,Y-K(2
M W ,8#!5YS;$MF;0V0(>-I)A'#,I$        !E9+1PS*1         562T<
M,RD0        %EDM'#,I$        !=))QPS*1         862T<6*C!H@(C
M   " @(" @(R5><VQ/8VMI8L*H2EP:("+0   F*4=E8GE^9V!G*71D:'-@?R
M9C8O*H2EP:(")P   D(6EL>6=H9&!R(6YD8VYX(P*H2EP:("(P"P!257QI;6
MEN86)I=6-M=U-"J$I6%#'OX.8D,>="K@I (5 "          X*0"%0      
M     + 2 T@N4'#U)L=&IHX<+"I0  !4-H+D @1/4U12>3;2S"##,(+D @5*
M5&EM9;2B0BLJM*)"*RK!--+F @)J=&TN('!&U^8" G)A;2XP0%8VUN8" GAL
M'C;2Y@(":G2'^X'D @1'35-45#;2Y@("9W1Y-M+,(+2B@N0"!E-U;E!O<]C[
M@;T?5#;2Y@(#9&5C>3;2S"!4-M+F @)R87DVTLP@PR[2Y@(#9&5C2"Y@\,1&
M1E0VEM :'ZJ!Y (%5&AR97.;[='F @-D96,JLX'D @9/;&1$96,JL]&I'@GH
MH>\BG2W0Y@(#9&5C2"Y@ "6GEL3&MA(#U2\R[")(+D P115$12LJF^VA[R*=
M+4"G DXJ4 $           !.*E !            *S$ +QYM+B @%];F @)G
M=#,I$        !7@WAH)K3&3 @(      ( !9ZN!Y (&1FEX06YG,RD@    
M  !@$N#>&C,I(        #90\!K9NW&X'T@N0$ D%W9'92-(+E#PY/3TY)1G
M(\T,LA(#U2_B7R/#+C*'&OHNTMD"V/MA."I4-H+D @135$%4>3;2S" K,5#]
M(L,N@N0"!%-4052THM+%'OHNTMD"$IAQ?QE4-H+D @)437DVTLP@5#:"Y ("
M1%1Y-M+,($@N4'!$E=96AN0"!%=404)4-H+D @1/5$%">3;2S" K,5#](NTP
M@N0"!%-4052THL+/'KDV@N0"!%-4051T*H#D @1/5$%"2"Y0\.3T].2$Y ($
M3U-44D@N0  %%22%Y ($4U1!5"LQX.\@PRY"*RJ;[:'O(ITM<#0JI*6Q$@/5
M+_)G'#DVLA(#N09 0"07=D?0V0(>-A),(VTN$.#F82.THC*3 @(      %4"
MP332Y@(!=VTN$/#F82/#+D)E(T@N0/!$%2249R,HSD$K*IOMH>\BG2T@,RIT
MPC'L(FTN$."&Y (%3TY/3TZ=ZJ'O(ITM<#0J=,*Q$@.U+]+9 D>C4BT<*S%0
M_2(K,5#[(ITM(#,JU<)Q-"K5PK$2 ]4ODBPJ,RD0        9  :(VTN$) V
M["(RHS(Q'/HNTMD"2"Y \$05)-3F @%IA_O!A1Q&RT%E(VTN$/"69R/-#+(2
M ]4O@N0"!%=404)M+A"0=K@?7,AAM!Q4-M+F @%W>3;2S"##+M+F @%O;2X0
M<->I'D>C,C$<">BA[R*=+>"D A4 , @       #@I (5 !          8$$>
MPR[2Y@(!;S,I(       4"7@NQ[Z+M+9 D@N4/#D]/3DU.8" 6\)K3&3 @( 
M     "8!9ZLQDP("       F 4V^T>8" 6_>HN+>&D@N4( U!1?FMA(#U2\R
M[")M+A!P-Y," @      50*^ZZ'O(ITMT.8" 6YM+A!PE] :,RD@      !@
M$G"V&C,I(       8!+0Y!MM+A!PYRTJ[JV!Y (%6%-P86XK,5#](C;DT;L?
M3BI0 0           &TN$)"6+"H)K;%I&=ZB,G@<O?M!3AXK,5#](L,N,H<:
M^B[2V0+8^V$X*E0V@N0"!%-4051Y-M+,(#,I$        &- 92-M+A"0EF<C
MS0RR$@/5+\(D(_XUXE\CPRXRDP(!        E!/#H>\BG2V Y ($3U-44D@N
M4(!%E=96AN0" D142"X@0-4DF1F'^T%E(T@N0/ T12659R/-#(+D @585&EM
M92LQ4/TB.3:R$@-%!5" 19765E;0V0(>-A),(VTN$##G82-M+A PERPJK>5Q
MN!^XR8&]'\$TTN8" 6]M+A!PYV$C-N0QDP("       Q 6TN$'"7T!K>HE+P
M&DXJ4 $ .P        #>HC)X'&TN$/!&3A[^->)?(SDVLA(#X0!0@#4%%^96
MT-D"'C823"-M+A# UN8" 6X>-M+F @%L,RD@      !@$M#D&U0VTN8" 6QY
M-M+,(,,NTN8" 6QM+A#@=K8:,RD@      !@$M#%'OHNTMD";2X0P#:3 @( 
M     "4!2"Y0@,64YE9&*RIM+A# UN8" 6YGJS&3 @(      "<!":V!Y (%
M6$QI;F4K,5#[(ITMT.8" 6QM+A# UN8" 6YGJY$L*@FM@>0"!5A,:6YE*S%0
M_2+^-9)C(RLQ@!@ !5A,:6YE!9TMX&$CP332Y@(!<VTN$&#F82-(+E P1265
M!-7F @%FR:)RMAIM+A PE] :FY;AI (5            X"TJ@\>!Y (%4U12
M25#DY-'F @%SWJ)RMAJ;EN&D A4           #@+2J#Q]&['^3DX5\C.3:R
M$@/Z %!P]2;'1E;@L0(/"  $ 'X \/___P,  (#____^______/__Q\ P/^!
M'_  _ /____S_W\  (#_YQ_X/_@#_.'_\_]_   ^_^'__P\@2 "!_^,#'@  
M</QP_L / ?\% )C"^    $!\^#\$ ,"?_Y\! OA_1 # #(,? /@#____?S*8
M_\  X.##AP#^_____S'R ."!>>'Q_P  _____P> \\/#)R/$__\(0/__G__Q
M\'/PCW\.'?]_ /SSSQ_^X?@#_@]_) ?_?_#_^=\__^?\\_\_'@<"_O_Y?WW^
M__]C_O/_?W\#0?[_"P\C!___ ?_S_W]_#^#_?P 6(L__?\3_\_]__X_X_WX#
M(,3__P?S__/_?_[__O]X ('D__\'\?_S___X/_[_?XBS____)_#_\___\X?_
M_T\_@//__V?^__/__^.0__\?_Y_#___O___S___#/O__G_\?!_S_Y___\_?_
MCP[__\__#X_Q>.#___/G_[\ \/_/_S^><W+N___S__\_0.#_W_]_SC=GYO__
M\____\'__\\_?^"G0\;___/__^_/P/^?/__QCPO&_]OS___O#X#_O_O_]X\+
MA__;\____S\__C_ O_.? Y'___/___]___S_SX_Y_P<0___S____,__P_\^.
M_/^' OI_\____SO_Q/_?3O[_#P @?_/___^__Y__GV___Q_@"?[S__O_/_^_
MG[]G__]_@(/X\__[_W_^G_^_;_3__T>$__/_____^M__O\_P__\?Y>_S__W_
M__C?_SP#\/__S\'/\__]___[S_\_N]'__^.?Q_/_____^^/_/[_9___Y/^_S
M______OY_W^?^?__^7__\______Y^?]_SO___^%Q__/______?S__^;___\3
M</_S_____SW^___P____PSD_\_____\]__________^!/_+_____C?______
M____SS_R_____^S__________\\/\______D____________C_/_____]/__
M_________^_S_____Y#_____________\______@G_____________/_____
M_______________S____________________\_____^?______________/_
M____Q_____\//@  X/_S____?\#__W\/X('__P_X\___?T#0_W\ X/______
MP_/_ 0 ,R/\#_________\/S!YS__P<^^/_________C\PG_____P?______
M____X?/G_________________P&"G__________________'\___________
M__________/____________________S____________________\_______
M_____________R."  535%))4 4>*Q #  $ , @ ____________________
M_P]$ %! A297-E<PDP*9"0      !2, ,"!5-C<PDP(!        !!\ ($"E
M)3"3 @        "5'0!0$"3V5D=7T-D"'C:"A1IT*K 2 UT1PJ(",0" ! 5"
M@S.%!9+6!L=6UE;F1A=&E_;FEBPJA*7!H@(K ""6!Z(4UE8V!Z+D E+$QI;V
M1D?G+2J$I<&B B\ P%/&QI;V1D<'-#;G<I<V-^921E;G,R\JA*7!H@(M  !5
M)\:6-@9"]M86EN:V S*'%B97UC$JA*7!H@(9 !#F1@92YJ;VEA<B,RJ$I6$X
M*A^G@;T?6*C!H@(I " 4-E=&!O+F!A(&,E7G9I56=I<L*H2EP:("&P  )_=V
M)A?6!B*6I^,M*H2EP:("&P"@](;F!G(5QK96)H<P*H2EP:("+0# LU;&9I?F
M!A0V%D;F4E?GXE9&Y],Q*H2E02LJ'Z>!O1]8J,&B BL $,1V]B:71H?6-@=B
M]E;G1@:2YI8L*H2EP:(",0!P$C1')_?F]M:6-A;&!F+T)M=6QQ96YBTJA*7!
MH@(K &#V)@<R%,8V5L<61O<F-W<"(I8W+RJ$I<&B B< H%06Y@;25%96-\<"
M0H66)D>&,"J$I<&B B$ 4$261I?VYL8"$I.#4^/2,2J$I3$O*J2E02LJEA&2
M8R,K,0 W  1(96QP!)TMX&$C6*A!IP(K,= 5(2PJ\ ( 4')E<W,@3D]7(&9O
M<B!C=7)R96YTR:)"6!HL*O " &1A>6QI9VAT(&UA<"P@;W(@5$A%3MZB0E@:
M+"KP @!T;R!P:6-K(&$@9&%Y("8@=&EM92[SHD)8&BPJL ( 4V5T(%1:('1O
M('EO=7(@=&EM91VC0E@:+"K0 @!Z;VYE("AE9RX@0T14(#T@+34I+C*C0E@:
MAJ/R<1K8^X&%&BPJL ( 5&\@:6YT97)R=7!T+"!P<F5S<\FB0E@:+"J0 @!A
M;GD@:V5Y(&]T:&5R('1H86[>HD)8&BPJT ( 3TXO05143BP@86YD(&ET('=I
M;&SSHD)8&BPJ\ ( <W1O<"!I;B!A(&9E=R!S96-O;F1S"*-"6!HL*O ! &%N
M9"!C;&5A;B!U<"X=HT)8&K2B\G$:V/N!A1HL*O " "=.3U<G('5P9&%T97,@
M=&AE(&UA<,FB0E@:+"KP @!C;VYT:6YU86QL>2!U;G1I;"!Y;W7>HD)8&BPJ
MT ( :6YT97)R=7!T(&ET+" G5$A%3B?SHD)8&BPJ\ ( 9')A=W,@82!M87 @
M86YD(&5N9',N"*-"6!JTHF(9(?.B0EH:.3:R$@.P T! A5;F1M#9 AXV0J<"
M="K H@(/ .!#%$15U-D"'C823"-M+A"0YF$C2"X@0$053"-M+A! YF$C;2X0
MD#;L(H?[<;@?;;LAEQ[Z+M+9 FTN$$ VNAMGJ[$2 [4OTMD"PRYRN!^CNS&3
M @(        ![JUQN!]MNR&7'OHNTMD";2X00#:3 @(        ![JTQNALS
M*2         04/ :9ZNQ$@/5+[(2 ]4O0F4C2"X@0$259R/-#/(](T@N4#"%
M=D?5]G$CG2TP.AKSHD)8&MZB\G$:V/N!O1]M+A! 1F4C2"X@0$259R/-#(+D
M @53:'=4;2LQ4/TB_C7B7R,Y-K(2 RLQ0*<"+"KP   ^5$E-19TMX&$CP332
MY@(!:1XV@N0" E1-P332Y@(!=!XVTN8" 6E4-H+D @)437DVTLP@WS."Y (%
M4VAW5&T?-]+9 J.C,2\JA*7A+2H?IX&]']C[T>8" 714-H+D @)437DVTLP@
M2"Y0,(5V1]6V$@/5+^)?(_XUDF,C*S&P$@-T*L"B @T $/0"U=39 AXV@N0"
M E1-,RD0        $I#0&H?[,>PBM*+BNQ[Z+M+9 C,I$        "1PMAHK
M,5#](E0V@N0" E1->3;2S"!(+E PA79'U99C(RLQL!(#="JP$@-T*K 2 W0J
MP*(""0!P]-;9 AXV0BLJEA&"Y (%1U1I;66THD)E(T@N0#!%%4259R/-#(+D
M @93=6Y#;&LY-K(2 RLQL!(#71&"Y (%4VAW5&TY-K(2 Y<$,.#T=C?0V0(>
M-B*!&?>7064C2"X@0-649R/-#$)E(T@N($!$E6<CS0R"Y (%1U1I;67)HD)E
<(T@N0#!%%4259R/-#(+D @93=6Y#;&LY-K(2 V<C
 
end
-- 
Jim Elliott		      "Like a bridge he'll come between us, not a wall"
elliott@veronica.cs.wisc.edu

ngsl@hpsgm2.sgp.hp.com (Shuh Lit Ng) (05/08/91)

Hello Jim,

That ia a neat program, I like it a lot!  It's a bit
too big though (8 kbyte, urrk...).  If I leave it on for 
a period of time, how much energy does this program
consume?