From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/DISKCOPY/COPYINIT.ASM | 1046 +++++++++++++++ v4.0/src/CMD/DISKCOPY/DCOPYMS.INC | 269 ++++ v4.0/src/CMD/DISKCOPY/DCOPYP.ASM | 139 ++ v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM | 413 ++++++ v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM | 153 +++ v4.0/src/CMD/DISKCOPY/DCPYMACR.INC | 164 +++ v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM | 2452 ++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU | 207 +++ v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK | 6 + v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL | 65 + v4.0/src/CMD/DISKCOPY/MAKEFILE | 57 + 11 files changed, 4971 insertions(+) create mode 100644 v4.0/src/CMD/DISKCOPY/COPYINIT.ASM create mode 100644 v4.0/src/CMD/DISKCOPY/DCOPYMS.INC create mode 100644 v4.0/src/CMD/DISKCOPY/DCOPYP.ASM create mode 100644 v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM create mode 100644 v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM create mode 100644 v4.0/src/CMD/DISKCOPY/DCPYMACR.INC create mode 100644 v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM create mode 100644 v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU create mode 100644 v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK create mode 100644 v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL create mode 100644 v4.0/src/CMD/DISKCOPY/MAKEFILE (limited to 'v4.0/src/CMD/DISKCOPY') diff --git a/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM b/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM new file mode 100644 index 0000000..4410925 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/COPYINIT.ASM @@ -0,0 +1,1046 @@ + PAGE 90,132 ;A2 + TITLE COPYINIT -- DISKCOPY INITIALIZATION PROGRAM +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: COPYINIT + +; DESCRIPTIVE NAME: Initialization for Diskette to diskette 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. + +; 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 +; INCLUDE DISKCOPY.EQU +; INCLUDE PATHMAC.INC ;PATHGEN MACRO + +; INTERNAL REFERENCES: +; ROUTINES: +; INIT - INITIALIZATION ROUTINE, MAIN PROGRAM +; SOURCE_TARGET_DRV - CONVERT SOURCE/TARGET DRIVE TO BIOS VALUES +; TEST_DRIVE_VALIDITY - ARE SOURCE/TARGET DRIVES VALID? +; DOS_DRIVE_VALIDITY - CHECK DOS DRIVE VALIDITY BYTE +; TEST_REMOVABLE - IS SPECIFIED DRIVE REMOVABLE? +; CHK_SINGLE_DRIV_OP - IS TARGET DRIVE SAME AS SOURCE? +; GET_LOGICAL_DRIVE - GET LOG. DRIV NO. WHO OWNS PHYSICAL DRIVE +; DISKETTE_DRV_TYPE - CHECK COMPATABILITY SOURCE/TARGET DRIVES +; CHECK_REDIRECTION - IS DEVICE REDIRECTED? +; BUFFER_SIZE - FINDS START AND END OF BUFFER +; SETUP_CTRL_BREAK - SETUP THE CTRL-BREAK VECTOR +; CHECK_SERVER - IS SERVER OR REDIRECTOR LOADED? + +; 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. +; PARSER - 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 COPYINIT,NUL + +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. + +; For instructions as to how to LINK, see prolog for DISKCOPY. + +;PROGRAM AUTHOR: Original written by: JK +; 4.00 modifications by: EMK +;****************** END OF SPECIFICATIONS ***************************** + IF1 + %OUT COMPONENT=DISKCOPY, MODULE=COPYINIT.SAL + ENDIF + +;DATE: 9-22-83 +;TIME: 8:00 PM +;DATE: 10-30-84 - chk_para routine added. many parts are modified to +; permit DISKCOPY /1, DISKCOPY D: /1 cases. Restore diskbase +; before return to DOS when invalid DOS version occurs. +;DATE: 3-27-85 MAIN PARTS OF DISKCOPY PROGRAM HAS BEEN REWRITTEN +; TO USE NEW IOCTL FUNCTION CALLS - READ, WRITE AND FORMAT. + + INCLUDE DCPYMACR.INC + INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO + +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + + INCLUDE DISKCOPY.EQU +;$salut (4,2,9,41) +;**************************************************************************** +; * +; EXTERNAL VARIABLES * +; * +;**************************************************************************** + + EXTRN PARSER:NEAR ;DCOPYPAR.SAL - DRIVES SYS PARSER ;AN000; + + EXTRN RECOMMENDED_BYTES_SECTOR:WORD ;SOURCE DRIVE DEFAULT BYTES/SECTOR + EXTRN S_OWNER_SAVED:BYTE + EXTRN T_OWNER_SAVED:BYTE + EXTRN ASCII_DRV1_ID:BYTE ;40H SOURCE DRIVE ID IN ASCII + EXTRN ASCII_DRV2_ID:BYTE ;40H TARGET DRIVE ID IN ASCII + EXTRN MSGNUM_INVALID_DRV:BYTE ;"INVALID DRIVE SPECIFICATION" ;AC000; + EXTRN MSGNUM_NOT_COMPATIBLE :BYTE ;"DEVICE TYPE OF DISKETTE TYPES NOT COMPATIBLE";AC000; + EXTRN MSGNUM_DRV_REDIRECTED:BYTE ;"INVALID, DRIVE REDIRECTED" ;AC000; + + + EXTRN SUBLIST_8 :WORD ; ;AN000; + EXTRN SUBLIST_9 :WORD ; ;AN000; + EXTRN SUBLIST_13 :WORD ; ;AN000; + EXTRN SUBLIST_17A :WORD ; ;AN000; + EXTRN SUBLIST_17B :WORD ; ;AN000; + EXTRN SUBLIST_17C :WORD ; ;AN000; + EXTRN SUBLIST_19C :WORD ; ;AN000; + EXTRN SUBLIST_19D :WORD ; ;AN000; + EXTRN SUBLIST_19E :WORD ; ;AN000; + EXTRN SUBLIST_26A :WORD ; ;AN001; + EXTRN SUBLIST_26B :WORD ; ;AN001; + EXTRN SUBLIST_PARSE:WORD ;PARSE ERROR XX - %0 ;AN003; + +.XLIST +;EXTRN MSG_INVALID_PARM_PTR:BYTE ;"INVALID PARAMETER" +;EXTRN MSG_INVALID_DOS :BYTE ;"INVALID DOS" +.LIST + EXTRN S_DRV_SECT_TRACK :BYTE ;SECT/TRACK + EXTRN S_DRV_HEADS :BYTE ;# OF HEADS + EXTRN S_DRV_TRACKS :BYTE ;# OF TRACKS + EXTRN T_DRV_SECT_TRACK :BYTE + EXTRN T_DRV_HEADS :BYTE + EXTRN T_DRV_TRACKS :BYTE + EXTRN SOURCE_DRIVE :BYTE ;SRC DRV LOGICAL NUMBER + EXTRN TARGET_DRIVE :BYTE ;TARGET DRV LOGICAL NUMBER + EXTRN COPY_TYPE :BYTE ;1 = 1-DRIVE COPY 2 = 2-DRIVE COPY + EXTRN USER_OPTION :BYTE ;NO OPTION (-1) /1 (1), INVALID (9) + EXTRN BUFFER_BEGIN :WORD ;STARTING BUFFER @ FOR LOADING + EXTRN BUFFER_END :WORD ;ENDING BUFFER @ FOR LOADING + EXTRN MAIN_EXIT :WORD ;EXIT ADDRESS FOR CONTROL-BREAK + + EXTRN IO_ERROR :BYTE + + EXTRN DS_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM + EXTRN DT_IOCTL_DRV_PARM :BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM + EXTRN DS_specialFunctions :BYTE ;AND THEIR CONTENTS + EXTRN DT_specialFunctions :BYTE + EXTRN DS_deviceType:BYTE + EXTRN DT_deviceType:BYTE + EXTRN DS_deviceAttributes :WORD + EXTRN DT_deviceAttributes :WORD + EXTRN DS_numberOfCylinders :WORD + EXTRN DT_numberOfCylinders :WORD + EXTRN DS_mediaType :BYTE + EXTRN DT_mediaType :BYTE + EXTRN DS_BPB_PTR :BYTE + EXTRN DT_BPB_PTR :BYTE + + EXTRN MS_IOCTL_DRV_PARM :BYTE ;DRIVE PARM FROM SOURCE MEDIUM + EXTRN MT_IOCTL_DRV_PARM :BYTE + + EXTRN GENERIC_IOCTL :NEAR + EXTRN SET_LOGICAL_DRIVE :NEAR + +; $salut (4,20,24,41) ; ;AN000; +MY_BPB STRUC +CBYTE_SECT DW 0 ; 200H BYTES / SECTOR +CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER +CRESEV_SECT DW 0 ; 1h RESERVED SECTORS +CFAT DB 0 ; 2h # OF FATS +CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES +CTOTSECT DW 0 ; 02D0h TOTAL # OF SECTORS + ; INC. BOOT SECT, DIRECTORIES +MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR +CSECT_FAT DW 0 ; 2h SECTORS / FAT +CSECT_TRACK DW 0 ; +CHEAD DW 0 ; +CHIDDEN_SECT DD 0 ; +BIG_TOT_SECT DD 0 ; + DB 6 DUP (0) ; +MY_BPB ENDS + + +;**************************************************************************** +; * +; VARIABLE DECLARATIONS * +; * +;**************************************************************************** +DRIVE_VALID DW ? ;DRIVE VALIDITY INDICATOR +DEFAULT_DRV DB ? ;DEFAULT DRIVE ID (0=A,1=B,ETC) +NUMBER_OF_DRV DB ? ;TOTAL # OF DISKT DRIVES ON THE SYS + ;(NUMBER_OF_DRV = 0 ---> 1 DRIVE) +ASCII_DRIVE_LETTER DB " :",0 + PATHLABL COPYINIT ;AN015; + HEADER ; ;AN000; +; $salut (4,9,15,41) ; ;AN000; +;############################################################################# +; INITIALIZATION ROUTINE - MAIN PROGRAM +INIT PROC NEAR + PUBLIC INIT ;MAKE ENTRY IN LINK MAP ;AN000; + +;OUTPUT: DX = EXIT CODE, "FINE" +;############################################################################# + + MOV DRIVE_VALID,AX ;SAVE DRIVE VALIDITY BYTE + +; REPLACE THE "FILL_SEG" IN THE SUBLIST MESSAGE CONTROL BLOCKS. + +; BECAUSE THIS IS A .COM STYLE FILE, THESE SEGID VALUES CANNOT +; BE PROVIDED BY THE DOS SYSTEM LOADER, BUT MUST BE DYNAMICALLY +; PERFORMED AT EXECUTION TIME AS PART OF A .COM FILE'S OBLIGATION +; TO BE "SELF-RELOCATING". + + MOV AX,CS ;GET SEGID OF COMMON SEGMENT ;AN000; + MOV SUBLIST_8.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_9.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_13.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17A.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17B.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17C.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_19C.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_19D.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_19E.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_26A.SUB_VALUE_SEG,AX ; ;AN001; + MOV SUBLIST_26B.SUB_VALUE_SEG,AX ; ;AN001; + MOV SUBLIST_PARSE.SUB_VALUE_SEG,AX ; ;AN003; + + CALL SETUP_CTRL_BREAK ;STEALS CTRL_BREAK + CLD ;CLEAR DIRECTION FLAG + MOV DX,FINE ;ASSUME EVERYTHING IS FINE +.XLIST +; CALL SCREENING ;CHECK DOS VERSION AND INPUT PARMS +; CALL CHK_PARA ; GENERAL SYNTAX CHECK +.LIST + CALL PARSER ;LOOK AT DOS COMMAND LINE ;AN000; + + CMP DX,FINE ;IF ALL OK ;AN000; +; $IF E ; ;AN000; + JNE $$IF1 + CALL SOURCE_TARGET_DRV ;SET UP TO USE THE DRIVE LETTERS ;AN000; + + CALL TEST_DRIVE_VALIDITY + + CMP DX,FINE +; $IF E ; ;AN000; + JNE $$IF2 + CALL DISKETTE_DRV_TYPE ;SOURCE & TARGET DRIVE TYPES + + CMP DX,FINE ;IF FINE & DANDY +; $IF E ; ;AN000; + JNE $$IF3 + CALL BUFFER_SIZE ;GET BUFFER SIZE FOR COPYING + +; $ENDIF ; ;AN000; +$$IF3: +; $ENDIF ; ;AN000; +$$IF2: +; $ENDIF ; ;AN000; +$$IF1: +EXIT_INIT: ;DX <-- 1 IF INIT OK + RET ;DX <-- ERROR OFFSET IF NOT OK + ;RETURN TO CALLER +INIT ENDP ;END INITIALLIZATION PROGRAM + +.XLIST +; HEADER +;****************************************************************************** +; SUBROUTINE NAME : SCREENING - CHECKS THE FOLLOWING: * +; - DOS VERSION * +; - GENERAL SYNTAX CHECKING FOR PARAMETERS * +; INPUT : NONE * +; OUTPUT : DX : FINE - NO ERROR * +; (OTHERS)- ERROR MSG OFFSET * +;****************************************************************************** + +;SCREENING PROC NEAR + ;CHECK DOS VERSION: +; MOV AH,DOSVER_FUNC ;SEE IF CORRECT DOS VERSION +; INT 21H ;FUNCTION CALL (AL <- DOS VERSION) + ;NOTE: BX IS DESTROYED +; XCHG AH,AL ;AH=MAJOR VER, AL=MINOR VER +; CMP AX,expected_version ;IF DOS MAJOR VERSION LESS THAN 3.00 +; $IF NE ;THEN ISSUE ERROR MSG +; MOV DX,OFFSET MSG_INVALID_DOS +; MOV AH,PRINT_FUNC ;USE PRINT FUNCTION TO TELL USER +; INT 21H ;THAT HE IS USING THE OLD VERSION +; INT 20H ;EXIT TO DOS +; $ELSE ;VERSION OK +; CALL CHK_PARA ;GENERAL SYNTAX CHECK +; $ENDIF ;END VERSION TEST +; RET +;SCREENING ENDP +; HEADER +;************************************************************************** + +;kiser: this proc is to be deleted + +;CHK_PARA PROC NEAR +; CHECK SYNTAX OF THE ENTERED PARAMETERS * +; ALSO, DETERMINE THE USER OPTION "/1" IS ENTERED OR NOT. * +; INPUT: DX = FINE * +; IF /1 HAS BEEN ENTERED, THE VARIABLE USER_OPTION = OPTION_1 * +; ELSE USER_OPTION = NO_OPTION. * +; OUTPUT: DX = FINE - NO ERROR * +; OTHERWISE DX POINTS TO ERROR MSG * +;************************************************************************** +; PUSH CX +; MOV USER_OPTION, NO_OPTION ;ASSUME NO /1 IS ENTERED. +; XOR CX, CX +; MOV CL, BYTE PTR DS:BEGIN_UNFORM_AREA ;GET # OF CHR +; CMP CL, 0 +; $IF NZ +; CLD ;CLEAR DIRECTION +; MOV DI, BEGIN_UNFORM_AREA+2 ;STARTING POINT OF PARA +; DEC CL ;TO IGNORE LAST CHR (0DH) +; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY. THE POINTER +; ; WILL POINT TO THE NEXT NON_BLANK CHR +; +; $IF NZ ;SOMETHING OTHER THAN BLANKS +; ; ARE ENTERED +; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 ? +; +; JNC SLASH_ONE ;YES +; CALL CHK_DRV_SPEC ;IS IT A DRIVE SPECIFICATION LIKE d: ? +; +; JC INVALID_PARA ;IF NOT, THEN ERROR +; JZ CHK_PARA_EXIT ;NO MORE CHR? THEN, OK. (EX. DISKCOPY D:) +; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 ? +; +; JNC SLASH_ONE ;YES.(EX. DISKCOPY D:/1) +; CALL CHK_BLANK ;IF NOT, NEXT CHR SHOULD BE A BLANK. +; +; JC INVALID_PARA ;OTHERWISE, ERROR. +; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY. +; +; JZ CHK_PARA_EXIT ;(EX. DISKCOPY D: ) +; CALL CHK_SLASH_ONE ;IS IT A /1 ? +; +; JNC SLASH_ONE ;YES. (EX. DISKCOPY D: /1) +; CALL CHK_DRV_SPEC ;IF NOT /1, THEN IS IT A DRV SPEC? +; +; JC INVALID_PARA ;OTHERWISE, ERROR. +; CALL SKIP_BLANKS ;SKIP BLANKS, IF ANY. +; +; JZ CHK_PARA_EXIT ;NO MORE CHR. (EX. DISKCOPY D: D:) +; CALL CHK_SLASH_ONE ;OTHERWISE, IT SHOULD BE /1. +; +; JNC SLASH_ONE ;YES, /1. JMP TO SLASH_ONE +; JMP INVALID_PARA ;PARAMETER ERROR. +;SLASH_ONE: +; MOV USER_OPTION, OPTION_1 ;YES, /1 HAS BEEN ENTERED. +; CALL SKIP_BLANKS ;/1 SHOULD BE END OF PARAMETERS, OR ONLY BLANKS CAN FOLLOW. +; +; $IF NZ +;INVALID_PARA: +; MOV DX,OFFSET MSG_INVALID_PARM_PTR ;WRONG PARM ENTERED MSG +; $ENDIF +; $ENDIF +; $ENDIF +;CHK_PARA_EXIT: +; POP CX +; +; RET +;CHK_PARA ENDP +; HEADER +;*************************************************************************** +;SKIP_BLANKS PROC NEAR +; ** SKIP BLANKS, OR TABS IF ANY, IN THE PARAMETER STRING. * +; INPUT: ES:DI POINTS TO THE CURRENT CHR. * +; CX - # OF REMAINING CHR IN THE STRING. * +; OUTPUT: ES:DI POINT TO THE NEXT NON_BLANK CHR. * +; CX IS ADJUSTED ACCORINGLY. * +; IF THE CURRENT CHR IS NOT A BLANK, THEN DI, CX VALUE NOT CHANGED.* +; IF CX = 0, THEN ZERO FLAG WILL BE SET AND EXIT THIS PROC. * +;*************************************************************************** +; $DO +; MOV AL, 20H ;20H=BLANK +; CLD ;CLEAR DIRECTION +; REPE SCASB +; $LEAVE Z ;IF NOT FOUND A NON_BLANK CHR YET, AND CX=0, EXIT THIS ROUTINE. +; DEC DI ;OTHERWISE, RESTORE DI TO THE NON_BLANK POSITION. +; INC CX ; AND RESTORE CX TO WHERE IT WAS AT NON_BLANK CHR +; ;(IF FOUND A NON_BLANK CHR, ZERO FLAG WOULD NOT BE SET) +; MOV AL, ES:BYTE PTR [DI] +; CMP AL, 09H ;09H=TAB +; $LEAVE NZ ;IF THE NON_BLANK CHR IS NOT A TAB THEN EXIT +; INC DI ;ELSE TRY SKIP AGAIN +; DEC CX +; $ENDDO +; RET +;SKIP_BLANKS ENDP +; HEADER +;*************************************************************************** + +;kiser: this proc is to be deleted + +;CHK_SLASH_ONE PROC NEAR +; ** CHECK CURRENT CHR IS / FOLLOWED BY 1. * +; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. * +; CX REPRESENTS THE # OF CHR'S IN THE STRING. * +; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX CHANGED ACCORDINGLY. * +; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. * +; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. * +;*************************************************************************** +; +; CLC ;CLEAR CARRY FLAG +; CMP CX, 2 ;# OF CHR IN THE STRING. +; $IF NL,AND ;IF LESS THAN 2, THEN SET CARRY AND EXIT. +; +; MOV AX, ES:WORD PTR [DI] ;GET CURRENT WORD IN AX +; CMP AX, '1/' ;IS IT /1 ? +; $IF Z ;IF NOT, THEN SET CARRY AND EXIT +; INC DI ;ADJUST CX, DI TO THE NEXT CHR +; INC DI +; DEC CX +; DEC CX +; CMP CX, 0 ;IF NO MORE CHR, THEN SET ZERO FLAG. +; $ELSE +; STC ;NOT FOUND, SET CARRY FLAG. +; $ENDIF +; RET +;CHK_SLASH_ONE ENDP +; HEADER +;*************************************************************************** + +;kiser: this proc is to be deleted + +;CHK_DRV_SPEC PROC NEAR +; ** CHECK CURRENT CHR IS ALPHA CHR FOLLOWED BY COLON. * +; INPUT: ES:DI POINTS TO THE CURRENT CHR TO BE CHECKED. * +; CX -- # OF CHR IN THE STRING. * +; OUTPUT: FOUND - DI POINTS TO THE NEXT CHR. CX ADJUSTED ACCORDINGLY. * +; IF THIS HAD BEEN A LAST WORD, ZERO FLAG WILL BE SET. * +; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. * +;*************************************************************************** + +; CLC ;CLEAR CARRY +; CMP CX, 2 ;# OF CHR REMAINING IN THE STRING. +; $IF NL,AND ;IF NOT LESS THAN 2, THEN FOUND +; ;IF LESS THAN 2, THEN NOT FOUND - SET CARRY AND EXIT. +; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR +; AND AL, 11011111B ;CHANGE IT TO UPPER_CASE CHR. +; CMP AL, 'A' +; $IF NB,AND ;NOT BELOW 'A', THEN MAYBE FOUND OK +; +; CMP AL, 'Z' +; $IF NA,AND ;NOT ABOVE 'Z', THEN FOUND +; +; MOV AL, ES:BYTE PTR [DI+1] ;LOOK AHEAD THE FOLLOWING CHR. +; CMP AL, ':' ;SHOULD BE A COLON. +; $IF Z ;IF FOUND. +; INC DI ;FOUND. ADJUST CX, DI TO THE NEXT CHR. +; INC DI +; DEC CX +; DEC CX +; CMP CX, 0 ;IF NO MORE CHR, THAN SET THE ZERO FLAG. +; $ELSE +; STC ;SET CARRY +; $ENDIF +; RET +;CHK_DRV_SPEC ENDP +; HEADER +;*************************************************************************** + +;kiser: this proc is to be deleted + +;CHK_BLANK PROC NEAR +;; ** CHECK THE CURRENT CHR IS A BLANK OR TAB * +;; INPUT: ES:DI POINTS TO THE CURRENT CHR. * +; CX - # OF CHR IN THE STRING. * +; OUTPUT: FOUND - DI MOVES TO THE NEXT CHR. CX DECREASES BY 1. * +; NOT FOUND - CARRY IS SET. DI, CX UNCHANGED. * +;*************************************************************************** + +; CLC ;CLEAR CARRY +; CMP CX, 1 ;IF LESS THAN 1, NOT FOUND. +; $IF L,OR ;GO SET CARRY AND EXIT +; +; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR +; CMP AL, 020H ;020H=BLANK CHR +; $IF NZ,AND ;NOT FOUND +; CMP AL, 09H ;09H=TAB CHR +; $IF NZ ;NOT FOUND EITHER +; +; ;THEN NOT FOUND +; STC ;SET CARRY +; $ELSE ;CHAR MUST BE EITHER TAB OR BLANK +; INC DI ;FOUND. ADJUST DI, CX +; DEC CX +; $ENDIF +; RET +;CHK_BLANK ENDP +.LIST + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : SOURCE_TARGET_DRV DETERMINES SOURCE & TARGET DRIVES & * +; CONVERT THEM FROM DOS TO BIOS VALUE * +; INPUT : SOURCE_DRIVE & TARGET_DRIVE HAVE DOS DRIVE ID'S: * +; 0 = DEFAULT 1 = DRV A * +; 2 = DRV B 3 = DRV C ETC * +; * +; * +; OUTPUT : DEFAULT_DRV: CURRENT DEFAULT DRIVE * +; 0 - DRIVE A 1 - DRIVE B * +; 2 - DRIVE C 3 - DRIVE D * +; * +; : SOURCE_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. * +; : TARGET_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. * +; (UNCHANGED) * +;****************************************************************************** +SOURCE_TARGET_DRV PROC NEAR + PUBLIC SOURCE_TARGET_DRV ;MAKE ENTRY IN LINK MAP ;AN000; + ;GET CURRENT DEFAULT DRIVE + MOV AH,CURRENTDRV_FUNC ;FUNCTION CALL (19H) + ;(AL <- CURRENT DEFAULT DRV + INT 21H ;0 = A, 1 = B, ETC) + + MOV DEFAULT_DRV,AL ;SAVE IT + INC AL ;NOW A=1, B=2, ETC ;AN000; + CMP SOURCE_DRIVE,ZERO ;FIRST DRV ENTERED? ;AC000; +; $IF E ;NO DRIVE LETTER ENTERED + JNE $$IF7 + MOV SOURCE_DRIVE,AL ;USE DEFAULT DRIVE AS SOURCE ;AC000; + MOV TARGET_DRIVE,AL ; AND AS TARGET ;AC000; +; $ELSE + JMP SHORT $$EN7 +$$IF7: + CMP TARGET_DRIVE,ZERO ;WAS THE SECOND DRIVE ID SPECIFIED? ;AC000; +; $IF E ;NO, SO TARGET DRV IS DEFAULT ;AC000; + JNE $$IF9 + MOV TARGET_DRIVE,AL ;USE DEFAULT DRIVE AS TARGET ;AC000; +; $ENDIF +$$IF9: +; $ENDIF +$$EN7: + MOV AX,WORD PTR SOURCE_DRIVE ;SOURCE TO AL, TARGET TO AH ;AC000; + ADD ASCII_DRV1_ID,AL ;MAKE THE DRIVE ALPHABET READABLE + ADD ASCII_DRV2_ID,AH ;IN THE MESSAGE + + RET + +SOURCE_TARGET_DRV ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : TEST_DRIVE_VALIDITY--MAKE SURE SOURCE AND TARGET DRIVES * +; SPECIFIED BY USER ARE VALID FOR DISKCOPY * +; * +; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE * +; * +; OUTPUT : DX='FINE' IF DRIVES ARE VALID, ELSE DX CONTAINS MSG PTR * +;****************************************************************************** + +TEST_DRIVE_VALIDITY PROC NEAR + PUBLIC TEST_DRIVE_VALIDITY ;MAKE ENTRY IN LINK MAP ;AN000; + + CALL DOS_DRIVE_VALIDITY + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF12 + + MOV BL,SOURCE_DRIVE + CALL CHECK_REDIRECTION + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF12 + + MOV BL,TARGET_DRIVE + CALL CHECK_REDIRECTION + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF12 + + MOV BL,SOURCE_DRIVE + CALL CHECK_SERVER + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF12 + + MOV BL,TARGET_DRIVE + CALL CHECK_SERVER + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF12 + + CALL TEST_REMOVABLE + + CMP DX,FINE +; $IF E ; ;AC000; + JNE $$IF12 + + CALL CHK_SINGLE_DRV_OP ;CHECK IF IT IS + ; ONE PHYSICAL DRIVE OPERATION +; $ENDIF ; ;AC000; +$$IF12: + RET + +TEST_DRIVE_VALIDITY ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : DOS_DRIVE_VALIDITY -- CHECK DOS DRIVE VALIDITY BYTE * +; * +; INPUT : DRIVE_VALID:BYTE * +; * +; OUTPUT : DX="FINE" IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR * +;****************************************************************************** + +DOS_DRIVE_VALIDITY PROC NEAR + + CMP DRIVE_VALID,0 ;SEE IF DRIVES ARE VALID DOS DEVICE +; $IF NE + JE $$IF14 + MOV DX,OFFSET MSGNUM_INVALID_DRV ; ;AC000; +; $ENDIF +$$IF14: + RET + +DOS_DRIVE_VALIDITY ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : TEST_REMOVABLE -- CHECK IF DRIVES SPECIFED ARE REMOVABLE * +; * +; INPUT : SOURCE_DRIVE:BYTE, TARGET_DRIVE:BYTE * +; * +; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR * +;****************************************************************************** + +TEST_REMOVABLE PROC NEAR + + MOV BL,SOURCE_DRIVE ;GET PARM 1 DRIVE ID + + MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE = 4408h + INT 21H ;IOCTL CALL +; $IF NC ;IF DRIVE ID IS WITHIN RANGE + JC $$IF16 + CMP AX,REMOVABLE ;THEN IF SOURCE DRIVE IS FIXED +; $IF NE ; THEN + JE $$IF17 + MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE HARD ;AC000; + ; DRIVE ERROR MESSAGE +; $ELSE ;ELSE, SRC IS REMOVABLE; + JMP SHORT $$EN17 +$$IF17: + MOV BL,TARGET_DRIVE ;NOW GO CHECK TARGET + + MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE + INT 21H ;IOCTL CALL +; $IF NC ;IF DRV WITHIN RANGE + JC $$IF19 + CMP AX,REMOVABLE ;THEN TGT DRV IS FIXED +; $IF NE ; THEN + JE $$IF20 + MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE HARD ;AC000; + ; DRV ERROR MSG +; $ENDIF ;END TEST IF TGT DRV IS FIXED +$$IF20: +; $ELSE ;TGT DRV OUT OF RANGE. EX. DRIVE X: + JMP SHORT $$EN19 +$$IF19: + MOV DX,OFFSET MSGNUM_INVALID_DRV ; ;AC000; +; $ENDIF ;END TEST IF TGT WITHIN RANGE +$$EN19: +; $ENDIF ;END IF SRC IS REMOVABLE +$$EN17: +; $ELSE ;ELSE, SRC DRV OUT OF RANGE + JMP SHORT $$EN16 +$$IF16: + MOV DX,OFFSET MSGNUM_INVALID_DRV ;PRINT ERROR MSG ;AC000; +; $ENDIF ;END TEST IF SRC DRV WITHIN RANGE +$$EN16: + RET + +TEST_REMOVABLE ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : CHK_SINGLE_DRV_OP * +; * +; INPUT : SOURCE_DRIVE - LOGICAL DRIVE NUMBER * +; TARGET_DRIVE * +; * +; OUTPUT : COPY_TYPE WILL BE SET TO ONE OR TWO DEPENDING ON THE * +; TEST RESULT. IF IT IS A SINGLE DRIVE COPY, THEN * +; TARGET DRIVE LETTER WILL BE CHANGED TO THAT OF SOURCE. * +; THE OWNERSHIP OF THE SOURCE AND TARGET DRIVE LETTER * +; MIGHT HAVE BEEN CHANGED. * +; SO, BEFORE EXIT TO DOS, THEY SHOULD BE RESET TO THE SAVED* +; ONE USING S_OWNER_SAVED AND T_OWNER_SAVED UNLESS THEY * +; ARE EQUAL TO 0. (0 MEANS ONLY ONE DRIVE LETTER ASSIGNED.)* +; ASCII_DRV1_ID, ASCII_DRV2_ID MAY BE CHANGED ACCORDINGLY. * +;****************************************************************************** + +CHK_SINGLE_DRV_OP PROC NEAR + + PUSH AX + + MOV BL,SOURCE_DRIVE + CALL GET_LOGICAL_DRIVE + + MOV S_OWNER_SAVED, AL ;SAVE CURRENT OWNER DRIVE LETTER. + MOV BL, TARGET_DRIVE + CALL GET_LOGICAL_DRIVE + + MOV T_OWNER_SAVED, AL ;SAVE CURRENT OWNER + MOV BL, SOURCE_DRIVE + CALL SET_LOGICAL_DRIVE + + MOV BL, TARGET_DRIVE + CALL SET_LOGICAL_DRIVE + + MOV BL, SOURCE_DRIVE + CALL GET_LOGICAL_DRIVE ;CHECK SOURCE DRV LETTER + ; STILL HAS A OWNERSHIP. + + CMP AL, SOURCE_DRIVE ; +; $IF NE ;IF IT DOES NOT, THEN A + JE $$IF27 + ; SINGLE DRIVE COPY. + MOV COPY_TYPE, ONE + MOV BL, SOURCE_DRIVE + MOV TARGET_DRIVE, BL ;SET TARGET DRV LETTER + ; TO THAT OF SOURCE + MOV BL, ASCII_DRV1_ID + MOV ASCII_DRV2_ID, BL + MOV BL, SOURCE_DRIVE + CALL SET_LOGICAL_DRIVE ;SET THE OWNER BACK TO + ; SOURCE DRV LETTER + +; $ELSE + JMP SHORT $$EN27 +$$IF27: + CMP AL, TARGET_DRIVE ;SOURCE DRV LETTER = TARGET DRV + ; LETTER CASE, FOR EX. DISKCOPY A: A: +; $IF E + JNE $$IF29 + MOV COPY_TYPE, ONE +; $ELSE + JMP SHORT $$EN29 +$$IF29: + MOV COPY_TYPE, TWO +; $ENDIF +$$EN29: +; $ENDIF +$$EN27: + + POP AX + + RET +CHK_SINGLE_DRV_OP ENDP + HEADER ;AN000; +;****************************************************************************** +GET_LOGICAL_DRIVE PROC NEAR +; *** GET THE LOGICAL DRIVE NUMBER WHO HAS THE OWNERSHIP OF THE PHYSICAL +; DRIVE. +; INPUT: BL = DRIVE NUMBER (0=DEFAULT, 1=A, 2=B...) +; OUTPUT: AL = DRIVE NUMBER (0= ONLY ONE DRIVE LETTER ASSIGNED TO THE +; BLOCK DEVICE. OTHERWISE, 1=A, 2=B...) +; +;****************************************************************************** + + MOV AH, 44H + MOV AL, 0EH ; GET THE OWNER OF LOGICAL DRIVE NUMBER + INT 21H + CMP AL, 0 ;ONLY ONE DRIVE LETTER ASSIGNED? +; $IF E + JNE $$IF33 + MOV AL, BL ;THEN SET THE INPUT DRIVE NUMBER TO AL. +; $ENDIF +$$IF33: + + RET + +GET_LOGICAL_DRIVE ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : DISKETTE_DRV_TYPE DOES THE FOLLOWING: * +; - GETS SOURCE, TARGET DRIVE INFORMATION * +; - CHECK REMOVABLE DRIVE * +; *** REMARK: WILL NOT ALLOW DISKCOPY BETWEEN 5.25" AND 3.5" DRIVES. * +; *** ALSO, IN THE MAIN PROGRAM, SOURCE MEDIA BPB INFORMATIONS (# OF SEC/TRK, * +; *** # OF TRACKS) SHOULD BE CHECKED AGAINST TARGET DEVICE INFORMATIONS. * +; *** IF # OF SECT/TRACK, # OF TRACKS OF TARGET DEVICE ARE EQUAL TO, OR * +; *** GREATER THAN THOSE OF THE SOURCE MEDIA BPB, THEN IT IS OK. OTHERWISE * +; *** DEVICE NOT COMPATIBLE. * +; *** IF THIS DOES NOT GAURANTEES COMPATIBILITY BETWEEN SOURCE AND TARGET * +; *** DEVICE OR MEDIA, EVENTUALLY, FAILURE TO FORMAT THE TARGET WILL * +; *** TELL THAT SOURCE, TARGET DEVICE OR MEDIA ARE NOT COMPATIBLE. * +; * +;****************************************************************************** +DISKETTE_DRV_TYPE PROC NEAR + PUSH AX + + xor bx, bx + MOV BL, SOURCE_DRIVE + MOV CL, GETDEVPARM ;=60h + MOV DX, OFFSET DS_IOCTL_DRV_PARM ;POINTER TO THE CONTROL STRING + CALL GENERIC_IOCTL ;GET DEFAULT DEVICE PARM. + + TEST DS_deviceAttributes, 0001h ;CHECK REMOVABLE. 0001 = NOT REMOVABLE +; $IF E,AND ;NO, CONTINUE ;AC000; + JNE $$IF35 + + MOV AX, DS_numberOfCylinders ;CURRENTLY IGNORE AH. ASSUME LESS + ; THAN TWO BYTES + MOV S_DRV_TRACKS, AL + MOV BX, OFFSET DS_BPB_PTR + MOV AX, [BX].CHead + MOV S_DRV_HEADS, AL + MOV AX, [BX].CSECT_TRACK + MOV S_DRV_SECT_TRACK, AL + MOV AX, [BX].CBYTE_SECT ;RECOMMENDED BYTES/SECTOR + MOV RECOMMENDED_BYTES_SECTOR, AX + + XOR BX,BX + MOV BL, TARGET_DRIVE + MOV CL, GETDEVPARM + MOV DX, OFFSET DT_IOCTL_DRV_PARM + CALL GENERIC_IOCTL ;GET DEFAULT DEVICE PARM. + + TEST DT_deviceAttributes, 0001h ;FIXED DISK? +; $IF Z ;TARGET IS NOT FIXED DISK, OK ;AC000; + JNZ $$IF35 + + MOV AX, DT_numberOfCylinders + MOV T_DRV_TRACKS, AL + MOV BX, OFFSET DT_BPB_PTR + MOV AX, [BX].CHead + MOV T_DRV_HEADS, AL + MOV AX, [BX].CSECT_TRACK + MOV T_DRV_SECT_TRACK, AL + +;**NOW, CHECK SOURCE, TARGET DEVICE COMPATIBILITY + MOV DX, FINE ;GUESS, ALL WILL BE OK + ; DX MAY BE CHANGED TO REFLECT ERROR + CMP DS_deviceType, DRV_720 ;0 - 48 TPI, 5.25", 96 TPI, + ; 5.25", 2 - 720kb, 3.5" +; $IF E ;WILL ONLY ALLOW DISKCOPY BETWEEN ;AC000; + JNE $$IF36 + ; 720KB, 3.5 SOURCE, TARGET + + CMP DT_deviceType, DRV_720 ;target = 720KB also? +; $IF NE ; ;AC000; + JE $$IF37 + MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ;AC000; +; $ENDIF ; ;AC000; +$$IF37: +; $ELSE ;SINCE SOURCE NOT 720 ;AC000; + JMP SHORT $$EN36 +$$IF36: + CMP DT_deviceType, DRV_720 ;SOURCE IS NOT 720kb, + ; IS TARGET 720? +; $IF E ;IF SO, THEN ;AC000; + JNE $$IF40 + ;DDT IS NOT COMPATIBLE + MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000; +; $ENDIF ; ;AC000; +$$IF40: +; $ENDIF ; ;AC000; +$$EN36: +; $ELSE ;SINCE SOURCE IS FIXED DISK, ERROR ;AC000; + JMP SHORT $$EN35 +$$IF35: + MOV DX, OFFSET MSGNUM_INVALID_DRV ;ISSUE BAD DRV MSG ;AC000; +; $ENDIF ; ;AC000; +$$EN35: + POP AX + RET + +DISKETTE_DRV_TYPE ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : CHECK_REDIRECTION FIND OUT IF DEVICE IS REDIRECTED * +; IF IT IS, GENERATE ERROR MSG & EXIT * +; INPUT : BL - DRIVE TO BE TESTED * +; : AL : CURRENT DEFAULT DRIV * +; * +; OUTPUT : DX = LOCAL_DRV (-1) * +; = DIRECTED ( ERROR MSG OFFSET) * +; = INVALID_DRIVE (ERROR MSG OFFSET) * +;****************************************************************************** +CHECK_REDIRECTION PROC NEAR + + PUSH AX ;SAVE REGISTERS + PUSH BX + PUSH CX + + MOV CX,DX ;SAVE RET TEMPORARILY + MOV AH,IOCTL_FUNC ;GET IOCTL FUNTION & + MOV AL,REDIRECTED_FUNC ;IOCTL SUB-FUNCTION ******CHECK*** + + INT 21H ;AND GO FIND OUT IF IT'S LOCAL +; $IF C + JNC $$IF45 + MOV CX,OFFSET MSGNUM_INVALID_DRV ;REDIR INVALID ;AC000; + +; $ELSE + JMP SHORT $$EN45 +$$IF45: + TEST DX,REMOTE_DRV ;IF DRIVE IS REDIRECTED +; $IF NZ + JZ $$IF47 + + MOV CX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000; +; $ENDIF +$$IF47: +; $ENDIF +$$EN45: + MOV DX,CX ;GET ERROR MSG @ + + POP CX ;RESTORE REGISTERS + POP BX + POP AX + RET ;RETURN TO CALLER +CHECK_REDIRECTION ENDP + HEADER ; ;AN000; +;****************************************************************************** +; SUBROUTINE NAME : BUFFER_SIZE DETERMINES WHERE BUFFER STARTS & ENDS * +; INPUT : NONE * +; * +; OUTPUT : BUFFER_BEGIN ADDRESS * +; : BUFFER_END ADDRESS * +;****************************************************************************** +BUFFER_SIZE PROC NEAR + + + PUSH AX ;SAVE REGISTERS + PUSH BX + PUSH CX + MOV BX, offset init ;GET ADDR OF INIT + 1024 AS + ; A START OF BUFFER + add bx, 1024 ;(OFFSET FROM CS, IN BYTES) + MOV CL,4 ;CONVERT OFFSET INTO SEGMT BY DIVIDING + SHR BX,CL ;IT BY 16 + + MOV AX,CS ;CS + OFFSET => INIT+1024@ IN SEGMENT + ADD BX,AX ;WHERE BUFFER CAN START + + ;NEED TO START AT A NEW SECTOR ==> + AND BL,CLEAR_SEGMENT ;TRUNCATE TO PREVIOUS 512 BYTE BOUNDRY + ;(GET PREVIOUS SECTOR NUMBER) + ADD BX,20H ;THEN, ADVANCE TO THE BEGINNING OF + ;NEXT SECTOR (SINCE PART OF PREVIOUS + ;SECTOR WAS USED) + + MOV BUFFER_BEGIN,BX ;SAVE OUR BUFFER START SEGMENT ADDR + ;(AT THE BEGINNING OF A SECTOR WITH + ;SEGMENT BITS CLEARED) + + MOV BX,DS:TWO ;GET ADDR WHERE BUFFER ENDS + MOV BUFFER_END,BX ;(TOP OF MEMORY, OFFSET 2 IN PSP) + + POP CX ;RESTORE REGISTERS + POP BX + POP AX + RET ;RETURN TO CALLER +BUFFER_SIZE ENDP + HEADER ; ;AN000; +;****************************************************************************** +SETUP_CTRL_BREAK PROC NEAR ;SETUP CTRL-BREAK VECTOR +;****************************************************************************** + PUSH AX + PUSH BX + PUSH DX + PUSH ES + + MOV AX,SET_CTL_BREAK_VECT ;SET THE CTRL-BREAK VECTOR + MOV DX,OFFSET MAIN_EXIT + INT 21H + + POP ES + POP DX + POP BX + POP AX + RET + +SETUP_CTRL_BREAK ENDP + HEADER ; ;AN000; +;****************************************************************************** +CHECK_SERVER PROC NEAR ;SEE IF SERVER OR REDIRECTOR IS IN++ +; +; INPUT: BL = DRIVE NUMBER (1=A,2=B ETC....) +;****************************************************************************** + MOV AH,0 ;SEE IF SERVER LOADED + INT SERVER + CMP AH,0 +; $IF E + JNE $$IF50 + MOV DX,FINE +; $ELSE + JMP SHORT $$EN50 +$$IF50: + DEC BL + ADD BL,"A" ;CONVERT TO ASCII DRIVE LETTER + MOV ASCII_DRIVE_LETTER,BL ;PUT IN ASCIIZ STRING + MOV SI,OFFSET ASCII_DRIVE_LETTER + MOV AH,SHARED + CLC + INT SERVER +; $IF C + JNC $$IF52 + MOV DX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000; +; $ELSE + JMP SHORT $$EN52 +$$IF52: + MOV DX,FINE +; $ENDIF +$$EN52: +; $ENDIF +$$EN50: + RET +CHECK_SERVER ENDP + +COPYINIT_END LABEL NEAR + PUBLIC COPYINIT_END + + PATHLABL COPYINIT ;AN015; + +CSEG ENDS + END + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC b/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC new file mode 100644 index 0000000..2cb7622 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DCOPYMS.INC @@ -0,0 +1,269 @@ +;:util DISKCOPY ;utility name +;:class 1 ;DOS extended errors: +;:class 2 ;parse errors: +;1 Too many parameters +;2 Required parameter missing +;3 Invalid switch +;4 Invalid keyword +;5 Parameter value not in allowed range +;6 Parameter value not allowed [parse ret codes 6 and 7] +;7 (undefined) +;8 Parameter format not correct +;9 (undefined) +;10 Invalid parameter [no corresponding parse ret code] +;11 Invalid parameter combination [no corresponding parse ret code] +;; +;:class A ;system messages +;:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version" +;; +;:def 2 CR,LF +; +;:use 3 PARSE10 ;CR,LF,"Invalid parameter",CR,LF +; +;:def 4 "Do not specify filename(s)",CR,LF +;"Command Format: DISKCOPY d: d: [/1]",CR,LF +;; +;:def 5 CR,LF,"Invalid drive specification",CR,LF +;"Specified drive does not exist",CR,LF +;"or is non-removable",CR,LF +; +;:def 6 CR,LF,"Cannot DISKCOPY to or from",CR,LF +;"a network drive",CR,LF +; +;:def 7 CR,LF,"Formatting while copying",CR,LF +; +;:def 8 CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF +; +;:def 9 CR,LF,"Insert TARGET diskette in drive %1:",CR,LF +; +;:def 10 "Make sure a diskette is inserted into",CR,LF +;"the drive and the door is closed",CR,LF +; +;:def 11 CR,LF,"Target diskette may be unusable",CR,LF +; +;:def 12 CR,LF,"Target diskette unusable",CR,LF +; +;:use 13 EXTEND21 ;CR,LF,Drive not ready",CR,LF +; +;:use 14 EXTEND19 ;CR,LF,"Attempt to write to write-protected diskette",CR,LF +; +;:use 15 COMMON28 ;CR,LF,"Press any key to continue . . .",CR,LF +; +;:def 16 CR,LF,"Copy another diskette (Y/N)? " +; +;:def 17 CR,LF,"Copying %1 tracks",CR,LF +;"%2 Sectors/Track, %3 Side(s)",CR,LF +; +;:def 18 CR,LF,"Drive types or diskette types",CR,LF +;"not compatible",CR,LF +; +;:def 19 CR,LF,"Unrecoverable read error on drive %1",CR,LF +;"Side %2, track %3",CR,LF +; +;:def 20 CR,LF,"Unrecoverable write error on drive %1",CR,LF +;"Side %2, track %3",CR,LF +; +;:def 21 CR,LF,"Copy process ended",CR,LF +; +;:def 22 CR,LF,"SOURCE diskette bad or incompatible" +; +;:def 23 CR,LF,"TARGET diskette bad or incompatible" +; +;:use 25 EXTEND8 ;CR,LF,"Insufficient memory",CR,LF +; +;:use 26 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF +; +;:end +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + IF1 ;AN000; + %OUT COMPONENT=DISKCOPY, MODULE=DCOPYMS.INC... ;AN000; + ENDIF ;AN000; +; $SALUT (0,13,18,22) ; ;AN000; +;THIS MODULE IS INCLUDED IN DCOPYSM.SAL. +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + HEADER ;AN000; + +FOUR_SUBS EQU 4 ;AN000;FOUR VARIABLES IN ONE MSG +PC_ID_4 EQU 4 ;AN000;IDENTIFIES FOURTH REPLACEMENT PARM +LETTER_A EQU "A" ;AN000;DEFAULT DRIVE ID +PAD_0 EQU "0" ;AN001;PAD CHAR FOR NUMERIC FIXED LEN FIELD +FILL_OFF EQU 0 ;AN000;TO BE FILLED IN WITH OFFSET TO DATA +FILL_SEG EQU 0 ;AN000;TO BE FILLED IN WITH THE COMMON SEG ID + ; SINCE A .COM FILE CANNOT HAVE + ; SEGMENT FIXUP RECORDS + +; DOS FUNCTIONS REFERENCED: +CLEAR_BUF EQU 0C0H ;AN007;CLEAR KEYBOARD BUFFER BEFORE INPUT +KEY_IN EQU 08H ;AN000;WAIT FOR STD INPUT, NO ECHO + ;OUTPUT: AL = CHAR FROM KEYBOARD + ;CTL-BREAK IS CHECKED FOR + +KEY_IN_ECHO EQU 01H ;AN000;WAIT FOR STD INPUT, ECHO RESPONSE + ;OUTPUT: AL = CHAR FROM KEYBOARD + ;CTL-BREAK IS CHECKED FOR + +SUBLIST_PARSE SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_0,SF_BITS ,MAX_0,MIN_1,PAD_BLK> ;AN003; + PUBLIC SUBLIST_PARSE ;AN003; + +; THE NEXT GROUP ARE ADDITIONAL CLASS "A" MESSAGES +; SPECIFICALLY DEFINED FOR THE DISKCOPY UTILITY + + ;CR,LF +MSGNUM_CR_LF MSG_DESC <2> ;AN000; + PUBLIC MSGNUM_CR_LF ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Invalid parameter",CR,LF +MSGNUM_INVALID_PARM MSG_DESC <3> ;AN000; + PUBLIC MSGNUM_INVALID_PARM ;AN000; +; = = = = = = = = = = = = = = = = + ; "Do not specify filename(s)",CR,LF + ; "Command Format: DISKCOPY d: d: [/1]",CR,LF +MSGNUM_INVALID_PARM2 MSG_DESC <4> ;AN000; + PUBLIC MSGNUM_INVALID_PARM2 ;AN000; +; = = = = = = = = = = = = = = = = + ;:def 5 CR,LF,"Invalid drive specification",CR,LF + ;"Specified drive does not exist",CR,LF + ;"or is non-removable",CR,LF +MSGNUM_INVALID_DRV MSG_DESC <5> ;AN000; + PUBLIC MSGNUM_INVALID_DRV ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Cannot DISKCOPY to or from",CR,LF + ;"a network drive",CR,LF +MSGNUM_DRV_REDIRECTED MSG_DESC <6> ;AN000; + PUBLIC MSGNUM_DRV_REDIRECTED ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Formatting while copying",CR,LF +MSGNUM_FORMATTING MSG_DESC <7> ;AN000; + PUBLIC MSGNUM_FORMATTING ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF +MSGNUM_LOAD_SOURCE MSG_DESC <8,,SUBLIST_8,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_LOAD_SOURCE ;AN000; + +SUBLIST_8 SUBLIST <,,ASCII_DRV1_ID,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1> ;AN000; + PUBLIC SUBLIST_8 ;AN000; + +ASCII_DRV1_ID DB LETTER_A - BYTE;AN000; + PUBLIC ASCII_DRV1_ID ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Insert TARGET diskette in drive %1:",CR,LF +MSGNUM_LOAD_TARGET MSG_DESC <9,,SUBLIST_9,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_LOAD_TARGET ;AN000; + +SUBLIST_9 SUBLIST <,,ASCII_DRV2_ID,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1> ;AN000; + PUBLIC SUBLIST_9 ;AN000; + +ASCII_DRV2_ID DB LETTER_A - BYTE ;AN000;A:=1, B:=1, ETC + PUBLIC ASCII_DRV2_ID ;AN000; +; = = = = = = = = = = = = = = = = + ;:def 10 "Make sure a diskette is inserted into",CR,LF + ;"the drive and the door is closed",CR,LF +MSGNUM_CLOSE_DOOR MSG_DESC <10> ;AN004; + PUBLIC MSGNUM_CLOSE_DOOR ;AN004; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Target diskette may be unusable",CR,LF +MSGNUM_TARGET_MB_UNUSABLE MSG_DESC <11> ;AN000; + PUBLIC MSGNUM_TARGET_MB_UNUSABLE ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Target diskette unusable",CR,LF +MSGNUM_TARGET_UNUSABLE MSG_DESC <12> ;AN000; + PUBLIC MSGNUM_TARGET_UNUSABLE ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Drive not ready - %0",CR,LF +MSGNUM_GET_READY MSG_DESC <13,,SUBLIST_13,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_GET_READY ;AN000; + +SUBLIST_13 SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_0,SF_BITS,MAX_0,MIN_1> ;AN000; + PUBLIC SUBLIST_13 ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Attempt to write to write-protected diskette",CR,LF +MSGNUM_WRITE_PROTECT MSG_DESC <14> ;AN000; + PUBLIC MSGNUM_WRITE_PROTECT ;AN000; +; = = = = = = = = = = = = = = = = + ;"Press any key to continue . . .",CR,LF +MSGNUM_STRIKE MSG_DESC <15,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN)> ;AN007; + PUBLIC MSGNUM_STRIKE ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Copy another diskette (Y/N)? " + ; AND READ RESPONSE TO AL + ; (EVENTUALLY EXPECTED IN "USER_INPUT") +MSGNUM_COPY_ANOTHER MSG_DESC <16,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN_ECHO)> ;AN007; + PUBLIC MSGNUM_COPY_ANOTHER ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Copying %1 tracks",CR,LF + ;"%2 Sectors/Track, %3 Side(s)",CR,LF +MSGNUM_COPYING MSG_DESC <17,,SUBLIST_17A,THREE_SUBS> ;AN000; + PUBLIC MSGNUM_COPYING ;AN000; + +SUBLIST_17A SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1> ;AN000; +SUBLIST_17B SUBLIST <,,MSG_SECTRK,FILL_SEG,PC_ID_2,SF_BITS,MAX_0,MIN_1> ;AN000; +SUBLIST_17C SUBLIST <,,MSG_SIDES,FILL_SEG,PC_ID_3,SF_BITS,MAX_0,MIN_1> ;AN000; + PUBLIC SUBLIST_17A ;AN000; + PUBLIC SUBLIST_17B ;AN000; + PUBLIC SUBLIST_17C ;AN000; + +MSG_TRACKS DW 0 ;AN000;NUMBER OF TRACKS +MSG_SECTRK DW 0 ;AN000;NUMBER OF SECTORS PER TRACK +MSG_SIDES DW 0 ;AN000;NUMBER OF SIDES + PUBLIC MSG_TRACKS ;AN000; + PUBLIC MSG_SECTRK ;AN000; + PUBLIC MSG_SIDES ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Drive types or diskette types",CR,LF + ;"not compatible",CR,LF +MSGNUM_NOT_COMPATIBLE MSG_DESC <18> ;AN000; + PUBLIC MSGNUM_NOT_COMPATIBLE ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Unrecoverable read error on drive %1",CR,LF + ;"Side %2, track %3",CR,LF +MSGNUM_HARD_ERROR_READ MSG_DESC <19,,SUBLIST_19C,THREE_SUBS> ;AN000; + PUBLIC MSGNUM_HARD_ERROR_READ ;AN000; + + ;CR,LF,"Unrecoverable write error on drive %1",CR,LF + ;"Side %2, track %3",CR,LF +MSGNUM_HARD_ERROR_WRITE MSG_DESC <20,,SUBLIST_19C,THREE_SUBS> ;AN000; + PUBLIC MSGNUM_HARD_ERROR_WRITE ;AN000; + +SUBLIST_19C SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1> ;AN000; +SUBLIST_19D SUBLIST <,,ERROR_SIDE_NUMBER,FILL_SEG,PC_ID_2,SF_BITS,MAX_0,MIN_1> ;AN000; +SUBLIST_19E SUBLIST <,,ERROR_TRACK_NUMBER,FILL_SEG,PC_ID_3,SF_BITS,MAX_0,MIN_1> ;AN000; + PUBLIC SUBLIST_19C ;AN000; + PUBLIC SUBLIST_19D ;AN000; + PUBLIC SUBLIST_19E ;AN000; + +DRIVE_LETTER DB LETTER_A,":",NULL ;AN000; + PUBLIC DRIVE_LETTER ;AN000; + +ERROR_SIDE_NUMBER DW ? ;AN000; + PUBLIC ERROR_SIDE_NUMBER ;AN000; + +ERROR_TRACK_NUMBER DW ? ;AN000; + PUBLIC ERROR_TRACK_NUMBER ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Copy process ended",CR,LF +MSGNUM_FATAL_ERROR MSG_DESC <21> ;AN000; + PUBLIC MSGNUM_FATAL_ERROR ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"SOURCE diskette bad or incompatible" +MSGNUM_BAD_SOURCE MSG_DESC <22> ;AN000; + PUBLIC MSGNUM_BAD_SOURCE ;AN000; + +; = = = = = = = = = = = = = = = = + ;CR,LF,"TARGET diskette bad or incompatible" +MSGNUM_BAD_TARGET MSG_DESC <23> ;AN000; + PUBLIC MSGNUM_BAD_TARGET ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Insufficient memory",CR,LF +MSGNUM_UNSUF_MEMORY MSG_DESC <25> ;AN000; + PUBLIC MSGNUM_UNSUF_MEMORY ;AN000; +; = = = = = = = = = = = = = = = = + ;"Volume Serial Number is %1-%2" +MSGNUM_SERNO MSG_DESC <26,,SUBLIST_26A,TWO_SUBS> ;AN001; + PUBLIC MSGNUM_SERNO ;AN001; + +SUBLIST_26A SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS,DWORD,DWORD,PAD_0> ;AN001; +SUBLIST_26B SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_2,SF_BITS,DWORD,DWORD,PAD_0> ;AN001; + PUBLIC SUBLIST_26A,SUBLIST_26B ;AN001; +; = = = = = = = = = = = = = = = = +;end of DCOPYMS.INC + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM new file mode 100644 index 0000000..344b8c4 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DCOPYP.ASM @@ -0,0 +1,139 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOPYP.SAL - DISKCOPY SYSTEM COMMAND LINE PARSER +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOPYP.SAL +; +; DESCRIPTIVE NAME: Include the DOS system PARSER in the SEGMENT +; configuration expected by the modules of DISKCOPY. +; +;FUNCTION: The common code of the DOS command line PARSER is optimized by +; the setting of certain switches that cause the conditional +; assembly of only the required portions of the common PARSER. +; The segment registers are ASSUMED according to the type .COM. +; The Common PARSER is then INCLUDEd. +; +; ENTRY POINT: SYSPARSE, near +; +; INPUT: +; ES - has seg id of the SEGMENT +; that contains the input control blocks, +; defined below. +; +; DI - offset into ES of the PARMS INPUT BLOCK +; +; DS - has seg id of the SEGMENT +; that contains the DOS input COMMAND +; string, which is originally presented at 81h +; in the PSP. +; +; SI - offset into DS of the text of the DOS input COMMAND string +; as originally presented at 81H in the PSP. +; +; DX - zero +; +; CX - ordinal value, intially zero, updated on each subsequent call +; to the value returned in CX on the previous call. +; +; CS - points to the segment containing the +; INCLUDE PARSE.ASM statement +; +; DS - also points to the segment containing the INCLUDE +; PARSE.ASM statement. +; +; EXIT-NORMAL: Output registers: +; AX - return code: +; RC_No_Error equ 0 ; No error +; RC_EOL equ -1 ; End of command line +; +; DX - Offset into ES of the selected RESULT BLOCK. +; BL - terminated delimiter code +; CX - new operand ordinal +; SI - set past scanned operand +; +; EXIT-ERROR: Output registers: +; AX - return code: +; RC_Too_Many equ 1 ; Too many operands +; RC_Op_Missing equ 2 ; Required operand missing +; RC_Not_In_SW equ 3 ; Not in switch list provided +; RC_Not_In_Key equ 4 ; Not in keyword list provided +; RC_Out_Of_Range equ 6 ; Out of range specified +; RC_Not_In_Val equ 7 ; Not in value list provided +; RC_Not_In_Str equ 8 ; Not in string list provided +; RC_Syntax equ 9 ; Syntax error +; +; INTERNAL REFERENCES: +; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.ASM) +; +; DATA AREAS: none +; +; EXTERNAL REFERENCES: +; ROUTINES: none +; +; DATA AREAS: control blocks pointed to by input registers. +; +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: +; +; SALUT DCOPYP,NUL,; +; +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. +; +; For LINK instructions, refer to the PROLOG of the main module, +; DISKCOPY.SAL. +; +;PROGRAM AUTHOR: DOS 4.00 EMK +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOPY, MODULE=DCOPYP.SAL... ;AN000; + ENDIF ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +; = = = = = = = = = = = = + INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; +.XLIST ;AN000; + SUBTTL TEXT ;AN000; +.LIST ;AN000; + PAGE ;;AN000; + ENDM ;;AN000; + +; = = = = = = = = = = = = + HEADER ;AN000; +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000; + +;DISKCOPY INPUT PARMS EXPECTED: +; [D: [d:]] [/1] + + PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT + +FARSW EQU 0 ;AN000;CALL THE PARSER BY NEAR CALL +DATESW EQU 0 ;AN000;SUPPRESS DATE CHECKING +TIMESW EQU 0 ;AN000;SUPPRESS TIME CHECKING +FILESW EQU 0 ;AN000;SUPPRESS CHECK FILE SPECIFICATION +CAPSW EQU 1 ;AN000;DO USE FILE TABLE CAPS +CMPXSW EQU 0 ;AN000;SUPPRESS CHECKING COMPLEX LIST +DRVSW EQU 1 ;AN000;DO SUPPORT DRIVE ONLY FORMAT +QUSSW EQU 0 ;AN000;SUPPRESS SUPPORT OF QUOTED STRING FORMAT +NUMSW EQU 0 ;AN000;SUPPRESS CHECKING NUMERIC VALUE +KEYSW EQU 0 ;AN000;SUPPRESS KEYWORD SUPPORT +SWSW EQU 1 ;AN000;DO SUPPORT SWITCHES +VAL1SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 1 +VAL2SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 2 +VAL3SW EQU 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 3 +INCSW EQU 0 ;AN000;DO NOT INCLUDE PSDATA.INC +BASESW EQU 1 ;AN014;SPECIFY, PSDATA POINTED TO BY "DS" + + INCLUDE PSDATA.INC ;AN015; + + PATHLABL DCOPYP ;AN015; + INCLUDE PARSE.ASM ;AN000; + PATHLABL DCOPYP ;AN015; + +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM new file mode 100644 index 0000000..0b74cec --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DCOPYPAR.ASM @@ -0,0 +1,413 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOPYPAR.SAL - LOOK AT COMMAND LINE PARMS +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOPYPAR.SAL +; +; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters +; and the interface to the DOS system PARSER. +; +;FUNCTION: The static data areas are prescribed by the DOS system PARSER +; to define the several parameters presented to DISKCOPY. These +; data areas are passed to the PARSER, and its responses checked +; to determine the nature of the user's specifications. Any errors +; found in the user's parameters are defined in messages back +; to the user. +; +; ENTRY POINT: PARSER, near +; +; INPUT: (DOS COMMAND LINE PARAMETERS) +; +; [d:][path] DISKCOPY [d: [d:]][/1] +; +; WHERE +; [d:][path] - Path where the DISKCOPY command resides. +; +; [d:] - To specify the Source drive +; +; [d:] - To specify the Destination drive +; +; [/1] - To copy only the first side of the diskette, +; regardless of the diskette or drive type. +; +; Upon entry to PARSER in this module, +; "CURRENT_PARM" = offset to start of parm text in command string +; "ORDINAL" = initialized to zero +; PSP+81H = text of DOS command line parms string + +; EXIT-NORMAL: +; "SOURCE_DRIVE" = CHAR OF FIRST DRIVE ID SPECIFIED, BLANK IF NONE +; "TARGET_DRIVE" = CHAR OF SECOND DRIVE ID IF BOTH SPECIFIED, BLANK +; IF NONE OR ONLY ONE SPECIFIED +; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED. + +; EXIT-ERROR: +; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR". + +; INTERNAL REFERENCES: +; ROUTINES: +; PARSER:NEAR Call the system Parser to decode command line +; PARSE_ERROR:NEAR Display the appropriate Parse error message. + +; DATA AREAS: +; The several parameter control blocks, defined by the System +; PARSER interface, defining the DISKCOPY parameters. + +; EXTERNAL REFERENCES: +; ROUTINES: +; SENDMSG:NEAR Uses Msg Descriptor to drive message handler. +; SYSPARSE:NEAR System Command Line Common Parser. +; +; DATA AREAS: +; EXITFL:BYTE Errorlevel return code. +; MSGNUM_PARSE:WORD Message descriptor for all parse errors. +; USER_OPTION:BYTE /1 parm indicator +; SOURCE_DRIVE:BYTE character of first specified drive +; TARGET_DRIVE:BYTE character of second specified drive +; +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: +; +; SALUT DCOPYPAR,NUL +; +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. +; +; For LINK instructions, refer to the PROLOG of the main module, +; DISKCOPY.SAL. +; +;PROGRAM AUTHOR: DOS 4.00 EMK +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOPY, MODULE=DCOPYPAR.SAL... ;AN000; + ENDIF ;AN000; +; = = = = = = = = = = = = + INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; +.XLIST ;;AN000; + SUBTTL TEXT ;;AN000; +.LIST ;;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = +; $SALUT (4,23,28,36) ;AN000; +; LOCAL EQUATES + +FALSE EQU 0 ;AN000;RETURN VALUES FOR +TRUE EQU NOT FALSE ;AN000; /1 SWITCH +CHAR_A EQU "A" ;AN000;ASCII VALUE OF CHARACTER "A" +BLANK EQU " " ;AN001; +NUL EQU 0 ;AN003; +; = = = = = = = = = = = = +; EXIT CODES FROM SYSPARSE (WHEN CY=0) + +SYSPRM_EX_OK EQU 0 ;AN000; no error +SYSPRM_EX_MANY EQU 1 ;AN000; too many operands +SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing +SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided +SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided +SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified +SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided +SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided +SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error +SYSPRM_EX_EOL EQU -1 ;AN000; end of command line +; = = = = = = = = = = = = + HEADER ;AN000; +PSP STRUC ;AN000; + DB 80H DUP (?) ;AN000;SKIP OVER FIRST HALF OF PSP +PSP_PARMLEN DB ? ;AN000;NUMBER OF BYTES IN DOS COMMAND LINE +PSP_COMMAND DB 127 DUP(?) ;AN000;TEXT OF DOS COMMAND LINE +PSP ENDS ;AN000; + +MSG_DESC STRUC ;AN003; +MSG_NUM DW ? ;AN003;MESSAGE NUMBER (TO AX) +MSG_HANDLE DW ? ;AN003;HANDLE OF OUTPUT DEVICE (TO BX) +MSG_SUBLIST DW ? ;AN003;POINTER TO SUBLIST (TO SI) +MSG_COUNT DW ? ;AN003;SUBSTITUTION COUNT (TO CX) +MSG_CLASS DW ? ;AN003;MESSAGE CLASS (IN HIGH BYTE, TO DH) + ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) +MSG_DESC ENDS ;AN003; + +ONE_SUBS EQU 1 ;AN003;NUMBER OF VARIABLES + +SUBLIST STRUC ;AN000; +SUB_SIZE DB ? ;AN003;SUBLIST SIZE (POINTER TO NEXT SUBLIST) +SUB_RES DB ? ;AN003;RESERVED + ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD +SUB_VALUE DW ? ;AN003;TIME, DATE, OR PTR TO DATA ITEM +SUB_VALUE_SEG DW ? ;AN003;SEG ID OF PTR + ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME + ; IF THIS IS A .COM FILE) +SUB_ID DB ? ;AN003;N OF %N +SUB_FLAGS DB ? ;AN003;DATA TYPE FLAGS +SUB_MAX_WIDTH DB ? ;AN003;MAXIMUM FIELD WIDTH (0=UNLIMITED) +SUB_MIN_WIDTH DB ? ;AN003;MINIMUM FIELD WIDTH +SUB_PAD_CHAR DB ? ;AN003;CHARACTER FOR PAD FIELD + ; CAN BE " ", "0" OR ",". + ; "," CAUSES INSERTION OF THE ACTIVE + ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. +SUBLIST ENDS ;AN003; + +; = = = = = = = = = = = = + HEADER ;AN000; +; $SALUT (4,14,19,36) ;AN000; + EXTRN EXPAR:ABS ;AN000;ERRORLEVEL VALUE FOR BAD PARMS + EXTRN FINE:ABS ;AN000;RETURN STATUS INDICATOR +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000; + + EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR + EXTRN SYSPARSE:NEAR ;AN000;SYSTEM COMMAND LINE PARSER + + EXTRN EXITFL:BYTE ;AN000;ERRORLEVEL RETURN CODE + + EXTRN SOURCE_DRIVE:BYTE ;AN000;FIRST DRIVE LETTER SPECIFIED IN PARMS + EXTRN TARGET_DRIVE:BYTE ;AN000;SECOND DRIVE LETTER SPECIFIED + + EXTRN USER_OPTION:BYTE ;AN000;NO OPTION (-1) /1 (1), INVALID (9) +NO_OPTION EQU -1 ;AN000;NO OPTION "/1" SPECIFIED +OPTION_1 EQU 1 ;AN000;OPTION "/1" SPECIFIED + EXTRN MSGNUM_PARSE:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS + EXTRN MSGNUM_INVALID_PARM2:WORD ;AN005;HELP INFO + EXTRN SUBLIST_PARSE:WORD ;AN003;POINTS TO INVALID PARM +; = = = = = = = = = = = = + +CURRENT_PARM DW 81H ;AN000;POINTER INTO COMMAND OF NEXT OPERAND + PUBLIC CURRENT_PARM ;AN000; + +ORDINAL DW 0 ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE + PUBLIC ORDINAL ;AN000; + +; = = = = = = = = = = = = + HEADER ;AN000; + +;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER + + PUBLIC PARMS ;AN000;LET LINK MAKE PARMS BLOCK ADDRESSABLE +PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK + DW PARMSX ;AN000;POINTER TO PARMS EXTENSION + DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2) + ; NEXT LIST WOULD BE EXTRA DELIM LIST + ; (,& WHITESPACE ALWAYS) + ; NEXT LIST WOULD BE EXTRA END OF LINE LIST + ; (CR,LF,0 ALWAYS) + +;SYSTEM PARSER PARAMETER EXTENSION CONTROL BLOCK +PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK + DB 0,2 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED + DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1 + DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 2 + + DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED + DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH 1 + + DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED + ; THERE IS NO CONTROL BLOCK + ; DEFINING KEYWORDS + +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + HEADER ;AN000; +;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL + +;FIRST POSITIONAL PARAMETER IS: +; [D:] - SPECIFY THE SOURCE DRIVE. + + PUBLIC CONTROL_POS ;AN000;LET LINK MAKE THIS ADDRESSABLE +CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC, + ; OPTIONAL + DW 0101H ;AN000; CONTROLS TYPE MATCHED + ; SELECTED BITS: "DRIVE ONLY" AND "OPTIONAL" + + ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) + ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE + ; CHECKED) + ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) + ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) + ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) + ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) + ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) + ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) + ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) + ; 0010H=IGNORE ":" AT END IN MATCH + ; 0002H=REPEATS ALLOWED + ; 0001H=OPTIONAL + + DW 0002H ;AN000;FUNCTION_FLAGS + ; 0001H=CAP RESULT BY FILE TABLE + ; 0002H=CAP RESULT BY CHAR TABLE + ; 0010H=REMOVE ":" AT END + DW RESULT1 ;AN000; RESULT BUFFER + DW NOVALS ;AN000; NO VALUE LISTS + DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS + ; IN FOLLOWING LIST + +;VALUE CONTROL BLOCK FOR THE POSITIONAL PARAMETERS +NOVALS DB 0 ;AN000;NO VALUE DEFINITIONS + +;RESULTS CONTROL BLOCK FOR THE POSITIONAL PARAMETER +RESULT1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS + DB 6 ;AN000; TYPE RETURNED: 0=RESERVED, + ; 1=NUMBER, 2=LIST INDEX, + ; 3=STRING, 4=COMPLEX, + ; 5=FILESPEC, 6=DRIVE + ; 7=DATE, 8=TIME + ; 9=QUOTED STRING +RESULT_TAG DB 0FFH ;AN000; MATCHED ITEM TAG + DW 0 ;AN000;POINTER TO SYNONYM + +RESULT_PTR1 DB ? ;AN000;DRIVE NUMBER (A=1, B=2, ETC) + +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + HEADER ;AN000; +;PARSER CONTROL BLOCK DEFINING THE ONLY SWITCH, OPTIONAL + +;THE SWITCH IS "/1", MEANING ONLY COPY FIRST SIDE. + + PUBLIC CONTROL_SW ;AN000;LET LINK MAKE THIS ADDRESSABLE +CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /1 + DW 0001H ;AN000; CONTROLS TYPE MATCHED + ;SELECTED BITS: "OPTIONAL" + ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) + ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE + ; CHECKED) + ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) + ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) + ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) + ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) + ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) + ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) + ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) + ; 0010H=IGNORE ":" AT END IN MATCH + ; 0002H=REPEATS ALLOWED + ; 0001H=OPTIONAL + + DW 0002H ;AN000;FUNCTION_FLAGS + ; 0001H=CAP RESULT BY FILE TABLE + ; 0002H=CAP RESULT BY CHAR TABLE + ; 0010H=REMOVE ":" AT END + + DW RESULTSW1 ;AN000; RESULT BUFFER + DW NOVALS ;AN000; VALUE LISTS + DB 1 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS + ; IN FOLLOWING LIST +SW_1 DB "/1",0 ;AN000; IF n >0, SWITCH 1 + +;RESULTS CONTROL BLOCK FOR THE SWITCHES +RESULTSW1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS + DB 3 ;AN000; TYPE RETURNED: 0=RESERVED, + ; 1=NUMBER, 2=LIST INDEX, + ; 3=STRING, 4=COMPLEX, + ; 5=FILESPEC, 6=DRIVE + ; 7=DATE, 8=TIME + ; 9=QUOTED STRING + DB 0FFh ;AN000; MATCHED ITEM TAG + + DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:) +RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE +; = = = = = = = = = = = = + PATHLABL DCOPYPAR ;AN015; + HEADER ;AN000; +; $SALUT (4,4,9,36) ;AN000; +PARSER PROC NEAR ;AN000; + PUBLIC PARSER ;AN000; + +;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING +; "ORDINAL" = COUNT OF NEXT PARM TO PARSE +; PSP+81H = TEXT OF DOS COMMAND LINE PARMS STRING +;OUTPUT: "SOURCE_DRIVE" = VALUE OF FIRST DRIVE ID SPECIFIED, 0 IF NONE +; "TARGET_DRIVE" = VALUE OF SECOND DRIVE ID IF BOTH SPECIFIED, 0 +; IF NONE OR ONLY ONE SPECIFIED +; "USER_OPTION" = "OPTION_1" IF /1 SPECIFIED, -1 IF NOT SPECIFIED +; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR". +; DX="FINE" IF NO ERROR, OR HAS OFFSET OF PARSE ERROR DESCRIPTOR IF PROBLEM +; = = = = = = = = = = = = + + MOV USER_OPTION, NO_OPTION ;AN000;ASSUME NO /1 IS ENTERED. +; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE + JMP SHORT $$SS1 +$$DO1: + ;LOOKING AT RETURN CODE FROM SYSPARSE... + CMP AX,SYSPRM_EX_OK ;AN000;WERE THERE ANY ERRORS? +; $EXITIF NE ;AN000;HAD A PROBLEM + JE $$IF1 + CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR + +; $ORELSE ;AN000;SINCE NO PROBLEM, SO FAR + JMP SHORT $$SR1 +$$IF1: + MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT + MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT + MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND + CMP BX,OFFSET RESULT1 ;AN000;WAS POSITIONAL PARM SPECIFIED? +; $IF E ;AN000;IF POSITIONAL PARM SPECIFIED, + JNE $$IF4 + MOV SI,CX ;AN000;USE COUNT OF POSITIONALS AS INDEX + MOV AL,RESULT_PTR1 ;AN000;GET VALUE OF DRIVE (A=1, B=2, ETC) + MOV SOURCE_DRIVE-1[SI],AL ;AN000;SAVE RESPONSE VALUE + ;IN EITHER SOURCE_DRIVE OR TARGET_DRIVE + ;ACCORDING TO ORDINAL IN SI (FROM CX) +; $ELSE ;AN000;SINCE NOT POSITIONAL PARM SPECIFIED + JMP SHORT $$EN4 +$$IF4: + MOV SW_1,BLANK ;AN001;AVOID GETTING DUPLICATE SWITCH + MOV USER_OPTION,OPTION_1 ;AN000;MUST HAVE BEEN THE SWITCH, /1 +; $ENDIF ;AN000; +$$EN4: +; $STRTSRCH ;AN000; +$$SS1: + LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON + MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM + XOR DX,DX ;AN000; RESERVED, INIT TO ZERO + MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO + CALL SYSPARSE ;AN000;LOOK AT DOS PARMS + ; AX=EXIT CODE + ; BL=TERMINATED DELIMETER CODE + ; CX=NEW OPERAND ORDINAL + ; SI=SET TO PAST SCANNED OPERAND + ; DX=SELECTED RESULT BUFFER + CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS? + ;IF NOT, LOOP BACK AND FIND OUT + ; WHAT THAT PARM IS +; $ENDLOOP E ;AN000;END OF LIST + JNE $$DO1 + MOV DX,FINE ;AN000;REPORT THAT PARSER WENT OK +; $ENDSRCH ;AN000;FINISHED WITH DOS COMMAND LINE +$$SR1: + RET ;AN000;RETURN TO CALLER +PARSER ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +PARSE_ERROR PROC NEAR ;AN000; +;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE. +; "CURRENT_PARM" - OFFSET TO WHERE THE BAD PARM STARTED +;OUTPUT: APPROPRIATE ERROR MESSAGE IS PREPARED FOR DISPLAY. +; DX IS SET TO OFFSET OF PARSE ERROR DESCRIPTOR. +; = = = = = = = = = = = = + + MOV MSGNUM_PARSE,AX ;AN000;PASS MESSAGE NUMBER TO DESCRIPTOR + MOV EXITFL,EXPAR ;AN000;ERRORLEVEL CODE TO "PARM ERROR" + MOV AX,CURRENT_PARM ;AN003;GET POINTER TO START OF BAD PARM + CMP SI,AX ;AN003;HAS THE INDEX TO COMMAND LINE MOVED? +; $IF NE ;AN003;YES, THERE IS A FAULTY PARM + JE $$IF10 + MOV BYTE PTR [SI],NUL ;AN003;DELIMIT THE BAD PARM + MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM + + MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN003;POINT TO SUBLIST + MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN003;SET COUNT OF SUBLISTS TO ONE +; $ENDIF ;AN003;INDEX MOVED? +$$IF10: + MOV DI,OFFSET MSGNUM_PARSE ;AC005;PASS BACK OFFSET TO PARSE ERR DESCRIPTOR + CALL SENDMSG ;AN005;DISPLAY THE ERROR MESSAGE + + ; "Do not specify filename(s)",CR,LF + ; "Command Format: DISKCOPY d: d: [/1]",CR,LF + MOV DX,OFFSET MSGNUM_INVALID_PARM2 ;AN005;DISPLAY HELP INFO + RET ;AN000;RETURN TO CALLER +PARSE_ERROR ENDP ;AN000; +; = = = = = = = = = = = = + PATHLABL DCOPYPAR ;AN015; +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM b/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM new file mode 100644 index 0000000..035fa73 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DCOPYSM.ASM @@ -0,0 +1,153 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOPYSM.SAL - DISKCOPY SYSTEM MESSAGES +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOPYSM.SAL + +; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT +; configuration expected by the modules of DISKCOPY. + +;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a +; part of the DISKCOPY module by using INCLUDE to bring in the +; common portion, in SYSMSG.INC. This included code contains +; the routines to initialize for message services, to find +; where a particular message is, and to display a message. + +; ENTRY POINT: SYSDISPMSG:near +; SYSGETMSG:near +; SYSLOADMSG:near + +; INPUT: +; AX = MESSAGE NUMBER +; BX = HANDLE TO DISPLAY TO (-1 means use DOS functions 1-12) +; SI = OFFSET IN ES: OF SUBLIST, OR 0 IF NONE +; CX = NUMBER OF %PARMS, 0 IF NONE +; DX = CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW +; CALL SYSDISPMSG ;DISPLAY THE MESSAGE + +; If carry set, extended error already called: +; AX = EXTENDED MESSAGE NUMBER +; BH = ERROR CLASS +; BL = SUGGESTED ACTION +; CH = LOCUS +; _ _ _ _ _ _ _ _ _ _ _ _ + +; AX = MESSAGE NUMBER +; DH = MESSAGE CLASS (1=DOS EXTENDED ERROR, 2=PARSE ERROR, -1=UTILITY MSG) +; CALL SYSGETMSG ;FIND WHERE A MSG IS + +; If carry set, error +; CX = 0, MESSAGE NOT FOUND +; If carry not set, ok, and resulting regs are: +; CX = MESSAGE SIZE +; DS:SI = MESSAGE TEXT +; _ _ _ _ _ _ _ _ _ _ _ _ + +; CALL SYSLOADMSG ;SET ADDRESSABILITY TO MSGS, CHECK DOS VERSION +; If carry not set: +; CX = SIZE OF MSGS LOADED + +; If carry is set, regs preset up for SYSDISPMSG, as: +; AX = ERROR CODE IF CARRY SET +; AX = 1, INCORRECT DOS VERSION +; DH =-1, (Utility msg) +; OR, +; AX = 1, Error loading messages +; DH = 0, (Message manager error) +; BX = STDERR +; CX = NO_REPLACE +; DL = NO_INPUT + +; EXIT-NORMAL: CARRY is not set + +; EXIT-ERROR: CARRY is set +; Call Get Extended Error for reason code, for SYSDISPMSG and +; SYSGETMSG. + +; INTERNAL REFERENCES: +; ROUTINES: (Generated by the MSG_SERVICES macro) +; SYSLOADMSG +; SYSDISPMSG +; SYSGETMSG + +; DATA AREAS: +; INCLUDED "DCOPYMS.INC" - message defining control blocks +; INCLUDE SYSMSG.INC ;Permit System Message handler definition + +; EXTERNAL REFERENCES: +; ROUTINES: none + +; DATA AREAS: control blocks pointed to by input registers. + +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: + +; SALUT DCOPYSM,NUL + +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. + +; For LINK instructions, refer to the PROLOG of the main module, +; DISKCOPY.SAL. + +; COPYRIGHT: "Version 4.00 (C)Copyright 1988 Microsoft" +; "Licensed Material - Property of Microsoft " +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOPY, MODULE=DCOPYSM.SAL... ;AN000; + ENDIF ;AN000; +; = = = = = = = = = = = = + INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; +.XLIST ;;AN000; + SUBTTL TEXT ;;AN000; +.LIST ;;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = + INCLUDE SYSMSG.INC ;AN000;PERMIT SYSTEM MESSAGE HANDLER DEFINITION + MSG_UTILNAME ;AN000;IDENTIFY THE COMPONENT +; = = = = = = = = = = = = + HEADER ;AN000; +; $SALUT (4,12,18,36) ;AN000; +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER + +;(deleted ;AN010;) PUBLIC COPYRIGHT ; +;(deleted ;AN010;) COPYRIGHT DB "MS DOS DISKCOPY Utility " +;(deleted ;AN010;) INCLUDE COPYRIGH.INC ;(this is now being done my MSG_SERVICES) + HEADER ;AN000; + INCLUDE MSGHAN.INC ;AN000;DEFINE THE MESSAGE HANDLER CONTROL BLOCKS + INCLUDE DCOPYMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS + HEADER ;AN000; + MSG_SERVICES ;AN000;WORKAREAS FOR SYSTEM MESSAGE HANDLER +; = = = = = = = = = = = = + HEADER ;AN000; + PUBLIC SYSLOADMSG ;AN000; + PUBLIC SYSDISPMSG ;AN000; + + MSG_SERVICES ;AN000;MSG TEXT + + PATHLABL DCOPYSM ;AN015; + ;DEFAULT=CHECK DOS VERSION + ;DEFAULT=NEARmsg + ;DEFAULT=INPUTmsg + ;DEFAULT=NUMmsg + ;DEFAULT=NO TIMEmsg + ;DEFAULT=NO DATEmsg +; MSG_SERVICES +.xlist ;AN000; +.xcref ;AN000; + MSG_SERVICES ;AN000; +.cref ;AN000; +.list ;AN000; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + PATHLABL DCOPYSM ;AN015; +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC b/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC new file mode 100644 index 0000000..da247a5 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DCPYMACR.INC @@ -0,0 +1,164 @@ + IF1 ;AN000; + %OUT COMPONENT=DISKCOPY, INCLUDING DCPYMACR.INC...;AN000; + ENDIF ;AN000; +;***************************************************************************; +; MACRO DEFINITION ; +;***************************************************************************; + +HEADER MACRO TEXT ;AN000; +.XLIST ;AN000; + SUBTTL &TEXT ;AN000; +.LIST ;AN000; + PAGE ;AN000; + ENDM ;AN000; +; = = = = = = = = = +; $SALUT (0,36,40,44) +DOSCALL MACRO FUNC,SUBFUNC ;;AN000; + IFNB ;;AN000;IS THERE ANY PARMS AT ALL? + IFNB ;;AN000; + MOV AX,(FUNC SHL 8)+SUBFUNC ;;AN000;FUNC TO AH,SUBFUNC TO AL + ELSE ;;AN000;SINCE THERE IS NO SUBFUNC + MOV AH,FUNC ;;AN000; + ENDIF ;;AN000; + ENDIF ;;AN000; + INT 21H ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = +PRINT MACRO MESSAGE;;AN000; + MOV DI,OFFSET MESSAGE ;;AC000; + CALL SENDMSG ;;AC000; + ENDM ;;AN000; +; = = = = = = = = = +; $SALUT (0,16,22,36) +MY_TRACKLAYOUT MACRO ;AN000; + LOCAL CSECT_F ;AN000; +CSECT_F DW 0 ;;AN000;# OF SECTORS IN A TRACK. Currently 18 is max. + ;; THE REST IS FOR FUTURE MEDIA + DW 1 ;;AN000;1 ST SECTOR + DW 512 ;;AN000;# OF BYTES + DW 2 ;;AN000; + DW 512 ;;AN000; + DW 3 ;;AN000; + DW 512 ;;AN000; + DW 4 ;;AN000; + DW 512 ;;AN000; + DW 5 ;;AN000; + DW 512 ;;AN000; + DW 6 ;;AN000; + DW 512 ;;AN000; + DW 7 ;;AN000; + DW 512 ;;AN000; + DW 8 ;;AN000; + DW 512 ;;AN000; + DW 9 ;;AN000; + DW 512 ;;AN000; + DW 10 ;;AN000; + DW 512 ;;AN000; + DW 11 ;;AN000; + DW 512 ;;AN000; + DW 12 ;;AN000; + DW 512 ;;AN000; + DW 13 ;;AN000; + DW 512 ;;AN000; + DW 14 ;;AN000; + DW 512 ;;AN000; + DW 15 ;;AN000; + DW 512 ;;AN000; + DW 16 ;;AN000; + DW 512 ;;AN000; + DW 17 ;;AN000; + DW 512 ;;AN000; + DW 18 ;;AN000; + DW 512 ;;AN000;CURRENTLY 18 SECTORS/TRACK IS MAXIMUM + DW 19 ;;AN000;BELOW IS FOR THE FUTURE MEDIA. + DW 512 ;;AN000; + DW 20 ;;AN000; + DW 512 ;;AN000; + DW 21 ;;AN000; + DW 512 ;;AN000; + DW 22 ;;AN000; + DW 512 ;;AN000; + DW 23 ;;AN000; + DW 512 ;;AN000; + DW 24 ;;AN000; + DW 512 ;;AN000; + DW 25 ;;AN000; + DW 512 ;;AN000; + DW 26 ;;AN000; + DW 512 ;;AN000; + DW 27 ;;AN000; + DW 512 ;;AN000; + DW 28 ;;AN000; + DW 512 ;;AN000; + DW 29 ;;AN000; + DW 512 ;;AN000; + DW 30 ;;AN000; + DW 512 ;;AN000; + DW 31 ;;AN000; + DW 512 ;;AN000; + DW 32 ;;AN000; + DW 512 ;;AN000; + DW 33 ;;AN000; + DW 512 ;;AN000; + DW 34 ;;AN000; + DW 512 ;;AN000; + DW 35 ;;AN000; + DW 512 ;;AN000; + DW 36 ;;AN000; + DW 512 ;;AN000; + DW 37 ;;AN000; + DW 512 ;;AN000; + DW 38 ;;AN000; + DW 512 ;;AN000; + DW 39 ;;AN000; + DW 512 ;;AN000; + DW 40 ;;AN000; + DW 512 ;;AN000; + DW 41 ;;AN000; + DW 512 ;;AN000; + DW 42 ;;AN000; + DW 512 ;;AN000; + DW 43 ;;AN000; + DW 512 ;;AN000; + DW 44 ;;AN000; + DW 512 ;;AN000; + DW 45 ;;AN000; + DW 512 ;;AN000; + DW 46 ;;AN000; + DW 512 ;;AN000; + DW 47 ;;AN000; + DW 512 ;;AN000; + DW 48 ;;AN000; + DW 512 ;;AN000; + DW 49 ;;AN000; + DW 512 ;;AN000; + DW 50 ;;AN000; + DW 512 ;;AN000; + DW 51 ;;AN000; + DW 512 ;;AN000; + DW 52 ;;AN000; + DW 512 ;;AN000; + DW 53 ;;AN000; + DW 512 ;;AN000; + DW 54 ;;AN000; + DW 512 ;;AN000; + DW 55 ;;AN000; + DW 512 ;;AN000; + DW 56 ;;AN000; + DW 512 ;;AN000; + DW 57 ;;AN000; + DW 512 ;;AN000; + DW 58 ;;AN000; + DW 512 ;;AN000; + DW 59 ;;AN000; + DW 512 ;;AN000; + DW 60 ;;AN000; + DW 512 ;;AN000; + DW 61 ;;AN000; + DW 512 ;;AN000; + DW 62 ;;AN000; + DW 512 ;;AN000; + DW 63 ;;AN000; + DW 512 ;;AN000; + ENDM ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM new file mode 100644 index 0000000..e278c9e --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM @@ -0,0 +1,2452 @@ + 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 +; 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 ***************************** + IF1 ; + %OUT COMPONENT=DISKCOPY, MODULE=DISKCOPY.SAL ; + ENDIF ; + +;***************************************************************************** +; * +; 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 * +; * +;***************************************************************************** + + + +;***************************************************************************** +; * +; MACRO DEFINITION * +; * +;***************************************************************************** + + INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO + INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF) + INCLUDE DISKCOPY.EQU ;EQUATES + +; $salut (4,16,22,36) ;AN000; +MY_BPB STRUC ; +CBYTE_SECT DW 0 ; 200H BYTES / SECTOR +CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER +CRESEV_SECT DW 0 ; 1h RESERVED SECTORS +CFAT DB 0 ; 2h # OF FATS +CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES +CTOTSECT DW 0 ; 02D0h TOTAL # OF SECTORS INCLUDING + ; BOOT SECT, DIRECTORIES ... +MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR +CSECT_FAT DW 0 ; 2h SECTORS / FAT +CSECT_TRACK DW 0 ; +CHEAD DW 0 ; +CHIDDEN_SECT DD 0 ; +BIG_TOT_SECT DD 0 ; + DB 6 DUP (0) ; +MY_BPB ENDS ; + + INCLUDE BOOTFORM.INC ;AN013;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER + +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 +.XLIST ; +;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE +;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE +;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE +;EXTRN MSG_SOURCE_BAD_PTR :BYTE +;EXTRN YES :BYTE +;EXTRN NO :BYTE +.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) + + 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 + +;***************************************************************************** + ORG 100H ;PROGRAM ENTRY POINT + +DISKCOPY: ; + JMP BEGIN ; +;***************************************************************************** + +;INTERNAL STACK AREA + EVEN ;AN000;MAKE STACK WORD ALIGNED + DB 64 DUP ('STACK ') ;512 BYTES +MY_STACK_PTR LABEL WORD ; + +;***************************************************************************** +; * +; INTERNAL VARIABLES * +; * +;***************************************************************************** +; $salut (4,22,26,36) ;AN000; +; INPUT PARMETERS FROM INIT SUBROUTINE: + +S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED SOUCE DRIVE OWNERSHIP +T_OWNER_SAVED DB 0 ; + +RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA +SOURCE_DRIVE DB 0 ;SOURCE DRIVE ID: 1=DRV A, 2=DRV B ETC. +TARGET_DRIVE DB 0 ;TARGET DRIVE ID +USER_OPTION DB 0 ;=1 OF /1 OPTION IS ENTERED +COPY_TYPE DB 1 ;SINGLE DRV COPY=1, DOUBLE DRIVE COPY=2 +BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT] +BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT] +S_DRV_SECT_TRACK DB ? ;SECT/TRACK, device informations. +S_DRV_HEADS DB ? ;# OF HEADS +S_DRV_TRACKS DB ? ;# OF TRACKS +T_DRV_SECT_TRACK DB ? ; +T_DRV_HEADS DB ? ; +T_DRV_TRACKS DB ? ; + +;DEFAULT BPB FOR OLD MEDIA +;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK) +BPB48_SINGLE DW 512 ;BYTES/SECTOR + DB 1 ;SECTOR/CLUSTER + DW 1 ;# OF RESERVED SECTORS + DB 2 ;# OF FATS + DW 40h ;# OF ROOT ENTRY + DW 168h ;TOTAL # OF SECTORS IN THE MEDIA + DB 0FCh ;MEDIA BYTE + DW 2 ;SECTORS/FAT + +;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK) +BPB48_DOUBLE DW 512 ;BYTES/SECTOR + DB 2 ;SECTOR/CLUSTER + DW 1 ;# OF RESERVED SECTORS + DB 2 ;# OF FATS + DW 70h ;# OF ROOT ENTRY + DW 2D0h ;TOTAL # OF SECTORS IN THE MEDIA + DB 0FDh ;MEDIA BYTE + DW 2 ;SECTORS/FAT + +;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK) +BPB96 DW 512 ;BYTES/SECTOR + DB 1 ;SECTOR/CLUSTER + DW 1 ;# OF RESERVED SECTORS + DB 2 ;# OF FATS + DW 0E0h ;# OF ROOT ENTRY + DW 960h ;TOTAL # OF SECTORS IN THE MEDIA + DB 0F9h ;MEDIA BYTE + DW 7 ;SECTORS/FAT +BPB96_LENG EQU $-BPB96 ;THIS LENGTH WILL BE USED FOR BPB48 ALSO. + +; LOCAL VARIABLES: +VOLSER_FLAG DB 0 ;AN000;0=EITHER MEDIA NOT READ YET, OR +; SOURCE VOL SER ID NOT AVAILABLE +; 1=TARGET NEEDS VOL SER WRITTEN +SERIAL DD 0 ;AN013;SERIAL NUMBER OF NEW DISKETTE +EXITFL DB EXOK ;AN000;ERRORLEVEL VALUE + PUBLIC EXITFL ;AN000; + PUBLIC EXPAR ;AN000; +EXCBR EQU 2 ;AN000;CONTROL BREAK +EXVER EQU 1 ;AN000;BAD DOS VERSION ERRORLEVEL CODE +EXPAR EQU 1 ;AN000; BAD PARMS, OR OTHER ERRORS +EXOK EQU 0 ;AN000;NORMAL ERRORLEVEL RET CODE + +S_DRV_SET_FLAG DB 0 ;1 = SOURCE DRIVE PARM HAD BEEN SET +T_DRV_SET_FLAG DB 0 ;1 = TARGET DRIVE PARM HAD BEEN SET + +IOCTL_SECTOR DW 1 ;used for READ_A_SECTOR routine. +IOCTL_TRACK DW 0 ;IN THE TRACK +IOCTL_HEAD DW 0 ;HEAD 0 +SAV_CSECT DW 0 ;TEMPORARY SAVING PLACE +SAV_CN1 DW 0 ; +SAV_CB1 DW 0 ; +SAV_CYLN DW 0 ; + +BOOT_SECT_TRACK DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK +BOOT_TOT_TRACK DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks +BOOT_NUM_HEAD DW 0 ;NUMBER OF HEADS +BOOT_BYTE_SECTOR DW 0 ;BYTES / SECTOR + +READ_S_BPB_FAILURE DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1 +READ_T_BPB_FAILURE DB 0 ; + +;*** Informations from CHECK_SOURCE. +;*** These will be used as a basis for the copy process. +LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79) +END_OF_TRACK DB 15 ;END OF TRACK, 8,9 OR 15 CURRENTLY. +bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes +NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED + +FORMAT_FLAG DB 0 ;(ON/OFF) FORMAT BEFORE WRITE IF TURNED ON +TRACK_TO_READ DB 0 ;NEXT TRACK TO READ +TRACK_TO_WRITE DB 0 ;NEXT TRACK TO WRITE +TRACK_TO_FORMAT DB 0 ;STARTS FORMAT WITH THIS TRACK + ; TO THE LAST TRACK +TRACK_SIZE DW ? ;BYTES/CYLINDER [IN SEGMENTS] +SECTOR_SIZE DB ? ;BYTES/SECTOR [IN SEGMENTS] +BUFFER_PTR DW ? ;BUFFER POINTER FOR READ/WRITE OP +COPY_ERROR DB 0 ;=0 IF NO ERROR, >0 IF ERROR DETECTED +SIDE DB ? ;NEXT SIDE TO READ/WRITE (0,1) +SIDE_TO_FORMAT DB 0 ;NEXT SIDE TO FORMAT (0, 1) +OPERATION DB ? ;READ/WRITE/VERIFY OPERATION +COPY_STATUS DB ? ;(OK OR FATAL) ABORT COPY PROCESS IF FATAL +USER_INPUT DB ? ;DISKCOPY AGAIN? +IO_ERROR DB 0 ;SET BY EXTENDED_ERROR_HANDLER +UKM_ERR DB 0 ;AN011;IF ON, HARD ERROR IS TYPE: "UNKNOWN MEDIA" +MSG_FLAG DB ? ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE + ;IS TO BE DISPLAYED (ON/OFF) +TARGET_OP DB 0 ;FLAG TO INDICATE ANY OPERATIONS ON TARGET +TRY_FORMAT_FLAG DB 0 ;FLAG TO INDICATE "TRY_FORMAT" PROCEDURE TO + ; CHECK THE "TIME OUT ERROR" +TIME_OUT_FLAG DB 0 ;FLAG TO INDICATE THE "TIME OUT" ERROR + ; WAS A REAL "TIME OUT ERROR" +SELECT_FLAG DB 0 ;INDICATES SELECT IS PRESENT + PAGE ; +; DEVICE PARAMETER TABLE +;the returned info. still has the following format. + +DS_IOCTL_DRV_PARM LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM +DS_specialFunctions db ? ; +DS_deviceType db ? ;0 - 5.25"(48tpi), 1 - 5.25"(96tpi), + ; 2 - 3.5"(720KB) +DS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, + ; 0002h - CHANGE LINE SUPPORTED +DS_numberOfCylinders dw ? ; +DS_mediaType db ? ; +DS_BPB_PTR LABEL BYTE ; +DS_deviceBPB my_bpb <> ; +DS_trackLayout LABEL WORD ;AC000; + my_trackLayout ;AC000; +;--------------------------------------- + +DT_IOCTL_DRV_PARM LABEL BYTE ; +DT_specialFunctions db ? ; +DT_deviceType db ? ; +DT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, + ; 0002h - CHANGE LINE SUPPORTED +DT_numberOfCylinders dw ? ; +DT_mediaType db ? ; +DT_BPB_PTR LABEL BYTE ; +DT_deviceBPB my_bpb <> ; +DT_trackLayout LABEL WORD ;AC000; + my_trackLayout ;AC000; + +;--------------------------------------- + +MS_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM +MS_specialFunctions db ? ; +MS_deviceType db ? ; +MS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, + ; 0002h - CHANGE LINE SUPPORTED +MS_numberOfCylinders dw ? ; +MS_mediaType db ? ; +MS_BPB_PTR LABEL BYTE ; +MS_deviceBPB my_bpb <> ; +MS_deviceBPB_leng equ $-MS_deviceBPB ; +MS_trackLayout LABEL WORD ;AC000; + my_trackLayout ;AC000; +;--------------------------------------- +MT_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM +MT_specialFunctions db ? ; +MT_deviceType db ? ; +MT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, + ; 0002h - CHANGE LINE SUPPORTED +MT_numberOfCylinders dw ? ; +MT_mediaType db ? ; +MT_BPB_PTR LABEL BYTE ; +MT_deviceBPB my_bpb <> ; +MT_trackLayout LABEL WORD ;AC000; + my_trackLayout ;AC000; + + +; IOCTL format a track function control string. +IOCTL_FORMAT LABEL BYTE ; +FspecialFunctions db 0 ; +FHead dw ? ; +FCylinder dw ? ; + +; IOCTL read/write a track. +IOCTL_R_W LABEL BYTE ; +specialFunctions db 0 ; +Head dw ? ; +Cylinder dw ? ; +FirstSectors dw ? ; +numberOfSectors dw ? ; +TAddress_off dw ? ; +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; + HEADER ;AN000; + PUBLIC DISKCOPY_BEGIN ; +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; +BEGIN PROC NEAR ; + PUBLIC BEGIN ;AN000; +;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE + + MOV SP, OFFSET MY_STACK_PTR ;MOVE SP TO MY STACK PTR + CALL SYSLOADMSG ;AN000;INIT SYSMSG HANDLER + +; $IF C ;AN000;IF THERE WAS A PROBLEM + JNC $$IF1 + CALL SYSDISPMSG ;AN000;LET HIM SAY WHY HE HAD A PROBLEM + + MOV EXITFL,EXVER ;AN000;TELL ERRORLEVEL BAD DOS VERSION +; $ELSE ;AN000;SINCE SYSDISPMSG IS HAPPY + JMP SHORT $$EN1 +$$IF1: + CALL INIT ;RUN INITIALIZATION ROUTINE + + CMP DX,FINE ;CHECK FOR ERROR DURING INIT +; $IF E ;IF NO ERROR THEN PROCEED TO COPY + JNE $$IF3 +; $DO ; +$$DO4: + CALL COPY ;PERFORM DISKCOPY + + CALL TEST_REPEAT ;COPY ANOTHER ? + +; $ENDDO C ; + JNC $$DO4 + ;NORMAL RETURN CODE ALREADY IN "EXITFL" +; $ELSE ;ELSE IF ERROR DETECTED IN INIT + JMP SHORT $$EN3 +$$IF3: +.XLIST ; +; PUSH DX +; PUSH CS +; CALL PRINTF ;DISPLAY ERROR MESSAGE +.LIST ; + MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000; + ;DI HAS OFFSET OF MESSAGE DESCRIPTOR + CALL SENDMSG ;AC000;DISPLAY THE ERROR MESSAGE + + MOV EXITFL,EXVER ;AC000;ERROR RETURN CODE +; $ENDIF ; +$$EN3: + JMP SHORT EXIT_TO_DOS ; + +MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK + MOV EXITFL,EXCBR ;AC000; FOR CONTROL-BREAK EXIT + +EXIT_TO_DOS: ; + XOR BX, BX ; + + MOV BL, S_OWNER_SAVED ;RESTORE ORIGINAL SOURCE, + ; TARGET DRIVE OWNER. + CALL SET_LOGICAL_DRIVE ; + + MOV BL, T_OWNER_SAVED ; + CALL SET_LOGICAL_DRIVE ; + + CMP S_DRV_SET_FLAG, 0 ; +; $IF NE ;AN000; + JE $$IF8 + MOV BL, SOURCE_DRIVE ; + MOV DS_specialFunctions, SET_SP_FUNC_DOS ;=0 + MOV DX, OFFSET DS_IOCTL_DRV_PARM ; + CALL SET_DRV_PARM_DEF ;RESTORE SOURCE DRIVE PARM + +; $ENDIF ;AN000; +$$IF8: + + CMP T_DRV_SET_FLAG, 0 ; +; $IF NE ;AN000; + JE $$IF10 + MOV BL, TARGET_DRIVE ; + MOV DT_specialFunctions, SET_SP_FUNC_DOS ;=0 + MOV DX, OFFSET DT_IOCTL_DRV_PARM ; + CALL SET_DRV_PARM_DEF ;RESTORE TARGET DRIVE PARM + +; $ENDIF ;AN000; +$$IF10: +EXIT_PROGRAM: ; + +; $ENDIF ;AN000;OK WITH SYSDISPMSG? +$$EN1: + MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE + DOSCALL RET_CD_EXIT ;AN000;RETURN TO DOS WITH RET CODE + + INT 20H ;AN000;IF ABOVE NOT WORK, +BEGIN ENDP ;AN000; +; = = = = = = = = = = = = = = = = = + HEADER ;AN000; + PUBLIC SET_LOGICAL_DRIVE ; +;***************************************************************************** +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. +;***************************************************************************** + CMP BL, 0 ; +; $IF NE ;IF BL = 0, THEN JUST RETURN + JE $$IF13 + ;ELSE SET BL AS AN OWNER OF THAT DRIVE + MOV AX,(IOCTL_FUNC SHL 8)+SET_LOGIC_DRIVE ;AC000; + INT 21H ; +; $ENDIF ; +$$IF13: + RET ; +SET_LOGICAL_DRIVE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +;MODULE NAME: COPY * +; * +; INPUT: COPY_TYPE BYTE 1=SINGLE DRIVE COPY * +; 2=DOUBLE DRIVE COPY * +; * +; OUTPUT: NONE * +;***************************************************************************** +COPY PROC NEAR ;COPY DISKETTE IMAGE + MOV VOLSER_FLAG,0 ;AN000;RESET MEDIA ID VOL SERIAL NUMBER FLAG + MOV COPY_ERROR,0 ;RESET COPY ERROR FLAG + MOV COPY_STATUS,OK ;RESET COPY STATUS BYTE + MOV TARGET_OP, OFF ; + MOV TRY_FORMAT_FLAG, OFF ; + MOV TIME_OUT_FLAG, OFF ; + MOV FORMAT_FLAG,OFF ;ASSUME FORMAT IS NOT REQUIRED + MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG + MOV READ_T_BPB_FAILURE, 0 ; + MOV AX, RECOMMENDED_BYTES_SECTOR ; + MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE TO READ A SECTOR + CMP COPY_TYPE,2 ;IF TWO DRIVE COPY +; $IF E ; + JNE $$IF15 + PRINT MSGNUM_LOAD_SOURCE ;AC000;OUTPUT LOAD SOURCE DISKETTE MESSAGE + ;"INSERT SOURCE DISKETTE INTO DRIVE X:" + + PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:" + + CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB) + +; $ENDIF ; +$$IF15: + MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS + MOV TRACK_TO_WRITE,0 ; + +COPY_TEST_END: ; +; $SEARCH ; +$$DO17: + MOV AL,TRACK_TO_WRITE ;WHILE TRACK_TO_WRITE<=LAST_TRACK + CMP AL,LAST_TRACK ; +; $LEAVE A ; + JA $$EN17 + CALL READ_SOURCE ;READ AS MANY TRACK AS POSSIBLE + + CMP COPY_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE +; $EXITIF E,NUL,OR ; + JE $$SR17 + CALL WRITE_TARGET ;WRITE THE CONTENT OF BUFFER TO TARGET + + CMP COPY_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE +; $EXITIF E,NUL ; + JE $$SR17 +; $ENDLOOP ; + JMP SHORT $$DO17 +$$EN17: + + CMP COPY_ERROR,FALSE ;IF ERROR IN COPY +; $IF NE ; + JE $$IF21 + ;CR,LF,"Target diskette may be unusable",CR,LF + PRINT MSGNUM_TARGET_MB_UNUSABLE ;AC000; + +; $ENDIF ; +$$IF21: +; $ENDSRCH ; +$$SR17: + CMP COPY_STATUS,FATAL ;WAS COPY ABORTED ? +; $IF E ; + JNE $$IF24 + ;CR,LF,"Copy process ended",CR,LF + PRINT MSGNUM_FATAL_ERROR ;AC000;IF SO THEN TELL USER + +; $ELSE ;AN000;SINCE NOT ABORTED, + JMP SHORT $$EN24 +$$IF24: + CALL WRITE_VOLSER ;AN000;GO CHANGE VOLID OF TARGET + +; $ENDIF ; +$$EN24: + RET ; + +COPY ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC TEST_REPEAT ;AN000;MAKE ENTRY IN LINK MAP +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 + JMP SHORT $$SS27 +$$DO27: + PRINT MSGNUM_CR_LF ;AC000; + +; $STRTSRCH ;AN000; +$$SS27: + ;CR,LF,"Copy another diskette (Y/N)?" + PRINT MSGNUM_COPY_ANOTHER ;AC000;SEE IF USER WANTS TO COPY ANOTHER + ; AND READ RESPONSE TO AL + PUSH AX ;AN000;SAVE THE RESPONSE + PRINT MSGNUM_CR_LF ;AC000; + + POP DX ;AN000;RESTORE THE REPONSE CHAR TO DL + 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" + JC $$SR27 + + CMP AX,BAD_YESNO ;AN000;WAS THE RESPONSE INVALID? +; $ENDLOOP B ;AN000;QUIT IF OK ANSWER (AX=0 OR 1) + JNB $$DO27 + CMP AL,YES ;AN000;WAS "YES" SPECIFIED +; $IF E ;AN000;IF "YES" + JNE $$IF31 + CLC ;AN000;CLEAR CARRY TO INDICATE COPY AGAIN +; $ELSE ;AN000;SINCE NOT "YES" + JMP SHORT $$EN31 +$$IF31: + STC ;AN000;SET CARRY TO INDICATE NO REPEAT +; $ENDIF ;AN000; +$$EN31: +; $ENDSRCH ;AN000; +$$SR27: +.XLIST ; +; MOV AL,USER_INPUT +; AND AL,11011111B ;MAKE USER INPUT UPPER CASE +; CMP AL,YES ;IF YES THEN COPY AGAIN +; $EXITIF E +; CLC ;CLEAR CARRY TO INDICATE COPY AGAIN +; $ORELSE +; CMP AL,NO ;IF NOT "N" OR "Y" THEN PROMPT AGAIN +; $ENDLOOP E +; STC ;SET CARRY TO INDICATE NO REPEAT +; $ENDSRCH +.LIST ; + RET ; + +TEST_REPEAT ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC READ_SOURCE ;AN000;MAKE ENTRY IN LINK MAP * +READ_SOURCE PROC NEAR ;READ AS MANY TRACKS AS POSSIBLE FROM SOURCE* +; ;DISKETTE TO FILL THE AVAILABLE BUFFER SPACE * +;***************************************************************************** + + CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY +; $IF E ;PROMPT MSG + JNE $$IF35 + PRINT MSGNUM_LOAD_SOURCE ;AN000;"INSERT SOURCE DISKETTE INTO DRIVE X:" + + CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB) + +; $ENDIF ; +$$IF35: + CMP TRACK_TO_READ,0 ;1ST TRACK ? +; $IF NE,OR ;IF NOT + JNE $$LL37 + + CALL CHECK_SOURCE ;DO NECESSARY CHECKING + + CALL CALC_TRACK_SIZE ; + + CALL CHECK_MEMORY_SIZE ; + + CMP COPY_STATUS,FATAL ; +; $IF NE ; + JE $$IF37 +$$LL37: +;(deleted ;AN013;) CALL READ_VOLSER ;GO READ THE MEDIA ID TO GET SERIAL NUMBER ;AN000; + + MOV BX,BUFFER_BEGIN ; + MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER + +; $DO ; +$$DO38: + MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS? + CMP AL,LAST_TRACK ; +; $LEAVE A ; + JA $$EN38 + MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE + ADD AX,TRACK_SIZE ; + CMP AX,BUFFER_END ; +; $LEAVE A ; + JA $$EN38 + MOV OPERATION,READ_FUNC ; + CALL READ_WRITE_TRACK ;NO, GO READ ANOTHER TRACK + + INC TRACK_TO_READ ; +; $ENDDO ; + JMP SHORT $$DO38 +$$EN38: +; $ENDIF ; +$$IF37: + RET ; +READ_SOURCE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC WRITE_TARGET ;AN000;MAKE ENTRY IN LINK MAP +WRITE_TARGET PROC ;WRITE DATA FROM MEMORY TO TARGET DISKETTE* +; * +;***************************************************************************** + + CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY +; $IF E ;PROMPT MSG + JNE $$IF43 + PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:" + + CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB) + +; $ENDIF ; +$$IF43: + MOV TARGET_OP, ON ;INDICATE A OPERATION ON TARGET + MOV BX,BUFFER_BEGIN ; + MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER + CMP TRACK_TO_WRITE,0 ;IF TRK 0, CHECK COMPATIBILITY +; $IF NE,OR ; + JNE $$LL45 + + MOV SIDE, 0 ; + CALL CHECK_TARGET ; + + CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT +; $IF NE ; + JE $$IF45 +$$LL45: + +; $DO ; +$$DO46: + MOV AL,TRACK_TO_WRITE ;DID WE FINISH WRITING ALL TRACKS? + CMP AL,LAST_TRACK ; +; $LEAVE A ; + JA $$EN46 + MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE + ADD AX,TRACK_SIZE ; + CMP AX,BUFFER_END ; +; $LEAVE A ; + JA $$EN46 + MOV OPERATION,WRITE_FUNC ; + CALL READ_WRITE_TRACK ;NO, GO WRITE ANOTHER TRACK + + CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT +; $LEAVE E ; + JE $$EN46 + INC TRACK_TO_WRITE ; +; $ENDDO ; + JMP SHORT $$DO46 +$$EN46: +; $ENDIF ; +$$IF45: + MOV TARGET_OP, OFF ; + RET ; +WRITE_TARGET ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC READ_WRITE_TRACK ;AN000;MAKE ENTRY IN LINK MAP +READ_WRITE_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY * +; * +;INPUT: OPERATION = 61h THEN READ OPERATION * +; 41h THEN WRITE OPERATION * +;***************************************************************************** + + MOV SIDE, 0 ; +; $DO ; +$$DO52: + MOV MSG_FLAG, ON ; + CMP OPERATION, READ_FUNC ; +; $IF E ; + JNE $$IF53 + CALL READ_OP ; + +; $ELSE ; + JMP SHORT $$EN53 +$$IF53: + CALL WRITE_OP ; + + CMP COPY_STATUS, FATAL ; + JE RWT_EXIT ; + +; $ENDIF ; +$$EN53: + CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY? +; $IF E ;YES + JNE $$IF56 + MOV AX, TRACK_SIZE ; +; $ELSE ;NO, DOUBLE SIDE + JMP SHORT $$EN56 +$$IF56: + XOR DX, DX ; + MOV AX, TRACK_SIZE ; + MOV CX, 2 ; + DIV CX ;AX / 2 +; $ENDIF ; +$$EN56: + ADD BUFFER_PTR, AX ; + INC SIDE ;NEXT SIDE + MOV AL, SIDE ; + CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE? +; $ENDDO G ; + JNG $$DO52 +RWT_EXIT: ; + RET ; +READ_WRITE_TRACK ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC READ_OP ;AN000;MAKE ENTRY IN LINK MAP +READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION * +; * +;***************************************************************************** + +; $SEARCH ; +$$DO60: + XOR AX, AX ; + MOV AL, SIDE ; + MOV Head, AX ;HEAD TO READ + MOV AL, TRACK_TO_READ ; + MOV Cylinder, AX ;TRACK TO READ + MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ??? + MOV AX, BUFFER_PTR ; + MOV Taddress_seg, AX ;BUFFER ADDRESS + MOV Taddress_off, 0 ; + XOR BX, BX ; + MOV BL, SOURCE_DRIVE ; + MOV CL, READ_FUNC ;=61h + MOV DX, OFFSET IOCTL_R_W ; + CALL GENERIC_IOCTL ; + + CMP IO_ERROR, NO_ERROR ;OK? +; $EXITIF E ;AC013;IF NO ERROR SO FAR, GOOD + JNE $$IF60 + CMP CYLINDER,0 ;AN013;IS THIS THE FIRST READ? +; $IF E,AND ;AN013;IF THIS IS THE FIRST TRACK, AND + JNE $$IF62 + CMP HEAD,0 ;AN013;IS THIS THE FIRST SIDE? +; $IF E ;AN013;AND IF THIS IS THE FIRST SIDE + JNE $$IF62 + CALL MAYBE_ADJUST_SERIAL ;AN013;IF BOOT HAS SERIAL, GENERATE NEW ONE + +; $ENDIF ;AN013;FIRST TRACK AND HEAD? +$$IF62: +; $ORELSE ;AN013;SINCE SOME KIND OF ERROR, OOPS + JMP SHORT $$SR60 +$$IF60: + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? +; $ENDLOOP NE ; + JE $$DO60 + + CMP MSG_FLAG, ON ;ELSE HARD ERROR. SEE IF + ; MESSAGE TO BE DISPLAYED +; $IF E ; + JNE $$IF66 + + MOV AH, READ_FUNC ; + mov dl, source_drive ; + CALL ERROR_MESSAGE ; + + INC COPY_ERROR ;INCREASE COPY_ERROR COUNT + MOV MSG_FLAG, OFF ; +; $ENDIF ; +$$IF66: +; $ENDSRCH ; +$$SR60: + RET ; +READ_OP ENDP ; +; = = = = = = = = = = = = + HEADER ;AN013; +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. + + PUSH ES ;AN013;SAVE EXTRA SEG REG TEMPORARILY + PUSH BX ;AN013;AND SAVE THE BASE POINTER + PUSH SI ;AN013; AND THE INDEX + LES BX,DWORD PTR TADDRESS_OFF ;AN013;POINT TO BUFFER AREA CONTAINING BOOT RECORD + LEA SI,ES:[BX].EXT_BOOT_BPB ;AN013;POINT TO BPB PORTION OF BOOT RECORD + MOV AL,ES:[SI].EBPB_MEDIADESCRIPTOR ;AN013;GET TYPE OF MEDIA + AND AL,0F0H ;AN013;SAVE LEFT NIBBLE ONLY + CMP AL,0F0H ;AN013;IF DISKETTE HAS PROPER DESCRIPTOR +; $IF E ;AN013;IF OK DESCRIPTOR + JNE $$IF69 + MOV AL,ES:[BX].EXT_BOOT_SIG ;AN013;GET "SIGNATURE" OF BOOT RECORD + 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 + JE $$LL70 + 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 + JNE $$IF70 +$$LL70: +; GET CURRENT DATE + DOSCALL GET_DATE ;AN013;READ SYSTEM DATE + ;OUTPUT: DL = DAY (1-31) + ; AL = DAY OF WEEK (0=SUN,6=SAT) + ; CX = YEAR (1980-2099) + ; DH = MONTH (1-12) + PUSH CX ;AN013;SAVE THESE FOR + PUSH DX ;AN013; INPUT INTO HASH ALGORITHM +; GET CURRENT TIME + DOSCALL GET_TIME ;AN013;READ SYSTEM TIME CLOCK + ;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 + + POP AX ;AN013;GET THE DX FROM DATE + ADD AX,DX ;AN013;ADD IN THE DX FROM TIME + MOV WORD PTR SERIAL,AX ;AN013;SAVE FIRST RESULT OF HASH + MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL,AX ;AN013;AND IN BOOT RECORD ITSELF + + POP AX ;AN013;GET THE CX FROM DATE + ADD AX,CX ;AN013;ADD IN THE CX FROM TIME + MOV WORD PTR SERIAL+WORD,AX ;AN013;SAVE SECOND RESULT OF HASH + MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL+WORD,AX ;AN013;AND IN BOOT RECORD + + MOV VOLSER_FLAG,TRUE ;AN013;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN + +; $ENDIF ;AN013;BOOT HAVE SERIAL? +$$IF70: +; $ENDIF ;AN013;PROPER DESCRIPTOR? +$$IF69: + POP SI ;AN013;RESTORE THE INDEX REG + POP BX ;AN013;RESTORE THE BASE POINTER + POP ES ;AN013;RESTORE EXTRA SEG REG + RET ;AN013;RETURN TO CALLER +MAYBE_ADJUST_SERIAL ENDP ;AN013; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC WRITE_OP ;AN000;MAKE ENTRY IN LINK MAP +WRITE_OP PROC NEAR ;IOCTL WRITE A TRACK OPERATION * +; * +;***************************************************************************** + +WO_AGAIN: ; +; $SEARCH ; +$$DO73: + XOR AX, AX ; + MOV AL, SIDE ; + MOV Head, AX ;HEAD TO WRITE + MOV AL, TRACK_TO_WRITE ; + MOV Cylinder, AX ;TRACK TO WRITE + MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ??? + MOV AX, BUFFER_PTR ; + MOV Taddress_seg, AX ;BUFFER ADDRESS + MOV Taddress_off, 0 ; + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV CL, WRITE_FUNC ;= 41h + MOV DX, OFFSET IOCTL_R_W ; + CALL GENERIC_IOCTL ; + + CMP IO_ERROR, NO_ERROR ;OK? +; $LEAVE E ;YES, SUCCESS. EXIT THIS ROUTINE + JE $$EN73 + + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? + JE WO_AGAIN ; + ;ELSE HARD ERROR + ;WRITE FAILURE, LET'S TRY TO FORMAT. + CMP FORMAT_FLAG, ON ;WAS THIS TRACK FORMATTED BEFORE? +; $EXITIF E ;YES, GIVE UP WRITING AND + JNE $$IF73 + ; CHECK WHEN IT HAPPENDED. + ;GIVE UP WRITING AND SHOW ERROR MESSAGE. + INC COPY_ERROR ;INDICATE ERROR OCCURS DURING COPY. + MOV AH, WRITE_FUNC ; + mov dl, target_drive ; + CALL ERROR_MESSAGE ;SHOW MESSAGE 'WRITE ERROR SIDE, TRACK...' + + MOV MSG_FLAG, OFF ; +; $ORELSE ;ELSE TRY FORMAT AND TRY WRITE AGAIN + JMP SHORT $$SR73 +$$IF73: + + ;CR,LF,"Formatting while copying",CR,LF + PRINT MSGNUM_FORMATTING ;AN000;SHOW MESSAGE + + MOV FORMAT_FLAG, ON ;FORMAT ALL TRACKS FROM THIS TRACK + CALL FORMAT_ALL ;format all the rest of the tracks + + CMP COPY_STATUS, FATAL ; +; $ENDLOOP E ; + JNE $$DO73 +$$EN73: +.XLIST ; +;this next is dead code, nobody calls WO_FATAL, so the move copy_status +;and the print not compatible msg should be removed, and just the JMP WO_EXIT +;will no longer be needed to skip stuff that is not there. Kiser +; JMP WO_EXIT ;AND EXIT THIS ROUTINE +;WO_FATAL: +; MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM +; PRINT MSG_NOT_COMPATIBLE ;SHOW NOT COMPATIABLE MESSAGE +.LIST ; +; $ENDSRCH ; +$$SR73: +WO_EXIT: ; + RET ; + +WRITE_OP ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC FORMAT_ALL ;AN000;MAKE ENTRY IN LINK MAP +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. * +;***************************************************************************** + + MOV CX, MS_deviceBPB_leng ;set length of BPB + MOV SI, OFFSET MS_deviceBPB ; + MOV DI, OFFSET MT_deviceBPB ; + REP MOVSB ; + CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation + + MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B + MOV CL, SETDEVPARM ;=40h + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + XOR BX, BX ; + mov bl, last_track ;patch 3/27/86 for 3.2 diskcopy. J.K. + inc bl ; + mov MT_numberOfCylinders, bx ;make sure target # of cyl. + MOV BL, TARGET_DRIVE ; + CALL GENERIC_IOCTL ; + + JC FA_FATAL ; + + MOV FspecialFunctions, STATUS_CHK ;check to see if the parameters set + ;by "SET DEVICE PARM" func above are + ; supported or not. + MOV AX,(IOCTL_FUNC SHL 8)+GENERIC_IOCTL_CODE ;AC000;(440DH) + MOV CH, MAJOR_CODE ;=8 + MOV CL, FORMAT_FUNC ;=42H + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV DX, OFFSET IOCTL_FORMAT ;result is in Fspecialfunction + INT 21H ;0 - Thre is ROM support of AH=18h, INT 13h, and + ; it is a valid combination + + MOV AL, FspecialFunctions ;1 - No ROM support. 2 - There is ROM support, + ; but invalid combination + MOV FspecialFunctions, FORMAT_SP_FUNC ;restore specialfunction value + CMP AL, 2 ;ROM support, but this combination is not valid? + JE FA_FATAL ; + + MOV AL, TRACK_TO_WRITE ; + MOV TRACK_TO_FORMAT, AL ; + MOV AL, SIDE ; + MOV SIDE_TO_FORMAT, AL ; + CMP AL, NO_OF_SIDES ; + JE FA_SIDE_WHILE ;STARTS WITH THE OTHER SIDE TO FORMAT + +FA_TRACK_WHILE: ; + MOV AL, LAST_TRACK ; + CMP TRACK_TO_FORMAT, AL ; + JA FA_DONE ; + +FA_SIDE_WHILE: ; + MOV AL, NO_OF_SIDES ; + CMP SIDE_TO_FORMAT, AL ; + JA FA_NEXT_TRACK ; + + CALL FORMAT_TRACK ;FORMAT THIS TRACK + + CMP IO_ERROR, HARD_ERROR ; + JNE FA_NEXT_SIDE ; + + CMP SIDE_TO_FORMAT, 1 ;HARD ERROR AT SIDE 1? + JNE FA_TARGET_BAD ;THEN ASSUME TARGET DISKETTE BAD + + CMP TRACK_TO_FORMAT, 0 ;AT CYLINDER 0? + JNE FA_TARGET_BAD ; + + JMP FA_FATAL ;THEN, SOURCE IS TWO SIDED AND + ; TARGET IS SINGLE SIDE DISKETTE + +FA_NEXT_SIDE: ; + INC SIDE_TO_FORMAT ; + JMP FA_SIDE_WHILE ; + +FA_NEXT_TRACK: ; + MOV SIDE_TO_FORMAT, 0 ;RESET SIDE_TO_FORMAT + INC TRACK_TO_FORMAT ; + JMP FA_TRACK_WHILE ; + +FA_FATAL: ; + 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 + + JMP SHORT FA_DONE ; + +FA_TARGET_BAD: ; + 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 + +FA_DONE: ; + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + MOV MT_specialFunctions, SET_SP_FUNC_DEF ; + CALL SET_DRV_PARM_DEF ;SET IT BACK FOR WRITING. + + RET ; +FORMAT_ALL ENDP ; +; = = = = = = = = = = = = + HEADER ;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 +FORMAT_TRACK PROC NEAR ; + +FT_AGAIN: ; +; $DO ; +$$DO79: + XOR AX, AX ; + MOV AL, SIDE_TO_FORMAT ; + MOV FHead, AX ;HEAD TO FORMAT + MOV AL, TRACK_TO_FORMAT ; + MOV FCylinder, AX ;TRACK TO FORMAT + + XOR BX, BX ; + MOV BL, TARGET_DRIVE ;DRIVE TO FORMAT + MOV CL, FORMAT_FUNC ;=42h + MOV DX, OFFSET IOCTL_FORMAT ; + CALL GENERIC_IOCTL ; + + CMP IO_ERROR, SOFT_ERROR ;TRY FORMAT AGAIN? + ; (DRIVE NOT READY OR WRITE PROTECTED) +; $ENDDO NE ; + JE $$DO79 + + RET ; +FORMAT_TRACK ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * + PUBLIC CHECK_SOURCE ;AN000;MAKE ENTRY IN LINK MAP +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 ; +$$DO81: + XOR BX, BX ; + MOV BL, SOURCE_DRIVE ; + MOV MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b + MOV CL, GETDEVPARM ;=60h + MOV DX, OFFSET MS_IOCTL_DRV_PARM ; + CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER + ;WITH DEFAULT DEVICE INFO. + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? +; $ENDDO NE ; + JE $$DO81 + + CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB? + JE CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST. + + cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86 + je cs_old ; + + cmp ms_deviceBPB.chead,0 ;cannot trust the info from dos + je cs_old ;sanity check for divide by 0 + + MOV AX, MS_deviceBPB.CTOTSECT ; + CWD ;CONVERT IT TO A DOUBLE WORD + DIV MS_deviceBPB.CSECT_TRACK ; + DIV MS_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS + CMP AL, T_DRV_TRACKS ;SOURCE MEDIA # OF TRACK > TARGET + ; DEVICE # OF TRACKS? + JA CS_FATAL ;THEN, NOT COMPATIBLE. + + DEC AX ;DECREASE BY 1 FOR THE USE OF THIS PROGRAM. + MOV LAST_TRACK, AL ;SET LAST_TRACK + MOV AX, MS_deviceBPB.CSECT_TRACK ; + CMP AL, T_DRV_SECT_TRACK ;SOURCE MEDIA # OF SECT/TRACK > TARGET + ; DEVICE # OF SECT/TRACK? + JA CS_FATAL ;THEN, NOT COMPATIBLE + + MOV END_OF_TRACK, AL ; + MOV AX, MS_deviceBPB.CBYTE_SECT ; + MOV bSECTOR_SIZE, AX ;set the sector size in bytes. + CMP USER_OPTION, 1 ; + JE CS_OPTION_1 ; + + MOV AX, MS_deviceBPB.CHEAD ;HEAD=1, 2 + CMP AL, T_DRV_HEADS ;COMPARE SOURCE MEDIA SIDE WITH + ; TARGET DRIVE HEAD NUMBER + JA CS_FATAL ;SOURCE MEDIUM IS DOUBLE SIDED AND + ; TARGET DRIVE IS SINGLE SIDED. + + DEC AX ; + MOV NO_OF_SIDES, AL ;NO_OF_SIDES=0, 1 + JMP CS_SET_TABLE ; +; = = = = = = = = = = = +CS_FATAL: ; + MOV COPY_STATUS, FATAL ; + ;CR,LF,"Drive types or diskette types",CR,LF + ;"not compatible",CR,LF + PRINT MSGNUM_NOT_COMPATIBLE ;AC000; + JMP CS_EXIT ; + +; = = = = = = = = = = = +CS_BAD: ; + MOV COPY_STATUS, FATAL ; + PRINT MSGNUM_BAD_SOURCE ;CR,LF,"SOURCE diskette bad or incompatible" + + JMP CS_EXIT ; + +; = = = = = = = = = = = +CS_OLD: ; + MOV READ_S_BPB_FAILURE, 1 ;SET FLAG + MOV bSECTOR_SIZE, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES + XOR BX, BX ; + MOV BL, SOURCE_DRIVE ; + MOV IOCTL_TRACK, 0 ;TRACK=0 + MOV IOCTL_SECTOR, 8 ;SECTOR=8 + MOV IOCTL_HEAD, 0 ;HEAD = 0 + CALL READ_A_SECTOR ; + + JC CS_BAD ;SOURCE BAD + + MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR=9 + CALL READ_A_SECTOR ; + + JC CS_SECT8 ;YES, 8 SECTORS. ASSUME 40 TRACKS + + MOV IOCTL_SECTOR, 15 ;try to read sector=15 + CALL READ_A_SECTOR ; + + JC CS_SECT9 ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA + + JMP SHORT CS_SECT15 ; + +; = = = = = = = = = = = +CS_OPTION_1: ; + MOV NO_OF_SIDES, 0 ;1 SIDE COPY + JMP SHORT CS_SET_TABLE ; + +; = = = = = = = = = = = +CS_SECT15: ; + MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15 + MOV LAST_TRACK, 79 ; + JMP SHORT CS_CHK_SIDE ; + +; = = = = = = = = = = = +CS_SECT8: ; + MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS + MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS. + JMP SHORT CS_CHK_SIDE ; + +; = = = = = = = = = = = +CS_SECT9: ; + MOV END_OF_TRACK, 9 ; + MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE + JMP SHORT CS_CHK_SIDE ; + +; = = = = = = = = = = = +CS_CHK_SIDE: ; + CMP USER_OPTION, 1 ; + JE CS_OPTION_1 ; + + MOV IOCTL_HEAD, 1 ;HEAD 1 + XOR AX, AX ; + MOV AL, END_OF_TRACK ;READ MATCHING END_OF_TRACK + ; OF THE OTHER SURFACE. + MOV IOCTL_SECTOR, AX ; + CALL READ_A_SECTOR ; + + JC CS_OPTION_1 ;1 SIDED SOURCE + + MOV NO_OF_SIDES, 1 ;2 SIDED SOURCE + CMP T_DRV_HEADS, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET + ; DOUBLE SIDED DRV? + JE CS_SET_TABLE ; + + JMP CS_FATAL ;NOT COMPATIBLE + +; = = = = = = = = = = = +CS_SET_TABLE: ; + CMP READ_S_BPB_FAILURE, 1 ;DISKETTE WITHOUT BPB INFO? +; $IF E ; + JNE $$IF83 + CALL SET_FOR_THE_OLD ; + +; $ENDIF ; +$$IF83: + MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE + CALL SET_TRACKLAYOUT ; + + MOV BX, OFFSET MT_trackLayout ;YES, ASSUME TARGET IS SAME + CALL SET_TRACKLAYOUT ; + + MOV S_DRV_SET_FLAG, 1 ; + XOR BX, BX ; + MOV BL, SOURCE_DRIVE ; + MOV MS_specialFunctions, SET_SP_FUNC_DEF ;=00000100B + MOV DX, OFFSET MS_IOCTL_DRV_PARM ; + CALL SET_DRV_PARM_DEF ;NOW, SET SOURCE DRIVE PARM + ; FOR READ OPERATION. + + XOR AX, AX ; + MOV AL, END_OF_TRACK ; + MOV numberOfSectors, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE + + MOV AL, LAST_TRACK ;NOW, SHOW THE MESSAGE "COPYING ..." + INC AL ; +.XLIST ; +; MOV BYTE PTR MSG_COPYING_PTR+2, AL ;HOW MANY TRACKS? +.LIST ; + MOV BYTE PTR MSG_TRACKS, AL ;AC000;HOW MANY TRACKS? + + MOV AL, END_OF_TRACK ; +.XLIST ; +; MOV BYTE PTR MSG_COPYING_PTR+4, AL ;HOW MANY SECTORS? +.LIST ; + MOV BYTE PTR MSG_SECTRK,AL ;AC000;HOW MANY SECTORS? + + MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY + INC AL ; +.XLIST ; +; MOV BYTE PTR MSG_COPYING_PTR+6, AL +.LIST ; + 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; + +CS_EXIT: ; + RET ; + +CHECK_SOURCE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;****************************************************************************** + PUBLIC READ_A_SECTOR ;AN000;MAKE ENTRY IN LINK MAP +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 * +; +;****************************************************************************** + + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + + MOV AX, numberOfSectors ;SAVE IOCTL_R_W TABLE VALUES + MOV SAV_CSECT, AX ; + +;RAS_AGAIN: +; $DO ; +$$DO85: + MOV AX, IOCTL_HEAD ; + MOV Head, AX ;SURFACE TO READ + MOV AX, IOCTL_TRACK ; + MOV Cylinder, AX ;TRACK TO READ + MOV AX, IOCTL_SECTOR ; + dec ax ;????? currently + ; firstsector=0 => 1st sector ???? + MOV FirstSectors, AX ;SECTOR TO READ + MOV numberOfSectors, 1 ;read just one sector + MOV AX, offset INIT ;READ IT INTO INIT + ; (CURRELTLY, MAX 1K) + MOV TAddress_off, AX ; + MOV TAddress_seg, DS ; + MOV CL, READ_FUNC ; + MOV DX, OFFSET IOCTL_R_W ;POINTS TO CONTROL TABLE + call generic_ioctl ; + + CMP IO_ERROR, SOFT_ERROR ;TRY ONCE MORE? +; $ENDDO NE ; + JE $$DO85 + + CMP IO_ERROR, HARD_ERROR ;HARD ERROR? +; $IF NE ; + JE $$IF87 + + CLC ;READ SUCCESS +; $ELSE ; + JMP SHORT $$EN87 +$$IF87: + STC ;SET CARRY +; $ENDIF ; +$$EN87: + MOV AX, SAV_CSECT ;RESTORE ORIGINAL IOCTL_R_W TABLE + MOV numberOfSectors, AX ; + POP DX ; + POP CX ; + POP BX ; + POP AX ; + RET ; + +READ_A_SECTOR ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC CALC_TRACK_SIZE ;AN000;MAKE ENTRY IN LINK MAP +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. * +;***************************************************************************** + + PUSH AX ; + PUSH BX ; + PUSH CX ; + + MOV AX, bSECTOR_SIZE ; + MOV CL, 16 ; + DIV CL ;AX / 16 = AL ... AH + CMP AH, 0 ;NO REMAINER? +; $IF NE ; + JE $$IF90 + + INC AL ;THERE REMAINER IS. INC AL + +; $ENDIF ; +$$IF90: + MOV SECTOR_SIZE, AL ;SECTOR_SIZE+ IN PARA. + MOV AL,NO_OF_SIDES ;TRACK_SIZE = (NO OF SIDES + INC AL ; + 1) + MUL END_OF_TRACK ; * END_OF_TRACK + MOV BL,SECTOR_SIZE ; * SECTPR_SIZE + MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG) + MOV TRACK_SIZE,AX ;TO STORE A TRACK + POP CX ; + POP BX ; + POP AX ; + + RET ; +CALC_TRACK_SIZE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC CHECK_MEMORY_SIZE ;AN000;MAKE ENTRY IN LINK MAP +CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COPY 1 TRACK INTO +; TO BUFFER ELSE ABORT COPY * +;***************************************************************************** + MOV AX,BUFFER_END ;CALCULATE AVAILABLE MEMORY + SUB AX,BUFFER_BEGIN ;IN SEGMENTS + CMP AX,TRACK_SIZE ;DO WE HAVE ENOUGH TO STORE A CYLINDER? +; $IF B ; + JNB $$IF92 + MOV COPY_STATUS,FATAL ;NO, ABORT COPY + PRINT MSGNUM_UNSUF_MEMORY ;AC000;AND TELL USER WHY + +; $ENDIF ; +$$IF92: + RET ; + +CHECK_MEMORY_SIZE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC SET_FOR_THE_OLD ;AN000;MAKE ENTRY IN LINK MAP +SET_FOR_THE_OLD PROC NEAR ; + +;set MS_deviceBPB for before-2.0 formatted media +;***************************************************************************** + PUSH AX ; + + 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 + JNA $$IF94 + MOV SI, OFFSET BPB96 ; +; $ELSE ; + JMP SHORT $$EN94 +$$IF94: + CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY? +; $IF NE ;IF NOT, + JE $$IF96 + MOV SI, OFFSET BPB48_DOUBLE ;USE BPB48 DOUBLE +; $ELSE ; + JMP SHORT $$EN96 +$$IF96: + MOV SI, OFFSET BPB48_SINGLE ; +; $ENDIF ; +$$EN96: +; $ENDIF ; +$$EN94: + XOR AX, AX ; + MOV AL, END_OF_TRACK ; + + MOV MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM + MOV DI, OFFSET MS_deviceBPB ; + MOV CX, BPB96_LENG ; + REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB + + POP AX ; + RET ; +SET_FOR_THE_OLD ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC SET_TRACKLAYOUT ;AN000;MAKE ENTRY IN LINK MAP +SET_TRACKLAYOUT PROC NEAR ; + +;INPUT: BX - POINTER TO DESTINATION +;***************************************************************************** + + XOR CX, CX ; + MOV CL, END_OF_TRACK ; + MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF + ; SECTORS IN A TRACK + ADD BX, 2 ;NOW BX POINTS TO + ; THE FIRST SECTORNUMBER + MOV CX, 1 ; + MOV AX, bSECTOR_SIZE ; + +; $DO ; +$$DO100: + CMP CL, END_OF_TRACK ; +; $LEAVE A ; + JA $$EN100 + + MOV WORD PTR [BX], CX ; + INC BX ; + INC BX ; + MOV WORD PTR [BX], AX ; + INC BX ; + INC BX ; + + INC CX ; +; $ENDDO ; + JMP SHORT $$DO100 +$$EN100: + + RET ; +SET_TRACKLAYOUT ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC CHECK_TARGET ;AN000;MAKE ENTRY IN LINK MAP +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 ; +$$DO103: + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b + MOV CL, GETDEVPARM ;=60h + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER + ;WITH DEFAULT DEVICE INFO. + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? +; $ENDDO NE ; + JE $$DO103 + + CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB? + JE CT_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST. + + cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86 for 3.2 diskcopy + je ct_old ; + + cmp mt_deviceBPB.chead,0 ;cannot belive the info from dos + je ct_old ;sanity check for divide by 0. + + MOV AX, MT_deviceBPB.CTOTSECT ; + CWD ;CONVERT IT TO A DOUBLE WORD + DIV MT_deviceBPB.CSECT_TRACK ; + DIV MT_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS + DEC AX ;DECREASE BY 1 FOR THIS PROGRAM. + CMP LAST_TRACK, AL ;COMPARE WITH THE LAST TRACK OF SOURCE + JE CT_SECTOR_TRACK ;IF SAME, THEN CHECK SECTOR PER TRACK + ;SINCE NOT THE SAME, CONTINUE... + + CMP MT_deviceBPB.CSECT_TRACK,0FH ;AN012;IS TARGET 15 SEC / TRK? + JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE... + ;YES, 15 SEC/TRACK, CONTINUE... + + CMP LAST_TRACK,27H ;AN012;IS SOURCE ORIGINALLY 40 TRACK? + JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE... + ;YES, 40 TRACK, CONTINUE... + JMP CT_FATAL ;AN012;ABORT THIS, DO NOT MESS UP THE 1.2M + ; WITH NOBLE ATTEMPTS TO FORMAT +CT_SECTOR_TRACK: ; + MOV AX, MT_deviceBPB.CSECT_TRACK ; + CMP END_OF_TRACK, AL ; + JNE CT_FORMAT ; + +CT_BYTE_SECTOR: ; + MOV AX, MT_deviceBPB.CBYTE_SECT ; + CMP AX, bSECTOR_SIZE ; + JNE CT_FORMAT ; + +CT_HEAD: ; + MOV AX, MT_deviceBPB.CHEAD ; + DEC AX ; + CMP AL, NO_OF_SIDES ; + JB CT_FORMAT ;IF TARGET SIDE < SOURCE SIDE + ; THEN FORMAT IT. + + JMP CT_SET_DRV ;TARGET IS O.K. SET DRIVE PARM + ; AND EXIT + +CT_FORMAT: ; + PRINT MSGNUM_FORMATTING ;AC000;"Formatting while copying" + + MOV FORMAT_FLAG, ON ; + CALL FORMAT_ALL ;FORMAT ALL TRACKS STARTING + ; FROM TRACK_TO_WRITE + JMP CT_EXIT ; + +CT_OLD: ;AC011; + CMP UKM_ERR,ON ;AN011;IS THIS HARD ERROR "UNKNOWN MEDIA"? + JE CT_FORMAT ;AN011; IF SO, GO TRY FORMATTING + ;SAME OLD... ;AGAIN, THIS DOES + ; NOT RECOGNIZE 3.5 MEDIA + MOV READ_T_BPB_FAILURE, 1 ;SET THE FLAG + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV IOCTL_TRACK, 0 ; + MOV IOCTL_SECTOR, 8 ; + MOV IOCTL_HEAD, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8 + CALL READ_A_SECTOR ; + + JC CT_FORMAT ;ASSUME TARGET MEDIA NOT FORMATTED. + + MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9 + CALL READ_A_SECTOR ; + + JC CT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA + + MOV IOCTL_SECTOR, 15 ; + CALL READ_A_SECTOR ; + + JC CT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA + +;CT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA + CMP END_OF_TRACK, 15 ;IS SOURCE ALSO 96 TPI? + JNE CT_FATAL ;NO, FATAL ERROR + + JMP CT_EXIT_OLD ;OK + +CT_8_SECTOR: ; + CMP END_OF_TRACK, 15 ; + JE CT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR + + CMP END_OF_TRACK, 9 ; + JE CT_FORMAT ;IF SOURCE IS 9 SECTOR, THEN + ; SHOULD FORMAT TARGET + + JMP CT_EXIT_OLD ;ELSE ASSUME SOURCE IS 8 SECTOR. + +CT_9_SECTOR: ; + CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI ? + JNE CT_EXIT_OLD ;NO. SOUCE IS 8 OR 9 + ; SECTORED 48 TPI DISKETTE + +CT_FATAL: ; + MOV COPY_STATUS, FATAL ; + ;"Drive types or diskette types" + PRINT MSGNUM_NOT_COMPATIBLE ;AC000;"not compatible" + + JMP SHORT CT_EXIT ; + +CT_EXIT_OLD: ; + MOV CX, MS_deviceBPB_leng ; + MOV SI, OFFSET MS_deviceBPB ; + MOV DI, OFFSET MT_deviceBPB ; + REP MOVSB ;set MT_deviceBPB to MS_deviceBPB +CT_SET_DRV: ; + MOV T_DRV_SET_FLAG, 1 ;INDICATE THE TARGET DEFAULT + ; DEVICE PARM HAS BEEN SET. + XOR BX, BX ; + mov bl, last_track ;patch for 3.2 diskcopy, 3/27/86 J.K. + inc bl ; + mov MT_numberOfCylinders, bx ;make sure the # of cyl of the target + MOV BL, TARGET_DRIVE ; + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + MOV MT_specialFunctions, SET_SP_FUNC_DEF ; + CALL SET_DRV_PARM_DEF ; + +CT_EXIT: ; + RET ; + +CHECK_TARGET ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC CHK_MULTI_MEDIA ;AN000;MAKE ENTRY IN LINK MAP +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 +;***************************************************************************** + CLC ;CLEAR CARRY + CMP LAST_TRACK, 39 ;SOURCE IS 48 TPI MEDIA? +; $IF E,AND ; + JNE $$IF105 + CMP AL, 79 ;AND TARGET IS 96 TPI MEDIA? +; $IF E ; + JNE $$IF105 + STC ;THEN SET CARRY +; $ELSE ; + JMP SHORT $$EN105 +$$IF105: + CMP LAST_TRACK, 79 ;SOURCE IS 96 TPI MEDIA? +; $IF E,AND ; + JNE $$IF107 + CMP AL, 39 ;AND TARGET IS 48 TPI? +; $IF E ; + JNE $$IF107 + STC ; +; $ENDIF ; +$$IF107: +; $ENDIF ; +$$EN105: + RET ; +CHK_MULTI_MEDIA ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC SET_DRV_PARM_DEF ;AN000;MAKE ENTRY IN LINK MAP +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 +;***************************************************************************** + MOV CL, SETDEVPARM ;=40H + CALL GENERIC_IOCTL ; + + RET ; +SET_DRV_PARM_DEF ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC CHK_MEDIATYPE ;AN000;MAKE ENTRY IN LINK MAP +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. +;***************************************************************************** + + MOV AL, T_DRV_TRACKS ;TARGET DEVICE MAXIUM TRACKS + DEC AL ; + CMP LAST_TRACK, AL ;COMPARE SOURCE MEDIA # OF TRACKS TO IT +; $IF B,OR ; + JB $$LL110 + MOV AL, T_DRV_SECT_TRACK ; + CMP END_OF_TRACK, AL ;SOURCE # OF SECT/TRACK < TARGET DEVICE? +; $IF B ; + JNB $$IF110 +$$LL110: + MOV MT_mediaType, 1 ; +; $ENDIF ; +$$IF110: + RET ; +CHK_MEDIATYPE ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC GENERIC_IOCTL ;AN000;MAKE ENTRY IN LINK MAP +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 +;***************************************************************************** + MOV IO_ERROR, NO_ERROR ;reset io_error + MOV CH, MAJOR_CODE ;MAJOR CODE, REMOVABLE = 08H + DOSCALL IOCTL_FUNC,GENERIC_IOCTL_CODE ;AC000;(440DH) CALL THE DEVICE DRIVER + +; $IF C ; + JNC $$IF112 + CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS! + +; $ENDIF ; +$$IF112: + RET ; +GENERIC_IOCTL ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC EXTENDED_ERROR_HANDLER ;AN000;MAKE ENTRY IN LINK MAP +EXTENDED_ERROR_HANDLER PROC NEAR ; +;INPUT: BL - LOGICAL DRIVE LETTER +;***************************************************************************** + + PUSHF ; + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + PUSH SI ; + PUSH DI ; + PUSH ES ; + PUSH DS ; + PUSH BX ; + + MOV AH, EXTENDED_ERROR ;59H + MOV BX, 0 ; + INT 21H ; + + POP BX ;RESTORE BL FOR DRIVE LETTER + POP DS ; + POP ES ; + + CMP AX, 21 ;DRIVE NOT READY? (TIME_OUT ERROR?) + JE EEH_CHK_TIMEOUT ; + + CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED? + JE WARN_USER_2 ; + + JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR + +EEH_CHK_TIMEOUT: ;BECAUSE OF THE INACCURACY + ; OF TIME OUT ERROR, + ;IN READING AND WRITING OPERATION, + ; CHECK OUT CAREFULLY WITH "FORMAT" + CMP FORMAT_FLAG, ON ;AFTER OR DURING FORMAT OPERATION, + JE WARN_USER_1 ; TIME OUT ERROR IS + ; ASSUMED TO BE CORRECT. + + CMP TRY_FORMAT_FLAG, ON ;HAPPENED AT "TRY_FORMAT" PROCEDURE? + JE EEH_TIMEOUT ; + + CMP TARGET_OP, ON ;HAPPENED ON TARGET DRIVE? + JNE WARN_USER_1 ;IF NOT, THEN ASSUME TIME OUT ERROR + + MOV TRY_FORMAT_FLAG, ON ; + CALL TRY_FORMAT ;JUST TRY TO FORMAT THE TRACK. + + MOV TRY_FORMAT_FLAG, OFF ; + CMP TIME_OUT_FLAG, ON ;REAL TIME OUT? + JE WARN_USER_1 ;YES, A SOFT ERROR. + + CMP IO_ERROR, SOFT_ERROR ;IT HAPPENED AT TRY_FORMAT PROC AND + ; PC_AT WHEN THE DRIVE DOOR OPENED ABRUPTLY. + JE EEH_EXIT ;IT WAS WRITE PROTECTED ERROR. + + JMP EEH_HARD_ERROR ;NO, "ADDRESS MARK NOT OUT". A HARD ERROR. + +EEH_TIMEOUT: ; + MOV TIME_OUT_FLAG, ON ;SET TIME_OUT_FLAG AND EXIT THIS ROUTINE + JMP EEH_EXIT ; + +WARN_USER_1: ; + MOV DRIVE_LETTER, 'A' ; + DEC BL ;CHANGE LOGICAL TO PHYSICAL + ADD DRIVE_LETTER, BL ; + PRINT MSGNUM_GET_READY ;AC000;"Drive not ready - %0" + + PRINT MSGNUM_CLOSE_DOOR ;AN004;"Make sure a diskette is inserted into + ; the drive and the door is closed" + JMP WAIT_FOR_USER ; + +WARN_USER_2: ; + PRINT MSGNUM_WRITE_PROTECT ;AC000;"Attempt to write to write-protected diskette" + +WAIT_FOR_USER: ; + ;"Press any key when ready . . ." + CALL PRESS_ANY_KEY ;AC000; THEN WAIT FOR ANY RESPONSE + + MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN + JMP SHORT EEH_EXIT ; + +EEH_HARD_ERROR: ; + MOV IO_ERROR, HARD_ERROR ; + MOV UKM_ERR,OFF ;AN011;ASSUME NOT "UNKNOWN MEDIA" TYPE ERROR + CMP AX,26 ;AN011;IS THE ERROR TYPE IS "UNKNOWN MEDIA"? +; $IF E ;AN011;IF "UNKNOWN MEDIA" TYPE ERROR + JNE $$IF114 + MOV UKM_ERR,ON ;AN011;SET FLAG TO INDICATE "UNKNOWN MEDIA" + ; TO CAUSE FORMATTING OF TARGET DISKETTE +; $ENDIF ;AN011; +$$IF114: + +EEH_EXIT: ; + POP DI ; + POP SI ; + POP DX ; + POP CX ; + POP BX ; + POP AX ; + POPF ; + RET ; +.XLIST ; +;EEH_JUST_EXIT: +; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT (IN MAIN PROC) +.LIST ; +EXTENDED_ERROR_HANDLER ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** + PUBLIC TRY_FORMAT ;AN000;MAKE ENTRY IN LINK MAP +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. +;***************************************************************************** + PUSH ES ; + + PUSH DS ; + POP ES ; + + MOV CX, MS_deviceBPB_leng ;set length of BPB + MOV SI, OFFSET MS_deviceBPB ; + MOV DI, OFFSET MT_deviceBPB ; + REP MOVSB ; + CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation + + MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B + MOV CL, SETDEVPARM ;=40h + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + CALL GENERIC_IOCTL ; + + XOR AX, AX ; + MOV AL, SIDE ;SIDE TO FORMAT + MOV Fhead, AX ; + MOV AL, TRACK_TO_WRITE ;TRACK TO FORMAT + MOV Fcylinder, AX ; + + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV CL, FORMAT_FUNC ;=42h + MOV DX, OFFSET IOCTL_FORMAT ; + CALL GENERIC_IOCTL ; + + MOV AL, IO_ERROR ;SAVE IO_ERROR, IN CASE FOR PC_AT CASE. + PUSH AX ; + + XOR BX, BX ; + MOV BL, TARGET_DRIVE ; + MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET + MOV DX, OFFSET MT_IOCTL_DRV_PARM ; + MOV MT_specialFunctions, SET_SP_FUNC_DEF ; + CALL SET_DRV_PARM_DEF ;SET IT BACK FOR NORMAL + ; OPERATION, EX. WRITING + + POP AX ; + MOV IO_ERROR, AL ;RESTORE IO_ERROR + + POP ES ; + + RET ; + +TRY_FORMAT ENDP ; +; = = = = = = = = = = = = + HEADER ;AN000; +;***************************************************************************** +; * +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) * +; * +;***************************************************************************** + CMP AH,READ_FUNC ;ERROR DURING READ ? +.XLIST ; +; $IF E +; MOV BX,OFFSET READ_ERROR +; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING READ OP +; MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ +; $ELSE +; MOV BX,OFFSET WRITE_ERROR +; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING WRITE OP +; MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE +; $ENDIF +.LIST ; +; $IF E ;AN000;YES, READ ERROR + JNE $$IF116 + MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ + MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ;AN000; +; $ELSE ;AN000;NO, NOT READ, MUST BE WRITE ERROR + JMP SHORT $$EN116 +$$IF116: + MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE + MOV DI,OFFSET MSGNUM_HARD_ERROR_WRITE ;AN000; +; $ENDIF ;AN000;READ ERROR? +$$EN116: + MOV AL,SIDE ; + MOV DRIVE_LETTER,"A" ; + dec dl ;change logical drive letter to physical one. + ADD DRIVE_LETTER,DL ;SHOW DRIVE LETTER +.XLIST ; +; MOV BYTE PTR MSG_HARD_ERROR_PTR+8,AL ;SIDE NUMBER +; MOV BYTE PTR MSG_HARD_ERROR_PTR+10,BL ;TRACK NUMBER WHERE THE ERROR +.LIST ; + MOV BYTE PTR ERROR_SIDE_NUMBER,AL ;AC000;SIDE NUMBER + MOV BYTE PTR ERROR_TRACK_NUMBER,BL ;AC000;TRACK NUMBER WHERE THE ERROR + ;CR,LF,"Unrecoverable read/write error on drive %1",CR,LF + CALL SENDMSG ;"Side %2, track %3",CR,LF ;ACN000; + + RET ; +ERROR_MESSAGE ENDP ; +.XLIST ; +; HEADER +;KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT +;***************************************************************************** +; * +;PROMPT PROC NEAR ;DISPLAY MESSAGE * +; AND GET A USER INPUT CHARACTER * +; PUBLIC PROMPT * +; * +; INPUT: DX = MESSAGE POINTER * +; OUTPUT: BYTE USER_INPUT * +; * +;***************************************************************************** +; PUSH AX +; MOV AX,KB_INPUT_FUNC ;KEYBOARD INPUT +; INT 21H +; MOV USER_INPUT,AL ;SAVE USER'S RESPONSE +; POP AX +; RET +;PROMPT ENDP +; HEADER +;CALL_PRINTF PROC NEAR +; PUBLIC CALL_PRINTF +;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST +; PUSH DX +; PUSH CS +; CALL PRINTF + +; RET +;CALL_PRINTF ENDP +; = = = = = = = = = = = = +.list ; + HEADER ;AN000; +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 +; = = = = = = = = = = = = + + PUSH BX ;AN000;SAVE CALLER'S REGS + PUSH CX ;AN000; + PUSH DX ;AN000; + PUSH SI ;AN000; + +; PASS PARMS TO MESSAGE HANDLER IN +; THE APPROPRIATE REGISTERS IT NEEDS. + MOV BX,[DI].MSG_NUM ;AC006;MESSAGE NUMBER + MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE + MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE + MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW + MOV AX,SELECT_MPX ;AN006;REQUEST THE SELECT MULTIPLEXOR, IF PRESENT + INT MULTIPLEXOR ;AN006;CALL THE MULTIPLEXOR FUNCTION + + CMP AL,SELECT_PRESENT ;AN006;CHECK MULTIPLEXOR RESPONSE CODE +; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE + JE $$IF119 + MOV AX,[DI].MSG_NUM ;AN000;MESSAGE NUMBER + MOV BX,[DI].MSG_HANDLE ;AN006;HANDLE TO DISPLAY TO + CALL SYSDISPMSG ;AN000;DISPLAY THE MESSAGE + +; $IF C ;AN000;IF THERE IS A PROBLEM + JNC $$IF120 + ;AX=EXTENDED ERROR NUMBER ;AN000; + LEA DI,MSGNUM_EXTERR ;AN000;GET REST OF ERROR DESCRIPTOR + MOV BX,[DI].MSG_HANDLE ;AN000;HANDLE TO DISPLAY TO + MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE + MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE + MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW + CALL SYSDISPMSG ;AN000;TRY TO SAY WHAT HAPPENED + + STC ;AN000;REPORT PROBLEM +; $ENDIF ;AN000;PROBLEM WITH DISPLAY? +$$IF120: +; $ELSE ;AN006;SINCE SELECT DID THE MESSAGE + JMP SHORT $$EN119 +$$IF119: + MOV SELECT_FLAG,TRUE ;AN006;INDICATE SELECT IS DOING THE MESSAGES + CLC ;AN006;GENERATE A "NO PROBLEM" RESPONSE +; $ENDIF ;AN006;DID SELECT HANDLE THE MESSAGE? +$$EN119: + + POP SI ;AN000;RESTORE CALLER'S REGISTERS + POP DX ;AN000; + POP CX ;AN000; + POP BX ;AN000; + + RET ;AN000; +SENDMSG ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +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" +; = = = = = = = = = = = = + + CMP SELECT_FLAG,TRUE ;AN006;IS SELECT DOING THE MESSAGES? +; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE + 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; + MOV AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;AN000;(6523H) GET EXTENDED + ; COUNTRY INFORMATION, (Y/N) + INT 21H ;AN000;SEE IF Y OR N + +; $ELSE ;AN006;SINCE SELECT IS NOT PRESET + JMP SHORT $$EN124 +$$IF124: + MOV AX,NO ;AN006;ASSUME RESPONSE WAS 'NO' +; $ENDIF ;AN006; +$$EN124: + RET ;AN000;RETURN TO CALLER +YESNO ENDP ;AN000; +; = = = = = = = = = = = = +;(deleted ;AN013;) HEADER ;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 ;AN000; +WRITE_VOLSER PROC NEAR ;AN000; + PUBLIC WRITE_VOLSER ;AN000;MAKE ENTRY IN LINK MAP + CMP VOLSER_FLAG,TRUE ;AN000;IF NEW NUMBER READY TO BE WRITTEN +; $IF E ;AN000;THEN WRITE IT + 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. + + LEA AX,SERIAL ;AC013;GET POINTER TO DATA TO BE PRINTED + MOV SUBLIST_26B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST + + LEA AX,SERIAL+WORD ;AC013;GET POINTER TO DATA TO BE PRINTED + MOV SUBLIST_26A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST + + PRINT MSGNUM_CR_LF ;AN000;SKIP A SPACE + + ;"Volume Serial Number is %1-%2" + PRINT MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER + +; $ENDIF ;AN000; +$$IF127: + RET ;AN000;RETURN TO CALLER +WRITE_VOLSER ENDP ;AN000; +; = = = = = = = = = = = = = = = = = = = + HEADER ;AN000; +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 + + PRINT MSGNUM_STRIKE ;AN000;"Press any key when ready..." + + RET ;AN000;RETURN TO CALLER +PRESS_ANY_KEY ENDP ;AN000; +; = = = = = = = = = = = = + PUBLIC DISKCOPY_END ; +DISKCOPY_END LABEL NEAR ; + + PATHLABL DISKCOPY ;AN015; +CSEG ENDS ; + END DISKCOPY ; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU b/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU new file mode 100644 index 0000000..914fc43 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.EQU @@ -0,0 +1,207 @@ + IF1 ; + %OUT COMPONENT=DISKCOPY, INCLUDING DISKCOPY.EQU... ; + ENDIF ; +; $SALUT (4,21,26,36) +;---------------------------------------------------------------------------; +; EQUATES ; +;---------------------------------------------------------------------------; + +; *** CONSTANTS *** + +ZERO EQU 0 ; +ONE EQU 1 ; +TWO EQU 2 ; +THREE EQU 3 ; +FOUR EQU 4 ; +TYPE_4 EQU 4 ; +FIVE EQU 5 ; +SIX EQU 6 ; +SEVEN EQU 7 ; +EIGHT EQU 8 ; +NINE EQU 9 ; +TEN EQU 0AH ; +ON EQU 1 ; +OFF EQU 0 ; +TRUE EQU 01 ; +FALSE EQU 00 ; +GOOD EQU 0 ; +BAD EQU 1 ; +FIRST EQU 1 ; +SECOND EQU 2 ; +NO_ERROR EQU 0 ; +SOFT_ERROR EQU 1 ; +HARD_ERROR EQU 2 ; + +BLANK EQU 20H ;BLANK IN ASCII (32 DEC) +CLEAR_SEGMENT EQU 0E0H ;USED TO CLEAR SEGMENT BITS (ROUND UP + ;TO NEXT SECTOR) +SECTOR8 EQU 8 ; +SECTOR9 EQU 9 ; +SECTOR14 EQU 14 ; +SECTOR15 EQU 15 ; +DRV_48TPI EQU 0 ;48 TPI DRIVE +DRV_96TPI EQU 1 ;96 TPI DRIVE +DRV_720 EQU 2 ;3.5", 720 KB DRIVE (FOR CASHEW OR P14) +NRLFUNC EQU 5F02H ;GET NETWORK-REDIRECTION-LIST FUNCTION +NRLMAX EQU 1CH ;(MAXIMUM # OF NAMES ON NRL) - 1 +DOS20 EQU 2 ;DOS VERSION 2.0 + PUBLIC FINE ;AN000;PARSER NEEDS IT +FINE EQU -1 ;"FINE AND DANDY", USED FOR RETURN CODE + ;(-1 WAS USED TO AVOID CONFUSION WITH ERROR + ;OFFSET WHICH CAN BE ZERO) +LOCAL_DRV EQU -1 ;DEVICE NOT DIRECTED +REMOTE_DRV EQU 1000H ;REMOTE DRIVE TEST BITS +NO_OPTION EQU -1 ;NO OPTION "/1" SPECIFIED +OPTION_1 EQU 1 ;OPTION "/1" SPECIFIED +REMOVABLE EQU 0000H ;REMOVABLE FILE +INVAL_PARM EQU -9 ;INVALID PARAMETER ENTERED +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; *** COPY STATUS BYTE *** + +FATAL EQU 01H ;FATAL COPY ERROR, ABORT +OK EQU 00H ;OK, PROCEED +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; *** PROGRAM SEGMENT PREFIX *** + +FCB1_DRV_ID EQU 5CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 1 +FCB1_FILENM EQU 5DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 1 +FCB2_DRV_ID EQU 6CH ;DRIVE NUMBER ADDR IN FILE CONTROL BLOCK 2 +FCB2_FILENM EQU 6DH ;FILE NAME ADDR IN FILE CONTROL BLOCK 2 +BEGIN_UNFORM_AREA EQU 80H ;BEGINNING @ OF THE UNFORMATTED AREA +END_UNFORM_AREA EQU 100H ;ENDING @ OF THE UNFORMATTED AREA +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; *** DOS FUNCTONS *** + +KB_INPUT_FUNC EQU 01H ;DOS KEYBOARD INPUT FUNCTION +PRINT_FUNC EQU 09H ;DOS PRINT STRING FUNCTION +REDIRECTED_FUNC EQU 09H ;IOCTL SUB FUNCTION ****** TO BE CHECKED **** +CURRENTDRV_FUNC EQU 19H ;GET CURRENT DRIVE FUNCTION CALL +DOSVER_FUNC EQU 30H ;DOS VERSION FUNCTION CALL +IOCTL_FUNC EQU 44H ;IOCTL FUNCTION CALL +GET_DISKBASE_VECTOR EQU 351EH ; +SET_DISKBASE_VECTOR EQU 251EH ; +GET_CTL_BREAK_VECT EQU 3523H ;AN000;GET VECTOR FOR INT 23H (CTRL-BREAK) +SET_CTL_BREAK_VECT EQU 2523H ;AN000;SET VECTOR FOR INT 23H (CTRL-BREAK) +DRIVE_CHECK EQU 4408H ;DOS CHECK FOR REMOVABLE DRIVE IOCTL CALL +STD_ERROR EQU 0002H ;STANDARD ERROR FILE HANDLE +WRITE_FILE EQU 40H ;WRITE TO FILE OR DEVICE FUNCTION CALL +GET_ASSIGN_MODE EQU 5F00H ;SET ASSIGN MODE COMMAND +SET_ASSIGN_MODE EQU 5F01H ;SET ASSIGN MODE COMMAND +SERVER EQU 2AH ;NETWORK SERVER INTERUPT +SHARED EQU 03H ;DEVICE SHARED CHECK +EXTENDED_ERROR EQU 59H ;EXTENDED ERROR +GET_DATE EQU 2AH ;AN000;READ SYSTEM DATE +GET_TIME EQU 2CH ;AN000;READ SYSTEM TIME CLOCK +RET_CD_EXIT EQU 4CH ;AN000;EXIT TO DOS, PASSING RETURN CODE +GET_EXT_CNTRY_INFO EQU 65H ;AN000;GET EXTENDED COUNTRY INFORMATION +YESNO_CHECK EQU 23H ;AN000;REQUEST (Y/N) CHECK OF GET_EXT_CNTRY_INFO +NO EQU 0 ;AN006;(Y/N) RESPONSE IS "NO" +YES EQU 1 ;AN000;(Y/N) RESPONSE IS "YES" +BAD_YESNO EQU 2 ;AN000;(Y/N) RESPONSE IS NEITHER "Y" NOR "N" +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; *** IOCTL DISKETTE I/O FUNCTONS *** +GENERIC_IOCTL_CODE EQU 0DH ;GENERIC IOCTL REQUEST +MAJOR_CODE EQU 08H ;GENERIC IOCTL MAJOR CODE +READ_FUNC EQU 61H ;IOCTL DISKETTE READ FUNCTION +WRITE_FUNC EQU 41H ;IOCTL DISKETTE WRITE FUNCTION +VERIFY_FUNC EQU 62H ;IOCTL DISKETTE VERIFY FUNCTION +FORMAT_FUNC EQU 42H ;IOCTL DISKETTE FORMAT FUNCTION +GETDEVPARM EQU 60H ;IOCTL GET DEVICE PARAMETER +SETDEVPARM EQU 40H ;IOCTL SET DEVICE PARAMETER +SET_LOGIC_DRIVE EQU 0FH ;AN000;IOCTL SET LOGICAL DRIVE +;(deleted ;AN013) GSET_MEDIA_ID EQU 69H ;GET OR SET MEDIA ID ;AN009; +;(deleted ;AN013) GET_ID EQU 0 ;AL=0;GET MEDIA ID ;AN009; +;(deleted ;AN013) SET_ID EQU 1 ;AL=1;SET MEDIA ID ;AN009; + +;special Functions +GET_SP_FUNC_DEF EQU 00000000B ;GET DEVICE PARM. DEFAULT BPB +GET_SP_FUNC_MED EQU 00000001B ;GET DEVICE PARM. BOOT BPB +SET_SP_FUNC_DEF EQU 00000100B ;SET DEFAULT DEVICE PARM +SET_SP_FUNC_DOS EQU 00000100B ;SET DEVICE PARM BEFORE RETURN TO DOS. +SET_SP_BF_FORM EQU 00000101B ;SET DEV PARM BEFORE FORMAT +R_W_SP_FUNC EQU 00000000B ;READ, WRITE +STATUS_CHK EQU 00000001B ;USED IN FORMAT PACKET AND VALIDATE + ;THE "SET DEVICE PARM" REQUEST. +FORMAT_SP_FUNC EQU 00000000B ;FORMAT +.XLIST ; +;READ_DASD_FUNC EQU 15H ;BIOS READ DASD TYPE (DISKETTE DRIVE TYPE) +;SET_DASD_FUNC EQU 17H ;BIOS SET DASD TYPE +;COMPARE_FUNC EQU 03H ;BIOS COMPARE FUNC # FOR ERROR MSG PROC +.LIST ; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; *** BIOS DISKETTE I/O ERROR CODES *** + +;NOT_READY EQU 80H ;DISKETTE I/O NOT READY ERROR +;CHANG_LINE EQU 06H ;CHANGE LINE ERROR +;BAD_CONTROLLER EQU 20H ;BAD DISKETTE/DISK CONTOROLLER +;WRITE_PROTECT EQU 03H ;DISKETTE I/O WRITE PROTECT ERROR +;BAD_ADDR_MARK EQU 02H ;DISKETTE I/O BAD ADDRESS MARK ERROR +;REC_NOT_FOUND EQU 04H ;DISETTTE I/O RECORD NOT FOUND ERROR +;BAD_CRC EQU 10H ;DISKETTE I/O BAD CRC ERROR +;HARD_WR_ERROR EQU 03H ;DISKETTE WRITE HARD ERROR COUNT +;HARD_FMT_ERROR EQU 02H ;DISKETTE FORMAT HARD ERROR COUNT +;SINGLE_SIDE_COPY EQU 00H ;WHEN READING TRACK 0 SIDE 1 IF HARD ERROR + ;OCCURS, WE WILL ASSUME IT WILL BE SINGLE + ;SIDED COPY AND AL WILL BE SET TO 0, SO THAT + ;BUFFER_PTR WILL NOT BE ADVANCED AND + ;IF THE TRACK HAPPENS TO FALL INTO DMA BOUNDRY + ;IT WILL SKIP THE SECOND PART OF READ_TRACK +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; SYSTEM MESSAGE HANDLER EQUATES +EXT_ERR_CLASS EQU 01H ;AN000;DOS Extended error class +PARSE_ERR_CLASS EQU 02H ;AN000;Parse error class +UTILITY_MSG_CLASS EQU 0FFH ;AN000;Utility message class +CLASS_A EQU UTILITY_MSG_CLASS ;AN000;IN MSG DESCRIPTOR +MAX_0 EQU 0 ;AN000;MAXIMUM WIDTH OF STRING FIELD (0=NO LIMIT) +PAD_BLK EQU " " ;AN000;CHAR FOR PAD FIELD +STDOUT EQU 0001H ;AN000;Standard Output device handle +STDERR EQU 0002H ;AN000;Standard Error Output device handle + +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; SELECT MULTIPLEXOR INTERFACE +SELECT_MPX EQU 0ADC1H ;AN006;THE SELECT MULTIPLEXOR ID +SELECT_PRESENT EQU 0FFH ;AN006;RESPONSE IN AL, IF SELECT IS PRESENT +MULTIPLEXOR EQU 2FH ;AN006;THE MULTIPLEXOR INTERRUPT NUMBER +;---------------------------------------------------------------------------; +; CONTROL BLOCKS (STRUCS) ; +;---------------------------------------------------------------------------; + +MSG_DESC STRUC ; +MSG_NUM DW 0 ;AN000;MESSAGE NUMBER (TO AX) +MSG_HANDLE DW STDOUT ;AN000;HANDLE OF OUTPUT DEVICE (TO BX) +MSG_SUBLIST DW 0 ;AN000;POINTER TO SUBLIST (TO SI) +MSG_COUNT DW 0 ;AN000;SUBSTITUTION COUNT (TO CX) +MSG_CLASS DW CLASS_A SHL 8 ;AN000;MESSAGE CLASS (IN HIGH BYTE, TO DH) + ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN000; +MSG_DESC ENDS ;AN000; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +SUBLIST STRUC ;AN000; +SUB_SIZE DB 11 ;AN000;SUBLIST SIZE (POINTER TO NEXT SUBLIST) +SUB_RES DB 0 ;AN000;RESERVED + ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD +SUB_VALUE DW 0 ;AN000;TIME, DATE, OR PTR TO DATA ITEM +SUB_VALUE_SEG DW 0 ;AN000;SEG ID OF PTR + ;(ABOVE FIELD MUST BE FILLED AT EXECUTION + ; TIME, IF THIS IS A .COM FILE) +SUB_ID DB 0 ;AN000;N OF %N +SUB_FLAGS DB 0 ;AN000;DATA TYPE FLAGS +SUB_MAX_WIDTH DB MAX_0 ;AN000;MAXIMUM FIELD WIDTH (0=UNLIMITED) +SUB_MIN_WIDTH DB 0 ;AN000;MINIMUM FIELD WIDTH +SUB_PAD_CHAR DB PAD_BLK ;AN000;CHARACTER FOR PAD FIELD + ; CAN BE " ", "0" OR ",". + ; "," CAUSES INSERTION OF THE ACTIVE + ; THOUSANDS SEPARATOR BETWEEN EVERY + ; 3 DIGITS. +SUBLIST ENDS ;AN000; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +;BUFFER AREA FOR COMMUNICATION WITH GET/SET MEDIA ID FUNCTION CALL +; (USED BY VOLSER PROC) + +;(deleted ;AN013;) A_MEDIA_ID_INFO STRUC ; ;AN000; +;(deleted ;AN013;) MI_LEVEL DW 0 ;INFO LEVEL ;AN000; +;(deleted ;AN013;) MI_SERIAL DD 0 ;SERIAL # ;AN000; +;(deleted ;AN013;) MI_LABEL DB 11 DUP (' ') ;VOLUME LABEL ;AN000; +;(deleted ;AN013;) MI_SYSTEM DB 8 DUP (' ') ;FILE SYSTEM TYPE ;AN000; +;(deleted ;AN013;) A_MEDIA_ID_INFO ENDS ; ;AN000; + +;END OF DISKCOPY.EQU diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK b/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK new file mode 100644 index 0000000..b0eaaff --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.LNK @@ -0,0 +1,6 @@ +DISKCOPY.OBJ+ +DCOPYSM.OBJ+ +DCOPYP.OBJ+ +DCOPYPAR.OBJ+ +COPYINIT.OBJ; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL b/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL new file mode 100644 index 0000000..bc346ac --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.SKL @@ -0,0 +1,65 @@ +:util DISKCOPY ;AN000;utility name +:class A ;AN000;system messages +:use 1 COMMON1 ;AN000;MSG 1 is always "Incorrect DOS version" + +:def 2 CR,LF ;AN000; + +:use 3 PARSE10 ;AN000;CR,LF,"Invalid parameter",CR,LF + +:def 4 "Do not specify filename(s)",CR,LF ;AN000; +"Command Format: DISKCOPY d: d: [/1]",CR,LF ;AN000; + +:def 5 CR,LF,"Invalid drive specification",CR,LF ;AN000; +"Specified drive does not exist",CR,LF ;AN000; +"or is non-removable",CR,LF ;AN000; + +:def 6 CR,LF,"Cannot DISKCOPY to or from",CR,LF ;AN000; +"a network drive",CR,LF ;AN000; + +:def 7 CR,LF,"Formatting while copying",CR,LF ;AN000; + +:def 8 CR,LF,"Insert SOURCE diskette in drive %1:",CR,LF ;AN000; + +:def 9 CR,LF,"Insert TARGET diskette in drive %1:",CR,LF ;AN000; + +:def 10 "Make sure a diskette is inserted into",CR,LF ;AN004; +"the drive and the door is closed",CR,LF ;AN004; + +:def 11 CR,LF,"Target diskette may be unusable",CR,LF ;AN000; + +:def 12 CR,LF,"Target diskette unusable",CR,LF ;AN000; + +:use 13 EXTEND21 ;AN000;CR,LF,Drive not ready",CR,LF + +:use 14 EXTEND19 ;AN000;CR,LF,"Attempt to write to write-protected diskette",CR,LF + +:use 15 COMMON28 ;AN000;CR,LF,"Press any key to continue . . .",CR,LF + +:def 16 CR,LF,"Copy another diskette (Y/N)? " ;AN000; + +:def 17 CR,LF,"Copying %1 tracks",CR,LF ;AN000; +"%2 Sectors/Track, %3 Side(s)",CR,LF ;AN000; + +:def 18 CR,LF,"Drive types or diskette types",CR,LF ;AN000; +"not compatible",CR,LF ;AN000; + +:def 19 CR,LF,"Unrecoverable read error on drive %1",CR,LF ;AN000; +"Side %2, track %3",CR,LF ;AN000; + +:def 20 CR,LF,"Unrecoverable write error on drive %1",CR,LF ;AN000; +"Side %2, track %3",CR,LF ;AN000; + +:def 21 CR,LF,"Copy process ended",CR,LF ;AN000; + +:def 22 CR,LF,"SOURCE diskette bad or incompatible",CR,LF ;AC008; + +:def 23 CR,LF,"TARGET diskette bad or incompatible",CR,LF ;AC008; + +:use 25 EXTEND8 ;AN000;"Insufficient memory",CR,LF + +:use 26 COMMON36 ;AN001;"Volume Serial Number is %1-%2",CR,LF + +:end ;AN000; +lume Serial Number is %1-%2",CR,LF + +:end \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOPY/MAKEFILE b/v4.0/src/CMD/DISKCOPY/MAKEFILE new file mode 100644 index 0000000..9a3e564 --- /dev/null +++ b/v4.0/src/CMD/DISKCOPY/MAKEFILE @@ -0,0 +1,57 @@ +#************************** makefile for cmd\append *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h + +# +####################### dependencies begin here. ######################### +# + +all: diskcopy.com + +diskcopy.ctl: diskcopy.skl \ + $(msg)\$(COUNTRY).msg \ + makefile + +diskcopy.obj: diskcopy.asm \ + makefile \ + dcpymacr.inc \ + diskcopy.equ \ + $(inc)\bootform.inc + +copyinit.obj: copyinit.asm \ + makefile \ + dcpymacr.inc \ + diskcopy.equ + +dcopyp.obj: dcopyp.asm \ + makefile \ + $(inc)\parse.asm + +dcopysm.obj: dcopysm.asm \ + makefile \ + $(inc)\sysmsg.inc \ + $(inc)\msghan.inc \ + $(inc)\versiona.inc \ + diskcopy.ctl \ + diskcopy.cla \ + diskcopy.cl1 \ + diskcopy.cl2 \ + dcopyms.inc \ + $(inc)\copyrigh.inc + +dcopypar.obj: dcopypar.asm \ + makefile + +diskcopy.com: diskcopy.obj \ + makefile \ + diskcopy.lnk \ + dcopysm.obj \ + dcopyp.obj \ + dcopypar.obj \ + copyinit.obj + link @diskcopy.lnk + exe2bin diskcopy.exe diskcopy.com + del diskcopy.exe -- cgit v1.2.3