]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / IFSFUNC / IFSFDOS.ASM
1 PAGE ,132 ; \ f ;AN000;
2 ; SCCSID = @(#)ifsfdos.asm 1.0 87/08/29 ;AN000;
3 TITLE IFSFUNC DOS CALLBACK ROUTINES - Routines for ifs ;AN000;
4 NAME IFSFDOS ;AN000;
5 ;*********************************************************************************** ;AN000;
6 ; ;AN000;
7 ; IFS DOS Callback Routines ;AN000;
8 ; ;AN000;
9 ; IFSFDOS ;AN000;
10 ; ;AN000;
11 ; REVISION HISTORY: ;AN000;
12 ; A000 - Original version 4.00 AUG 1987 DCR - 96 ;AN000;
13 ; A001 - DCR 47 Get disk/device pause status AUG '87 RG ;AN000;
14 ; A002 - PTM 2610 Time/date problems DEC '87 RG ;AN000;
15 ; ;AN000;
16 ; LOC - ;AN000;
17 ; ;AN000;
18 ;*********************************************************************************** ;AN000;
19 ;AN000;
20 .xlist ;AN000;
21 .xcref ;AN000;
22 INCLUDE IFSFSYM.INC ;AN000;
23 INCLUDE IFSSYM.INC ;AN000;
24 INCLUDE DOSSYM.INC ;AN000;
25 INCLUDE DEVSYM.INC ;AN000;
26 .cref ;AN000;
27 .list ;AN000;
28 .sall ;AN000;
29 ;AN000;
30 AsmVars <IBM, INSTALLED, DEBUG, PATHGEN> ;AN000;
31 ;AN000;
32 IFSSEG SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
33 IFSSEG ENDS ;AN000;
34 ;AN000;
35 include dosseg.asm ;AN000;
36 ;AN000;
37 DATA SEGMENT WORD PUBLIC 'DATA' ;AN000;
38 ; DOSGROUP data ;AN000;
39 Extrn YEAR:WORD
40 Extrn YRTAB:BYTE
41 Extrn MONTAB:BYTE
42 DATA ENDS ;AN000;
43 ;AN000;
44 IFSSEG SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
45 ASSUME SS:DOSGROUP,CS:IFSSEG ;AN000;
46 ;AN000;
47 ;IFS Data ;AN000;
48 ;AN000;
49 Extrn IFSFUNC_FLAGS:WORD ;AN000;
50 Extrn DOSCALL@:DWORD ;AN000;
51 Extrn fAssign:BYTE ;AN001;
52 Extrn fPrint:BYTE ;AN001;
53 ;AN000;
54 ;AN000;
55 BREAK <SET_IFS_DOSCALL@ - prep for ifs dos requests to come to ifsfunc> ;AN000;
56 ;************************************************************************************ ;AN000;
57 ; ;AN000;
58 ; SET_IFS_DOSCALL@ ;AN000;
59 ; ;AN000;
60 ;Called by: ;AN000;
61 ; IFSFUNCINIT ;AN000;
62 ; ;AN000;
63 ; Routines called: ;AN000;
64 ; none ;AN000;
65 ; ;AN000;
66 ; Inputs: ;AN000;
67 ; DS-ifsseg ;AN000;
68 ; ;AN000;
69 ; Function: ;AN000;
70 ; replace ifs_doscall@ addresses in all ifs driver headers with ;AN000;
71 ; ifsfunc address ;AN000;
72 ; ;AN000;
73 ; Outputs: ;AN000;
74 ; none ;AN000;
75 ; ;AN000;
76 ; Notes: all preserved ;AN000;
77 ; ;AN000;
78 ;************************************************************************************ ;AN000;
79 ;AN000;
80 procedure SET_IFS_DOSCALL@,NEAR ;AN000;
81 ASSUME DS:IFSSEG ;AN000;
82 TEST IFSFUNC_FLAGS,NO_IFS_DRIVERS ;AN000;
83 JZ SID_20 ;AN000;
84 transfer ifs_1000 ;AN000;
85 SID_20: ;AN000;
86 SaveReg <AX,BX,ES,DI,SI> ;AN000;
87 MOV AH,Get_In_Vars ; Get ptr to ifs hdr chain ;AN000;
88 INT 21h ; es:bx -> sysinitvars ;AN000;
89 LES DI,ES:[BX.SYSI_IFS] ; es:di -> 1st ifs driver ;AN000;
90 SaveReg <ES,DI> ;AN000;
91 LES DI,ES:[DI.IFS_DOSCALL@] ;AN000;
92 MOV WORD PTR [DOSCALL@],DI ;AN000;
93 MOV WORD PTR [DOSCALL@+2],ES ;AN000;
94 RestoreReg <DI,ES> ; 1st driver addr ;AN000;
95 MOV SI,OFFSET IFSFUNC_DOSCALL@ ;AN000;
96 SID_40: ; *** loop here on ifs_doscall@ fixing ;AN000;
97 MOV WORD PTR ES:[DI.IFS_DOSCALL@],SI ;AN000;
98 MOV WORD PTR ES:[DI.IFS_DOSCALL@+2],DS ;AN000;
99 LES DI,ES:[DI.IFS_NEXT] ; check next fs driver ;AN000;
100 CMP DI,NULL_PTR ; if ptr null, end of ifs drivers ;AN000;
101 JNE SID_40 ;AN000;
102 MOV AX,ES ;AN000;
103 CMP AX,NULL_PTR ;AN000;
104 JNE SID_40 ;AN000;
105 ;AN000;
106 SID_1000: ;AN000;
107 RestoreReg <SI,DI,ES,BX,AX> ;AN000;
108 return ;AN000;
109 ;AN000;
110 EndProc SET_IFS_DOSCALL@ ;AN000;
111 ;AN000;
112 ;AN000;
113 ;AN000;
114 BREAK <IFSFUNC_DOSCALL@ - DOS Callbacks> ;AN000;
115 ;************************************************************************************ ;AN000;
116 ; ;AN000;
117 ; IFSFUNC_DOSCALL@ ;AN000;
118 ; ;AN000;
119 ;Called by: ;AN000;
120 ; IFS Drivers ;AN000;
121 ; ;AN000;
122 ; Routines called: ;AN000;
123 ; none ;AN000;
124 ; ;AN000;
125 ; Inputs: ;AN000;
126 ; SS-dosgroup ;AN000;
127 ; ;AN000;
128 ; Function: ;AN000;
129 ; ;AN000;
130 ; Outputs: ;AN000;
131 ; none ;AN000;
132 ; ;AN000;
133 ; Notes: none preserved ;AN000;
134 ; ;AN000;
135 ;************************************************************************************ ;AN000;
136 ;AN000;
137 procedure IFSFUNC_DOSCALL@,FAR ;AN000;
138 ;AN000;
139 CMP AH,33 ;AN001;
140 JNE ID_20 ;AN000;
141 CALL DOS_RETURN_ASSIGN_MODE ;AN001;
142 JMP SHORT ID_1000 ;AN001;
143 ID_20: ;AN001;
144 CMP AH,34 ;AN000;
145 JNE ID_40 ;AN000;
146 CALL DOS_TO_NET_DATE ;AN000;
147 JMP SHORT ID_1000 ;AN000;
148 ID_40: ;AN000;
149 CMP AH,35 ;AN000;
150 JNE ID_100 ;AN000;
151 CALL NET_TO_DOS_DATE ;AN000;
152 JMP SHORT ID_1000 ;AN000;
153 ID_100: ;AN000;
154 CALL CS:[DOSCALL@] ;AN000;
155 ;AN000;
156 ID_1000: ;AN000;
157 RET ;AN000;
158 ;AN000;
159 ;AN000;
160 EndProc IFSFUNC_DOSCALL@ ;AN000;
161
162
163 BREAK <DOS_RETURN_ASSIGN_MODE -- Return Assign Mode> ;AN000;
164
165 ;************************************************************************************
166 ;
167 ; DOS_RETURN_ASSIGN_MODE
168 ;
169 ; Called by: IFSFUNC_DOSCALL@
170 ;
171 ; Routines called: None
172 ;
173 ; Inputs:
174 ; BL = macro type
175 ; 3 - device
176 ; 4 - drive
177 ; Function:
178 ; If macro type = 3 (network printer) THEN
179 ; BX = fPrint .AND. 1
180 ; Elseif macro type = 4 (network disk) THEN
181 ; BX = fAssign .AND. 1
182 ; Else set error_invalid_function
183 ;
184 ; Output:
185 ; Carry clear - BH = mode (0 - off, 1 - on)
186 ; Carry set - AL error code
187 ;
188 ; Notes: This routine needed only for UNC file system. This is the
189 ; only FS that supports pause.
190 ;
191 ;************************************************************************************
192
193 Procedure DOS_RETURN_ASSIGN_MODE,NEAR ;AN001;
194 ASSUME DS:NOTHING,ES:NOTHING ;AN001;
195 ;AN001;
196 CMP BL,3 ; if (type == drive) ;AN001;
197 JZ DRAM_20 ;AN001;
198 CMP BL,4 ;AN001;
199 JNZ DRAM_60 ;AN001;
200 MOV BH,fAssign ; t = fAssign; ;AN001;
201 JMP Short DRAM_40 ; else ;AN001;
202 DRAM_20: ; if (type == print) ;AN001;
203 MOV BH,fPrint ; t = fPrint; ;AN001;
204 DRAM_40: ;AN001;
205 AND BH,1 ; return t&1; ;AN001;
206 transfer ifs_990 ; go to general good ret in util ;AN001;
207 ;AN001;
208 DRAM_60: ;AN001;
209 MOV AL,error_invalid_function ;AN001;
210 transfer ifs_980 ; go to general bad ret in util ;AN001;
211 ;AN001;
212 EndProc DOS_RETURN_ASSIGN_MODE ;AN001;
213
214 BREAK <DOS_TO_NET_DATE -- Convert dos date/time to network date> ;AN000;
215
216 ;************************************************************************************
217 ;
218 ; DOS_TO_NET
219 ;
220 ; Called by: IFSFUNC_DOSCALL@
221 ;
222 ; Routines called: None
223 ;
224 ; Inputs: ;AN000;
225 ; DX = MS-DOS Date ;AN000;
226 ; CX = MS-DOS Time ;AN000;
227 ; Function: ;AN000;
228 ; Convert DOS Date Time to Network date ;AN000;
229 ; Outputs: ;AN000;
230 ; DX:CX = Seconds since 1-1-70 ;AN000;
231 ; No other registers Revised ;AN000;
232 ;
233 ;************************************************************************************
234
235 FOURYEARS = (3*365) + 366 ; Days in four years ;AN000;
236
237 procedure DOS_TO_NET_DATE,NEAR ;AN000;
238 ASSUME DS:NOTHING,ES:NOTHING ;AN000;
239 ;AN000;
240 OR AL,AL ; check where to get dos date/time ;AN002;
241 JNZ DTND_20 ;AN002;
242 CallInstall DATE16,MultDOS,13 ; Get local date/time ;AN000;
243 MOV CX,DX ;AN000;
244 XCHG AX,DX ;AN000;
245 ;AN000;
246 DTND_20: ;AN002;
247 PUSH DS ;AN000;
248 PUSH SS ;AN000;
249 POP DS ;AN000;
250 ASSUME DS:DOSGROUP ;AN000;
251 PUSH [YEAR] ; The routines in DOS (in particular ;AN000;
252 ; GET_DATE) do not like [YEAR] ;AN000;
253 ; getting changed by the call ;AN000;
254 ; to SETYEAR. ;AN000;
255 PUSH SI ;AN000;
256 PUSH BX ;AN000;
257 PUSH AX ;AN000;
258 PUSH CX ;AN000;
259 PUSH DX ;AN000;
260 ;AN000;
261 MOV CL,9 ;AN000;
262 SHR DX,CL ; Year to DL ;AN000;
263 MOV CX,DX ; Year in CX (CL) ;AN000;
264 POP DX ;AN000;
265 AND DX,1FFH ; Mask off year ;AN000;
266 SHL DX,1 ;AN000;
267 SHL DX,1 ;AN000;
268 SHL DX,1 ; Month in DH ;AN000;
269 SHR DL,1 ;AN000;
270 SHR DL,1 ;AN000;
271 SHR DL,1 ; Right justify day in DL ;AN000;
272 CallInstall SetYear,MultDOS,27 ; Set [YEAR] and # days in FEB ;AN000;
273 SHR CX,1 ;AN000;
274 SHR CX,1 ; Divide year by 4, chuck remainder ;AN000;
275 MOV AX,FOURYEARS ;AN000;
276 MOV BX,DX ; Get DX out of way ;AN000;
277 MUL CX ; # days in AX ;AN000;
278 MOV CL,BYTE PTR [YEAR] ;AN000;
279 AND CL,3 ; Get remainder from / by 4 ;AN000;
280 MOV SI,OFFSET DOSGROUP:YRTAB ;AN000;
281 MOV DX,AX ;AN000;
282 SHL CX,1 ; Two entries/year ;AN000;
283 CallInstall DSum,MultDOS,28,<AX>,<SI> ;AN000;
284 MOV CL,BH ; Month ;AN000;
285 DEC CX ; Make 0 indexed ;AN000;
286 MOV SI,OFFSET DOSGROUP:MONTAB ;AN000;
287 CallInstall DSum,MultDOS,28,<AX>,<AX> ;AN000;
288 MOV CL,BL ; day of month ;AN000;
289 DEC CX ; Make 0 indexed ;AN000;
290 ADD CX,DX ; CX is days since 1-1-80 ;AN000;
291 ; ;AN000;
292 ; The following three instructions implement this: ;AN000;
293 ; ;AN000;
294 ; CX * 15180H sec/day = (CX * 5180H) + (CX * 10000H) ;AN000;
295 ; ;AN000;
296 MOV AX,5180h ;AN000;
297 MUL CX ; (DX:AX) = days * 5180h ;AN000;
298 ADD DX,CX ; (DX:AX) = days * 15180h = seconds ;AN000;
299 ;AN000;
300 ADD AX,0A600H ;AN000;
301 ADC DX,012CEH ; Bias by # seconds from 1-1-70 to ;AN000;
302 ; 1-1-80 (12CEA600H) ;AN000;
303 POP BX ; Get DOS time ;AN000;
304 PUSH AX ;AN000;
305 PUSH DX ; Save date seconds ;AN000;
306 PUSH BX ;AN000;
307 MOV CL,11 ;AN000;
308 SHR BX,CL ; BX is hours ;AN000;
309 MOV AX,60 ;AN000;
310 MUL BX ; AX hours converted to minutes ;AN000;
311 ; 5A0H min/day so DX = 0 ;AN000;
312 POP BX ;AN000;
313 PUSH BX ;AN000;
314 AND BX,7FFH ; Mask off hours ;AN000;
315 MOV CL,5 ;AN000;
316 SHR BX,CL ; BX is minutes ;AN000;
317 ADD AX,BX ; AX is minutes ;AN000;
318 MOV BX,60 ;AN000;
319 MUL BX ; DX:AX is hours:min converted to sec ;AN000;
320 POP BX ;AN000;
321 AND BX,1FH ; BX is seconds/2 ;AN000;
322 SHL BX,1 ; BX is seconds ;AN000;
323 ADD AX,BX ;AN000;
324 ADC DX,0 ;AN000;
325 MOV CX,AX ; DX:CX is DOS time in seconds ;AN000;
326 POP BX ;AN000;
327 POP SI ; BX:SI is DOS Date in seconds ;AN000;
328 ADD CX,SI ;AN000;
329 ADC DX,BX ; DX:CX is NET time ;AN000;
330 POP AX ;AN000;
331 POP BX ;AN000;
332 POP SI ;AN000;
333 POP [YEAR] ;AN000;
334 POP DS ;AN000;
335 return ;AN000;
336 ;AN000;
337 EndProc DOS_TO_NET_DATE ;AN000;
338 ;AN000;
339 ; Inputs: ;AN000;
340 ; DX:CX = Seconds since 1-1-70 ;AN000;
341 ; Function: ;AN000;
342 ; Convert Network date to DOS Date Time ;AN000;
343 ; NOTE: WARNING!!!!!!! ;AN000;
344 ; This routine WILL NOT convert network times > 92CEA5FFH ;AN000;
345 ; (7FFFFFFF + 12CEA600). If such a time is encountered this ;AN000;
346 ; routine returns 1-1-80 0:0:0. ;AN000;
347 ; Outputs: ;AN000;
348 ; DX = MS-DOS Date ;AN000;
349 ; CX = MS-DOS Time ;AN000;
350 ; No other registers Revised ;AN000;
351 ;AN000;
352 procedure NET_TO_DOS_DATE,NEAR ;AN000;
353 ASSUME DS:NOTHING,ES:NOTHING ;AN000;
354 SUB CX,0A600H ;AN000;
355 SBB DX,012CEH ; UnBias by # seconds from 1-1-70 to ;AN000;
356 ; 1-1-80 (12CEA600H) ;AN000;
357 JNC GO_ON ;AN000;
358 ; Date is before 1-1-80 ;AN000;
359 TO_BIG_LITTLE_TIME: ;AN000;
360 XOR DX,DX ;AN000;
361 MOV CX,DX ; Set 1-1-80 0:0:0 ;AN000;
362 return ;AN000;
363 ;AN000;
364 GO_ON: ;AN000;
365 TEST DX,8000H ; Check for high bit ;AN000;
366 JNZ TO_BIG_LITTLE_TIME ;AN000;
367 PUSH DS ;AN000;
368 PUSH SS ;AN000;
369 POP DS ;AN000;
370 ASSUME DS:DOSGROUP ;AN000;
371 PUSH [YEAR] ; The routines in DOS (in particular ;AN000;
372 ; GET_DATE) do not like [YEAR] ;AN000;
373 ; getting changed by the call ;AN000;
374 ; to SETYEAR. ;AN000;
375 PUSH AX ;AN000;
376 PUSH BX ;AN000;
377 PUSH SI ;AN000;
378 PUSH BP ;AN000;
379 XCHG AX,CX ; DX:AX # seconds ;AN000;
380 MOV SI,0A8C0h ; (si) = seconds in a half day ;AN000;
381 ; 15180H/2 ;AN000;
382 ; ;AN000;
383 ; NOTE: The following DIV is the reason we can't convert times with the ;AN000;
384 ; high bit set (after they're unbiased by 1-1-80 - 1-1-70). ;AN000;
385 ; If we tried one it MIGHT overflow. The cutoff is ;AN000;
386 ; actually (A8C0 * FFFF) + A8BF = A8BFFFFF but we choose a smaller ;AN000;
387 ; number (7FFFFFFF) because it's easier to test for. 7FFFFFFF = ;AN000;
388 ; about 68 years from 1-1-80 which is 1-1-2048. ;AN000;
389 ; ;AN000;
390 DIV SI ; (AX) = 2*days ;AN000;
391 ; (CX) = half-day remainder ;AN000;
392 MOV BX,DX ;AN000;
393 XOR DX,DX ;AN000;
394 MOV CX,DX ;AN000;
395 SHR AX,1 ; DX:AX = days ;AN000;
396 JNC NTDD1 ; didn't shift off a bit, no extra rem ;AN000;
397 ADD BX,0A8C0h ; did shift bit, adjust remainder ;AN000;
398 ADC CX,0 ; by extra 1/2 day of seconds ;AN000;
399 ;AN000;
400 ;DX:AX is # days since 1-1-80 ;AN000;
401 ;CX:BX is seconds into that day ;AN000;
402 NTDD1: ;AN000;
403 PUSH DX ;AN000;
404 PUSH AX ;AN000;
405 MOV DX,CX ;AN000;
406 MOV AX,BX ;AN000;
407 MOV CX,60 ; 60 sec/min ;AN000;
408 DIV CX ;AN000;
409 ;AX is min, DX(DL) is secs ;AN000;
410 DIV CL ; 60 min/hr ;AN000;
411 ;AH is Min, AL is hrs ;AN000;
412 SHR DL,1 ; Div seconds by 2 ;AN000;
413 AND DL,1FH ; DL is seconds/2 ;AN000;
414 MOV DH,AH ; Copy min to DH ;AN000;
415 MOV CL,5 ;AN000;
416 SHL AH,CL ; Low 3 bits of min in high 3 bits ;AN000;
417 OR DL,AH ; DL is now low byte of time ;AN000;
418 MOV CL,3 ;AN000;
419 SHR DH,CL ; High 3 bits of min to low 3 bits ;AN000;
420 AND DH,7 ;AN000;
421 MOV CL,3 ;AN000;
422 SHL AL,CL ; Hours to high 5 bits ;AN000;
423 AND AL,0F8H ;AN000;
424 OR DH,AL ; DX is now DOS time ;AN000;
425 MOV CX,DX ;AN000;
426 POP AX ;AN000;
427 POP DX ; DX:AX days since 1-1-80 ;AN000;
428 PUSH CX ; Stash time ;AN000;
429 MOV CX,FOURYEARS ;AN000;
430 DIV CX ; AX # four year increments ;AN000;
431 ; DX remainder days ;AN000;
432 SHL AX,1 ;AN000;
433 SHL AX,1 ;AN000;
434 SHL AX,1 ; Mult by 8 (AX # 1/2 years) ;AN000;
435 MOV CX,AX ;AN000;
436 MOV SI,OFFSET DOSGROUP:YRTAB ;AN000;
437 CallInstall DSlide,MultDOS,29,<AX>,<AX> ;AN000;
438 SHR CX,1 ; 1/2 years to whole years ;AN000;
439 JNC SK ;AN000;
440 ADD DX,200 ; Extra 1/2 year ;AN000;
441 SK: ;AN000;
442 CallInstall SetYear,multDOS,27 ;AN000;
443 PUSH CX ;AN000;
444 MOV CL,1 ; At least at first month in year ;AN000;
445 MOV SI,OFFSET DOSGROUP:MONTAB ;AN000;
446 CallInstall DSlide,MultDOS,29,<AX>,<AX> ;AN000;
447 INC DX ; Days start at 1 ;AN000;
448 POP AX ;AN000;
449 MOV CH,CL ;AN000;
450 ; DL is day, CH is month, AL is year ;AN000;
451 SHL AL,1 ; Year to high 7 bits ;AN000;
452 AND AL,0FEH ;AN000;
453 MOV AH,CH ;AN000;
454 MOV CL,3 ;AN000;
455 SHR AH,CL ; High bit of month to bit 0 ;AN000;
456 AND AH,1 ;AN000;
457 OR AH,AL ; AH is high byte of date ;AN000;
458 AND DL,1FH ; Day is low 5 bits ;AN000;
459 MOV CL,5 ;AN000;
460 SHL CH,CL ; Low 3 bits of month to high 3 bits ;AN000;
461 AND CH,0E0H ;AN000;
462 OR DL,CH ;AN000;
463 MOV DH,AH ; Date in DX ;AN000;
464 POP CX ; Time to CX ;AN000;
465 POP BP ;AN000;
466 POP SI ;AN000;
467 POP BX ;AN000;
468 POP AX ;AN000;
469 POP [YEAR] ;AN000;
470 POP DS ;AN000;
471 return ;AN000;
472 ;AN000;
473 EndProc NET_TO_DOS_DATE ;AN000;
474 ;AN000;
475 IFSSEG ENDS ;AN000;
476 END ;AN000;