summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DISKCOMP/COMPINIT.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/DISKCOMP/COMPINIT.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/DISKCOMP/COMPINIT.ASM')
-rw-r--r--v4.0/src/CMD/DISKCOMP/COMPINIT.ASM1123
1 files changed, 1123 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM b/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM
new file mode 100644
index 0000000..245b78c
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM
@@ -0,0 +1,1123 @@
1 PAGE 90,132 ;A2
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
114CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AC000;
115 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
116
117 INCLUDE DISKCOMP.EQU
118NOOP 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)
200MY_BPB STRUC
201CBYTE_SECT DW 0 ; 200H BYTES / SECTOR
202CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER
203CRESEV_SECT DW 0 ; 1h RESERVED SECTORS
204CFAT DB 0 ; 2h # OF FATS
205CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES
206CTOTSECT DW 0 ; 02D0h TOT. # OF SECT.
207 ; INCL BOOT SECT, DIRS
208MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR
209CSECT_FAT DW 0 ; 2h SECTORS / FAT
210CSECT_TRACK DW 0 ;
211CHEAD DW 0 ;
212CHIDDEN_SECT DD 0 ;
213BIG_TOT_SECT DD 0 ;
214 DB 6 DUP (0) ;
215MY_BPB ENDS
216
217;USED TO CHECK FOR PRESENCE OF 386 MACHINE:
218BIOS_SYSTEM_DESCRIPTOR struc ;SYSTEM TYPE STRUC ;AN001;
219bios_SD_leng dw ? ;VECTOR LENGTH ;AN001;
220bios_SD_modelbyte db ? ;SYSTEM MODEL TYPE ;AN001;
221bios_SD_scnd_modelbyte db ? ; ;AN001;
222 db ? ; ;AN001;
223bios_SD_featurebyte1 db ? ; ;AN001;
224 db 4 dup (?) ; ;AN001;
225BIOS_SYSTEM_DESCRIPTOR ends ;END OF STRUC ;AN001;
226
227
228;****************************************************************************
229; *
230; VARIABLE DECLARATIONS *
231; *
232;****************************************************************************
233DRIVE_VALID DW ? ;DRIVE VALIDITY BYTE
234DEFAULT_DRV DB ? ;DEFAULT DRIVE ID
235NUMBER_OF_DRV DB ? ;TOTAL # OF DISKT DRIVES ON THE SYS
236 ;(NUMBER_OF_DRV = 0 ---> 1 DRIVE)
237ASCII_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
243INIT 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
310INIT 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
550PC_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
586PC_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;******************************************************************************
600SOURCE_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
642SOURCE_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
653TEST_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
702TEST_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
713DOS_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
724DOS_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
734TEST_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
782TEST_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
801CHK_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
853CHK_SINGLE_DRV_OP ENDP
854 HEADER <GET_LOGICAL_DRIVE - GET LOG. DRIV NO. WHO OWNS PHYSICAL DRIVE>
855;******************************************************************************
856GET_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
879GET_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;******************************************************************************
891DISKETTE_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
970DISKETTE_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;******************************************************************************
982CHECK_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
1016CHECK_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;******************************************************************************
1026BUFFER_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
1059BUFFER_SIZE ENDP
1060 HEADER <SETUP_CTRL_BREAK - SETUP THE CTRL-BREAK VECTOR>
1061;******************************************************************************
1062SETUP_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
1080SETUP_CTRL_BREAK ENDP
1081 HEADER <CHECK_SERVER - IS SERVER OR REDIRECTOR LOADED?>
1082;******************************************************************************
1083CHECK_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
1116CHECK_SERVER ENDP
1117
1118 Public INIT_END
1119INIT_END LABEL BYTE
1120 PATHLABL COMPINIT ;AN013;
1121CSEG ENDS
1122 END
1123 \ No newline at end of file