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/DISKCOMP/COMPINIT.ASM | 1123 ++++++++++++++++++++ v4.0/src/CMD/DISKCOMP/DCMPMACR.INC | 171 +++ v4.0/src/CMD/DISKCOMP/DCOMPMS.INC | 232 ++++ v4.0/src/CMD/DISKCOMP/DCOMPP.ASM | 123 +++ v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM | 427 ++++++++ v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM | 159 +++ v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM | 2060 ++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU | 170 +++ v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK | 6 + v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL | 56 + v4.0/src/CMD/DISKCOMP/MAKEFILE | 59 ++ 11 files changed, 4586 insertions(+) create mode 100644 v4.0/src/CMD/DISKCOMP/COMPINIT.ASM create mode 100644 v4.0/src/CMD/DISKCOMP/DCMPMACR.INC create mode 100644 v4.0/src/CMD/DISKCOMP/DCOMPMS.INC create mode 100644 v4.0/src/CMD/DISKCOMP/DCOMPP.ASM create mode 100644 v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM create mode 100644 v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM create mode 100644 v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM create mode 100644 v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU create mode 100644 v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK create mode 100644 v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL create mode 100644 v4.0/src/CMD/DISKCOMP/MAKEFILE (limited to 'v4.0/src/CMD/DISKCOMP') diff --git a/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM b/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM new file mode 100644 index 0000000..245b78c --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/COMPINIT.ASM @@ -0,0 +1,1123 @@ + PAGE 90,132 ;A2 + TITLE COMPINIT -- DISKCOMP INITIALIZATION PROGRAM +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: COMPINIT + +; DESCRIPTIVE NAME: Initialization for Diskette to diskette copy Utility + +;FUNCTION: DISKCOMP is to compare the contents of the diskette in the +; specified source drive to the diskette in the target +; drive. If necessary for the diskettes to use volume serial +; numbers, the actual value of those number is ignored. + +; Multiple compares may be performed with one load of DISKCOMP. +; A prompt, "Compare another (Y/N)?" permits additional +; executions, all with the same drive specifications. + +; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN". + +; INPUT: (DOS command line parameters) + +; [d:][path] DISKCOMP [d: [d:]] [/1] [/8] + +; WHERE +; [d:][path] - Path where the DISKCOMP command resides. + +; [d:] - To specify the Source drive +; +; [d:] - To specify the Target drive +; +; [/1] - To compare only the first side of the diskette, +; regardless of the diskette or drive type. + +; [/8] - To compare only the first 8 sectors per track, +; even if the first diskette contains 9/15 sectors +; per track. +; +; 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 compared, including the unused +; sectors. There is no awareness of the separate files +; involved. A unique volume serial number, if present, +; is ignored in the comparison process. + +; INCLUDED FILES: +; PATHMAC.INC - PATHGEN MACRO +; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF) + +; INTERNAL REFERENCES: +; ROUTINES: +; INIT - initialization main routine +; 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 logical drive who owns the 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: +; DCOMPSM.SAL - Defines the control blocks that describe the messages +; DCOMPPAR.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 COMPINIT,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 DISKCOMP. + +;PROGRAM AUTHOR: Original written by: Jin K. +; 4.00 modifications by: Edwin M. K. +;****************** END OF SPECIFICATIONS ***************************** + IF1 + %OUT COMPONENT=DISKCOMP, MODULE=COMPINIT.SAL + ENDIF + +;REVISION HISTORY: +;DATE: 10-30-84 - chk_para routine added. Many parts are modified to +; permit DISKCOMP /1, DISKCOMP D: /1 cases. Restore diskbase +; before return to DOS when invalid DOS version occurs. +;DATE: 3-27-85 MAIN PARTS OF DISKCOMP PROGRAM HAS BEEN REWRITTEN +; TO USE NEW IOCTL FUNCTIONS 'READ', 'GET_DEVICE_PARAMETERS'. +; A000 - Change spelling of "LOCAL" to "LOCALX" to make MASM 3 happy. + + INCLUDE PATHMAC.INC ;AN013; + INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF) + +CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AC000; + ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + + INCLUDE DISKCOMP.EQU +NOOP EQU 90H ;NO-OPERTION INSTRUCTION, USED TO DELETE ;AN001; + ; 386 SUPPORT ;AN001; +;$salut (4,2,9,41) +;**************************************************************************** +; * +; EXTERNAL VARIABLES * +; * +;**************************************************************************** + EXTRN PARSER:NEAR ;DCOPYPAR.SAL - DRIVES SYS PARSER ;AN000; + + EXTRN RECOMMENDED_BYTES_SECTOR:WORD + 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 SUBLIST_78 :WORD ; ;AN000; + EXTRN SUBLIST_11 :WORD ; ;AN000; + EXTRN SUBLIST_15A :WORD ; ;AN000; + EXTRN SUBLIST_15B :WORD ; ;AN000; + EXTRN SUBLIST_15C :WORD ; ;AN000; + EXTRN SUBLIST_17B :WORD ; ;AN000; + EXTRN SUBLIST_17C :WORD ; ;AN000; + EXTRN SUBLIST_17D :WORD ; ;AN000; + EXTRN SUBLIST_PARSE:WORD ;PARSE ERROR XX - %0 ;AN004; + + EXTRN MSGNUM_INVALID_PARM:BYTE ;"INVALID PARAMETER" ;AC000; + EXTRN MSGNUM_INVALID_DRV:BYTE ;"INVALID DRIVE SPECIFICATION" ;AC000; + EXTRN MSGNUM_DRV_REDIRECTED:BYTE ;"INVALID, DRIVE REDIRECTED" ;AC000; + EXTRN MSGNUM_NOT_COMPATIBLE:BYTE ;"DEVICE OR DISKETTE TYPES NOT COMPATIBLE";AC000; +.XLIST +;EXTRN MSG_INVALID_DOS :BYTE ;MSG FOR DOS1.0 AND 1.1 +.LIST + + EXTRN TRACK_TO_READ :BYTE + EXTRN SIDE:BYTE + + 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 COPY_TYPE :BYTE ;1 = 1-DRIVE COPY 2 = 2-DRIVE COPY + EXTRN USER_OPTION :BYTE ;NO OPTION (-1) /1 (1), INVALID (9) + EXTRN USER_OPTION_8 :BYTE ;NO OPTION (-1) /8 (1), INVALID (9) + EXTRN BUFFER_BEGIN :WORD ;STARTING BUFFER @ FOR LOADING + EXTRN BUFFER_END :WORD ;ENDING BUFFER @ FOR LOADING + EXTRN START_BUFFER :WORD ;START OF BUFFER SPACE + EXTRN MAIN_EXIT :WORD ;EXIT ADDRESS FOR CONTROL-BREAK + + EXTRN ORG_SOURCE_DRIVE:BYTE ;LOGICAL SOURCE DRIVE NUMBER + EXTRN ORG_TARGET_DRIVE:BYTE ; TARGET + EXTRN SOURCE_DRIVE:BYTE ;AS SPECIFIED BY USER PARMS, DR NUM ;AN000; + EXTRN TARGET_DRIVE:BYTE ;AS SPECIFIED BY USER PARMS, DR NUM ;AN000; + + 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 PATCH_386:BYTE ;PATCH AREA, CHANGED TO NOOP IF NOT 386 ;AN001; + + EXTRN GENERIC_IOCTL :NEAR + EXTRN SET_LOGICAL_DRIVE :NEAR +; $salut (4,24,28,41) +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 TOT. # OF SECT. + ; INCL BOOT SECT, DIRS +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 + +;USED TO CHECK FOR PRESENCE OF 386 MACHINE: +BIOS_SYSTEM_DESCRIPTOR struc ;SYSTEM TYPE STRUC ;AN001; +bios_SD_leng dw ? ;VECTOR LENGTH ;AN001; +bios_SD_modelbyte db ? ;SYSTEM MODEL TYPE ;AN001; +bios_SD_scnd_modelbyte db ? ; ;AN001; + db ? ; ;AN001; +bios_SD_featurebyte1 db ? ; ;AN001; + db 4 dup (?) ; ;AN001; +BIOS_SYSTEM_DESCRIPTOR ends ;END OF STRUC ;AN001; + + +;**************************************************************************** +; * +; VARIABLE DECLARATIONS * +; * +;**************************************************************************** +DRIVE_VALID DW ? ;DRIVE VALIDITY BYTE +DEFAULT_DRV DB ? ;DEFAULT DRIVE ID +NUMBER_OF_DRV DB ? ;TOTAL # OF DISKT DRIVES ON THE SYS + ;(NUMBER_OF_DRV = 0 ---> 1 DRIVE) +ASCII_DRIVE_LETTER DB " :",0 + PATHLABL COMPINIT ;AN013; + 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 + CALL PC_386_CHK ;SEE IF THIS IS A 386 MACHINE ;AN001; + +; 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 + MOV SUBLIST_78.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_11.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_15A.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_15B.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_15C.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17B.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17C.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_17D.SUB_VALUE_SEG,AX ; ;AN000; + MOV SUBLIST_PARSE.SUB_VALUE_SEG,AX ; ;AN004; + + 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 +; CMP DX,FINE ;IF FINE & DANDY +; JNE EXIT_INIT +.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 ;DETERMINE SOURCE AND TARGET DRV + +; $ENDIF ; ;AN000; +$$IF1: + CMP DX,FINE ;IF STILL FINE AND DANDY ;AN000; +; $IF E ; ;AN000; + JNE $$IF3 + CALL TEST_DRIVE_VALIDITY + + CMP DX,FINE +; $IF E ; ;AN000; + JNE $$IF4 + CALL DISKETTE_DRV_TYPE ;SOURCE & TARGET DRIVE TYPES + + CMP DX,FINE ;IF FINE & DANDY +; $IF E ; ;AN000; + JNE $$IF5 + CALL BUFFER_SIZE ;GET BUFFER SIZE FOR COPYING + +; $ENDIF ; ;AN000; +$$IF5: +; $ENDIF ; ;AN000; +$$IF4: +; $ENDIF ; ;AN000; +$$IF3: + RET ;RETURN TO CALLER + +INIT ENDP ;END INITIALLIZATION PROGRAM + +;############################################################################# +.XLIST +; HEADER +;****************************************************************************** +; SUBROUTINE NAME : SCREENING - CHECKS THE FOLLOWING: * +; - DOS VERSION * +; - DRIVE ID VALIDITY * +; - FILE NAME ENTERED BY MISTAKE? * +; INPUT : BL : DRIVE VALIDITY BYTE * +; 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) +;; XCHG AH,AL ;AH=MAJOR VER, AL=MINOR VER +; CMP AX,expected_version ;IF DOS MAJOR VERSION LESS THAN 2.0 +; $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 +; $ELSE ;VERSION OK +; CALL CHK_PARA ;GENERAL SYNTAX CHECK +; $ENDIF ;END VERSION TEST +; RET +;SCREENING ENDP +; HEADER +;;************************************************************************** +;CHK_PARA PROC NEAR +;; CHECK SYNTAX OF THE ENTERED PARAMETERS * +;; ALSO, DETERMINE THE USER OPTION "/1" AND/OR "/8" IS ENTERED. * +;; INPUT: DX = FINE * +;; IF /1 HAS BEEN ENTERED, THE VARIABLE USER_OPTION = OPTION_1 * +;; ELSE USER_OPTION = NO_OPTION. * +;; IF /8 HAS BEEN ENTERED, THE USER_OPTION_8 WILL BE ON * +;; OUTPUT: DX = FINE - NO ERROR * +;; OTHERWISE DX POINTS TO ERROR MSG * +;;************************************************************************** +; PUSH CX +; MOV USER_OPTION, NO_OPTION ;ASSUME NO /1 IS ENTERED. +; MOV USER_OPTION_8, OFF ;ASSUME /8 IS NOT ENTERED. +; XOR CX, CX +; MOV CL, BYTE PTR DS:BEGIN_UNFORM_AREA ;GET # OF CHR +; CMP CL, 0 +; JZ CHK_PARA_EXIT +; 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 +; JZ CHK_PARA_EXIT ;ONLY BLANKS ARE ENTERED. +; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 OR /8 ? +; 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. DISKCOMP D:) +; CALL CHK_SLASH_ONE ;IS NEXT WORD /1 OR /8 ? +; JNC SLASH_ONE ;YES.(EX. DISKCOMP 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. DISKCOMP D: ) +; CALL CHK_SLASH_ONE ;IS IT /1 OR /8 ? +; JNC SLASH_ONE ;YES. (EX. DISKCOMP D: /1) +; CALL CHK_DRV_SPEC ;IF NOT /1 OR /8, 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. DISKCOMP D: D:) +; CALL CHK_SLASH_ONE ;OTHERWISE, /1 AND/OR /8 SHOULD BE FOLLOWED. +; JNC SLASH_ONE ;YES, /1 OR /8. JMP TO SLASH_ONE +; JMP INVALID_PARA ;PARAMETER ERROR. +;SLASH_ONE: ;YES, FOUND EITHER OF /1 OR /8. +; CALL SKIP_BLANKS ;/1 SHOULD BE END OF PARAMETERS, OR ONLY BLANKS CAN FOLLOW. +; JZ CHK_PARA_EXIT ;NO MORE CHR? THEN OK. +; CMP USER_OPTION, OPTION_1 ;WAS IT /1? +; JZ SLASH_8 ;THEN CHECK WHETHER NEXT IS /8. +; CALL CHK_SLASH_ONE ;OTHERWISE, IT WAS /8. NOW CHECK /1. +; JC INVALID_PARA ;NOT FOUND, ERROR +; CMP USER_OPTION, OPTION_1 +; JZ CHK_PRE_EXIT ;YES, IT IS /1 +; JMP INVALID_PARA ;OTHERWISE, FOUND /8 AGAIN. ERROR +;SLASH_8: +; CALL CHK_SLASH_ONE ;CHECK IT IS /8 +; JC INVALID_PARA ;NOT FOUND? ERROR +; CMP USER_OPTION_8, ON +; JZ CHK_PRE_EXIT ;YES. IT IS /8 +; JMP INVALID_PARA ;OTHERWISE, FOUND /1 AGAIN. ERROR +;CHK_PRE_EXIT: +; CALL SKIP_BLANKS ;SKIP BLANKS IF ANY. +; JZ CHK_PARA_EXIT ;THERE SHOULD NOT BE ANY MORE PARAMETER. +;INVALID_PARA: +; MOV DX,OFFSET MSG_INVALID_PARM_PTR ;WRONG PARM ENTERED MSG +;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. * +;*************************************************************************** +;SKIP_AGAIN: +; MOV AL, 20H ;20H=BLANK +; CLD ;CLEAR DIRECTION +; REPE SCASB +; JZ SK_BL_1 ;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 +; JNZ SK_BL_1 ;IF THE NON_BLANK CHR IS NOT A TAB THEN EXIT +; INC DI ;ELSE TRY SKIP AGAIN. +; DEC CX +; JMP SKIP_AGAIN +;SK_BL_1: +; RET +;SKIP_BLANKS ENDP +; HEADER +;;*************************************************************************** +;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. +; JL CK_SL_0 ;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 ? +; JZ CK_SL_1 ;YES. SET USER_OPTION +; CMP AX, '8/' ;IS IT /8 THEN ? +; JZ CK_SL_2 ;YES. SET USER_OPTION_8 +;CK_SL_0: +; STC ;OTHERWISE, NOT FOUND. SET CARRY +; JMP CK_SL_4 ; AND RETURN +;CK_SL_1: +; MOV USER_OPTION, OPTION_1 +; JMP CK_SL_3 +;CK_SL_2: +; MOV USER_OPTION_8, ON +;CK_SL_3: ;ADJUST CX, DI TO THE NEXT CHR. +; INC DI +; INC DI +; DEC CX +; DEC CX +; CMP CX, 0 ;SET ZERO FLAG IF NO MORE CHR. +;CK_SL_4: +; RET +;CHK_SLASH_ONE ENDP +; HEADER +;;*************************************************************************** +;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. +; JL CK_DR_1 ;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' +; JB CK_DR_1 ;LESS THAN 'A', THEN NOT FOUND. +; CMP AL, 'Z' +; JA CK_DR_1 ;ABOVE 'Z', THEN NOT FOUND. +; MOV AL, ES:BYTE PTR [DI+1] ;LOOK AHEAD THE FOLLOWING CHR. +; CMP AL, ':' ;SHOULD BE A COLON. +; JNZ CK_DR_1 ;NOT 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. +; JMP CK_DR_2 +;CK_DR_1: +; STC ;SET CARRY +;CK_DR_2: +; RET +;CHK_DRV_SPEC ENDP +; HEADER +;;*************************************************************************** +;CHK_BLANK PROC NEAR +;; ** CHECK THE CURRENT CHR IS A BLANK OR A 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. +; JL CK_BL_0 ;SET CARRY AND EXIT +; MOV AL, ES:BYTE PTR [DI] ;GET CURRENT CHR +; CMP AL, 020H ;020H=BLANK CHR +; JZ CK_BL_1 ;FOUND +; CMP AL, 09H ;09H=TAB CHR +; JZ CK_BL_1 ;FOUND +;CK_BL_0: +; STC ;NOT FOUND. SET CARRY +; JMP CK_BL_2 +;CK_BL_1: +; INC DI ;FOUND. ADJUST DI, CX +; DEC CX +;CK_BL_2: +; RET +;CHK_BLANK ENDP +.LIST + HEADER +; QUERIES THE BIOS TO DETERMINE WHAT TYPE OF +; MACHINE WE ARE ON. WE ARE LOOKING FOR A 386. +; THIS WILL BE USED TO DETERMINE IF A DOUBLE WORD MOVE +; IS TO BE PERFORMED. +; +; INPUTS : NONE +; +; OUTPUTS : IF A 386 NOT PRESENT, CODE IS +; *** P A T C H E D *** +; TO NO-OP THE SUPPORT FOR THE DOUBLE WORD MOVE +;========================================================================= + +PC_386_CHK PROC NEAR ;DETERMINE MACHINE TYPE ;AN001; + + PUSH AX ;SAVE AFFECTED REGS ;AN001; + PUSH BX ; ;AN001; + PUSH ES ; ;AN001; + + MOV AH,0C0H ;RETURN SYSTEM CONFIGURATION ;AN001; + INT 15H ;ES:[BX] POINTS TO BIOS ;AN001; + ; SYSTEM DESCRIPTOR + ASSUME ES:NOTHING ;AN001; + +; $IF C,OR ;IF NOT A GOOD RETURN, OR... ;AN001; + JC $$LL9 + CMP AH,0 ;IS IT NEW FORMAT FOR CONFIG. ;AN001; +; $IF NE,OR ;NO, OR... ;AN001; + JNE $$LL9 + CMP ES:[BX].BIOS_SD_MODELBYTE,0F8H ;CHECK MODEL ;AN001; +; $IF NE ;IF IT IS NOT A 386 MACHINE? ;AN001; + JE $$IF9 +$$LL9: + ;PATCH OUT THE 386 CODE + MOV AL,NOOP ;WITH A NO-OP INSTRUCTION ;AN001; + MOV PATCH_386,AL ; ;AN001; + MOV PATCH_386+1,AL ; ;AN001; + MOV PATCH_386+2,AL ; ;AN001; +; $ENDIF ; ;AN001; +$$IF9: + + POP ES ;RESTORE REGS. ;AN001; + ASSUME ES:CSEG ;BACK TO USUAL ;AN001; + + POP BX ; ;AN001; + POP AX ; ;AN001; + + RET ; ;AN001; + +PC_386_CHK ENDP ; ;AN001; + 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 ETC. * +; * +; OUTPUT : ORG_SOURCE_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. * +; : ORG_TARGET_DRIVE 1 = DRIVE A 2 = DRIVE B ETC. * +; * +; : COPY_TYPE 1 = SINGLE DRV COPY, 2 = 2 DRIVE COPY * +; : DX : FINE - NO ERROR * +;****************************************************************************** +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 + + CMP SOURCE_DRIVE,ZERO ;FIRST DRV ENTERED? ;AC000; +; $IF E ;NO DRIVE LETTER ENTERED + JNE $$IF11 + MOV CH, DEFAULT_DRV ;SET SOURCE, TARGET DRIVE TO + INC CH + MOV ORG_SOURCE_DRIVE, CH ;DEFAULT DRIVE + MOV CL, CH + MOV ORG_TARGET_DRIVE, CL +; $ELSE + JMP SHORT $$EN11 +$$IF11: + MOV CH,SOURCE_DRIVE ;GET SOURCE DRIVE FROM SPECIFIED PARM ;AC000; + MOV ORG_SOURCE_DRIVE, CH + CMP TARGET_DRIVE,ZERO ;WAS A SECOND DRIVE SPECIFIED ;AC000; +; $IF E ;TARGET DRIVE IS DEFAULT + JNE $$IF13 + MOV CL, DEFAULT_DRV + INC CL ;MAKE IT A LOGICAL DRIVE NUMBER + MOV ORG_TARGET_DRIVE, CL +; $ELSE + JMP SHORT $$EN13 +$$IF13: + MOV CL, TARGET_DRIVE ;USE USER SPECIFIED TARGET DRIVE ;AC000; + MOV ORG_TARGET_DRIVE, CL +; $ENDIF +$$EN13: +; $ENDIF +$$EN11: + + ADD ASCII_DRV1_ID,CH ;SETUP DRIVE ID ALPHABET IN THE + ADD ASCII_DRV2_ID,CL ;MESSAGES + + 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 : ORG_SOURCE_DRIVE:BYTE, ORG_TARGET_DRIVE:BYTE * +; * +; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE 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 $$IF17 + + MOV BL,ORG_SOURCE_DRIVE + CALL CHECK_REDIRECTION + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF17 + + MOV BL,ORG_TARGET_DRIVE + CALL CHECK_REDIRECTION + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF17 + + MOV BL,ORG_SOURCE_DRIVE + CALL CHECK_SERVER + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF17 + + MOV BL,ORG_TARGET_DRIVE + CALL CHECK_SERVER + + CMP DX,FINE +; $IF E,AND ; ;AC000; + JNE $$IF17 + + CALL TEST_REMOVABLE + + CMP DX,FINE +; $IF E ; ;AC000; + JNE $$IF17 + + CALL CHK_SINGLE_DRV_OP ;CHECK IF IT IS + ; ONE PHYSICAL DRIVE OPERATION +; $ENDIF ; ;AC000; +$$IF17: + RET + +TEST_DRIVE_VALIDITY ENDP + HEADER +;****************************************************************************** +; SUBROUTINE NAME : DOS_DRIVE_VALIDITY -- CHEKC DOS DRIVE VALIDITY BYTE * +; * +; INPUT : DRIVE_VALID:BYTE * +; THIS IS THE ORIGINAL VALUE PRESENTED IN AX BY DOS LOADER * +; * +; OUTPUT : DX=FILE IF DRIVES ARE VALID ELSE DX CONTAINS MESSAGE PTR * +;****************************************************************************** + +DOS_DRIVE_VALIDITY PROC NEAR + PUBLIC DOS_DRIVE_VALIDITY ;MAKE ENTRY IN LINK MAP ;AN000; + + CMP DRIVE_VALID,0 ;SEE IF DRIVES ARE VALID DOS DEVICE +; $IF NE + JE $$IF19 + MOV DX,OFFSET MSGNUM_INVALID_DRV ;AC000; +; $ENDIF +$$IF19: + RET + +DOS_DRIVE_VALIDITY ENDP + HEADER +;****************************************************************************** +; 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 + PUBLIC TEST_REMOVABLE ;MAKE ENTRY IN LINK MAP ;AN000; + + MOV BL,ORG_SOURCE_DRIVE ;GET PARM 1 DRIVE ID + + MOV AX,DRIVE_CHECK ;CHECK FOR REMOVABLE DRIVE + INT 21H ;IOCTL CALL + +; $IF NC ;IF DRIVE ID IS WITHIN RANGE + JC $$IF21 + CMP AX,REMOVABLE ;THEN IF SOURCE DRIVE IS FIXED +; $IF NE ; THEN + JE $$IF22 + MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000; + ; HARD DRIVE ERROR MESSAGE +; $ELSE ;ELSE, SRC IS REMOVABLE; + JMP SHORT $$EN22 +$$IF22: + MOV BL,ORG_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 $$IF24 + CMP AX,REMOVABLE ;THEN TGT DRV IS FIXED +; $IF NE ; THEN + JE $$IF25 + MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000; + ; HARD DRV ERROR MSG +; $ENDIF ;END TEST IF TGT DRV IS FIXED +$$IF25: +; $ELSE ;TGT DRV OUT OF RANGE. EX. DRIVE X: + JMP SHORT $$EN24 +$$IF24: + MOV DX,OFFSET MSGNUM_INVALID_DRV ;GENERATE ;AC000; + ; HARD DRV ERROR MSG +; $ENDIF ;END TEST IF TGT WITHIN RANGE +$$EN24: +; $ENDIF ;END IF SRC IS REMOVABLE +$$EN22: +; $ELSE ;ELSE, SRC DRV OUT OF RANGE + JMP SHORT $$EN21 +$$IF21: + MOV DX,OFFSET MSGNUM_INVALID_DRV ;PRINT ERROR MSG ;AC000; +; $ENDIF ;END TEST IF SRC DRV WITHIN RANGE +$$EN21: + RET + +TEST_REMOVABLE ENDP + HEADER +;****************************************************************************** +; SUBROUTINE NAME : CHK_SINGLE_DRV_OP * +; * +; INPUT : ORG_SOURCE_DRIVE - LOGICAL DRIVE NUMBER * +; ORG_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 + PUBLIC CHK_SINGLE_DRV_OP ;MAKE ENTRY IN LINK MAP ;AN000; + + PUSH AX + + MOV BL,ORG_SOURCE_DRIVE + CALL GET_LOGICAL_DRIVE + + MOV S_OWNER_SAVED, AL ;SAVE CURRENT OWNER DRIVE LETTER. + MOV BL, ORG_TARGET_DRIVE + CALL GET_LOGICAL_DRIVE + + MOV T_OWNER_SAVED, AL ;SAVE CURRENT OWNER + MOV BL, ORG_SOURCE_DRIVE + CALL SET_LOGICAL_DRIVE + + MOV BL, ORG_TARGET_DRIVE + CALL SET_LOGICAL_DRIVE + + MOV BL, ORG_SOURCE_DRIVE + CALL GET_LOGICAL_DRIVE ;CHECK IF SOURCE DRIVE OWNERSHIP HAS NOT BEEN CHAGNED? + + CMP AL, ORG_SOURCE_DRIVE +; $IF NE ;IF IT HAS BEEN CHANGED TO TARGET, THEN A SINGLE DRIVE COMPARE. + JE $$IF32 + MOV COPY_TYPE, ONE + MOV BL, ORG_SOURCE_DRIVE + MOV ORG_TARGET_DRIVE, BL ;SET TARGET DRV LETTER TO THE SOURCE. + MOV BL, ASCII_DRV1_ID + MOV ASCII_DRV2_ID, BL + MOV BL, ORG_SOURCE_DRIVE + CALL SET_LOGICAL_DRIVE ;SET THE OWNER BACK TO SOURCE DRV LETTER + +; $ELSE + JMP SHORT $$EN32 +$$IF32: + CMP AL, ORG_TARGET_DRIVE ; SOURCE DRV LETTER = TARGET DRV LETTER CASE, FOR EX. DISKCOMP A: A: +; $IF E + JNE $$IF34 + MOV COPY_TYPE, ONE +; $ELSE + JMP SHORT $$EN34 +$$IF34: + MOV COPY_TYPE, TWO +; $ENDIF +$$EN34: +; $ENDIF +$$EN32: + + POP AX + + RET +CHK_SINGLE_DRV_OP ENDP + HEADER +;****************************************************************************** +GET_LOGICAL_DRIVE PROC NEAR + PUBLIC GET_LOGICAL_DRIVE ;MAKE ENTRY IN LINK MAP ;AN000; +; *** 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 $$IF38 + MOV AL, BL ;THEN SET IT TO THE INPUT DRIVE LETTER +; $ENDIF +$$IF38: + + RET + +GET_LOGICAL_DRIVE ENDP + HEADER +;****************************************************************************** +; SUBROUTINE NAME : DISKETTE_DRV_TYPE DOES THE FOLLOWING: * +; - GETS SOURCE, TARGET DRIVE INFORMATIONS * +; - CHECK IF IT IS A REMOVABLE DRIVE. * +; INPUT : SOURCE_DRIVE & TARGET_DRIVE * +; 1 = DRIVE A 2 = DRIVE B, ETC. * +; * +; OUTPUT : DX : FINE - NO ERROR * +; (OTHERS)- ERROR MSG OFFSET * +;****************************************************************************** +DISKETTE_DRV_TYPE PROC NEAR + PUBLIC DISKETTE_DRV_TYPE ;MAKE ENTRY IN LINK MAP ;AN000; + + PUSH AX + XOR BX,BX + MOV BL, ORG_SOURCE_DRIVE + MOV CL, GETDEVPARM ;=60h + MOV DX, OFFSET DS_IOCTL_DRV_PARM ;POINTER TO THE CONTROL STRING + CALL GENERIC_IOCTL ;GET DEVICE PARM. + + TEST DS_deviceAttributes, 0001h ;CHECK REMOVABLE. 0001 = NOT REMOVABLE +; $IF E,AND ;NO, CONTINUE ;AC000; + JNE $$IF40 + + 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, ORG_TARGET_DRIVE + MOV CL, GETDEVPARM + MOV DX, OFFSET DT_IOCTL_DRV_PARM + CALL GENERIC_IOCTL + + TEST DT_deviceAttributes, 0001h +; $IF Z ;TARGET IS NOT FIXED DISK, OK ;AC000; + JNZ $$IF40 + 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 + +;*** CHECK 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 $$IF41 + ; 720KB, 3.5 SOURCE, TARGET + + CMP DT_deviceType, DRV_720 ;target = 720KB also? +; $IF NE ; ;AC000; + JE $$IF42 + MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000; +; $ENDIF ; ;AC000; +$$IF42: +; $ELSE ;SINCE SOURCE NOT 720 ;AC000; + JMP SHORT $$EN41 +$$IF41: + CMP DT_deviceType, DRV_720 ;SOURCE IS NOT 720kb, + ; IS TARGET 720? +; $IF E ;IF SO, THEN ;AC000; + JNE $$IF45 + ;DDT IS NOT COMPATIBLE + MOV DX, OFFSET MSGNUM_NOT_COMPATIBLE ; ;AC000; +; $ENDIF ; ;AC000; +$$IF45: +; $ENDIF ; ;AC000; +$$EN41: +; $ELSE ;SINCE SOURCE IS FIXED DISK, ERROR ;AC000; + JMP SHORT $$EN40 +$$IF40: + MOV DX, OFFSET MSGNUM_INVALID_DRV ;ISSUE INVALID DRV MSG ;AC000; +; $ENDIF ; ;AC000; +$$EN40: + POP AX + RET + +DISKETTE_DRV_TYPE ENDP + HEADER +;****************************************************************************** +; 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 + PUBLIC CHECK_REDIRECTION ;MAKE ENTRY IN LINK MAP ;AN000; + + 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 $$IF50 + MOV CX,OFFSET MSGNUM_INVALID_DRV ;REDIR INVALID ;AC000; + +; $ELSE + JMP SHORT $$EN50 +$$IF50: + TEST DX,REMOTE_DRV ;IF DRIVE IS REDIRECTED +; $IF NZ + JZ $$IF52 + + MOV CX,OFFSET MSGNUM_DRV_REDIRECTED ; ;AC000; +; $ENDIF +$$IF52: +; $ENDIF +$$EN50: + MOV DX,CX ;GET ERROR MSG @ + + POP CX ;RESTORE REGISTERS + POP BX + POP AX + RET ;RETURN TO CALLER +CHECK_REDIRECTION ENDP + HEADER +;****************************************************************************** +; SUBROUTINE NAME : BUFFER_SIZE DETERMINES WHERE BUFFER STARTS & ENDS * +; INPUT : NONE * +; * +; OUTPUT : BUFFER_BEGIN ADDRESS * +; : BUFFER_END ADDRESS * +; : START_BUFFER ADDRESS +;****************************************************************************** +BUFFER_SIZE PROC NEAR + PUBLIC BUFFER_SIZE ;MAKE ENTRY IN LINK MAP ;AN000; + + PUSH AX ;SAVE REGISTERS + PUSH BX + PUSH CX + MOV BX,OFFSET init ;GET ADDR OF INIT+1024 AS A FREE MEMORY + 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 @ 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 + MOV START_BUFFER,BX ;SAVE IT AGAIN ELSEWHERE + ;(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 +;****************************************************************************** +SETUP_CTRL_BREAK PROC NEAR ;SETUP CTRL-BREAK VECTOR + PUBLIC SETUP_CTRL_BREAK ;MAKE ENTRY IN LINK MAP ;AN000; +;****************************************************************************** + PUSH AX + PUSH BX + PUSH DX + PUSH ES + + MOV AX,2523H ;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 +;****************************************************************************** +CHECK_SERVER PROC NEAR ;SEE IF SERVER OR REDIRECTOR IS IN++ + PUBLIC CHECK_SERVER ;MAKE ENTRY IN LINK MAP ;AN000; +; +; INPUT: BL = DRIVE NUMBER (1=A,2=B ETC....) +;****************************************************************************** + MOV AH,0 ;SEE IF SERVER LOADED + INT SERVER + CMP AH,0 +; $IF E + JNE $$IF55 + MOV DX,FINE +; $ELSE + JMP SHORT $$EN55 +$$IF55: + 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 $$IF57 + MOV DX,OFFSET MSGNUM_DRV_REDIRECTED ;AC000; +; $ELSE + JMP SHORT $$EN57 +$$IF57: + MOV DX,FINE +; $ENDIF +$$EN57: +; $ENDIF +$$EN55: + RET +CHECK_SERVER ENDP + + Public INIT_END +INIT_END LABEL BYTE + PATHLABL COMPINIT ;AN013; +CSEG ENDS + END + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC b/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC new file mode 100644 index 0000000..f0cdd0d --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DCMPMACR.INC @@ -0,0 +1,171 @@ + IF1 ;AN000; + %OUT INCLUDING DCMPMACR.INC...;AN000; + ELSE ;AN000; +; %OUT INCLUDING DCMPMACR.INC... + ENDIF ;AN000; +;***************************************************************************; +; MACRO DEFINITION ; +;***************************************************************************; + +HEADER MACRO TEXT ;;AN000; +.XLIST ;;AN000; + SUBTTL &TEXT ;;AN000; +.LIST ;;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = +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; +; = = = = = = = = = +.xlist ;AN000; +;INPUT MACRO MESSAGE +; PRINT MESSAGE +; CALL PROMPT +; ENDM +.list ;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/DISKCOMP/DCOMPMS.INC b/v4.0/src/CMD/DISKCOMP/DCOMPMS.INC new file mode 100644 index 0000000..6808808 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DCOMPMS.INC @@ -0,0 +1,232 @@ +;:util DISKCOMP ;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 ;"Incorrect DOS version" +; +;:use 2 EXTEND8 ;"Insufficient memory" +; +;:use 3 PARSE10 ;"Invalid parameter" +;; +;:def 4 "Do not specify filename(s)",CR,LF +;"Command format: DISKCOMP d: d: [/1][/8]",LF,CR +; +;: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 DISKCOMP to or from",CR,LF +;"a network drive",CR,LF +; +;:def 7 CR,LF,"Insert FIRST diskette in drive %1:",CR,LF +; +;:def 8 CR,LF,"Insert SECOND diskette in drive %1:",CR,LF +; +;:def 9 CR,LF,"FIRST diskette bad or incompatible",CR,LF +; +;:def 10 CR,LF,"SECOND diskette bad or incompatible",CR,LF +; +;:use 11 EXTEND21 ;"Drive not ready" NOTE CHANGE %1 TO %0 +; +;:use 12 COMMON28 ;"Press any key to continue . . ." +; +;:use 13 EXTEND19 ;CR,LF,"Attempt to write to write-protected diskette",CR,LF +; +;:def 14 CR,LF,"Compare another diskette (Y/N) ?" +; +;:def 15 CR,LF,"Comparing %1 tracks",CR,LF +;"%2 sectors per track, %3 side(s)",CR,LF +; +;:def 16 CR,LF,"Drive types or diskette types",CR,LF +;"not compatible",CR,LF +; +;:def 17 CR,LF,"Unrecoverable read error on drive %2",CR,LF +;"side %3, track %4",CR,LF +; +;:def 18 CR,LF,"Compare error on",CR,LF,"side %3, track %4",CR,LF +; +;:def 19 "Make sure a diskette is inserted into",CR,LF +;"the drive and the door is closed",CR,LF +; +;:def 20 CR,LF,"Compare process ended",CR,LF +; +;:def 21 CR,LF,"Compare OK",CR,LF +; +;:def 22 CR,LF +;:end +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + IF1 ;AN000; + %OUT COMPONENT=DISKCOMP, MODULE=DCOMPMS.INC...;AN000; + ENDIF ;AN000; +; $SALUT (0,13,18,22) ; ;AN000; +;THIS MODULE IS INCLUDED IN DCOMPSM.SAL. +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +FOUR_SUBS EQU 4 ;AN000;FOUR VARIABLES IN ONE MSG +PC_ID_4 EQU 4 ;AN000;IDENTIFIES FOURTH REPLACEMENT PARM +PC_ID_5 EQU 5 ;AN000;IDENTIFIES FIFTH REPLACEMENT PARM +LETTER_A EQU "A" ;AN000;DEFAULT DRIVE ID +CLEAR_BUF EQU 0C0H ;AN006;CLEAR KEYBOARD BUFFER BEFORE INPUT +KEY_IN_ECHO EQU 1 ;AN000;REQUEST KEYBOARD INPUT TO AL, ECHO RESPONSE +KEY_IN EQU 8 ;AN000;REQUEST KEYBOARD INPUT TO AL, NO ECHO +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 + +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 DISKCOMP UTILITY + + ;"Insufficient memory" +MSGNUM_UNSUF_MEMORY MSG_DESC <2> ;AN000; + PUBLIC MSGNUM_UNSUF_MEMORY ;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: DISKCOMP d: d: [/1][/8]",CR,LF +MSGNUM_INVALID_PARM2 MSG_DESC <4> ;AN000; + PUBLIC MSGNUM_INVALID_PARM2 ;AN000; + +; = = = = = = = = = = = = = = = = + ;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 DISKCOMP to or from",CR,LF + ;"a network drive",CR,LF +MSGNUM_DRV_REDIRECTED MSG_DESC <6> ;AN000; + PUBLIC MSGNUM_DRV_REDIRECTED ;AN000; + +; = = = = = = = = = = = = = = = = + ;CR,LF,"Insert FIRST diskette in drive %1:",CR,LF +MSGNUM_LOAD_FIRST MSG_DESC <7,,SUBLIST_78,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_LOAD_FIRST,SUBLIST_78 ;AN000; + +SUBLIST_78 SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1>;AN000; +;THE "FILL" FIELDS NEED TO BE SET TO POINT TO +;"ASCII_DRV1_ID" OR "ASCII_DRV2_ID"(BELOW). + + ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF +MSGNUM_LOAD_SECOND MSG_DESC <8,,SUBLIST_78,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_LOAD_SECOND ;AN000; + + ;IF "FIRST" SPECIFIED +ASCII_DRV1_ID DB LETTER_A-BYTE ;AN000; + + ;IF "SECOND" SPECIFIED +ASCII_DRV2_ID DB LETTER_A-BYTE ;AN000; + PUBLIC ASCII_DRV1_ID,ASCII_DRV2_ID ;AN000; + +; = = = = = = = = = = = = = = = = + ;CR,LF,"FIRST diskette bad or incompatible",CR,LF +MSGNUM_BAD_FIRST MSG_DESC <9> ;AN000; + PUBLIC MSGNUM_BAD_FIRST ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"SECOND diskette bad or incompatible",CR,LF +MSGNUM_BAD_SECOND MSG_DESC <10> ;AN000; + PUBLIC MSGNUM_BAD_SECOND ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,Drive not ready",CR,LF +MSGNUM_GET_READY MSG_DESC <11,,SUBLIST_11,ONE_SUBS> ;AN000; + PUBLIC MSGNUM_GET_READY ;AN000; + +SUBLIST_11 SUBLIST <,,DRIVE_LETTER,FILL_SEG,PC_ID_0,SF_BITS,MAX_0,MIN_1>;AN000; + PUBLIC SUBLIST_11 ;AN000; + +DRIVE_LETTER DB LETTER_A,":",NULL ;AN000; + PUBLIC DRIVE_LETTER ;AN000; + +SKIP_MSG DB NULL ;AN000; + PUBLIC SKIP_MSG ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Press any key to continue . . .",CR,LF +MSGNUM_STRIKE MSG_DESC <12,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN)> ;AN006; + PUBLIC MSGNUM_STRIKE ;AN000; +; = = = = = = = = = = = = = = = = +; ;CR,LF,"Attempt to write to write-protected diskette",CR,LF +MSGNUM_WRITE_PROTECT MSG_DESC <13> ;AN000; + PUBLIC MSGNUM_WRITE_PROTECT ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Compare another diskette (Y/N) ?" +MSGNUM_COMP_ANOTHER MSG_DESC <14,,,,(CLASS_A SHL 8) OR (CLEAR_BUF + KEY_IN_ECHO)> ;AN006; + PUBLIC MSGNUM_COMP_ANOTHER ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Comparing %1 tracks",CR,LF + ;"%2 Sectors/Track, %3 Side(s)",CR,LF +MSGNUM_COMPARING MSG_DESC <15,,SUBLIST_15A,THREE_SUBS> ;AN000; + PUBLIC MSGNUM_COMPARING ;AN000; + +SUBLIST_15A SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_1,SF_BITS,MAX_0,MIN_1>;AN000; +SUBLIST_15B SUBLIST <,,MSG_SECTRK,FILL_SEG,PC_ID_2,SF_BITS,MAX_0,MIN_1>;AN000; +SUBLIST_15C SUBLIST <,,MSG_SIDES,FILL_SEG,PC_ID_3,SF_BITS,MAX_0,MIN_1>;AN000; + PUBLIC SUBLIST_15A,SUBLIST_15B,SUBLIST_15C ;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,MSG_SECTRK,MSG_SIDES ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Drive types or diskette types",CR,LF + ;"not compatible",CR,LF +MSGNUM_NOT_COMPATIBLE MSG_DESC <16> ;AN000; + PUBLIC MSGNUM_NOT_COMPATIBLE ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Unrecoverable read error on drive %2",CR,LF + ;"side %3, track %4",CR,LF + ;%2 IS "DRIVE_LETTER", AND + ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4. +MSGNUM_HARD_ERROR_READ MSG_DESC <17,,SUBLIST_17B,THREE_SUBS> ;AN000; + PUBLIC MSGNUM_HARD_ERROR_READ ;AN000; + +SUBLIST_17B SUBLIST <,,DRIVE_LETTER,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; +SUBLIST_17D SUBLIST <,,MSG_TRACKS,FILL_SEG,PC_ID_4,SF_BITS,MAX_0,MIN_1>;AN000; + PUBLIC SUBLIST_17B,SUBLIST_17C,SUBLIST_17D ;AN000; + + ;CR,LF,"Compare error on",CR,LF + ;"side %3, track %4",CR,LF + ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4. +MSGNUM_HARD_ERROR_COMP MSG_DESC <18,,SUBLIST_17C,TWO_SUBS> ;AN000; + PUBLIC MSGNUM_HARD_ERROR_COMP ;AN000; +; = = = = = = = = = = = = = = = = + ;:def 19 "Make sure a diskette is inserted into",CR,LF + ;"the drive and the door is closed",CR,LF +MSGNUM_CLOSE_DOOR MSG_DESC <19> ;AN004; + PUBLIC MSGNUM_CLOSE_DOOR ;AN004; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Compare process ended",CR,LF +MSGNUM_FATAL_ERROR MSG_DESC <20> ;AN000; + PUBLIC MSGNUM_FATAL_ERROR ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF,"Compare OK",CR,LF +MSGNUM_COMP_OK MSG_DESC <21> ;AN000; + PUBLIC MSGNUM_COMP_OK ;AN000; +; = = = = = = = = = = = = = = = = + ;CR,LF +MSGNUM_NEWLINE MSG_DESC <22> ;AC007; + PUBLIC MSGNUM_NEWLINE ;AN000; +; = = = = = = = = = = = = = = = = +;end of DCOMPMS.INC + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM new file mode 100644 index 0000000..369434b --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DCOMPP.ASM @@ -0,0 +1,123 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOMPP.SAL - DISKCOMP SYSTEM COMMAND LINE PARSER +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOMPP.SAL +; +; DESCRIPTIVE NAME: Include the DOS system PARSER in the SEGMENT +; configuration expected by the modules of DISKCOMP. +; +;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 DCOMPP,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, +; DISKCOMP.SAL. +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOMP, MODULE=DCOMPP.SAL... ;AN000; + ENDIF ;AN000; +; = = = = = = = = = = = = + INCLUDE PATHMAC.INC ;AN013; +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000; + + PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT + +INCSW EQU 0 ;AC013;DO NOT INCLUDE PSDATA.INC +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 0 ;AN000;SUPPRESS 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 +BASESW EQU 1 ;AN012;SPECIFY, PSDATA POINTED TO BY "DS" + INCLUDE PSDATA.INC ;AN013;PARSER DATA AREA + PATHLABL DCOMPP ;AN013; +;.XLIST ;AN000; +;.XCREF ;AN000; + INCLUDE PARSE.ASM ;AN000; +.LIST ;AN000; +.CREF ;AN000; + PATHLABL DCOMPP ;AN013; +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM new file mode 100644 index 0000000..7a549d2 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DCOMPPAR.ASM @@ -0,0 +1,427 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOMPPAR.SAL - LOOK AT COMMAND LINE PARMS +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOMPPAR.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 DISKCOMP. 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] DISKCOMP [d: [d:]] [/1] [/8] + +; WHERE +; [d:][path] - Path where the DISKCOMP command resides. + +; [d:] - To specify the Source drive +; +; [d:] - To specify the Target drive +; +; [/1] - To compare only the first side of the diskette, +; regardless of the diskette or drive type. + +; [/8] - To compare only the first 8 sectors per track, +; even if the first diskette contains 9/15 sectors +; per track. +; +; 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. +; "USER_OPTION_8" = 01 ON IF /8, -1 IF /8 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 DISKCOMP 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 +; USER_OPTION_8:BYTE /8 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 DCOMPPAR,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, +; DISKCOMP.SAL. + +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOMP, MODULE=DCOMPPAR.SAL... ;AN000; + ENDIF ;AN000; + INCLUDE PATHMAC.INC ;AN013; +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; +.XLIST ;AN000; + SUBTTL TEXT ;AN000; +.LIST ;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = +; $SALUT (4,23,28,36) ;AN000; +CHAR_A EQU "A" ;AN000;ASCII VALUE OF CHARACTER "A" +NUL EQU 0 ;AN003;ASCIIZ STRING DELIMITER +; 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);AN003; +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 ;AN003; +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 ;AN003; + ; IF THIS IS A .COM FILE) ;AN003; +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 ",". ;AN003; + ; "," CAUSES INSERTION OF THE ACTIVE ;AN003; + ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN003; +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 + +BLANK EQU " " ;AN002;WIPE OUT SWITCH TO AVOID DUPLICATE + +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 USER_OPTION:BYTE ;AN000;NO OPTION (-1) /1 (1), INVALID (9) +NO_OPTION EQU -1 ;AN000;OPTION NOT SPECIFIED +OPTION_1 EQU 1 ;AN000;OPTION "/1" SPECIFIED +OPTION_8 EQU 1 ;AN000;OPTION "/8" SPECIFIED + EXTRN USER_OPTION_8:BYTE ;AN000;NO OPTION (-1) /8 (1), INVALID (9) + + EXTRN MSGNUM_PARSE:WORD ;AN000;MESSAGE DESCRIPTOR FOR ALL PARSE ERRORS + EXTRN MSGNUM_INVALID_PARM2:WORD ;AN005;HELP MESSAGE DESCRIPTOR + 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 + + 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 0000H ;AN000;FUNCTION_FLAGS (NO CAPITALIZATION NEEDED) + ; 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 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 +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 TWO SWITCHES, OPTIONAL + +;THE SWITCH IS "/1", MEANING ONLY COMPARE THE FIRST SIDE. +;THE SECOND SWITCH IS "/8", MEANING ONLY LOOK AT FIRST 8 SECTORS PER TRACK. + + PUBLIC CONTROL_SW ;AN000;LET LINK MAKE THIS ADDRESSABLE +CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR FOR /1 OR /8 + DW 0000H ;AN000; CONTROLS TYPE MATCHED + ; 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 0000H ;AN000;FUNCTION_FLAGS (NO CAPITALIZATION) + ; 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 2 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS + ; IN FOLLOWING LIST +SINGLE_SIDED LABEL BYTE ;AN002; +SW_1 DB "/1",0 ;AN000; IF n >0, KEYWORD 1 +SW_8 DB "/8",0 ;AN000;SECOND KEYWORD + +;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 + +RESULTSWSYN DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:) +RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE +; = = = = = = = = = = = = + PATHLABL DCOMPPAR ;AN013; + 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" = A=1, B=2, 0 IF NONE +; "TARGET_DRIVE" = A=1, B=2, 0 IF NONE +; "USER_OPTION" = 01 ON IF /1, -1 IF /1 NOT SPECIFIED. +; "USER_OPTION_8" = 01 ON IF /8, -1 IF /8 NOT SPECIFIED. +; IF ERROR, ERROR MESSAGE IS DISPLAYED, AND "EXITFL" HAS "EXPAR". +; = = = = = = = = = = = = + MOV USER_OPTION,NO_OPTION ;AN000;SET DEFAULT, SWITCH NOT FOUND + MOV USER_OPTION_8,NO_OPTION ;AN000;SET DEFAULT, SWITCH NOT FOUND + +; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE + JMP SHORT $$SS1 +$$DO1: + ;LOOKING AT RETURN CODE FROM SYSPARSE... ;AN000; + 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 DRIVE 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 AL,SINGLE_SIDED+BYTE ;AN000;GET ID PORTION OF SWITCH + MOV BX,RESULTSWSYN ;AN000;GET OFFSET TO MATCHING SWITCH + CMP [BX]+BYTE,AL ;AN000;WAS IT /1? +; $IF E ;AN000;YES IT WAS /1 + JNE $$IF6 + MOV SW_1,BLANK ;AN002;AVOID GETTING /1 AGAIN + MOV USER_OPTION,OPTION_1 ;AN000;MUST HAVE BEEN THE SWITCH, /1 +; $ELSE ;AN000;SINCE IT WAS NOT /1, MUST BE /8 + JMP SHORT $$EN6 +$$IF6: + MOV SW_8,BLANK ;AN002;AVOID GETTING /8 AGAIN + MOV USER_OPTION_8,OPTION_8 ;AN000;REPORT BACK, IT WAS /8 +; $ENDIF ;AN000; +$$EN6: +; $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 INTO COMMAND OF WHERE TO START LOOKING FOR PARM +;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 $$IF13 + 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? +$$IF13: + MOV DI,OFFSET MSGNUM_PARSE ;AC005;OFFSET TO PARSE ERR DESCRIPTOR + CALL SENDMSG ;AN005;DISPLAY ERROR MSG + + MOV DX,OFFSET MSGNUM_INVALID_PARM2 ;AN005;PASS BACK OFFSET TO HELP MSG + RET ;AN000;RETURN TO CALLER +PARSE_ERROR ENDP ;AN000; +; = = = = = = = = = = = = + PATHLABL DCOMPPAR ;AN013; +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM b/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM new file mode 100644 index 0000000..73eb45a --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DCOMPSM.ASM @@ -0,0 +1,159 @@ + PAGE 90,132 ;AN000;A2 + TITLE DCOMPSM.SAL - DISKCOMP SYSTEM MESSAGES +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DCOMPSM.SAL + +; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT +; configuration expected by the modules of DISKCOMP. + +;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a +; part of the DISKCOMP 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 "DCOMPMS.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 DCOMPSM,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, +; DISKCOMP.SAL. + +; COPYRIGHT: "Version 4.00 (C)Copyright 1988 Microsoft" +; "Licensed Material - Property of Microsoft " +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=DISKCOMP, MODULE=DCOMPSM.SAL... ;AN000; + ENDIF ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; + INCLUDE PATHMAC.INC ;AN013; +; = = = = = = = = = = = = +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 DISKCOMP Utility " +;(deleted ;AN010;) INCLUDE COPYRIGH.INC ;(moved to MSG_SERVICES) + HEADER ;AN000; + INCLUDE MSGHAN.INC ;AN000;DEFINE THE MESSAGE HANDLER CONTROL BLOCKS + INCLUDE DCOMPMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS + HEADER ;AN000; + MSG_SERVICES ;AN000;DATA AREA FOR THE MESSAGE HANDLER +; = = = = = = = = = = = = + HEADER ;AN000; + PUBLIC SYSLOADMSG ;AN000; + PUBLIC SYSDISPMSG ;AN000; + + MSG_SERVICES ;AN000;MSG TEXT + PATHLABL DCOMPSM ;AN013; + ;DEFAULT=CHECK DOS VERSION + ;DEFAULT=NEARmsg + ;DEFAULT=INPUTmsg + ;DEFAULT=NUMmsg + ;DEFAULT=NO TIMEmsg + ;DEFAULT=NO DATEmsg + ;DEFAULT=NO GETmsg +; MSG_SERVICES +.XLIST ;AN000; +.XCREF ;AN000; + MSG_SERVICES ;AN000; +.LIST ;AN000; +.CREF ;AN000; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + PATHLABL DCOMPSM ;AN013; + + +CSEG ENDS ;AN000; + +include msgdcl.inc + + END ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM new file mode 100644 index 0000000..83d6a61 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM @@ -0,0 +1,2060 @@ + PAGE 90,132 ;A2 + TITLE DISKCOMP.SAL - COPY COMPLETE DISKETTE +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: DISKCOMP + +; DESCRIPTIVE NAME: Diskette to diskette complete compare Utility + +;FUNCTION: DISKCOMP is to compare the contents of the diskette in the +; specified first drive to the diskette in the second +; drive. If the first drive has a vol serial number, that +; field in both diskettes is ignored in the comparison +; of that one sector, because DISKCOPY will create a unique +; volume serial number when it duplicates a diskette. + +; Multiple compares may be performed with one load of DISKCOMP. +; A prompt, "Compare another (Y/N)?" permits additional +; executions, all with the same drive specifications. + +; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN". + +; INPUT: (DOS command line parameters) + +; [d:][path] DISKCOMP [d: [d:]] [/1] [/8] + +; WHERE +; [d:][path] - Path where the DISKCOMP command resides. + +; [d:] - To specify the First drive +; +; [d:] - To specify the Second drive +; +; [/1] - To compare only the first side of the diskette, +; regardless of the diskette or drive type. + +; [/8] - To compare only the first 8 sectors per track, +; even if the first diskette contains 9/15 sectors +; per track. +; +; 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 CTRL-BREAK. + +; EFFECTS: The entire diskette is compared, including the unused +; sectors. There is no awareness of the separate files +; involved. A unique volume serial number is ignored +; for the comparison of the first sector. + +; INCLUDED FILES: +; PATHMAC.INC - PATHGEN MACRO +; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF) +; INCLUDE DISKCOMP.EQU ;EQUATES + +; INTERNAL REFERENCES: +; ROUTINES: +; BEGIN - entry point from DOS +; SET_LOGICAL_DRIVE - set log. drive letter as owner of drive +; COMP - compare the diskette image +; TEST_REPEAT - see if user wants to compare another +; READ_SOURCE - read from first drive as much as possible +; CHECK_SOURCE - determine first diskette type +; READ_A_SECTOR - use IOCTL read to get a sector +; CALC_TRACK_SIZE - find mem size to hold one track +; CHECK_MEMORY_SIZE - be sure enuf memory to compare 1 track +; COMP_TARGET - compare memory data with secon diskette +; CHECK_TARGET - compare second disk boot record +; SET_DRV_PARM - request IOCTL to set device parm +; COMP_TRACK - read and compare specified track +; SWAP_DRIVE - setup for diskette swapping +; READ_TRACK - read a track to memory +; READ_OP - IOCTL to read a track +; SET_FOR_THE_OLD - use pre 2.0 BPB +; SET_TRACKLAYOUT - determine sectors per track +; GENERIC_IOCTL - perform specified IOCTL function +; EXTENDED_ERROR_HANDLER - determine and service extended errors +; SET_DRV_PARM_DEF - set drive parms via IOCTL +; +; VOLSER - during compare of first sector, avoid vol ser # +; SENDMSG - passes parms to regs and invokes the system message routine. + +; 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: +; DCOMPSM.SAL - Defines the control blocks that describe the messages +; DCOMPPAR.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 DISKCOMP,NUL + +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. + +; Sample LINK command: + +; LINK @DISKCOMP.ARF + +; Where the DISKCOMP.ARF is defined as: + +; DISKCOMP+ +; DCOMPSM+ +; DCOMPP+ +; DCOMPPAR+ +; COMPINIT + +; 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, +; Ignore vol serial number differences. +; A001 386 Support +; A002 Avoid duplicate switches +; A003 PTM 540 Show parm in error +; A004 PTM 752 Add close door after drive not ready +; A005 PTM 756 Add help msg after parm error message +; A006 PTM1100 Clear keyboard buffer before input response +; A007 PTM1464 Delete unused msgs: 22,23,24 +; A008 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID +; A009 PTM1605 PUT A BLANK LINE OUT BEFORE PRESS ANY KEY MSG +; A010 PTM1821 move INCLUDE COPYRIGH.INC to MSG_SERVICE macro +; A011 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO +; REMOVE USE OF GET/SET MEDIA ID +; A012 PTM3262 Specify BASESW EQU 1 before PARSE.ASM +; A013 PTM3512 PATHGEN +; +; COPYRIGHT: The following notice is found in the OBJ code generated from +; the "DCOMPSM.SAL" module: + +; "Version 4.00 (C) Copyright 1988 Microsoft" +; "Licensed Material - Property of Microsoft " + +;PROGRAM AUTHOR: Original written by: Jin K. +; 4.00 modifications by: Edwin M. K. +;****************** END OF SPECIFICATIONS ***************************** + IF1 ; ;AN000; + %OUT COMPONENT=DISKCOMP, MODULE=DISKCOMP.SAL + ENDIF ; ;AN000; +;***************************************************************************** +; * +; D I S K C O M P * +; * +; UPDATE HISTORY: 8-21, 8-22, 8-30, 9-4, 9-20, 9-21, 12-19 * +; 2-15-84, 2-17, 4-29, 6-20,7-24,3-27-85 * +; * +;***************************************************************************** + + INCLUDE PATHMAC.INC ;AN013; + INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF) + INCLUDE DISKCOMP.EQU ;EQUATES + +; $salut (4,16,22,36) ; ;AN000; +;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE, +;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN +;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED. + +MSG_DESC STRUC ; ;AN000; +MSG_NUM DW ? ;MESSAGE NUMBER (TO AX) ;AN000; +MSG_HANDLE DW ? ;HANDLE OF OUTPUT DEVICE (TO BX) ;AN000; +MSG_SUBLIST DW ? ;POINTER TO SUBLIST (TO SI) ;AN000; +MSG_COUNT DW ? ;SUBSTITUTION COUNT (TO CX) ;AN000; +MSG_CLASS DW ? ;MESSAGE CLASS (IN HIGH BYTE, TO DH) ;AN000; + ;LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) ;AN000; +MSG_DESC ENDS ; ;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 + +CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AN000; + ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG + +;***************************************************************************** +; * +; EXTERNAL VARIABLES * +; * +;***************************************************************************** +;$salut (4,2,9,36) + +.XLIST +;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE +;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE +;EXTRN COMPAT_ERROR :NEAR +;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE +;EXTRN YES :BYTE +;EXTRN NO :BYTE +;EXTRN MSG_FIRST_BAD_PTR :BYTE +.LIST + + EXTRN SYSLOADMSG :NEAR ;SYSTEM MSG HANDLER INTIALIZATION ;AN000; + EXTRN SYSDISPMSG :NEAR ;SYSTEM MSG HANDLER DISPLAY ;AN000; + + EXTRN INIT :NEAR ;INITIALIZATION ROUTINE + + EXTRN MSG_TRACKS :WORD ; ;AN000; + EXTRN MSG_SECTRK :WORD ; ;AN000; + EXTRN MSG_SIDES :WORD ; ;AN000; + + EXTRN ASCII_DRV1_ID :BYTE ; ;AN000; + EXTRN ASCII_DRV2_ID :BYTE ; ;AN000; + + EXTRN SUBLIST_78 :WORD ; ;AN000; + EXTRN SUBLIST_17B :WORD ; ;AN000; + + EXTRN MSGNUM_EXTERR :WORD ;EXTENDED ERROR MSG DESCRIPTOR ;AN000; + EXTRN MSGNUM_LOAD_FIRST :BYTE ; ;AC000; + EXTRN MSGNUM_LOAD_SECOND :BYTE ; ;AC000; + EXTRN MSGNUM_NOT_COMPATIBLE:BYTE ; ;AC000; + EXTRN MSGNUM_COMP_ANOTHER:BYTE ; ;AC000; + EXTRN MSGNUM_GET_READY :BYTE ; ;AC000; + EXTRN MSGNUM_CLOSE_DOOR :BYTE ; ;AN004; + EXTRN MSGNUM_FATAL_ERROR :BYTE ; ;AC000; + EXTRN MSGNUM_UNSUF_MEMORY:BYTE ; ;AC000; + EXTRN MSGNUM_BAD_FIRST :BYTE ; ;AC000; + EXTRN MSGNUM_BAD_SECOND :BYTE ; ;AC000; + EXTRN MSGNUM_HARD_ERROR_READ :BYTE ; ;AC000; + EXTRN MSGNUM_HARD_ERROR_COMP :BYTE ; ;AC000; + EXTRN MSGNUM_COMPARING :BYTE ; ;AC000; + EXTRN MSGNUM_STRIKE :BYTE ; ;AC000; + EXTRN MSGNUM_WRITE_PROTECT:BYTE ; ;AC000; + EXTRN MSGNUM_COMP_OK :BYTE ; ;AC000; + EXTRN MSGNUM_NEWLINE :BYTE ; + EXTRN DRIVE_LETTER :BYTE ; + EXTRN SKIP_MSG :BYTE ;NULL REPLACEMENT FOR DRIVE LETTER ;AN000; + PAGE +;***************************************************************************** +; * +; PUBLIC VARIABLES * +; * +;***************************************************************************** + + PUBLIC DISKCOMP_BEGIN + PUBLIC DISKCOMP_END + PUBLIC RECOMMENDED_BYTES_SECTOR + PUBLIC S_OWNER_SAVED + PUBLIC T_OWNER_SAVED + PUBLIC COMP + 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 END_OF_TRACK + PUBLIC BUFFER_BEGIN + PUBLIC START_BUFFER + PUBLIC BUFFER_END + PUBLIC TRACK_TO_READ + PUBLIC TRACK_TO_COMP + PUBLIC SIDE + PUBLIC USER_INPUT + PUBLIC MAIN_EXIT + + PUBLIC NO_OF_SIDES + PUBLIC USER_OPTION_8 + PUBLIC ORG_SOURCE_DRIVE + PUBLIC ORG_TARGET_DRIVE + PUBLIC COMP_STATUS + PUBLIC OPERATION + + 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 ; + +DISKCOMP: + JMP BEGIN +;***************************************************************************** + EVEN ;PUT STACK ONTO A WORD ALIGNMENT BOUNDARY ;AN000; +;INTERNAL STACK AREA + + DB 64 DUP ('STACK ') ;512 BYTES + +MY_STACK_PTR LABEL WORD + PAGE +;***************************************************************************** +; * +; INTERNAL VARIABLES * +; * +;***************************************************************************** + +; $salut (4,22,26,36) ; ;AN000; +;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. + + + +; INPUT PARMETERS FROM INIT SUBROUTINE: + +S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED + ; SOURCE DRIVE OWNERSHIP +T_OWNER_SAVED DB 0 +RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA + +;IT IS ASSUMED THE NEXT TWO BYTES ARE CONSECUTIVE, +;AND DEFINED IN SOURCE/TARGET ORDER, BY DCOMPPAR.SAL. +SOURCE_DRIVE DB 0 ;1=A:, 2=B:,... +TARGET_DRIVE DB 0 + +ORG_SOURCE_DRIVE DB ? ;ORIGINAL SOURCE DRIVE +ORG_TARGET_DRIVE DB ? ;ORIGINAL TARGET DRIVE + +USER_OPTION DB 0 +COPY_TYPE DB 1 +START_BUFFER DW 0 +BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT] +BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT] +USER_OPTION_8 DB ? +SECT_TRACK_LAYOUT DW 0 + +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 ? + +;LOCAL VARIABLES: +FIRST_TIME DB 0 ;SWITCH TO ACTIVATE VOLSER CHECK ;AN000; +EXITFL DB EXOK ;ERRORLEVEL VALUE ;AN000; + PUBLIC EXITFL ; ;AN000; +EXCBR EQU 2 ;CONTROL-BREAK REQUESTED TERMINATION ;AN000; +EXVER EQU 1 ;BAD DOS VERSION ERRORLEVEL CODE ;AN000; +EXPAR EQU 1 ;ERROR IN INPUT PARMS IN COMMAND LINE ;AN000; +EXOK EQU 0 ;NORMAL ERRORLEVEL RET CODE ;AN000; + PUBLIC EXPAR ; ;AN000; + +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 + +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 gotten from CHECK_SOURCE. +;*** These will be used as a basis for the comp process. +LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79) +END_OF_TRACK DB 15 ;END OF TRACK +bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes +NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED + +TRACK_TO_READ DB 0 +TRACK_TO_COMP DB 0 +TRACK_SIZE DW 0 ;BYTES/CYLINDER [IN SEGMENTS] +SECTOR_SIZE DB 0 ;BYTES/SECTOR [IN SEGMENTS] +BYTES_IN_TRACK DW ? ;BYTES/ONE SIDE TRACK (USED IN COMP_TRACK) +BUFFER_PTR DW ? +COMP_ERROR DB 0 +SIDE DB ? +OPERATION DB ? +COMP_STATUS DB ? +USER_INPUT DB ? ;DISKCOMP AGAIN? +SEC_BUFFER DW ? ;SECONDARY BUFFER SEG ADDR +COMPARE_PTR DW ? ;COMPARE POINTER +IO_ERROR DB 0 ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE +MSG_FLAG DB ? +S_DRV_SET_FLAG DB 0 ;SOURCE DEVICE PARM HAS BEEN SET? +T_DRV_SET_FLAG DB 0 + +;--------------------------------------- +;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, 1=5.25 96 TPI, 2=3.5" 720 KB + ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK +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 ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB + ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK +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 ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB + ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK +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 ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB + ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK +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 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 ? + +;(deleted ;AN011;) MEDIA_ID_BUFFER A_MEDIA_ID_INFO <> ;BUFFER FOR GET/SET MEDIA ID ;AN000; + PATHLABL DISKCOMP ;AN013; + HEADER ; ;AN000; + PUBLIC DISKCOMP_BEGIN ; ;AN000; +DISKCOMP_BEGIN LABEL BYTE +;***************************************************************************** +; * +; D I S K C O M P 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 AREA + CALL SYSLOADMSG ;INIT SYSMSG HANDLER ;AN000; + +; $IF C ;IF THERE WAS A PROBLEM ;AN000; + JNC $$IF1 + CALL SYSDISPMSG ;LET HIM SAY WHY HE HAD A PROBLEM ;AN000; + + MOV EXITFL,EXVER ;TELL ERRORLEVEL BAD DOS VERSION ;AN000; +; $ELSE ;SINCE SYSDISPMSG IS HAPPY ;AN000; + 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 COMP + JNE $$IF3 +; $DO +$$DO4: + CALL COMP ;PERFORM DISKCOMP + + CALL TEST_REPEAT ;COMP ANOTHER ? + +; $ENDDO C + JNC $$DO4 + ;NORMAL RETURN CODE ALREADY IN "EXITFL" +; $ELSE ;ELSE IF ERROR DETECTED IN INIT + JMP SHORT $$EN3 +$$IF3: + MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000; + ;DI HAS OFFSET OF MESSAGE DESCRIPTOR + CALL SENDMSG ;DISPLAY THE ERROR MESSAGE ;AC000; + + MOV EXITFL,EXVER ;ERROR RETURN CODE ;AC000; +; $ENDIF +$$EN3: + JMP SHORT EXIT_TO_DOS + +MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK + MOV EXITFL,EXCBR ; FOR CONTROL-BREAK EXIT ;AC000; + +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, S_OWNER_SAVED + 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, T_OWNER_SAVED + 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: + MOV AL,EXITFL ;PASS ERRORLEVEL RET CODE ;AN000; +; $ENDIF ;OK WITH SYSDISPMSG? ;AN000; +$$EN1: + MOV AL,EXITFL ;PASS BACK ERRORLEVEL RET CODE ;AN000; + DOSCALL RET_CD_EXIT ;RETURN TO DOS WITH RET CODE ;AN000; + + INT 20H ;IF ABOVE NOT WORK, ;AN000; +BEGIN ENDP ; ;AN000; +; = = = = = = = = = = = = = = = = = + HEADER ; ;AN000; +MORE_INIT PROC NEAR ; ;AN000; + RET ;RETURN TO CALLER ;AN000; +MORE_INIT 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 ;IS THIS DRIVE ZERO? + ;IF BL = 0, THEN JUST RETURN +; $IF NE + JE $$IF13 + DOSCALL IOCTL_FUNC,SET_LOG_DRIVE ; ;AC000; + ;SET BL AS AN OWNER OF THAT DRIVE +; $ENDIF +$$IF13: + RET +SET_LOGICAL_DRIVE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +COMP PROC NEAR +;***************************************************************************** + MOV AL,ORG_SOURCE_DRIVE ;INITIALIZE THE FIRST AND SECOND + MOV SOURCE_DRIVE,AL ;DRIVE IN THE ORDER THE USER + MOV AL,ORG_TARGET_DRIVE ;ENTERED ON THE COMMAND LINE + MOV TARGET_DRIVE,AL + MOV AX, RECOMMENDED_BYTES_SECTOR + MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE + ; TO READ A SECTOR + MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG + MOV READ_T_BPB_FAILURE, 0 + MOV COMP_ERROR,0 ;RESET COMPARE ERROR COUNT + MOV COMP_STATUS,OK ;RESET COMP STATUS BYTE + CMP COPY_TYPE,2 ;IF TWO DRIVE COMP +; $IF E + JNE $$IF15 + CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000; + + CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000; + + CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009; + +; $ENDIF +$$IF15: + MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS + MOV TRACK_TO_COMP,0 + +COMP_TEST_END: + MOV AL,TRACK_TO_COMP ;WHILE TRACK_TO_COMP<=LAST_TRACK + CMP AL,LAST_TRACK + JA COMP_END + + CALL READ_SOURCE + + CMP COMP_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE + JE COMP_EXIT + + CALL COMP_TARGET + + CMP COMP_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE + JE COMP_EXIT ;DISKETTES ARE COMPATIBLE + + JMP COMP_TEST_END + +COMP_END: + CMP COMP_ERROR,0 ;IF ERROR IN COMP +; $IF E ;WARN USER + JNE $$IF17 + PRINT MSGNUM_COMP_OK ;"Compare OK" ;AC000; + +;kiser note: this is a warning???? + +; $ENDIF +$$IF17: + +COMP_EXIT: + CMP COMP_STATUS,FATAL ;WAS COMP ABORTED ? +; $IF E + JNE $$IF19 + ;"Compare process ended" + PRINT MSGNUM_FATAL_ERROR ;IF SO THEN TELL USER ;AC000; + +; $ENDIF +$$IF19: + RET + +COMP ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +DISPLAY_LOAD_FIRST PROC NEAR ; ;AN000; + PUBLIC DISPLAY_LOAD_FIRST ; ;AN000; +; = = = = = = = = = = = = + + MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV1_ID ;PASS CHAR DRIVE ID ;AN000; + ;"Insert FIRST diskette in drive %1:" + PRINT MSGNUM_LOAD_FIRST ;OUTPUT LOAD FIRST DISKETTE MESSAGE ;AC000; + + MOV MSG_FLAG,SECOND + RET ;RETURN TO CALLER ;AN000; +DISPLAY_LOAD_FIRST ENDP ; ;AN000; +; = = = = = = = = = = = = + HEADER ; ;AN000; +DISPLAY_LOAD_SECOND PROC NEAR ; ;AN000; + PUBLIC DISPLAY_LOAD_SECOND ; ;AN000; +; = = = = = = = = = = = = + + MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV2_ID ;PASS CHAR DRIVE ID ;AN000; + ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF + PRINT MSGNUM_LOAD_SECOND ;OUTPUT LOAD SECOND DISKETTE MESSAGE ;AC000; + + MOV MSG_FLAG,FIRST + RET ;RETURN TO CALLER ;AN000; +DISPLAY_LOAD_SECOND ENDP ; ;AN000; +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC TEST_REPEAT ;MAKE ENTRY IN LINK MAP ;AN000; +TEST_REPEAT PROC NEAR ;TEST IF USER WANTS TO COMP ANOTHER * +; DISKETTE * +; INPUT : USER_INPUT ("Y" OR "N") +; OUTPUT: NC = COMP AGAIN * +; CY = EXIT TO DOS * +;***************************************************************************** +; $SEARCH ;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED ;AC000; +$$DO21: + ;"Compare another diskette (Y/N)?" + PRINT MSGNUM_COMP_ANOTHER ;SEE IF USER WANTS TO COMPARE ANOTHER ;AC000; + ; AND READ RESPONSE TO AL + PUSH AX ;SAVE THE RESPONSE ;AN000; + PRINT MSGNUM_NEWLINE ;CR,LF,LF ;AC000; + + POP DX ;RESTORE THE REPONSE CHAR TO DL ;AN000; + CALL YESNO ;CHECK FOR (Y/N) ;AN000; + +; $EXITIF C,NUL ;QUIT IF OK ANSWER ;AN000; + JC $$SR21 + CMP AL,BAD_YESNO ;WAS THE RESPONSE INVALID? ;AN000; +; $ENDLOOP B ;QUIT IF OK ANSWER (AX=0 OR 1) ;AN000; + JNB $$DO21 + CMP AL,YES ;WAS "YES" SPECIFIED ;AN000; +; $IF E ;IF "YES" ;AN000; + JNE $$IF24 + MOV FIRST_TIME,ZERO ;SET UP TO DO ANOTHER VOLSER CHECK ;AN000; + CLC ;CLEAR CARRY TO INDICATE COMPARE AGAIN ;AN000; +; $ELSE ;SINCE NOT "YES" ;AN000; + JMP SHORT $$EN24 +$$IF24: + STC ;SET CARRY TO INDICATE NO REPEAT ;AN000; +; $ENDIF ; ;AN000; +$$EN24: +; $ENDSRCH ; ;AN000; +$$SR21: + RET + +TEST_REPEAT ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC READ_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000; +READ_SOURCE PROC NEAR ;FILL ALL AVAILABLE MOMORY WITH SOURCE DATA +; * +;***************************************************************************** + + CMP TRACK_TO_READ,0 ;1ST TRACK ? +; $IF E ;IF SO + JNE $$IF28 + CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP +; $IF E ;PROMPT MSG + JNE $$IF29 + CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000; + + CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC000; + +; $ENDIF +$$IF29: + CALL CHECK_SOURCE ;DO NECESSARY CHECKING + + CALL CALC_TRACK_SIZE + + CALL CHECK_MEMORY_SIZE + + CMP COMP_STATUS,FATAL + JE RS_EXIT + +; $ENDIF +$$IF28: + MOV BX,BUFFER_BEGIN + MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER + +; $DO +$$DO32: + MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS? + CMP AL,LAST_TRACK +; $LEAVE A + JA $$EN32 + + MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE + ADD AX,TRACK_SIZE + CMP AX,BUFFER_END +; $LEAVE A + JA $$EN32 + + CALL READ_TRACK ;NO, GO READ ANOTHER TRACK + + INC TRACK_TO_READ +; $ENDDO + JMP SHORT $$DO32 +$$EN32: + +RS_EXIT: + RET + +READ_SOURCE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC CHECK_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000; +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. +;***************************************************************************** + +CS_AGAIN: + 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? + JE CS_AGAIN + + CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB? + JNE CS_NEW ; ;AC000; +CS_OLD_BRIDGE: + JMP CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST. ;AC000; +CS_NEW: ; ;AN000; + cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86 J.K. + je cs_old_BRIDGE + + cmp ms_deviceBPB.chead,0 ;cannot trust the info. from DOS. + je cs_old ;sanity check for devide 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 ;IF # OF TRACKS FOR SOURCE MEDIA > # OF + ; TRACKS FOR TARGET DEVICE + JA CS_FATAL ;THEN, NOT COMPATIBLE + + DEC AX ;DECREASE BY 1 FOR THIS PROGRAM'S USE. + MOV LAST_TRACK, AL ;SET LAST_TRACK + MOV AX, MS_deviceBPB.CSECT_TRACK + MOV SECT_TRACK_LAYOUT, AX ;VARIABLE FOR MS, MT_trackLayout.CSECT_F + CMP USER_OPTION_8, ON ;/8 OPTION SPECIFIED? + JNE CS_GO_ON + + CMP AX, 8 ;SOURCE MEDIA # OF SECTORS/TRACK < 8 ? + JB CS_FATAL ;IF IT IS, THEN FATAL ERROR. + + MOV AX, 8 ;ELSE SET IT TO 8 +CS_GO_ON: + CMP AL, T_DRV_SECT_TRACK + JA CS_FATAL + + MOV END_OF_TRACK, AL ;SET END_OF_TRACK + 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 COMP_STATUS, FATAL + ;"Drive types or diskette types" + ;"not compatible" + PRINT MSGNUM_NOT_COMPATIBLE ; ;AC000; + + JMP CS_EXIT + +CS_BAD: + MOV COMP_STATUS, FATAL + PRINT MSGNUM_BAD_FIRST ;"FIRST diskette bad or incompatible" ;AC000; + + 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 CS_SECT15 + +CS_OPTION_1: + MOV NO_OF_SIDES, 0 ;1 SIDE COPY + JMP CS_SET_TABLE + +CS_SECT15: + MOV SECT_TRACK_LAYOUT, 15 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F + MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15 + MOV LAST_TRACK, 79 + JMP CS_OPTIONS + +CS_SECT8: + MOV SECT_TRACK_LAYOUT, 8 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F + MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS + MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS. + JMP CS_OPTIONS + +CS_SECT9: + MOV SECT_TRACK_LAYOUT, 9 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F + MOV END_OF_TRACK, 9 + MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE +CS_OPTIONS: + CMP USER_OPTION_8, ON + JNE CS_CHK_SIDE + + MOV END_OF_TRACK, 8 +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? + JNE CS_SET_TABLE_NEXT + + CALL SET_FOR_THE_OLD ;set deviceBPB info for before 2.0 level + +CS_SET_TABLE_NEXT: + MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE + CALL SET_TRACKLAYOUT + + MOV S_DRV_SET_FLAG, 1 ;indicate SOURCE DRIVE + ; PARAMETER HAS BEEN SET + XOR BX, BX + MOV BL, SOURCE_DRIVE + MOV DX, OFFSET MS_IOCTL_DRV_PARM + MOV MS_specialFunctions, SET_SP_FUNC_DEF + CALL SET_DRV_PARM_DEF ;set device parameter for read + + 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 "COMPARING ..." + INC AL + MOV BYTE PTR MSG_TRACKS,AL ;HOW MANY TRACKS? ;AC000; + + MOV AL, END_OF_TRACK + MOV BYTE PTR MSG_SECTRK,AL ;HOW MANY SECTORS? ;AC000; + + MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY + INC AL + MOV BYTE PTR MSG_SIDES,AL ; ;AC000; + ;CR,LF,"Comparing %1 tracks",CR,LF + ;"%2 Sectors/Track, %3 Side(s)",CR,LF + PRINT MSGNUM_COMPARING ; ;AC000; + +CS_EXIT: + RET + +CHECK_SOURCE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC READ_A_SECTOR ;MAKE ENTRY IN LINK MAP ;AN000; +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 + +; $DO +$$DO36: + 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 $$DO36 + + CMP IO_ERROR, HARD_ERROR ;HARD ERROR? +; $IF NE + JE $$IF38 + + CLC ;READ SUCCESS +; $ELSE + JMP SHORT $$EN38 +$$IF38: + + STC ;READ FAILURE, SET CARRY +; $ENDIF +$$EN38: + 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 ;MAKE ENTRY IN LINK MAP ;AN000; +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 + XOR DX, DX + XOR BX, BX + MOV BL, END_OF_TRACK + MUL BX ;ASSUME DX=0 + MOV BYTES_IN_TRACK,AX ;BYTES/TRACK ON A SIDE OF THE DISKETTE + + MOV AX, bSECTOR_SIZE + MOV CL, 16 + DIV CL ;AX / 16 = AL ... AH + CMP AH, 0 ;NO REMAINER? +; $IF NE + JE $$IF41 + + INC AL ;THERE REMAINER IS. INC AL +; $ENDIF +$$IF41: + 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 + + MOV BX,START_BUFFER ;SET SECONDARY AT START OF BUFFER SPACE + MOV SEC_BUFFER,BX ;SET THE SECONDARY BUFFER SEG ADDR + ADD BX,AX ;MOVE THE PRIMARY BUFFER BELOW THE + MOV BUFFER_BEGIN,BX ;SECONDARY BUFFER + POP CX + POP BX + POP AX + + RET + +CALC_TRACK_SIZE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC CHECK_MEMORY_SIZE ;MAKE ENTRY IN LINK MAP ;AN000; +CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COMP 1 TRACK INTO +; TO BUFFER ELSE ABORT COMP * +;***************************************************************************** + MOV AX,BUFFER_END + SUB AX,BUFFER_BEGIN + CMP AX,TRACK_SIZE +; $IF B + JNB $$IF43 + MOV COMP_STATUS,FATAL + ;"Insufficient memory" + PRINT MSGNUM_UNSUF_MEMORY ; ;AC000; + +; $ENDIF +$$IF43: + RET + +CHECK_MEMORY_SIZE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC COMP_TARGET ;MAKE ENTRY IN LINK MAP ;AN000; +COMP_TARGET PROC NEAR ;COMPARE DATA FROM MEMORY TO TARGET DISKETTE +; * +;***************************************************************************** + + CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP +; $IF E ;PROMPT MSG + JNE $$IF45 + CMP MSG_FLAG,SECOND +; $IF E + JNE $$IF46 + CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000; + +; $ELSE + JMP SHORT $$EN46 +$$IF46: + CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000; + +; $ENDIF +$$EN46: + CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009; + +; $ENDIF +$$IF45: + MOV BX,BUFFER_BEGIN + MOV COMPARE_PTR,BX ;INITIALIZE BUFFER POINTER + CMP TRACK_TO_COMP,0 ;IF TRK 0, CHECK COMPATIBILITY +; $IF E + JNE $$IF50 + CALL CHECK_TARGET + + CMP COMP_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT + JE CT_EXIT + +; $ENDIF +$$IF50: + + CALL SWAP_DRIVE + +; $DO +$$DO52: + CALL COMP_TRACK ;NO, GO READ ANOTHER TRACK + + INC TRACK_TO_READ + MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS? + CMP AL,LAST_TRACK +; $LEAVE A + JA $$EN52 + + MOV AX,COMPARE_PTR ;DID WE RUN OUT OF BUFFER SPACE + ADD AX,TRACK_SIZE + CMP AX,BUFFER_END +; $ENDDO A + JNA $$DO52 +$$EN52: + +CT_EXIT: + RET +COMP_TARGET ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC CHECK_TARGET ;MAKE ENTRY IN LINK MAP ;AN000; +CHECK_TARGET PROC NEAR ; * +; ** CHECK_SOURCE PROCEDURE ALREADY CHECKS OUT THE INCOMPATIBILITY BETWEEN * +; ** SOURCE MEDIA AND TARGET DRIVE. (CHECKING SOURCE MEDIA SECTOR/TRACK * +; ** EXCEEDS TARGET DRV SECTOR/TRACK, AND SOURCE MEDIA # OF TRACKS WITH * +; ** THAT OF TARGET DRV.) * +; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. * +; ** IF A SUCCESS,THEN COMPARE BPB INFO WITH THAT OF SOURCE MEDIA. * +; ** IF THEY ARE DIFFERENT, THEN ERROR - NOT COMPATIBLE * +; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR * +; ** COMPATIBILITY REASONS. * +;***************************************************************************** +; $DO +$$DO55: + XOR BX, BX + MOV BL, TARGET_DRIVE + MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b + MOV CL, GETDEVPARM + MOV DX, OFFSET MT_IOCTL_DRV_PARM + CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER + ;WITH THE DEFAULT DEVICE INFO. + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? +; $ENDDO NE + JE $$DO55 + + CMP IO_ERROR, HARD_ERROR ;ASSUME OLD DISKTETTE. OR DISKETTE BAD + JE CHT_OLD + + cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86, J.K. + je cht_old + + cmp mt_deviceBPB.chead,0 ;cannot trust the info from DOS. + je cht_old ;sanity check for devide 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 SOURCE LAST TRACK + JNE CHT_FATAL_BRIDGE ;IF LAST_TRACK IS DIFFERENT, + ; THEN INCOMPATIBLE. + + MOV AX, MT_deviceBPB.CSECT_TRACK + MOV SECT_TRACK_LAYOUT, AX ;VARIBLE FOR MT_trackLayout.CSECT_F +CHT_GO_ON: + CMP END_OF_TRACK, AL + JA CHT_FATAL_BRIDGE ;IF SOURCE END_OF_TRACK > TARGET + ; END_OF_TRACK, THEN ERROR + + ;8 SECTORED SOURCE AND 9 SECTORED TARGET + ; IS OK AS FAR AS THE COMPATIBILITY GOES. + MOV AX, MT_deviceBPB.CBYTE_SECT + CMP AX, bSECTOR_SIZE ;IF SECTOR SIZE ARE DIFFERENT, THEN + ; NOT COMPATIBLE + JNE CHT_FATAL_BRIDGE + + CMP NO_OF_SIDES, 1 ;TWO SIDED COPY? + JNE CHT_SET_BRIDGE ;NO, ONE SIDED. DON'T + ; CARE ABOUT TARGET SIDES. + + CMP MT_deviceBPB.CHEAD, 2 ;TARGET FORMATTED INTO TWO SIDES? + JNE CHT_FATAL_BRIDGE ;NO, NOT COMPATIBLE + + JMP CHT_SET_DRV ;OK. SOURCE, TARGET MEDIA ARE MATCHING. SET + ; DRV PARM FOR READING + +CHT_SET_BRIDGE: + JMP CHT_SET_DRV + +CHT_FATAL_BRIDGE: + JMP CHT_FATAL + +CHT_SECOND_BAD: + MOV COMP_STATUS, FATAL + PRINT MSGNUM_BAD_SECOND ;"SECOND diskette bad or incompatible" ;AC000; + + JMP CHT_EXIT + +CHT_OLD: ;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 CHT_SECOND_BAD ;ASSUME TARGET MEDIA NOT FORMATTED. + + MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9 + CALL READ_A_SECTOR + + JC CHT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA + + MOV IOCTL_SECTOR, 15 + CALL READ_A_SECTOR + + JC CHT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA + +;CHT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA + MOV SECT_TRACK_LAYOUT, 15 + CMP END_OF_TRACK, 15 ;IS SOUCE ALSO 96 TPI? + JNE CHT_FATAL ;NO, FATAL ERROR + + JMP SHORT CHT_CHK_SIDE ;YES, OK. + +CHT_8_SECTOR: + MOV SECT_TRACK_LAYOUT, 8 + CMP END_OF_TRACK, 15 + JE CHT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR + + CMP END_OF_TRACK, 9 + JE CHT_FATAL ;IF SOURCE IS 9 SECTOR, THEN + ; SHOULD FORMAT TARGET + + JMP SHORT CHT_CHK_SIDE ;ELSE ASSUME SOURCE IS 8 SECTOR. + +CHT_9_SECTOR: + MOV SECT_TRACK_LAYOUT, 9 + CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI? THEN ERROR + JE CHT_FATAL ;ELSE SOUCE IS 8 OR 9 SECTORED + ; 48 TPI DISKETTE + +CHT_CHK_SIDE: ;CHECK THE TARGET DISKETTE # OF SIDES + CMP NO_OF_SIDES, 0 ;1 SIDE COMP? + JE CHT_EXIT_OLD ; + + MOV IOCTL_HEAD, 1 ;ELSE TWO SIDE COMP + XOR AX, AX + MOV AL, END_OF_TRACK ;TRY TO READ MATCHING TARGET SECTOR + MOV IOCTL_SECTOR, AX ;OF THE OTHERSIDE + CALL READ_A_SECTOR + + JNC CHT_EXIT_OLD ;SUCCESS? OK + +CHT_FATAL: + CALL COMPAT_ERROR + + JMP SHORT CHT_EXIT + +CHT_EXIT_OLD: + CALL SET_FOR_THE_OLD ;SET MT_deviceBPB INFO. + +CHT_SET_DRV: + MOV BX, OFFSET MT_trackLayout ;SET TARGET TRACK LAYOUT + CALL SET_TRACKLAYOUT + + JC CHT_FATAL ;IF FAILED, THEN, NOT COMPATIBLE + + MOV T_DRV_SET_FLAG, 1 ;INDICATES THE TARGET DEFAULT + ; DEVICE PARM HAS BEEN SET + XOR BX, BX + mov bl, last_track ;To make sure the number of + ; cyl. of target. 3/27/86,J.K. + inc bl + mov MT_numberOfCylinders, bx + MOV BL, TARGET_DRIVE + MOV DX, OFFSET MT_IOCTL_DRV_PARM + MOV MT_specialFunctions, SET_SP_FUNC_DEF + CALL SET_DRV_PARM_DEF + +CHT_EXIT: + RET + +CHECK_TARGET ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC SET_DRV_PARM_DEF ;MAKE ENTRY IN LINK MAP ;AN000; +SET_DRV_PARM_DEF PROC NEAR +;INPUT: BL - DRIVE NUMBER +; DX - POINTER TO THE PARAMETER TABLE +; specialFunction should be set before this call +;***************************************************************************** + + MOV CL, SETDEVPARM ;=40H + CALL GENERIC_IOCTL + + RET + +SET_DRV_PARM_DEF ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC COMP_TRACK ;MAKE ENTRY IN LINK MAP ;AN000; +COMP_TRACK PROC NEAR ;COMPARE TRACK SPECIFIED IN TRACK_TO_COMP +; * +;***************************************************************************** + MOV AX,SEC_BUFFER ;READ IN THE TRACK TO BE COMPARED + MOV BUFFER_PTR,AX ;INTO THE SECONDARY BUFFER + CALL READ_TRACK + + MOV SIDE,0 ;START ON SIDE ZERO + MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE + PUSH DS + PUSH ES + MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR + MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR + + ASSUME ES:NOTHING + ASSUME DS:NOTHING + + XOR DI,DI ;SET TO START OF TRACK + XOR SI,SI + CMP FIRST_TIME,ZERO ;IF THIS IS THE FIRST SECTOR TO BE COMPARED ;AN000; +; $IF E ; ;AN000; + JNE $$IF57 + CALL VOLSER ;SPECIAL HANDLING FOR VOL SER # ;AN000; + + MOV FIRST_TIME,ONE ;FLAG FIRST TIME AS "DONE" ;AN000; +; $ENDIF ; ;AN000; +$$IF57: + CALL DO_COMPARE ;COMPARE STRING ;AN000; + + POP ES + POP DS + + ASSUME ES:CSEG + ASSUME DS:CSEG + +; $IF NZ + JZ $$IF59 + PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT + MOV OPERATION,COMPARE_FUNC + CALL ERROR_MESSAGE + + INC COMP_ERROR + POP AX +; $ENDIF +$$IF59: + CMP NO_OF_SIDES,1 ;TWO SIDED COMPARE? +; $IF E ;YES + JNE $$IF61 + MOV SIDE,1 ;MARK IT AS SUCH + MOV SI,BYTES_IN_TRACK ;BUMP UP BUFFER POINTERS + MOV DI,BYTES_IN_TRACK ;TO START OF SECOND SIDE + MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE + PUSH DS + PUSH ES + MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR + MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR + CALL DO_COMPARE ;COMPARE STRING ;AN000; + + POP ES + POP DS +; $IF NZ + JZ $$IF62 + PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT + MOV OPERATION,COMPARE_FUNC + CALL ERROR_MESSAGE + + INC COMP_ERROR + POP AX +; $ENDIF +$$IF62: +; $ENDIF +$$IF61: + MOV AX,TRACK_SIZE ;ADVANCE COMPARE POINTER + ADD COMPARE_PTR,AX + RET +COMP_TRACK ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +DO_COMPARE PROC NEAR ; ;AN000; + PUBLIC DO_COMPARE ;ADD ENTRY TO LINK MAP ;AN000; +;INPUT: DS:[SI] POINTS TO ONE BUFFER, ES:[DI] POINTS TO THE OTHER +; CX HAS THE BYTE COUNT +;OUTPUT:CONDITION CODE IN CONDITION FLAGS REFLECT RESULT OF COMPARISON +; = = = = = = = = = = = = + SHR CX,1 ;DIVIDE BY TWO, CHANGE TO WORD COUNT ;AN000; + + PUBLIC PATCH_386 ;SO INIT CAN DO FIXUP ;AN001; +PATCH_386 LABEL BYTE + SHR CX,1 ;CONVERT WORD COUNT TO DWORD COUNT ;AN001; + DB 66H ;PREFIX FOR A DWORD COMPARE ;AN001; +; END OF PATCH AREA. IF THIS IS NOT A 386, THE ABOVE 3 BYTES ARE CHANGED +; TO NOP BY DISKINIT.SAL DURING INITIALIZATION. + + REPE CMPSW ;PERFORM THE COMPARISON ;AN000; + + RET ;RETURN TO CALLER ;AN000; +DO_COMPARE ENDP ; ;AN000; +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC SWAP_DRIVE ;MAKE ENTRY IN LINK MAP ;AN000; +SWAP_DRIVE PROC NEAR ;SWAP SOURCE, TARGET DRIVE +;***************************************************************************** + MOV AL,SOURCE_DRIVE + XCHG AL,TARGET_DRIVE + MOV SOURCE_DRIVE,AL + MOV AL,TRACK_TO_COMP + XCHG AL,TRACK_TO_READ + MOV TRACK_TO_COMP,AL + RET + +SWAP_DRIVE ENDP + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC READ_TRACK ;MAKE ENTRY IN LINK MAP ;AN000; +READ_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY +; * +;***************************************************************************** + + MOV SIDE, 0 +; $DO +$$DO65: + CALL READ_OP + + CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY? +; $IF E ;YES + JNE $$IF66 + MOV AX, TRACK_SIZE +; $ELSE ;NO, DOUBLE SIDE + JMP SHORT $$EN66 +$$IF66: + XOR DX, DX + MOV AX, TRACK_SIZE + MOV CX, 2 + DIV CX ;AX / 2 +; $ENDIF +$$EN66: + ADD BUFFER_PTR, AX + INC SIDE ;NEXT SIDE + MOV AL, SIDE + CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE? +; $ENDDO G + JNG $$DO65 + RET + +READ_TRACK ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** +; * + PUBLIC READ_OP ;MAKE ENTRY IN LINK MAP ;AN000; +READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION +; * +;***************************************************************************** +; $SEARCH +$$DO70: +RO_AGAIN: + 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,NUL + JE $$SR70 + + CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN? +; $ENDLOOP NE + JE $$DO70 + + MOV OPERATION, READ_FUNC + PUSH AX + CALL ERROR_MESSAGE + + POP AX + INC COMP_ERROR ;INCREASE COPY_ERROR COUNT +; $ENDSRCH +$$SR70: + RET +READ_OP ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC SET_FOR_THE_OLD ;MAKE ENTRY IN LINK MAP ;AN000; +SET_FOR_THE_OLD PROC NEAR +;set MS_deviceBPB or MT_deviceBPB for before-2.0 formatted media. +;***************************************************************************** + PUSH AX + + CMP SECT_TRACK_LAYOUT,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 $$IF74 + MOV SI, OFFSET BPB96 +; $ELSE + JMP SHORT $$EN74 +$$IF74: + CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY? +; $IF NE + JE $$IF76 + MOV SI, OFFSET BPB48_DOUBLE ;ELSE USE BPB48 DOUBLE +; $ELSE + JMP SHORT $$EN76 +$$IF76: + MOV SI, OFFSET BPB48_SINGLE +; $ENDIF +$$EN76: +; $ENDIF +$$EN74: + MOV AX, SECT_TRACK_LAYOUT + CMP READ_S_BPB_FAILURE, 1 ;FAILURE ON THE SOURCE? +; $IF E + JNE $$IF80 + 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 +; $ELSE + JMP SHORT $$EN80 +$$IF80: + CMP READ_T_BPB_FAILURE, 1 ;FAILURE ON THE TARGET? +; $IF E + JNE $$IF82 + MOV MT_deviceBPB.CSECT_TRACK,AX + MOV DI, OFFSET MT_deviceBPB + MOV CX, BPB96_LENG + REP MOVSB ;OLD DEFAULT BPB INTO => MT_deviceBPB +; $ENDIF +$$IF82: +; $ENDIF +$$EN80: + POP AX + RET +SET_FOR_THE_OLD ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;***************************************************************************** + PUBLIC SET_TRACKLAYOUT ;MAKE ENTRY IN LINK MAP ;AN000; +SET_TRACKLAYOUT PROC NEAR +;INPUT: BX - POINTER TO DESTINATION +; SECT_TRACK_LAYOUT +;***************************************************************************** + MOV CX, SECT_TRACK_LAYOUT ;MEDIA SECTORS/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 +$$DO85: + CMP CX, SECT_TRACK_LAYOUT +; $LEAVE A + JA $$EN85 + + MOV WORD PTR [BX], CX + INC BX + INC BX + MOV WORD PTR [BX], AX + INC BX + INC BX + + INC CX +; $ENDDO + JMP SHORT $$DO85 +$$EN85: + + RET +SET_TRACKLAYOUT ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +PUBLIC GENERIC_IOCTL +;****************************************************************************** +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 +; 62 - VERIFY TRACK +; BL - LOGICAL DRIVE LETTER +; DS:DX - POINTER TO PARAMETERS +;****************************************************************************** + + MOV IO_ERROR, NO_ERROR ;reset io_error + MOV AH, IOCTL_FUNC ;IOCTL FUNC = 44H + MOV AL, GENERIC_IOCTL_CODE ;GENERIC IOCTL REQUEST = 0DH + MOV CH, MAJOR_CODE ;MAJOR CODE=08H, REMOVABLE + INT 21H +; $IF C + JNC $$IF88 + CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS! + +; $ENDIF +$$IF88: + RET +GENERIC_IOCTL ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +;****************************************************************************** + PUBLIC EXTENDED_ERROR_HANDLER ;MAKE ENTRY IN LINK MAP ;AN000; +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, 59H + MOV BX, 0 + INT 21H + +; CMP BL, 5 ;ACTION=IMMEDIATE EXIT? +; JE EEH_JUST_EXIT + + POP BX ;RESTORE BL FOR DRIVE LETTER + POP DS + POP ES + + CMP AX, 21 ;DRIVE NOT READY? + JE WARN_USER_1 + + CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED? + JE WARN_USER_2 + + JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR + +WARN_USER_1: + MOV DRIVE_LETTER, 'A' + DEC BL ;CHANGE LOGICAL TO PHYSICAL + ADD DRIVE_LETTER, BL + ;"Drive not ready - X:" + PRINT MSGNUM_GET_READY ; ;AC000; + + PRINT MSGNUM_CLOSE_DOOR ;"Make sure a diskette is inserted into ;AN004; + ; the drive and the door is closed" + JMP WAIT_FOR_USER + +WARN_USER_2: + ;"Attempt to write to write-protected diskette" + PRINT MSGNUM_WRITE_PROTECT ; ;AC000; + +WAIT_FOR_USER: + CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009; + +EEH_SOFT_ERROR: + MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN + JMP SHORT EEH_EXIT + +EEH_HARD_ERROR: + MOV IO_ERROR, HARD_ERROR + +EEH_EXIT: + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + RET + +;EEH_JUST_EXIT: +; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT + +EXTENDED_ERROR_HANDLER ENDP +.XLIST +; 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; +ERROR_MESSAGE PROC NEAR ;DISPLAY ERROR MESSAGE + PUBLIC ERROR_MESSAGE +; +; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE) +; AND WHERE IT FAILED (TRACK NO. AND SIDE). +; +; INPUT: OPERATION = IOCTL DISKETTE READ(=61H) OR COMPARE_FUNC(59H) +; = = = = = = = = = = = = + + CMP OPERATION,READ_FUNC ;ERROR DURING READ ? +; $IF E + JNE $$IF90 +.XLIST +; MOV BX,OFFSET READ_ERROR ;TELL USER ERROR DURING READ OP +; MOV MSG_HARD_ERROR_PTR+2,BX +.LIST + MOV DL,SOURCE_DRIVE ;WHICH DRIVE IS BAD + dec dl ;change logical letter to phisical + ADD DL,"A" ;CORRESPONDANT ALPHABET + MOV DRIVE_LETTER,DL + MOV SUBLIST_17B.SUB_VALUE,OFFSET DRIVE_LETTER ; + + MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ + ;CR,LF,"Unrecoverable read error on drive %2",CR,LF + ;"side %3, track %4",CR,LF + ;%2 IS "DRIVE_LETTER", AND + ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4. + MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ; ;AN000; +; $ELSE + JMP SHORT $$EN90 +$$IF90: +.XLIST +; MOV BX,OFFSET COMPARE_ERROR ;TELL USER ERROR DURING COMPARE OP +; MOV MSG_HARD_ERROR_PTR+2,BX +.LIST + MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR WRITE + ;CR,LF,"Compare error on",CR,LF + ;"side %3, track %4",CR,LF + ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4. + MOV DI,OFFSET MSGNUM_HARD_ERROR_COMP ; ;AN000; +; $ENDIF +$$EN90: + + MOV AL,SIDE + MOV BYTE PTR MSG_SIDES,AL + MOV BYTE PTR MSG_TRACKS,BL + CALL SENDMSG ;PRINT MSG SELECTED ABOVE ;AN000; + + RET +ERROR_MESSAGE ENDP +; = = = = = = = = = = = = + HEADER ; ;AN000; +COMPAT_ERROR PROC NEAR ;DISPLAY COMPAT MSG + PUBLIC COMPAT_ERROR +; = = = = = = = = = = = = + + MOV COMP_STATUS,FATAL ;INCOMPATIBLE, ABORT + ;"Drive types or diskette types" + ;"not compatible" + PRINT MSGNUM_NOT_COMPATIBLE + + RET +COMPAT_ERROR ENDP +; = = = = = = = = = = = = + HEADER ; ;AN009; +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_NEWLINE ;SKIP A SPACE ;AN009; + + PRINT MSGNUM_STRIKE ;"Press any key when ready..." ;AN009; + + RET ;RETURN TO CALLER ;AN009; +PRESS_ANY_KEY ENDP ; ;AN009; +; = = = = = = = = = = = = + 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 ; SAVE CALLER'S REGS ;AN000; + PUSH CX ; ;AN000; + PUSH DX ; ;AN000; + PUSH SI ; ;AN000; + +; PASS PARMS TO MESSAGE HANDLER IN +; THE APPROPRIATE REGISTERS IT NEEDS. + MOV AX,[DI].MSG_NUM ;MESSAGE NUMBER ;AN000; + MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000; + MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000; + MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000; + MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000; + CALL SYSDISPMSG ;DISPLAY THE MESSAGE ;AN000; + +; $IF C ;IF THERE IS A PROBLEM ;AN000; + JNC $$IF93 + ;AX=EXTENDED ERROR NUMBER ;AN000; + LEA DI,MSGNUM_EXTERR ;GET REST OF ERROR DESCRIPTOR ;AN000; + MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000; + MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000; + MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000; + MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000; + CALL SYSDISPMSG ;TRY TO SAY WHAT HAPPENED ;AN000; + + STC ;REPORT PROBLEM ;AN000; +; $ENDIF ;PROBLEM WITH DISPLAY? ;AN000; +$$IF93: + + POP SI ;RESTORE CALLER'S REGISTERS ;AN000; + POP DX ; ;AN000; + POP CX ; ;AN000; + POP BX ; ;AN000; + + RET ;RETURN TO CALLER ;AN000; +SENDMSG ENDP ; ;AN000; +; = = = = = = = = = = = = + HEADER ; ;AN000; +YESNO PROC NEAR ; ;AN000; + PUBLIC YESNO ;MAKE ENTRY IN LINK MAP ;AN000; +;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED +;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" +; = = = = = = = = = = = = + ;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 ;(6523H) GET EXTENDED ;AN000; + ; COUNTRY INFORMATION, (Y/N) + INT 21H ;SEE IF Y OR N ;AN000; + + RET ;RETURN TO CALLER ;AN000; +YESNO ENDP ; ;AN000; +; = = = = = = = = = = = = + HEADER ; ;AN000; +VOLSER PROC NEAR ;VERIFY FIRST SECTOR, IGNORING VOL SER # ;AN000; + PUBLIC VOLSER ; ;AN000; +;IF THE FIRST DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN +;COPY IT TO THE SECOND DISKETTE BUFFER AREA (NOT THE DISKETTE). +;INPUT: FIRST DRIVE NUMBER +; DS:=SEGID OF BUFFER OF FIRST DISKETTE, FIRST SECTOR, SIDE 0 +; ES:=SEGID OF BUFFER OF SECOND DISKETTE, FIRST SECTOR, SIDE 0 +; SI AND DI = 0, INDEX OF WHERE IN BUFFERS TO START LOOKING +; CX="BYTES_IN_TRACK"; NUMBER OF BYTES TO BE EVENTUALLY COMPARED +;OUTPUT: BUFFER OF 2ND DISKETTE ALTERED TO MATCH THE VOL SERIAL NUMBER OF 1ST. +; = = = = = = = = = = = = = = = = = = + + ASSUME DS:NOTHING ;BUFFER OF FIRST DISKETTE ;AN000; + ASSUME ES:NOTHING ;BUFFER OF SECOND DISKETTE ;AN000; + + PUSH CX ;SAVE CALLER'S REGS ;AN000; + PUSH SI ; ;AN000; + PUSH DI ; ;AN000; +;(deleted ;AN011;) PUSH DS ;SAVE BUFFER OF FIRST DISKETTE ;AN000; + +;(deleted ;AN011;) PUSH CS ;RESTORE ADDRESSABILITY TO COMMON SEG ;AN000; +;(deleted ;AN011;) POP DS ; TO ACCESS GET MEDIA ID BUFFER AREA ;AN000; +;(deleted ;AN011;) ASSUME DS:CSEG ;AN000; + +;(deleted ;AN011;); ISSUE GET MEDIA ID FROM SOURCE +;(deleted ;AN011;) MOV BH,0 ;BH=0, RES ;AN000; +;(deleted ;AN011;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (A:=1, B:=2, ETC.) ;AN000; +;(deleted ;AN011;) MOV DX,OFFSET MEDIA_ID_BUFFER ;DS:DX=BUFFER +;(deleted ;AN011;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC008; +;(deleted ;AN011;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD) +;(deleted ;AN011;) POP DS ;RESTORE THIS BACK TO BUFFER OF FIRST DISKETTE;AN000; +;(deleted ;AN011;) ASSUME DS:NOTHING ; LIKE IT WAS AT ENTRY TO THIS PROC ;AN000; + +;(deleted ;AN011;) $IF NC ;IF THERE IS NO PROBLEM ;AN000; +;(deleted ;AN011;) ; THEN THIS DISKETTE HAS A VOL SER # + + PUSH BX ;AN011; + LEA BX,DS:[DI].EXT_BOOT_BPB ;AN011;POINT TO BPB PORTION OF BOOT RECORD + MOV AL,DS:[BX].EBPB_MEDIADESCRIPTOR ;AN011;GET TYPE OF MEDIA + AND AL,0F0H ;AN011;SAVE LEFT NIBBLE ONLY + CMP AL,0F0H ;AN011;IF DISKETTE HAS PROPER DESCRIPTOR +; $IF E ;AN011; + JNE $$IF95 + MOV AL,DS:[DI].EXT_BOOT_SIG ;AN011;GET "SIGNATURE" OF BOOT RECORD + CMP AL,28H ;AN011;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1? +; $IF E,OR ;AN011;YES, IS A BOOT WITH A SERIAL IN IT + JE $$LL96 + CMP AL,29H ;AN011;IS THIS A BOOT STYLE OF OS/S 1.2? +; $IF E ;AN011;YES, IS A BOOT WITH A SERIAL IN IT + JNE $$IF96 +$$LL96: + +;THE PURPOSE HERE IS TO CAUSE DISKCOMP TO IGNORE ANY DIFFERENCES IN THE +;VOL SERIAL NUMBER FIELD. THIS IS DONE BY TAKING ONE VOL SERIAL NUMBER +;FROM ONE BUFFER, ALREADY LOADED WITH THE FIRST TRACK OF ONE DISKETTE, +;AND MOVING THAT SERIAL NUMBER TO THE CORRESPONDING POSITION IN THE OTHER +;BUFFER, ALREADY LOADED WITH THE SIMILAR TRACK FROM THE OTHER DISKETTE. +;WHEN THIS RETURNS TO THE MAIN ROUTINE, THE ENTIRE TRACK (INCUDING THIS +;VOL SERIAL NUMBER FIELD) WILL BE COMPARED. IF THERE ARE ANY DIFFERENCES, +;THEY WILL BE OTHER THAN IN THE VOL SERIAL NUMBERS. + + MOV SI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS + MOV DI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS + MOV CX,TYPE VOL_SERIAL ;GET NUMBER BYTES IN VOL SER FIELD + REP MOVSB ;FORCE THE SERIAL NUMBERS TO BE ALIKE + +; $ENDIF ; ;AN000; +$$IF96: +; $ENDIF ;AN011; +$$IF95: + POP BX ;AN011; + POP DI + POP SI + POP CX ;RESTORE COUNT + RET ;RETURN TO CALLER ;AN000; +VOLSER ENDP ;AN000; +; = = = = = = = = = = = = = = = = = = = +DISKCOMP_END LABEL BYTE + PATHLABL DISKCOMP ;AN013; +CSEG ENDS + END DISKCOMP + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU b/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU new file mode 100644 index 0000000..3777c37 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.EQU @@ -0,0 +1,170 @@ + + IF1 + %OUT INCLUDING DISKCOMP.EQU... + ELSE +; %OUT INCLUDING DISKCOMP.EQU... + ENDIF + +;---------------------------------------------------------------------------; +; 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 +HARD_ERROR EQU 02 +SOFT_ERROR EQU 01 +NO_ERROR EQU 0 +;DOS_LEVEL EQU 0314H ;DOS VERSION 3.20 +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 FUNTION +NRLMAX EQU 1CH ;(MAXIMUM # OF NAMES ON NRL) - 1 +DOS20 EQU 2 ;DOS VERSION 2.0 + PUBLIC FINE ; ;AN000; +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 + +PAGE +; *** 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 *** + +RET_CD_EXIT EQU 4CH ;EXIT TO DOS, PASSING RETURN CODE ;AN000; +PUT_CHAR EQU 02H ;DOS DISPLAY OUTPUT FUNCTION +PRINT_FUNC EQU 09H ;DOS PRINT STRING FUNCTION +REDIRECTED_FUNC EQU 09H ;IOCTL SUB FUNCTION ****** TO BE CHECKED **** +KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT (CLEARS INPUT BUFF FIRST) +CURRENTDRV_FUNC EQU 19H ;GET CURRENT DRIVE FUNCTION CALL +;DOSVER_FUNC EQU 30H ;DOS VERSION FUNCTION CALL +IOCTL_FUNC EQU 44H ;IOCTL FUNCTION CALL +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 +GET_EXT_CNTRY_INFO EQU 65H ;GET EXTENDED COUNTRY INFO ;AN000; +YESNO_CHECK EQU 23H ;REQUEST (Y/N) CHECK OF GET_EXT_CNTRY_INFO ;AN000; +YES EQU 1 ;(Y/N) RESPONSE IS "YES" ;AN000; +BAD_YESNO EQU 2 ;(Y/N) RESPONSE IS NEITHER "Y" NOR "N" ;AN000; + +;IOCTL DISKETTE I/O FUNCTIONS +GENERIC_IOCTL_CODE EQU 0DH ;GENERIC IOCTL REQUEST +MAJOR_CODE EQU 08H ;GENERIC IOCTL MAJOR CODE +READ_FUNC EQU 61H ;IOCTL DISKETTE RAED FUNCITON +WRITE_FUNC EQU 41H ;IOCTL DISKETTE WRITE FUNCTION +VERIFY_FUNC EQU 62H ;IOCTL DISKETTE VERIFY FUNCTION +FORMAT_FUNC EQU 42H ;IOCTL DISKETTE FORMAT FUNCITON +GETDEVPARM EQU 60H ;IOCTL GET DEVICE PARAMETER +SETDEVPARM EQU 40H ;IOCTL SET DEVICE PARAMETER +SET_LOG_DRIVE EQU 0FH ;SET LOGICAL DRIVE ;AN000; +GSET_MEDIA_ID EQU 69H ;GET/SET MEDIA ID ;AN008; +GET_ID EQU 0 ;AL=0, GET MEDIA ID ;AN008; +SET_ID EQU 1 ;AL=1, SET MEDIA ID ;AN008; +; +COMPARE_FUNC EQU 59H ;JUST USED TO IDENTIFY FOR ERROR MESSAGE +; +;specialFunctions +GET_SP_FUNC_DEF EQU 00000000B ;GET DEVICE PARM. DEFAULT BPB +GET_SP_FUNC_MED EQU 00000001B ;GET DEVICE PARM. media bpb +SET_SP_FUNC_DEF EQU 00000100B ;SET DEFAULT DEVICE PARM +SET_SP_FUNC_DOS EQU 00000100B ;SET DEVICE PARM BEFORE RETURN TO DOS +R_W_SP_FUNC EQU 00000000B ;READ, WRITE + +; *** 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 + +; *** COPY STATUS BYTE *** + +FATAL EQU 01H ;FATAL COPY ERROR, ABORT +OK EQU 00H ;OK, PROCEED + +; *** MESSAGES SUBLIST DESCRIPTOR *** + +SUBLIST STRUC ;AN000; +SUB_SIZE DB ? ;SUBLIST SIZE (POINTER TO NEXT SUBLIST) ;AN000; +SUB_RES DB ? ;RESERVED ;AN000; + ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN000; +SUB_VALUE DW ? ;TIME, DATE, OR PTR TO DATA ITEM ;AN000; +SUB_VALUE_SEG DW ? ;SEG ID OF PTR ;AN000; + ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN000; + ; IF THIS IS A .COM FILE) ;AN000; +SUB_ID DB ? ;N OF %N ;AN000; +SUB_FLAGS DB ? ;DATA TYPE FLAGS ;AN000; +SUB_MAX_WIDTH DB ? ;MAXIMUM FIELD WIDTH (0=UNLIMITED) ;AN000; +SUB_MIN_WIDTH DB ? ;MINIMUM FIELD WIDTH ;AN000; +SUB_PAD_CHAR DB ? ;CHARACTER FOR PAD FIELD ;AN000; + ; CAN BE " ", "0" OR ",". ;AN000; + ; "," CAUSES INSERTION OF THE ACTIVE ;AN000; + ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN000; +SUBLIST ENDS ;AN000; + + ;BUFFER AREA FOR COMMUNICATION WITH GET/SET MEDIA ID FUNCTION CALL: +;(deleted ;AN011;) A_MEDIA_ID_INFO struc +;(deleted ;AN011;) MI_level dw 0 ;info level +;(deleted ;AN011;) MI_Serial dd 0 ;Serial # +;(deleted ;AN011;) MI_Label db 11 dup (' ') ;Volume Label +;(deleted ;AN011;) MI_System db 8 dup (' ') ;File System type +;(deleted ;AN011;) A_MEDIA_ID_INFO ends + INCLUDE BOOTFORM.INC ;GET DESCRIPTION OF BOOT RECORD +VOL_SERIAL EQU EXT_BOOT_SERIAL ;LOCATION IN BOOT RECORD OF VOLSER NUM ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK b/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK new file mode 100644 index 0000000..a6d0f36 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.LNK @@ -0,0 +1,6 @@ +DISKCOMP+ +DCOMPSM+ +DCOMPP+ +DCOMPPAR+ +COMPINIT; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL b/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL new file mode 100644 index 0000000..44e8251 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.SKL @@ -0,0 +1,56 @@ +:util DISKCOMP ;AN000;utility name +:class A ;AN000;system messages +; +:use 1 COMMON1 ;AN000;"Incorrect DOS version" +; +:use 2 EXTEND8 ;AN000;"Insufficient memory" +; +:use 3 PARSE10 ;AN000;"Invalid parameter" +; +:def 4 "Do not specify filename(s)",CR,LF ;AN000; +"Command format: DISKCOMP d: d: [/1][/8]",LF,CR ;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 DISKCOMP to or from",CR,LF ;AN000; +"a network drive",CR,LF ;AN000; +; +:def 7 CR,LF,"Insert FIRST diskette in drive %1:",CR,LF ;AN000; + +:def 8 CR,LF,"Insert SECOND diskette in drive %1:",CR,LF ;AN000; + +:def 9 CR,LF,"FIRST diskette bad or incompatible",CR,LF ;AN000; + +:def 10 CR,LF,"SECOND diskette bad or incompatible",CR,LF ;AN000; +; +:use 11 EXTEND21 ;AN000;"Drive not ready" NOTE CHANGE %1 TO %0 +; +:use 12 COMMON28 ;AN000;"Press any key to continue . . ." +; +:use 13 EXTEND19 ;AN000;CR,LF,"Attempt to write to write-protected diskette",CR,LF +; +:def 14 CR,LF,"Compare another diskette (Y/N) ?" ;AN000; +; +:def 15 CR,LF,"Comparing %1 tracks",CR,LF ;AN000; +"%2 sectors per track, %3 side(s)",CR,LF ;AN000; +; +:def 16 CR,LF,"Drive types or diskette types",CR,LF ;AN000; +"not compatible",CR,LF ;AN000; +; +:def 17 CR,LF,"Unrecoverable read error on drive %2",CR,LF ;AN000; +"side %3, track %4",CR,LF ;AN000; +; +:def 18 CR,LF,"Compare error on",CR,LF,"side %3, track %4",CR,LF ;AN000; +; +:def 19 "Make sure a diskette is inserted into",CR,LF ;AN004; +"the drive and the door is closed",CR,LF ;AN004; +; +:def 20 CR,LF,"Compare process ended",CR,LF ;AN000; +; +:def 21 CR,LF,"Compare OK",CR,LF ;AN000; +; +:def 22 CR,LF ;AC007; +:end ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/DISKCOMP/MAKEFILE b/v4.0/src/CMD/DISKCOMP/MAKEFILE new file mode 100644 index 0000000..09415b1 --- /dev/null +++ b/v4.0/src/CMD/DISKCOMP/MAKEFILE @@ -0,0 +1,59 @@ +#************************** makefile for cmd\append *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h + +# +####################### dependencies begin here. ######################### +# + +all: diskcomp.com + +diskcomp.ctl: diskcomp.skl \ + $(msg)\$(COUNTRY).msg \ + makefile + +diskcomp.obj: diskcomp.asm \ + makefile \ + dcmpmacr.inc \ + $(inc)\bootform.inc \ + diskcomp.equ + +compinit.obj: compinit.asm \ + makefile \ + dcmpmacr.inc \ + $(inc)\bootform.inc \ + diskcomp.equ + +dcompp.obj: dcompp.asm \ + makefile \ + $(inc)\parse.asm + +dcompsm.obj: dcompsm.asm \ + makefile \ + $(inc)\sysmsg.inc \ + $(inc)\msghan.inc \ + $(inc)\versiona.inc \ + diskcomp.ctl \ + diskcomp.cla \ + diskcomp.cl1 \ + diskcomp.cl2 \ + dcompms.inc \ + $(inc)\copyrigh.inc + +dcomppar.obj: dcomppar.asm \ + makefile + +diskcomp.com: diskcomp.obj \ + makefile \ + diskcomp.lnk \ + dcompsm.obj \ + dcompp.obj \ + dcomppar.obj \ + compinit.obj + link @diskcomp.lnk + exe2bin diskcomp.exe diskcomp.com + del diskcomp.exe + -- cgit v1.2.3