[comp.sys.handhelds] HP28: EXACT Utility for real time clock

jdg@hpqtdla.HP.COM (James Gentles) (03/22/90)

HP28S EXACT: A utility addition to the clock function to improve accuracy

This routine when added to the suite of programs for the clock on the 
HP28S will allow you to automatically increase the accuracy of the clock.
It works as follows. It has stored in EXLST the binary when the clock was
last known to be correct. If you tell it the time now it then knows the
length of time since the last EXACT and the error between your entry and 
its time. This is used to offset DIVR which is a variable which translates
the clock binary into a real of the format H.MMSS. This has been written
for one particular clock routine, author unknown, but it was last posted
to notes in Jan. I have reposted it at the end of this text (I accept no
responsibility for it). It could be easily modified for other clock routines.

Modification to existing programs:
TIME and SETTIME both contain 29491199, which is the divisor to get from
   the 28S binary to H.MMSS. This is really 60*60*8192 ( the 28S clock
   is incremented 8192ish times a second ). These should be replaced with
   DIVR, and DIVR should contain 29491200.
DATE and SETDATE similarily contain 707788800 which is 24*DIVR. Replace 
   this with DIVR 24 * in both routines

The first time you use the routine:
1. Set the time exactly using the old method SETTIME and immediately execute
   syseval #4554d (2BB). Store it in EXLST.
2. Any subsequent setting enter H.MMSS then press EXACT instead of SETTIME.

A warning:
1. Allow a reasonable error (>5 seconds) to build up between pressing
   EXACTs. 
2. Make sure you do get the time exact when you use EXACT or you'll make
   the accuracy worse. You could save off old versions of DIVR if you
   want to be safe. If however you then reinstate them you will then have
   to reset the time with SETTIME and SETDATE.
3. Dont try to use exact about midnight, it might not work.
3. I cannot guarantee the code, I am using it myself but it takes many days
   of waiting to check that the accuracy is improving!

Footnote:
   DIVR should be 29491200 for a perfect crystal ( I think ), thats 60 *
   60 * 8192. That gave me an increase of about 1 second/day, My 28
   seems to like 29491600 better, less than 1 second/5days so far.
   Thats 13ppm off frequency.

Any comments, please email and I'll try to help
James Gentles


Uses:  TIME: Returns the binary obtained by calling syseval #4554d (2BB) 
             in level 2 and the current time in H.MMSS in level 1.  
      EXLST: A variable containing the binary returned from syseval #4554d 
             (2BB) at a time in the past when the time was known exactly.
    SETTIME: Accepts a number H.MMSS and sets up the clock
       DIVR: A constant 29491200 ( or thereabouts)

EXACT  3BFA
<< TIME EXLST DATE -> s bn n bo d              ! get time and date NOW
  << n s HMS- HMS-> bn B->R bo B->R - DIVR     ! COMPUTE ERROR AND time since
  / -> er tm                                   ! last exact, er & tm
    << er tm / 8192 * DIVR + 'DIVR' STO TIME   ! modify DIVR to new value
    SWAP DROP er ->HMS HMS- SETTIME d SETDATE  ! update TIME and DATE
    bn 'EXLST' STO                             ! Store time now in EXLST
    >>
  >>
>>
 
SYMBOL KEY:
->  141:-Right_hand_arrow 
<<  146:-Start_program_construct 
>>  147:-End_program_construct 


---------------------------------------------------------------------
      I have no professional connection with Hewlett-Packard's 
    calculator operations other than as a user of their products.
---------------------------------------------------------------------
Opinions expressed are my own, and are not intended to be an official
              statement by Hewlett-Packard Company
---------------------------------------------------------------------
Name:         James Gentles   GM4WZP
Organization: Hewlett-Packard  Queensferry Telecomunications Division
Email:        jdg@hpqtdla.hpsqf.hp.com                         hp-sdd 
Address:      Station Road, South Queensferry, West Lothian, Scotland
---------------------------------------------------------------------
REPOSTING OF HP28S CLOCK UTILITY( I have not corrected any errors):
--------------------------------------------------------------------------

Directory               PROGRAM CHECKSUMS
--------------------------------------------------------------------------
->PG4      CLOCK   C2BD     TM      5A2F     JC2     5E06     MTHLST  66D5
           CLDR    C603     FMTTIME 5ACF     CJ2     CF65     DM      4247
           DCAL    6912     FMTDATE 57B8     DOW2    6174     TMSTMP  59DA
           SETTIME CEB3     JC      EEA3     DAYS    3ADB     CKOR    var?
           SETDATE 6138     CJ      B4B4     NDAYS   F062     DKOR    var?
           TIME    A651     DW      7A7E     MTHS    4398
           DATE    FD70     DOW     34F7     CAL     EE76


->PG4 Directory:
================

     CLOCK and all the other programs in that directory perform the function
of turning the HP28S into a clock and calendar.  This works by calling a
syseval at #4554d (version 2BB) which is a continuous counter register.  The
time and date is calibrated off the counter using the SETTIME and SETDATE
programs.

To set time and date to : 2:27.50 pm, Nov. 12, 1989

                    ENTER...  14.2750 SETTIME
                    THEN....  11.121989 SETDATE

pressing CLOCK yields

          +---------------------+
          |                     |
          |Sun, Nov  12, 1989   |
          |                     |  <- The time will continuously update
          |     2:27:50 pm      |
          +---------------------+

Press any key other than ON to restore display (Pressing ON leaves garbage
on the stack).

     CLDR displays a scrolling calendar of the current month.


->PG4 Directory:
================

  CLOCK:    << RCWS 64 STWS LCD-> CLLCD WHILE KEY NOT REPEAT " " DATE
               FMTDATE + 2 DISP TIME SWAP DROP FMTTIME "      " SWAP
               + 4 DISP END DROP ->LCD STWS CLMF >>

SETTIME:    << 0 'CKOR' STO TIME SWAP DROP HMS-> SWAP HMS-> DUP2
               IF > THEN 24 + END SWAP - 'CKOR' STO >>

SETDATE:    << -> d << DM d CJ2 707788800 * - 'DKOR' STO >> >>

   TIME:    << TM DUP B->R 29491199 / 24 MOD CKOR + 24 MOD ->HMS >>

   DATE:    << DM DKOR - 707788800 / JC2 >>

     TM:    << RCWS 64 STWS # 4554d SYSEVAL SWAP STWS >>

FMTTIME:    << RCLF 58 CHR -> t f c << t 10000 * IP 10000 / 't' STO
               IF t 12 >= THEN t 12 - 't' STO " pm" ELSE " am" END
               IF t 1 < THEN t 12 + 't' STO END t IP STD ->STR c + t
               FP 4 FIX ->STR DUP 3 4 SUB c + SWAP 5 6 SUB + + SWAP
               + f STOF >> >>

FMTDATE:    << RCLF STD -> d f << d DOW2 SWAP DROP ", " + MTHS d IP
               GET + " " + d FP 100 * IP ->STR + ", " + d 100 * FP
               10000 * ->STR + f STOF >> >>

     JC:    << 1721119.2 - DUP DUP 36524.25 / IP SWAP OVER + SWAP 4
               / IP - DUP ROT DROP 365.25 SWAP OVER / IP SWAP OVER *
               SWAP ROT ROT IP - .3 - DUP 30.6 SWAP OVER / IP SWAP
               OVER * SWAP -> k << SWAP OVER - 1 + SWAP DROP k >>
               DUP 9 IF > THEN ROT 1 + SWAP 9 - ELSE ROT SWAP 3 + END
               ROT IP >>

     CJ:    << << 2.85 - 12 / + >> -> y m d yp << 367 y m yp EVAL *
               IP y m yp EVAL IP - .75 y m yp EVAL IP * - d + IP .75
               y m yp EVAL 100 / IP * - IP 1721115 + >> >>

    DOW:    << CJ 1 + 7 MOD DUP 1 + DAYS SWAP GET >>

    JC2:    << JC 100 / + SWAP 1000000 / + >>

    CJ2:    << DUP IP SWAP FP 100 * DUP IP SWAP FP 10000 * ROT ROT CJ >>

   DOW2:    << CJ2 1 + 7 MOD DUP 1 + DAYS SWAP GET >>

   DAYS:    { "Sun" "Mon" "Tues" "Weds" "Thur" "Fri" "Sat" }

  NDAYS:    { 31 28 31 30 31 30 31 31 30 31 30 31 }

   MTHS:    { "Jan " "Feb " "Mar " "Apr " "May " "June" "July" "Aug "
              "Sept" "Oct " "Nov " "Dec " }

 MTHLST:    << RCLF STD -> f << DUP IP SWAP FP 10000 * -> mm yy << yy
               mm 1 DOW DROP -> dow << "      " -> s << { } s MTHS
               mm GET + " " + yy ->STR + s + + "  S  M  T  W  T  F  S"
               + -> ml << "" IF dow 0 <> THEN IF 1 dow <= THEN 1 dow
               START "   " + NEXT END END 1 NDAYS mm GET IF mm 2 ==
               yy 4 MOD 0 == AND THEN 1 + END FOR x " " + IF x 10 <
               THEN " " + END x ->STR + NEXT DUP SIZE -> dl s
               << 0 s 21 / IP FOR x ml dl x 21 * 1 + DUP 20 + SUB +
               'ml' STO NEXT ml " " + >> >> >> >> >> f STOF >> >>

     DM:    << RCWS -> w << 64 STWS TIME HMS-> 12 SWAP - 29491200 * DUP
               IF 0 < THEN NEG - ELSE + END B->R w STWS >> >>

 TMSTMP:    << DATE FMTDATE PR1 TIME FMTTIME PR1 3 DROPN CR CR >>

   CLDR:    << LCD-> SWAP MTHLST DUP SIZE -> l s << WHILE KEY NOT
               REPEAT 0 s 1 - FOR k 1 4 FOR d l k d + IF DUP s >
               THEN s - END GET d DISP NEXT .5 WAIT NEXT END DROP
               ->LCD CLMF >> >>

   CKOR:    13.2727633333          ;  Varies when time is set.

   DKOR:    -1.46830298706E15

jdg@hpqtdla.HP.COM (James Gentles) (03/22/90)

My apologies, The EXACT program quoted on the basenote is not the correct
revision, this one should now be correct.

EXACT  2470
<< TIME EXLST DATE -> s bn n bo d              ! get time and date NOW
  << n s HMS- HMS-> bn B->R bo B->R - DIVR     ! COMPUTE ERROR AND time since
  / -> er tm                                   ! last exact, er & tm
    << er tm / 1 + DIVR * 'DIVR' STO TIME      ! modify DIVR to new value
    SWAP DROP er ->HMS HMS- SETTIME d SETDATE  ! update TIME and DATE
    bn 'EXLST' STO                             ! Store time now in EXLST
    >>
  >>
>>
 
SYMBOL KEY:
->  141:-Right_hand_arrow 
<<  146:-Start_program_construct 
>>  147:-End_program_construct 


---------------------------------------------------------------------
      I have no professional connection with Hewlett-Packard's 
    calculator operations other than as a user of their products.
---------------------------------------------------------------------
Opinions expressed are my own, and are not intended to be an official
              statement by Hewlett-Packard Company
---------------------------------------------------------------------
Name:         James Gentles   GM4WZP
Organization: Hewlett-Packard  Queensferry Telecomunications Division
Email:        jdg@hpqtdla.hpsqf.hp.com                         hp-sdd 
Address:      Station Road, South Queensferry, West Lothian, Scotland
---------------------------------------------------------------------