summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DISKCOMP
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/DISKCOMP')
-rw-r--r--v4.0/src/CMD/DISKCOMP/COMPINIT.ASM1123
-rw-r--r--v4.0/src/CMD/DISKCOMP/DCMPMACR.INC171
-rw-r--r--v4.0/src/CMD/DISKCOMP/DCOMPMS.INC232
-rw-r--r--v4.0/src/CMD/DISKCOMP/DCOMPP.ASM123
-rw-r--r--v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM427
-rw-r--r--v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM159
-rw-r--r--v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM2060
-rw-r--r--v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU170
-rw-r--r--v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK6
-rw-r--r--v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL56
-rw-r--r--v4.0/src/CMD/DISKCOMP/MAKEFILE59
11 files changed, 4586 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
diff --git a/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC b/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC
new file mode 100644
index 0000000..f0cdd0d
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC
@@ -0,0 +1,171 @@
1 IF1 ;AN000;
2 %OUT INCLUDING DCMPMACR.INC...;AN000;
3 ELSE ;AN000;
4; %OUT INCLUDING DCMPMACR.INC...
5 ENDIF ;AN000;
6;***************************************************************************;
7; MACRO DEFINITION ;
8;***************************************************************************;
9
10HEADER MACRO TEXT ;;AN000;
11.XLIST ;;AN000;
12 SUBTTL &TEXT ;;AN000;
13.LIST ;;AN000;
14 PAGE ;;AN000;
15 ENDM ;;AN000;
16; = = = = = = = = =
17DOSCALL MACRO FUNC,SUBFUNC ;;AN000;
18 IFNB <FUNC> ;;AN000;IS THERE ANY PARMS AT ALL?
19 IFNB <SUBFUNC> ;;AN000;
20 MOV AX,(FUNC SHL 8)+SUBFUNC ;;AN000;FUNC TO AH,SUBFUNC TO AL
21 ELSE ;;AN000;SINCE THERE IS NO SUBFUNC
22 MOV AH,FUNC ;;AN000;
23 ENDIF ;;AN000;
24 ENDIF ;;AN000;
25 INT 21H ;;AN000;
26 ENDM ;;AN000;
27; = = = = = = = = =
28PRINT MACRO MESSAGE ;;AN000;
29 MOV DI,OFFSET MESSAGE ;;AC000;
30 CALL SENDMSG ;;AC000;
31 ENDM ;;AN000;
32; = = = = = = = = =
33.xlist ;AN000;
34;INPUT MACRO MESSAGE
35; PRINT MESSAGE
36; CALL PROMPT
37; ENDM
38.list ;AN000;
39; $SALUT (0,16,22,36)
40MY_TRACKLAYOUT MACRO ;;AN000;
41 LOCAL CSECT_F ;;AN000;
42CSECT_F DW 0 ;;AN000;# OF SECTORS IN A TRACK. Currently 18 is max.
43 ;; THE REST IS FOR FUTURE MEDIA
44 DW 1 ;;AN000;1 ST SECTOR
45 DW 512 ;;AN000;# OF BYTES
46 DW 2 ;;AN000;
47 DW 512 ;;AN000;
48 DW 3 ;;AN000;
49 DW 512 ;;AN000;
50 DW 4 ;;AN000;
51 DW 512 ;;AN000;
52 DW 5 ;;AN000;
53 DW 512 ;;AN000;
54 DW 6 ;;AN000;
55 DW 512 ;;AN000;
56 DW 7 ;;AN000;
57 DW 512 ;;AN000;
58 DW 8 ;;AN000;
59 DW 512 ;;AN000;
60 DW 9 ;;AN000;
61 DW 512 ;;AN000;
62 DW 10 ;;AN000;
63 DW 512 ;;AN000;
64 DW 11 ;;AN000;
65 DW 512 ;;AN000;
66 DW 12 ;;AN000;
67 DW 512 ;;AN000;
68 DW 13 ;;AN000;
69 DW 512 ;;AN000;
70 DW 14 ;;AN000;
71 DW 512 ;;AN000;
72 DW 15 ;;AN000;
73 DW 512 ;;AN000;
74 DW 16 ;;AN000;
75 DW 512 ;;AN000;
76 DW 17 ;;AN000;
77 DW 512 ;;AN000;
78 DW 18 ;;AN000;
79 DW 512 ;;AN000;CURRENTLY 18 SECTORS/TRACK IS MAXIMUM
80 DW 19 ;;AN000;BELOW IS FOR THE FUTURE MEDIA.
81 DW 512 ;;AN000;
82 DW 20 ;;AN000;
83 DW 512 ;;AN000;
84 DW 21 ;;AN000;
85 DW 512 ;;AN000;
86 DW 22 ;;AN000;
87 DW 512 ;;AN000;
88 DW 23 ;;AN000;
89 DW 512 ;;AN000;
90 DW 24 ;;AN000;
91 DW 512 ;;AN000;
92 DW 25 ;;AN000;
93 DW 512 ;;AN000;
94 DW 26 ;;AN000;
95 DW 512 ;;AN000;
96 DW 27 ;;AN000;
97 DW 512 ;;AN000;
98 DW 28 ;;AN000;
99 DW 512 ;;AN000;
100 DW 29 ;;AN000;
101 DW 512 ;;AN000;
102 DW 30 ;;AN000;
103 DW 512 ;;AN000;
104 DW 31 ;;AN000;
105 DW 512 ;;AN000;
106 DW 32 ;;AN000;
107 DW 512 ;;AN000;
108 DW 33 ;;AN000;
109 DW 512 ;;AN000;
110 DW 34 ;;AN000;
111 DW 512 ;;AN000;
112 DW 35 ;;AN000;
113 DW 512 ;;AN000;
114 DW 36 ;;AN000;
115 DW 512 ;;AN000;
116 DW 37 ;;AN000;
117 DW 512 ;;AN000;
118 DW 38 ;;AN000;
119 DW 512 ;;AN000;
120 DW 39 ;;AN000;
121 DW 512 ;;AN000;
122 DW 40 ;;AN000;
123 DW 512 ;;AN000;
124 DW 41 ;;AN000;
125 DW 512 ;;AN000;
126 DW 42 ;;AN000;
127 DW 512 ;;AN000;
128 DW 43 ;;AN000;
129 DW 512 ;;AN000;
130 DW 44 ;;AN000;
131 DW 512 ;;AN000;
132 DW 45 ;;AN000;
133 DW 512 ;;AN000;
134 DW 46 ;;AN000;
135 DW 512 ;;AN000;
136 DW 47 ;;AN000;
137 DW 512 ;;AN000;
138 DW 48 ;;AN000;
139 DW 512 ;;AN000;
140 DW 49 ;;AN000;
141 DW 512 ;;AN000;
142 DW 50 ;;AN000;
143 DW 512 ;;AN000;
144 DW 51 ;;AN000;
145 DW 512 ;;AN000;
146 DW 52 ;;AN000;
147 DW 512 ;;AN000;
148 DW 53 ;;AN000;
149 DW 512 ;;AN000;
150 DW 54 ;;AN000;
151 DW 512 ;;AN000;
152 DW 55 ;;AN000;
153 DW 512 ;;AN000;
154 DW 56 ;;AN000;
155 DW 512 ;;AN000;
156 DW 57 ;;AN000;
157 DW 512 ;;AN000;
158 DW 58 ;;AN000;
159 DW 512 ;;AN000;
160 DW 59 ;;AN000;
161 DW 512 ;;AN000;
162 DW 60 ;;AN000;
163 DW 512 ;;AN000;
164 DW 61 ;;AN000;
165 DW 512 ;;AN000;
166 DW 62 ;;AN000;
167 DW 512 ;;AN000;
168 DW 63 ;;AN000;
169 DW 512 ;;AN000;
170 ENDM ;AN000;
171 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPMS.INC b/v4.0/src/CMD/DISKCOMP/DCOMPMS.INC
new file mode 100644
index 0000000..6808808
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DCOMPMS.INC
@@ -0,0 +1,232 @@
1;:util DISKCOMP ;utility name
2;:class 1 ;DOS extended errors:
3;:class 2 ;parse errors:
4;1 Too many parameters
5;2 Required parameter missing
6;3 Invalid switch
7;4 Invalid keyword
8;5 Parameter value not in allowed range
9;6 Parameter value not allowed [parse ret codes 6 and 7]
10;7 (undefined)
11;8 Parameter format not correct
12;9 (undefined)
13;10 Invalid parameter [no corresponding parse ret code]
14;11 Invalid parameter combination [no corresponding parse ret code]
15;;
16;:class A ;system messages
17;
18;:use 1 COMMON1 ;"Incorrect DOS version"
19;
20;:use 2 EXTEND8 ;"Insufficient memory"
21;
22;:use 3 PARSE10 ;"Invalid parameter"
23;;
24;:def 4 "Do not specify filename(s)",CR,LF
25;"Command format: DISKCOMP d: d: [/1][/8]",LF,CR
26;
27;:def 5 CR,LF,"Invalid drive specification",CR,LF
28;"Specified drive does not exist",CR,LF
29;"or is non-removable",CR,LF
30;
31;:def 6 CR,LF,"Cannot DISKCOMP to or from",CR,LF
32;"a network drive",CR,LF
33;
34;:def 7 CR,LF,"Insert FIRST diskette in drive %1:",CR,LF
35;
36;:def 8 CR,LF,"Insert SECOND diskette in drive %1:",CR,LF
37;
38;:def 9 CR,LF,"FIRST diskette bad or incompatible",CR,LF
39;
40;:def 10 CR,LF,"SECOND diskette bad or incompatible",CR,LF
41;
42;:use 11 EXTEND21 ;"Drive not ready" NOTE CHANGE %1 TO %0
43;
44;:use 12 COMMON28 ;"Press any key to continue . . ."
45;
46;:use 13 EXTEND19 ;CR,LF,"Attempt to write to write-protected diskette",CR,LF
47;
48;:def 14 CR,LF,"Compare another diskette (Y/N) ?"
49;
50;:def 15 CR,LF,"Comparing %1 tracks",CR,LF
51;"%2 sectors per track, %3 side(s)",CR,LF
52;
53;:def 16 CR,LF,"Drive types or diskette types",CR,LF
54;"not compatible",CR,LF
55;
56;:def 17 CR,LF,"Unrecoverable read error on drive %2",CR,LF
57;"side %3, track %4",CR,LF
58;
59;:def 18 CR,LF,"Compare error on",CR,LF,"side %3, track %4",CR,LF
60;
61;:def 19 "Make sure a diskette is inserted into",CR,LF
62;"the drive and the door is closed",CR,LF
63;
64;:def 20 CR,LF,"Compare process ended",CR,LF
65;
66;:def 21 CR,LF,"Compare OK",CR,LF
67;
68;:def 22 CR,LF
69;:end
70; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
71 IF1 ;AN000;
72 %OUT COMPONENT=DISKCOMP, MODULE=DCOMPMS.INC...;AN000;
73 ENDIF ;AN000;
74; $SALUT (0,13,18,22) ; ;AN000;
75;THIS MODULE IS INCLUDED IN DCOMPSM.SAL.
76; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
77
78FOUR_SUBS EQU 4 ;AN000;FOUR VARIABLES IN ONE MSG
79PC_ID_4 EQU 4 ;AN000;IDENTIFIES FOURTH REPLACEMENT PARM
80PC_ID_5 EQU 5 ;AN000;IDENTIFIES FIFTH REPLACEMENT PARM
81LETTER_A EQU "A" ;AN000;DEFAULT DRIVE ID
82CLEAR_BUF EQU 0C0H ;AN006;CLEAR KEYBOARD BUFFER BEFORE INPUT
83KEY_IN_ECHO EQU 1 ;AN000;REQUEST KEYBOARD INPUT TO AL, ECHO RESPONSE
84KEY_IN EQU 8 ;AN000;REQUEST KEYBOARD INPUT TO AL, NO ECHO
85FILL_OFF EQU 0 ;AN000;TO BE FILLED IN WITH OFFSET TO DATA
86FILL_SEG EQU 0 ;AN000;TO BE FILLED IN WITH THE COMMON SEG ID
87 ; SINCE A .COM FILE CANNOT HAVE
88 ; SEGMENT FIXUP RECORDS
89
90SUBLIST_PARSE SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_0,SF_BITS <SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1,PAD_BLK> ;AN003;
91 PUBLIC SUBLIST_PARSE ;AN003;
92
93; THE NEXT GROUP ARE ADDITIONAL CLASS "A" MESSAGES
94; SPECIFICALLY DEFINED FOR THE DISKCOMP UTILITY
95
96 ;"Insufficient memory"
97MSGNUM_UNSUF_MEMORY MSG_DESC <2> ;AN000;
98 PUBLIC MSGNUM_UNSUF_MEMORY ;AN000;
99
100 ;CR,LF,"Invalid parameter",CR,LF
101MSGNUM_INVALID_PARM MSG_DESC <3> ;AN000;
102 PUBLIC MSGNUM_INVALID_PARM ;AN000;
103
104 ;"Do not specify filename(s)",CR,LF
105 ;"Command format: DISKCOMP d: d: [/1][/8]",CR,LF
106MSGNUM_INVALID_PARM2 MSG_DESC <4> ;AN000;
107 PUBLIC MSGNUM_INVALID_PARM2 ;AN000;
108
109; = = = = = = = = = = = = = = = =
110 ;CR,LF,"Invalid drive specification",CR,LF
111 ;"Specified drive does not exist",CR,LF
112 ;"or is non-removable",CR,LF
113MSGNUM_INVALID_DRV MSG_DESC <5> ;AN000;
114 PUBLIC MSGNUM_INVALID_DRV ;AN000;
115
116; = = = = = = = = = = = = = = = =
117 ;CR,LF,"Cannot DISKCOMP to or from",CR,LF
118 ;"a network drive",CR,LF
119MSGNUM_DRV_REDIRECTED MSG_DESC <6> ;AN000;
120 PUBLIC MSGNUM_DRV_REDIRECTED ;AN000;
121
122; = = = = = = = = = = = = = = = =
123 ;CR,LF,"Insert FIRST diskette in drive %1:",CR,LF
124MSGNUM_LOAD_FIRST MSG_DESC <7,,SUBLIST_78,ONE_SUBS> ;AN000;
125 PUBLIC MSGNUM_LOAD_FIRST,SUBLIST_78 ;AN000;
126
127SUBLIST_78 SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_CH,SF_CHAR>,MAX_0,MIN_1>;AN000;
128;THE "FILL" FIELDS NEED TO BE SET TO POINT TO
129;"ASCII_DRV1_ID" OR "ASCII_DRV2_ID"(BELOW).
130
131 ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF
132MSGNUM_LOAD_SECOND MSG_DESC <8,,SUBLIST_78,ONE_SUBS> ;AN000;
133 PUBLIC MSGNUM_LOAD_SECOND ;AN000;
134
135 ;IF "FIRST" SPECIFIED
136ASCII_DRV1_ID DB LETTER_A-BYTE ;AN000;
137
138 ;IF "SECOND" SPECIFIED
139ASCII_DRV2_ID DB LETTER_A-BYTE ;AN000;
140 PUBLIC ASCII_DRV1_ID,ASCII_DRV2_ID ;AN000;
141
142; = = = = = = = = = = = = = = = =
143 ;CR,LF,"FIRST diskette bad or incompatible",CR,LF
144MSGNUM_BAD_FIRST MSG_DESC <9> ;AN000;
145 PUBLIC MSGNUM_BAD_FIRST ;AN000;
146; = = = = = = = = = = = = = = = =
147 ;CR,LF,"SECOND diskette bad or incompatible",CR,LF
148MSGNUM_BAD_SECOND MSG_DESC <10> ;AN000;
149 PUBLIC MSGNUM_BAD_SECOND ;AN000;
150; = = = = = = = = = = = = = = = =
151 ;CR,LF,Drive not ready",CR,LF
152MSGNUM_GET_READY MSG_DESC <11,,SUBLIST_11,ONE_SUBS> ;AN000;
153 PUBLIC MSGNUM_GET_READY ;AN000;
154
155SUBLIST_11 SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_0,SF_BITS<SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1>;AN000;
156 PUBLIC SUBLIST_11 ;AN000;
157
158DRIVE_LETTER DB LETTER_A,":",NULL ;AN000;
159 PUBLIC DRIVE_LETTER ;AN000;
160
161SKIP_MSG DB NULL ;AN000;
162 PUBLIC SKIP_MSG ;AN000;
163; = = = = = = = = = = = = = = = =
164 ;CR,LF,"Press any key to continue . . .",CR,LF
165MSGNUM_STRIKE MSG_DESC <12,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN)> ;AN006;
166 PUBLIC MSGNUM_STRIKE ;AN000;
167; = = = = = = = = = = = = = = = =
168; ;CR,LF,"Attempt to write to write-protected diskette",CR,LF
169MSGNUM_WRITE_PROTECT MSG_DESC <13> ;AN000;
170 PUBLIC MSGNUM_WRITE_PROTECT ;AN000;
171; = = = = = = = = = = = = = = = =
172 ;CR,LF,"Compare another diskette (Y/N) ?"
173MSGNUM_COMP_ANOTHER MSG_DESC <14,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN_ECHO)> ;AN006;
174 PUBLIC MSGNUM_COMP_ANOTHER ;AN000;
175; = = = = = = = = = = = = = = = =
176 ;CR,LF,"Comparing %1 tracks",CR,LF
177 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
178MSGNUM_COMPARING MSG_DESC <15,,SUBLIST_15A,THREE_SUBS> ;AN000;
179 PUBLIC MSGNUM_COMPARING ;AN000;
180
181SUBLIST_15A SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1>;AN000;
182SUBLIST_15B SUBLIST <,,MSG_SECTRK,FILL_SEG,PC_ID_2,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1>;AN000;
183SUBLIST_15C SUBLIST <,,MSG_SIDES,FILL_SEG,PC_ID_3,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1>;AN000;
184 PUBLIC SUBLIST_15A,SUBLIST_15B,SUBLIST_15C ;AN000;
185
186MSG_TRACKS DW 0 ;AN000;NUMBER OF TRACKS
187MSG_SECTRK DW 0 ;AN000;NUMBER OF SECTORS PER TRACK
188MSG_SIDES DW 0 ;AN000;NUMBER OF SIDES
189 PUBLIC MSG_TRACKS,MSG_SECTRK,MSG_SIDES ;AN000;
190; = = = = = = = = = = = = = = = =
191 ;CR,LF,"Drive types or diskette types",CR,LF
192 ;"not compatible",CR,LF
193MSGNUM_NOT_COMPATIBLE MSG_DESC <16> ;AN000;
194 PUBLIC MSGNUM_NOT_COMPATIBLE ;AN000;
195; = = = = = = = = = = = = = = = =
196 ;CR,LF,"Unrecoverable read error on drive %2",CR,LF
197 ;"side %3, track %4",CR,LF
198 ;%2 IS "DRIVE_LETTER", AND
199 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
200MSGNUM_HARD_ERROR_READ MSG_DESC <17,,SUBLIST_17B,THREE_SUBS> ;AN000;
201 PUBLIC MSGNUM_HARD_ERROR_READ ;AN000;
202
203SUBLIST_17B SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_2,SF_BITS<SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1>;AN000;
204SUBLIST_17C SUBLIST <,,MSG_SIDES,FILL_SEG,PC_ID_3,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
205SUBLIST_17D SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_4,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1>;AN000;
206 PUBLIC SUBLIST_17B,SUBLIST_17C,SUBLIST_17D ;AN000;
207
208 ;CR,LF,"Compare error on",CR,LF
209 ;"side %3, track %4",CR,LF
210 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
211MSGNUM_HARD_ERROR_COMP MSG_DESC <18,,SUBLIST_17C,TWO_SUBS> ;AN000;
212 PUBLIC MSGNUM_HARD_ERROR_COMP ;AN000;
213; = = = = = = = = = = = = = = = =
214 ;:def 19 "Make sure a diskette is inserted into",CR,LF
215 ;"the drive and the door is closed",CR,LF
216MSGNUM_CLOSE_DOOR MSG_DESC <19> ;AN004;
217 PUBLIC MSGNUM_CLOSE_DOOR ;AN004;
218; = = = = = = = = = = = = = = = =
219 ;CR,LF,"Compare process ended",CR,LF
220MSGNUM_FATAL_ERROR MSG_DESC <20> ;AN000;
221 PUBLIC MSGNUM_FATAL_ERROR ;AN000;
222; = = = = = = = = = = = = = = = =
223 ;CR,LF,"Compare OK",CR,LF
224MSGNUM_COMP_OK MSG_DESC <21> ;AN000;
225 PUBLIC MSGNUM_COMP_OK ;AN000;
226; = = = = = = = = = = = = = = = =
227 ;CR,LF
228MSGNUM_NEWLINE MSG_DESC <22> ;AC007;
229 PUBLIC MSGNUM_NEWLINE ;AN000;
230; = = = = = = = = = = = = = = = =
231;end of DCOMPMS.INC
232 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM
new file mode 100644
index 0000000..369434b
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM
@@ -0,0 +1,123 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOMPP.SAL - DISKCOMP SYSTEM COMMAND LINE PARSER
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOMPP.SAL
5;
6; DESCRIPTIVE NAME: Include the DOS system PARSER in the SEGMENT
7; configuration expected by the modules of DISKCOMP.
8;
9;FUNCTION: The common code of the DOS command line PARSER is optimized by
10; the setting of certain switches that cause the conditional
11; assembly of only the required portions of the common PARSER.
12; The segment registers are ASSUMED according to the type .COM.
13; The Common PARSER is then INCLUDEd.
14;
15; ENTRY POINT: SYSPARSE, near
16;
17; INPUT:
18; ES - has seg id of the SEGMENT
19; that contains the input control blocks,
20; defined below.
21;
22; DI - offset into ES of the PARMS INPUT BLOCK
23;
24; DS - has seg id of the SEGMENT
25; that contains the DOS input COMMAND
26; string, which is originally presented at 81h
27; in the PSP.
28;
29; SI - offset into DS of the text of the DOS input COMMAND string
30; as originally presented at 81H in the PSP.
31;
32; DX - zero
33;
34; CX - ordinal value, intially zero, updated on each subsequent call
35; to the value returned in CX on the previous call.
36;
37; CS - points to the segment containing the
38; INCLUDE PARSE.ASM statement
39;
40; DS - also points to the segment containing the INCLUDE
41; PARSE.ASM statement.
42;
43; EXIT-NORMAL: Output registers:
44; AX - return code:
45; RC_No_Error equ 0 ; No error
46; RC_EOL equ -1 ; End of command line
47;
48; DX - Offset into ES of the selected RESULT BLOCK.
49; BL - terminated delimiter code
50; CX - new operand ordinal
51; SI - set past scanned operand
52;
53; EXIT-ERROR: Output registers:
54; AX - return code:
55; RC_Too_Many equ 1 ; Too many operands
56; RC_Op_Missing equ 2 ; Required operand missing
57; RC_Not_In_SW equ 3 ; Not in switch list provided
58; RC_Not_In_Key equ 4 ; Not in keyword list provided
59; RC_Out_Of_Range equ 6 ; Out of range specified
60; RC_Not_In_Val equ 7 ; Not in value list provided
61; RC_Not_In_Str equ 8 ; Not in string list provided
62; RC_Syntax equ 9 ; Syntax error
63;
64; INTERNAL REFERENCES:
65; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.ASM)
66;
67; DATA AREAS: none
68;
69; EXTERNAL REFERENCES:
70; ROUTINES: none
71;
72; DATA AREAS: control blocks pointed to by input registers.
73;
74; NOTES:
75; This module should be processed with the SALUT preprocessor
76; with the re-alignment not requested, as:
77;
78; SALUT DCOMPP,NUL,;
79;
80; To assemble these modules, the alphabetical or sequential
81; ordering of segments may be used.
82;
83; For LINK instructions, refer to the PROLOG of the main module,
84; DISKCOMP.SAL.
85;
86;****************** END OF SPECIFICATIONS *****************************
87 IF1 ;AN000;
88 %OUT COMPONENT=DISKCOMP, MODULE=DCOMPP.SAL... ;AN000;
89 ENDIF ;AN000;
90; = = = = = = = = = = = =
91 INCLUDE PATHMAC.INC ;AN013;
92CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
93 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;
94
95 PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT
96
97INCSW EQU 0 ;AC013;DO NOT INCLUDE PSDATA.INC
98FARSW EQU 0 ;AN000;CALL THE PARSER BY NEAR CALL
99DATESW EQU 0 ;AN000;SUPPRESS DATE CHECKING
100TIMESW EQU 0 ;AN000;SUPPRESS TIME CHECKING
101FILESW EQU 0 ;AN000;SUPPRESS CHECK FILE SPECIFICATION
102CAPSW EQU 0 ;AN000;SUPPRESS FILE TABLE CAPS
103CMPXSW EQU 0 ;AN000;SUPPRESS CHECKING COMPLEX LIST
104DRVSW EQU 1 ;AN000;DO SUPPORT DRIVE ONLY FORMAT
105QUSSW EQU 0 ;AN000;SUPPRESS SUPPORT OF QUOTED STRING FORMAT
106NUMSW EQU 0 ;AN000;SUPPRESS CHECKING NUMERIC VALUE
107KEYSW EQU 0 ;AN000;SUPPRESS KEYWORD SUPPORT
108SWSW EQU 1 ;AN000;DO SUPPORT SWITCHES
109VAL1SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 1
110VAL2SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 2
111VAL3SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 3
112BASESW EQU 1 ;AN012;SPECIFY, PSDATA POINTED TO BY "DS"
113 INCLUDE PSDATA.INC ;AN013;PARSER DATA AREA
114 PATHLABL DCOMPP ;AN013;
115;.XLIST ;AN000;
116;.XCREF ;AN000;
117 INCLUDE PARSE.ASM ;AN000;
118.LIST ;AN000;
119.CREF ;AN000;
120 PATHLABL DCOMPP ;AN013;
121CSEG ENDS ;AN000;
122 END ;AN000;
123 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM
new file mode 100644
index 0000000..7a549d2
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM
@@ -0,0 +1,427 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOMPPAR.SAL - LOOK AT COMMAND LINE PARMS
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOMPPAR.SAL
5
6; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters
7; and the interface to the DOS system PARSER.
8
9;FUNCTION: The static data areas are prescribed by the DOS system PARSER
10; to define the several parameters presented to DISKCOMP. These
11; data areas are passed to the PARSER, and its responses checked
12; to determine the nature of the user's specifications. Any errors
13; found in the user's parameters are defined in messages back
14; to the user.
15
16; ENTRY POINT: PARSER, near
17
18; INPUT: (DOS COMMAND LINE PARAMETERS)
19
20; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
21
22; WHERE
23; [d:][path] - Path where the DISKCOMP command resides.
24
25; [d:] - To specify the Source drive
26;
27; [d:] - To specify the Target drive
28;
29; [/1] - To compare only the first side of the diskette,
30; regardless of the diskette or drive type.
31
32; [/8] - To compare only the first 8 sectors per track,
33; even if the first diskette contains 9/15 sectors
34; per track.
35;
36; Upon entry to PARSER in this module,
37; "CURRENT_PARM" = offset to start of parm text in command string
38; "ORDINAL" = initialized to zero
39; PSP+81H = text of DOS command line parms string
40
41; EXIT-NORMAL:
42; "SOURCE_DRIVE" = CHAR OF FIRST DRIVE ID SPECIFIED, BLANK IF NONE
43; "TARGET_DRIVE" = CHAR OF SECOND DRIVE ID IF BOTH SPECIFIED, BLANK
44; IF NONE OR ONLY ONE SPECIFIED
45; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED.
46; "USER_OPTION_8" = 01 ON IF /8, -1 IF /8 NOT SPECIFIED.
47
48; EXIT-ERROR:
49; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
50
51; INTERNAL REFERENCES:
52; ROUTINES:
53; PARSER:NEAR Call the system Parser to decode command line
54; PARSE_ERROR:NEAR Display the appropriate Parse error message.
55
56; DATA AREAS:
57; The several parameter control blocks, defined by the System
58; PARSER interface, defining the DISKCOMP parameters.
59
60; EXTERNAL REFERENCES:
61; ROUTINES:
62; SENDMSG:NEAR Uses Msg Descriptor to drive message handler.
63; SYSPARSE:NEAR System Command Line Common Parser.
64
65; DATA AREAS:
66; EXITFL:BYTE Errorlevel return code.
67; MSGNUM_PARSE:WORD Message descriptor for all parse errors.
68; USER_OPTION:BYTE /1 parm indicator
69; USER_OPTION_8:BYTE /8 parm indicator
70; SOURCE_DRIVE:BYTE character of first specified drive
71; TARGET_DRIVE:BYTE character of second specified drive
72
73; NOTES:
74; This module should be processed with the SALUT preprocessor
75; with the re-alignment not requested, as:
76
77; SALUT DCOMPPAR,NUL
78
79; To assemble these modules, the alphabetical or sequential
80; ordering of segments may be used.
81
82; For LINK instructions, refer to the PROLOG of the main module,
83; DISKCOMP.SAL.
84
85;****************** END OF SPECIFICATIONS *****************************
86 IF1 ;AN000;
87 %OUT COMPONENT=DISKCOMP, MODULE=DCOMPPAR.SAL... ;AN000;
88 ENDIF ;AN000;
89 INCLUDE PATHMAC.INC ;AN013;
90; = = = = = = = = = = = =
91HEADER MACRO TEXT ;;AN000;
92.XLIST ;AN000;
93 SUBTTL TEXT ;AN000;
94.LIST ;AN000;
95 PAGE ;;AN000;
96 ENDM ;;AN000;
97; = = = = = = = = = = = =
98; $SALUT (4,23,28,36) ;AN000;
99CHAR_A EQU "A" ;AN000;ASCII VALUE OF CHARACTER "A"
100NUL EQU 0 ;AN003;ASCIIZ STRING DELIMITER
101; EXIT CODES FROM SYSPARSE (WHEN CY=0)
102
103SYSPRM_EX_OK EQU 0 ;AN000; no error
104SYSPRM_EX_MANY EQU 1 ;AN000; too many operands
105SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing
106SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided
107SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided
108SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified
109SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided
110SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided
111SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error
112SYSPRM_EX_EOL EQU -1 ;AN000; end of command line
113; = = = = = = = = = = = =
114 HEADER <STRUC - DEFINITIONS OF EXTERNAL CONTROL BLOCKS> ;AN000;
115PSP STRUC ;AN000;
116 DB 80H DUP (?) ;AN000;SKIP OVER FIRST HALF OF PSP
117PSP_PARMLEN DB ? ;AN000;NUMBER OF BYTES IN DOS COMMAND LINE
118PSP_COMMAND DB 127 DUP(?) ;AN000;TEXT OF DOS COMMAND LINE
119PSP ENDS ;AN000;
120
121MSG_DESC STRUC ;AN003;
122MSG_NUM DW ? ;AN003;MESSAGE NUMBER (TO AX)
123MSG_HANDLE DW ? ;AN003;HANDLE OF OUTPUT DEVICE (TO BX)
124MSG_SUBLIST DW ? ;AN003;POINTER TO SUBLIST (TO SI)
125MSG_COUNT DW ? ;AN003;SUBSTITUTION COUNT (TO CX)
126MSG_CLASS DW ? ;AN003;MESSAGE CLASS (IN HIGH BYTE, TO DH)
127 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN003;
128MSG_DESC ENDS ;AN003;
129
130ONE_SUBS EQU 1 ;AN003;NUMBER OF VARIABLES
131
132SUBLIST STRUC ;AN000;
133SUB_SIZE DB ? ;AN003;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
134SUB_RES DB ? ;AN003;RESERVED
135 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN003;
136SUB_VALUE DW ? ;AN003;TIME, DATE, OR PTR TO DATA ITEM
137SUB_VALUE_SEG DW ? ;AN003;SEG ID OF PTR
138 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN003;
139 ; IF THIS IS A .COM FILE) ;AN003;
140SUB_ID DB ? ;AN003;N OF %N
141SUB_FLAGS DB ? ;AN003;DATA TYPE FLAGS
142SUB_MAX_WIDTH DB ? ;AN003;MAXIMUM FIELD WIDTH (0=UNLIMITED)
143SUB_MIN_WIDTH DB ? ;AN003;MINIMUM FIELD WIDTH
144SUB_PAD_CHAR DB ? ;AN003;CHARACTER FOR PAD FIELD
145 ; CAN BE " ", "0" OR ",". ;AN003;
146 ; "," CAUSES INSERTION OF THE ACTIVE ;AN003;
147 ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN003;
148SUBLIST ENDS ;AN003;
149
150; = = = = = = = = = = = =
151 HEADER <PARSING WORKAREAS> ;AN000;
152; $SALUT (4,14,19,36) ;AN000;
153 EXTRN EXPAR:ABS ;AN000;ERRORLEVEL VALUE FOR BAD PARMS
154 EXTRN FINE:ABS ;AN000;RETURN STATUS INDICATOR
155
156BLANK EQU " " ;AN002;WIPE OUT SWITCH TO AVOID DUPLICATE
157
158CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
159 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;
160
161 EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR
162 EXTRN SYSPARSE:NEAR ;AN000;SYSTEM COMMAND LINE PARSER
163
164 EXTRN EXITFL:BYTE ;AN000;ERRORLEVEL RETURN CODE
165
166 EXTRN SOURCE_DRIVE:BYTE ;AN000;FIRST DRIVE LETTER SPECIFIED IN PARMS
167 EXTRN USER_OPTION:BYTE ;AN000;NO OPTION (-1) /1 (1), INVALID (9)
168NO_OPTION EQU -1 ;AN000;OPTION NOT SPECIFIED
169OPTION_1 EQU 1 ;AN000;OPTION "/1" SPECIFIED
170OPTION_8 EQU 1 ;AN000;OPTION "/8" SPECIFIED
171 EXTRN USER_OPTION_8:BYTE ;AN000;NO OPTION (-1) /8 (1), INVALID (9)
172
173 EXTRN MSGNUM_PARSE:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS
174 EXTRN MSGNUM_INVALID_PARM2:WORD ;AN005;HELP MESSAGE DESCRIPTOR
175 EXTRN SUBLIST_PARSE:WORD ;AN003;POINTS TO INVALID PARM
176; = = = = = = = = = = = =
177
178CURRENT_PARM DW 81H ;AN000;POINTER INTO COMMAND OF NEXT OPERAND
179 PUBLIC CURRENT_PARM ;AN000;
180
181ORDINAL DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE
182 PUBLIC ORDINAL ;AN000;
183
184; = = = = = = = = = = = =
185 HEADER <DOS COMMAND LINE PARSER CONTROL BLOCKS> ;AN000;
186
187;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER
188
189 PUBLIC PARMS ;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE
190PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK
191 DW PARMSX ;AN000;POINTER TO PARMS EXTENSION
192 DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2)
193 ; NEXT LIST WOULD BE EXTRA DELIM LIST
194 ; (,& WHITESPACE ALWAYS)
195 ; NEXT LIST WOULD BE EXTRA END OF LINE LIST
196 ; (CR,LF,0 ALWAYS)
197
198;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK
199PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK
200 DB 0,2 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED
201 DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1
202 DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 2
203
204 DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED
205 DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH
206
207 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED
208 ; THERE IS NO CONTROL BLOCK
209 ; DEFINING KEYWORDS
210
211; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
212 HEADER <POSITIONAL PARM DESCRIPTOR BLOCK> ;AN000;
213;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL
214
215;FIRST POSITIONAL PARAMETER IS:
216; [D:] - SPECIFY THE SOURCE DRIVE.
217
218 PUBLIC CONTROL_POS ;AN000;LET LINK MAKE THIS ADDRESSABLE
219CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC,
220 ; OPTIONAL
221 DW 0101H ;AN000; CONTROLS TYPE MATCHED
222 ; SELECTED BITS: "DRIVE ONLY" AND "OPTIONAL"
223
224 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
225 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
226 ; CHECKED)
227 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
228 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
229 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
230 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
231 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
232 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
233 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
234 ; 0010H=IGNORE ":" AT END IN MATCH
235 ; 0002H=REPEATS ALLOWED
236 ; 0001H=OPTIONAL
237
238 DW 0000H ;AN000;FUNCTION_FLAGS (NO CAPITALIZATION NEEDED)
239 ; 0001H=CAP RESULT BY FILE TABLE
240 ; 0002H=CAP RESULT BY CHAR TABLE
241 ; 0010H=REMOVE ":" AT END
242 DW RESULT1 ;AN000; RESULT BUFFER
243 DW NOVALS ;AN000; NO VALUE LISTS
244 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
245 ; IN FOLLOWING LIST
246
247;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS
248NOVALS DB 0 ;AN000;NO VALUE DEFINITIONS
249
250;RESULTS CONTROL BLOCK FOR THE POSITIONAL PARAMETER
251RESULT1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
252 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
253 ; 1=NUMBER, 2=LIST INDEX,
254 ; 3=STRING, 4=COMPLEX,
255 ; 5=FILESPEC, 6=DRIVE
256 ; 7=DATE, 8=TIME
257 ; 9=QUOTED STRING
258RESULT_TAG DB 0FFH ;AN000; MATCHED ITEM TAG
259 DW 0 ;AN000;POINTER TO SYNONYM
260
261RESULT_PTR1 DB ? ;AN000;DRIVE NUMBER (A=1, B=2, ETC)
262
263; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
264 HEADER <SWITCH PARM DESCRIPTOR BLOCK> ;AN000;
265;PARSER CONTROL BLOCK DEFINING THE TWO SWITCHES, OPTIONAL
266
267;THE SWITCH IS "/1", MEANING ONLY COMPARE THE FIRST SIDE.
268;THE SECOND SWITCH IS "/8", MEANING ONLY LOOK AT FIRST 8 SECTORS PER TRACK.
269
270 PUBLIC CONTROL_SW ;AN000;LET LINK MAKE THIS ADDRESSABLE
271CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /1 OR /8
272 DW 0000H ;AN000; CONTROLS TYPE MATCHED
273 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
274 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
275 ; CHECKED)
276 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
277 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
278 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
279 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
280 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
281 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
282 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
283 ; 0010H=IGNORE ":" AT END IN MATCH
284 ; 0002H=REPEATS ALLOWED
285 ; 0001H=OPTIONAL
286
287 DW 0000H ;AN000;FUNCTION_FLAGS (NO CAPITALIZATION)
288 ; 0001H=CAP RESULT BY FILE TABLE
289 ; 0002H=CAP RESULT BY CHAR TABLE
290 ; 0010H=REMOVE ":" AT END
291
292 DW RESULTSW1 ;AN000; RESULT BUFFER
293 DW NOVALS ;AN000; VALUE LISTS
294 DB 2 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
295 ; IN FOLLOWING LIST
296SINGLE_SIDED LABEL BYTE ;AN002;
297SW_1 DB "/1",0 ;AN000; IF n >0, KEYWORD 1
298SW_8 DB "/8",0 ;AN000;SECOND KEYWORD
299
300;RESULTS CONTROL BLOCK FOR THE SWITCHES
301RESULTSW1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
302 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
303 ; 1=NUMBER, 2=LIST INDEX,
304 ; 3=STRING, 4=COMPLEX,
305 ; 5=FILESPEC, 6=DRIVE
306 ; 7=DATE, 8=TIME
307 ; 9=QUOTED STRING
308 DB 0FFh ;AN000; MATCHED ITEM TAG
309
310RESULTSWSYN DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
311RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE
312; = = = = = = = = = = = =
313 PATHLABL DCOMPPAR ;AN013;
314 HEADER <PARSER - ASK SYSPARM TO DECODE PARAMETERS> ;AN000;
315; $SALUT (4,4,9,36) ;AN000;
316PARSER PROC NEAR ;AN000;
317 PUBLIC PARSER ;AN000;
318
319;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING
320; "ORDINAL" = COUNT OF NEXT PARM TO PARSE
321; PSP+81H = TEXT OF DOS COMMAND LINE PARMS STRING
322;OUTPUT: "SOURCE_DRIVE" = A=1, B=2, 0 IF NONE
323; "TARGET_DRIVE" = A=1, B=2, 0 IF NONE
324; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED.
325; "USER_OPTION_8" = 01 ON IF /8, -1 IF /8 NOT SPECIFIED.
326; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
327; = = = = = = = = = = = =
328 MOV USER_OPTION,NO_OPTION ;AN000;SET DEFAULT, SWITCH NOT FOUND
329 MOV USER_OPTION_8,NO_OPTION ;AN000;SET DEFAULT, SWITCH NOT FOUND
330
331; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE
332 JMP SHORT $$SS1
333$$DO1:
334 ;LOOKING AT RETURN CODE FROM SYSPARSE... ;AN000;
335 CMP AX,SYSPRM_EX_OK ;AN000;WERE THERE ANY ERRORS?
336; $EXITIF NE ;AN000;HAD A PROBLEM
337 JE $$IF1
338 CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR
339
340; $ORELSE ;AN000;SINCE NO PROBLEM, SO FAR
341 JMP SHORT $$SR1
342$$IF1:
343 MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT
344 MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT
345 MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND
346 CMP BX,OFFSET RESULT1 ;AN000;WAS POSITIONAL PARM SPECIFIED?
347; $IF E ;AN000;IF POSITIONAL PARM SPECIFIED,
348 JNE $$IF4
349 MOV SI,CX ;AN000;USE COUNT OF POSITIONALS AS INDEX
350 MOV AL,RESULT_PTR1 ;AN000;GET VALUE OF DRIVE (A=1, B=2, ETC)
351 MOV SOURCE_DRIVE-1[SI],AL ;AN000;SAVE RESPONSE DRIVE VALUE
352 ;IN EITHER SOURCE_DRIVE OR TARGET_DRIVE
353 ;ACCORDING TO ORDINAL IN SI (FROM CX)
354; $ELSE ;AN000;SINCE NOT POSITIONAL PARM SPECIFIED
355 JMP SHORT $$EN4
356$$IF4:
357 MOV AL,SINGLE_SIDED+BYTE ;AN000;GET ID PORTION OF SWITCH
358 MOV BX,RESULTSWSYN ;AN000;GET OFFSET TO MATCHING SWITCH
359 CMP [BX]+BYTE,AL ;AN000;WAS IT /1?
360; $IF E ;AN000;YES IT WAS /1
361 JNE $$IF6
362 MOV SW_1,BLANK ;AN002;AVOID GETTING /1 AGAIN
363 MOV USER_OPTION,OPTION_1 ;AN000;MUST HAVE BEEN THE SWITCH, /1
364; $ELSE ;AN000;SINCE IT WAS NOT /1, MUST BE /8
365 JMP SHORT $$EN6
366$$IF6:
367 MOV SW_8,BLANK ;AN002;AVOID GETTING /8 AGAIN
368 MOV USER_OPTION_8,OPTION_8 ;AN000;REPORT BACK, IT WAS /8
369; $ENDIF ;AN000;
370$$EN6:
371; $ENDIF ;AN000;
372$$EN4:
373; $STRTSRCH ;AN000;
374$$SS1:
375 LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON
376 MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM
377 XOR DX,DX ;AN000; RESERVED, INIT TO ZERO
378 MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO
379 CALL SYSPARSE ;AN000;LOOK AT DOS PARMS
380 ; AX=EXIT CODE
381 ; BL=TERMINATED DELIMETER CODE
382 ; CX=NEW OPERAND ORDINAL
383 ; SI=SET TO PAST SCANNED OPERAND
384 ; DX=SELECTED RESULT BUFFER
385 CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS?
386 ;IF NOT, LOOP BACK AND FIND OUT
387 ; WHAT THAT PARM IS
388; $ENDLOOP E ;AN000;END OF LIST
389 JNE $$DO1
390 MOV DX,FINE ;AN000;REPORT THAT PARSER WENT OK
391; $ENDSRCH ;AN000;FINISHED WITH DOS COMMAND LINE
392$$SR1:
393 RET ;AN000;RETURN TO CALLER
394PARSER ENDP ;AN000;
395; = = = = = = = = = = = =
396 HEADER <PARSE_ERROR - DISPLAY REASON FOR PARSE ERROR> ;AN000;
397PARSE_ERROR PROC NEAR ;AN000;
398;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE.
399; "CURRENT_PARM" - OFFSET INTO COMMAND OF WHERE TO START LOOKING FOR PARM
400;OUTPUT: APPROPRIATE ERROR MESSAGE IS PREPARED FOR DISPLAY.
401; DX IS SET TO OFFSET OF PARSE ERROR DESCRIPTOR.
402; = = = = = = = = = = = =
403
404 MOV MSGNUM_PARSE,AX ;AN000;PASS MESSAGE NUMBER TO DESCRIPTOR
405 MOV EXITFL,EXPAR ;AN000;ERRORLEVEL CODE TO "PARM ERROR"
406 MOV AX,CURRENT_PARM ;AN003;GET POINTER TO START OF BAD PARM
407 CMP SI,AX ;AN003;HAS THE INDEX TO COMMAND LINE MOVED?
408; $IF NE ;AN003;YES, THERE IS A FAULTY PARM
409 JE $$IF13
410 MOV BYTE PTR [SI],NUL ;AN003;DELIMIT THE BAD PARM
411 MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM
412
413 MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN003;POINT TO SUBLIST
414 MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN003;SET COUNT OF SUBLISTS TO ONE
415; $ENDIF ;AN003;INDEX MOVED?
416$$IF13:
417 MOV DI,OFFSET MSGNUM_PARSE ;AC005;OFFSET TO PARSE ERR DESCRIPTOR
418 CALL SENDMSG ;AN005;DISPLAY ERROR MSG
419
420 MOV DX,OFFSET MSGNUM_INVALID_PARM2 ;AN005;PASS BACK OFFSET TO HELP MSG
421 RET ;AN000;RETURN TO CALLER
422PARSE_ERROR ENDP ;AN000;
423; = = = = = = = = = = = =
424 PATHLABL DCOMPPAR ;AN013;
425CSEG ENDS ;AN000;
426 END ;AN000;
427 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM
new file mode 100644
index 0000000..73eb45a
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM
@@ -0,0 +1,159 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOMPSM.SAL - DISKCOMP SYSTEM MESSAGES
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOMPSM.SAL
5
6; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT
7; configuration expected by the modules of DISKCOMP.
8
9;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a
10; part of the DISKCOMP module by using INCLUDE to bring in the
11; common portion, in SYSMSG.INC. This included code contains
12; the routines to initialize for message services, to find
13; where a particular message is, and to display a message.
14
15; ENTRY POINT: SYSDISPMSG:near
16; SYSGETMSG:near
17; SYSLOADMSG:near
18
19; INPUT:
20; AX = MESSAGE NUMBER
21; BX = HANDLE TO DISPLAY TO (-1 means use DOS functions 1-12)
22; SI = OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
23; CX = NUMBER OF %PARMS, 0 IF NONE
24; DX = CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
25; CALL SYSDISPMSG ;DISPLAY THE MESSAGE
26
27; If carry set, extended error already called:
28; AX = EXTENDED MESSAGE NUMBER
29; BH = ERROR CLASS
30; BL = SUGGESTED ACTION
31; CH = LOCUS
32; _ _ _ _ _ _ _ _ _ _ _ _
33
34; AX = MESSAGE NUMBER
35; DH = MESSAGE CLASS (1=DOS EXTENDED ERROR, 2=PARSE ERROR, -1=UTILITY MSG)
36; CALL SYSGETMSG ;FIND WHERE A MSG IS
37
38; If carry set, error
39; CX = 0, MESSAGE NOT FOUND
40; If carry NOT set ok, and resulting regs are:
41; CX = MESSAGE SIZE
42; DS:SI = MESSAGE TEXT
43; _ _ _ _ _ _ _ _ _ _ _ _
44
45; CALL SYSLOADMSG ;SET ADDRESSABILITY TO MSGS, CHECK DOS VERSION
46; If carry not set:
47; CX = SIZE OF MSGS LOADED
48
49; If carry is set, regs preset up for SYSDISPMSG, as:
50; AX = ERROR CODE IF CARRY SET
51; AX = 1, INCORRECT DOS VERSION
52; DH =-1, (Utility msg)
53; OR,
54; AX = 1, Error loading messages
55; DH = 0, (Message manager error)
56; BX = STDERR
57; CX = NO_REPLACE
58; DL = NO_INPUT
59
60; EXIT-NORMAL: CARRY is not set
61
62; EXIT-ERROR: CARRY is set
63; Call Get Extended Error for reason code, for SYSDISPMSG and
64; SYSGETMSG.
65
66; INTERNAL REFERENCES:
67; ROUTINES: (Generated by the MSG_SERVICES macro)
68; SYSLOADMSG
69; SYSDISPMSG
70; SYSGETMSG
71
72; DATA AREAS:
73; INCLUDED "DCOMPMS.INC" - message defining control blocks
74; INCLUDE SYSMSG.INC ;Permit System Message handler definition
75
76; EXTERNAL REFERENCES:
77; ROUTINES: none
78
79; DATA AREAS: control blocks pointed to by input registers.
80
81; NOTES:
82; This module should be processed with the SALUT preprocessor
83; with the re-alignment not requested, as:
84
85; SALUT DCOMPSM,NUL
86
87; To assemble these modules, the alphabetical or sequential
88; ordering of segments may be used.
89
90; For LINK instructions, refer to the PROLOG of the main module,
91; DISKCOMP.SAL.
92
93; COPYRIGHT: "Version 4.00 (C)Copyright 1988 Microsoft"
94; "Licensed Material - Property of Microsoft "
95;
96;****************** END OF SPECIFICATIONS *****************************
97 IF1 ;AN000;
98 %OUT COMPONENT=DISKCOMP, MODULE=DCOMPSM.SAL... ;AN000;
99 ENDIF ;AN000;
100; = = = = = = = = = = = =
101 HEADER <LOCAL MACRO DEFINITIONS> ;AN000;
102 INCLUDE PATHMAC.INC ;AN013;
103; = = = = = = = = = = = =
104HEADER MACRO TEXT ;;AN000;
105.XLIST ;;AN000;
106 SUBTTL TEXT ;AN000;
107.LIST ;;AN000;
108 PAGE ;;AN000;
109 ENDM ;;AN000;
110; = = = = = = = = = = = =
111 INCLUDE SYSMSG.INC ;AN000;PERMIT SYSTEM MESSAGE HANDLER DEFINITION
112 MSG_UTILNAME <DISKCOMP> ;AN000;IDENTIFY THE COMPONENT
113; = = = = = = = = = = = =
114 HEADER <DEFINITION OF MESSAGES> ;AN000;
115; $SALUT (4,12,18,36) ;AN000;
116CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
117 ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER
118 ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER
119 ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER
120 ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER
121
122;(deleted ;AN010;) PUBLIC COPYRIGHT ;
123;(deleted ;AN010;) COPYRIGHT DB "MS DOS DISKCOMP Utility "
124;(deleted ;AN010;) INCLUDE COPYRIGH.INC ;(moved to MSG_SERVICES)
125 HEADER <MESSAGE HANDLER CONTROL BLOCKS> ;AN000;
126 INCLUDE MSGHAN.INC ;AN000;DEFINE THE MESSAGE HANDLER CONTROL BLOCKS
127 INCLUDE DCOMPMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS
128 HEADER <MESSAGE DATA AREAS> ;AN000;
129 MSG_SERVICES <MSGDATA> ;AN000;DATA AREA FOR THE MESSAGE HANDLER
130; = = = = = = = = = = = =
131 HEADER <SYSTEM MESSAGE HANDLER> ;AN000;
132 PUBLIC SYSLOADMSG ;AN000;
133 PUBLIC SYSDISPMSG ;AN000;
134
135 MSG_SERVICES <DISKCOMP.CLA,DISKCOMP.CL1,DISKCOMP.CL2> ;AN000;MSG TEXT
136 PATHLABL DCOMPSM ;AN013;
137 ;DEFAULT=CHECK DOS VERSION
138 ;DEFAULT=NEARmsg
139 ;DEFAULT=INPUTmsg
140 ;DEFAULT=NUMmsg
141 ;DEFAULT=NO TIMEmsg
142 ;DEFAULT=NO DATEmsg
143 ;DEFAULT=NO GETmsg
144; MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg>
145.XLIST ;AN000;
146.XCREF ;AN000;
147 MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg> ;AN000;
148.LIST ;AN000;
149.CREF ;AN000;
150; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
151 PATHLABL DCOMPSM ;AN013;
152
153
154CSEG ENDS ;AN000;
155
156include msgdcl.inc
157
158 END ;AN000;
159 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM
new file mode 100644
index 0000000..83d6a61
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM
@@ -0,0 +1,2060 @@
1 PAGE 90,132 ;A2
2 TITLE DISKCOMP.SAL - COPY COMPLETE DISKETTE
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DISKCOMP
5
6; DESCRIPTIVE NAME: Diskette to diskette complete compare Utility
7
8;FUNCTION: DISKCOMP is to compare the contents of the diskette in the
9; specified first drive to the diskette in the second
10; drive. If the first drive has a vol serial number, that
11; field in both diskettes is ignored in the comparison
12; of that one sector, because DISKCOPY will create a unique
13; volume serial number when it duplicates a diskette.
14
15; Multiple compares may be performed with one load of DISKCOMP.
16; A prompt, "Compare another (Y/N)?" permits additional
17; executions, all with the same drive specifications.
18
19; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN".
20
21; INPUT: (DOS command line parameters)
22
23; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
24
25; WHERE
26; [d:][path] - Path where the DISKCOMP command resides.
27
28; [d:] - To specify the First drive
29;
30; [d:] - To specify the Second drive
31;
32; [/1] - To compare only the first side of the diskette,
33; regardless of the diskette or drive type.
34
35; [/8] - To compare only the first 8 sectors per track,
36; even if the first diskette contains 9/15 sectors
37; per track.
38;
39; EXIT-NORMAL: Errorlevel = 0
40; Function completed successfully.
41
42; EXIT-ERROR: Errorlevel = 1
43; Abnormal termination due to error, wrong DOS,
44; invalid parameters, unrecoverable I/O errors on
45; the diskette.
46; Errorlevel = 2
47; Termination requested by CTRL-BREAK.
48
49; EFFECTS: The entire diskette is compared, including the unused
50; sectors. There is no awareness of the separate files
51; involved. A unique volume serial number is ignored
52; for the comparison of the first sector.
53
54; INCLUDED FILES:
55; PATHMAC.INC - PATHGEN MACRO
56; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
57; INCLUDE DISKCOMP.EQU ;EQUATES
58
59; INTERNAL REFERENCES:
60; ROUTINES:
61; BEGIN - entry point from DOS
62; SET_LOGICAL_DRIVE - set log. drive letter as owner of drive
63; COMP - compare the diskette image
64; TEST_REPEAT - see if user wants to compare another
65; READ_SOURCE - read from first drive as much as possible
66; CHECK_SOURCE - determine first diskette type
67; READ_A_SECTOR - use IOCTL read to get a sector
68; CALC_TRACK_SIZE - find mem size to hold one track
69; CHECK_MEMORY_SIZE - be sure enuf memory to compare 1 track
70; COMP_TARGET - compare memory data with secon diskette
71; CHECK_TARGET - compare second disk boot record
72; SET_DRV_PARM - request IOCTL to set device parm
73; COMP_TRACK - read and compare specified track
74; SWAP_DRIVE - setup for diskette swapping
75; READ_TRACK - read a track to memory
76; READ_OP - IOCTL to read a track
77; SET_FOR_THE_OLD - use pre 2.0 BPB
78; SET_TRACKLAYOUT - determine sectors per track
79; GENERIC_IOCTL - perform specified IOCTL function
80; EXTENDED_ERROR_HANDLER - determine and service extended errors
81; SET_DRV_PARM_DEF - set drive parms via IOCTL
82;
83; VOLSER - during compare of first sector, avoid vol ser #
84; SENDMSG - passes parms to regs and invokes the system message routine.
85
86; DATA AREAS:
87; PSP - Contains the DOS command line parameters.
88; WORKAREA - Temporary storage
89
90; EXTERNAL REFERENCES:
91; ROUTINES:
92; SYSDISPMSG - Uses the MSG parm lists to construct the messages
93; on STDOUT.
94; SYSLOADMSG - Loads messages, makes them accessable.
95; SYSPARSE - Processes the DOS Command line, finds parms.
96
97; DATA AREAS:
98; DCOMPSM.SAL - Defines the control blocks that describe the messages
99; DCOMPPAR.SAL - Defines the control blocks that describe the
100; DOS Command line parameters.
101
102; NOTES:
103; This module should be processed with the SALUT preprocessor
104; with the re-alignment not requested, as:
105
106; SALUT DISKCOMP,NUL
107
108; To assemble these modules, the alphabetical or sequential
109; ordering of segments may be used.
110
111; Sample LINK command:
112
113; LINK @DISKCOMP.ARF
114
115; Where the DISKCOMP.ARF is defined as:
116
117; DISKCOMP+
118; DCOMPSM+
119; DCOMPP+
120; DCOMPPAR+
121; COMPINIT
122
123; These modules must be linked in this order. The load module is
124; a COM file, to be converted to COM with EXE2BIN.
125
126; REVISION HISTORY:
127; A000 Version 4.00: add PARSER, System Message Handler,
128; Ignore vol serial number differences.
129; A001 386 Support
130; A002 Avoid duplicate switches
131; A003 PTM 540 Show parm in error
132; A004 PTM 752 Add close door after drive not ready
133; A005 PTM 756 Add help msg after parm error message
134; A006 PTM1100 Clear keyboard buffer before input response
135; A007 PTM1464 Delete unused msgs: 22,23,24
136; A008 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
137; A009 PTM1605 PUT A BLANK LINE OUT BEFORE PRESS ANY KEY MSG
138; A010 PTM1821 move INCLUDE COPYRIGH.INC to MSG_SERVICE macro
139; A011 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
140; REMOVE USE OF GET/SET MEDIA ID
141; A012 PTM3262 Specify BASESW EQU 1 before PARSE.ASM
142; A013 PTM3512 PATHGEN
143;
144; COPYRIGHT: The following notice is found in the OBJ code generated from
145; the "DCOMPSM.SAL" module:
146
147; "Version 4.00 (C) Copyright 1988 Microsoft"
148; "Licensed Material - Property of Microsoft "
149
150;PROGRAM AUTHOR: Original written by: Jin K.
151; 4.00 modifications by: Edwin M. K.
152;****************** END OF SPECIFICATIONS *****************************
153 IF1 ; ;AN000;
154 %OUT COMPONENT=DISKCOMP, MODULE=DISKCOMP.SAL
155 ENDIF ; ;AN000;
156;*****************************************************************************
157; *
158; D I S K C O M P *
159; *
160; UPDATE HISTORY: 8-21, 8-22, 8-30, 9-4, 9-20, 9-21, 12-19 *
161; 2-15-84, 2-17, 4-29, 6-20,7-24,3-27-85 *
162; *
163;*****************************************************************************
164
165 INCLUDE PATHMAC.INC ;AN013;
166 INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
167 INCLUDE DISKCOMP.EQU ;EQUATES
168
169; $salut (4,16,22,36) ; ;AN000;
170;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE,
171;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN
172;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED.
173
174MSG_DESC STRUC ; ;AN000;
175MSG_NUM DW ? ;MESSAGE NUMBER (TO AX) ;AN000;
176MSG_HANDLE DW ? ;HANDLE OF OUTPUT DEVICE (TO BX) ;AN000;
177MSG_SUBLIST DW ? ;POINTER TO SUBLIST (TO SI) ;AN000;
178MSG_COUNT DW ? ;SUBSTITUTION COUNT (TO CX) ;AN000;
179MSG_CLASS DW ? ;MESSAGE CLASS (IN HIGH BYTE, TO DH) ;AN000;
180 ;LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) ;AN000;
181MSG_DESC ENDS ; ;AN000;
182
183MY_BPB STRUC
184CBYTE_SECT DW 0 ; 200H ;BYTES / SECTOR
185CSECT_CLUSTER DB 0 ; 2h ;SECTORS / CLUSTER
186CRESEV_SECT DW 0 ; 1h ;RESERVED SECTORS
187CFAT DB 0 ; 2h ;# OF FATS
188CROOTENTRY DW 0 ; 70h ;# OF ROOT ENTRIES
189CTOTSECT DW 0 ; 02D0h ;TOTAL # OF SECTORS INCLUDING
190 ; BOOT SECT, DIRECTORIES
191MEDIA_DESCRIP DB 0 ;0FDh ;MEDIA DISCRIPTOR
192CSECT_FAT DW 0 ; 2h ;SECTORS / FAT
193CSECT_TRACK DW 0 ;
194CHEAD DW 0 ;
195CHIDDEN_SECT DD 0 ;
196BIG_TOT_SECT DD 0 ;
197 DB 6 DUP (0) ;
198MY_BPB ENDS
199
200CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AN000;
201 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
202
203;*****************************************************************************
204; *
205; EXTERNAL VARIABLES *
206; *
207;*****************************************************************************
208;$salut (4,2,9,36)
209
210.XLIST
211;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
212;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
213;EXTRN COMPAT_ERROR :NEAR
214;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
215;EXTRN YES :BYTE
216;EXTRN NO :BYTE
217;EXTRN MSG_FIRST_BAD_PTR :BYTE
218.LIST
219
220 EXTRN SYSLOADMSG :NEAR ;SYSTEM MSG HANDLER INTIALIZATION ;AN000;
221 EXTRN SYSDISPMSG :NEAR ;SYSTEM MSG HANDLER DISPLAY ;AN000;
222
223 EXTRN INIT :NEAR ;INITIALIZATION ROUTINE
224
225 EXTRN MSG_TRACKS :WORD ; ;AN000;
226 EXTRN MSG_SECTRK :WORD ; ;AN000;
227 EXTRN MSG_SIDES :WORD ; ;AN000;
228
229 EXTRN ASCII_DRV1_ID :BYTE ; ;AN000;
230 EXTRN ASCII_DRV2_ID :BYTE ; ;AN000;
231
232 EXTRN SUBLIST_78 :WORD ; ;AN000;
233 EXTRN SUBLIST_17B :WORD ; ;AN000;
234
235 EXTRN MSGNUM_EXTERR :WORD ;EXTENDED ERROR MSG DESCRIPTOR ;AN000;
236 EXTRN MSGNUM_LOAD_FIRST :BYTE ; ;AC000;
237 EXTRN MSGNUM_LOAD_SECOND :BYTE ; ;AC000;
238 EXTRN MSGNUM_NOT_COMPATIBLE:BYTE ; ;AC000;
239 EXTRN MSGNUM_COMP_ANOTHER:BYTE ; ;AC000;
240 EXTRN MSGNUM_GET_READY :BYTE ; ;AC000;
241 EXTRN MSGNUM_CLOSE_DOOR :BYTE ; ;AN004;
242 EXTRN MSGNUM_FATAL_ERROR :BYTE ; ;AC000;
243 EXTRN MSGNUM_UNSUF_MEMORY:BYTE ; ;AC000;
244 EXTRN MSGNUM_BAD_FIRST :BYTE ; ;AC000;
245 EXTRN MSGNUM_BAD_SECOND :BYTE ; ;AC000;
246 EXTRN MSGNUM_HARD_ERROR_READ :BYTE ; ;AC000;
247 EXTRN MSGNUM_HARD_ERROR_COMP :BYTE ; ;AC000;
248 EXTRN MSGNUM_COMPARING :BYTE ; ;AC000;
249 EXTRN MSGNUM_STRIKE :BYTE ; ;AC000;
250 EXTRN MSGNUM_WRITE_PROTECT:BYTE ; ;AC000;
251 EXTRN MSGNUM_COMP_OK :BYTE ; ;AC000;
252 EXTRN MSGNUM_NEWLINE :BYTE ;
253 EXTRN DRIVE_LETTER :BYTE ;
254 EXTRN SKIP_MSG :BYTE ;NULL REPLACEMENT FOR DRIVE LETTER ;AN000;
255 PAGE
256;*****************************************************************************
257; *
258; PUBLIC VARIABLES *
259; *
260;*****************************************************************************
261
262 PUBLIC DISKCOMP_BEGIN
263 PUBLIC DISKCOMP_END
264 PUBLIC RECOMMENDED_BYTES_SECTOR
265 PUBLIC S_OWNER_SAVED
266 PUBLIC T_OWNER_SAVED
267 PUBLIC COMP
268 PUBLIC SOURCE_DRIVE
269 PUBLIC TARGET_DRIVE
270 PUBLIC S_DRV_SECT_TRACK
271 PUBLIC S_DRV_HEADS
272 PUBLIC S_DRV_TRACKS
273 PUBLIC T_DRV_SECT_TRACK
274 PUBLIC T_DRV_HEADS
275 PUBLIC T_DRV_TRACKS
276 PUBLIC USER_OPTION
277 PUBLIC COPY_TYPE
278 PUBLIC END_OF_TRACK
279 PUBLIC BUFFER_BEGIN
280 PUBLIC START_BUFFER
281 PUBLIC BUFFER_END
282 PUBLIC TRACK_TO_READ
283 PUBLIC TRACK_TO_COMP
284 PUBLIC SIDE
285 PUBLIC USER_INPUT
286 PUBLIC MAIN_EXIT
287
288 PUBLIC NO_OF_SIDES
289 PUBLIC USER_OPTION_8
290 PUBLIC ORG_SOURCE_DRIVE
291 PUBLIC ORG_TARGET_DRIVE
292 PUBLIC COMP_STATUS
293 PUBLIC OPERATION
294
295 PUBLIC IO_ERROR
296
297 PUBLIC DS_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
298 PUBLIC DT_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
299 PUBLIC DS_specialFunctions ;AND THEIR CONTENTS
300 PUBLIC DT_specialFunctions
301 PUBLIC DS_deviceType
302 PUBLIC DT_deviceType
303 PUBLIC DS_deviceAttributes
304 PUBLIC DT_deviceAttributes
305 PUBLIC DS_numberOfCylinders
306 PUBLIC DT_numberOfCylinders
307 PUBLIC DS_mediaType
308 PUBLIC DT_mediaType
309 PUBLIC DS_BPB_PTR
310 PUBLIC DT_BPB_PTR
311
312 PUBLIC MS_IOCTL_DRV_PARM ;DRIVE PARM FROM SOURCE MEDIUM
313 PUBLIC MT_IOCTL_DRV_PARM ;DRIVE PARM FROM TARGET MEDIUM
314
315;*****************************************************************************
316 ORG 100H ;PROGRAM ENTRY POINT ;
317
318DISKCOMP:
319 JMP BEGIN
320;*****************************************************************************
321 EVEN ;PUT STACK ONTO A WORD ALIGNMENT BOUNDARY ;AN000;
322;INTERNAL STACK AREA
323
324 DB 64 DUP ('STACK ') ;512 BYTES
325
326MY_STACK_PTR LABEL WORD
327 PAGE
328;*****************************************************************************
329; *
330; INTERNAL VARIABLES *
331; *
332;*****************************************************************************
333
334; $salut (4,22,26,36) ; ;AN000;
335;DEFAULT BPB FOR OLD MEDIA
336;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
337BPB48_SINGLE DW 512 ;BYTES/SECTOR
338 DB 1 ;SECTOR/CLUSTER
339 DW 1 ;# OF RESERVED SECTORS
340 DB 2 ;# OF FATS
341 DW 40h ;# OF ROOT ENTRY
342 DW 168h ;TOTAL # OF SECTORS IN THE MEDIA
343 DB 0FCh ;MEDIA BYTE
344 DW 2 ;SECTORS/FAT
345
346;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
347BPB48_DOUBLE DW 512 ;BYTES/SECTOR
348 DB 2 ;SECTOR/CLUSTER
349 DW 1 ;# OF RESERVED SECTORS
350 DB 2 ;# OF FATS
351 DW 70h ;# OF ROOT ENTRY
352 DW 2D0h ;TOTAL # OF SECTORS IN THE MEDIA
353 DB 0FDh ;MEDIA BYTE
354 DW 2 ;SECTORS/FAT
355
356;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
357BPB96 DW 512 ;BYTES/SECTOR
358 DB 1 ;SECTOR/CLUSTER
359 DW 1 ;# OF RESERVED SECTORS
360 DB 2 ;# OF FATS
361 DW 0E0h ;# OF ROOT ENTRY
362 DW 960h ;TOTAL # OF SECTORS IN THE MEDIA
363 DB 0F9h ;MEDIA BYTE
364 DW 7 ;SECTORS/FAT
365BPB96_LENG EQU $-BPB96 ;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
366
367
368
369; INPUT PARMETERS FROM INIT SUBROUTINE:
370
371S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED
372 ; SOURCE DRIVE OWNERSHIP
373T_OWNER_SAVED DB 0
374RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
375
376;IT IS ASSUMED THE NEXT TWO BYTES ARE CONSECUTIVE,
377;AND DEFINED IN SOURCE/TARGET ORDER, BY DCOMPPAR.SAL.
378SOURCE_DRIVE DB 0 ;1=A:, 2=B:,...
379TARGET_DRIVE DB 0
380
381ORG_SOURCE_DRIVE DB ? ;ORIGINAL SOURCE DRIVE
382ORG_TARGET_DRIVE DB ? ;ORIGINAL TARGET DRIVE
383
384USER_OPTION DB 0
385COPY_TYPE DB 1
386START_BUFFER DW 0
387BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT]
388BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT]
389USER_OPTION_8 DB ?
390SECT_TRACK_LAYOUT DW 0
391
392S_DRV_SECT_TRACK DB ? ;SECT/TRACK, device informations.
393S_DRV_HEADS DB ? ;# OF HEADS
394S_DRV_TRACKS DB ? ;# OF TRACKS
395T_DRV_SECT_TRACK DB ?
396T_DRV_HEADS DB ?
397T_DRV_TRACKS DB ?
398
399;LOCAL VARIABLES:
400FIRST_TIME DB 0 ;SWITCH TO ACTIVATE VOLSER CHECK ;AN000;
401EXITFL DB EXOK ;ERRORLEVEL VALUE ;AN000;
402 PUBLIC EXITFL ; ;AN000;
403EXCBR EQU 2 ;CONTROL-BREAK REQUESTED TERMINATION ;AN000;
404EXVER EQU 1 ;BAD DOS VERSION ERRORLEVEL CODE ;AN000;
405EXPAR EQU 1 ;ERROR IN INPUT PARMS IN COMMAND LINE ;AN000;
406EXOK EQU 0 ;NORMAL ERRORLEVEL RET CODE ;AN000;
407 PUBLIC EXPAR ; ;AN000;
408
409IOCTL_SECTOR DW 1 ;used for READ_A_SECTOR routine.
410IOCTL_TRACK DW 0 ;IN THE TRACK
411IOCTL_HEAD DW 0 ;HEAD 0
412SAV_CSECT DW 0 ;TEMPORARY SAVING PLACE
413
414BOOT_SECT_TRACK DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
415BOOT_TOT_TRACK DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
416BOOT_NUM_HEAD DW 0 ;NUMBER OF HEADS
417BOOT_BYTE_SECTOR DW 0 ;BYTES / SECTOR
418
419READ_S_BPB_FAILURE DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
420READ_T_BPB_FAILURE DB 0
421
422;*** Informations gotten from CHECK_SOURCE.
423;*** These will be used as a basis for the comp process.
424LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
425END_OF_TRACK DB 15 ;END OF TRACK
426bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes
427NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED
428
429TRACK_TO_READ DB 0
430TRACK_TO_COMP DB 0
431TRACK_SIZE DW 0 ;BYTES/CYLINDER [IN SEGMENTS]
432SECTOR_SIZE DB 0 ;BYTES/SECTOR [IN SEGMENTS]
433BYTES_IN_TRACK DW ? ;BYTES/ONE SIDE TRACK (USED IN COMP_TRACK)
434BUFFER_PTR DW ?
435COMP_ERROR DB 0
436SIDE DB ?
437OPERATION DB ?
438COMP_STATUS DB ?
439USER_INPUT DB ? ;DISKCOMP AGAIN?
440SEC_BUFFER DW ? ;SECONDARY BUFFER SEG ADDR
441COMPARE_PTR DW ? ;COMPARE POINTER
442IO_ERROR DB 0 ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
443MSG_FLAG DB ?
444S_DRV_SET_FLAG DB 0 ;SOURCE DEVICE PARM HAS BEEN SET?
445T_DRV_SET_FLAG DB 0
446
447;---------------------------------------
448;DEVICE PARAMETER TABLE
449;the returned info. still has the following format.
450
451DS_IOCTL_DRV_PARM LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
452DS_specialFunctions db ?
453DS_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
454 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
455DS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
456 ; LINE SUPPORTED
457DS_numberOfCylinders dw ?
458DS_mediaType db ?
459DS_BPB_PTR LABEL BYTE
460DS_deviceBPB my_bpb <>
461DS_trackLayout LABEL WORD ; ;AC000;
462 my_trackLayout ; ;AC000;
463;---------------------------------------
464
465DT_IOCTL_DRV_PARM LABEL BYTE
466DT_specialFunctions db ?
467DT_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
468 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
469DT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
470 ; LINE SUPPORTED
471DT_numberOfCylinders dw ?
472DT_mediaType db ?
473DT_BPB_PTR LABEL BYTE
474DT_deviceBPB my_bpb <>
475DT_trackLayout LABEL WORD ; ;AC000;
476 my_trackLayout ; ;AC000;
477
478;---------------------------------------
479
480MS_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
481MS_specialFunctions db ?
482MS_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
483 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
484MS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
485 ; LINE SUPPORTED
486MS_numberOfCylinders dw ?
487MS_mediaType db ?
488MS_BPB_PTR LABEL BYTE
489MS_deviceBPB my_bpb <>
490MS_deviceBPB_leng equ $-MS_deviceBPB
491MS_trackLayout LABEL WORD ; ;AC000;
492 my_trackLayout ; ;AC000;
493;---------------------------------------
494MT_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
495MT_specialFunctions db ?
496MT_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
497 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
498MT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
499 ; LINE SUPPORTED
500MT_numberOfCylinders dw ?
501MT_mediaType db ?
502MT_BPB_PTR LABEL BYTE
503MT_deviceBPB my_bpb <>
504MT_trackLayout LABEL WORD ; ;AC000;
505 my_trackLayout ; ;AC000;
506
507;IOCTL read/write a track.
508IOCTL_R_W LABEL BYTE
509specialFunctions db 0
510Head dw ?
511Cylinder dw ?
512FirstSectors dw ?
513numberOfSectors dw ?
514TAddress_off dw ?
515TAddress_seg dw ?
516
517;(deleted ;AN011;) MEDIA_ID_BUFFER A_MEDIA_ID_INFO <> ;BUFFER FOR GET/SET MEDIA ID ;AN000;
518 PATHLABL DISKCOMP ;AN013;
519 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ; ;AN000;
520 PUBLIC DISKCOMP_BEGIN ; ;AN000;
521DISKCOMP_BEGIN LABEL BYTE
522;*****************************************************************************
523; *
524; D I S K C O M P M A I N P R O G R A M *
525; *
526;*****************************************************************************
527
528; $salut (4,4,10,36) ; ;AN000;
529BEGIN PROC NEAR
530 PUBLIC BEGIN ; ;AN000;
531;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
532
533 MOV SP, OFFSET MY_STACK_PTR ;MOVE SP TO MY STACK AREA
534 CALL SYSLOADMSG ;INIT SYSMSG HANDLER ;AN000;
535
536; $IF C ;IF THERE WAS A PROBLEM ;AN000;
537 JNC $$IF1
538 CALL SYSDISPMSG ;LET HIM SAY WHY HE HAD A PROBLEM ;AN000;
539
540 MOV EXITFL,EXVER ;TELL ERRORLEVEL BAD DOS VERSION ;AN000;
541; $ELSE ;SINCE SYSDISPMSG IS HAPPY ;AN000;
542 JMP SHORT $$EN1
543$$IF1:
544 CALL INIT ;RUN INITIALIZATION ROUTINE
545
546 CMP DX,FINE ;CHECK FOR ERROR DURING INIT
547; $IF E ;IF NO ERROR THEN PROCEED TO COMP
548 JNE $$IF3
549; $DO
550$$DO4:
551 CALL COMP ;PERFORM DISKCOMP
552
553 CALL TEST_REPEAT ;COMP ANOTHER ?
554
555; $ENDDO C
556 JNC $$DO4
557 ;NORMAL RETURN CODE ALREADY IN "EXITFL"
558; $ELSE ;ELSE IF ERROR DETECTED IN INIT
559 JMP SHORT $$EN3
560$$IF3:
561 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
562 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
563 CALL SENDMSG ;DISPLAY THE ERROR MESSAGE ;AC000;
564
565 MOV EXITFL,EXVER ;ERROR RETURN CODE ;AC000;
566; $ENDIF
567$$EN3:
568 JMP SHORT EXIT_TO_DOS
569
570MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
571 MOV EXITFL,EXCBR ; FOR CONTROL-BREAK EXIT ;AC000;
572
573EXIT_TO_DOS:
574 XOR BX, BX
575
576 MOV BL, S_OWNER_SAVED ;RESTORE ORIGINAL SOURCE,
577 ; TARGET DRIVE OWNER.
578 CALL SET_LOGICAL_DRIVE
579
580 MOV BL, T_OWNER_SAVED
581 CALL SET_LOGICAL_DRIVE
582
583 CMP S_DRV_SET_FLAG, 0
584; $IF NE ; ;AN000;
585 JE $$IF8
586 MOV BL, S_OWNER_SAVED
587 MOV DS_specialFunctions, SET_SP_FUNC_DOS ;=0
588 MOV DX, OFFSET DS_IOCTL_DRV_PARM
589 CALL SET_DRV_PARM_DEF ;RESTORE SOURCE DRIVE PARM
590
591; $ENDIF ; ;AN000;
592$$IF8:
593
594 CMP T_DRV_SET_FLAG, 0
595; $IF NE ; ;AN000;
596 JE $$IF10
597 MOV BL, T_OWNER_SAVED
598 MOV DT_specialFunctions, SET_SP_FUNC_DOS ;=0
599 MOV DX, OFFSET DT_IOCTL_DRV_PARM
600 CALL SET_DRV_PARM_DEF ;RESTORE TARGET DRIVE PARM
601
602; $ENDIF ; ;AN000;
603$$IF10:
604EXIT_PROGRAM:
605 MOV AL,EXITFL ;PASS ERRORLEVEL RET CODE ;AN000;
606; $ENDIF ;OK WITH SYSDISPMSG? ;AN000;
607$$EN1:
608 MOV AL,EXITFL ;PASS BACK ERRORLEVEL RET CODE ;AN000;
609 DOSCALL RET_CD_EXIT ;RETURN TO DOS WITH RET CODE ;AN000;
610
611 INT 20H ;IF ABOVE NOT WORK, ;AN000;
612BEGIN ENDP ; ;AN000;
613; = = = = = = = = = = = = = = = = =
614 HEADER <MORE_INIT - FINISH INIT, DO COMP> ; ;AN000;
615MORE_INIT PROC NEAR ; ;AN000;
616 RET ;RETURN TO CALLER ;AN000;
617MORE_INIT ENDP ; ;AN000;
618; = = = = = = = = = = = =
619 HEADER <SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE> ; ;AN000;
620 PUBLIC SET_LOGICAL_DRIVE
621;*****************************************************************************
622SET_LOGICAL_DRIVE PROC NEAR
623; *** SET THE LOGICAL DRIVE LETTER THAT WILL BE THE OWNER OF THE DRIVE
624; INPUT: BL - DRIVE LETTER
625; OUTPUT: OWNER WILL BE SET ACCORDINGLY.
626;*****************************************************************************
627 CMP BL, 0 ;IS THIS DRIVE ZERO?
628 ;IF BL = 0, THEN JUST RETURN
629; $IF NE
630 JE $$IF13
631 DOSCALL IOCTL_FUNC,SET_LOG_DRIVE ; ;AC000;
632 ;SET BL AS AN OWNER OF THAT DRIVE
633; $ENDIF
634$$IF13:
635 RET
636SET_LOGICAL_DRIVE ENDP
637; = = = = = = = = = = = =
638 HEADER <COMP - PERFORM THE OVERALL COMPARISON> ; ;AN000;
639;*****************************************************************************
640COMP PROC NEAR
641;*****************************************************************************
642 MOV AL,ORG_SOURCE_DRIVE ;INITIALIZE THE FIRST AND SECOND
643 MOV SOURCE_DRIVE,AL ;DRIVE IN THE ORDER THE USER
644 MOV AL,ORG_TARGET_DRIVE ;ENTERED ON THE COMMAND LINE
645 MOV TARGET_DRIVE,AL
646 MOV AX, RECOMMENDED_BYTES_SECTOR
647 MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE
648 ; TO READ A SECTOR
649 MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG
650 MOV READ_T_BPB_FAILURE, 0
651 MOV COMP_ERROR,0 ;RESET COMPARE ERROR COUNT
652 MOV COMP_STATUS,OK ;RESET COMP STATUS BYTE
653 CMP COPY_TYPE,2 ;IF TWO DRIVE COMP
654; $IF E
655 JNE $$IF15
656 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
657
658 CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000;
659
660 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
661
662; $ENDIF
663$$IF15:
664 MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS
665 MOV TRACK_TO_COMP,0
666
667COMP_TEST_END:
668 MOV AL,TRACK_TO_COMP ;WHILE TRACK_TO_COMP<=LAST_TRACK
669 CMP AL,LAST_TRACK
670 JA COMP_END
671
672 CALL READ_SOURCE
673
674 CMP COMP_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE
675 JE COMP_EXIT
676
677 CALL COMP_TARGET
678
679 CMP COMP_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE
680 JE COMP_EXIT ;DISKETTES ARE COMPATIBLE
681
682 JMP COMP_TEST_END
683
684COMP_END:
685 CMP COMP_ERROR,0 ;IF ERROR IN COMP
686; $IF E ;WARN USER
687 JNE $$IF17
688 PRINT MSGNUM_COMP_OK ;"Compare OK" ;AC000;
689
690;kiser note: this is a warning????
691
692; $ENDIF
693$$IF17:
694
695COMP_EXIT:
696 CMP COMP_STATUS,FATAL ;WAS COMP ABORTED ?
697; $IF E
698 JNE $$IF19
699 ;"Compare process ended"
700 PRINT MSGNUM_FATAL_ERROR ;IF SO THEN TELL USER ;AC000;
701
702; $ENDIF
703$$IF19:
704 RET
705
706COMP ENDP
707; = = = = = = = = = = = =
708 HEADER <DISPLAY_LOAD_FIRST - MOUNT FIRST DISKETTE> ; ;AN000;
709DISPLAY_LOAD_FIRST PROC NEAR ; ;AN000;
710 PUBLIC DISPLAY_LOAD_FIRST ; ;AN000;
711; = = = = = = = = = = = =
712
713 MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV1_ID ;PASS CHAR DRIVE ID ;AN000;
714 ;"Insert FIRST diskette in drive %1:"
715 PRINT MSGNUM_LOAD_FIRST ;OUTPUT LOAD FIRST DISKETTE MESSAGE ;AC000;
716
717 MOV MSG_FLAG,SECOND
718 RET ;RETURN TO CALLER ;AN000;
719DISPLAY_LOAD_FIRST ENDP ; ;AN000;
720; = = = = = = = = = = = =
721 HEADER <DISPLAY_SECOND - MOUNT FIRST DISKETTE> ; ;AN000;
722DISPLAY_LOAD_SECOND PROC NEAR ; ;AN000;
723 PUBLIC DISPLAY_LOAD_SECOND ; ;AN000;
724; = = = = = = = = = = = =
725
726 MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV2_ID ;PASS CHAR DRIVE ID ;AN000;
727 ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF
728 PRINT MSGNUM_LOAD_SECOND ;OUTPUT LOAD SECOND DISKETTE MESSAGE ;AC000;
729
730 MOV MSG_FLAG,FIRST
731 RET ;RETURN TO CALLER ;AN000;
732DISPLAY_LOAD_SECOND ENDP ; ;AN000;
733; = = = = = = = = = = = =
734 HEADER <TEST_REPEAT - PROMPT FOR ANOTHER COMPARE> ; ;AN000;
735;*****************************************************************************
736; *
737 PUBLIC TEST_REPEAT ;MAKE ENTRY IN LINK MAP ;AN000;
738TEST_REPEAT PROC NEAR ;TEST IF USER WANTS TO COMP ANOTHER *
739; DISKETTE *
740; INPUT : USER_INPUT ("Y" OR "N")
741; OUTPUT: NC = COMP AGAIN *
742; CY = EXIT TO DOS *
743;*****************************************************************************
744; $SEARCH ;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED ;AC000;
745$$DO21:
746 ;"Compare another diskette (Y/N)?"
747 PRINT MSGNUM_COMP_ANOTHER ;SEE IF USER WANTS TO COMPARE ANOTHER ;AC000;
748 ; AND READ RESPONSE TO AL
749 PUSH AX ;SAVE THE RESPONSE ;AN000;
750 PRINT MSGNUM_NEWLINE ;CR,LF,LF ;AC000;
751
752 POP DX ;RESTORE THE REPONSE CHAR TO DL ;AN000;
753 CALL YESNO ;CHECK FOR (Y/N) ;AN000;
754
755; $EXITIF C,NUL ;QUIT IF OK ANSWER ;AN000;
756 JC $$SR21
757 CMP AL,BAD_YESNO ;WAS THE RESPONSE INVALID? ;AN000;
758; $ENDLOOP B ;QUIT IF OK ANSWER (AX=0 OR 1) ;AN000;
759 JNB $$DO21
760 CMP AL,YES ;WAS "YES" SPECIFIED ;AN000;
761; $IF E ;IF "YES" ;AN000;
762 JNE $$IF24
763 MOV FIRST_TIME,ZERO ;SET UP TO DO ANOTHER VOLSER CHECK ;AN000;
764 CLC ;CLEAR CARRY TO INDICATE COMPARE AGAIN ;AN000;
765; $ELSE ;SINCE NOT "YES" ;AN000;
766 JMP SHORT $$EN24
767$$IF24:
768 STC ;SET CARRY TO INDICATE NO REPEAT ;AN000;
769; $ENDIF ; ;AN000;
770$$EN24:
771; $ENDSRCH ; ;AN000;
772$$SR21:
773 RET
774
775TEST_REPEAT ENDP
776; = = = = = = = = = = = =
777 HEADER <READ_SOURCE - FILL AVAIL MEM WITH FIRST DISKETTE> ; ;AN000;
778;*****************************************************************************
779; *
780 PUBLIC READ_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000;
781READ_SOURCE PROC NEAR ;FILL ALL AVAILABLE MOMORY WITH SOURCE DATA
782; *
783;*****************************************************************************
784
785 CMP TRACK_TO_READ,0 ;1ST TRACK ?
786; $IF E ;IF SO
787 JNE $$IF28
788 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP
789; $IF E ;PROMPT MSG
790 JNE $$IF29
791 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
792
793 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC000;
794
795; $ENDIF
796$$IF29:
797 CALL CHECK_SOURCE ;DO NECESSARY CHECKING
798
799 CALL CALC_TRACK_SIZE
800
801 CALL CHECK_MEMORY_SIZE
802
803 CMP COMP_STATUS,FATAL
804 JE RS_EXIT
805
806; $ENDIF
807$$IF28:
808 MOV BX,BUFFER_BEGIN
809 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
810
811; $DO
812$$DO32:
813 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
814 CMP AL,LAST_TRACK
815; $LEAVE A
816 JA $$EN32
817
818 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
819 ADD AX,TRACK_SIZE
820 CMP AX,BUFFER_END
821; $LEAVE A
822 JA $$EN32
823
824 CALL READ_TRACK ;NO, GO READ ANOTHER TRACK
825
826 INC TRACK_TO_READ
827; $ENDDO
828 JMP SHORT $$DO32
829$$EN32:
830
831RS_EXIT:
832 RET
833
834READ_SOURCE ENDP
835; = = = = = = = = = = = =
836 HEADER <CHECK_SOURCE - DETERMINE FIRST DISKETTE TYPE> ; ;AN000;
837;*****************************************************************************
838; *
839 PUBLIC CHECK_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000;
840CHECK_SOURCE PROC NEAR ;CHECK SOURCE DISKETTE TYPE *
841; SET END_OF_TRACK, LAST_TRACK *
842; NO_OF_SIDES, bSECTOR_SIZE *
843; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
844; ** fails to get that info, then the source medium must be bad(vergin) or *
845; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
846; ** For compatibility reasons (in case of non IBM formatted media), this *
847; ** routine covers old diskcopy routines. But this will only supports
848; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
849; ** media. Other non IBM formatted media which are formatted differenty
850; ** from those values will result in unpreditable copy process.
851;*****************************************************************************
852
853CS_AGAIN:
854 XOR BX, BX
855 MOV BL, SOURCE_DRIVE
856 MOV MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b
857 MOV CL, GETDEVPARM ;=60h
858 MOV DX, OFFSET MS_IOCTL_DRV_PARM
859 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
860 ;WITH DEFAULT DEVICE INFO.
861 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
862 JE CS_AGAIN
863
864 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
865 JNE CS_NEW ; ;AC000;
866CS_OLD_BRIDGE:
867 JMP CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST. ;AC000;
868CS_NEW: ; ;AN000;
869 cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86 J.K.
870 je cs_old_BRIDGE
871
872 cmp ms_deviceBPB.chead,0 ;cannot trust the info. from DOS.
873 je cs_old ;sanity check for devide by 0.
874
875 MOV AX, MS_deviceBPB.CTOTSECT
876 CWD ;CONVERT IT TO A DOUBLE WORD
877 DIV MS_deviceBPB.CSECT_TRACK
878 DIV MS_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
879 CMP AL, T_DRV_TRACKS ;IF # OF TRACKS FOR SOURCE MEDIA > # OF
880 ; TRACKS FOR TARGET DEVICE
881 JA CS_FATAL ;THEN, NOT COMPATIBLE
882
883 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM'S USE.
884 MOV LAST_TRACK, AL ;SET LAST_TRACK
885 MOV AX, MS_deviceBPB.CSECT_TRACK
886 MOV SECT_TRACK_LAYOUT, AX ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
887 CMP USER_OPTION_8, ON ;/8 OPTION SPECIFIED?
888 JNE CS_GO_ON
889
890 CMP AX, 8 ;SOURCE MEDIA # OF SECTORS/TRACK < 8 ?
891 JB CS_FATAL ;IF IT IS, THEN FATAL ERROR.
892
893 MOV AX, 8 ;ELSE SET IT TO 8
894CS_GO_ON:
895 CMP AL, T_DRV_SECT_TRACK
896 JA CS_FATAL
897
898 MOV END_OF_TRACK, AL ;SET END_OF_TRACK
899 MOV AX, MS_deviceBPB.CBYTE_SECT
900 MOV bSECTOR_SIZE, AX ;set the sector size in bytes.
901 CMP USER_OPTION, 1
902 JE CS_OPTION_1
903
904 MOV AX, MS_deviceBPB.CHEAD ;HEAD=1, 2
905 CMP AL, T_DRV_HEADS ;COMPARE SOURCE MEDIA SIDE WITH TARGET
906 ; DRIVE HEAD NUMBER
907 JA CS_FATAL ;SOURCE MEDIUM IS DOUBLE SIDED AND
908 ; TARGET DRIVE IS SINGLE SIDED.
909
910 DEC AX
911 MOV NO_OF_SIDES, AL ;NO_OF_SIDES=0, 1
912 JMP CS_SET_TABLE
913
914CS_FATAL:
915 MOV COMP_STATUS, FATAL
916 ;"Drive types or diskette types"
917 ;"not compatible"
918 PRINT MSGNUM_NOT_COMPATIBLE ; ;AC000;
919
920 JMP CS_EXIT
921
922CS_BAD:
923 MOV COMP_STATUS, FATAL
924 PRINT MSGNUM_BAD_FIRST ;"FIRST diskette bad or incompatible" ;AC000;
925
926 JMP CS_EXIT
927
928CS_OLD:
929
930 MOV READ_S_BPB_FAILURE, 1 ;SET FLAG
931 MOV bSECTOR_SIZE, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
932 XOR BX, BX
933 MOV BL, SOURCE_DRIVE
934 MOV IOCTL_TRACK, 0 ;TRACK=0
935 MOV IOCTL_SECTOR, 8 ;SECTOR=8
936 MOV IOCTL_HEAD, 0 ;HEAD = 0
937 CALL READ_A_SECTOR
938
939 JC CS_BAD ;SOURCE BAD
940
941 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR=9
942 CALL READ_A_SECTOR
943
944 JC CS_SECT8 ;YES, 8 SECTORS. ASSUME 40 TRACKS
945
946 MOV IOCTL_SECTOR, 15 ;try to read sector=15
947 CALL READ_A_SECTOR
948
949 JC CS_SECT9 ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
950
951 JMP CS_SECT15
952
953CS_OPTION_1:
954 MOV NO_OF_SIDES, 0 ;1 SIDE COPY
955 JMP CS_SET_TABLE
956
957CS_SECT15:
958 MOV SECT_TRACK_LAYOUT, 15 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
959 MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15
960 MOV LAST_TRACK, 79
961 JMP CS_OPTIONS
962
963CS_SECT8:
964 MOV SECT_TRACK_LAYOUT, 8 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
965 MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS
966 MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS.
967 JMP CS_OPTIONS
968
969CS_SECT9:
970 MOV SECT_TRACK_LAYOUT, 9 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
971 MOV END_OF_TRACK, 9
972 MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE
973CS_OPTIONS:
974 CMP USER_OPTION_8, ON
975 JNE CS_CHK_SIDE
976
977 MOV END_OF_TRACK, 8
978CS_CHK_SIDE:
979 CMP USER_OPTION, 1
980 JE CS_OPTION_1
981
982 MOV IOCTL_HEAD, 1 ;HEAD 1
983 XOR AX, AX
984 MOV AL, END_OF_TRACK ;READ MATCHING END_OF_TRACK
985 ; OF THE OTHER SURFACE.
986 MOV IOCTL_SECTOR, AX
987 CALL READ_A_SECTOR
988
989 JC CS_OPTION_1 ;1 SIDED SOURCE
990
991 MOV NO_OF_SIDES, 1 ;2 SIDED SOURCE
992 CMP T_DRV_HEADS, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
993 ; DOUBLE SIDED DRV?
994 JE CS_SET_TABLE
995
996 JMP CS_FATAL ;NOT COMPATIBLE
997
998CS_SET_TABLE:
999 CMP READ_S_BPB_FAILURE, 1 ;diskette without BPB info?
1000 JNE CS_SET_TABLE_NEXT
1001
1002 CALL SET_FOR_THE_OLD ;set deviceBPB info for before 2.0 level
1003
1004CS_SET_TABLE_NEXT:
1005 MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE
1006 CALL SET_TRACKLAYOUT
1007
1008 MOV S_DRV_SET_FLAG, 1 ;indicate SOURCE DRIVE
1009 ; PARAMETER HAS BEEN SET
1010 XOR BX, BX
1011 MOV BL, SOURCE_DRIVE
1012 MOV DX, OFFSET MS_IOCTL_DRV_PARM
1013 MOV MS_specialFunctions, SET_SP_FUNC_DEF
1014 CALL SET_DRV_PARM_DEF ;set device parameter for read
1015
1016 XOR AX, AX
1017 MOV AL, END_OF_TRACK
1018 MOV numberOfSectors, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1019
1020 MOV AL, LAST_TRACK ;NOW, SHOW THE MESSAGE "COMPARING ..."
1021 INC AL
1022 MOV BYTE PTR MSG_TRACKS,AL ;HOW MANY TRACKS? ;AC000;
1023
1024 MOV AL, END_OF_TRACK
1025 MOV BYTE PTR MSG_SECTRK,AL ;HOW MANY SECTORS? ;AC000;
1026
1027 MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY
1028 INC AL
1029 MOV BYTE PTR MSG_SIDES,AL ; ;AC000;
1030 ;CR,LF,"Comparing %1 tracks",CR,LF
1031 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1032 PRINT MSGNUM_COMPARING ; ;AC000;
1033
1034CS_EXIT:
1035 RET
1036
1037CHECK_SOURCE ENDP
1038; = = = = = = = = = = = =
1039 HEADER <READ_A_SECTOR - USE IOCTL READ TO GET A SECTOR> ; ;AN000;
1040;*****************************************************************************
1041 PUBLIC READ_A_SECTOR ;MAKE ENTRY IN LINK MAP ;AN000;
1042READ_A_SECTOR PROC NEAR
1043;
1044;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL.
1045;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY.
1046;INPUT: BX - LOGICAL DRIVE NUMBER
1047; IOCTL_SECTOR - SECTOR TO READ
1048; IOCTL_TRACK - TRACK
1049; IOCTL_HEAD - HEAD TO READ
1050; bSECTOR_SIZE - SECTOR SIZE IN BYTES
1051;OUTPUT:
1052; IF NOT A SUCCESS, CARRY WILL BE SET
1053; ALL REGISTORS SAVED
1054;*****************************************************************************
1055 PUSH AX
1056 PUSH BX
1057 PUSH CX
1058 PUSH DX
1059
1060 MOV AX, numberOfSectors ;SAVE IOCTL_R_W TABLE VALUES
1061 MOV SAV_CSECT, AX
1062
1063; $DO
1064$$DO36:
1065 MOV AX, IOCTL_HEAD
1066 MOV Head, AX ;SURFACE TO READ
1067 MOV AX, IOCTL_TRACK
1068 MOV Cylinder, AX ;TRACK TO READ
1069 MOV AX, IOCTL_SECTOR
1070 dec ax ;????? currently firstsector=0 =>
1071 ; 1st sector ????
1072 MOV FirstSectors, AX ;SECTOR TO READ
1073 MOV numberOfSectors, 1 ;read just one sector
1074 MOV AX, offset INIT ;READ IT INTO INIT (CURRELTLY, MAX 1K)
1075 MOV TAddress_off, AX
1076 MOV TAddress_seg, DS
1077 MOV CL, READ_FUNC
1078 MOV DX, OFFSET IOCTL_R_W ;POINTS TO CONTROL TABLE
1079 call generic_ioctl
1080
1081 CMP IO_ERROR, SOFT_ERROR ;TRY ONCE MORE?
1082; $ENDDO NE
1083 JE $$DO36
1084
1085 CMP IO_ERROR, HARD_ERROR ;HARD ERROR?
1086; $IF NE
1087 JE $$IF38
1088
1089 CLC ;READ SUCCESS
1090; $ELSE
1091 JMP SHORT $$EN38
1092$$IF38:
1093
1094 STC ;READ FAILURE, SET CARRY
1095; $ENDIF
1096$$EN38:
1097 MOV AX, SAV_CSECT ;RESTORE ORIGINAL IOCTL_R_W TABLE
1098 MOV numberOfSectors, AX
1099 POP DX
1100 POP CX
1101 POP BX
1102 POP AX
1103 RET
1104READ_A_SECTOR ENDP
1105; = = = = = = = = = = = =
1106 HEADER <CALC_TRACK_SIZE - FIND MEM SIZE TO HOLD ONE TRACK> ; ;AN000;
1107;*****************************************************************************
1108; *
1109 PUBLIC CALC_TRACK_SIZE ;MAKE ENTRY IN LINK MAP ;AN000;
1110CALC_TRACK_SIZE PROC NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1111; TRACK (IN SEGMENTS) *
1112;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE
1113;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE.
1114;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT
1115;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS.
1116;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh.
1117;*****************************************************************************
1118
1119 PUSH AX
1120 PUSH BX
1121 PUSH CX
1122
1123 MOV AX, bSECTOR_SIZE
1124 XOR DX, DX
1125 XOR BX, BX
1126 MOV BL, END_OF_TRACK
1127 MUL BX ;ASSUME DX=0
1128 MOV BYTES_IN_TRACK,AX ;BYTES/TRACK ON A SIDE OF THE DISKETTE
1129
1130 MOV AX, bSECTOR_SIZE
1131 MOV CL, 16
1132 DIV CL ;AX / 16 = AL ... AH
1133 CMP AH, 0 ;NO REMAINER?
1134; $IF NE
1135 JE $$IF41
1136
1137 INC AL ;THERE REMAINER IS. INC AL
1138; $ENDIF
1139$$IF41:
1140 MOV SECTOR_SIZE, AL ;SECTOR_SIZE+ IN PARA.
1141 MOV AL,NO_OF_SIDES ;TRACK_SIZE = (NO OF SIDES
1142 INC AL ; + 1)
1143 MUL END_OF_TRACK ; * END_OF_TRACK
1144 MOV BL,SECTOR_SIZE ; * SECTPR_SIZE
1145 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1146 MOV TRACK_SIZE,AX ;TO STORE A TRACK
1147
1148 MOV BX,START_BUFFER ;SET SECONDARY AT START OF BUFFER SPACE
1149 MOV SEC_BUFFER,BX ;SET THE SECONDARY BUFFER SEG ADDR
1150 ADD BX,AX ;MOVE THE PRIMARY BUFFER BELOW THE
1151 MOV BUFFER_BEGIN,BX ;SECONDARY BUFFER
1152 POP CX
1153 POP BX
1154 POP AX
1155
1156 RET
1157
1158CALC_TRACK_SIZE ENDP
1159; = = = = = = = = = = = =
1160 HEADER <CHECK_MEMORY_SIZE - BE SURE ENUF ME TO COMPARE 1 TRACK> ; ;AN000;
1161;*****************************************************************************
1162; *
1163 PUBLIC CHECK_MEMORY_SIZE ;MAKE ENTRY IN LINK MAP ;AN000;
1164CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COMP 1 TRACK INTO
1165; TO BUFFER ELSE ABORT COMP *
1166;*****************************************************************************
1167 MOV AX,BUFFER_END
1168 SUB AX,BUFFER_BEGIN
1169 CMP AX,TRACK_SIZE
1170; $IF B
1171 JNB $$IF43
1172 MOV COMP_STATUS,FATAL
1173 ;"Insufficient memory"
1174 PRINT MSGNUM_UNSUF_MEMORY ; ;AC000;
1175
1176; $ENDIF
1177$$IF43:
1178 RET
1179
1180CHECK_MEMORY_SIZE ENDP
1181; = = = = = = = = = = = =
1182 HEADER <COMP_TARGET - COMPARE MEM DATA WITH SECOND DISKETTE> ; ;AN000;
1183;*****************************************************************************
1184; *
1185 PUBLIC COMP_TARGET ;MAKE ENTRY IN LINK MAP ;AN000;
1186COMP_TARGET PROC NEAR ;COMPARE DATA FROM MEMORY TO TARGET DISKETTE
1187; *
1188;*****************************************************************************
1189
1190 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP
1191; $IF E ;PROMPT MSG
1192 JNE $$IF45
1193 CMP MSG_FLAG,SECOND
1194; $IF E
1195 JNE $$IF46
1196 CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000;
1197
1198; $ELSE
1199 JMP SHORT $$EN46
1200$$IF46:
1201 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
1202
1203; $ENDIF
1204$$EN46:
1205 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
1206
1207; $ENDIF
1208$$IF45:
1209 MOV BX,BUFFER_BEGIN
1210 MOV COMPARE_PTR,BX ;INITIALIZE BUFFER POINTER
1211 CMP TRACK_TO_COMP,0 ;IF TRK 0, CHECK COMPATIBILITY
1212; $IF E
1213 JNE $$IF50
1214 CALL CHECK_TARGET
1215
1216 CMP COMP_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
1217 JE CT_EXIT
1218
1219; $ENDIF
1220$$IF50:
1221
1222 CALL SWAP_DRIVE
1223
1224; $DO
1225$$DO52:
1226 CALL COMP_TRACK ;NO, GO READ ANOTHER TRACK
1227
1228 INC TRACK_TO_READ
1229 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
1230 CMP AL,LAST_TRACK
1231; $LEAVE A
1232 JA $$EN52
1233
1234 MOV AX,COMPARE_PTR ;DID WE RUN OUT OF BUFFER SPACE
1235 ADD AX,TRACK_SIZE
1236 CMP AX,BUFFER_END
1237; $ENDDO A
1238 JNA $$DO52
1239$$EN52:
1240
1241CT_EXIT:
1242 RET
1243COMP_TARGET ENDP
1244; = = = = = = = = = = = =
1245 HEADER <CHECK_TARGET - COMPARE SECOND DISK BOOT RECORD> ; ;AN000;
1246;*****************************************************************************
1247 PUBLIC CHECK_TARGET ;MAKE ENTRY IN LINK MAP ;AN000;
1248CHECK_TARGET PROC NEAR ; *
1249; ** CHECK_SOURCE PROCEDURE ALREADY CHECKS OUT THE INCOMPATIBILITY BETWEEN *
1250; ** SOURCE MEDIA AND TARGET DRIVE. (CHECKING SOURCE MEDIA SECTOR/TRACK *
1251; ** EXCEEDS TARGET DRV SECTOR/TRACK, AND SOURCE MEDIA # OF TRACKS WITH *
1252; ** THAT OF TARGET DRV.) *
1253; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1254; ** IF A SUCCESS,THEN COMPARE BPB INFO WITH THAT OF SOURCE MEDIA. *
1255; ** IF THEY ARE DIFFERENT, THEN ERROR - NOT COMPATIBLE *
1256; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1257; ** COMPATIBILITY REASONS. *
1258;*****************************************************************************
1259; $DO
1260$$DO55:
1261 XOR BX, BX
1262 MOV BL, TARGET_DRIVE
1263 MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1264 MOV CL, GETDEVPARM
1265 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1266 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1267 ;WITH THE DEFAULT DEVICE INFO.
1268 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1269; $ENDDO NE
1270 JE $$DO55
1271
1272 CMP IO_ERROR, HARD_ERROR ;ASSUME OLD DISKTETTE. OR DISKETTE BAD
1273 JE CHT_OLD
1274
1275 cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86, J.K.
1276 je cht_old
1277
1278 cmp mt_deviceBPB.chead,0 ;cannot trust the info from DOS.
1279 je cht_old ;sanity check for devide by 0
1280
1281 MOV AX, MT_deviceBPB.CTOTSECT
1282 CWD ;CONVERT IT TO A DOUBLE WORD
1283 DIV MT_deviceBPB.CSECT_TRACK
1284 DIV MT_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1285 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM
1286 CMP LAST_TRACK, AL ;COMPARE WITH SOURCE LAST TRACK
1287 JNE CHT_FATAL_BRIDGE ;IF LAST_TRACK IS DIFFERENT,
1288 ; THEN INCOMPATIBLE.
1289
1290 MOV AX, MT_deviceBPB.CSECT_TRACK
1291 MOV SECT_TRACK_LAYOUT, AX ;VARIBLE FOR MT_trackLayout.CSECT_F
1292CHT_GO_ON:
1293 CMP END_OF_TRACK, AL
1294 JA CHT_FATAL_BRIDGE ;IF SOURCE END_OF_TRACK > TARGET
1295 ; END_OF_TRACK, THEN ERROR
1296
1297 ;8 SECTORED SOURCE AND 9 SECTORED TARGET
1298 ; IS OK AS FAR AS THE COMPATIBILITY GOES.
1299 MOV AX, MT_deviceBPB.CBYTE_SECT
1300 CMP AX, bSECTOR_SIZE ;IF SECTOR SIZE ARE DIFFERENT, THEN
1301 ; NOT COMPATIBLE
1302 JNE CHT_FATAL_BRIDGE
1303
1304 CMP NO_OF_SIDES, 1 ;TWO SIDED COPY?
1305 JNE CHT_SET_BRIDGE ;NO, ONE SIDED. DON'T
1306 ; CARE ABOUT TARGET SIDES.
1307
1308 CMP MT_deviceBPB.CHEAD, 2 ;TARGET FORMATTED INTO TWO SIDES?
1309 JNE CHT_FATAL_BRIDGE ;NO, NOT COMPATIBLE
1310
1311 JMP CHT_SET_DRV ;OK. SOURCE, TARGET MEDIA ARE MATCHING. SET
1312 ; DRV PARM FOR READING
1313
1314CHT_SET_BRIDGE:
1315 JMP CHT_SET_DRV
1316
1317CHT_FATAL_BRIDGE:
1318 JMP CHT_FATAL
1319
1320CHT_SECOND_BAD:
1321 MOV COMP_STATUS, FATAL
1322 PRINT MSGNUM_BAD_SECOND ;"SECOND diskette bad or incompatible" ;AC000;
1323
1324 JMP CHT_EXIT
1325
1326CHT_OLD: ;SAME OLD. ;AGAIN, THIS DOES
1327 ; NOT RECOGNIZE 3.5 MEDIA
1328 MOV READ_T_BPB_FAILURE, 1 ;SET THE FLAG.
1329 XOR BX, BX
1330 MOV BL, TARGET_DRIVE
1331 MOV IOCTL_TRACK, 0
1332 MOV IOCTL_SECTOR, 8
1333 MOV IOCTL_HEAD, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1334 CALL READ_A_SECTOR
1335
1336 JC CHT_SECOND_BAD ;ASSUME TARGET MEDIA NOT FORMATTED.
1337
1338 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9
1339 CALL READ_A_SECTOR
1340
1341 JC CHT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA
1342
1343 MOV IOCTL_SECTOR, 15
1344 CALL READ_A_SECTOR
1345
1346 JC CHT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA
1347
1348;CHT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1349 MOV SECT_TRACK_LAYOUT, 15
1350 CMP END_OF_TRACK, 15 ;IS SOUCE ALSO 96 TPI?
1351 JNE CHT_FATAL ;NO, FATAL ERROR
1352
1353 JMP SHORT CHT_CHK_SIDE ;YES, OK.
1354
1355CHT_8_SECTOR:
1356 MOV SECT_TRACK_LAYOUT, 8
1357 CMP END_OF_TRACK, 15
1358 JE CHT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1359
1360 CMP END_OF_TRACK, 9
1361 JE CHT_FATAL ;IF SOURCE IS 9 SECTOR, THEN
1362 ; SHOULD FORMAT TARGET
1363
1364 JMP SHORT CHT_CHK_SIDE ;ELSE ASSUME SOURCE IS 8 SECTOR.
1365
1366CHT_9_SECTOR:
1367 MOV SECT_TRACK_LAYOUT, 9
1368 CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI? THEN ERROR
1369 JE CHT_FATAL ;ELSE SOUCE IS 8 OR 9 SECTORED
1370 ; 48 TPI DISKETTE
1371
1372CHT_CHK_SIDE: ;CHECK THE TARGET DISKETTE # OF SIDES
1373 CMP NO_OF_SIDES, 0 ;1 SIDE COMP?
1374 JE CHT_EXIT_OLD ;
1375
1376 MOV IOCTL_HEAD, 1 ;ELSE TWO SIDE COMP
1377 XOR AX, AX
1378 MOV AL, END_OF_TRACK ;TRY TO READ MATCHING TARGET SECTOR
1379 MOV IOCTL_SECTOR, AX ;OF THE OTHERSIDE
1380 CALL READ_A_SECTOR
1381
1382 JNC CHT_EXIT_OLD ;SUCCESS? OK
1383
1384CHT_FATAL:
1385 CALL COMPAT_ERROR
1386
1387 JMP SHORT CHT_EXIT
1388
1389CHT_EXIT_OLD:
1390 CALL SET_FOR_THE_OLD ;SET MT_deviceBPB INFO.
1391
1392CHT_SET_DRV:
1393 MOV BX, OFFSET MT_trackLayout ;SET TARGET TRACK LAYOUT
1394 CALL SET_TRACKLAYOUT
1395
1396 JC CHT_FATAL ;IF FAILED, THEN, NOT COMPATIBLE
1397
1398 MOV T_DRV_SET_FLAG, 1 ;INDICATES THE TARGET DEFAULT
1399 ; DEVICE PARM HAS BEEN SET
1400 XOR BX, BX
1401 mov bl, last_track ;To make sure the number of
1402 ; cyl. of target. 3/27/86,J.K.
1403 inc bl
1404 mov MT_numberOfCylinders, bx
1405 MOV BL, TARGET_DRIVE
1406 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1407 MOV MT_specialFunctions, SET_SP_FUNC_DEF
1408 CALL SET_DRV_PARM_DEF
1409
1410CHT_EXIT:
1411 RET
1412
1413CHECK_TARGET ENDP
1414; = = = = = = = = = = = =
1415 HEADER <SET_DRV_PARM - REQUEST IOCTL TO SET DEVICE PARM> ; ;AN000;
1416;*****************************************************************************
1417 PUBLIC SET_DRV_PARM_DEF ;MAKE ENTRY IN LINK MAP ;AN000;
1418SET_DRV_PARM_DEF PROC NEAR
1419;INPUT: BL - DRIVE NUMBER
1420; DX - POINTER TO THE PARAMETER TABLE
1421; specialFunction should be set before this call
1422;*****************************************************************************
1423
1424 MOV CL, SETDEVPARM ;=40H
1425 CALL GENERIC_IOCTL
1426
1427 RET
1428
1429SET_DRV_PARM_DEF ENDP
1430; = = = = = = = = = = = =
1431 HEADER <COMP_TRACK - READ AND COMPARE SPECIFIED TRACK> ; ;AN000;
1432;*****************************************************************************
1433; *
1434 PUBLIC COMP_TRACK ;MAKE ENTRY IN LINK MAP ;AN000;
1435COMP_TRACK PROC NEAR ;COMPARE TRACK SPECIFIED IN TRACK_TO_COMP
1436; *
1437;*****************************************************************************
1438 MOV AX,SEC_BUFFER ;READ IN THE TRACK TO BE COMPARED
1439 MOV BUFFER_PTR,AX ;INTO THE SECONDARY BUFFER
1440 CALL READ_TRACK
1441
1442 MOV SIDE,0 ;START ON SIDE ZERO
1443 MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE
1444 PUSH DS
1445 PUSH ES
1446 MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR
1447 MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR
1448
1449 ASSUME ES:NOTHING
1450 ASSUME DS:NOTHING
1451
1452 XOR DI,DI ;SET TO START OF TRACK
1453 XOR SI,SI
1454 CMP FIRST_TIME,ZERO ;IF THIS IS THE FIRST SECTOR TO BE COMPARED ;AN000;
1455; $IF E ; ;AN000;
1456 JNE $$IF57
1457 CALL VOLSER ;SPECIAL HANDLING FOR VOL SER # ;AN000;
1458
1459 MOV FIRST_TIME,ONE ;FLAG FIRST TIME AS "DONE" ;AN000;
1460; $ENDIF ; ;AN000;
1461$$IF57:
1462 CALL DO_COMPARE ;COMPARE STRING ;AN000;
1463
1464 POP ES
1465 POP DS
1466
1467 ASSUME ES:CSEG
1468 ASSUME DS:CSEG
1469
1470; $IF NZ
1471 JZ $$IF59
1472 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1473 MOV OPERATION,COMPARE_FUNC
1474 CALL ERROR_MESSAGE
1475
1476 INC COMP_ERROR
1477 POP AX
1478; $ENDIF
1479$$IF59:
1480 CMP NO_OF_SIDES,1 ;TWO SIDED COMPARE?
1481; $IF E ;YES
1482 JNE $$IF61
1483 MOV SIDE,1 ;MARK IT AS SUCH
1484 MOV SI,BYTES_IN_TRACK ;BUMP UP BUFFER POINTERS
1485 MOV DI,BYTES_IN_TRACK ;TO START OF SECOND SIDE
1486 MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE
1487 PUSH DS
1488 PUSH ES
1489 MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR
1490 MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR
1491 CALL DO_COMPARE ;COMPARE STRING ;AN000;
1492
1493 POP ES
1494 POP DS
1495; $IF NZ
1496 JZ $$IF62
1497 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1498 MOV OPERATION,COMPARE_FUNC
1499 CALL ERROR_MESSAGE
1500
1501 INC COMP_ERROR
1502 POP AX
1503; $ENDIF
1504$$IF62:
1505; $ENDIF
1506$$IF61:
1507 MOV AX,TRACK_SIZE ;ADVANCE COMPARE POINTER
1508 ADD COMPARE_PTR,AX
1509 RET
1510COMP_TRACK ENDP
1511; = = = = = = = = = = = =
1512 HEADER <DO_COMPARE - PERFORM THE COMPARISON> ; ;AN000;
1513DO_COMPARE PROC NEAR ; ;AN000;
1514 PUBLIC DO_COMPARE ;ADD ENTRY TO LINK MAP ;AN000;
1515;INPUT: DS:[SI] POINTS TO ONE BUFFER, ES:[DI] POINTS TO THE OTHER
1516; CX HAS THE BYTE COUNT
1517;OUTPUT:CONDITION CODE IN CONDITION FLAGS REFLECT RESULT OF COMPARISON
1518; = = = = = = = = = = = =
1519 SHR CX,1 ;DIVIDE BY TWO, CHANGE TO WORD COUNT ;AN000;
1520
1521 PUBLIC PATCH_386 ;SO INIT CAN DO FIXUP ;AN001;
1522PATCH_386 LABEL BYTE
1523 SHR CX,1 ;CONVERT WORD COUNT TO DWORD COUNT ;AN001;
1524 DB 66H ;PREFIX FOR A DWORD COMPARE ;AN001;
1525; END OF PATCH AREA. IF THIS IS NOT A 386, THE ABOVE 3 BYTES ARE CHANGED
1526; TO NOP BY DISKINIT.SAL DURING INITIALIZATION.
1527
1528 REPE CMPSW ;PERFORM THE COMPARISON ;AN000;
1529
1530 RET ;RETURN TO CALLER ;AN000;
1531DO_COMPARE ENDP ; ;AN000;
1532; = = = = = = = = = = = =
1533 HEADER <SWAP_DRIVE - SETUP FOR DISKETTE SWAPPING> ; ;AN000;
1534;*****************************************************************************
1535 PUBLIC SWAP_DRIVE ;MAKE ENTRY IN LINK MAP ;AN000;
1536SWAP_DRIVE PROC NEAR ;SWAP SOURCE, TARGET DRIVE
1537;*****************************************************************************
1538 MOV AL,SOURCE_DRIVE
1539 XCHG AL,TARGET_DRIVE
1540 MOV SOURCE_DRIVE,AL
1541 MOV AL,TRACK_TO_COMP
1542 XCHG AL,TRACK_TO_READ
1543 MOV TRACK_TO_COMP,AL
1544 RET
1545
1546SWAP_DRIVE ENDP
1547 HEADER <READ_TRACK - READ A TRACK TO MEMORY> ; ;AN000;
1548;*****************************************************************************
1549; *
1550 PUBLIC READ_TRACK ;MAKE ENTRY IN LINK MAP ;AN000;
1551READ_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY
1552; *
1553;*****************************************************************************
1554
1555 MOV SIDE, 0
1556; $DO
1557$$DO65:
1558 CALL READ_OP
1559
1560 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1561; $IF E ;YES
1562 JNE $$IF66
1563 MOV AX, TRACK_SIZE
1564; $ELSE ;NO, DOUBLE SIDE
1565 JMP SHORT $$EN66
1566$$IF66:
1567 XOR DX, DX
1568 MOV AX, TRACK_SIZE
1569 MOV CX, 2
1570 DIV CX ;AX / 2
1571; $ENDIF
1572$$EN66:
1573 ADD BUFFER_PTR, AX
1574 INC SIDE ;NEXT SIDE
1575 MOV AL, SIDE
1576 CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE?
1577; $ENDDO G
1578 JNG $$DO65
1579 RET
1580
1581READ_TRACK ENDP
1582; = = = = = = = = = = = =
1583 HEADER <READ_OP - IOCTL TO READ A TRACK> ; ;AN000;
1584;*****************************************************************************
1585; *
1586 PUBLIC READ_OP ;MAKE ENTRY IN LINK MAP ;AN000;
1587READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION
1588; *
1589;*****************************************************************************
1590; $SEARCH
1591$$DO70:
1592RO_AGAIN:
1593 XOR AX, AX
1594 MOV AL, SIDE
1595 MOV Head, AX ;HEAD TO READ
1596 MOV AL, TRACK_TO_READ
1597 MOV Cylinder, AX ;TRACK TO READ
1598 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1599 MOV AX, BUFFER_PTR
1600 MOV Taddress_seg, AX ;BUFFER ADDRESS
1601 MOV Taddress_off, 0
1602 XOR BX, BX
1603 MOV BL, SOURCE_DRIVE
1604 MOV CL, READ_FUNC ;=61h
1605 MOV DX, OFFSET IOCTL_R_W
1606 CALL GENERIC_IOCTL
1607
1608 CMP IO_ERROR, NO_ERROR ;OK?
1609; $EXITIF E,NUL
1610 JE $$SR70
1611
1612 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1613; $ENDLOOP NE
1614 JE $$DO70
1615
1616 MOV OPERATION, READ_FUNC
1617 PUSH AX
1618 CALL ERROR_MESSAGE
1619
1620 POP AX
1621 INC COMP_ERROR ;INCREASE COPY_ERROR COUNT
1622; $ENDSRCH
1623$$SR70:
1624 RET
1625READ_OP ENDP
1626; = = = = = = = = = = = =
1627 HEADER <SET_FOR_THE_OLD - USE PRE 2.0 BPB> ; ;AN000;
1628;*****************************************************************************
1629 PUBLIC SET_FOR_THE_OLD ;MAKE ENTRY IN LINK MAP ;AN000;
1630SET_FOR_THE_OLD PROC NEAR
1631;set MS_deviceBPB or MT_deviceBPB for before-2.0 formatted media.
1632;*****************************************************************************
1633 PUSH AX
1634
1635 CMP SECT_TRACK_LAYOUT,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1636 ;NO_OF_SIDES. IF SINGLE SIDE COPY
1637 ; THEN USE BPB48_SINGLE
1638 ;ELSE USE BPB48_DOUBLE.
1639; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1640 JNA $$IF74
1641 MOV SI, OFFSET BPB96
1642; $ELSE
1643 JMP SHORT $$EN74
1644$$IF74:
1645 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1646; $IF NE
1647 JE $$IF76
1648 MOV SI, OFFSET BPB48_DOUBLE ;ELSE USE BPB48 DOUBLE
1649; $ELSE
1650 JMP SHORT $$EN76
1651$$IF76:
1652 MOV SI, OFFSET BPB48_SINGLE
1653; $ENDIF
1654$$EN76:
1655; $ENDIF
1656$$EN74:
1657 MOV AX, SECT_TRACK_LAYOUT
1658 CMP READ_S_BPB_FAILURE, 1 ;FAILURE ON THE SOURCE?
1659; $IF E
1660 JNE $$IF80
1661 MOV MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1662 MOV DI, OFFSET MS_deviceBPB
1663 MOV CX, BPB96_LENG
1664 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1665; $ELSE
1666 JMP SHORT $$EN80
1667$$IF80:
1668 CMP READ_T_BPB_FAILURE, 1 ;FAILURE ON THE TARGET?
1669; $IF E
1670 JNE $$IF82
1671 MOV MT_deviceBPB.CSECT_TRACK,AX
1672 MOV DI, OFFSET MT_deviceBPB
1673 MOV CX, BPB96_LENG
1674 REP MOVSB ;OLD DEFAULT BPB INTO => MT_deviceBPB
1675; $ENDIF
1676$$IF82:
1677; $ENDIF
1678$$EN80:
1679 POP AX
1680 RET
1681SET_FOR_THE_OLD ENDP
1682; = = = = = = = = = = = =
1683 HEADER <SET_TRACKLAYOUT - DETERMINE SECTORS PER TRACK> ; ;AN000;
1684;*****************************************************************************
1685 PUBLIC SET_TRACKLAYOUT ;MAKE ENTRY IN LINK MAP ;AN000;
1686SET_TRACKLAYOUT PROC NEAR
1687;INPUT: BX - POINTER TO DESTINATION
1688; SECT_TRACK_LAYOUT
1689;*****************************************************************************
1690 MOV CX, SECT_TRACK_LAYOUT ;MEDIA SECTORS/TRACK
1691 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF SECTORS
1692 ; IN A TRACK
1693 ADD BX, 2 ;NOW BX POINTS TO THE FIRST SECTORNUMBER
1694 MOV CX, 1
1695 MOV AX, bSECTOR_SIZE
1696
1697; $DO
1698$$DO85:
1699 CMP CX, SECT_TRACK_LAYOUT
1700; $LEAVE A
1701 JA $$EN85
1702
1703 MOV WORD PTR [BX], CX
1704 INC BX
1705 INC BX
1706 MOV WORD PTR [BX], AX
1707 INC BX
1708 INC BX
1709
1710 INC CX
1711; $ENDDO
1712 JMP SHORT $$DO85
1713$$EN85:
1714
1715 RET
1716SET_TRACKLAYOUT ENDP
1717; = = = = = = = = = = = =
1718 HEADER <GENERIC_IOCTL - PERFORM SPECIFIED IOCTL FUNCTION> ; ;AN000;
1719PUBLIC GENERIC_IOCTL
1720;******************************************************************************
1721GENERIC_IOCTL PROC NEAR
1722;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1723; 61 - READ TRACK, 41 - WRITE TRACK,
1724; 42 - FORMAT AND VERIFY TRACK
1725; 62 - VERIFY TRACK
1726; BL - LOGICAL DRIVE LETTER
1727; DS:DX - POINTER TO PARAMETERS
1728;******************************************************************************
1729
1730 MOV IO_ERROR, NO_ERROR ;reset io_error
1731 MOV AH, IOCTL_FUNC ;IOCTL FUNC = 44H
1732 MOV AL, GENERIC_IOCTL_CODE ;GENERIC IOCTL REQUEST = 0DH
1733 MOV CH, MAJOR_CODE ;MAJOR CODE=08H, REMOVABLE
1734 INT 21H
1735; $IF C
1736 JNC $$IF88
1737 CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS!
1738
1739; $ENDIF
1740$$IF88:
1741 RET
1742GENERIC_IOCTL ENDP
1743; = = = = = = = = = = = =
1744 HEADER <EXTENDED_ERROR - DETERMINE AND SERVICE EXTENDED ERRORS> ; ;AN000;
1745;******************************************************************************
1746 PUBLIC EXTENDED_ERROR_HANDLER ;MAKE ENTRY IN LINK MAP ;AN000;
1747EXTENDED_ERROR_HANDLER PROC NEAR
1748;INPUT: BL - LOGICAL DRIVE LETTER
1749;******************************************************************************
1750 PUSHF
1751 PUSH AX
1752 PUSH BX
1753 PUSH CX
1754 PUSH DX
1755 PUSH SI
1756 PUSH DI
1757 PUSH ES
1758 PUSH DS
1759 PUSH BX
1760
1761 MOV AH, 59H
1762 MOV BX, 0
1763 INT 21H
1764
1765; CMP BL, 5 ;ACTION=IMMEDIATE EXIT?
1766; JE EEH_JUST_EXIT
1767
1768 POP BX ;RESTORE BL FOR DRIVE LETTER
1769 POP DS
1770 POP ES
1771
1772 CMP AX, 21 ;DRIVE NOT READY?
1773 JE WARN_USER_1
1774
1775 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
1776 JE WARN_USER_2
1777
1778 JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR
1779
1780WARN_USER_1:
1781 MOV DRIVE_LETTER, 'A'
1782 DEC BL ;CHANGE LOGICAL TO PHYSICAL
1783 ADD DRIVE_LETTER, BL
1784 ;"Drive not ready - X:"
1785 PRINT MSGNUM_GET_READY ; ;AC000;
1786
1787 PRINT MSGNUM_CLOSE_DOOR ;"Make sure a diskette is inserted into ;AN004;
1788 ; the drive and the door is closed"
1789 JMP WAIT_FOR_USER
1790
1791WARN_USER_2:
1792 ;"Attempt to write to write-protected diskette"
1793 PRINT MSGNUM_WRITE_PROTECT ; ;AC000;
1794
1795WAIT_FOR_USER:
1796 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
1797
1798EEH_SOFT_ERROR:
1799 MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN
1800 JMP SHORT EEH_EXIT
1801
1802EEH_HARD_ERROR:
1803 MOV IO_ERROR, HARD_ERROR
1804
1805EEH_EXIT:
1806 POP DI
1807 POP SI
1808 POP DX
1809 POP CX
1810 POP BX
1811 POP AX
1812 POPF
1813 RET
1814
1815;EEH_JUST_EXIT:
1816; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT
1817
1818EXTENDED_ERROR_HANDLER ENDP
1819.XLIST
1820; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
1821;CALL_PRINTF PROC NEAR
1822; PUBLIC CALL_PRINTF
1823;;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
1824; PUSH DX
1825; PUSH CS
1826; CALL PRINTF
1827;
1828; RET
1829;CALL_PRINTF ENDP
1830.LIST
1831; = = = = = = = = = = = =
1832 HEADER <ERROR_MESSAGE - DISPLAY THE ERROR MESSAGE> ; ;AN000;
1833ERROR_MESSAGE PROC NEAR ;DISPLAY ERROR MESSAGE
1834 PUBLIC ERROR_MESSAGE
1835;
1836; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE)
1837; AND WHERE IT FAILED (TRACK NO. AND SIDE).
1838;
1839; INPUT: OPERATION = IOCTL DISKETTE READ(=61H) OR COMPARE_FUNC(59H)
1840; = = = = = = = = = = = =
1841
1842 CMP OPERATION,READ_FUNC ;ERROR DURING READ ?
1843; $IF E
1844 JNE $$IF90
1845.XLIST
1846; MOV BX,OFFSET READ_ERROR ;TELL USER ERROR DURING READ OP
1847; MOV MSG_HARD_ERROR_PTR+2,BX
1848.LIST
1849 MOV DL,SOURCE_DRIVE ;WHICH DRIVE IS BAD
1850 dec dl ;change logical letter to phisical
1851 ADD DL,"A" ;CORRESPONDANT ALPHABET
1852 MOV DRIVE_LETTER,DL
1853 MOV SUBLIST_17B.SUB_VALUE,OFFSET DRIVE_LETTER ;
1854
1855 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
1856 ;CR,LF,"Unrecoverable read error on drive %2",CR,LF
1857 ;"side %3, track %4",CR,LF
1858 ;%2 IS "DRIVE_LETTER", AND
1859 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1860 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ; ;AN000;
1861; $ELSE
1862 JMP SHORT $$EN90
1863$$IF90:
1864.XLIST
1865; MOV BX,OFFSET COMPARE_ERROR ;TELL USER ERROR DURING COMPARE OP
1866; MOV MSG_HARD_ERROR_PTR+2,BX
1867.LIST
1868 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR WRITE
1869 ;CR,LF,"Compare error on",CR,LF
1870 ;"side %3, track %4",CR,LF
1871 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1872 MOV DI,OFFSET MSGNUM_HARD_ERROR_COMP ; ;AN000;
1873; $ENDIF
1874$$EN90:
1875
1876 MOV AL,SIDE
1877 MOV BYTE PTR MSG_SIDES,AL
1878 MOV BYTE PTR MSG_TRACKS,BL
1879 CALL SENDMSG ;PRINT MSG SELECTED ABOVE ;AN000;
1880
1881 RET
1882ERROR_MESSAGE ENDP
1883; = = = = = = = = = = = =
1884 HEADER <COMBAT_ERROR - DISPLAY INCOMPATIBLE MSG> ; ;AN000;
1885COMPAT_ERROR PROC NEAR ;DISPLAY COMPAT MSG
1886 PUBLIC COMPAT_ERROR
1887; = = = = = = = = = = = =
1888
1889 MOV COMP_STATUS,FATAL ;INCOMPATIBLE, ABORT
1890 ;"Drive types or diskette types"
1891 ;"not compatible"
1892 PRINT MSGNUM_NOT_COMPATIBLE
1893
1894 RET
1895COMPAT_ERROR ENDP
1896; = = = = = = = = = = = =
1897 HEADER <PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT> ; ;AN009;
1898PRESS_ANY_KEY PROC NEAR ;
1899;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
1900;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
1901;PRECEEDING MESSAGES.
1902; = = = = = = = = = = = =
1903 PRINT MSGNUM_NEWLINE ;SKIP A SPACE ;AN009;
1904
1905 PRINT MSGNUM_STRIKE ;"Press any key when ready..." ;AN009;
1906
1907 RET ;RETURN TO CALLER ;AN009;
1908PRESS_ANY_KEY ENDP ; ;AN009;
1909; = = = = = = = = = = = =
1910 HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ; ;AN000;
1911SENDMSG PROC NEAR ; ;AN000;
1912 PUBLIC SENDMSG ; ;AN000;
1913; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
1914; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
1915; IF CARRY CLEAR, ALL OK
1916; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
1917
1918; = = = = = = = = = = = =
1919
1920 PUSH BX ; SAVE CALLER'S REGS ;AN000;
1921 PUSH CX ; ;AN000;
1922 PUSH DX ; ;AN000;
1923 PUSH SI ; ;AN000;
1924
1925; PASS PARMS TO MESSAGE HANDLER IN
1926; THE APPROPRIATE REGISTERS IT NEEDS.
1927 MOV AX,[DI].MSG_NUM ;MESSAGE NUMBER ;AN000;
1928 MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000;
1929 MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1930 MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1931 MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1932 CALL SYSDISPMSG ;DISPLAY THE MESSAGE ;AN000;
1933
1934; $IF C ;IF THERE IS A PROBLEM ;AN000;
1935 JNC $$IF93
1936 ;AX=EXTENDED ERROR NUMBER ;AN000;
1937 LEA DI,MSGNUM_EXTERR ;GET REST OF ERROR DESCRIPTOR ;AN000;
1938 MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000;
1939 MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1940 MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1941 MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1942 CALL SYSDISPMSG ;TRY TO SAY WHAT HAPPENED ;AN000;
1943
1944 STC ;REPORT PROBLEM ;AN000;
1945; $ENDIF ;PROBLEM WITH DISPLAY? ;AN000;
1946$$IF93:
1947
1948 POP SI ;RESTORE CALLER'S REGISTERS ;AN000;
1949 POP DX ; ;AN000;
1950 POP CX ; ;AN000;
1951 POP BX ; ;AN000;
1952
1953 RET ;RETURN TO CALLER ;AN000;
1954SENDMSG ENDP ; ;AN000;
1955; = = = = = = = = = = = =
1956 HEADER <YESNO - DETERMINE IF A RESPONSE IS YES OR NO> ; ;AN000;
1957YESNO PROC NEAR ; ;AN000;
1958 PUBLIC YESNO ;MAKE ENTRY IN LINK MAP ;AN000;
1959;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
1960;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
1961; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
1962; = = = = = = = = = = = =
1963 ;AL=SUBFUNCTION, AS:
1964 ; 20H=CAPITALIZE SINGLE CHAR
1965 ; 21H=CAPITALIZE STRING
1966 ; 22H=CAPITALIZE ASCIIZ STRING
1967 ; 23H=YES/NO CHECK
1968 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
1969 ; 80H BIT 1=USE FILE UPPER CASE TABLE
1970 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
1971 MOV AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;(6523H) GET EXTENDED ;AN000;
1972 ; COUNTRY INFORMATION, (Y/N)
1973 INT 21H ;SEE IF Y OR N ;AN000;
1974
1975 RET ;RETURN TO CALLER ;AN000;
1976YESNO ENDP ; ;AN000;
1977; = = = = = = = = = = = =
1978 HEADER <VOLSER - VERIFY FIRST SECTOR, IGNORE VOL SER #> ; ;AN000;
1979VOLSER PROC NEAR ;VERIFY FIRST SECTOR, IGNORING VOL SER # ;AN000;
1980 PUBLIC VOLSER ; ;AN000;
1981;IF THE FIRST DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN
1982;COPY IT TO THE SECOND DISKETTE BUFFER AREA (NOT THE DISKETTE).
1983;INPUT: FIRST DRIVE NUMBER
1984; DS:=SEGID OF BUFFER OF FIRST DISKETTE, FIRST SECTOR, SIDE 0
1985; ES:=SEGID OF BUFFER OF SECOND DISKETTE, FIRST SECTOR, SIDE 0
1986; SI AND DI = 0, INDEX OF WHERE IN BUFFERS TO START LOOKING
1987; CX="BYTES_IN_TRACK"; NUMBER OF BYTES TO BE EVENTUALLY COMPARED
1988;OUTPUT: BUFFER OF 2ND DISKETTE ALTERED TO MATCH THE VOL SERIAL NUMBER OF 1ST.
1989; = = = = = = = = = = = = = = = = = =
1990
1991 ASSUME DS:NOTHING ;BUFFER OF FIRST DISKETTE ;AN000;
1992 ASSUME ES:NOTHING ;BUFFER OF SECOND DISKETTE ;AN000;
1993
1994 PUSH CX ;SAVE CALLER'S REGS ;AN000;
1995 PUSH SI ; ;AN000;
1996 PUSH DI ; ;AN000;
1997;(deleted ;AN011;) PUSH DS ;SAVE BUFFER OF FIRST DISKETTE ;AN000;
1998
1999;(deleted ;AN011;) PUSH CS ;RESTORE ADDRESSABILITY TO COMMON SEG ;AN000;
2000;(deleted ;AN011;) POP DS ; TO ACCESS GET MEDIA ID BUFFER AREA ;AN000;
2001;(deleted ;AN011;) ASSUME DS:CSEG ;AN000;
2002
2003;(deleted ;AN011;); ISSUE GET MEDIA ID FROM SOURCE
2004;(deleted ;AN011;) MOV BH,0 ;BH=0, RES ;AN000;
2005;(deleted ;AN011;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (A:=1, B:=2, ETC.) ;AN000;
2006;(deleted ;AN011;) MOV DX,OFFSET MEDIA_ID_BUFFER ;DS:DX=BUFFER
2007;(deleted ;AN011;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC008;
2008;(deleted ;AN011;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2009;(deleted ;AN011;) POP DS ;RESTORE THIS BACK TO BUFFER OF FIRST DISKETTE;AN000;
2010;(deleted ;AN011;) ASSUME DS:NOTHING ; LIKE IT WAS AT ENTRY TO THIS PROC ;AN000;
2011
2012;(deleted ;AN011;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2013;(deleted ;AN011;) ; THEN THIS DISKETTE HAS A VOL SER #
2014
2015 PUSH BX ;AN011;
2016 LEA BX,DS:[DI].EXT_BOOT_BPB ;AN011;POINT TO BPB PORTION OF BOOT RECORD
2017 MOV AL,DS:[BX].EBPB_MEDIADESCRIPTOR ;AN011;GET TYPE OF MEDIA
2018 AND AL,0F0H ;AN011;SAVE LEFT NIBBLE ONLY
2019 CMP AL,0F0H ;AN011;IF DISKETTE HAS PROPER DESCRIPTOR
2020; $IF E ;AN011;
2021 JNE $$IF95
2022 MOV AL,DS:[DI].EXT_BOOT_SIG ;AN011;GET "SIGNATURE" OF BOOT RECORD
2023 CMP AL,28H ;AN011;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
2024; $IF E,OR ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2025 JE $$LL96
2026 CMP AL,29H ;AN011;IS THIS A BOOT STYLE OF OS/S 1.2?
2027; $IF E ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2028 JNE $$IF96
2029$$LL96:
2030
2031;THE PURPOSE HERE IS TO CAUSE DISKCOMP TO IGNORE ANY DIFFERENCES IN THE
2032;VOL SERIAL NUMBER FIELD. THIS IS DONE BY TAKING ONE VOL SERIAL NUMBER
2033;FROM ONE BUFFER, ALREADY LOADED WITH THE FIRST TRACK OF ONE DISKETTE,
2034;AND MOVING THAT SERIAL NUMBER TO THE CORRESPONDING POSITION IN THE OTHER
2035;BUFFER, ALREADY LOADED WITH THE SIMILAR TRACK FROM THE OTHER DISKETTE.
2036;WHEN THIS RETURNS TO THE MAIN ROUTINE, THE ENTIRE TRACK (INCUDING THIS
2037;VOL SERIAL NUMBER FIELD) WILL BE COMPARED. IF THERE ARE ANY DIFFERENCES,
2038;THEY WILL BE OTHER THAN IN THE VOL SERIAL NUMBERS.
2039
2040 MOV SI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS
2041 MOV DI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS
2042 MOV CX,TYPE VOL_SERIAL ;GET NUMBER BYTES IN VOL SER FIELD
2043 REP MOVSB ;FORCE THE SERIAL NUMBERS TO BE ALIKE
2044
2045; $ENDIF ; ;AN000;
2046$$IF96:
2047; $ENDIF ;AN011;
2048$$IF95:
2049 POP BX ;AN011;
2050 POP DI
2051 POP SI
2052 POP CX ;RESTORE COUNT
2053 RET ;RETURN TO CALLER ;AN000;
2054VOLSER ENDP ;AN000;
2055; = = = = = = = = = = = = = = = = = = =
2056DISKCOMP_END LABEL BYTE
2057 PATHLABL DISKCOMP ;AN013;
2058CSEG ENDS
2059 END DISKCOMP
2060 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU b/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU
new file mode 100644
index 0000000..3777c37
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU
@@ -0,0 +1,170 @@
1
2 IF1
3 %OUT INCLUDING DISKCOMP.EQU...
4 ELSE
5; %OUT INCLUDING DISKCOMP.EQU...
6 ENDIF
7
8;---------------------------------------------------------------------------;
9; EQUATES ;
10;---------------------------------------------------------------------------;
11
12; *** CONSTANTS ***
13
14ZERO EQU 0
15ONE EQU 1
16TWO EQU 2
17THREE EQU 3
18FOUR EQU 4
19TYPE_4 EQU 4
20FIVE EQU 5
21SIX EQU 6
22SEVEN EQU 7
23EIGHT EQU 8
24NINE EQU 9
25TEN EQU 0AH
26ON EQU 1
27OFF EQU 0
28TRUE EQU 01
29FALSE EQU 00
30GOOD EQU 0
31BAD EQU 1
32FIRST EQU 1
33SECOND EQU 2
34HARD_ERROR EQU 02
35SOFT_ERROR EQU 01
36NO_ERROR EQU 0
37;DOS_LEVEL EQU 0314H ;DOS VERSION 3.20
38BLANK EQU 20H ;BLANK IN ASCII (32 DEC)
39CLEAR_SEGMENT EQU 0E0H ;USED TO CLEAR SEGMENT BITS (ROUND UP
40 ;TO NEXT SECTOR)
41SECTOR8 EQU 8 ;
42SECTOR9 EQU 9 ;
43SECTOR14 EQU 14 ;
44SECTOR15 EQU 15 ;
45DRV_48TPI EQU 0 ;48 TPI DRIVE
46DRV_96TPI EQU 1 ;96 TPI DRIVE
47DRV_720 EQU 2 ;3.5", 720 KB DRIVE (FOR CASHEW OR P14)
48NRLFUNC EQU 5F02H ;GET NETWORK-REDIRECTION-LIST FUNTION
49NRLMAX EQU 1CH ;(MAXIMUM # OF NAMES ON NRL) - 1
50DOS20 EQU 2 ;DOS VERSION 2.0
51 PUBLIC FINE ; ;AN000;
52FINE EQU -1 ;"FINE AND DANDY", USED FOR RETURN CODE
53 ;(-1 WAS USED TO AVOID CONFUSION WITH ERROR
54 ;OFFSET WHICH CAN BE ZERO)
55LOCAL_DRV EQU -1 ;DEVICE NOT DIRECTED
56REMOTE_DRV EQU 1000H ;REMOTE DRIVE TEST BITS
57NO_OPTION EQU -1 ;NO OPTION "/1" SPECIFIED
58OPTION_1 EQU 1 ;OPTION "/1" SPECIFIED
59REMOVABLE EQU 0000H ;REMOVABLE FILE
60INVAL_PARM EQU -9 ;INVALID PARAMETER ENTERED
61
62PAGE
63; *** PROGRAM SEGMENT PREFIX ***
64
65FCB1_DRV_ID EQU 5CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 1
66FCB1_FILENM EQU 5DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 1
67FCB2_DRV_ID EQU 6CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 2
68FCB2_FILENM EQU 6DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 2
69BEGIN_UNFORM_AREA EQU 80H ;BEGINNING @ OF THE UNFORMATTED AREA
70END_UNFORM_AREA EQU 100H ;ENDING @ OF THE UNFORMATTED AREA
71
72
73; *** DOS FUNCTONS ***
74
75RET_CD_EXIT EQU 4CH ;EXIT TO DOS, PASSING RETURN CODE ;AN000;
76PUT_CHAR EQU 02H ;DOS DISPLAY OUTPUT FUNCTION
77PRINT_FUNC EQU 09H ;DOS PRINT STRING FUNCTION
78REDIRECTED_FUNC EQU 09H ;IOCTL SUB FUNCTION ****** TO BE CHECKED ****
79KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT (CLEARS INPUT BUFF FIRST)
80CURRENTDRV_FUNC EQU 19H ;GET CURRENT DRIVE FUNCTION CALL
81;DOSVER_FUNC EQU 30H ;DOS VERSION FUNCTION CALL
82IOCTL_FUNC EQU 44H ;IOCTL FUNCTION CALL
83DRIVE_CHECK EQU 4408H ;DOS CHECK FOR REMOVABLE DRIVE IOCTL CALL
84STD_ERROR EQU 0002H ;STANDARD ERROR FILE HANDLE
85WRITE_FILE EQU 40H ;WRITE TO FILE OR DEVICE FUNCTION CALL
86GET_ASSIGN_MODE EQU 5F00H ;SET ASSIGN MODE COMMAND
87SET_ASSIGN_MODE EQU 5F01H ;SET ASSIGN MODE COMMAND
88SERVER EQU 2AH ;NETWORK SERVER INTERUPT
89SHARED EQU 03H ;DEVICE SHARED CHECK
90GET_EXT_CNTRY_INFO EQU 65H ;GET EXTENDED COUNTRY INFO ;AN000;
91YESNO_CHECK EQU 23H ;REQUEST (Y/N) CHECK OF GET_EXT_CNTRY_INFO ;AN000;
92YES EQU 1 ;(Y/N) RESPONSE IS "YES" ;AN000;
93BAD_YESNO EQU 2 ;(Y/N) RESPONSE IS NEITHER "Y" NOR "N" ;AN000;
94
95;IOCTL DISKETTE I/O FUNCTIONS
96GENERIC_IOCTL_CODE EQU 0DH ;GENERIC IOCTL REQUEST
97MAJOR_CODE EQU 08H ;GENERIC IOCTL MAJOR CODE
98READ_FUNC EQU 61H ;IOCTL DISKETTE RAED FUNCITON
99WRITE_FUNC EQU 41H ;IOCTL DISKETTE WRITE FUNCTION
100VERIFY_FUNC EQU 62H ;IOCTL DISKETTE VERIFY FUNCTION
101FORMAT_FUNC EQU 42H ;IOCTL DISKETTE FORMAT FUNCITON
102GETDEVPARM EQU 60H ;IOCTL GET DEVICE PARAMETER
103SETDEVPARM EQU 40H ;IOCTL SET DEVICE PARAMETER
104SET_LOG_DRIVE EQU 0FH ;SET LOGICAL DRIVE ;AN000;
105GSET_MEDIA_ID EQU 69H ;GET/SET MEDIA ID ;AN008;
106GET_ID EQU 0 ;AL=0, GET MEDIA ID ;AN008;
107SET_ID EQU 1 ;AL=1, SET MEDIA ID ;AN008;
108;
109COMPARE_FUNC EQU 59H ;JUST USED TO IDENTIFY FOR ERROR MESSAGE
110;
111;specialFunctions
112GET_SP_FUNC_DEF EQU 00000000B ;GET DEVICE PARM. DEFAULT BPB
113GET_SP_FUNC_MED EQU 00000001B ;GET DEVICE PARM. media bpb
114SET_SP_FUNC_DEF EQU 00000100B ;SET DEFAULT DEVICE PARM
115SET_SP_FUNC_DOS EQU 00000100B ;SET DEVICE PARM BEFORE RETURN TO DOS
116R_W_SP_FUNC EQU 00000000B ;READ, WRITE
117
118; *** BIOS DISKETTE I/O ERROR CODES ***
119
120;NOT_READY EQU 80H ;DISKETTE I/O NOT READY ERROR
121;CHANG_LINE EQU 06H ;CHANGE LINE ERROR
122;BAD_CONTROLLER EQU 20H ;BAD DISKETTE/DISK CONTOROLLER
123;WRITE_PROTECT EQU 03H ;DISKETTE I/O WRITE PROTECT ERROR
124;BAD_ADDR_MARK EQU 02H ;DISKETTE I/O BAD ADDRESS MARK ERROR
125;REC_NOT_FOUND EQU 04H ;DISETTTE I/O RECORD NOT FOUND ERROR
126;BAD_CRC EQU 10H ;DISKETTE I/O BAD CRC ERROR
127;HARD_WR_ERROR EQU 03H ;DISKETTE WRITE HARD ERROR COUNT
128;HARD_FMT_ERROR EQU 02H ;DISKETTE FORMAT HARD ERROR COUNT
129;SINGLE_SIDE_COPY EQU 00H ;WHEN READING TRACK 0 SIDE 1 IF HARD ERROR
130 ;OCCURS, WE WILL ASSUME IT WILL BE SINGLE
131 ;SIDED COPY AND AL WILL BE SET TO 0, SO THAT
132 ;BUFFER_PTR WILL NOT BE ADVANCED AND
133 ;IF THE TRACK HAPPENS TO FALL INTO DMA BOUNDRY
134 ;IT WILL SKIP THE SECOND PART OF READ_TRACK
135
136; *** COPY STATUS BYTE ***
137
138FATAL EQU 01H ;FATAL COPY ERROR, ABORT
139OK EQU 00H ;OK, PROCEED
140
141; *** MESSAGES SUBLIST DESCRIPTOR ***
142
143SUBLIST STRUC ;AN000;
144SUB_SIZE DB ? ;SUBLIST SIZE (POINTER TO NEXT SUBLIST) ;AN000;
145SUB_RES DB ? ;RESERVED ;AN000;
146 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN000;
147SUB_VALUE DW ? ;TIME, DATE, OR PTR TO DATA ITEM ;AN000;
148SUB_VALUE_SEG DW ? ;SEG ID OF PTR ;AN000;
149 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN000;
150 ; IF THIS IS A .COM FILE) ;AN000;
151SUB_ID DB ? ;N OF %N ;AN000;
152SUB_FLAGS DB ? ;DATA TYPE FLAGS ;AN000;
153SUB_MAX_WIDTH DB ? ;MAXIMUM FIELD WIDTH (0=UNLIMITED) ;AN000;
154SUB_MIN_WIDTH DB ? ;MINIMUM FIELD WIDTH ;AN000;
155SUB_PAD_CHAR DB ? ;CHARACTER FOR PAD FIELD ;AN000;
156 ; CAN BE " ", "0" OR ",". ;AN000;
157 ; "," CAUSES INSERTION OF THE ACTIVE ;AN000;
158 ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN000;
159SUBLIST ENDS ;AN000;
160
161 ;BUFFER AREA FOR COMMUNICATION WITH GET/SET MEDIA ID FUNCTION CALL:
162;(deleted ;AN011;) A_MEDIA_ID_INFO struc
163;(deleted ;AN011;) MI_level dw 0 ;info level
164;(deleted ;AN011;) MI_Serial dd 0 ;Serial #
165;(deleted ;AN011;) MI_Label db 11 dup (' ') ;Volume Label
166;(deleted ;AN011;) MI_System db 8 dup (' ') ;File System type
167;(deleted ;AN011;) A_MEDIA_ID_INFO ends
168 INCLUDE BOOTFORM.INC ;GET DESCRIPTION OF BOOT RECORD
169VOL_SERIAL EQU EXT_BOOT_SERIAL ;LOCATION IN BOOT RECORD OF VOLSER NUM ;AN000;
170 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK b/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK
new file mode 100644
index 0000000..a6d0f36
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK
@@ -0,0 +1,6 @@
1DISKCOMP+
2DCOMPSM+
3DCOMPP+
4DCOMPPAR+
5COMPINIT;
6 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL b/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL
new file mode 100644
index 0000000..44e8251
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL
@@ -0,0 +1,56 @@
1:util DISKCOMP ;AN000;utility name
2:class A ;AN000;system messages
3;
4:use 1 COMMON1 ;AN000;"Incorrect DOS version"
5;
6:use 2 EXTEND8 ;AN000;"Insufficient memory"
7;
8:use 3 PARSE10 ;AN000;"Invalid parameter"
9;
10:def 4 "Do not specify filename(s)",CR,LF ;AN000;
11"Command format: DISKCOMP d: d: [/1][/8]",LF,CR ;AN000;
12;
13:def 5 CR,LF,"Invalid drive specification",CR,LF ;AN000;
14"Specified drive does not exist",CR,LF ;AN000;
15"or is non-removable",CR,LF ;AN000;
16;
17:def 6 CR,LF,"Cannot DISKCOMP to or from",CR,LF ;AN000;
18"a network drive",CR,LF ;AN000;
19;
20:def 7 CR,LF,"Insert FIRST diskette in drive %1:",CR,LF ;AN000;
21
22:def 8 CR,LF,"Insert SECOND diskette in drive %1:",CR,LF ;AN000;
23
24:def 9 CR,LF,"FIRST diskette bad or incompatible",CR,LF ;AN000;
25
26:def 10 CR,LF,"SECOND diskette bad or incompatible",CR,LF ;AN000;
27;
28:use 11 EXTEND21 ;AN000;"Drive not ready" NOTE CHANGE %1 TO %0
29;
30:use 12 COMMON28 ;AN000;"Press any key to continue . . ."
31;
32:use 13 EXTEND19 ;AN000;CR,LF,"Attempt to write to write-protected diskette",CR,LF
33;
34:def 14 CR,LF,"Compare another diskette (Y/N) ?" ;AN000;
35;
36:def 15 CR,LF,"Comparing %1 tracks",CR,LF ;AN000;
37"%2 sectors per track, %3 side(s)",CR,LF ;AN000;
38;
39:def 16 CR,LF,"Drive types or diskette types",CR,LF ;AN000;
40"not compatible",CR,LF ;AN000;
41;
42:def 17 CR,LF,"Unrecoverable read error on drive %2",CR,LF ;AN000;
43"side %3, track %4",CR,LF ;AN000;
44;
45:def 18 CR,LF,"Compare error on",CR,LF,"side %3, track %4",CR,LF ;AN000;
46;
47:def 19 "Make sure a diskette is inserted into",CR,LF ;AN004;
48"the drive and the door is closed",CR,LF ;AN004;
49;
50:def 20 CR,LF,"Compare process ended",CR,LF ;AN000;
51;
52:def 21 CR,LF,"Compare OK",CR,LF ;AN000;
53;
54:def 22 CR,LF ;AC007;
55:end ;AN000;
56 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOMP/MAKEFILE b/v4.0/src/CMD/DISKCOMP/MAKEFILE
new file mode 100644
index 0000000..09415b1
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/MAKEFILE
@@ -0,0 +1,59 @@
1#************************** makefile for cmd\append ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: diskcomp.com
13
14diskcomp.ctl: diskcomp.skl \
15 $(msg)\$(COUNTRY).msg \
16 makefile
17
18diskcomp.obj: diskcomp.asm \
19 makefile \
20 dcmpmacr.inc \
21 $(inc)\bootform.inc \
22 diskcomp.equ
23
24compinit.obj: compinit.asm \
25 makefile \
26 dcmpmacr.inc \
27 $(inc)\bootform.inc \
28 diskcomp.equ
29
30dcompp.obj: dcompp.asm \
31 makefile \
32 $(inc)\parse.asm
33
34dcompsm.obj: dcompsm.asm \
35 makefile \
36 $(inc)\sysmsg.inc \
37 $(inc)\msghan.inc \
38 $(inc)\versiona.inc \
39 diskcomp.ctl \
40 diskcomp.cla \
41 diskcomp.cl1 \
42 diskcomp.cl2 \
43 dcompms.inc \
44 $(inc)\copyrigh.inc
45
46dcomppar.obj: dcomppar.asm \
47 makefile
48
49diskcomp.com: diskcomp.obj \
50 makefile \
51 diskcomp.lnk \
52 dcompsm.obj \
53 dcompp.obj \
54 dcomppar.obj \
55 compinit.obj
56 link @diskcomp.lnk
57 exe2bin diskcomp.exe diskcomp.com
58 del diskcomp.exe
59