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

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / DISKCOMP / COMPINIT.ASM
1 PAGE 90,132 ;\ f\eA\b\e2
2 TITLE COMPINIT -- DISKCOMP INITIALIZATION PROGRAM
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: COMPINIT
5
6 ; DESCRIPTIVE NAME: Initialization for Diskette to diskette copy Utility
7
8 ;FUNCTION: DISKCOMP is to compare the contents of the diskette in the
9 ; specified source drive to the diskette in the target
10 ; drive. If necessary for the diskettes to use volume serial
11 ; numbers, the actual value of those number is ignored.
12
13 ; Multiple compares may be performed with one load of DISKCOMP.
14 ; A prompt, "Compare another (Y/N)?" permits additional
15 ; executions, all with the same drive specifications.
16
17 ; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN".
18
19 ; INPUT: (DOS command line parameters)
20
21 ; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
22
23 ; WHERE
24 ; [d:][path] - Path where the DISKCOMP command resides.
25
26 ; [d:] - To specify the Source drive
27 ;
28 ; [d:] - To specify the Target drive
29 ;
30 ; [/1] - To compare only the first side of the diskette,
31 ; regardless of the diskette or drive type.
32
33 ; [/8] - To compare only the first 8 sectors per track,
34 ; even if the first diskette contains 9/15 sectors
35 ; per track.
36 ;
37 ; EXIT-NORMAL: Errorlevel = 0
38 ; Function completed successfully.
39
40 ; EXIT-ERROR: Errorlevel = 1
41 ; Abnormal termination due to error, wrong DOS,
42 ; invalid parameters, unrecoverable I/O errors on
43 ; the diskette.
44
45 ; EFFECTS: The entire source diskette is compared, including the unused
46 ; sectors. There is no awareness of the separate files
47 ; involved. A unique volume serial number, if present,
48 ; is ignored in the comparison process.
49
50 ; INCLUDED FILES:
51 ; PATHMAC.INC - PATHGEN MACRO
52 ; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
53
54 ; INTERNAL REFERENCES:
55 ; ROUTINES:
56 ; INIT - initialization main routine
57 ; SOURCE_TARGET_DRV - convert source/target drive to bios values
58 ; TEST_DRIVE_VALIDITY - are source/target drives valid?
59 ; DOS_DRIVE_VALIDITY -- check dos drive validity byte
60 ; TEST_REMOVABLE - is specified drive removable?
61 ; CHK_SINGLE_DRIV_OP - is target drive same as source?
62 ; GET_LOGICAL_DRIVE - get logical drive who owns the physical drive
63 ; DISKETTE_DRV_TYPE - check compatability source/target drives
64 ; CHECK_REDIRECTION - is device redirected?
65 ; BUFFER_SIZE - finds start and end of buffer
66 ; SETUP_CTRL_BREAK - setup the ctrl-break vector
67 ; CHECK_SERVER - is server or redirector loaded?
68
69 ; DATA AREAS:
70 ; PSP - Contains the DOS command line parameters.
71 ; WORKAREA - Temporary storage
72
73 ; EXTERNAL REFERENCES:
74 ; ROUTINES:
75 ; SYSDISPMSG - Uses the MSG parm lists to construct the messages
76 ; on STDOUT.
77 ; SYSLOADMSG - Loads messages, makes them accessable.
78 ; PARSER - Processes the DOS Command line, finds parms.
79
80 ; DATA AREAS:
81 ; DCOMPSM.SAL - Defines the control blocks that describe the messages
82 ; DCOMPPAR.SAL - Defines the control blocks that describe the
83 ; DOS Command line parameters.
84
85 ; NOTES:
86 ; This module should be processed with the SALUT preprocessor
87 ; with the re-alignment not requested, as:
88
89 ; SALUT COMPINIT,NUL
90
91 ; To assemble these modules, the alphabetical or sequential
92 ; ordering of segments may be used.
93
94 ; For instructions as to how to LINK, see prolog for DISKCOMP.
95
96 ;PROGRAM AUTHOR: Original written by: Jin K.
97 ; 4.00 modifications by: Edwin M. K.
98 ;****************** END OF SPECIFICATIONS *****************************
99 IF1
100 %OUT COMPONENT=DISKCOMP, MODULE=COMPINIT.SAL
101 ENDIF
102
103 ;REVISION HISTORY:
104 ;DATE: 10-30-84 - chk_para routine added. Many parts are modified to
105 ; permit DISKCOMP /1, DISKCOMP D: /1 cases. Restore diskbase
106 ; before return to DOS when invalid DOS version occurs.
107 ;DATE: 3-27-85 MAIN PARTS OF DISKCOMP PROGRAM HAS BEEN REWRITTEN
108 ; TO USE NEW IOCTL FUNCTIONS 'READ', 'GET_DEVICE_PARAMETERS'.
109 ; A000 - Change spelling of "LOCAL" to "LOCALX" to make MASM 3 happy.
110
111 INCLUDE PATHMAC.INC ;AN013;
112 INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
113
114 CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AC000;
115 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
116
117 INCLUDE DISKCOMP.EQU
118 NOOP EQU 90H ;NO-OPERTION INSTRUCTION, USED TO DELETE ;AN001;
119 ; 386 SUPPORT ;AN001;
120 ;$salut (4,2,9,41)
121 ;****************************************************************************
122 ; *
123 ; EXTERNAL VARIABLES *
124 ; *
125 ;****************************************************************************
126 EXTRN PARSER:NEAR ;DCOPYPAR.SAL - DRIVES SYS PARSER ;AN000;
127
128 EXTRN RECOMMENDED_BYTES_SECTOR:WORD
129 EXTRN S_OWNER_SAVED:BYTE
130 EXTRN T_OWNER_SAVED:BYTE
131 EXTRN ASCII_DRV1_ID:BYTE ;40H SOURCE DRIVE ID IN ASCII
132 EXTRN ASCII_DRV2_ID:BYTE ;40H TARGET DRIVE ID IN ASCII
133
134 EXTRN SUBLIST_78 :WORD ; ;AN000;
135 EXTRN SUBLIST_11 :WORD ; ;AN000;
136 EXTRN SUBLIST_15A :WORD ; ;AN000;
137 EXTRN SUBLIST_15B :WORD ; ;AN000;
138 EXTRN SUBLIST_15C :WORD ; ;AN000;
139 EXTRN SUBLIST_17B :WORD ; ;AN000;
140 EXTRN SUBLIST_17C :WORD ; ;AN000;
141 EXTRN SUBLIST_17D :WORD ; ;AN000;
142 EXTRN SUBLIST_PARSE:WORD ;PARSE ERROR XX - %0 ;AN004;
143
144 EXTRN MSGNUM_INVALID_PARM:BYTE ;"INVALID PARAMETER" ;AC000;
145 EXTRN MSGNUM_INVALID_DRV:BYTE ;"INVALID DRIVE SPECIFICATION" ;AC000;
146 EXTRN MSGNUM_DRV_REDIRECTED:BYTE ;"INVALID, DRIVE REDIRECTED" ;AC000;
147 EXTRN MSGNUM_NOT_COMPATIBLE:BYTE ;"DEVICE OR DISKETTE TYPES NOT COMPATIBLE";AC000;
148 .XLIST
149 ;EXTRN MSG_INVALID_DOS :BYTE ;MSG FOR DOS1.0 AND 1.1
150 .LIST
151
152 EXTRN TRACK_TO_READ :BYTE
153 EXTRN SIDE:BYTE
154
155 EXTRN S_DRV_SECT_TRACK :BYTE ;SECT/TRACK
156 EXTRN S_DRV_HEADS :BYTE ;# OF HEADS
157 EXTRN S_DRV_TRACKS :BYTE ;# OF TRACKS
158 EXTRN T_DRV_SECT_TRACK :BYTE
159 EXTRN T_DRV_HEADS :BYTE
160 EXTRN T_DRV_TRACKS :BYTE
161
162 EXTRN COPY_TYPE :BYTE ;1 = 1-DRIVE COPY 2 = 2-DRIVE COPY
163 EXTRN USER_OPTION :BYTE ;NO OPTION (-1) /1 (1), INVALID (9)
164 EXTRN USER_OPTION_8 :BYTE ;NO OPTION (-1) /8 (1), INVALID (9)
165 EXTRN BUFFER_BEGIN :WORD ;STARTING BUFFER @ FOR LOADING
166 EXTRN BUFFER_END :WORD ;ENDING BUFFER @ FOR LOADING
167 EXTRN START_BUFFER :WORD ;START OF BUFFER SPACE
168 EXTRN MAIN_EXIT :WORD ;EXIT ADDRESS FOR CONTROL-BREAK
169
170 EXTRN ORG_SOURCE_DRIVE:BYTE ;LOGICAL SOURCE DRIVE NUMBER
171 EXTRN ORG_TARGET_DRIVE:BYTE ; TARGET
172 EXTRN SOURCE_DRIVE:BYTE ;AS SPECIFIED BY USER PARMS, DR NUM ;AN000;
173 EXTRN TARGET_DRIVE:BYTE ;AS SPECIFIED BY USER PARMS, DR NUM ;AN000;
174
175 EXTRN IO_ERROR :BYTE
176
177 EXTRN DS_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
178 EXTRN DT_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
179 EXTRN DS_specialFunctions :BYTE ;AND THEIR CONTENTS
180 EXTRN DT_specialFunctions :BYTE
181 EXTRN DS_deviceType:BYTE
182 EXTRN DT_deviceType:BYTE
183 EXTRN DS_deviceAttributes :WORD
184 EXTRN DT_deviceAttributes :WORD
185 EXTRN DS_numberOfCylinders :WORD
186 EXTRN DT_numberOfCylinders :WORD
187 EXTRN DS_mediaType :BYTE
188 EXTRN DT_mediaType :BYTE
189 EXTRN DS_BPB_PTR :BYTE
190 EXTRN DT_BPB_PTR :BYTE
191
192 EXTRN MS_IOCTL_DRV_PARM :BYTE ;DRIVE PARM FROM SOURCE MEDIUM
193 EXTRN MT_IOCTL_DRV_PARM :BYTE
194
195 EXTRN PATCH_386:BYTE ;PATCH AREA, CHANGED TO NOOP IF NOT 386 ;AN001;
196
197 EXTRN GENERIC_IOCTL :NEAR
198 EXTRN SET_LOGICAL_DRIVE :NEAR
199 ; $salut (4,24,28,41)
200 MY_BPB STRUC
201 CBYTE_SECT DW 0 ; 200H BYTES / SECTOR
202 CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER
203 CRESEV_SECT DW 0 ; 1h RESERVED SECTORS
204 CFAT DB 0 ; 2h # OF FATS
205 CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES
206 CTOTSECT DW 0 ; 02D0h TOT. # OF SECT.
207 ; INCL BOOT SECT, DIRS
208 MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR
209 CSECT_FAT DW 0 ; 2h SECTORS / FAT
210 CSECT_TRACK DW 0 ;
211 CHEAD DW 0 ;
212 CHIDDEN_SECT DD 0 ;
213 BIG_TOT_SECT DD 0 ;
214 DB 6 DUP (0) ;
215 MY_BPB ENDS
216
217 ;USED TO CHECK FOR PRESENCE OF 386 MACHINE:
218 BIOS_SYSTEM_DESCRIPTOR struc ;SYSTEM TYPE STRUC ;AN001;
219 bios_SD_leng dw ? ;VECTOR LENGTH ;AN001;
220 bios_SD_modelbyte db ? ;SYSTEM MODEL TYPE ;AN001;
221 bios_SD_scnd_modelbyte db ? ; ;AN001;
222 db ? ; ;AN001;
223 bios_SD_featurebyte1 db ? ; ;AN001;
224 db 4 dup (?) ; ;AN001;
225 BIOS_SYSTEM_DESCRIPTOR ends ;END OF STRUC ;AN001;
226
227
228 ;****************************************************************************
229 ; *
230 ; VARIABLE DECLARATIONS *
231 ; *
232 ;****************************************************************************
233 DRIVE_VALID DW ? ;DRIVE VALIDITY BYTE
234 DEFAULT_DRV DB ? ;DEFAULT DRIVE ID
235 NUMBER_OF_DRV DB ? ;TOTAL # OF DISKT DRIVES ON THE SYS
236 ;(NUMBER_OF_DRV = 0 ---> 1 DRIVE)
237 ASCII_DRIVE_LETTER DB " :",0
238 PATHLABL COMPINIT ;AN013;
239 HEADER <INIT - INITIALIZATION ROUTINE, MAIN PROGRAM> ; ;AN000;
240 ; $salut (4,9,15,41) ; ;AN000;
241 ;#############################################################################
242 ; INITIALIZATION ROUTINE - MAIN PROGRAM
243 INIT PROC NEAR
244 PUBLIC INIT ;MAKE ENTRY IN LINK MAP ;AN000;
245
246 ;OUTPUT: DX = EXIT CODE, "FINE"
247 ;#############################################################################
248
249 MOV DRIVE_VALID,AX ;SAVE DRIVE VALIDITY BYTE
250 CALL PC_386_CHK ;SEE IF THIS IS A 386 MACHINE ;AN001;
251
252 ; REPLACE THE "FILL_SEG" IN THE SUBLIST MESSAGE CONTROL BLOCKS.
253
254 ; BECAUSE THIS IS A .COM STYLE FILE, THESE SEGID VALUES CANNOT
255 ; BE PROVIDED BY THE DOS SYSTEM LOADER, BUT MUST BE DYNAMICALLY
256 ; PERFORMED AT EXECUTION TIME AS PART OF A .COM FILE'S OBLIGATION
257 ; TO BE "SELF-RELOCATING".
258
259 MOV AX,CS ;GET SEGID OF COMMON SEGMENT
260 MOV SUBLIST_78.SUB_VALUE_SEG,AX ; ;AN000;
261 MOV SUBLIST_11.SUB_VALUE_SEG,AX ; ;AN000;
262 MOV SUBLIST_15A.SUB_VALUE_SEG,AX ; ;AN000;
263 MOV SUBLIST_15B.SUB_VALUE_SEG,AX ; ;AN000;
264 MOV SUBLIST_15C.SUB_VALUE_SEG,AX ; ;AN000;
265 MOV SUBLIST_17B.SUB_VALUE_SEG,AX ; ;AN000;
266 MOV SUBLIST_17C.SUB_VALUE_SEG,AX ; ;AN000;
267 MOV SUBLIST_17D.SUB_VALUE_SEG,AX ; ;AN000;
268 MOV SUBLIST_PARSE.SUB_VALUE_SEG,AX ; ;AN004;
269
270 CALL SETUP_CTRL_BREAK ;STEALS CTRL_BREAK
271 CLD ;CLEAR DIRECTION FLAG
272 MOV DX,FINE ;ASSUME EVERYTHING IS FINE
273 .XLIST
274 ; CALL SCREENING ;CHECK DOS VERSION AND INPUT PARMS
275 ; CMP DX,FINE ;IF FINE & DANDY
276 ; JNE EXIT_INIT
277 .LIST
278 CALL PARSER ;LOOK AT DOS COMMAND LINE ;AN000;
279
280 CMP DX,FINE ;IF ALL OK ;AN000;
281 ; $IF E ; ;AN000;
282 JNE $$IF1
283 CALL SOURCE_TARGET_DRV ;DETERMINE SOURCE AND TARGET DRV
284
285 ; $ENDIF ; ;AN000;
286 $$IF1:
287 CMP DX,FINE ;IF STILL FINE AND DANDY ;AN000;
288 ; $IF E ; ;AN000;
289 JNE $$IF3
290 CALL TEST_DRIVE_VALIDITY
291
292 CMP DX,FINE
293 ; $IF E ; ;AN000;
294 JNE $$IF4
295 CALL DISKETTE_DRV_TYPE ;SOURCE & TARGET DRIVE TYPES
296
297 CMP DX,FINE ;IF FINE & DANDY
298 ; $IF E ; ;AN000;
299 JNE $$IF5
300 CALL BUFFER_SIZE ;GET BUFFER SIZE FOR COPYING
301
302 ; $ENDIF ; ;AN000;
303 $$IF5:
304 ; $ENDIF ; ;AN000;
305 $$IF4:
306 ; $ENDIF ; ;AN000;
307 $$IF3:
308 RET ;RETURN TO CALLER
309
310 INIT ENDP ;END INITIALLIZATION PROGRAM
311
312 ;#############################################################################
313 .XLIST
314 ; HEADER <SCREENING - CHECK DOS VERSION, SYNTAX PARMS>
315 ;******************************************************************************
316 ; SUBROUTINE NAME : SCREENING - CHECKS THE FOLLOWING: *
317 ; - DOS VERSION *
318 ; - DRIVE ID VALIDITY *
319 ; - FILE NAME ENTERED BY MISTAKE? *
320 ; INPUT : BL : DRIVE VALIDITY BYTE *
321 ; OUTPUT : DX : FINE - NO ERROR *
322 ; (OTHERS)- ERROR MSG OFFSET *
323 ;******************************************************************************
324 ;SCREENING PROC NEAR
325
326 ;CHECK DOS VERSION:
327 ; MOV AH,DOSVER_FUNC ;SEE IF CORRECT DOS VERSION
328 ; INT 21H ;FUNCTION CALL (AL <- DOS VERSION)
329 ;; XCHG AH,AL ;AH=MAJOR VER, AL=MINOR VER
330 ; CMP AX,expected_version ;IF DOS MAJOR VERSION LESS THAN 2.0
331 ; $IF NE ;THEN ISSUE ERROR MSG
332 ; MOV DX,OFFSET MSG_INVALID_DOS
333 ; MOV AH,PRINT_FUNC ;USE PRINT FUNCTION TO TELL USER
334 ; INT 21H ;THAT HE IS USING THE OLD VERSION
335 ; INT 20H
336 ; $ELSE ;VERSION OK
337 ; CALL CHK_PARA ;GENERAL SYNTAX CHECK
338 ; $ENDIF ;END VERSION TEST
339 ; RET
340 ;SCREENING ENDP
341 ; HEADER <CHK_PARA - SYNTAX PARMS, OPTION /1 /8>
342 ;;**************************************************************************
343 ;CHK_PARA PROC NEAR
344 ;; CHECK SYNTAX OF THE ENTERED PARAMETERS *
345 ;; ALSO, DETERMINE THE USER OPTION "/1" AND/OR "/8" IS ENTERED. *
346 ;; INPUT: DX = FINE *
347 ;; IF /1 HAS BEEN ENTERED, THE VARIABLE USER_OPTION = OPTION_1 *
348 ;; ELSE USER_OPTION = NO_OPTION. *
349 ;; IF /8 HAS BEEN ENTERED, THE USER_OPTION_8 WILL BE ON *
350 ;; OUTPUT: DX = FINE - NO ERROR *
351 ;; OTHERWISE DX POINTS TO ERROR MSG *
352 ;;**************************************************************************
353 ; PUSH CX
354 ; MOV USER_OPTION, NO_OPTION ;ASSUME NO /1 IS ENTERED.
355 ; MOV USER_OPTION_8, OFF ;ASSUME /8 IS NOT ENTERED.
356 ; XOR CX, CX
357 ; MOV CL, BYTE PTR DS:BEGIN_UNFORM_AREA ;GET # OF CHR
358 ; CMP CL, 0
359 ; JZ CHK_PARA_EXIT
360 ; CLD ;CLEAR DIRECTION
361 ; MOV DI, BEGIN_UNFORM_AREA+2 ;STARTING POINT OF PARA
362 ; DEC CL ;TO IGNORE LAST CHR (0DH)
363 ; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY. THE POINTER WILL POINT TO THE NEXT NON_BLANK CHR
364 ; JZ CHK_PARA_EXIT ;ONLY BLANKS ARE ENTERED.
365 ; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 OR /8 ?
366 ; JNC SLASH_ONE ;YES
367 ; CALL CHK_DRV_SPEC ;IS IT A DRIVE SPECIFICATION LIKE d: ?
368 ; JC INVALID_PARA ;IF NOT, THEN ERROR
369 ; JZ CHK_PARA_EXIT ;NO MORE CHR? THEN, OK. (EX. DISKCOMP D:)
370 ; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 OR /8 ?
371 ; JNC SLASH_ONE ;YES.(EX. DISKCOMP D:/1)
372 ; CALL CHK_BLANK ;IF NOT, NEXT CHR SHOULD BE A BLANK.
373 ; JC INVALID_PARA ;OTHERWISE, ERROR.
374 ; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY.
375 ; JZ CHK_PARA_EXIT ;(EX. DISKCOMP D: )
376 ; CALL CHK_SLASH_ONE ;IS IT /1 OR /8 ?
377 ; JNC SLASH_ONE ;YES. (EX. DISKCOMP D: /1)
378 ; CALL CHK_DRV_SPEC ;IF NOT /1 OR /8, THEN IS IT A DRV SPEC?
379 ; JC INVALID_PARA ;OTHERWISE, ERROR.
380 ; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY.
381 ; JZ CHK_PARA_EXIT ;NO MORE CHR. (EX. DISKCOMP D: D:)
382 ; CALL CHK_SLASH_ONE ;OTHERWISE, /1 AND/OR /8 SHOULD BE FOLLOWED.
383 ; JNC SLASH_ONE ;YES, /1 OR /8. JMP TO SLASH_ONE
384 ; JMP INVALID_PARA ;PARAMETER ERROR.
385 ;SLASH_ONE: ;YES, FOUND EITHER OF /1 OR /8.
386 ; CALL SKIP_BLANKS ;/1 SHOULD BE END OF PARAMETERS, OR ONLY BLANKS CAN FOLLOW.
387 ; JZ CHK_PARA_EXIT ;NO MORE CHR? THEN OK.
388 ; CMP USER_OPTION, OPTION_1 ;WAS IT /1?
389 ; JZ SLASH_8 ;THEN CHECK WHETHER NEXT IS /8.
390 ; CALL CHK_SLASH_ONE ;OTHERWISE, IT WAS /8. NOW CHECK /1.
391 ; JC INVALID_PARA ;NOT FOUND, ERROR
392 ; CMP USER_OPTION, OPTION_1
393 ; JZ CHK_PRE_EXIT ;YES, IT IS /1
394 ; JMP INVALID_PARA ;OTHERWISE, FOUND /8 AGAIN. ERROR
395 ;SLASH_8:
396 ; CALL CHK_SLASH_ONE ;CHECK IT IS /8
397 ; JC INVALID_PARA ;NOT FOUND? ERROR
398 ; CMP USER_OPTION_8, ON
399 ; JZ CHK_PRE_EXIT ;YES. IT IS /8
400 ; JMP INVALID_PARA ;OTHERWISE, FOUND /1 AGAIN. ERROR
401 ;CHK_PRE_EXIT:
402 ; CALL SKIP_BLANKS ;SKIP BLANKS IF ANY.
403 ; JZ CHK_PARA_EXIT ;THERE SHOULD NOT BE ANY MORE PARAMETER.
404 ;INVALID_PARA:
405 ; MOV DX,OFFSET MSG_INVALID_PARM_PTR ;WRONG PARM ENTERED MSG
406 ;CHK_PARA_EXIT:
407 ; POP CX
408 ;
409 ; RET
410 ;CHK_PARA ENDP
411 ; HEADER <SKIP_BLANKS - IGNORE BLANKS/TABS IN PARMS PARSING>
412 ;***************************************************************************
413 ;SKIP_BLANKS PROC NEAR
414 ; ** SKIP BLANKS OR TABS, IF ANY, IN THE PARAMETER STRING. *
415 ; INPUT: ES:DI POINTS TO THE CURRENT CHR. *
416 ; CX - # OF REMAINING CHR IN THE STRING. *
417 ; OUTPUT: ES:DI POINT TO THE NEXT NON_BLANK CHR. *
418 ; CX IS ADJUSTED ACCORINGLY. *
419 ; IF THE CURRENT CHR IS NOT A BLANK, THEN DI, CX VALUE NOT CHANGED.*
420 ; IF CX = 0, THEN ZERO FLAG WILL BE SET AND EXIT THIS PROC. *
421 ;***************************************************************************
422 ;SKIP_AGAIN:
423 ; MOV AL, 20H ;20H=BLANK
424 ; CLD ;CLEAR DIRECTION
425 ; REPE SCASB
426 ; JZ SK_BL_1 ;IF NOT FOUND A NON_BLANK CHR YET, AND CX=0, EXIT THIS ROUTINE.
427 ; DEC DI ;OTHERWISE, RESTORE DI TO THE NON_BLANK POSITION.
428 ; INC CX ; AND RESTORE CX TO WHERE IT WAS AT NON_BLANK CHR
429 ; ;(IF FOUND A NON_BLANK CHR, ZERO FLAG WOULD NOT BE SET)
430 ; MOV AL, ES:BYTE PTR [DI]
431 ; CMP AL, 09H ;09H=TAB
432 ; JNZ SK_BL_1 ;IF THE NON_BLANK CHR IS NOT A TAB THEN EXIT
433 ; INC DI ;ELSE TRY SKIP AGAIN.
434 ; DEC CX
435 ; JMP SKIP_AGAIN
436 ;SK_BL_1:
437 ; RET
438 ;SKIP_BLANKS ENDP
439 ; HEADER <CHK_SLASH - IS CURRENT PARM /1 OR /8>
440 ;;***************************************************************************
441 ;CHK_SLASH_ONE PROC NEAR
442 ; ** CHECK CURRENT CHR IS / FOLLOWED BY 1. *
443 ; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. *
444 ; CX REPRESENTS THE # OF CHR'S IN THE STRING. *
445 ; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX CHANGED ACCORDINGLY. *
446 ; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. *
447 ; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
448 ;***************************************************************************
449
450 ; CLC ;CLEAR CARRY FLAG
451 ; CMP CX, 2 ;# OF CHR IN THE STRING.
452 ; JL CK_SL_0 ;IF LESS THAN 2, THEN SET CARRY AND EXIT.
453 ; MOV AX, ES:WORD PTR [DI] ;GET CURRENT WORD IN AX
454 ; CMP AX, '1/' ;IS IT /1 ?
455 ; JZ CK_SL_1 ;YES. SET USER_OPTION
456 ; CMP AX, '8/' ;IS IT /8 THEN ?
457 ; JZ CK_SL_2 ;YES. SET USER_OPTION_8
458 ;CK_SL_0:
459 ; STC ;OTHERWISE, NOT FOUND. SET CARRY
460 ; JMP CK_SL_4 ; AND RETURN
461 ;CK_SL_1:
462 ; MOV USER_OPTION, OPTION_1
463 ; JMP CK_SL_3
464 ;CK_SL_2:
465 ; MOV USER_OPTION_8, ON
466 ;CK_SL_3: ;ADJUST CX, DI TO THE NEXT CHR.
467 ; INC DI
468 ; INC DI
469 ; DEC CX
470 ; DEC CX
471 ; CMP CX, 0 ;SET ZERO FLAG IF NO MORE CHR.
472 ;CK_SL_4:
473 ; RET
474 ;CHK_SLASH_ONE ENDP
475 ; HEADER <CHK_DRV - CURRENT PARM CHAR IS DRIVE AND COLON?>
476 ;;***************************************************************************
477 ;CHK_DRV_SPEC PROC NEAR
478 ; ** CHECK CURRENT CHR IS ALPHA CHR FOLLOWED BY COLON. *
479 ; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. *
480 ; CX -- # OF CHR IN THE STRING. *
481 ; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX ADJUSTED ACCORDINGLY. *
482 ; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. *
483 ; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
484 ;***************************************************************************
485
486 ; CLC ;CLEAR CARRY
487 ; CMP CX, 2 ;# OF CHR REMAINING IN THE STRING.
488 ; JL CK_DR_1 ;IF LESS THAN 2, THEN NOT FOUND - SET CARRY AND EXIT.
489 ; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR
490 ; AND AL, 11011111B ;CHANGE IT TO UPPER_CASE CHR.
491 ; CMP AL, 'A'
492 ; JB CK_DR_1 ;LESS THAN 'A', THEN NOT FOUND.
493 ; CMP AL, 'Z'
494 ; JA CK_DR_1 ;ABOVE 'Z', THEN NOT FOUND.
495 ; MOV AL, ES:BYTE PTR [DI+1] ;LOOK AHEAD THE FOLLOWING CHR.
496 ; CMP AL, ':' ;SHOULD BE A COLON.
497 ; JNZ CK_DR_1 ;NOT FOUND.
498 ; INC DI ;FOUND. ADJUST CX, DI TO THE NEXT CHR.
499 ; INC DI
500 ; DEC CX
501 ; DEC CX
502 ; CMP CX, 0 ;IF NO MORE CHR, THAN SET THE ZERO FLAG.
503 ; JMP CK_DR_2
504 ;CK_DR_1:
505 ; STC ;SET CARRY
506 ;CK_DR_2:
507 ; RET
508 ;CHK_DRV_SPEC ENDP
509 ; HEADER <CHK_BLANK - IS CURRENT CHAR IN PARM BLANK OR TAB>
510 ;;***************************************************************************
511 ;CHK_BLANK PROC NEAR
512 ;; ** CHECK THE CURRENT CHR IS A BLANK OR A TAB. *
513 ;; INPUT: ES:DI POINTS TO THE CURRENT CHR. *
514 ;; CX - # OF CHR IN THE STRING. *
515 ;; OUTPUT: FOUND - DI MOVES TO THE NEXT CHR. CX DECREASES BY 1. *
516 ;; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
517 ;;***************************************************************************
518 ;
519 ; CLC ;CLEAR CARRY
520 ; CMP CX, 1 ;IF LESS THAN 1, NOT FOUND.
521 ; JL CK_BL_0 ;SET CARRY AND EXIT
522 ; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR
523 ; CMP AL, 020H ;020H=BLANK CHR
524 ; JZ CK_BL_1 ;FOUND
525 ; CMP AL, 09H ;09H=TAB CHR
526 ; JZ CK_BL_1 ;FOUND
527 ;CK_BL_0:
528 ; STC ;NOT FOUND. SET CARRY
529 ; JMP CK_BL_2
530 ;CK_BL_1:
531 ; INC DI ;FOUND. ADJUST DI, CX
532 ; DEC CX
533 ;CK_BL_2:
534 ; RET
535 ;CHK_BLANK ENDP
536 .LIST
537 HEADER <PC_386_CHK - SEE IF THIS IS A 386 MACHINE>
538 ; QUERIES THE BIOS TO DETERMINE WHAT TYPE OF
539 ; MACHINE WE ARE ON. WE ARE LOOKING FOR A 386.
540 ; THIS WILL BE USED TO DETERMINE IF A DOUBLE WORD MOVE
541 ; IS TO BE PERFORMED.
542 ;
543 ; INPUTS : NONE
544 ;
545 ; OUTPUTS : IF A 386 NOT PRESENT, CODE IS
546 ; *** P A T C H E D ***
547 ; TO NO-OP THE SUPPORT FOR THE DOUBLE WORD MOVE
548 ;=========================================================================
549
550 PC_386_CHK PROC NEAR ;DETERMINE MACHINE TYPE ;AN001;
551
552 PUSH AX ;SAVE AFFECTED REGS ;AN001;
553 PUSH BX ; ;AN001;
554 PUSH ES ; ;AN001;
555
556 MOV AH,0C0H ;RETURN SYSTEM CONFIGURATION ;AN001;
557 INT 15H ;ES:[BX] POINTS TO BIOS ;AN001;
558 ; SYSTEM DESCRIPTOR
559 ASSUME ES:NOTHING ;AN001;
560
561 ; $IF C,OR ;IF NOT A GOOD RETURN, OR... ;AN001;
562 JC $$LL9
563 CMP AH,0 ;IS IT NEW FORMAT FOR CONFIG. ;AN001;
564 ; $IF NE,OR ;NO, OR... ;AN001;
565 JNE $$LL9
566 CMP ES:[BX].BIOS_SD_MODELBYTE,0F8H ;CHECK MODEL ;AN001;
567 ; $IF NE ;IF IT IS NOT A 386 MACHINE? ;AN001;
568 JE $$IF9
569 $$LL9:
570 ;PATCH OUT THE 386 CODE
571 MOV AL,NOOP ;WITH A NO-OP INSTRUCTION ;AN001;
572 MOV PATCH_386,AL ; ;AN001;
573 MOV PATCH_386+1,AL ; ;AN001;
574 MOV PATCH_386+2,AL ; ;AN001;
575 ; $ENDIF ; ;AN001;
576 $$IF9:
577
578 POP ES ;RESTORE REGS. ;AN001;
579 ASSUME ES:CSEG ;BACK TO USUAL ;AN001;
580
581 POP BX ; ;AN001;
582 POP AX ; ;AN001;
583
584 RET ; ;AN001;
585
586 PC_386_CHK ENDP ; ;AN001;
587 HEADER <SOURCE_TARGET_DRV - CONVERT SRC/TARGET DR TO BIOS VALS> ; ;AN000;
588 ;******************************************************************************
589 ; SUBROUTINE NAME : SOURCE_TARGET_DRV DETERMINES SOURCE & TARGET DRIVES & *
590 ; CONVERT THEM FROM DOS TO BIOS VALUE *
591 ; INPUT : SOURCE_DRIVE & TARGET_DRIVE HAVE DOS DRIVE ID'S: *
592 ; 0 = DEFAULT 1 = DRV A ETC. *
593 ; *
594 ; OUTPUT : ORG_SOURCE_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
595 ; : ORG_TARGET_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
596 ; *
597 ; : COPY_TYPE 1 = SINGLE DRV COPY, 2 = 2 DRIVE COPY *
598 ; : DX : FINE - NO ERROR *
599 ;******************************************************************************
600 SOURCE_TARGET_DRV PROC NEAR
601 PUBLIC SOURCE_TARGET_DRV ;MAKE ENTRY IN LINK MAP ;AN000;
602 ;GET CURRENT DEFAULT DRIVE
603 MOV AH,CURRENTDRV_FUNC ;FUNCTION CALL (19H)
604 ;(AL <- CURRENT DEFAULT DRV
605 INT 21H ;0 = A, 1 = B, ETC)
606
607 MOV DEFAULT_DRV,AL ;SAVE IT
608
609 CMP SOURCE_DRIVE,ZERO ;FIRST DRV ENTERED? ;AC000;
610 ; $IF E ;NO DRIVE LETTER ENTERED
611 JNE $$IF11
612 MOV CH, DEFAULT_DRV ;SET SOURCE, TARGET DRIVE TO
613 INC CH
614 MOV ORG_SOURCE_DRIVE, CH ;DEFAULT DRIVE
615 MOV CL, CH
616 MOV ORG_TARGET_DRIVE, CL
617 ; $ELSE
618 JMP SHORT $$EN11
619 $$IF11:
620 MOV CH,SOURCE_DRIVE ;GET SOURCE DRIVE FROM SPECIFIED PARM ;AC000;
621 MOV ORG_SOURCE_DRIVE, CH
622 CMP TARGET_DRIVE,ZERO ;WAS A SECOND DRIVE SPECIFIED ;AC000;
623 ; $IF E ;TARGET DRIVE IS DEFAULT
624 JNE $$IF13
625 MOV CL, DEFAULT_DRV
626 INC CL ;MAKE IT A LOGICAL DRIVE NUMBER
627 MOV ORG_TARGET_DRIVE, CL
628 ; $ELSE
629 JMP SHORT $$EN13
630 $$IF13:
631 MOV CL, TARGET_DRIVE ;USE USER SPECIFIED TARGET DRIVE ;AC000;
632 MOV ORG_TARGET_DRIVE, CL
633 ; $ENDIF
634 $$EN13:
635 ; $ENDIF
636 $$EN11:
637
638 ADD ASCII_DRV1_ID,CH ;SETUP DRIVE ID ALPHABET IN THE
639 ADD ASCII_DRV2_ID,CL ;MESSAGES
640
641 RET
642 SOURCE_TARGET_DRV ENDP
643 HEADER <TEST_DRIVE_VALIDITY - ARE SOURCE/TARGET DRIVES VALID?> ; ;AN000;
644 ;******************************************************************************
645 ; SUBROUTINE NAME : TEST_DRIVE_VALIDITY--MAKE SURE SOURCE AND TARGET DRIVES *
646 ; SPECIFIED BY USER ARE VALID FOR DISKCOPY *
647 ; *
648 ; INPUT : ORG_SOURCE_DRIVE:BYTE, ORG_TARGET_DRIVE:BYTE *
649 ; *
650 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
651 ;******************************************************************************
652
653 TEST_DRIVE_VALIDITY PROC NEAR
654 PUBLIC TEST_DRIVE_VALIDITY ;MAKE ENTRY IN LINK MAP ;AN000;
655
656 CALL DOS_DRIVE_VALIDITY
657
658 CMP DX,FINE
659 ; $IF E,AND ; ;AC000;
660 JNE $$IF17
661
662 MOV BL,ORG_SOURCE_DRIVE
663 CALL CHECK_REDIRECTION
664
665 CMP DX,FINE
666 ; $IF E,AND ; ;AC000;
667 JNE $$IF17
668
669 MOV BL,ORG_TARGET_DRIVE
670 CALL CHECK_REDIRECTION
671
672 CMP DX,FINE
673 ; $IF E,AND ; ;AC000;
674 JNE $$IF17
675
676 MOV BL,ORG_SOURCE_DRIVE
677 CALL CHECK_SERVER
678
679 CMP DX,FINE
680 ; $IF E,AND ; ;AC000;
681 JNE $$IF17
682
683 MOV BL,ORG_TARGET_DRIVE
684 CALL CHECK_SERVER
685
686 CMP DX,FINE
687 ; $IF E,AND ; ;AC000;
688 JNE $$IF17
689
690 CALL TEST_REMOVABLE
691
692 CMP DX,FINE
693 ; $IF E ; ;AC000;
694 JNE $$IF17
695
696 CALL CHK_SINGLE_DRV_OP ;CHECK IF IT IS
697 ; ONE PHYSICAL DRIVE OPERATION
698 ; $ENDIF ; ;AC000;
699 $$IF17:
700 RET
701
702 TEST_DRIVE_VALIDITY ENDP
703 HEADER <DOS_DRIVE_VALIDITY - CHECK DOS DRIVE VALIDITY BYTE>
704 ;******************************************************************************
705 ; SUBROUTINE NAME : DOS_DRIVE_VALIDITY -- CHEKC DOS DRIVE VALIDITY BYTE *
706 ; *
707 ; INPUT : DRIVE_VALID:BYTE *
708 ; THIS IS THE ORIGINAL VALUE PRESENTED IN AX BY DOS LOADER *
709 ; *
710 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
711 ;******************************************************************************
712
713 DOS_DRIVE_VALIDITY PROC NEAR
714 PUBLIC DOS_DRIVE_VALIDITY ;MAKE ENTRY IN LINK MAP ;AN000;
715
716 CMP DRIVE_VALID,0 ;SEE IF DRIVES ARE VALID DOS DEVICE
717 ; $IF NE
718 JE $$IF19
719 MOV DX,OFFSET MSGNUM_INVALID_DRV ;AC000;
720 ; $ENDIF
721 $$IF19:
722 RET
723
724 DOS_DRIVE_VALIDITY ENDP
725 HEADER <TEST_REMOVABLE - IS SPECIFIED DRIVE REMOVABLE?>
726 ;******************************************************************************
727 ; SUBROUTINE NAME : TEST_REMOVABLE -- CHECK IF DRIVES SPECIFED ARE REMOVABLE *
728 ; *
729 ; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE *
730 ; *
731 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
732 ;******************************************************************************
733
734 TEST_REMOVABLE PROC NEAR
735 PUBLIC TEST_REMOVABLE ;MAKE ENTRY IN LINK MAP ;AN000;
736
737 MOV BL,ORG_SOURCE_DRIVE ;GET PARM 1 DRIVE ID
738
739 MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE
740 INT 21H ;IOCTL CALL
741
742 ; $IF NC ;IF DRIVE ID IS WITHIN RANGE
743 JC $$IF21
744 CMP AX,REMOVABLE ;THEN IF SOURCE DRIVE IS FIXED
745 ; $IF NE ; THEN
746 JE $$IF22
747 MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000;
748 ; HARD DRIVE ERROR MESSAGE
749 ; $ELSE ;ELSE, SRC IS REMOVABLE;
750 JMP SHORT $$EN22
751 $$IF22:
752 MOV BL,ORG_TARGET_DRIVE ;NOW GO CHECK TARGET
753 MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE
754 INT 21H ;IOCTL CALL
755
756 ; $IF NC ;IF DRV WITHIN RANGE
757 JC $$IF24
758 CMP AX,REMOVABLE ;THEN TGT DRV IS FIXED
759 ; $IF NE ; THEN
760 JE $$IF25
761 MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000;
762 ; HARD DRV ERROR MSG
763 ; $ENDIF ;END TEST IF TGT DRV IS FIXED
764 $$IF25:
765 ; $ELSE ;TGT DRV OUT OF RANGE. EX. DRIVE X:
766 JMP SHORT $$EN24
767 $$IF24:
768 MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000;
769 ; HARD DRV ERROR MSG
770 ; $ENDIF ;END TEST IF TGT WITHIN RANGE
771 $$EN24:
772 ; $ENDIF ;END IF SRC IS REMOVABLE
773 $$EN22:
774 ; $ELSE ;ELSE, SRC DRV OUT OF RANGE
775 JMP SHORT $$EN21
776 $$IF21:
777 MOV DX,OFFSET MSGNUM_INVALID_DRV ;PRINT ERROR MSG ;AC000;
778 ; $ENDIF ;END TEST IF SRC DRV WITHIN RANGE
779 $$EN21:
780 RET
781
782 TEST_REMOVABLE ENDP
783 HEADER <CHK_SINGLE_DRIV_OP - IS TARGET DRIVE SAME AS SOURCE?>
784 ;******************************************************************************
785 ; SUBROUTINE NAME : CHK_SINGLE_DRV_OP *
786 ; *
787 ; INPUT : ORG_SOURCE_DRIVE - LOGICAL DRIVE NUMBER *
788 ; ORG_TARGET_DRIVE *
789 ; *
790 ; OUTPUT : COPY_TYPE WILL BE SET TO ONE OR TWO DEPENDING ON THE *
791 ; TEST RESULT. IF IT IS A SINGLE DRIVE COPY, THEN *
792 ; TARGET DRIVE LETTER WILL BE CHANGED TO THAT OF SOURCE. *
793 ; THE OWNERSHIP OF THE SOURCE AND TARGET DRIVE LETTER *
794 ; MIGHT HAVE BEEN CHANGED. *
795 ; SO, BEFORE EXIT TO DOS, THEY SHOULD BE RESET TO THE SAVED*
796 ; ONE USING S_OWNER_SAVED AND T_OWNER_SAVED UNLESS THEY *
797 ; ARE EQUAL TO 0. (0 MEANS ONLY ONE DRIVE LETTER ASSIGNED.)*
798 ; ASCII_DRV1_ID, ASCII_DRV2_ID MAY BE CHANGED ACCORDINGLY. *
799 ;******************************************************************************
800
801 CHK_SINGLE_DRV_OP PROC NEAR
802 PUBLIC CHK_SINGLE_DRV_OP ;MAKE ENTRY IN LINK MAP ;AN000;
803
804 PUSH AX
805
806 MOV BL,ORG_SOURCE_DRIVE
807 CALL GET_LOGICAL_DRIVE
808
809 MOV S_OWNER_SAVED, AL ;SAVE CURRENT OWNER DRIVE LETTER.
810 MOV BL, ORG_TARGET_DRIVE
811 CALL GET_LOGICAL_DRIVE
812
813 MOV T_OWNER_SAVED, AL ;SAVE CURRENT OWNER
814 MOV BL, ORG_SOURCE_DRIVE
815 CALL SET_LOGICAL_DRIVE
816
817 MOV BL, ORG_TARGET_DRIVE
818 CALL SET_LOGICAL_DRIVE
819
820 MOV BL, ORG_SOURCE_DRIVE
821 CALL GET_LOGICAL_DRIVE ;CHECK IF SOURCE DRIVE OWNERSHIP HAS NOT BEEN CHAGNED?
822
823 CMP AL, ORG_SOURCE_DRIVE
824 ; $IF NE ;IF IT HAS BEEN CHANGED TO TARGET, THEN A SINGLE DRIVE COMPARE.
825 JE $$IF32
826 MOV COPY_TYPE, ONE
827 MOV BL, ORG_SOURCE_DRIVE
828 MOV ORG_TARGET_DRIVE, BL ;SET TARGET DRV LETTER TO THE SOURCE.
829 MOV BL, ASCII_DRV1_ID
830 MOV ASCII_DRV2_ID, BL
831 MOV BL, ORG_SOURCE_DRIVE
832 CALL SET_LOGICAL_DRIVE ;SET THE OWNER BACK TO SOURCE DRV LETTER
833
834 ; $ELSE
835 JMP SHORT $$EN32
836 $$IF32:
837 CMP AL, ORG_TARGET_DRIVE ; SOURCE DRV LETTER = TARGET DRV LETTER CASE, FOR EX. DISKCOMP A: A:
838 ; $IF E
839 JNE $$IF34
840 MOV COPY_TYPE, ONE
841 ; $ELSE
842 JMP SHORT $$EN34
843 $$IF34:
844 MOV COPY_TYPE, TWO
845 ; $ENDIF
846 $$EN34:
847 ; $ENDIF
848 $$EN32:
849
850 POP AX
851
852 RET
853 CHK_SINGLE_DRV_OP ENDP
854 HEADER <GET_LOGICAL_DRIVE - GET LOG. DRIV NO. WHO OWNS PHYSICAL DRIVE>
855 ;******************************************************************************
856 GET_LOGICAL_DRIVE PROC NEAR
857 PUBLIC GET_LOGICAL_DRIVE ;MAKE ENTRY IN LINK MAP ;AN000;
858 ; *** GET THE LOGICAL DRIVE NUMBER WHO HAS THE OWNERSHIP OF THE PHYSICAL
859 ; DRIVE.
860 ; INPUT: BL = DRIVE NUMBER (0=DEFAULT, 1=A, 2=B...)
861 ; OUTPUT: AL = DRIVE NUMBER (0= ONLY ONE DRIVE LETTER ASSIGNED TO THE
862 ; BLOCK DEVICE. OTHERWISE, 1=A, 2=B...)
863 ;
864 ;******************************************************************************
865
866 MOV AH, 44H
867 MOV AL, 0EH ; GET THE OWNER OF LOGICAL DRIVE NUMBER
868 INT 21H
869
870 CMP AL, 0 ;ONLY ONE DRIVE LETTER ASSIGNED?
871 ; $IF E
872 JNE $$IF38
873 MOV AL, BL ;THEN SET IT TO THE INPUT DRIVE LETTER
874 ; $ENDIF
875 $$IF38:
876
877 RET
878
879 GET_LOGICAL_DRIVE ENDP
880 HEADER <DISKETTE_DRV_TYPE - CHECK COMPATABILITY SOURCE/TARGET DRIVES>
881 ;******************************************************************************
882 ; SUBROUTINE NAME : DISKETTE_DRV_TYPE DOES THE FOLLOWING: *
883 ; - GETS SOURCE, TARGET DRIVE INFORMATIONS *
884 ; - CHECK IF IT IS A REMOVABLE DRIVE. *
885 ; INPUT : SOURCE_DRIVE & TARGET_DRIVE *
886 ; 1 = DRIVE A 2 = DRIVE B, ETC. *
887 ; *
888 ; OUTPUT : DX : FINE - NO ERROR *
889 ; (OTHERS)- ERROR MSG OFFSET *
890 ;******************************************************************************
891 DISKETTE_DRV_TYPE PROC NEAR
892 PUBLIC DISKETTE_DRV_TYPE ;MAKE ENTRY IN LINK MAP ;AN000;
893
894 PUSH AX
895 XOR BX,BX
896 MOV BL, ORG_SOURCE_DRIVE
897 MOV CL, GETDEVPARM ;=60h
898 MOV DX, OFFSET DS_IOCTL_DRV_PARM ;POINTER TO THE CONTROL STRING
899 CALL GENERIC_IOCTL ;GET DEVICE PARM.
900
901 TEST DS_deviceAttributes, 0001h ;CHECK REMOVABLE. 0001 = NOT REMOVABLE
902 ; $IF E,AND ;NO, CONTINUE ;AC000;
903 JNE $$IF40
904
905 MOV AX, DS_numberOfCylinders ;CURRENTLY IGNORE AH. ASSUME LESS
906 ; THAN TWO BYTES
907 MOV S_DRV_TRACKS, AL
908 MOV BX, OFFSET DS_BPB_PTR
909 MOV AX, [BX].CHead
910 MOV S_DRV_HEADS, AL
911 MOV AX, [BX].CSECT_TRACK
912 MOV S_DRV_SECT_TRACK, AL
913 MOV AX, [BX].CBYTE_SECT ;RECOMMENDED BYTES/SECTOR
914 MOV RECOMMENDED_BYTES_SECTOR, AX
915
916 XOR BX,BX
917 MOV BL, ORG_TARGET_DRIVE
918 MOV CL, GETDEVPARM
919 MOV DX, OFFSET DT_IOCTL_DRV_PARM
920 CALL GENERIC_IOCTL
921
922 TEST DT_deviceAttributes, 0001h
923 ; $IF Z ;TARGET IS NOT FIXED DISK, OK ;AC000;
924 JNZ $$IF40
925 MOV AX, DT_numberOfCylinders
926 MOV T_DRV_TRACKS, AL
927 MOV BX, OFFSET DT_BPB_PTR
928 MOV AX, [BX].CHead
929 MOV T_DRV_HEADS, AL
930 MOV AX, [BX].CSECT_TRACK
931 MOV T_DRV_SECT_TRACK, AL
932
933 ;*** CHECK DEVICE COMPATIBILITY
934 MOV DX, FINE ;GUESS, ALL WILL BE OK
935 ; DX MAY BE CHANGED TO REFLECT ERROR
936 CMP DS_deviceType, DRV_720 ;0 - 48 TPI, 5.25", 96 TPI,
937 ; 5.25", 2 - 720kb, 3.5"
938 ; $IF E ;WILL ONLY ALLOW DISKCOPY BETWEEN ;AC000;
939 JNE $$IF41
940 ; 720KB, 3.5 SOURCE, TARGET
941
942 CMP DT_deviceType, DRV_720 ;target = 720KB also?
943 ; $IF NE ; ;AC000;
944 JE $$IF42
945 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000;
946 ; $ENDIF ; ;AC000;
947 $$IF42:
948 ; $ELSE ;SINCE SOURCE NOT 720 ;AC000;
949 JMP SHORT $$EN41
950 $$IF41:
951 CMP DT_deviceType, DRV_720 ;SOURCE IS NOT 720kb,
952 ; IS TARGET 720?
953 ; $IF E ;IF SO, THEN ;AC000;
954 JNE $$IF45
955 ;DDT IS NOT COMPATIBLE
956 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000;
957 ; $ENDIF ; ;AC000;
958 $$IF45:
959 ; $ENDIF ; ;AC000;
960 $$EN41:
961 ; $ELSE ;SINCE SOURCE IS FIXED DISK, ERROR ;AC000;
962 JMP SHORT $$EN40
963 $$IF40:
964 MOV DX, OFFSET MSGNUM_INVALID_DRV ;ISSUE INVALID DRV MSG ;AC000;
965 ; $ENDIF ; ;AC000;
966 $$EN40:
967 POP AX
968 RET
969
970 DISKETTE_DRV_TYPE ENDP
971 HEADER <CHECK_REDIRECTION - IS DEVICE REDIRECTED?>
972 ;******************************************************************************
973 ; SUBROUTINE NAME : CHECK_REDIRECTION FIND OUT IF DEVICE IS REDIRECTED *
974 ; IF IT IS, GENERATE ERROR MSG & EXIT *
975 ; INPUT : BL - DRIVE TO BE TESTED *
976 ; : AL : CURRENT DEFAULT DRIV *
977 ; *
978 ; OUTPUT : DX = LOCAL_DRV (-1) *
979 ; = DIRECTED ( ERROR MSG OFFSET) *
980 ; = INVALID_DRIVE (ERROR MSG OFFSET) *
981 ;******************************************************************************
982 CHECK_REDIRECTION PROC NEAR
983 PUBLIC CHECK_REDIRECTION ;MAKE ENTRY IN LINK MAP ;AN000;
984
985 PUSH AX ;SAVE REGISTERS
986 PUSH BX
987 PUSH CX
988
989 MOV CX,DX ;SAVE RET TEMPORARILY
990 MOV AH,IOCTL_FUNC ;GET IOCTL FUNTION &
991 MOV AL,REDIRECTED_FUNC ;IOCTL SUB-FUNCTION ******CHECK***
992
993 INT 21H ;AND GO FIND OUT IF IT'S LOCAL
994 ; $IF C
995 JNC $$IF50
996 MOV CX,OFFSET MSGNUM_INVALID_DRV ;REDIR INVALID ;AC000;
997
998 ; $ELSE
999 JMP SHORT $$EN50
1000 $$IF50:
1001 TEST DX,REMOTE_DRV ;IF DRIVE IS REDIRECTED
1002 ; $IF NZ
1003 JZ $$IF52
1004
1005 MOV CX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000;
1006 ; $ENDIF
1007 $$IF52:
1008 ; $ENDIF
1009 $$EN50:
1010 MOV DX,CX ;GET ERROR MSG @
1011
1012 POP CX ;RESTORE REGISTERS
1013 POP BX
1014 POP AX
1015 RET ;RETURN TO CALLER
1016 CHECK_REDIRECTION ENDP
1017 HEADER <BUFFER_SIZE - FINDS START AND END OF BUFFER>
1018 ;******************************************************************************
1019 ; SUBROUTINE NAME : BUFFER_SIZE DETERMINES WHERE BUFFER STARTS & ENDS *
1020 ; INPUT : NONE *
1021 ; *
1022 ; OUTPUT : BUFFER_BEGIN ADDRESS *
1023 ; : BUFFER_END ADDRESS *
1024 ; : START_BUFFER ADDRESS
1025 ;******************************************************************************
1026 BUFFER_SIZE PROC NEAR
1027 PUBLIC BUFFER_SIZE ;MAKE ENTRY IN LINK MAP ;AN000;
1028
1029 PUSH AX ;SAVE REGISTERS
1030 PUSH BX
1031 PUSH CX
1032 MOV BX,OFFSET init ;GET ADDR OF INIT+1024 AS A FREE MEMORY
1033 add bx, 1024 ;(OFFSET FROM CS, IN BYTES)
1034 MOV CL,4 ;CONVERT OFFSET INTO SEGMT BY DIVIDING
1035 SHR BX,CL ;IT BY 16
1036
1037 MOV AX,CS ;CS + OFFSET => INIT @ IN SEGMENT
1038 ADD BX,AX ;WHERE BUFFER CAN START
1039
1040 ;NEED TO START AT A NEW SECTOR ==>
1041 AND BL,CLEAR_SEGMENT ;TRUNCATE TO PREVIOUS 512 BYTE BOUNDRY
1042 ;(GET PREVIOUS SECTOR NUMBER)
1043 ADD BX,20H ;THEN, ADVANCE TO THE BEGINNING OF
1044 ;NEXT SECTOR (SINCE PART OF PREVIOUS
1045 ;SECTOR WAS USED)
1046
1047 MOV BUFFER_BEGIN,BX ;SAVE OUR BUFFER START SEGMENT ADDR
1048 MOV START_BUFFER,BX ;SAVE IT AGAIN ELSEWHERE
1049 ;(AT THE BEGINNING OF A SECTOR WITH
1050 ;SEGMENT BITS CLEARED)
1051
1052 MOV BX,DS:TWO ;GET ADDR WHERE BUFFER ENDS
1053 MOV BUFFER_END,BX ;(TOP OF MEMORY, OFFSET 2 IN PSP)
1054
1055 POP CX ;RESTORE REGISTERS
1056 POP BX
1057 POP AX
1058 RET ;RETURN TO CALLER
1059 BUFFER_SIZE ENDP
1060 HEADER <SETUP_CTRL_BREAK - SETUP THE CTRL-BREAK VECTOR>
1061 ;******************************************************************************
1062 SETUP_CTRL_BREAK PROC NEAR ;SETUP CTRL-BREAK VECTOR
1063 PUBLIC SETUP_CTRL_BREAK ;MAKE ENTRY IN LINK MAP ;AN000;
1064 ;******************************************************************************
1065 PUSH AX
1066 PUSH BX
1067 PUSH DX
1068 PUSH ES
1069
1070 MOV AX,2523H ;SET THE CTRL-BREAK VECTOR
1071 MOV DX,OFFSET MAIN_EXIT
1072 INT 21H
1073
1074 POP ES
1075 POP DX
1076 POP BX
1077 POP AX
1078 RET
1079
1080 SETUP_CTRL_BREAK ENDP
1081 HEADER <CHECK_SERVER - IS SERVER OR REDIRECTOR LOADED?>
1082 ;******************************************************************************
1083 CHECK_SERVER PROC NEAR ;SEE IF SERVER OR REDIRECTOR IS IN++
1084 PUBLIC CHECK_SERVER ;MAKE ENTRY IN LINK MAP ;AN000;
1085 ;
1086 ; INPUT: BL = DRIVE NUMBER (1=A,2=B ETC....)
1087 ;******************************************************************************
1088 MOV AH,0 ;SEE IF SERVER LOADED
1089 INT SERVER
1090 CMP AH,0
1091 ; $IF E
1092 JNE $$IF55
1093 MOV DX,FINE
1094 ; $ELSE
1095 JMP SHORT $$EN55
1096 $$IF55:
1097 DEC BL
1098 ADD BL,"A" ;CONVERT TO ASCII DRIVE LETTER
1099 MOV ASCII_DRIVE_LETTER,BL ;PUT IN ASCIIZ STRING
1100 MOV SI,OFFSET ASCII_DRIVE_LETTER
1101 MOV AH,SHARED
1102 CLC
1103 INT SERVER
1104 ; $IF C
1105 JNC $$IF57
1106 MOV DX,OFFSET MSGNUM_DRV_REDIRECTED ;AC000;
1107 ; $ELSE
1108 JMP SHORT $$EN57
1109 $$IF57:
1110 MOV DX,FINE
1111 ; $ENDIF
1112 $$EN57:
1113 ; $ENDIF
1114 $$EN55:
1115 RET
1116 CHECK_SERVER ENDP
1117
1118 Public INIT_END
1119 INIT_END LABEL BYTE
1120 PATHLABL COMPINIT ;AN013;
1121 CSEG ENDS
1122 END
1123 \1a