Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-1


					PAGE	90,132			;A2
					TITLE	DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;
				;****************** START OF SPECIFICATIONS *****************************
				; MODULE NAME: DISKCOPY
				
				; DESCRIPTIVE NAME: Diskette to diskette complete copy Utility
				
				;FUNCTION: DISKCOPY is to copy the contents of the diskette in the
				;	   specified source drive to the diskette in the target
				;	   drive.  If necessary, the target diskette is also
				;	   formatted.
				
				
				;	   Multiple copies may be performed with one load of DISKCOPY.
				;	   A prompt, "Copy another (Y/N)?" permits additional
				;	   executions, all with the same drive specifications.
				
				; ENTRY POINT: "DISKCOPY" at ORG 100h, jumps to "BEGIN".
				
				; INPUT: (DOS command line parameters)
				;	 [d:][path]DISKCOPY [d: [D:]][/1]
				
				;	 Where
				
				;	 [d:][path] before DISKCOPY to specify the drive and path that
				;		    contains the DISKCOPY command file.
				
				;	 [d:]	    to specify the source drive id
				
				;	 [D:]	    to specify the destination drive id
				
				;	 [/1]	    to request single sided operations only
				
				; EXIT-NORMAL: Errorlevel = 0
				;	      Function completed successfully.
				
				; EXIT-ERROR: Errorlevel = 1
				;	      Abnormal termination due to error, wrong DOS,
				;	      invalid parameters, unrecoverable I/O errors on
				;	      the diskette.
				;
				;	      Errorlevel = 2
				;	      Termination requested by Cntrl-Break.
				
				; EFFECTS: The entire source diskette is copied, including the unused
				;	   sectors.  There is no awareness of the separate files
				;	   involved.  A unique volume serial number is generated
				;	   for the target diskette.
				
				; INCLUDED FILES:
				;	INCLUDE DCPYMACR.INC		;(formerly called MACRO.DEF)
				;	INCLUDE DISKCOPY.EQU		;EQUATES
				;	INCLUDE BOOTFORM.INC		;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
				;	INCLUDE PATHMAC.INC		;PATHGEN MACRO
				
				; INTERNAL REFERENCES:
				;    ROUTINES:
				;	 BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
				;	 SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE
				;	 COPY - COPY THE DISKETTE IMAGE
				;	 TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER
				;	 READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE
				;	 WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE
				;	 READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY
				;	 READ_OP - IOCTL READ A TRACK OPERATION
				;	 MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT
				;	 WRITE_OP - IOCTL WRITE A TRACK OPERATION
				;	 FORMAT_ALL - FORMATS ALL TRACKS TO END
				;	 FORMAT_TRACK - IOCTL FORMAT A TRACK
				;	 CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE
				;	 READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ
				;	 CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK
				;	 CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK
				;	 SET_FOR_THE_OLD  - SET BPB FOR BEFORE-2.0 FMTTED MEDIA
				;	 SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE
				;	 CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?
				;	 CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA
				;	 SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL
				;	 CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT
				;	 GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER
				;	 EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS
				;	 TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY
				;	 ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE
				;	 SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
				;	 YESNO - DETERMINE IF A RESPONSE IS YES OR NO
				;(DELETED ;AN013;)READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-2


				;	 WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET
				;    DATA AREAS:
				;	PSP - Contains the DOS command line parameters.
				;	WORKAREA - Temporary storage
				
				; EXTERNAL REFERENCES:
				;    ROUTINES:
				;	SYSDISPMSG - Uses the MSG parm lists to construct the messages
				;		 on STDOUT.
				;	SYSLOADMSG - Loads messages, makes them accessable.
				;	SYSPARSE - Processes the DOS Command line, finds parms.
				
				;    DATA AREAS:
				;	 DCOPYSM.SAL - Defines the control blocks that describe the messages
				;	 DCOPYPAR.SAL - Defines the control blocks that describe the
				;		DOS Command line parameters.
				
				; NOTES:
				;	 This module should be processed with the SALUT preprocessor
				;	 with the re-alignment not requested, as:
				
				;		SALUT DISKCOPY,NUL
				
				;	 To assemble these modules, the alphabetical or sequential
				;	 ordering of segments may be used.
				
				;	 Sample LINK command:
				
				; LINK @DISKCOPY.ARF
				
				; Where the DISKCOPY.ARF is defined as:
				
				;	 DISKCOPY+
				;	 DCOPYSM+
				;	 DCOPYP+
				;	 DCOPYPAR+
				;	 COPYINIT
				
				;	 These modules must be linked in this order.  The load module is
				;	 a COM file, to be converted to COM with EXE2BIN.
				
				; REVISION HISTORY:
				;	     A000 Version 4.00: add PARSER, System Message Handler,
				;		  Make new unique vol serial number on new diskette.
				;	     A001 DCR 27, display vol serial number, if present.
				;	     A002 ptm473 Flag duplicate switches as error
				;	     A003 Display parm in error
				;	     A004 PTR752 Add close door to drive not ready
				;	     A005 PTR756 After bad parms, specify help info
				;	     A006 DCR210 SELECT, if present, handles all msgs
				;	     A007 PTM1100 Clear keyboard buffer before input response
				;	     A008 PTM1434 CR,LF MISSING FROM MSGS 22 AND 23
				;	     A009 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
				;	     A010 PTM1821 Move INCLUDE COPYRIGH.INC into MSG_SERVICE macro.
				;	     A011 PTM1837 ADD CHECK FOR UNKNOWN MEDIA TO TRIGGER FORMAT
				;	     A012 PTM2441 COPY FROM 360 TO 1.2 CLOBBERS 1.2
				;	     A013 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
				;			REMOVE USE OF GET/SET MEDIA ID
				;	     A014 PTM3262 specify BASESW EQU 1 before PARSE.ASM
				;	     A015 PTM3512 PATHGEN
				;
				; COPYRIGHT: The following notice is found in the OBJ code generated from
				;	     the "DCOPYSM.SAL" module:
				
				;	     "Version 4.00 (C) Copyright 1988 Microsoft"
				;	     "Licensed Material - Property of Microsoft  "
				
				;PROGRAM AUTHOR: Original written by: JK
				;		 4.00 modifications by: EMK
				;****************** END OF SPECIFICATIONS *****************************
				
				;*****************************************************************************
				;									     *
				;			     D I S K C O P Y				     *
				;									     *
				;  UPDATE HISTORY: 7-31, 8-3, 8-5A, 8-6, 8-7, 8-8, 8-10, 8-11, 8-13, 8-14    *
				;		   8-16, 8-17, 8-18, 8-20, 8-28, 9-3, 9-11, 10-6, 10-11      *
				;		   11-7,11-12, 11-17, 11-18, 12-19, 2-16-84, 3-27, 4-5, 4-7  *
				;		   6-20,7-23,10-31,3-27,4-24				     *
				;									     *
				;*****************************************************************************
				
				
				
				;*****************************************************************************
				;									     *
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-3


				;			     MACRO DEFINITION				     *
				;									     *
				;*****************************************************************************
				
					INCLUDE PATHMAC.INC		;AN015;PATHGEN MACRO
			     C	;;***********************************************************************
			     C	;; NAME: pathlabl
			     C	;; DESC: creates a public label at the spot it is placed, using the name
			     C	;;       given.
			     C	;; INPUT: either module name or procedure name
			     C	;; OUTPUT: public label
			     C	;; LOGIC: LBL-parameter-name will have four values -
			     C	;;            - one for each pass (2)
			     C	;;            - one for start and one for stop
			     C	;;        if LBL is not defined, it is first pass, at beginning label
			     C	;;              - set it to 1 and create the start label
			     C	;;        if LBL = 1, it is first pass, at end label
			     C	;;              - set it to 2 and create stop label
			     C	;;        if LBL = 2, it is second pass, at beginning label
			     C	;;              - set it to 3 and create the start label
			     C	;;        if LBL = 3, it is second pass, at end label
			     C	;;              - set it to 4 and create stop label
			     C	;;        if LBL = 4, it is second pass,
			     C	;;              - this macro has been invoked more than twice with same parm
			     C	;;              - issue error message
			     C	;;***********************************************************************
			     C	
			     C	pathlabl MACRO pnam
			     C	IFNDEF LBL_&pnam                        ;;IF THIS IS THE FIRST TIME,
			     C	    LBL_&pnam = 0                       ;;DEFINE IT, INITIALLY ZERO
			     C	ELSE                                    ;;SINCE IT IS DEFINED
			     C	    IF (LBL_&pnam GT 3)                 ;;IF USED TOO MANY TIMES,
			     C	        .ERR NON-UNIQUE OPERAND ON PATHLABL
			     C	        EXITM                           ;;ABORT THIS GENERATION
			     C	    ENDIF
			     C	ENDIF
			     C	
			     C	IF (LBL_&pnam EQ 0) OR (LBL_&pnam EQ 2) ;;ready for START?
			     C	    $$A_START_&pnam:                    ;;create START label
			     C	    PUBLIC $$A_START_&pnam              ;;make it public
			     C	ELSE                                    ;;SINCE SWITCH MAY BE 1 OR 3,
			     C	    $$A_STOP_&pnam:                     ;;create STOP label
			     C	    PUBLIC $$A_STOP_&pnam               ;;make it public
			     C	ENDIF
			     C	LBL_&pnam = LBL_&pnam + 1               ;;INCREMENT SWITCH
			     C	ENDM
					INCLUDE DCPYMACR.INC		;(formerly called MACRO.DEF)
			     C	;***************************************************************************;
			     C	;			     MACRO DEFINITION				    ;
			     C	;***************************************************************************;
			     C	
			     C	HEADER	MACRO	TEXT			;AN000;
			     C	.XLIST					;AN000;
			     C		SUBTTL	&TEXT			;AN000;
			     C	.LIST					;AN000;
			     C		PAGE				;AN000;
			     C		ENDM				;AN000;
			     C	;  =  =  =  =  =  =  =	=  =
			     C	;				   $SALUT (0,36,40,44)
			     C	DOSCALL 			   MACRO FUNC,SUBFUNC ;;AN000;
			     C					   IFNB <FUNC> ;;AN000;IS THERE ANY PARMS AT ALL?
			     C					   IFNB <SUBFUNC> ;;AN000;
			     C					   MOV AX,(FUNC SHL 8)+SUBFUNC ;;AN000;FUNC TO AH,SUBFUNC TO AL
			     C					   ELSE    ;;AN000;SINCE THERE IS NO SUBFUNC
			     C					   MOV AH,FUNC ;;AN000;
			     C					   ENDIF   ;;AN000;
			     C					   ENDIF   ;;AN000;
			     C					   INT 21H ;;AN000;
			     C					   ENDM    ;;AN000;
			     C	;  =  =  =  =  =  =  =	=  =
			     C	PRINT				   MACRO MESSAGE;;AN000;
			     C					   MOV DI,OFFSET MESSAGE  ;;AC000;
			     C					   CALL SENDMSG 	  ;;AC000;
			     C					   ENDM 		  ;;AN000;
			     C	;  =  =  =  =  =  =  =	=  =
			     C	;	       $SALUT (0,16,22,36)
			     C	MY_TRACKLAYOUT MACRO		   ;AN000;
			     C		       LOCAL CSECT_F							;AN000;
			     C	CSECT_F        DW    0		   ;;AN000;# OF SECTORS IN A TRACK. Currently 18 is max.
			     C					   ;;  THE REST IS FOR FUTURE MEDIA
			     C		       DW    1		   ;;AN000;1 ST SECTOR
			     C		       DW    512	   ;;AN000;# OF BYTES
			     C		       DW    2		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    3		   ;;AN000;
			     C		       DW    512	   ;;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-4


			     C		       DW    4		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    5		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    6		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    7		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    8		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    9		   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    10 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    11 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    12 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    13 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    14 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    15 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    16 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    17 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    18 	   ;;AN000;
			     C		       DW    512	   ;;AN000;CURRENTLY 18 SECTORS/TRACK IS MAXIMUM
			     C		       DW    19 	   ;;AN000;BELOW IS FOR THE FUTURE MEDIA.
			     C		       DW    512	   ;;AN000;
			     C		       DW    20 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    21 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    22 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    23 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    24 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    25 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    26 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    27 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    28 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    29 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    30 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    31 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    32 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    33 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    34 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    35 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    36 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    37 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    38 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    39 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    40 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    41 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    42 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    43 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    44 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    45 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    46 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-5


			     C		       DW    47 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    48 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    49 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    50 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    51 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    52 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    53 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    54 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    55 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    56 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    57 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    58 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    59 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    60 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    61 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    62 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       DW    63 	   ;;AN000;
			     C		       DW    512	   ;;AN000;
			     C		       ENDM								;AN000;
			     C	
					INCLUDE DISKCOPY.EQU		;EQUATES
			     C	;		    $SALUT (4,21,26,36)
			     C	;---------------------------------------------------------------------------;
			     C	;				 EQUATES				    ;
			     C	;---------------------------------------------------------------------------;
			     C	
			     C	;			   *** CONSTANTS ***
			     C	
 = 0000                      C	ZERO		    EQU  0	   ;
 = 0001                      C	ONE		    EQU  1	   ;
 = 0002                      C	TWO		    EQU  2	   ;
 = 0003                      C	THREE		    EQU  3	   ;
 = 0004                      C	FOUR		    EQU  4	   ;
 = 0004                      C	TYPE_4		    EQU  4	   ;
 = 0005                      C	FIVE		    EQU  5	   ;
 = 0006                      C	SIX		    EQU  6	   ;
 = 0007                      C	SEVEN		    EQU  7	   ;
 = 0008                      C	EIGHT		    EQU  8	   ;
 = 0009                      C	NINE		    EQU  9	   ;
 = 000A                      C	TEN		    EQU  0AH	   ;
 = 0001                      C	ON		    EQU  1	   ;
 = 0000                      C	OFF		    EQU  0	   ;
 = 0001                      C	TRUE		    EQU  01	   ;
 = 0000                      C	FALSE		    EQU  00	   ;
 = 0000                      C	GOOD		    EQU  0	   ;
 = 0001                      C	BAD		    EQU  1	   ;
 = 0001                      C	FIRST		    EQU  1	   ;
 = 0002                      C	SECOND		    EQU  2	   ;
 = 0000                      C	NO_ERROR	    EQU  0	   ;
 = 0001                      C	SOFT_ERROR	    EQU  1	   ;
 = 0002                      C	HARD_ERROR	    EQU  2	   ;
			     C	
 = 0020                      C	BLANK		    EQU  20H	   ;BLANK IN ASCII (32 DEC)
 = 00E0                      C	CLEAR_SEGMENT	    EQU  0E0H	   ;USED TO CLEAR SEGMENT BITS (ROUND UP
			     C					   ;TO NEXT SECTOR)
 = 0008                      C	SECTOR8 	    EQU  8	   ;
 = 0009                      C	SECTOR9 	    EQU  9	   ;
 = 000E                      C	SECTOR14	    EQU  14	   ;
 = 000F                      C	SECTOR15	    EQU  15	   ;
 = 0000                      C	DRV_48TPI	    EQU  0	   ;48 TPI DRIVE
 = 0001                      C	DRV_96TPI	    EQU  1	   ;96 TPI DRIVE
 = 0002                      C	DRV_720 	    EQU  2	   ;3.5", 720 KB DRIVE (FOR CASHEW OR P14)
 = 5F02                      C	NRLFUNC 	    EQU  5F02H	   ;GET NETWORK-REDIRECTION-LIST FUNCTION
 = 001C                      C	NRLMAX		    EQU  1CH	   ;(MAXIMUM # OF NAMES ON NRL) - 1
 = 0002                      C	DOS20		    EQU  2	   ;DOS VERSION 2.0
			     C			    PUBLIC FINE    ;AN000;PARSER NEEDS IT
 =-0001                      C	FINE		    EQU  -1	   ;"FINE AND DANDY", USED FOR RETURN CODE
			     C					   ;(-1 WAS USED TO AVOID CONFUSION WITH ERROR
			     C					   ;OFFSET WHICH CAN BE ZERO)
 =-0001                      C	LOCAL_DRV	    EQU  -1	   ;DEVICE NOT DIRECTED
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-6


 = 1000                      C	REMOTE_DRV	    EQU  1000H	   ;REMOTE DRIVE TEST BITS
 =-0001                      C	NO_OPTION	    EQU  -1	   ;NO OPTION "/1" SPECIFIED
 = 0001                      C	OPTION_1	    EQU  1	   ;OPTION "/1" SPECIFIED
 = 0000                      C	REMOVABLE	    EQU  0000H	   ;REMOVABLE FILE
 =-0009                      C	INVAL_PARM	    EQU  -9	   ;INVALID PARAMETER ENTERED
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;		    *** COPY STATUS BYTE ***
			     C	
 = 0001                      C	FATAL		    EQU  01H	   ;FATAL COPY ERROR, ABORT
 = 0000                      C	OK		    EQU  00H	   ;OK, PROCEED
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;		    *** PROGRAM SEGMENT PREFIX ***
			     C	
 = 005C                      C	FCB1_DRV_ID	    EQU  5CH	   ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 1
 = 005D                      C	FCB1_FILENM	    EQU  5DH	   ;FILE NAME ADDR IN FILE CONTROL BLOCK 1
 = 006C                      C	FCB2_DRV_ID	    EQU  6CH	   ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 2
 = 006D                      C	FCB2_FILENM	    EQU  6DH	   ;FILE NAME ADDR IN FILE CONTROL BLOCK 2
 = 0080                      C	BEGIN_UNFORM_AREA   EQU  80H	   ;BEGINNING @ OF THE UNFORMATTED AREA
 = 0100                      C	END_UNFORM_AREA     EQU  100H	   ;ENDING @ OF THE UNFORMATTED AREA
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;			*** DOS FUNCTONS ***
			     C	
 = 0001                      C	KB_INPUT_FUNC	    EQU  01H	   ;DOS KEYBOARD INPUT FUNCTION
 = 0009                      C	PRINT_FUNC	    EQU  09H	   ;DOS PRINT STRING FUNCTION
 = 0009                      C	REDIRECTED_FUNC     EQU  09H	   ;IOCTL SUB FUNCTION ****** TO BE CHECKED ****
 = 0019                      C	CURRENTDRV_FUNC     EQU  19H	   ;GET CURRENT DRIVE FUNCTION CALL
 = 0030                      C	DOSVER_FUNC	    EQU  30H	   ;DOS VERSION FUNCTION CALL
 = 0044                      C	IOCTL_FUNC	    EQU  44H	   ;IOCTL FUNCTION CALL
 = 351E                      C	GET_DISKBASE_VECTOR EQU  351EH	   ;
 = 251E                      C	SET_DISKBASE_VECTOR EQU  251EH	   ;
 = 3523                      C	GET_CTL_BREAK_VECT  EQU  3523H	   ;AN000;GET VECTOR FOR INT 23H (CTRL-BREAK)
 = 2523                      C	SET_CTL_BREAK_VECT  EQU  2523H	   ;AN000;SET VECTOR FOR INT 23H (CTRL-BREAK)
 = 4408                      C	DRIVE_CHECK	    EQU  4408H	   ;DOS CHECK FOR REMOVABLE DRIVE IOCTL CALL
 = 0002                      C	STD_ERROR	    EQU  0002H	   ;STANDARD ERROR FILE HANDLE
 = 0040                      C	WRITE_FILE	    EQU  40H	   ;WRITE TO FILE OR DEVICE FUNCTION CALL
 = 5F00                      C	GET_ASSIGN_MODE     EQU  5F00H	   ;SET ASSIGN MODE COMMAND
 = 5F01                      C	SET_ASSIGN_MODE     EQU  5F01H	   ;SET ASSIGN MODE COMMAND
 = 002A                      C	SERVER		    EQU  2AH	   ;NETWORK SERVER INTERUPT
 = 0003                      C	SHARED		    EQU  03H	   ;DEVICE SHARED CHECK
 = 0059                      C	EXTENDED_ERROR	    EQU  59H	   ;EXTENDED ERROR
 = 002A                      C	GET_DATE	    EQU  2AH	   ;AN000;READ SYSTEM DATE
 = 002C                      C	GET_TIME	    EQU  2CH	   ;AN000;READ SYSTEM TIME CLOCK
 = 004C                      C	RET_CD_EXIT	    EQU  4CH	   ;AN000;EXIT TO DOS, PASSING RETURN CODE
 = 0065                      C	GET_EXT_CNTRY_INFO  EQU  65H	   ;AN000;GET EXTENDED COUNTRY INFORMATION
 = 0023                      C	YESNO_CHECK	    EQU  23H	   ;AN000;REQUEST (Y/N) CHECK OF GET_EXT_CNTRY_INFO
 = 0000                      C	NO		    EQU  0	   ;AN006;(Y/N) RESPONSE IS "NO"
 = 0001                      C	YES		    EQU  1	   ;AN000;(Y/N) RESPONSE IS "YES"
 = 0002                      C	BAD_YESNO	    EQU  2	   ;AN000;(Y/N) RESPONSE IS NEITHER "Y" NOR "N"
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;	*** IOCTL DISKETTE I/O FUNCTONS ***
 = 000D                      C	GENERIC_IOCTL_CODE  EQU  0DH	   ;GENERIC IOCTL REQUEST
 = 0008                      C	MAJOR_CODE	    EQU  08H	   ;GENERIC IOCTL MAJOR CODE
 = 0061                      C	READ_FUNC	    EQU  61H	   ;IOCTL DISKETTE READ FUNCTION
 = 0041                      C	WRITE_FUNC	    EQU  41H	   ;IOCTL DISKETTE WRITE FUNCTION
 = 0062                      C	VERIFY_FUNC	    EQU  62H	   ;IOCTL DISKETTE VERIFY FUNCTION
 = 0042                      C	FORMAT_FUNC	    EQU  42H	   ;IOCTL DISKETTE FORMAT FUNCTION
 = 0060                      C	GETDEVPARM	    EQU  60H	   ;IOCTL GET DEVICE PARAMETER
 = 0040                      C	SETDEVPARM	    EQU  40H	   ;IOCTL SET DEVICE PARAMETER
 = 000F                      C	SET_LOGIC_DRIVE     EQU  0FH	   ;AN000;IOCTL SET LOGICAL DRIVE
			     C	;(deleted ;AN013) GSET_MEDIA_ID  EQU 69H  ;GET OR SET MEDIA ID			;AN009;
			     C	;(deleted ;AN013) GET_ID	 EQU 0	  ;AL=0;GET MEDIA ID			;AN009;
			     C	;(deleted ;AN013) SET_ID	 EQU 1	  ;AL=1;SET MEDIA ID			;AN009;
			     C	
			     C	;special Functions
 = 0000                      C	GET_SP_FUNC_DEF     EQU  00000000B ;GET DEVICE PARM. DEFAULT BPB
 = 0001                      C	GET_SP_FUNC_MED     EQU  00000001B ;GET DEVICE PARM. BOOT BPB
 = 0004                      C	SET_SP_FUNC_DEF     EQU  00000100B ;SET DEFAULT DEVICE PARM
 = 0004                      C	SET_SP_FUNC_DOS     EQU  00000100B ;SET DEVICE PARM BEFORE RETURN TO DOS.
 = 0005                      C	SET_SP_BF_FORM	    EQU  00000101B ;SET DEV PARM BEFORE FORMAT
 = 0000                      C	R_W_SP_FUNC	    EQU  00000000B ;READ, WRITE
 = 0001                      C	STATUS_CHK	    EQU  00000001B ;USED IN FORMAT PACKET AND VALIDATE
			     C					   ;THE "SET DEVICE PARM" REQUEST.
 = 0000                      C	FORMAT_SP_FUNC	    EQU  00000000B ;FORMAT
			     C	.LIST				   ;
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;	       *** BIOS DISKETTE I/O ERROR CODES ***
			     C	
			     C	;NOT_READY	   EQU	   80H	   ;DISKETTE I/O NOT READY ERROR
			     C	;CHANG_LINE	   EQU	   06H	   ;CHANGE LINE ERROR
			     C	;BAD_CONTROLLER    EQU	   20H	   ;BAD DISKETTE/DISK CONTOROLLER
			     C	;WRITE_PROTECT	   EQU	   03H	   ;DISKETTE I/O WRITE PROTECT ERROR
			     C	;BAD_ADDR_MARK	   EQU	   02H	   ;DISKETTE I/O BAD ADDRESS MARK ERROR
			     C	;REC_NOT_FOUND	   EQU	   04H	   ;DISETTTE I/O RECORD NOT FOUND ERROR
			     C	;BAD_CRC	   EQU	   10H	   ;DISKETTE I/O BAD CRC ERROR
			     C	;HARD_WR_ERROR	   EQU	   03H	   ;DISKETTE WRITE HARD ERROR COUNT
			     C	;HARD_FMT_ERROR    EQU	   02H	   ;DISKETTE FORMAT HARD ERROR COUNT
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-7


			     C	;SINGLE_SIDE_COPY  EQU	   00H	   ;WHEN READING TRACK 0 SIDE 1 IF HARD ERROR
			     C					   ;OCCURS, WE WILL ASSUME IT WILL BE SINGLE
			     C					   ;SIDED COPY AND AL WILL BE SET TO 0, SO THAT
			     C					   ;BUFFER_PTR WILL NOT BE ADVANCED AND
			     C					   ;IF THE TRACK HAPPENS TO FALL INTO DMA BOUNDRY
			     C					   ;IT WILL SKIP THE SECOND PART OF READ_TRACK
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;		SYSTEM MESSAGE HANDLER EQUATES
 = 0001                      C	EXT_ERR_CLASS	    EQU  01H	   ;AN000;DOS Extended error class
 = 0002                      C	PARSE_ERR_CLASS     EQU  02H	   ;AN000;Parse error class
 = 00FF                      C	UTILITY_MSG_CLASS   EQU  0FFH	   ;AN000;Utility message class
 =                           C	CLASS_A 	    EQU  UTILITY_MSG_CLASS ;AN000;IN MSG DESCRIPTOR
 = 0000                      C	MAX_0		    EQU  0	   ;AN000;MAXIMUM WIDTH OF STRING FIELD (0=NO LIMIT)
 = 0020                      C	PAD_BLK 	    EQU  " "       ;AN000;CHAR FOR PAD FIELD
 = 0001                      C	STDOUT		    EQU  0001H	   ;AN000;Standard Output device handle
 = 0002                      C	STDERR		    EQU  0002H	   ;AN000;Standard Error Output device handle
			     C	
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;		SELECT MULTIPLEXOR INTERFACE
 = ADC1                      C	SELECT_MPX	    EQU  0ADC1H    ;AN006;THE SELECT MULTIPLEXOR ID
 = 00FF                      C	SELECT_PRESENT	    EQU  0FFH	   ;AN006;RESPONSE IN AL, IF SELECT IS PRESENT
 = 002F                      C	MULTIPLEXOR	    EQU  2FH	   ;AN006;THE MULTIPLEXOR INTERRUPT NUMBER
			     C	;---------------------------------------------------------------------------;
			     C	;			   CONTROL BLOCKS (STRUCS)			    ;
			     C	;---------------------------------------------------------------------------;
			     C	
			     C	MSG_DESC	    STRUC	   ;
 0000  0000                  C	MSG_NUM 	    DW	 0	   ;AN000;MESSAGE NUMBER (TO AX)
 0002  0001                  C	MSG_HANDLE	    DW	 STDOUT    ;AN000;HANDLE OF OUTPUT DEVICE (TO BX)
 0004  0000                  C	MSG_SUBLIST	    DW	 0	   ;AN000;POINTER TO SUBLIST (TO SI)
 0006  0000                  C	MSG_COUNT	    DW	 0	   ;AN000;SUBSTITUTION COUNT (TO CX)
 0008  FF00                  C	MSG_CLASS	    DW	 CLASS_A SHL 8 ;AN000;MESSAGE CLASS (IN HIGH BYTE, TO DH)
			     C					   ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN000;
 000A                        C	MSG_DESC	    ENDS	   ;AN000;
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	SUBLIST 	    STRUC	   ;AN000;
 0000  0B                    C	SUB_SIZE	    DB	 11	   ;AN000;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
 0001  00                    C	SUB_RES 	    DB	 0	   ;AN000;RESERVED
			     C					   ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD
 0002  0000                  C	SUB_VALUE	    DW	 0	   ;AN000;TIME, DATE, OR PTR TO DATA ITEM
 0004  0000                  C	SUB_VALUE_SEG	    DW	 0	   ;AN000;SEG ID OF PTR
			     C					   ;(ABOVE FIELD MUST BE FILLED AT EXECUTION
			     C					   ; TIME, IF THIS IS A .COM FILE)
 0006  00                    C	SUB_ID		    DB	 0	   ;AN000;N OF %N
 0007  00                    C	SUB_FLAGS	    DB	 0	   ;AN000;DATA TYPE FLAGS
 0008  00                    C	SUB_MAX_WIDTH	    DB	 MAX_0	   ;AN000;MAXIMUM FIELD WIDTH (0=UNLIMITED)
 0009  00                    C	SUB_MIN_WIDTH	    DB	 0	   ;AN000;MINIMUM FIELD WIDTH
 000A  20                    C	SUB_PAD_CHAR	    DB	 PAD_BLK   ;AN000;CHARACTER FOR PAD FIELD
			     C					   ; CAN BE " ", "0" OR ",".
			     C					   ; "," CAUSES INSERTION OF THE ACTIVE
			     C					   ; THOUSANDS SEPARATOR BETWEEN EVERY
			     C					   ; 3 DIGITS.
 000B                        C	SUBLIST 	    ENDS	   ;AN000;
			     C	; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
			     C	;BUFFER AREA FOR COMMUNICATION WITH GET/SET MEDIA ID FUNCTION CALL
			     C	; (USED BY VOLSER PROC)
			     C	
			     C	;(deleted ;AN013;) A_MEDIA_ID_INFO     STRUC	      ; 			;AN000;
			     C	;(deleted ;AN013;) MI_LEVEL	       DW   0	      ;INFO LEVEL		;AN000;
			     C	;(deleted ;AN013;) MI_SERIAL	       DD   0	      ;SERIAL # 		;AN000;
			     C	;(deleted ;AN013;) MI_LABEL	       DB   11 DUP (' ') ;VOLUME LABEL          ;AN000;
			     C	;(deleted ;AN013;) MI_SYSTEM	       DB   8 DUP (' ') ;FILE SYSTEM TYPE       ;AN000;
			     C	;(deleted ;AN013;) A_MEDIA_ID_INFO     ENDS	      ; 			;AN000;
			     C	
			     C	;END OF DISKCOPY.EQU
				
				;	       $salut (4,16,22,36) ;AN000;
				MY_BPB	       STRUC		   ;
 0000  0000			CBYTE_SECT     DW    0		   ; 200H  BYTES / SECTOR
 0002  00			CSECT_CLUSTER  DB    0		   ; 2h    SECTORS / CLUSTER
 0003  0000			CRESEV_SECT    DW    0		   ; 1h    RESERVED SECTORS
 0005  00			CFAT	       DB    0		   ; 2h    # OF FATS
 0006  0000			CROOTENTRY     DW    0		   ; 70h   # OF ROOT ENTRIES
 0008  0000			CTOTSECT       DW    0		   ; 02D0h TOTAL # OF SECTORS INCLUDING
								   ; BOOT SECT, DIRECTORIES ...
 000A  00			MEDIA_DESCRIP  DB    0		   ;0FDh   MEDIA DISCRIPTOR
 000B  0000			CSECT_FAT      DW    0		   ; 2h    SECTORS / FAT
 000D  0000			CSECT_TRACK    DW    0		   ;
 000F  0000			CHEAD	       DW    0		   ;
 0011  00000000			CHIDDEN_SECT   DD    0		   ;
 0015  00000000			BIG_TOT_SECT   DD    0		   ;
 0019  0006[				       DB    6 DUP (0)	   ;
	   00			
			 ]	
				
 001F				MY_BPB	       ENDS		   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-8


				
					       INCLUDE BOOTFORM.INC ;AN013;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
			     C		%OUT BOOTFORM.INC...
			     C	;****************************************************************************
			     C	;AN000; - Structure of the Extended IBMBOOT record for DOS -. J.K.
			     C	;AN001; - D304 Include PHYDRV, CURHD to the header structure	 11/09/87 J.K.
			     C	;****************************************************************************
			     C	
 = 0200                      C	BOOT_SIZE		 EQU	 512
 = 0029                      C	EXT_BOOT_SIGNATURE	 EQU	 41		;Extended boot signature
			     C	;
			     C	EXT_BPB_INFO		STRUC
 0000  0000                  C	EBPB_BYTESPERSECTOR	 DW	 ?
 0002  00                    C	EBPB_SECTORSPERCLUSTER	 DB	 ?
 0003  0000                  C	EBPB_RESERVEDSECTORS	 DW	 ?
 0005  00                    C	EBPB_NUMBEROFFATS	 DB	 ?
 0006  0000                  C	EBPB_ROOTENTRIES	 DW	 ?
 0008  0000                  C	EBPB_TOTALSECTORS	 DW	 ?
 000A  00                    C	EBPB_MEDIADESCRIPTOR	 DB	 ?
 000B  0000                  C	EBPB_SECTORSPERFAT	 DW	 ?
 000D  0000                  C	EBPB_SECTORSPERTRACK	 DW	 ?
 000F  0000                  C	EBPB_HEADS		 DW	 ?
 0011  00000000              C	EBPB_HIDDENSECTOR	 DD	 ?
 0015  00000000              C	EBPB_BIGTOTALSECTORS	 DD	 ?
 0019                        C	EXT_BPB_INFO		ENDS
			     C	;
			     C	;AN001; EXT_PHYDRV, EXT_CURHD included in the header for OS2.
			     C	EXT_IBMBOOT_HEADER	STRUC
 0000  0003[                 C	EXT_BOOT_JUMP		DB	3 DUP (?)
	   ??                C	
			 ]   C	
			     C	
 0003  0008[                 C	EXT_BOOT_OEM		DB	8 DUP (?)
	   ??                C	
			 ]   C	
			     C	
 000B  0019[                 C	EXT_BOOT_BPB		DB	type EXT_BPB_INFO dup (?)
	   ??                C	
			 ]   C	
			     C	
 0024  80                    C	EXT_PHYDRV		DB	80h
 0025  00                    C	EXT_CURHD		DB	0
 0026  29                    C	EXT_BOOT_SIG		DB	EXT_BOOT_SIGNATURE
 0027  00000000              C	EXT_BOOT_SERIAL 	DD	?
 002B  000B[                 C	EXT_BOOT_VOL_LABEL	DB	11 DUP (?)
	   ??                C	
			 ]   C	
			     C	
 0036  0008[                 C	EXT_SYSTEM_ID		DB	8  DUP (?)
	   ??                C	
			 ]   C	
			     C	
 003E                        C	EXT_IBMBOOT_HEADER	ENDS
			     C	;
 = 01FE                      C	BOOT_SIGNATURE	=     word ptr (BOOT_SIZE-2)
			     C	
			     C	;
			     C	;J.K. This is the number of sectors (of size 512 bytes) that will cover
			     C	;the size of IBMLOAD program.  IBMBOOT program has to at least read this
			     C	;many sectors, and these sectors should be the first cluster and consecutive.
			     C	;Make sure IBMBOOT program uses the same value as this.
 = 0003                      C	IBMLOADSIZE	equ	3	;Number of sectors IBMBOOT program should read in.
			     C	
			     C	
				
 0000				CSEG	       SEGMENT PARA PUBLIC 'CODE' ;AN000;
					       ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG ;
				
				;*****************************************************************************
				;									     *
				;			EXTERNAL VARIABLES				     *
				;									     *
				;*****************************************************************************
				;$salut (4,2,9,36)		   ;AN000;
				 EXTRN	SYSLOADMSG	    :NEAR  ;AN000;SYSTEM MSG HANDLER INTIALIZATION
				 EXTRN	SYSDISPMSG	    :NEAR  ;AN000;SYSTEM MSG HANDLER DISPLAY
				
				 EXTRN	INIT		    :NEAR  ;INITIALIZATION ROUTINE
				.LIST				   ;
				 EXTRN	ASCII_DRV1_ID	    :BYTE  ;AN000;SOURCE DRIVE LETTER CHARACTER
				 EXTRN	ASCII_DRV2_ID	    :BYTE  ;AN000;TARGET DRIVE LETTER CHARACTER
				 EXTRN	MSG_TRACKS	    :WORD  ;AN000;NUMBER OF TRACKS
				 EXTRN	MSG_SECTRK	    :WORD  ;AN000;SECTORS PER TRACK
				 EXTRN	MSG_SIDES	    :WORD  ;AN000;NUMBER OF SIDES
				 EXTRN	ERROR_SIDE_NUMBER   :WORD  ;AN000;NUMBER OF SIDES (SUBFIELD OF MSG 19)
				 EXTRN	ERROR_TRACK_NUMBER  :WORD  ;AN000;NUMBER OF TRACKS (SUBFIELD OF MSG 19)
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-9


				
				 EXTRN	MSGNUM_EXTERR	    :WORD  ;AN000;EXTENDED ERROR MSG DESCRIPTOR
				 EXTRN	MSGNUM_HARD_ERROR_READ:WORD ;AN000;"Unrecoverable read/write error on drive %1",CR,LF
				 EXTRN	MSGNUM_HARD_ERROR_WRITE:WORD ;AN000;"Side %2, track %3" ;
				 EXTRN	MSGNUM_LOAD_SOURCE   :WORD ;AC000;"Insert SOURCE diskette in drive %2:"
				 EXTRN	MSGNUM_LOAD_TARGET   :WORD ;AC000;"Insert TARGET diskette in drive %2:"
				 EXTRN	MSGNUM_TARGET_MB_UNUSABLE :WORD ;AC000;"Target diskette may be unusable"
				 EXTRN	MSGNUM_NOT_COMPATIBLE :WORD ;AC000;"Drive types or diskette types",CR,LF
								   ;"not compatible"
				 EXTRN	MSGNUM_BAD_SOURCE  :WORD   ;AC000;"SOURCE diskette bad or incompatible"
				 EXTRN	MSGNUM_BAD_TARGET  :WORD   ;AC000;"TARGET diskette bad or incompatible"
				 EXTRN	MSGNUM_COPY_ANOTHER :WORD  ;AC000;"Copy another diskette (Y/N)?"
				 EXTRN	MSGNUM_FORMATTING  :WORD   ;AC000;"Formatting while copying"
				 EXTRN	MSGNUM_GET_READY   :WORD   ;AC000;"Drive not ready - %0"
				 EXTRN	MSGNUM_CLOSE_DOOR  :WORD   ;AN004;"Make sure a diskette is inserted into
								   ; the drive and the door is closed"
				 EXTRN	MSGNUM_FATAL_ERROR :WORD   ;AC000;"Copy process ended"
				 EXTRN	MSGNUM_UNSUF_MEMORY:WORD   ;AC000;"Insufficient memory"
				 EXTRN	MSGNUM_COPYING	   :WORD   ;AC000;"Copying %1 tracks",CR,LF
								   ;"%2 Sectors/Track, %3 Side(s)"
				 EXTRN	MSGNUM_STRIKE	   :WORD   ;AC000;"Press any key to continue . . ."
				 EXTRN	MSGNUM_WRITE_PROTECT :WORD ;AC000;"Attempt to write to write-protected diskette"
				 EXTRN	MSGNUM_CR_LF	   :WORD   ;AC000;
				 EXTRN	MSGNUM_SERNO	    :WORD  ;AN001;"VOLUME SERIAL NUMBER IS %1-%0"
				 EXTRN	SUBLIST_26A	    :WORD  ;AN001;POINTS TO FIRST PART OF SERIAL NUMBER
				 EXTRN	SUBLIST_26B	    :WORD  ;AN001;POINTS TO SECND PART OF SERIAL NUMBER
				
				 EXTRN	DRIVE_LETTER	   :BYTE   ;AN000;
				;*****************************************************************************
				;									     *
				;			     PUBLIC VARIABLES				     *
				;									     *
				;*****************************************************************************
				
				 PUBLIC RECOMMENDED_BYTES_SECTOR   ;
				 PUBLIC COPY			   ;
				 PUBLIC S_OWNER_SAVED		   ;
				 PUBLIC T_OWNER_SAVED		   ;
				 PUBLIC SOURCE_DRIVE		   ;
				 PUBLIC TARGET_DRIVE		   ;
				 PUBLIC S_DRV_SECT_TRACK	   ;
				 PUBLIC S_DRV_HEADS		   ;
				 PUBLIC S_DRV_TRACKS		   ;
				 PUBLIC T_DRV_SECT_TRACK	   ;
				 PUBLIC T_DRV_HEADS		   ;
				 PUBLIC T_DRV_TRACKS		   ;
				 PUBLIC USER_OPTION		   ;
				 PUBLIC COPY_TYPE		   ;
				 PUBLIC BUFFER_BEGIN		   ;
				 PUBLIC BUFFER_END		   ;
				 PUBLIC TRACK_TO_READ		   ;
				 PUBLIC TRACK_TO_WRITE		   ;
				 PUBLIC SIDE			   ;
				 PUBLIC USER_INPUT		   ;
				 PUBLIC MAIN_EXIT		   ;
				
				 PUBLIC IO_ERROR		   ;
				
				 PUBLIC DS_IOCTL_DRV_PARM	   ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
				 PUBLIC DT_IOCTL_DRV_PARM	   ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
				 PUBLIC DS_specialFunctions	   ;AND THEIR CONTENTS
				 PUBLIC DT_specialFunctions	   ;
				 PUBLIC DS_deviceType		   ;
				 PUBLIC DT_deviceType		   ;
				 PUBLIC DS_deviceAttributes	   ;
				 PUBLIC DT_deviceAttributes	   ;
				 PUBLIC DS_numberOfCylinders	   ;
				 PUBLIC DT_numberOfCylinders	   ;
				 PUBLIC DS_mediaType		   ;
				 PUBLIC DT_mediaType		   ;
				 PUBLIC DS_BPB_PTR		   ;
				 PUBLIC DT_BPB_PTR		   ;
				
				 PUBLIC MS_IOCTL_DRV_PARM	   ;DRIVE PARM FROM SOURCE MEDIUM
				 PUBLIC MT_IOCTL_DRV_PARM	   ;DRIVE PARM FROM TARGET MEDIUM
				
				;*****************************************************************************
 0100				 ORG	100H			   ;PROGRAM ENTRY POINT
				
 0100				DISKCOPY:			   ;
 0100  E9 081A R		 JMP	BEGIN			   ;
				;*****************************************************************************
				
				;INTERNAL STACK AREA
 0103  90			 EVEN				   ;AN000;MAKE STACK WORD ALIGNED
 0104  0040[			 DB	64 DUP ('STACK   ')	   ;512 BYTES
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-10


	   53 54 41 43 4B	
	   20 20 20		
			 ]	
				
 0304				MY_STACK_PTR LABEL WORD 	   ;
				
				;*****************************************************************************
				;									     *
				;			INTERNAL VARIABLES				     *
				;									     *
				;*****************************************************************************
				;		     $salut (4,22,26,36) ;AN000;
				; INPUT PARMETERS FROM INIT SUBROUTINE:
				
 0304  00			S_OWNER_SAVED	     DB  0	   ;DRIVE LETTER THAT OWNED SOUCE DRIVE OWNERSHIP
 0305  00			T_OWNER_SAVED	     DB  0	   ;
				
 0306  0000			RECOMMENDED_BYTES_SECTOR DW 0	   ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
 0308  00			SOURCE_DRIVE	     DB  0	   ;SOURCE DRIVE ID: 1=DRV A, 2=DRV B ETC.
 0309  00			TARGET_DRIVE	     DB  0	   ;TARGET DRIVE ID
 030A  00			USER_OPTION	     DB  0	   ;=1 OF /1 OPTION IS ENTERED
 030B  01			COPY_TYPE	     DB  1	   ;SINGLE DRV COPY=1, DOUBLE DRIVE COPY=2
 030C  1000			BUFFER_BEGIN	     DW  1000H	   ;BEGINNING OF BUFFER ADDR [IN SEGMENT]
 030E  3FF0			BUFFER_END	     DW  3FF0H	   ;END OF BUFFER ADDR [IN SEGMENT]
 0310  00			S_DRV_SECT_TRACK     DB  ?	   ;SECT/TRACK, device informations.
 0311  00			S_DRV_HEADS	     DB  ?	   ;# OF HEADS
 0312  00			S_DRV_TRACKS	     DB  ?	   ;# OF TRACKS
 0313  00			T_DRV_SECT_TRACK     DB  ?	   ;
 0314  00			T_DRV_HEADS	     DB  ?	   ;
 0315  00			T_DRV_TRACKS	     DB  ?	   ;
				
				;DEFAULT BPB FOR OLD MEDIA
				;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
 0316  0200			BPB48_SINGLE	     DW  512	   ;BYTES/SECTOR
 0318  01					     DB  1	   ;SECTOR/CLUSTER
 0319  0001					     DW  1	   ;# OF RESERVED SECTORS
 031B  02					     DB  2	   ;# OF FATS
 031C  0040					     DW  40h	   ;# OF ROOT ENTRY
 031E  0168					     DW  168h	   ;TOTAL # OF SECTORS IN THE MEDIA
 0320  FC					     DB  0FCh	   ;MEDIA BYTE
 0321  0002					     DW  2	   ;SECTORS/FAT
				
				;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
 0323  0200			BPB48_DOUBLE	     DW  512	   ;BYTES/SECTOR
 0325  02					     DB  2	   ;SECTOR/CLUSTER
 0326  0001					     DW  1	   ;# OF RESERVED SECTORS
 0328  02					     DB  2	   ;# OF FATS
 0329  0070					     DW  70h	   ;# OF ROOT ENTRY
 032B  02D0					     DW  2D0h	   ;TOTAL # OF SECTORS IN THE MEDIA
 032D  FD					     DB  0FDh	   ;MEDIA BYTE
 032E  0002					     DW  2	   ;SECTORS/FAT
				
				;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
 0330  0200			BPB96		     DW  512	   ;BYTES/SECTOR
 0332  01					     DB  1	   ;SECTOR/CLUSTER
 0333  0001					     DW  1	   ;# OF RESERVED SECTORS
 0335  02					     DB  2	   ;# OF FATS
 0336  00E0					     DW  0E0h	   ;# OF ROOT ENTRY
 0338  0960					     DW  960h	   ;TOTAL # OF SECTORS IN THE MEDIA
 033A  F9					     DB  0F9h	   ;MEDIA BYTE
 033B  0007					     DW  7	   ;SECTORS/FAT
 = 000D				BPB96_LENG	     EQU $-BPB96   ;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
				
				;			LOCAL VARIABLES:
 033D  00			VOLSER_FLAG	     DB  0	   ;AN000;0=EITHER MEDIA NOT READ YET, OR
				;				    SOURCE VOL SER ID NOT AVAILABLE
				;				    1=TARGET NEEDS VOL SER WRITTEN
 033E  00000000			SERIAL		     DD  0	   ;AN013;SERIAL NUMBER OF NEW DISKETTE
 0342  00			EXITFL		     DB  EXOK	   ;AN000;ERRORLEVEL VALUE
						     PUBLIC EXITFL ;AN000;
						     PUBLIC EXPAR  ;AN000;
 = 0002				EXCBR		     EQU 2	   ;AN000;CONTROL BREAK
 = 0001				EXVER		     EQU 1	   ;AN000;BAD DOS VERSION ERRORLEVEL CODE
 = 0001				EXPAR		     EQU 1	   ;AN000; BAD PARMS, OR OTHER ERRORS
 = 0000				EXOK		     EQU 0	   ;AN000;NORMAL ERRORLEVEL RET CODE
				
 0343  00			S_DRV_SET_FLAG	     DB  0	   ;1 = SOURCE DRIVE PARM HAD BEEN SET
 0344  00			T_DRV_SET_FLAG	     DB  0	   ;1 = TARGET DRIVE PARM HAD BEEN SET
				
 0345  0001			IOCTL_SECTOR	     DW  1	   ;used for READ_A_SECTOR routine.
 0347  0000			IOCTL_TRACK	     DW  0	   ;IN THE TRACK
 0349  0000			IOCTL_HEAD	     DW  0	   ;HEAD 0
 034B  0000			SAV_CSECT	     DW  0	   ;TEMPORARY SAVING PLACE
 034D  0000			SAV_CN1 	     DW  0	   ;
 034F  0000			SAV_CB1 	     DW  0	   ;
 0351  0000			SAV_CYLN	     DW  0	   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-11


				
 0353  0000			BOOT_SECT_TRACK      DW  0	   ;TEMP SAVING PLACE OF SECTOR/TRACK
 0355  0000			BOOT_TOT_TRACK	     DW  0	   ;FOUND FROM THE BOOT SECTOR. max # of tracks
 0357  0000			BOOT_NUM_HEAD	     DW  0	   ;NUMBER OF HEADS
 0359  0000			BOOT_BYTE_SECTOR     DW  0	   ;BYTES / SECTOR
				
 035B  00			READ_S_BPB_FAILURE   DB  0	   ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
 035C  00			READ_T_BPB_FAILURE   DB  0	   ;
				
				;*** Informations from CHECK_SOURCE.
				;*** These will be used as a basis for the copy process.
 035D  4F			LAST_TRACK	     DB  79	   ;LAST CYLINDER OF THE DASD (39 OR 79)
 035E  0F			END_OF_TRACK	     DB  15	   ;END OF TRACK, 8,9 OR 15 CURRENTLY.
 035F  0200			bSECTOR_SIZE	     DW  512	   ;BYTES/SECTOR in bytes
 0361  00			NO_OF_SIDES	     DB  ?	   ;0=SINGLE SIDED, 1=DOUBLE SIDED
				
 0362  00			FORMAT_FLAG	     DB  0	   ;(ON/OFF) FORMAT BEFORE WRITE IF TURNED ON
 0363  00			TRACK_TO_READ	     DB  0	   ;NEXT TRACK TO READ
 0364  00			TRACK_TO_WRITE	     DB  0	   ;NEXT TRACK TO WRITE
 0365  00			TRACK_TO_FORMAT      DB  0	   ;STARTS FORMAT WITH THIS TRACK
								   ; TO THE LAST TRACK
 0366  0000			TRACK_SIZE	     DW  ?	   ;BYTES/CYLINDER [IN SEGMENTS]
 0368  00			SECTOR_SIZE	     DB  ?	   ;BYTES/SECTOR [IN SEGMENTS]
 0369  0000			BUFFER_PTR	     DW  ?	   ;BUFFER POINTER FOR READ/WRITE OP
 036B  00			COPY_ERROR	     DB  0	   ;=0 IF NO ERROR, >0 IF ERROR DETECTED
 036C  00			SIDE		     DB  ?	   ;NEXT SIDE TO READ/WRITE (0,1)
 036D  00			SIDE_TO_FORMAT	     DB  0	   ;NEXT SIDE TO FORMAT (0, 1)
 036E  00			OPERATION	     DB  ?	   ;READ/WRITE/VERIFY OPERATION
 036F  00			COPY_STATUS	     DB  ?	   ;(OK OR FATAL) ABORT COPY PROCESS IF FATAL
 0370  00			USER_INPUT	     DB  ?	   ;DISKCOPY AGAIN?
 0371  00			IO_ERROR	     DB  0	   ;SET BY EXTENDED_ERROR_HANDLER
 0372  00			UKM_ERR 	     DB  0	   ;AN011;IF ON, HARD ERROR IS TYPE: "UNKNOWN MEDIA"
 0373  00			MSG_FLAG	     DB  ?	   ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
								   ;IS TO BE DISPLAYED (ON/OFF)
 0374  00			TARGET_OP	     DB  0	   ;FLAG TO INDICATE ANY OPERATIONS ON TARGET
 0375  00			TRY_FORMAT_FLAG      DB  0	   ;FLAG TO INDICATE "TRY_FORMAT" PROCEDURE TO
								   ; CHECK THE "TIME OUT ERROR"
 0376  00			TIME_OUT_FLAG	     DB  0	   ;FLAG TO INDICATE THE "TIME OUT" ERROR
								   ; WAS A REAL "TIME OUT ERROR"
 0377  00			SELECT_FLAG	     DB  0	   ;INDICATES SELECT IS PRESENT
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-12


						     PAGE	   ;
				;		    DEVICE PARAMETER TABLE
				;the returned info. still has the following format.
				
 0378				DS_IOCTL_DRV_PARM    LABEL BYTE    ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
 0378  00			DS_specialFunctions  db  ?	   ;
 0379  00			DS_deviceType	     db  ?	   ;0 - 5.25"(48tpi), 1 - 5.25"(96tpi),
								   ; 2 - 3.5"(720KB)
 037A  0000			DS_deviceAttributes  dw  ?	   ;0001h - NOT REMOVABLE,
								   ; 0002h - CHANGE LINE SUPPORTED
 037C  0000			DS_numberOfCylinders dw  ?	   ;
 037E  00			DS_mediaType	     db  ?	   ;
 037F				DS_BPB_PTR	     LABEL BYTE    ;
 037F  0000			DS_deviceBPB	     my_bpb <>	   ;
 0381  00			
 0382  0000			
 0384  00			
 0385  0000			
 0387  0000			
 0389  00			
 038A  0000			
 038C  0000			
 038E  0000			
 0390  00000000			
 0394  00000000			
 0398  0006[			
	   00			
			 ]	
				
 039E				DS_trackLayout	     LABEL WORD    ;AC000;
						     my_trackLayout ;AC000;
 039E  0000                  1	??0000        DW    0		   ; 
 03A0  0001                  1		       DW    1		   ; 
 03A2  0200                  1		       DW    512	   ; 
 03A4  0002                  1		       DW    2		   ; 
 03A6  0200                  1		       DW    512	   ; 
 03A8  0003                  1		       DW    3		   ; 
 03AA  0200                  1		       DW    512	   ; 
 03AC  0004                  1		       DW    4		   ; 
 03AE  0200                  1		       DW    512	   ; 
 03B0  0005                  1		       DW    5		   ; 
 03B2  0200                  1		       DW    512	   ; 
 03B4  0006                  1		       DW    6		   ; 
 03B6  0200                  1		       DW    512	   ; 
 03B8  0007                  1		       DW    7		   ; 
 03BA  0200                  1		       DW    512	   ; 
 03BC  0008                  1		       DW    8		   ; 
 03BE  0200                  1		       DW    512	   ; 
 03C0  0009                  1		       DW    9		   ; 
 03C2  0200                  1		       DW    512	   ; 
 03C4  000A                  1		       DW    10 	   ; 
 03C6  0200                  1		       DW    512	   ; 
 03C8  000B                  1		       DW    11 	   ; 
 03CA  0200                  1		       DW    512	   ; 
 03CC  000C                  1		       DW    12 	   ; 
 03CE  0200                  1		       DW    512	   ; 
 03D0  000D                  1		       DW    13 	   ; 
 03D2  0200                  1		       DW    512	   ; 
 03D4  000E                  1		       DW    14 	   ; 
 03D6  0200                  1		       DW    512	   ; 
 03D8  000F                  1		       DW    15 	   ; 
 03DA  0200                  1		       DW    512	   ; 
 03DC  0010                  1		       DW    16 	   ; 
 03DE  0200                  1		       DW    512	   ; 
 03E0  0011                  1		       DW    17 	   ; 
 03E2  0200                  1		       DW    512	   ; 
 03E4  0012                  1		       DW    18 	   ; 
 03E6  0200                  1		       DW    512	   ; 
 03E8  0013                  1		       DW    19 	   ; 
 03EA  0200                  1		       DW    512	   ; 
 03EC  0014                  1		       DW    20 	   ; 
 03EE  0200                  1		       DW    512	   ; 
 03F0  0015                  1		       DW    21 	   ; 
 03F2  0200                  1		       DW    512	   ; 
 03F4  0016                  1		       DW    22 	   ; 
 03F6  0200                  1		       DW    512	   ; 
 03F8  0017                  1		       DW    23 	   ; 
 03FA  0200                  1		       DW    512	   ; 
 03FC  0018                  1		       DW    24 	   ; 
 03FE  0200                  1		       DW    512	   ; 
 0400  0019                  1		       DW    25 	   ; 
 0402  0200                  1		       DW    512	   ; 
 0404  001A                  1		       DW    26 	   ; 
 0406  0200                  1		       DW    512	   ; 
 0408  001B                  1		       DW    27 	   ; 
 040A  0200                  1		       DW    512	   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-13


 040C  001C                  1		       DW    28 	   ; 
 040E  0200                  1		       DW    512	   ; 
 0410  001D                  1		       DW    29 	   ; 
 0412  0200                  1		       DW    512	   ; 
 0414  001E                  1		       DW    30 	   ; 
 0416  0200                  1		       DW    512	   ; 
 0418  001F                  1		       DW    31 	   ; 
 041A  0200                  1		       DW    512	   ; 
 041C  0020                  1		       DW    32 	   ; 
 041E  0200                  1		       DW    512	   ; 
 0420  0021                  1		       DW    33 	   ; 
 0422  0200                  1		       DW    512	   ; 
 0424  0022                  1		       DW    34 	   ; 
 0426  0200                  1		       DW    512	   ; 
 0428  0023                  1		       DW    35 	   ; 
 042A  0200                  1		       DW    512	   ; 
 042C  0024                  1		       DW    36 	   ; 
 042E  0200                  1		       DW    512	   ; 
 0430  0025                  1		       DW    37 	   ; 
 0432  0200                  1		       DW    512	   ; 
 0434  0026                  1		       DW    38 	   ; 
 0436  0200                  1		       DW    512	   ; 
 0438  0027                  1		       DW    39 	   ; 
 043A  0200                  1		       DW    512	   ; 
 043C  0028                  1		       DW    40 	   ; 
 043E  0200                  1		       DW    512	   ; 
 0440  0029                  1		       DW    41 	   ; 
 0442  0200                  1		       DW    512	   ; 
 0444  002A                  1		       DW    42 	   ; 
 0446  0200                  1		       DW    512	   ; 
 0448  002B                  1		       DW    43 	   ; 
 044A  0200                  1		       DW    512	   ; 
 044C  002C                  1		       DW    44 	   ; 
 044E  0200                  1		       DW    512	   ; 
 0450  002D                  1		       DW    45 	   ; 
 0452  0200                  1		       DW    512	   ; 
 0454  002E                  1		       DW    46 	   ; 
 0456  0200                  1		       DW    512	   ; 
 0458  002F                  1		       DW    47 	   ; 
 045A  0200                  1		       DW    512	   ; 
 045C  0030                  1		       DW    48 	   ; 
 045E  0200                  1		       DW    512	   ; 
 0460  0031                  1		       DW    49 	   ; 
 0462  0200                  1		       DW    512	   ; 
 0464  0032                  1		       DW    50 	   ; 
 0466  0200                  1		       DW    512	   ; 
 0468  0033                  1		       DW    51 	   ; 
 046A  0200                  1		       DW    512	   ; 
 046C  0034                  1		       DW    52 	   ; 
 046E  0200                  1		       DW    512	   ; 
 0470  0035                  1		       DW    53 	   ; 
 0472  0200                  1		       DW    512	   ; 
 0474  0036                  1		       DW    54 	   ; 
 0476  0200                  1		       DW    512	   ; 
 0478  0037                  1		       DW    55 	   ; 
 047A  0200                  1		       DW    512	   ; 
 047C  0038                  1		       DW    56 	   ; 
 047E  0200                  1		       DW    512	   ; 
 0480  0039                  1		       DW    57 	   ; 
 0482  0200                  1		       DW    512	   ; 
 0484  003A                  1		       DW    58 	   ; 
 0486  0200                  1		       DW    512	   ; 
 0488  003B                  1		       DW    59 	   ; 
 048A  0200                  1		       DW    512	   ; 
 048C  003C                  1		       DW    60 	   ; 
 048E  0200                  1		       DW    512	   ; 
 0490  003D                  1		       DW    61 	   ; 
 0492  0200                  1		       DW    512	   ; 
 0494  003E                  1		       DW    62 	   ; 
 0496  0200                  1		       DW    512	   ; 
 0498  003F                  1		       DW    63 	   ; 
 049A  0200                  1		       DW    512	   ; 
				;---------------------------------------
				
 049C				DT_IOCTL_DRV_PARM    LABEL BYTE    ;
 049C  00			DT_specialFunctions  db  ?	   ;
 049D  00			DT_deviceType	     db  ?	   ;
 049E  0000			DT_deviceAttributes  dw  ?	   ;0001h - NOT REMOVABLE,
								   ; 0002h - CHANGE LINE SUPPORTED
 04A0  0000			DT_numberOfCylinders dw  ?	   ;
 04A2  00			DT_mediaType	     db  ?	   ;
 04A3				DT_BPB_PTR	     LABEL BYTE    ;
 04A3  0000			DT_deviceBPB	     my_bpb <>	   ;
 04A5  00			
 04A6  0000			
 04A8  00			
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-14


 04A9  0000			
 04AB  0000			
 04AD  00			
 04AE  0000			
 04B0  0000			
 04B2  0000			
 04B4  00000000			
 04B8  00000000			
 04BC  0006[			
	   00			
			 ]	
				
 04C2				DT_trackLayout	     LABEL WORD    ;AC000;
						     my_trackLayout ;AC000;
 04C2  0000                  1	??0001        DW    0		   ; 
 04C4  0001                  1		       DW    1		   ; 
 04C6  0200                  1		       DW    512	   ; 
 04C8  0002                  1		       DW    2		   ; 
 04CA  0200                  1		       DW    512	   ; 
 04CC  0003                  1		       DW    3		   ; 
 04CE  0200                  1		       DW    512	   ; 
 04D0  0004                  1		       DW    4		   ; 
 04D2  0200                  1		       DW    512	   ; 
 04D4  0005                  1		       DW    5		   ; 
 04D6  0200                  1		       DW    512	   ; 
 04D8  0006                  1		       DW    6		   ; 
 04DA  0200                  1		       DW    512	   ; 
 04DC  0007                  1		       DW    7		   ; 
 04DE  0200                  1		       DW    512	   ; 
 04E0  0008                  1		       DW    8		   ; 
 04E2  0200                  1		       DW    512	   ; 
 04E4  0009                  1		       DW    9		   ; 
 04E6  0200                  1		       DW    512	   ; 
 04E8  000A                  1		       DW    10 	   ; 
 04EA  0200                  1		       DW    512	   ; 
 04EC  000B                  1		       DW    11 	   ; 
 04EE  0200                  1		       DW    512	   ; 
 04F0  000C                  1		       DW    12 	   ; 
 04F2  0200                  1		       DW    512	   ; 
 04F4  000D                  1		       DW    13 	   ; 
 04F6  0200                  1		       DW    512	   ; 
 04F8  000E                  1		       DW    14 	   ; 
 04FA  0200                  1		       DW    512	   ; 
 04FC  000F                  1		       DW    15 	   ; 
 04FE  0200                  1		       DW    512	   ; 
 0500  0010                  1		       DW    16 	   ; 
 0502  0200                  1		       DW    512	   ; 
 0504  0011                  1		       DW    17 	   ; 
 0506  0200                  1		       DW    512	   ; 
 0508  0012                  1		       DW    18 	   ; 
 050A  0200                  1		       DW    512	   ; 
 050C  0013                  1		       DW    19 	   ; 
 050E  0200                  1		       DW    512	   ; 
 0510  0014                  1		       DW    20 	   ; 
 0512  0200                  1		       DW    512	   ; 
 0514  0015                  1		       DW    21 	   ; 
 0516  0200                  1		       DW    512	   ; 
 0518  0016                  1		       DW    22 	   ; 
 051A  0200                  1		       DW    512	   ; 
 051C  0017                  1		       DW    23 	   ; 
 051E  0200                  1		       DW    512	   ; 
 0520  0018                  1		       DW    24 	   ; 
 0522  0200                  1		       DW    512	   ; 
 0524  0019                  1		       DW    25 	   ; 
 0526  0200                  1		       DW    512	   ; 
 0528  001A                  1		       DW    26 	   ; 
 052A  0200                  1		       DW    512	   ; 
 052C  001B                  1		       DW    27 	   ; 
 052E  0200                  1		       DW    512	   ; 
 0530  001C                  1		       DW    28 	   ; 
 0532  0200                  1		       DW    512	   ; 
 0534  001D                  1		       DW    29 	   ; 
 0536  0200                  1		       DW    512	   ; 
 0538  001E                  1		       DW    30 	   ; 
 053A  0200                  1		       DW    512	   ; 
 053C  001F                  1		       DW    31 	   ; 
 053E  0200                  1		       DW    512	   ; 
 0540  0020                  1		       DW    32 	   ; 
 0542  0200                  1		       DW    512	   ; 
 0544  0021                  1		       DW    33 	   ; 
 0546  0200                  1		       DW    512	   ; 
 0548  0022                  1		       DW    34 	   ; 
 054A  0200                  1		       DW    512	   ; 
 054C  0023                  1		       DW    35 	   ; 
 054E  0200                  1		       DW    512	   ; 
 0550  0024                  1		       DW    36 	   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-15


 0552  0200                  1		       DW    512	   ; 
 0554  0025                  1		       DW    37 	   ; 
 0556  0200                  1		       DW    512	   ; 
 0558  0026                  1		       DW    38 	   ; 
 055A  0200                  1		       DW    512	   ; 
 055C  0027                  1		       DW    39 	   ; 
 055E  0200                  1		       DW    512	   ; 
 0560  0028                  1		       DW    40 	   ; 
 0562  0200                  1		       DW    512	   ; 
 0564  0029                  1		       DW    41 	   ; 
 0566  0200                  1		       DW    512	   ; 
 0568  002A                  1		       DW    42 	   ; 
 056A  0200                  1		       DW    512	   ; 
 056C  002B                  1		       DW    43 	   ; 
 056E  0200                  1		       DW    512	   ; 
 0570  002C                  1		       DW    44 	   ; 
 0572  0200                  1		       DW    512	   ; 
 0574  002D                  1		       DW    45 	   ; 
 0576  0200                  1		       DW    512	   ; 
 0578  002E                  1		       DW    46 	   ; 
 057A  0200                  1		       DW    512	   ; 
 057C  002F                  1		       DW    47 	   ; 
 057E  0200                  1		       DW    512	   ; 
 0580  0030                  1		       DW    48 	   ; 
 0582  0200                  1		       DW    512	   ; 
 0584  0031                  1		       DW    49 	   ; 
 0586  0200                  1		       DW    512	   ; 
 0588  0032                  1		       DW    50 	   ; 
 058A  0200                  1		       DW    512	   ; 
 058C  0033                  1		       DW    51 	   ; 
 058E  0200                  1		       DW    512	   ; 
 0590  0034                  1		       DW    52 	   ; 
 0592  0200                  1		       DW    512	   ; 
 0594  0035                  1		       DW    53 	   ; 
 0596  0200                  1		       DW    512	   ; 
 0598  0036                  1		       DW    54 	   ; 
 059A  0200                  1		       DW    512	   ; 
 059C  0037                  1		       DW    55 	   ; 
 059E  0200                  1		       DW    512	   ; 
 05A0  0038                  1		       DW    56 	   ; 
 05A2  0200                  1		       DW    512	   ; 
 05A4  0039                  1		       DW    57 	   ; 
 05A6  0200                  1		       DW    512	   ; 
 05A8  003A                  1		       DW    58 	   ; 
 05AA  0200                  1		       DW    512	   ; 
 05AC  003B                  1		       DW    59 	   ; 
 05AE  0200                  1		       DW    512	   ; 
 05B0  003C                  1		       DW    60 	   ; 
 05B2  0200                  1		       DW    512	   ; 
 05B4  003D                  1		       DW    61 	   ; 
 05B6  0200                  1		       DW    512	   ; 
 05B8  003E                  1		       DW    62 	   ; 
 05BA  0200                  1		       DW    512	   ; 
 05BC  003F                  1		       DW    63 	   ; 
 05BE  0200                  1		       DW    512	   ; 
				
				;---------------------------------------
				
 05C0				MS_IOCTL_DRV_PARM    LABEL BYTE    ;DRIVE PARM FROM SOURCE MEDIUM
 05C0  00			MS_specialFunctions  db  ?	   ;
 05C1  00			MS_deviceType	     db  ?	   ;
 05C2  0000			MS_deviceAttributes  dw  ?	   ;0001h - NOT REMOVABLE,
								   ; 0002h - CHANGE LINE SUPPORTED
 05C4  0000			MS_numberOfCylinders dw  ?	   ;
 05C6  00			MS_mediaType	     db  ?	   ;
 05C7				MS_BPB_PTR	     LABEL BYTE    ;
 05C7  0000			MS_deviceBPB	     my_bpb <>	   ;
 05C9  00			
 05CA  0000			
 05CC  00			
 05CD  0000			
 05CF  0000			
 05D1  00			
 05D2  0000			
 05D4  0000			
 05D6  0000			
 05D8  00000000			
 05DC  00000000			
 05E0  0006[			
	   00			
			 ]	
				
 = 001F				MS_deviceBPB_leng    equ $-MS_deviceBPB ;
 05E6				MS_trackLayout	     LABEL WORD    ;AC000;
						     my_trackLayout ;AC000;
 05E6  0000                  1	??0002        DW    0		   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-16


 05E8  0001                  1		       DW    1		   ; 
 05EA  0200                  1		       DW    512	   ; 
 05EC  0002                  1		       DW    2		   ; 
 05EE  0200                  1		       DW    512	   ; 
 05F0  0003                  1		       DW    3		   ; 
 05F2  0200                  1		       DW    512	   ; 
 05F4  0004                  1		       DW    4		   ; 
 05F6  0200                  1		       DW    512	   ; 
 05F8  0005                  1		       DW    5		   ; 
 05FA  0200                  1		       DW    512	   ; 
 05FC  0006                  1		       DW    6		   ; 
 05FE  0200                  1		       DW    512	   ; 
 0600  0007                  1		       DW    7		   ; 
 0602  0200                  1		       DW    512	   ; 
 0604  0008                  1		       DW    8		   ; 
 0606  0200                  1		       DW    512	   ; 
 0608  0009                  1		       DW    9		   ; 
 060A  0200                  1		       DW    512	   ; 
 060C  000A                  1		       DW    10 	   ; 
 060E  0200                  1		       DW    512	   ; 
 0610  000B                  1		       DW    11 	   ; 
 0612  0200                  1		       DW    512	   ; 
 0614  000C                  1		       DW    12 	   ; 
 0616  0200                  1		       DW    512	   ; 
 0618  000D                  1		       DW    13 	   ; 
 061A  0200                  1		       DW    512	   ; 
 061C  000E                  1		       DW    14 	   ; 
 061E  0200                  1		       DW    512	   ; 
 0620  000F                  1		       DW    15 	   ; 
 0622  0200                  1		       DW    512	   ; 
 0624  0010                  1		       DW    16 	   ; 
 0626  0200                  1		       DW    512	   ; 
 0628  0011                  1		       DW    17 	   ; 
 062A  0200                  1		       DW    512	   ; 
 062C  0012                  1		       DW    18 	   ; 
 062E  0200                  1		       DW    512	   ; 
 0630  0013                  1		       DW    19 	   ; 
 0632  0200                  1		       DW    512	   ; 
 0634  0014                  1		       DW    20 	   ; 
 0636  0200                  1		       DW    512	   ; 
 0638  0015                  1		       DW    21 	   ; 
 063A  0200                  1		       DW    512	   ; 
 063C  0016                  1		       DW    22 	   ; 
 063E  0200                  1		       DW    512	   ; 
 0640  0017                  1		       DW    23 	   ; 
 0642  0200                  1		       DW    512	   ; 
 0644  0018                  1		       DW    24 	   ; 
 0646  0200                  1		       DW    512	   ; 
 0648  0019                  1		       DW    25 	   ; 
 064A  0200                  1		       DW    512	   ; 
 064C  001A                  1		       DW    26 	   ; 
 064E  0200                  1		       DW    512	   ; 
 0650  001B                  1		       DW    27 	   ; 
 0652  0200                  1		       DW    512	   ; 
 0654  001C                  1		       DW    28 	   ; 
 0656  0200                  1		       DW    512	   ; 
 0658  001D                  1		       DW    29 	   ; 
 065A  0200                  1		       DW    512	   ; 
 065C  001E                  1		       DW    30 	   ; 
 065E  0200                  1		       DW    512	   ; 
 0660  001F                  1		       DW    31 	   ; 
 0662  0200                  1		       DW    512	   ; 
 0664  0020                  1		       DW    32 	   ; 
 0666  0200                  1		       DW    512	   ; 
 0668  0021                  1		       DW    33 	   ; 
 066A  0200                  1		       DW    512	   ; 
 066C  0022                  1		       DW    34 	   ; 
 066E  0200                  1		       DW    512	   ; 
 0670  0023                  1		       DW    35 	   ; 
 0672  0200                  1		       DW    512	   ; 
 0674  0024                  1		       DW    36 	   ; 
 0676  0200                  1		       DW    512	   ; 
 0678  0025                  1		       DW    37 	   ; 
 067A  0200                  1		       DW    512	   ; 
 067C  0026                  1		       DW    38 	   ; 
 067E  0200                  1		       DW    512	   ; 
 0680  0027                  1		       DW    39 	   ; 
 0682  0200                  1		       DW    512	   ; 
 0684  0028                  1		       DW    40 	   ; 
 0686  0200                  1		       DW    512	   ; 
 0688  0029                  1		       DW    41 	   ; 
 068A  0200                  1		       DW    512	   ; 
 068C  002A                  1		       DW    42 	   ; 
 068E  0200                  1		       DW    512	   ; 
 0690  002B                  1		       DW    43 	   ; 
 0692  0200                  1		       DW    512	   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-17


 0694  002C                  1		       DW    44 	   ; 
 0696  0200                  1		       DW    512	   ; 
 0698  002D                  1		       DW    45 	   ; 
 069A  0200                  1		       DW    512	   ; 
 069C  002E                  1		       DW    46 	   ; 
 069E  0200                  1		       DW    512	   ; 
 06A0  002F                  1		       DW    47 	   ; 
 06A2  0200                  1		       DW    512	   ; 
 06A4  0030                  1		       DW    48 	   ; 
 06A6  0200                  1		       DW    512	   ; 
 06A8  0031                  1		       DW    49 	   ; 
 06AA  0200                  1		       DW    512	   ; 
 06AC  0032                  1		       DW    50 	   ; 
 06AE  0200                  1		       DW    512	   ; 
 06B0  0033                  1		       DW    51 	   ; 
 06B2  0200                  1		       DW    512	   ; 
 06B4  0034                  1		       DW    52 	   ; 
 06B6  0200                  1		       DW    512	   ; 
 06B8  0035                  1		       DW    53 	   ; 
 06BA  0200                  1		       DW    512	   ; 
 06BC  0036                  1		       DW    54 	   ; 
 06BE  0200                  1		       DW    512	   ; 
 06C0  0037                  1		       DW    55 	   ; 
 06C2  0200                  1		       DW    512	   ; 
 06C4  0038                  1		       DW    56 	   ; 
 06C6  0200                  1		       DW    512	   ; 
 06C8  0039                  1		       DW    57 	   ; 
 06CA  0200                  1		       DW    512	   ; 
 06CC  003A                  1		       DW    58 	   ; 
 06CE  0200                  1		       DW    512	   ; 
 06D0  003B                  1		       DW    59 	   ; 
 06D2  0200                  1		       DW    512	   ; 
 06D4  003C                  1		       DW    60 	   ; 
 06D6  0200                  1		       DW    512	   ; 
 06D8  003D                  1		       DW    61 	   ; 
 06DA  0200                  1		       DW    512	   ; 
 06DC  003E                  1		       DW    62 	   ; 
 06DE  0200                  1		       DW    512	   ; 
 06E0  003F                  1		       DW    63 	   ; 
 06E2  0200                  1		       DW    512	   ; 
				;---------------------------------------
 06E4				MT_IOCTL_DRV_PARM    LABEL BYTE    ;DRIVE PARM FROM TARGET MEDIUM
 06E4  00			MT_specialFunctions  db  ?	   ;
 06E5  00			MT_deviceType	     db  ?	   ;
 06E6  0000			MT_deviceAttributes  dw  ?	   ;0001h - NOT REMOVABLE,
								   ; 0002h - CHANGE LINE SUPPORTED
 06E8  0000			MT_numberOfCylinders dw  ?	   ;
 06EA  00			MT_mediaType	     db  ?	   ;
 06EB				MT_BPB_PTR	     LABEL BYTE    ;
 06EB  0000			MT_deviceBPB	     my_bpb <>	   ;
 06ED  00			
 06EE  0000			
 06F0  00			
 06F1  0000			
 06F3  0000			
 06F5  00			
 06F6  0000			
 06F8  0000			
 06FA  0000			
 06FC  00000000			
 0700  00000000			
 0704  0006[			
	   00			
			 ]	
				
 070A				MT_trackLayout	     LABEL WORD    ;AC000;
						     my_trackLayout ;AC000;
 070A  0000                  1	??0003        DW    0		   ; 
 070C  0001                  1		       DW    1		   ; 
 070E  0200                  1		       DW    512	   ; 
 0710  0002                  1		       DW    2		   ; 
 0712  0200                  1		       DW    512	   ; 
 0714  0003                  1		       DW    3		   ; 
 0716  0200                  1		       DW    512	   ; 
 0718  0004                  1		       DW    4		   ; 
 071A  0200                  1		       DW    512	   ; 
 071C  0005                  1		       DW    5		   ; 
 071E  0200                  1		       DW    512	   ; 
 0720  0006                  1		       DW    6		   ; 
 0722  0200                  1		       DW    512	   ; 
 0724  0007                  1		       DW    7		   ; 
 0726  0200                  1		       DW    512	   ; 
 0728  0008                  1		       DW    8		   ; 
 072A  0200                  1		       DW    512	   ; 
 072C  0009                  1		       DW    9		   ; 
 072E  0200                  1		       DW    512	   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-18


 0730  000A                  1		       DW    10 	   ; 
 0732  0200                  1		       DW    512	   ; 
 0734  000B                  1		       DW    11 	   ; 
 0736  0200                  1		       DW    512	   ; 
 0738  000C                  1		       DW    12 	   ; 
 073A  0200                  1		       DW    512	   ; 
 073C  000D                  1		       DW    13 	   ; 
 073E  0200                  1		       DW    512	   ; 
 0740  000E                  1		       DW    14 	   ; 
 0742  0200                  1		       DW    512	   ; 
 0744  000F                  1		       DW    15 	   ; 
 0746  0200                  1		       DW    512	   ; 
 0748  0010                  1		       DW    16 	   ; 
 074A  0200                  1		       DW    512	   ; 
 074C  0011                  1		       DW    17 	   ; 
 074E  0200                  1		       DW    512	   ; 
 0750  0012                  1		       DW    18 	   ; 
 0752  0200                  1		       DW    512	   ; 
 0754  0013                  1		       DW    19 	   ; 
 0756  0200                  1		       DW    512	   ; 
 0758  0014                  1		       DW    20 	   ; 
 075A  0200                  1		       DW    512	   ; 
 075C  0015                  1		       DW    21 	   ; 
 075E  0200                  1		       DW    512	   ; 
 0760  0016                  1		       DW    22 	   ; 
 0762  0200                  1		       DW    512	   ; 
 0764  0017                  1		       DW    23 	   ; 
 0766  0200                  1		       DW    512	   ; 
 0768  0018                  1		       DW    24 	   ; 
 076A  0200                  1		       DW    512	   ; 
 076C  0019                  1		       DW    25 	   ; 
 076E  0200                  1		       DW    512	   ; 
 0770  001A                  1		       DW    26 	   ; 
 0772  0200                  1		       DW    512	   ; 
 0774  001B                  1		       DW    27 	   ; 
 0776  0200                  1		       DW    512	   ; 
 0778  001C                  1		       DW    28 	   ; 
 077A  0200                  1		       DW    512	   ; 
 077C  001D                  1		       DW    29 	   ; 
 077E  0200                  1		       DW    512	   ; 
 0780  001E                  1		       DW    30 	   ; 
 0782  0200                  1		       DW    512	   ; 
 0784  001F                  1		       DW    31 	   ; 
 0786  0200                  1		       DW    512	   ; 
 0788  0020                  1		       DW    32 	   ; 
 078A  0200                  1		       DW    512	   ; 
 078C  0021                  1		       DW    33 	   ; 
 078E  0200                  1		       DW    512	   ; 
 0790  0022                  1		       DW    34 	   ; 
 0792  0200                  1		       DW    512	   ; 
 0794  0023                  1		       DW    35 	   ; 
 0796  0200                  1		       DW    512	   ; 
 0798  0024                  1		       DW    36 	   ; 
 079A  0200                  1		       DW    512	   ; 
 079C  0025                  1		       DW    37 	   ; 
 079E  0200                  1		       DW    512	   ; 
 07A0  0026                  1		       DW    38 	   ; 
 07A2  0200                  1		       DW    512	   ; 
 07A4  0027                  1		       DW    39 	   ; 
 07A6  0200                  1		       DW    512	   ; 
 07A8  0028                  1		       DW    40 	   ; 
 07AA  0200                  1		       DW    512	   ; 
 07AC  0029                  1		       DW    41 	   ; 
 07AE  0200                  1		       DW    512	   ; 
 07B0  002A                  1		       DW    42 	   ; 
 07B2  0200                  1		       DW    512	   ; 
 07B4  002B                  1		       DW    43 	   ; 
 07B6  0200                  1		       DW    512	   ; 
 07B8  002C                  1		       DW    44 	   ; 
 07BA  0200                  1		       DW    512	   ; 
 07BC  002D                  1		       DW    45 	   ; 
 07BE  0200                  1		       DW    512	   ; 
 07C0  002E                  1		       DW    46 	   ; 
 07C2  0200                  1		       DW    512	   ; 
 07C4  002F                  1		       DW    47 	   ; 
 07C6  0200                  1		       DW    512	   ; 
 07C8  0030                  1		       DW    48 	   ; 
 07CA  0200                  1		       DW    512	   ; 
 07CC  0031                  1		       DW    49 	   ; 
 07CE  0200                  1		       DW    512	   ; 
 07D0  0032                  1		       DW    50 	   ; 
 07D2  0200                  1		       DW    512	   ; 
 07D4  0033                  1		       DW    51 	   ; 
 07D6  0200                  1		       DW    512	   ; 
 07D8  0034                  1		       DW    52 	   ; 
 07DA  0200                  1		       DW    512	   ; 
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-19


 07DC  0035                  1		       DW    53 	   ; 
 07DE  0200                  1		       DW    512	   ; 
 07E0  0036                  1		       DW    54 	   ; 
 07E2  0200                  1		       DW    512	   ; 
 07E4  0037                  1		       DW    55 	   ; 
 07E6  0200                  1		       DW    512	   ; 
 07E8  0038                  1		       DW    56 	   ; 
 07EA  0200                  1		       DW    512	   ; 
 07EC  0039                  1		       DW    57 	   ; 
 07EE  0200                  1		       DW    512	   ; 
 07F0  003A                  1		       DW    58 	   ; 
 07F2  0200                  1		       DW    512	   ; 
 07F4  003B                  1		       DW    59 	   ; 
 07F6  0200                  1		       DW    512	   ; 
 07F8  003C                  1		       DW    60 	   ; 
 07FA  0200                  1		       DW    512	   ; 
 07FC  003D                  1		       DW    61 	   ; 
 07FE  0200                  1		       DW    512	   ; 
 0800  003E                  1		       DW    62 	   ; 
 0802  0200                  1		       DW    512	   ; 
 0804  003F                  1		       DW    63 	   ; 
 0806  0200                  1		       DW    512	   ; 
				
				
				;		IOCTL  format a track function control string.
 0808				IOCTL_FORMAT	     LABEL BYTE    ;
 0808  00			FspecialFunctions    db  0	   ;
 0809  0000			FHead		     dw  ?	   ;
 080B  0000			FCylinder	     dw  ?	   ;
				
				;		IOCTL read/write a track.
 080D				IOCTL_R_W	     LABEL BYTE    ;
 080D  00			specialFunctions     db  0	   ;
 080E  0000			Head		     dw  ?	   ;
 0810  0000			Cylinder	     dw  ?	   ;
 0812  0000			FirstSectors	     dw  ?	   ;
 0814  0000			numberOfSectors      dw  ?	   ;
 0816  0000			TAddress_off	     dw  ?	   ;
 0818  0000			TAddress_seg	     dw  ?	   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				;		GET/SET MEDIA ID - FUNCTION OF GENERIC IOCTL
				;			(USED BY VOLSER PROC)
				;(Deleted ;AN013;) MEDIA_ID_BUF A_MEDIA_ID_INFO <> ;				;AN000;
				;  =  =  =  =  =  =  =	=  =  =  =  =
						     PATHLABL DISKCOPY ;AN015;
 081A                        1	    $$A_START_DISKCOPY:                    ; 
						     HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-20
BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS			;AN000;   

						     PUBLIC DISKCOPY_BEGIN ;
 081A				DISKCOPY_BEGIN	     LABEL NEAR    ;
				
				;*****************************************************************************
				;									     *
				;		 D I S K C O P Y   M A I N   P R O G R A M		     *
				;									     *
				;*****************************************************************************
				;  $salut (4,4,10,36)		   ;AN000;
 081A				BEGIN PROC NEAR 		   ;
				   PUBLIC BEGIN 		   ;AN000;
				;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
				
 081A  BC 0304 R		   MOV	 SP, OFFSET MY_STACK_PTR   ;MOVE SP TO MY STACK PTR
 081D  E8 0000 E		   CALL  SYSLOADMSG		   ;AN000;INIT SYSMSG HANDLER
				
				;  $IF	 C			   ;AN000;IF THERE WAS A PROBLEM
 0820  73 0A			   JNC $$IF1
 0822  E8 0000 E		       CALL  SYSDISPMSG 	   ;AN000;LET HIM SAY WHY HE HAD A PROBLEM
				
 0825  C6 06 0342 R 01		       MOV   EXITFL,EXVER	   ;AN000;TELL ERRORLEVEL BAD DOS VERSION
				;  $ELSE			   ;AN000;SINCE SYSDISPMSG IS HAPPY
 082A  EB 5F			   JMP SHORT $$EN1
 082C				$$IF1:
 082C  E8 0000 E		       CALL  INIT		   ;RUN INITIALIZATION ROUTINE
				
 082F  83 FA FF			       CMP   DX,FINE		   ;CHECK FOR ERROR DURING INIT
				;      $IF   E			   ;IF NO ERROR THEN PROCEED TO COPY
 0832  75 0A			       JNE $$IF3
				;	   $DO			   ;
 0834				$$DO4:
 0834  E8 089F R			       CALL  COPY	   ;PERFORM DISKCOPY
				
 0837  E8 0931 R			       CALL  TEST_REPEAT   ;COPY ANOTHER ?
				
				;	   $ENDDO C		   ;
 083A  73 F8				   JNC $$DO4
								   ;NORMAL RETURN CODE ALREADY IN "EXITFL"
				;      $ELSE			   ;ELSE IF ERROR DETECTED IN INIT
 083C  EB 0A			       JMP SHORT $$EN3
 083E				$$IF3:
				.LIST				   ;
 083E  8B FA				   MOV	 DI,DX		   ;PASS NUMBER OF ERROR MSG, IF ANY		;AD000;
								   ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
 0840  E8 115A R			   CALL  SENDMSG	   ;AC000;DISPLAY THE ERROR MESSAGE
				
 0843  C6 06 0342 R 01			   MOV	 EXITFL,EXVER	   ;AC000;ERROR RETURN CODE
				;      $ENDIF			   ;
 0848				$$EN3:
 0848  EB 05			       JMP   SHORT EXIT_TO_DOS	   ;
				
 084A				MAIN_EXIT:			   ;COME HERE AFTER CONTROL-BREAK
 084A  C6 06 0342 R 02		       MOV   EXITFL,EXCBR	   ;AC000;  FOR CONTROL-BREAK EXIT
				
 084F				EXIT_TO_DOS:			   ;
 084F  33 DB			       XOR   BX, BX		   ;
				
 0851  8A 1E 0304 R		       MOV   BL, S_OWNER_SAVED	   ;RESTORE ORIGINAL SOURCE,
								   ; TARGET DRIVE OWNER.
 0855  E8 0894 R		       CALL  SET_LOGICAL_DRIVE	   ;
				
 0858  8A 1E 0305 R		       MOV   BL, T_OWNER_SAVED	   ;
 085C  E8 0894 R		       CALL  SET_LOGICAL_DRIVE	   ;
				
 085F  80 3E 0343 R 00		       CMP   S_DRV_SET_FLAG, 0	   ;
				;      $IF   NE 		   ;AN000;
 0864  74 0F			       JE $$IF8
 0866  8A 1E 0308 R			   MOV	 BL, SOURCE_DRIVE  ;
 086A  C6 06 0378 R 04			   MOV	 DS_specialFunctions, SET_SP_FUNC_DOS ;=0
 086F  BA 0378 R			   MOV	 DX, OFFSET DS_IOCTL_DRV_PARM ;
 0872  E8 0FF8 R			   CALL  SET_DRV_PARM_DEF  ;RESTORE SOURCE DRIVE PARM
				
				;      $ENDIF			   ;AN000;
 0875				$$IF8:
				
 0875  80 3E 0344 R 00		       CMP   T_DRV_SET_FLAG, 0	   ;
				;      $IF   NE 		   ;AN000;
 087A  74 0F			       JE $$IF10
 087C  8A 1E 0309 R			   MOV	 BL, TARGET_DRIVE  ;
 0880  C6 06 049C R 04			   MOV	 DT_specialFunctions, SET_SP_FUNC_DOS ;=0
 0885  BA 049C R			   MOV	 DX, OFFSET DT_IOCTL_DRV_PARM ;
 0888  E8 0FF8 R			   CALL  SET_DRV_PARM_DEF  ;RESTORE TARGET DRIVE PARM
				
				;      $ENDIF			   ;AN000;
 088B				$$IF10:
 088B				EXIT_PROGRAM:			   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-21
BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS			;AN000;   

				
				;  $ENDIF			   ;AN000;OK WITH SYSDISPMSG?
 088B				$$EN1:
 088B  A0 0342 R		   MOV	 AL,EXITFL		   ;AN000;PASS BACK ERRORLEVEL RET CODE
				   DOSCALL RET_CD_EXIT		   ;AN000;RETURN TO DOS WITH RET CODE
 088E  B4 4C                 1					   MOV AH,RET_CD_EXIT ; 
 0890  CD 21                 1					   INT 21H ; 
				
 0892  CD 20			   INT	 20H			   ;AN000;IF ABOVE NOT WORK,
 0894				BEGIN ENDP			   ;AN000;
				; = = = = = = = = = = = = = = = = =
				   HEADER <SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-22
SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE			;A

				   PUBLIC SET_LOGICAL_DRIVE	   ;
				;*****************************************************************************
 0894				SET_LOGICAL_DRIVE PROC NEAR	   ;
				;	*** SET THE LOGICAL DRIVE LETTER THAT WILL BE THE OWNER OF THE DRIVE
				;	INPUT: BL - DRIVE LETTER
				;	OUTPUT: OWNER WILL BE SET ACCORDINGLY.
				;*****************************************************************************
 0894  80 FB 00			   CMP	 BL, 0			   ;
				;  $IF	 NE			   ;IF BL = 0, THEN JUST RETURN
 0897  74 05			   JE $$IF13
								   ;ELSE SET BL AS AN OWNER OF THAT DRIVE
 0899  B8 440F			       MOV   AX,(IOCTL_FUNC SHL 8)+SET_LOGIC_DRIVE ;AC000;
 089C  CD 21			       INT   21H		   ;
				;  $ENDIF			   ;
 089E				$$IF13:
 089E  C3			   RET				   ;
 089F				SET_LOGICAL_DRIVE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <COPY - COPY THE DISKETTE IMAGE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-23
COPY - COPY THE DISKETTE IMAGE			;AN000;                    

				;*****************************************************************************
				;MODULE NAME:  COPY							     *
				;									     *
				;      INPUT:  COPY_TYPE  BYTE	1=SINGLE DRIVE COPY			     *
				;				2=DOUBLE DRIVE COPY			     *
				;									     *
				;     OUTPUT:  NONE							     *
				;*****************************************************************************
 089F				COPY PROC NEAR			   ;COPY DISKETTE IMAGE
 089F  C6 06 033D R 00		   MOV	 VOLSER_FLAG,0		   ;AN000;RESET MEDIA ID VOL SERIAL NUMBER FLAG
 08A4  C6 06 036B R 00		   MOV	 COPY_ERROR,0		   ;RESET COPY ERROR FLAG
 08A9  C6 06 036F R 00		   MOV	 COPY_STATUS,OK 	   ;RESET COPY STATUS BYTE
 08AE  C6 06 0374 R 00		   MOV	 TARGET_OP, OFF 	   ;
 08B3  C6 06 0375 R 00		   MOV	 TRY_FORMAT_FLAG, OFF	   ;
 08B8  C6 06 0376 R 00		   MOV	 TIME_OUT_FLAG, OFF	   ;
 08BD  C6 06 0362 R 00		   MOV	 FORMAT_FLAG,OFF	   ;ASSUME FORMAT IS NOT REQUIRED
 08C2  C6 06 035B R 00		   MOV	 READ_S_BPB_FAILURE, 0	   ;RESET GET BPB FAILURE FLAG
 08C7  C6 06 035C R 00		   MOV	 READ_T_BPB_FAILURE, 0	   ;
 08CC  A1 0306 R		   MOV	 AX, RECOMMENDED_BYTES_SECTOR ;
 08CF  A3 035F R		   MOV	 bSECTOR_SIZE, AX	   ;USE RECOMMENDED SECTOR SIZE TO READ A SECTOR
 08D2  80 3E 030B R 02		   CMP	 COPY_TYPE,2		   ;IF TWO DRIVE COPY
				;  $IF	 E			   ;
 08D7  75 0F			   JNE $$IF15
				       PRINT MSGNUM_LOAD_SOURCE    ;AC000;OUTPUT LOAD SOURCE DISKETTE MESSAGE
 08D9  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_LOAD_SOURCE  ; 
 08DC  E8 115A R             1					   CALL SENDMSG 	  ; 
								   ;"INSERT SOURCE DISKETTE INTO DRIVE X:"
				
				       PRINT MSGNUM_LOAD_TARGET    ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
 08DF  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_LOAD_TARGET  ; 
 08E2  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 08E5  E8 11D1 R		       CALL  PRESS_ANY_KEY	   ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
				
				;  $ENDIF			   ;
 08E8				$$IF15:
 08E8  C6 06 0363 R 00		   MOV	 TRACK_TO_READ,0	   ;INITIALIZE TRACK NUMBERS
 08ED  C6 06 0364 R 00		   MOV	 TRACK_TO_WRITE,0	   ;
				
 08F2				COPY_TEST_END:			   ;
				;  $SEARCH			   ;
 08F2				$$DO17:
 08F2  A0 0364 R		       MOV   AL,TRACK_TO_WRITE	   ;WHILE TRACK_TO_WRITE<=LAST_TRACK
 08F5  3A 06 035D R		       CMP   AL,LAST_TRACK	   ;
				;  $LEAVE A			   ;
 08F9  77 16			   JA $$EN17
 08FB  E8 095A R		       CALL  READ_SOURCE	   ;READ AS MANY TRACK AS POSSIBLE
				
 08FE  80 3E 036F R 01		       CMP   COPY_STATUS,FATAL	   ;MAKE SURE DRIVES WERE COMPATIBLE
				;  $EXITIF E,NUL,OR		   ;
 0903  74 19			   JE $$SR17
 0905  E8 09AE R		       CALL  WRITE_TARGET	   ;WRITE THE CONTENT OF BUFFER TO TARGET
				
 0908  80 3E 036F R 01		       CMP   COPY_STATUS,FATAL	   ;MAKE SURE TARGET AND SOURCE
				;  $EXITIF E,NUL		   ;
 090D  74 0F			   JE $$SR17
				;  $ENDLOOP			   ;
 090F  EB E1			   JMP SHORT $$DO17
 0911				$$EN17:
				
 0911  80 3E 036B R 00		       CMP   COPY_ERROR,FALSE	   ;IF ERROR IN COPY
				;      $IF   NE 		   ;
 0916  74 06			       JE $$IF21
								   ;CR,LF,"Target diskette may be unusable",CR,LF
					   PRINT MSGNUM_TARGET_MB_UNUSABLE ;AC000;
 0918  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_TARGET_MB_UNUSABLE  ; 
 091B  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				;      $ENDIF			   ;
 091E				$$IF21:
				;  $ENDSRCH			   ;
 091E				$$SR17:
 091E  80 3E 036F R 01		   CMP	 COPY_STATUS,FATAL	   ;WAS COPY ABORTED ?
				;  $IF	 E			   ;
 0923  75 08			   JNE $$IF24
								   ;CR,LF,"Copy process ended",CR,LF
				       PRINT MSGNUM_FATAL_ERROR    ;AC000;IF SO THEN TELL USER
 0925  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_FATAL_ERROR  ; 
 0928  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				;  $ELSE			   ;AN000;SINCE NOT ABORTED,
 092B  EB 03			   JMP SHORT $$EN24
 092D				$$IF24:
 092D  E8 11AF R		       CALL  WRITE_VOLSER	   ;AN000;GO CHANGE VOLID OF TARGET
				
				;  $ENDIF			   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-24
COPY - COPY THE DISKETTE IMAGE			;AN000;                    

 0930				$$EN24:
 0930  C3			   RET				   ;
				
 0931				COPY ENDP			   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-25
TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER			;AN000;   

				;*****************************************************************************
				;									     *
				   PUBLIC TEST_REPEAT		   ;AN000;MAKE ENTRY IN LINK MAP
 0931				TEST_REPEAT PROC NEAR		   ;TEST IF USER WANTS TO COPY ANOTHER		*
				;				 DISKETTE				     *
				; INPUT : USER_INPUT ("Y" OR "N")
				; OUTPUT: NC = COPY AGAIN						     *
				;	  CY = EXIT TO DOS						     *
				;*****************************************************************************
				;  $SEARCH COMPLEX		   ;AC000;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED
 0931  EB 06			   JMP SHORT $$SS27
 0933				$$DO27:
				       PRINT MSGNUM_CR_LF	   ;AC000;
 0933  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_CR_LF  ; 
 0936  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				;  $STRTSRCH			   ;AN000;
 0939				$$SS27:
								   ;CR,LF,"Copy another diskette (Y/N)?"
				       PRINT MSGNUM_COPY_ANOTHER   ;AC000;SEE IF USER WANTS TO COPY ANOTHER
 0939  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_COPY_ANOTHER  ; 
 093C  E8 115A R             1					   CALL SENDMSG 	  ; 
								   ; AND READ RESPONSE TO AL
 093F  50			       PUSH  AX 		   ;AN000;SAVE THE RESPONSE
				       PRINT MSGNUM_CR_LF	   ;AC000;
 0940  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_CR_LF  ; 
 0943  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0946  5A			       POP   DX 		   ;AN000;RESTORE THE REPONSE CHAR TO DL
 0947  E8 119D R		       CALL  YESNO		   ;AN000;CHECK FOR (Y/N)
								   ;AX=0,NO; AX=1,YES; AX=2,INVALID
				;  $EXITIF C,NUL		   ;AN000;IF CARRY SET, PROBLEM,PRETEND "NO"
 094A  72 0D			   JC $$SR27
				
 094C  3D 0002			       CMP   AX,BAD_YESNO	   ;AN000;WAS THE RESPONSE INVALID?
				;  $ENDLOOP B			   ;AN000;QUIT IF OK ANSWER (AX=0 OR 1)
 094F  73 E2			   JNB $$DO27
 0951  3C 01			       CMP   AL,YES		   ;AN000;WAS "YES" SPECIFIED
				;      $IF   E			   ;AN000;IF "YES"
 0953  75 03			       JNE $$IF31
 0955  F8				   CLC			   ;AN000;CLEAR CARRY TO INDICATE COPY AGAIN
				;      $ELSE			   ;AN000;SINCE NOT "YES"
 0956  EB 01			       JMP SHORT $$EN31
 0958				$$IF31:
 0958  F9				   STC			   ;AN000;SET CARRY TO INDICATE NO REPEAT
				;      $ENDIF			   ;AN000;
 0959				$$EN31:
				;  $ENDSRCH			   ;AN000;
 0959				$$SR27:
				.LIST				   ;
 0959  C3			   RET				   ;
				
 095A				TEST_REPEAT ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-26
READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE			;AN000;

				;*****************************************************************************
				;									     *
				   PUBLIC READ_SOURCE		   ;AN000;MAKE ENTRY IN LINK MAP		   *
 095A				READ_SOURCE PROC NEAR		   ;READ AS MANY TRACKS AS POSSIBLE FROM SOURCE*
				;			    ;DISKETTE TO FILL THE AVAILABLE BUFFER SPACE     *
				;*****************************************************************************
				
 095A  80 3E 030B R 01		   CMP	 COPY_TYPE,1		   ;IF SINGLE DRIVE COPY
				;  $IF	 E			   ;PROMPT MSG
 095F  75 09			   JNE $$IF35
				       PRINT MSGNUM_LOAD_SOURCE    ;AN000;"INSERT SOURCE DISKETTE INTO DRIVE X:"
 0961  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_LOAD_SOURCE  ; 
 0964  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0967  E8 11D1 R		       CALL  PRESS_ANY_KEY	   ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
				
				;  $ENDIF			   ;
 096A				$$IF35:
 096A  80 3E 0363 R 00		   CMP	 TRACK_TO_READ,0	   ;1ST TRACK ?
				;  $IF	 NE,OR			   ;IF NOT
 096F  75 10			   JNE $$LL37
				
 0971  E8 0C6A R		   CALL  CHECK_SOURCE		   ;DO NECESSARY CHECKING
				
 0974  E8 0E2B R		   CALL  CALC_TRACK_SIZE	   ;
				
 0977  E8 0E55 R		   CALL  CHECK_MEMORY_SIZE	   ;
				
 097A  80 3E 036F R 01		   CMP	 COPY_STATUS,FATAL	   ;
				;  $IF	 NE			   ;
 097F  74 2C			   JE $$IF37
 0981				$$LL37:
				;(deleted ;AN013;) CALL  READ_VOLSER ;GO READ THE MEDIA ID TO GET SERIAL NUMBER ;AN000;
				
 0981  8B 1E 030C R		       MOV   BX,BUFFER_BEGIN	   ;
 0985  89 1E 0369 R		       MOV   BUFFER_PTR,BX	   ;INITIALIZE BUFFER POINTER
				
				;      $DO			   ;
 0989				$$DO38:
 0989  A0 0363 R			   MOV	 AL,TRACK_TO_READ  ;DID WE FINISH READING ALL TRACKS?
 098C  3A 06 035D R			   CMP	 AL,LAST_TRACK	   ;
				;      $LEAVE A 		   ;
 0990  77 1B			       JA $$EN38
 0992  A1 0369 R			   MOV	 AX,BUFFER_PTR	   ;DID WE RUN OUT OF BUFFER SPACE
 0995  03 06 0366 R			   ADD	 AX,TRACK_SIZE	   ;
 0999  3B 06 030E R			   CMP	 AX,BUFFER_END	   ;
				;      $LEAVE A 		   ;
 099D  77 0E			       JA $$EN38
 099F  C6 06 036E R 61			   MOV	 OPERATION,READ_FUNC ;
 09A4  E8 0A12 R			   CALL  READ_WRITE_TRACK  ;NO, GO READ ANOTHER TRACK
				
 09A7  FE 06 0363 R			   INC	 TRACK_TO_READ	   ;
				;      $ENDDO			   ;
 09AB  EB DC			       JMP SHORT $$DO38
 09AD				$$EN38:
				;  $ENDIF			   ;
 09AD				$$IF37:
 09AD  C3			   RET				   ;
 09AE				READ_SOURCE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-27
WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE			;

				;*****************************************************************************
				;									     *
				   PUBLIC WRITE_TARGET		   ;AN000;MAKE ENTRY IN LINK MAP
 09AE				WRITE_TARGET PROC		   ;WRITE DATA FROM MEMORY TO TARGET DISKETTE*
				;									     *
				;*****************************************************************************
				
 09AE  80 3E 030B R 01		   CMP	 COPY_TYPE,1		   ;IF SINGLE DRIVE COPY
				;  $IF	 E			   ;PROMPT MSG
 09B3  75 09			   JNE $$IF43
				       PRINT MSGNUM_LOAD_TARGET    ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
 09B5  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_LOAD_TARGET  ; 
 09B8  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 09BB  E8 11D1 R		       CALL  PRESS_ANY_KEY	   ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
				
				;  $ENDIF			   ;
 09BE				$$IF43:
 09BE  C6 06 0374 R 01		   MOV	 TARGET_OP, ON		   ;INDICATE A OPERATION ON TARGET
 09C3  8B 1E 030C R		   MOV	 BX,BUFFER_BEGIN	   ;
 09C7  89 1E 0369 R		   MOV	 BUFFER_PTR,BX		   ;INITIALIZE BUFFER POINTER
 09CB  80 3E 0364 R 00		   CMP	 TRACK_TO_WRITE,0	   ;IF TRK 0, CHECK COMPATIBILITY
				;  $IF	 NE,OR			   ;
 09D0  75 0F			   JNE $$LL45
				
 09D2  C6 06 036C R 00		   MOV	 SIDE, 0		   ;
 09D7  E8 0EBF R		   CALL  CHECK_TARGET		   ;
				
 09DA  80 3E 036F R 01		   CMP	 COPY_STATUS,FATAL	   ;IF INCOMPATIBLE, THEN EXIT
				;  $IF	 NE			   ;
 09DF  74 2B			   JE $$IF45
 09E1				$$LL45:
				
				;      $DO			   ;
 09E1				$$DO46:
 09E1  A0 0364 R			   MOV	 AL,TRACK_TO_WRITE ;DID WE FINISH WRITING ALL TRACKS?
 09E4  3A 06 035D R			   CMP	 AL,LAST_TRACK	   ;
				;      $LEAVE A 		   ;
 09E8  77 22			       JA $$EN46
 09EA  A1 0369 R			   MOV	 AX,BUFFER_PTR	   ;DID WE RUN OUT OF BUFFER SPACE
 09ED  03 06 0366 R			   ADD	 AX,TRACK_SIZE	   ;
 09F1  3B 06 030E R			   CMP	 AX,BUFFER_END	   ;
				;      $LEAVE A 		   ;
 09F5  77 15			       JA $$EN46
 09F7  C6 06 036E R 41			   MOV	 OPERATION,WRITE_FUNC ;
 09FC  E8 0A12 R			   CALL  READ_WRITE_TRACK  ;NO, GO WRITE ANOTHER TRACK
				
 09FF  80 3E 036F R 01			   CMP	 COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
				;      $LEAVE E 		   ;
 0A04  74 06			       JE $$EN46
 0A06  FE 06 0364 R			   INC	 TRACK_TO_WRITE    ;
				;      $ENDDO			   ;
 0A0A  EB D5			       JMP SHORT $$DO46
 0A0C				$$EN46:
				;  $ENDIF			   ;
 0A0C				$$IF45:
 0A0C  C6 06 0374 R 00		   MOV	 TARGET_OP, OFF 	   ;
 0A11  C3			   RET				   ;
 0A12				WRITE_TARGET ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-28
READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY			;

				;*****************************************************************************
				;									     *
				   PUBLIC READ_WRITE_TRACK	   ;AN000;MAKE ENTRY IN LINK MAP
 0A12				READ_WRITE_TRACK PROC NEAR	   ;READ A TRACK AND STORE IT INTO MEMORY   *
				;									     *
				;INPUT:  OPERATION = 61h THEN READ OPERATION				     *
				;		     41h THEN WRITE OPERATION				     *
				;*****************************************************************************
				
 0A12  C6 06 036C R 00		   MOV	 SIDE, 0		   ;
				;  $DO				   ;
 0A17				$$DO52:
 0A17  C6 06 0373 R 01		       MOV   MSG_FLAG, ON	   ;
 0A1C  80 3E 036E R 61		       CMP   OPERATION, READ_FUNC  ;
				;      $IF   E			   ;
 0A21  75 05			       JNE $$IF53
 0A23  E8 0A5A R			   CALL  READ_OP	   ;
				
				;      $ELSE			   ;
 0A26  EB 0A			       JMP SHORT $$EN53
 0A28				$$IF53:
 0A28  E8 0B0A R			   CALL  WRITE_OP	   ;
				
 0A2B  80 3E 036F R 01			   CMP	 COPY_STATUS, FATAL ;
 0A30  74 27				   JE	 RWT_EXIT	   ;
				
				;      $ENDIF			   ;
 0A32				$$EN53:
 0A32  80 3E 0361 R 00		       CMP   NO_OF_SIDES, 0	   ;SINGLE SIDE COPY?
				;      $IF   E			   ;YES
 0A37  75 05			       JNE $$IF56
 0A39  A1 0366 R			   MOV	 AX, TRACK_SIZE    ;
				;      $ELSE			   ;NO, DOUBLE SIDE
 0A3C  EB 0A			       JMP SHORT $$EN56
 0A3E				$$IF56:
 0A3E  33 D2				   XOR	 DX, DX 	   ;
 0A40  A1 0366 R			   MOV	 AX, TRACK_SIZE    ;
 0A43  B9 0002				   MOV	 CX, 2		   ;
 0A46  F7 F1				   DIV	 CX		   ;AX / 2
				;      $ENDIF			   ;
 0A48				$$EN56:
 0A48  01 06 0369 R		       ADD   BUFFER_PTR, AX	   ;
 0A4C  FE 06 036C R		       INC   SIDE		   ;NEXT SIDE
 0A50  A0 036C R		       MOV   AL, SIDE		   ;
 0A53  3A 06 0361 R		       CMP   AL, NO_OF_SIDES	   ;FINISHED WITH THE LAST SIDE?
				;  $ENDDO G			   ;
 0A57  7E BE			   JNG $$DO52
 0A59				RWT_EXIT:			   ;
 0A59  C3			   RET				   ;
 0A5A				READ_WRITE_TRACK ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <READ_OP - IOCTL READ A TRACK OPERATION> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-29
READ_OP - IOCTL READ A TRACK OPERATION			;AN000;            

				;*****************************************************************************
				;									     *
				   PUBLIC READ_OP		   ;AN000;MAKE ENTRY IN LINK MAP
 0A5A				READ_OP PROC NEAR		   ;IOCTL READ A TRACK OPERATION	*
				;									     *
				;*****************************************************************************
				
				;  $SEARCH			   ;
 0A5A				$$DO60:
 0A5A  33 C0			       XOR   AX, AX		   ;
 0A5C  A0 036C R		       MOV   AL, SIDE		   ;
 0A5F  A3 080E R		       MOV   Head, AX		   ;HEAD TO READ
 0A62  A0 0363 R		       MOV   AL, TRACK_TO_READ	   ;
 0A65  A3 0810 R		       MOV   Cylinder, AX	   ;TRACK TO READ
 0A68  C7 06 0812 R 0000	       MOV   FirstSectors, 0	   ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
 0A6E  A1 0369 R		       MOV   AX, BUFFER_PTR	   ;
 0A71  A3 0818 R		       MOV   Taddress_seg, AX	   ;BUFFER ADDRESS
 0A74  C7 06 0816 R 0000	       MOV   Taddress_off, 0	   ;
 0A7A  33 DB			       XOR   BX, BX		   ;
 0A7C  8A 1E 0308 R		       MOV   BL, SOURCE_DRIVE	   ;
 0A80  B1 61			       MOV   CL, READ_FUNC	   ;=61h
 0A82  BA 080D R		       MOV   DX, OFFSET IOCTL_R_W  ;
 0A85  E8 1018 R		       CALL  GENERIC_IOCTL	   ;
				
 0A88  80 3E 0371 R 00		       CMP   IO_ERROR, NO_ERROR    ;OK?
				;  $EXITIF E			   ;AC013;IF NO ERROR SO FAR, GOOD
 0A8D  75 13			   JNE $$IF60
 0A8F  83 3E 0810 R 00		       CMP   CYLINDER,0 	   ;AN013;IS THIS THE FIRST READ?
				;      $IF   E,AND		   ;AN013;IF THIS IS THE FIRST TRACK, AND
 0A94  75 0A			       JNE $$IF62
 0A96  83 3E 080E R 00		       CMP   HEAD,0		   ;AN013;IS THIS THE FIRST SIDE?
				;      $IF   E			   ;AN013;AND IF THIS IS THE FIRST SIDE
 0A9B  75 03			       JNE $$IF62
 0A9D  E8 0AC3 R			   CALL  MAYBE_ADJUST_SERIAL ;AN013;IF BOOT HAS SERIAL, GENERATE NEW ONE
				
				;      $ENDIF			   ;AN013;FIRST TRACK AND HEAD?
 0AA0				$$IF62:
				;  $ORELSE			   ;AN013;SINCE SOME KIND OF ERROR, OOPS
 0AA0  EB 20			   JMP SHORT $$SR60
 0AA2				$$IF60:
 0AA2  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY AGAIN?
				;  $ENDLOOP NE			   ;
 0AA7  74 B1			   JE $$DO60
				
 0AA9  80 3E 0373 R 01		       CMP   MSG_FLAG, ON	   ;ELSE HARD ERROR. SEE IF
								   ; MESSAGE TO BE DISPLAYED
				;      $IF   E			   ;
 0AAE  75 12			       JNE $$IF66
				
 0AB0  B4 61				   MOV	 AH, READ_FUNC	   ;
 0AB2  8A 16 0308 R			   mov	 dl, source_drive  ;
 0AB6  E8 112C R			   CALL  ERROR_MESSAGE	   ;
				
 0AB9  FE 06 036B R			   INC	 COPY_ERROR	   ;INCREASE COPY_ERROR COUNT
 0ABD  C6 06 0373 R 00			   MOV	 MSG_FLAG, OFF	   ;
				;      $ENDIF			   ;
 0AC2				$$IF66:
				;  $ENDSRCH			   ;
 0AC2				$$SR60:
 0AC2  C3			   RET				   ;
 0AC3				READ_OP ENDP			   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT> ;AN013;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-30
MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT			;AN000;     

 0AC3				MAYBE_ADJUST_SERIAL PROC NEAR	   ;AN013;
				;INPUT: TADDRESS_OFF/_SEG HAS TRACK BUFFER WHICH HAS BOOT RECORD
				;	"VOLSER_FLAG" IS FALSE.
				;OUTPUT:SERIAL NUMBER FIELD IS MODIFIED TO HAVE NEW SERIAL NUMBER
				;	A COPY OF WHICH IS PRESERVED IN "SERIAL" FOR LATER DISPLAY IN MSG.
				;	"VOLSER_FLAG" SET TO TRUE TO INDICATE NEW SERIAL GENERATED.
				;	IF THIS BOOT DOES NOT HAVE A SERIAL, NO CHANGE MADE, AND
				;	"VOLSER_FLAG" LEFT AS FALSE.
				
				;	A BOOT RECORD IS ASSUMED TO HAVE A SERIAL NUMBER IF:
				;	EBPB_MEDIADESCRIPTOR=0F?H AND EXT_BOOT_SIG IS EITHER 28H OR 29H.
				
 0AC3  06			   PUSH  ES			   ;AN013;SAVE EXTRA SEG REG TEMPORARILY
 0AC4  53			   PUSH  BX			   ;AN013;AND SAVE THE BASE POINTER
 0AC5  56			   PUSH  SI			   ;AN013; AND THE INDEX
 0AC6  C4 1E 0816 R		   LES	 BX,DWORD PTR TADDRESS_OFF ;AN013;POINT TO BUFFER AREA CONTAINING BOOT RECORD
 0ACA  8D 77 0B			   LEA	 SI,ES:[BX].EXT_BOOT_BPB   ;AN013;POINT TO BPB PORTION OF BOOT RECORD
 0ACD  26: 8A 44 0A		   MOV	 AL,ES:[SI].EBPB_MEDIADESCRIPTOR ;AN013;GET TYPE OF MEDIA
 0AD1  24 F0			   AND	 AL,0F0H		   ;AN013;SAVE LEFT NIBBLE ONLY
 0AD3  3C F0			   CMP	 AL,0F0H		   ;AN013;IF DISKETTE HAS PROPER DESCRIPTOR
				;  $IF	 E			   ;AN013;IF OK DESCRIPTOR
 0AD5  75 2F			   JNE $$IF69
 0AD7  26: 8A 47 26		       MOV   AL,ES:[BX].EXT_BOOT_SIG ;AN013;GET "SIGNATURE" OF BOOT RECORD
 0ADB  3C 28			       CMP   AL,28H		   ;AN013;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
				;      $IF   E,OR		   ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
 0ADD  74 04			       JE $$LL70
 0ADF  3C 29			       CMP   AL,29H		   ;AN013;IS THIS A BOOT STYLE OF OS/S 1.2?
				;      $IF   E			   ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
 0AE1  75 23			       JNE $$IF70
 0AE3				$$LL70:
				;		GET CURRENT DATE
					   DOSCALL GET_DATE	   ;AN013;READ SYSTEM DATE
 0AE3  B4 2A                 1					   MOV AH,GET_DATE ; 
 0AE5  CD 21                 1					   INT 21H ; 
								   ;OUTPUT: DL = DAY (1-31)
								   ;  AL = DAY OF WEEK (0=SUN,6=SAT)
								   ;  CX = YEAR (1980-2099)
								   ;  DH = MONTH (1-12)
 0AE7  51				   PUSH  CX		   ;AN013;SAVE THESE FOR
 0AE8  52				   PUSH  DX		   ;AN013; INPUT INTO HASH ALGORITHM
				;		GET CURRENT TIME
					   DOSCALL GET_TIME	   ;AN013;READ SYSTEM TIME CLOCK
 0AE9  B4 2C                 1					   MOV AH,GET_TIME ; 
 0AEB  CD 21                 1					   INT 21H ; 
								   ;OUTPUT: CH = HOUR (0-23)
								   ;  CL = MINUTES (0-59)
								   ;  DH = SECONDS (0-59)
								   ;  DL = HUNDREDTHS (0-99)
				
				;		   HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
				;			   SERIAL+0 = DX FROM DATE + DX FROM TIME
				;			   SERIAL+2 = CX FROM DATE + CX FROM TIME
				
 0AED  58				   POP	 AX		   ;AN013;GET THE DX FROM DATE
 0AEE  03 C2				   ADD	 AX,DX		   ;AN013;ADD IN THE DX FROM TIME
 0AF0  A3 033E R			   MOV	 WORD PTR SERIAL,AX ;AN013;SAVE FIRST RESULT OF HASH
 0AF3  26: 89 47 27			   MOV	 WORD PTR ES:[BX].EXT_BOOT_SERIAL,AX ;AN013;AND IN BOOT RECORD ITSELF
				
 0AF7  58				   POP	 AX		   ;AN013;GET THE CX FROM DATE
 0AF8  03 C1				   ADD	 AX,CX		   ;AN013;ADD IN THE CX FROM TIME
 0AFA  A3 0340 R			   MOV	 WORD PTR SERIAL+WORD,AX ;AN013;SAVE SECOND RESULT OF HASH
 0AFD  26: 89 47 29			   MOV	 WORD PTR ES:[BX].EXT_BOOT_SERIAL+WORD,AX ;AN013;AND IN BOOT RECORD
				
 0B01  C6 06 033D R 01			   MOV	 VOLSER_FLAG,TRUE  ;AN013;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN
				
				;      $ENDIF			   ;AN013;BOOT HAVE SERIAL?
 0B06				$$IF70:
				;  $ENDIF			   ;AN013;PROPER DESCRIPTOR?
 0B06				$$IF69:
 0B06  5E			   POP	 SI			   ;AN013;RESTORE THE INDEX REG
 0B07  5B			   POP	 BX			   ;AN013;RESTORE THE BASE POINTER
 0B08  07			   POP	 ES			   ;AN013;RESTORE EXTRA SEG REG
 0B09  C3			   RET				   ;AN013;RETURN TO CALLER
 0B0A				MAYBE_ADJUST_SERIAL ENDP	   ;AN013;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <WRITE_OP - IOCTL WRITE A TRACK OPERATION> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-31
WRITE_OP - IOCTL WRITE A TRACK OPERATION			;AN000;          

				;*****************************************************************************
				;									     *
				   PUBLIC WRITE_OP		   ;AN000;MAKE ENTRY IN LINK MAP
 0B0A				WRITE_OP PROC NEAR		   ;IOCTL WRITE A TRACK OPERATION	*
				;									     *
				;*****************************************************************************
				
 0B0A				WO_AGAIN:			   ;
				;  $SEARCH			   ;
 0B0A				$$DO73:
 0B0A  33 C0			       XOR   AX, AX		   ;
 0B0C  A0 036C R		       MOV   AL, SIDE		   ;
 0B0F  A3 080E R		       MOV   Head, AX		   ;HEAD TO WRITE
 0B12  A0 0364 R		       MOV   AL, TRACK_TO_WRITE    ;
 0B15  A3 0810 R		       MOV   Cylinder, AX	   ;TRACK TO WRITE
 0B18  C7 06 0812 R 0000	       MOV   FirstSectors, 0	   ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
 0B1E  A1 0369 R		       MOV   AX, BUFFER_PTR	   ;
 0B21  A3 0818 R		       MOV   Taddress_seg, AX	   ;BUFFER ADDRESS
 0B24  C7 06 0816 R 0000	       MOV   Taddress_off, 0	   ;
 0B2A  33 DB			       XOR   BX, BX		   ;
 0B2C  8A 1E 0309 R		       MOV   BL, TARGET_DRIVE	   ;
 0B30  B1 41			       MOV   CL, WRITE_FUNC	   ;= 41h
 0B32  BA 080D R		       MOV   DX, OFFSET IOCTL_R_W  ;
 0B35  E8 1018 R		       CALL  GENERIC_IOCTL	   ;
				
 0B38  80 3E 0371 R 00		       CMP   IO_ERROR, NO_ERROR    ;OK?
				;  $LEAVE E			   ;YES, SUCCESS. EXIT THIS ROUTINE
 0B3D  74 37			   JE $$EN73
				
 0B3F  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY AGAIN?
 0B44  74 C4			       JE    WO_AGAIN		   ;
								   ;ELSE HARD ERROR
								   ;WRITE FAILURE, LET'S TRY TO FORMAT.
 0B46  80 3E 0362 R 01		       CMP   FORMAT_FLAG, ON	   ;WAS THIS TRACK FORMATTED BEFORE?
				;  $EXITIF E			   ;YES, GIVE UP WRITING AND
 0B4B  75 14			   JNE $$IF73
								   ; CHECK WHEN IT HAPPENDED.
								   ;GIVE UP WRITING AND SHOW ERROR MESSAGE.
 0B4D  FE 06 036B R		       INC   COPY_ERROR 	   ;INDICATE ERROR OCCURS DURING COPY.
 0B51  B4 41			       MOV   AH, WRITE_FUNC	   ;
 0B53  8A 16 0309 R		       mov   dl, target_drive	   ;
 0B57  E8 112C R		       CALL  ERROR_MESSAGE	   ;SHOW MESSAGE 'WRITE ERROR SIDE, TRACK...'
				
 0B5A  C6 06 0373 R 00		       MOV   MSG_FLAG, OFF	   ;
				;  $ORELSE			   ;ELSE TRY FORMAT AND TRY WRITE AGAIN
 0B5F  EB 15			   JMP SHORT $$SR73
 0B61				$$IF73:
				
								   ;CR,LF,"Formatting while copying",CR,LF
				       PRINT MSGNUM_FORMATTING	   ;AN000;SHOW MESSAGE
 0B61  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_FORMATTING  ; 
 0B64  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0B67  C6 06 0362 R 01		       MOV   FORMAT_FLAG, ON	   ;FORMAT ALL TRACKS FROM THIS TRACK
 0B6C  E8 0B77 R		       CALL  FORMAT_ALL 	   ;format all the rest of the tracks
				
 0B6F  80 3E 036F R 01		       CMP   COPY_STATUS, FATAL    ;
				;  $ENDLOOP E			   ;
 0B74  75 94			   JNE $$DO73
 0B76				$$EN73:
				.LIST				   ;
				;  $ENDSRCH			   ;
 0B76				$$SR73:
 0B76				WO_EXIT:			   ;
 0B76  C3			   RET				   ;
				
 0B77				WRITE_OP ENDP			   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <FORMAT_ALL - FORMATS ALL TRACKS TO END> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-32
FORMAT_ALL - FORMATS ALL TRACKS TO END			;AN000;            

				;*****************************************************************************
				;									     *
				   PUBLIC FORMAT_ALL		   ;AN000;MAKE ENTRY IN LINK MAP
 0B77				FORMAT_ALL PROC NEAR		   ;
				;									     *
				;Format all tracks starting from TRACK_TO_WRITE to the end.		     *
				;This routine will set MT_deviceBPB to that of MS_deviceBPB.		     *
				;trackLayout had been all set correctly.				     *
				;If error, then fail to diskcopy.					     *
				;*****************************************************************************
				
 0B77  B9 001F			   MOV	 CX, MS_deviceBPB_leng	   ;set length of BPB
 0B7A  BE 05C7 R		   MOV	 SI, OFFSET MS_deviceBPB   ;
 0B7D  BF 06EB R		   MOV	 DI, OFFSET MT_deviceBPB   ;
 0B80  F3/ A4			   REP	 MOVSB			   ;
 0B82  E8 0FFE R		   CALL  CHK_MEDIATYPE		   ;set MT_mediaTYPE for FORMAT operation
				
 0B85  C6 06 06E4 R 05		   MOV	 MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
 0B8A  B1 40			   MOV	 CL, SETDEVPARM 	   ;=40h
 0B8C  BA 06E4 R		   MOV	 DX, OFFSET MT_IOCTL_DRV_PARM ;
 0B8F  33 DB			   XOR	 BX, BX 		   ;
 0B91  8A 1E 035D R		   mov	 bl, last_track 	   ;patch 3/27/86 for 3.2 diskcopy. J.K.
 0B95  FE C3			   inc	 bl			   ;
 0B97  89 1E 06E8 R		   mov	 MT_numberOfCylinders, bx  ;make sure target # of cyl.
 0B9B  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 0B9F  E8 1018 R		   CALL  GENERIC_IOCTL		   ;
				
 0BA2  72 73			   JC	 FA_FATAL		   ;
				
 0BA4  C6 06 0808 R 01		   MOV	 FspecialFunctions, STATUS_CHK ;check to see if the parameters set
								   ;by "SET DEVICE PARM" func above are
								   ; supported or not.
 0BA9  B8 440D			   MOV	 AX,(IOCTL_FUNC SHL 8)+GENERIC_IOCTL_CODE ;AC000;(440DH)
 0BAC  B5 08			   MOV	 CH, MAJOR_CODE 	   ;=8
 0BAE  B1 42			   MOV	 CL, FORMAT_FUNC	   ;=42H
 0BB0  33 DB			   XOR	 BX, BX 		   ;
 0BB2  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 0BB6  BA 0808 R		   MOV	 DX, OFFSET IOCTL_FORMAT   ;result is in Fspecialfunction
 0BB9  CD 21			   INT	 21H			   ;0 - Thre is ROM support of AH=18h, INT 13h, and
								   ; it is a valid combination
				
 0BBB  A0 0808 R		   MOV	 AL, FspecialFunctions	   ;1 - No ROM support. 2 - There is ROM support,
								   ; but invalid combination
 0BBE  C6 06 0808 R 00		   MOV	 FspecialFunctions, FORMAT_SP_FUNC ;restore specialfunction value
 0BC3  3C 02			   CMP	 AL, 2			   ;ROM support, but this combination is not valid?
 0BC5  74 50			   JE	 FA_FATAL		   ;
				
 0BC7  A0 0364 R		   MOV	 AL, TRACK_TO_WRITE	   ;
 0BCA  A2 0365 R		   MOV	 TRACK_TO_FORMAT, AL	   ;
 0BCD  A0 036C R		   MOV	 AL, SIDE		   ;
 0BD0  A2 036D R		   MOV	 SIDE_TO_FORMAT, AL	   ;
 0BD3  3A 06 0361 R		   CMP	 AL, NO_OF_SIDES	   ;
 0BD7  74 09			   JE	 FA_SIDE_WHILE		   ;STARTS WITH THE OTHER SIDE TO FORMAT
				
 0BD9				FA_TRACK_WHILE: 		   ;
 0BD9  A0 035D R		   MOV	 AL, LAST_TRACK 	   ;
 0BDC  38 06 0365 R		   CMP	 TRACK_TO_FORMAT, AL	   ;
 0BE0  77 4D			   JA	 FA_DONE		   ;
				
 0BE2				FA_SIDE_WHILE:			   ;
 0BE2  A0 0361 R		   MOV	 AL, NO_OF_SIDES	   ;
 0BE5  38 06 036D R		   CMP	 SIDE_TO_FORMAT, AL	   ;
 0BE9  77 21			   JA	 FA_NEXT_TRACK		   ;
				
 0BEB  E8 0C46 R		   CALL  FORMAT_TRACK		   ;FORMAT THIS TRACK
				
 0BEE  80 3E 0371 R 02		   CMP	 IO_ERROR, HARD_ERROR	   ;
 0BF3  75 11			   JNE	 FA_NEXT_SIDE		   ;
				
 0BF5  80 3E 036D R 01		   CMP	 SIDE_TO_FORMAT, 1	   ;HARD ERROR AT SIDE 1?
 0BFA  75 28			   JNE	 FA_TARGET_BAD		   ;THEN ASSUME TARGET DISKETTE BAD
				
 0BFC  80 3E 0365 R 00		   CMP	 TRACK_TO_FORMAT, 0	   ;AT CYLINDER 0?
 0C01  75 21			   JNE	 FA_TARGET_BAD		   ;
				
 0C03  EB 12 90			   JMP	 FA_FATAL		   ;THEN, SOURCE IS TWO SIDED AND
								   ; TARGET IS SINGLE SIDE DISKETTE
				
 0C06				FA_NEXT_SIDE:			   ;
 0C06  FE 06 036D R		   INC	 SIDE_TO_FORMAT 	   ;
 0C0A  EB D6			   JMP	 FA_SIDE_WHILE		   ;
				
 0C0C				FA_NEXT_TRACK:			   ;
 0C0C  C6 06 036D R 00		   MOV	 SIDE_TO_FORMAT, 0	   ;RESET SIDE_TO_FORMAT
 0C11  FE 06 0365 R		   INC	 TRACK_TO_FORMAT	   ;
 0C15  EB C2			   JMP	 FA_TRACK_WHILE 	   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-33
FORMAT_ALL - FORMATS ALL TRACKS TO END			;AN000;            

				
 0C17				FA_FATAL:			   ;
 0C17  C6 06 036F R 01		   MOV	 COPY_STATUS, FATAL	   ;WE ARE GOING TO ABORT PROGRAM
								   ;"Drive types or diskette types"
								   ;"not compatible"
				   PRINT MSGNUM_NOT_COMPATIBLE	   ;AC000;SHOW NOT COMPATIBLE MESSAGE
 0C1C  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_NOT_COMPATIBLE  ; 
 0C1F  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0C22  EB 0B			   JMP	 SHORT FA_DONE		   ;
				
 0C24				FA_TARGET_BAD:			   ;
 0C24  C6 06 036F R 01		   MOV	 COPY_STATUS, FATAL	   ;WE ARE GOING TO ABORT PROGRAM
								   ;CR,LF,"TARGET diskette bad or incompatible"
				   PRINT MSGNUM_BAD_TARGET	   ;AC000;SHOW TARGET BAD MESSAGE
 0C29  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_BAD_TARGET  ; 
 0C2C  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0C2F				FA_DONE:			   ;
 0C2F  33 DB			   XOR	 BX, BX 		   ;
 0C31  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 0C35  C6 06 0344 R 01		   MOV	 T_DRV_SET_FLAG, 1	   ;INDICATE TARGET DRIVE PARM HAS BEEN SET
 0C3A  BA 06E4 R		   MOV	 DX, OFFSET MT_IOCTL_DRV_PARM ;
 0C3D  C6 06 06E4 R 04		   MOV	 MT_specialFunctions, SET_SP_FUNC_DEF ;
 0C42  E8 0FF8 R		   CALL  SET_DRV_PARM_DEF	   ;SET IT BACK FOR WRITING.
				
 0C45  C3			   RET				   ;
 0C46				FORMAT_ALL ENDP 		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <FORMAT_TRACK - IOCTL FORMAT A TRACK> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-34
FORMAT_TRACK - IOCTL FORMAT A TRACK			;AN000;               

				;******************************************************************************
				; SUBROUTINE NAME :  FORMAT_TRACK     -  IOCTL FORMAT A TRACK		      *
				;					 (BOTH SIDES IF 2-SIDED DSKT)	      *
				;									      *
				; INPUT 	  :   TRACK_TO_FORMAT					      *
				;		  :   SIDE	       BYTE  0, 1  (HEAD NUMBER)	      *
				;		  :   END_OF_TRACK     BYTE  8, 9, 15			      *
				;		  :   TARGET_DRIVE     BYTE  1 = A, 2 = B, ETC		      *
				;									      *
				; OUTPUT	  :   none. This routine does not report format error.	      *
				;		      Write routine will detect the error consequently.       *
				; REGISTER(S) AFFECTED: 						      *
				;******************************************************************************
				   PUBLIC FORMAT_TRACK		   ;AN000;MAKE ENTRY IN LINK MAP
 0C46				FORMAT_TRACK PROC NEAR		   ;
				
 0C46				FT_AGAIN:			   ;
				;  $DO				   ;
 0C46				$$DO79:
 0C46  33 C0			       XOR   AX, AX		   ;
 0C48  A0 036D R		       MOV   AL, SIDE_TO_FORMAT    ;
 0C4B  A3 0809 R		       MOV   FHead, AX		   ;HEAD TO FORMAT
 0C4E  A0 0365 R		       MOV   AL, TRACK_TO_FORMAT   ;
 0C51  A3 080B R		       MOV   FCylinder, AX	   ;TRACK TO FORMAT
				
 0C54  33 DB			       XOR   BX, BX		   ;
 0C56  8A 1E 0309 R		       MOV   BL, TARGET_DRIVE	   ;DRIVE TO FORMAT
 0C5A  B1 42			       MOV   CL, FORMAT_FUNC	   ;=42h
 0C5C  BA 0808 R		       MOV   DX, OFFSET IOCTL_FORMAT ;
 0C5F  E8 1018 R		       CALL  GENERIC_IOCTL	   ;
				
 0C62  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY FORMAT AGAIN?
								   ; (DRIVE NOT READY OR WRITE PROTECTED)
				;  $ENDDO NE			   ;
 0C67  74 DD			   JE $$DO79
				
 0C69  C3			   RET				   ;
 0C6A				FORMAT_TRACK ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-35
CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE			;AN000;         

				;*****************************************************************************
				;									     *
				   PUBLIC CHECK_SOURCE		   ;AN000;MAKE ENTRY IN LINK MAP
 0C6A				CHECK_SOURCE PROC NEAR		   ;CHECK SOURCE DISKETTE TYPE		     *
				;				   SET END_OF_TRACK, LAST_TRACK 	     *
				;				   NO_OF_SIDES, bSECTOR_SIZE		     *
				; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on.  If it   *
				; ** fails to get that info, then the source medium must be bad(vergin) or   *
				; ** below DOS 2.0 level diskette, and will jmp to the old logic.	     *
				; ** For compatibility reasons (in case of non IBM formatted media), this    *
				; ** routine covers old diskcopy routines.  But this will only supports
				; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
				; ** media.  Other non IBM formatted media which are formatted differenty
				; ** from those values will result in unpreditable copy process.
				;*****************************************************************************
				
				;  $DO				   ;
 0C6A				$$DO81:
 0C6A  33 DB			       XOR   BX, BX		   ;
 0C6C  8A 1E 0308 R		       MOV   BL, SOURCE_DRIVE	   ;
 0C70  C6 06 05C0 R 01		       MOV   MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b
 0C75  B1 60			       MOV   CL, GETDEVPARM	   ;=60h
 0C77  BA 05C0 R		       MOV   DX, OFFSET MS_IOCTL_DRV_PARM ;
 0C7A  E8 1018 R		       CALL  GENERIC_IOCTL	   ;TRY TO GET MEDIA BPB INFO TOGETHER
								   ;WITH DEFAULT DEVICE INFO.
 0C7D  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY AGAIN?
				;  $ENDDO NE			   ;
 0C82  74 E6			   JE $$DO81
				
 0C84  80 3E 0371 R 02		   CMP	 IO_ERROR, HARD_ERROR	   ;CANNOT GET MEDIA BPB?
 0C89  74 69			   JE	 CS_OLD 		   ;ASSUME OLD FORMATTED DISKETTE, FIRST.
				
 0C8B  83 3E 05D4 R 00		   cmp	 ms_deviceBPB.csect_track,0 ;patch 1/16/86
 0C90  74 62			   je	 cs_old 		   ;
				
 0C92  83 3E 05D6 R 00		   cmp	 ms_deviceBPB.chead,0	   ;cannot trust the info from dos
 0C97  74 5B			   je	 cs_old 		   ;sanity check for divide by 0
				
 0C99  A1 05CF R		   MOV	 AX, MS_deviceBPB.CTOTSECT ;
 0C9C  99			   CWD				   ;CONVERT IT TO A DOUBLE WORD
 0C9D  F7 36 05D4 R		   DIV	 MS_deviceBPB.CSECT_TRACK  ;
 0CA1  F7 36 05D6 R		   DIV	 MS_deviceBPB.CHEAD	   ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
 0CA5  3A 06 0315 R		   CMP	 AL, T_DRV_TRACKS	   ;SOURCE MEDIA # OF TRACK > TARGET
								   ; DEVICE # OF TRACKS?
 0CA9  77 2D			   JA	 CS_FATAL		   ;THEN, NOT COMPATIBLE.
				
 0CAB  48			   DEC	 AX			   ;DECREASE BY 1 FOR THE USE OF THIS PROGRAM.
 0CAC  A2 035D R		   MOV	 LAST_TRACK, AL 	   ;SET LAST_TRACK
 0CAF  A1 05D4 R		   MOV	 AX, MS_deviceBPB.CSECT_TRACK ;
 0CB2  3A 06 0313 R		   CMP	 AL, T_DRV_SECT_TRACK	   ;SOURCE MEDIA # OF SECT/TRACK > TARGET
								   ; DEVICE # OF SECT/TRACK?
 0CB6  77 20			   JA	 CS_FATAL		   ;THEN, NOT COMPATIBLE
				
 0CB8  A2 035E R		   MOV	 END_OF_TRACK, AL	   ;
 0CBB  A1 05C7 R		   MOV	 AX, MS_deviceBPB.CBYTE_SECT ;
 0CBE  A3 035F R		   MOV	 bSECTOR_SIZE, AX	   ;set the sector size in bytes.
 0CC1  80 3E 030A R 01		   CMP	 USER_OPTION, 1 	   ;
 0CC6  74 6C			   JE	 CS_OPTION_1		   ;
				
 0CC8  A1 05D6 R		   MOV	 AX, MS_deviceBPB.CHEAD    ;HEAD=1, 2
 0CCB  3A 06 0314 R		   CMP	 AL, T_DRV_HEADS	   ;COMPARE SOURCE MEDIA SIDE WITH
								   ; TARGET DRIVE HEAD NUMBER
 0CCF  77 07			   JA	 CS_FATAL		   ;SOURCE MEDIUM IS DOUBLE SIDED AND
								   ; TARGET DRIVE IS SINGLE SIDED.
				
 0CD1  48			   DEC	 AX			   ;
 0CD2  A2 0361 R		   MOV	 NO_OF_SIDES, AL	   ;NO_OF_SIDES=0, 1
 0CD5  E9 0D88 R		   JMP	 CS_SET_TABLE		   ;
				;  =  =  =  =  =  =  =	=  =  =  =
 0CD8				CS_FATAL:			   ;
 0CD8  C6 06 036F R 01		   MOV	 COPY_STATUS, FATAL	   ;
								   ;CR,LF,"Drive types or diskette types",CR,LF
								   ;"not compatible",CR,LF
				   PRINT MSGNUM_NOT_COMPATIBLE	   ;AC000;
 0CDD  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_NOT_COMPATIBLE  ; 
 0CE0  E8 115A R             1					   CALL SENDMSG 	  ; 
 0CE3  E9 0DD8 R		   JMP	 CS_EXIT		   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0CE6				CS_BAD: 			   ;
 0CE6  C6 06 036F R 01		   MOV	 COPY_STATUS, FATAL	   ;
				   PRINT MSGNUM_BAD_SOURCE	   ;CR,LF,"SOURCE diskette bad or incompatible"
 0CEB  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_BAD_SOURCE  ; 
 0CEE  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0CF1  E9 0DD8 R		   JMP	 CS_EXIT		   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-36
CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE			;AN000;         

				
				;  =  =  =  =  =  =  =	=  =  =  =
 0CF4				CS_OLD: 			   ;
 0CF4  C6 06 035B R 01		   MOV	 READ_S_BPB_FAILURE, 1	   ;SET FLAG
 0CF9  C7 06 035F R 0200	   MOV	 bSECTOR_SIZE, 512	   ;OLD SECTOR SIZE MUST BE 512 BYTES
 0CFF  33 DB			   XOR	 BX, BX 		   ;
 0D01  8A 1E 0308 R		   MOV	 BL, SOURCE_DRIVE	   ;
 0D05  C7 06 0347 R 0000	   MOV	 IOCTL_TRACK, 0 	   ;TRACK=0
 0D0B  C7 06 0345 R 0008	   MOV	 IOCTL_SECTOR, 8	   ;SECTOR=8
 0D11  C7 06 0349 R 0000	   MOV	 IOCTL_HEAD, 0		   ;HEAD = 0
 0D17  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0D1A  72 CA			   JC	 CS_BAD 		   ;SOURCE BAD
				
 0D1C  C7 06 0345 R 0009	   MOV	 IOCTL_SECTOR, 9	   ;TRY TO READ SECTOR=9
 0D22  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0D25  72 20			   JC	 CS_SECT8		   ;YES, 8 SECTORS. ASSUME 40 TRACKS
				
 0D27  C7 06 0345 R 000F	   MOV	 IOCTL_SECTOR, 15	   ;try to read sector=15
 0D2D  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0D30  72 21			   JC	 CS_SECT9		   ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
				
 0D32  EB 07			   JMP	 SHORT CS_SECT15	   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D34				CS_OPTION_1:			   ;
 0D34  C6 06 0361 R 00		   MOV	 NO_OF_SIDES, 0 	   ;1 SIDE COPY
 0D39  EB 4D			   JMP	 SHORT CS_SET_TABLE	   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D3B				CS_SECT15:			   ;
 0D3B  C6 06 035E R 0F		   MOV	 END_OF_TRACK, 15	   ;ELSE END_OF_TRACK = 15
 0D40  C6 06 035D R 4F		   MOV	 LAST_TRACK, 79 	   ;
 0D45  EB 18			   JMP	 SHORT CS_CHK_SIDE	   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D47				CS_SECT8:			   ;
 0D47  C6 06 035E R 08		   MOV	 END_OF_TRACK, 8	   ;SOURCE 8 SECTORS
 0D4C  C6 06 035D R 27		   MOV	 LAST_TRACK,  39	   ;ASSUME 40 TRACKS.
 0D51  EB 0C			   JMP	 SHORT CS_CHK_SIDE	   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D53				CS_SECT9:			   ;
 0D53  C6 06 035E R 09		   MOV	 END_OF_TRACK, 9	   ;
 0D58  C6 06 035D R 27		   MOV	 LAST_TRACK, 39 	   ;ASSUME 5.25 DISKETTE
 0D5D  EB 00			   JMP	 SHORT CS_CHK_SIDE	   ;
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D5F				CS_CHK_SIDE:			   ;
 0D5F  80 3E 030A R 01		   CMP	 USER_OPTION, 1 	   ;
 0D64  74 CE			   JE	 CS_OPTION_1		   ;
				
 0D66  C7 06 0349 R 0001	   MOV	 IOCTL_HEAD, 1		   ;HEAD 1
 0D6C  33 C0			   XOR	 AX, AX 		   ;
 0D6E  A0 035E R		   MOV	 AL, END_OF_TRACK	   ;READ MATCHING END_OF_TRACK
								   ; OF THE OTHER SURFACE.
 0D71  A3 0345 R		   MOV	 IOCTL_SECTOR, AX	   ;
 0D74  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0D77  72 BB			   JC	 CS_OPTION_1		   ;1 SIDED SOURCE
				
 0D79  C6 06 0361 R 01		   MOV	 NO_OF_SIDES, 1 	   ;2 SIDED SOURCE
 0D7E  80 3E 0314 R 02		   CMP	 T_DRV_HEADS, 2 	   ;SOUCE=2 SIDED MEDIUM. IS TARGET
								   ; DOUBLE SIDED DRV?
 0D83  74 03			   JE	 CS_SET_TABLE		   ;
				
 0D85  E9 0CD8 R		   JMP	 CS_FATAL		   ;NOT COMPATIBLE
				
				;  =  =  =  =  =  =  =	=  =  =  =
 0D88				CS_SET_TABLE:			   ;
 0D88  80 3E 035B R 01		   CMP	 READ_S_BPB_FAILURE, 1	   ;DISKETTE WITHOUT BPB INFO?
				;  $IF	 E			   ;
 0D8D  75 03			   JNE $$IF83
 0D8F  E8 0E6E R		       CALL  SET_FOR_THE_OLD	   ;
				
				;  $ENDIF			   ;
 0D92				$$IF83:
 0D92  BB 05E6 R		   MOV	 BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE
 0D95  E8 0E9C R		   CALL  SET_TRACKLAYOUT	   ;
				
 0D98  BB 070A R		   MOV	 BX, OFFSET MT_trackLayout ;YES, ASSUME TARGET IS SAME
 0D9B  E8 0E9C R		   CALL  SET_TRACKLAYOUT	   ;
				
 0D9E  C6 06 0343 R 01		   MOV	 S_DRV_SET_FLAG, 1	   ;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-37
CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE			;AN000;         

 0DA3  33 DB			   XOR	 BX, BX 		   ;
 0DA5  8A 1E 0308 R		   MOV	 BL, SOURCE_DRIVE	   ;
 0DA9  C6 06 05C0 R 04		   MOV	 MS_specialFunctions, SET_SP_FUNC_DEF ;=00000100B
 0DAE  BA 05C0 R		   MOV	 DX, OFFSET MS_IOCTL_DRV_PARM ;
 0DB1  E8 0FF8 R		   CALL  SET_DRV_PARM_DEF	   ;NOW, SET SOURCE DRIVE PARM
								   ; FOR READ OPERATION.
				
 0DB4  33 C0			   XOR	 AX, AX 		   ;
 0DB6  A0 035E R		   MOV	 AL, END_OF_TRACK	   ;
 0DB9  A3 0814 R		   MOV	 numberOfSectors, AX	   ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
				
 0DBC  A0 035D R		   MOV	 AL, LAST_TRACK 	   ;NOW, SHOW THE MESSAGE "COPYING ..."
 0DBF  FE C0			   INC	 AL			   ;
				.LIST				   ;
 0DC1  A2 0000 E		   MOV	 BYTE PTR MSG_TRACKS, AL   ;AC000;HOW MANY TRACKS?
				
 0DC4  A0 035E R		   MOV	 AL, END_OF_TRACK	   ;
				.LIST				   ;
 0DC7  A2 0000 E		   MOV	 BYTE PTR MSG_SECTRK,AL    ;AC000;HOW MANY SECTORS?
				
 0DCA  A0 0361 R		   MOV	 AL, NO_OF_SIDES	   ;TELL USER HOW MANY SIDE TO COPY
 0DCD  FE C0			   INC	 AL			   ;
				.LIST				   ;
 0DCF  A2 0000 E		   MOV	 BYTE PTR MSG_SIDES,AL	   ;AC000;HOW MANY SIDES?
								   ;CR,LF,"Copying %1 tracks",CR,LF
								   ;"%2 Sectors/Track, %3 Side(s)",CR,LF
				   PRINT MSGNUM_COPYING 	   ;AC000;
 0DD2  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_COPYING  ; 
 0DD5  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0DD8				CS_EXIT:			   ;
 0DD8  C3			   RET				   ;
				
 0DD9				CHECK_SOURCE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-38
READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ			;AN000;    

				;******************************************************************************
				   PUBLIC READ_A_SECTOR 	   ;AN000;MAKE ENTRY IN LINK MAP
 0DD9				READ_A_SECTOR PROC NEAR 	   ;
				;									      *
				;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL.			      *
				;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY. 		      *
				;INPUT: BX - LOGICAL DRIVE NUMBER					      *
				;	IOCTL_SECTOR - SECTOR TO READ					      *
				;	IOCTL_TRACK - TRACK						      *
				;	IOCTL_HEAD - HEAD TO READ					      *
				;	bSECTOR_SIZE - SECTOR SIZE IN BYTES				      *
				;OUTPUT:								      *
				;	IF NOT A SUCCESS, CARRY WILL BE SET				      *
				;	ALL REGISTORS SAVED						      *
				;
				;******************************************************************************
				
 0DD9  50			   PUSH  AX			   ;
 0DDA  53			   PUSH  BX			   ;
 0DDB  51			   PUSH  CX			   ;
 0DDC  52			   PUSH  DX			   ;
				
 0DDD  A1 0814 R		   MOV	 AX, numberOfSectors	   ;SAVE IOCTL_R_W TABLE VALUES
 0DE0  A3 034B R		   MOV	 SAV_CSECT, AX		   ;
				
				;RAS_AGAIN:
				;  $DO				   ;
 0DE3				$$DO85:
 0DE3  A1 0349 R		       MOV   AX, IOCTL_HEAD	   ;
 0DE6  A3 080E R		       MOV   Head, AX		   ;SURFACE TO READ
 0DE9  A1 0347 R		       MOV   AX, IOCTL_TRACK	   ;
 0DEC  A3 0810 R		       MOV   Cylinder, AX	   ;TRACK TO READ
 0DEF  A1 0345 R		       MOV   AX, IOCTL_SECTOR	   ;
 0DF2  48			       dec   ax 		   ;????? currently
								   ; firstsector=0 => 1st sector ????
 0DF3  A3 0812 R		       MOV   FirstSectors, AX	   ;SECTOR TO READ
 0DF6  C7 06 0814 R 0001	       MOV   numberOfSectors, 1    ;read just one sector
 0DFC  B8 0000 E		       MOV   AX, offset INIT	   ;READ IT INTO INIT
								   ; (CURRELTLY, MAX 1K)
 0DFF  A3 0816 R		       MOV   TAddress_off, AX	   ;
 0E02  8C 1E 0818 R		       MOV   TAddress_seg, DS	   ;
 0E06  B1 61			       MOV   CL, READ_FUNC	   ;
 0E08  BA 080D R		       MOV   DX, OFFSET IOCTL_R_W  ;POINTS TO CONTROL TABLE
 0E0B  E8 1018 R		       call  generic_ioctl	   ;
				
 0E0E  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY ONCE MORE?
				;  $ENDDO NE			   ;
 0E13  74 CE			   JE $$DO85
				
 0E15  80 3E 0371 R 02		   CMP	 IO_ERROR, HARD_ERROR	   ;HARD ERROR?
				;  $IF	 NE			   ;
 0E1A  74 03			   JE $$IF87
				
 0E1C  F8			       CLC			   ;READ SUCCESS
				;  $ELSE			   ;
 0E1D  EB 01			   JMP SHORT $$EN87
 0E1F				$$IF87:
 0E1F  F9			       STC			   ;SET CARRY
				;  $ENDIF			   ;
 0E20				$$EN87:
 0E20  A1 034B R		   MOV	 AX, SAV_CSECT		   ;RESTORE ORIGINAL IOCTL_R_W TABLE
 0E23  A3 0814 R		   MOV	 numberOfSectors, AX	   ;
 0E26  5A			   POP	 DX			   ;
 0E27  59			   POP	 CX			   ;
 0E28  5B			   POP	 BX			   ;
 0E29  58			   POP	 AX			   ;
 0E2A  C3			   RET				   ;
				
 0E2B				READ_A_SECTOR ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-39
CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK			;AN000; 

				;*****************************************************************************
				   PUBLIC CALC_TRACK_SIZE	   ;AN000;MAKE ENTRY IN LINK MAP
 0E2B				CALC_TRACK_SIZE PROC NEAR	   ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
				;			      TRACK (IN SEGMENTS)			     *
				;
				;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE.  IF bSECTOR_SIZE CANNOT BE *
				;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE.      *
				;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY.  THE ACTUAL COPY OR FORMAT  *
				;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS.	     *
				;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh.     *
				;*****************************************************************************
				
 0E2B  50			   PUSH  AX			   ;
 0E2C  53			   PUSH  BX			   ;
 0E2D  51			   PUSH  CX			   ;
				
 0E2E  A1 035F R		   MOV	 AX, bSECTOR_SIZE	   ;
 0E31  B1 10			   MOV	 CL, 16 		   ;
 0E33  F6 F1			   DIV	 CL			   ;AX / 16 = AL ... AH
 0E35  80 FC 00			   CMP	 AH, 0			   ;NO REMAINER?
				;  $IF	 NE			   ;
 0E38  74 02			   JE $$IF90
				
 0E3A  FE C0			       INC   AL 		   ;THERE REMAINER IS.	INC AL
				
				;  $ENDIF			   ;
 0E3C				$$IF90:
 0E3C  A2 0368 R		   MOV	 SECTOR_SIZE, AL	   ;SECTOR_SIZE+ IN PARA.
 0E3F  A0 0361 R		   MOV	 AL,NO_OF_SIDES 	   ;TRACK_SIZE = (NO OF SIDES
 0E42  FE C0			   INC	 AL			   ;		  + 1)
 0E44  F6 26 035E R		   MUL	 END_OF_TRACK		   ;		  * END_OF_TRACK
 0E48  8A 1E 0368 R		   MOV	 BL,SECTOR_SIZE 	   ;		  * SECTPR_SIZE
 0E4C  F6 E3			   MUL	 BL			   ;AMOUNT OF MEMORY REQUIRED (IN SEG)
 0E4E  A3 0366 R		   MOV	 TRACK_SIZE,AX		   ;TO STORE A TRACK
 0E51  59			   POP	 CX			   ;
 0E52  5B			   POP	 BX			   ;
 0E53  58			   POP	 AX			   ;
				
 0E54  C3			   RET				   ;
 0E55				CALC_TRACK_SIZE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-40
CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK			;A

				;*****************************************************************************
				   PUBLIC CHECK_MEMORY_SIZE	   ;AN000;MAKE ENTRY IN LINK MAP
 0E55				CHECK_MEMORY_SIZE PROC NEAR	   ;MAKE SURE WE HAVE ENOUGH TO COPY 1 TRACK INTO
				;			      TO BUFFER ELSE ABORT COPY 		     *
				;*****************************************************************************
 0E55  A1 030E R		   MOV	 AX,BUFFER_END		   ;CALCULATE AVAILABLE MEMORY
 0E58  2B 06 030C R		   SUB	 AX,BUFFER_BEGIN	   ;IN SEGMENTS
 0E5C  3B 06 0366 R		   CMP	 AX,TRACK_SIZE		   ;DO WE HAVE ENOUGH TO STORE A CYLINDER?
				;  $IF	 B			   ;
 0E60  73 0B			   JNB $$IF92
 0E62  C6 06 036F R 01		       MOV   COPY_STATUS,FATAL	   ;NO, ABORT COPY
				       PRINT MSGNUM_UNSUF_MEMORY   ;AC000;AND TELL USER WHY
 0E67  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_UNSUF_MEMORY  ; 
 0E6A  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				;  $ENDIF			   ;
 0E6D				$$IF92:
 0E6D  C3			   RET				   ;
				
 0E6E				CHECK_MEMORY_SIZE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <SET_FOR_THE_OLD  - SET BPB FOR BEFORE-2.0 FMTTED MEDIA> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-41
SET_FOR_THE_OLD  - SET BPB FOR BEFORE-2.0 FMTTED MEDIA			;AN

				;*****************************************************************************
				   PUBLIC SET_FOR_THE_OLD	   ;AN000;MAKE ENTRY IN LINK MAP
 0E6E				SET_FOR_THE_OLD PROC NEAR	   ;
				
				;set MS_deviceBPB for before-2.0 formatted media
				;*****************************************************************************
 0E6E  50			   PUSH  AX			   ;
				
 0E6F  80 3E 035E R 09		   CMP	 END_OF_TRACK,9 	   ;IF SECTORS/TRACK <= 9, THEN CHECK
								   ;NO_OF_SIDES. IF SINGLE SIDE
								   ; COPY THEN USE BPB48_SINGLE
								   ;ELSE USE BPB48_DOUBLE.
				;  $IF	 A			   ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
 0E74  76 05			   JNA $$IF94
 0E76  BE 0330 R		       MOV   SI, OFFSET BPB96	   ;
				;  $ELSE			   ;
 0E79  EB 0F			   JMP SHORT $$EN94
 0E7B				$$IF94:
 0E7B  80 3E 0361 R 00		       CMP   NO_OF_SIDES, 0	   ;SINGLE SIDE COPY?
				;      $IF   NE 		   ;IF NOT,
 0E80  74 05			       JE $$IF96
 0E82  BE 0323 R			   MOV	 SI, OFFSET BPB48_DOUBLE ;USE BPB48 DOUBLE
				;      $ELSE			   ;
 0E85  EB 03			       JMP SHORT $$EN96
 0E87				$$IF96:
 0E87  BE 0316 R			   MOV	 SI, OFFSET BPB48_SINGLE ;
				;      $ENDIF			   ;
 0E8A				$$EN96:
				;  $ENDIF			   ;
 0E8A				$$EN94:
 0E8A  33 C0			   XOR	 AX, AX 		   ;
 0E8C  A0 035E R		   MOV	 AL, END_OF_TRACK	   ;
				
 0E8F  A3 05D4 R		   MOV	 MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
 0E92  BF 05C7 R		   MOV	 DI, OFFSET MS_deviceBPB   ;
 0E95  B9 000D			   MOV	 CX, BPB96_LENG 	   ;
 0E98  F3/ A4			   REP	 MOVSB			   ;OLD DEFAULT BPB INFO => MS_deviceBPB
				
 0E9A  58			   POP	 AX			   ;
 0E9B  C3			   RET				   ;
 0E9C				SET_FOR_THE_OLD ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-42
SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE			;AN000;        

				;*****************************************************************************
				   PUBLIC SET_TRACKLAYOUT	   ;AN000;MAKE ENTRY IN LINK MAP
 0E9C				SET_TRACKLAYOUT PROC NEAR	   ;
				
				;INPUT: BX - POINTER TO DESTINATION
				;*****************************************************************************
				
 0E9C  33 C9			   XOR	 CX, CX 		   ;
 0E9E  8A 0E 035E R		   MOV	 CL, END_OF_TRACK	   ;
 0EA2  89 0F			   MOV	 WORD PTR [BX], CX	   ;SET CSECT_F TO THE NUMBER OF
								   ; SECTORS IN A TRACK
 0EA4  83 C3 02			   ADD	 BX, 2			   ;NOW BX POINTS TO
								   ; THE FIRST SECTORNUMBER
 0EA7  B9 0001			   MOV	 CX, 1			   ;
 0EAA  A1 035F R		   MOV	 AX, bSECTOR_SIZE	   ;
				
				;  $DO				   ;
 0EAD				$$DO100:
 0EAD  3A 0E 035E R		       CMP   CL, END_OF_TRACK	   ;
				;  $LEAVE A			   ;
 0EB1  77 0B			   JA $$EN100
				
 0EB3  89 0F			       MOV   WORD PTR [BX], CX	   ;
 0EB5  43			       INC   BX 		   ;
 0EB6  43			       INC   BX 		   ;
 0EB7  89 07			       MOV   WORD PTR [BX], AX	   ;
 0EB9  43			       INC   BX 		   ;
 0EBA  43			       INC   BX 		   ;
				
 0EBB  41			       INC   CX 		   ;
				;  $ENDDO			   ;
 0EBC  EB EF			   JMP SHORT $$DO100
 0EBE				$$EN100:
				
 0EBE  C3			   RET				   ;
 0EBF				SET_TRACKLAYOUT ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-43
CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?			;AN000;

				;*****************************************************************************
				   PUBLIC CHECK_TARGET		   ;AN000;MAKE ENTRY IN LINK MAP
 0EBF				CHECK_TARGET PROC NEAR		   ;					*
				;   ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD.		     *
				;   ** IF A SUCCESS,THEN COMPARES BPB INFO WITH THAT OF SOURCE MEDIA.	     *
				;   ** IF THEY ARE DIFFERENT, THEN SET FORMAT_FLAG AND RETURN.		     *
				;   ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR      *
				;   ** COMPATIBILITY REASON.						     *
				;*****************************************************************************
				
				;  $DO				   ;
 0EBF				$$DO103:
 0EBF  33 DB			       XOR   BX, BX		   ;
 0EC1  8A 1E 0309 R		       MOV   BL, TARGET_DRIVE	   ;
 0EC5  C6 06 06E4 R 01		       MOV   MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b
 0ECA  B1 60			       MOV   CL, GETDEVPARM	   ;=60h
 0ECC  BA 06E4 R		       MOV   DX, OFFSET MT_IOCTL_DRV_PARM ;
 0ECF  E8 1018 R		       CALL  GENERIC_IOCTL	   ;TRY TO GET MEDIA BPB INFO TOGETHER
								   ;WITH DEFAULT DEVICE INFO.
 0ED2  80 3E 0371 R 01		       CMP   IO_ERROR, SOFT_ERROR  ;TRY AGAIN?
				;  $ENDDO NE			   ;
 0ED7  74 E6			   JE $$DO103
				
 0ED9  80 3E 0371 R 02		   CMP	 IO_ERROR, HARD_ERROR	   ;CANNOT GET MEDIA BPB?
 0EDE  74 62			   JE	 CT_OLD 		   ;ASSUME OLD FORMATTED DISKETTE, FIRST.
				
 0EE0  83 3E 06F8 R 00		   cmp	 mt_deviceBPB.csect_track,0 ;patch 1/16/86 for 3.2 diskcopy
 0EE5  74 5B			   je	 ct_old 		   ;
				
 0EE7  83 3E 06FA R 00		   cmp	 mt_deviceBPB.chead,0	   ;cannot belive the info from dos
 0EEC  74 54			   je	 ct_old 		   ;sanity check for divide by 0.
				
 0EEE  A1 06F3 R		   MOV	 AX, MT_deviceBPB.CTOTSECT ;
 0EF1  99			   CWD				   ;CONVERT IT TO A DOUBLE WORD
 0EF2  F7 36 06F8 R		   DIV	 MT_deviceBPB.CSECT_TRACK  ;
 0EF6  F7 36 06FA R		   DIV	 MT_deviceBPB.CHEAD	   ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
 0EFA  48			   DEC	 AX			   ;DECREASE BY 1 FOR THIS PROGRAM.
 0EFB  38 06 035D R		   CMP	 LAST_TRACK, AL 	   ;COMPARE WITH THE LAST TRACK OF SOURCE
 0EFF  74 11			   JE	 CT_SECTOR_TRACK	   ;IF SAME, THEN CHECK SECTOR PER TRACK
								   ;SINCE NOT THE SAME, CONTINUE...
				
 0F01  83 3E 06F8 R 0F		   CMP	 MT_deviceBPB.CSECT_TRACK,0FH ;AN012;IS TARGET 15 SEC / TRK?
 0F06  75 29			   JNE	 CT_FORMAT		   ;AN012;NO, SOMETHING ELSE...
								   ;YES, 15 SEC/TRACK, CONTINUE...
				
 0F08  80 3E 035D R 27		   CMP	 LAST_TRACK,27H 	   ;AN012;IS SOURCE ORIGINALLY 40 TRACK?
 0F0D  75 22			   JNE	 CT_FORMAT		   ;AN012;NO, SOMETHING ELSE...
								   ;YES, 40 TRACK, CONTINUE...
 0F0F  E9 0FA3 R		   JMP	 CT_FATAL		   ;AN012;ABORT THIS, DO NOT MESS UP THE 1.2M
								   ; WITH NOBLE ATTEMPTS TO FORMAT
 0F12				CT_SECTOR_TRACK:		   ;
 0F12  A1 06F8 R		   MOV	 AX, MT_deviceBPB.CSECT_TRACK ;
 0F15  38 06 035E R		   CMP	 END_OF_TRACK, AL	   ;
 0F19  75 16			   JNE	 CT_FORMAT		   ;
				
 0F1B				CT_BYTE_SECTOR: 		   ;
 0F1B  A1 06EB R		   MOV	 AX, MT_deviceBPB.CBYTE_SECT ;
 0F1E  3B 06 035F R		   CMP	 AX, bSECTOR_SIZE	   ;
 0F22  75 0D			   JNE	 CT_FORMAT		   ;
				
 0F24				CT_HEAD:			   ;
 0F24  A1 06FA R		   MOV	 AX, MT_deviceBPB.CHEAD    ;
 0F27  48			   DEC	 AX			   ;
 0F28  3A 06 0361 R		   CMP	 AL, NO_OF_SIDES	   ;
 0F2C  72 03			   JB	 CT_FORMAT		   ;IF TARGET SIDE < SOURCE SIDE
								   ; THEN FORMAT IT.
				
 0F2E  E9 0FBB R		   JMP	 CT_SET_DRV		   ;TARGET IS O.K. SET DRIVE PARM
								   ; AND EXIT
				
 0F31				CT_FORMAT:			   ;
				   PRINT MSGNUM_FORMATTING	   ;AC000;"Formatting while copying"
 0F31  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_FORMATTING  ; 
 0F34  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0F37  C6 06 0362 R 01		   MOV	 FORMAT_FLAG, ON	   ;
 0F3C  E8 0B77 R		   CALL  FORMAT_ALL		   ;FORMAT ALL TRACKS STARTING
								   ; FROM TRACK_TO_WRITE
 0F3F  E9 0FDB R		   JMP	 CT_EXIT		   ;
				
 0F42				CT_OLD: 			   ;AC011;
 0F42  80 3E 0372 R 01		   CMP	 UKM_ERR,ON		   ;AN011;IS THIS HARD ERROR "UNKNOWN MEDIA"?
 0F47  74 E8			   JE	 CT_FORMAT		   ;AN011; IF SO, GO TRY FORMATTING
								   ;SAME OLD... ;AGAIN, THIS DOES
								   ; NOT RECOGNIZE 3.5 MEDIA
 0F49  C6 06 035C R 01		   MOV	 READ_T_BPB_FAILURE, 1	   ;SET THE FLAG
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-44
CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?			;AN000;

 0F4E  33 DB			   XOR	 BX, BX 		   ;
 0F50  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 0F54  C7 06 0347 R 0000	   MOV	 IOCTL_TRACK, 0 	   ;
 0F5A  C7 06 0345 R 0008	   MOV	 IOCTL_SECTOR, 8	   ;
 0F60  C7 06 0349 R 0000	   MOV	 IOCTL_HEAD, 0		   ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
 0F66  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0F69  72 C6			   JC	 CT_FORMAT		   ;ASSUME TARGET MEDIA NOT FORMATTED.
				
 0F6B  C7 06 0345 R 0009	   MOV	 IOCTL_SECTOR, 9	   ;TRY TO READ SECTOR 9
 0F71  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0F74  72 15			   JC	 CT_8_SECTOR		   ;TARGET IS 8 SECTOR MEDIA
				
 0F76  C7 06 0345 R 000F	   MOV	 IOCTL_SECTOR, 15	   ;
 0F7C  E8 0DD9 R		   CALL  READ_A_SECTOR		   ;
				
 0F7F  72 1B			   JC	 CT_9_SECTOR		   ;TARGET IS 9 SECTOR MEDIA
				
				;CT_15_SECTOR:				;TARGET IS 15 SECTOR MEDIA
 0F81  80 3E 035E R 0F		   CMP	 END_OF_TRACK, 15	   ;IS SOURCE ALSO 96 TPI?
 0F86  75 1B			   JNE	 CT_FATAL		   ;NO, FATAL ERROR
				
 0F88  EB 26 90			   JMP	 CT_EXIT_OLD		   ;OK
				
 0F8B				CT_8_SECTOR:			   ;
 0F8B  80 3E 035E R 0F		   CMP	 END_OF_TRACK, 15	   ;
 0F90  74 11			   JE	 CT_FATAL		   ;IF SOURCE IS 96 TPI, THEN FATAL ERROR
				
 0F92  80 3E 035E R 09		   CMP	 END_OF_TRACK, 9	   ;
 0F97  74 98			   JE	 CT_FORMAT		   ;IF SOURCE IS 9 SECTOR, THEN
								   ; SHOULD FORMAT TARGET
				
 0F99  EB 15 90			   JMP	 CT_EXIT_OLD		   ;ELSE ASSUME SOURCE IS 8 SECTOR.
				
 0F9C				CT_9_SECTOR:			   ;
 0F9C  80 3E 035E R 0F		   CMP	 END_OF_TRACK, 15	   ;IS SOURCE 96 TPI ?
 0FA1  75 0D			   JNE	 CT_EXIT_OLD		   ;NO. SOUCE IS 8 OR 9
								   ; SECTORED 48 TPI DISKETTE
				
 0FA3				CT_FATAL:			   ;
 0FA3  C6 06 036F R 01		   MOV	 COPY_STATUS, FATAL	   ;
								   ;"Drive types or diskette types"
				   PRINT MSGNUM_NOT_COMPATIBLE	   ;AC000;"not compatible"
 0FA8  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_NOT_COMPATIBLE  ; 
 0FAB  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 0FAE  EB 2B			   JMP	 SHORT	 CT_EXIT	   ;
				
 0FB0				CT_EXIT_OLD:			   ;
 0FB0  B9 001F			   MOV	 CX, MS_deviceBPB_leng	   ;
 0FB3  BE 05C7 R		   MOV	 SI, OFFSET MS_deviceBPB   ;
 0FB6  BF 06EB R		   MOV	 DI, OFFSET MT_deviceBPB   ;
 0FB9  F3/ A4			   REP	 MOVSB			   ;set MT_deviceBPB to MS_deviceBPB
 0FBB				CT_SET_DRV:			   ;
 0FBB  C6 06 0344 R 01		   MOV	 T_DRV_SET_FLAG, 1	   ;INDICATE THE TARGET DEFAULT
								   ; DEVICE PARM HAS BEEN SET.
 0FC0  33 DB			   XOR	 BX, BX 		   ;
 0FC2  8A 1E 035D R		   mov	 bl, last_track 	   ;patch for 3.2 diskcopy, 3/27/86 J.K.
 0FC6  FE C3			   inc	 bl			   ;
 0FC8  89 1E 06E8 R		   mov	 MT_numberOfCylinders, bx  ;make sure the # of cyl of the target
 0FCC  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 0FD0  BA 06E4 R		   MOV	 DX, OFFSET MT_IOCTL_DRV_PARM ;
 0FD3  C6 06 06E4 R 04		   MOV	 MT_specialFunctions, SET_SP_FUNC_DEF ;
 0FD8  E8 0FF8 R		   CALL  SET_DRV_PARM_DEF	   ;
				
 0FDB				CT_EXIT:			   ;
 0FDB  C3			   RET				   ;
				
 0FDC				CHECK_TARGET ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-45
CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA			;AN000;   

				;*****************************************************************************
				   PUBLIC CHK_MULTI_MEDIA	   ;AN000;MAKE ENTRY IN LINK MAP
 0FDC				CHK_MULTI_MEDIA PROC NEAR	   ;
				;IF THE SOURCE IS 96 TPI DISKETTE, AND TARGET IS 48 TPI
				;DISKETTE, OR VICE VERSA, THEN SET THE CARRY BIT.
				;THIS ROUTINE BE CALLED WHEN BPB INFORMATIONS OF TARGET HAS BEEN SUCCESSFULLY
				;READ.
				;*** CURRENTLY, ONLY 96 TPI DRIVE IN PC_AT CAN HAVE MULTI_MEDIA.
				;INPUT: AX - TARGET MEDIA CYLINDER NUMBER - 1
				;	LAST_TRACK - SOURCE MEDIA CYLINDER NUMBER - 1
				;*****************************************************************************
 0FDC  F8			   CLC				   ;CLEAR CARRY
 0FDD  80 3E 035D R 27		   CMP	 LAST_TRACK, 39 	   ;SOURCE IS 48 TPI MEDIA?
				;  $IF	 E,AND			   ;
 0FE2  75 07			   JNE $$IF105
 0FE4  3C 4F			   CMP	 AL, 79 		   ;AND TARGET IS 96 TPI MEDIA?
				;  $IF	 E			   ;
 0FE6  75 03			   JNE $$IF105
 0FE8  F9			       STC			   ;THEN SET CARRY
				;  $ELSE			   ;
 0FE9  EB 0C			   JMP SHORT $$EN105
 0FEB				$$IF105:
 0FEB  80 3E 035D R 4F		       CMP   LAST_TRACK, 79	   ;SOURCE IS 96 TPI MEDIA?
				;      $IF   E,AND		   ;
 0FF0  75 05			       JNE $$IF107
 0FF2  3C 27			       CMP   AL, 39		   ;AND TARGET IS 48 TPI?
				;      $IF   E			   ;
 0FF4  75 01			       JNE $$IF107
 0FF6  F9				   STC			   ;
				;      $ENDIF			   ;
 0FF7				$$IF107:
				;  $ENDIF			   ;
 0FF7				$$EN105:
 0FF7  C3			   RET				   ;
 0FF8				CHK_MULTI_MEDIA ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-46
SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL			;AN000;      

				;*****************************************************************************
				   PUBLIC SET_DRV_PARM_DEF	   ;AN000;MAKE ENTRY IN LINK MAP
 0FF8				SET_DRV_PARM_DEF PROC NEAR	   ;
				;SET THE DRV PARMAMETERS
				;INPUT: BL - DRIVE NUMBER
				;	DX - POINTER TO THE DEFAULT PARAMETER TABLE
				;	specialfunc should be set before calling this routine
				;*****************************************************************************
 0FF8  B1 40			   MOV	 CL, SETDEVPARM 	   ;=40H
 0FFA  E8 1018 R		   CALL  GENERIC_IOCTL		   ;
				
 0FFD  C3			   RET				   ;
 0FFE				SET_DRV_PARM_DEF ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-47
CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT			;

				;*****************************************************************************
				   PUBLIC CHK_MEDIATYPE 	   ;AN000;MAKE ENTRY IN LINK MAP
 0FFE				CHK_MEDIATYPE PROC NEAR 	   ;
				;SET THE mediaType OF IOCTL_DRV_PARM FOR TARGET DRIVE IN CASE OF FORMAT.
				;IF TARGET IS A MULTI-MEDIA DEVICE, mediaType SHOULD BE SET CORRECTLY
				;TO FORMAT THE TARGET MEDIA.
				;IF EITHER OF LAST_TRACK OR END_OF_TRACK IS LESS THAN THAT OF TARGET
				;DRIVE, THEN mediaType WILL BE SET TO 1. OTHERWISE, IT WILL BE 0 FOR
				;THE DEFAULT VALUE.
				;*****************************************************************************
				
 0FFE  A0 0315 R		   MOV	 AL, T_DRV_TRACKS	   ;TARGET DEVICE MAXIUM TRACKS
 1001  FE C8			   DEC	 AL			   ;
 1003  38 06 035D R		   CMP	 LAST_TRACK, AL 	   ;COMPARE SOURCE MEDIA # OF TRACKS TO IT
				;  $IF	 B,OR			   ;
 1007  72 09			   JB $$LL110
 1009  A0 0313 R		   MOV	 AL, T_DRV_SECT_TRACK	   ;
 100C  38 06 035E R		   CMP	 END_OF_TRACK, AL	   ;SOURCE # OF SECT/TRACK < TARGET DEVICE?
				;  $IF	 B			   ;
 1010  73 05			   JNB $$IF110
 1012				$$LL110:
 1012  C6 06 06EA R 01		       MOV   MT_mediaType, 1	   ;
				;  $ENDIF			   ;
 1017				$$IF110:
 1017  C3			   RET				   ;
 1018				CHK_MEDIATYPE ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-48
GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER			;AN000;

				;*****************************************************************************
				   PUBLIC GENERIC_IOCTL 	   ;AN000;MAKE ENTRY IN LINK MAP
 1018				GENERIC_IOCTL PROC NEAR 	   ;
				;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
				;			 61 - READ TRACK, 41 - WRITE TRACK,
				;			 42 - FORMAT AND VERIFY TRACK, 43 - SET MEDIA ID
				;			 62 - VERIFY TRACK, 63 - GET MEDIA ID
				;	BL - LOGICAL DRIVE LETTER
				;	DS:DX - POINTER TO PARAMETERS
				;*****************************************************************************
 1018  C6 06 0371 R 00		   MOV	 IO_ERROR, NO_ERROR	   ;reset io_error
 101D  B5 08			   MOV	 CH, MAJOR_CODE 	   ;MAJOR CODE, REMOVABLE = 08H
				   DOSCALL IOCTL_FUNC,GENERIC_IOCTL_CODE ;AC000;(440DH) CALL THE DEVICE DRIVER
 101F  B8 440D               1					   MOV AX,(IOCTL_FUNC SHL 8)+GENERIC_IOCTL_CODE ; 
 1022  CD 21                 1					   INT 21H ; 
				
				;  $IF	 C			   ;
 1024  73 03			   JNC $$IF112
 1026  E8 102A R		       CALL  EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS!
				
				;  $ENDIF			   ;
 1029				$$IF112:
 1029  C3			   RET				   ;
 102A				GENERIC_IOCTL ENDP		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-49
EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS			;AN000;    

				;*****************************************************************************
				   PUBLIC EXTENDED_ERROR_HANDLER   ;AN000;MAKE ENTRY IN LINK MAP
 102A				EXTENDED_ERROR_HANDLER PROC NEAR   ;
				;INPUT: BL - LOGICAL DRIVE LETTER
				;*****************************************************************************
				
 102A  9C			   PUSHF			   ;
 102B  50			   PUSH  AX			   ;
 102C  53			   PUSH  BX			   ;
 102D  51			   PUSH  CX			   ;
 102E  52			   PUSH  DX			   ;
 102F  56			   PUSH  SI			   ;
 1030  57			   PUSH  DI			   ;
 1031  06			   PUSH  ES			   ;
 1032  1E			   PUSH  DS			   ;
 1033  53			   PUSH  BX			   ;
				
 1034  B4 59			   MOV	 AH, EXTENDED_ERROR	   ;59H
 1036  BB 0000			   MOV	 BX, 0			   ;
 1039  CD 21			   INT	 21H			   ;
				
 103B  5B			   POP	 BX			   ;RESTORE BL FOR DRIVE LETTER
 103C  1F			   POP	 DS			   ;
 103D  07			   POP	 ES			   ;
				
 103E  3D 0015			   CMP	 AX, 21 		   ;DRIVE NOT READY? (TIME_OUT ERROR?)
 1041  74 08			   JE	 EEH_CHK_TIMEOUT	   ;
				
 1043  3D 0013			   CMP	 AX, 19 		   ;ATTEMP TO WRITE ON WRITE_PROTECTED?
 1046  74 58			   JE	 WARN_USER_2		   ;
				
 1048  EB 66 90			   JMP	 EEH_HARD_ERROR 	   ;OTHERWISE, HARD_ERROR
				
 104B				EEH_CHK_TIMEOUT:		   ;BECAUSE OF THE INACCURACY
								   ; OF TIME OUT ERROR,
								   ;IN READING AND WRITING OPERATION,
								   ; CHECK OUT CAREFULLY WITH "FORMAT"
 104B  80 3E 0362 R 01		   CMP	 FORMAT_FLAG, ON	   ;AFTER OR DURING FORMAT OPERATION,
 1050  74 34			   JE	 WARN_USER_1		   ; TIME OUT ERROR IS
								   ; ASSUMED TO BE CORRECT.
				
 1052  80 3E 0375 R 01		   CMP	 TRY_FORMAT_FLAG, ON	   ;HAPPENED AT "TRY_FORMAT" PROCEDURE?
 1057  74 25			   JE	 EEH_TIMEOUT		   ;
				
 1059  80 3E 0374 R 01		   CMP	 TARGET_OP, ON		   ;HAPPENED ON TARGET DRIVE?
 105E  75 26			   JNE	 WARN_USER_1		   ;IF NOT, THEN ASSUME TIME OUT ERROR
				
 1060  C6 06 0375 R 01		   MOV	 TRY_FORMAT_FLAG, ON	   ;
 1065  E8 10CC R		   CALL  TRY_FORMAT		   ;JUST TRY TO FORMAT THE TRACK.
				
 1068  C6 06 0375 R 00		   MOV	 TRY_FORMAT_FLAG, OFF	   ;
 106D  80 3E 0376 R 01		   CMP	 TIME_OUT_FLAG, ON	   ;REAL TIME OUT?
 1072  74 12			   JE	 WARN_USER_1		   ;YES, A SOFT ERROR.
				
 1074  80 3E 0371 R 01		   CMP	 IO_ERROR, SOFT_ERROR	   ;IT HAPPENED AT TRY_FORMAT PROC AND
								   ; PC_AT WHEN THE DRIVE DOOR OPENED ABRUPTLY.
 1079  74 49			   JE	 EEH_EXIT		   ;IT WAS WRITE PROTECTED ERROR.
				
 107B  EB 33 90			   JMP	 EEH_HARD_ERROR 	   ;NO, "ADDRESS MARK NOT OUT". A HARD ERROR.
				
 107E				EEH_TIMEOUT:			   ;
 107E  C6 06 0376 R 01		   MOV	 TIME_OUT_FLAG, ON	   ;SET TIME_OUT_FLAG AND EXIT THIS ROUTINE
 1083  EB 3F 90			   JMP	 EEH_EXIT		   ;
				
 1086				WARN_USER_1:			   ;
 1086  C6 06 0000 E 41		   MOV	 DRIVE_LETTER, 'A'	   ;
 108B  FE CB			   DEC	 BL			   ;CHANGE LOGICAL TO PHYSICAL
 108D  00 1E 0000 E		   ADD	 DRIVE_LETTER, BL	   ;
				   PRINT MSGNUM_GET_READY	   ;AC000;"Drive not ready - %0"
 1091  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_GET_READY  ; 
 1094  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				   PRINT MSGNUM_CLOSE_DOOR	   ;AN004;"Make sure a diskette is inserted into
 1097  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_CLOSE_DOOR  ; 
 109A  E8 115A R             1					   CALL SENDMSG 	  ; 
								   ;  the drive and the door is closed"
 109D  EB 07 90			   JMP	 WAIT_FOR_USER		   ;
				
 10A0				WARN_USER_2:			   ;
				   PRINT MSGNUM_WRITE_PROTECT	   ;AC000;"Attempt to write to write-protected diskette"
 10A0  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_WRITE_PROTECT  ; 
 10A3  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 10A6				WAIT_FOR_USER:			   ;
								   ;"Press any key when ready . . ."
 10A6  E8 11D1 R		   CALL  PRESS_ANY_KEY		   ;AC000; THEN WAIT FOR ANY RESPONSE
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-50
EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS			;AN000;    

				
 10A9  C6 06 0371 R 01		   MOV	 IO_ERROR, SOFT_ERROR	   ;INDICATE THE CALLER TO TRY AGAIN
 10AE  EB 14			   JMP	 SHORT EEH_EXIT 	   ;
				
 10B0				EEH_HARD_ERROR: 		   ;
 10B0  C6 06 0371 R 02		   MOV	 IO_ERROR, HARD_ERROR	   ;
 10B5  C6 06 0372 R 00		   MOV	 UKM_ERR,OFF		   ;AN011;ASSUME NOT "UNKNOWN MEDIA" TYPE ERROR
 10BA  3D 001A			   CMP	 AX,26			   ;AN011;IS THE ERROR TYPE IS "UNKNOWN MEDIA"?
				;  $IF	 E			   ;AN011;IF "UNKNOWN MEDIA" TYPE ERROR
 10BD  75 05			   JNE $$IF114
 10BF  C6 06 0372 R 01		       MOV   UKM_ERR,ON 	   ;AN011;SET FLAG TO INDICATE "UNKNOWN MEDIA"
								   ; TO CAUSE FORMATTING OF TARGET DISKETTE
				;  $ENDIF			   ;AN011;
 10C4				$$IF114:
				
 10C4				EEH_EXIT:			   ;
 10C4  5F			   POP	 DI			   ;
 10C5  5E			   POP	 SI			   ;
 10C6  5A			   POP	 DX			   ;
 10C7  59			   POP	 CX			   ;
 10C8  5B			   POP	 BX			   ;
 10C9  58			   POP	 AX			   ;
 10CA  9D			   POPF 			   ;
 10CB  C3			   RET				   ;
				.LIST				   ;
 10CC				EXTENDED_ERROR_HANDLER ENDP	   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-51
TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY			

				;*****************************************************************************
				   PUBLIC TRY_FORMAT		   ;AN000;MAKE ENTRY IN LINK MAP
 10CC				TRY_FORMAT PROC NEAR		   ;
				;*** TRY TO FORMAT A TRACK.
				;*** CALLED BY "EXTENDED_ERROR_HANDLER" TO CHECK THE TIME OUT ERROR IS A REAL
				;*** ONE OR CAUSED BY "ADDR MARK NOT FOUND" ERROR.(THIS IS HARDWARE ERROR THAT
				;*** DOES NOT GIVE CORRECT ERROR CODE).
				;*** THIS ROUTINE WILL CALL "GENERIC_IOCTL" WHICH IN TURN WILL CALL "EXTENDED_
				;*** ERROR_HANDLER" WHERE THE ERROR WILL BE REEXAMINED.
				;*****************************************************************************
 10CC  06			   PUSH  ES			   ;
				
 10CD  1E			   PUSH  DS			   ;
 10CE  07			   POP	 ES			   ;
				
 10CF  B9 001F			   MOV	 CX, MS_deviceBPB_leng	   ;set length of BPB
 10D2  BE 05C7 R		   MOV	 SI, OFFSET MS_deviceBPB   ;
 10D5  BF 06EB R		   MOV	 DI, OFFSET MT_deviceBPB   ;
 10D8  F3/ A4			   REP	 MOVSB			   ;
 10DA  E8 0FFE R		   CALL  CHK_MEDIATYPE		   ;set MT_mediaTYPE for FORMAT operation
				
 10DD  C6 06 06E4 R 05		   MOV	 MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
 10E2  B1 40			   MOV	 CL, SETDEVPARM 	   ;=40h
 10E4  BA 06E4 R		   MOV	 DX, OFFSET MT_IOCTL_DRV_PARM ;
 10E7  33 DB			   XOR	 BX, BX 		   ;
 10E9  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 10ED  E8 1018 R		   CALL  GENERIC_IOCTL		   ;
				
 10F0  33 C0			   XOR	 AX, AX 		   ;
 10F2  A0 036C R		   MOV	 AL, SIDE		   ;SIDE TO FORMAT
 10F5  A3 0809 R		   MOV	 Fhead, AX		   ;
 10F8  A0 0364 R		   MOV	 AL, TRACK_TO_WRITE	   ;TRACK TO FORMAT
 10FB  A3 080B R		   MOV	 Fcylinder, AX		   ;
				
 10FE  33 DB			   XOR	 BX, BX 		   ;
 1100  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 1104  B1 42			   MOV	 CL, FORMAT_FUNC	   ;=42h
 1106  BA 0808 R		   MOV	 DX, OFFSET IOCTL_FORMAT   ;
 1109  E8 1018 R		   CALL  GENERIC_IOCTL		   ;
				
 110C  A0 0371 R		   MOV	 AL, IO_ERROR		   ;SAVE IO_ERROR, IN CASE FOR PC_AT CASE.
 110F  50			   PUSH  AX			   ;
				
 1110  33 DB			   XOR	 BX, BX 		   ;
 1112  8A 1E 0309 R		   MOV	 BL, TARGET_DRIVE	   ;
 1116  C6 06 0344 R 01		   MOV	 T_DRV_SET_FLAG, 1	   ;INDICATE TARGET DRIVE PARM HAS BEEN SET
 111B  BA 06E4 R		   MOV	 DX, OFFSET MT_IOCTL_DRV_PARM ;
 111E  C6 06 06E4 R 04		   MOV	 MT_specialFunctions, SET_SP_FUNC_DEF ;
 1123  E8 0FF8 R		   CALL  SET_DRV_PARM_DEF	   ;SET IT BACK FOR NORMAL
								   ; OPERATION, EX. WRITING
				
 1126  58			   POP	 AX			   ;
 1127  A2 0371 R		   MOV	 IO_ERROR, AL		   ;RESTORE IO_ERROR
				
 112A  07			   POP	 ES			   ;
				
 112B  C3			   RET				   ;
				
 112C				TRY_FORMAT ENDP 		   ;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-52
ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE			;AN000;        

				;*****************************************************************************
				;									     *
 112C				ERROR_MESSAGE PROC NEAR 	   ;DISPLAY ERROR MESSAGE		     *
				   PUBLIC ERROR_MESSAGE 	   ;AN000;MAKE ENTRY IN LINK MAP
				;									     *
				;  FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE)  *
				;	     AND WHERE IT FAILED (TRACK NO. AND SIDE).			     *
				;									     *
				;  INPUT: AH = IOCTL I/O COMMAND CODE  (3=READ, 4=WRITE)		     *
				;									     *
				;*****************************************************************************
 112C  80 FC 61			   CMP	 AH,READ_FUNC		   ;ERROR DURING READ ?
				.LIST				   ;
				;  $IF	 E			   ;AN000;YES, READ ERROR
 112F  75 09			   JNE $$IF116
 1131  8A 1E 0363 R		       MOV   BL,TRACK_TO_READ	   ;SAVE BAD TRACK NUMBER FOR READ
 1135  BF 0000 E		       MOV   DI,OFFSET MSGNUM_HARD_ERROR_READ ;AN000;
				;  $ELSE			   ;AN000;NO, NOT READ, MUST BE WRITE ERROR
 1138  EB 07			   JMP SHORT $$EN116
 113A				$$IF116:
 113A  8A 1E 0364 R		       MOV   BL,TRACK_TO_WRITE	   ;SAVE BAD TRACK NUMBER FOR WRITE
 113E  BF 0000 E		       MOV   DI,OFFSET MSGNUM_HARD_ERROR_WRITE ;AN000;
				;  $ENDIF			   ;AN000;READ ERROR?
 1141				$$EN116:
 1141  A0 036C R		   MOV	 AL,SIDE		   ;
 1144  C6 06 0000 E 41		   MOV	 DRIVE_LETTER,"A"	   ;
 1149  FE CA			   dec	 dl			   ;change logical drive letter to physical one.
 114B  00 16 0000 E		   ADD	 DRIVE_LETTER,DL	   ;SHOW DRIVE LETTER
				.LIST				   ;
 114F  A2 0000 E		   MOV	 BYTE PTR ERROR_SIDE_NUMBER,AL ;AC000;SIDE NUMBER
 1152  88 1E 0000 E		   MOV	 BYTE PTR ERROR_TRACK_NUMBER,BL ;AC000;TRACK NUMBER WHERE THE ERROR
								   ;CR,LF,"Unrecoverable read/write error on drive %1",CR,LF
 1156  E8 115A R		   CALL  SENDMSG		   ;"Side %2, track %3",CR,LF			;ACN000;
				
 1159  C3			   RET				   ;
 115A				ERROR_MESSAGE ENDP		   ;
				.list				   ;
				   HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-53
SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG	

 115A				SENDMSG PROC NEAR		   ;AN000;
				   PUBLIC SENDMSG		   ;AN000;
				; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
				; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
				;	   IF CARRY CLEAR, ALL OK
				;	   IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
				;  =  =  =  =  =  =  =	=  =  =  =  =
				
 115A  53			   PUSH  BX			   ;AN000;SAVE CALLER'S REGS
 115B  51			   PUSH  CX			   ;AN000;
 115C  52			   PUSH  DX			   ;AN000;
 115D  56			   PUSH  SI			   ;AN000;
				
				;		 PASS PARMS TO MESSAGE HANDLER IN
				;		 THE APPROPRIATE REGISTERS IT NEEDS.
 115E  8B 1D			   MOV	 BX,[DI].MSG_NUM	   ;AC006;MESSAGE NUMBER
 1160  8B 75 04			   MOV	 SI,[DI].MSG_SUBLIST	   ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
 1163  8B 4D 06			   MOV	 CX,[DI].MSG_COUNT	   ;AN000;NUMBER OF %PARMS, 0 IF NONE
 1166  8B 55 08			   MOV	 DX,[DI].MSG_CLASS	   ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
 1169  B8 ADC1			   MOV	 AX,SELECT_MPX		   ;AN006;REQUEST THE SELECT MULTIPLEXOR, IF PRESENT
 116C  CD 2F			   INT	 MULTIPLEXOR		   ;AN006;CALL THE MULTIPLEXOR FUNCTION
				
 116E  3C FF			   CMP	 AL,SELECT_PRESENT	   ;AN006;CHECK MULTIPLEXOR RESPONSE CODE
				;  $IF	 NE			   ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
 1170  74 20			   JE $$IF119
 1172  8B 05			       MOV   AX,[DI].MSG_NUM	   ;AN000;MESSAGE NUMBER
 1174  8B 5D 02			       MOV   BX,[DI].MSG_HANDLE    ;AN006;HANDLE TO DISPLAY TO
 1177  E8 0000 E		       CALL  SYSDISPMSG 	   ;AN000;DISPLAY THE MESSAGE
				
				;      $IF   C			   ;AN000;IF THERE IS A PROBLEM
 117A  73 14			       JNC $$IF120
								   ;AX=EXTENDED ERROR NUMBER			;AN000;
 117C  8D 3E 0000 E			   LEA	 DI,MSGNUM_EXTERR  ;AN000;GET REST OF ERROR DESCRIPTOR
 1180  8B 5D 02				   MOV	 BX,[DI].MSG_HANDLE ;AN000;HANDLE TO DISPLAY TO
 1183  8B 75 04				   MOV	 SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
 1186  8B 4D 06				   MOV	 CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE
 1189  8B 55 08				   MOV	 DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
 118C  E8 0000 E			   CALL  SYSDISPMSG	   ;AN000;TRY TO SAY WHAT HAPPENED
				
 118F  F9				   STC			   ;AN000;REPORT PROBLEM
				;      $ENDIF			   ;AN000;PROBLEM WITH DISPLAY?
 1190				$$IF120:
				;  $ELSE			   ;AN006;SINCE SELECT DID THE MESSAGE
 1190  EB 06			   JMP SHORT $$EN119
 1192				$$IF119:
 1192  C6 06 0377 R 01		       MOV   SELECT_FLAG,TRUE	   ;AN006;INDICATE SELECT IS DOING THE MESSAGES
 1197  F8			       CLC			   ;AN006;GENERATE A "NO PROBLEM" RESPONSE
				;  $ENDIF			   ;AN006;DID SELECT HANDLE THE MESSAGE?
 1198				$$EN119:
				
 1198  5E			   POP	 SI			   ;AN000;RESTORE CALLER'S REGISTERS
 1199  5A			   POP	 DX			   ;AN000;
 119A  59			   POP	 CX			   ;AN000;
 119B  5B			   POP	 BX			   ;AN000;
				
 119C  C3			   RET				   ;AN000;
 119D				SENDMSG ENDP			   ;AN000;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   HEADER <YESNO - DETERMINE IF A RESPONSE IS YES OR NO> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-54
YESNO - DETERMINE IF A RESPONSE IS YES OR NO			;AN000;      

 119D				YESNO PROC NEAR 		   ;AN000;
				   PUBLIC YESNO 		   ;AN000;MAKE ENTRY IN LINK MAP
				;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
				;	SELECT_FLAG - IF SELECT IS DOING MESSAGES, ALWAYS ASSUME "NO"
				;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
				;	IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
				;  =  =  =  =  =  =  =	=  =  =  =  =
				
 119D  80 3E 0377 R 01		   CMP	 SELECT_FLAG,TRUE	   ;AN006;IS SELECT DOING THE MESSAGES?
				;  $IF	 NE			   ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
 11A2  74 07			   JE $$IF124
								   ;AL=SUBFUNCTION, AS:
								   ;  20H=CAPITALIZE SINGLE CHAR
								   ;  21H=CAPITALIZE STRING
								   ;  22H=CAPITALIZE ASCIIZ STRING
								   ;  23H=YES/NO CHECK
								   ;  80H BIT 0=USE NORMAL UPPER CASE TABLE
								   ;  80H BIT 1=USE FILE UPPER CASE TABLE
								   ;DL=CHAR TO CAP (FUNCTION 23H)		;AN000;
 11A4  B8 6523			       MOV   AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;AN000;(6523H) GET EXTENDED
								   ; COUNTRY INFORMATION, (Y/N)
 11A7  CD 21			       INT   21H		   ;AN000;SEE IF Y OR N
				
				;  $ELSE			   ;AN006;SINCE SELECT IS NOT PRESET
 11A9  EB 03			   JMP SHORT $$EN124
 11AB				$$IF124:
 11AB  B8 0000			       MOV   AX,NO		   ;AN006;ASSUME RESPONSE WAS 'NO'
				;  $ENDIF			   ;AN006;
 11AE				$$EN124:
 11AE  C3			   RET				   ;AN000;RETURN TO CALLER
 11AF				YESNO ENDP			   ;AN000;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				;(deleted ;AN013;)   HEADER <READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE> ;AN000;
				;(deleted ;AN013;) READ_VOLSER PROC NEAR	      ; 			;AN000;
				;(deleted ;AN013;)    PUBLIC READ_VOLSER	      ; 			;AN000;
				;(deleted ;AN013;) ;IF THE SOURCE DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN MAKE A NEW ONE
				;(deleted ;AN013;) ; AND SEND IT TO THE TARGET DISKETTE.  FOR OLD STYLE DISKETTES THAT DID NOT
				;(deleted ;AN013;) ; HAVE ANY VOL SERIAL NUMBER, MAKE NO CHANGE AFTER THE TRADITIONAL FULL COPY.
				;(deleted ;AN013;) ;INPUT: SOURCE AND TARGET DRIVE ID
				;(deleted ;AN013;) ;	   THE TARGET DISKETTE IS A COMPLETE COPY OF THE SOURCE.
				;(deleted ;AN013;) ;REFERENCED: A_MEDIA_ID_INFO STRUC (DEFINED IN DISKCOPY.EQU)
				;(deleted ;AN013;) ; = = = = = = = = = = = = = = = = = =
				;(deleted ;AN013;) ;		  ISSUE GET MEDIA ID FROM SOURCE
				;(deleted ;AN013;)    MOV BH,ZERO		 ;BH=0, RES		   ;AN000;
				;(deleted ;AN013;)    MOV BL,SOURCE_DRIVE	 ;BL=DRIVE NUM (1=A:, 2=B:, ETC);AN000;
				;(deleted ;AN013;)    MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC);AN000;
				;(deleted ;AN013;)    DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID	;AC009;
				;(deleted ;AN013;)				 ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
				;(deleted ;AN013;)
				;(deleted ;AN013;)    $IF NC			 ;IF THERE IS NO PROBLEM	;AN000;
				;(deleted ;AN013;) ;	     GET CURRENT DATE
				;(deleted ;AN013;)	  DOSCALL GET_DATE	 ;READ SYSTEM DATE		;AN000;
				;(deleted ;AN013;)				 ;OUTPUT: DL = DAY (1-31)
				;(deleted ;AN013;)				 ;  AL = DAY OF WEEK (0=SUN,6=SAT)
				;(deleted ;AN013;)				 ;  CX = YEAR (1980-2099)
				;(deleted ;AN013;)				 ;  DH = MONTH (1-12)
				;(deleted ;AN013;)	  PUSH	CX		 ;SAVE THESE FOR		;AN000;
				;(deleted ;AN013;)	  PUSH	DX		 ; INPUT INTO HASH ALGORITHM	;AN000;
				;(deleted ;AN013;) ;	      GET CURRENT TIME
				;(deleted ;AN013;)	  DOSCALL GET_TIME	 ;READ SYSTEM TIME CLOCK	;AN000;
				;(deleted ;AN013;)				 ;OUTPUT: CH = HOUR (0-23)
				;(deleted ;AN013;)				 ;  CL = MINUTES (0-59)
				;(deleted ;AN013;)				 ;  DH = SECONDS (0-59)
				;(deleted ;AN013;)				 ;  DL = HUNDREDTHS (0-99)
				;(deleted ;AN013;)
				;(deleted ;AN013;) ; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
				;(deleted ;AN013;) ;	      MI_SERIAL+0 = DX FROM DATE + DX FROM TIME
				;(deleted ;AN013;) ;	      MI_SERIAL+2 = CX FROM DATE + CX FROM TIME
				;(deleted ;AN013;)
				;(deleted ;AN013;)	  POP	AX		 ;GET THE DX FROM DATE		;AN000;
				;(deleted ;AN013;)	  ADD	AX,DX		 ;ADD IN THE DX FROM TIME	;AN000;
				;(deleted ;AN013;)	  MOV	WORD PTR MEDIA_ID_BUF.MI_SERIAL,AX ;SAVE FIRST RESULT OF HASH;AN000;
				;(deleted ;AN013;)
				;(deleted ;AN013;)	  POP	AX		 ;GET THE CX FROM DATE		;AN000;
				;(deleted ;AN013;)	  ADD	AX,CX		 ;ADD IN THE CX FROM TIME	;AN000;
				;(deleted ;AN013;)	  MOV	WORD PTR MEDIA_ID_BUF.MI_SERIAL+WORD,AX ;SAVE SECOND RESULT OF HASH;
				AN000;
				;(deleted ;AN013;)
				;(deleted ;AN013;)	  MOV	VOLSER_FLAG,TRUE ;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN;AN000
				;
				;(deleted ;AN013;)    $ENDIF			 ;				;AN000;
				;(deleted ;AN013;)    RET			 ;RETURN TO CALLER		;AN000;
				;(deleted ;AN013;) READ_VOLSER ENDP		 ;				;AN000;
				; = = = = = = = = = = = = = = = = = = =
				   HEADER <WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-55
WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET			;AN000;   

 11AF				WRITE_VOLSER PROC NEAR		   ;AN000;
				   PUBLIC WRITE_VOLSER		   ;AN000;MAKE ENTRY IN LINK MAP
 11AF  80 3E 033D R 01		   CMP	 VOLSER_FLAG,TRUE	   ;AN000;IF NEW NUMBER READY TO BE WRITTEN
				;  $IF	 E			   ;AN000;THEN WRITE IT
 11B4  75 1A			   JNE $$IF127
				
				;NOTE FOR ;AN013;
				;THERE IS NO NEED TO DO A SET MEDIA ID TO WRITE OUT THE MODIFIED SERIAL NUMBER
				;BECAUSE THAT NUMBER WAS CHANGED IN THE IMAGE OF THE BOOT RECORD WHEN THE
				;ORIGINAL BOOT RECORD WAS READ IN, SO WHEN THAT TRACK IMAGE WAS WRITTEN,
				;IT CONTAINED THE NEW SERIAL NUMBER ALREADY.
				
				;(deleted ;AN013;) ;	 ISSUE SET MEDIA ID TO TARGET
				;(deleted ;AN013;)  MOV   BH,ZERO		;BH=0, RES			;AN000;
				;(deleted ;AN013;)  MOV   BL,TARGET_DRIVE	;BL=DRIVE NUM			;AN000;
				;(deleted ;AN013;)  MOV   DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see STRUC above);AN000;
				;(deleted ;AN013;)  DOSCALL GSET_MEDIA_ID,SET_ID ;(6901H) SET MEDIA ID		;AC009;
				
				; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
				; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER.  THE ORDER OF
				; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
				; MOST SIGNIFICANT WORD.  WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
				; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 26A SUBLIST,
				; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
				; REPRESENTED BY THE 26B SUBLIST.
				
 11B6  8D 06 033E R		       LEA   AX,SERIAL		   ;AC013;GET POINTER TO DATA TO BE PRINTED
 11BA  A3 0002 E		       MOV   SUBLIST_26B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
				
 11BD  8D 06 0340 R		       LEA   AX,SERIAL+WORD	   ;AC013;GET POINTER TO DATA TO BE PRINTED
 11C1  A3 0002 E		       MOV   SUBLIST_26A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
				
				       PRINT MSGNUM_CR_LF	   ;AN000;SKIP A SPACE
 11C4  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_CR_LF  ; 
 11C7  E8 115A R             1					   CALL SENDMSG 	  ; 
				
								   ;"Volume Serial Number is %1-%2"
				       PRINT MSGNUM_SERNO	   ;AN001;DISPLAY THE NEW SERIAL NUMBER
 11CA  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_SERNO  ; 
 11CD  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				;  $ENDIF			   ;AN000;
 11D0				$$IF127:
 11D0  C3			   RET				   ;AN000;RETURN TO CALLER
 11D1				WRITE_VOLSER ENDP		   ;AN000;
				; = = = = = = = = = = = = = = = = = = =
				   HEADER <PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT> ;AN000;
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Page     1-56
PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT			;AN000;   

 11D1				PRESS_ANY_KEY PROC NEAR 	   ;
				;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
				;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
				;PRECEEDING MESSAGES.
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   PRINT MSGNUM_CR_LF		   ;AN000;SKIP A SPACE
 11D1  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_CR_LF  ; 
 11D4  E8 115A R             1					   CALL SENDMSG 	  ; 
				
				   PRINT MSGNUM_STRIKE		   ;AN000;"Press any key when ready..."
 11D7  BF 0000 E             1					   MOV DI,OFFSET MSGNUM_STRIKE  ; 
 11DA  E8 115A R             1					   CALL SENDMSG 	  ; 
				
 11DD  C3			   RET				   ;AN000;RETURN TO CALLER
 11DE				PRESS_ANY_KEY ENDP		   ;AN000;
				;  =  =  =  =  =  =  =	=  =  =  =  =
				   PUBLIC DISKCOPY_END		   ;
 11DE				DISKCOPY_END LABEL NEAR 	   ;
				
				   PATHLABL DISKCOPY		   ;AN015;
 11DE                        1	    $$A_STOP_DISKCOPY:                     ; 
 11DE				CSEG ENDS			   ;
				   END	 DISKCOPY		   ;

Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-1


Macros:

		N a m e			Lines

DOSCALL  . . . . . . . . . . . .  	   8
HEADER . . . . . . . . . . . . .  	   4
MY_TRACKLAYOUT . . . . . . . . .  	 128
PATHLABL . . . . . . . . . . . .  	  16
PRINT  . . . . . . . . . . . . .  	   2

Structures and Records:

                N a m e                 Width   # fields
                                        Shift   Width   Mask    Initial

EXT_BPB_INFO . . . . . . . . . .  	0019	000C
  EBPB_BYTESPERSECTOR  . . . . .  	0000
  EBPB_SECTORSPERCLUSTER . . . .  	0002
  EBPB_RESERVEDSECTORS . . . . .  	0003
  EBPB_NUMBEROFFATS  . . . . . .  	0005
  EBPB_ROOTENTRIES . . . . . . .  	0006
  EBPB_TOTALSECTORS  . . . . . .  	0008
  EBPB_MEDIADESCRIPTOR . . . . .  	000A
  EBPB_SECTORSPERFAT . . . . . .  	000B
  EBPB_SECTORSPERTRACK . . . . .  	000D
  EBPB_HEADS . . . . . . . . . .  	000F
  EBPB_HIDDENSECTOR  . . . . . .  	0011
  EBPB_BIGTOTALSECTORS . . . . .  	0015
EXT_IBMBOOT_HEADER . . . . . . .  	003E	0009
  EXT_BOOT_JUMP  . . . . . . . .  	0000
  EXT_BOOT_OEM . . . . . . . . .  	0003
  EXT_BOOT_BPB . . . . . . . . .  	000B
  EXT_PHYDRV . . . . . . . . . .  	0024
  EXT_CURHD  . . . . . . . . . .  	0025
  EXT_BOOT_SIG . . . . . . . . .  	0026
  EXT_BOOT_SERIAL  . . . . . . .  	0027
  EXT_BOOT_VOL_LABEL . . . . . .  	002B
  EXT_SYSTEM_ID  . . . . . . . .  	0036
MSG_DESC . . . . . . . . . . . .  	000A	0005
  MSG_NUM  . . . . . . . . . . .  	0000
  MSG_HANDLE . . . . . . . . . .  	0002
  MSG_SUBLIST  . . . . . . . . .  	0004
  MSG_COUNT  . . . . . . . . . .  	0006
  MSG_CLASS  . . . . . . . . . .  	0008
MY_BPB . . . . . . . . . . . . .  	001F	000D
  CBYTE_SECT . . . . . . . . . .  	0000
  CSECT_CLUSTER  . . . . . . . .  	0002
  CRESEV_SECT  . . . . . . . . .  	0003
  CFAT . . . . . . . . . . . . .  	0005
  CROOTENTRY . . . . . . . . . .  	0006
  CTOTSECT . . . . . . . . . . .  	0008
  MEDIA_DESCRIP  . . . . . . . .  	000A
  CSECT_FAT  . . . . . . . . . .  	000B
  CSECT_TRACK  . . . . . . . . .  	000D
  CHEAD  . . . . . . . . . . . .  	000F
  CHIDDEN_SECT . . . . . . . . .  	0011
  BIG_TOT_SECT . . . . . . . . .  	0015
SUBLIST  . . . . . . . . . . . .  	000B	0009
  SUB_SIZE . . . . . . . . . . .  	0000
  SUB_RES  . . . . . . . . . . .  	0001
  SUB_VALUE  . . . . . . . . . .  	0002
  SUB_VALUE_SEG  . . . . . . . .  	0004
  SUB_ID . . . . . . . . . . . .  	0006
  SUB_FLAGS  . . . . . . . . . .  	0007
  SUB_MAX_WIDTH  . . . . . . . .  	0008
  SUB_MIN_WIDTH  . . . . . . . .  	0009
  SUB_PAD_CHAR . . . . . . . . .  	000A

Segments and Groups:

                N a m e         	Length	 Align	Combine Class

CSEG . . . . . . . . . . . . . .  	11DE	PARA	PUBLIC	'CODE'

Symbols:            

                N a m e         	Type	 Value	 Attr

ASCII_DRV1_ID  . . . . . . . . .  	V BYTE	0000	CSEG	External
ASCII_DRV2_ID  . . . . . . . . .  	V BYTE	0000	CSEG	External

BAD  . . . . . . . . . . . . . .  	NUMBER	0001	
BAD_YESNO  . . . . . . . . . . .  	NUMBER	0002	
BEGIN  . . . . . . . . . . . . .  	N PROC	081A	CSEG	Global	Length = 007A
BEGIN_UNFORM_AREA  . . . . . . .  	NUMBER	0080	
BLANK  . . . . . . . . . . . . .  	NUMBER	0020	
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-2


BOOT_BYTE_SECTOR . . . . . . . .  	L WORD	0359	CSEG
BOOT_NUM_HEAD  . . . . . . . . .  	L WORD	0357	CSEG
BOOT_SECT_TRACK  . . . . . . . .  	L WORD	0353	CSEG
BOOT_SIGNATURE . . . . . . . . .  	WORD	01FE	
BOOT_SIZE  . . . . . . . . . . .  	NUMBER	0200	
BOOT_TOT_TRACK . . . . . . . . .  	L WORD	0355	CSEG
BPB48_DOUBLE . . . . . . . . . .  	L WORD	0323	CSEG
BPB48_SINGLE . . . . . . . . . .  	L WORD	0316	CSEG
BPB96  . . . . . . . . . . . . .  	L WORD	0330	CSEG
BPB96_LENG . . . . . . . . . . .  	NUMBER	000D	
BSECTOR_SIZE . . . . . . . . . .  	L WORD	035F	CSEG
BUFFER_BEGIN . . . . . . . . . .  	L WORD	030C	CSEG	Global
BUFFER_END . . . . . . . . . . .  	L WORD	030E	CSEG	Global
BUFFER_PTR . . . . . . . . . . .  	L WORD	0369	CSEG

CALC_TRACK_SIZE  . . . . . . . .  	N PROC	0E2B	CSEG	Global	Length = 002A
CHECK_MEMORY_SIZE  . . . . . . .  	N PROC	0E55	CSEG	Global	Length = 0019
CHECK_SOURCE . . . . . . . . . .  	N PROC	0C6A	CSEG	Global	Length = 016F
CHECK_TARGET . . . . . . . . . .  	N PROC	0EBF	CSEG	Global	Length = 011D
CHK_MEDIATYPE  . . . . . . . . .  	N PROC	0FFE	CSEG	Global	Length = 001A
CHK_MULTI_MEDIA  . . . . . . . .  	N PROC	0FDC	CSEG	Global	Length = 001C
CLASS_A  . . . . . . . . . . . .  	ALIAS	 UTILITY_MSG_CLASS		
CLEAR_SEGMENT  . . . . . . . . .  	NUMBER	00E0	
COPY . . . . . . . . . . . . . .  	N PROC	089F	CSEG	Global	Length = 0092
COPY_ERROR . . . . . . . . . . .  	L BYTE	036B	CSEG
COPY_STATUS  . . . . . . . . . .  	L BYTE	036F	CSEG
COPY_TEST_END  . . . . . . . . .  	L NEAR	08F2	CSEG
COPY_TYPE  . . . . . . . . . . .  	L BYTE	030B	CSEG	Global
CS_BAD . . . . . . . . . . . . .  	L NEAR	0CE6	CSEG
CS_CHK_SIDE  . . . . . . . . . .  	L NEAR	0D5F	CSEG
CS_EXIT  . . . . . . . . . . . .  	L NEAR	0DD8	CSEG
CS_FATAL . . . . . . . . . . . .  	L NEAR	0CD8	CSEG
CS_OLD . . . . . . . . . . . . .  	L NEAR	0CF4	CSEG
CS_OPTION_1  . . . . . . . . . .  	L NEAR	0D34	CSEG
CS_SECT15  . . . . . . . . . . .  	L NEAR	0D3B	CSEG
CS_SECT8 . . . . . . . . . . . .  	L NEAR	0D47	CSEG
CS_SECT9 . . . . . . . . . . . .  	L NEAR	0D53	CSEG
CS_SET_TABLE . . . . . . . . . .  	L NEAR	0D88	CSEG
CT_8_SECTOR  . . . . . . . . . .  	L NEAR	0F8B	CSEG
CT_9_SECTOR  . . . . . . . . . .  	L NEAR	0F9C	CSEG
CT_BYTE_SECTOR . . . . . . . . .  	L NEAR	0F1B	CSEG
CT_EXIT  . . . . . . . . . . . .  	L NEAR	0FDB	CSEG
CT_EXIT_OLD  . . . . . . . . . .  	L NEAR	0FB0	CSEG
CT_FATAL . . . . . . . . . . . .  	L NEAR	0FA3	CSEG
CT_FORMAT  . . . . . . . . . . .  	L NEAR	0F31	CSEG
CT_HEAD  . . . . . . . . . . . .  	L NEAR	0F24	CSEG
CT_OLD . . . . . . . . . . . . .  	L NEAR	0F42	CSEG
CT_SECTOR_TRACK  . . . . . . . .  	L NEAR	0F12	CSEG
CT_SET_DRV . . . . . . . . . . .  	L NEAR	0FBB	CSEG
CURRENTDRV_FUNC  . . . . . . . .  	NUMBER	0019	
CYLINDER . . . . . . . . . . . .  	L WORD	0810	CSEG

DISKCOPY . . . . . . . . . . . .  	L NEAR	0100	CSEG
DISKCOPY_BEGIN . . . . . . . . .  	L NEAR	081A	CSEG	Global
DISKCOPY_END . . . . . . . . . .  	L NEAR	11DE	CSEG	Global
DOS20  . . . . . . . . . . . . .  	NUMBER	0002	
DOSVER_FUNC  . . . . . . . . . .  	NUMBER	0030	
DRIVE_CHECK  . . . . . . . . . .  	NUMBER	4408	
DRIVE_LETTER . . . . . . . . . .  	V BYTE	0000	CSEG	External
DRV_48TPI  . . . . . . . . . . .  	NUMBER	0000	
DRV_720  . . . . . . . . . . . .  	NUMBER	0002	
DRV_96TPI  . . . . . . . . . . .  	NUMBER	0001	
DS_BPB_PTR . . . . . . . . . . .  	L BYTE	037F	CSEG	Global
DS_deviceAttributes  . . . . . .  	L WORD	037A	CSEG	Global
DS_DEVICEBPB . . . . . . . . . .  	L 	037F	CSEG
DS_deviceType  . . . . . . . . .  	L BYTE	0379	CSEG	Global
DS_IOCTL_DRV_PARM  . . . . . . .  	L BYTE	0378	CSEG	Global
DS_mediaType . . . . . . . . . .  	L BYTE	037E	CSEG	Global
DS_numberOfCylinders . . . . . .  	L WORD	037C	CSEG	Global
DS_specialFunctions  . . . . . .  	L BYTE	0378	CSEG	Global
DS_TRACKLAYOUT . . . . . . . . .  	L WORD	039E	CSEG
DT_BPB_PTR . . . . . . . . . . .  	L BYTE	04A3	CSEG	Global
DT_deviceAttributes  . . . . . .  	L WORD	049E	CSEG	Global
DT_DEVICEBPB . . . . . . . . . .  	L 	04A3	CSEG
DT_deviceType  . . . . . . . . .  	L BYTE	049D	CSEG	Global
DT_IOCTL_DRV_PARM  . . . . . . .  	L BYTE	049C	CSEG	Global
DT_mediaType . . . . . . . . . .  	L BYTE	04A2	CSEG	Global
DT_numberOfCylinders . . . . . .  	L WORD	04A0	CSEG	Global
DT_specialFunctions  . . . . . .  	L BYTE	049C	CSEG	Global
DT_TRACKLAYOUT . . . . . . . . .  	L WORD	04C2	CSEG

EEH_CHK_TIMEOUT  . . . . . . . .  	L NEAR	104B	CSEG
EEH_EXIT . . . . . . . . . . . .  	L NEAR	10C4	CSEG
EEH_HARD_ERROR . . . . . . . . .  	L NEAR	10B0	CSEG
EEH_TIMEOUT  . . . . . . . . . .  	L NEAR	107E	CSEG
EIGHT  . . . . . . . . . . . . .  	NUMBER	0008	
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-3


END_OF_TRACK . . . . . . . . . .  	L BYTE	035E	CSEG
END_UNFORM_AREA  . . . . . . . .  	NUMBER	0100	
ERROR_MESSAGE  . . . . . . . . .  	N PROC	112C	CSEG	Global	Length = 002E
ERROR_SIDE_NUMBER  . . . . . . .  	V WORD	0000	CSEG	External
ERROR_TRACK_NUMBER . . . . . . .  	V WORD	0000	CSEG	External
EXCBR  . . . . . . . . . . . . .  	NUMBER	0002	
EXITFL . . . . . . . . . . . . .  	L BYTE	0342	CSEG	Global
EXIT_PROGRAM . . . . . . . . . .  	L NEAR	088B	CSEG
EXIT_TO_DOS  . . . . . . . . . .  	L NEAR	084F	CSEG
EXOK . . . . . . . . . . . . . .  	NUMBER	0000	
EXPAR  . . . . . . . . . . . . .  	NUMBER	0001		Global
EXTENDED_ERROR . . . . . . . . .  	NUMBER	0059	
EXTENDED_ERROR_HANDLER . . . . .  	N PROC	102A	CSEG	Global	Length = 00A2
EXT_BOOT_SIGNATURE . . . . . . .  	NUMBER	0029	
EXT_ERR_CLASS  . . . . . . . . .  	NUMBER	0001	
EXVER  . . . . . . . . . . . . .  	NUMBER	0001	

FALSE  . . . . . . . . . . . . .  	NUMBER	0000	
FATAL  . . . . . . . . . . . . .  	NUMBER	0001	
FA_DONE  . . . . . . . . . . . .  	L NEAR	0C2F	CSEG
FA_FATAL . . . . . . . . . . . .  	L NEAR	0C17	CSEG
FA_NEXT_SIDE . . . . . . . . . .  	L NEAR	0C06	CSEG
FA_NEXT_TRACK  . . . . . . . . .  	L NEAR	0C0C	CSEG
FA_SIDE_WHILE  . . . . . . . . .  	L NEAR	0BE2	CSEG
FA_TARGET_BAD  . . . . . . . . .  	L NEAR	0C24	CSEG
FA_TRACK_WHILE . . . . . . . . .  	L NEAR	0BD9	CSEG
FCB1_DRV_ID  . . . . . . . . . .  	NUMBER	005C	
FCB1_FILENM  . . . . . . . . . .  	NUMBER	005D	
FCB2_DRV_ID  . . . . . . . . . .  	NUMBER	006C	
FCB2_FILENM  . . . . . . . . . .  	NUMBER	006D	
FCYLINDER  . . . . . . . . . . .  	L WORD	080B	CSEG
FHEAD  . . . . . . . . . . . . .  	L WORD	0809	CSEG
FINE . . . . . . . . . . . . . .  	NUMBER	-0001		Global
FIRST  . . . . . . . . . . . . .  	NUMBER	0001	
FIRSTSECTORS . . . . . . . . . .  	L WORD	0812	CSEG
FIVE . . . . . . . . . . . . . .  	NUMBER	0005	
FORMAT_ALL . . . . . . . . . . .  	N PROC	0B77	CSEG	Global	Length = 00CF
FORMAT_FLAG  . . . . . . . . . .  	L BYTE	0362	CSEG
FORMAT_FUNC  . . . . . . . . . .  	NUMBER	0042	
FORMAT_SP_FUNC . . . . . . . . .  	NUMBER	0000	
FORMAT_TRACK . . . . . . . . . .  	N PROC	0C46	CSEG	Global	Length = 0024
FOUR . . . . . . . . . . . . . .  	NUMBER	0004	
FSPECIALFUNCTIONS  . . . . . . .  	L BYTE	0808	CSEG
FT_AGAIN . . . . . . . . . . . .  	L NEAR	0C46	CSEG

GENERIC_IOCTL  . . . . . . . . .  	N PROC	1018	CSEG	Global	Length = 0012
GENERIC_IOCTL_CODE . . . . . . .  	NUMBER	000D	
GETDEVPARM . . . . . . . . . . .  	NUMBER	0060	
GET_ASSIGN_MODE  . . . . . . . .  	NUMBER	5F00	
GET_CTL_BREAK_VECT . . . . . . .  	NUMBER	3523	
GET_DATE . . . . . . . . . . . .  	NUMBER	002A	
GET_DISKBASE_VECTOR  . . . . . .  	NUMBER	351E	
GET_EXT_CNTRY_INFO . . . . . . .  	NUMBER	0065	
GET_SP_FUNC_DEF  . . . . . . . .  	NUMBER	0000	
GET_SP_FUNC_MED  . . . . . . . .  	NUMBER	0001	
GET_TIME . . . . . . . . . . . .  	NUMBER	002C	
GOOD . . . . . . . . . . . . . .  	NUMBER	0000	

HARD_ERROR . . . . . . . . . . .  	NUMBER	0002	
HEAD . . . . . . . . . . . . . .  	L WORD	080E	CSEG

IBMLOADSIZE  . . . . . . . . . .  	NUMBER	0003	
INIT . . . . . . . . . . . . . .  	L NEAR	0000	CSEG	External
INVAL_PARM . . . . . . . . . . .  	NUMBER	-0009	
IOCTL_FORMAT . . . . . . . . . .  	L BYTE	0808	CSEG
IOCTL_FUNC . . . . . . . . . . .  	NUMBER	0044	
IOCTL_HEAD . . . . . . . . . . .  	L WORD	0349	CSEG
IOCTL_R_W  . . . . . . . . . . .  	L BYTE	080D	CSEG
IOCTL_SECTOR . . . . . . . . . .  	L WORD	0345	CSEG
IOCTL_TRACK  . . . . . . . . . .  	L WORD	0347	CSEG
IO_ERROR . . . . . . . . . . . .  	L BYTE	0371	CSEG	Global

KB_INPUT_FUNC  . . . . . . . . .  	NUMBER	0001	

LAST_TRACK . . . . . . . . . . .  	L BYTE	035D	CSEG
LBL_DISKCOPY . . . . . . . . . .  	NUMBER	0004	
LOCAL_DRV  . . . . . . . . . . .  	NUMBER	-0001	

MAIN_EXIT  . . . . . . . . . . .  	L NEAR	084A	CSEG	Global
MAJOR_CODE . . . . . . . . . . .  	NUMBER	0008	
MAX_0  . . . . . . . . . . . . .  	NUMBER	0000	
MAYBE_ADJUST_SERIAL  . . . . . .  	N PROC	0AC3	CSEG	Length = 0047
MSGNUM_BAD_SOURCE  . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_BAD_TARGET  . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_CLOSE_DOOR  . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_COPYING . . . . . . . . .  	V WORD	0000	CSEG	External
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-4


MSGNUM_COPY_ANOTHER  . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_CR_LF . . . . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_EXTERR  . . . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_FATAL_ERROR . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_FORMATTING  . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_GET_READY . . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_HARD_ERROR_READ . . . . .  	V WORD	0000	CSEG	External
MSGNUM_HARD_ERROR_WRITE  . . . .  	V WORD	0000	CSEG	External
MSGNUM_LOAD_SOURCE . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_LOAD_TARGET . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_NOT_COMPATIBLE  . . . . .  	V WORD	0000	CSEG	External
MSGNUM_SERNO . . . . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_STRIKE  . . . . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_TARGET_MB_UNUSABLE  . . .  	V WORD	0000	CSEG	External
MSGNUM_UNSUF_MEMORY  . . . . . .  	V WORD	0000	CSEG	External
MSGNUM_WRITE_PROTECT . . . . . .  	V WORD	0000	CSEG	External
MSG_FLAG . . . . . . . . . . . .  	L BYTE	0373	CSEG
MSG_SECTRK . . . . . . . . . . .  	V WORD	0000	CSEG	External
MSG_SIDES  . . . . . . . . . . .  	V WORD	0000	CSEG	External
MSG_TRACKS . . . . . . . . . . .  	V WORD	0000	CSEG	External
MS_BPB_PTR . . . . . . . . . . .  	L BYTE	05C7	CSEG
MS_DEVICEATTRIBUTES  . . . . . .  	L WORD	05C2	CSEG
MS_DEVICEBPB . . . . . . . . . .  	L 	05C7	CSEG
MS_DEVICEBPB_LENG  . . . . . . .  	NUMBER	001F	
MS_DEVICETYPE  . . . . . . . . .  	L BYTE	05C1	CSEG
MS_IOCTL_DRV_PARM  . . . . . . .  	L BYTE	05C0	CSEG	Global
MS_MEDIATYPE . . . . . . . . . .  	L BYTE	05C6	CSEG
MS_NUMBEROFCYLINDERS . . . . . .  	L WORD	05C4	CSEG
MS_SPECIALFUNCTIONS  . . . . . .  	L BYTE	05C0	CSEG
MS_TRACKLAYOUT . . . . . . . . .  	L WORD	05E6	CSEG
MT_BPB_PTR . . . . . . . . . . .  	L BYTE	06EB	CSEG
MT_DEVICEATTRIBUTES  . . . . . .  	L WORD	06E6	CSEG
MT_DEVICEBPB . . . . . . . . . .  	L 	06EB	CSEG
MT_DEVICETYPE  . . . . . . . . .  	L BYTE	06E5	CSEG
MT_IOCTL_DRV_PARM  . . . . . . .  	L BYTE	06E4	CSEG	Global
MT_MEDIATYPE . . . . . . . . . .  	L BYTE	06EA	CSEG
MT_NUMBEROFCYLINDERS . . . . . .  	L WORD	06E8	CSEG
MT_SPECIALFUNCTIONS  . . . . . .  	L BYTE	06E4	CSEG
MT_TRACKLAYOUT . . . . . . . . .  	L WORD	070A	CSEG
MULTIPLEXOR  . . . . . . . . . .  	NUMBER	002F	
MY_STACK_PTR . . . . . . . . . .  	L WORD	0304	CSEG

NINE . . . . . . . . . . . . . .  	NUMBER	0009	
NO . . . . . . . . . . . . . . .  	NUMBER	0000	
NO_ERROR . . . . . . . . . . . .  	NUMBER	0000	
NO_OF_SIDES  . . . . . . . . . .  	L BYTE	0361	CSEG
NO_OPTION  . . . . . . . . . . .  	NUMBER	-0001	
NRLFUNC  . . . . . . . . . . . .  	NUMBER	5F02	
NRLMAX . . . . . . . . . . . . .  	NUMBER	001C	
NUMBEROFSECTORS  . . . . . . . .  	L WORD	0814	CSEG

OFF  . . . . . . . . . . . . . .  	NUMBER	0000	
OK . . . . . . . . . . . . . . .  	NUMBER	0000	
ON . . . . . . . . . . . . . . .  	NUMBER	0001	
ONE  . . . . . . . . . . . . . .  	NUMBER	0001	
OPERATION  . . . . . . . . . . .  	L BYTE	036E	CSEG
OPTION_1 . . . . . . . . . . . .  	NUMBER	0001	

PAD_BLK  . . . . . . . . . . . .  	NUMBER	0020	
PARSE_ERR_CLASS  . . . . . . . .  	NUMBER	0002	
PRESS_ANY_KEY  . . . . . . . . .  	N PROC	11D1	CSEG	Length = 000D
PRINT_FUNC . . . . . . . . . . .  	NUMBER	0009	

READ_A_SECTOR  . . . . . . . . .  	N PROC	0DD9	CSEG	Global	Length = 0052
READ_FUNC  . . . . . . . . . . .  	NUMBER	0061	
READ_OP  . . . . . . . . . . . .  	N PROC	0A5A	CSEG	Global	Length = 0069
READ_SOURCE  . . . . . . . . . .  	N PROC	095A	CSEG	Global	Length = 0054
READ_S_BPB_FAILURE . . . . . . .  	L BYTE	035B	CSEG
READ_T_BPB_FAILURE . . . . . . .  	L BYTE	035C	CSEG
READ_WRITE_TRACK . . . . . . . .  	N PROC	0A12	CSEG	Global	Length = 0048
RECOMMENDED_BYTES_SECTOR . . . .  	L WORD	0306	CSEG	Global
REDIRECTED_FUNC  . . . . . . . .  	NUMBER	0009	
REMOTE_DRV . . . . . . . . . . .  	NUMBER	1000	
REMOVABLE  . . . . . . . . . . .  	NUMBER	0000	
RET_CD_EXIT  . . . . . . . . . .  	NUMBER	004C	
RWT_EXIT . . . . . . . . . . . .  	L NEAR	0A59	CSEG
R_W_SP_FUNC  . . . . . . . . . .  	NUMBER	0000	

SAV_CB1  . . . . . . . . . . . .  	L WORD	034F	CSEG
SAV_CN1  . . . . . . . . . . . .  	L WORD	034D	CSEG
SAV_CSECT  . . . . . . . . . . .  	L WORD	034B	CSEG
SAV_CYLN . . . . . . . . . . . .  	L WORD	0351	CSEG
SECOND . . . . . . . . . . . . .  	NUMBER	0002	
SECTOR14 . . . . . . . . . . . .  	NUMBER	000E	
SECTOR15 . . . . . . . . . . . .  	NUMBER	000F	
SECTOR8  . . . . . . . . . . . .  	NUMBER	0008	
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-5


SECTOR9  . . . . . . . . . . . .  	NUMBER	0009	
SECTOR_SIZE  . . . . . . . . . .  	L BYTE	0368	CSEG
SELECT_FLAG  . . . . . . . . . .  	L BYTE	0377	CSEG
SELECT_MPX . . . . . . . . . . .  	NUMBER	ADC1	
SELECT_PRESENT . . . . . . . . .  	NUMBER	00FF	
SENDMSG  . . . . . . . . . . . .  	N PROC	115A	CSEG	Global	Length = 0043
SERIAL . . . . . . . . . . . . .  	L DWORD	033E	CSEG
SERVER . . . . . . . . . . . . .  	NUMBER	002A	
SETDEVPARM . . . . . . . . . . .  	NUMBER	0040	
SET_ASSIGN_MODE  . . . . . . . .  	NUMBER	5F01	
SET_CTL_BREAK_VECT . . . . . . .  	NUMBER	2523	
SET_DISKBASE_VECTOR  . . . . . .  	NUMBER	251E	
SET_DRV_PARM_DEF . . . . . . . .  	N PROC	0FF8	CSEG	Global	Length = 0006
SET_FOR_THE_OLD  . . . . . . . .  	N PROC	0E6E	CSEG	Global	Length = 002E
SET_LOGICAL_DRIVE  . . . . . . .  	N PROC	0894	CSEG	Global	Length = 000B
SET_LOGIC_DRIVE  . . . . . . . .  	NUMBER	000F	
SET_SP_BF_FORM . . . . . . . . .  	NUMBER	0005	
SET_SP_FUNC_DEF  . . . . . . . .  	NUMBER	0004	
SET_SP_FUNC_DOS  . . . . . . . .  	NUMBER	0004	
SET_TRACKLAYOUT  . . . . . . . .  	N PROC	0E9C	CSEG	Global	Length = 0023
SEVEN  . . . . . . . . . . . . .  	NUMBER	0007	
SHARED . . . . . . . . . . . . .  	NUMBER	0003	
SIDE . . . . . . . . . . . . . .  	L BYTE	036C	CSEG	Global
SIDE_TO_FORMAT . . . . . . . . .  	L BYTE	036D	CSEG
SIX  . . . . . . . . . . . . . .  	NUMBER	0006	
SOFT_ERROR . . . . . . . . . . .  	NUMBER	0001	
SOURCE_DRIVE . . . . . . . . . .  	L BYTE	0308	CSEG	Global
SPECIALFUNCTIONS . . . . . . . .  	L BYTE	080D	CSEG
STATUS_CHK . . . . . . . . . . .  	NUMBER	0001	
STDERR . . . . . . . . . . . . .  	NUMBER	0002	
STDOUT . . . . . . . . . . . . .  	NUMBER	0001	
STD_ERROR  . . . . . . . . . . .  	NUMBER	0002	
SUBLIST_26A  . . . . . . . . . .  	V WORD	0000	CSEG	External
SUBLIST_26B  . . . . . . . . . .  	V WORD	0000	CSEG	External
SYSDISPMSG . . . . . . . . . . .  	L NEAR	0000	CSEG	External
SYSLOADMSG . . . . . . . . . . .  	L NEAR	0000	CSEG	External
S_DRV_HEADS  . . . . . . . . . .  	L BYTE	0311	CSEG	Global
S_DRV_SECT_TRACK . . . . . . . .  	L BYTE	0310	CSEG	Global
S_DRV_SET_FLAG . . . . . . . . .  	L BYTE	0343	CSEG
S_DRV_TRACKS . . . . . . . . . .  	L BYTE	0312	CSEG	Global
S_OWNER_SAVED  . . . . . . . . .  	L BYTE	0304	CSEG	Global

TADDRESS_OFF . . . . . . . . . .  	L WORD	0816	CSEG
TADDRESS_SEG . . . . . . . . . .  	L WORD	0818	CSEG
TARGET_DRIVE . . . . . . . . . .  	L BYTE	0309	CSEG	Global
TARGET_OP  . . . . . . . . . . .  	L BYTE	0374	CSEG
TEN  . . . . . . . . . . . . . .  	NUMBER	000A	
TEST_REPEAT  . . . . . . . . . .  	N PROC	0931	CSEG	Global	Length = 0029
THREE  . . . . . . . . . . . . .  	NUMBER	0003	
TIME_OUT_FLAG  . . . . . . . . .  	L BYTE	0376	CSEG
TRACK_SIZE . . . . . . . . . . .  	L WORD	0366	CSEG
TRACK_TO_FORMAT  . . . . . . . .  	L BYTE	0365	CSEG
TRACK_TO_READ  . . . . . . . . .  	L BYTE	0363	CSEG	Global
TRACK_TO_WRITE . . . . . . . . .  	L BYTE	0364	CSEG	Global
TRUE . . . . . . . . . . . . . .  	NUMBER	0001	
TRY_FORMAT . . . . . . . . . . .  	N PROC	10CC	CSEG	Global	Length = 0060
TRY_FORMAT_FLAG  . . . . . . . .  	L BYTE	0375	CSEG
TWO  . . . . . . . . . . . . . .  	NUMBER	0002	
TYPE_4 . . . . . . . . . . . . .  	NUMBER	0004	
T_DRV_HEADS  . . . . . . . . . .  	L BYTE	0314	CSEG	Global
T_DRV_SECT_TRACK . . . . . . . .  	L BYTE	0313	CSEG	Global
T_DRV_SET_FLAG . . . . . . . . .  	L BYTE	0344	CSEG
T_DRV_TRACKS . . . . . . . . . .  	L BYTE	0315	CSEG	Global
T_OWNER_SAVED  . . . . . . . . .  	L BYTE	0305	CSEG	Global

UKM_ERR  . . . . . . . . . . . .  	L BYTE	0372	CSEG
USER_INPUT . . . . . . . . . . .  	L BYTE	0370	CSEG	Global
USER_OPTION  . . . . . . . . . .  	L BYTE	030A	CSEG	Global
UTILITY_MSG_CLASS  . . . . . . .  	NUMBER	00FF	

VERIFY_FUNC  . . . . . . . . . .  	NUMBER	0062	
VOLSER_FLAG  . . . . . . . . . .  	L BYTE	033D	CSEG

WAIT_FOR_USER  . . . . . . . . .  	L NEAR	10A6	CSEG
WARN_USER_1  . . . . . . . . . .  	L NEAR	1086	CSEG
WARN_USER_2  . . . . . . . . . .  	L NEAR	10A0	CSEG
WO_AGAIN . . . . . . . . . . . .  	L NEAR	0B0A	CSEG
WO_EXIT  . . . . . . . . . . . .  	L NEAR	0B76	CSEG
WRITE_FILE . . . . . . . . . . .  	NUMBER	0040	
WRITE_FUNC . . . . . . . . . . .  	NUMBER	0041	
WRITE_OP . . . . . . . . . . . .  	N PROC	0B0A	CSEG	Global	Length = 006D
WRITE_TARGET . . . . . . . . . .  	N PROC	09AE	CSEG	Global	Length = 0064
WRITE_VOLSER . . . . . . . . . .  	N PROC	11AF	CSEG	Global	Length = 0022

YES  . . . . . . . . . . . . . .  	NUMBER	0001	
YESNO  . . . . . . . . . . . . .  	N PROC	119D	CSEG	Global	Length = 0012
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-6


YESNO_CHECK  . . . . . . . . . .  	NUMBER	0023	

ZERO . . . . . . . . . . . . . .  	NUMBER	0000	

$$A_START_DISKCOPY . . . . . . .  	L NEAR	081A	CSEG	Global
$$A_STOP_DISKCOPY  . . . . . . .  	L NEAR	11DE	CSEG	Global
$$DO100  . . . . . . . . . . . .  	L NEAR	0EAD	CSEG
$$DO103  . . . . . . . . . . . .  	L NEAR	0EBF	CSEG
$$DO17 . . . . . . . . . . . . .  	L NEAR	08F2	CSEG
$$DO27 . . . . . . . . . . . . .  	L NEAR	0933	CSEG
$$DO38 . . . . . . . . . . . . .  	L NEAR	0989	CSEG
$$DO4  . . . . . . . . . . . . .  	L NEAR	0834	CSEG
$$DO46 . . . . . . . . . . . . .  	L NEAR	09E1	CSEG
$$DO52 . . . . . . . . . . . . .  	L NEAR	0A17	CSEG
$$DO60 . . . . . . . . . . . . .  	L NEAR	0A5A	CSEG
$$DO73 . . . . . . . . . . . . .  	L NEAR	0B0A	CSEG
$$DO79 . . . . . . . . . . . . .  	L NEAR	0C46	CSEG
$$DO81 . . . . . . . . . . . . .  	L NEAR	0C6A	CSEG
$$DO85 . . . . . . . . . . . . .  	L NEAR	0DE3	CSEG
$$EN1  . . . . . . . . . . . . .  	L NEAR	088B	CSEG
$$EN100  . . . . . . . . . . . .  	L NEAR	0EBE	CSEG
$$EN105  . . . . . . . . . . . .  	L NEAR	0FF7	CSEG
$$EN116  . . . . . . . . . . . .  	L NEAR	1141	CSEG
$$EN119  . . . . . . . . . . . .  	L NEAR	1198	CSEG
$$EN124  . . . . . . . . . . . .  	L NEAR	11AE	CSEG
$$EN17 . . . . . . . . . . . . .  	L NEAR	0911	CSEG
$$EN24 . . . . . . . . . . . . .  	L NEAR	0930	CSEG
$$EN3  . . . . . . . . . . . . .  	L NEAR	0848	CSEG
$$EN31 . . . . . . . . . . . . .  	L NEAR	0959	CSEG
$$EN38 . . . . . . . . . . . . .  	L NEAR	09AD	CSEG
$$EN46 . . . . . . . . . . . . .  	L NEAR	0A0C	CSEG
$$EN53 . . . . . . . . . . . . .  	L NEAR	0A32	CSEG
$$EN56 . . . . . . . . . . . . .  	L NEAR	0A48	CSEG
$$EN73 . . . . . . . . . . . . .  	L NEAR	0B76	CSEG
$$EN87 . . . . . . . . . . . . .  	L NEAR	0E20	CSEG
$$EN94 . . . . . . . . . . . . .  	L NEAR	0E8A	CSEG
$$EN96 . . . . . . . . . . . . .  	L NEAR	0E8A	CSEG
$$IF1  . . . . . . . . . . . . .  	L NEAR	082C	CSEG
$$IF10 . . . . . . . . . . . . .  	L NEAR	088B	CSEG
$$IF105  . . . . . . . . . . . .  	L NEAR	0FEB	CSEG
$$IF107  . . . . . . . . . . . .  	L NEAR	0FF7	CSEG
$$IF110  . . . . . . . . . . . .  	L NEAR	1017	CSEG
$$IF112  . . . . . . . . . . . .  	L NEAR	1029	CSEG
$$IF114  . . . . . . . . . . . .  	L NEAR	10C4	CSEG
$$IF116  . . . . . . . . . . . .  	L NEAR	113A	CSEG
$$IF119  . . . . . . . . . . . .  	L NEAR	1192	CSEG
$$IF120  . . . . . . . . . . . .  	L NEAR	1190	CSEG
$$IF124  . . . . . . . . . . . .  	L NEAR	11AB	CSEG
$$IF127  . . . . . . . . . . . .  	L NEAR	11D0	CSEG
$$IF13 . . . . . . . . . . . . .  	L NEAR	089E	CSEG
$$IF15 . . . . . . . . . . . . .  	L NEAR	08E8	CSEG
$$IF21 . . . . . . . . . . . . .  	L NEAR	091E	CSEG
$$IF24 . . . . . . . . . . . . .  	L NEAR	092D	CSEG
$$IF3  . . . . . . . . . . . . .  	L NEAR	083E	CSEG
$$IF31 . . . . . . . . . . . . .  	L NEAR	0958	CSEG
$$IF35 . . . . . . . . . . . . .  	L NEAR	096A	CSEG
$$IF37 . . . . . . . . . . . . .  	L NEAR	09AD	CSEG
$$IF43 . . . . . . . . . . . . .  	L NEAR	09BE	CSEG
$$IF45 . . . . . . . . . . . . .  	L NEAR	0A0C	CSEG
$$IF53 . . . . . . . . . . . . .  	L NEAR	0A28	CSEG
$$IF56 . . . . . . . . . . . . .  	L NEAR	0A3E	CSEG
$$IF60 . . . . . . . . . . . . .  	L NEAR	0AA2	CSEG
$$IF62 . . . . . . . . . . . . .  	L NEAR	0AA0	CSEG
$$IF66 . . . . . . . . . . . . .  	L NEAR	0AC2	CSEG
$$IF69 . . . . . . . . . . . . .  	L NEAR	0B06	CSEG
$$IF70 . . . . . . . . . . . . .  	L NEAR	0B06	CSEG
$$IF73 . . . . . . . . . . . . .  	L NEAR	0B61	CSEG
$$IF8  . . . . . . . . . . . . .  	L NEAR	0875	CSEG
$$IF83 . . . . . . . . . . . . .  	L NEAR	0D92	CSEG
$$IF87 . . . . . . . . . . . . .  	L NEAR	0E1F	CSEG
$$IF90 . . . . . . . . . . . . .  	L NEAR	0E3C	CSEG
$$IF92 . . . . . . . . . . . . .  	L NEAR	0E6D	CSEG
$$IF94 . . . . . . . . . . . . .  	L NEAR	0E7B	CSEG
$$IF96 . . . . . . . . . . . . .  	L NEAR	0E87	CSEG
$$LL110  . . . . . . . . . . . .  	L NEAR	1012	CSEG
$$LL37 . . . . . . . . . . . . .  	L NEAR	0981	CSEG
$$LL45 . . . . . . . . . . . . .  	L NEAR	09E1	CSEG
$$LL70 . . . . . . . . . . . . .  	L NEAR	0AE3	CSEG
$$SR17 . . . . . . . . . . . . .  	L NEAR	091E	CSEG
$$SR27 . . . . . . . . . . . . .  	L NEAR	0959	CSEG
$$SR60 . . . . . . . . . . . . .  	L NEAR	0AC2	CSEG
$$SR73 . . . . . . . . . . . . .  	L NEAR	0B76	CSEG
$$SS27 . . . . . . . . . . . . .  	L NEAR	0939	CSEG
??0000 . . . . . . . . . . . . .  	L WORD	039E	CSEG
??0001 . . . . . . . . . . . . .  	L WORD	04C2	CSEG
??0002 . . . . . . . . . . . . .  	L WORD	05E6	CSEG
Microsoft (R) Macro Assembler Version 5.10                  2/14/25 23:44:55
DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;               Symbols-7


??0003 . . . . . . . . . . . . .  	L WORD	070A	CSEG
@CPU . . . . . . . . . . . . . .  	TEXT  0101h		
@FILENAME  . . . . . . . . . . .  	TEXT  diskcopy		
@VERSION . . . . . . . . . . . .  	TEXT  510		


   2913 Source  Lines
   3659 Total   Lines
    480 Symbols

  44610 + 202368 Bytes symbol space free

      0 Warning Errors
      0 Severe  Errors
