]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/TIME.ASM
1 ; SCCSID = @(#)time.asm 1.1 85/04/10
2 TITLE TIME
- time
and date functions
5 ; System Calls and low level routines for DATE and TIME
18 ; Modification history:
20 ; Created: ARR 30 March 1983
25 ; get the appropriate segment definitions
29 CODE SEGMENT BYTE PUBLIC 'CODE'
30 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
50 FOURYEARS
= 3*365 + 366
52 SUBTTL DATE
AND TIME
- SYSTEM CALLS
42,43,44,45
54 procedure $GET_DATE
,NEAR
55 ASSUME
DS:NOTHING
,ES:NOTHING
65 CALL READTIME
;Check for rollover to next day
68 ; WARNING!!!! DAY and MONTH must be adjacently allocated!
70 MOV BX,WORD PTR [DAY
] ; fetch both day and month
71 invoke get_user_stack
;Get pointer to user registers
73 MOV [SI.user_DX
],BX ;DH=month, DL=day
74 ADD AX,1980 ;Put bias back
75 MOV [SI.user_CX
],AX ;CX=year
76 MOV AL,BYTE PTR [WEEKDAY
]
80 procedure $SET_DATE
,NEAR ;System call 43
81 ASSUME
DS:NOTHING
,ES:NOTHING
88 ; AL = -1 date bad, = 0 OK
90 MOV AL,-1 ;Be ready to flag error
91 SUB CX,1980 ;Fix bias in year
92 retc
;Error if not big enough
93 CMP CX,119 ;Year must be less than 2100
98 retz
;Error if either month or day is 0
99 CMP DH,12 ;Check against max. month
106 procedure $GET_TIME
,NEAR ;System call 44
107 ASSUME
DS:NOTHING
,ES:NOTHING
118 invoke get_user_stack
;Get pointer to user registers
125 procedure $SET_TIME
,NEAR ;System call 45
126 ASSUME
DS:NOTHING
,ES:NOTHING
133 ; AL = -1 time bad, = 0 OK
135 MOV AL,-1 ;Flag in case of error
136 CMP CH,24 ;Check hours
138 CMP CL,60 ;Check minutes
140 CMP DH,60 ;Check seconds
142 CMP DL,100 ;Check 1/100's
147 MOV BX,OFFSET DOSGROUP
:TIMEBUF
153 DOSAssume
CS,<ES>,"TIME/SetRead"
157 invoke DEVIOCALL2
;Get correct day count
159 DOSAssume
CS,<DS>,"TIME/DevIOCall2"
162 POP WORD PTR [TIMEBUF
+4]
163 POP WORD PTR [TIMEBUF
+2]
166 invoke DEVIOCALL2
;Set the time
171 SUBTTL DATE16
, READTIME
, DODATE
-- GUTS OF TIME
AND DATE
175 ; Date16 returns the current date in AX, current time in DX
176 ; AX - YYYYYYYMMMMDDDDD years months days
177 ; DX - HHHHHMMMMMMSSSSS hours minutes seconds/2
179 ; DS = DOSGROUP on output
181 procedure DATE16
,NEAR
188 SHL CL,1 ;Minutes to left part of byte
190 SHL CX,1 ;Push hours and minutes to left end
193 SHR DH,1 ;Count every two seconds
194 OR CL,DH ;Combine seconds with hours and minutes
197 ; WARNING! MONTH and YEAR must be adjacently allocated
199 MOV AX,WORD PTR [MONTH
] ;Fetch month and year
201 SHL AL,CL ;Push month to left to make room for day
208 ;Gets time in CX:DX. Figures new date if it has changed.
211 procedure READTIME
,NEAR
212 DOSAssume
CS,<DS>,"ReadTime"
215 MOV [DATE_FLAG
],0 ; reset date flag for CPMIO
218 MOV BX,OFFSET DOSGROUP
:TIMEBUF
226 invoke DEVIOCALL2
;Get correct date and time
228 DOSAssume
CS,<DS>,"ReadTime/DevIOCall2"
231 MOV AX,WORD PTR [TIMEBUF
]
232 MOV CX,WORD PTR [TIMEBUF
+2]
233 MOV DX,WORD PTR [TIMEBUF
+4]
234 CMP AX,[DAYCNT
] ;See if day count is the same
236 CMP AX,FOURYEARS
*30 ;Number of days in 120 years
237 JAE RET22
;Ignore if too large
243 MOV CX,FOURYEARS
;Number of days in 4 years
244 DIV CX ;Compute number of 4-year units
247 SHL AX,1 ;Multiply by 8 (no. of half-years)
248 MOV CX,AX ;<240 implies AH=0
249 MOV SI,OFFSET DOSGROUP
:YRTAB
;Table of days in each year
250 CALL DSLIDE
;Find out which of four years we're in
251 SHR CX,1 ;Convert half-years to whole years
252 JNC SK
;Extra half-year?
256 MOV CL,1 ;At least at first month in year
257 MOV SI,OFFSET DOSGROUP
:MONTAB
;Table of days in each month
258 CALL DSLIDE
;Find out which month we're in
260 INC DX ;Remainder is day of month (start with one)
262 CALL WKDAY
;Set day of week
269 procedure DSLIDE
,NEAR
272 LODSB ;Get count of days
273 CMP DX,AX ;See if it will fit
276 INC CX ;Count one more month/year
280 procedure SETYEAR
,NEAR
281 ;Set year with value in CX. Adjust length of February for this year.
282 MOV BYTE PTR [YEAR
],CL
285 TEST CL,3 ;Check for leap year
287 JNZ SAVFEB
;28 days if no leap year
290 MOV [MONTAB
+1],AL ;Store for February
294 procedure DODATE
,NEAR
295 DOSAssume
CS,<DS>,"DoDate"
297 CALL CHKYR
;Set Feb. up for new year
299 MOV BX,OFFSET DOSGROUP
:MONTAB
-1
300 XLAT ;Look up days in month
302 MOV AL,-1 ;Restore error flag, just in case
303 retc
;Error if too many days
306 ; WARNING! DAY and MONTH must be adjacently allocated
308 MOV WORD PTR [DAY
],DX ;Set both day and month
314 MOV CL,BYTE PTR [YEAR
]
316 MOV SI,OFFSET DOSGROUP
:YRTAB
318 SHL CX,1 ;Two entries per year, so double count
319 CALL DSUM
;Add up the days in each year
320 MOV CL,BH ;Month of year
321 MOV SI,OFFSET DOSGROUP
:MONTAB
322 DEC CX ;Account for months starting with one
323 CALL DSUM
;Add up days in each month
324 MOV CL,BL ;Day of month
325 DEC CX ;Account for days starting with one
326 ADD DX,CX ;Add in to day total
327 XCHG AX,DX ;Get day count in AX
332 MOV BX,OFFSET DOSGROUP
:TIMEBUF
338 DOSAssume
CS,<ES>,"DoDate/SetRead"
342 invoke DEVIOCALL2
;Get correct date and time
345 DOSAssume
CS,<DS>,"DoDate/DevIOCall2"
347 POP WORD PTR [TIMEBUF
]
351 invoke DEVIOCALL2
;Set the date
353 DOSAssume
CS,<DS>,"DoDate/DevIOCall2(second)"
361 INC AX ;First day was Tuesday
362 DIV CX ;Compute day of week