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;
5 ;*********************************************************************************** ;AN000;
7 ; IFS DOS Callback Routines ;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;
18 ;*********************************************************************************** ;AN000;
22 INCLUDE IFSFSYM
.INC ;AN000;
23 INCLUDE IFSSYM
.INC ;AN000;
24 INCLUDE DOSSYM
.INC ;AN000;
25 INCLUDE DEVSYM
.INC ;AN000;
30 AsmVars
<IBM
, INSTALLED
, DEBUG
, PATHGEN
> ;AN000;
32 IFSSEG
SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
35 include dosseg
.asm
;AN000;
37 DATA SEGMENT WORD PUBLIC 'DATA' ;AN000;
38 ; DOSGROUP data ;AN000;
44 IFSSEG
SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
45 ASSUME
SS:DOSGROUP
,CS:IFSSEG
;AN000;
49 Extrn IFSFUNC_FLAGS
:WORD ;AN000;
50 Extrn DOSCALL@
:DWORD ;AN000;
51 Extrn fAssign
:BYTE ;AN001;
52 Extrn fPrint
:BYTE ;AN001;
55 BREAK <SET_IFS_DOSCALL@
- prep for ifs dos requests to come to ifsfunc
> ;AN000;
56 ;************************************************************************************ ;AN000;
58 ; SET_IFS_DOSCALL@ ;AN000;
63 ; Routines called: ;AN000;
70 ; replace ifs_doscall@ addresses in all ifs driver headers with ;AN000;
71 ; ifsfunc address ;AN000;
76 ; Notes: all preserved ;AN000;
78 ;************************************************************************************ ;AN000;
80 procedure SET_IFS_DOSCALL@
,NEAR ;AN000;
81 ASSUME
DS:IFSSEG
;AN000;
82 TEST IFSFUNC_FLAGS
,NO_IFS_DRIVERS
;AN000;
84 transfer ifs_1000
;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;
103 CMP AX,NULL_PTR
;AN000;
107 RestoreReg
<SI,DI,ES,BX,AX> ;AN000;
110 EndProc SET_IFS_DOSCALL@
;AN000;
114 BREAK <IFSFUNC_DOSCALL@
- DOS Callbacks
> ;AN000;
115 ;************************************************************************************ ;AN000;
117 ; IFSFUNC_DOSCALL@ ;AN000;
120 ; IFS Drivers ;AN000;
122 ; Routines called: ;AN000;
126 ; SS-dosgroup ;AN000;
133 ; Notes: none preserved ;AN000;
135 ;************************************************************************************ ;AN000;
137 procedure IFSFUNC_DOSCALL@
,FAR ;AN000;
141 CALL DOS_RETURN_ASSIGN_MODE
;AN001;
142 JMP SHORT ID_1000
;AN001;
146 CALL DOS_TO_NET_DATE
;AN000;
147 JMP SHORT ID_1000
;AN000;
151 CALL NET_TO_DOS_DATE
;AN000;
152 JMP SHORT ID_1000
;AN000;
154 CALL CS:[DOSCALL@
] ;AN000;
160 EndProc IFSFUNC_DOSCALL@
;AN000;
163 BREAK <DOS_RETURN_ASSIGN_MODE
-- Return Assign Mode
> ;AN000;
165 ;************************************************************************************
167 ; DOS_RETURN_ASSIGN_MODE
169 ; Called by: IFSFUNC_DOSCALL@
171 ; Routines called: None
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
185 ; Carry clear - BH = mode (0 - off, 1 - on)
186 ; Carry set - AL error code
188 ; Notes: This routine needed only for UNC file system. This is the
189 ; only FS that supports pause.
191 ;************************************************************************************
193 Procedure DOS_RETURN_ASSIGN_MODE
,NEAR ;AN001;
194 ASSUME
DS:NOTHING
,ES:NOTHING
;AN001;
196 CMP BL,3 ; if (type == drive) ;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;
205 AND BH,1 ; return t&1; ;AN001;
206 transfer ifs_990
; go to general good ret in util ;AN001;
209 MOV AL,error_invalid_function
;AN001;
210 transfer ifs_980
; go to general bad ret in util ;AN001;
212 EndProc DOS_RETURN_ASSIGN_MODE
;AN001;
214 BREAK <DOS_TO_NET_DATE
-- Convert dos date
/time to network date
> ;AN000;
216 ;************************************************************************************
220 ; Called by: IFSFUNC_DOSCALL@
222 ; Routines called: None
225 ; DX = MS-DOS Date ;AN000;
226 ; CX = MS-DOS Time ;AN000;
228 ; Convert DOS Date Time to Network date ;AN000;
230 ; DX:CX = Seconds since 1-1-70 ;AN000;
231 ; No other registers Revised ;AN000;
233 ;************************************************************************************
235 FOURYEARS
= (3*365) + 366 ; Days in four years ;AN000;
237 procedure DOS_TO_NET_DATE
,NEAR ;AN000;
238 ASSUME
DS:NOTHING
,ES:NOTHING
;AN000;
240 OR AL,AL ; check where to get dos date/time ;AN002;
242 CallInstall DATE16
,MultDOS
,13 ; Get local date/time ;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;
262 SHR DX,CL ; Year to DL ;AN000;
263 MOV CX,DX ; Year in CX (CL) ;AN000;
265 AND DX,1FFH
; Mask off year ;AN000;
268 SHL DX,1 ; Month in DH ;AN000;
271 SHR DL,1 ; Right justify day in DL ;AN000;
272 CallInstall SetYear
,MultDOS
,27 ; Set [YEAR] and # days in FEB ;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;
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;
292 ; The following three instructions implement this: ;AN000;
294 ; CX * 15180H sec/day = (CX * 5180H) + (CX * 10000H) ;AN000;
297 MUL CX ; (DX:AX) = days * 5180h ;AN000;
298 ADD DX,CX ; (DX:AX) = days * 15180h = seconds ;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;
305 PUSH DX ; Save date seconds ;AN000;
308 SHR BX,CL ; BX is hours ;AN000;
310 MUL BX ; AX hours converted to minutes ;AN000;
311 ; 5A0H min/day so DX = 0 ;AN000;
314 AND BX,7FFH
; Mask off hours ;AN000;
316 SHR BX,CL ; BX is minutes ;AN000;
317 ADD AX,BX ; AX is minutes ;AN000;
319 MUL BX ; DX:AX is hours:min converted to sec ;AN000;
321 AND BX,1FH
; BX is seconds/2 ;AN000;
322 SHL BX,1 ; BX is seconds ;AN000;
325 MOV CX,AX ; DX:CX is DOS time in seconds ;AN000;
327 POP SI ; BX:SI is DOS Date in seconds ;AN000;
329 ADC DX,BX ; DX:CX is NET time ;AN000;
337 EndProc DOS_TO_NET_DATE
;AN000;
340 ; DX:CX = Seconds since 1-1-70 ;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;
348 ; DX = MS-DOS Date ;AN000;
349 ; CX = MS-DOS Time ;AN000;
350 ; No other registers Revised ;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;
358 ; Date is before 1-1-80 ;AN000;
359 TO_BIG_LITTLE_TIME: ;AN000;
361 MOV CX,DX ; Set 1-1-80 0:0:0 ;AN000;
365 TEST DX,8000H
; Check for high bit ;AN000;
366 JNZ TO_BIG_LITTLE_TIME
;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;
379 XCHG AX,CX ; DX:AX # seconds ;AN000;
380 MOV SI,0A8C0h ; (si) = seconds in a half day ;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;
390 DIV SI ; (AX) = 2*days ;AN000;
391 ; (CX) = half-day remainder ;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;
400 ;DX:AX is # days since 1-1-80 ;AN000;
401 ;CX:BX is seconds into that day ;AN000;
407 MOV CX,60 ; 60 sec/min ;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;
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;
419 SHR DH,CL ; High 3 bits of min to low 3 bits ;AN000;
422 SHL AL,CL ; Hours to high 5 bits ;AN000;
424 OR DH,AL ; DX is now DOS time ;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;
434 SHL AX,1 ; Mult by 8 (AX # 1/2 years) ;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;
440 ADD DX,200 ; Extra 1/2 year ;AN000;
442 CallInstall SetYear
,multDOS
,27 ;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;
450 ; DL is day, CH is month, AL is year ;AN000;
451 SHL AL,1 ; Year to high 7 bits ;AN000;
455 SHR AH,CL ; High bit of month to bit 0 ;AN000;
457 OR AH,AL ; AH is high byte of date ;AN000;
458 AND DL,1FH
; Day is low 5 bits ;AN000;
460 SHL CH,CL ; Low 3 bits of month to high 3 bits ;AN000;
463 MOV DH,AH ; Date in DX ;AN000;
464 POP CX ; Time to CX ;AN000;
473 EndProc NET_TO_DOS_DATE
;AN000;