summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DISKCOPY
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/DISKCOPY
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/DISKCOPY')
-rw-r--r--v4.0/src/CMD/DISKCOPY/COPYINIT.ASM1046
-rw-r--r--v4.0/src/CMD/DISKCOPY/DCOPYMS.INC269
-rw-r--r--v4.0/src/CMD/DISKCOPY/DCOPYP.ASM139
-rw-r--r--v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM413
-rw-r--r--v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM153
-rw-r--r--v4.0/src/CMD/DISKCOPY/DCPYMACR.INC164
-rw-r--r--v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM2452
-rw-r--r--v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU207
-rw-r--r--v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK6
-rw-r--r--v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL65
-rw-r--r--v4.0/src/CMD/DISKCOPY/MAKEFILE57
11 files changed, 4971 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM b/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM
new file mode 100644
index 0000000..4410925
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM
@@ -0,0 +1,1046 @@
1 PAGE 90,132 ;A2
2 TITLE COPYINIT -- DISKCOPY INITIALIZATION PROGRAM
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: COPYINIT
5
6; DESCRIPTIVE NAME: Initialization for Diskette to diskette copy Utility
7
8;FUNCTION: DISKCOPY is to copy the contents of the diskette in the
9; specified source drive to the diskette in the target
10; drive. If necessary, the target diskette is also
11; formatted.
12
13; Multiple copies may be performed with one load of DISKCOPY.
14; A prompt, "Copy another (Y/N)?" permits additional
15; executions, all with the same drive specifications.
16
17; ENTRY POINT: "DISKCOPY" at ORG 100h, jumps to "BEGIN".
18
19; INPUT: (DOS command line parameters)
20; [d:][path]DISKCOPY [d: [D:]][/1]
21
22; Where
23
24; [d:][path] before DISKCOPY to specify the drive and path that
25; contains the DISKCOPY command file.
26
27; [d:] to specify the source drive id
28
29; [D:] to specify the destination drive id
30
31; [/1] to request single sided operations only
32
33; EXIT-NORMAL: Errorlevel = 0
34; Function completed successfully.
35
36; EXIT-ERROR: Errorlevel = 1
37; Abnormal termination due to error, wrong DOS,
38; invalid parameters, unrecoverable I/O errors on
39; the diskette.
40
41; EFFECTS: The entire source diskette is copied, including the unused
42; sectors. There is no awareness of the separate files
43; involved. A unique volume serial number is generated
44; for the target diskette.
45
46; INCLUDED FILES:
47; INCLUDE DCPYMACR.INC
48; INCLUDE DISKCOPY.EQU
49; INCLUDE PATHMAC.INC ;PATHGEN MACRO
50
51; INTERNAL REFERENCES:
52; ROUTINES:
53; INIT - INITIALIZATION ROUTINE, MAIN PROGRAM
54; SOURCE_TARGET_DRV - CONVERT SOURCE/TARGET DRIVE TO BIOS VALUES
55; TEST_DRIVE_VALIDITY - ARE SOURCE/TARGET DRIVES VALID?
56; DOS_DRIVE_VALIDITY - CHECK DOS DRIVE VALIDITY BYTE
57; TEST_REMOVABLE - IS SPECIFIED DRIVE REMOVABLE?
58; CHK_SINGLE_DRIV_OP - IS TARGET DRIVE SAME AS SOURCE?
59; GET_LOGICAL_DRIVE - GET LOG. DRIV NO. WHO OWNS PHYSICAL DRIVE
60; DISKETTE_DRV_TYPE - CHECK COMPATABILITY SOURCE/TARGET DRIVES
61; CHECK_REDIRECTION - IS DEVICE REDIRECTED?
62; BUFFER_SIZE - FINDS START AND END OF BUFFER
63; SETUP_CTRL_BREAK - SETUP THE CTRL-BREAK VECTOR
64; CHECK_SERVER - IS SERVER OR REDIRECTOR LOADED?
65
66; DATA AREAS:
67; PSP - Contains the DOS command line parameters.
68; WORKAREA - Temporary storage
69
70; EXTERNAL REFERENCES:
71; ROUTINES:
72; SYSDISPMSG - Uses the MSG parm lists to construct the messages
73; on STDOUT.
74; SYSLOADMSG - Loads messages, makes them accessable.
75; PARSER - Processes the DOS Command line, finds parms.
76
77; DATA AREAS:
78; DCOPYSM.SAL - Defines the control blocks that describe the messages
79; DCOPYPAR.SAL - Defines the control blocks that describe the
80; DOS Command line parameters.
81
82; NOTES:
83; This module should be processed with the SALUT preprocessor
84; with the re-alignment not requested, as:
85
86; SALUT COPYINIT,NUL
87
88; To assemble these modules, the alphabetical or sequential
89; ordering of segments may be used.
90
91; For instructions as to how to LINK, see prolog for DISKCOPY.
92
93;PROGRAM AUTHOR: Original written by: JK
94; 4.00 modifications by: EMK
95;****************** END OF SPECIFICATIONS *****************************
96 IF1
97 %OUT COMPONENT=DISKCOPY, MODULE=COPYINIT.SAL
98 ENDIF
99
100;DATE: 9-22-83
101;TIME: 8:00 PM
102;DATE: 10-30-84 - chk_para routine added. many parts are modified to
103; permit DISKCOPY /1, DISKCOPY D: /1 cases. Restore diskbase
104; before return to DOS when invalid DOS version occurs.
105;DATE: 3-27-85 MAIN PARTS OF DISKCOPY PROGRAM HAS BEEN REWRITTEN
106; TO USE NEW IOCTL FUNCTION CALLS - READ, WRITE AND FORMAT.
107
108 INCLUDE DCPYMACR.INC
109 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
110
111CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
112 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
113
114 INCLUDE DISKCOPY.EQU
115;$salut (4,2,9,41)
116;****************************************************************************
117; *
118; EXTERNAL VARIABLES *
119; *
120;****************************************************************************
121
122 EXTRN PARSER:NEAR ;DCOPYPAR.SAL - DRIVES SYS PARSER ;AN000;
123
124 EXTRN RECOMMENDED_BYTES_SECTOR:WORD ;SOURCE DRIVE DEFAULT BYTES/SECTOR
125 EXTRN S_OWNER_SAVED:BYTE
126 EXTRN T_OWNER_SAVED:BYTE
127 EXTRN ASCII_DRV1_ID:BYTE ;40H SOURCE DRIVE ID IN ASCII
128 EXTRN ASCII_DRV2_ID:BYTE ;40H TARGET DRIVE ID IN ASCII
129 EXTRN MSGNUM_INVALID_DRV:BYTE ;"INVALID DRIVE SPECIFICATION" ;AC000;
130 EXTRN MSGNUM_NOT_COMPATIBLE :BYTE ;"DEVICE TYPE OF DISKETTE TYPES NOT COMPATIBLE";AC000;
131 EXTRN MSGNUM_DRV_REDIRECTED:BYTE ;"INVALID, DRIVE REDIRECTED" ;AC000;
132
133
134 EXTRN SUBLIST_8 :WORD ; ;AN000;
135 EXTRN SUBLIST_9 :WORD ; ;AN000;
136 EXTRN SUBLIST_13 :WORD ; ;AN000;
137 EXTRN SUBLIST_17A :WORD ; ;AN000;
138 EXTRN SUBLIST_17B :WORD ; ;AN000;
139 EXTRN SUBLIST_17C :WORD ; ;AN000;
140 EXTRN SUBLIST_19C :WORD ; ;AN000;
141 EXTRN SUBLIST_19D :WORD ; ;AN000;
142 EXTRN SUBLIST_19E :WORD ; ;AN000;
143 EXTRN SUBLIST_26A :WORD ; ;AN001;
144 EXTRN SUBLIST_26B :WORD ; ;AN001;
145 EXTRN SUBLIST_PARSE:WORD ;PARSE ERROR XX - %0 ;AN003;
146
147.XLIST
148;EXTRN MSG_INVALID_PARM_PTR:BYTE ;"INVALID PARAMETER"
149;EXTRN MSG_INVALID_DOS :BYTE ;"INVALID DOS"
150.LIST
151 EXTRN S_DRV_SECT_TRACK :BYTE ;SECT/TRACK
152 EXTRN S_DRV_HEADS :BYTE ;# OF HEADS
153 EXTRN S_DRV_TRACKS :BYTE ;# OF TRACKS
154 EXTRN T_DRV_SECT_TRACK :BYTE
155 EXTRN T_DRV_HEADS :BYTE
156 EXTRN T_DRV_TRACKS :BYTE
157 EXTRN SOURCE_DRIVE :BYTE ;SRC DRV LOGICAL NUMBER
158 EXTRN TARGET_DRIVE :BYTE ;TARGET DRV LOGICAL NUMBER
159 EXTRN COPY_TYPE :BYTE ;1 = 1-DRIVE COPY 2 = 2-DRIVE COPY
160 EXTRN USER_OPTION :BYTE ;NO OPTION (-1) /1 (1), INVALID (9)
161 EXTRN BUFFER_BEGIN :WORD ;STARTING BUFFER @ FOR LOADING
162 EXTRN BUFFER_END :WORD ;ENDING BUFFER @ FOR LOADING
163 EXTRN MAIN_EXIT :WORD ;EXIT ADDRESS FOR CONTROL-BREAK
164
165 EXTRN IO_ERROR :BYTE
166
167 EXTRN DS_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
168 EXTRN DT_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
169 EXTRN DS_specialFunctions :BYTE ;AND THEIR CONTENTS
170 EXTRN DT_specialFunctions :BYTE
171 EXTRN DS_deviceType:BYTE
172 EXTRN DT_deviceType:BYTE
173 EXTRN DS_deviceAttributes :WORD
174 EXTRN DT_deviceAttributes :WORD
175 EXTRN DS_numberOfCylinders :WORD
176 EXTRN DT_numberOfCylinders :WORD
177 EXTRN DS_mediaType :BYTE
178 EXTRN DT_mediaType :BYTE
179 EXTRN DS_BPB_PTR :BYTE
180 EXTRN DT_BPB_PTR :BYTE
181
182 EXTRN MS_IOCTL_DRV_PARM :BYTE ;DRIVE PARM FROM SOURCE MEDIUM
183 EXTRN MT_IOCTL_DRV_PARM :BYTE
184
185 EXTRN GENERIC_IOCTL :NEAR
186 EXTRN SET_LOGICAL_DRIVE :NEAR
187
188; $salut (4,20,24,41) ; ;AN000;
189MY_BPB STRUC
190CBYTE_SECT DW 0 ; 200H BYTES / SECTOR
191CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER
192CRESEV_SECT DW 0 ; 1h RESERVED SECTORS
193CFAT DB 0 ; 2h # OF FATS
194CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES
195CTOTSECT DW 0 ; 02D0h TOTAL # OF SECTORS
196 ; INC. BOOT SECT, DIRECTORIES
197MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR
198CSECT_FAT DW 0 ; 2h SECTORS / FAT
199CSECT_TRACK DW 0 ;
200CHEAD DW 0 ;
201CHIDDEN_SECT DD 0 ;
202BIG_TOT_SECT DD 0 ;
203 DB 6 DUP (0) ;
204MY_BPB ENDS
205
206
207;****************************************************************************
208; *
209; VARIABLE DECLARATIONS *
210; *
211;****************************************************************************
212DRIVE_VALID DW ? ;DRIVE VALIDITY INDICATOR
213DEFAULT_DRV DB ? ;DEFAULT DRIVE ID (0=A,1=B,ETC)
214NUMBER_OF_DRV DB ? ;TOTAL # OF DISKT DRIVES ON THE SYS
215 ;(NUMBER_OF_DRV = 0 ---> 1 DRIVE)
216ASCII_DRIVE_LETTER DB " :",0
217 PATHLABL COPYINIT ;AN015;
218 HEADER <INIT - INITIALIZATION ROUTINE, MAIN PROGRAM> ; ;AN000;
219; $salut (4,9,15,41) ; ;AN000;
220;#############################################################################
221; INITIALIZATION ROUTINE - MAIN PROGRAM
222INIT PROC NEAR
223 PUBLIC INIT ;MAKE ENTRY IN LINK MAP ;AN000;
224
225;OUTPUT: DX = EXIT CODE, "FINE"
226;#############################################################################
227
228 MOV DRIVE_VALID,AX ;SAVE DRIVE VALIDITY BYTE
229
230; REPLACE THE "FILL_SEG" IN THE SUBLIST MESSAGE CONTROL BLOCKS.
231
232; BECAUSE THIS IS A .COM STYLE FILE, THESE SEGID VALUES CANNOT
233; BE PROVIDED BY THE DOS SYSTEM LOADER, BUT MUST BE DYNAMICALLY
234; PERFORMED AT EXECUTION TIME AS PART OF A .COM FILE'S OBLIGATION
235; TO BE "SELF-RELOCATING".
236
237 MOV AX,CS ;GET SEGID OF COMMON SEGMENT ;AN000;
238 MOV SUBLIST_8.SUB_VALUE_SEG,AX ; ;AN000;
239 MOV SUBLIST_9.SUB_VALUE_SEG,AX ; ;AN000;
240 MOV SUBLIST_13.SUB_VALUE_SEG,AX ; ;AN000;
241 MOV SUBLIST_17A.SUB_VALUE_SEG,AX ; ;AN000;
242 MOV SUBLIST_17B.SUB_VALUE_SEG,AX ; ;AN000;
243 MOV SUBLIST_17C.SUB_VALUE_SEG,AX ; ;AN000;
244 MOV SUBLIST_19C.SUB_VALUE_SEG,AX ; ;AN000;
245 MOV SUBLIST_19D.SUB_VALUE_SEG,AX ; ;AN000;
246 MOV SUBLIST_19E.SUB_VALUE_SEG,AX ; ;AN000;
247 MOV SUBLIST_26A.SUB_VALUE_SEG,AX ; ;AN001;
248 MOV SUBLIST_26B.SUB_VALUE_SEG,AX ; ;AN001;
249 MOV SUBLIST_PARSE.SUB_VALUE_SEG,AX ; ;AN003;
250
251 CALL SETUP_CTRL_BREAK ;STEALS CTRL_BREAK
252 CLD ;CLEAR DIRECTION FLAG
253 MOV DX,FINE ;ASSUME EVERYTHING IS FINE
254.XLIST
255; CALL SCREENING ;CHECK DOS VERSION AND INPUT PARMS
256; CALL CHK_PARA ; GENERAL SYNTAX CHECK
257.LIST
258 CALL PARSER ;LOOK AT DOS COMMAND LINE ;AN000;
259
260 CMP DX,FINE ;IF ALL OK ;AN000;
261; $IF E ; ;AN000;
262 JNE $$IF1
263 CALL SOURCE_TARGET_DRV ;SET UP TO USE THE DRIVE LETTERS ;AN000;
264
265 CALL TEST_DRIVE_VALIDITY
266
267 CMP DX,FINE
268; $IF E ; ;AN000;
269 JNE $$IF2
270 CALL DISKETTE_DRV_TYPE ;SOURCE & TARGET DRIVE TYPES
271
272 CMP DX,FINE ;IF FINE & DANDY
273; $IF E ; ;AN000;
274 JNE $$IF3
275 CALL BUFFER_SIZE ;GET BUFFER SIZE FOR COPYING
276
277; $ENDIF ; ;AN000;
278$$IF3:
279; $ENDIF ; ;AN000;
280$$IF2:
281; $ENDIF ; ;AN000;
282$$IF1:
283EXIT_INIT: ;DX <-- 1 IF INIT OK
284 RET ;DX <-- ERROR OFFSET IF NOT OK
285 ;RETURN TO CALLER
286INIT ENDP ;END INITIALLIZATION PROGRAM
287
288.XLIST
289; HEADER <SCREENING - CHECK DOS VERSION, SYNTAX PARMS>
290;******************************************************************************
291; SUBROUTINE NAME : SCREENING - CHECKS THE FOLLOWING: *
292; - DOS VERSION *
293; - GENERAL SYNTAX CHECKING FOR PARAMETERS *
294; INPUT : NONE *
295; OUTPUT : DX : FINE - NO ERROR *
296; (OTHERS)- ERROR MSG OFFSET *
297;******************************************************************************
298
299;SCREENING PROC NEAR
300 ;CHECK DOS VERSION:
301; MOV AH,DOSVER_FUNC ;SEE IF CORRECT DOS VERSION
302; INT 21H ;FUNCTION CALL (AL <- DOS VERSION)
303 ;NOTE: BX IS DESTROYED
304; XCHG AH,AL ;AH=MAJOR VER, AL=MINOR VER
305; CMP AX,expected_version ;IF DOS MAJOR VERSION LESS THAN 3.00
306; $IF NE ;THEN ISSUE ERROR MSG
307; MOV DX,OFFSET MSG_INVALID_DOS
308; MOV AH,PRINT_FUNC ;USE PRINT FUNCTION TO TELL USER
309; INT 21H ;THAT HE IS USING THE OLD VERSION
310; INT 20H ;EXIT TO DOS
311; $ELSE ;VERSION OK
312; CALL CHK_PARA ;GENERAL SYNTAX CHECK
313; $ENDIF ;END VERSION TEST
314; RET
315;SCREENING ENDP
316; HEADER <CHK_PARA - SYNTAX PARMS, OPTION /1>
317;**************************************************************************
318
319;kiser: this proc is to be deleted
320
321;CHK_PARA PROC NEAR
322; CHECK SYNTAX OF THE ENTERED PARAMETERS *
323; ALSO, DETERMINE THE USER OPTION "/1" IS ENTERED OR NOT. *
324; INPUT: DX = FINE *
325; IF /1 HAS BEEN ENTERED, THE VARIABLE USER_OPTION = OPTION_1 *
326; ELSE USER_OPTION = NO_OPTION. *
327; OUTPUT: DX = FINE - NO ERROR *
328; OTHERWISE DX POINTS TO ERROR MSG *
329;**************************************************************************
330; PUSH CX
331; MOV USER_OPTION, NO_OPTION ;ASSUME NO /1 IS ENTERED.
332; XOR CX, CX
333; MOV CL, BYTE PTR DS:BEGIN_UNFORM_AREA ;GET # OF CHR
334; CMP CL, 0
335; $IF NZ
336; CLD ;CLEAR DIRECTION
337; MOV DI, BEGIN_UNFORM_AREA+2 ;STARTING POINT OF PARA
338; DEC CL ;TO IGNORE LAST CHR (0DH)
339; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY. THE POINTER
340; ; WILL POINT TO THE NEXT NON_BLANK CHR
341;
342; $IF NZ ;SOMETHING OTHER THAN BLANKS
343; ; ARE ENTERED
344; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 ?
345;
346; JNC SLASH_ONE ;YES
347; CALL CHK_DRV_SPEC ;IS IT A DRIVE SPECIFICATION LIKE d: ?
348;
349; JC INVALID_PARA ;IF NOT, THEN ERROR
350; JZ CHK_PARA_EXIT ;NO MORE CHR? THEN, OK. (EX. DISKCOPY D:)
351; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 ?
352;
353; JNC SLASH_ONE ;YES.(EX. DISKCOPY D:/1)
354; CALL CHK_BLANK ;IF NOT, NEXT CHR SHOULD BE A BLANK.
355;
356; JC INVALID_PARA ;OTHERWISE, ERROR.
357; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY.
358;
359; JZ CHK_PARA_EXIT ;(EX. DISKCOPY D: )
360; CALL CHK_SLASH_ONE ;IS IT A /1 ?
361;
362; JNC SLASH_ONE ;YES. (EX. DISKCOPY D: /1)
363; CALL CHK_DRV_SPEC ;IF NOT /1, THEN IS IT A DRV SPEC?
364;
365; JC INVALID_PARA ;OTHERWISE, ERROR.
366; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY.
367;
368; JZ CHK_PARA_EXIT ;NO MORE CHR. (EX. DISKCOPY D: D:)
369; CALL CHK_SLASH_ONE ;OTHERWISE, IT SHOULD BE /1.
370;
371; JNC SLASH_ONE ;YES, /1. JMP TO SLASH_ONE
372; JMP INVALID_PARA ;PARAMETER ERROR.
373;SLASH_ONE:
374; MOV USER_OPTION, OPTION_1 ;YES, /1 HAS BEEN ENTERED.
375; CALL SKIP_BLANKS ;/1 SHOULD BE END OF PARAMETERS, OR ONLY BLANKS CAN FOLLOW.
376;
377; $IF NZ
378;INVALID_PARA:
379; MOV DX,OFFSET MSG_INVALID_PARM_PTR ;WRONG PARM ENTERED MSG
380; $ENDIF
381; $ENDIF
382; $ENDIF
383;CHK_PARA_EXIT:
384; POP CX
385;
386; RET
387;CHK_PARA ENDP
388; HEADER <SKIP_BLANKS - IGNORE BLANKS/TABS IN PARMS PARSING>
389;***************************************************************************
390;SKIP_BLANKS PROC NEAR
391; ** SKIP BLANKS, OR TABS IF ANY, IN THE PARAMETER STRING. *
392; INPUT: ES:DI POINTS TO THE CURRENT CHR. *
393; CX - # OF REMAINING CHR IN THE STRING. *
394; OUTPUT: ES:DI POINT TO THE NEXT NON_BLANK CHR. *
395; CX IS ADJUSTED ACCORINGLY. *
396; IF THE CURRENT CHR IS NOT A BLANK, THEN DI, CX VALUE NOT CHANGED.*
397; IF CX = 0, THEN ZERO FLAG WILL BE SET AND EXIT THIS PROC. *
398;***************************************************************************
399; $DO
400; MOV AL, 20H ;20H=BLANK
401; CLD ;CLEAR DIRECTION
402; REPE SCASB
403; $LEAVE Z ;IF NOT FOUND A NON_BLANK CHR YET, AND CX=0, EXIT THIS ROUTINE.
404; DEC DI ;OTHERWISE, RESTORE DI TO THE NON_BLANK POSITION.
405; INC CX ; AND RESTORE CX TO WHERE IT WAS AT NON_BLANK CHR
406; ;(IF FOUND A NON_BLANK CHR, ZERO FLAG WOULD NOT BE SET)
407; MOV AL, ES:BYTE PTR [DI]
408; CMP AL, 09H ;09H=TAB
409; $LEAVE NZ ;IF THE NON_BLANK CHR IS NOT A TAB THEN EXIT
410; INC DI ;ELSE TRY SKIP AGAIN
411; DEC CX
412; $ENDDO
413; RET
414;SKIP_BLANKS ENDP
415; HEADER <CHK_SLASH - IS CURRENT PARM /1>
416;***************************************************************************
417
418;kiser: this proc is to be deleted
419
420;CHK_SLASH_ONE PROC NEAR
421; ** CHECK CURRENT CHR IS / FOLLOWED BY 1. *
422; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. *
423; CX REPRESENTS THE # OF CHR'S IN THE STRING. *
424; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX CHANGED ACCORDINGLY. *
425; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. *
426; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
427;***************************************************************************
428;
429; CLC ;CLEAR CARRY FLAG
430; CMP CX, 2 ;# OF CHR IN THE STRING.
431; $IF NL,AND ;IF LESS THAN 2, THEN SET CARRY AND EXIT.
432;
433; MOV AX, ES:WORD PTR [DI] ;GET CURRENT WORD IN AX
434; CMP AX, '1/' ;IS IT /1 ?
435; $IF Z ;IF NOT, THEN SET CARRY AND EXIT
436; INC DI ;ADJUST CX, DI TO THE NEXT CHR
437; INC DI
438; DEC CX
439; DEC CX
440; CMP CX, 0 ;IF NO MORE CHR, THEN SET ZERO FLAG.
441; $ELSE
442; STC ;NOT FOUND, SET CARRY FLAG.
443; $ENDIF
444; RET
445;CHK_SLASH_ONE ENDP
446; HEADER <CHK_DRV - CURRENT PARM CHAR IS DRIVE AND COLON?>
447;***************************************************************************
448
449;kiser: this proc is to be deleted
450
451;CHK_DRV_SPEC PROC NEAR
452; ** CHECK CURRENT CHR IS ALPHA CHR FOLLOWED BY COLON. *
453; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. *
454; CX -- # OF CHR IN THE STRING. *
455; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX ADJUSTED ACCORDINGLY. *
456; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. *
457; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
458;***************************************************************************
459
460; CLC ;CLEAR CARRY
461; CMP CX, 2 ;# OF CHR REMAINING IN THE STRING.
462; $IF NL,AND ;IF NOT LESS THAN 2, THEN FOUND
463; ;IF LESS THAN 2, THEN NOT FOUND - SET CARRY AND EXIT.
464; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR
465; AND AL, 11011111B ;CHANGE IT TO UPPER_CASE CHR.
466; CMP AL, 'A'
467; $IF NB,AND ;NOT BELOW 'A', THEN MAYBE FOUND OK
468;
469; CMP AL, 'Z'
470; $IF NA,AND ;NOT ABOVE 'Z', THEN FOUND
471;
472; MOV AL, ES:BYTE PTR [DI+1] ;LOOK AHEAD THE FOLLOWING CHR.
473; CMP AL, ':' ;SHOULD BE A COLON.
474; $IF Z ;IF FOUND.
475; INC DI ;FOUND. ADJUST CX, DI TO THE NEXT CHR.
476; INC DI
477; DEC CX
478; DEC CX
479; CMP CX, 0 ;IF NO MORE CHR, THAN SET THE ZERO FLAG.
480; $ELSE
481; STC ;SET CARRY
482; $ENDIF
483; RET
484;CHK_DRV_SPEC ENDP
485; HEADER <CHK_BLANK - IS CURRENT CHAR IN PARM BLANK OR TAB>
486;***************************************************************************
487
488;kiser: this proc is to be deleted
489
490;CHK_BLANK PROC NEAR
491;; ** CHECK THE CURRENT CHR IS A BLANK OR TAB *
492;; INPUT: ES:DI POINTS TO THE CURRENT CHR. *
493; CX - # OF CHR IN THE STRING. *
494; OUTPUT: FOUND - DI MOVES TO THE NEXT CHR. CX DECREASES BY 1. *
495; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. *
496;***************************************************************************
497
498; CLC ;CLEAR CARRY
499; CMP CX, 1 ;IF LESS THAN 1, NOT FOUND.
500; $IF L,OR ;GO SET CARRY AND EXIT
501;
502; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR
503; CMP AL, 020H ;020H=BLANK CHR
504; $IF NZ,AND ;NOT FOUND
505; CMP AL, 09H ;09H=TAB CHR
506; $IF NZ ;NOT FOUND EITHER
507;
508; ;THEN NOT FOUND
509; STC ;SET CARRY
510; $ELSE ;CHAR MUST BE EITHER TAB OR BLANK
511; INC DI ;FOUND. ADJUST DI, CX
512; DEC CX
513; $ENDIF
514; RET
515;CHK_BLANK ENDP
516.LIST
517 HEADER <SOURCE_TARGET_DRV - CONV. SRC/TARGET DRV TO BIOS VALUES> ; ;AN000;
518;******************************************************************************
519; SUBROUTINE NAME : SOURCE_TARGET_DRV DETERMINES SOURCE & TARGET DRIVES & *
520; CONVERT THEM FROM DOS TO BIOS VALUE *
521; INPUT : SOURCE_DRIVE & TARGET_DRIVE HAVE DOS DRIVE ID'S: *
522; 0 = DEFAULT 1 = DRV A *
523; 2 = DRV B 3 = DRV C ETC *
524; *
525; *
526; OUTPUT : DEFAULT_DRV: CURRENT DEFAULT DRIVE *
527; 0 - DRIVE A 1 - DRIVE B *
528; 2 - DRIVE C 3 - DRIVE D *
529; *
530; : SOURCE_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
531; : TARGET_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. *
532; (UNCHANGED) *
533;******************************************************************************
534SOURCE_TARGET_DRV PROC NEAR
535 PUBLIC SOURCE_TARGET_DRV ;MAKE ENTRY IN LINK MAP ;AN000;
536 ;GET CURRENT DEFAULT DRIVE
537 MOV AH,CURRENTDRV_FUNC ;FUNCTION CALL (19H)
538 ;(AL <- CURRENT DEFAULT DRV
539 INT 21H ;0 = A, 1 = B, ETC)
540
541 MOV DEFAULT_DRV,AL ;SAVE IT
542 INC AL ;NOW A=1, B=2, ETC ;AN000;
543 CMP SOURCE_DRIVE,ZERO ;FIRST DRV ENTERED? ;AC000;
544; $IF E ;NO DRIVE LETTER ENTERED
545 JNE $$IF7
546 MOV SOURCE_DRIVE,AL ;USE DEFAULT DRIVE AS SOURCE ;AC000;
547 MOV TARGET_DRIVE,AL ; AND AS TARGET ;AC000;
548; $ELSE
549 JMP SHORT $$EN7
550$$IF7:
551 CMP TARGET_DRIVE,ZERO ;WAS THE SECOND DRIVE ID SPECIFIED? ;AC000;
552; $IF E ;NO, SO TARGET DRV IS DEFAULT ;AC000;
553 JNE $$IF9
554 MOV TARGET_DRIVE,AL ;USE DEFAULT DRIVE AS TARGET ;AC000;
555; $ENDIF
556$$IF9:
557; $ENDIF
558$$EN7:
559 MOV AX,WORD PTR SOURCE_DRIVE ;SOURCE TO AL, TARGET TO AH ;AC000;
560 ADD ASCII_DRV1_ID,AL ;MAKE THE DRIVE ALPHABET READABLE
561 ADD ASCII_DRV2_ID,AH ;IN THE MESSAGE
562
563 RET
564
565SOURCE_TARGET_DRV ENDP
566 HEADER <TEST_DRIVE_VALIDITY - ARE SOURCE/TARGET DRIVES VALID?> ; ;AN000;
567;******************************************************************************
568; SUBROUTINE NAME : TEST_DRIVE_VALIDITY--MAKE SURE SOURCE AND TARGET DRIVES *
569; SPECIFIED BY USER ARE VALID FOR DISKCOPY *
570; *
571; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE *
572; *
573; OUTPUT : DX='FINE' IF DRIVES ARE VALID, ELSE DX CONTAINS MSG PTR *
574;******************************************************************************
575
576TEST_DRIVE_VALIDITY PROC NEAR
577 PUBLIC TEST_DRIVE_VALIDITY ;MAKE ENTRY IN LINK MAP ;AN000;
578
579 CALL DOS_DRIVE_VALIDITY
580
581 CMP DX,FINE
582; $IF E,AND ; ;AC000;
583 JNE $$IF12
584
585 MOV BL,SOURCE_DRIVE
586 CALL CHECK_REDIRECTION
587
588 CMP DX,FINE
589; $IF E,AND ; ;AC000;
590 JNE $$IF12
591
592 MOV BL,TARGET_DRIVE
593 CALL CHECK_REDIRECTION
594
595 CMP DX,FINE
596; $IF E,AND ; ;AC000;
597 JNE $$IF12
598
599 MOV BL,SOURCE_DRIVE
600 CALL CHECK_SERVER
601
602 CMP DX,FINE
603; $IF E,AND ; ;AC000;
604 JNE $$IF12
605
606 MOV BL,TARGET_DRIVE
607 CALL CHECK_SERVER
608
609 CMP DX,FINE
610; $IF E,AND ; ;AC000;
611 JNE $$IF12
612
613 CALL TEST_REMOVABLE
614
615 CMP DX,FINE
616; $IF E ; ;AC000;
617 JNE $$IF12
618
619 CALL CHK_SINGLE_DRV_OP ;CHECK IF IT IS
620 ; ONE PHYSICAL DRIVE OPERATION
621; $ENDIF ; ;AC000;
622$$IF12:
623 RET
624
625TEST_DRIVE_VALIDITY ENDP
626 HEADER <DOS_DRIVE_VALIDITY - CHECK DOS DRIVE VALIDITY BYTE> ; ;AN000;
627;******************************************************************************
628; SUBROUTINE NAME : DOS_DRIVE_VALIDITY -- CHECK DOS DRIVE VALIDITY BYTE *
629; *
630; INPUT : DRIVE_VALID:BYTE *
631; *
632; OUTPUT : DX="FINE" IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
633;******************************************************************************
634
635DOS_DRIVE_VALIDITY PROC NEAR
636
637 CMP DRIVE_VALID,0 ;SEE IF DRIVES ARE VALID DOS DEVICE
638; $IF NE
639 JE $$IF14
640 MOV DX,OFFSET MSGNUM_INVALID_DRV ; ;AC000;
641; $ENDIF
642$$IF14:
643 RET
644
645DOS_DRIVE_VALIDITY ENDP
646 HEADER <TEST_REMOVABLE - IS SPECIFIED DRIVE REMOVABLE?> ; ;AN000;
647;******************************************************************************
648; SUBROUTINE NAME : TEST_REMOVABLE -- CHECK IF DRIVES SPECIFED ARE REMOVABLE *
649; *
650; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE *
651; *
652; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR *
653;******************************************************************************
654
655TEST_REMOVABLE PROC NEAR
656
657 MOV BL,SOURCE_DRIVE ;GET PARM 1 DRIVE ID
658
659 MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE = 4408h
660 INT 21H ;IOCTL CALL
661; $IF NC ;IF DRIVE ID IS WITHIN RANGE
662 JC $$IF16
663 CMP AX,REMOVABLE ;THEN IF SOURCE DRIVE IS FIXED
664; $IF NE ; THEN
665 JE $$IF17
666 MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE HARD ;AC000;
667 ; DRIVE ERROR MESSAGE
668; $ELSE ;ELSE, SRC IS REMOVABLE;
669 JMP SHORT $$EN17
670$$IF17:
671 MOV BL,TARGET_DRIVE ;NOW GO CHECK TARGET
672
673 MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE
674 INT 21H ;IOCTL CALL
675; $IF NC ;IF DRV WITHIN RANGE
676 JC $$IF19
677 CMP AX,REMOVABLE ;THEN TGT DRV IS FIXED
678; $IF NE ; THEN
679 JE $$IF20
680 MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE HARD ;AC000;
681 ; DRV ERROR MSG
682; $ENDIF ;END TEST IF TGT DRV IS FIXED
683$$IF20:
684; $ELSE ;TGT DRV OUT OF RANGE. EX. DRIVE X:
685 JMP SHORT $$EN19
686$$IF19:
687 MOV DX,OFFSET MSGNUM_INVALID_DRV ; ;AC000;
688; $ENDIF ;END TEST IF TGT WITHIN RANGE
689$$EN19:
690; $ENDIF ;END IF SRC IS REMOVABLE
691$$EN17:
692; $ELSE ;ELSE, SRC DRV OUT OF RANGE
693 JMP SHORT $$EN16
694$$IF16:
695 MOV DX,OFFSET MSGNUM_INVALID_DRV ;PRINT ERROR MSG ;AC000;
696; $ENDIF ;END TEST IF SRC DRV WITHIN RANGE
697$$EN16:
698 RET
699
700TEST_REMOVABLE ENDP
701 HEADER <CHK_SINGLE_DRIV_OP - IS TARGET DRIVE SAME AS SOURCE?> ; ;AN000;
702;******************************************************************************
703; SUBROUTINE NAME : CHK_SINGLE_DRV_OP *
704; *
705; INPUT : SOURCE_DRIVE - LOGICAL DRIVE NUMBER *
706; TARGET_DRIVE *
707; *
708; OUTPUT : COPY_TYPE WILL BE SET TO ONE OR TWO DEPENDING ON THE *
709; TEST RESULT. IF IT IS A SINGLE DRIVE COPY, THEN *
710; TARGET DRIVE LETTER WILL BE CHANGED TO THAT OF SOURCE. *
711; THE OWNERSHIP OF THE SOURCE AND TARGET DRIVE LETTER *
712; MIGHT HAVE BEEN CHANGED. *
713; SO, BEFORE EXIT TO DOS, THEY SHOULD BE RESET TO THE SAVED*
714; ONE USING S_OWNER_SAVED AND T_OWNER_SAVED UNLESS THEY *
715; ARE EQUAL TO 0. (0 MEANS ONLY ONE DRIVE LETTER ASSIGNED.)*
716; ASCII_DRV1_ID, ASCII_DRV2_ID MAY BE CHANGED ACCORDINGLY. *
717;******************************************************************************
718
719CHK_SINGLE_DRV_OP PROC NEAR
720
721 PUSH AX
722
723 MOV BL,SOURCE_DRIVE
724 CALL GET_LOGICAL_DRIVE
725
726 MOV S_OWNER_SAVED, AL ;SAVE CURRENT OWNER DRIVE LETTER.
727 MOV BL, TARGET_DRIVE
728 CALL GET_LOGICAL_DRIVE
729
730 MOV T_OWNER_SAVED, AL ;SAVE CURRENT OWNER
731 MOV BL, SOURCE_DRIVE
732 CALL SET_LOGICAL_DRIVE
733
734 MOV BL, TARGET_DRIVE
735 CALL SET_LOGICAL_DRIVE
736
737 MOV BL, SOURCE_DRIVE
738 CALL GET_LOGICAL_DRIVE ;CHECK SOURCE DRV LETTER
739 ; STILL HAS A OWNERSHIP.
740
741 CMP AL, SOURCE_DRIVE ;
742; $IF NE ;IF IT DOES NOT, THEN A
743 JE $$IF27
744 ; SINGLE DRIVE COPY.
745 MOV COPY_TYPE, ONE
746 MOV BL, SOURCE_DRIVE
747 MOV TARGET_DRIVE, BL ;SET TARGET DRV LETTER
748 ; TO THAT OF SOURCE
749 MOV BL, ASCII_DRV1_ID
750 MOV ASCII_DRV2_ID, BL
751 MOV BL, SOURCE_DRIVE
752 CALL SET_LOGICAL_DRIVE ;SET THE OWNER BACK TO
753 ; SOURCE DRV LETTER
754
755; $ELSE
756 JMP SHORT $$EN27
757$$IF27:
758 CMP AL, TARGET_DRIVE ;SOURCE DRV LETTER = TARGET DRV
759 ; LETTER CASE, FOR EX. DISKCOPY A: A:
760; $IF E
761 JNE $$IF29
762 MOV COPY_TYPE, ONE
763; $ELSE
764 JMP SHORT $$EN29
765$$IF29:
766 MOV COPY_TYPE, TWO
767; $ENDIF
768$$EN29:
769; $ENDIF
770$$EN27:
771
772 POP AX
773
774 RET
775CHK_SINGLE_DRV_OP ENDP
776 HEADER <GET_LOGICAL_DRIVE - GET LOG. DRIV NO. WHO OWNS PHYS. DRIVE> ;AN000;
777;******************************************************************************
778GET_LOGICAL_DRIVE PROC NEAR
779; *** GET THE LOGICAL DRIVE NUMBER WHO HAS THE OWNERSHIP OF THE PHYSICAL
780; DRIVE.
781; INPUT: BL = DRIVE NUMBER (0=DEFAULT, 1=A, 2=B...)
782; OUTPUT: AL = DRIVE NUMBER (0= ONLY ONE DRIVE LETTER ASSIGNED TO THE
783; BLOCK DEVICE. OTHERWISE, 1=A, 2=B...)
784;
785;******************************************************************************
786
787 MOV AH, 44H
788 MOV AL, 0EH ; GET THE OWNER OF LOGICAL DRIVE NUMBER
789 INT 21H
790 CMP AL, 0 ;ONLY ONE DRIVE LETTER ASSIGNED?
791; $IF E
792 JNE $$IF33
793 MOV AL, BL ;THEN SET THE INPUT DRIVE NUMBER TO AL.
794; $ENDIF
795$$IF33:
796
797 RET
798
799GET_LOGICAL_DRIVE ENDP
800 HEADER <DISKETTE_DRV_TYPE - CHECK COMPATABILITY SOURCE/TARGET DRIVES> ; ;AN000;
801;******************************************************************************
802; SUBROUTINE NAME : DISKETTE_DRV_TYPE DOES THE FOLLOWING: *
803; - GETS SOURCE, TARGET DRIVE INFORMATION *
804; - CHECK REMOVABLE DRIVE *
805; *** REMARK: WILL NOT ALLOW DISKCOPY BETWEEN 5.25" AND 3.5" DRIVES. *
806; *** ALSO, IN THE MAIN PROGRAM, SOURCE MEDIA BPB INFORMATIONS (# OF SEC/TRK, *
807; *** # OF TRACKS) SHOULD BE CHECKED AGAINST TARGET DEVICE INFORMATIONS. *
808; *** IF # OF SECT/TRACK, # OF TRACKS OF TARGET DEVICE ARE EQUAL TO, OR *
809; *** GREATER THAN THOSE OF THE SOURCE MEDIA BPB, THEN IT IS OK. OTHERWISE *
810; *** DEVICE NOT COMPATIBLE. *
811; *** IF THIS DOES NOT GAURANTEES COMPATIBILITY BETWEEN SOURCE AND TARGET *
812; *** DEVICE OR MEDIA, EVENTUALLY, FAILURE TO FORMAT THE TARGET WILL *
813; *** TELL THAT SOURCE, TARGET DEVICE OR MEDIA ARE NOT COMPATIBLE. *
814; *
815;******************************************************************************
816DISKETTE_DRV_TYPE PROC NEAR
817 PUSH AX
818
819 xor bx, bx
820 MOV BL, SOURCE_DRIVE
821 MOV CL, GETDEVPARM ;=60h
822 MOV DX, OFFSET DS_IOCTL_DRV_PARM ;POINTER TO THE CONTROL STRING
823 CALL GENERIC_IOCTL ;GET DEFAULT DEVICE PARM.
824
825 TEST DS_deviceAttributes, 0001h ;CHECK REMOVABLE. 0001 = NOT REMOVABLE
826; $IF E,AND ;NO, CONTINUE ;AC000;
827 JNE $$IF35
828
829 MOV AX, DS_numberOfCylinders ;CURRENTLY IGNORE AH. ASSUME LESS
830 ; THAN TWO BYTES
831 MOV S_DRV_TRACKS, AL
832 MOV BX, OFFSET DS_BPB_PTR
833 MOV AX, [BX].CHead
834 MOV S_DRV_HEADS, AL
835 MOV AX, [BX].CSECT_TRACK
836 MOV S_DRV_SECT_TRACK, AL
837 MOV AX, [BX].CBYTE_SECT ;RECOMMENDED BYTES/SECTOR
838 MOV RECOMMENDED_BYTES_SECTOR, AX
839
840 XOR BX,BX
841 MOV BL, TARGET_DRIVE
842 MOV CL, GETDEVPARM
843 MOV DX, OFFSET DT_IOCTL_DRV_PARM
844 CALL GENERIC_IOCTL ;GET DEFAULT DEVICE PARM.
845
846 TEST DT_deviceAttributes, 0001h ;FIXED DISK?
847; $IF Z ;TARGET IS NOT FIXED DISK, OK ;AC000;
848 JNZ $$IF35
849
850 MOV AX, DT_numberOfCylinders
851 MOV T_DRV_TRACKS, AL
852 MOV BX, OFFSET DT_BPB_PTR
853 MOV AX, [BX].CHead
854 MOV T_DRV_HEADS, AL
855 MOV AX, [BX].CSECT_TRACK
856 MOV T_DRV_SECT_TRACK, AL
857
858;**NOW, CHECK SOURCE, TARGET DEVICE COMPATIBILITY
859 MOV DX, FINE ;GUESS, ALL WILL BE OK
860 ; DX MAY BE CHANGED TO REFLECT ERROR
861 CMP DS_deviceType, DRV_720 ;0 - 48 TPI, 5.25", 96 TPI,
862 ; 5.25", 2 - 720kb, 3.5"
863; $IF E ;WILL ONLY ALLOW DISKCOPY BETWEEN ;AC000;
864 JNE $$IF36
865 ; 720KB, 3.5 SOURCE, TARGET
866
867 CMP DT_deviceType, DRV_720 ;target = 720KB also?
868; $IF NE ; ;AC000;
869 JE $$IF37
870 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ;AC000;
871; $ENDIF ; ;AC000;
872$$IF37:
873; $ELSE ;SINCE SOURCE NOT 720 ;AC000;
874 JMP SHORT $$EN36
875$$IF36:
876 CMP DT_deviceType, DRV_720 ;SOURCE IS NOT 720kb,
877 ; IS TARGET 720?
878; $IF E ;IF SO, THEN ;AC000;
879 JNE $$IF40
880 ;DDT IS NOT COMPATIBLE
881 MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000;
882; $ENDIF ; ;AC000;
883$$IF40:
884; $ENDIF ; ;AC000;
885$$EN36:
886; $ELSE ;SINCE SOURCE IS FIXED DISK, ERROR ;AC000;
887 JMP SHORT $$EN35
888$$IF35:
889 MOV DX, OFFSET MSGNUM_INVALID_DRV ;ISSUE BAD DRV MSG ;AC000;
890; $ENDIF ; ;AC000;
891$$EN35:
892 POP AX
893 RET
894
895DISKETTE_DRV_TYPE ENDP
896 HEADER <CHECK_REDIRECTION - IS DEVICE REDIRECTED?> ; ;AN000;
897;******************************************************************************
898; SUBROUTINE NAME : CHECK_REDIRECTION FIND OUT IF DEVICE IS REDIRECTED *
899; IF IT IS, GENERATE ERROR MSG & EXIT *
900; INPUT : BL - DRIVE TO BE TESTED *
901; : AL : CURRENT DEFAULT DRIV *
902; *
903; OUTPUT : DX = LOCAL_DRV (-1) *
904; = DIRECTED ( ERROR MSG OFFSET) *
905; = INVALID_DRIVE (ERROR MSG OFFSET) *
906;******************************************************************************
907CHECK_REDIRECTION PROC NEAR
908
909 PUSH AX ;SAVE REGISTERS
910 PUSH BX
911 PUSH CX
912
913 MOV CX,DX ;SAVE RET TEMPORARILY
914 MOV AH,IOCTL_FUNC ;GET IOCTL FUNTION &
915 MOV AL,REDIRECTED_FUNC ;IOCTL SUB-FUNCTION ******CHECK***
916
917 INT 21H ;AND GO FIND OUT IF IT'S LOCAL
918; $IF C
919 JNC $$IF45
920 MOV CX,OFFSET MSGNUM_INVALID_DRV ;REDIR INVALID ;AC000;
921
922; $ELSE
923 JMP SHORT $$EN45
924$$IF45:
925 TEST DX,REMOTE_DRV ;IF DRIVE IS REDIRECTED
926; $IF NZ
927 JZ $$IF47
928
929 MOV CX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000;
930; $ENDIF
931$$IF47:
932; $ENDIF
933$$EN45:
934 MOV DX,CX ;GET ERROR MSG @
935
936 POP CX ;RESTORE REGISTERS
937 POP BX
938 POP AX
939 RET ;RETURN TO CALLER
940CHECK_REDIRECTION ENDP
941 HEADER <BUFFER_SIZE - FINDS START AND END OF BUFFER> ; ;AN000;
942;******************************************************************************
943; SUBROUTINE NAME : BUFFER_SIZE DETERMINES WHERE BUFFER STARTS & ENDS *
944; INPUT : NONE *
945; *
946; OUTPUT : BUFFER_BEGIN ADDRESS *
947; : BUFFER_END ADDRESS *
948;******************************************************************************
949BUFFER_SIZE PROC NEAR
950
951
952 PUSH AX ;SAVE REGISTERS
953 PUSH BX
954 PUSH CX
955 MOV BX, offset init ;GET ADDR OF INIT + 1024 AS
956 ; A START OF BUFFER
957 add bx, 1024 ;(OFFSET FROM CS, IN BYTES)
958 MOV CL,4 ;CONVERT OFFSET INTO SEGMT BY DIVIDING
959 SHR BX,CL ;IT BY 16
960
961 MOV AX,CS ;CS + OFFSET => INIT+1024@ IN SEGMENT
962 ADD BX,AX ;WHERE BUFFER CAN START
963
964 ;NEED TO START AT A NEW SECTOR ==>
965 AND BL,CLEAR_SEGMENT ;TRUNCATE TO PREVIOUS 512 BYTE BOUNDRY
966 ;(GET PREVIOUS SECTOR NUMBER)
967 ADD BX,20H ;THEN, ADVANCE TO THE BEGINNING OF
968 ;NEXT SECTOR (SINCE PART OF PREVIOUS
969 ;SECTOR WAS USED)
970
971 MOV BUFFER_BEGIN,BX ;SAVE OUR BUFFER START SEGMENT ADDR
972 ;(AT THE BEGINNING OF A SECTOR WITH
973 ;SEGMENT BITS CLEARED)
974
975 MOV BX,DS:TWO ;GET ADDR WHERE BUFFER ENDS
976 MOV BUFFER_END,BX ;(TOP OF MEMORY, OFFSET 2 IN PSP)
977
978 POP CX ;RESTORE REGISTERS
979 POP BX
980 POP AX
981 RET ;RETURN TO CALLER
982BUFFER_SIZE ENDP
983 HEADER <SETUP_CTRL_BREAK - SETUP THE CTRL-BREAK VECTOR> ; ;AN000;
984;******************************************************************************
985SETUP_CTRL_BREAK PROC NEAR ;SETUP CTRL-BREAK VECTOR
986;******************************************************************************
987 PUSH AX
988 PUSH BX
989 PUSH DX
990 PUSH ES
991
992 MOV AX,SET_CTL_BREAK_VECT ;SET THE CTRL-BREAK VECTOR
993 MOV DX,OFFSET MAIN_EXIT
994 INT 21H
995
996 POP ES
997 POP DX
998 POP BX
999 POP AX
1000 RET
1001
1002SETUP_CTRL_BREAK ENDP
1003 HEADER <CHECK_SERVER - IS SERVER OR REDIRECTOR LOADED?> ; ;AN000;
1004;******************************************************************************
1005CHECK_SERVER PROC NEAR ;SEE IF SERVER OR REDIRECTOR IS IN++
1006;
1007; INPUT: BL = DRIVE NUMBER (1=A,2=B ETC....)
1008;******************************************************************************
1009 MOV AH,0 ;SEE IF SERVER LOADED
1010 INT SERVER
1011 CMP AH,0
1012; $IF E
1013 JNE $$IF50
1014 MOV DX,FINE
1015; $ELSE
1016 JMP SHORT $$EN50
1017$$IF50:
1018 DEC BL
1019 ADD BL,"A" ;CONVERT TO ASCII DRIVE LETTER
1020 MOV ASCII_DRIVE_LETTER,BL ;PUT IN ASCIIZ STRING
1021 MOV SI,OFFSET ASCII_DRIVE_LETTER
1022 MOV AH,SHARED
1023 CLC
1024 INT SERVER
1025; $IF C
1026 JNC $$IF52
1027 MOV DX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000;
1028; $ELSE
1029 JMP SHORT $$EN52
1030$$IF52:
1031 MOV DX,FINE
1032; $ENDIF
1033$$EN52:
1034; $ENDIF
1035$$EN50:
1036 RET
1037CHECK_SERVER ENDP
1038
1039COPYINIT_END LABEL NEAR
1040 PUBLIC COPYINIT_END
1041
1042 PATHLABL COPYINIT ;AN015;
1043
1044CSEG ENDS
1045 END
1046 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC b/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC
new file mode 100644
index 0000000..2cb7622
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC
@@ -0,0 +1,269 @@
1;:util DISKCOPY ;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;:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version"
18;;
19;:def 2 CR,LF
20;
21;:use 3 PARSE10 ;CR,LF,"Invalid parameter",CR,LF
22;
23;:def 4 "Do not specify filename(s)",CR,LF
24;"Command Format: DISKCOPY d: d: [/1]",CR,LF
25;;
26;:def 5 CR,LF,"Invalid drive specification",CR,LF
27;"Specified drive does not exist",CR,LF
28;"or is non-removable",CR,LF
29;
30;:def 6 CR,LF,"Cannot DISKCOPY to or from",CR,LF
31;"a network drive",CR,LF
32;
33;:def 7 CR,LF,"Formatting while copying",CR,LF
34;
35;:def 8 CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF
36;
37;:def 9 CR,LF,"Insert TARGET diskette in drive %1:",CR,LF
38;
39;:def 10 "Make sure a diskette is inserted into",CR,LF
40;"the drive and the door is closed",CR,LF
41;
42;:def 11 CR,LF,"Target diskette may be unusable",CR,LF
43;
44;:def 12 CR,LF,"Target diskette unusable",CR,LF
45;
46;:use 13 EXTEND21 ;CR,LF,Drive not ready",CR,LF
47;
48;:use 14 EXTEND19 ;CR,LF,"Attempt to write to write-protected diskette",CR,LF
49;
50;:use 15 COMMON28 ;CR,LF,"Press any key to continue . . .",CR,LF
51;
52;:def 16 CR,LF,"Copy another diskette (Y/N)? "
53;
54;:def 17 CR,LF,"Copying %1 tracks",CR,LF
55;"%2 Sectors/Track, %3 Side(s)",CR,LF
56;
57;:def 18 CR,LF,"Drive types or diskette types",CR,LF
58;"not compatible",CR,LF
59;
60;:def 19 CR,LF,"Unrecoverable read error on drive %1",CR,LF
61;"Side %2, track %3",CR,LF
62;
63;:def 20 CR,LF,"Unrecoverable write error on drive %1",CR,LF
64;"Side %2, track %3",CR,LF
65;
66;:def 21 CR,LF,"Copy process ended",CR,LF
67;
68;:def 22 CR,LF,"SOURCE diskette bad or incompatible"
69;
70;:def 23 CR,LF,"TARGET diskette bad or incompatible"
71;
72;:use 25 EXTEND8 ;CR,LF,"Insufficient memory",CR,LF
73;
74;:use 26 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF
75;
76;:end
77; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
78 IF1 ;AN000;
79 %OUT COMPONENT=DISKCOPY, MODULE=DCOPYMS.INC... ;AN000;
80 ENDIF ;AN000;
81; $SALUT (0,13,18,22) ; ;AN000;
82;THIS MODULE IS INCLUDED IN DCOPYSM.SAL.
83; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
84 HEADER <MESSAGE DESCRIPTORS FOR SPECIFIC MESSAGES> ;AN000;
85
86FOUR_SUBS EQU 4 ;AN000;FOUR VARIABLES IN ONE MSG
87PC_ID_4 EQU 4 ;AN000;IDENTIFIES FOURTH REPLACEMENT PARM
88LETTER_A EQU "A" ;AN000;DEFAULT DRIVE ID
89PAD_0 EQU "0" ;AN001;PAD CHAR FOR NUMERIC FIXED LEN FIELD
90FILL_OFF EQU 0 ;AN000;TO BE FILLED IN WITH OFFSET TO DATA
91FILL_SEG EQU 0 ;AN000;TO BE FILLED IN WITH THE COMMON SEG ID
92 ; SINCE A .COM FILE CANNOT HAVE
93 ; SEGMENT FIXUP RECORDS
94
95; DOS FUNCTIONS REFERENCED:
96CLEAR_BUF EQU 0C0H ;AN007;CLEAR KEYBOARD BUFFER BEFORE INPUT
97KEY_IN EQU 08H ;AN000;WAIT FOR STD INPUT, NO ECHO
98 ;OUTPUT: AL = CHAR FROM KEYBOARD
99 ;CTL-BREAK IS CHECKED FOR
100
101KEY_IN_ECHO EQU 01H ;AN000;WAIT FOR STD INPUT, ECHO RESPONSE
102 ;OUTPUT: AL = CHAR FROM KEYBOARD
103 ;CTL-BREAK IS CHECKED FOR
104
105SUBLIST_PARSE SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_0,SF_BITS <SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1,PAD_BLK> ;AN003;
106 PUBLIC SUBLIST_PARSE ;AN003;
107
108; THE NEXT GROUP ARE ADDITIONAL CLASS "A" MESSAGES
109; SPECIFICALLY DEFINED FOR THE DISKCOPY UTILITY
110
111 ;CR,LF
112MSGNUM_CR_LF MSG_DESC <2> ;AN000;
113 PUBLIC MSGNUM_CR_LF ;AN000;
114; = = = = = = = = = = = = = = = =
115 ;CR,LF,"Invalid parameter",CR,LF
116MSGNUM_INVALID_PARM MSG_DESC <3> ;AN000;
117 PUBLIC MSGNUM_INVALID_PARM ;AN000;
118; = = = = = = = = = = = = = = = =
119 ; "Do not specify filename(s)",CR,LF
120 ; "Command Format: DISKCOPY d: d: [/1]",CR,LF
121MSGNUM_INVALID_PARM2 MSG_DESC <4> ;AN000;
122 PUBLIC MSGNUM_INVALID_PARM2 ;AN000;
123; = = = = = = = = = = = = = = = =
124 ;:def 5 CR,LF,"Invalid drive specification",CR,LF
125 ;"Specified drive does not exist",CR,LF
126 ;"or is non-removable",CR,LF
127MSGNUM_INVALID_DRV MSG_DESC <5> ;AN000;
128 PUBLIC MSGNUM_INVALID_DRV ;AN000;
129; = = = = = = = = = = = = = = = =
130 ;CR,LF,"Cannot DISKCOPY to or from",CR,LF
131 ;"a network drive",CR,LF
132MSGNUM_DRV_REDIRECTED MSG_DESC <6> ;AN000;
133 PUBLIC MSGNUM_DRV_REDIRECTED ;AN000;
134; = = = = = = = = = = = = = = = =
135 ;CR,LF,"Formatting while copying",CR,LF
136MSGNUM_FORMATTING MSG_DESC <7> ;AN000;
137 PUBLIC MSGNUM_FORMATTING ;AN000;
138; = = = = = = = = = = = = = = = =
139 ;CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF
140MSGNUM_LOAD_SOURCE MSG_DESC <8,,SUBLIST_8,ONE_SUBS> ;AN000;
141 PUBLIC MSGNUM_LOAD_SOURCE ;AN000;
142
143SUBLIST_8 SUBLIST <,,ASCII_DRV1_ID,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_CH,SF_CHAR>,MAX_0,MIN_1> ;AN000;
144 PUBLIC SUBLIST_8 ;AN000;
145
146ASCII_DRV1_ID DB LETTER_A - BYTE;AN000;
147 PUBLIC ASCII_DRV1_ID ;AN000;
148; = = = = = = = = = = = = = = = =
149 ;CR,LF,"Insert TARGET diskette in drive %1:",CR,LF
150MSGNUM_LOAD_TARGET MSG_DESC <9,,SUBLIST_9,ONE_SUBS> ;AN000;
151 PUBLIC MSGNUM_LOAD_TARGET ;AN000;
152
153SUBLIST_9 SUBLIST <,,ASCII_DRV2_ID,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_CH,SF_CHAR>,MAX_0,MIN_1> ;AN000;
154 PUBLIC SUBLIST_9 ;AN000;
155
156ASCII_DRV2_ID DB LETTER_A - BYTE ;AN000;A:=1, B:=1, ETC
157 PUBLIC ASCII_DRV2_ID ;AN000;
158; = = = = = = = = = = = = = = = =
159 ;:def 10 "Make sure a diskette is inserted into",CR,LF
160 ;"the drive and the door is closed",CR,LF
161MSGNUM_CLOSE_DOOR MSG_DESC <10> ;AN004;
162 PUBLIC MSGNUM_CLOSE_DOOR ;AN004;
163; = = = = = = = = = = = = = = = =
164 ;CR,LF,"Target diskette may be unusable",CR,LF
165MSGNUM_TARGET_MB_UNUSABLE MSG_DESC <11> ;AN000;
166 PUBLIC MSGNUM_TARGET_MB_UNUSABLE ;AN000;
167; = = = = = = = = = = = = = = = =
168 ;CR,LF,"Target diskette unusable",CR,LF
169MSGNUM_TARGET_UNUSABLE MSG_DESC <12> ;AN000;
170 PUBLIC MSGNUM_TARGET_UNUSABLE ;AN000;
171; = = = = = = = = = = = = = = = =
172 ;CR,LF,"Drive not ready - %0",CR,LF
173MSGNUM_GET_READY MSG_DESC <13,,SUBLIST_13,ONE_SUBS> ;AN000;
174 PUBLIC MSGNUM_GET_READY ;AN000;
175
176SUBLIST_13 SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_0,SF_BITS<SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1> ;AN000;
177 PUBLIC SUBLIST_13 ;AN000;
178; = = = = = = = = = = = = = = = =
179 ;CR,LF,"Attempt to write to write-protected diskette",CR,LF
180MSGNUM_WRITE_PROTECT MSG_DESC <14> ;AN000;
181 PUBLIC MSGNUM_WRITE_PROTECT ;AN000;
182; = = = = = = = = = = = = = = = =
183 ;"Press any key to continue . . .",CR,LF
184MSGNUM_STRIKE MSG_DESC <15,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN)> ;AN007;
185 PUBLIC MSGNUM_STRIKE ;AN000;
186; = = = = = = = = = = = = = = = =
187 ;CR,LF,"Copy another diskette (Y/N)? "
188 ; AND READ RESPONSE TO AL
189 ; (EVENTUALLY EXPECTED IN "USER_INPUT")
190MSGNUM_COPY_ANOTHER MSG_DESC <16,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN_ECHO)> ;AN007;
191 PUBLIC MSGNUM_COPY_ANOTHER ;AN000;
192; = = = = = = = = = = = = = = = =
193 ;CR,LF,"Copying %1 tracks",CR,LF
194 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
195MSGNUM_COPYING MSG_DESC <17,,SUBLIST_17A,THREE_SUBS> ;AN000;
196 PUBLIC MSGNUM_COPYING ;AN000;
197
198SUBLIST_17A SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
199SUBLIST_17B SUBLIST <,,MSG_SECTRK,FILL_SEG,PC_ID_2,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
200SUBLIST_17C SUBLIST <,,MSG_SIDES,FILL_SEG,PC_ID_3,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
201 PUBLIC SUBLIST_17A ;AN000;
202 PUBLIC SUBLIST_17B ;AN000;
203 PUBLIC SUBLIST_17C ;AN000;
204
205MSG_TRACKS DW 0 ;AN000;NUMBER OF TRACKS
206MSG_SECTRK DW 0 ;AN000;NUMBER OF SECTORS PER TRACK
207MSG_SIDES DW 0 ;AN000;NUMBER OF SIDES
208 PUBLIC MSG_TRACKS ;AN000;
209 PUBLIC MSG_SECTRK ;AN000;
210 PUBLIC MSG_SIDES ;AN000;
211; = = = = = = = = = = = = = = = =
212 ;CR,LF,"Drive types or diskette types",CR,LF
213 ;"not compatible",CR,LF
214MSGNUM_NOT_COMPATIBLE MSG_DESC <18> ;AN000;
215 PUBLIC MSGNUM_NOT_COMPATIBLE ;AN000;
216; = = = = = = = = = = = = = = = =
217 ;CR,LF,"Unrecoverable read error on drive %1",CR,LF
218 ;"Side %2, track %3",CR,LF
219MSGNUM_HARD_ERROR_READ MSG_DESC <19,,SUBLIST_19C,THREE_SUBS> ;AN000;
220 PUBLIC MSGNUM_HARD_ERROR_READ ;AN000;
221
222 ;CR,LF,"Unrecoverable write error on drive %1",CR,LF
223 ;"Side %2, track %3",CR,LF
224MSGNUM_HARD_ERROR_WRITE MSG_DESC <20,,SUBLIST_19C,THREE_SUBS> ;AN000;
225 PUBLIC MSGNUM_HARD_ERROR_WRITE ;AN000;
226
227SUBLIST_19C SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_1,SF_BITS<SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1> ;AN000;
228SUBLIST_19D SUBLIST <,,ERROR_SIDE_NUMBER,FILL_SEG,PC_ID_2,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
229SUBLIST_19E SUBLIST <,,ERROR_TRACK_NUMBER,FILL_SEG,PC_ID_3,SF_BITS<SF_LEFT,,SF_WORD,SF_UN_BD>,MAX_0,MIN_1> ;AN000;
230 PUBLIC SUBLIST_19C ;AN000;
231 PUBLIC SUBLIST_19D ;AN000;
232 PUBLIC SUBLIST_19E ;AN000;
233
234DRIVE_LETTER DB LETTER_A,":",NULL ;AN000;
235 PUBLIC DRIVE_LETTER ;AN000;
236
237ERROR_SIDE_NUMBER DW ? ;AN000;
238 PUBLIC ERROR_SIDE_NUMBER ;AN000;
239
240ERROR_TRACK_NUMBER DW ? ;AN000;
241 PUBLIC ERROR_TRACK_NUMBER ;AN000;
242; = = = = = = = = = = = = = = = =
243 ;CR,LF,"Copy process ended",CR,LF
244MSGNUM_FATAL_ERROR MSG_DESC <21> ;AN000;
245 PUBLIC MSGNUM_FATAL_ERROR ;AN000;
246; = = = = = = = = = = = = = = = =
247 ;CR,LF,"SOURCE diskette bad or incompatible"
248MSGNUM_BAD_SOURCE MSG_DESC <22> ;AN000;
249 PUBLIC MSGNUM_BAD_SOURCE ;AN000;
250
251; = = = = = = = = = = = = = = = =
252 ;CR,LF,"TARGET diskette bad or incompatible"
253MSGNUM_BAD_TARGET MSG_DESC <23> ;AN000;
254 PUBLIC MSGNUM_BAD_TARGET ;AN000;
255; = = = = = = = = = = = = = = = =
256 ;CR,LF,"Insufficient memory",CR,LF
257MSGNUM_UNSUF_MEMORY MSG_DESC <25> ;AN000;
258 PUBLIC MSGNUM_UNSUF_MEMORY ;AN000;
259; = = = = = = = = = = = = = = = =
260 ;"Volume Serial Number is %1-%2"
261MSGNUM_SERNO MSG_DESC <26,,SUBLIST_26A,TWO_SUBS> ;AN001;
262 PUBLIC MSGNUM_SERNO ;AN001;
263
264SUBLIST_26A SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS<SF_RIGHT,,SF_WORD,SF_UN_BH>,DWORD,DWORD,PAD_0> ;AN001;
265SUBLIST_26B SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_2,SF_BITS<SF_RIGHT,,SF_WORD,SF_UN_BH>,DWORD,DWORD,PAD_0> ;AN001;
266 PUBLIC SUBLIST_26A,SUBLIST_26B ;AN001;
267; = = = = = = = = = = = = = = = =
268;end of DCOPYMS.INC
269 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM
new file mode 100644
index 0000000..344b8c4
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM
@@ -0,0 +1,139 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOPYP.SAL - DISKCOPY SYSTEM COMMAND LINE PARSER
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOPYP.SAL
5;
6; DESCRIPTIVE NAME: Include the DOS system PARSER in the SEGMENT
7; configuration expected by the modules of DISKCOPY.
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 DCOPYP,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; DISKCOPY.SAL.
85;
86;PROGRAM AUTHOR: DOS 4.00 EMK
87;
88;****************** END OF SPECIFICATIONS *****************************
89 IF1 ;AN000;
90 %OUT COMPONENT=DISKCOPY, MODULE=DCOPYP.SAL... ;AN000;
91 ENDIF ;AN000;
92; = = = = = = = = = = = =
93 HEADER <MACRO DEFINITION> ;AN000;
94; = = = = = = = = = = = =
95 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
96; = = = = = = = = = = = =
97HEADER MACRO TEXT ;;AN000;
98.XLIST ;AN000;
99 SUBTTL TEXT ;AN000;
100.LIST ;AN000;
101 PAGE ;;AN000;
102 ENDM ;;AN000;
103
104; = = = = = = = = = = = =
105 HEADER <SYSPARSE - SYSTEM COMMAND LINE PARSER> ;AN000;
106CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
107 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;
108
109;DISKCOPY INPUT PARMS EXPECTED:
110; [D: [d:]] [/1]
111
112 PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT
113
114FARSW EQU 0 ;AN000;CALL THE PARSER BY NEAR CALL
115DATESW EQU 0 ;AN000;SUPPRESS DATE CHECKING
116TIMESW EQU 0 ;AN000;SUPPRESS TIME CHECKING
117FILESW EQU 0 ;AN000;SUPPRESS CHECK FILE SPECIFICATION
118CAPSW EQU 1 ;AN000;DO USE FILE TABLE CAPS
119CMPXSW EQU 0 ;AN000;SUPPRESS CHECKING COMPLEX LIST
120DRVSW EQU 1 ;AN000;DO SUPPORT DRIVE ONLY FORMAT
121QUSSW EQU 0 ;AN000;SUPPRESS SUPPORT OF QUOTED STRING FORMAT
122NUMSW EQU 0 ;AN000;SUPPRESS CHECKING NUMERIC VALUE
123KEYSW EQU 0 ;AN000;SUPPRESS KEYWORD SUPPORT
124SWSW EQU 1 ;AN000;DO SUPPORT SWITCHES
125VAL1SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 1
126VAL2SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 2
127VAL3SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 3
128INCSW EQU 0 ;AN000;DO NOT INCLUDE PSDATA.INC
129BASESW EQU 1 ;AN014;SPECIFY, PSDATA POINTED TO BY "DS"
130
131 INCLUDE PSDATA.INC ;AN015;
132
133 PATHLABL DCOPYP ;AN015;
134 INCLUDE PARSE.ASM ;AN000;
135 PATHLABL DCOPYP ;AN015;
136
137CSEG ENDS ;AN000;
138 END ;AN000;
139 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM
new file mode 100644
index 0000000..0b74cec
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM
@@ -0,0 +1,413 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOPYPAR.SAL - LOOK AT COMMAND LINE PARMS
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOPYPAR.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 DISKCOPY. 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] DISKCOPY [d: [d:]][/1]
21;
22; WHERE
23; [d:][path] - Path where the DISKCOPY command resides.
24;
25; [d:] - To specify the Source drive
26;
27; [d:] - To specify the Destination drive
28;
29; [/1] - To copy only the first side of the diskette,
30; regardless of the diskette or drive type.
31;
32; Upon entry to PARSER in this module,
33; "CURRENT_PARM" = offset to start of parm text in command string
34; "ORDINAL" = initialized to zero
35; PSP+81H = text of DOS command line parms string
36
37; EXIT-NORMAL:
38; "SOURCE_DRIVE" = CHAR OF FIRST DRIVE ID SPECIFIED, BLANK IF NONE
39; "TARGET_DRIVE" = CHAR OF SECOND DRIVE ID IF BOTH SPECIFIED, BLANK
40; IF NONE OR ONLY ONE SPECIFIED
41; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED.
42
43; EXIT-ERROR:
44; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
45
46; INTERNAL REFERENCES:
47; ROUTINES:
48; PARSER:NEAR Call the system Parser to decode command line
49; PARSE_ERROR:NEAR Display the appropriate Parse error message.
50
51; DATA AREAS:
52; The several parameter control blocks, defined by the System
53; PARSER interface, defining the DISKCOPY parameters.
54
55; EXTERNAL REFERENCES:
56; ROUTINES:
57; SENDMSG:NEAR Uses Msg Descriptor to drive message handler.
58; SYSPARSE:NEAR System Command Line Common Parser.
59;
60; DATA AREAS:
61; EXITFL:BYTE Errorlevel return code.
62; MSGNUM_PARSE:WORD Message descriptor for all parse errors.
63; USER_OPTION:BYTE /1 parm indicator
64; SOURCE_DRIVE:BYTE character of first specified drive
65; TARGET_DRIVE:BYTE character of second specified drive
66;
67; NOTES:
68; This module should be processed with the SALUT preprocessor
69; with the re-alignment not requested, as:
70;
71; SALUT DCOPYPAR,NUL
72;
73; To assemble these modules, the alphabetical or sequential
74; ordering of segments may be used.
75;
76; For LINK instructions, refer to the PROLOG of the main module,
77; DISKCOPY.SAL.
78;
79;PROGRAM AUTHOR: DOS 4.00 EMK
80;****************** END OF SPECIFICATIONS *****************************
81 IF1 ;AN000;
82 %OUT COMPONENT=DISKCOPY, MODULE=DCOPYPAR.SAL... ;AN000;
83 ENDIF ;AN000;
84; = = = = = = = = = = = =
85 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
86; = = = = = = = = = = = =
87HEADER MACRO TEXT ;;AN000;
88.XLIST ;;AN000;
89 SUBTTL TEXT ;;AN000;
90.LIST ;;AN000;
91 PAGE ;;AN000;
92 ENDM ;;AN000;
93; = = = = = = = = = = = =
94; $SALUT (4,23,28,36) ;AN000;
95; LOCAL EQUATES
96
97FALSE EQU 0 ;AN000;RETURN VALUES FOR
98TRUE EQU NOT FALSE ;AN000; /1 SWITCH
99CHAR_A EQU "A" ;AN000;ASCII VALUE OF CHARACTER "A"
100BLANK EQU " " ;AN001;
101NUL EQU 0 ;AN003;
102; = = = = = = = = = = = =
103; EXIT CODES FROM SYSPARSE (WHEN CY=0)
104
105SYSPRM_EX_OK EQU 0 ;AN000; no error
106SYSPRM_EX_MANY EQU 1 ;AN000; too many operands
107SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing
108SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided
109SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided
110SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified
111SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided
112SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided
113SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error
114SYSPRM_EX_EOL EQU -1 ;AN000; end of command line
115; = = = = = = = = = = = =
116 HEADER <STRUC - DEFINITIONS OF EXTERNAL CONTROL BLOCKS> ;AN000;
117PSP STRUC ;AN000;
118 DB 80H DUP (?) ;AN000;SKIP OVER FIRST HALF OF PSP
119PSP_PARMLEN DB ? ;AN000;NUMBER OF BYTES IN DOS COMMAND LINE
120PSP_COMMAND DB 127 DUP(?) ;AN000;TEXT OF DOS COMMAND LINE
121PSP ENDS ;AN000;
122
123MSG_DESC STRUC ;AN003;
124MSG_NUM DW ? ;AN003;MESSAGE NUMBER (TO AX)
125MSG_HANDLE DW ? ;AN003;HANDLE OF OUTPUT DEVICE (TO BX)
126MSG_SUBLIST DW ? ;AN003;POINTER TO SUBLIST (TO SI)
127MSG_COUNT DW ? ;AN003;SUBSTITUTION COUNT (TO CX)
128MSG_CLASS DW ? ;AN003;MESSAGE CLASS (IN HIGH BYTE, TO DH)
129 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL)
130MSG_DESC ENDS ;AN003;
131
132ONE_SUBS EQU 1 ;AN003;NUMBER OF VARIABLES
133
134SUBLIST STRUC ;AN000;
135SUB_SIZE DB ? ;AN003;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
136SUB_RES DB ? ;AN003;RESERVED
137 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD
138SUB_VALUE DW ? ;AN003;TIME, DATE, OR PTR TO DATA ITEM
139SUB_VALUE_SEG DW ? ;AN003;SEG ID OF PTR
140 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME
141 ; IF THIS IS A .COM FILE)
142SUB_ID DB ? ;AN003;N OF %N
143SUB_FLAGS DB ? ;AN003;DATA TYPE FLAGS
144SUB_MAX_WIDTH DB ? ;AN003;MAXIMUM FIELD WIDTH (0=UNLIMITED)
145SUB_MIN_WIDTH DB ? ;AN003;MINIMUM FIELD WIDTH
146SUB_PAD_CHAR DB ? ;AN003;CHARACTER FOR PAD FIELD
147 ; CAN BE " ", "0" OR ",".
148 ; "," CAUSES INSERTION OF THE ACTIVE
149 ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS.
150SUBLIST ENDS ;AN003;
151
152; = = = = = = = = = = = =
153 HEADER <PARSING WORKAREAS> ;AN000;
154; $SALUT (4,14,19,36) ;AN000;
155 EXTRN EXPAR:ABS ;AN000;ERRORLEVEL VALUE FOR BAD PARMS
156 EXTRN FINE:ABS ;AN000;RETURN STATUS INDICATOR
157CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
158 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;
159
160 EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR
161 EXTRN SYSPARSE:NEAR ;AN000;SYSTEM COMMAND LINE PARSER
162
163 EXTRN EXITFL:BYTE ;AN000;ERRORLEVEL RETURN CODE
164
165 EXTRN SOURCE_DRIVE:BYTE ;AN000;FIRST DRIVE LETTER SPECIFIED IN PARMS
166 EXTRN TARGET_DRIVE:BYTE ;AN000;SECOND DRIVE LETTER SPECIFIED
167
168 EXTRN USER_OPTION:BYTE ;AN000;NO OPTION (-1) /1 (1), INVALID (9)
169NO_OPTION EQU -1 ;AN000;NO OPTION "/1" SPECIFIED
170OPTION_1 EQU 1 ;AN000;OPTION "/1" SPECIFIED
171 EXTRN MSGNUM_PARSE:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS
172 EXTRN MSGNUM_INVALID_PARM2:WORD ;AN005;HELP INFO
173 EXTRN SUBLIST_PARSE:WORD ;AN003;POINTS TO INVALID PARM
174; = = = = = = = = = = = =
175
176CURRENT_PARM DW 81H ;AN000;POINTER INTO COMMAND OF NEXT OPERAND
177 PUBLIC CURRENT_PARM ;AN000;
178
179ORDINAL DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE
180 PUBLIC ORDINAL ;AN000;
181
182; = = = = = = = = = = = =
183 HEADER <DOS COMMAND LINE PARSER CONTROL BLOCKS> ;AN000;
184
185;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER
186
187 PUBLIC PARMS ;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE
188PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK
189 DW PARMSX ;AN000;POINTER TO PARMS EXTENSION
190 DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2)
191 ; NEXT LIST WOULD BE EXTRA DELIM LIST
192 ; (,& WHITESPACE ALWAYS)
193 ; NEXT LIST WOULD BE EXTRA END OF LINE LIST
194 ; (CR,LF,0 ALWAYS)
195
196;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK
197PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK
198 DB 0,2 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED
199 DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1
200 DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 2
201
202 DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED
203 DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH 1
204
205 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED
206 ; THERE IS NO CONTROL BLOCK
207 ; DEFINING KEYWORDS
208
209; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
210 HEADER <POSITIONAL PARM DESCRIPTOR BLOCK> ;AN000;
211;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL
212
213;FIRST POSITIONAL PARAMETER IS:
214; [D:] - SPECIFY THE SOURCE DRIVE.
215
216 PUBLIC CONTROL_POS ;AN000;LET LINK MAKE THIS ADDRESSABLE
217CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC,
218 ; OPTIONAL
219 DW 0101H ;AN000; CONTROLS TYPE MATCHED
220 ; SELECTED BITS: "DRIVE ONLY" AND "OPTIONAL"
221
222 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
223 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
224 ; CHECKED)
225 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
226 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
227 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
228 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
229 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
230 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
231 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
232 ; 0010H=IGNORE ":" AT END IN MATCH
233 ; 0002H=REPEATS ALLOWED
234 ; 0001H=OPTIONAL
235
236 DW 0002H ;AN000;FUNCTION_FLAGS
237 ; 0001H=CAP RESULT BY FILE TABLE
238 ; 0002H=CAP RESULT BY CHAR TABLE
239 ; 0010H=REMOVE ":" AT END
240 DW RESULT1 ;AN000; RESULT BUFFER
241 DW NOVALS ;AN000; NO VALUE LISTS
242 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
243 ; IN FOLLOWING LIST
244
245;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS
246NOVALS DB 0 ;AN000;NO VALUE DEFINITIONS
247
248;RESULTS CONTROL BLOCK FOR THE POSITIONAL PARAMETER
249RESULT1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
250 DB 6 ;AN000; TYPE RETURNED: 0=RESERVED,
251 ; 1=NUMBER, 2=LIST INDEX,
252 ; 3=STRING, 4=COMPLEX,
253 ; 5=FILESPEC, 6=DRIVE
254 ; 7=DATE, 8=TIME
255 ; 9=QUOTED STRING
256RESULT_TAG DB 0FFH ;AN000; MATCHED ITEM TAG
257 DW 0 ;AN000;POINTER TO SYNONYM
258
259RESULT_PTR1 DB ? ;AN000;DRIVE NUMBER (A=1, B=2, ETC)
260
261; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
262 HEADER <SWITCH PARM DESCRIPTOR BLOCK> ;AN000;
263;PARSER CONTROL BLOCK DEFINING THE ONLY SWITCH, OPTIONAL
264
265;THE SWITCH IS "/1", MEANING ONLY COPY FIRST SIDE.
266
267 PUBLIC CONTROL_SW ;AN000;LET LINK MAKE THIS ADDRESSABLE
268CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /1
269 DW 0001H ;AN000; CONTROLS TYPE MATCHED
270 ;SELECTED BITS: "OPTIONAL"
271 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
272 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
273 ; CHECKED)
274 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
275 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
276 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
277 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
278 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
279 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
280 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
281 ; 0010H=IGNORE ":" AT END IN MATCH
282 ; 0002H=REPEATS ALLOWED
283 ; 0001H=OPTIONAL
284
285 DW 0002H ;AN000;FUNCTION_FLAGS
286 ; 0001H=CAP RESULT BY FILE TABLE
287 ; 0002H=CAP RESULT BY CHAR TABLE
288 ; 0010H=REMOVE ":" AT END
289
290 DW RESULTSW1 ;AN000; RESULT BUFFER
291 DW NOVALS ;AN000; VALUE LISTS
292 DB 1 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
293 ; IN FOLLOWING LIST
294SW_1 DB "/1",0 ;AN000; IF n >0, SWITCH 1
295
296;RESULTS CONTROL BLOCK FOR THE SWITCHES
297RESULTSW1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
298 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
299 ; 1=NUMBER, 2=LIST INDEX,
300 ; 3=STRING, 4=COMPLEX,
301 ; 5=FILESPEC, 6=DRIVE
302 ; 7=DATE, 8=TIME
303 ; 9=QUOTED STRING
304 DB 0FFh ;AN000; MATCHED ITEM TAG
305
306 DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
307RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE
308; = = = = = = = = = = = =
309 PATHLABL DCOPYPAR ;AN015;
310 HEADER <PARSER - ASK SYSPARM TO DECODE PARAMETERS> ;AN000;
311; $SALUT (4,4,9,36) ;AN000;
312PARSER PROC NEAR ;AN000;
313 PUBLIC PARSER ;AN000;
314
315;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING
316; "ORDINAL" = COUNT OF NEXT PARM TO PARSE
317; PSP+81H = TEXT OF DOS COMMAND LINE PARMS STRING
318;OUTPUT: "SOURCE_DRIVE" = VALUE OF FIRST DRIVE ID SPECIFIED, 0 IF NONE
319; "TARGET_DRIVE" = VALUE OF SECOND DRIVE ID IF BOTH SPECIFIED, 0
320; IF NONE OR ONLY ONE SPECIFIED
321; "USER_OPTION" = "OPTION_1" IF /1 SPECIFIED, -1 IF NOT SPECIFIED
322; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR".
323; DX="FINE" IF NO ERROR, OR HAS OFFSET OF PARSE ERROR DESCRIPTOR IF PROBLEM
324; = = = = = = = = = = = =
325
326 MOV USER_OPTION, NO_OPTION ;AN000;ASSUME NO /1 IS ENTERED.
327; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE
328 JMP SHORT $$SS1
329$$DO1:
330 ;LOOKING AT RETURN CODE FROM SYSPARSE...
331 CMP AX,SYSPRM_EX_OK ;AN000;WERE THERE ANY ERRORS?
332; $EXITIF NE ;AN000;HAD A PROBLEM
333 JE $$IF1
334 CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR
335
336; $ORELSE ;AN000;SINCE NO PROBLEM, SO FAR
337 JMP SHORT $$SR1
338$$IF1:
339 MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT
340 MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT
341 MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND
342 CMP BX,OFFSET RESULT1 ;AN000;WAS POSITIONAL PARM SPECIFIED?
343; $IF E ;AN000;IF POSITIONAL PARM SPECIFIED,
344 JNE $$IF4
345 MOV SI,CX ;AN000;USE COUNT OF POSITIONALS AS INDEX
346 MOV AL,RESULT_PTR1 ;AN000;GET VALUE OF DRIVE (A=1, B=2, ETC)
347 MOV SOURCE_DRIVE-1[SI],AL ;AN000;SAVE RESPONSE VALUE
348 ;IN EITHER SOURCE_DRIVE OR TARGET_DRIVE
349 ;ACCORDING TO ORDINAL IN SI (FROM CX)
350; $ELSE ;AN000;SINCE NOT POSITIONAL PARM SPECIFIED
351 JMP SHORT $$EN4
352$$IF4:
353 MOV SW_1,BLANK ;AN001;AVOID GETTING DUPLICATE SWITCH
354 MOV USER_OPTION,OPTION_1 ;AN000;MUST HAVE BEEN THE SWITCH, /1
355; $ENDIF ;AN000;
356$$EN4:
357; $STRTSRCH ;AN000;
358$$SS1:
359 LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON
360 MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM
361 XOR DX,DX ;AN000; RESERVED, INIT TO ZERO
362 MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO
363 CALL SYSPARSE ;AN000;LOOK AT DOS PARMS
364 ; AX=EXIT CODE
365 ; BL=TERMINATED DELIMETER CODE
366 ; CX=NEW OPERAND ORDINAL
367 ; SI=SET TO PAST SCANNED OPERAND
368 ; DX=SELECTED RESULT BUFFER
369 CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS?
370 ;IF NOT, LOOP BACK AND FIND OUT
371 ; WHAT THAT PARM IS
372; $ENDLOOP E ;AN000;END OF LIST
373 JNE $$DO1
374 MOV DX,FINE ;AN000;REPORT THAT PARSER WENT OK
375; $ENDSRCH ;AN000;FINISHED WITH DOS COMMAND LINE
376$$SR1:
377 RET ;AN000;RETURN TO CALLER
378PARSER ENDP ;AN000;
379; = = = = = = = = = = = =
380 HEADER <PARSE_ERROR - DISPLAY REASON FOR PARSE ERROR> ;AN000;
381PARSE_ERROR PROC NEAR ;AN000;
382;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE.
383; "CURRENT_PARM" - OFFSET TO WHERE THE BAD PARM STARTED
384;OUTPUT: APPROPRIATE ERROR MESSAGE IS PREPARED FOR DISPLAY.
385; DX IS SET TO OFFSET OF PARSE ERROR DESCRIPTOR.
386; = = = = = = = = = = = =
387
388 MOV MSGNUM_PARSE,AX ;AN000;PASS MESSAGE NUMBER TO DESCRIPTOR
389 MOV EXITFL,EXPAR ;AN000;ERRORLEVEL CODE TO "PARM ERROR"
390 MOV AX,CURRENT_PARM ;AN003;GET POINTER TO START OF BAD PARM
391 CMP SI,AX ;AN003;HAS THE INDEX TO COMMAND LINE MOVED?
392; $IF NE ;AN003;YES, THERE IS A FAULTY PARM
393 JE $$IF10
394 MOV BYTE PTR [SI],NUL ;AN003;DELIMIT THE BAD PARM
395 MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM
396
397 MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN003;POINT TO SUBLIST
398 MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN003;SET COUNT OF SUBLISTS TO ONE
399; $ENDIF ;AN003;INDEX MOVED?
400$$IF10:
401 MOV DI,OFFSET MSGNUM_PARSE ;AC005;PASS BACK OFFSET TO PARSE ERR DESCRIPTOR
402 CALL SENDMSG ;AN005;DISPLAY THE ERROR MESSAGE
403
404 ; "Do not specify filename(s)",CR,LF
405 ; "Command Format: DISKCOPY d: d: [/1]",CR,LF
406 MOV DX,OFFSET MSGNUM_INVALID_PARM2 ;AN005;DISPLAY HELP INFO
407 RET ;AN000;RETURN TO CALLER
408PARSE_ERROR ENDP ;AN000;
409; = = = = = = = = = = = =
410 PATHLABL DCOPYPAR ;AN015;
411CSEG ENDS ;AN000;
412 END ;AN000;
413 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM
new file mode 100644
index 0000000..035fa73
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM
@@ -0,0 +1,153 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE DCOPYSM.SAL - DISKCOPY SYSTEM MESSAGES
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DCOPYSM.SAL
5
6; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT
7; configuration expected by the modules of DISKCOPY.
8
9;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a
10; part of the DISKCOPY 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 "DCOPYMS.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 DCOPYSM,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; DISKCOPY.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=DISKCOPY, MODULE=DCOPYSM.SAL... ;AN000;
99 ENDIF ;AN000;
100; = = = = = = = = = = = =
101 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
102; = = = = = = = = = = = =
103HEADER MACRO TEXT ;;AN000;
104.XLIST ;;AN000;
105 SUBTTL TEXT ;;AN000;
106.LIST ;;AN000;
107 PAGE ;;AN000;
108 ENDM ;;AN000;
109; = = = = = = = = = = = =
110 INCLUDE SYSMSG.INC ;AN000;PERMIT SYSTEM MESSAGE HANDLER DEFINITION
111 MSG_UTILNAME <DISKCOPY> ;AN000;IDENTIFY THE COMPONENT
112; = = = = = = = = = = = =
113 HEADER <DEFINITION OF MESSAGES> ;AN000;
114; $SALUT (4,12,18,36) ;AN000;
115CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
116 ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER
117 ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER
118 ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER
119 ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER
120
121;(deleted ;AN010;) PUBLIC COPYRIGHT ;
122;(deleted ;AN010;) COPYRIGHT DB "MS DOS DISKCOPY Utility "
123;(deleted ;AN010;) INCLUDE COPYRIGH.INC ;(this is now being done my MSG_SERVICES)
124 HEADER <MESSAGE HANDLER CONTROL BLOCKS> ;AN000;
125 INCLUDE MSGHAN.INC ;AN000;DEFINE THE MESSAGE HANDLER CONTROL BLOCKS
126 INCLUDE DCOPYMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS
127 HEADER <MESSAGE DATA AREAS> ;AN000;
128 MSG_SERVICES <MSGDATA> ;AN000;WORKAREAS FOR SYSTEM MESSAGE HANDLER
129; = = = = = = = = = = = =
130 HEADER <SYSTEM MESSAGE HANDLER> ;AN000;
131 PUBLIC SYSLOADMSG ;AN000;
132 PUBLIC SYSDISPMSG ;AN000;
133
134 MSG_SERVICES <DISKCOPY.CL1,DISKCOPY.CL2,DISKCOPY.CLA> ;AN000;MSG TEXT
135
136 PATHLABL DCOPYSM ;AN015;
137 ;DEFAULT=CHECK DOS VERSION
138 ;DEFAULT=NEARmsg
139 ;DEFAULT=INPUTmsg
140 ;DEFAULT=NUMmsg
141 ;DEFAULT=NO TIMEmsg
142 ;DEFAULT=NO DATEmsg
143; MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg>
144.xlist ;AN000;
145.xcref ;AN000;
146 MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg> ;AN000;
147.cref ;AN000;
148.list ;AN000;
149; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
150 PATHLABL DCOPYSM ;AN015;
151CSEG ENDS ;AN000;
152 END ;AN000;
153 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC b/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC
new file mode 100644
index 0000000..da247a5
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC
@@ -0,0 +1,164 @@
1 IF1 ;AN000;
2 %OUT COMPONENT=DISKCOPY, INCLUDING DCPYMACR.INC...;AN000;
3 ENDIF ;AN000;
4;***************************************************************************;
5; MACRO DEFINITION ;
6;***************************************************************************;
7
8HEADER MACRO TEXT ;AN000;
9.XLIST ;AN000;
10 SUBTTL &TEXT ;AN000;
11.LIST ;AN000;
12 PAGE ;AN000;
13 ENDM ;AN000;
14; = = = = = = = = =
15; $SALUT (0,36,40,44)
16DOSCALL MACRO FUNC,SUBFUNC ;;AN000;
17 IFNB <FUNC> ;;AN000;IS THERE ANY PARMS AT ALL?
18 IFNB <SUBFUNC> ;;AN000;
19 MOV AX,(FUNC SHL 8)+SUBFUNC ;;AN000;FUNC TO AH,SUBFUNC TO AL
20 ELSE ;;AN000;SINCE THERE IS NO SUBFUNC
21 MOV AH,FUNC ;;AN000;
22 ENDIF ;;AN000;
23 ENDIF ;;AN000;
24 INT 21H ;;AN000;
25 ENDM ;;AN000;
26; = = = = = = = = =
27PRINT MACRO MESSAGE;;AN000;
28 MOV DI,OFFSET MESSAGE ;;AC000;
29 CALL SENDMSG ;;AC000;
30 ENDM ;;AN000;
31; = = = = = = = = =
32; $SALUT (0,16,22,36)
33MY_TRACKLAYOUT MACRO ;AN000;
34 LOCAL CSECT_F ;AN000;
35CSECT_F DW 0 ;;AN000;# OF SECTORS IN A TRACK. Currently 18 is max.
36 ;; THE REST IS FOR FUTURE MEDIA
37 DW 1 ;;AN000;1 ST SECTOR
38 DW 512 ;;AN000;# OF BYTES
39 DW 2 ;;AN000;
40 DW 512 ;;AN000;
41 DW 3 ;;AN000;
42 DW 512 ;;AN000;
43 DW 4 ;;AN000;
44 DW 512 ;;AN000;
45 DW 5 ;;AN000;
46 DW 512 ;;AN000;
47 DW 6 ;;AN000;
48 DW 512 ;;AN000;
49 DW 7 ;;AN000;
50 DW 512 ;;AN000;
51 DW 8 ;;AN000;
52 DW 512 ;;AN000;
53 DW 9 ;;AN000;
54 DW 512 ;;AN000;
55 DW 10 ;;AN000;
56 DW 512 ;;AN000;
57 DW 11 ;;AN000;
58 DW 512 ;;AN000;
59 DW 12 ;;AN000;
60 DW 512 ;;AN000;
61 DW 13 ;;AN000;
62 DW 512 ;;AN000;
63 DW 14 ;;AN000;
64 DW 512 ;;AN000;
65 DW 15 ;;AN000;
66 DW 512 ;;AN000;
67 DW 16 ;;AN000;
68 DW 512 ;;AN000;
69 DW 17 ;;AN000;
70 DW 512 ;;AN000;
71 DW 18 ;;AN000;
72 DW 512 ;;AN000;CURRENTLY 18 SECTORS/TRACK IS MAXIMUM
73 DW 19 ;;AN000;BELOW IS FOR THE FUTURE MEDIA.
74 DW 512 ;;AN000;
75 DW 20 ;;AN000;
76 DW 512 ;;AN000;
77 DW 21 ;;AN000;
78 DW 512 ;;AN000;
79 DW 22 ;;AN000;
80 DW 512 ;;AN000;
81 DW 23 ;;AN000;
82 DW 512 ;;AN000;
83 DW 24 ;;AN000;
84 DW 512 ;;AN000;
85 DW 25 ;;AN000;
86 DW 512 ;;AN000;
87 DW 26 ;;AN000;
88 DW 512 ;;AN000;
89 DW 27 ;;AN000;
90 DW 512 ;;AN000;
91 DW 28 ;;AN000;
92 DW 512 ;;AN000;
93 DW 29 ;;AN000;
94 DW 512 ;;AN000;
95 DW 30 ;;AN000;
96 DW 512 ;;AN000;
97 DW 31 ;;AN000;
98 DW 512 ;;AN000;
99 DW 32 ;;AN000;
100 DW 512 ;;AN000;
101 DW 33 ;;AN000;
102 DW 512 ;;AN000;
103 DW 34 ;;AN000;
104 DW 512 ;;AN000;
105 DW 35 ;;AN000;
106 DW 512 ;;AN000;
107 DW 36 ;;AN000;
108 DW 512 ;;AN000;
109 DW 37 ;;AN000;
110 DW 512 ;;AN000;
111 DW 38 ;;AN000;
112 DW 512 ;;AN000;
113 DW 39 ;;AN000;
114 DW 512 ;;AN000;
115 DW 40 ;;AN000;
116 DW 512 ;;AN000;
117 DW 41 ;;AN000;
118 DW 512 ;;AN000;
119 DW 42 ;;AN000;
120 DW 512 ;;AN000;
121 DW 43 ;;AN000;
122 DW 512 ;;AN000;
123 DW 44 ;;AN000;
124 DW 512 ;;AN000;
125 DW 45 ;;AN000;
126 DW 512 ;;AN000;
127 DW 46 ;;AN000;
128 DW 512 ;;AN000;
129 DW 47 ;;AN000;
130 DW 512 ;;AN000;
131 DW 48 ;;AN000;
132 DW 512 ;;AN000;
133 DW 49 ;;AN000;
134 DW 512 ;;AN000;
135 DW 50 ;;AN000;
136 DW 512 ;;AN000;
137 DW 51 ;;AN000;
138 DW 512 ;;AN000;
139 DW 52 ;;AN000;
140 DW 512 ;;AN000;
141 DW 53 ;;AN000;
142 DW 512 ;;AN000;
143 DW 54 ;;AN000;
144 DW 512 ;;AN000;
145 DW 55 ;;AN000;
146 DW 512 ;;AN000;
147 DW 56 ;;AN000;
148 DW 512 ;;AN000;
149 DW 57 ;;AN000;
150 DW 512 ;;AN000;
151 DW 58 ;;AN000;
152 DW 512 ;;AN000;
153 DW 59 ;;AN000;
154 DW 512 ;;AN000;
155 DW 60 ;;AN000;
156 DW 512 ;;AN000;
157 DW 61 ;;AN000;
158 DW 512 ;;AN000;
159 DW 62 ;;AN000;
160 DW 512 ;;AN000;
161 DW 63 ;;AN000;
162 DW 512 ;;AN000;
163 ENDM ;AN000;
164 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
new file mode 100644
index 0000000..e278c9e
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
@@ -0,0 +1,2452 @@
1 PAGE 90,132 ;A2
2 TITLE DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DISKCOPY
5
6; DESCRIPTIVE NAME: Diskette to diskette complete copy Utility
7
8;FUNCTION: DISKCOPY is to copy the contents of the diskette in the
9; specified source drive to the diskette in the target
10; drive. If necessary, the target diskette is also
11; formatted.
12
13
14; Multiple copies may be performed with one load of DISKCOPY.
15; A prompt, "Copy another (Y/N)?" permits additional
16; executions, all with the same drive specifications.
17
18; ENTRY POINT: "DISKCOPY" at ORG 100h, jumps to "BEGIN".
19
20; INPUT: (DOS command line parameters)
21; [d:][path]DISKCOPY [d: [D:]][/1]
22
23; Where
24
25; [d:][path] before DISKCOPY to specify the drive and path that
26; contains the DISKCOPY command file.
27
28; [d:] to specify the source drive id
29
30; [D:] to specify the destination drive id
31
32; [/1] to request single sided operations only
33
34; EXIT-NORMAL: Errorlevel = 0
35; Function completed successfully.
36
37; EXIT-ERROR: Errorlevel = 1
38; Abnormal termination due to error, wrong DOS,
39; invalid parameters, unrecoverable I/O errors on
40; the diskette.
41;
42; Errorlevel = 2
43; Termination requested by Cntrl-Break.
44
45; EFFECTS: The entire source diskette is copied, including the unused
46; sectors. There is no awareness of the separate files
47; involved. A unique volume serial number is generated
48; for the target diskette.
49
50; INCLUDED FILES:
51; INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF)
52; INCLUDE DISKCOPY.EQU ;EQUATES
53; INCLUDE BOOTFORM.INC ;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
54; INCLUDE PATHMAC.INC ;PATHGEN MACRO
55
56; INTERNAL REFERENCES:
57; ROUTINES:
58; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
59; SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE
60; COPY - COPY THE DISKETTE IMAGE
61; TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER
62; READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE
63; WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE
64; READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY
65; READ_OP - IOCTL READ A TRACK OPERATION
66; MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT
67; WRITE_OP - IOCTL WRITE A TRACK OPERATION
68; FORMAT_ALL - FORMATS ALL TRACKS TO END
69; FORMAT_TRACK - IOCTL FORMAT A TRACK
70; CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE
71; READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ
72; CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK
73; CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK
74; SET_FOR_THE_OLD - SET BPB FOR BEFORE-2.0 FMTTED MEDIA
75; SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE
76; CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?
77; CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA
78; SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL
79; CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT
80; GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER
81; EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS
82; TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY
83; ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE
84; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
85; YESNO - DETERMINE IF A RESPONSE IS YES OR NO
86;(DELETED ;AN013;)READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE
87; WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET
88; DATA AREAS:
89; PSP - Contains the DOS command line parameters.
90; WORKAREA - Temporary storage
91
92; EXTERNAL REFERENCES:
93; ROUTINES:
94; SYSDISPMSG - Uses the MSG parm lists to construct the messages
95; on STDOUT.
96; SYSLOADMSG - Loads messages, makes them accessable.
97; SYSPARSE - Processes the DOS Command line, finds parms.
98
99; DATA AREAS:
100; DCOPYSM.SAL - Defines the control blocks that describe the messages
101; DCOPYPAR.SAL - Defines the control blocks that describe the
102; DOS Command line parameters.
103
104; NOTES:
105; This module should be processed with the SALUT preprocessor
106; with the re-alignment not requested, as:
107
108; SALUT DISKCOPY,NUL
109
110; To assemble these modules, the alphabetical or sequential
111; ordering of segments may be used.
112
113; Sample LINK command:
114
115; LINK @DISKCOPY.ARF
116
117; Where the DISKCOPY.ARF is defined as:
118
119; DISKCOPY+
120; DCOPYSM+
121; DCOPYP+
122; DCOPYPAR+
123; COPYINIT
124
125; These modules must be linked in this order. The load module is
126; a COM file, to be converted to COM with EXE2BIN.
127
128; REVISION HISTORY:
129; A000 Version 4.00: add PARSER, System Message Handler,
130; Make new unique vol serial number on new diskette.
131; A001 DCR 27, display vol serial number, if present.
132; A002 ptm473 Flag duplicate switches as error
133; A003 Display parm in error
134; A004 PTR752 Add close door to drive not ready
135; A005 PTR756 After bad parms, specify help info
136; A006 DCR210 SELECT, if present, handles all msgs
137; A007 PTM1100 Clear keyboard buffer before input response
138; A008 PTM1434 CR,LF MISSING FROM MSGS 22 AND 23
139; A009 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
140; A010 PTM1821 Move INCLUDE COPYRIGH.INC into MSG_SERVICE macro.
141; A011 PTM1837 ADD CHECK FOR UNKNOWN MEDIA TO TRIGGER FORMAT
142; A012 PTM2441 COPY FROM 360 TO 1.2 CLOBBERS 1.2
143; A013 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
144; REMOVE USE OF GET/SET MEDIA ID
145; A014 PTM3262 specify BASESW EQU 1 before PARSE.ASM
146; A015 PTM3512 PATHGEN
147;
148; COPYRIGHT: The following notice is found in the OBJ code generated from
149; the "DCOPYSM.SAL" module:
150
151; "Version 4.00 (C) Copyright 1988 Microsoft"
152; "Licensed Material - Property of Microsoft "
153
154;PROGRAM AUTHOR: Original written by: JK
155; 4.00 modifications by: EMK
156;****************** END OF SPECIFICATIONS *****************************
157 IF1 ;
158 %OUT COMPONENT=DISKCOPY, MODULE=DISKCOPY.SAL ;
159 ENDIF ;
160
161;*****************************************************************************
162; *
163; D I S K C O P Y *
164; *
165; UPDATE HISTORY: 7-31, 8-3, 8-5A, 8-6, 8-7, 8-8, 8-10, 8-11, 8-13, 8-14 *
166; 8-16, 8-17, 8-18, 8-20, 8-28, 9-3, 9-11, 10-6, 10-11 *
167; 11-7,11-12, 11-17, 11-18, 12-19, 2-16-84, 3-27, 4-5, 4-7 *
168; 6-20,7-23,10-31,3-27,4-24 *
169; *
170;*****************************************************************************
171
172
173
174;*****************************************************************************
175; *
176; MACRO DEFINITION *
177; *
178;*****************************************************************************
179
180 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
181 INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF)
182 INCLUDE DISKCOPY.EQU ;EQUATES
183
184; $salut (4,16,22,36) ;AN000;
185MY_BPB STRUC ;
186CBYTE_SECT DW 0 ; 200H BYTES / SECTOR
187CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER
188CRESEV_SECT DW 0 ; 1h RESERVED SECTORS
189CFAT DB 0 ; 2h # OF FATS
190CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES
191CTOTSECT DW 0 ; 02D0h TOTAL # OF SECTORS INCLUDING
192 ; BOOT SECT, DIRECTORIES ...
193MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR
194CSECT_FAT DW 0 ; 2h SECTORS / FAT
195CSECT_TRACK DW 0 ;
196CHEAD DW 0 ;
197CHIDDEN_SECT DD 0 ;
198BIG_TOT_SECT DD 0 ;
199 DB 6 DUP (0) ;
200MY_BPB ENDS ;
201
202 INCLUDE BOOTFORM.INC ;AN013;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
203
204CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
205 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG ;
206
207;*****************************************************************************
208; *
209; EXTERNAL VARIABLES *
210; *
211;*****************************************************************************
212;$salut (4,2,9,36) ;AN000;
213 EXTRN SYSLOADMSG :NEAR ;AN000;SYSTEM MSG HANDLER INTIALIZATION
214 EXTRN SYSDISPMSG :NEAR ;AN000;SYSTEM MSG HANDLER DISPLAY
215
216 EXTRN INIT :NEAR ;INITIALIZATION ROUTINE
217.XLIST ;
218;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
219;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
220;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
221;EXTRN MSG_SOURCE_BAD_PTR :BYTE
222;EXTRN YES :BYTE
223;EXTRN NO :BYTE
224.LIST ;
225 EXTRN ASCII_DRV1_ID :BYTE ;AN000;SOURCE DRIVE LETTER CHARACTER
226 EXTRN ASCII_DRV2_ID :BYTE ;AN000;TARGET DRIVE LETTER CHARACTER
227 EXTRN MSG_TRACKS :WORD ;AN000;NUMBER OF TRACKS
228 EXTRN MSG_SECTRK :WORD ;AN000;SECTORS PER TRACK
229 EXTRN MSG_SIDES :WORD ;AN000;NUMBER OF SIDES
230 EXTRN ERROR_SIDE_NUMBER :WORD ;AN000;NUMBER OF SIDES (SUBFIELD OF MSG 19)
231 EXTRN ERROR_TRACK_NUMBER :WORD ;AN000;NUMBER OF TRACKS (SUBFIELD OF MSG 19)
232
233 EXTRN MSGNUM_EXTERR :WORD ;AN000;EXTENDED ERROR MSG DESCRIPTOR
234 EXTRN MSGNUM_HARD_ERROR_READ:WORD ;AN000;"Unrecoverable read/write error on drive %1",CR,LF
235 EXTRN MSGNUM_HARD_ERROR_WRITE:WORD ;AN000;"Side %2, track %3" ;
236 EXTRN MSGNUM_LOAD_SOURCE :WORD ;AC000;"Insert SOURCE diskette in drive %2:"
237 EXTRN MSGNUM_LOAD_TARGET :WORD ;AC000;"Insert TARGET diskette in drive %2:"
238 EXTRN MSGNUM_TARGET_MB_UNUSABLE :WORD ;AC000;"Target diskette may be unusable"
239 EXTRN MSGNUM_NOT_COMPATIBLE :WORD ;AC000;"Drive types or diskette types",CR,LF
240 ;"not compatible"
241 EXTRN MSGNUM_BAD_SOURCE :WORD ;AC000;"SOURCE diskette bad or incompatible"
242 EXTRN MSGNUM_BAD_TARGET :WORD ;AC000;"TARGET diskette bad or incompatible"
243 EXTRN MSGNUM_COPY_ANOTHER :WORD ;AC000;"Copy another diskette (Y/N)?"
244 EXTRN MSGNUM_FORMATTING :WORD ;AC000;"Formatting while copying"
245 EXTRN MSGNUM_GET_READY :WORD ;AC000;"Drive not ready - %0"
246 EXTRN MSGNUM_CLOSE_DOOR :WORD ;AN004;"Make sure a diskette is inserted into
247 ; the drive and the door is closed"
248 EXTRN MSGNUM_FATAL_ERROR :WORD ;AC000;"Copy process ended"
249 EXTRN MSGNUM_UNSUF_MEMORY:WORD ;AC000;"Insufficient memory"
250 EXTRN MSGNUM_COPYING :WORD ;AC000;"Copying %1 tracks",CR,LF
251 ;"%2 Sectors/Track, %3 Side(s)"
252 EXTRN MSGNUM_STRIKE :WORD ;AC000;"Press any key to continue . . ."
253 EXTRN MSGNUM_WRITE_PROTECT :WORD ;AC000;"Attempt to write to write-protected diskette"
254 EXTRN MSGNUM_CR_LF :WORD ;AC000;
255 EXTRN MSGNUM_SERNO :WORD ;AN001;"VOLUME SERIAL NUMBER IS %1-%0"
256 EXTRN SUBLIST_26A :WORD ;AN001;POINTS TO FIRST PART OF SERIAL NUMBER
257 EXTRN SUBLIST_26B :WORD ;AN001;POINTS TO SECND PART OF SERIAL NUMBER
258
259 EXTRN DRIVE_LETTER :BYTE ;AN000;
260;*****************************************************************************
261; *
262; PUBLIC VARIABLES *
263; *
264;*****************************************************************************
265
266 PUBLIC RECOMMENDED_BYTES_SECTOR ;
267 PUBLIC COPY ;
268 PUBLIC S_OWNER_SAVED ;
269 PUBLIC T_OWNER_SAVED ;
270 PUBLIC SOURCE_DRIVE ;
271 PUBLIC TARGET_DRIVE ;
272 PUBLIC S_DRV_SECT_TRACK ;
273 PUBLIC S_DRV_HEADS ;
274 PUBLIC S_DRV_TRACKS ;
275 PUBLIC T_DRV_SECT_TRACK ;
276 PUBLIC T_DRV_HEADS ;
277 PUBLIC T_DRV_TRACKS ;
278 PUBLIC USER_OPTION ;
279 PUBLIC COPY_TYPE ;
280 PUBLIC BUFFER_BEGIN ;
281 PUBLIC BUFFER_END ;
282 PUBLIC TRACK_TO_READ ;
283 PUBLIC TRACK_TO_WRITE ;
284 PUBLIC SIDE ;
285 PUBLIC USER_INPUT ;
286 PUBLIC MAIN_EXIT ;
287
288 PUBLIC IO_ERROR ;
289
290 PUBLIC DS_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
291 PUBLIC DT_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
292 PUBLIC DS_specialFunctions ;AND THEIR CONTENTS
293 PUBLIC DT_specialFunctions ;
294 PUBLIC DS_deviceType ;
295 PUBLIC DT_deviceType ;
296 PUBLIC DS_deviceAttributes ;
297 PUBLIC DT_deviceAttributes ;
298 PUBLIC DS_numberOfCylinders ;
299 PUBLIC DT_numberOfCylinders ;
300 PUBLIC DS_mediaType ;
301 PUBLIC DT_mediaType ;
302 PUBLIC DS_BPB_PTR ;
303 PUBLIC DT_BPB_PTR ;
304
305 PUBLIC MS_IOCTL_DRV_PARM ;DRIVE PARM FROM SOURCE MEDIUM
306 PUBLIC MT_IOCTL_DRV_PARM ;DRIVE PARM FROM TARGET MEDIUM
307
308;*****************************************************************************
309 ORG 100H ;PROGRAM ENTRY POINT
310
311DISKCOPY: ;
312 JMP BEGIN ;
313;*****************************************************************************
314
315;INTERNAL STACK AREA
316 EVEN ;AN000;MAKE STACK WORD ALIGNED
317 DB 64 DUP ('STACK ') ;512 BYTES
318MY_STACK_PTR LABEL WORD ;
319
320;*****************************************************************************
321; *
322; INTERNAL VARIABLES *
323; *
324;*****************************************************************************
325; $salut (4,22,26,36) ;AN000;
326; INPUT PARMETERS FROM INIT SUBROUTINE:
327
328S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED SOUCE DRIVE OWNERSHIP
329T_OWNER_SAVED DB 0 ;
330
331RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
332SOURCE_DRIVE DB 0 ;SOURCE DRIVE ID: 1=DRV A, 2=DRV B ETC.
333TARGET_DRIVE DB 0 ;TARGET DRIVE ID
334USER_OPTION DB 0 ;=1 OF /1 OPTION IS ENTERED
335COPY_TYPE DB 1 ;SINGLE DRV COPY=1, DOUBLE DRIVE COPY=2
336BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT]
337BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT]
338S_DRV_SECT_TRACK DB ? ;SECT/TRACK, device informations.
339S_DRV_HEADS DB ? ;# OF HEADS
340S_DRV_TRACKS DB ? ;# OF TRACKS
341T_DRV_SECT_TRACK DB ? ;
342T_DRV_HEADS DB ? ;
343T_DRV_TRACKS DB ? ;
344
345;DEFAULT BPB FOR OLD MEDIA
346;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
347BPB48_SINGLE DW 512 ;BYTES/SECTOR
348 DB 1 ;SECTOR/CLUSTER
349 DW 1 ;# OF RESERVED SECTORS
350 DB 2 ;# OF FATS
351 DW 40h ;# OF ROOT ENTRY
352 DW 168h ;TOTAL # OF SECTORS IN THE MEDIA
353 DB 0FCh ;MEDIA BYTE
354 DW 2 ;SECTORS/FAT
355
356;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
357BPB48_DOUBLE DW 512 ;BYTES/SECTOR
358 DB 2 ;SECTOR/CLUSTER
359 DW 1 ;# OF RESERVED SECTORS
360 DB 2 ;# OF FATS
361 DW 70h ;# OF ROOT ENTRY
362 DW 2D0h ;TOTAL # OF SECTORS IN THE MEDIA
363 DB 0FDh ;MEDIA BYTE
364 DW 2 ;SECTORS/FAT
365
366;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
367BPB96 DW 512 ;BYTES/SECTOR
368 DB 1 ;SECTOR/CLUSTER
369 DW 1 ;# OF RESERVED SECTORS
370 DB 2 ;# OF FATS
371 DW 0E0h ;# OF ROOT ENTRY
372 DW 960h ;TOTAL # OF SECTORS IN THE MEDIA
373 DB 0F9h ;MEDIA BYTE
374 DW 7 ;SECTORS/FAT
375BPB96_LENG EQU $-BPB96 ;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
376
377; LOCAL VARIABLES:
378VOLSER_FLAG DB 0 ;AN000;0=EITHER MEDIA NOT READ YET, OR
379; SOURCE VOL SER ID NOT AVAILABLE
380; 1=TARGET NEEDS VOL SER WRITTEN
381SERIAL DD 0 ;AN013;SERIAL NUMBER OF NEW DISKETTE
382EXITFL DB EXOK ;AN000;ERRORLEVEL VALUE
383 PUBLIC EXITFL ;AN000;
384 PUBLIC EXPAR ;AN000;
385EXCBR EQU 2 ;AN000;CONTROL BREAK
386EXVER EQU 1 ;AN000;BAD DOS VERSION ERRORLEVEL CODE
387EXPAR EQU 1 ;AN000; BAD PARMS, OR OTHER ERRORS
388EXOK EQU 0 ;AN000;NORMAL ERRORLEVEL RET CODE
389
390S_DRV_SET_FLAG DB 0 ;1 = SOURCE DRIVE PARM HAD BEEN SET
391T_DRV_SET_FLAG DB 0 ;1 = TARGET DRIVE PARM HAD BEEN SET
392
393IOCTL_SECTOR DW 1 ;used for READ_A_SECTOR routine.
394IOCTL_TRACK DW 0 ;IN THE TRACK
395IOCTL_HEAD DW 0 ;HEAD 0
396SAV_CSECT DW 0 ;TEMPORARY SAVING PLACE
397SAV_CN1 DW 0 ;
398SAV_CB1 DW 0 ;
399SAV_CYLN DW 0 ;
400
401BOOT_SECT_TRACK DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
402BOOT_TOT_TRACK DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
403BOOT_NUM_HEAD DW 0 ;NUMBER OF HEADS
404BOOT_BYTE_SECTOR DW 0 ;BYTES / SECTOR
405
406READ_S_BPB_FAILURE DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
407READ_T_BPB_FAILURE DB 0 ;
408
409;*** Informations from CHECK_SOURCE.
410;*** These will be used as a basis for the copy process.
411LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
412END_OF_TRACK DB 15 ;END OF TRACK, 8,9 OR 15 CURRENTLY.
413bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes
414NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED
415
416FORMAT_FLAG DB 0 ;(ON/OFF) FORMAT BEFORE WRITE IF TURNED ON
417TRACK_TO_READ DB 0 ;NEXT TRACK TO READ
418TRACK_TO_WRITE DB 0 ;NEXT TRACK TO WRITE
419TRACK_TO_FORMAT DB 0 ;STARTS FORMAT WITH THIS TRACK
420 ; TO THE LAST TRACK
421TRACK_SIZE DW ? ;BYTES/CYLINDER [IN SEGMENTS]
422SECTOR_SIZE DB ? ;BYTES/SECTOR [IN SEGMENTS]
423BUFFER_PTR DW ? ;BUFFER POINTER FOR READ/WRITE OP
424COPY_ERROR DB 0 ;=0 IF NO ERROR, >0 IF ERROR DETECTED
425SIDE DB ? ;NEXT SIDE TO READ/WRITE (0,1)
426SIDE_TO_FORMAT DB 0 ;NEXT SIDE TO FORMAT (0, 1)
427OPERATION DB ? ;READ/WRITE/VERIFY OPERATION
428COPY_STATUS DB ? ;(OK OR FATAL) ABORT COPY PROCESS IF FATAL
429USER_INPUT DB ? ;DISKCOPY AGAIN?
430IO_ERROR DB 0 ;SET BY EXTENDED_ERROR_HANDLER
431UKM_ERR DB 0 ;AN011;IF ON, HARD ERROR IS TYPE: "UNKNOWN MEDIA"
432MSG_FLAG DB ? ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
433 ;IS TO BE DISPLAYED (ON/OFF)
434TARGET_OP DB 0 ;FLAG TO INDICATE ANY OPERATIONS ON TARGET
435TRY_FORMAT_FLAG DB 0 ;FLAG TO INDICATE "TRY_FORMAT" PROCEDURE TO
436 ; CHECK THE "TIME OUT ERROR"
437TIME_OUT_FLAG DB 0 ;FLAG TO INDICATE THE "TIME OUT" ERROR
438 ; WAS A REAL "TIME OUT ERROR"
439SELECT_FLAG DB 0 ;INDICATES SELECT IS PRESENT
440 PAGE ;
441; DEVICE PARAMETER TABLE
442;the returned info. still has the following format.
443
444DS_IOCTL_DRV_PARM LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
445DS_specialFunctions db ? ;
446DS_deviceType db ? ;0 - 5.25"(48tpi), 1 - 5.25"(96tpi),
447 ; 2 - 3.5"(720KB)
448DS_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
449 ; 0002h - CHANGE LINE SUPPORTED
450DS_numberOfCylinders dw ? ;
451DS_mediaType db ? ;
452DS_BPB_PTR LABEL BYTE ;
453DS_deviceBPB my_bpb <> ;
454DS_trackLayout LABEL WORD ;AC000;
455 my_trackLayout ;AC000;
456;---------------------------------------
457
458DT_IOCTL_DRV_PARM LABEL BYTE ;
459DT_specialFunctions db ? ;
460DT_deviceType db ? ;
461DT_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
462 ; 0002h - CHANGE LINE SUPPORTED
463DT_numberOfCylinders dw ? ;
464DT_mediaType db ? ;
465DT_BPB_PTR LABEL BYTE ;
466DT_deviceBPB my_bpb <> ;
467DT_trackLayout LABEL WORD ;AC000;
468 my_trackLayout ;AC000;
469
470;---------------------------------------
471
472MS_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
473MS_specialFunctions db ? ;
474MS_deviceType db ? ;
475MS_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
476 ; 0002h - CHANGE LINE SUPPORTED
477MS_numberOfCylinders dw ? ;
478MS_mediaType db ? ;
479MS_BPB_PTR LABEL BYTE ;
480MS_deviceBPB my_bpb <> ;
481MS_deviceBPB_leng equ $-MS_deviceBPB ;
482MS_trackLayout LABEL WORD ;AC000;
483 my_trackLayout ;AC000;
484;---------------------------------------
485MT_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
486MT_specialFunctions db ? ;
487MT_deviceType db ? ;
488MT_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
489 ; 0002h - CHANGE LINE SUPPORTED
490MT_numberOfCylinders dw ? ;
491MT_mediaType db ? ;
492MT_BPB_PTR LABEL BYTE ;
493MT_deviceBPB my_bpb <> ;
494MT_trackLayout LABEL WORD ;AC000;
495 my_trackLayout ;AC000;
496
497
498; IOCTL format a track function control string.
499IOCTL_FORMAT LABEL BYTE ;
500FspecialFunctions db 0 ;
501FHead dw ? ;
502FCylinder dw ? ;
503
504; IOCTL read/write a track.
505IOCTL_R_W LABEL BYTE ;
506specialFunctions db 0 ;
507Head dw ? ;
508Cylinder dw ? ;
509FirstSectors dw ? ;
510numberOfSectors dw ? ;
511TAddress_off dw ? ;
512TAddress_seg dw ? ;
513; = = = = = = = = = = = =
514; GET/SET MEDIA ID - FUNCTION OF GENERIC IOCTL
515; (USED BY VOLSER PROC)
516;(Deleted ;AN013;) MEDIA_ID_BUF A_MEDIA_ID_INFO <> ; ;AN000;
517; = = = = = = = = = = = =
518 PATHLABL DISKCOPY ;AN015;
519 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ;AN000;
520 PUBLIC DISKCOPY_BEGIN ;
521DISKCOPY_BEGIN LABEL NEAR ;
522
523;*****************************************************************************
524; *
525; D I S K C O P Y M A I N P R O G R A M *
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 PTR
534 CALL SYSLOADMSG ;AN000;INIT SYSMSG HANDLER
535
536; $IF C ;AN000;IF THERE WAS A PROBLEM
537 JNC $$IF1
538 CALL SYSDISPMSG ;AN000;LET HIM SAY WHY HE HAD A PROBLEM
539
540 MOV EXITFL,EXVER ;AN000;TELL ERRORLEVEL BAD DOS VERSION
541; $ELSE ;AN000;SINCE SYSDISPMSG IS HAPPY
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 COPY
548 JNE $$IF3
549; $DO ;
550$$DO4:
551 CALL COPY ;PERFORM DISKCOPY
552
553 CALL TEST_REPEAT ;COPY 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.XLIST ;
562; PUSH DX
563; PUSH CS
564; CALL PRINTF ;DISPLAY ERROR MESSAGE
565.LIST ;
566 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
567 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
568 CALL SENDMSG ;AC000;DISPLAY THE ERROR MESSAGE
569
570 MOV EXITFL,EXVER ;AC000;ERROR RETURN CODE
571; $ENDIF ;
572$$EN3:
573 JMP SHORT EXIT_TO_DOS ;
574
575MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
576 MOV EXITFL,EXCBR ;AC000; FOR CONTROL-BREAK EXIT
577
578EXIT_TO_DOS: ;
579 XOR BX, BX ;
580
581 MOV BL, S_OWNER_SAVED ;RESTORE ORIGINAL SOURCE,
582 ; TARGET DRIVE OWNER.
583 CALL SET_LOGICAL_DRIVE ;
584
585 MOV BL, T_OWNER_SAVED ;
586 CALL SET_LOGICAL_DRIVE ;
587
588 CMP S_DRV_SET_FLAG, 0 ;
589; $IF NE ;AN000;
590 JE $$IF8
591 MOV BL, SOURCE_DRIVE ;
592 MOV DS_specialFunctions, SET_SP_FUNC_DOS ;=0
593 MOV DX, OFFSET DS_IOCTL_DRV_PARM ;
594 CALL SET_DRV_PARM_DEF ;RESTORE SOURCE DRIVE PARM
595
596; $ENDIF ;AN000;
597$$IF8:
598
599 CMP T_DRV_SET_FLAG, 0 ;
600; $IF NE ;AN000;
601 JE $$IF10
602 MOV BL, TARGET_DRIVE ;
603 MOV DT_specialFunctions, SET_SP_FUNC_DOS ;=0
604 MOV DX, OFFSET DT_IOCTL_DRV_PARM ;
605 CALL SET_DRV_PARM_DEF ;RESTORE TARGET DRIVE PARM
606
607; $ENDIF ;AN000;
608$$IF10:
609EXIT_PROGRAM: ;
610
611; $ENDIF ;AN000;OK WITH SYSDISPMSG?
612$$EN1:
613 MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE
614 DOSCALL RET_CD_EXIT ;AN000;RETURN TO DOS WITH RET CODE
615
616 INT 20H ;AN000;IF ABOVE NOT WORK,
617BEGIN 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 ;
628; $IF NE ;IF BL = 0, THEN JUST RETURN
629 JE $$IF13
630 ;ELSE SET BL AS AN OWNER OF THAT DRIVE
631 MOV AX,(IOCTL_FUNC SHL 8)+SET_LOGIC_DRIVE ;AC000;
632 INT 21H ;
633; $ENDIF ;
634$$IF13:
635 RET ;
636SET_LOGICAL_DRIVE ENDP ;
637; = = = = = = = = = = = =
638 HEADER <COPY - COPY THE DISKETTE IMAGE> ;AN000;
639;*****************************************************************************
640;MODULE NAME: COPY *
641; *
642; INPUT: COPY_TYPE BYTE 1=SINGLE DRIVE COPY *
643; 2=DOUBLE DRIVE COPY *
644; *
645; OUTPUT: NONE *
646;*****************************************************************************
647COPY PROC NEAR ;COPY DISKETTE IMAGE
648 MOV VOLSER_FLAG,0 ;AN000;RESET MEDIA ID VOL SERIAL NUMBER FLAG
649 MOV COPY_ERROR,0 ;RESET COPY ERROR FLAG
650 MOV COPY_STATUS,OK ;RESET COPY STATUS BYTE
651 MOV TARGET_OP, OFF ;
652 MOV TRY_FORMAT_FLAG, OFF ;
653 MOV TIME_OUT_FLAG, OFF ;
654 MOV FORMAT_FLAG,OFF ;ASSUME FORMAT IS NOT REQUIRED
655 MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG
656 MOV READ_T_BPB_FAILURE, 0 ;
657 MOV AX, RECOMMENDED_BYTES_SECTOR ;
658 MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE TO READ A SECTOR
659 CMP COPY_TYPE,2 ;IF TWO DRIVE COPY
660; $IF E ;
661 JNE $$IF15
662 PRINT MSGNUM_LOAD_SOURCE ;AC000;OUTPUT LOAD SOURCE DISKETTE MESSAGE
663 ;"INSERT SOURCE DISKETTE INTO DRIVE X:"
664
665 PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
666
667 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
668
669; $ENDIF ;
670$$IF15:
671 MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS
672 MOV TRACK_TO_WRITE,0 ;
673
674COPY_TEST_END: ;
675; $SEARCH ;
676$$DO17:
677 MOV AL,TRACK_TO_WRITE ;WHILE TRACK_TO_WRITE<=LAST_TRACK
678 CMP AL,LAST_TRACK ;
679; $LEAVE A ;
680 JA $$EN17
681 CALL READ_SOURCE ;READ AS MANY TRACK AS POSSIBLE
682
683 CMP COPY_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE
684; $EXITIF E,NUL,OR ;
685 JE $$SR17
686 CALL WRITE_TARGET ;WRITE THE CONTENT OF BUFFER TO TARGET
687
688 CMP COPY_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE
689; $EXITIF E,NUL ;
690 JE $$SR17
691; $ENDLOOP ;
692 JMP SHORT $$DO17
693$$EN17:
694
695 CMP COPY_ERROR,FALSE ;IF ERROR IN COPY
696; $IF NE ;
697 JE $$IF21
698 ;CR,LF,"Target diskette may be unusable",CR,LF
699 PRINT MSGNUM_TARGET_MB_UNUSABLE ;AC000;
700
701; $ENDIF ;
702$$IF21:
703; $ENDSRCH ;
704$$SR17:
705 CMP COPY_STATUS,FATAL ;WAS COPY ABORTED ?
706; $IF E ;
707 JNE $$IF24
708 ;CR,LF,"Copy process ended",CR,LF
709 PRINT MSGNUM_FATAL_ERROR ;AC000;IF SO THEN TELL USER
710
711; $ELSE ;AN000;SINCE NOT ABORTED,
712 JMP SHORT $$EN24
713$$IF24:
714 CALL WRITE_VOLSER ;AN000;GO CHANGE VOLID OF TARGET
715
716; $ENDIF ;
717$$EN24:
718 RET ;
719
720COPY ENDP ;
721; = = = = = = = = = = = =
722 HEADER <TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER> ;AN000;
723;*****************************************************************************
724; *
725 PUBLIC TEST_REPEAT ;AN000;MAKE ENTRY IN LINK MAP
726TEST_REPEAT PROC NEAR ;TEST IF USER WANTS TO COPY ANOTHER *
727; DISKETTE *
728; INPUT : USER_INPUT ("Y" OR "N")
729; OUTPUT: NC = COPY AGAIN *
730; CY = EXIT TO DOS *
731;*****************************************************************************
732; $SEARCH COMPLEX ;AC000;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED
733 JMP SHORT $$SS27
734$$DO27:
735 PRINT MSGNUM_CR_LF ;AC000;
736
737; $STRTSRCH ;AN000;
738$$SS27:
739 ;CR,LF,"Copy another diskette (Y/N)?"
740 PRINT MSGNUM_COPY_ANOTHER ;AC000;SEE IF USER WANTS TO COPY ANOTHER
741 ; AND READ RESPONSE TO AL
742 PUSH AX ;AN000;SAVE THE RESPONSE
743 PRINT MSGNUM_CR_LF ;AC000;
744
745 POP DX ;AN000;RESTORE THE REPONSE CHAR TO DL
746 CALL YESNO ;AN000;CHECK FOR (Y/N)
747 ;AX=0,NO; AX=1,YES; AX=2,INVALID
748; $EXITIF C,NUL ;AN000;IF CARRY SET, PROBLEM,PRETEND "NO"
749 JC $$SR27
750
751 CMP AX,BAD_YESNO ;AN000;WAS THE RESPONSE INVALID?
752; $ENDLOOP B ;AN000;QUIT IF OK ANSWER (AX=0 OR 1)
753 JNB $$DO27
754 CMP AL,YES ;AN000;WAS "YES" SPECIFIED
755; $IF E ;AN000;IF "YES"
756 JNE $$IF31
757 CLC ;AN000;CLEAR CARRY TO INDICATE COPY AGAIN
758; $ELSE ;AN000;SINCE NOT "YES"
759 JMP SHORT $$EN31
760$$IF31:
761 STC ;AN000;SET CARRY TO INDICATE NO REPEAT
762; $ENDIF ;AN000;
763$$EN31:
764; $ENDSRCH ;AN000;
765$$SR27:
766.XLIST ;
767; MOV AL,USER_INPUT
768; AND AL,11011111B ;MAKE USER INPUT UPPER CASE
769; CMP AL,YES ;IF YES THEN COPY AGAIN
770; $EXITIF E
771; CLC ;CLEAR CARRY TO INDICATE COPY AGAIN
772; $ORELSE
773; CMP AL,NO ;IF NOT "N" OR "Y" THEN PROMPT AGAIN
774; $ENDLOOP E
775; STC ;SET CARRY TO INDICATE NO REPEAT
776; $ENDSRCH
777.LIST ;
778 RET ;
779
780TEST_REPEAT ENDP ;
781; = = = = = = = = = = = =
782 HEADER <READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE> ;AN000;
783;*****************************************************************************
784; *
785 PUBLIC READ_SOURCE ;AN000;MAKE ENTRY IN LINK MAP *
786READ_SOURCE PROC NEAR ;READ AS MANY TRACKS AS POSSIBLE FROM SOURCE*
787; ;DISKETTE TO FILL THE AVAILABLE BUFFER SPACE *
788;*****************************************************************************
789
790 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY
791; $IF E ;PROMPT MSG
792 JNE $$IF35
793 PRINT MSGNUM_LOAD_SOURCE ;AN000;"INSERT SOURCE DISKETTE INTO DRIVE X:"
794
795 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
796
797; $ENDIF ;
798$$IF35:
799 CMP TRACK_TO_READ,0 ;1ST TRACK ?
800; $IF NE,OR ;IF NOT
801 JNE $$LL37
802
803 CALL CHECK_SOURCE ;DO NECESSARY CHECKING
804
805 CALL CALC_TRACK_SIZE ;
806
807 CALL CHECK_MEMORY_SIZE ;
808
809 CMP COPY_STATUS,FATAL ;
810; $IF NE ;
811 JE $$IF37
812$$LL37:
813;(deleted ;AN013;) CALL READ_VOLSER ;GO READ THE MEDIA ID TO GET SERIAL NUMBER ;AN000;
814
815 MOV BX,BUFFER_BEGIN ;
816 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
817
818; $DO ;
819$$DO38:
820 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
821 CMP AL,LAST_TRACK ;
822; $LEAVE A ;
823 JA $$EN38
824 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
825 ADD AX,TRACK_SIZE ;
826 CMP AX,BUFFER_END ;
827; $LEAVE A ;
828 JA $$EN38
829 MOV OPERATION,READ_FUNC ;
830 CALL READ_WRITE_TRACK ;NO, GO READ ANOTHER TRACK
831
832 INC TRACK_TO_READ ;
833; $ENDDO ;
834 JMP SHORT $$DO38
835$$EN38:
836; $ENDIF ;
837$$IF37:
838 RET ;
839READ_SOURCE ENDP ;
840; = = = = = = = = = = = =
841 HEADER <WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE> ;AN000;
842;*****************************************************************************
843; *
844 PUBLIC WRITE_TARGET ;AN000;MAKE ENTRY IN LINK MAP
845WRITE_TARGET PROC ;WRITE DATA FROM MEMORY TO TARGET DISKETTE*
846; *
847;*****************************************************************************
848
849 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY
850; $IF E ;PROMPT MSG
851 JNE $$IF43
852 PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
853
854 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
855
856; $ENDIF ;
857$$IF43:
858 MOV TARGET_OP, ON ;INDICATE A OPERATION ON TARGET
859 MOV BX,BUFFER_BEGIN ;
860 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
861 CMP TRACK_TO_WRITE,0 ;IF TRK 0, CHECK COMPATIBILITY
862; $IF NE,OR ;
863 JNE $$LL45
864
865 MOV SIDE, 0 ;
866 CALL CHECK_TARGET ;
867
868 CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
869; $IF NE ;
870 JE $$IF45
871$$LL45:
872
873; $DO ;
874$$DO46:
875 MOV AL,TRACK_TO_WRITE ;DID WE FINISH WRITING ALL TRACKS?
876 CMP AL,LAST_TRACK ;
877; $LEAVE A ;
878 JA $$EN46
879 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
880 ADD AX,TRACK_SIZE ;
881 CMP AX,BUFFER_END ;
882; $LEAVE A ;
883 JA $$EN46
884 MOV OPERATION,WRITE_FUNC ;
885 CALL READ_WRITE_TRACK ;NO, GO WRITE ANOTHER TRACK
886
887 CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
888; $LEAVE E ;
889 JE $$EN46
890 INC TRACK_TO_WRITE ;
891; $ENDDO ;
892 JMP SHORT $$DO46
893$$EN46:
894; $ENDIF ;
895$$IF45:
896 MOV TARGET_OP, OFF ;
897 RET ;
898WRITE_TARGET ENDP ;
899; = = = = = = = = = = = =
900 HEADER <READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY> ;AN000;
901;*****************************************************************************
902; *
903 PUBLIC READ_WRITE_TRACK ;AN000;MAKE ENTRY IN LINK MAP
904READ_WRITE_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY *
905; *
906;INPUT: OPERATION = 61h THEN READ OPERATION *
907; 41h THEN WRITE OPERATION *
908;*****************************************************************************
909
910 MOV SIDE, 0 ;
911; $DO ;
912$$DO52:
913 MOV MSG_FLAG, ON ;
914 CMP OPERATION, READ_FUNC ;
915; $IF E ;
916 JNE $$IF53
917 CALL READ_OP ;
918
919; $ELSE ;
920 JMP SHORT $$EN53
921$$IF53:
922 CALL WRITE_OP ;
923
924 CMP COPY_STATUS, FATAL ;
925 JE RWT_EXIT ;
926
927; $ENDIF ;
928$$EN53:
929 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
930; $IF E ;YES
931 JNE $$IF56
932 MOV AX, TRACK_SIZE ;
933; $ELSE ;NO, DOUBLE SIDE
934 JMP SHORT $$EN56
935$$IF56:
936 XOR DX, DX ;
937 MOV AX, TRACK_SIZE ;
938 MOV CX, 2 ;
939 DIV CX ;AX / 2
940; $ENDIF ;
941$$EN56:
942 ADD BUFFER_PTR, AX ;
943 INC SIDE ;NEXT SIDE
944 MOV AL, SIDE ;
945 CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE?
946; $ENDDO G ;
947 JNG $$DO52
948RWT_EXIT: ;
949 RET ;
950READ_WRITE_TRACK ENDP ;
951; = = = = = = = = = = = =
952 HEADER <READ_OP - IOCTL READ A TRACK OPERATION> ;AN000;
953;*****************************************************************************
954; *
955 PUBLIC READ_OP ;AN000;MAKE ENTRY IN LINK MAP
956READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION *
957; *
958;*****************************************************************************
959
960; $SEARCH ;
961$$DO60:
962 XOR AX, AX ;
963 MOV AL, SIDE ;
964 MOV Head, AX ;HEAD TO READ
965 MOV AL, TRACK_TO_READ ;
966 MOV Cylinder, AX ;TRACK TO READ
967 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
968 MOV AX, BUFFER_PTR ;
969 MOV Taddress_seg, AX ;BUFFER ADDRESS
970 MOV Taddress_off, 0 ;
971 XOR BX, BX ;
972 MOV BL, SOURCE_DRIVE ;
973 MOV CL, READ_FUNC ;=61h
974 MOV DX, OFFSET IOCTL_R_W ;
975 CALL GENERIC_IOCTL ;
976
977 CMP IO_ERROR, NO_ERROR ;OK?
978; $EXITIF E ;AC013;IF NO ERROR SO FAR, GOOD
979 JNE $$IF60
980 CMP CYLINDER,0 ;AN013;IS THIS THE FIRST READ?
981; $IF E,AND ;AN013;IF THIS IS THE FIRST TRACK, AND
982 JNE $$IF62
983 CMP HEAD,0 ;AN013;IS THIS THE FIRST SIDE?
984; $IF E ;AN013;AND IF THIS IS THE FIRST SIDE
985 JNE $$IF62
986 CALL MAYBE_ADJUST_SERIAL ;AN013;IF BOOT HAS SERIAL, GENERATE NEW ONE
987
988; $ENDIF ;AN013;FIRST TRACK AND HEAD?
989$$IF62:
990; $ORELSE ;AN013;SINCE SOME KIND OF ERROR, OOPS
991 JMP SHORT $$SR60
992$$IF60:
993 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
994; $ENDLOOP NE ;
995 JE $$DO60
996
997 CMP MSG_FLAG, ON ;ELSE HARD ERROR. SEE IF
998 ; MESSAGE TO BE DISPLAYED
999; $IF E ;
1000 JNE $$IF66
1001
1002 MOV AH, READ_FUNC ;
1003 mov dl, source_drive ;
1004 CALL ERROR_MESSAGE ;
1005
1006 INC COPY_ERROR ;INCREASE COPY_ERROR COUNT
1007 MOV MSG_FLAG, OFF ;
1008; $ENDIF ;
1009$$IF66:
1010; $ENDSRCH ;
1011$$SR60:
1012 RET ;
1013READ_OP ENDP ;
1014; = = = = = = = = = = = =
1015 HEADER <MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT> ;AN013;
1016MAYBE_ADJUST_SERIAL PROC NEAR ;AN013;
1017;INPUT: TADDRESS_OFF/_SEG HAS TRACK BUFFER WHICH HAS BOOT RECORD
1018; "VOLSER_FLAG" IS FALSE.
1019;OUTPUT:SERIAL NUMBER FIELD IS MODIFIED TO HAVE NEW SERIAL NUMBER
1020; A COPY OF WHICH IS PRESERVED IN "SERIAL" FOR LATER DISPLAY IN MSG.
1021; "VOLSER_FLAG" SET TO TRUE TO INDICATE NEW SERIAL GENERATED.
1022; IF THIS BOOT DOES NOT HAVE A SERIAL, NO CHANGE MADE, AND
1023; "VOLSER_FLAG" LEFT AS FALSE.
1024
1025; A BOOT RECORD IS ASSUMED TO HAVE A SERIAL NUMBER IF:
1026; EBPB_MEDIADESCRIPTOR=0F?H AND EXT_BOOT_SIG IS EITHER 28H OR 29H.
1027
1028 PUSH ES ;AN013;SAVE EXTRA SEG REG TEMPORARILY
1029 PUSH BX ;AN013;AND SAVE THE BASE POINTER
1030 PUSH SI ;AN013; AND THE INDEX
1031 LES BX,DWORD PTR TADDRESS_OFF ;AN013;POINT TO BUFFER AREA CONTAINING BOOT RECORD
1032 LEA SI,ES:[BX].EXT_BOOT_BPB ;AN013;POINT TO BPB PORTION OF BOOT RECORD
1033 MOV AL,ES:[SI].EBPB_MEDIADESCRIPTOR ;AN013;GET TYPE OF MEDIA
1034 AND AL,0F0H ;AN013;SAVE LEFT NIBBLE ONLY
1035 CMP AL,0F0H ;AN013;IF DISKETTE HAS PROPER DESCRIPTOR
1036; $IF E ;AN013;IF OK DESCRIPTOR
1037 JNE $$IF69
1038 MOV AL,ES:[BX].EXT_BOOT_SIG ;AN013;GET "SIGNATURE" OF BOOT RECORD
1039 CMP AL,28H ;AN013;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
1040; $IF E,OR ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1041 JE $$LL70
1042 CMP AL,29H ;AN013;IS THIS A BOOT STYLE OF OS/S 1.2?
1043; $IF E ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1044 JNE $$IF70
1045$$LL70:
1046; GET CURRENT DATE
1047 DOSCALL GET_DATE ;AN013;READ SYSTEM DATE
1048 ;OUTPUT: DL = DAY (1-31)
1049 ; AL = DAY OF WEEK (0=SUN,6=SAT)
1050 ; CX = YEAR (1980-2099)
1051 ; DH = MONTH (1-12)
1052 PUSH CX ;AN013;SAVE THESE FOR
1053 PUSH DX ;AN013; INPUT INTO HASH ALGORITHM
1054; GET CURRENT TIME
1055 DOSCALL GET_TIME ;AN013;READ SYSTEM TIME CLOCK
1056 ;OUTPUT: CH = HOUR (0-23)
1057 ; CL = MINUTES (0-59)
1058 ; DH = SECONDS (0-59)
1059 ; DL = HUNDREDTHS (0-99)
1060
1061; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
1062; SERIAL+0 = DX FROM DATE + DX FROM TIME
1063; SERIAL+2 = CX FROM DATE + CX FROM TIME
1064
1065 POP AX ;AN013;GET THE DX FROM DATE
1066 ADD AX,DX ;AN013;ADD IN THE DX FROM TIME
1067 MOV WORD PTR SERIAL,AX ;AN013;SAVE FIRST RESULT OF HASH
1068 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL,AX ;AN013;AND IN BOOT RECORD ITSELF
1069
1070 POP AX ;AN013;GET THE CX FROM DATE
1071 ADD AX,CX ;AN013;ADD IN THE CX FROM TIME
1072 MOV WORD PTR SERIAL+WORD,AX ;AN013;SAVE SECOND RESULT OF HASH
1073 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL+WORD,AX ;AN013;AND IN BOOT RECORD
1074
1075 MOV VOLSER_FLAG,TRUE ;AN013;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN
1076
1077; $ENDIF ;AN013;BOOT HAVE SERIAL?
1078$$IF70:
1079; $ENDIF ;AN013;PROPER DESCRIPTOR?
1080$$IF69:
1081 POP SI ;AN013;RESTORE THE INDEX REG
1082 POP BX ;AN013;RESTORE THE BASE POINTER
1083 POP ES ;AN013;RESTORE EXTRA SEG REG
1084 RET ;AN013;RETURN TO CALLER
1085MAYBE_ADJUST_SERIAL ENDP ;AN013;
1086; = = = = = = = = = = = =
1087 HEADER <WRITE_OP - IOCTL WRITE A TRACK OPERATION> ;AN000;
1088;*****************************************************************************
1089; *
1090 PUBLIC WRITE_OP ;AN000;MAKE ENTRY IN LINK MAP
1091WRITE_OP PROC NEAR ;IOCTL WRITE A TRACK OPERATION *
1092; *
1093;*****************************************************************************
1094
1095WO_AGAIN: ;
1096; $SEARCH ;
1097$$DO73:
1098 XOR AX, AX ;
1099 MOV AL, SIDE ;
1100 MOV Head, AX ;HEAD TO WRITE
1101 MOV AL, TRACK_TO_WRITE ;
1102 MOV Cylinder, AX ;TRACK TO WRITE
1103 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1104 MOV AX, BUFFER_PTR ;
1105 MOV Taddress_seg, AX ;BUFFER ADDRESS
1106 MOV Taddress_off, 0 ;
1107 XOR BX, BX ;
1108 MOV BL, TARGET_DRIVE ;
1109 MOV CL, WRITE_FUNC ;= 41h
1110 MOV DX, OFFSET IOCTL_R_W ;
1111 CALL GENERIC_IOCTL ;
1112
1113 CMP IO_ERROR, NO_ERROR ;OK?
1114; $LEAVE E ;YES, SUCCESS. EXIT THIS ROUTINE
1115 JE $$EN73
1116
1117 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1118 JE WO_AGAIN ;
1119 ;ELSE HARD ERROR
1120 ;WRITE FAILURE, LET'S TRY TO FORMAT.
1121 CMP FORMAT_FLAG, ON ;WAS THIS TRACK FORMATTED BEFORE?
1122; $EXITIF E ;YES, GIVE UP WRITING AND
1123 JNE $$IF73
1124 ; CHECK WHEN IT HAPPENDED.
1125 ;GIVE UP WRITING AND SHOW ERROR MESSAGE.
1126 INC COPY_ERROR ;INDICATE ERROR OCCURS DURING COPY.
1127 MOV AH, WRITE_FUNC ;
1128 mov dl, target_drive ;
1129 CALL ERROR_MESSAGE ;SHOW MESSAGE 'WRITE ERROR SIDE, TRACK...'
1130
1131 MOV MSG_FLAG, OFF ;
1132; $ORELSE ;ELSE TRY FORMAT AND TRY WRITE AGAIN
1133 JMP SHORT $$SR73
1134$$IF73:
1135
1136 ;CR,LF,"Formatting while copying",CR,LF
1137 PRINT MSGNUM_FORMATTING ;AN000;SHOW MESSAGE
1138
1139 MOV FORMAT_FLAG, ON ;FORMAT ALL TRACKS FROM THIS TRACK
1140 CALL FORMAT_ALL ;format all the rest of the tracks
1141
1142 CMP COPY_STATUS, FATAL ;
1143; $ENDLOOP E ;
1144 JNE $$DO73
1145$$EN73:
1146.XLIST ;
1147;this next is dead code, nobody calls WO_FATAL, so the move copy_status
1148;and the print not compatible msg should be removed, and just the JMP WO_EXIT
1149;will no longer be needed to skip stuff that is not there. Kiser
1150; JMP WO_EXIT ;AND EXIT THIS ROUTINE
1151;WO_FATAL:
1152; MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1153; PRINT MSG_NOT_COMPATIBLE ;SHOW NOT COMPATIABLE MESSAGE
1154.LIST ;
1155; $ENDSRCH ;
1156$$SR73:
1157WO_EXIT: ;
1158 RET ;
1159
1160WRITE_OP ENDP ;
1161; = = = = = = = = = = = =
1162 HEADER <FORMAT_ALL - FORMATS ALL TRACKS TO END> ;AN000;
1163;*****************************************************************************
1164; *
1165 PUBLIC FORMAT_ALL ;AN000;MAKE ENTRY IN LINK MAP
1166FORMAT_ALL PROC NEAR ;
1167; *
1168;Format all tracks starting from TRACK_TO_WRITE to the end. *
1169;This routine will set MT_deviceBPB to that of MS_deviceBPB. *
1170;trackLayout had been all set correctly. *
1171;If error, then fail to diskcopy. *
1172;*****************************************************************************
1173
1174 MOV CX, MS_deviceBPB_leng ;set length of BPB
1175 MOV SI, OFFSET MS_deviceBPB ;
1176 MOV DI, OFFSET MT_deviceBPB ;
1177 REP MOVSB ;
1178 CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation
1179
1180 MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
1181 MOV CL, SETDEVPARM ;=40h
1182 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1183 XOR BX, BX ;
1184 mov bl, last_track ;patch 3/27/86 for 3.2 diskcopy. J.K.
1185 inc bl ;
1186 mov MT_numberOfCylinders, bx ;make sure target # of cyl.
1187 MOV BL, TARGET_DRIVE ;
1188 CALL GENERIC_IOCTL ;
1189
1190 JC FA_FATAL ;
1191
1192 MOV FspecialFunctions, STATUS_CHK ;check to see if the parameters set
1193 ;by "SET DEVICE PARM" func above are
1194 ; supported or not.
1195 MOV AX,(IOCTL_FUNC SHL 8)+GENERIC_IOCTL_CODE ;AC000;(440DH)
1196 MOV CH, MAJOR_CODE ;=8
1197 MOV CL, FORMAT_FUNC ;=42H
1198 XOR BX, BX ;
1199 MOV BL, TARGET_DRIVE ;
1200 MOV DX, OFFSET IOCTL_FORMAT ;result is in Fspecialfunction
1201 INT 21H ;0 - Thre is ROM support of AH=18h, INT 13h, and
1202 ; it is a valid combination
1203
1204 MOV AL, FspecialFunctions ;1 - No ROM support. 2 - There is ROM support,
1205 ; but invalid combination
1206 MOV FspecialFunctions, FORMAT_SP_FUNC ;restore specialfunction value
1207 CMP AL, 2 ;ROM support, but this combination is not valid?
1208 JE FA_FATAL ;
1209
1210 MOV AL, TRACK_TO_WRITE ;
1211 MOV TRACK_TO_FORMAT, AL ;
1212 MOV AL, SIDE ;
1213 MOV SIDE_TO_FORMAT, AL ;
1214 CMP AL, NO_OF_SIDES ;
1215 JE FA_SIDE_WHILE ;STARTS WITH THE OTHER SIDE TO FORMAT
1216
1217FA_TRACK_WHILE: ;
1218 MOV AL, LAST_TRACK ;
1219 CMP TRACK_TO_FORMAT, AL ;
1220 JA FA_DONE ;
1221
1222FA_SIDE_WHILE: ;
1223 MOV AL, NO_OF_SIDES ;
1224 CMP SIDE_TO_FORMAT, AL ;
1225 JA FA_NEXT_TRACK ;
1226
1227 CALL FORMAT_TRACK ;FORMAT THIS TRACK
1228
1229 CMP IO_ERROR, HARD_ERROR ;
1230 JNE FA_NEXT_SIDE ;
1231
1232 CMP SIDE_TO_FORMAT, 1 ;HARD ERROR AT SIDE 1?
1233 JNE FA_TARGET_BAD ;THEN ASSUME TARGET DISKETTE BAD
1234
1235 CMP TRACK_TO_FORMAT, 0 ;AT CYLINDER 0?
1236 JNE FA_TARGET_BAD ;
1237
1238 JMP FA_FATAL ;THEN, SOURCE IS TWO SIDED AND
1239 ; TARGET IS SINGLE SIDE DISKETTE
1240
1241FA_NEXT_SIDE: ;
1242 INC SIDE_TO_FORMAT ;
1243 JMP FA_SIDE_WHILE ;
1244
1245FA_NEXT_TRACK: ;
1246 MOV SIDE_TO_FORMAT, 0 ;RESET SIDE_TO_FORMAT
1247 INC TRACK_TO_FORMAT ;
1248 JMP FA_TRACK_WHILE ;
1249
1250FA_FATAL: ;
1251 MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1252 ;"Drive types or diskette types"
1253 ;"not compatible"
1254 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;SHOW NOT COMPATIBLE MESSAGE
1255
1256 JMP SHORT FA_DONE ;
1257
1258FA_TARGET_BAD: ;
1259 MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1260 ;CR,LF,"TARGET diskette bad or incompatible"
1261 PRINT MSGNUM_BAD_TARGET ;AC000;SHOW TARGET BAD MESSAGE
1262
1263FA_DONE: ;
1264 XOR BX, BX ;
1265 MOV BL, TARGET_DRIVE ;
1266 MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
1267 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1268 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
1269 CALL SET_DRV_PARM_DEF ;SET IT BACK FOR WRITING.
1270
1271 RET ;
1272FORMAT_ALL ENDP ;
1273; = = = = = = = = = = = =
1274 HEADER <FORMAT_TRACK - IOCTL FORMAT A TRACK> ;AN000;
1275;******************************************************************************
1276; SUBROUTINE NAME : FORMAT_TRACK - IOCTL FORMAT A TRACK *
1277; (BOTH SIDES IF 2-SIDED DSKT) *
1278; *
1279; INPUT : TRACK_TO_FORMAT *
1280; : SIDE BYTE 0, 1 (HEAD NUMBER) *
1281; : END_OF_TRACK BYTE 8, 9, 15 *
1282; : TARGET_DRIVE BYTE 1 = A, 2 = B, ETC *
1283; *
1284; OUTPUT : none. This routine does not report format error. *
1285; Write routine will detect the error consequently. *
1286; REGISTER(S) AFFECTED: *
1287;******************************************************************************
1288 PUBLIC FORMAT_TRACK ;AN000;MAKE ENTRY IN LINK MAP
1289FORMAT_TRACK PROC NEAR ;
1290
1291FT_AGAIN: ;
1292; $DO ;
1293$$DO79:
1294 XOR AX, AX ;
1295 MOV AL, SIDE_TO_FORMAT ;
1296 MOV FHead, AX ;HEAD TO FORMAT
1297 MOV AL, TRACK_TO_FORMAT ;
1298 MOV FCylinder, AX ;TRACK TO FORMAT
1299
1300 XOR BX, BX ;
1301 MOV BL, TARGET_DRIVE ;DRIVE TO FORMAT
1302 MOV CL, FORMAT_FUNC ;=42h
1303 MOV DX, OFFSET IOCTL_FORMAT ;
1304 CALL GENERIC_IOCTL ;
1305
1306 CMP IO_ERROR, SOFT_ERROR ;TRY FORMAT AGAIN?
1307 ; (DRIVE NOT READY OR WRITE PROTECTED)
1308; $ENDDO NE ;
1309 JE $$DO79
1310
1311 RET ;
1312FORMAT_TRACK ENDP ;
1313; = = = = = = = = = = = =
1314 HEADER <CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE> ;AN000;
1315;*****************************************************************************
1316; *
1317 PUBLIC CHECK_SOURCE ;AN000;MAKE ENTRY IN LINK MAP
1318CHECK_SOURCE PROC NEAR ;CHECK SOURCE DISKETTE TYPE *
1319; SET END_OF_TRACK, LAST_TRACK *
1320; NO_OF_SIDES, bSECTOR_SIZE *
1321; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
1322; ** fails to get that info, then the source medium must be bad(vergin) or *
1323; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
1324; ** For compatibility reasons (in case of non IBM formatted media), this *
1325; ** routine covers old diskcopy routines. But this will only supports
1326; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
1327; ** media. Other non IBM formatted media which are formatted differenty
1328; ** from those values will result in unpreditable copy process.
1329;*****************************************************************************
1330
1331; $DO ;
1332$$DO81:
1333 XOR BX, BX ;
1334 MOV BL, SOURCE_DRIVE ;
1335 MOV MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1336 MOV CL, GETDEVPARM ;=60h
1337 MOV DX, OFFSET MS_IOCTL_DRV_PARM ;
1338 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1339 ;WITH DEFAULT DEVICE INFO.
1340 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1341; $ENDDO NE ;
1342 JE $$DO81
1343
1344 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
1345 JE CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST.
1346
1347 cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86
1348 je cs_old ;
1349
1350 cmp ms_deviceBPB.chead,0 ;cannot trust the info from dos
1351 je cs_old ;sanity check for divide by 0
1352
1353 MOV AX, MS_deviceBPB.CTOTSECT ;
1354 CWD ;CONVERT IT TO A DOUBLE WORD
1355 DIV MS_deviceBPB.CSECT_TRACK ;
1356 DIV MS_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1357 CMP AL, T_DRV_TRACKS ;SOURCE MEDIA # OF TRACK > TARGET
1358 ; DEVICE # OF TRACKS?
1359 JA CS_FATAL ;THEN, NOT COMPATIBLE.
1360
1361 DEC AX ;DECREASE BY 1 FOR THE USE OF THIS PROGRAM.
1362 MOV LAST_TRACK, AL ;SET LAST_TRACK
1363 MOV AX, MS_deviceBPB.CSECT_TRACK ;
1364 CMP AL, T_DRV_SECT_TRACK ;SOURCE MEDIA # OF SECT/TRACK > TARGET
1365 ; DEVICE # OF SECT/TRACK?
1366 JA CS_FATAL ;THEN, NOT COMPATIBLE
1367
1368 MOV END_OF_TRACK, AL ;
1369 MOV AX, MS_deviceBPB.CBYTE_SECT ;
1370 MOV bSECTOR_SIZE, AX ;set the sector size in bytes.
1371 CMP USER_OPTION, 1 ;
1372 JE CS_OPTION_1 ;
1373
1374 MOV AX, MS_deviceBPB.CHEAD ;HEAD=1, 2
1375 CMP AL, T_DRV_HEADS ;COMPARE SOURCE MEDIA SIDE WITH
1376 ; TARGET DRIVE HEAD NUMBER
1377 JA CS_FATAL ;SOURCE MEDIUM IS DOUBLE SIDED AND
1378 ; TARGET DRIVE IS SINGLE SIDED.
1379
1380 DEC AX ;
1381 MOV NO_OF_SIDES, AL ;NO_OF_SIDES=0, 1
1382 JMP CS_SET_TABLE ;
1383; = = = = = = = = = = =
1384CS_FATAL: ;
1385 MOV COPY_STATUS, FATAL ;
1386 ;CR,LF,"Drive types or diskette types",CR,LF
1387 ;"not compatible",CR,LF
1388 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;
1389 JMP CS_EXIT ;
1390
1391; = = = = = = = = = = =
1392CS_BAD: ;
1393 MOV COPY_STATUS, FATAL ;
1394 PRINT MSGNUM_BAD_SOURCE ;CR,LF,"SOURCE diskette bad or incompatible"
1395
1396 JMP CS_EXIT ;
1397
1398; = = = = = = = = = = =
1399CS_OLD: ;
1400 MOV READ_S_BPB_FAILURE, 1 ;SET FLAG
1401 MOV bSECTOR_SIZE, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
1402 XOR BX, BX ;
1403 MOV BL, SOURCE_DRIVE ;
1404 MOV IOCTL_TRACK, 0 ;TRACK=0
1405 MOV IOCTL_SECTOR, 8 ;SECTOR=8
1406 MOV IOCTL_HEAD, 0 ;HEAD = 0
1407 CALL READ_A_SECTOR ;
1408
1409 JC CS_BAD ;SOURCE BAD
1410
1411 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR=9
1412 CALL READ_A_SECTOR ;
1413
1414 JC CS_SECT8 ;YES, 8 SECTORS. ASSUME 40 TRACKS
1415
1416 MOV IOCTL_SECTOR, 15 ;try to read sector=15
1417 CALL READ_A_SECTOR ;
1418
1419 JC CS_SECT9 ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
1420
1421 JMP SHORT CS_SECT15 ;
1422
1423; = = = = = = = = = = =
1424CS_OPTION_1: ;
1425 MOV NO_OF_SIDES, 0 ;1 SIDE COPY
1426 JMP SHORT CS_SET_TABLE ;
1427
1428; = = = = = = = = = = =
1429CS_SECT15: ;
1430 MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15
1431 MOV LAST_TRACK, 79 ;
1432 JMP SHORT CS_CHK_SIDE ;
1433
1434; = = = = = = = = = = =
1435CS_SECT8: ;
1436 MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS
1437 MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS.
1438 JMP SHORT CS_CHK_SIDE ;
1439
1440; = = = = = = = = = = =
1441CS_SECT9: ;
1442 MOV END_OF_TRACK, 9 ;
1443 MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE
1444 JMP SHORT CS_CHK_SIDE ;
1445
1446; = = = = = = = = = = =
1447CS_CHK_SIDE: ;
1448 CMP USER_OPTION, 1 ;
1449 JE CS_OPTION_1 ;
1450
1451 MOV IOCTL_HEAD, 1 ;HEAD 1
1452 XOR AX, AX ;
1453 MOV AL, END_OF_TRACK ;READ MATCHING END_OF_TRACK
1454 ; OF THE OTHER SURFACE.
1455 MOV IOCTL_SECTOR, AX ;
1456 CALL READ_A_SECTOR ;
1457
1458 JC CS_OPTION_1 ;1 SIDED SOURCE
1459
1460 MOV NO_OF_SIDES, 1 ;2 SIDED SOURCE
1461 CMP T_DRV_HEADS, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
1462 ; DOUBLE SIDED DRV?
1463 JE CS_SET_TABLE ;
1464
1465 JMP CS_FATAL ;NOT COMPATIBLE
1466
1467; = = = = = = = = = = =
1468CS_SET_TABLE: ;
1469 CMP READ_S_BPB_FAILURE, 1 ;DISKETTE WITHOUT BPB INFO?
1470; $IF E ;
1471 JNE $$IF83
1472 CALL SET_FOR_THE_OLD ;
1473
1474; $ENDIF ;
1475$$IF83:
1476 MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE
1477 CALL SET_TRACKLAYOUT ;
1478
1479 MOV BX, OFFSET MT_trackLayout ;YES, ASSUME TARGET IS SAME
1480 CALL SET_TRACKLAYOUT ;
1481
1482 MOV S_DRV_SET_FLAG, 1 ;
1483 XOR BX, BX ;
1484 MOV BL, SOURCE_DRIVE ;
1485 MOV MS_specialFunctions, SET_SP_FUNC_DEF ;=00000100B
1486 MOV DX, OFFSET MS_IOCTL_DRV_PARM ;
1487 CALL SET_DRV_PARM_DEF ;NOW, SET SOURCE DRIVE PARM
1488 ; FOR READ OPERATION.
1489
1490 XOR AX, AX ;
1491 MOV AL, END_OF_TRACK ;
1492 MOV numberOfSectors, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1493
1494 MOV AL, LAST_TRACK ;NOW, SHOW THE MESSAGE "COPYING ..."
1495 INC AL ;
1496.XLIST ;
1497; MOV BYTE PTR MSG_COPYING_PTR+2, AL ;HOW MANY TRACKS?
1498.LIST ;
1499 MOV BYTE PTR MSG_TRACKS, AL ;AC000;HOW MANY TRACKS?
1500
1501 MOV AL, END_OF_TRACK ;
1502.XLIST ;
1503; MOV BYTE PTR MSG_COPYING_PTR+4, AL ;HOW MANY SECTORS?
1504.LIST ;
1505 MOV BYTE PTR MSG_SECTRK,AL ;AC000;HOW MANY SECTORS?
1506
1507 MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY
1508 INC AL ;
1509.XLIST ;
1510; MOV BYTE PTR MSG_COPYING_PTR+6, AL
1511.LIST ;
1512 MOV BYTE PTR MSG_SIDES,AL ;AC000;HOW MANY SIDES?
1513 ;CR,LF,"Copying %1 tracks",CR,LF
1514 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1515 PRINT MSGNUM_COPYING ;AC000;
1516
1517CS_EXIT: ;
1518 RET ;
1519
1520CHECK_SOURCE ENDP ;
1521; = = = = = = = = = = = =
1522 HEADER <READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ> ;AN000;
1523;******************************************************************************
1524 PUBLIC READ_A_SECTOR ;AN000;MAKE ENTRY IN LINK MAP
1525READ_A_SECTOR PROC NEAR ;
1526; *
1527;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL. *
1528;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY. *
1529;INPUT: BX - LOGICAL DRIVE NUMBER *
1530; IOCTL_SECTOR - SECTOR TO READ *
1531; IOCTL_TRACK - TRACK *
1532; IOCTL_HEAD - HEAD TO READ *
1533; bSECTOR_SIZE - SECTOR SIZE IN BYTES *
1534;OUTPUT: *
1535; IF NOT A SUCCESS, CARRY WILL BE SET *
1536; ALL REGISTORS SAVED *
1537;
1538;******************************************************************************
1539
1540 PUSH AX ;
1541 PUSH BX ;
1542 PUSH CX ;
1543 PUSH DX ;
1544
1545 MOV AX, numberOfSectors ;SAVE IOCTL_R_W TABLE VALUES
1546 MOV SAV_CSECT, AX ;
1547
1548;RAS_AGAIN:
1549; $DO ;
1550$$DO85:
1551 MOV AX, IOCTL_HEAD ;
1552 MOV Head, AX ;SURFACE TO READ
1553 MOV AX, IOCTL_TRACK ;
1554 MOV Cylinder, AX ;TRACK TO READ
1555 MOV AX, IOCTL_SECTOR ;
1556 dec ax ;????? currently
1557 ; firstsector=0 => 1st sector ????
1558 MOV FirstSectors, AX ;SECTOR TO READ
1559 MOV numberOfSectors, 1 ;read just one sector
1560 MOV AX, offset INIT ;READ IT INTO INIT
1561 ; (CURRELTLY, MAX 1K)
1562 MOV TAddress_off, AX ;
1563 MOV TAddress_seg, DS ;
1564 MOV CL, READ_FUNC ;
1565 MOV DX, OFFSET IOCTL_R_W ;POINTS TO CONTROL TABLE
1566 call generic_ioctl ;
1567
1568 CMP IO_ERROR, SOFT_ERROR ;TRY ONCE MORE?
1569; $ENDDO NE ;
1570 JE $$DO85
1571
1572 CMP IO_ERROR, HARD_ERROR ;HARD ERROR?
1573; $IF NE ;
1574 JE $$IF87
1575
1576 CLC ;READ SUCCESS
1577; $ELSE ;
1578 JMP SHORT $$EN87
1579$$IF87:
1580 STC ;SET CARRY
1581; $ENDIF ;
1582$$EN87:
1583 MOV AX, SAV_CSECT ;RESTORE ORIGINAL IOCTL_R_W TABLE
1584 MOV numberOfSectors, AX ;
1585 POP DX ;
1586 POP CX ;
1587 POP BX ;
1588 POP AX ;
1589 RET ;
1590
1591READ_A_SECTOR ENDP ;
1592; = = = = = = = = = = = =
1593 HEADER <CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK> ;AN000;
1594;*****************************************************************************
1595 PUBLIC CALC_TRACK_SIZE ;AN000;MAKE ENTRY IN LINK MAP
1596CALC_TRACK_SIZE PROC NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1597; TRACK (IN SEGMENTS) *
1598;
1599;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE *
1600;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE. *
1601;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT *
1602;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS. *
1603;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh. *
1604;*****************************************************************************
1605
1606 PUSH AX ;
1607 PUSH BX ;
1608 PUSH CX ;
1609
1610 MOV AX, bSECTOR_SIZE ;
1611 MOV CL, 16 ;
1612 DIV CL ;AX / 16 = AL ... AH
1613 CMP AH, 0 ;NO REMAINER?
1614; $IF NE ;
1615 JE $$IF90
1616
1617 INC AL ;THERE REMAINER IS. INC AL
1618
1619; $ENDIF ;
1620$$IF90:
1621 MOV SECTOR_SIZE, AL ;SECTOR_SIZE+ IN PARA.
1622 MOV AL,NO_OF_SIDES ;TRACK_SIZE = (NO OF SIDES
1623 INC AL ; + 1)
1624 MUL END_OF_TRACK ; * END_OF_TRACK
1625 MOV BL,SECTOR_SIZE ; * SECTPR_SIZE
1626 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1627 MOV TRACK_SIZE,AX ;TO STORE A TRACK
1628 POP CX ;
1629 POP BX ;
1630 POP AX ;
1631
1632 RET ;
1633CALC_TRACK_SIZE ENDP ;
1634; = = = = = = = = = = = =
1635 HEADER <CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK> ;AN000;
1636;*****************************************************************************
1637 PUBLIC CHECK_MEMORY_SIZE ;AN000;MAKE ENTRY IN LINK MAP
1638CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COPY 1 TRACK INTO
1639; TO BUFFER ELSE ABORT COPY *
1640;*****************************************************************************
1641 MOV AX,BUFFER_END ;CALCULATE AVAILABLE MEMORY
1642 SUB AX,BUFFER_BEGIN ;IN SEGMENTS
1643 CMP AX,TRACK_SIZE ;DO WE HAVE ENOUGH TO STORE A CYLINDER?
1644; $IF B ;
1645 JNB $$IF92
1646 MOV COPY_STATUS,FATAL ;NO, ABORT COPY
1647 PRINT MSGNUM_UNSUF_MEMORY ;AC000;AND TELL USER WHY
1648
1649; $ENDIF ;
1650$$IF92:
1651 RET ;
1652
1653CHECK_MEMORY_SIZE ENDP ;
1654; = = = = = = = = = = = =
1655 HEADER <SET_FOR_THE_OLD - SET BPB FOR BEFORE-2.0 FMTTED MEDIA> ;AN000;
1656;*****************************************************************************
1657 PUBLIC SET_FOR_THE_OLD ;AN000;MAKE ENTRY IN LINK MAP
1658SET_FOR_THE_OLD PROC NEAR ;
1659
1660;set MS_deviceBPB for before-2.0 formatted media
1661;*****************************************************************************
1662 PUSH AX ;
1663
1664 CMP END_OF_TRACK,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1665 ;NO_OF_SIDES. IF SINGLE SIDE
1666 ; COPY THEN USE BPB48_SINGLE
1667 ;ELSE USE BPB48_DOUBLE.
1668; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1669 JNA $$IF94
1670 MOV SI, OFFSET BPB96 ;
1671; $ELSE ;
1672 JMP SHORT $$EN94
1673$$IF94:
1674 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1675; $IF NE ;IF NOT,
1676 JE $$IF96
1677 MOV SI, OFFSET BPB48_DOUBLE ;USE BPB48 DOUBLE
1678; $ELSE ;
1679 JMP SHORT $$EN96
1680$$IF96:
1681 MOV SI, OFFSET BPB48_SINGLE ;
1682; $ENDIF ;
1683$$EN96:
1684; $ENDIF ;
1685$$EN94:
1686 XOR AX, AX ;
1687 MOV AL, END_OF_TRACK ;
1688
1689 MOV MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1690 MOV DI, OFFSET MS_deviceBPB ;
1691 MOV CX, BPB96_LENG ;
1692 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1693
1694 POP AX ;
1695 RET ;
1696SET_FOR_THE_OLD ENDP ;
1697; = = = = = = = = = = = =
1698 HEADER <SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE> ;AN000;
1699;*****************************************************************************
1700 PUBLIC SET_TRACKLAYOUT ;AN000;MAKE ENTRY IN LINK MAP
1701SET_TRACKLAYOUT PROC NEAR ;
1702
1703;INPUT: BX - POINTER TO DESTINATION
1704;*****************************************************************************
1705
1706 XOR CX, CX ;
1707 MOV CL, END_OF_TRACK ;
1708 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF
1709 ; SECTORS IN A TRACK
1710 ADD BX, 2 ;NOW BX POINTS TO
1711 ; THE FIRST SECTORNUMBER
1712 MOV CX, 1 ;
1713 MOV AX, bSECTOR_SIZE ;
1714
1715; $DO ;
1716$$DO100:
1717 CMP CL, END_OF_TRACK ;
1718; $LEAVE A ;
1719 JA $$EN100
1720
1721 MOV WORD PTR [BX], CX ;
1722 INC BX ;
1723 INC BX ;
1724 MOV WORD PTR [BX], AX ;
1725 INC BX ;
1726 INC BX ;
1727
1728 INC CX ;
1729; $ENDDO ;
1730 JMP SHORT $$DO100
1731$$EN100:
1732
1733 RET ;
1734SET_TRACKLAYOUT ENDP ;
1735; = = = = = = = = = = = =
1736 HEADER <CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?> ;AN000;
1737;*****************************************************************************
1738 PUBLIC CHECK_TARGET ;AN000;MAKE ENTRY IN LINK MAP
1739CHECK_TARGET PROC NEAR ; *
1740; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1741; ** IF A SUCCESS,THEN COMPARES BPB INFO WITH THAT OF SOURCE MEDIA. *
1742; ** IF THEY ARE DIFFERENT, THEN SET FORMAT_FLAG AND RETURN. *
1743; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1744; ** COMPATIBILITY REASON. *
1745;*****************************************************************************
1746
1747; $DO ;
1748$$DO103:
1749 XOR BX, BX ;
1750 MOV BL, TARGET_DRIVE ;
1751 MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1752 MOV CL, GETDEVPARM ;=60h
1753 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1754 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1755 ;WITH DEFAULT DEVICE INFO.
1756 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1757; $ENDDO NE ;
1758 JE $$DO103
1759
1760 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
1761 JE CT_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST.
1762
1763 cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86 for 3.2 diskcopy
1764 je ct_old ;
1765
1766 cmp mt_deviceBPB.chead,0 ;cannot belive the info from dos
1767 je ct_old ;sanity check for divide by 0.
1768
1769 MOV AX, MT_deviceBPB.CTOTSECT ;
1770 CWD ;CONVERT IT TO A DOUBLE WORD
1771 DIV MT_deviceBPB.CSECT_TRACK ;
1772 DIV MT_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1773 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM.
1774 CMP LAST_TRACK, AL ;COMPARE WITH THE LAST TRACK OF SOURCE
1775 JE CT_SECTOR_TRACK ;IF SAME, THEN CHECK SECTOR PER TRACK
1776 ;SINCE NOT THE SAME, CONTINUE...
1777
1778 CMP MT_deviceBPB.CSECT_TRACK,0FH ;AN012;IS TARGET 15 SEC / TRK?
1779 JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE...
1780 ;YES, 15 SEC/TRACK, CONTINUE...
1781
1782 CMP LAST_TRACK,27H ;AN012;IS SOURCE ORIGINALLY 40 TRACK?
1783 JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE...
1784 ;YES, 40 TRACK, CONTINUE...
1785 JMP CT_FATAL ;AN012;ABORT THIS, DO NOT MESS UP THE 1.2M
1786 ; WITH NOBLE ATTEMPTS TO FORMAT
1787CT_SECTOR_TRACK: ;
1788 MOV AX, MT_deviceBPB.CSECT_TRACK ;
1789 CMP END_OF_TRACK, AL ;
1790 JNE CT_FORMAT ;
1791
1792CT_BYTE_SECTOR: ;
1793 MOV AX, MT_deviceBPB.CBYTE_SECT ;
1794 CMP AX, bSECTOR_SIZE ;
1795 JNE CT_FORMAT ;
1796
1797CT_HEAD: ;
1798 MOV AX, MT_deviceBPB.CHEAD ;
1799 DEC AX ;
1800 CMP AL, NO_OF_SIDES ;
1801 JB CT_FORMAT ;IF TARGET SIDE < SOURCE SIDE
1802 ; THEN FORMAT IT.
1803
1804 JMP CT_SET_DRV ;TARGET IS O.K. SET DRIVE PARM
1805 ; AND EXIT
1806
1807CT_FORMAT: ;
1808 PRINT MSGNUM_FORMATTING ;AC000;"Formatting while copying"
1809
1810 MOV FORMAT_FLAG, ON ;
1811 CALL FORMAT_ALL ;FORMAT ALL TRACKS STARTING
1812 ; FROM TRACK_TO_WRITE
1813 JMP CT_EXIT ;
1814
1815CT_OLD: ;AC011;
1816 CMP UKM_ERR,ON ;AN011;IS THIS HARD ERROR "UNKNOWN MEDIA"?
1817 JE CT_FORMAT ;AN011; IF SO, GO TRY FORMATTING
1818 ;SAME OLD... ;AGAIN, THIS DOES
1819 ; NOT RECOGNIZE 3.5 MEDIA
1820 MOV READ_T_BPB_FAILURE, 1 ;SET THE FLAG
1821 XOR BX, BX ;
1822 MOV BL, TARGET_DRIVE ;
1823 MOV IOCTL_TRACK, 0 ;
1824 MOV IOCTL_SECTOR, 8 ;
1825 MOV IOCTL_HEAD, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1826 CALL READ_A_SECTOR ;
1827
1828 JC CT_FORMAT ;ASSUME TARGET MEDIA NOT FORMATTED.
1829
1830 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9
1831 CALL READ_A_SECTOR ;
1832
1833 JC CT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA
1834
1835 MOV IOCTL_SECTOR, 15 ;
1836 CALL READ_A_SECTOR ;
1837
1838 JC CT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA
1839
1840;CT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1841 CMP END_OF_TRACK, 15 ;IS SOURCE ALSO 96 TPI?
1842 JNE CT_FATAL ;NO, FATAL ERROR
1843
1844 JMP CT_EXIT_OLD ;OK
1845
1846CT_8_SECTOR: ;
1847 CMP END_OF_TRACK, 15 ;
1848 JE CT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1849
1850 CMP END_OF_TRACK, 9 ;
1851 JE CT_FORMAT ;IF SOURCE IS 9 SECTOR, THEN
1852 ; SHOULD FORMAT TARGET
1853
1854 JMP CT_EXIT_OLD ;ELSE ASSUME SOURCE IS 8 SECTOR.
1855
1856CT_9_SECTOR: ;
1857 CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI ?
1858 JNE CT_EXIT_OLD ;NO. SOUCE IS 8 OR 9
1859 ; SECTORED 48 TPI DISKETTE
1860
1861CT_FATAL: ;
1862 MOV COPY_STATUS, FATAL ;
1863 ;"Drive types or diskette types"
1864 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;"not compatible"
1865
1866 JMP SHORT CT_EXIT ;
1867
1868CT_EXIT_OLD: ;
1869 MOV CX, MS_deviceBPB_leng ;
1870 MOV SI, OFFSET MS_deviceBPB ;
1871 MOV DI, OFFSET MT_deviceBPB ;
1872 REP MOVSB ;set MT_deviceBPB to MS_deviceBPB
1873CT_SET_DRV: ;
1874 MOV T_DRV_SET_FLAG, 1 ;INDICATE THE TARGET DEFAULT
1875 ; DEVICE PARM HAS BEEN SET.
1876 XOR BX, BX ;
1877 mov bl, last_track ;patch for 3.2 diskcopy, 3/27/86 J.K.
1878 inc bl ;
1879 mov MT_numberOfCylinders, bx ;make sure the # of cyl of the target
1880 MOV BL, TARGET_DRIVE ;
1881 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1882 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
1883 CALL SET_DRV_PARM_DEF ;
1884
1885CT_EXIT: ;
1886 RET ;
1887
1888CHECK_TARGET ENDP ;
1889; = = = = = = = = = = = =
1890 HEADER <CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA> ;AN000;
1891;*****************************************************************************
1892 PUBLIC CHK_MULTI_MEDIA ;AN000;MAKE ENTRY IN LINK MAP
1893CHK_MULTI_MEDIA PROC NEAR ;
1894;IF THE SOURCE IS 96 TPI DISKETTE, AND TARGET IS 48 TPI
1895;DISKETTE, OR VICE VERSA, THEN SET THE CARRY BIT.
1896;THIS ROUTINE BE CALLED WHEN BPB INFORMATIONS OF TARGET HAS BEEN SUCCESSFULLY
1897;READ.
1898;*** CURRENTLY, ONLY 96 TPI DRIVE IN PC_AT CAN HAVE MULTI_MEDIA.
1899;INPUT: AX - TARGET MEDIA CYLINDER NUMBER - 1
1900; LAST_TRACK - SOURCE MEDIA CYLINDER NUMBER - 1
1901;*****************************************************************************
1902 CLC ;CLEAR CARRY
1903 CMP LAST_TRACK, 39 ;SOURCE IS 48 TPI MEDIA?
1904; $IF E,AND ;
1905 JNE $$IF105
1906 CMP AL, 79 ;AND TARGET IS 96 TPI MEDIA?
1907; $IF E ;
1908 JNE $$IF105
1909 STC ;THEN SET CARRY
1910; $ELSE ;
1911 JMP SHORT $$EN105
1912$$IF105:
1913 CMP LAST_TRACK, 79 ;SOURCE IS 96 TPI MEDIA?
1914; $IF E,AND ;
1915 JNE $$IF107
1916 CMP AL, 39 ;AND TARGET IS 48 TPI?
1917; $IF E ;
1918 JNE $$IF107
1919 STC ;
1920; $ENDIF ;
1921$$IF107:
1922; $ENDIF ;
1923$$EN105:
1924 RET ;
1925CHK_MULTI_MEDIA ENDP ;
1926; = = = = = = = = = = = =
1927 HEADER <SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL> ;AN000;
1928;*****************************************************************************
1929 PUBLIC SET_DRV_PARM_DEF ;AN000;MAKE ENTRY IN LINK MAP
1930SET_DRV_PARM_DEF PROC NEAR ;
1931;SET THE DRV PARMAMETERS
1932;INPUT: BL - DRIVE NUMBER
1933; DX - POINTER TO THE DEFAULT PARAMETER TABLE
1934; specialfunc should be set before calling this routine
1935;*****************************************************************************
1936 MOV CL, SETDEVPARM ;=40H
1937 CALL GENERIC_IOCTL ;
1938
1939 RET ;
1940SET_DRV_PARM_DEF ENDP ;
1941; = = = = = = = = = = = =
1942 HEADER <CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT> ;AN000;
1943;*****************************************************************************
1944 PUBLIC CHK_MEDIATYPE ;AN000;MAKE ENTRY IN LINK MAP
1945CHK_MEDIATYPE PROC NEAR ;
1946;SET THE mediaType OF IOCTL_DRV_PARM FOR TARGET DRIVE IN CASE OF FORMAT.
1947;IF TARGET IS A MULTI-MEDIA DEVICE, mediaType SHOULD BE SET CORRECTLY
1948;TO FORMAT THE TARGET MEDIA.
1949;IF EITHER OF LAST_TRACK OR END_OF_TRACK IS LESS THAN THAT OF TARGET
1950;DRIVE, THEN mediaType WILL BE SET TO 1. OTHERWISE, IT WILL BE 0 FOR
1951;THE DEFAULT VALUE.
1952;*****************************************************************************
1953
1954 MOV AL, T_DRV_TRACKS ;TARGET DEVICE MAXIUM TRACKS
1955 DEC AL ;
1956 CMP LAST_TRACK, AL ;COMPARE SOURCE MEDIA # OF TRACKS TO IT
1957; $IF B,OR ;
1958 JB $$LL110
1959 MOV AL, T_DRV_SECT_TRACK ;
1960 CMP END_OF_TRACK, AL ;SOURCE # OF SECT/TRACK < TARGET DEVICE?
1961; $IF B ;
1962 JNB $$IF110
1963$$LL110:
1964 MOV MT_mediaType, 1 ;
1965; $ENDIF ;
1966$$IF110:
1967 RET ;
1968CHK_MEDIATYPE ENDP ;
1969; = = = = = = = = = = = =
1970 HEADER <GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER> ;AN000;
1971;*****************************************************************************
1972 PUBLIC GENERIC_IOCTL ;AN000;MAKE ENTRY IN LINK MAP
1973GENERIC_IOCTL PROC NEAR ;
1974;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1975; 61 - READ TRACK, 41 - WRITE TRACK,
1976; 42 - FORMAT AND VERIFY TRACK, 43 - SET MEDIA ID
1977; 62 - VERIFY TRACK, 63 - GET MEDIA ID
1978; BL - LOGICAL DRIVE LETTER
1979; DS:DX - POINTER TO PARAMETERS
1980;*****************************************************************************
1981 MOV IO_ERROR, NO_ERROR ;reset io_error
1982 MOV CH, MAJOR_CODE ;MAJOR CODE, REMOVABLE = 08H
1983 DOSCALL IOCTL_FUNC,GENERIC_IOCTL_CODE ;AC000;(440DH) CALL THE DEVICE DRIVER
1984
1985; $IF C ;
1986 JNC $$IF112
1987 CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS!
1988
1989; $ENDIF ;
1990$$IF112:
1991 RET ;
1992GENERIC_IOCTL ENDP ;
1993; = = = = = = = = = = = =
1994 HEADER <EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS> ;AN000;
1995;*****************************************************************************
1996 PUBLIC EXTENDED_ERROR_HANDLER ;AN000;MAKE ENTRY IN LINK MAP
1997EXTENDED_ERROR_HANDLER PROC NEAR ;
1998;INPUT: BL - LOGICAL DRIVE LETTER
1999;*****************************************************************************
2000
2001 PUSHF ;
2002 PUSH AX ;
2003 PUSH BX ;
2004 PUSH CX ;
2005 PUSH DX ;
2006 PUSH SI ;
2007 PUSH DI ;
2008 PUSH ES ;
2009 PUSH DS ;
2010 PUSH BX ;
2011
2012 MOV AH, EXTENDED_ERROR ;59H
2013 MOV BX, 0 ;
2014 INT 21H ;
2015
2016 POP BX ;RESTORE BL FOR DRIVE LETTER
2017 POP DS ;
2018 POP ES ;
2019
2020 CMP AX, 21 ;DRIVE NOT READY? (TIME_OUT ERROR?)
2021 JE EEH_CHK_TIMEOUT ;
2022
2023 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
2024 JE WARN_USER_2 ;
2025
2026 JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR
2027
2028EEH_CHK_TIMEOUT: ;BECAUSE OF THE INACCURACY
2029 ; OF TIME OUT ERROR,
2030 ;IN READING AND WRITING OPERATION,
2031 ; CHECK OUT CAREFULLY WITH "FORMAT"
2032 CMP FORMAT_FLAG, ON ;AFTER OR DURING FORMAT OPERATION,
2033 JE WARN_USER_1 ; TIME OUT ERROR IS
2034 ; ASSUMED TO BE CORRECT.
2035
2036 CMP TRY_FORMAT_FLAG, ON ;HAPPENED AT "TRY_FORMAT" PROCEDURE?
2037 JE EEH_TIMEOUT ;
2038
2039 CMP TARGET_OP, ON ;HAPPENED ON TARGET DRIVE?
2040 JNE WARN_USER_1 ;IF NOT, THEN ASSUME TIME OUT ERROR
2041
2042 MOV TRY_FORMAT_FLAG, ON ;
2043 CALL TRY_FORMAT ;JUST TRY TO FORMAT THE TRACK.
2044
2045 MOV TRY_FORMAT_FLAG, OFF ;
2046 CMP TIME_OUT_FLAG, ON ;REAL TIME OUT?
2047 JE WARN_USER_1 ;YES, A SOFT ERROR.
2048
2049 CMP IO_ERROR, SOFT_ERROR ;IT HAPPENED AT TRY_FORMAT PROC AND
2050 ; PC_AT WHEN THE DRIVE DOOR OPENED ABRUPTLY.
2051 JE EEH_EXIT ;IT WAS WRITE PROTECTED ERROR.
2052
2053 JMP EEH_HARD_ERROR ;NO, "ADDRESS MARK NOT OUT". A HARD ERROR.
2054
2055EEH_TIMEOUT: ;
2056 MOV TIME_OUT_FLAG, ON ;SET TIME_OUT_FLAG AND EXIT THIS ROUTINE
2057 JMP EEH_EXIT ;
2058
2059WARN_USER_1: ;
2060 MOV DRIVE_LETTER, 'A' ;
2061 DEC BL ;CHANGE LOGICAL TO PHYSICAL
2062 ADD DRIVE_LETTER, BL ;
2063 PRINT MSGNUM_GET_READY ;AC000;"Drive not ready - %0"
2064
2065 PRINT MSGNUM_CLOSE_DOOR ;AN004;"Make sure a diskette is inserted into
2066 ; the drive and the door is closed"
2067 JMP WAIT_FOR_USER ;
2068
2069WARN_USER_2: ;
2070 PRINT MSGNUM_WRITE_PROTECT ;AC000;"Attempt to write to write-protected diskette"
2071
2072WAIT_FOR_USER: ;
2073 ;"Press any key when ready . . ."
2074 CALL PRESS_ANY_KEY ;AC000; THEN WAIT FOR ANY RESPONSE
2075
2076 MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN
2077 JMP SHORT EEH_EXIT ;
2078
2079EEH_HARD_ERROR: ;
2080 MOV IO_ERROR, HARD_ERROR ;
2081 MOV UKM_ERR,OFF ;AN011;ASSUME NOT "UNKNOWN MEDIA" TYPE ERROR
2082 CMP AX,26 ;AN011;IS THE ERROR TYPE IS "UNKNOWN MEDIA"?
2083; $IF E ;AN011;IF "UNKNOWN MEDIA" TYPE ERROR
2084 JNE $$IF114
2085 MOV UKM_ERR,ON ;AN011;SET FLAG TO INDICATE "UNKNOWN MEDIA"
2086 ; TO CAUSE FORMATTING OF TARGET DISKETTE
2087; $ENDIF ;AN011;
2088$$IF114:
2089
2090EEH_EXIT: ;
2091 POP DI ;
2092 POP SI ;
2093 POP DX ;
2094 POP CX ;
2095 POP BX ;
2096 POP AX ;
2097 POPF ;
2098 RET ;
2099.XLIST ;
2100;EEH_JUST_EXIT:
2101; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT (IN MAIN PROC)
2102.LIST ;
2103EXTENDED_ERROR_HANDLER ENDP ;
2104; = = = = = = = = = = = =
2105 HEADER <TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY> ;AN000;
2106;*****************************************************************************
2107 PUBLIC TRY_FORMAT ;AN000;MAKE ENTRY IN LINK MAP
2108TRY_FORMAT PROC NEAR ;
2109;*** TRY TO FORMAT A TRACK.
2110;*** CALLED BY "EXTENDED_ERROR_HANDLER" TO CHECK THE TIME OUT ERROR IS A REAL
2111;*** ONE OR CAUSED BY "ADDR MARK NOT FOUND" ERROR.(THIS IS HARDWARE ERROR THAT
2112;*** DOES NOT GIVE CORRECT ERROR CODE).
2113;*** THIS ROUTINE WILL CALL "GENERIC_IOCTL" WHICH IN TURN WILL CALL "EXTENDED_
2114;*** ERROR_HANDLER" WHERE THE ERROR WILL BE REEXAMINED.
2115;*****************************************************************************
2116 PUSH ES ;
2117
2118 PUSH DS ;
2119 POP ES ;
2120
2121 MOV CX, MS_deviceBPB_leng ;set length of BPB
2122 MOV SI, OFFSET MS_deviceBPB ;
2123 MOV DI, OFFSET MT_deviceBPB ;
2124 REP MOVSB ;
2125 CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation
2126
2127 MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
2128 MOV CL, SETDEVPARM ;=40h
2129 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
2130 XOR BX, BX ;
2131 MOV BL, TARGET_DRIVE ;
2132 CALL GENERIC_IOCTL ;
2133
2134 XOR AX, AX ;
2135 MOV AL, SIDE ;SIDE TO FORMAT
2136 MOV Fhead, AX ;
2137 MOV AL, TRACK_TO_WRITE ;TRACK TO FORMAT
2138 MOV Fcylinder, AX ;
2139
2140 XOR BX, BX ;
2141 MOV BL, TARGET_DRIVE ;
2142 MOV CL, FORMAT_FUNC ;=42h
2143 MOV DX, OFFSET IOCTL_FORMAT ;
2144 CALL GENERIC_IOCTL ;
2145
2146 MOV AL, IO_ERROR ;SAVE IO_ERROR, IN CASE FOR PC_AT CASE.
2147 PUSH AX ;
2148
2149 XOR BX, BX ;
2150 MOV BL, TARGET_DRIVE ;
2151 MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
2152 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
2153 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
2154 CALL SET_DRV_PARM_DEF ;SET IT BACK FOR NORMAL
2155 ; OPERATION, EX. WRITING
2156
2157 POP AX ;
2158 MOV IO_ERROR, AL ;RESTORE IO_ERROR
2159
2160 POP ES ;
2161
2162 RET ;
2163
2164TRY_FORMAT ENDP ;
2165; = = = = = = = = = = = =
2166 HEADER <ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE> ;AN000;
2167;*****************************************************************************
2168; *
2169ERROR_MESSAGE PROC NEAR ;DISPLAY ERROR MESSAGE *
2170 PUBLIC ERROR_MESSAGE ;AN000;MAKE ENTRY IN LINK MAP
2171; *
2172; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE) *
2173; AND WHERE IT FAILED (TRACK NO. AND SIDE). *
2174; *
2175; INPUT: AH = IOCTL I/O COMMAND CODE (3=READ, 4=WRITE) *
2176; *
2177;*****************************************************************************
2178 CMP AH,READ_FUNC ;ERROR DURING READ ?
2179.XLIST ;
2180; $IF E
2181; MOV BX,OFFSET READ_ERROR
2182; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING READ OP
2183; MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
2184; $ELSE
2185; MOV BX,OFFSET WRITE_ERROR
2186; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING WRITE OP
2187; MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE
2188; $ENDIF
2189.LIST ;
2190; $IF E ;AN000;YES, READ ERROR
2191 JNE $$IF116
2192 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
2193 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ;AN000;
2194; $ELSE ;AN000;NO, NOT READ, MUST BE WRITE ERROR
2195 JMP SHORT $$EN116
2196$$IF116:
2197 MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE
2198 MOV DI,OFFSET MSGNUM_HARD_ERROR_WRITE ;AN000;
2199; $ENDIF ;AN000;READ ERROR?
2200$$EN116:
2201 MOV AL,SIDE ;
2202 MOV DRIVE_LETTER,"A" ;
2203 dec dl ;change logical drive letter to physical one.
2204 ADD DRIVE_LETTER,DL ;SHOW DRIVE LETTER
2205.XLIST ;
2206; MOV BYTE PTR MSG_HARD_ERROR_PTR+8,AL ;SIDE NUMBER
2207; MOV BYTE PTR MSG_HARD_ERROR_PTR+10,BL ;TRACK NUMBER WHERE THE ERROR
2208.LIST ;
2209 MOV BYTE PTR ERROR_SIDE_NUMBER,AL ;AC000;SIDE NUMBER
2210 MOV BYTE PTR ERROR_TRACK_NUMBER,BL ;AC000;TRACK NUMBER WHERE THE ERROR
2211 ;CR,LF,"Unrecoverable read/write error on drive %1",CR,LF
2212 CALL SENDMSG ;"Side %2, track %3",CR,LF ;ACN000;
2213
2214 RET ;
2215ERROR_MESSAGE ENDP ;
2216.XLIST ;
2217; HEADER <PROMPT - READ RESPONSE FROM KEYBOARD>
2218;KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT
2219;*****************************************************************************
2220; *
2221;PROMPT PROC NEAR ;DISPLAY MESSAGE *
2222; AND GET A USER INPUT CHARACTER *
2223; PUBLIC PROMPT *
2224; *
2225; INPUT: DX = MESSAGE POINTER *
2226; OUTPUT: BYTE USER_INPUT *
2227; *
2228;*****************************************************************************
2229; PUSH AX
2230; MOV AX,KB_INPUT_FUNC ;KEYBOARD INPUT
2231; INT 21H
2232; MOV USER_INPUT,AL ;SAVE USER'S RESPONSE
2233; POP AX
2234; RET
2235;PROMPT ENDP
2236; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
2237;CALL_PRINTF PROC NEAR
2238; PUBLIC CALL_PRINTF
2239;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
2240; PUSH DX
2241; PUSH CS
2242; CALL PRINTF
2243
2244; RET
2245;CALL_PRINTF ENDP
2246; = = = = = = = = = = = =
2247.list ;
2248 HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ;AN000;
2249SENDMSG PROC NEAR ;AN000;
2250 PUBLIC SENDMSG ;AN000;
2251; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
2252; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
2253; IF CARRY CLEAR, ALL OK
2254; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
2255; = = = = = = = = = = = =
2256
2257 PUSH BX ;AN000;SAVE CALLER'S REGS
2258 PUSH CX ;AN000;
2259 PUSH DX ;AN000;
2260 PUSH SI ;AN000;
2261
2262; PASS PARMS TO MESSAGE HANDLER IN
2263; THE APPROPRIATE REGISTERS IT NEEDS.
2264 MOV BX,[DI].MSG_NUM ;AC006;MESSAGE NUMBER
2265 MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2266 MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE
2267 MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2268 MOV AX,SELECT_MPX ;AN006;REQUEST THE SELECT MULTIPLEXOR, IF PRESENT
2269 INT MULTIPLEXOR ;AN006;CALL THE MULTIPLEXOR FUNCTION
2270
2271 CMP AL,SELECT_PRESENT ;AN006;CHECK MULTIPLEXOR RESPONSE CODE
2272; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2273 JE $$IF119
2274 MOV AX,[DI].MSG_NUM ;AN000;MESSAGE NUMBER
2275 MOV BX,[DI].MSG_HANDLE ;AN006;HANDLE TO DISPLAY TO
2276 CALL SYSDISPMSG ;AN000;DISPLAY THE MESSAGE
2277
2278; $IF C ;AN000;IF THERE IS A PROBLEM
2279 JNC $$IF120
2280 ;AX=EXTENDED ERROR NUMBER ;AN000;
2281 LEA DI,MSGNUM_EXTERR ;AN000;GET REST OF ERROR DESCRIPTOR
2282 MOV BX,[DI].MSG_HANDLE ;AN000;HANDLE TO DISPLAY TO
2283 MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2284 MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE
2285 MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2286 CALL SYSDISPMSG ;AN000;TRY TO SAY WHAT HAPPENED
2287
2288 STC ;AN000;REPORT PROBLEM
2289; $ENDIF ;AN000;PROBLEM WITH DISPLAY?
2290$$IF120:
2291; $ELSE ;AN006;SINCE SELECT DID THE MESSAGE
2292 JMP SHORT $$EN119
2293$$IF119:
2294 MOV SELECT_FLAG,TRUE ;AN006;INDICATE SELECT IS DOING THE MESSAGES
2295 CLC ;AN006;GENERATE A "NO PROBLEM" RESPONSE
2296; $ENDIF ;AN006;DID SELECT HANDLE THE MESSAGE?
2297$$EN119:
2298
2299 POP SI ;AN000;RESTORE CALLER'S REGISTERS
2300 POP DX ;AN000;
2301 POP CX ;AN000;
2302 POP BX ;AN000;
2303
2304 RET ;AN000;
2305SENDMSG ENDP ;AN000;
2306; = = = = = = = = = = = =
2307 HEADER <YESNO - DETERMINE IF A RESPONSE IS YES OR NO> ;AN000;
2308YESNO PROC NEAR ;AN000;
2309 PUBLIC YESNO ;AN000;MAKE ENTRY IN LINK MAP
2310;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
2311; SELECT_FLAG - IF SELECT IS DOING MESSAGES, ALWAYS ASSUME "NO"
2312;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
2313; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
2314; = = = = = = = = = = = =
2315
2316 CMP SELECT_FLAG,TRUE ;AN006;IS SELECT DOING THE MESSAGES?
2317; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2318 JE $$IF124
2319 ;AL=SUBFUNCTION, AS:
2320 ; 20H=CAPITALIZE SINGLE CHAR
2321 ; 21H=CAPITALIZE STRING
2322 ; 22H=CAPITALIZE ASCIIZ STRING
2323 ; 23H=YES/NO CHECK
2324 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
2325 ; 80H BIT 1=USE FILE UPPER CASE TABLE
2326 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
2327 MOV AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;AN000;(6523H) GET EXTENDED
2328 ; COUNTRY INFORMATION, (Y/N)
2329 INT 21H ;AN000;SEE IF Y OR N
2330
2331; $ELSE ;AN006;SINCE SELECT IS NOT PRESET
2332 JMP SHORT $$EN124
2333$$IF124:
2334 MOV AX,NO ;AN006;ASSUME RESPONSE WAS 'NO'
2335; $ENDIF ;AN006;
2336$$EN124:
2337 RET ;AN000;RETURN TO CALLER
2338YESNO ENDP ;AN000;
2339; = = = = = = = = = = = =
2340;(deleted ;AN013;) HEADER <READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE> ;AN000;
2341;(deleted ;AN013;) READ_VOLSER PROC NEAR ; ;AN000;
2342;(deleted ;AN013;) PUBLIC READ_VOLSER ; ;AN000;
2343;(deleted ;AN013;) ;IF THE SOURCE DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN MAKE A NEW ONE
2344;(deleted ;AN013;) ; AND SEND IT TO THE TARGET DISKETTE. FOR OLD STYLE DISKETTES THAT DID NOT
2345;(deleted ;AN013;) ; HAVE ANY VOL SERIAL NUMBER, MAKE NO CHANGE AFTER THE TRADITIONAL FULL COPY.
2346;(deleted ;AN013;) ;INPUT: SOURCE AND TARGET DRIVE ID
2347;(deleted ;AN013;) ; THE TARGET DISKETTE IS A COMPLETE COPY OF THE SOURCE.
2348;(deleted ;AN013;) ;REFERENCED: A_MEDIA_ID_INFO STRUC (DEFINED IN DISKCOPY.EQU)
2349;(deleted ;AN013;) ; = = = = = = = = = = = = = = = = = =
2350;(deleted ;AN013;) ; ISSUE GET MEDIA ID FROM SOURCE
2351;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2352;(deleted ;AN013;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (1=A:, 2=B:, ETC);AN000;
2353;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC);AN000;
2354;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC009;
2355;(deleted ;AN013;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2356;(deleted ;AN013;)
2357;(deleted ;AN013;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2358;(deleted ;AN013;) ; GET CURRENT DATE
2359;(deleted ;AN013;) DOSCALL GET_DATE ;READ SYSTEM DATE ;AN000;
2360;(deleted ;AN013;) ;OUTPUT: DL = DAY (1-31)
2361;(deleted ;AN013;) ; AL = DAY OF WEEK (0=SUN,6=SAT)
2362;(deleted ;AN013;) ; CX = YEAR (1980-2099)
2363;(deleted ;AN013;) ; DH = MONTH (1-12)
2364;(deleted ;AN013;) PUSH CX ;SAVE THESE FOR ;AN000;
2365;(deleted ;AN013;) PUSH DX ; INPUT INTO HASH ALGORITHM ;AN000;
2366;(deleted ;AN013;) ; GET CURRENT TIME
2367;(deleted ;AN013;) DOSCALL GET_TIME ;READ SYSTEM TIME CLOCK ;AN000;
2368;(deleted ;AN013;) ;OUTPUT: CH = HOUR (0-23)
2369;(deleted ;AN013;) ; CL = MINUTES (0-59)
2370;(deleted ;AN013;) ; DH = SECONDS (0-59)
2371;(deleted ;AN013;) ; DL = HUNDREDTHS (0-99)
2372;(deleted ;AN013;)
2373;(deleted ;AN013;) ; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
2374;(deleted ;AN013;) ; MI_SERIAL+0 = DX FROM DATE + DX FROM TIME
2375;(deleted ;AN013;) ; MI_SERIAL+2 = CX FROM DATE + CX FROM TIME
2376;(deleted ;AN013;)
2377;(deleted ;AN013;) POP AX ;GET THE DX FROM DATE ;AN000;
2378;(deleted ;AN013;) ADD AX,DX ;ADD IN THE DX FROM TIME ;AN000;
2379;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL,AX ;SAVE FIRST RESULT OF HASH;AN000;
2380;(deleted ;AN013;)
2381;(deleted ;AN013;) POP AX ;GET THE CX FROM DATE ;AN000;
2382;(deleted ;AN013;) ADD AX,CX ;ADD IN THE CX FROM TIME ;AN000;
2383;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL+WORD,AX ;SAVE SECOND RESULT OF HASH;AN000;
2384;(deleted ;AN013;)
2385;(deleted ;AN013;) MOV VOLSER_FLAG,TRUE ;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN;AN000;
2386;(deleted ;AN013;) $ENDIF ; ;AN000;
2387;(deleted ;AN013;) RET ;RETURN TO CALLER ;AN000;
2388;(deleted ;AN013;) READ_VOLSER ENDP ; ;AN000;
2389; = = = = = = = = = = = = = = = = = = =
2390 HEADER <WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET> ;AN000;
2391WRITE_VOLSER PROC NEAR ;AN000;
2392 PUBLIC WRITE_VOLSER ;AN000;MAKE ENTRY IN LINK MAP
2393 CMP VOLSER_FLAG,TRUE ;AN000;IF NEW NUMBER READY TO BE WRITTEN
2394; $IF E ;AN000;THEN WRITE IT
2395 JNE $$IF127
2396
2397;NOTE FOR ;AN013;
2398;THERE IS NO NEED TO DO A SET MEDIA ID TO WRITE OUT THE MODIFIED SERIAL NUMBER
2399;BECAUSE THAT NUMBER WAS CHANGED IN THE IMAGE OF THE BOOT RECORD WHEN THE
2400;ORIGINAL BOOT RECORD WAS READ IN, SO WHEN THAT TRACK IMAGE WAS WRITTEN,
2401;IT CONTAINED THE NEW SERIAL NUMBER ALREADY.
2402
2403;(deleted ;AN013;) ; ISSUE SET MEDIA ID TO TARGET
2404;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2405;(deleted ;AN013;) MOV BL,TARGET_DRIVE ;BL=DRIVE NUM ;AN000;
2406;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see STRUC above);AN000;
2407;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,SET_ID ;(6901H) SET MEDIA ID ;AC009;
2408
2409; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
2410; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF
2411; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
2412; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
2413; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 26A SUBLIST,
2414; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
2415; REPRESENTED BY THE 26B SUBLIST.
2416
2417 LEA AX,SERIAL ;AC013;GET POINTER TO DATA TO BE PRINTED
2418 MOV SUBLIST_26B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
2419
2420 LEA AX,SERIAL+WORD ;AC013;GET POINTER TO DATA TO BE PRINTED
2421 MOV SUBLIST_26A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
2422
2423 PRINT MSGNUM_CR_LF ;AN000;SKIP A SPACE
2424
2425 ;"Volume Serial Number is %1-%2"
2426 PRINT MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER
2427
2428; $ENDIF ;AN000;
2429$$IF127:
2430 RET ;AN000;RETURN TO CALLER
2431WRITE_VOLSER ENDP ;AN000;
2432; = = = = = = = = = = = = = = = = = = =
2433 HEADER <PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT> ;AN000;
2434PRESS_ANY_KEY PROC NEAR ;
2435;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
2436;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
2437;PRECEEDING MESSAGES.
2438; = = = = = = = = = = = =
2439 PRINT MSGNUM_CR_LF ;AN000;SKIP A SPACE
2440
2441 PRINT MSGNUM_STRIKE ;AN000;"Press any key when ready..."
2442
2443 RET ;AN000;RETURN TO CALLER
2444PRESS_ANY_KEY ENDP ;AN000;
2445; = = = = = = = = = = = =
2446 PUBLIC DISKCOPY_END ;
2447DISKCOPY_END LABEL NEAR ;
2448
2449 PATHLABL DISKCOPY ;AN015;
2450CSEG ENDS ;
2451 END DISKCOPY ;
2452 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU b/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU
new file mode 100644
index 0000000..914fc43
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU
@@ -0,0 +1,207 @@
1 IF1 ;
2 %OUT COMPONENT=DISKCOPY, INCLUDING DISKCOPY.EQU... ;
3 ENDIF ;
4; $SALUT (4,21,26,36)
5;---------------------------------------------------------------------------;
6; EQUATES ;
7;---------------------------------------------------------------------------;
8
9; *** CONSTANTS ***
10
11ZERO EQU 0 ;
12ONE EQU 1 ;
13TWO EQU 2 ;
14THREE EQU 3 ;
15FOUR EQU 4 ;
16TYPE_4 EQU 4 ;
17FIVE EQU 5 ;
18SIX EQU 6 ;
19SEVEN EQU 7 ;
20EIGHT EQU 8 ;
21NINE EQU 9 ;
22TEN EQU 0AH ;
23ON EQU 1 ;
24OFF EQU 0 ;
25TRUE EQU 01 ;
26FALSE EQU 00 ;
27GOOD EQU 0 ;
28BAD EQU 1 ;
29FIRST EQU 1 ;
30SECOND EQU 2 ;
31NO_ERROR EQU 0 ;
32SOFT_ERROR EQU 1 ;
33HARD_ERROR EQU 2 ;
34
35BLANK EQU 20H ;BLANK IN ASCII (32 DEC)
36CLEAR_SEGMENT EQU 0E0H ;USED TO CLEAR SEGMENT BITS (ROUND UP
37 ;TO NEXT SECTOR)
38SECTOR8 EQU 8 ;
39SECTOR9 EQU 9 ;
40SECTOR14 EQU 14 ;
41SECTOR15 EQU 15 ;
42DRV_48TPI EQU 0 ;48 TPI DRIVE
43DRV_96TPI EQU 1 ;96 TPI DRIVE
44DRV_720 EQU 2 ;3.5", 720 KB DRIVE (FOR CASHEW OR P14)
45NRLFUNC EQU 5F02H ;GET NETWORK-REDIRECTION-LIST FUNCTION
46NRLMAX EQU 1CH ;(MAXIMUM # OF NAMES ON NRL) - 1
47DOS20 EQU 2 ;DOS VERSION 2.0
48 PUBLIC FINE ;AN000;PARSER NEEDS IT
49FINE EQU -1 ;"FINE AND DANDY", USED FOR RETURN CODE
50 ;(-1 WAS USED TO AVOID CONFUSION WITH ERROR
51 ;OFFSET WHICH CAN BE ZERO)
52LOCAL_DRV EQU -1 ;DEVICE NOT DIRECTED
53REMOTE_DRV EQU 1000H ;REMOTE DRIVE TEST BITS
54NO_OPTION EQU -1 ;NO OPTION "/1" SPECIFIED
55OPTION_1 EQU 1 ;OPTION "/1" SPECIFIED
56REMOVABLE EQU 0000H ;REMOVABLE FILE
57INVAL_PARM EQU -9 ;INVALID PARAMETER ENTERED
58; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
59; *** COPY STATUS BYTE ***
60
61FATAL EQU 01H ;FATAL COPY ERROR, ABORT
62OK EQU 00H ;OK, PROCEED
63; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
64; *** PROGRAM SEGMENT PREFIX ***
65
66FCB1_DRV_ID EQU 5CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 1
67FCB1_FILENM EQU 5DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 1
68FCB2_DRV_ID EQU 6CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 2
69FCB2_FILENM EQU 6DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 2
70BEGIN_UNFORM_AREA EQU 80H ;BEGINNING @ OF THE UNFORMATTED AREA
71END_UNFORM_AREA EQU 100H ;ENDING @ OF THE UNFORMATTED AREA
72; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
73; *** DOS FUNCTONS ***
74
75KB_INPUT_FUNC EQU 01H ;DOS KEYBOARD INPUT FUNCTION
76PRINT_FUNC EQU 09H ;DOS PRINT STRING FUNCTION
77REDIRECTED_FUNC EQU 09H ;IOCTL SUB FUNCTION ****** TO BE CHECKED ****
78CURRENTDRV_FUNC EQU 19H ;GET CURRENT DRIVE FUNCTION CALL
79DOSVER_FUNC EQU 30H ;DOS VERSION FUNCTION CALL
80IOCTL_FUNC EQU 44H ;IOCTL FUNCTION CALL
81GET_DISKBASE_VECTOR EQU 351EH ;
82SET_DISKBASE_VECTOR EQU 251EH ;
83GET_CTL_BREAK_VECT EQU 3523H ;AN000;GET VECTOR FOR INT 23H (CTRL-BREAK)
84SET_CTL_BREAK_VECT EQU 2523H ;AN000;SET VECTOR FOR INT 23H (CTRL-BREAK)
85DRIVE_CHECK EQU 4408H ;DOS CHECK FOR REMOVABLE DRIVE IOCTL CALL
86STD_ERROR EQU 0002H ;STANDARD ERROR FILE HANDLE
87WRITE_FILE EQU 40H ;WRITE TO FILE OR DEVICE FUNCTION CALL
88GET_ASSIGN_MODE EQU 5F00H ;SET ASSIGN MODE COMMAND
89SET_ASSIGN_MODE EQU 5F01H ;SET ASSIGN MODE COMMAND
90SERVER EQU 2AH ;NETWORK SERVER INTERUPT
91SHARED EQU 03H ;DEVICE SHARED CHECK
92EXTENDED_ERROR EQU 59H ;EXTENDED ERROR
93GET_DATE EQU 2AH ;AN000;READ SYSTEM DATE
94GET_TIME EQU 2CH ;AN000;READ SYSTEM TIME CLOCK
95RET_CD_EXIT EQU 4CH ;AN000;EXIT TO DOS, PASSING RETURN CODE
96GET_EXT_CNTRY_INFO EQU 65H ;AN000;GET EXTENDED COUNTRY INFORMATION
97YESNO_CHECK EQU 23H ;AN000;REQUEST (Y/N) CHECK OF GET_EXT_CNTRY_INFO
98NO EQU 0 ;AN006;(Y/N) RESPONSE IS "NO"
99YES EQU 1 ;AN000;(Y/N) RESPONSE IS "YES"
100BAD_YESNO EQU 2 ;AN000;(Y/N) RESPONSE IS NEITHER "Y" NOR "N"
101; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
102; *** IOCTL DISKETTE I/O FUNCTONS ***
103GENERIC_IOCTL_CODE EQU 0DH ;GENERIC IOCTL REQUEST
104MAJOR_CODE EQU 08H ;GENERIC IOCTL MAJOR CODE
105READ_FUNC EQU 61H ;IOCTL DISKETTE READ FUNCTION
106WRITE_FUNC EQU 41H ;IOCTL DISKETTE WRITE FUNCTION
107VERIFY_FUNC EQU 62H ;IOCTL DISKETTE VERIFY FUNCTION
108FORMAT_FUNC EQU 42H ;IOCTL DISKETTE FORMAT FUNCTION
109GETDEVPARM EQU 60H ;IOCTL GET DEVICE PARAMETER
110SETDEVPARM EQU 40H ;IOCTL SET DEVICE PARAMETER
111SET_LOGIC_DRIVE EQU 0FH ;AN000;IOCTL SET LOGICAL DRIVE
112;(deleted ;AN013) GSET_MEDIA_ID EQU 69H ;GET OR SET MEDIA ID ;AN009;
113;(deleted ;AN013) GET_ID EQU 0 ;AL=0;GET MEDIA ID ;AN009;
114;(deleted ;AN013) SET_ID EQU 1 ;AL=1;SET MEDIA ID ;AN009;
115
116;special Functions
117GET_SP_FUNC_DEF EQU 00000000B ;GET DEVICE PARM. DEFAULT BPB
118GET_SP_FUNC_MED EQU 00000001B ;GET DEVICE PARM. BOOT BPB
119SET_SP_FUNC_DEF EQU 00000100B ;SET DEFAULT DEVICE PARM
120SET_SP_FUNC_DOS EQU 00000100B ;SET DEVICE PARM BEFORE RETURN TO DOS.
121SET_SP_BF_FORM EQU 00000101B ;SET DEV PARM BEFORE FORMAT
122R_W_SP_FUNC EQU 00000000B ;READ, WRITE
123STATUS_CHK EQU 00000001B ;USED IN FORMAT PACKET AND VALIDATE
124 ;THE "SET DEVICE PARM" REQUEST.
125FORMAT_SP_FUNC EQU 00000000B ;FORMAT
126.XLIST ;
127;READ_DASD_FUNC EQU 15H ;BIOS READ DASD TYPE (DISKETTE DRIVE TYPE)
128;SET_DASD_FUNC EQU 17H ;BIOS SET DASD TYPE
129;COMPARE_FUNC EQU 03H ;BIOS COMPARE FUNC # FOR ERROR MSG PROC
130.LIST ;
131; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
132; *** BIOS DISKETTE I/O ERROR CODES ***
133
134;NOT_READY EQU 80H ;DISKETTE I/O NOT READY ERROR
135;CHANG_LINE EQU 06H ;CHANGE LINE ERROR
136;BAD_CONTROLLER EQU 20H ;BAD DISKETTE/DISK CONTOROLLER
137;WRITE_PROTECT EQU 03H ;DISKETTE I/O WRITE PROTECT ERROR
138;BAD_ADDR_MARK EQU 02H ;DISKETTE I/O BAD ADDRESS MARK ERROR
139;REC_NOT_FOUND EQU 04H ;DISETTTE I/O RECORD NOT FOUND ERROR
140;BAD_CRC EQU 10H ;DISKETTE I/O BAD CRC ERROR
141;HARD_WR_ERROR EQU 03H ;DISKETTE WRITE HARD ERROR COUNT
142;HARD_FMT_ERROR EQU 02H ;DISKETTE FORMAT HARD ERROR COUNT
143;SINGLE_SIDE_COPY EQU 00H ;WHEN READING TRACK 0 SIDE 1 IF HARD ERROR
144 ;OCCURS, WE WILL ASSUME IT WILL BE SINGLE
145 ;SIDED COPY AND AL WILL BE SET TO 0, SO THAT
146 ;BUFFER_PTR WILL NOT BE ADVANCED AND
147 ;IF THE TRACK HAPPENS TO FALL INTO DMA BOUNDRY
148 ;IT WILL SKIP THE SECOND PART OF READ_TRACK
149; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
150; SYSTEM MESSAGE HANDLER EQUATES
151EXT_ERR_CLASS EQU 01H ;AN000;DOS Extended error class
152PARSE_ERR_CLASS EQU 02H ;AN000;Parse error class
153UTILITY_MSG_CLASS EQU 0FFH ;AN000;Utility message class
154CLASS_A EQU UTILITY_MSG_CLASS ;AN000;IN MSG DESCRIPTOR
155MAX_0 EQU 0 ;AN000;MAXIMUM WIDTH OF STRING FIELD (0=NO LIMIT)
156PAD_BLK EQU " " ;AN000;CHAR FOR PAD FIELD
157STDOUT EQU 0001H ;AN000;Standard Output device handle
158STDERR EQU 0002H ;AN000;Standard Error Output device handle
159
160; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
161; SELECT MULTIPLEXOR INTERFACE
162SELECT_MPX EQU 0ADC1H ;AN006;THE SELECT MULTIPLEXOR ID
163SELECT_PRESENT EQU 0FFH ;AN006;RESPONSE IN AL, IF SELECT IS PRESENT
164MULTIPLEXOR EQU 2FH ;AN006;THE MULTIPLEXOR INTERRUPT NUMBER
165;---------------------------------------------------------------------------;
166; CONTROL BLOCKS (STRUCS) ;
167;---------------------------------------------------------------------------;
168
169MSG_DESC STRUC ;
170MSG_NUM DW 0 ;AN000;MESSAGE NUMBER (TO AX)
171MSG_HANDLE DW STDOUT ;AN000;HANDLE OF OUTPUT DEVICE (TO BX)
172MSG_SUBLIST DW 0 ;AN000;POINTER TO SUBLIST (TO SI)
173MSG_COUNT DW 0 ;AN000;SUBSTITUTION COUNT (TO CX)
174MSG_CLASS DW CLASS_A SHL 8 ;AN000;MESSAGE CLASS (IN HIGH BYTE, TO DH)
175 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN000;
176MSG_DESC ENDS ;AN000;
177; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
178SUBLIST STRUC ;AN000;
179SUB_SIZE DB 11 ;AN000;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
180SUB_RES DB 0 ;AN000;RESERVED
181 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD
182SUB_VALUE DW 0 ;AN000;TIME, DATE, OR PTR TO DATA ITEM
183SUB_VALUE_SEG DW 0 ;AN000;SEG ID OF PTR
184 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION
185 ; TIME, IF THIS IS A .COM FILE)
186SUB_ID DB 0 ;AN000;N OF %N
187SUB_FLAGS DB 0 ;AN000;DATA TYPE FLAGS
188SUB_MAX_WIDTH DB MAX_0 ;AN000;MAXIMUM FIELD WIDTH (0=UNLIMITED)
189SUB_MIN_WIDTH DB 0 ;AN000;MINIMUM FIELD WIDTH
190SUB_PAD_CHAR DB PAD_BLK ;AN000;CHARACTER FOR PAD FIELD
191 ; CAN BE " ", "0" OR ",".
192 ; "," CAUSES INSERTION OF THE ACTIVE
193 ; THOUSANDS SEPARATOR BETWEEN EVERY
194 ; 3 DIGITS.
195SUBLIST ENDS ;AN000;
196; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
197;BUFFER AREA FOR COMMUNICATION WITH GET/SET MEDIA ID FUNCTION CALL
198; (USED BY VOLSER PROC)
199
200;(deleted ;AN013;) A_MEDIA_ID_INFO STRUC ; ;AN000;
201;(deleted ;AN013;) MI_LEVEL DW 0 ;INFO LEVEL ;AN000;
202;(deleted ;AN013;) MI_SERIAL DD 0 ;SERIAL # ;AN000;
203;(deleted ;AN013;) MI_LABEL DB 11 DUP (' ') ;VOLUME LABEL ;AN000;
204;(deleted ;AN013;) MI_SYSTEM DB 8 DUP (' ') ;FILE SYSTEM TYPE ;AN000;
205;(deleted ;AN013;) A_MEDIA_ID_INFO ENDS ; ;AN000;
206
207;END OF DISKCOPY.EQU
diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK b/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK
new file mode 100644
index 0000000..b0eaaff
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK
@@ -0,0 +1,6 @@
1DISKCOPY.OBJ+
2DCOPYSM.OBJ+
3DCOPYP.OBJ+
4DCOPYPAR.OBJ+
5COPYINIT.OBJ;
6 \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL b/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL
new file mode 100644
index 0000000..bc346ac
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL
@@ -0,0 +1,65 @@
1:util DISKCOPY ;AN000;utility name
2:class A ;AN000;system messages
3:use 1 COMMON1 ;AN000;MSG 1 is always "Incorrect DOS version"
4
5:def 2 CR,LF ;AN000;
6
7:use 3 PARSE10 ;AN000;CR,LF,"Invalid parameter",CR,LF
8
9:def 4 "Do not specify filename(s)",CR,LF ;AN000;
10"Command Format: DISKCOPY d: d: [/1]",CR,LF ;AN000;
11
12:def 5 CR,LF,"Invalid drive specification",CR,LF ;AN000;
13"Specified drive does not exist",CR,LF ;AN000;
14"or is non-removable",CR,LF ;AN000;
15
16:def 6 CR,LF,"Cannot DISKCOPY to or from",CR,LF ;AN000;
17"a network drive",CR,LF ;AN000;
18
19:def 7 CR,LF,"Formatting while copying",CR,LF ;AN000;
20
21:def 8 CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF ;AN000;
22
23:def 9 CR,LF,"Insert TARGET diskette in drive %1:",CR,LF ;AN000;
24
25:def 10 "Make sure a diskette is inserted into",CR,LF ;AN004;
26"the drive and the door is closed",CR,LF ;AN004;
27
28:def 11 CR,LF,"Target diskette may be unusable",CR,LF ;AN000;
29
30:def 12 CR,LF,"Target diskette unusable",CR,LF ;AN000;
31
32:use 13 EXTEND21 ;AN000;CR,LF,Drive not ready",CR,LF
33
34:use 14 EXTEND19 ;AN000;CR,LF,"Attempt to write to write-protected diskette",CR,LF
35
36:use 15 COMMON28 ;AN000;CR,LF,"Press any key to continue . . .",CR,LF
37
38:def 16 CR,LF,"Copy another diskette (Y/N)? " ;AN000;
39
40:def 17 CR,LF,"Copying %1 tracks",CR,LF ;AN000;
41"%2 Sectors/Track, %3 Side(s)",CR,LF ;AN000;
42
43:def 18 CR,LF,"Drive types or diskette types",CR,LF ;AN000;
44"not compatible",CR,LF ;AN000;
45
46:def 19 CR,LF,"Unrecoverable read error on drive %1",CR,LF ;AN000;
47"Side %2, track %3",CR,LF ;AN000;
48
49:def 20 CR,LF,"Unrecoverable write error on drive %1",CR,LF ;AN000;
50"Side %2, track %3",CR,LF ;AN000;
51
52:def 21 CR,LF,"Copy process ended",CR,LF ;AN000;
53
54:def 22 CR,LF,"SOURCE diskette bad or incompatible",CR,LF ;AC008;
55
56:def 23 CR,LF,"TARGET diskette bad or incompatible",CR,LF ;AC008;
57
58:use 25 EXTEND8 ;AN000;"Insufficient memory",CR,LF
59
60:use 26 COMMON36 ;AN001;"Volume Serial Number is %1-%2",CR,LF
61
62:end ;AN000;
63lume Serial Number is %1-%2",CR,LF
64
65:end \ No newline at end of file
diff --git a/v4.0/src/CMD/DISKCOPY/MAKEFILE b/v4.0/src/CMD/DISKCOPY/MAKEFILE
new file mode 100644
index 0000000..9a3e564
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/MAKEFILE
@@ -0,0 +1,57 @@
1#************************** makefile for cmd\append ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: diskcopy.com
13
14diskcopy.ctl: diskcopy.skl \
15 $(msg)\$(COUNTRY).msg \
16 makefile
17
18diskcopy.obj: diskcopy.asm \
19 makefile \
20 dcpymacr.inc \
21 diskcopy.equ \
22 $(inc)\bootform.inc
23
24copyinit.obj: copyinit.asm \
25 makefile \
26 dcpymacr.inc \
27 diskcopy.equ
28
29dcopyp.obj: dcopyp.asm \
30 makefile \
31 $(inc)\parse.asm
32
33dcopysm.obj: dcopysm.asm \
34 makefile \
35 $(inc)\sysmsg.inc \
36 $(inc)\msghan.inc \
37 $(inc)\versiona.inc \
38 diskcopy.ctl \
39 diskcopy.cla \
40 diskcopy.cl1 \
41 diskcopy.cl2 \
42 dcopyms.inc \
43 $(inc)\copyrigh.inc
44
45dcopypar.obj: dcopypar.asm \
46 makefile
47
48diskcopy.com: diskcopy.obj \
49 makefile \
50 diskcopy.lnk \
51 dcopysm.obj \
52 dcopyp.obj \
53 dcopypar.obj \
54 copyinit.obj
55 link @diskcopy.lnk
56 exe2bin diskcopy.exe diskcopy.com
57 del diskcopy.exe