summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSCLOCK.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/BIOS/MSCLOCK.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/BIOS/MSCLOCK.ASM')
-rw-r--r--v4.0/src/BIOS/MSCLOCK.ASM296
1 files changed, 296 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/MSCLOCK.ASM b/v4.0/src/BIOS/MSCLOCK.ASM
new file mode 100644
index 0000000..5d66d03
--- /dev/null
+++ b/v4.0/src/BIOS/MSCLOCK.ASM
@@ -0,0 +1,296 @@
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
42HaveCMOSClock db 0 ;set by MSINIT.
43 public base_century
44base_century db 19
45 public base_year
46base_year db 80
47 public month_tab
48month_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
54BinToBCD dw 0 ;should point to Bin_To_BCD proc in MSINIT
55 public DaycntToDay
56DaycntToDay 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
63TimeToTicks 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
82TIM$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
106No_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
127No_CMOS_2:
128 jmp EXIT
129TIM$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;
139public time_to_ticks
140TIME_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
183TIME_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
198TIM$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
206noroll1:
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
268NOADJ:
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
293TIM$READ ENDP
294CODE ENDS
295 END
296 \ No newline at end of file