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;
|