]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/TIME.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / TIME.ASM
1 ; SCCSID = @(#)time.asm 1.1 85/04/10
2 TITLE TIME - time and date functions
3 NAME TIME
4 ;
5 ; System Calls and low level routines for DATE and TIME
6 ;
7 ; $GET_DATE
8 ; $SET_DATE
9 ; $GET_TIME
10 ; $SET_TIME
11 ; DATE16
12 ; READTIME
13 ; DSLIDE
14 ; SETYEAR
15 ; DODATE
16 ; DSUM
17 ;
18 ; Modification history:
19 ;
20 ; Created: ARR 30 March 1983
21 ;
22
23 .xlist
24 ;
25 ; get the appropriate segment definitions
26 ;
27 include dosseg.asm
28
29 CODE SEGMENT BYTE PUBLIC 'CODE'
30 ASSUME SS:DOSGROUP,CS:DOSGROUP
31
32 .xcref
33 INCLUDE DOSSYM.INC
34 INCLUDE DEVSYM.INC
35 .cref
36 .list
37
38
39 i_need DAY,BYTE
40 i_need MONTH,BYTE
41 i_need YEAR,WORD
42 i_need WEEKDAY,BYTE
43 i_need TIMEBUF,6
44 i_need BCLOCK,DWORD
45 i_need DAYCNT,WORD
46 i_need YRTAB,8
47 i_need MONTAB,12
48 i_need DATE_FLAG,WORD
49
50 FOURYEARS = 3*365 + 366
51
52 SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45
53 PAGE
54 procedure $GET_DATE,NEAR
55 ASSUME DS:NOTHING,ES:NOTHING
56
57 ; Inputs:
58 ; None
59 ; Function:
60 ; Return current date
61 ; Returns:
62 ; Date in CX:DX
63
64 Context DS
65 CALL READTIME ;Check for rollover to next day
66 MOV AX,[YEAR]
67 ;
68 ; WARNING!!!! DAY and MONTH must be adjacently allocated!
69 ;
70 MOV BX,WORD PTR [DAY] ; fetch both day and month
71 invoke get_user_stack ;Get pointer to user registers
72 ASSUME DS:NOTHING
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]
77 return
78 EndProc $GET_DATE
79
80 procedure $SET_DATE,NEAR ;System call 43
81 ASSUME DS:NOTHING,ES:NOTHING
82
83 ; Inputs:
84 ; CX:DX valid date
85 ; Function:
86 ; Set current date
87 ; Returns:
88 ; AL = -1 date bad, = 0 OK
89
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
94 JA RET24
95 OR DH,DH
96 retz
97 OR DL,DL
98 retz ;Error if either month or day is 0
99 CMP DH,12 ;Check against max. month
100 JA RET24
101 Context DS
102 invoke DODATE
103 RET24: return
104 EndProc $SET_DATE
105
106 procedure $GET_TIME,NEAR ;System call 44
107 ASSUME DS:NOTHING,ES:NOTHING
108
109 ; Inputs:
110 ; None
111 ; Function:
112 ; Get current time
113 ; Returns:
114 ; Time in CX:DX
115
116 Context DS
117 CALL READTIME
118 invoke get_user_stack ;Get pointer to user registers
119 MOV [SI.user_DX],DX
120 MOV [SI.user_CX],CX
121 XOR AL,AL
122 RET26: return
123 EndProc $GET_TIME
124
125 procedure $SET_TIME,NEAR ;System call 45
126 ASSUME DS:NOTHING,ES:NOTHING
127
128 ; Inputs:
129 ; CX:DX = Time
130 ; Function:
131 ; Set time
132 ; Returns:
133 ; AL = -1 time bad, = 0 OK
134
135 MOV AL,-1 ;Flag in case of error
136 CMP CH,24 ;Check hours
137 JAE RET26
138 CMP CL,60 ;Check minutes
139 JAE RET26
140 CMP DH,60 ;Check seconds
141 JAE RET26
142 CMP DL,100 ;Check 1/100's
143 JAE RET26
144 PUSH CX
145 PUSH DX
146 Context DS
147 MOV BX,OFFSET DOSGROUP:TIMEBUF
148 MOV CX,6
149 XOR DX,DX
150 MOV AX,DX
151 PUSH BX
152 invoke SETREAD
153 DOSAssume CS,<ES>,"TIME/SetRead"
154 PUSH DS
155 LDS SI,[BCLOCK]
156 ASSUME DS:NOTHING
157 invoke DEVIOCALL2 ;Get correct day count
158 POP DS
159 DOSAssume CS,<DS>,"TIME/DevIOCall2"
160 POP BX
161 invoke SETWRITE
162 POP WORD PTR [TIMEBUF+4]
163 POP WORD PTR [TIMEBUF+2]
164 LDS SI,[BCLOCK]
165 ASSUME DS:NOTHING
166 invoke DEVIOCALL2 ;Set the time
167 XOR AL,AL
168 return
169 EndProc $SET_TIME
170
171 SUBTTL DATE16, READTIME, DODATE -- GUTS OF TIME AND DATE
172 PAGE
173
174 ;
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
178 ;
179 ; DS = DOSGROUP on output
180
181 procedure DATE16,NEAR
182 Context DS
183 ASSUME ES:NOTHING
184 PUSH CX
185 PUSH ES
186 CALL READTIME
187 POP ES
188 SHL CL,1 ;Minutes to left part of byte
189 SHL CL,1
190 SHL CX,1 ;Push hours and minutes to left end
191 SHL CX,1
192 SHL CX,1
193 SHR DH,1 ;Count every two seconds
194 OR CL,DH ;Combine seconds with hours and minutes
195 MOV DX,CX
196 ;
197 ; WARNING! MONTH and YEAR must be adjacently allocated
198 ;
199 MOV AX,WORD PTR [MONTH] ;Fetch month and year
200 MOV CL,4
201 SHL AL,CL ;Push month to left to make room for day
202 SHL AX,1
203 POP CX
204 OR AL,[DAY]
205 return
206 EndProc DATE16
207
208 ;Gets time in CX:DX. Figures new date if it has changed.
209 ;Uses AX, CX, DX.
210
211 procedure READTIME,NEAR
212 DOSAssume CS,<DS>,"ReadTime"
213 ASSUME ES:NOTHING
214
215 MOV [DATE_FLAG],0 ; reset date flag for CPMIO
216 PUSH SI
217 PUSH BX
218 MOV BX,OFFSET DOSGROUP:TIMEBUF
219 MOV CX,6
220 XOR DX,DX
221 MOV AX,DX
222 invoke SETREAD
223 PUSH DS
224 LDS SI,[BCLOCK]
225 ASSUME DS:NOTHING
226 invoke DEVIOCALL2 ;Get correct date and time
227 POP DS
228 DOSAssume CS,<DS>,"ReadTime/DevIOCall2"
229 POP BX
230 POP SI
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
235 retz
236 CMP AX,FOURYEARS*30 ;Number of days in 120 years
237 JAE RET22 ;Ignore if too large
238 MOV [DAYCNT],AX
239 PUSH SI
240 PUSH CX
241 PUSH DX ;Save time
242 XOR DX,DX
243 MOV CX,FOURYEARS ;Number of days in 4 years
244 DIV CX ;Compute number of 4-year units
245 SHL AX,1
246 SHL AX,1
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?
253 ADD DX,200
254 SK:
255 CALL SETYEAR
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
259 MOV [MONTH],CL
260 INC DX ;Remainder is day of month (start with one)
261 MOV [DAY],DL
262 CALL WKDAY ;Set day of week
263 POP DX
264 POP CX
265 POP SI
266 RET22: return
267 EndProc READTIME
268
269 procedure DSLIDE,NEAR
270 MOV AH,0
271 DSLIDE1:
272 LODSB ;Get count of days
273 CMP DX,AX ;See if it will fit
274 retc ;If not, done
275 SUB DX,AX
276 INC CX ;Count one more month/year
277 JMP SHORT DSLIDE1
278 EndProc DSLIDE
279
280 procedure SETYEAR,NEAR
281 ;Set year with value in CX. Adjust length of February for this year.
282 MOV BYTE PTR [YEAR],CL
283
284 CHKYR:
285 TEST CL,3 ;Check for leap year
286 MOV AL,28
287 JNZ SAVFEB ;28 days if no leap year
288 INC AL ;Add leap day
289 SAVFEB:
290 MOV [MONTAB+1],AL ;Store for February
291 RET23: return
292 EndProc SETYEAR
293
294 procedure DODATE,NEAR
295 DOSAssume CS,<DS>,"DoDate"
296 ASSUME ES:NOTHING
297 CALL CHKYR ;Set Feb. up for new year
298 MOV AL,DH
299 MOV BX,OFFSET DOSGROUP:MONTAB-1
300 XLAT ;Look up days in month
301 CMP AL,DL
302 MOV AL,-1 ;Restore error flag, just in case
303 retc ;Error if too many days
304 CALL SETYEAR
305 ;
306 ; WARNING! DAY and MONTH must be adjacently allocated
307 ;
308 MOV WORD PTR [DAY],DX ;Set both day and month
309 SHR CX,1
310 SHR CX,1
311 MOV AX,FOURYEARS
312 MOV BX,DX
313 MUL CX
314 MOV CL,BYTE PTR [YEAR]
315 AND CL,3
316 MOV SI,OFFSET DOSGROUP:YRTAB
317 MOV DX,AX
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
328 MOV [DAYCNT],AX
329 PUSH SI
330 PUSH BX
331 PUSH AX
332 MOV BX,OFFSET DOSGROUP:TIMEBUF
333 MOV CX,6
334 XOR DX,DX
335 MOV AX,DX
336 PUSH BX
337 invoke SETREAD
338 DOSAssume CS,<ES>,"DoDate/SetRead"
339 PUSH DS
340 LDS SI,[BCLOCK]
341 ASSUME DS:NOTHING
342 invoke DEVIOCALL2 ;Get correct date and time
343 POP DS
344 POP BX
345 DOSAssume CS,<DS>,"DoDate/DevIOCall2"
346 invoke SETWRITE
347 POP WORD PTR [TIMEBUF]
348 PUSH DS
349 LDS SI,[BCLOCK]
350 ASSUME DS:NOTHING
351 invoke DEVIOCALL2 ;Set the date
352 POP DS
353 DOSAssume CS,<DS>,"DoDate/DevIOCall2(second)"
354 POP BX
355 POP SI
356 WKDAY:
357 MOV AX,[DAYCNT]
358 XOR DX,DX
359 MOV CX,7
360 INC AX
361 INC AX ;First day was Tuesday
362 DIV CX ;Compute day of week
363 MOV [WEEKDAY],DL
364 XOR AL,AL ;Flag OK
365 Ret25: return
366 EndProc DODATE
367
368 procedure DSUM,NEAR
369 MOV AH,0
370 JCXZ RET25
371 DSUM1:
372 LODSB
373 ADD DX,AX
374 LOOP DSUM1
375 return
376 EndProc DSUM
377
378 CODE ENDS
379 END
380 \1a