home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / at / atnudg2.arc / ATCLOCK.ASM < prev    next >
Assembly Source File  |  1988-09-07  |  18KB  |  570 lines

  1.       page    64,130
  2.       Title E ATCLOCK - Daily housekeeping.F
  3. ;box
  4. ;╒═════════════════════════════════════════════════════════════╕
  5. ;│  Created 2 Jan. '88                                         │
  6. ;│  Date of last revision: 07-Sep-1988                   │
  7. ;╞═════════════════════════════════════════════════════════════╡
  8. ;│  ATCLOCK.ASM                            │
  9. ;│                                   │
  10. ;│  Single segment '.COM' type program.                │
  11. ;│  Description of function:  Checks for 1st time run today    │
  12. ;│  from 'TODAY.AT' file. Nudges clock if so.               │
  13. ;│  Keeps standard/daylight time, changes 1 hour if needed.    │
  14. ;│  Set nudge value with '/Nxxx', daylight-std with '/D','/S'. │
  15. ;│                                   │
  16. ;╘═════════════════════════════════════════════════════════════╛
  17. ;ebx
  18. ;   3 April '88 - Daylight savings time!
  19. ;   5 Sept. '88 - Major revision. Midnight rollover,
  20. ;    multiple days, daylight/standard comands.
  21. ; Macros used for messages to stdout. Structure for date file.
  22. ; Uses .286 mode. Program is not re-entrant.
  23. ; Link with: ASMUTILS.LIB
  24. ;
  25. .286
  26. INCLUDE   ASMUTILS.ASI
  27. .SALL
  28. CSEG    SEGMENT PARA PUBLIC 'CODE'    ;Segments at beginning,
  29. CSEG    ENDS
  30. MSGSEG    SEGMENT BYTE PUBLIC 'CODE'    ;Message data at end.
  31. MSGSEG    ENDS
  32. CGroup    GROUP    CSEG,MSGSEG        ;All really the same segment.
  33. ;    ; Flag bits for /Commands.
  34. NewNudge  EQU    1
  35. DSCmdRcvd EQU    2
  36. Daylite   EQU    4
  37. OneNudge  EQU    8
  38. ;
  39. DateInfo  STRUC
  40. PDATE      DB    ' '
  41. DOW      DB    ?,?,?,?     ; Today's date with month/day names.
  42. DOM      DB    ?,?,?        ; Like " Sun 08 Jan 1989 "
  43. MONTH      DB    ?,?,?,?
  44. CENTURY   DB    ?,?
  45. YEAR      DB    ?,?,' '
  46. StOrDl      DB    'S'        ; S-standard time, D-daylight.
  47. BinYear   DW    ?        ; Year in binary.
  48. JulDate   DW    ?        ; Julian date in binary.
  49. PDATNUMS  DB    6 DUP (?)    ; Date in numbers. Like: "890108"
  50. AscNudge  DB    5 DUP (?)    ; Nudge value. Like "-0182"
  51. DateInfo  ENDS
  52.     PAGE
  53. SEGZERO   SEGMENT  AT 0
  54.       ORG    46CH    ;Time info in BIOS' data area.
  55. TimerLow  DW    ?
  56. TimerHigh DW    ?
  57. SEGZERO   ENDS
  58. ;
  59. CSEG      SEGMENT
  60.       ASSUME CS:CGroup,DS:CGroup
  61. EXTRN      Asc2Bin:NEAR, SkipSpac:NEAR, AX4Digs:NEAR, DispDOSMsg:NEAR,\
  62.     NextLine:NEAR, SimplMsg:NEAR, ProgName:NEAR
  63.       ORG    100H
  64. START:      JMP    PROG
  65. SCommands DB    0    ;Flags for '/' commands.
  66. NudgeVal  DW    0    ;# ticks to nudge clock.
  67. DOSDate   DateInfo <>
  68. ;      ;Structure expansion edited out of listing.
  69. TFDate      DateInfo <>
  70. MsgSize   EQU    OFFSET DOSDate.StOrDl - OFFSET DOSDate
  71. TFSiz      EQU    TYPE DOSDate    ; Size of our data file. <Pg. 187>
  72. DaysPassed  DW    0    ;#days to adjust for, calculated if needed.
  73. CMOSCent  DB    19H
  74. CMOSYear  DB    ?
  75. CMOSMon   DB    ?
  76. CMOSDay   DB    ?
  77. DaysPerMon  DB    31
  78. DaysInFeb   DB    28,31,30,31,30,31,31,30,31,30
  79. DAYS      DB    'Sun Mon Tue Wed Thu Fri Sat '
  80. MOS      DB    'JanFebMarAprMayJunJulAugSepOctNovDec'
  81. TimeDisp  DB    ' '
  82. TimeData  DB    ?,?,':',?,?,':',?,?
  83. TFName      DB    60 DUP (?)
  84. TodayAT   DB    'TODAY.AT',0
  85. CmdLtrs   DB    '1DNS'
  86. CmdProcs  DW    OneCmd,DSCmds,NCmd,DSCmds
  87. ULine      DB    2,0    ;Buffer to get a 'y' or 'n'.
  88. UResp      DB    0,0
  89.       PAGE
  90. ;    ; --- Begin main program ---
  91. PROG      PROC    NEAR
  92.       CLD
  93. ;    ; Check DOS Version
  94.       MOV    AH,30H        ; Check for DOS Version 3.0+.
  95.       INT    21H
  96.       CMP    AL,3
  97.       JAE    @F        ; If so, continue.
  98.       DMessage <"ATCLOCK: Requires DOS 3 or above!"> \
  99.       AddLine+ErrorMsg+NoRet ;Macro for display error and abort.
  100. ;    ; This error message won't even work under DOS 1.0!
  101. ;
  102. ;    ; Check command line for /N /D /S or /1 commands.
  103. @@:      MOV    SI,80H        ;Read data from PSP 'till we get
  104.       LODSB         ; '/' or end of line.
  105.       CMP    AL,02        ;Must be 2 chars entered.
  106.       JB    GetPath
  107.       CALL    SkipSpac    ;Skip spaces after '/'.
  108. ReadCmds: LODSB
  109.       CMP    AL,0DH
  110.       JE    GetPath
  111.       CMP    AL,'/'
  112.       JNE    ReadCmds
  113.       LODSB
  114.       CMP    AL,0DH
  115.       JE    GetPath
  116.       AND    AL,0DFH     ;Force upper case.
  117.       MOV    DI,OFFSET CmdLtrs    ;Check for a match to one
  118.       MOV    CX,CmdProcs - CmdLtrs    ; of our commands.
  119.       REPNE SCASB
  120.       JNE    ReadCmds        ;Loop if no match.
  121.       SUB    DI,OFFSET CmdLtrs + 1    ;DI = Command index.
  122.       SHL    DI,1            ;DI = offset in table.
  123.       CALL    CmdProcs[DI]        ;Execute the command.
  124.       JMP    ReadCmds
  125. ;
  126. ;    ; Get the path to our directory. Generate date file's name.
  127. GetPath:  PUSH    DS        ;Save our segment.
  128.       CALL    ProgName    ;Get path name to this prog in DS:SI.
  129.       MOV    DI,OFFSET TFName ;Move path into name field for
  130.       REP    MOVSB        ; our data file.
  131.       POP    DS        ;Get our segment back and move in
  132.       MOV    SI,OFFSET TodayAT ; filename after path.
  133.       MOV    CX,9
  134.       REP    MOVSB
  135. ;
  136. ;    ; Get the date and compare with the date file.
  137.       CALL    DateData    ; Convert DOS date to our formats.
  138.       CALL    GetDateFile    ; Try to read in the date file.
  139.       JC    ReWrite     ;Skip tests if no file.
  140. ;
  141. ;    ; File read OK. Check dates.
  142.       MOV    SI,OFFSET DOSDate.BinYear ;[SI]-DOS' numeric date.
  143.       MOV    DI,OFFSET TFDate.BinYear  ;[DI]-File's "       "
  144.       MOV    CX,05        ;2 words + 6 digits.
  145.       REPE    CMPSW        ;Compare.
  146.       JE    CheckDS     ;Branch if same day.
  147. PAGE
  148. ;    ; New day. Calculate the number that have passed.
  149.       TEST    SCommands,OneNudge
  150.       JZ    @F        ;Set single day if /1 command.
  151.       MOV    DaysPassed,1
  152.       JMP SHORT CheckDS
  153. @@:      CALL    GetPassed
  154.       CMP    DaysPassed,0    ;File error if no days passed.
  155.       JE    ReWrite     ;Ignore old file, rewrite.
  156. ;
  157. ;    ; File data is good. Check Std/Daylight params.
  158. CheckDS:  MOV    AL,TFDate.StOrDl    ;Get file's param.
  159.       CMP    AL,DOSDate.StOrDl    ;Old = New ?
  160.       JE    @F            ;Branch if so.
  161.       TEST    SCommands,DSCmdRcvd    ;Did we get a command?
  162.       JNZ    DSChange        ;Branch if we did.
  163.       MOV    DOSDate.StOrDl,AL    ;No command, set new=old.
  164. @@:      CMP    DaysPassed,0        ;Nudge if new day.
  165.       JNE    NewDay
  166.       TEST    SCommands,NewNudge  ;Not new day. Rewrite file if
  167.       JZ    SetCMOS         ;a new nudge value was entered.
  168. ReWrite:  CALL    WrDateFile
  169.       JMP SHORT SetCMOS        ;Just set the clock if not.
  170. ;
  171. ;    ; We have a command to exchange daylight <> standard.
  172. DSChange: CALL    TimeChange    ;Ask for confirm, change if OK.
  173.       CMP    DaysPassed,0    ; If no nudge required, write
  174.       JE    WrtToday    ; the date file and quit.
  175. ;
  176. ;    ; New day - nudge the clock.
  177. NewDay:   TEST    SCommands,NewNudge  ;Did we set new nudge value?
  178.       JNZ    @F            ;Branch if yes.
  179.       MOV    SI,OFFSET TFDate.AscNudge
  180.       MOV    CX,04        ;Convert 4 digits to binary.
  181.       CALL    Asc2Bin
  182.       MOV    NudgeVal,AX    ;Save as current nudge value.
  183. @@:      MOV    AX,NudgeVal    ;Get amount to adjust.
  184.       TEST    AX,AX        ;Skip this if it's zero.
  185.       JZ    WrtToday
  186.       IMUL    DaysPassed    ;Ticks per day * Number of days.
  187.       CALL    AdjustDOS    ; Adjust the DOS clock first.
  188. ;
  189. ;    ; Clock twiddling done if needed. Update file, set clock.
  190. WrtToday: CALL    WrDateFile    ; Write new date file.
  191.       CALL    DateData    ; Recalculate the date params from DOS.
  192. SetCMOS:  CALL    SetATClock    ; Set the CMOS clock.
  193. ;
  194. ;    ; Display current date, time.
  195.       MOV    DX,OFFSET DOSDate   ;Write date to screen.
  196.       MOV    CX,MsgSize
  197.       MOV    AH,AddLine
  198.       CALL    SimplMsg
  199.       MOV    DX,OFFSET TimeDisp  ;Write time to screen.
  200.       MOV    CX,9            ;9 characters, + CrLf.
  201.       MOV    AH,AddLine
  202.       CALL    SimplMsg
  203.       RET
  204. PROG      ENDP
  205. ;    ; *** End main program ***
  206. PAGE
  207. ; ; Command response functions.
  208. ;    ; /1 command - Nudge clock by one day only.
  209. OneCmd      PROC    NEAR        ;Just set the flag.
  210.       OR    SCommands,OneNudge
  211.       RET
  212. OneCmd      ENDP
  213. ;
  214. ;    ; /N command - set new nudge value.
  215. NCmd      PROC    NEAR
  216.       CALL    SkipSpac    ;Skip spaces after 'N'.
  217.       MOV    CX,04        ;Get up to four digits.
  218.       CALL    Asc2Bin
  219.       CMP    CX,04        ;Did we get any digits?
  220.       JE    @F        ;Branch if no - leave it zero.
  221.       MOV    NudgeVal,AX    ;Set new value and flag.
  222.       OR    SCommands,NewNudge ;(could be 0).
  223. @@:      RET
  224. NCmd      ENDP
  225. ;
  226. ;    ; /S or /D commands - Standard or Daylight.
  227. DSCmds      PROC    NEAR
  228.       OR    SCommands,DSCmdRcvd    ;Set command flag.
  229.       MOV    DOSDate.StOrDl,AL    ;Save the letter.
  230.       RET
  231. DSCmds      ENDP
  232. ;
  233. ; ; Subroutines for clock prog.
  234. GetDateFile PROC NEAR        ;Try to open the date file.
  235.       MOV    DX,OFFSET TFName ;We will return carry set if fail.
  236.       MOV    AX,3D02H    ;Read/write access.
  237.       INT    21H
  238.       JC    NoDF        ;Return error if no file.
  239. ;    ; The file is open. Try to read it.
  240.       MOV    BX,AX        ;Handle to BX.
  241.       MOV    CX,TFSiz    ;# bytes to CX.
  242.       MOV    DX,OFFSET TFDate
  243.       MOV    AH,3FH        ;'Read from file or device'
  244.       INT    21H
  245.       JC    ReadErr     ;Must have no DOS error and #bytes
  246.       CMP    AX,CX        ; read = # requested or file NG.
  247.       JE    ReadOK
  248. ReadErr:  MOV    AH,3EH        ;Error on read. Close file, forget.
  249.       INT    21H        ;Ignore close errors.
  250.       STC            ;Return fail.
  251.       JMP SHORT NoDF
  252. ReadOK:   MOV    AH,3EH        ;Close file so we can re-write it.
  253.       INT    21H        ;Clears carry.
  254. NoDF:      RET
  255. GetDateFile ENDP
  256.       PAGE
  257. ;    ; Get date from DOS. Setup our data area with:
  258. ;    ; 1. Full date in Ascii for display & date file.
  259. ;    ; 2. Date in numbers for date file / compare.
  260. ;    ; 3. Julian day, year in binary for days passed calculate.
  261. ;    ; 4. Binary format needed by CMOS clocks.
  262. DateData  PROC    NEAR
  263.       MOV    DI,OFFSET DOSDate.PDATE
  264.       MOV    AX,2A20H    ;Put a space at beginning.
  265.       STOSB         ;Revise date string from start.
  266.       INT    21H        ;DOS Get date call.
  267.       MOV    DOSDate.BinYear,CX ;Save year. AL has day-of-week.
  268. ; ;Day of week.
  269.       MOV    SI,OFFSET DAYS
  270.       XOR    AH,AH        ;Multiply days x4 for offset
  271.       ADD    SI,AX        ; into table.
  272.       CALL    SetDM        ;Convert & store.
  273. ; ;Day of month in Ascii.
  274.       MOV    AL,DL        ;Day of month in binary.
  275.       CALL    ConvDig     ;Convert & store.
  276.       MOV    CMOSDay,AL    ;Save for setting clock.
  277.       MOV BYTE PTR [DI],' '     ;Add a space.
  278.       MOV AX,WORD PTR DosDate.DOM      ;Put same value in numeric
  279.       MOV WORD PTR DOSDate.PDATNUMS + 4,AX     ;date.
  280. ; ;Month.
  281.       MOV    AL,DH        ;Get month number, 1-12 (not 0-11)
  282.       MOV    DI,OFFSET DOSDate.PDATNUMS + 2 ; for variety.
  283.       CALL    ConvDig     ;Put in numeric date field.
  284.       MOV    CMOSMon,AL    ;Save for setting clock.
  285.       MOV    AL,DH        ;Adjust and put month name in.
  286.       DEC    AL
  287.       MOV    DI,OFFSET DOSDate.MONTH
  288.       MOV    SI,OFFSET MOS    ;Months calculated like days.
  289.       CALL    SetDM
  290. ; ;Julian date in binary.
  291.       MOV    AX,DX        ;Binary month/day to AH/AL.
  292.       MOV    DX,DOSDate.BinYear ;Binary year to DX.
  293.       CALL    JulianDate    ;Get Julian date in AX.
  294.       MOV    DOSDate.JulDate,AX ;Save for file.
  295. ; ;Year.
  296.       MOV    AX,'91'         ;Put in '19'.
  297.       SUB    DX,1900         ;Get (Year-1900).
  298.       CMP    DX,100
  299.       JB    Twentieth
  300.       MOV    CMOSCent,20H
  301.       MOV    AX,'02'     ;Change after 2000.
  302.       SUB    DX,100
  303. Twentieth: STOSW
  304.       MOV    AL,DL        ;Put year in AL.
  305.       CALL    ConvDig
  306.       MOV    CMOSYear,AL    ;Save for setting clock.
  307.       MOV BYTE PTR [DI],' '
  308.       MOV    AX,[DI-2]    ;Put year in numeric date.
  309.       MOV WORD PTR DOSDate.PDATNUMS,AX
  310.       RET
  311. DateData  ENDP
  312. PAGE
  313. ;    ; Calculate number of days passed since last run.
  314. GetPassed PROC    NEAR
  315.       MOV    AX,DOSDate.JulDate  ;Today's Julian date, year.
  316.       MOV    BX,DOSDate.BinYear
  317.       SUB    BX,TFDate.BinYear   ;Get # years gone by.
  318.       JZ    @F            ;Branch if none.
  319.       DEC    BX            ;Sanity check.
  320.       JNZ    DFNoGood        ;Branch if > 1 year.
  321.       ADD    AX,365        ;Correct for a year. Check for
  322.       TEST BYTE PTR TFDate.BinYear,03 ; last year was a leap.
  323.       JNZ    @F        ;Branch if it wasn't.
  324.       INC    AX        ;One more day to correct.
  325. @@:      SUB    AX,TFDate.JulDate
  326.       JC    DFNoGood    ;Branch if today < yesterday.
  327.       TEST    AH,AH        ;Check for difference > 255.
  328.       JZ    @F        ;Branch if not - file is OK.
  329. DFNoGood: DMessage <"ATCLOCK: Date file invalid!"> \
  330.       AddLine+ErrorMsg+NoRet ; Return w/o updating DaysPassed.
  331. @@:      MOV    DaysPassed,AX    ;Save # days to adjust for.
  332.       RET
  333. GetPassed ENDP
  334. ;
  335. ; ; Change daylight - standard after confirmation.
  336. TimeChange PROC NEAR
  337. @@:      DMessage <"Do you want to set the clock ">
  338.       CMP    DOSDate.StOrDl,'D'    ;Ask for confirmation.
  339.       JE    @F            ;Branch if going to daylight.
  340.       DMessage <"back 1 hour for standard time? ">
  341.       JMP SHORT WaitConf
  342. @@:      DMessage <"ahead 1 hour for daylight time? ">
  343. WaitConf: CALL    GetYorN     ;Wait for response.
  344.       JNE    NoTC        ;Branch if 'No'.
  345.       MOV    DX,1        ;Set one hour's worth of ticks.
  346.       MOV    AX,7
  347.       CMP    DOSDate.StOrDl,'D'  ;Are we going to daylight?
  348.       JE    @F        ;Branch if positive adjust.
  349.       NEG    AX        ;Add negative 1 hour.
  350.       NOT    DX
  351. @@:      CALL    AdjustDOS    ;Enter correction to DOS clock only.
  352.       DMessage <"Time change set."> AddLine
  353. NoTC:      RET
  354. TimeChange ENDP
  355. ;
  356. ;    ; Adjust the DOS clock by DX:AX ticks (signed).
  357. AdjustDOS PROC    NEAR
  358.       XOR    BX,BX        ;Get access to data area.
  359.       MOV    DS,BX
  360.       ASSUME  DS:SEGZERO    ;Inform MASM.
  361.       CLI            ;Hold the clock off.
  362.       ADD    AX,TimerLow    ; Get the adjusted values in AX:DX.
  363.       ADC    DX,TimerHigh
  364.       CMP    DX,23        ;Check for over/underflow.
  365.       JA    DayChange    ;Branch if so.
  366.       JB    @F        ;Branch elsewhere if < 23Hrs.
  367.       CMP    AX,7*24     ;Check for > 23:59.
  368.       JAE    DayChange
  369. @@:      CALL    TicsDays    ;No overflow. Set clock, reload seg.
  370.       JMP SHORT AdjDone
  371. ;
  372. DayChange: TEST DH,80H        ;Date rolled.
  373.       JZ    Manana        ;Branch if forward.
  374.       ADD    AX,7*24     ;It's yesterday.
  375.       ADC    DX,24        ;Put 24 hrs. back into clock.
  376.       CALL    TicsDays    ;Set clock, int on, reload seg.
  377.       DEC    AX        ;Take the 1 day out of the calendar.
  378.       JNZ    @F        ;Branch if same year.
  379.       DEC    DX        ;Now NewYears' Eve.
  380.       MOV    AX,365
  381.       TEST    DX,03
  382.       JNZ    @F
  383.       INC    AX        ;Now New Years' Eve of a leap year!
  384. @@:      JMP SHORT NewDate
  385. ;
  386. Manana:   SUB    AX,7*24     ;Take the day back out of the clock.
  387.       SBB    DX,24
  388.       CALL    TicsDays    ;Set clock, int on, reload seg.
  389.       ASSUME  DS:CGroup    ;Don't mislead Masm.
  390.       INC    AX        ;Put the day into the calendar.
  391.       MOV    BX,365        ;Set BX to #days this year.
  392.       TEST    DX,03
  393.       JNZ    @F
  394.       INC    BX        ;It's a leap year.
  395. @@:      CMP    AX,BX        ;Check for year rolled.
  396.       JBE    NewDate
  397.       INC    DX
  398.       MOV    AX,1        ;Happy New Year!
  399. NewDate:  CALL    Jul2DOS     ;Set the new date in DOS.
  400. AdjDone:  DMessage <"Clock adjusted."> AddLine
  401.       RET
  402. AdjustDos ENDP
  403. ;
  404. ; ; Write new date file. Set nudge value from variable.
  405. WrDateFile PROC NEAR
  406.       MOV    AX,NudgeVal    ;Convert nudge value to ascii in
  407.       MOV    DI,OFFSET DOSDate.AscNudge     ;date info.
  408.       CALL    AX4Digs
  409.       MOV    DX,OFFSET TFName    ;Create or overwrite 'Today'.
  410.       XOR    CX,CX            ;Normal, visible file.
  411.       MOV    AH,3CH
  412.       INT    21H
  413.       JC    WritErr         ;Bail out if error on create.
  414.       MOV    BX,AX            ;File handle to BX.
  415.       MOV    CX,TFSiz        ;# bytes to CX.
  416.       MOV    DX,OFFSET DOSDate   ;DX -> data to write.
  417.       MOV    AH,40H            ;'Write to file or device'.
  418.       INT    21H
  419.       JC    WritErr         ;Bail on error.
  420.       CMP    AX,CX            ;Also if disk full <gasp>.
  421.       JE    WriteOK
  422. WritErr:  DMessage <"ATCLOCK: DOS error writing data file!"> \
  423.       AddLine+ErrorMsg
  424. WriteOK:  MOV    AH,3EH            ;Close the file.
  425.       INT    21H            ;Ignore errors. Can't do anything.
  426.       RET
  427. WrDateFile ENDP
  428. PAGE
  429. ;      ;Set the CMOS clock from the DOS clock.
  430. SetATClock PROC NEAR
  431.       MOV    AH,2CH        ;Let DOS convert the raw ticks to
  432.       INT    21H        ; hr:min:sec.  We don't care if a
  433.       CMP    DL,45        ; tick went by.  Round off DOS'
  434.       JB    @F        ; ".01" seconds.
  435.       INC    DH
  436. ;      ;Change DOS time data to clock data format.
  437. @@:      MOV    DI,OFFSET TimeData  ;Point to time display data.
  438.       MOV    AL,CH        ;Convert hours for display and
  439.       CALL    ConvDig     ; to BCD for CMOS clock call.
  440.       INC    DI        ;Skip the colon.
  441.       MOV    CH,AL
  442.       MOV    AL,CL        ;Same for minutes.
  443.       CALL    ConvDig
  444.       INC    DI        ;Skip the colon.
  445.       MOV    CL,AL
  446.       MOV    AL,DH        ;Same for seconds.
  447.       CALL    ConvDig
  448.       INC    DI        ;Skip the colon.
  449.       MOV    DH,AL
  450.       XOR    DL,DL        ;DL=0 for standard time,
  451.       CMP    DOSDate.StOrDl,'D'
  452.       JNE    @F        ; 1 for daylight.
  453.       INC    DL
  454. @@:      MOV    AH,03
  455.       INT    1AH        ;Set the CMOS clock.
  456. ;      ;Set the date from our date from DOS.
  457.       MOV    CH,CMOSCent        ;Good for 112 more years...
  458.       MOV    CL,CMOSYear
  459.       MOV    DH,CMOSMon
  460.       MOV    DL,CMOSDay
  461.       MOV    AH,05
  462.       INT    1AH        ;Set the date.
  463.       RET
  464. SetATClock ENDP
  465. ;
  466. ;    ; Julian date: From month/day in AH/AL,
  467. JulianDate PROC NEAR        ; Binary year in DX. Result in AX.
  468.       PUSH    DX
  469.       MOV    CL,28        ;Default 28 days in Feb.
  470.       TEST    DX,03        ;Non-zero means non leap year.
  471.       JNZ    @F        ;Good for years between 1900 & 2100.
  472.       INC    CL
  473. @@:      MOV    DaysInFeb,CL    ;Set February.
  474.       MOV    SI,OFFSET DaysPerMon
  475.       XOR    CX,CX
  476.       MOV    DX,CX
  477.       XCHG    CL,AH        ;Add days per month oneata time.
  478.       MOV    DL,AL        ;Accumulate in DX.
  479.       DEC    CX        ;Months 0-11.
  480.       JZ    @F        ;No correction for January.
  481. NxtMonth: LODSB
  482.       ADD    DX,AX
  483.       LOOP    NxtMonth
  484. @@:      MOV    AX,DX        ;Result in right place.
  485.       POP    DX
  486.       RET
  487. JulianDate ENDP
  488. ;
  489. ;    ; Jul2DOS: Convert Year:Julian in DX:AX to DOS format
  490. ;    ; and set the DOS clock.
  491. Jul2DOS   PROC    NEAR
  492.       MOV    CX,DX        ;Year same format.
  493.       MOV    SI,OFFSET DaysPerMon
  494.       MOV    BL,28        ;Set correct #days in Feb.
  495.       TEST    DX,03
  496.       JNZ    @F
  497.       INC    BL
  498. @@:      MOV    DaysInFeb,BL
  499.       XOR    DX,DX
  500.       MOV    BX,DX        ;Clear scratch regs.
  501. IncMos:   INC    DH        ;Add to months & subtract days.
  502.       TEST    AH,AH        ;Skip check if still > 255.
  503.       JNZ    @F
  504.       CMP    AL,[SI]     ;Conversion done if
  505.       JBE    Found        ; AX < #days in month DH.
  506. @@:      MOV    BL,[SI]
  507.       SUB    AX,BX        ;Subtract the month, loop.
  508.       INC    SI
  509.       JMP    IncMos
  510. Found:      MOV    DL,AL        ;Set proper regs for DOS.
  511.       MOV    AH,2BH        ;Set DOS date.
  512.       INT    21H
  513.       RET
  514. Jul2DOS   ENDP
  515. ;
  516. ;    ; Get yes or no response from user.
  517. GetYorN   PROC    NEAR
  518.       MOV    DX,OFFSET ULine
  519.       MOV    AH,0AH        ;Via redirectable call.
  520.       INT    21H
  521.       XOR    AH,AH        ;No options for message.
  522.       CALL    NextLine    ;cr,lf...
  523.       MOV    AL,UResp    ;Get the letter.
  524.       AND    AL,0DFH     ;Force upper case.
  525.       CMP    AL,'Y'        ;It's Y or it's not!
  526.       RET
  527. GetYorN   ENDP
  528. ;
  529. TicsDays  PROC    NEAR    ;Set Bios clock, load date.
  530.       ASSUME  DS:SEGZERO
  531.       MOV    TimerLow,AX
  532.       MOV    TimerHigh,DX
  533.       STI            ;Int back on, get our segment.
  534.       MOV    AX,CS
  535.       MOV    DS,AX
  536.       ASSUME  DS:CGroup
  537.       MOV    AX,DOSDate.JulDate  ;DX:AX = Year:Julian date.
  538.       MOV    DX,DOSDate.BinYear
  539.       RET
  540. TicsDays  ENDP
  541. PAGE
  542. ;      ; Update day or month data.
  543. SetDM      PROC    NEAR
  544.       XOR    AH,AH        ;Mult. AL x3 for data address
  545.       ADD    SI,AX        ;in list. Move data to o/p area.
  546.       SHL    AL,1
  547.       ADD    SI,AX
  548.       MOV    CX,03
  549.       REP    MOVSB
  550.       MOV    AL,' '
  551.       STOSB         ;Add space after data.
  552.       RET
  553. SetDM      ENDP
  554. ;
  555. ;      ; Convert binary # in AL to 2-digit Ascii for display
  556. ;      ; and packed BCD for CMOS clock set call. Uses BX.
  557. ConvDig   PROC    NEAR
  558.       AAM            ;AL to unpacked BCD in AH,AL.
  559.       MOV    BX,AX        ;Save for further convert.
  560.       OR    AX,3030H    ;Change to Ascii.
  561.       XCHG    AL,AH        ;Change to Intel.
  562.       STOSW         ;Save for display.
  563.       MOV    AL,BL        ;Get LS nibble.
  564.       SHL    BH,4        ;OR in MS nibble.
  565.       OR    AL,BH
  566.       RET
  567. ConvDig   ENDP
  568. CSEG      ENDS
  569.       END    START
  570.