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 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1123 insertions(+) create mode 100644 v4.0/src/CMD/DISKCOMP/COMPINIT.ASM (limited to 'v4.0/src/CMD/DISKCOMP/COMPINIT.ASM') 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 -- cgit v1.2.3