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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / BIOS / MSCLOCK.ASM
1 TITLE MSCLOCK - DOS 3.3
2 ;----------------------------------------------------------------
3 ; :
4 ; CLOCK DEVICE DRIVER :
5 ; :
6 ; :
7 ; This file contains the Clock Device Driver. :
8 ; :
9 ; The routines in this files are: :
10 ; :
11 ; routine function :
12 ; ------- -------- :
13 ; TIM$WRIT Set the current time :
14 ; TIM$READ Read the current time :
15 ; Time_To_Ticks Convert time to corresponding :
16 ; number of clock ticks :
17 ; :
18 ; The clock ticks at the rate of: :
19 ; :
20 ; 1193180/65536 ticks/second (about 18.2 ticks per second):
21 ; See each routine for information on the use. :
22 ; :
23 ;----------------------------------------------------------------
24
25
26 itest=0
27 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
28 INCLUDE MSMACRO.INC
29
30 EXTRN EXIT:NEAR
31 ;
32 ; DAYCNT is the number of days since 1-1-80.
33 ; Each time the clock is read it is necessary to check if another day has
34 ; passed. The ROM only returns the day rollover once so if it is missed
35 ; the time will be off by a day.
36 ;
37 EXTRN DAYCNT:WORD ;MSDATA
38
39 ;;Rev 3.30 Modification ------------------------------------------------
40 ; variables for real time clock setting
41 public HaveCMOSClock
42 HaveCMOSClock db 0 ;set by MSINIT.
43 public base_century
44 base_century db 19
45 public base_year
46 base_year db 80
47 public month_tab
48 month_tab db 31,28,31,30,31,30,31,31,30,31,30,31
49
50 ; The following are indirect intra-segment call addresses. The
51 ;procedures are defined in MSINIT for relocation. MSINIT will set these
52 ;address when the relocation is done.
53 public BinToBCD
54 BinToBCD dw 0 ;should point to Bin_To_BCD proc in MSINIT
55 public DaycntToDay
56 DaycntToDay dw 0 ;should point to Daycnt_to_day in MSINIT
57
58 ;********************************************************************
59 ; Indirect call address of TIME_TO_TICKS procedure.
60 ;This will be used by the relocatable portable suspend/resume code.
61
62 public TimeToTicks
63 TimeToTicks dw Time_To_Ticks
64
65 ;;End of Modification ------------------------------------------------
66
67 ;--------------------------------------------------------------------
68 ;
69 ; Settime sets the current time
70 ;
71 ; On entry ES:[DI] has the current time:
72 ;
73 ; number of days since 1-1-80 (WORD)
74 ; minutes (0-59) (BYTE)
75 ; hours (0-23) (BYTE)
76 ; hundredths of seconds (0-99) (BYTE)
77 ; seconds (0-59) (BYTE)
78 ;
79 ; Each number has been checked for the correct range.
80 ;
81 PUBLIC TIM$WRIT
82 TIM$WRIT PROC NEAR
83 ASSUME DS:CODE
84 mov AX,WORD PTR ES:[DI]
85 push AX ;DAYCNT. We need to set this at the very
86 ; end to avoid tick windows.
87 ;;Rev 3.30 Modification
88 cmp HaveCMOSClock, 0
89 je No_CMOS_1
90 mov al,es:[di+3] ;get binary hours
91 call BinToBCD ;convert to BCD
92 mov ch,al ;CH = BCD hours
93 mov al,es:[di+2] ;get binary minutes
94 call BinToBCD ;convert to BCD
95 mov cl,al ;CL = BCD minutes
96 mov al,es:[di+5] ;get binary seconds
97 call BinToBCD ;convert to BCD
98 mov dh,al ;DH = BCD seconds
99 mov dl,0 ;DL = 0 (ST) or 1 (DST)
100 cli ;turn off timer
101 mov ah,03h ;set RTC time
102 int 1Ah ;call rom bios clock routine
103 sti
104
105 ;;End of Modification
106 No_CMOS_1:
107 mov CX,WORD PTR ES:[DI+2]
108 mov DX,WORD PTR ES:[DI+4]
109 ;;Rev 3.30 Modification
110 call time_to_ticks ; convert time to ticks
111 ;CX:DX now has time in ticks
112 cli ; Turn off timer
113 mov AH, 1 ; command is set time in clock
114 int 1Ah ; call rom-bios clock routines
115 pop [DAYCNT]
116 sti
117 ;CMOS clock -------------------------------------
118 cmp HaveCMOSClock, 0
119 je No_CMOS_2
120 call DaycntToDay ; convert to BCD format
121 cli ; Turn off timer
122 mov AH,05h ; set RTC date
123 int 1Ah ; call rom-bios clock routines
124 sti
125 ;------------------------------------------------
126
127 No_CMOS_2:
128 jmp EXIT
129 TIM$WRIT ENDP
130 ;;End of Modification
131
132
133
134 ;
135 ; convert time to ticks
136 ; input : time in CX and DX
137 ; ticks returned in CX:DX
138 ;
139 public time_to_ticks
140 TIME_TO_TICKS PROC NEAR
141
142 ; first convert from Hour,min,sec,hund. to
143 ; total number of 100th of seconds
144 mov AL,60
145 mul CH ;Hours to minutes
146 mov CH,0
147 add AX,CX ;Total minutes
148 mov CX,6000 ;60*100
149 mov BX,DX ;Get out of the way of the multiply
150 mul CX ;Convert to 1/100 sec
151 mov CX,AX
152 mov AL,100
153 mul BH ;Convert seconds to 1/100 sec
154 add CX,AX ;Combine seconds with hours and min.
155 adc DX,0 ;Ripple carry
156 mov BH,0
157 add CX,BX ;Combine 1/100 sec
158 adc DX,0
159
160 ;;Rev 3.30 Modification
161 ;DX:CX IS TIME IN 1/100 SEC
162 XCHG AX,DX
163 XCHG AX,CX ;NOW TIME IS IN CX:AX
164 MOV BX,59659
165 MUL BX ;MULTIPLY LOW HALF
166 XCHG DX,CX
167 XCHG AX,DX ;CX->AX, AX->DX, DX->CX
168 MUL BX ;MULTIPLY HIGH HALF
169 ADD AX,CX ;COMBINE OVERLAPPING PRODUCTS
170 ADC DX,0
171 XCHG AX,DX ;AX:DX=TIME*59659
172 MOV BX,5
173 DIV BL ;DIVIDE HIGH HALF BY 5
174 MOV CL,AL
175 MOV CH,0
176 MOV AL,AH ;REMAINDER OF DIVIDE-BY-5
177 CBW
178 XCHG AX,DX ;USE IT TO EXTEND LOW HALF
179 DIV BX ;DIVDE LOW HALF BY 5
180 MOV DX,AX
181 ; CX:DX is now number of ticks in time
182 ret
183 TIME_TO_TICKS ENDP
184 ;;End of Modification
185
186
187 ;
188 ; Gettime reads date and time
189 ; and returns the following information:
190 ;
191 ; ES:[DI] =count of days since 1-1-80
192 ; ES:[DI+2]=hours
193 ; ES:[DI+3]=minutes
194 ; ES:[DI+4]=seconds
195 ; ES:[DI+5]=hundredths of seconds
196 ;
197 PUBLIC TIM$READ
198 TIM$READ PROC NEAR
199 ; read the clock
200 xor AH, AH ; set command to read clock
201 int 1Ah ; call rom-bios to get time
202
203 or al,al ; check for a new day
204 jz noroll1 ; if al=0 then don't reset day count
205 INC [DAYCNT] ; CATCH ROLLOVE
206 noroll1:
207 MOV SI,[DAYCNT]
208
209 ;
210 ; we now need to convert the time in tick to the time in 100th of
211 ; seconds. The relation between tick and seconds is:
212 ;
213 ; 65536 seconds
214 ; ----------------
215 ; 1,193,180 tick
216 ;
217 ; To get to 100th of second we need to multiply by 100. The equation is:
218 ;
219 ; Ticks from clock * 65536 * 100
220 ; --------------------------------- = time in 100th of seconds
221 ; 1,193,180
222 ;
223 ; Fortunately this fromula simplifies to:
224 ;
225 ; Ticks from clock * 5 * 65,536
226 ; --------------------------------- = time in 100th of seconds
227 ; 59,659
228 ;
229 ; The calculation is done by first multipling tick by 5. Next we divide by
230 ; 59,659. In this division we multiply by 65,536 by shifting the dividend
231 ; my 16 bits to the left.
232 ;
233 ; start with ticks in CX:DX
234 ; multiply by 5
235 MOV AX,CX
236 MOV BX,DX
237 SHL DX,1
238 RCL CX,1 ;TIMES 2
239 SHL DX,1
240 RCL CX,1 ;TIMES 4
241 ADD DX,BX
242 ADC AX,CX ;TIMES 5
243 XCHG AX,DX
244
245
246 ; now have ticks * 5 in DX:AX
247 ; we now need to multiply by 65,536 and divide by 59659 d.
248
249 mov CX,59659 ; get divisor
250 div CX
251 ; DX now has remainder
252 ; AX has high word of final quotient
253 mov BX,AX ; put high work if safe place
254 xor AX,AX ; this is the multiply by 65536
255 div CX ; BX:AX now has time in 100th of seconds
256
257 ;
258 ;Rounding based on the remainder may be added here
259 ;The result in BX:AX is time in 1/100 second.
260 mov DX,BX
261 mov CX,200 ;Extract 1/100's
262 ;Division by 200 is necessary to ensure no overflow--max result
263 ;is number of seconds in a day/2 = 43200.
264 div CX
265 cmp DL,100 ;Remainder over 100?
266 jb NOADJ
267 sub DL,100 ;Keep 1/100's less than 100
268 NOADJ:
269 cmc ;If we subtracted 100, carry is now set
270 mov BL,DL ;Save 1/100's
271 ;To compensate for dividing by 200 instead of 100, we now multiply
272 ;by two, shifting a one in if the remainder had exceeded 100.
273 rcl AX,1
274 mov DL,0
275 rcl DX,1
276 mov CX,60 ;Divide out seconds
277 div CX
278 mov BH,DL ;Save the seconds
279 div CL ;Break into hours and minutes
280 xchg AL,AH
281
282 ;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec)
283
284 push AX
285 MOV AX,SI ; DAYCNT
286 stosw
287 pop AX
288 stosw
289 mov AX,BX
290 stosw
291 jmp EXIT
292
293 TIM$READ ENDP
294 CODE ENDS
295 END
296 \1a