summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/IFSFUNC/IFSFDOS.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/CMD/IFSFUNC/IFSFDOS.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/CMD/IFSFUNC/IFSFDOS.ASM')
-rw-r--r--v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM476
1 files changed, 476 insertions, 0 deletions
diff --git a/v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM b/v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM
new file mode 100644
index 0000000..6f3ff2d
--- /dev/null
+++ b/v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM
@@ -0,0 +1,476 @@
1 PAGE ,132 ;  ;AN000;
2; SCCSID = @(#)ifsfdos.asm 1.0 87/08/29 ;AN000;
3TITLE IFSFUNC DOS CALLBACK ROUTINES - Routines for ifs ;AN000;
4NAME 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;
22INCLUDE IFSFSYM.INC ;AN000;
23INCLUDE IFSSYM.INC ;AN000;
24INCLUDE DOSSYM.INC ;AN000;
25INCLUDE DEVSYM.INC ;AN000;
26.cref ;AN000;
27.list ;AN000;
28.sall ;AN000;
29 ;AN000;
30AsmVars <IBM, INSTALLED, DEBUG, PATHGEN> ;AN000;
31 ;AN000;
32IFSSEG SEGMENT BYTE PUBLIC 'IFSSEG' ;AN000;
33IFSSEG ENDS ;AN000;
34 ;AN000;
35include dosseg.asm ;AN000;
36 ;AN000;
37DATA SEGMENT WORD PUBLIC 'DATA' ;AN000;
38 ; DOSGROUP data ;AN000;
39 Extrn YEAR:WORD
40 Extrn YRTAB:BYTE
41 Extrn MONTAB:BYTE
42DATA ENDS ;AN000;
43 ;AN000;
44IFSSEG 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;
55BREAK <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;
81ASSUME DS:IFSSEG ;AN000;
82 TEST IFSFUNC_FLAGS,NO_IFS_DRIVERS ;AN000;
83 JZ SID_20 ;AN000;
84 transfer ifs_1000 ;AN000;
85SID_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;
96SID_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;
106SID_1000: ;AN000;
107 RestoreReg <SI,DI,ES,BX,AX> ;AN000;
108 return ;AN000;
109 ;AN000;
110EndProc SET_IFS_DOSCALL@ ;AN000;
111 ;AN000;
112 ;AN000;
113 ;AN000;
114BREAK <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;
143ID_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;
148ID_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;
153ID_100: ;AN000;
154 CALL CS:[DOSCALL@] ;AN000;
155 ;AN000;
156ID_1000: ;AN000;
157 RET ;AN000;
158 ;AN000;
159 ;AN000;
160EndProc IFSFUNC_DOSCALL@ ;AN000;
161
162
163BREAK <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;
194ASSUME 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;
202DRAM_20: ; if (type == print) ;AN001;
203 MOV BH,fPrint ; t = fPrint; ;AN001;
204DRAM_40: ;AN001;
205 AND BH,1 ; return t&1; ;AN001;
206 transfer ifs_990 ; go to general good ret in util ;AN001;
207 ;AN001;
208DRAM_60: ;AN001;
209 MOV AL,error_invalid_function ;AN001;
210 transfer ifs_980 ; go to general bad ret in util ;AN001;
211 ;AN001;
212EndProc DOS_RETURN_ASSIGN_MODE ;AN001;
213
214BREAK <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
235FOURYEARS = (3*365) + 366 ; Days in four years ;AN000;
236
237 procedure DOS_TO_NET_DATE,NEAR ;AN000;
238ASSUME 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;
246DTND_20: ;AN002;
247 PUSH DS ;AN000;
248 PUSH SS ;AN000;
249 POP DS ;AN000;
250ASSUME 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;
337EndProc 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;
353ASSUME 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;
359TO_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;
364GO_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;
370ASSUME 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;
402NTDD1: ;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;
441SK: ;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;
473EndProc NET_TO_DOS_DATE ;AN000;
474 ;AN000;
475IFSSEG ENDS ;AN000;
476END ;AN000;