1 PAGE
90,132 ;\ f\eA\b\e2
2 TITLE COMPINIT
-- DISKCOMP INITIALIZATION PROGRAM
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: COMPINIT
6 ; DESCRIPTIVE NAME: Initialization for Diskette to diskette copy Utility
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.
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.
17 ; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN".
19 ; INPUT: (DOS command line parameters)
21 ; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
24 ; [d:][path] - Path where the DISKCOMP command resides.
26 ; [d:] - To specify the Source drive
28 ; [d:] - To specify the Target drive
30 ; [/1] - To compare only the first side of the diskette,
31 ; regardless of the diskette or drive type.
33 ; [/8] - To compare only the first 8 sectors per track,
34 ; even if the first diskette contains 9/15 sectors
37 ; EXIT-NORMAL: Errorlevel = 0
38 ; Function completed successfully.
40 ; EXIT-ERROR: Errorlevel = 1
41 ; Abnormal termination due to error, wrong DOS,
42 ; invalid parameters, unrecoverable I/O errors on
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.
51 ; PATHMAC.INC - PATHGEN MACRO
52 ; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
54 ; INTERNAL REFERENCES:
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?
70 ; PSP - Contains the DOS command line parameters.
71 ; WORKAREA - Temporary storage
73 ; EXTERNAL REFERENCES:
75 ; SYSDISPMSG - Uses the MSG parm lists to construct the messages
77 ; SYSLOADMSG - Loads messages, makes them accessable.
78 ; PARSER - Processes the DOS Command line, finds parms.
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.
86 ; This module should be processed with the SALUT preprocessor
87 ; with the re-alignment not requested, as:
91 ; To assemble these modules, the alphabetical or sequential
92 ; ordering of segments may be used.
94 ; For instructions as to how to LINK, see prolog for DISKCOMP.
96 ;PROGRAM AUTHOR: Original written by: Jin K.
97 ; 4.00 modifications by: Edwin M. K.
98 ;****************** END OF SPECIFICATIONS *****************************
100 %
OUT COMPONENT
=DISKCOMP
, MODULE
=COMPINIT
.SAL
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.
111 INCLUDE PATHMAC
.INC ;AN013;
112 INCLUDE DCMPMACR
.INC ;(FORMERLY CALLED MACRO.DEF)
114 CSEG
SEGMENT PARA
PUBLIC 'CODE' ; ;AC000;
115 ASSUME
CS:CSEG
, DS:CSEG
, ES:CSEG
, SS:CSEG
118 NOOP EQU 90H
;NO-OPERTION INSTRUCTION, USED TO DELETE ;AN001;
119 ; 386 SUPPORT ;AN001;
121 ;****************************************************************************
123 ; EXTERNAL VARIABLES *
125 ;****************************************************************************
126 EXTRN PARSER
:NEAR ;DCOPYPAR.SAL - DRIVES SYS PARSER ;AN000;
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
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;
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;
149 ;EXTRN MSG_INVALID_DOS :BYTE ;MSG FOR DOS1.0 AND 1.1
152 EXTRN TRACK_TO_READ
:BYTE
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
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
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;
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
192 EXTRN MS_IOCTL_DRV_PARM
:BYTE ;DRIVE PARM FROM SOURCE MEDIUM
193 EXTRN MT_IOCTL_DRV_PARM
:BYTE
195 EXTRN PATCH_386
:BYTE ;PATCH AREA, CHANGED TO NOOP IF NOT 386 ;AN001;
197 EXTRN GENERIC_IOCTL
:NEAR
198 EXTRN SET_LOGICAL_DRIVE
:NEAR
199 ; $salut (4,24,28,41)
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
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;
223 bios_SD_featurebyte1 db ?
; ;AN001;
224 db 4 dup (?
) ; ;AN001;
225 BIOS_SYSTEM_DESCRIPTOR ends
;END OF STRUC ;AN001;
228 ;****************************************************************************
230 ; VARIABLE DECLARATIONS *
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
244 PUBLIC INIT
;MAKE ENTRY IN LINK MAP ;AN000;
246 ;OUTPUT: DX = EXIT CODE, "FINE"
247 ;#############################################################################
249 MOV DRIVE_VALID
,AX ;SAVE DRIVE VALIDITY BYTE
250 CALL PC_386_CHK
;SEE IF THIS IS A 386 MACHINE ;AN001;
252 ; REPLACE THE "FILL_SEG" IN THE SUBLIST MESSAGE CONTROL BLOCKS.
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".
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;
270 CALL SETUP_CTRL_BREAK
;STEALS CTRL_BREAK
271 CLD ;CLEAR DIRECTION FLAG
272 MOV DX,FINE
;ASSUME EVERYTHING IS FINE
274 ; CALL SCREENING ;CHECK DOS VERSION AND INPUT PARMS
275 ; CMP DX,FINE ;IF FINE & DANDY
278 CALL PARSER
;LOOK AT DOS COMMAND LINE ;AN000;
280 CMP DX,FINE
;IF ALL OK ;AN000;
283 CALL SOURCE_TARGET_DRV
;DETERMINE SOURCE AND TARGET DRV
287 CMP DX,FINE
;IF STILL FINE AND DANDY ;AN000;
290 CALL TEST_DRIVE_VALIDITY
295 CALL DISKETTE_DRV_TYPE
;SOURCE & TARGET DRIVE TYPES
297 CMP DX,FINE
;IF FINE & DANDY
300 CALL BUFFER_SIZE
;GET BUFFER SIZE FOR COPYING
308 RET ;RETURN TO CALLER
310 INIT ENDP
;END INITIALLIZATION PROGRAM
312 ;#############################################################################
314 ; HEADER <SCREENING - CHECK DOS VERSION, SYNTAX PARMS>
315 ;******************************************************************************
316 ; SUBROUTINE NAME : SCREENING - CHECKS THE FOLLOWING: *
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 ;******************************************************************************
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
337 ; CALL CHK_PARA ;GENERAL SYNTAX CHECK
338 ; $ENDIF ;END VERSION TEST
341 ; HEADER <CHK_PARA - SYNTAX PARMS, OPTION /1 /8>
342 ;;**************************************************************************
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 ;;**************************************************************************
354 ; MOV USER_OPTION, NO_OPTION ;ASSUME NO /1 IS ENTERED.
355 ; MOV USER_OPTION_8, OFF ;ASSUME /8 IS NOT ENTERED.
357 ; MOV CL, BYTE PTR DS:BEGIN_UNFORM_AREA ;GET # OF CHR
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 ?
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
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
402 ; CALL SKIP_BLANKS ;SKIP BLANKS IF ANY.
403 ; JZ CHK_PARA_EXIT ;THERE SHOULD NOT BE ANY MORE PARAMETER.
405 ; MOV DX,OFFSET MSG_INVALID_PARM_PTR ;WRONG PARM ENTERED MSG
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 ;***************************************************************************
423 ; MOV AL, 20H ;20H=BLANK
424 ; CLD ;CLEAR DIRECTION
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.
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 ;***************************************************************************
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
459 ; STC ;OTHERWISE, NOT FOUND. SET CARRY
460 ; JMP CK_SL_4 ; AND RETURN
462 ; MOV USER_OPTION, OPTION_1
465 ; MOV USER_OPTION_8, ON
466 ;CK_SL_3: ;ADJUST CX, DI TO THE NEXT CHR.
471 ; CMP CX, 0 ;SET ZERO FLAG IF NO MORE CHR.
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 ;***************************************************************************
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.
492 ; JB CK_DR_1 ;LESS THAN 'A', THEN NOT FOUND.
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.
502 ; CMP CX, 0 ;IF NO MORE CHR, THAN SET THE ZERO FLAG.
509 ; HEADER <CHK_BLANK - IS CURRENT CHAR IN PARM BLANK OR TAB>
510 ;;***************************************************************************
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 ;;***************************************************************************
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
525 ; CMP AL, 09H ;09H=TAB CHR
528 ; STC ;NOT FOUND. SET CARRY
531 ; INC DI ;FOUND. ADJUST DI, CX
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.
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 ;=========================================================================
550 PC_386_CHK PROC
NEAR ;DETERMINE MACHINE TYPE ;AN001;
552 PUSH AX ;SAVE AFFECTED REGS ;AN001;
556 MOV AH,0C0H ;RETURN SYSTEM CONFIGURATION ;AN001;
557 INT 15H
;ES:[BX] POINTS TO BIOS ;AN001;
559 ASSUME
ES:NOTHING
;AN001;
561 ; $IF C,OR ;IF NOT A GOOD RETURN, OR... ;AN001;
563 CMP AH,0 ;IS IT NEW FORMAT FOR CONFIG. ;AN001;
564 ; $IF NE,OR ;NO, OR... ;AN001;
566 CMP ES:[BX].BIOS_SD_MODELBYTE
,0F8H ;CHECK MODEL ;AN001;
567 ; $IF NE ;IF IT IS NOT A 386 MACHINE? ;AN001;
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;
578 POP ES ;RESTORE REGS. ;AN001;
579 ASSUME
ES:CSEG
;BACK TO USUAL ;AN001;
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. *
594 ; OUTPUT : ORG_SOURCE_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
595 ; : ORG_TARGET_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
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)
607 MOV DEFAULT_DRV
,AL ;SAVE IT
609 CMP SOURCE_DRIVE
,ZERO
;FIRST DRV ENTERED? ;AC000;
610 ; $IF E ;NO DRIVE LETTER ENTERED
612 MOV CH, DEFAULT_DRV
;SET SOURCE, TARGET DRIVE TO
614 MOV ORG_SOURCE_DRIVE
, CH ;DEFAULT DRIVE
616 MOV ORG_TARGET_DRIVE
, CL
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
626 INC CL ;MAKE IT A LOGICAL DRIVE NUMBER
627 MOV ORG_TARGET_DRIVE
, CL
631 MOV CL, TARGET_DRIVE
;USE USER SPECIFIED TARGET DRIVE ;AC000;
632 MOV ORG_TARGET_DRIVE
, CL
638 ADD ASCII_DRV1_ID
,CH ;SETUP DRIVE ID ALPHABET IN THE
639 ADD ASCII_DRV2_ID
,CL ;MESSAGES
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 *
648 ; INPUT : ORG_SOURCE_DRIVE:BYTE, ORG_TARGET_DRIVE:BYTE *
650 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
651 ;******************************************************************************
653 TEST_DRIVE_VALIDITY PROC
NEAR
654 PUBLIC TEST_DRIVE_VALIDITY
;MAKE ENTRY IN LINK MAP ;AN000;
656 CALL DOS_DRIVE_VALIDITY
659 ; $IF E,AND ; ;AC000;
662 MOV BL,ORG_SOURCE_DRIVE
663 CALL CHECK_REDIRECTION
666 ; $IF E,AND ; ;AC000;
669 MOV BL,ORG_TARGET_DRIVE
670 CALL CHECK_REDIRECTION
673 ; $IF E,AND ; ;AC000;
676 MOV BL,ORG_SOURCE_DRIVE
680 ; $IF E,AND ; ;AC000;
683 MOV BL,ORG_TARGET_DRIVE
687 ; $IF E,AND ; ;AC000;
696 CALL CHK_SINGLE_DRV_OP
;CHECK IF IT IS
697 ; ONE PHYSICAL DRIVE OPERATION
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 *
707 ; INPUT : DRIVE_VALID:BYTE *
708 ; THIS IS THE ORIGINAL VALUE PRESENTED IN AX BY DOS LOADER *
710 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
711 ;******************************************************************************
713 DOS_DRIVE_VALIDITY PROC
NEAR
714 PUBLIC DOS_DRIVE_VALIDITY
;MAKE ENTRY IN LINK MAP ;AN000;
716 CMP DRIVE_VALID
,0 ;SEE IF DRIVES ARE VALID DOS DEVICE
719 MOV DX,OFFSET MSGNUM_INVALID_DRV
;AC000;
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 *
729 ; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE *
731 ; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
732 ;******************************************************************************
734 TEST_REMOVABLE PROC
NEAR
735 PUBLIC TEST_REMOVABLE
;MAKE ENTRY IN LINK MAP ;AN000;
737 MOV BL,ORG_SOURCE_DRIVE
;GET PARM 1 DRIVE ID
739 MOV AX,DRIVE_CHECK
;CHECK FOR REMOVABLE DRIVE
742 ; $IF NC ;IF DRIVE ID IS WITHIN RANGE
744 CMP AX,REMOVABLE
;THEN IF SOURCE DRIVE IS FIXED
747 MOV DX,OFFSET MSGNUM_INVALID_DRV
;GENERATE ;AC000;
748 ; HARD DRIVE ERROR MESSAGE
749 ; $ELSE ;ELSE, SRC IS REMOVABLE;
752 MOV BL,ORG_TARGET_DRIVE
;NOW GO CHECK TARGET
753 MOV AX,DRIVE_CHECK
;CHECK FOR REMOVABLE DRIVE
756 ; $IF NC ;IF DRV WITHIN RANGE
758 CMP AX,REMOVABLE
;THEN TGT DRV IS FIXED
761 MOV DX,OFFSET MSGNUM_INVALID_DRV
;GENERATE ;AC000;
763 ; $ENDIF ;END TEST IF TGT DRV IS FIXED
765 ; $ELSE ;TGT DRV OUT OF RANGE. EX. DRIVE X:
768 MOV DX,OFFSET MSGNUM_INVALID_DRV
;GENERATE ;AC000;
770 ; $ENDIF ;END TEST IF TGT WITHIN RANGE
772 ; $ENDIF ;END IF SRC IS REMOVABLE
774 ; $ELSE ;ELSE, SRC DRV OUT OF RANGE
777 MOV DX,OFFSET MSGNUM_INVALID_DRV
;PRINT ERROR MSG ;AC000;
778 ; $ENDIF ;END TEST IF SRC DRV WITHIN RANGE
783 HEADER
<CHK_SINGLE_DRIV_OP
- IS TARGET DRIVE SAME
AS SOURCE?
>
784 ;******************************************************************************
785 ; SUBROUTINE NAME : CHK_SINGLE_DRV_OP *
787 ; INPUT : ORG_SOURCE_DRIVE - LOGICAL DRIVE NUMBER *
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 ;******************************************************************************
801 CHK_SINGLE_DRV_OP PROC
NEAR
802 PUBLIC CHK_SINGLE_DRV_OP
;MAKE ENTRY IN LINK MAP ;AN000;
806 MOV BL,ORG_SOURCE_DRIVE
807 CALL GET_LOGICAL_DRIVE
809 MOV S_OWNER_SAVED
, AL ;SAVE CURRENT OWNER DRIVE LETTER.
810 MOV BL, ORG_TARGET_DRIVE
811 CALL GET_LOGICAL_DRIVE
813 MOV T_OWNER_SAVED
, AL ;SAVE CURRENT OWNER
814 MOV BL, ORG_SOURCE_DRIVE
815 CALL SET_LOGICAL_DRIVE
817 MOV BL, ORG_TARGET_DRIVE
818 CALL SET_LOGICAL_DRIVE
820 MOV BL, ORG_SOURCE_DRIVE
821 CALL GET_LOGICAL_DRIVE
;CHECK IF SOURCE DRIVE OWNERSHIP HAS NOT BEEN CHAGNED?
823 CMP AL, ORG_SOURCE_DRIVE
824 ; $IF NE ;IF IT HAS BEEN CHANGED TO TARGET, THEN A SINGLE DRIVE COMPARE.
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
837 CMP AL, ORG_TARGET_DRIVE
; SOURCE DRV LETTER = TARGET DRV LETTER CASE, FOR EX. DISKCOMP A: A:
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
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...)
864 ;******************************************************************************
867 MOV AL, 0EH ; GET THE OWNER OF LOGICAL DRIVE NUMBER
870 CMP AL, 0 ;ONLY ONE DRIVE LETTER ASSIGNED?
873 MOV AL, BL ;THEN SET IT TO THE INPUT DRIVE LETTER
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. *
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;
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.
901 TEST DS_deviceAttributes
, 0001h ;CHECK REMOVABLE. 0001 = NOT REMOVABLE
902 ; $IF E,AND ;NO, CONTINUE ;AC000;
905 MOV AX, DS_numberOfCylinders
;CURRENTLY IGNORE AH. ASSUME LESS
908 MOV BX, OFFSET DS_BPB_PTR
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
917 MOV BL, ORG_TARGET_DRIVE
919 MOV DX, OFFSET DT_IOCTL_DRV_PARM
922 TEST DT_deviceAttributes
, 0001h
923 ; $IF Z ;TARGET IS NOT FIXED DISK, OK ;AC000;
925 MOV AX, DT_numberOfCylinders
927 MOV BX, OFFSET DT_BPB_PTR
930 MOV AX, [BX].CSECT_TRACK
931 MOV T_DRV_SECT_TRACK
, AL
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;
940 ; 720KB, 3.5 SOURCE, TARGET
942 CMP DT_deviceType
, DRV_720
;target = 720KB also?
945 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE
; ;AC000;
948 ; $ELSE ;SINCE SOURCE NOT 720 ;AC000;
951 CMP DT_deviceType
, DRV_720
;SOURCE IS NOT 720kb,
953 ; $IF E ;IF SO, THEN ;AC000;
955 ;DDT IS NOT COMPATIBLE
956 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE
; ;AC000;
961 ; $ELSE ;SINCE SOURCE IS FIXED DISK, ERROR ;AC000;
964 MOV DX, OFFSET MSGNUM_INVALID_DRV
;ISSUE INVALID DRV MSG ;AC000;
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 *
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;
985 PUSH AX ;SAVE REGISTERS
989 MOV CX,DX ;SAVE RET TEMPORARILY
990 MOV AH,IOCTL_FUNC
;GET IOCTL FUNTION &
991 MOV AL,REDIRECTED_FUNC
;IOCTL SUB-FUNCTION ******CHECK***
993 INT 21H
;AND GO FIND OUT IF IT'S LOCAL
996 MOV CX,OFFSET MSGNUM_INVALID_DRV
;REDIR INVALID ;AC000;
1001 TEST DX,REMOTE_DRV
;IF DRIVE IS REDIRECTED
1005 MOV CX,OFFSET MSGNUM_DRV_REDIRECTED
; ;AC000;
1010 MOV DX,CX ;GET ERROR MSG @
1012 POP CX ;RESTORE REGISTERS
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 *
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;
1029 PUSH AX ;SAVE REGISTERS
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
1037 MOV AX,CS ;CS + OFFSET => INIT @ IN SEGMENT
1038 ADD BX,AX ;WHERE BUFFER CAN START
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
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)
1052 MOV BX,DS:TWO
;GET ADDR WHERE BUFFER ENDS
1053 MOV BUFFER_END
,BX ;(TOP OF MEMORY, OFFSET 2 IN PSP)
1055 POP CX ;RESTORE REGISTERS
1058 RET ;RETURN TO CALLER
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 ;******************************************************************************
1070 MOV AX,2523H
;SET THE CTRL-BREAK VECTOR
1071 MOV DX,OFFSET MAIN_EXIT
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;
1086 ; INPUT: BL = DRIVE NUMBER (1=A,2=B ETC....)
1087 ;******************************************************************************
1088 MOV AH,0 ;SEE IF SERVER LOADED
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
1106 MOV DX,OFFSET MSGNUM_DRV_REDIRECTED
;AC000;
1120 PATHLABL COMPINIT
;AN013;