summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/IFSFUNC/IFSFDOS.ASM
blob: 6f3ff2d00663d95124ca32431128efcda9cd4712 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
	PAGE	,132			; 						 ;AN000;
;	SCCSID = @(#)ifsfdos.asm	1.0 87/08/29					 ;AN000;
TITLE	IFSFUNC DOS CALLBACK ROUTINES - Routines for ifs				 ;AN000;
NAME	IFSFDOS 									 ;AN000;
;***********************************************************************************	 ;AN000;
;											 ;AN000;
; IFS DOS Callback Routines								 ;AN000;
;											 ;AN000;
; IFSFDOS										 ;AN000;
;											 ;AN000;
; REVISION HISTORY:									 ;AN000;
;	A000 - Original version 4.00	AUG 1987   DCR - 96				 ;AN000;
;	A001 - DCR 47 Get disk/device pause status AUG '87 RG                       ;AN000;
;	A002 - PTM 2610 Time/date problems	   DEC '87 RG                       ;AN000;
;											 ;AN000;
; LOC - 										 ;AN000;
;											 ;AN000;
;***********************************************************************************	 ;AN000;
											 ;AN000;
.xlist											 ;AN000;
.xcref											 ;AN000;
INCLUDE IFSFSYM.INC									 ;AN000;
INCLUDE IFSSYM.INC									 ;AN000;
INCLUDE DOSSYM.INC									 ;AN000;
INCLUDE DEVSYM.INC									 ;AN000;
.cref											 ;AN000;
.list											 ;AN000;
.sall											 ;AN000;
											 ;AN000;
AsmVars <IBM, INSTALLED, DEBUG, PATHGEN>						 ;AN000;
											 ;AN000;
IFSSEG	SEGMENT BYTE PUBLIC 'IFSSEG'                                                     ;AN000;
IFSSEG	ENDS										 ;AN000;
											 ;AN000;
include dosseg.asm									 ;AN000;
											 ;AN000;
DATA		SEGMENT WORD PUBLIC 'DATA'                                               ;AN000;
	; DOSGROUP data 								 ;AN000;
	Extrn	YEAR:WORD
	Extrn	YRTAB:BYTE
	Extrn	MONTAB:BYTE
DATA		ENDS									 ;AN000;
											 ;AN000;
IFSSEG	SEGMENT BYTE PUBLIC 'IFSSEG'                                                     ;AN000;
	ASSUME	SS:DOSGROUP,CS:IFSSEG							 ;AN000;
											 ;AN000;
	;IFS Data									 ;AN000;
											 ;AN000;
	Extrn	IFSFUNC_FLAGS:WORD							 ;AN000;
	Extrn	DOSCALL@:DWORD								 ;AN000;
	Extrn	fAssign:BYTE								 ;AN001;
	Extrn	fPrint:BYTE								 ;AN001;
											 ;AN000;
											 ;AN000;
BREAK <SET_IFS_DOSCALL@ - prep for ifs dos requests to come to ifsfunc> 		 ;AN000;
;************************************************************************************	 ;AN000;
;											 ;AN000;
; SET_IFS_DOSCALL@									 ;AN000;
;											 ;AN000;
;Called by:										 ;AN000;
;     IFSFUNCINIT									 ;AN000;
;											 ;AN000;
; Routines called:									 ;AN000;
;	none										 ;AN000;
;											 ;AN000;
; Inputs:										 ;AN000;
;	   DS-ifsseg									 ;AN000;
;											 ;AN000;
; Function:										 ;AN000;
;	replace ifs_doscall@ addresses in all ifs driver headers with			 ;AN000;
;	ifsfunc address 								 ;AN000;
;											 ;AN000;
; Outputs:										 ;AN000;
;	none										 ;AN000;
;											 ;AN000;
; Notes: all preserved									 ;AN000;
;											 ;AN000;
;************************************************************************************	 ;AN000;
											 ;AN000;
	procedure   SET_IFS_DOSCALL@,NEAR						 ;AN000;
ASSUME	DS:IFSSEG									 ;AN000;
	TEST	IFSFUNC_FLAGS,NO_IFS_DRIVERS						 ;AN000;
	JZ	SID_20									 ;AN000;
	transfer ifs_1000								 ;AN000;
SID_20: 										 ;AN000;
	SaveReg <AX,BX,ES,DI,SI>							 ;AN000;
	MOV	AH,Get_In_Vars			; Get ptr to ifs hdr chain		 ;AN000;
	INT	21h				; es:bx -> sysinitvars			 ;AN000;
	LES	DI,ES:[BX.SYSI_IFS]		; es:di -> 1st ifs driver		 ;AN000;
	SaveReg <ES,DI> 								 ;AN000;
	LES	DI,ES:[DI.IFS_DOSCALL@] 						 ;AN000;
	MOV	WORD PTR [DOSCALL@],DI							 ;AN000;
	MOV	WORD PTR [DOSCALL@+2],ES						 ;AN000;
	RestoreReg <DI,ES>			; 1st driver addr			 ;AN000;
	MOV	SI,OFFSET IFSFUNC_DOSCALL@						 ;AN000;
SID_40: 					; *** loop here on ifs_doscall@ fixing	 ;AN000;
	MOV	WORD PTR ES:[DI.IFS_DOSCALL@],SI					 ;AN000;
	MOV	WORD PTR ES:[DI.IFS_DOSCALL@+2],DS					 ;AN000;
	LES	DI,ES:[DI.IFS_NEXT]		; check next fs driver			 ;AN000;
	CMP	DI,NULL_PTR			; if ptr null, end of ifs drivers	 ;AN000;
	JNE	SID_40									 ;AN000;
	MOV	AX,ES									 ;AN000;
	CMP	AX,NULL_PTR								 ;AN000;
	JNE	SID_40									 ;AN000;
											 ;AN000;
SID_1000:										 ;AN000;
	RestoreReg <SI,DI,ES,BX,AX>							 ;AN000;
	return										 ;AN000;
											 ;AN000;
EndProc SET_IFS_DOSCALL@								 ;AN000;
											 ;AN000;
											 ;AN000;
											 ;AN000;
BREAK <IFSFUNC_DOSCALL@ - DOS Callbacks>						 ;AN000;
;************************************************************************************	 ;AN000;
;											 ;AN000;
; IFSFUNC_DOSCALL@									 ;AN000;
;											 ;AN000;
;Called by:										 ;AN000;
;     IFS Drivers									 ;AN000;
;											 ;AN000;
; Routines called:									 ;AN000;
;	none										 ;AN000;
;											 ;AN000;
; Inputs:										 ;AN000;
;	   SS-dosgroup									 ;AN000;
;											 ;AN000;
; Function:										 ;AN000;
;											 ;AN000;
; Outputs:										 ;AN000;
;	none										 ;AN000;
;											 ;AN000;
; Notes: none preserved 								 ;AN000;
;											 ;AN000;
;************************************************************************************	 ;AN000;
											 ;AN000;
	procedure   IFSFUNC_DOSCALL@,FAR						 ;AN000;
											 ;AN000;
	CMP	AH,33									 ;AN001;
	JNE	ID_20									 ;AN000;
	CALL	DOS_RETURN_ASSIGN_MODE							 ;AN001;
	JMP	SHORT ID_1000								 ;AN001;
ID_20:											 ;AN001;
	CMP	AH,34									 ;AN000;
	JNE	ID_40									 ;AN000;
	CALL	DOS_TO_NET_DATE 							 ;AN000;
	JMP	SHORT ID_1000								 ;AN000;
ID_40:											 ;AN000;
	CMP	AH,35									 ;AN000;
	JNE	ID_100									 ;AN000;
	CALL	NET_TO_DOS_DATE 							 ;AN000;
	JMP	SHORT ID_1000								 ;AN000;
ID_100: 										 ;AN000;
	CALL	CS:[DOSCALL@]							      ;AN000;
											 ;AN000;
ID_1000:										 ;AN000;
	RET										 ;AN000;
											 ;AN000;
											 ;AN000;
EndProc IFSFUNC_DOSCALL@								 ;AN000;


BREAK <DOS_RETURN_ASSIGN_MODE -- Return Assign Mode>					 ;AN000;

;************************************************************************************
;
; DOS_RETURN_ASSIGN_MODE
;
; Called by:  IFSFUNC_DOSCALL@
;
; Routines called:   None
;
; Inputs:
;	    BL = macro type
;		 3 - device
;		 4 - drive
; Function:
;	If macro type = 3 (network printer) THEN
;	   BX = fPrint .AND. 1
;	Elseif macro type = 4 (network disk) THEN
;	   BX = fAssign .AND. 1
;	Else set error_invalid_function
;
; Output:
;	Carry clear - BH = mode (0 - off, 1 - on)
;	Carry set   - AL error code
;
; Notes:  This routine needed only for UNC file system.  This is the
;	  only FS that supports pause.
;
;************************************************************************************

	Procedure   DOS_RETURN_ASSIGN_MODE,NEAR 					 ;AN001;
ASSUME	DS:NOTHING,ES:NOTHING								 ;AN001;
											 ;AN001;
	CMP	BL,3			; if (type == drive)				 ;AN001;
	JZ	DRAM_20 								 ;AN001;
	CMP	BL,4									 ;AN001;
	JNZ	DRAM_60 								 ;AN001;
	MOV	BH,fAssign		;    t = fAssign;				 ;AN001;
	JMP	Short DRAM_40		; else						 ;AN001;
DRAM_20:				; if (type == print)				 ;AN001;
	MOV	BH,fPrint		;    t = fPrint;				 ;AN001;
DRAM_40:										 ;AN001;
	AND	BH,1			;   return t&1; 				 ;AN001;
	transfer ifs_990		; go to general good ret in util		 ;AN001;
											 ;AN001;
DRAM_60:										 ;AN001;
	MOV	AL,error_invalid_function						 ;AN001;
	transfer ifs_980		; go to general bad ret in util 		 ;AN001;
											 ;AN001;
EndProc DOS_RETURN_ASSIGN_MODE								 ;AN001;

BREAK <DOS_TO_NET_DATE	-- Convert dos date/time to network date>			 ;AN000;

;************************************************************************************
;
; DOS_TO_NET
;
; Called by:  IFSFUNC_DOSCALL@
;
; Routines called:   None
;
; Inputs:										 ;AN000;
;	DX = MS-DOS Date								 ;AN000;
;	CX = MS-DOS Time								 ;AN000;
; Function:										 ;AN000;
;	Convert DOS Date Time to Network date						 ;AN000;
; Outputs:										 ;AN000;
;	DX:CX = Seconds since 1-1-70							 ;AN000;
; No other registers Revised								 ;AN000;
;
;************************************************************************************

FOURYEARS	= (3*365) + 366 	; Days in four years				 ;AN000;

	procedure DOS_TO_NET_DATE,NEAR							 ;AN000;
ASSUME	DS:NOTHING,ES:NOTHING								 ;AN000;
											 ;AN000;
	OR	AL,AL			; check where to get dos date/time		 ;AN002;
	JNZ	DTND_20 								 ;AN002;
	CallInstall DATE16,MultDOS,13	; Get local date/time				 ;AN000;
	MOV	CX,DX									 ;AN000;
	XCHG	AX,DX									 ;AN000;
											 ;AN000;
DTND_20:										 ;AN002;
	PUSH	DS									 ;AN000;
	PUSH	SS									 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	PUSH	[YEAR]			; The routines in DOS (in particular		 ;AN000;
					;	GET_DATE) do not like [YEAR]		 ;AN000;
					;	getting changed by the call		 ;AN000;
					;	to SETYEAR.				 ;AN000;
	PUSH	SI									 ;AN000;
	PUSH	BX									 ;AN000;
	PUSH	AX									 ;AN000;
	PUSH	CX									 ;AN000;
	PUSH	DX									 ;AN000;
											 ;AN000;
	MOV	CL,9									 ;AN000;
	SHR	DX,CL			; Year to DL					 ;AN000;
	MOV	CX,DX			; Year in CX (CL)				 ;AN000;
	POP	DX									 ;AN000;
	AND	DX,1FFH 		; Mask off year 				 ;AN000;
	SHL	DX,1									 ;AN000;
	SHL	DX,1									 ;AN000;
	SHL	DX,1			; Month in DH					 ;AN000;
	SHR	DL,1									 ;AN000;
	SHR	DL,1									 ;AN000;
	SHR	DL,1			; Right justify day in DL			 ;AN000;
	CallInstall SetYear,MultDOS,27	; Set [YEAR] and # days in FEB			 ;AN000;
	SHR	CX,1									 ;AN000;
	SHR	CX,1			; Divide year by 4, chuck remainder		 ;AN000;
	MOV	AX,FOURYEARS								 ;AN000;
	MOV	BX,DX			; Get DX out of way				 ;AN000;
	MUL	CX			; # days in AX					 ;AN000;
	MOV	CL,BYTE PTR [YEAR]							 ;AN000;
	AND	CL,3			; Get remainder from / by 4			 ;AN000;
	MOV	SI,OFFSET DOSGROUP:YRTAB						 ;AN000;
	MOV	DX,AX									 ;AN000;
	SHL	CX,1			; Two entries/year				 ;AN000;
	CallInstall DSum,MultDOS,28,<AX>,<SI>						 ;AN000;
	MOV	CL,BH			; Month 					 ;AN000;
	DEC	CX			; Make 0 indexed				 ;AN000;
	MOV	SI,OFFSET DOSGROUP:MONTAB						 ;AN000;
	CallInstall DSum,MultDOS,28,<AX>,<AX>						 ;AN000;
	MOV	CL,BL			; day of month					 ;AN000;
	DEC	CX			; Make 0 indexed				 ;AN000;
	ADD	CX,DX			; CX is days since 1-1-80			 ;AN000;
;											 ;AN000;
; The following three instructions implement this:					 ;AN000;
;											 ;AN000;
;		CX * 15180H sec/day = (CX * 5180H) + (CX * 10000H)			 ;AN000;
;											 ;AN000;
	MOV	AX,5180h								 ;AN000;
	MUL	CX			; (DX:AX) = days * 5180h			 ;AN000;
	ADD	DX,CX			; (DX:AX) = days * 15180h = seconds		 ;AN000;
											 ;AN000;
	ADD	AX,0A600H								 ;AN000;
	ADC	DX,012CEH		; Bias by # seconds from 1-1-70 to		 ;AN000;
					; 1-1-80 (12CEA600H)				 ;AN000;
	POP	BX			; Get DOS time					 ;AN000;
	PUSH	AX									 ;AN000;
	PUSH	DX			; Save date seconds				 ;AN000;
	PUSH	BX									 ;AN000;
	MOV	CL,11									 ;AN000;
	SHR	BX,CL			; BX is hours					 ;AN000;
	MOV	AX,60									 ;AN000;
	MUL	BX			; AX hours converted to minutes 		 ;AN000;
					;    5A0H min/day so DX = 0			 ;AN000;
	POP	BX									 ;AN000;
	PUSH	BX									 ;AN000;
	AND	BX,7FFH 		; Mask off hours				 ;AN000;
	MOV	CL,5									 ;AN000;
	SHR	BX,CL			; BX is minutes 				 ;AN000;
	ADD	AX,BX			; AX is minutes 				 ;AN000;
	MOV	BX,60									 ;AN000;
	MUL	BX			; DX:AX is hours:min converted to sec		 ;AN000;
	POP	BX									 ;AN000;
	AND	BX,1FH			; BX is seconds/2				 ;AN000;
	SHL	BX,1			; BX is seconds 				 ;AN000;
	ADD	AX,BX									 ;AN000;
	ADC	DX,0									 ;AN000;
	MOV	CX,AX			; DX:CX is DOS time in seconds			 ;AN000;
	POP	BX									 ;AN000;
	POP	SI			; BX:SI is DOS Date in seconds			 ;AN000;
	ADD	CX,SI									 ;AN000;
	ADC	DX,BX			; DX:CX is NET time				 ;AN000;
	POP	AX									 ;AN000;
	POP	BX									 ;AN000;
	POP	SI									 ;AN000;
	POP	[YEAR]									 ;AN000;
	POP	DS									 ;AN000;
	return										 ;AN000;
											 ;AN000;
EndProc DOS_TO_NET_DATE 								 ;AN000;
											 ;AN000;
; Inputs:										 ;AN000;
;	DX:CX = Seconds since 1-1-70							 ;AN000;
; Function:										 ;AN000;
;	Convert Network date to DOS Date Time						 ;AN000;
;    NOTE: WARNING!!!!!!!								 ;AN000;
;	This routine WILL NOT convert network times > 92CEA5FFH 			 ;AN000;
;	(7FFFFFFF + 12CEA600). If such a time is encountered this			 ;AN000;
;	routine returns 1-1-80 0:0:0.							 ;AN000;
; Outputs:										 ;AN000;
;	DX = MS-DOS Date								 ;AN000;
;	CX = MS-DOS Time								 ;AN000;
; No other registers Revised								 ;AN000;
											 ;AN000;
	procedure NET_TO_DOS_DATE,NEAR							 ;AN000;
ASSUME	DS:NOTHING,ES:NOTHING								 ;AN000;
	SUB	CX,0A600H								 ;AN000;
	SBB	DX,012CEH		; UnBias by # seconds from 1-1-70 to		 ;AN000;
					; 1-1-80 (12CEA600H)				 ;AN000;
	JNC	GO_ON									 ;AN000;
	; Date is before 1-1-80 							 ;AN000;
TO_BIG_LITTLE_TIME:									 ;AN000;
	XOR	DX,DX									 ;AN000;
	MOV	CX,DX	; Set 1-1-80 0:0:0						 ;AN000;
	return										 ;AN000;
											 ;AN000;
GO_ON:											 ;AN000;
	TEST	DX,8000H		; Check for high bit				 ;AN000;
	JNZ	TO_BIG_LITTLE_TIME							 ;AN000;
	PUSH	DS									 ;AN000;
	PUSH	SS									 ;AN000;
	POP	DS									 ;AN000;
ASSUME	DS:DOSGROUP									 ;AN000;
	PUSH	[YEAR]			; The routines in DOS (in particular		 ;AN000;
					;	GET_DATE) do not like [YEAR]		 ;AN000;
					;	getting changed by the call		 ;AN000;
					;	to SETYEAR.				 ;AN000;
	PUSH	AX									 ;AN000;
	PUSH	BX									 ;AN000;
	PUSH	SI									 ;AN000;
	PUSH	BP									 ;AN000;
	XCHG	AX,CX			; DX:AX # seconds				 ;AN000;
	MOV	SI,0A8C0h		; (si) = seconds in a half day			 ;AN000;
					;    15180H/2					 ;AN000;
;											 ;AN000;
; NOTE: The following DIV is the reason we can't convert times with the                  ;AN000;
;	high bit set (after they're unbiased by 1-1-80 - 1-1-70).                        ;AN000;
;	If we tried one it MIGHT overflow. The cutoff is				 ;AN000;
;	actually (A8C0 * FFFF) + A8BF = A8BFFFFF but we choose a smaller		 ;AN000;
;	number (7FFFFFFF) because it's easier to test for. 7FFFFFFF =                    ;AN000;
;	about 68 years from 1-1-80 which is 1-1-2048.					 ;AN000;
;											 ;AN000;
	DIV	SI			; (AX) = 2*days 				 ;AN000;
					; (CX) = half-day remainder			 ;AN000;
	MOV	BX,DX									 ;AN000;
	XOR	DX,DX									 ;AN000;
	MOV	CX,DX									 ;AN000;
	SHR	AX,1			; DX:AX = days					 ;AN000;
	JNC	NTDD1			; didn't shift off a bit, no extra rem           ;AN000;
	ADD	BX,0A8C0h		; did shift bit, adjust remainder		 ;AN000;
	ADC	CX,0			;   by extra 1/2 day of seconds 		 ;AN000;
											 ;AN000;
	;DX:AX is # days since 1-1-80							 ;AN000;
	;CX:BX is seconds into that day 						 ;AN000;
NTDD1:											 ;AN000;
	PUSH	DX									 ;AN000;
	PUSH	AX									 ;AN000;
	MOV	DX,CX									 ;AN000;
	MOV	AX,BX									 ;AN000;
	MOV	CX,60			; 60 sec/min					 ;AN000;
	DIV	CX									 ;AN000;
	;AX is min, DX(DL) is secs							 ;AN000;
	DIV	CL			; 60 min/hr					 ;AN000;
	;AH is Min, AL is hrs								 ;AN000;
	SHR	DL,1			; Div seconds by 2				 ;AN000;
	AND	DL,1FH			; DL is seconds/2				 ;AN000;
	MOV	DH,AH			; Copy min to DH				 ;AN000;
	MOV	CL,5									 ;AN000;
	SHL	AH,CL			; Low 3 bits of min in high 3 bits		 ;AN000;
	OR	DL,AH			; DL is now low byte of time			 ;AN000;
	MOV	CL,3									 ;AN000;
	SHR	DH,CL			; High 3 bits of min to low 3 bits		 ;AN000;
	AND	DH,7									 ;AN000;
	MOV	CL,3									 ;AN000;
	SHL	AL,CL			; Hours to high 5 bits				 ;AN000;
	AND	AL,0F8H 								 ;AN000;
	OR	DH,AL			; DX is now DOS time				 ;AN000;
	MOV	CX,DX									 ;AN000;
	POP	AX									 ;AN000;
	POP	DX			; DX:AX days since 1-1-80			 ;AN000;
	PUSH	CX			; Stash time					 ;AN000;
	MOV	CX,FOURYEARS								 ;AN000;
	DIV	CX			; AX # four year increments			 ;AN000;
					; DX remainder days				 ;AN000;
	SHL	AX,1									 ;AN000;
	SHL	AX,1									 ;AN000;
	SHL	AX,1			; Mult by 8 (AX # 1/2 years)			 ;AN000;
	MOV	CX,AX									 ;AN000;
	MOV	SI,OFFSET DOSGROUP:YRTAB						 ;AN000;
	CallInstall DSlide,MultDOS,29,<AX>,<AX> 					 ;AN000;
	SHR	CX,1			; 1/2 years to whole years			 ;AN000;
	JNC	SK									 ;AN000;
	ADD	DX,200			; Extra 1/2 year				 ;AN000;
SK:											 ;AN000;
	CallInstall SetYear,multDOS,27							 ;AN000;
	PUSH	CX									 ;AN000;
	MOV	CL,1			; At least at first month in year		 ;AN000;
	MOV	SI,OFFSET DOSGROUP:MONTAB						 ;AN000;
	CallInstall DSlide,MultDOS,29,<AX>,<AX> 					 ;AN000;
	INC	DX			; Days start at 1				 ;AN000;
	POP	AX									 ;AN000;
	MOV	CH,CL									 ;AN000;
	; DL is day, CH is month, AL is year						 ;AN000;
	SHL	AL,1			; Year to high 7 bits				 ;AN000;
	AND	AL,0FEH 								 ;AN000;
	MOV	AH,CH									 ;AN000;
	MOV	CL,3									 ;AN000;
	SHR	AH,CL			; High bit of month to bit 0			 ;AN000;
	AND	AH,1									 ;AN000;
	OR	AH,AL			; AH is high byte of date			 ;AN000;
	AND	DL,1FH			; Day is low 5 bits				 ;AN000;
	MOV	CL,5									 ;AN000;
	SHL	CH,CL			; Low 3 bits of month to high 3 bits		 ;AN000;
	AND	CH,0E0H 								 ;AN000;
	OR	DL,CH									 ;AN000;
	MOV	DH,AH			; Date in DX					 ;AN000;
	POP	CX			; Time to CX					 ;AN000;
	POP	BP									 ;AN000;
	POP	SI									 ;AN000;
	POP	BX									 ;AN000;
	POP	AX									 ;AN000;
	POP	[YEAR]									 ;AN000;
	POP	DS									 ;AN000;
	return										 ;AN000;
											 ;AN000;
EndProc NET_TO_DOS_DATE 								 ;AN000;
											 ;AN000;
IFSSEG	ENDS										 ;AN000;
END											 ;AN000;