Date: Sun, 13 Dec 1998 18:16:30 -0500 (EST)
From: john Latala <jrlatala@golden.net>
Subject: update to my BCLK program

This is an super set to my BCLK program but you might still want to keep
BCLK around because this new version is a really memory pig ... it's about
30 KBytes when it's installed and ready to run!

To that end I've given it a new name so it will co-exist with BCLK. I call
it BC which stands for 'Big Clock'.

It's kind of important that you keep it named BC because it requires that
it be installed into the ( HOME BC } directory! This was done because the
directory was created to be a newsgroup posting. The large GROBs used by
the program were converted to ASCII using Wick ->ASC program. 

I've included a setup program (Setup) which will unASC all those GROBs
back to their original form and the BC directory name is hardwired into
that program. You can rename the directory but you've got to do it AFTER
you run the Setup program.

Here's the BC directory object ...

This posting is a directory object that contains a number of clock
programs for displaying the current time in various formats.

The current formats are:

        Format          Description
        ------          -----------
        Analog          normal analog clock
        Digital         digital clock with large digits
        7 segment       digital clock with large 7-segment digits
        Dot matrix      digital clock with large dot matrix digits
        Odometer        digital clock with large digits scrolling onto the
                        display like a car odometer
        Date/time       two-line medium sized digits date/time display
        Abaclockus      date/time displayed on an abacus
        Bar             bar graph display
        Gauge           'moving tape' display like used on altimeters of
                        airplanes with a 'glass' cockpit
        English         written english

INSTALLATION
------------

Proper installation requires that you also have Wicks ->ASC program
installed on your calculator.  This is because many of the programs use
large GROBs and they've been converted to ASCII because they won't post 
properly in their original form.

The program MUST be installed in the { HOME BC } directory. BC stands for
Big Clock which originally meant the digits but since the directory is now
something like 30 KBytes in size it could also imply the size ...

This is done because there ia a program supplied ( { HOME BC Setup } )
which will convert the ASCII GROBs back into their original format.
The Setup program has the directory paths and names hardwired into it.

I did it this way because it's quite simple and it works.  After you've
run the Setup program you can rename/move BC to somewhere/something
else as you see fit.

The installation sequence is:

        - if you don't have it already then install Wicks ->ASC program 
          first. If you don't do this my program won't work because it
          needs to use ASC->

        - hit HOME to make sure we're in the HOME directory

        - download the directory object and make sure it's stored in the 
          BC directory in your HOME directory

        - change to the BC directory

        - run the Setup program to get the GROBs converted from ASCII 
          back into their original format

        - turn on the custom menu by hitting CST

        - hit the ALL menu button which should run each of the clock 
          programs for thirty seconds.

        - if that worked then you can delete the Setup program to save 
          a little space

        - if that didn't work then something got mangled in the download
          or you didn't put the program into the BC directory in HOME

        - if you still have problems then post a not on the comp.sys.hp48
          newsgroup describing it and I'll see what I can do.
          
        - check the OPERATIONS section below and then have fun amazing
          your friends with the clock displays!
          
OPERATION
---------

Everything is run from the custom menu in the BC directory, Changing to
the BC directory and hitting the CST key will show you the following
menu keys:

        ALL Clk T12 T24 T?  _CLKS

ALL will run each clock for thirty seconds before going to the next
clock.  Most of the clock programs will abort when a key is hit so this
can be used to move through the clocks faster.

Clk will display a scrolling menu like the equation library.  Use the
up and down arrows to move to the clock you want run then hit the ENTER
key to run it.  Any key other than the up/down arrows and the ENTER
will abort the Clk program.  Once a clock program is running hitting
any key will stop it except for the analog clock program.  Keep reading
for details.

T12 sets the calculator's system flag to display time in 12-hour
format.

T24 sets the calculator's system flag to display time in 24-hour
format.

T?  displays the current 12/24 hour setting.
 
_CLKS (the '_' is intended to mean a a directory entry) will display another 
menu:

    ANALOG DIGITAL 7SEGMENT DOTMATRIX ODOMETER DATETIME ABACUS BAR ENGLISH

Hitting the menu key will run the appropriate clock program.
Left-shifting a menu key will run the clock program with the 12/24 flag
temporarily set to 12 hour mode.  Right-shifting a menu key will run
the clock program with the 12/24 flag temporarily set to the 24 hour
mode.

If you start a clock program this way and then just let it run it will
eventually turn itself off.  I wrote the programs this way so you
wouldn't kill your batteries if your calculator accidentally got turned
on by mistake and one of the clock programs was accidentally run.  You
might also start the program and put the calculator down (i.e. if the
phone rings or something).

If you want to change the time constant for how long the programs run
before they shut down then store a new value into the TIMEOUT variable 
in the BC directory.  The value is the number of 8.182 KHz clock ticks 
you want the program to run for (i.e. 8192 is one second, 81920 is ten
seconds, ... ).

As mentioned before most of the clock programs will stop running when a
key is hit.  The only one that won't is the analog clock display.
While it's running the following keys are functional:

        Key     Usage
        ---     -----
        +/-     toggle between 12 hour and 24 hour clock
        1/x     'invert' the display reversing the clockface

Any other keys stop the program.

%%HP: T(3)A(D)F(.);
DIR
  CLKS
    DIR
      @
      @ Analog clock display
      @
      CLK0
        DIR
          CLK
          @
          @ clock display program
          @
            \<< 
              @
              @ hour hand and minute hand
              @
              { (15,0) (0,-2) (-2,0) (0,2) (15,0) }
              { (25,0) (0,-3) (-3,0) (0,2) (25,0) }
              @
              @ center of clock
              @
              (63,32)
              @
              @ program termination flag
              @
              0
              @
              @ reverse clockface flag
              @
              0
              @
              @ program autostop tick value
              @
              TICKS TIMEOUT + 
              \-> hh mh c done rflag timeout
              \<<
                @
                @ clear PICT, force a blank LCD, view graphics screen
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ wait until either user abort or timeout
                @
                WHILE done NOT REPEAT 
                  @
                  @ get the time and break it up into h/m/s/t
                  @
                  TIME UTIME 
                  \-> h m s t
                  \<< 
                    @
                    @ use a 12-hour clock and figure out angle from 
                    @ vertical to hour hand
                    @
                    h 12 MOD m 60 / + 12 / 360 *
                    IF rflag THEN 
                      @
                      @ we rotate the hand 90 degrees clockwise to
                      @ to the vertical 
                      @
                      90 
                    ELSE 
                      @
                      @ we do 360-theta+90 to rotate the hand to the
                      @ vertical and have have increasing angles move
                      @ clockwise
                      @
                      NEG 450
                    END 
                    + 
                    @
                    @ we do the same thing for the minute hand
                    @
                    m s 60 / + 60 / 360 * 
                    IF rflag THEN 
                      90
                    ELSE 
                      NEG 450
                    END 
                    + 
                    \-> h\Gh m\Gh
                    \<< 
                      @ 
                      @ display the clockface
                      @
                      PICT { # 20h # 0h }
                      @
                      @ 12 hour AM/PM clock or 24 hour
                      @
                      IF -41 FC? THEN 
                        @
                        @ 12 hour use 1-12 clockface
                        @
                        CF1 rflag 1 + GET
                      ELSE 
                        @
                        @ 24 hour use 1-12 clockface for AM and 12-24 
                        @ clockface for PM
                        @
                        h 12 < CF1 rflag 1 + GET CF13 rflag 1 + GET IFTE
                      END 
                      REPL 
                      @
                      @ update the AM/PM indicator
                      @
                      PICT { # 0h # 39h }
                      @
                      @ are we displaying a 24 hour clock or a 12 hour
                      @
                      IF -41 FS? THEN 
                        @
                        @ 24 hour clock just clear out the AM/PM indicator
                        @
                        "  "
                      ELSE 
                        @
                        @ 12 hour clock so update AM/PM indicator
                        @
                        h 12 \>= "PM" "AM" IFTE
                      END 
                      2 \->GROB REPL 
                      @
                      @ draw the hour hand
                      @
                      1 hh SIZE
                      FOR i 
                        @
                        @ get the applicable hand coordinate
                        @
                        hh i GET 
                        @
                        @ rotate it into the correct position
                        @
                        1 h\Gh \->POLAR * 
                        @ 
                        @ shift if to the center of the screen
                        @
                        c + C\->R 
                        @
                        @ we want the y coordinate so it's increasing 
                        @ downward
                        @
                        64 SWAP - 
                        @
                        @ convert both numbers to binary 
                        @
                        R\->B SWAP R\->B SWAP 
                        @ 
                        @ wrap it into a list for use as a screen
                        @ coordinate
                        @
                        2 \->LIST
                        @
                        @ we draw the line from the 'previous' point which
                        @ was left on the stack to the current point we
                        @ just calculated. We want to leave the new current 
                        @ point on the stack for the next line.
                        @
                        @ If this is the first there is no previous 
                        @ point and we can't draw a line.
                        IF i 1 > THEN 
                          SWAP OVER LINE
                        END
                      NEXT 
                      DROP 
                      @
                      @ do the same thing for the minute hand
                      @
                      1 mh SIZE
                      FOR i 
                        mh i GET 1 m\Gh \->POLAR * c + C\->R 
                        64 SWAP - R\->B SWAP R\->B SWAP 2 \->LIST
                        IF i 1 > THEN 
                          SWAP OVER LINE
                        END
                      NEXT 
                      DROP
                    \>> 
                    @
                    @ we spend the rest of this minute updating the LCD 
                    @ with the current seconds.
                    @
                    @ we get out of this loop when the current minute 
                    @ expires or the user hits a key:
                    @
                    @ Key         Usage
                    @ ---         -----
                    @ +/-         toggle between 12 and 24 hour clock
                    @ 1/x         flip the display left<=>right
                    @ other       stop program
                    @
                    1 
                    WHILE REPEAT 
                      @
                      @ display the current seconds
                      @
                      PICT { # 0h # 0h } TIME 100 * FP 100 * IP FMT99 
                      1 i \->GROB REPL
                      @
                      @ was a key hit
                      @
                      IF KEY THEN 
                        \-> k
                        \<<
                          @
                          @ if it's +/- key toggle 12/24 display
                          @
                          IF k 52 == THEN
                            IF -41 FS? THEN
                              -41 CF
                            ELSE
                              -41 SF
                            END
                          ELSE
                            @
                            @ if it's 1/x key flop the display
                            @
                            IF k 46 == THEN
                              rflag NOT 'rflag' STO
                            ELSE
                              @
                              @ it's something else stop the program
                              @
                              1 'done' STO
                            END
                          END 
                          @
                          @ exit the wait loop because key was pressed
                          @
                          0
                        \>>
                      ELSE
                        @
                        @ timeout?
                        @
                        IF TICKS timeout > THEN 
                          0 'wait' STO 
                          1 'done' STO
                        ELSE
                          @
                          @ has the minute changed
                          @
                          TIME FP 100 * IP m ==
                        END
                      END
                    END
                  \>>
                END
              \>>
            \>>
          @
          @ normal 1-12 clockface
          @
          CF1
"47A20E1B20FF300F3000F3000000000CFF100000000000C3C1E1000000000830
800E00000000060214203000000081400001C0000000C8003708810000002100
240042000008100027000C0000044330210C0110000202207708002000011220
00080440008002200008008000840770000C1090004000000000000100210000
0000004200300000000000060050000000000005080320000000083808025000
0000002804225000000008321402500000000800140720000000083012100000
00000004220000000000000022000000000000002A0000000000000821000000
000000004100000000000000490000000000000841C10000000000C143410000
0000000167C10000000000C1730100000000000161C10000000000C149000000
00000008410000000000000041000000000000004A0000000000000822000000
0000000022000000000000002210000000000004240E000000000820140A0000
00000820142E000000000832180A000000000028080E00000000002800500000
0000000500300000000000060021000000000042004000000000000100840C10
000C1090008000100004008000011800000C1440000204008100102000044400
400C111000081000C1000C0000002100410042000000C800C108810000008140
0001C000000006021420300000000830800E0000000000C3C1E100000000000C
FF1000000E1B20FF300F3000F3000000000CFF100000000000C3C1E100000000
0830800E00000000060214203000000081400001C0000000C800760881000000
2100120042000008100072000C00000448104206611000020800770220200001
180000022440008008000002208000840C100007709000400000000000010021
00000000004200300000000000060050000000000005080E0000000002680802
000000000528042E0000000005221408000000000520140E0000000002701210
000000000004220000000000000022000000000000002A000000000000082100
0000000000004100000000000000490000000000000841C10000000000C14340
00000000004167C10000000000C1734000000000004061C10000000000C14900
000000000008410000000000000041000000000000004A000000000000082200
00000000000022000000000000002210000000000004240A000000000830140A
000000000820142E000000000832180200000000082808020000000008380050
0000000000050030000000000006002100000000004200400000000000010084
0C10000C1090008000100004008000011C100008044000020400C00010200004
4C100100111000081000C1000C0000002100410042000000C800C10881000000
81400001C000000006021420300000000830800E0000000000C3C1E100000000
000CFF1000000B2130A67D"
          @
          @ 13-24 clockface
          @
          CF13
"47A20E1B20FF300F3000F3000000000CFF100000000000C3C1E1000000000830
800E00000000060214203000000081400001C0000000C8007508810000002100
450042000008100077000C000004477014037110000204407402402000011770
0002744000800140000240800084077000077090004000000000000100210000
0000004200300000000000060050000000000005080770000000035808044000
0000025804277000000002721401100000000240140770000000074012100000
00000004220000000000000022000000000000002A0000000000000821000000
000000004100000000000000490000000000000841E600000000089343840000
0000009067E4000000000093732400000000001261EE0000000008B369000000
00000008410000000000000041000000000000004A0000000000000822000000
0000000022000000000000002210000000000004248B300000000370140A2000
0000021014AB2000000002721888200000000258088B30000000077800500000
0000000500300000000000060021000000000042004000000000000100840370
0006E09000800250000480800001127000044440000202403704202000044770
250E21100008100027000C0000002100250042000000C8007708810000008140
0001C000000006021420300000000830800E0000000000C3C1E100000000000C
FF1000000E1B20FF300F3000F3000000000CFF100000000000C3C1E100000000
0830800E00000000060214203000000081400001C0000000C800570881000000
2100510042000008100077000C00000447601407711000020120170110200001
1720000774400080012000014080008407700007709000400000000000010021
0000000000420030000000000006005000000000000508056000000007780805
2000000001180427200000000772140120000000044014017000000007701210
000000000004220000000000000022000000000000002A000000000000082100
0000000000004100000000000000490000000000000841EC0000000000B34384
00000000009067E4000000000093732400000000001263EE0000000008B34900
000000000008410000000000000041000000000000004A000000000000082200
000000000000220000000000000022100000000000042407600000000EE01404
200000000A201427200000000AE21805200000000A880807700000000EE80050
0000000000050030000000000006002100000000004200400000000000010084
8330000760900080801000052080000111100007244000020210760120200004
4A30520771100008100072000C0000002100520042000000C800770881000000
81400001C000000006021420300000000830800E0000000000C3C1E100000000
000CFF1000000B2130C116"
        END
      CLK1
        @
        @ digital clock display (HH:MM)
        @
        DIR
          @
          @ normal digital clock using large font
          @
          CLK
            \<< D 'DIGITS' STO CLOCK \>>
          @
          @ digital clock with seven segment font
          @
          CLK7
            \<< D7 'DIGITS' STO CLOCK \>>
          @
          @ digital clock with dot matrix font
          @
          CLKDM
            \<< DM 'DIGITS' STO CLOCK \>>
          @
          @ the actual clock display program that does all the work
          @
          CLOCK
            \<< 
              @
              @ program done flag
              @
              0 
              @
              @ this list stores the last value of seconds unit digit, 
              @ seconds tens digit, hour unit digit and hour tens digit
              @ that was written to the screen. 
              @
              @ Setting them to -1 ensures that all digit positions will
              @ get updated the first time through the loop.
              @
              { -1 -1 -1 -1 } 
              @
              @ autostop tick value
              @
              TICKS TIMEOUT + 
              @
              @ screen position for upper left hand corner of seconds 
              @ unit digit, seconds ten digit, hours unit digit and 
              @ hour tens digit
              @
              { 
                { # 65h # Ch } 
                { # 4Dh # Ch } 
                { # 1Dh # Ch } 
                { #  5h # Ch } 
              } 
              \-> done odigits ticks ulhc
              \<<
                @
                @ clear display and view graphics screen
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ display the colon in the HH:MM format. The colon is 
                @ stored in the eleventh position of each font
                @
                PICT { # 35h # Ch } 'DIGITS' 11 GET REPL
                @
                @ go until we're stopped or timeout
                @
                WHILE done NOT REPEAT 
                  @
                  @ break the time up into h/m/s/t
                  @
                  TIME UTIME 
                  \-> h m s t
                  \<<
                    @
                    @ force 12 hour display
                    @
                    IF -41 FC? THEN 
                      h 12 MOD 'h' STO
                    END 
                    @
                    @ get the minutes unit digit
                    @
                    m 10 MOD 
                    @
                    @ get the minutes tens digit
                    @
                    m 10 / IP 
                    @
                    @ get the hours units digit
                    @
                    h 10 MOD 
                    @
                    @ get the hours tens digit
                    @
                    h 10 / IP 
                    @
                    @ put in a list { munits mtens hunits htens }
                    @
                    4 \->LIST 
                    @
                    @ since the time display is an incrementing display 
                    @ we can stop updating the display when we get to 
                    @ the first digit that hasn't changed from the 
                    @ previous update
                    @
                    @ we do the updating from least significant (minutes 
                    @ unit digit) to most significant (hours tens digit).
                    @
                    1 
                    \-> digits i
                    \<<
                      @
                      @ does the current digit need updating
                      @
                      WHILE digits i GET odigits i GET \=/ REPEAT
                        @
                        @ a -1 indicates this is the first time we're 
                        @ updating this digit position. When that happens
                        @ there is no previous digit to remove so we just
                        @ display the current digit.
                        @
                        @ if this isn't the first time we're updating this
                        @ digit then we XOR the new digit to the screen 
                        @ then we XOR the old digit off the screen.
                        @
                        IF odigits i GET -1 == THEN 
                          PICT ulhc i GET 'DIGITS' digits i GET 
                          1 + GET REPL
                        ELSE 
                          PICT ulhc i GET 'DIGITS' digits i GET 
                          1 + GET GXOR 
                          PICT ulhc i GET 'DIGITS' odigits i GET 
                          1 + GET GXOR
                        END 
                        @
                        @ make the current digit the previous digit for
                        @ the next pass
                        @
                        odigits i digits i GET PUT 'odigits' STO 
                        @
                        @ do the next digit but keep it 1 .. 4
                        @
                        i 1 + 4 MIN 'i' STO
                      END 
                      @
                      @ we display the current seconds for the next minute
                      @
                      1
                      WHILE REPEAT 
                        @
                        @ display the seconds
                        @
                        PICT { # 7Ch # Ch } 
                        TIME 100 * FP 100 * IP FMT99 1 \->GROB REPL
                        @
                        @ has the minute changed
                        @
                        IF TIME FP 100 * IP m \=/ THEN 
                          @
                          @ exit the minute loop
                          @
                          0
                        ELSE
                          @
                          @ was there a key pressed
                          @
                          IF KEY THEN 
                            @
                            @ throw the key away
                            @
                            DROP 
                            @
                            @ force the program to stop
                            @
                            1 'done' STO 
                            @
                            @ stop the minute loop
                            @
                            0
                          ELSE
                            @
                            @ auto shutdown
                            @
                            IF TICKS ticks > THEN 
                              @
                              @ force the program to stop
                              @
                              1 'done' STO 
                              @
                              @ stop the minute loop
                              @
                              0
                            ELSE 
                              @
                              @ keep the minute loop going
                              @
                              1
                            END
                          END
                        END
                      END
                    \>>
                  \>>
                END
              \>>
            \>>
          @
          @ normal digits
          @
          D
"47A20E1B20FF00082000810000FFF000FFF000FFF000FFF00F000F0F000F0F00
0F0F000F0F000F0F000F0F000F0F000F0F00FF0F00FF0F00FF0F00FF0F0F0F0F
0F0F0F0F0F0F0F0F0FF00F0FF00F0FF00F0FF00F0F000F0F000F0F000F0F000F
0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF00000000000000000
000000000E1B20FF000820008100000F00000F00000F00000F0000FF0000FF00
00FF0000FF00000F00000F00000F00000F00000F00000F00000F00000F00000F
00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0000
0F00000F00000F00000F00000F0000FFF000FFF000FFF000FFF0000000000000
0000000000000E1B20FF00082000810000FFF000FFF000FFF000FFF00F000F0F
000F0F000F0F000F0F000F0F000F0F000F0F000F0000F00000F00000F00000F0
000F00000F00000F00000F0000F00000F00000F00000F0000F00000F00000F00
000F00000F00000F00000F00000F00000FFFFF0FFFFF0FFFFF0FFFFF00000000
00000000000000000E1B20FF00082000810000FFF000FFF000FFF000FFF00F00
0F0F000F0F000F0F000F00000F00000F00000F00000F00000F00000F00000F00
000F00FFF000FFF000FFF000FFF000000F00000F00000F00000F00000F00000F
00000F00000F0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF00000
000000000000000000000E1B20FF0008200081000000F00000F00000F00000F0
000FF0000FF0000FF0000FF000F0F000F0F000F0F000F0F00F00F00F00F00F00
F00F00F00FFFFF0FFFFF0FFFFF0FFFFF0000F00000F00000F00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000000000000000000000000E1B20FF0008200081000FFFFF0FFFFF0FFFFF0F
FFFF0F00000F00000F00000F00000F00000F00000F00000F00000FFFF00FFFF0
0FFFF00FFFF000000F00000F00000F00000F00000F00000F00000F00000F0000
0F00000F00000F00000F0F000F0F000F0F000F0F000F00FFF000FFF000FFF000
FFF00000000000000000000000000E1B20FF000820008100000FF0000FF0000F
F0000FF000F00000F00000F00000F0000F00000F00000F00000F00000F00000F
00000F00000F00000FFFF00FFFF00FFFF00FFFF00F000F0F000F0F000F0F000F
0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF000FF
F000FFF00000000000000000000000000E1B20FF0008200081000FFFFF0FFFFF
0FFFFF0FFFFF00000F00000F00000F00000F00000F00000F00000F00000F0000
F00000F00000F00000F0000F00000F00000F00000F0000F00000F00000F00000
F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F000
00F00000F0000000000000000000000000000E1B20FF00082000810000FFF000
FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F
0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF00F000F0F000F0F00
0F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000
FFF000FFF000FFF00000000000000000000000000E1B20FF00082000810000FF
F000FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F
000F0F000F0F000F0F000F0F000F00FFFF00FFFF00FFFF00FFFF00000F00000F
00000F00000F00000F00000F00000F00000F0000F00000F00000F00000F000FF
0000FF0000FF0000FF000000000000000000000000000E1B20FF000820008100
00000000000000000000000000000000000000000000000000FF0000FF0000FF
0000FF0000FF0000FF0000FF0000FF0000000000000000000000000000FF0000
FF0000FF0000FF0000FF0000FF0000FF0000FF00000000000000000000000000
0000000000000000000000000000000000000000000000000B21301C51"
          @
          @ seven segment digits
          @
          D7
"47A20E1B207E0004200041000EFFF70DFFFB0BFFFD07FFFE0F000F0F000F0F00
0F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F07000E03000C01
000801000803000C07000E0F000F0F000F0F000F0F000F0F000F0F000F0F000F
0F000F0F000F0F000F0F000F07FFFE0BFFFD0DFFFB0EFFF70E1B207E00042000
410000000000000800000C00000E00000F00000F00000F00000F00000F00000F
00000F00000F00000F00000F00000F00000E00000C00000800000800000C0000
0E00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00
000F00000E00000C0000080000000E1B207E0004200041000EFFF70CFFFB08FF
FD00FFFE00000F00000F00000F00000F00000F00000F00000F00000F00000F00
000F00000F00000E08FFFD0CFFFB0DFFF30BFFF10700000F00000F00000F0000
0F00000F00000F00000F00000F00000F00000F00000F000007FFF00BFFF10DFF
F30EFFF70E1B207E0004200041000EFFF70CFFFB08FFFD00FFFE00000F00000F
00000F00000F00000F00000F00000F00000F00000F00000F00000F00000E08FF
FD0CFFFB0CFFFB08FFFD00000E00000F00000F00000F00000F00000F00000F00
000F00000F00000F00000F00000F00FFFE08FFFD0CFFFB0EFFF70E1B207E0004
2000410000000001000803000C07000E0F000F0F000F0F000F0F000F0F000F0F
000F0F000F0F000F0F000F0F000F0F000F07000E0BFFFD0DFFFB0CFFFB08FFFD
00000E00000F00000F00000F00000F00000F00000F00000F00000F00000F0000
0F00000F00000E00000C0000080000000E1B207E0004200041000EFFF70DFFF3
0BFFF107FFF00F00000F00000F00000F00000F00000F00000F00000F00000F00
000F00000F00000700000BFFF10DFFF30CFFFB08FFFD00000E00000F00000F00
000F00000F00000F00000F00000F00000F00000F00000F00000F00FFFE08FFFD
0CFFFB0EFFF70E1B207E0004200041000EFFF70DFFF30BFFF107FFF00F00000F
00000F00000F00000F00000F00000F00000F00000F00000F00000F0000070000
0BFFF10DFFF30DFFFB0BFFFD07000E0F000F0F000F0F000F0F000F0F000F0F00
0F0F000F0F000F0F000F0F000F0F000F07FFFE0BFFFD0DFFFB0EFFF70E1B207E
0004200041000EFFF70CFFFB08FFFD00FFFE00000F00000F00000F00000F0000
0F00000F00000F00000F00000F00000F00000F00000E00000C00000800000800
000C00000E00000F00000F00000F00000F00000F00000F00000F00000F00000F
00000F00000F00000E00000C0000080000000E1B207E0004200041000EFFF70D
FFFB0BFFFD07FFFE0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F
0F000F0F000F0F000F07000E0BFFFD0DFFFB0DFFFB0BFFFD07000E0F000F0F00
0F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F07FFFE0B
FFFD0DFFFB0EFFF70E1B207E0004200041000EFFF70DFFFB0BFFFD07FFFE0F00
0F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F07
000E0BFFFD0DFFFB0CFFFB08FFFD00000E00000F00000F00000F00000F00000F
00000F00000F00000F00000F00000F00000F00FFFE08FFFD0CFFFB0EFFF70E1B
207E000420004100000000000000000000000000000000000000000000000000
000000000000000000000000000F00000F00000F00000F000000000000000000
00000000000F00000F00000F00000F0000000000000000000000000000000000
00000000000000000000000000000000000000000B21309B2F"
          @
          @ place holder for current digit font
          @
          DIGITS
            0
          @
          @ dot matrix digits
          @
          DM
"47A20E1B20FF0008200081000077700077700077700000000700070700070700
0700000007000707000707000700000007007707007707007700000007070707
0707070707000000077007077007077007000000070007070007070007000000
0700070700070700070000000077700077700077700000000000000000000000
000000000E1B20FF000820008100000700000700000700000000007700007700
0077000000000007000007000007000000000007000007000007000000000007
0000070000070000000000070000070000070000000000070000070000070000
0000000700000700000700000000007770007770007770000000000000000000
0000000000000E1B20FF00082000810000777000777000777000000007000707
0007070007000000070007070007070007000000000070000070000070000000
0007000007000007000000000070000070000070000000000700000700000700
0000000007000007000007000000000007777707777707777700000000000000
00000000000000000E1B20FF0008200081000077700077700077700000000700
0707000707000700000000000700000700000700000000000700000700000700
0000007770007770007770000000000007000007000007000000000007000007
0000070000000700070700070700070000000077700077700077700000000000
000000000000000000000E1B20FF000820008100000070000070000070000000
0007700007700007700000000070700070700070700000000700700700700700
7000000007777707777707777700000000007000007000007000000000007000
0070000070000000000070000070000070000000000070000070000070000000
0000000000000000000000000E1B20FF00082000810007777707777707777700
0000070000070000070000000000070000070000070000000000077770077770
0777700000000000070000070000070000000000070000070000070000000000
0700000700000700000007000707000707000700000000777000777000777000
00000000000000000000000000000E1B20FF0008200081000007700007700007
7000000000700000700000700000000007000007000007000000000007000007
0000070000000000077770077770077770000000070007070007070007000000
0700070700070700070000000700070700070700070000000077700077700077
700000000000000000000000000000000E1B20FF000820008100077777077777
0777770000000000070000070000070000000000070000070000070000000000
7000007000007000000000070000070000070000000000700000700000700000
0000007000007000007000000000007000007000007000000000007000007000
0070000000000000000000000000000000000E1B20FF00082000810000777000
7770007770000000070007070007070007000000070007070007070007000000
0700070700070700070000000077700077700077700000000700070700070700
0700000007000707000707000700000007000707000707000700000000777000
77700077700000000000000000000000000000000E1B20FF0008200081000077
7000777000777000000007000707000707000700000007000707000707000700
0000070007070007070007000000007777007777007777000000000007000007
0000070000000000070000070000070000000000700000700000700000000077
000077000077000000000000000000000000000000000E1B20FF000820008100
0000000000000000000000000000000000000000000000000077000077000077
0000000000770000770000770000000000000000000000000000000000770000
7700007700000000007700007700007700000000000000000000000000000000
0000000000000000000000000000000000000000000000000B213069F6"
        END
      CLK2
        @
        @ odometer like clock display. 
        @ At 50 seconds into the minute any digits that are supposed 
        @ to change are scrolled vertically off the top of the screen 
        @ while the replacement digit is scrolled on from the bottom
        @
        DIR
          CLK
            \<< 
              @
              @ program termination flag
              @
              0 
              @
              @ auto shutdown flag
              @
              TICKS TIMEOUT + 
              @
              @ get the width and height of a digit
              @
              GCOLON SIZE B\->R SWAP B\->R SWAP 
              \-> done ticks w h
              \<<
                @
                @ get the screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ display the colon
                @
                PICT { # 35h # Ch } GCOLON REPL
                WHILE done NOT REPEAT 
                  @
                  @ break the time up into h/m/s/t
                  @
                  TIME UTIME 
                  \-> hh mm ss tt
                  \<< 
                    @
                    @ 12 hour display
                    @
                    hh 12 MOD 'hh' STO
                    @
                    @ midnight to 1:00 and noon to 13:00 are displayed 
                    @
                    # as 12 and not as 00
                    IF hh 0 == THEN 
                      12 'hh' STO
                    END 
                    @
                    @ get the hours tens digit
                    @
                    hh 10 / IP
                    @
                    @ get the hours units digit
                    @
                    hh 
                    @
                    @ get the minutes tens digit
                    @
                    mm 10 / IP 
                    @
                    @ get the minutes units digit
                    @
                    mm 10 MOD 
                    \-> h10 h1 m10 m1
                    \<< 
                      @
                      @ hours tens digit
                      @
                      PICT { # 5h # Ch } GH10 # 0h h10 h *
                      @
                      @ the hours tens digit changes when the hours 
                      # goes from 09 to 10 or when the hours goes from 
                      @ 12 to 01. the change only happens when the 
                      @ current minutes are 59 and the seconds are >50
                      @
                      IF h1 9 == h1 12 == OR mm 59 == AND ss 50 > AND THEN
                        @
                        @ ss-50 generates a number from 0 to 10 which is 
                        @ used as the offset to 'slide' from one digit to 
                        @ the next
                        @
                        h ss 50 - 10 / * +
                      END 
                      R\->B 2 \->LIST 
                      w # 1h - OVER 2 GET h 1 - + 2 \->LIST SUB REPL 
                      @
                      @ hours units digit
                      @
                      PICT { # 1Dh # Ch } GH1 # 0h h1 1 - h *
                      @
                      @ the hours unit digit only changes when the 
                      @ minutes are 59 and the seconds are >50
                      @
                      IF mm 59 == ss 50 > AND THEN 
                        h ss 50 - 10 / * +
                      END 
                      R\->B 2 \->LIST 
                      w # 1h - OVER 2 GET h 1 - + 2 \->LIST SUB REPL 
                      @
                      @ minutes tens digit
                      @
                      PICT { # 4Dh # Ch } GM10 # 0h m10 h *
                      @
                      @ the minutes ten digit only changes when the 
                      @ minutes unit digit is 9 and the seconds is >50
                      @
                      IF m1 9 == ss 50 > AND THEN 
                        h ss 50 - 10 / * +
                      END 
                      R\->B 2 \->LIST 
                      w # 1h - OVER 2 GET h 1 - + 2 \->LIST SUB REPL 
                      @
                      @ minutes units digit
                      @
                      PICT { # 65h # Ch } GM1 # 0h m1 h *
                      @
                      @ the minutes unit digit only changes when the 
                      @ seconds is >50
                      @
                      IF ss 50 > THEN 
                        h ss 50 - 10 / * +
                      END 
                      R\->B 2 \->LIST 
                      w # 1h - OVER 2 GET h 1 - + 2 \->LIST SUB REPL 
                      @
                      @ wait around until we're 50 seconds into the minute
                      @
                      1 
                      WHILE REPEAT
                        @
                        @ any key press stops the program
                        @
                        IF KEY THEN 
                          @
                          @ throw the key away
                          @
                          DROP 
                          @
                          @ stop the program
                          @
                          1 'done' STO 
                          @
                          @ stop the minute wait loop
                          @
                          0
                        ELSE
                          @
                          @ timeout
                          @
                          IF TICKS ticks > THEN 
                            @
                            @ stop the program
                            @
                            1 'done' STO 
                            @
                            @ stop the minute wait loop
                            @
                            0
                          ELSE
                            @
                            @ are we in the first 50 seconds
                            @
                            IF TIME 100 * FP 100 * IP DUP 2 \>= 
                               SWAP 50 \<= AND
                            THEN
                              @
                              @ first 50, just update the current seconds
                              @
                              PICT { # 7Ch # Ch } 
                              TIME 100 * FP 100 * IP FMT99 1 \->GROB REPL 
                              @
                              @ keep waiting
                              @
                              1
                            ELSE 
                              @
                              @ time's up, change some digits
                              @
                              0
                            END
                          END
                        END
                      END
                    \>>
                  \>>
                END
              \>>
            \>>
          @
          @ colon GROB
          @
          GCOLON
"E1B20FF000820008100000000000000000000000000000000000000000000000
00000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF000000000000000
0000000000000FF0000FF0000FF0000FF0000FF0000FF0000FF0000FF0000000
0000000000000000000000000000000000000000000000000000000000000000
0000B41E"
          @
          @ hour units digits "1234567890121"
          @
          GH1
"E1B20F3C00802008100000F00000F00000F00000F0000FF0000FF0000FF0000F
F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000F00000F00000F0000FFF000FFF000FFF000FFF0000000000000000000000
00000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0
F000F0F000F0000F00000F00000F00000F0000F00000F00000F00000F0000F00
000F00000F00000F0000F00000F00000F00000F00000F00000F00000F00000F0
0000FFFFF0FFFFF0FFFFF0FFFFF00000000000000000000000000FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F00000F00000F00000F00000F00000
F00000F00000F00000F00FFF000FFF000FFF000FFF000000F00000F00000F000
00F00000F00000F00000F00000F0F000F0F000F0F000F0F000F00FFF000FFF00
0FFF000FFF00000000000000000000000000000F00000F00000F00000F0000FF
0000FF0000FF0000FF000F0F000F0F000F0F000F0F00F00F00F00F00F00F00F0
0F00FFFFF0FFFFF0FFFFF0FFFFF0000F00000F00000F00000F00000F00000F00
000F00000F00000F00000F00000F00000F00000F00000F00000F00000F000000
00000000000000000000FFFFF0FFFFF0FFFFF0FFFFF0F00000F00000F00000F0
0000F00000F00000F00000F00000FFFF00FFFF00FFFF00FFFF000000F00000F0
0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0F000
F0F000F0F000F0F000F00FFF000FFF000FFF000FFF0000000000000000000000
000000FF0000FF0000FF0000FF000F00000F00000F00000F0000F00000F00000
F00000F00000F00000F00000F00000F00000FFFF00FFFF00FFFF00FFFF00F000
F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F0
00F00FFF000FFF000FFF000FFF00000000000000000000000000FFFFF0FFFFF0
FFFFF0FFFFF00000F00000F00000F00000F00000F00000F00000F00000F0000F
00000F00000F00000F0000F00000F00000F00000F0000F00000F00000F00000F
00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0000
0F00000F00000000000000000000000000000FFF000FFF000FFF000FFF00F000
F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F0
00F00FFF000FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0
F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF000000
000000000000000000000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F0
00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFFF00FFFF0
0FFFF00FFFF00000F00000F00000F00000F00000F00000F00000F00000F0000F
00000F00000F00000F000FF0000FF0000FF0000FF00000000000000000000000
00000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0
F000F0F000F0F00FF0F00FF0F00FF0F00FF0F0F0F0F0F0F0F0F0F0F0F0F0FF00
F0FF00F0FF00F0FF00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F0
00F00FFF000FFF000FFF000FFF0000000000000000000000000000F00000F000
00F00000F0000FF0000FF0000FF0000FF00000F00000F00000F00000F00000F0
0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
F00000F00000F00000F00000F00000F00000F00000F00000F0000FFF000FFF00
0FFF000FFF000000000000000000000000000FFF000FFF000FFF000FFF00F000
F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0000F00000F00000F0000
0F0000F00000F00000F00000F0000F00000F00000F00000F0000F00000F00000
F00000F00000F00000F00000F00000F00000FFFFF0FFFFF0FFFFF0FFFFF00000
0000000000000000000000F00000F00000F00000F0000FF0000FF0000FF0000F
F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000F00000F00000F0000FFF000FFF000FFF000FFF0000000000000000000000
000078CC"
          @
          @ hour tens digits "010"
          @
          GH10
"E1B20FD200870008100000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000F00000F00000F00000F0000FF0000FF0000FF0000FF00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
F0000FFF000FFF000FFF000FFF00000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000145"
          @
          @ minutes unit digits "01234567890"
          @
          GM1
"E1B20F5A008B100810000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F0
00F0F000F0F000F0F000F0F000F0F00FF0F00FF0F00FF0F00FF0F0F0F0F0F0F0
F0F0F0F0F0F0FF00F0FF00F0FF00F0FF00F0F000F0F000F0F000F0F000F0F000
F0F000F0F000F0F000F00FFF000FFF000FFF000FFF0000000000000000000000
000000F00000F00000F00000F0000FF0000FF0000FF0000FF00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
F0000FFF000FFF000FFF000FFF000000000000000000000000000FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0000F
00000F00000F00000F0000F00000F00000F00000F0000F00000F00000F00000F
0000F00000F00000F00000F00000F00000F00000F00000F00000FFFFF0FFFFF0
FFFFF0FFFFF00000000000000000000000000FFF000FFF000FFF000FFF00F000
F0F000F0F000F0F000F00000F00000F00000F00000F00000F00000F00000F000
00F00FFF000FFF000FFF000FFF000000F00000F00000F00000F00000F00000F0
0000F00000F0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF000000
00000000000000000000000F00000F00000F00000F0000FF0000FF0000FF0000
FF000F0F000F0F000F0F000F0F00F00F00F00F00F00F00F00F00FFFFF0FFFFF0
FFFFF0FFFFF0000F00000F00000F00000F00000F00000F00000F00000F00000F
00000F00000F00000F00000F00000F00000F00000F0000000000000000000000
0000FFFFF0FFFFF0FFFFF0FFFFF0F00000F00000F00000F00000F00000F00000
F00000F00000FFFF00FFFF00FFFF00FFFF000000F00000F00000F00000F00000
F00000F00000F00000F00000F00000F00000F00000F0F000F0F000F0F000F0F0
00F00FFF000FFF000FFF000FFF0000000000000000000000000000FF0000FF00
00FF0000FF000F00000F00000F00000F0000F00000F00000F00000F00000F000
00F00000F00000F00000FFFF00FFFF00FFFF00FFFF00F000F0F000F0F000F0F0
00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF00
0FFF000FFF00000000000000000000000000FFFFF0FFFFF0FFFFF0FFFFF00000
F00000F00000F00000F00000F00000F00000F00000F0000F00000F00000F0000
0F0000F00000F00000F00000F0000F00000F00000F00000F00000F00000F0000
0F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000000
000000000000000000000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F0
00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000
F0F000F0F000F0F000F00FFF000FFF000FFF000FFF0000000000000000000000
00000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0
F000F0F000F0F000F0F000F0F000F0F000F00FFFF00FFFF00FFFF00FFFF00000
F00000F00000F00000F00000F00000F00000F00000F0000F00000F00000F0000
0F000FF0000FF0000FF0000FF0000000000000000000000000000FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F00F
F0F00FF0F00FF0F00FF0F0F0F0F0F0F0F0F0F0F0F0F0FF00F0FF00F0FF00F0FF
00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF00
0FFF000FFF00000000000000000000000000EF2B"
          @
          @ minutes tens digit "0123450"
          @
          GM10
"E1B20F960081100810000FFF000FFF000FFF000FFF00F000F0F000F0F000F0F0
00F0F000F0F000F0F000F0F000F0F00FF0F00FF0F00FF0F00FF0F0F0F0F0F0F0
F0F0F0F0F0F0FF00F0FF00F0FF00F0FF00F0F000F0F000F0F000F0F000F0F000
F0F000F0F000F0F000F00FFF000FFF000FFF000FFF0000000000000000000000
000000F00000F00000F00000F0000FF0000FF0000FF0000FF00000F00000F000
00F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0
0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000
F0000FFF000FFF000FFF000FFF000000000000000000000000000FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0000F
00000F00000F00000F0000F00000F00000F00000F0000F00000F00000F00000F
0000F00000F00000F00000F00000F00000F00000F00000F00000FFFFF0FFFFF0
FFFFF0FFFFF00000000000000000000000000FFF000FFF000FFF000FFF00F000
F0F000F0F000F0F000F00000F00000F00000F00000F00000F00000F00000F000
00F00FFF000FFF000FFF000FFF000000F00000F00000F00000F00000F00000F0
0000F00000F0F000F0F000F0F000F0F000F00FFF000FFF000FFF000FFF000000
00000000000000000000000F00000F00000F00000F0000FF0000FF0000FF0000
FF000F0F000F0F000F0F000F0F00F00F00F00F00F00F00F00F00FFFFF0FFFFF0
FFFFF0FFFFF0000F00000F00000F00000F00000F00000F00000F00000F00000F
00000F00000F00000F00000F00000F00000F00000F0000000000000000000000
0000FFFFF0FFFFF0FFFFF0FFFFF0F00000F00000F00000F00000F00000F00000
F00000F00000FFFF00FFFF00FFFF00FFFF000000F00000F00000F00000F00000
F00000F00000F00000F00000F00000F00000F00000F0F000F0F000F0F000F0F0
00F00FFF000FFF000FFF000FFF000000000000000000000000000FFF000FFF00
0FFF000FFF00F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F00F
F0F00FF0F00FF0F00FF0F0F0F0F0F0F0F0F0F0F0F0F0FF00F0FF00F0FF00F0FF
00F0F000F0F000F0F000F0F000F0F000F0F000F0F000F0F000F00FFF000FFF00
0FFF000FFF00000000000000000000000000922D"
        END
      CLK3
        @
        @ two line date/time display. 
        @ Date is "MMM DD YYYY" and time is "HH:MM"
        @
        DIR
          CLK
            \<< 
              @
              @ program done flag
              @
              0 
              @
              @ current screen digits from least significant (minute 
              @ unit, minute ten, hour unit, hour ten, day unit, day 
              @ ten, month, year unit, year ten, year hundred and year 
              @ thousand)
              @
              { -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 }
              @
              @ timeout shutdown
              @
              TICKS TIMEOUT + 
              @
              @ screen coordinates for upper left hand corner of each 
              @ digit position
              @
              { 
                { # 54h # 24h } { # 48h # 24h } { # 30h # 24h } 
                { # 24h # 24h } { # 3Ch #  8h } { # 30h #  8h } 
                { #  0h #  8h } { # 78h #  8h } { # 6Ch #  8h } 
                { # 60h #  8h } { # 54h #  8h } 
              } 
              \-> done odigits ticks ulhc
              \<<
                @
                @ get screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ display colon for time (hh:mm)
                @
                PICT { # 3Ch # 24h } 'DIGITS' 11 GET REPL
                WHILE done NOT REPEAT 
                  @
                  @ unpack date into m/d/y and time into h/m/s/t
                  @
                  DATE UDATE TIME UTIME 
                  \-> mm dd yy h m s t
                  \<<
                    @
                    @ 12 hour
                    @
                    IF -41 FC? THEN 
                      h 12 MOD 'h' STO
                    END 
                    @
                    @ minute unit
                    @
                    m 10 MOD 
                    @
                    @ minute ten
                    @
                    m 10 / IP 
                    @
                    @ hour unit
                    @
                    h 10 MOD 
                    @
                    @ hour ten
                    @
                    h 10 / IP 
                    @
                    @ day unit
                    @
                    dd 10 MOD
                    @
                    @ day ten
                    @
                    dd 10 / IP 
                    @
                    @ month
                    @
                    mm 
                    @
                    @ year unit
                    @
                    yy 10 MOD 
                    @
                    @ year ten
                    @
                    yy 10 / IP 10 MOD 
                    @
                    @ year hundred
                    @
                    yy 100 / IP 10 MOD 
                    @
                    @ year thousand
                    @
                    yy 1000 / IP 10 MOD 
                    @
                    @ wrap them all into an array
                    @
                    11 \->LIST 
                    \-> digits
                    \<< 
                      @
                      @ compare current digits with previous digits and 
                      @ update the screen as required
                      @
                      1 11
                      FOR i
                        IF digits i GET odigits i GET \=/ THEN 
                          PICT ulhc i GET i 7 == 'MONTHS' 'DIGITS' IFTE 
                          digits i GET i 7 == 0 1 IFTE + GET REPL 
                          odigits i digits i GET PUT 'odigits' STO
                        END
                      NEXT 
                      @
                      @ wait around for the this minute displaying the 
                      @ seconds. process any keys
                      @
                      1
                      WHILE REPEAT 
                        @
                        @ display the seconds
                        @
                        PICT { # 60h # 24h } 
                        TIME 100 * FP 100 * IP FMT99 1 \->GROB REPL
                        @
                        @ has the minute changed
                        @
                        IF TIME FP 100 * IP m \=/ THEN 
                          @
                          @ exit the minute loop
                          @
                          0
                        ELSE
                          @
                          @ was a key pressed
                          @
                          IF KEY THEN 
                            @
                            @ throw it away
                            @
                            DROP
                            @
                            @ end the program
                            @
                            1 'done' STO 
                            @
                            @ end the minute loop
                            @
                            0
                          ELSE
                            @
                            @ auto timeout
                            @
                            IF TICKS ticks > THEN 
                              @
                              @ end the program
                              @
                              1 'done' STO 
                              @
                              @ end the minute loop
                              @
                              0
                            ELSE 
                              @
                              @ hang around for the rest of the minute
                              @
                              0
                            END
                          END
                        END
                      END
                    \>>
                  \>>
                END
              \>>
            \>>
          @
          @ digits GROB
          @
          DIGITS
"47A20E1B20F500041000C0000CF00CF0030303030303030303C303C303330333
0F030F0303030303030303030CF00CF0000000000E1B20F500041000C0000030
00300C300C300030003000300030003000300030003000300030003000300CF0
0CF0000000000E1B20F500041000C0000CF00CF0030303030303030300C000C0
003000300C000C0003000300030003000FF30FF3000000000E1B20F500041000
C0000CF00CF00303030300030003000300030CF00CF000030003000300030303
03030CF00CF0000000000E1B20F500041000C00000C000C000F000F00CC00CC0
03C003C00FF30FF300C000C000C000C000C000C000C000C0000000000E1B20F5
00041000C0000FF30FF303000300030003000FF00FF000030003000300030003
0003030303030CF00CF0000000000E1B20F500041000C00000F000F00C000C00
03000300030003000FF00FF00303030303030303030303030CF00CF000000000
0E1B20F500041000C0000FF30FF3000300030003000300C000C0003000300C00
0C000C000C000C000C000C000C00000000000E1B20F500041000C0000CF00CF0
0303030303030303030303030CF00CF00303030303030303030303030CF00CF0
000000000E1B20F500041000C0000CF00CF00303030303030303030303030CF3
0CF3000300030003000300C000C00C300C30000000000E1B20F500041000C000
00000000000000000C300C300C300C30000000000C300C300C300C3000000000
00000000000000000B2130F762"
          @
          @ months GROB
          @
          MONTHS
"47A20E1B207D0004100042000003000000000300000000030000000003000000
000300000000030000000003CF0FF00003CF0FF0000300330300030033030303
CF33030303CF330303033033030303303303030330330303033033030CF0CF33
030CF0CF3303000000000000000000000E1B207D0004100042000FF30003000F
F300030003000003000300000300030000030003000003000300CF0FF00300CF
0FF00FF03033030FF03033030300FF33030300FF330303003003030300300303
030030030303003003030300CF0FF00300CF0FF0000000000000000000000E1B
207D000410004200030300000003030000000FC30000000FC300000003330000
0003330000000333CF03F30333CF03F30333003F000333003F000303CF330003
03CF330003033033000303303300030330330003033033000303CF33000303CF
3300000000000000000000000E1B207D0004100042000CF00000000CF0000000
03030000000303000000030300000003030000000303FF03F30303FF03F30FF3
303F000FF3303F00030330330003033033000303FF03000303FF030003033003
00030330030003033003000303300300000030000000003000000E1B207D0004
10004200030300000003030000000FC30000000FC30000000333000000033300
00000333CF03030333CF0303033300330303330033030303CF33030303CF3303
0303303CF30303303CF3030330300303033030030303CF30030303CF30030000
000CF00000000CF00E1B207D0004100042000003000000000300000000030000
000003000000000300000000030000000003303FF00003303FF0000330330300
0330330303033033030303303303030330330303033033030303303303030330
33030CF0CF33030CF0CF3303000000000000000000000E1B207D000410004200
0003000C300003000C3000030000300003000030000300003000030000300003
3030300003303030000330303000033030300303303030030330303003033030
300303303030030330303003033030300CF0CF3CF00CF0CF3CF0000000000000
000000000E1B207D0004100042000CF00000000CF00000000303000000030300
0000030300000003030000000303303CF00303303CF00FF33033030FF3303303
030330330303033033030303303CF30303303CF3030330300303033030030303
CF30030303CF30030000000CF00000000CF00E1B207D0004100042000CF00000
000CF000000003030000000303000000030000000003000000000300CF0FF003
00CF0FF00CF03033030CF03033030003FF33030003FF33030003300FF0000330
0FF0030330030003033003000CF0CF03000CF0CF030000000003000000000300
0E1B207D0004100042000CF0000C000CF0000C000303000C000303000C000303
000C000303000C000303CF3F300303CF3F300303300C000303300C000303300C
000303300C000303300C000303300C000303300CC00303300CC00CF0CF30300C
F0CF3030000000000000000000000E1B207D0004100042000303000000030300
00000F030000000F030000000F030000000F030000000333CF03030333CF0303
0333303303033330330303C330330303C330330303C330330303C33033030303
303CC00303303CC00303CF00300303CF0030000000000000000000000E1B207D
0004100042000FF00000000FF000000003030000000303000000030300000003
030000000303CF0CF30303CF0CF3030330330003033033000303FF33000303FF
330003033003000303300300030330030003033003000FF0CF0CF30FF0CF0CF3
000000000000000000000B21304FB6"
        END
      CLK4
        DIR
          @
          @ display the date and time as a 14-position abacus. 
          @ The display will be: YYYYMMDDhhmmss
          @
          CLK
            \<< 
              @
              @ program done flag
              @
              0 
              { -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 } 
              TICKS TIMEOUT + 
              \-> done odigits ticks
              \<<
                @
                @ get the screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ display the left and right frames
                @
                PICT { # 78h # 0h } 'DIGITS' 12 GET REPL 
                PICT { #  0h # 0h } 'DIGITS' 11 GET REPL
                WHILE done NOT REPEAT 
                  @
                  @ unpack date into m/d/y and time into h/m/s/t
                  @
                  DATE UDATE TIME UTIME 
                  \-> mm dd yy h m s t
                  \<<
                    @
                    @ 12 hour time
                    @
                    IF -41 FC? THEN 
                      h 12 MOD 'h' STO
                    END 
                    @
                    @ second unit
                    @
                    s 10 MOD 
                    @
                    @ second tens
                    @
                    s 10 / IP 
                    @
                    @ minute unit
                    @
                    m 10 MOD 
                    @
                    @ minute ten
                    @
                    m 10 / IP 
                    @
                    @ hour unit
                    @
                    h 10 MOD 
                    @
                    @ hour ten
                    @
                    h 10 / IP 
                    @
                    @ day unit
                    @
                    dd 10 MOD
                    @
                    @ day ten
                    @
                    dd 10 / IP 
                    @
                    @ month unit
                    @
                    mm 10 MOD 
                    @
                    @ month ten
                    @
                    mm 10 / IP 
                    @
                    @ year unit
                    @
                    yy 10 MOD 
                    @
                    @ year ten
                    @
                    yy 10 / IP 10 MOD 
                    @
                    @ year hundred
                    @
                    yy 100 / IP 10 MOD 
                    @
                    @ year thousand
                    @
                    yy 1000 / IP 10 MOD 
                    @
                    @ make the current digits list
                    @
                    14 \->LIST 
                    1
                    \-> digits i
                    \<< 
                      @
                      @ has this digit changed from last time
                      @
                      WHILE digits i GET odigits i GET \=/ REPEAT 
                        @
                        @ update the screen
                        @
                        PICT 15 i - 8 * R\->B # 0h 2 \->LIST 
                        'DIGITS' digits i GET 1 + GET REPL 
                        @
                        @ make the current digit the old digit
                        @
                        odigits i digits i GET PUT 'odigits' STO
                        @
                        @ check the next digit. This will make sure that
                        @ the loop stops because when we hit the 14th
                        @ digit the index will stay at 14. The next time
                        @ through the loop it will find that the digit 
                        @ hasn't changed so the loop stops. (I thought
                        @ that worked out pretty good! jRL)
                        @
                        i 1 + 14 MIN 'i' STO
                      END
                    \>>
                    @
                    @ was a key pressed
                    @
                    IF KEY THEN 
                      @
                      @ throw it away
                      @
                      DROP 
                      @
                      @ end the program
                      @
                      1 'done' STO
                    END
                    @
                    @ has we timed out
                    @
                    IF TICKS ticks > THEN 
                      @
                      @ end the program 
                      @
                      1 'done' STO
                    END
                  \>>
                END
              \>>
            \>>
          @
          @ bead GROBs
          @
          DIGITS
"47A20E1B2078000C30008000000FFFFFFFF8181E7FFFFE781818181818181818
1FFFF818181818181818181E7FFFFE78181E7FFFFE78181E7FFFFE78181E7FFF
FE78181FFFFFFFF00E1B2078000C30008000000FFFFFFFF8181E7FFFFE781818
1818181818181FFFF818181E7FFFFE78181818181818181E7FFFFE78181E7FFF
FE78181E7FFFFE78181FFFFFFFF00E1B2078000C30008000000FFFFFFFF8181E
7FFFFE7818181818181818181FFFF818181E7FFFFE78181E7FFFFE7818181818
1818181E7FFFFE78181E7FFFFE78181FFFFFFFF00E1B2078000C30008000000F
FFFFFFF8181E7FFFFE7818181818181818181FFFF818181E7FFFFE78181E7FFF
FE78181E7FFFFE78181818181818181E7FFFFE78181FFFFFFFF00E1B2078000C
30008000000FFFFFFFF8181E7FFFFE7818181818181818181FFFF818181E7FFF
FE78181E7FFFFE78181E7FFFFE78181E7FFFFE78181818181818181FFFFFFFF0
0E1B2078000C30008000000FFFFFFFF8181818181818181E7FFFFE7818181FFF
F818181818181818181E7FFFFE78181E7FFFFE78181E7FFFFE78181E7FFFFE78
181FFFFFFFF00E1B2078000C30008000000FFFFFFFF8181818181818181E7FFF
FE7818181FFFF818181E7FFFFE78181818181818181E7FFFFE78181E7FFFFE78
181E7FFFFE78181FFFFFFFF00E1B2078000C30008000000FFFFFFFF818181818
1818181E7FFFFE7818181FFFF818181E7FFFFE78181E7FFFFE78181818181818
181E7FFFFE78181E7FFFFE78181FFFFFFFF00E1B2078000C30008000000FFFFF
FFF8181818181818181E7FFFFE7818181FFFF818181E7FFFFE78181E7FFFFE78
181E7FFFFE78181818181818181E7FFFFE78181FFFFFFFF00E1B2078000C3000
8000000FFFFFFFF8181818181818181E7FFFFE7818181FFFF818181E7FFFFE78
181E7FFFFE78181E7FFFFE78181E7FFFFE78181818181818181FFFFFFFF00E1B
2078000C30008000000CFCFCFCFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFCFC3C
3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C
FCFCFCF00E1B2078000C30008000000F3F3F3F3C3C3C3C3C3C3C3C3C3C3C3C3C
3C3C3F3F3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C
3C3C3C3C3C3F3F3F3F300B21303870"
        END
      CLK5
        DIR
          @
          @ display the time as two bar graphs
          @
          CLK
            \<< 
              @
              @ program done flag
              @
              0 
              @
              @ autoshut down time
              @
              TICKS TIMEOUT +
              @
              @ bottom left hand corner of where hours tick marks start
              @
              # 83h -41 FC? # Ch # 18h IFTE -41 FC? 8 4 IFTE * - 2 / 
              # 14h 
              @
              @ bottom left hand corner of where minutes tick makrs start
              @
              # 83h # 3Ch 2 * - 2 / # 32h 
              \-> done timeout hx hy mx my
              \<<
                @
                @ get the screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ draw the tick marks
                @
                hx hy mx my Ticks
                WHILE done NOT REPEAT 
                  @
                  @ unpack the time into h/m/s/t
                  @
                  TIME UTIME 
                  \-> h m s t
                  \<<
                    @
                    @ 12 hour
                    @
                    IF -41 FC? THEN 
                      h 12 MOD 'h' STO
                    END 
                    @
                    @ use the hours (h) to build a GROB of the right size
                    @ the GROB is displayed one pixel below the tick marks
                    @ the weird calculations are to take into account 
                    @ whether the user wants a 12 hour display or a 24 hour 
                    @ display
                    @
                    PICT hx hy 2 + 2 \->LIST -41 FC? 12 24 IFTE -41 FC? 8 4 
                    IFTE * R\->B # 4h BLANK { # 0h # 0h } h m 60 / + -41 FC? 
                    8 4 IFTE * R\->B 1 + # 4h BLANK NEG REPL REPL
                    @
                    @ use the minutes (m) to do the same thing. Again the 
                    @ GROB will be two pixels below the tick marks. We don't 
                    @ have any weird calculations here since we're always 
                    @ showing a 60 minute scale
                    @
                    @ note that the minute scale is 120 pixels wide. That 
                    @ means that we have to update the screen after every 30 
                    @ second interval and not after every minute
                    @
                    PICT mx my 2 + 2 \->LIST 60 2 * R\->B # 4h BLANK 
                    { # 0h # 0h } m s 60 / + 2 * R\->B 1 + # 4h BLANK NEG 
                    REPL REPL
                    @
                    @ wait around for the half minute to pass
                    @
                    1
                    WHILE REPEAT 
                      @
                      @ update the seconds display
                      @
                      PICT { # 0h # 0h } 
                      TIME AHMST 7 8 SUB 1 \->GROB REPL
                      @
                      @ is the seconds either 00 or 30
                      @
                      IF TIME 10000 * IP 100 MOD 30 MOD 0 == THEN 
                        @
                        @ kill the wait loop
                        @
                        0
                      ELSE
                        @
                        @ was a key pressed
                        @
                        IF KEY THEN 
                          @
                          @ thow it away
                          @
                          DROP 
                          @
                          @ stop the program
                          @
                          1 'done' STO 
                          @
                          @ stop the half minute wait loop
                          @
                          0
                        ELSE
                          @
                          @ timeout
                          @
                          IF TICKS timeout > THEN 
                            @
                            @ stop the program
                            @
                            1 'done' STO 
                            @
                            @ stop the half minute wait loop
                            @
                            0
                          ELSE 
                            @
                            @ keep waiting
                            @
                            1
                          END
                        END
                      END
                    END
                  \>>
                END
              \>>
            \>>
          @
          @ display the tick marks
          @
          Ticks
            \<< 
              @
              @ we're passed the x/y coordinates of where the hours and 
              @ minutes tick marks start
              @
              \-> hx hy mx my
              \<< 
                @
                @ draw the long horizontal line for the hours tick marks
                @
                hx hy 2 \->LIST hx -41 FC? 12 24 IFTE -41 FC? 8 4 IFTE * + 
                hy \->LIST LINE 
                @
                @ now do the actual tick marks
                @
                0 -41 FC? 12 24 IFTE 
                FOR i 
                  hx i -41 FC? 8 4 IFTE * + hy 2 \->LIST DUP OBJ\-> DROP
                  @
                  @ for 12 hour display we tick the hours and quarter hours
                  @
                  @ for 24 hour display we tick the hours, quarter hours 
                  @ and noon/midnight
                  @
                  IF -41 FC? THEN
                    IF i 3 MOD 0 == THEN 
                      # 8h
                    ELSE 
                      # 4h
                    END
                  ELSE
                    IF i 12 MOD 0 == THEN 
                      # 8h
                    ELSE
                      IF i 3 MOD 0 == THEN 
                        # 4h
                      ELSE 
                        # 2h
                      END
                    END
                  END 
                  - 2 \->LIST LINE
                NEXT 
                @
                @ label the tick marks
                @
                0 -41 FC? 12 24 IFTE
                FOR i 
                  PICT i \->STR 1 \->GROB DUP SIZE DROP 2 / i -41 FC? 8 4 
                  IFTE * hx + 1 + SWAP - hy 16 - 2 \->LIST SWAP REPL 
                  3
                STEP 
                @
                @ draw the horizontal line for the minutes tick marks
                @
                mx 0 2 * + my 2 \->LIST mx 60 2 * + my 2 \->LIST LINE 
                @
                @ draw the tick marks
                @
                0 60
                FOR i 
                  mx i 2 * + my 2 \->LIST DUP OBJ\-> DROP
                  @
                  @ we tick each minute, each five minute and the quarters
                  @
                  IF i 15 MOD 0 == THEN 
                    # 8h
                  ELSE
                    IF i 5 MOD 0 == THEN 
                      # 4h
                    ELSE 
                      # 2h
                    END
                  END 
                  - 2 \->LIST LINE
                NEXT 
                @
                @ label the ticks
                @
                0 60
                FOR i 
                  PICT i \->STR 1 \->GROB DUP SIZE DROP 2 / i 2 * mx + 1 +
                  SWAP - my 16 - 2 \->LIST SWAP REPL 
                  15
                STEP
              \>>
            \>>
        END
      CLK6
        DIR
          @
          @ this is a moving tape display of the time 
          @
          CLK
            \<< 
              @
              @ program done flag
              @
              0 
              @
              @ auto shutdown
              @
              TICKS TIMEOUT + 
              \-> done timeout
              \<<
                @
                @ get the screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                @
                @ display the reference arrow
                @
                PICT { # 3Ch # 20h } ARROW REPL
                WHILE done NOT REPEAT 
                  @
                  @ break the time into h/m/s/t
                  @
                  TIME UTIME 
                  \-> h m s t
                  \<<
                    @
                    @ 12 hour
                    @
                    IF -41 FC? THEN 
                      h 12 MOD 'h' STO
                    END 
                    @
                    @ use the hour (h) and minute (m) to extract 131 pixel 
                    @ wide section out of the correct tick GROB (either the 
                    @ 12 hour one or the 24 hour one)
                    @
                    PICT { # 0h # 10h } -41 FC? G12 G24 IFTE h 60 * m +
                    R\->B # 0h 2 \->LIST DUP OBJ\-> DROP 15 + SWAP 131 + 
                    SWAP 2 \->LIST SUB REPL 
                    @
                    @ display the numeric time below the reference arrow
                    @
                    PICT h FMT99 ":" + m FMT99 + 1 \->GROB DUP SIZE DROP 2 / 
                    # 40h SWAP - # 26h 2 \->LIST SWAP REPL 
                    @
                    @ wait around for the rest of the half minute. We wait 
                    @ in 30 second intervals because in the tick mark GROB 
                    @ one minute spans two pixels
                    @
                    1
                    WHILE REPEAT 
                      @
                      @ display the seconds
                      @
                      PICT { # 0h # 0h } 
                      TIME 100 * FP 100 * IP FMT99 1 \->GROB REPL
                      @
                      @ has the half minutes changed
                      @
                      IF TIME 10000 * IP 100 MOD 30 MOD 0 == THEN 
                        @
                        @ exit the half minute wait loop
                        @
                        0
                      ELSE
                        @
                        @ was a key pressed
                        @
                        IF KEY THEN 
                          @
                          @ throw it away
                          @
                          DROP 
                          @
                          @ stop the program
                          @
                          1 'done' STO 
                          @
                          @ stop the half minute wait loop
                          @
                          0
                        ELSE
                          @
                          @ did we timeout
                          @
                          IF TICKS timeout > THEN 
                            @
                            @ stop the program
                            @
                            1 'done' STO 
                            @
                            @ stop the half minute wait loop
                            @
                            0
                          ELSE 
                            @
                            @ keep waiting
                            @
                            1
                          END
                        END
                      END
                    END
                  \>>
                END
              \>>
            \>>
          @
          @ reference arrow
          @
          ARROW
"E1B2071000400007000080C1E3F7AF1D"
          @
          @ 12 hour tick marks
          @
          G12
"E1B20F4D0001000E4300330000000000000370000000000000C0000000000000
0C10000000000000C10000000000000410000000000000C10000000000000810
000000000000C10000000000000C10000000000000C100000000000003200000
00000000330000000000000370000000000000C0220000000000000240000000
0000008000000000000000100000000000000100000000000004100000000000
0040000000000000040000000000000001000000000000041000000000000041
0000000000000250000000000000220000000000000240000000000000802200
00000000000270000000000000800000000000000C10000000000000C1000000
0000000C10000000000000C10000000000000C10000000000000800000000000
000C10000000000000C100000000000002500000000000002200000000000002
7000000000000080220000000000000210000000000000800000000000000400
0000000000000100000000000000100000000000000100000000000004100000
0000000040000000000000041000000000000001000000000000025000000000
0000220000000000000210000000000000807700000000000007700000000000
00C10000000000000C10000000000000C10000000000000010000000000000C1
0000000000000C10000000000000400000000000000C10000000000000C10000
0000000007200000000000007700000000000007700000000000008000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000C10000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000080000000000000080000000000000080
0000000000000800000000000000800000000000000800000000000000800000
0000000008000000000000008000000000000008000000000000008000000000
0000080000000000000080000000000000080000000000000000800000000000
0008000000000000008000000000000008000000000000008000000000000008
0000000000000080000000000000080000000000000080000000000000080000
0000000000800000000000000800000000000000800000000000000800000000
0000008080000000200000080000000200000080000000200000080000000200
0000800000002000000800000002000000800000002000000800000002000000
8000000020000008000000020000008000000020000008000000020000008000
0000200000080000000200000080800000002000000800000002000000800000
0020000008000000020000008000000020000008000000020000008000000020
0000080000000200000080000000200000080000000200000080000000200000
0800000002000000800000002000000800000002000000808000000020001008
0004000200010080004000200010080004000200010080004000200010080004
0002000100800040002000100800040002000100800040002000100800040002
0001008000400020001008000400020001008000400020001008000400020001
0080800040002000100800040002000100800040002000100800040002000100
8000400020001008000400020001008000400020001008000400020001008000
4000200010080004000200010080004000200010080004000200010080004000
2000100800040002000100808012480124801248012480124801248012480124
8012480124801248012480124801248012480124801248012480124801248012
4801248012480124801248012480124801248012480124801248012480124801
2480124801248012480124801248012480124801248080124801248012480124
8012480124801248012480124801248012480124801248012480124801248012
4801248012480124801248012480124801248012480124801248012480124801
2480124801248012480124801248012480124801248012480124801248012480
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFF39C02"
          @
          @ 24 hour tick marks
          @
          G24
"E1B20F881001000E1600770000000000000800000000000000C0000000000000
0C10000000000000C10000000000000410000000000000C10000000000000810
000000000000C10000000000000C10000000000000C100000000000003200000
0000000033000000000000037000000000000037000000000000035000000000
0000370000000000000360000000000000370000000000000370000000000000
3700000000000007200000000000007300000000000007700000000000007700
00000000000750000000000000C0440000000000000410000000000000800000
0000000000100000000000000100000000000004100000000000004000000000
0000040000000000000001000000000000041000000000000041000000000000
0250000000000000220000000000000240000000000000240000000000000250
0000000000002100000000000002100000000000002400000000000002500000
0000000025000000000000045000000000000042000000000000044000000000
0000440000000000000450000000000000807700000000000004100000000000
00800000000000000C10000000000000C10000000000000C10000000000000C1
0000000000000C10000000000000800000000000000C10000000000000C10000
0000000002500000000000002200000000000002700000000000002700000000
0000027000000000000027000000000000027000000000000022000000000000
0270000000000000270000000000000750000000000000720000000000000770
0000000000007700000000000007700000000000008014000000000000041000
0000000000800000000000000400000000000000010000000000000010000000
0000000100000000000004100000000000004000000000000004100000000000
0001000000000000025000000000000022000000000000021000000000000024
0000000000000240000000000000240000000000000250000000000000210000
0000000002500000000000002400000000000001500000000000001200000000
0000011000000000000014000000000000014000000000000080770000000000
000800000000000000C10000000000000C10000000000000C100000000000000
10000000000000C10000000000000C10000000000000400000000000000C1000
0000000000C10000000000000720000000000000770000000000000770000000
0000007700000000000007400000000000007700000000000007700000000000
0071000000000000077000000000000077000000000000072000000000000077
0000000000000770000000000000770000000000000740000000000000C10000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000008000000000000008000000000000008000000000000008000000
0000000080000000000000080000000000000080000000000000080000000000
0000800000000000000800000000000000800000000000000800000000000000
8000000000000008000000000000008000000000000008000000000000008000
0000000000080000000000000080000000000000080000000000000080000000
0000000800000000000000800000000000000800000000000000800000000000
0008000000000000008080000000200000080000000000000080000000000000
0800000000000000800000000000000800000000000000800000000000000800
0000000000008000000000000008000000000000008000000000000008000000
0000000080000000000000080000000000000080000000000000080000000000
0000800000000000000800000000000000800000000000000800000000000000
8000000000000008000000000000008000000000000008000000000000008000
0000000000080000000000000080800000002000000800000002000000800000
0020000008000000020000008000000020000008000000020000008000000020
0000080000000200000080000000200000080000000200000080000000200000
0800000002000000800000002000000800000002000000800000002000000800
0000020000008000000020000008000000020000008000000020000008000000
0200000080000000200000080000000200000080000000200000080000000200
0000800000002000000800000002000000808000000020000008000000020000
0080000000200000080000000200000080000000200000080000000200000080
0000002000000800000002000000800000002000000800000002000000800000
0020000008000000020000008000000020000008000000020000008000000020
0000080000000200000080000000200000080000000200000080000000200000
0800000002000000800000002000000800000002000000800000002000000800
0000020000008000000020000008000000020000008080004000200010080004
0002000100800040002000100800040002000100800040002000100800040002
0001008000400020001008000400020001008000400020001008000400020001
0080004000200010080004000200010080004000200010080004000200010080
0040002000100800040002000100800040002000100800040002000100800040
0020001008000400020001008000400020001008000400020001008000400020
0010080004000200010080004000200010080004000200010080800040002000
1008000400020001008000400020001008000400020001008000400020001008
0004000200010080004000200010080004000200010080004000200010080004
0002000100800040002000100800040002000100800040002000100800040002
0001008000400020001008000400020001008000400020001008000400020001
0080004000200010080004000200010080004000200010080004000200010080
0040002000100800040002000100800040002000100800040002000100808012
4801248012480124801248012480124801248012480124801248012480124801
2480124801248012480124801248012480124801248012480124801248012480
1248012480124801248012480124801248012480124801248012480124801248
0124801248012480124801248012480124801248012480124801248012480124
8012480124801248012480124801248012480124801248012480124801248012
4801248012480124801248012480124801248012480124801248012480124801
2480801248012480124801248012480124801248012480124801248012480124
8012480124801248012480124801248012480124801248012480124801248012
4801248012480124801248012480124801248012480124801248012480124801
2480124801248012480124801248012480124801248012480124801248012480
1248012480124801248012480124801248012480124801248012480124801248
0124801248012480124801248012480124801248012480124801248012480124
801248012480FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFF3797B"
        END
      CLK7
        @
        @ display the current time in written format
        @
        DIR
          CLK
            @
            @ display the written time using a small graphic font. The
            @ small graphic font was used so the string wouldn't be
            @ larger than the width of the LCD. Even with the smaller
            @ font this does happen for one particular time.
            @
            \<< 
              @
              @ program done flag
              @
              0 
              @
              @ auto shutdown time
              @
              TICKS TIMEOUT + 
              \-> done ticks
              \<<
                @
                @ get the screen ready
                @
                PICT PURGE 
                LCD\-> SIZE BLANK PICT STO
                { # 0h # 0h } PVIEW
                WHILE done NOT REPEAT 
                  @
                  @ unpack the time into h/m/s/t
                  @
                  TIME UTIME 
                  \-> h m s t
                  \<< 
                    @
                    @ blank out where the line of text goes in case the 
                    @ new text is shorter than the old text
                    @
                    PICT { # 0h # 1Dh } # 83h # 6h BLANK REPL 
                    @
                    @ convert h/m/s into a text string and then convert 
                    @ that into a GROB then center it in the screen
                    @
                    PICT h m s HM\->S 1 \->GROB DUP SIZE DROP
                    @
                    @ if the resulting GROB is wider than the screen then
                    @ start it flush with the left edge of the screen. If
                    @ the GROB is smaller than the screen then center it
                    @
                    IF DUP # 83h \>= THEN 
                      DROP # 0h
                    ELSE 
                      # 83h SWAP - 2 /
                    END 
                    # 1Dh 2 \->LIST SWAP REPL 
                    @
                    @ wait for the rest of the minute to pass
                    @
                    1
                    WHILE REPEAT 
                      @
                      @ display the running seconds
                      @
                      PICT { # 0h # 0h } 
                      TIME 100 * FP 100 * IP FMT99 1 \->GROB REPL
                      @
                      @ has the minute changed
                      @
                      IF TIME FP 100 * IP m \=/ THEN 
                        @
                        @ exit the minute wait loop
                        @
                        0
                      ELSE
                        @
                        @ was a key pressed
                        @
                        IF KEY THEN 
                          @
                          @ throw it away
                          @
                          DROP 
                          @
                          @ stop the program
                          @
                          1 'done' STO 
                          @
                          @ exit the minute wait loop
                          @
                          0
                        ELSE
                          @
                          @ did we timeout
                          @
                          IF TICKS ticks > THEN 
                            @
                            @ exit the program
                            @
                            1 'done' STO 
                            @
                            @ exit the minute wait loop
                            @
                            0
                          ELSE 
                            @
                            @ keep waiting
                            @
                            1
                          END
                        END
                      END
                    END
                  \>>
                END
              \>>
            \>>
          HM\->S
            @
            @ convert the numeric h/m/s into it's written format
            @
            @ the algorithm came from an MS-DOS based program that would
            @ display the time in text format. I just converted it into RPL
            @
            \<< 
              \-> h m s
              \<<
                IF s 29 > THEN 
                  m 1 + 'm' STO
                END
                IF m 32 > THEN 
                  h 1 + 'h' STO
                END 
                { "" "JUST GONE " "JUST AFTER " "NEARLY " "ALMOST " } 
                m 5 MOD 1 + GET m
                \-> m5
                \<<
                  IF m 5 MOD 3 \>= THEN 
                    m 5 + 'm5' STO
                  END 
                  { ""              "FIVE PAST "      "TEN PAST " 
                    "QUARTER PAST " "TWENTY PAST "    "TWENTY FIVE PAST "
                    "HALF PAST "    "TWENTY FIVE TO " "TWENTY TO "
                    "QUARTER TO "   "TEN TO "         "FIVE TO " 
                    "" } 
                  m5 5 / IP 1 + GET +
                  IF h 12 MOD 0 == THEN 
                    h 12 == "NOON" "MIDNIGHT" IFTE + 12 'h' STO
                  END
                  IF h 12 > THEN 
                    h 12 - 'h' STO
                  ELSE
                    IF h 0 == THEN 
                      12 'h' STO
                    END
                  END 
                  { "ONE"   "TWO"   "THREE" "FOUR" "FIVE"   "SIX"
                    "SEVEN" "EIGHT" "NINE"  "TEN"  "ELEVEN" ""    } 
                  h GET +
                  IF m 60 MOD 0 == h 12 \=/ AND THEN 
                    " O'CLOCK" +
                  END
                \>>
              \>>
            \>>
        END
    END
  Setup
    @
    @ many of these programs require large GROBs. To get these GROBs to 
    @ post properly they are converted to ASCII using Wicks ->ASC program.
    @
    @ To get all the ASCII encoded GROBs back to their original form run 
    @ the following program.
    @
    @ ******************************************************************
    @ ******************************************************************
    @ ***                                                            ***
    @ *** You run this program ONCE before trying any of the clocks  ***
    @ ***                                                            ***
    @ ******************************************************************
    @ ******************************************************************
    @
    \<< 
      @
      @ this list is a series of sublists with a path and then the 
      @ variables in that subdirectory that have to be unASC->ed.
      @
      { 
        { { HOME BC CLKS CLK0 } { CF1 CF13 } } 
        { { HOME BC CLKS CLK1 } { D D7 DIGITS DM } } 
        { { HOME BC CLKS CLK2 } { GCOLON GH1 GH10 GM1 GM10 } } 
        { { HOME BC CLKS CLK3 } { DIGITS MONTHS } }
        { { HOME BC CLKS CLK4 } { DIGITS } }
        { { HOME BC CLKS CLK6 } { ARROW G12 G24 } } 
      } 
      \-> l
      \<< 
        1 l SIZE
        FOR i 
          l i GET OBJ\-> DROP 
          \-> p n
          \<< 
            p 1 DISP 
            PATH 
            p EVAL 
            1 n SIZE
            FOR ii
              n ii GET 
              \-> v
              \<< 
                v 2 DISP 
                v RCL ASC\-> v STO
              \>>
            NEXT
            EVAL
          \>>
        NEXT
      \>>
    \>>
  AHMST
    @
    @ hh.mmsstt -> "hh:mm:ss.tt"
    @
    \<< 
      UTIME 
      \-> h m s t
      \<< 
        h FMT99   ":" + 
        m FMT99 + ":" + 
        s FMT99 + "." + 
        t FMT99 +
      \>>
    \>>
  ALL
    @
    @ runs each of the different clocks. Each clock is run for a few 
    @ seconds before moving to the next one. Hitting any key while a 
    @ clock is running aborts it and moves to the next one.
    @
    \<< 
      {
        \<< 'CLK0' 'CLK'   CLOCK \>>
        \<< 'CLK1' 'CLK'   CLOCK \>>
        \<< 'CLK1' 'CLK7'  CLOCK \>>
        \<< 'CLK1' 'CLKDM' CLOCK \>>
        \<< 'CLK2' 'CLK'   CLOCK \>>
        \<< 'CLK3' 'CLK'   CLOCK \>>
        \<< 'CLK4' 'CLK'   CLOCK \>>
        \<< 'CLK5' 'CLK'   CLOCK \>>
        \<< 'CLK6' 'CLK'   CLOCK \>>
        \<< 'CLK7' 'CLK'   CLOCK \>> 
      } 
      @
      @ save the old timeout value
      @
      TIMEOUT 
      \-> l otimeout
      \<< 
        @
        @ number of seconds you want each clock displayed for
        @
        30 
        @
        @ convert the time to ticks
        @
        8192 * 'TIMEOUT' STO 
        1 l SIZE
        FOR i 
          @
          @ get the clock program
          @
          l i GET 
          @
          @ run it
          @
          EVAL
        NEXT
        @
        @ restore the old timeout value
        @
        otimeout 'TIMEOUT' STO
      \>>
    \>>
  CENTER
    @
    @ pad the input string with blanks so the string will be centered
    @ in the 23 character width of the LCD (text mode). If the string 
    @ is longer than 23 characters then leave it alone
    @
    \<<
      IF DUP SIZE 23 < THEN
        "                       " OVER SIZE 23 SWAP - 2 / IP 
        1 SWAP SUB SWAP +
      END
    \>>
  CLOCK
    @
    @ helper function for the ALL program
    @ takes the name of a clocks directory and the name of a variable 
    @ in that directory to run
    @
    \<< 
      \-> d v
      \<< 
        @
        @ do into the CLKS directory
        @
        'CLKS' EVAL 
        @
        @ go into the specified directory
        @
        d EVAL 
        @
        @ run the specified program
        @
        v EVAL 
        @
        @ go back to the CLKS directory
        @
        UPDIR 
        @
        @ go back to the big clock directory ( { HOME BC } )
        @
        UPDIR TEXT
      \>>
    \>>
  Clk
    @
    @ allow the user to run any of the clock programs as well as change 
    @ the current 12/24 display format. 
    @
    \<< 
      { 
        :Analog:     \<< 'CLK0' 'CLK'   CLOCK \>> 
        :Digital:    \<< 'CLK1' 'CLK'   CLOCK \>> 
        :7 segment:  \<< 'CLK1' 'CLK7'  CLOCK \>>
        :Dot matrix: \<< 'CLK1' 'CLKDM' CLOCK \>> 
        :Odometer:   \<< 'CLK2' 'CLK'   CLOCK \>> 
        :Date/time:  \<< 'CLK3' 'CLK'   CLOCK \>>
        :Abaclockus: \<< 'CLK4' 'CLK'   CLOCK \>> 
        :Bar:        \<< 'CLK5' 'CLK'   CLOCK \>> 
        :Gauge:      \<< 'CLK6' 'CLK'   CLOCK \>> 
        :English:    \<< 'CLK7' 'CLK'   CLOCK \>> 
        :12 hr.:     \<< T12                  \>> 
        :24 hr.:     \<< T24                  \>> 
      } 
      0 
      \-> l done
      \<<
        WHILE done NOT REPEAT 
          @
          @ for each of the three lines around the current one
          @
          -3 3
          FOR i
            @
            @ is this the top line of the display
            @
            IF i -3 == THEN
              @
              @ if there are more items above the screen then the first 
              @ character on the line is an uparrow otherwise the first
              @ character is blank
              @
              IF I 4 > THEN
                "\|^"
              ELSE
                " "
              END
            ELSE
              @
              @ if this is the center line then display a right pointing 
              @ arrow to highlight this position
              @
              IF i 0 == THEN
                "\|>"
              ELSE
                @
                @ is this the last line of the display
                @
                IF i 3 == THEN
                  @
                  @ it there are more items below the screen then the 
                  @ first character on the line is a downarrow otherwise 
                  @ the first character is blank
                  @
                  IF I l SIZE 3 - < THEN 
                    "\|v"
                  ELSE 
                    " "
                  END
                ELSE 
                  @
                  @ it isn't the top line, the middle line or the bottom 
                  @ line so the first character is a blank
                  @
                  " "
                END
              END
            END
            @
            @ is this entry before the first one
            @
            IF I i + 1 < THEN 
              ""
            ELSE
              @
              @ is this entry after the last one
              @
              IF I i + l SIZE > THEN
                ""
              ELSE
                @
                @ get the entry
                @
                l I i + GET 
                @
                @ split it into it's tag and object
                @
                OBJ\-> 
                @
                @ throw the object away we want the tag
                @
                SWAP DROP
              END
            END 
            @
            @ display this line in the correct position on the screen
            @
            + i 4 + DISP
          NEXT 
          @
          @ get a key
          @
          0 WAIT 
          \-> k
          \<<
            @
            @ is it an up arrow
            @
            IF k 25.1 == THEN 
              @
              @ move one toward the front of the list
              @
              I 2 - 
              @
              @ if we move forward off the front of the list wrap around 
              @ to the back of the list
              @
              l SIZE MOD 1 + 
              'I' STO
            ELSE
              @
              @ is it a down arrow
              @
              IF k 35.1 == THEN
                @
                @ move one toward the end of the list and wrap to the 
                @ front if we fall off the end
                @
                I l SIZE MOD 1 + 
                'I' STO
              ELSE
                @
                @ is it an ENTER
                @
                IF k 51.1 == THEN 
                  @
                  @ get the item in the list
                  @
                  l I GET 
                  @
                  @ throw away the tag
                  @
                  DTAG
                  @
                  @ run it
                  @
                  EVAL
                ELSE 
                  @
                  @ it's not an up arrow, down arrow or ENTER so abort 
                  @ the program
                  @
                  1 'done' STO
                END
              END
            END
          \>>
        END
      \>>
    \>>
  FMT99
    @
    @ n -> "xx"
    @
    \<< 
      DUP 0 < "-" "" IFTE 
      SWAP ABS IP DUP 10 < "0" "" IFTE 
      SWAP \->STR + + 
    \>>
  T12
    @
    @ force 12 hour display
    @
    \<< -41 CF \>>
  T24
    @
    @ force 24 hour display
    @
    \<< -41 SF \>>
  T?
    @
    @ show user current 12/24 display setting
    @
    \<<
      IF -41 FS? THEN 
        "24"
      ELSE 
        "12"
      END
      " hour clock" + 1 DISP 
      "" 2 DISP 
      1 FREEZE
    \>>
  UDATE
    @
    @ aa.bbyyyy -> mm dd yy
    @
    @ unpacks a date into it's month, day and year. The form of the input 
    @ number is controlled by the system date flag (-42). The three output 
    @ numbers are always returned on the stach as month, day then year.
    @
    \<< 
      @
      @ save the users flags because we want to use LASTARG
      @
      RCLF 
      \-> f
      \<< 
        @
        @ make sure LASTARG is ON
        @
        -55 CF 
        IP
        LASTARG FP 100 * IP
        LASTARG FP 10000 * IP 
        \-> m d y
        \<<
          IF -42 FC? THEN 
            m d
          ELSE 
            d m
          END
          y
          @ restore the users flags
          f STOF
        \>>
      \>>
    \>>
  UTIME
    @
    @ hh.mmsstt -> hh mm ss tt
    @
    \<< 
      @
      @ save the users flag because we want to use LASTARG
      @
      RCLF 
      \-> f
      \<< 
        @
        @ force LASTARG on
        @
        -55 CF 
        IP
        LASTARG FP 100 * IP
        LASTARG FP 100 * IP
        LASTARG FP 100 * 
        @ restore the flags
        f STOF
      \>>
    \>>
  \->POLAR
    @
    @ r theta -> (r, theta)
    @
    \<< 
      \-> r \Ga
      \<< 
        'r*COS(\Ga)+i*r*SIN(\Ga)' \->NUM
      \>>
    \>>
  CST 
    { 
      ALL 
      Clk 
      T12
      T24 
      T? 
      {
        GROB 21 8 E30000FFFFF17ABDC1BBB6F1BB3FE1BBBED172A5E1FFFFF1
        \<< 
          { 
            { "ANALOG" \<< CLK TEXT \>> } 
            { 
              "DIGITAL"
              {
                \<< 'CLK1' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK1' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK1' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "7SEGMENT" 
              {
                \<< 'CLK1' 'CLK7' CLOCK \>>
                \<< RCLF T12 'CLK1' 'CLK7' CLOCK STOF \>>
                \<< RCLF T24 'CLK1' 'CLK7' CLOCK STOF \>> 
              } 
            } 
            {
              "DOTMATRIX" 
              {
                \<< 'CLK2' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK2' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK2' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "ODOMETER" 
              {
                \<< 'CLK3' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK3' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK3' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "DATETIME" 
              {
                \<< 'CLK4' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK4' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK4' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "ABACUS" 
              {
                \<< 'CLK5' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK5' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK5' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "BAR" 
              {
                \<< 'CLK6' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK6' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK6' 'CLK' CLOCK STOF \>> 
              } 
            } 
            {
              "ENGLISH" 
              {
                \<< 'CLK7' 'CLK' CLOCK \>>
                \<< RCLF T12 'CLK7' 'CLK' CLOCK STOF \>>
                \<< RCLF T24 'CLK7' 'CLK' CLOCK STOF \>> 
              } 
            } 
          } 
          TMENU
        \>> 
      } 
    }
  @
  @ remembers at which index the user left the Clk program
  @
  I 
    4
  @
  @ default timeout is 10 minutes (10 * 60 * 8192 ticks)
  @
  TIMEOUT 
    4915200
END
