home *** CD-ROM | disk | FTP | other *** search
- ;«RM82»«TS8,16,24,32,40,48»
- ;updated 11/21/90
-
- ;============================================================================
- ; Copyright (C) Copr. 1990 by Sidney J. Kelly
- ; All Rights Reserved.
- ; Sidney J. Kelly
- ; 150 Woodhaven Drive
- ; Pittsburgh, PA 15228
- ; home phone 412-561-0950 (7pm to 9:30pm EST)
- ;============================================================================
-
- DOSSEG
- .MODEL MEDIUM
-
- Public GETDRIVE, GETSUB, DRVSPACE, SETDRIVE, SUBEXIST, FLOPPYREADY, FLOPPYDRIVES, HARDRIVES, GETCURRENTNAME, TRUENAME, GETFULLPATH
-
- .CODE
-
- ; Please do not remove
- Copyright DB 13,10,'Copyright Copr. (C) 1990 Sidney J. Kelly',13,10
- Copyright1 DB 'All Rights Reserved',13,10,26
-
- ;============================================================================
- ; DECLARE SUB GETDRIVE(DRIVE$)
- ; CALL GETDRIVE(DRIVE$)
- ; Returns current drive name
- ; If LEN(DRIVE$)=0 then nothing happens
- ;
- ; Assumes that DRIVE$ is a near string, not TYPEd or part of a far string
- ; array. In other words, assumes DRIVE$ is in DGROUP
- ;============================================================================
-
- EVEN
- GETDRIVE PROC FAR
- Push BP
- Mov BP,SP ;save base frame
- Mov BX,[BP+6]
- Mov CX,[BX]
- Jcxz Error1 ;test LEN(Drive$) if 0 exit
- Mov AH,19h
- Int 21h
- Add AL,'A' ;Add A to value
- Xor AH,AH ;clear AH to 0
- Mov BX,[BP+6] ;get address of string descripter
- Mov BX,[BX+2] ;get actual string address
- Mov [BX],AL ;store AL in Drive$
- Error1:
- Pop BP
- Ret 2 ; one parameter passed
- ; so remove it
- GETDRIVE ENDP
-
- ;============================================================================
- ; DECLARE SUB GETSUB (PATH AS STRING * 64, PATHLEN%)
- ; Returns current subdirectory path, without Drive:\, (i.e. no "A:\")
- ; if LEN(Path$) not = to 64 then returns a pathlen% of -1
- ;
- ; PATH$ can not be a TYPEd string or a variable in a string array
- ; because there is a chance that string will be outside DGROUP.
- ; This routine assumes that Path$ is a near string.
- ;============================================================================
-
- EVEN
- GETSUB PROC FAR
- Push BP ;set up base pointer
- Mov BP,SP ;allow us to address the stack
- Push SI ;save index registers
- Push DI ; ditto
- Mov AX,SS
- Mov ES,AX ;set ES = to DGROUP for scasb
-
- assume ES:@data
-
- Mov BX,[BP+8] ;get address of Path$
- Mov AX,ES:[BX]
- Cmp AX,64 ;if LEN(PATH$) <> 64
- JNE Error ;then Error
- Mov SI,ES:[BX+2] ;it has to be 64 so Pathlen% value is
- Mov DI,SI ;calculated correctly below
- Xor DL,DL ;select default drive
- Mov AH,47h ;get current directory
- Int 21h
- JC Error ;if carry set, directory invalid
- Mov CX,64 ;determine length of Path$
- Xor AL,AL ;clear AL, the value to search
- ;for ending null
- Cld ;clear direction flag
- Repnz Scasb ;scan until reach end of Path$
- Mov AX,63 ;determine length of Path$
- Sub AX,CX
- Jmp Short finis
- Error:
- Mov AX,-1 ;return Pathlen% = -1 if error
- finis:
- Mov BX,[BP+6]
- Mov ES:[BX],AX
- Pop DI ;restore registers used
- Pop SI
- Pop BP
- Ret 4
- GETSUB ENDP
-
- ;============================================================================
- ; DECLARE SUB DRVSPACE (DRIVE$,SPACE&)
- ; checks if DRIVE$ <"A" or >"z", or if >"Z" & less <"a"
- ; Drive of "@" gives the current drive
- ; Invalid DRIVE$ gives a free space of 0
- ; Note: DOS does not correctly adjust this if use JOIN or SUBST and
- ; try to determine the size of a non-default drive.
- ;============================================================================
-
- EVEN
- DRVSPACE PROC FAR
- Push BP
- Mov BP,SP
- Mov BX,[BP+8] ;get drive letter from first parameter
- Mov CX,[BX]
- Jcxz Error_Set ;DRIVE$ is a null string so exit
- Mov BX,[BX+2] ;get string address
- Mov DL,[BX] ;store string in DL
- Xor DH,DH
- Cmp DL,'@' ;check if less than "@"
- JB Error_Set
- Cmp DL,'z' ;check if > "z"
- JA Error_Set
- Cmp DL,'@' ;select current if "@"
- JNE Spec_drive ;check if want current drive
- Mov AH,36h
- Xor DX,DX ;0 is current drive number
- Int 21h ;read current drive free space
- Cmp AX,0ffffh ;did an error occur?
- JE Error_Set ;routine returned invalid drive
- Jmp Short Quit ;valid drive
- Spec_drive:
- And DL,1fh ;allow A to Z or a to z
- Dec DL
- Cmp DX,19h ;final range check if > "Z" and < "a"
- JA Error_Set ;greater than "Z" so quit
- Inc DL
- Mov AH,36h
- Int 21h
- Cmp AX,0ffffh ;did an error occur?
- JE Error_Set
- Quit: ;store free SPACE& in DX:AX pair
- Mul CX ;multiply sectors/cluster * bytes per sector
- Mul BX ;multiply product by no. free clusters
- Jmp Short Finis1 ;the order of math is important
- Error_Set:
- Xor AX,AX ;returns a free SPACE& of 0
- Mov DX,AX ;saves a clock on 8086 chips
- Finis1:
- Mov BX,[BP+6] ;Stores the SPACE& in 2d parameter
- Mov [BX],AX ;store lowbyte from AX
- Mov [BX+2],DX ;store hibyte from DX
- Pop BP
- Ret 4
- DRVSPACE ENDP
-
- ;============================================================================
- ; DECLARE SUB SETDRIVE (DRIVE$,ErrCode%)
- ; no change occurs if DRIVE$ <"A" or >"z", or if >"Z" & less <"a"
- ; Returns ErrCode% = 0 (False) if no errors
- ; = -1 (True) if errors
- ; error checking includes range check and real test if a change occured
- ;============================================================================
-
- EVEN
- SETDRIVE PROC FAR
- Push BP
- Mov BP,SP ;set base frame pointer
- Mov AH,19h ;get default drive
- Int 21h
- Xor CH,CH
- Mov CL,AL ;store in CL
- Mov BX,[BP+8] ;get drive letter from first parameter
- Mov BX,[BX+2] ;get string address
- Mov DL,[BX] ;store string in DL
- Xor DH,DH
- Cmp DL,'A' ;check if less than "A"
- JB Error_Set1
- Cmp DL,'z' ;check if > "z"
- JA Error_Set1
- And DL,1fh ;allow A to Z or a to z
- Dec DL ;subtract one to make DX zero based drive number
- Cmp DL,19h ;final range check if > "Z" and < "a"
- JA Error_Set1 ;greater than "Z" so quit
- Cmp CL,DL
- je Quiter ;current equal's new drive so don't bother
- Mov AH,0Eh ;change drive
- Int 21h
- Mov AX,1900h ;get current directory again to
- ;see if change worked
- Int 21h
- Cmp AL,DL ;DL holds user selected drive
- JNE Error_Set1 ;unable to make a change so set error
- Quiter:
- Xor AX,AX ;clears ERRORCODE% to 0
- Jmp Short Finis2
- Error_Set1:
- Mov AX,-1 ;Sets ERRORCODE% to -1 if error occured
- Finis2:
- Mov BX,[BP+6] ;Stores the ERRORCODE% in 2d parameter
- Mov [BX],AX
- Pop BP
- Ret 4
- SETDRIVE ENDP
-
- ;============================================================================
- ; DECLARE SUB SUBEXIST (PATH$+CHR$(0),ErrCode%)
- ; Returns ErrCode% = 0 (False) if no errors,
- ; = -1 (True) if errors
- ; If a drive change is required, subdirectory on other drive will be made
- ; the "current" subdirectory on that other drive.
- ;
- ; PATH$ cannot be a TYPEd string or a variable in a string array
- ; because there is a chance that string will be outside DGROUP. String
- ; cocentenation is used to make sure it is in DGROUP.
- ;============================================================================
-
- EVEN
- StoragePath db 0,':\', 64 dup (0) ;temporarily store information.
- ;By storing DATA in code seg,
- ;this routine cannot be used
- ;under OS/2. We do it
- ;to save space in DGROUP
- EVEN
- SUBEXIST PROC FAR
- Push BP
- Mov BP,SP
- Push DS
- Push SI
- Push DI
- Mov AH,19h ;get original drive
- Int 21h
- Mov StoragePath,AL ;store drive number for later use
- Push DS ;save DS
- Mov AX,CS ;faster than PUSH CS, POP DS on 8088
- Mov DS,AX ;set DS == CS
- Mov AH,47h ;get original subdirectory
- Xor DL,DL ;of current drive
-
- ASSUME DS:@code ;tell DOS of change
-
- Mov SI, offset StoragePath+3 ;give original path
- Mov DI, SI
- Int 21h
- Pop DS
-
- ASSUME DS:@data
-
- Mov BX,[BP+8] ;get Path$
- Mov DI,[BX+2] ;store address of Path$ in DI
- Mov CX,[BX] ;get length of string in CX
- Jcxz String_Too_Short;if Path$ too short, bail out
- Cmp CX,03 ;check string size
- JB Short_Path ;if LEN(Path$) < 3,
- ;don't check for drive
- Cmp byte PTR [DI+1],':' ;check for colon
- JNE Short_Path ;skip drive check if no colon
- Mov DL,[DI] ;drive letter to DL
- And DX,001fh ;capitalize letter
- Dec DX ;reduce by zero, for zero bias
- Mov AH,0Eh ;select drive
- Int 21h
- Inc DI ;move pointer past DRIVE
- Inc DI ;move pointer past colon
- Short_Path:
- Mov DX,DI ;move pointer to DX
- Mov AH,3Bh ;change to new "current" directory
- Mov SI,-1 ;assume error
- Int 21h
- JC SubEx_Err ;error if carry set
- Xor SI,SI ;no error so return 0
- SubEx_Err:
- Mov BX,[BP+6]
- Mov [BX],SI ;store result from SI in ErrCode%
- Mov DL, StoragePath ;using original default drive
- Mov AH,0Eh ;select original drive
- Int 21h
- Add DL,65 ;convert drive letter to ASCII character
- Mov StoragePath,DL ;give us original drive letter
-
- Mov AX,CS ;set DS == CS
- Mov DS,AX
-
- Mov AH,3Bh ;change back to original subdirectory
-
- ASSUME DS:@code, ES:NOTHING
-
- Mov DX, offset StoragePath
- Int 21h
- SubEx_Finis:
- Pop DI ; restore saved registers
- Pop SI
- Pop DS
-
- ASSUME DS:@data
-
- Pop BP
- Ret 4 ; remove 2 * 2 parameters
-
- String_Too_Short:
- Mov SI,-1 ;Path$ a "" string, why bother
- Mov BX,[BP+6] ;report ErrCode of TRUE
- Mov [BX],SI ;store result from SI in ErrCode%
- Jmp Short SubEx_Finis
- SUBEXIST ENDP
-
- ;============================================================================
- ; DECLARE SUB FLOPPYREADY (DRIVE$, ErrCode%)
- ; Tests if floppy drive is ready, on a one floppy system
- ; treats drive B: as equivalent to drive A:
- ; ErrCode
- ; 128 = Time Out Error
- ; 80 = Track error
- ; -1 = Drive$ is not valid
- ; 0 = All a.o.k.
- ; Note : A critical error routine is not necessary for this routine to work
- ;============================================================================
-
- EVEN
- FLOPPYREADY PROC FAR
- Push BP
- Mov BP,SP
- Push SI
- call _Floppy ;get actual # of floppies in AX
- Mov SI,0003 ;assume 3 drives
- Mov BX,[BP+8]
- Mov CX,[BX] ;test LEN(DRIVE$)
- Jcxz ErrorFound ;if zero, then quit
- Mov BX,[BX+2] ; get actual string
- Mov DL,[BX] ;store in DL
- And DL,1Fh ;capitalize it
- Cmp DL,2
- JNE @f ;Check if want drive B: on
- Cmp AL,1 ;a one floppy system
- JNE @f
- Dec DL ;make call for B:, mimic A:
- @@:
- Cmp DL,AL ;if greater than allowed floppy #
- JA ErrorFound
- Dec DL ;zero bias
- Redo:
- Mov AX,401h
- Mov CX,1
- Xor DH,DH ;verify 1 sector of disk
- Int 13h
- Or AH,AH ;check for errors
- Mov AX,0000 ;can't use XOR because
- ;wd change flags
- JZ NormalExit ;found none so exit
- Dec SI ;decriment no. of drives
- JZ @f ;jump if no more drives
- Xor AH,AH ;reset drive if error
- Int 13h ;try again
- Jmp Short Redo
- @@:
- Mov AX,0100h ;read reset status
- Int 13h
- Xchg AH,AL ;put return value in AL
- Xor AH,AH ;clear AH
- NormalExit:
- Mov BX,[BP+6]
- Mov [BX],AX ;store in ErrCode
- Pop SI ;restore saved registers
- Pop BP
- Ret 4 ;remove 2 * 2 parameters
- ErrorFound:
- Mov AX,-1 ;return -1 for error
- Jmp NormalExit
- FLOPPYREADY ENDP
-
- ;---------------------------------------------------------------------
- ; DECLARE SUB FLOPPYDRIVES(NoDrives%)
- ; Returns number of physical floppy drives in system
- ;---------------------------------------------------------------------
-
- EVEN
- FLOPPYDRIVES PROC FAR
- Push BP
- Mov BP,SP
- Call _Floppy
- Mov BX,[BP+6]
- Mov [BX],AX ;store AX in value
- Pop BP
- Ret 2
- FLOPPYDRIVES ENDP
-
- EVEN
- _Floppy Proc Near
- Int 11h
- Shr AX,1 ;test if have any floppies
- JB @f ;jump if carry flag set
- Xor AX,AX ;else clear AX
- Jmp Short Fins1 ;quit
- @@:
- And AX,60h ;mask off floppy bits
- Mov CL,05 ;count the number of floppies
- Shr AX,CL
- Inc AX ;increment the final count
- Fins1:
- Ret
- _Floppy ENDP
-
- ;---------------------------------------------------------------------
- ; DECLARE SUB HARDDRIVES(NoDrives%)
- ; Returns number of physical hard disks in system
- ;---------------------------------------------------------------------
-
- EVEN
- HARDRIVES PROC FAR
- Push BP
- Mov BP,SP
- Xor AX,AX
- Mov ES,AX
- Mov BX,ES:[0475h] ; get info from 0040:0075h
- Mov AX,BX
- And AX,3 ; keep within range 0-4
- Mov BX,[BP+6]
- Mov [BX],AX ; store AX in value
- Pop BP
- Ret 2
- HARDRIVES ENDP
-
- ;=========================================================================
- ; DECLARE SUB GETCURRENTNAME (FName as STRING * 64, FileLength%)
- ; Returns current filename for dos version 3.xx and above
- ; if LEN(FName$) <> 64 then returns a FileLength% of -1
- ;
- ; FName$ can not be a TYPEd string or a variable in a string array
- ; because there is a chance that string will be outside DGROUP.
- ; This routine assumes that FName$ is a near string.
- ; Function returns an error if DOS version < 3.xx since function is not
- ; supported for that version.
- ;=========================================================================
-
- EVEN
- Env_Seg dw 0
- Env_Len dw 0
-
- EVEN
- GETCURRENTNAME PROC FAR
- Push BP ; set up base pointer
- Mov BP,SP ; allow us to address the stack
- Push SI ; save index registers
- Push DI ; ditto
- Push DS ; save segment registers
- Mov AH,30h ; check if DOS version > 2.xx
- Int 21h
- Cmp AL,3
- JB Error12 ; error if less than 3.00
- Cld ; clear direction flag
- Mov AH,62h ; get PSP address
- Int 21h
- Mov ES,BX ; store PSP address in ES
- Mov ES,ES:[002ch]; store PSP environment segment
- ; address in ES
- Mov Env_Seg,ES ; save environment address
- Xor DI,DI ; clear DI
- Xor AL,AL ; clear AL
- Mov CX,8000h ; assume environment segment
- ; is 32kb max
- DoubleNullLoop:
- Repne Scasb ; search using ES:DI
- ; until find a null
- ; (can't use scasw because the
- ; double null may fall on odd
- ; address)
-
- Scasb ; find the second null
- Jne DoubleNullLoop
-
- Add DI,2 ; skip over markers
- ; db 0, 1
- Mov Env_Len,DI ; save end of environment
- ; address
-
- Mov AX,SS
- Mov ES,AX ; set ES = to DGROUP for scasb
-
- Assume ES:@data
-
- Mov BX,[BP+8] ; get address of Path$
- Mov AX,ES:[BX]
- Cmp AX,64 ; if LEN(PATH$) <> 64
- Jne Error12 ; then Error
-
- Mov SI,ES:[BX+2] ; it has to be 64 so FileLength%
- ; value is calculated correctly below
- Mov DI,SI ; copy SI:offset in DI for use by
- ; Movsb and Scasb below.
-
- Push DI
- Mov CX,64 ; copy Name into FName$
- Mov DS,Env_Seg
- Mov SI,Env_Len
- Rep Movsb ; copy DS:SI to ES:DI
-
- Mov CX,64 ; length of FName$
- Xor AL,AL ; clear AL, the search value
- Pop DI ; search for null at end of name
- Repnz Scasb ; uses ES:DI to search
- ; scan until reach end of FName$
- Mov AX,63 ; determine length of FName$
- Sub AX,CX ; before the null
- Jmp Short Finis12
- Error12:
- Mov AX,-1 ; return FileLength% = -1
- ; if error
- Finis12:
- Mov BX,[BP+6]
- Mov ES:[BX],AX
- Pop DS ; restore registers used
- Pop DI
- Pop SI
- Pop BP
- Ret 4 ; remove 2 * 2 parameters
- GETCURRENTNAME ENDP
-
- ;============================================================================
- ; DECLARE SUB TRUENAME (OrigFile$+CHR$(0), TrueFName$, FileLength%)
- ; Purpose:
- ; Allows user to test for SUBST, ASSIGN, and JOIN using an
- ; undocumented call for DOS Version 3.xx and above
- ; The returned name will contain technically correct Drive: and Path
- ; information. However, the OrigFile$ is not checked so ? and * may be
- ; used, the OrigFile$ may even be non-existant.
- ;
- ; Shortcuts:
- ; OrigFile$ = "." to obtain current drive & subdirectory name
- ; OrigFile$ = ".." to obtain immediate parent drive & subdirectory name
- ;
- ; Usage:
- ; TrueFName$ = STR$(67,0)
- ; CALL TRUENAME(OrigFile$ + CHR$(0), TrueFName$, FileLength%)
- ; IF FileLength% = -1 THEN
- ; Error
- ; ELSE
- ; TrueFName$=LEFT$(TrueFName$, FileLength%)
- ; END IF
- ;============================================================================
-
- EVEN
- TRUENAME PROC FAR
- Push BP
- Mov BP,SP ; make stack addressable
- Push DI ; save variables we use
- Push SI
-
- Mov AH,30h ; check if DOS version > 2.xx
- Int 21h
- Cmp AL,3 ; AL contains the major version
- JB Error15 ; If less than 3.00, Error15
- Mov BX,[BP+8] ; get TrueFName$
- Mov CX,[BX] ; get length of string
- JCXZ Error14 ; if zero, Error
- Cmp CX,67 ; if not equal to 67 bytes, Error
- JNE Error14
- Mov DI,[BX+2] ; get address of TrueFName$ string
- Mov BX,[BP+10] ; get length of OrigFile$
- Mov CX,[BX] ; if length is zero, then Error
- JCXZ Error14
- Mov SI,[BX+2] ; get address of OrigFile$
-
- Mov AX,DS ; faster than PUSH & POP on 8088
- Mov ES,AX ; make ES==DS
- Push DI ; save address of DI
-
- ; input string DS:SI, output ES:DI
- Mov AH,60h ; call undocumented Expand Path Name
- Int 21h ; Dettmann, DOS Programmer's Reference
- ; 2d Edition (Que 1989), page 660
- ; Very good book
-
- Pop DI ; reset DI
- JC Error14 ; bad character in OrigFile$
-
- Mov CX,67 ; length of TrueFName$
- Xor AL,AL ; clear AL, the search value
- Cld ; clear the direction flag
- Repnz Scasb ; uses ES:DI to search
- ; scan until reach end of TrueFName$
- Mov AX,66 ; determine length of TrueFName$
- Sub AX,CX ; before the null
- Jmp Short Quit14 ; end routine
- Error14:
- Mov AX,-1 ; return a -1 for FileLength%
- Quit14:
- Mov BX,[BP+6]
- Mov [BX],AX ; store AX in FileLength%
- Pop SI ; restore saved registers
- Pop DI
- Pop BP
- Ret 6 ; clear variables off stack
-
- Error15: ; report DOS version is <3.xx
- Xor AX,AX ; so no danger of SUBST, JOIN
- Jmp Short Quit14 ; or ASSIGN
- TRUENAME ENDP
-
- ;=========================================================================
- ; DECLARE SUB GETFULLPATH (PATH$, PATHLEN%)
- ; Returns current subdirectory path, with Drive:\, e.g. "A:\"
- ; if LEN(Path$) <> 67 then returns a pathlen% of -1
- ;
- ; PATH$ can not be a TYPEd string or a variable in a string array
- ; because there is a chance that string will be outside DGROUP.
- ; This routine assumes that Path$ is a near string.
- ;=========================================================================
-
- EVEN
- GETFULLPATH PROC FAR
- Push BP ;set up base pointer
- Mov BP,SP ;allow us to address the stack
- Push SI ;save index registers
- Push DI ; ditto
-
- Mov BX,[BP+8] ;get address of Path$
- Mov AX,[BX]
- Cmp AX,67 ;if LEN(PATH$) <> 67
- JNE Error2 ;then Error
-
- Mov AX,SS
- Mov ES,AX ;set ES == to DGROUP for scasb
-
- assume ES:@data
-
- Mov AH,19h ;get current drive
- Int 21h
- Add AL,'A' ;Add A to value
- Xor AH,AH ;clear AH to 0
- Mov BX,[BX+2] ;get actual string address
- Mov Byte Ptr [BX],AL ;store AL in Drive$
- Mov Byte Ptr [BX+1],':' ;add colon
- Mov Byte Ptr [BX+2],'\' ;add backlash
-
- ADD BX,3 ;increase address by 3 to skip "A:\"
- Mov SI,BX ;it has to be 67 so Pathlen% value is
- Mov DI,SI ;calculated correctly below
- Xor DL,DL ;clear DL to get
- Mov AH,47h ;get current directory
- Int 21h
- JC Error ;if carry set, directory invalid
- Mov CX,64 ;find ending null in Path$
- Xor AL,AL ;clear AL, the value to search for
- Cld ;clear direction flag
- Repnz Scasb ;uses ES:DI to search Path$
- Mov AX,63 ;determine length of Path$
- Sub AX,CX
- Add AX,3 ;add length of drive "A:\"
- Jmp Short finis2
- Error2:
- Mov AX,-1 ;return Pathlen% = -1 if error
- finis2:
- Mov BX,[BP+6]
- Mov [BX],AX
- Pop DI ;restore registers used
- Pop SI
- Pop BP
- Ret 4
- GETFULLPATH ENDP
- END
-