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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / CHKDSK / CHKINIT.ASM
1 page ,132 ;\ f
2 ;*****************************************************************************
3 ;*****************************************************************************
4 ;UTILITY NAME: CHKOVER.COM
5 ;
6 ;MODULE NAME: CHKINIT.SAL
7 ;
8 ;ÚÄÄÄÄÄÄÄÄÄÄÄ¿
9 ;³ Main_Init ³
10 ;ÀÄÂÄÄÄÄÄÄÄÄÄÙ
11 ; ³
12 ; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
13 ; ôInit_Input_OutputÃÄÄÄÄ´Preload_Messages³
14 ; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
15 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
16 ; ³ ôParse_Drive_Letter ³
17 ; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
18 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
19 ; ³ ôParse_Command_Line ³
20 ;; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
21 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
22 ; ³ À´Interpret_Parse³
23 ; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
24 ; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
25 ; ôValidate_Target_DriveôCheck_Target_Drive³
26 ; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
27 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
28 ; ³ ôCheck_For_Network³
29 ; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
30 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
31 ; ³ À´Check_Translate_Drive³
32 ; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
33 ; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
34 ; ôHook_Interrupts³
35 ; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
36 ; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
37 ; ôClear_Append_X³
38 ; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
39 ; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
40 ; ôCHKDSK_IFSôEXEC_FS_CHKDSK³
41 ; ³ÀÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
42 ; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
43 ; ³ À´Main_Routine³
44 ; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
45 ; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
46 ; À´Reset_Append_X³
47 ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
48 ;*****************************************************************************
49 ;;an099;dcl for p3202
50 ;*****************************************************************************
51
52 ;
53 ;*****************************************************************************
54 ; Include files
55 ;*****************************************************************************
56 .xlist ;an000;bgb
57 include chkseg.inc ;an005;bgb ;an000;bgb
58 include pathmac.inc ;an000;bgb
59 INCLUDE CHKEQU.INC ; ;an000;bgb;AN000;
60 INCLUDE CHKCHNG.INC ;List of changes ;an000;bgb
61 include dossym.inc ;an000;bgb
62 INCLUDE SYSCALL.INC ; ;an000;bgb;AN000;
63 INCLUDE CHKMACRO.INC ; ;an000;bgb;AN000;
64 INCLUDE CHKPARSE.INC ; ;an000;bgb;AN000;
65 INCLUDE IOCTL.INC ;an000;bgb
66 .list ;an000;bgb
67 ;an000;bgb
68 ;an000;bgb
69 ;an000;bgb
70 psp segment public para 'DUMMY' ;an000;bgb
71 org 05Ch ;an000;bgb
72 FCB1 label byte ;an000;bgb
73 org 06Ch ;an000;bgb
74 FCB2 label byte ;an000;bgb
75 psp ends ;an000;bgb
76 ;an000;bgb
77 ; ;an000;bgb
78 DATA segment public para 'DATA' ;an000;bgb
79 ;***************************************************************************** ;an000;bgb
80 ; Data Area ;an000;bgb
81 ;***************************************************************************** ;an000;bgb
82 old_drive db 0 ;an000;bgb
83
84 include version.inc
85
86 IF IBMCOPYRIGHT
87
88 ELSE
89
90 myramdisk db 'RDV 1.20'
91
92 ENDIF
93
94 myvdisk db 'VDISK' ;an000;bgb
95 bytes_per_sector dw 0 ;an005;bgb ;an000;bgb
96 BPB_Buffer A_DeviceParameters <> ; ;an000;bgb;AN000;
97 ;an000;bgb
98 Data_Start_Low dw ? ; ;an000;bgb;AN000;
99 Data_Start_High dw ? ; ;an000;bgb
100 ;an000;bgb
101 public command_line_buffer ;an046;bgb
102 Command_Line_Buffer db 128 dup(0) ; ;an000;bgb;AN000;
103 Command_Line_Length equ $ - Command_Line_Buffer ; ;an000;bgb;AN000;
104 ;an046;bgb
105 Fatal_Error db 0 ; ;an000;bgb;AN000;
106 ;an000;bgb
107 Command_Line db NO ; ;an000;bgb
108 Append db 0 ; ;an000;bgb
109 ;an000;bgb
110 ifdef fsexec ;an038;bgb
111 ;These should stay together ; ;an038;bgb
112 ; --------------------------------------- ; ; ;an038;bgb
113 FS_String_Buffer db 13 dup(" ") ; ;an038;bgb
114 FS_String_End db "CHK.EXE",0 ; ;an038;bgb
115 Len_FS_String_End equ $ - FS_String_End ; ;an038;bgb
116 ;---------------------------------------- ; ;an038;bgb
117 FS_Not_Fat db 0 ; ;an038;bgb
118 FAT12_String db "FAT12 " ; ;an038;bgb
119 FAT16_String db "FAT16 " ; ;an038;bgb
120 Len_FS_ID_String equ $ - FAT16_String ; ;an038;bgb
121 Media_ID_Buffer Media_ID <> ; ;an038;bgb
122 endif ;an038;bgb
123
124 ExitStatus db 0 ; ;an000;bgb;AN000;
125 ;an000;bgb
126 PSP_Segment dw 0 ; ;an000;bgb;AN000;
127 tot_bytes_lo dw 0 ; low word of number of sectors in disk ;an000;bgb;an006;bgb
128 tot_bytes_hi dw 0 ;high word of number of sectors in disk ;an000;bgb;an006;bgb
129 fat_dir_secs dw 0 ;sectors in fat, directory and resvd ;an000;bgb;an006;bgb
130 ;an000;bgb
131 ;***************************************************************************** ;an000;bgb
132 ; Public Data Declarations ;an000;bgb
133 ;***************************************************************************** ;an000;bgb
134 public bpb_buffer ;an000;bgb;an006;bgb
135 public tot_bytes_lo ;an000;bgb;an006;bgb
136 public tot_bytes_hi ;an000;bgb;an006;bgb
137 public fat_dir_secs ;an000;bgb;an006;bgb
138 public bytes_per_sector ;an000;bgb;an005;bgb
139 Public Data_Start_Low ;an000;bgb
140 Public Data_Start_High ;an000;bgb
141 Public Fatal_Error ;an000;bgb
142 Public ExitStatus ;an000;bgb
143 Public PSP_Segment ;an000;bgb
144 ifdef fsexec ;an038;bgb
145 Public FS_String_Buffer ;an038;bgb
146 endif ;an038;bgb
147 ; ;an000;bgb
148 ;***************************************************************************** ;an000;bgb
149 ; External Data Declarations ;an000;bgb
150 ;***************************************************************************** ;an000;bgb
151 EXTRN movsi:word ;move si pointer here for display of invalid parm ;an046;bgb;an000;bgb;an005;bgb
152 EXTRN fatcnt:Byte ;an000;bgb;an005;bgb
153 EXTRN AllDrv:Byte ;an000;bgb
154 EXTRN VolNam:Byte ;an000;bgb
155 EXTRN BadDrvM:Byte ;an000;bgb
156 EXTRN OrphFCB:Byte ;an000;bgb
157 EXTRN Arg_Buf:Byte ;an000;bgb
158 EXTRN Noisy:Byte ;an000;bgb
159 EXTRN DoFix:Byte ;an000;bgb
160 EXTRN SubstErr:Byte ;an000;bgb
161 EXTRN No_Net_Arg:Byte ;an000;bgb
162 EXTRN UserDev:Byte ;an000;bgb
163 EXTRN BadDrv_Arg:Byte ;an000;bgb
164 EXTRN TranSrc:Byte ;an000;bgb
165 EXTRN ContCh:Word ;an000;bgb
166 EXTRN HardCh:Word ;an000;bgb
167 EXTRN Fragment:Byte ;an000;bgb
168 EXTRN Parse_Error_Msg:Byte ;an000;bgb
169 EXTRN Chkprmt_End:Byte ;an000;bgb
170 extrn save_drive:byte ;an000;bgb
171 EXTRN Read_Write_Relative:Byte ;an000;bgb
172 EXTRN inval_media:byte ;an000;bgb;an033;bgb
173 data ends ;an000;bgb
174 ;an000;bgb
175 ;an000;bgb
176 code segment public para 'CODE' ;an000;bgb
177 ;***************************************************************************** ;an000;bgb
178 ; External Routine Declarations ;an000;bgb
179 ;***************************************************************************** ;an000;bgb
180 ifdef fsexec ;an038;bgb
181 EXTRN Exec_FS_CHKDSK:Near ;an000;bgb
182 endif
183 EXTRN SysLoadMsg:Near ;an000;bgb
184 EXTRN SysDispMsg:Near ;an000;bgb
185 EXTRN Done:Near ;an000;bgb
186 EXTRN Main_Routine:Near ;an000;bgb
187 EXTRN INT_23:Near ;an000;bgb
188 EXTRN INT_24:Near ;an000;bgb
189 EXTRN Path_Name:Near ;an000;bgb
190 extrn read_once:near ;an000;bgb
191
192 public p97, multiply_32_bits ;an000;bgb
193 public func60 ;an000;bgb
194 public hook_interrupts ;an000;bgb
195 public get_bpb ;an000;bgb
196
197 pathlabl chkinit ;an000;bgb
198 ;***************************************************************************** ;an000;bgb
199 ;Routine name: Main_Init ;an000;bgb
200 ;***************************************************************************** ;an000;bgb
201 ; ;an000;bgb
202 ;Description: Main control routine for init section ;an000;bgb
203 ; ;an000;bgb
204 ;Called Procedures: Check_DOS_Version ;an000;bgb
205 ; Init_Input_Output ;an000;bgb
206 ; Validate_Target_Drive ;an000;bgb
207 ; Hook_Interrupts ;an000;bgb
208 ; Clear_Append_X ;an000;bgb
209 ; CHKDSK_IFS ;an000;bgb
210 ; Reset_Append_X ;an000;bgb
211 ; ;an000;bgb
212 ;Input: None ;an000;bgb
213 ; ;an000;bgb
214 ;Output: None ;an000;bgb
215 ; ;an000;bgb
216 ;Change History: Created 5/8/87 MT ;an000;bgb
217 ; ;an000;bgb
218 ;Psuedocode ;an000;bgb
219 ;---------- ;an000;bgb
220 ; ;an000;bgb
221 ; Set segregs to DATA ;an000;bgb
222 ; Get segment of PSP ;an000;bgb
223 ; Fatal_Error = NO ;an000;bgb
224 ; Flush all buffers (INT 21h AH=0Dh) ;an000;bgb
225 ; Parse input and load messages (CALL Init_Input_Output) ;an000;bgb
226 ; IF !Fatal_Error ;an000;bgb
227 ; Check target drive letter (CALL Validate_Target_Drive) ;an000;bgb
228 ; IF !Fatal_Error ;an000;bgb
229 ; Set up Control Break (CALL Hook_Interrupts) ;an000;bgb
230 ; IF !Fatal_Error ;an000;bgb
231 ; CALL Clear_Append_X ;an000;bgb
232 ; CALL CHKDSK_IFS ;an000;bgb
233 ; CALL Reset_Append_X ;an000;bgb
234 ; ENDIF ;an000;bgb
235 ; ENDIF ;an000;bgb
236 ; ENDIF ;an000;bgb
237 ; Exit program ;an000;bgb
238 ;***************************************************************************** ;an000;bgb
239 ;an000;bgb
240 Procedure Main_Init ; ;an000;bgb;AN000;
241 Set_Data_Segment ;Setup addressibility ;an000;bgb;AN000;
242 call get_psp ;an000;bgb
243 ;;;;;;;;DOS_Call GetCurrentPSP ;Get PSP segment address ;an000;bgb;ac034;bgb
244 ;;;;;;;;mov PSP_Segment,bx ;Save it for later ;an000;bgb;ac034;bgb
245 mov Fatal_Error,No ;Init the error flag ;an000;bgb;AN000;
246 Dos_Call Disk_Reset ;Flush all buffers ;an000;bgb
247 call Init_IO ;Setup messages and parse ;an000;bgb;AN000;
248 cmp Fatal_Error,Yes ;Error occur? ;an000;bgb;AN000;
249 ; $IF NE ;Nope, keep going ;an000;bgb;AN000;
250 JE $$IF1
251 call Validate_Target_Drive ;Check drive letter ;an000;bgb;AN000;
252 cmp Fatal_Error,Yes ;Error occur? ;an000;bgb;AN000;
253 ; $IF NE ;Nope, keep going ;an000;bgb;AN000;
254 JE $$IF2
255 ;;;;;;;;;;;;;;call Hook_Interrupts ;Set CNTRL -Break hook ;an000;bgb;AN000;
256 call Clear_Append_X ; ;an000;bgb;AN000;
257 call CHKDSK_IFS ;Chkdsk correct file system ;an000;bgb;AN000;
258 call Reset_Append_X ; ;an000;bgb;AN000;
259 ; $ENDIF ; ;an000;bgb;AN000;
260 $$IF2:
261 ; $ENDIF ; ;an000;bgb;AN000;
262 $$IF1:
263 mov al,ExitStatus ;Get Errorlevel ;an000;bgb;AN000;
264 DOS_Call Exit ;Exit program ;an000;bgb;AN000;
265 int 20h ;If other exit fails ;an000;bgb;AN000;
266 Main_Init endp ; ;an000;bgb;AN000;
267 ;an000;bgb
268 ;***************************************************************************** ;an000;bgb
269 ;Routine name: get_psp ;an000;bgb
270 ;***************************************************************************** ;an000;bgb
271 ;Description: get info from the psp area ;an000;bgb
272 ; ;an000;bgb
273 ;Called Procedures: get_drive ;an000;bgb
274 ; ;an000;bgb
275 ;Change History: Created 8/7/87 bgb ;an000;bgb
276 ; ;an000;bgb
277 ;Input: none ;an000;bgb
278 ; ;an000;bgb
279 ;Output: psp_segment ;an000;bgb
280 ; command_line_buffer ;an000;bgb
281 ; ;an000;bgb
282 ;Psuedocode ;an000;bgb
283 ;---------- ;an000;bgb
284 ; get addr of psp ;an000;bgb
285 ; move command line into data seg ;an000;bgb
286 ; get drive number of target ;an000;bgb
287 ; get addr of data seg ;an000;bgb
288 ; call get_drive ;an000;bgb
289 ; ret ;an000;bgb
290 ;***************************************************************************** ;an000;bgb
291 Procedure get_psp ;;AN000; ;an000;bgb
292 ;;;;;;;;DOS_Call GetCurrentPSP ;Get PSP segment address :AN035;b;an000;bgbgb
293 ;;;;;;;;mov PSP_Segment,bx ;Save it for later ;AN035;b;an000;bgbgb
294 ; get command line from psp ;an000;bgb;AN000;bgb
295 mov cx,PSP_Segment ;point ds to data seg ;an000;bgb;AN000;bgb
296 mov ds,cx ; " " " " " ;an000;bgb;AN000;bgb
297 assume ds:NOTHING,es:dg ; " " " " " ;an000;bgb;AN000;bgb
298 ; get the drive number of the target from the psp (0=default, a=1, b=2, c=3) ;AN;an000;bgb000;bgb
299 mov bl,ds:[FCB1] ;Get target drive from FCB -74 ;AN0;an000;bgb00;
300 Set_Data_Segment ;Set DS,ES to Data segment ;AN0;an000;bgb00;bgb
301 call get_drive ;an000;bgb
302 ret ;an000;bgb
303 get_psp endp ; ;AN000; ;an000;bgb
304 ;an000;bgb
305 ;an000;bgb
306 ;***************************************************************************** ;an000;bgb
307 ;Routine name: get_drive ;an000;bgb
308 ;***************************************************************************** ;an000;bgb
309 ;Description: get drive letter from reg bl ;an000;bgb
310 ; ;an000;bgb
311 ;Change History: Created 8/7/87 bgb ;an000;bgb
312 ; ;an000;bgb
313 ;Input: bl = drive num (default=0) ;an000;bgb
314 ; ;an000;bgb
315 ;Output: driveletter ;an000;bgb
316 ; user_drive ;an000;bgb
317 ; ;an000;bgb
318 ;Psuedocode ;an000;bgb
319 ;---------- ;an000;bgb
320 ; IF drive-num = default ;an000;bgb
321 ; get default drive number (a=1) ;an000;bgb
322 ; convert to letter ;an000;bgb
323 ; ELSE ;an000;bgb
324 ; convert to letter ;an000;bgb
325 ; ENDIF ;an000;bgb
326 ; move letter into data areas ;an000;bgb
327 ; ret ;an000;bgb
328 ;***************************************************************************** ;an000;bgb
329 Procedure get_drive ;;AN000; ;an000;bgb
330 ; convert drive number to drive letter ;an000;bgb
331 cmp bl,0 ;a=1 b=2 c=3 ;Is it default drive? 0=default ;AN000; ;an000;bgb
332 ; $IF E ;Yes, turn it into drive letter ;AN000; ;an000;bgb
333 JNE $$IF5
334 ; get default drive number ;an000;bgb
335 DOS_Call Get_Default_Drive ;Get default drive num in al ;AN00;an000;bgb0;
336 ;a=0, b=1, c=2 ;an000;bgb
337 ; $ELSE ;Not default, A=1 ;AN000; ;an000;bgb
338 JMP SHORT $$EN5
339 $$IF5:
340 ; bl already contains the correct drive number - save it ;an000;bgb
341 dec bl ;make it zero based ;an000;bgb
342 mov al,bl ;an000;bgb
343 ; $ENDIF ; 74+40=b4 ;an000;bgb
344 $$EN5:
345 mov BadDrvm+1,al ; " " " " ;an000;bgb ;AN000;
346 inc al ;an000;bgb
347 mov byte ptr Buffer.drnum_stroff,al ; ;an000;bgb ;
348 mov AllDrv,al ; ;an000;bgb ;AC000;
349 mov VolNam,al ; ;an000;bgb ;AC000;
350 mov OrphFCB,al ; ;an000;bgb ;AC000;
351 dec al ;an000;bgb
352 add al,"A" ;convert it to letter ;AN000; ;an000;bgb
353 mov arg_buf,al ;set up prompt msg ;AN0;an000;bgb00;bgb
354 ret ;an000;bgb
355 get_drive endp ; ;AN000; ;an000;bgb
356 ;an000;bgb
357 ;***************************************************************************** ;an000;bgb
358 ;Routine name: Init_Input_Output ;an000;bgb
359 ;***************************************************************************** ;an000;bgb
360 ; ;an000;bgb
361 ;description: Initialize messages, Parse command line if FAT file system ;an000;bgb
362 ; ;an000;bgb
363 ;Called Procedures: Preload_Messages ;an000;bgb
364 ; Parse_Command_Line ;an000;bgb
365 ; ;an000;bgb
366 ;Change History: Created 5/10/87 MT ;an000;bgb
367 ; ;an000;bgb
368 ;Input: PSP command line at 81h and length at 80h ;an000;bgb
369 ; ;an000;bgb
370 ;Output: FS_Not_FAT = YES/NO ;an000;bgb
371 ; ;an000;bgb
372 ;Psuedocode ;an000;bgb
373 ;---------- ;an000;bgb
374 ; ;an000;bgb
375 ; FS_Not_FAT = NO ;an000;bgb
376 ; Load messages (CALL Preload_Messages) ;an000;bgb
377 ; IF !Fatal_Error ;an000;bgb
378 ; Get file system type (INT 21h AX=440Dh, CX=084Eh GET MEDIA_ID) ;an000;bgb
379 ; IF CY (Old type diskette),OR ;an000;bgb
380 ; IF "FAT_12 ",OR ;an000;bgb
381 ; IF "FAT_16 " ;an000;bgb
382 ; CALL Parse_Command_Line ;an000;bgb
383 ; IF !Fatal_Error ;an000;bgb
384 ; Interpret_Parse ;an000;bgb
385 ; ENDIF ;an000;bgb
386 ; ELSE ;an000;bgb
387 ; Get drive letter only (CALL Parse_Drive_Letter) ;an000;bgb
388 ; FS_Not_FAT = YES ;an000;bgb
389 ; ENDIF ;an000;bgb
390 ; ENDIF ;an000;bgb
391 ; ret ;an000;bgb
392 ;***************************************************************************** ;an000;bgb
393 ;an000;bgb
394 Procedure Init_IO ; ;AN000; ;an000;bgb
395 ;an000;bgb
396 call Preload_Messages ;Load up message retriever ;an000;bgb;AN000;
397 ifdef fsexec ;an038;bgb
398 mov FS_Not_FAT,No ;an038;bgb
399 cmp Fatal_Error,YES ;Quit? ;an038;bgb;AN000;
400 ; $IF NE ;Nope, keep going ;an038;bgb;AN000;
401 JE $$IF8
402 mov al,GENERIC_IOCTL ;Generic IOCtl call ;an038;bgb;AN000;
403 push ds ; ;an038;bgb;AN000;
404 mov bx,PSP_Segment ; ;an038;bgb;AN000;
405 mov ds,bx ; ;an038;bgb;AN000;
406 assume ds:nothing ; ;an038;bgb;AN000;
407 ;an038;bgb
408 mov bl,ds:FCB1 ;Get drive (A=1) ;an038;bgb;AN000;
409 ;an038;bgb
410 pop ds ; ;an038;bgb;AN000;
411 assume ds:dg ; ;an038;bgb;AN000;
412 xor bh,bh ;Set bh=0 ;an038;bgb;AN000;
413 mov ch,RawIO ;Get Media ID call ;an038;bgb;AN000;
414 mov cl,GET_MEDIA_ID ; ;an038;bgb;AN000;
415 lea dx,Media_ID_Buffer ;Point at buffer ;an038;bgb;AN000;
416 DOS_Call IOCtl ;Do function call ;an038;bgb;AN000;
417 ; $IF C,OR ;Old style diskette, OR ;an038;bgb;AN000;
418 JC $$LL9
419 lea si,FAT12_String ;Check for FAT_12 string ;an038;bgb;AN000;
420 lea di,Media_ID_Buffer.Media_ID_File_System ; ;AN000;;an038;bgb
421 mov cx,Len_FS_ID_String ;Length of compare ;an038;bgb;AN000;
422 repe cmpsb ;Find it? ;an038;bgb;AN000;
423 ; $IF E,OR ;Nope, keep going ;an038;bgb;AN000;
424 JE $$LL9
425 lea si,FAT16_String ;Check for FAT_16 string ;an038;bgb;AN000;
426 lea di,Media_ID_Buffer.Media_ID_File_System ; ;AN000;;an038;bgb
427 mov cx,Len_FS_ID_String ;Length of compare ;an038;bgb;AN000;
428 repe cmpsb ;Do compare ;an038;bgb;AN000;
429 ; $IF E ;Find it? ;an038;bgb;AN000;
430 JNE $$IF9
431 $$LL9:
432 endif ;an038;bgb
433 call Parse_Command_Line ;Parse in command line input ;an038;bgb;AN000;
434 ifdef fsexec ;an038;bgb
435 ; $ELSE ;We got FS other than FAT ;an038;bgb;AN000;
436 JMP SHORT $$EN9
437 $$IF9:
438 ;;;;;;;;;;;;;;call Parse_Drive_Letter ;Only look for drive letter ;an038;bgb;AN000;
439 mov FS_Not_FAT,Yes ;Indicate exec file system ;an038;bgb;AN000;
440 mov cx,8 ;an038;bgb;an027;bgb
441 lea si,Media_ID_Buffer.Media_ID_File_System ;get file system;an038;bgb ;an027;bgb
442 lea di,fs_string_buffer ;put it here ;an038;bgb;an027;bgb
443 rep movsb ;an038;bgb;an027;bgb
444 lea di,fs_string_buffer ;point to beginning again ;an038;bgb;an027;bgb
445 ; $DO COMPLEX ;search th string until eol found ;an038;bgb;an027;bgb
446 JMP SHORT $$SD11
447 $$DO11:
448 inc di ;next char ;an038;bgb;an027;bgb
449 ; $STRTDO ;start loop here ;an038;bgb;an027;bgb
450 $$SD11:
451 cmp byte ptr [di],' ' ;end of string ? ;an038;bgb;an027;bgb
452 ; $ENDDO E ;end loop when eol found ;an038;bgb;an027;bgb
453 JNE $$DO11
454 lea si,fs_string_end ;get end of string - rec.exe ;an038;bgb;an027;bgb
455 mov cx,8 ; 8 more chars ;an038;bgb;an027;bgb
456 rep movsb ;move it in ;an038;bgb;an027;bgb
457 ; $ENDIF ; ;an038;bgb;AN000;
458 $$EN9:
459 ; $ENDIF ; ;an038;bgb;AN000;
460 $$IF8:
461 endif ;an038;bgb
462 ret ; ;an000;bgb;AN000;
463 ;an000;bgb
464 Init_IO endp ; ;AN000; ;an000;bgb
465 ;an000;bgb
466 ;***************************************************************************** ;an000;bgb
467 ;Routine name: Preload_Messages ;an000;bgb
468 ;***************************************************************************** ;an000;bgb
469 ; ;an000;bgb
470 ;Description: Preload messages using common message retriever routines. ;an000;bgb
471 ; ;an000;bgb
472 ;Called Procedures: SysLoadMsg ;an000;bgb
473 ; ;an000;bgb
474 ; ;an000;bgb
475 ;Change History: Created 5/1/87 MT ;an000;bgb
476 ; ;an000;bgb
477 ;Input: Fatal_Error = NO ;an000;bgb
478 ; ;an000;bgb
479 ;Output: Fatal_Error = YES/NO ;an000;bgb
480 ; ;an000;bgb
481 ;Psuedocode ;an000;bgb
482 ;---------- ;an000;bgb
483 ; ;an000;bgb
484 ; Preload All messages (Call SysLoadMsg) ;an000;bgb
485 ; IF error ;an000;bgb
486 ; Display SysLoadMsg error message ;an000;bgb
487 ; Fatal_Error = YES ;an000;bgb
488 ; ENDIF ;an000;bgb
489 ; ret ;an000;bgb
490 ;***************************************************************************** ;an000;bgb
491 ;an000;bgb
492 Procedure Preload_Messages ; ;an000;bgb;AN000;
493 ; ;an000;bgb
494 call SysLoadMsg ;Preload the messages ;an000;bgb;AN000;
495 ; $IF C ;Error? ;an000;bgb;AN000;
496 JNC $$IF16
497 call SysDispMsg ;Display preload msg ;an000;bgb;AN000;
498 mov Fatal_Error, YES ;Indicate error exit ;an000;bgb;AN000;
499 ; $ENDIF ; ;an000;bgb;AN000;
500 $$IF16:
501 ret ; ;an000;bgb;AN000;
502 ;an000;bgb
503 Preload_Messages endp ; ;an000;bgb;AN000;
504 ;an000;bgb
505 ;***************************************************************************** ;an000;bgb
506 ;Routine name: Parse_Drive_Letter ;an000;bgb
507 ;***************************************************************************** ;an000;bgb
508 ; ;an000;bgb
509 ;Description: Copy the command line - then parse looking only for drive ;an000;bgb
510 ; letter. Ignore errors, because this is only called to get ;an000;bgb
511 ; the drive letter for non-FAT chkdsk ;an000;bgb
512 ; ;an000;bgb
513 ;Called Procedures: SysParse ;an000;bgb
514 ; ;an000;bgb
515 ;Change History: Created 5/12/87 MT ;an000;bgb
516 ; ;an000;bgb
517 ;Input: Command line input at 81h ;an000;bgb
518 ; ;an000;bgb
519 ;Output: None ;an000;bgb
520 ; ;an000;bgb
521 ; ;an000;bgb
522 ;Psuedocode ;an000;bgb
523 ;---------- ;an000;bgb
524 ; Copy command line to buffer ;an000;bgb
525 ; DO ;an000;bgb
526 ; Parse buffer line (CALL SysParse) using drive letter only tables ;an000;bgb
527 ; LEAVE end of parse ;an000;bgb
528 ; ENDDO missing operand ;an000;bgb
529 ; ret ;an000;bgb
530 ;***************************************************************************** ;an000;bgb
531 ;an000;bgb
532 ;Procedure Parse_Drive_Letter ; ;an000;bgb;AN000;
533 ; Set_Data_Segment ;Set DS,ES to Data segment ;an000;bgb;AN000;
534 ; mov cx,PSP_Segment ;Get segment of PSP ;an000;bgb;AN000;
535 ; mov ds,cx ; " " " " ;an000;bgb;AN000;
536 ; assume ds:nothing ; ;an000;bgb;AN000;
537 ; mov si,Command_Line_Parms ;Point to command line ;an000;bgb;AN000;
538 ; lea di,Command_Line_Buffer ;Point to buffer to save to ;an000;bgb;AN000;
539 ; mov cx,Command_Line_Length ;Number of bytes to move ;an000;bgb;AN000;
540 ; rep movsb ;Copy the entire buffer ;an000;bgb;AN000;
541 ; Set_Data_Segment ; ;an000;bgb;AN000;
542 ; lea si,Command_Line_Buffer ;Pointer to parse line ;an000;bgb;AN000;
543 ; lea di,input_table ;Pointer to control table ;an000;bgb;AN000;
544 ; $DO ;Parse for drive letter ;an000;bgb;AN000;
545 ; xor dx,dx ;Parse line @SI ;an000;bgb;AN000;
546 ; xor cx,cx ;Parse table @DI ;an000;bgb;AN000;
547 ; call SysParse ;Go parse ;an000;bgb;AN000;
548 ; cmp ax,End_Of_Parse ;Check for end of parse ;an000;bgb;AN000;
549 ; $LEAVE E ;In other words, no drive letter;an000;bgb;AN000;
550 ; cmp ax,Operand_Missing ; exit if positional missing ;an000;bgb;AN000;
551 ; $ENDDO E ;Ignore errors!!! ;an000;bgb;AN000;
552 ; Set_Data_Segment ; ;an000;bgb;AN000;
553 ; ret ; ;an000;bgb;AN000;
554 ; ;an000;bgb
555 ;Parse_Drive_Letter endp ; ;an000;bgb;AN000;
556 ;an000;bgb
557 ;***************************************************************************** ;an000;bgb
558 ;Routine name: Parse_Command_Line ;an000;bgb
559 ;***************************************************************************** ;an000;bgb
560 ; ;an000;bgb
561 ;Description: Parse the command line. Check for errors, and display error and ;an000;bgb
562 ; exit program if found. Use parse error messages except in case ;an000;bgb
563 ; of no parameters, which has its own message ;an000;bgb
564 ; ;an000;bgb
565 ;Called Procedures: Message (macro) ;an000;bgb
566 ; SysParse ;an000;bgb
567 ; Interpret_Parse ;an000;bgb
568 ; ;an000;bgb
569 ;Change History: Created 5/1/87 MT ;an000;bgb
570 ; ;an000;bgb
571 ;Input: Fatal_Error = NO ;an000;bgb
572 ; PSP_Segment ;an000;bgb
573 ; ;an000;bgb
574 ;Output: Fatal_Error = YES/NO ;an000;bgb
575 ; Parse output buffers set up ;an000;bgb
576 ; ;an000;bgb
577 ; ;an000;bgb
578 ;Psuedocode ;an000;bgb
579 ;---------- ;an000;bgb
580 ; SEARCH ;an000;bgb
581 ; Parse command line (CALL SysParse) ;an000;bgb
582 ; EXITIF end of parsing command line ;an000;bgb
583 ; Figure out last thing parsed (Call Interpret_Parse) ;an000;bgb
584 ; ORELSE ;an000;bgb
585 ; See if parse error ;an000;bgb
586 ; ENDLOOP parse error ;an000;bgb
587 ; See what was parsed (Call Interpret_Parse) ;an000;bgb
588 ; Fatal_Error = YES ;an000;bgb
589 ; ENDSRCH ;an000;bgb
590 ; ret ;an000;bgb
591 ;***************************************************************************** ;an000;bgb
592 ;an000;bgb
593 Procedure Parse_Command_Line ; ;an000;bgb;AN000;
594 ;an000;bgb
595 push ds ;Save data segment ;an000;bgb;AN000;
596 Set_Data_Segment ; ;an000;bgb;AN000;
597 mov cx,PSP_Segment ;Get segment of PSP ;an000;bgb;AN000;
598 mov ds,cx ; " " " " ;an000;bgb;AN000;
599 ;an000;bgb
600 assume ds:nothing,es:dg ; ;an000;bgb;AN000;
601 ;an000;bgb
602 mov si,Command_Line_Parms ;Point at command line ;an000;bgb;AN000;
603 lea di,Command_Line_Buffer ;Where to put a copy of it ;an000;bgb;AN000;
604 mov cx,Command_Line_Length ;How long was input? ;an000;bgb;AN000;
605 repnz movsb ;Copy it ;an000;bgb;AN000;
606 lea Di,Command_Line_Buffer ; ;an046;bgb
607 public nextdi ;an046;bgb
608 nextdi: ;an046;bgb
609 mov al,0dh ;search for end of line ;an046;bgb
610 cmp al,ES:[Di] ;zero terminate string ;an046;bgb
611 ; $IF NZ ;an046;bgb
612 JZ $$IF18
613 inc di ;an046;bgb
614 jmp nextdi ;an046;bgb
615 ; $ELSE ;an046;bgb
616 JMP SHORT $$EN18
617 $$IF18:
618 mov byte ptr ES:[di+1],00 ;an046;bgb
619 ; $ENDIF ;an046;bgb
620 $$EN18:
621 ;an046;bgb
622 Set_Data_Segment ;Set DS,ES to Data segment ;an000;bgb;AN000;
623 xor cx,cx ; ;an000;bgb;AN000;
624 xor dx,dx ;Required for SysParse call ;;an000;bgbAN000;
625 lea si,Command_Line_Buffer ;Pointer to parse line ;an000;bgb ;AN000;
626 lea di,input_table ;Pointer to control table ;an000;bgb ;AN000;
627 ; $SEARCH ;Loop until all parsed ;an000;bgb;AN000;
628 $$DO21:
629 cmp Fatal_Error,Yes ;Interpret something bad? ;an000;bgb;AN000;
630 ; $EXITIF E,OR ;If so, don't parse any more ;an000;bgb;AN000;
631 JE $$LL22
632 call SysParse ;Go parse ;an000;bgb;AN000;
633 cmp ax,End_Of_Parse ;Check for end of parse ;an000;bgb;AN000;
634 ; $EXITIF E ;Is it? ;an000;bgb;AN000;
635 JNE $$IF21
636 $$LL22:
637 ;All done ;an000;bgb;AN000;
638 ; $ORELSE ;Not end ;an000;bgb;AN000;
639 JMP SHORT $$SR21
640 $$IF21:
641 cmp ax,0 ;Check for parse error ;an000;bgb;AN000;
642 ; $LEAVE NE ;Stop if there was one ;an000;bgb;AN000;
643 JNE $$EN21
644 call Interpret_Parse ;Go find what we parsed ;an000;bgb;AN000;
645 ; $ENDLOOP ;Parse error, see what it was ;an000;bgb;AN000;
646 JMP SHORT $$DO21
647 $$EN21:
648
649 dec si ;point to last byte of invalid parm
650 public decsi
651 decsi: cmp byte ptr [si],' ' ;are we pointing to a space? ;an046;bgb
652 ; $IF E,OR ;if so, we dont want to do that
653 JE $$LL26
654 cmp byte ptr [si],0dh ;are we pointing to CR? ;an046;bgb
655 ; $IF E ;if so, we dont want to do that
656 JNE $$IF26
657 $$LL26:
658 dec si ;find the last byte of parm
659 jmp decsi
660 ; $ENDIF
661 $$IF26:
662 mov byte ptr [si+1],00 ;zero terminate display string ;an046;bgb
663 nextsi:
664 public nextsi
665 dec si ;look at previous char ;an046;bgb
666 cmp byte ptr [si],' ' ;find parm separator ;an046;bgb
667 jnz nextsi ;loop until begin of parm found
668 mov movsi,si ;mov si into display parms ;an046;bgb
669 PARSE_MESSAGE ;Display parse error ;an000;bgb;AN000;
670 mov Fatal_Error,YES ;Indicate death! ;an000;bgb;AN000;
671 ; $ENDSRCH ; ;an000;bgb;AN000;
672 $$SR21:
673 pop ds ; ;an000;bgb;AN000;
674 ret ; ;an000;bgb;AN000;
675 ;an000;bgb
676 Parse_Command_Line endp ; ;an000;bgb;AN000;
677 ;an000;bgb
678 ;***************************************************************************** ;an000;bgb
679 ;Routine name: Interpret_Parse ;an000;bgb
680 ;***************************************************************************** ;an000;bgb
681 ; ;an000;bgb
682 ;description: Get any switches entered, and dr ;an000;bgb
683 ; ;an000;bgb
684 ; ;an000;bgb
685 ;Called Procedures: Message (macro) ;an000;bgb
686 ; ;an000;bgb
687 ;Change History: Created 5/1/87 MT ;an000;bgb
688 ; ;an000;bgb
689 ;Input: DS:DrNum (FCB at 5Ch) ;an000;bgb
690 ; ;an000;bgb
691 ;Output: Noisy = ON/OFF ;an000;bgb
692 ; DoFix = ON/OFF ;an000;bgb
693 ; ALLDRV = Target drive, A=1 ;an000;bgb
694 ; VOLNAM = Target drive, A=1 ;an000;bgb
695 ; ORPHFCB = Target drive, A=1 ;an000;bgb
696 ; BADDRVm+1 = Target drive, A=0 ;an000;bgb
697 ; Arg_Buf = Target drive letter ;an000;bgb
698 ; Fragment > 1 if filespec entered ;an000;bgb
699 ; ;an000;bgb
700 ;Psuedocode ;an000;bgb
701 ;---------- ;an000;bgb
702 ; ;an000;bgb
703 ; Noisy = OFF ;an000;bgb
704 ; DoFix = OFF ;an000;bgb
705 ; IF /V ;an000;bgb
706 ; Noisy = ON ;an000;bgb
707 ; ENDIF ;an000;bgb
708 ; IF /F ;an000;bgb
709 ; DoFix = ON ;an000;bgb
710 ; ENDIF ;an000;bgb
711 ; IF file spec entered ;an000;bgb
712 ; Build filename ;an000;bgb
713 ; Fragment = 1 ;an000;bgb
714 ; ENDIF ;an000;bgb
715 ; ret ;an000;bgb
716 ;***************************************************************************** ;an000;bgb
717 ;an000;bgb
718 Procedure Interpret_Parse ; ;an000;bgb;AN000;
719 ;an000;bgb
720 push ds ;Save segment ;an000;bgb;AN000;
721 push si ;Restore SI for parser ;an000;bgb;AN000;
722 push cx ; ;an000;bgb;AN000;
723 push di ; ;an000;bgb
724 Set_Data_Segment ; ;an000;bgb
725 cmp byte ptr Buffer.dfType,Type_Drive ;Have drive letter? ;AN000; ;an000;bgb
726 ; $IF E ;Yes, save info ;an000;bgb;AN000;
727 JNE $$IF29
728 and word ptr dfcontrol,filespec ;dont let another drive letter ;an000;bgb
729 mov al,byte ptr Buffer.Drnum_stroff ;Get drive entered ;;an000;bgbAN000;
730 mov AllDrv,al ; ;an000;bgb;AC000;
731 mov VolNam,al ; ;an000;bgb;AC000;
732 mov OrphFCB,al ; ;an000;bgb;AC000;
733 dec al ;Make it 0 based ;an000;bgb;AN000;
734 mov BadDrvm+1,al ; " " " " ;an000;bgb;AN000;
735 add al,'A' ;Make it a drive letter ;an000;bgb;AN000;
736 mov Arg_Buf,al ;Save it ;an000;bgb;AN000;
737 ; $ENDIF ; ;an000;bgb;AN000;
738 $$IF29:
739 cmp SwBuffer.Switch_Pointer,offset Sw_v ;AN020;;an000;bgbbgb
740 ; $IF E ; ;an000;bgb;AN000;
741 JNE $$IF31
742 mov Noisy,ON ;Set flag ;an000;bgb;AC000;
743 mov byte ptr sw_v,blank ;an000;bgb;an020;bgb
744 ; $ENDIF ; ;an000;bgb;AN000;
745 $$IF31:
746 cmp SwBuffer.Switch_Pointer,offset sw_f ;AN020;;an000;bgbbgb
747 ; $IF E ; ;an000;bgb;AN000;
748 JNE $$IF33
749 mov DoFix,ON ;Set flag ;an000;bgb;AC000;
750 mov byte ptr sw_f,blank ;;an000;bgban020;bgb
751 ; $ENDIF ; ;an000;bgb;AN000;
752 $$IF33:
753 ;;;;;;; cmp FileSpec_Buffer.FileSpec_Pointer,offset FileSpec_Control.Keyword;an000;bgb ;AN000;
754 cmp buffer.dftype, type_filespec ;an000;bgb
755 ; $IF E ; ;an000;bgb;AN000;
756 JNE $$IF35
757 mov word ptr dfcontrol,0 ;dont let another drive letter or filesp;an000;bgbec
758 mov si,Buffer.drnum_StrOff ; ;AN000; ;an000;bgb
759 lea di,Path_Name ;Point to where to build path ;an000;bgb;AN000;
760 cld ;SI-DI dir is up ;an000;bgb;AN000;
761 ; $DO ;Move string one char at a time ;an000;bgb;AN000;
762 $$DO36:
763 cmp byte ptr [si],Asciiz_End ;Is it the end? ;an000;bgb;AN000;
764 ; $LEAVE E ;You got it ;an000;bgb;AN000;
765 JE $$EN36
766 movsb ;Nope, move the character ;an000;bgb;AN000;
767 ; $ENDDO ;And keep crusin ;an000;bgb;AN000;
768 JMP SHORT $$DO36
769 $$EN36:
770 inc fragment ;To be compat with old code ;an000;bgb;AN000;
771 ; $ENDIF ; ;an000;bgb;AN000;
772 $$IF35:
773 pop di ;Restore parse regs ;an000;bgb;AN000;
774 pop cx ; ;an000;bgb;AN000;
775 pop si ; ;an000;bgb;AN000;
776 pop ds ; ;an000;bgb;AN000;
777 ret ; ;an000;bgb;AN000;
778 ;an000;bgb
779 ;an000;bgb
780 Interpret_Parse endp ; ;an000;bgb;AN000;
781 ;an000;bgb
782 ;an000;bgb
783 ;an000;bgb
784 ;***************************************************************************** ;an000;bgb
785 ;Routine name: Validate_Target_Drive ;an000;bgb
786 ;***************************************************************************** ;an000;bgb
787 ; ;an000;bgb
788 ;Description: Control routine for validating the specified format target drive. ;an000;bgb
789 ; If any of the called routines find an error, they will print ;an000;bgb
790 ; message and terminate program, without returning to this routine ;an000;bgb
791 ; ;an000;bgb
792 ;Called Procedures: Check_Target_Drive ;an000;bgb
793 ; Check_For_Network ;an000;bgb
794 ; Check_Translate_Drive ;an000;bgb
795 ; ;an000;bgb
796 ;Change History: Created 5/1/87 MT ;an000;bgb
797 ; ;an000;bgb
798 ;Input: Fatal_Error = NO ;an000;bgb
799 ; ;an000;bgb
800 ;Output: Fatal_Error = YES/NO ;an000;bgb
801 ; ;an000;bgb
802 ;Psuedocode ;an000;bgb
803 ;---------- ;an000;bgb
804 ; ;an000;bgb
805 ; CALL Check_Target_Drive ;an000;bgb
806 ; IF !Fatal_Error ;an000;bgb
807 ; CALL Check_For_Network ;an000;bgb
808 ; IF !Fatal_Error ;an000;bgb
809 ; CALL Check_Translate_Drive ;an000;bgb
810 ; ENDIF ;an000;bgb
811 ; ENDIF ;an000;bgb
812 ; ret ;an000;bgb
813 ;***************************************************************************** ;an000;bgb
814 ;an000;bgb
815 Procedure Validate_Target_Drive ; ;an000;bgb;AN000;
816 call Check_For_Network ;See if Network drive letter ;an000;;an043;bgbbgb;AN000;
817 cmp Fatal_Error,YES ;Can we continue? ;an0;an043;bgb00;bgb;AN000;
818 ; $IF NE ;Yep ;an0;an043;bgb00;bgb;AN000;
819 JE $$IF40
820 call Check_Target_Drive ;See if valid drive letter ;an000;bgb;AN000;
821 cmp Fatal_Error,YES ;Can we continue? ;an000;bgb;AN000;
822 ; $IF NE ;Yep ;an000;bgb;AN000;
823 JE $$IF41
824 call Check_For_Network ;See if Network drive letter ;an000;bgb;AN000;
825 cmp Fatal_Error,YES ;Can we continue? ;an000;bgb;AN000;
826 ; $IF NE ;Yep ;an000;bgb;AN000;
827 JE $$IF42
828 call Check_Translate_Drive ;See if Subst, Assigned ;an000;bgb;AN000;
829 ; $ENDIF ;- Fatal_Error passed back ;an000;bgb;AN000;
830 $$IF42:
831 ; $ENDIF ; ;an000;bgb;AN000;
832 $$IF41:
833 ; $ENDIF ;an000;bgb
834 $$IF40:
835 ret ; ;an000;bgb;AN000;
836 ;an000;bgb
837 Validate_Target_Drive endp ; ;an000;bgb;AN000;
838 ;an000;bgb
839 ;***************************************************************************** ;an000;bgb
840 ;Routine name: Check_Target_Drive ;an000;bgb
841 ;***************************************************************************** ;an000;bgb
842 ; ;an000;bgb
843 ;Description: Check to see if valid DOS drive by checking if drive is ;an000;bgb
844 ; removable. If error, the drive is invalid. Save default ;an000;bgb
845 ; drive info. Also get target drive BPB information, and compute ;an000;bgb
846 ; the start of the data area ;an000;bgb
847 ; ;an000;bgb
848 ;Called Procedures: Message (macro) ;an000;bgb
849 ; ;an000;bgb
850 ;Change History: Created 5/1/87 MT ;an000;bgb
851 ; ;an000;bgb
852 ;Input: Fatal_Error = NO ;an000;bgb
853 ; ;an000;bgb
854 ;Output: BIOSFile = default drive letter ;an000;bgb
855 ; DOSFile = default drive letter ;an000;bgb
856 ; CommandFile = default drive letter ;an000;bgb
857 ; Fatal_Error = YES/NO ;an000;bgb
858 ; ;an000;bgb
859 ;Psuedocode ;an000;bgb
860 ;---------- ;an000;bgb
861 ; ;an000;bgb
862 ; Get default drive (INT 21h, AH = 19h) ;an000;bgb
863 ; Convert it to drive letter ;an000;bgb
864 ; Save into BIOSFile,DOSFile,CommandFile ;an000;bgb
865 ; See if drive removable (INT 21h, AX=4409h IOCtl) ;an000;bgb
866 ; IF error - drive invalid ;an000;bgb
867 ; Display Invalid drive message ;an000;bgb
868 ; Fatal_Error= YES ;an000;bgb
869 ; ENDIF ;an000;bgb
870 ; Get BPB of target drive (Generic IOCtl Get Device parameters) ;an000;bgb
871 ; Compute start of data area ;an000;bgb
872 ; ret ;an000;bgb
873 ;***************************************************************************** ;an000;bgb
874 Procedure Check_Target_Drive ; ;an000;bgb;AN000;
875 call func60 ; ;an000;bgb
876 mov al,save_drive ;an000;bgb
877 cmp al,0ffh ;save drive spec ;an000;bgb
878 ; $IF E ;an000;bgb
879 JNE $$IF46
880 Message BadDrv_Arg ;Print message ;an000;bgb;AC000;
881 mov Fatal_Error,Yes ;Indicate error ;an000;bgb;AN000;
882 jmp Exit_Baddrv ;dont do rest of proc ;an000;bgb;an021;bgb;an099;
883 ; $ENDIF ;an000;bgb
884 $$IF46:
885 DOS_Call Get_Default_Drive ;Find the current drive 19 ;an000;bgb;AC000;
886 mov UserDev,al ;Save it ;an000;bgb; ;
887 cmp AllDrv,0 ;Was drive entered? ;an000;bgb;AN002;
888 ; $IF E ;No ;an000;bgb;AN002;
889 JNE $$IF48
890 mov BadDrvm+1,al ;Save 0 based number ;an000;bgb;AN002;
891 inc al ;Make 1 based ;an000;bgb;AN002;
892 mov byte ptr Buffer.Drnum_stroff,al ; ;an000;bgb ;
893 mov AllDrv,al ;Use default drive for ;an000;bgb;AN002;
894 mov VolNam,al ;entries for drive fields ;an000;bgb;AN002;
895 mov OrphFCB,al ; ;an000;bgb;AN002;
896 add al,'A'-1 ;Make it a drive letter ;an000;bgb;AN002;
897 mov Arg_Buf,al ;Save it ;an000;bgb;AN002;
898 ; $ENDIF ; ;an000;bgb;AN002;
899 $$IF48:
900 mov bl,alldrv ;Get drive number (A=1) ;AN00;an044;bgb;an000;bgb0;
901 mov al,09h ;See if drive is local ;an000;bgb;AC000;
902 DOS_Call IOCtl ;-this will fail if bad drive ;an000;bgb;AC000;
903 ; $IF C ;CY means invalid drive ;an000;bgb;AC000;
904 JNC $$IF50
905 Message BadDrv_Arg ;Print message ;an000;bgb;AC015;bgb
906 mov Fatal_Error,Yes ;Indicate error ;an000;bgb;AN015;bgb
907 ; $ENDIF ; ;an000;bgb;AN000;
908 $$IF50:
909 cmp fatal_error,no ;an000;bgb
910 ; $IF E ;an000;bgb
911 JNE $$IF52
912 get_bpb: mov al,GENERIC_IOCTL ;Get BPB information ;an000;bgb ;AN000;
913 mov ch,RawIO ; " " " " ;an000;bgb ;AN000;
914 mov cl,GET_DEVICE_PARAMETERS ; ;an000;bgb ;AN000;
915 mov bl,AllDrv ; " " " " ;an000;bgb ;AN000;
916 lea dx,BPB_Buffer ; dx points to bpb area ;an000;bgb ;AN000;
917 mov byte ptr bpb_buffer, 0ffh ;turn bit 0 on to get bpb inf;an000;bgbo of disk ;an008;bgb
918 DOS_Call IOCtl ; " " " " ;an000;bgb ;AN000;
919 mov bx,dx ;use bx as the pointer to bpb;an000;bgb ;an015;bgb
920 ; $IF C ;is ioct not supported or bad? ;an000;bgb ;an015;bgb
921 JNC $$IF53
922 mov al,BadDrvm+1 ; drive number a=0 ;an000;bgb ;AN015;bgb
923 lea bx,chkprmt_end ; transfer address es:bx ;an000;bgb ;an015;bgb
924 ;warning! this label must be the last in the code segment ;an000;bgb
925 mov cx,1 ; 1 sector - boot record ;an000;bgb ;an015;bgb
926 mov dx,0 ; logical sector 0 ;an000;bgb ;an015;bgb
927 mov Read_Write_Relative.Start_Sector_High,0 ; ;an000;bgb ;an015;bgb
928 call read_once ;an000;bgb ;an015;bgb
929 ; $IF C ;couldnt read the boot? ;an000;bgb ;an015;bgb
930 JNC $$IF54
931 Message BadDrv_Arg ;Print message ;an000;bgb ;AC015;bgb
932 mov Fatal_Error,Yes ;Indicate error ;an000;bgb ;AN015;bgb
933 ; $ELSE ;ioct not supported - is it vdisk ;an000;bgb ;an015;bgb
934 JMP SHORT $$EN54
935 $$IF54:
936 ; mov di,bx ;an000;bgb;an022;bgb
937 ; add di,3 ;es:di --> to vdisk area in boot rcd ;an000;bgb;an022;bgb
938 ; lea si,myvdisk ;ds:si --> proper vdisk string ;an000;bgb;an022;bgb
939 ; mov cx,5 ; compare 5 bytes ;an000;bgb;an022;bgb
940 ; repe cmpsb ;compare both strings ;an000;bgb;an022;bgb
941 IF IBMCOPYRIGHT
942 ; $IF NE ;an000;bgb;an022;bgb
943 ; jmp baddrv ;an000;bgb
944 ; $ENDIF ;an000;bgb;an022;bgb
945 ELSE
946 ; $IF NE
947 mov di,bx
948 add di,3
949 lea si,myramdisk
950 mov cx,8
951 repe cmpsb
952
953 ; $IF NE
954 JE $$IF56
955 jmp baddrv
956 ; $ENDIF
957 $$IF56:
958 ; $ENDIF
959 ENDIF
960 ; $ENDIF ;an000;bgb;an022;bgb
961 $$EN54:
962 add bx,4 ;boot-record-offset - device-paramete;an000;bgbr offset ;an015;bgb
963 ; $ENDIF ;an000;bgb ;an015;bgb
964 $$IF53:
965 ; $ENDIF ;an000;bgb
966 $$IF52:
967 cmp fatal_error,no ;an000;bgb
968 ; $IF E ;an000;bgb
969 JNE $$IF61
970 call get_boot_info ;an053;bgb
971 call calc_space ;an000;bgb
972 ; $ENDIF ;an000;bgb
973 $$IF61:
974 cmp bytes_per_sector,0 ;an000;bgb;an033;bgb
975 ; $IF E ;an000;bgb;an033;bgb
976 JNE $$IF63
977 baddrv: mov fatal_error,yes ;an000;bgb;an033;bgb
978 mov dx,offset dg:inval_media ;an000;bgb;an033;bgb
979 invoke printf_crlf ;an000;bgb;an033;bgb
980 ; $ENDIF ;an000;bgb;an033;bgb
981 $$IF63:
982 Exit_Baddrv: ;AN099;
983 ret ;And we're outa here ;an000;bgb;AN000;
984 Check_Target_Drive endp ; ;an000;bgb;AN000;
985 ;an000;bgb
986 ;an000;bgb
987
988 ;****************************************************************************** ;an053;bgb;an000;bgb
989 ; get_boot_info ;an053;bgb
990 ; ;an053;bgb
991 ; ;an053;bgb;an000;bgb
992 ; Inputs : none ;an053;bgb;an000;bgb
993 ; ;an053;bgb;an000;bgb
994 ; Outputs : ;an053;bgb
995 ;****************************************************************************** ;an053;bgb;an000;bgb
996 Procedure get_boot_info ; ;an053;bgb;an000;bgb
997 mov cx,[bx].BytePerSector ; usually 512 ;an053;bgb;an000;bgb ;an015;bgb
998 cmp cx,512 ;vdisk sizes ;an053;bgb
999 ; $IF NE,AND ;vdisk sizes ;an053;bgb
1000 JE $$IF65
1001 cmp cx,256 ;vdisk sizes ;an053;bgb
1002 ; $IF NE,AND ;vdisk sizes ;an053;bgb
1003 JE $$IF65
1004 cmp cx,128 ;vdisk sizes ;an053;bgb
1005 ; $IF NE ;vdisk sizes ;an053;bgb
1006 JE $$IF65
1007 jmp baddrv ;an053;bgb
1008 ; $ENDIF ;an053;bgb
1009 $$IF65:
1010 mov bytes_per_sector,cx ; ; ;an053;bgb;an000;bgb ;an005;bgb
1011 ;an053;bgb
1012 xor cx,cx ;Find # sectors used by FA;an053;bgb;an000;bgbT's ;AN000;
1013 mov cl,[bx].NumberOfFats ; " " " " ;an053;bgb;an000;bgb ;an015;bgb
1014 cmp cx,2 ;make sure it is ok ;an053;bgb;an032;bgb
1015 ; $IF NE,AND ;an053;bgb
1016 JE $$IF67
1017 cmp cx,1 ;make sure it is ok ;an053;bgb;an032;bgb
1018 ; $IF NE ;an053;bgb
1019 JE $$IF67
1020 jmp baddrv ;must be 2 fats ;an053;bgb ;an032;bgb
1021 ; $ENDIF ;an053;bgb
1022 $$IF67:
1023 mov fatcnt,cl ;an053;bgb;an000;bgb ;an005;bgb
1024 ;an053;bgb
1025 ;an053;bgb
1026 xor ax,ax ;an053;bgb
1027 mov al,[bx].SectorsPerCluster ;get total sectors ;an053;bgb ;an000;bgb;an015;bgb
1028 cmp ax,1 ;make sure it is ok ;an053;bgb;an032;bgb
1029 ; $IF NE,AND ;an053;bgb
1030 JE $$IF69
1031 cmp ax,2 ;make sure it is ok ;an053;bgb;an032;bgb
1032 ; $IF NE,AND ;an053;bgb
1033 JE $$IF69
1034 cmp ax,4 ;make sure it is ok ;an053;bgb;an032;bgb
1035 ; $IF NE,AND ;an053;bgb
1036 JE $$IF69
1037 cmp ax,8 ;make sure it is ok ;an053;bgb;an032;bgb
1038 ; $IF NE,AND ;an053;bgb
1039 JE $$IF69
1040 cmp ax,16 ;make sure it is ok ;an053;bgb;an032;bgb
1041 ; $IF NE,AND ;an053;bgb
1042 JE $$IF69
1043 cmp ax,32 ;make sure it is ok ;an053;bgb;an032;bgb
1044 ; $IF NE,AND ;an053;bgb
1045 JE $$IF69
1046 cmp ax,64 ;make sure it is ok ;an053;bgb;an032;bgb
1047 ; $IF NE,AND ;an053;bgb
1048 JE $$IF69
1049 cmp ax,128 ;make sure it is ok ;an053;bgb;an032;bgb
1050 ; $IF NE ;an053;bgb
1051 JE $$IF69
1052 jmp baddrv ;this is not! ;an053;bgb ;an032;bgb
1053 ; $ENDIF ;an053;bgb
1054 $$IF69:
1055 ;an053;bgb
1056 mov ax,[bx].SectorsPerFAT ; " " " " ;an053;bgb;an000;bgb ;an015;bgb
1057 cmp ax,0 ;make sure it is ok ;an053;bgb;an032;bgb
1058 jz baddrv ;this is not! ;an053;bgb;an032;bgb
1059 mul cx ; " " " " ;an053;bgb;an000;bgb ;AN000;
1060 push bx ;save bpb pointer ;an053;bgb;an000;bgb ;an015;bgb
1061 push dx ;Save results ;an053;bgb;an000;bgb ;AN000;
1062 push ax ; " " ;an053;bgb;an000;bgb ;AN000;
1063 ;an053;bgb
1064 mov ax,[bx].RootEntries ;Find number of sectors in root ;an053;bgb;an000;bgb ;an015;bgb
1065 cmp ax,2 ;make sure it is ok ;an053;bgb;an032;bgb
1066 ; $IF B,OR ;this is not! ;an053;bgb;an032;bgb
1067 JB $$LL71
1068 cmp ax,512 ;make sure it is ok ;an053;bgb;an032;bgb
1069 ; $IF A ;this is not! ;an053;bgb;an032;bgb
1070 JNA $$IF71
1071 $$LL71:
1072 jmp baddrv ;an053;bgb
1073 ; $ENDIF ;an053;bgb
1074 $$IF71:
1075 ;an053;bgb
1076 mov cl,Dir_Entries_Per_Sector ; by dividing RootEntries ;an053;bgb;an000;bgb ;AN000;
1077 cmp cl,0 ;an053;bgb;an000;bgb;an022;bgb
1078 ; $IF NE ;an053;bgb;an000;bgb;an022;bgb
1079 JE $$IF73
1080 div cl ; by (512/32) ;an053;bgb;an000;bgb;an022;bgb;AN000;
1081 ; $ENDIF ;an053;bgb;an000;bgb;an022;bgb
1082 $$IF73:
1083 pop bx ;Get low sectors per FAT b;an053;bgb;an000;bgback ;AN000;
1084 pop dx ;Get high part ;an053;bgb;an000;bgb ;AN000;
1085 add ax,bx ;Add to get FAT+Dir sector;an053;bgb;an000;bgbs ;AN000;
1086 adc dx,0 ;High part ;an053;bgb;an000;bgb ;AN000;
1087 mov fat_dir_secs,ax ;save it ;an053;bgb;an000;bgb ;an006;bgb
1088 inc fat_dir_secs ; 1 for reserved sector ;an053;bgb;an000;bgb ;an006;bgb
1089 pop bx ;restore bpb pointer ;an053;bgb;an000;bgb ;an015;bgb
1090 add ax,[bx].ReservedSectors ;Add in Boot record sectors ;an053;bgb;an000;bgb ;an015;bgb
1091 adc dx,0 ;to get start of data (DX:;an053;bgb;an000;bgbAX) ;AN000;
1092 mov Data_Start_Low,ax ;Save it ;an053;bgb;an000;bgb ;AN000;
1093 mov Data_Start_High,dx ; ;an053;bgb;an000;bgb ;AN000;
1094 ret ; ;an053;bgb;an000;bgb
1095 get_boot_info endp ; ;an053;bgb;an000;bgb
1096
1097
1098
1099
1100
1101
1102
1103 ;****************************************************************************** ;an000;bgb
1104 ; Calc_Space : Calculate the total space that is ;an000;bgb
1105 ; addressible on the the disk by DOS. ;an000;bgb
1106 ; ;an000;bgb
1107 ; Inputs : none ;an000;bgb
1108 ; ;an000;bgb
1109 ; Outputs : Fdsksiz - Size in bytes of the disk ;an000;bgb
1110 ;****************************************************************************** ;an000;bgb
1111 Procedure Calc_Space ; ;an000;bgb
1112 ; get the total number of clusters on the disk ;an000;bgb ;an006;bgb
1113 p97: xor ax,ax ;clear ax ;an000;bgb
1114 mov ah,36h ;Get disk free space ;an000;bgb
1115 mov dl,alldrv ; 1 based drive number ;an000;bgb
1116 push bx ;save bpb pointer ;an000;bgb;an015;bgb
1117 int 21h ;bx = total space avail ;an000;bgb
1118 ;multiply by sectors per cluster ;an000;bgb
1119 gtsecs: mov ax,dx ;get total clusters ;an000;bgb
1120 xor cx,cx ;clear cx ;an000;bgb
1121 pop bx ;restore bpb pointer ;an000;bgb;an015;bgb
1122 mov cl,[bx].SectorsPerCluster ;get total sectors ;an000;bgb;an015;bgb
1123 push bx ;save bpb pointer ;an000;bgb;an015;bgb
1124 xor bx,bx ;clear bx ;an000;bgb
1125 call Multiply_32_Bits ;multiply ;an000;bgb
1126 ;multiply by bytes per sector ;an000;bgb
1127 mov dx,bx ;save bx ;an000;bgb;an015;bgb
1128 pop bx ;get bpb addr ;an000;bgb;an015;bgb
1129 mov cx,[bx].BytePerSector ;get total bytes ;an000;bgb;an015;bgb
1130 mov bx,dx ;restore bx ;an000;bgb;an015;bgb
1131 call Multiply_32_Bits ; multiply ;an000;bgb
1132 ;result is bytes on disk ;an000;bgb
1133 mov tot_bytes_lo,ax ;save high word ;an000;bgb
1134 mov tot_bytes_hi,bx ;save low word ;an000;bgb
1135 ret ; ;an000;bgb
1136 Calc_Space endp ; ;an000;bgb
1137
1138
1139 ;***************************************************************************** ;an000;bgb
1140 ;Routine name: Check_For_Network ;an000;bgb
1141 ;***************************************************************************** ;an000;bgb
1142 ; ;an000;bgb
1143 ;Description: See if target drive isn't local, or if it is a shared drive. If ;an000;bgb
1144 ; so, exit with error message. The IOCtl call is not checked for ;an000;bgb
1145 ; an error because it is called previously in another routine, and ;an000;bgb
1146 ; invalid drive is the only error it can generate. That condition ;an000;bgb
1147 ; would not get this far ;an000;bgb
1148 ; ;an000;bgb
1149 ;Called Procedures: Message (macro) ;an000;bgb
1150 ; ;an000;bgb
1151 ;Change History: Created 5/1/87 MT ;an000;bgb
1152 ; ;an000;bgb
1153 ;Input: Drive_Letter_Buffer.Drive_Number ;an000;bgb
1154 ; Fatal_Error = NO ;an000;bgb
1155 ; ;an000;bgb
1156 ;Output: Fatal_Error = YES/NO ;an000;bgb
1157 ; ;an000;bgb
1158 ;Psuedocode ;an000;bgb
1159 ;---------- ;an000;bgb
1160 ; See if drive is local (INT 21h, AX=4409 IOCtl) ;an000;bgb
1161 ; IF not local ;an000;bgb
1162 ; Display network message ;an000;bgb
1163 ; Fatal_ERROR = YES ;an000;bgb
1164 ; ELSE ;an000;bgb
1165 ; IF 8000h bit set on return ;an000;bgb
1166 ; Display assign message ;an000;bgb
1167 ; Fatal_Error = YES ;an000;bgb
1168 ; ENDIF ;an000;bgb
1169 ; ENDIF ;an000;bgb
1170 ; ret ;an000;bgb
1171 ;***************************************************************************** ;an000;bgb
1172 ;an000;bgb
1173 Procedure Check_For_Network ; ;an000;bgb;AN000;
1174 ; ;an000;bgb
1175 mov bl,alldrv ;Drive is 1=A, 2=B ;an000;bgb; ;
1176 mov al,09h ;See if drive is local or remote;an000;bgb;AC000;
1177 DOS_CALL IOCtl ;We will not check for error ;an000;bgb;AC000;
1178 test dx,Net_Check ;if (x & 1200H)(redir or shared);an000;bgb; ;
1179 ; $IF NZ ;Found a net drive ;an000;bgb;AC000;
1180 JZ $$IF75
1181 Message No_Net_Arg ;Tell 'em ;an000;bgb;AC000;
1182 mov Fatal_Error,Yes ;Indicate bad stuff ;an000;bgb;AN000;
1183 ; $ELSE ;Local drive, now check assign ;an000;bgb;AN000;
1184 JMP SHORT $$EN75
1185 $$IF75:
1186 test dx,Assign_Check ;8000h bit is bad news ;an000;bgb; ;
1187 ; $IF NZ ;Found it ;an000;bgb;AC000;
1188 JZ $$IF77
1189 Message SubstErr ;Tell error ;an000;bgb;AC000;
1190 mov Fatal_Error,Yes ;Indicate bad stuff ;an000;bgb;AN000;
1191 ; $ENDIF ; ;an000;bgb;AN000;
1192 $$IF77:
1193 ; $ENDIF ; ;an000;bgb;AN000;
1194 $$EN75:
1195 ret ; ;an000;bgb;AN000;
1196 ;an000;bgb
1197 Check_For_Network endp ; ;an000;bgb;AN000;
1198 ;an000;bgb
1199 ;***************************************************************************** ;an000;bgb
1200 ;Routine name: Check_Translate_Drive ;an000;bgb
1201 ;***************************************************************************** ;an000;bgb
1202 ; ;an000;bgb
1203 ;Description: Do a name translate call on the drive letter to see if it is ;an000;bgb
1204 ; assigned by SUBST or ASSIGN ;an000;bgb
1205 ; ;an000;bgb
1206 ;Called Procedures: Message (macro) ;an000;bgb
1207 ; ;an000;bgb
1208 ;Change History: Created 5/1/87 MT ;an000;bgb
1209 ; ;an000;bgb
1210 ;Input: Drive_Letter_Buffer.Drive_Number ;an000;bgb
1211 ; Fatal_Error = NO ;an000;bgb
1212 ; ;an000;bgb
1213 ;Output: Fatal_Error = YES/NO ;an000;bgb
1214 ; ;an000;bgb
1215 ;Psuedocode ;an000;bgb
1216 ;---------- ;an000;bgb
1217 ; Put drive letter in ASCIIZ string "d:\",0 ;an000;bgb
1218 ; Do name translate call (INT 21) ;an000;bgb
1219 ; IF drive not same ;an000;bgb
1220 ; Display assigned message ;an000;bgb
1221 ; Fatal_Error = YES ;an000;bgb
1222 ; ENDIF ;an000;bgb
1223 ; ret ;an000;bgb
1224 ;***************************************************************************** ;an000;bgb
1225 Procedure Check_Translate_Drive ; ;an000;bgb;AN000;
1226 call func60 ; ;an000;bgb
1227 mov bl,byte ptr [TranSrc] ;Get drive letter from path ;an000;bgb; ;
1228 cmp bl,byte ptr [Chkprmt_End] ;Did drive letter change? ;an000;bgb; ;
1229 ; $IF NE ;If not the same, it be bad ;an000;bgb;AC000;
1230 JE $$IF80
1231 Message SubstErr ;Tell user ;an000;bgb;AC000;
1232 mov Fatal_Error,Yes ;Setup error flag ;an000;bgb;AN000;
1233 ; $ENDIF ; ;an000;bgb;AN000;
1234 $$IF80:
1235 ret ; ;an000;bgb;AN000;
1236 Check_Translate_Drive endp ; ;an000;bgb;AN000;
1237 ;an000;bgb
1238 ;an000;bgb
1239 Procedure func60 ; ;an000;bgb;AN000;
1240 ; PUSH DS ;ICE ;an000;bgb
1241 ; push bx ;ICE ;an000;bgb
1242 ; push ax ;ICE ;an000;bgb
1243 ; ;an000;bgb
1244 ; mov bx,0140H ;ICE ;an000;bgb
1245 ; xor ax,ax ;ICE ;an000;bgb
1246 ; mov ds,ax ;ICE ;an000;bgb
1247 ; mov ax,word ptr ds:[bx] ;ICE ;an000;bgb
1248 ; mov word ptr ds:[bx],ax ;ICE ;an000;bgb
1249 ; ;an000;bgb
1250 ; pop ax ;ICE ;an000;bgb
1251 ; pop bx ;ICE ;an000;bgb
1252 ; POP DS ;ICE ;an000;bgb
1253 ;an000;bgb
1254 mov byte ptr [transrc],'A' ;an000;bgb
1255 mov bl,alldrv ;Get drive ; ;an000;bgb ;
1256 dec bl ;Make it 0 based ;an000;bgb;AN001;
1257 add byte ptr [TranSrc],bl ;Make string "d:\" ;an000;bgb; ;
1258 lea si,TranSrc ;Point to translate string ;an000;bgb; ;
1259 push ds ;Set ES=DS (Data segment) ;an000;bgb; ;
1260 pop es ; " " " " ;an000;bgb; ;
1261 lea di,Chkprmt_End ;Point at output buffer ;an000;bgb; ;
1262 DOS_Call xNameTrans ;Get real path ;an000;bgb;AC000;
1263 ret ; ;an000;bgb;AN000;
1264 func60 endp ; ;AN000; ;an000;bgb
1265 ;an000;bgb
1266 ;an000;bgb
1267 ;***************************************************************************** ;an000;bgb
1268 ;Routine name: Hook_Interrupts ;an000;bgb
1269 ;***************************************************************************** ;an000;bgb
1270 ; ;an000;bgb
1271 ;Description: Change the interrupt handler for INT 13h to point to the ;an000;bgb
1272 ; ControlC_Handler routine ;an000;bgb
1273 ; ;an000;bgb
1274 ;Called Procedures: None ;an000;bgb
1275 ; ;an000;bgb
1276 ;Change History: Created 4/21/87 MT ;an000;bgb
1277 ; ;an000;bgb
1278 ;Input: None ;an000;bgb
1279 ; ;an000;bgb
1280 ;Output: None ;an000;bgb
1281 ; ;an000;bgb
1282 ;Psuedocode ;an000;bgb
1283 ;---------- ;an000;bgb
1284 ; ;an000;bgb
1285 ; Point at ControlC_Handler routine ;an000;bgb
1286 ; Set interrupt handler (INT 21h, AX=2523h) ;an000;bgb
1287 ; ret ;an000;bgb
1288 ;***************************************************************************** ;an000;bgb
1289 ;an000;bgb
1290 procedure Hook_Interrupts ; ;an000;bgb;AN000;
1291 ; ;an000;bgb
1292 mov al,23h ;an000;bgb
1293 DOS_Call Get_Interrupt_Vector ;Get the INT 23h handler ;an000;bgb;AC000;
1294 mov word ptr [CONTCH],bx ; ;an000;bgb
1295 mov bx,es ; ;an000;bgb;AN000;
1296 mov word ptr [CONTCH+2],bx ; ;an000;bgb
1297 mov al,23h ;Specify CNTRL handler ;an000;bgb; ;
1298 lea dx, INT_23 ;Point at it ;an000;bgb; ;
1299 push ds ;Save data seg ;an000;bgb; ;
1300 push cs ;Point to code segment ;an000;bgb; ;
1301 pop ds ; ;an000;bgb; ;
1302 DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;an000;bgb;AC000;
1303 pop ds ;Get Data degment back ;an000;bgb; ;
1304 mov al,24h ; ;an000;bgb
1305 DOS_Call Get_Interrupt_Vector ;Get the INT 24h handler ;an000;bgb;AC000;
1306 mov word ptr [HardCh],bx ;Save it ;an000;bgb
1307 mov bx,es ; ;an000;bgb
1308 mov word ptr [HardCh+2],bx ; ;an000;bgb
1309 mov al,24h ;Specify handler ;an000;bgb ; ;
1310 lea dx, INT_24 ;Point at it ;an000;bgb; ;
1311 push ds ;Save data seg ;an000;bgb; ;
1312 push cs ;Point to code segment ;an000;bgb; ;
1313 pop ds ; ;an000;bgb; ;
1314 DOS_Call Set_Interrupt_Vector ;Set the INT 23h handler ;an000;bgb;AC000;
1315 pop ds ;Get Data degment back ;an000;bgb; ;
1316 ret ; ;an000;bgb;AN000;
1317 ;an000;bgb
1318 hook_Interrupts endp ; ;an000;bgb;AN000;
1319 ;an000;bgb
1320 ;***************************************************************************** ;an000;bgb
1321 ;Routine name: Clear_Append_X ;an000;bgb
1322 ;***************************************************************************** ;an000;bgb
1323 ; ;an000;bgb
1324 ;Description: Determine if Append /XA is turned on thru INT 2Fh, and shut ;an000;bgb
1325 ; off for life of CHKDSK if it is. ;an000;bgb
1326 ; ;an000;bgb
1327 ;Called Procedures: None ;an000;bgb
1328 ; ;an000;bgb
1329 ; ;an000;bgb
1330 ;Change History: Created 5/13/87 MT ;an000;bgb
1331 ; ;an000;bgb
1332 ;Input: None ;an000;bgb
1333 ; ;an000;bgb
1334 ;Output: APPEND = YES/NO ;an000;bgb
1335 ; ;an000;bgb
1336 ;Psuedocode ;an000;bgb
1337 ;---------- ;an000;bgb
1338 ; ;an000;bgb
1339 ; Append = NO ;an000;bgb
1340 ; See if APPEND /X is present (INT 2Fh, AX=0B706h) ;an000;bgb
1341 ; IF present ;an000;bgb
1342 ; Turn append /X off (INT 2Fh, AX=B707h, BX = 0) ;an000;bgb
1343 ; Append = YES ;an000;bgb
1344 ; ENDIF ;an000;bgb
1345 ; ret ;an000;bgb
1346 ;***************************************************************************** ;an000;bgb
1347 ;an000;bgb
1348 Procedure Clear_Append_X ; ;an000;bgb ;AN000;
1349 ;an000;bgb
1350 mov Append,NO ;Init the Append /X flag ;an000;bgb;AN000;
1351 mov ax,Append_X ;Is Append /X there? ;an000;bgb;AN000;
1352 int Multiplex ; " " " " ;an000;bgb;AN000;
1353 cmp bx,Append_X_Set ;Was it turned on? ;an000;bgb;AN000;
1354 ; $IF E ;Yep ;an000;bgb;AN000;
1355 JNE $$IF82
1356 mov Append,YES ;Indicate that it was on ;an000;bgb;AN000;
1357 mov ax,Set_Append_X ;Turn Append /X off ;an000;bgb;AN000;
1358 mov bx,Append_Off ; " " " " ;an000;bgb;AN000;
1359 int Multiplex ; " " " " ;an000;bgb;AN000;
1360 ; $ENDIF ; ;an000;bgb;AN000;
1361 $$IF82:
1362 ret ; ;an000;bgb;AN000;
1363 ;an000;bgb
1364 Clear_Append_X endp ; ;an000;bgb;AN000;
1365 ;an000;bgb
1366 ;an000;bgb
1367 ;***************************************************************************** ;an000;bgb
1368 ;Routine name: CHKDSK_IFS ;an000;bgb
1369 ;***************************************************************************** ;an000;bgb
1370 ; ;an000;bgb
1371 ;Description: ;an000;bgb
1372 ; ;an000;bgb
1373 ;Called Procedures: Main_Routine ;an000;bgb
1374 ; EXEC_FS_CHKDSK ;an000;bgb
1375 ; Done ;an000;bgb
1376 ; ;an000;bgb
1377 ;Change History: Created 5/8/87 MT ;an000;bgb
1378 ; ;an000;bgb
1379 ;Input: FS_Not_FAT = Yes/No ;an000;bgb
1380 ; ;an000;bgb
1381 ;Output: None ;an000;bgb
1382 ; ;an000;bgb
1383 ;Psuedocode ;an000;bgb
1384 ;---------- ;an000;bgb
1385 ; ;an000;bgb
1386 ; IF File system other than FAT ;an000;bgb
1387 ; Go call file system specific CHKDSK (CALL Exec_FS_CHKDSK) ;an000;bgb
1388 ; ELSE ;an000;bgb
1389 ; Do FAT based CHKDSK (CALL Main_Routine) ;an000;bgb
1390 ; ENDIF ;an000;bgb
1391 ; Restore current drive (CALL Done) ;an000;bgb
1392 ; ret ;an000;bgb
1393 ;***************************************************************************** ;an000;bgb
1394 ;an000;bgb
1395 ;an000;bgb
1396 Procedure CHKDSK_IFS ; ;an000;bgb;AN000;
1397 ;an000;bgb
1398 ifdef fsexec ;an038;bgb
1399 cmp FS_Not_Fat,YES ;Is the target FS a FAT? ;an038;bgb;AN000;
1400 ; $IF E ;No, so need to exec the ;an038;bgb;AN000;
1401 JNE $$IF84
1402 call EXEC_FS_CHKDSK ; file system specific prog. ;an038;bgb;AN000;
1403 ; $ELSE ;It's a FAT ;an038;bgb;AN000;
1404 JMP SHORT $$EN84
1405 $$IF84:
1406 endif ;an038;bgb
1407 call Main_Routine ;Use canned code! ;an038;bgb;AN000;
1408 ifdef fsexec ;an038;bgb
1409 ; $ENDIF ; ;an038;bgb;AN000;
1410 $$EN84:
1411 endif ;an038;bgb
1412 call Done ;Restore current drive ;an000;bgb;AN000;
1413 ret ; ;an000;bgb;AN000;
1414 ;an000;bgb
1415 CHKDSK_IFS endp ; ;an000;bgb;AN000;
1416 ;an000;bgb
1417 ;***************************************************************************** ;an000;bgb
1418 ;Routine name: Reset_Append_X ;an000;bgb
1419 ;***************************************************************************** ;an000;bgb
1420 ; ;an000;bgb
1421 ;description: If APPEND /XA was on originally, turn it back on ;an000;bgb
1422 ; ;an000;bgb
1423 ;Called Procedures: None ;an000;bgb
1424 ; ;an000;bgb
1425 ; ;an000;bgb
1426 ;Change History: Created 5/13/87 MT ;an000;bgb
1427 ; ;an000;bgb
1428 ;Input: None ;an000;bgb
1429 ; ;an000;bgb
1430 ;Output: APPEND = YES/NO ;an000;bgb
1431 ; ;an000;bgb
1432 ;Psuedocode ;an000;bgb
1433 ;---------- ;an000;bgb
1434 ; ;an000;bgb
1435 ; IF APPEND = YES ;an000;bgb
1436 ; Turn append /X on (INT 2Fh, AX=B707h, BX = 1) ;an000;bgb
1437 ; ENDIF ;an000;bgb
1438 ; ret ;an000;bgb
1439 ;***************************************************************************** ;an000;bgb
1440 ;an000;bgb
1441 Procedure Reset_Append_X ; ;an000;bgb;AN000;
1442 ;an000;bgb
1443 cmp Append,Yes ;Was Append /X on to start with?;an000;bgb;AN000;
1444 ; $IF E ;Yep ;an000;bgb;AN000;
1445 JNE $$IF87
1446 mov ax,Set_Append_X ;Turn Append /X off ;an000;bgb;AN000;
1447 mov bx,Append_On ; " " " " ;an000;bgb;AN000;
1448 int Multiplex ; " " " " ;an000;bgb;AN000;
1449 ; $ENDIF ; ;an000;bgb;AN000;
1450 $$IF87:
1451 ret ; ;an000;bgb;AN000;
1452 ;an000;bgb
1453 Reset_Append_X endp ; ;an000;bgb;AN000;
1454 ;an000;bgb
1455 ;***************************************************************************** ;an000;bgb
1456 ;Routine name: Multiply_32_Bits ;an000;bgb
1457 ;***************************************************************************** ;an000;bgb
1458 ; ;an000;bgb
1459 ;Description: A real sleazy 32 bit x 16 bit multiply routine. Works by adding ;an000;bgb
1460 ; the 32 bit number to itself for each power of 2 contained in the ;an000;bgb
1461 ; 16 bit number. Whenever a bit that is set in the multiplier (CX) ;an000;bgb
1462 ; gets shifted to the bit 0 spot, it means that that amount has ;an000;bgb
1463 ; been multiplied so far, and it should be added into the total ;an000;bgb
1464 ; value. Take the example CX = 12 (1100). Using the associative ;an000;bgb
1465 ; rule, this is the same as CX = 8+4 (1000 + 0100). The ;an000;bgb
1466 ; multiply is done on this principle - whenever a bit that is set ;an000;bgb
1467 ; is shifted down to the bit 0 location, the value in BX:AX is ;an000;bgb
1468 ; added to the running total in DI:SI. The multiply is continued ;an000;bgb
1469 ; until CX = 0. The routine will exit with CY set if overflow ;an000;bgb
1470 ; occurs. ;an000;bgb
1471 ; ;an000;bgb
1472 ; ;an000;bgb
1473 ;Called Procedures: None ;an000;bgb
1474 ; ;an000;bgb
1475 ;Change History: Created 7/23/87 MT ;an000;bgb
1476 ; ;an000;bgb
1477 ;Input: BX:AX = 32 bit number to be multiplied ;an000;bgb
1478 ; CX = 16 bit number to be multiplied. (Must be even number) ;an000;bgb
1479 ; ;an000;bgb
1480 ;Output: BX:AX = output. ;an000;bgb
1481 ; CY set if overflow ;an000;bgb
1482 ; ;an000;bgb
1483 ;Psuedocode ;an000;bgb
1484 ;---------- ;an000;bgb
1485 ; ;an000;bgb
1486 ; Point at ControlC_Handler routine ;an000;bgb
1487 ; Set interrupt handler (INT 21h, AX=2523h) ;an000;bgb
1488 ; ret ;an000;bgb
1489 ;***************************************************************************** ;an000;bgb
1490 ;an000;bgb
1491 Public Multiply_32_Bits ;an000;bgb
1492 Multiply_32_Bits proc ; ;an000;bgb;AN000;
1493 ;an000;bgb
1494 push di ; ;an000;bgb;AN000;
1495 push si ; ;an000;bgb;AN000;
1496 xor di,di ;Init result to zero ;an000;bgb
1497 xor si,si ; ;an000;bgb
1498 cmp cx,0 ;Multiply by 0? ;an000;bgb;AN000;
1499 ; $IF NE ;Keep going if not ;an000;bgb;AN000;
1500 JE $$IF89
1501 ; $DO ;This works by adding the result;an000;bgb;AN000;
1502 $$DO90:
1503 test cx,1 ;Need to add in sum of this bit?;an000;bgb;AN000;
1504 ; $IF NZ ;Yes ;an000;bgb;AN000;
1505 JZ $$IF91
1506 add si,ax ;Add in the total so far for ;an000;bgb;AN000;
1507 adc di,bx ; this bit multiplier (CY oflow);an000;bgb;AN000;
1508 ; $ELSE ;Don't split multiplier ;an000;bgb;AN000;
1509 JMP SHORT $$EN91
1510 $$IF91:
1511 clc ;Force non exit ;an000;bgb;AN000;
1512 ; $ENDIF ; ;an000;bgb;AN000;
1513 $$EN91:
1514 ; $LEAVE C ;Leave on overflow ;an000;bgb;AN000;
1515 JC $$EN90
1516 shr cx,1 ;See if need to multiply value ;an000;bgb;AN000;
1517 cmp cx,0 ;by 2 ;an000;bgb;AN000;
1518 ; $LEAVE E ;Done if cx shifted down to zero;an000;bgb;AN000;
1519 JE $$EN90
1520 add ax,ax ;Each time cx is shifted, add ;an000;bgb;AN000;
1521 adc bx,bx ;value to itself (Multiply * 2) ;an000;bgb;AN000;
1522 ; $ENDDO C ;CY set on overflow ;an000;bgb;AN000;
1523 JNC $$DO90
1524 $$EN90:
1525 ; $IF NC ;If no overflow, add in DI:SI ;an000;bgb;AN000;
1526 JC $$IF97
1527 mov ax,si ; which contains the original ;an000;bgb;AN000;
1528 mov bx,di ; value if odd, 0 if even. This ;an000;bgb;AN000;
1529 clc ;Set no overflow flag ;an000;bgb;AN000;
1530 ; $ENDIF ; ;an000;bgb;AN000;
1531 $$IF97:
1532 ; $ELSE ; ;an000;bgb
1533 JMP SHORT $$EN89
1534 $$IF89:
1535 xor ax,ax ; ;an000;bgb
1536 xor bx,bx ; ;an000;bgb
1537 ; $ENDIF ;Multiply by 0 ;an000;bgb;AN000;
1538 $$EN89:
1539 pop si ; ;an000;bgb;AN000;
1540 pop di ; ;an000;bgb;AN000;
1541 ret ; ;an000;bgb;AN000;
1542 ;an000;bgb
1543 Multiply_32_Bits endp ;an000;bgb
1544 pathlabl chkinit ;an000;bgb
1545 code ends ;an000;bgb
1546 end ;an000;bgb
1547 ;an000;bgb
1548 \1a