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