10 REM > BLib.Time 1.03 12-Aug-2006
   20 REM RTC Time and date functions
   30 REM (C)J.G.Harston, may be freely used and redistributed
   40 REM ----------------------------------------------------
   50 REM All functions assume global control block
   60 REM pointed to by X%,Y% and set up as follows:
   70 REM  DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
   80 :
   90 :
  100 REM Real-Time-Clock reading functions
  110 REM =================================
  120 :
  130 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  140 REM FNtime        - return RTC time&date or null string if none present
  150 REM                 returned date is correct for years after 1996 and 1999
  160 :
  170 DEFFNtime:?X%=0:A%=14:CALL&FFF1:IF?X%=0:=""
  180 X%?24=13:A%=VAL$(X%+4):$(X%+4)=RIGHT$("0"+STR$(A%AND31),2):$(X%+11)=STR$(INTVAL$(X%+11)+(A%AND&E0)DIV2-100*(INTVAL$(X%+11)<1981)):X%?6=32:X%?15=46:=$X%
  190 :
  200 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  210 REM FNTime        - Return time&date or null string if none found
  220 REM                 On-board RTC and fileserver RTC are checked
  230 REM                 and day of week calculated
  240 :
  250 DEFFNTime:!X%=1:A%=14:CALL&FFF1:FORA%=0TO7:X%?A%=VALSTR$~X%?A%:NEXT
  260 ?X%=?X%+((X%?2)AND&E0)DIV2:X%?2=X%?2 AND31:IF?X%<81:?X%=?X%+100
  270 IF!X%=101:!X%=&10000700:X%!4=0:A%=20:CALL&FFF1:!X%=0:IFX%!4:?X%=81+(X%?5 DIV16)+((X%?4 AND&E0)DIV2):X%?1=X%?5 AND15:X%?2=X%?4 AND31:X%!4=X%!6
  280 IFX%?3=0:IFX%?2:X%?3=FNDate_DayOfWeek(X%?2,X%?1,1900+X%?0)
  290 =FNDay(X%?3)+","+FNd0(X%?2,2)+" "+FNMon(X%?1)+" "+FNd0(1900+X%?0,4)+"."+FNd0(X%?4,2)+":"+FNd0(X%?5,2)+":"+FNd0(X%?6,2)
  300 :
  310 :
  320 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  330 REM PROCtime      - read the RTC time&date
  340 REM On exit:  day%, month% and year% set to the current date and
  350 REM           hour%, minute% and second% set to the current time,
  360 REM           or zero if no RTC present
  370 :
  380 DEFPROCtime:year%=0:month%=0:day%=0:hour%=0:minute%=0:second%=0
  390 A%=14:!X%=1:CALL&FFF1:IF!X%=1:ENDPROC
  400 FORA%=0TO7:X%?A%=VALSTR$~X%?A%:NEXT
  410 ?X%=?X%+((X%?2)AND&E0)DIV2:X%?2=X%?2 AND31:IF?X%<81:?X%=?X%+100
  420 year%=1900+?X%:month%=X%?1:day%=X%?2:hour%=X%?4:minute%=X%?5:second%=X%?6
  430 ENDPROC
  440 :
  450 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  460 REM FNdate        - read current date as &yyyymmdd or zero if no RTC
  470 :
  480 DEFFNdate:A%=14:!X%=1:CALL&FFF1:IF!X%=1:=0
  490 ?X%=EVAL("&"+STR$((VALSTR$~?X%+(((VALSTR$~X%?2)DIV2)AND&F0))MOD100))
  500 =(VALSTR$~X%?2 AND31)+256*VALSTR$~X%?1+65536*(&1900+?X%-&700*(?X%<128))
  510 :
  520 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  530 REM FNDay(day%)   - return 3-char day of week string
  540 REM FNMon(month%) - return 3-char month string
  550 :
  560 DEFFNDay(A%):=MID$("000SunMonTueWedThuFriSat",A%*3+1,3)
  570 DEFFNMon(A%):=MID$("000JanFebMarAprMayJunJulAugSepOctNovDecDDDEEEFFF",A%*3+1,3)
  580 :
  590 REM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  600 REM FNDate_DayOfWeek(day%,month%,year%)
  610 REM               - return day of week for supplied date
  620 REM                 1=Sunday, 7=Saturday
  630 :
  640 DEFFNDate_DayOfWeek(d%,m%,y%):y%=y%MOD400
  650 =(y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+((y%MOD4)=0)-((y%-1)DIV100)-(m%>2AND((y%MOD4)=0AND(y%MOD100)<>0ORy%=0))+3)MOD7+1
  660 :
  670 DEFFNd0(A%,N%)=RIGHT$("00000000"+STR$A%,N%)