home *** CD-ROM | disk | FTP | other *** search
- ' Disclaimer:
- ' Use these routines at your own risk. I do not accept any liability
- ' for ANY problems that may occur from using these routines.
- '
- ' Now that I have that out of the way....
- '
- ' These functions are provided to complement the functions of Turbo Basic.
- ' While Turbo Basic provides many convenient functions, they seem to have
- ' missed a few important ones. You can, for example, use CHDIR to change
- ' the current directory, but Turbo Basic gives you no way to determine or
- ' return to the directory that was active when the program was run.
- '
- ' I also like knowing whether or not a given file exists before I begin
- ' any file I/O on that file. With the FindFirst and FindNext functions, you
- ' can build a string containing the entire directory ... this is useful
- ' in many applications. These routines were written using Turbo Basic
- ' keywords and functions instead of as inline assembler in order to give
- ' you an example of how to use Turbo Basic more effectively. Note that
- ' similar routines written as inline assembler would run LOTS faster.
- '
- ' Brett Jones, 01/18/89
- '
- ' Turbo Basic is a registered trademark of Borland International.
-
-
- Rem ++
- Rem
- Rem Begin Module DOSSTUFF
- Rem
- Rem
- Rem Purpose:
- Rem Turbo Basic routines to allow more complete access to
- Rem Disk Directories, Paths and Files.
- Rem
- Rem Routines:
- Rem FnExist% - Verify that a file exists on a disk
- Rem before attempting I/O.
- Rem FnCurrDrive$ - Return a single character describing
- Rem the currently logged in disk drive.
- Rem FnFreeSpace - Return the amount of free space available
- Rem on any valid disk.
- Rem FnFindFirst$ - Returns the first file in a directory that
- Rem matches a user defined mask.
- Rem FnFindNext$ - Returns subsequent files matching a user
- Rem defined mask after using FnFindFirst$.
- Rem FnVol$ - Returns the volume label for a disk.
- Rem FnDosVer# - Returns the current DOS version number.
- Rem FnCurrDir$ - Returns the current directory.
- Rem
- Rem Environment:
- Rem Turbo Basic
- Rem
- Rem Author: Creation Date:
- Rem Brett Jones 01/15/89
- Rem
- Rem Modified By:
- Rem 1, Brett Jones, 01/15/89 - Original
- Rem
- Rem --
-
-
- Def FnExist%(f$)
- local strseg,aseg,aptr,temp,a%,b%,a$
-
-
- rem Written by Brett Jones
- rem 01/17/89 - Original
- rem
- rem determine if file f$ exists
- rem works by checking for file attributes
- rem requires dos 2.0 and above
-
- def seg ' set default segment
- strseg = cvi(chr$(peek(0)) + chr$(peek(1))) ' get string segment
-
- a$ = ucase$(f$) + chr$(0) ' make f$ asciiz
-
- aseg = varseg(a$) ' segment for string pointer
- aptr = varptr(a$) ' pointer to string descriptor
-
- def seg=aseg ' set segment
- temp = cvi(chr$(peek(aptr + 2)) + chr$(peek(aptr + 3))) ' pointer to filename
-
- reg 1,&h4300 ' ah = 43h (CHMOD function)
- ' al = 00h (get attributes)
- reg 8,strseg ' ds = string segment
- reg 4,temp ' dx = string offset
-
- call interrupt &h21 ' perform dos call
-
- a% = reg(1) ' a% = ax
- b% = reg(3) ' b% = cx
-
- if a% = 2 or a% = 3 or a% = 5 then FnExist% = -1 else FnExist% = b%
-
- rem 2 = file not found
- rem 3 = path not found
- rem 5 = access denied
-
- def seg ' reset segment
-
- End Def
-
-
-
- Def FnCurrDrive$
- local ta$,ta%
-
- rem Written by Brett Jones
- rem 01/17/89 - Original
- rem
- rem FnCurrDrive$ returns a single character drive identifier which
- rem specifies the current drive in use.
- rem This function can be used with any version of dos.
-
- reg 1,&h1900 ' ah = 19h (report current drive)
- call interrupt &h21 ' perform dos interrupt
-
- ta$ = mki$(reg(1)) ' ta$ = 2 character string of ax
- ta% = asc(left$(ta$,1)) ' ta% = al
-
- FnCurrDrive$ = chr$(ta% + 65) ' return drive as a string {A..Z}
-
- End Def
-
-
-
- Def FnFreeSpace(drive%)
- local ra,rb,rc
-
- rem Written by Brett Jones
- rem 01/17/89 - Original
- rem
- rem FnFreeSpace will return the number of free bytes available
- rem on drive 'drive%'. If 'drive%' does not exist, then this
- rem function will return a -1.
- rem FnFreeSpace requires dos 2.00 or above.
-
- reg 1,&h3600 ' ah = 36h (get free space)
- reg 4,drive% ' dl = drive number (0 = default)
- call interrupt &h21 ' perform dos interrupt
-
- ra = reg(1) ' ra = ax (sectors per cluster or error)
-
- if ra = &hffff then fnfreespace = -1 : exit def ' exit if error occurs
-
- rb = reg(2) ' rb = number of available clusters
- rc = reg(3) ' rc = bytes per sector
- ' reg(4) {dx} contains total number of clusters
-
- FnFreeSpace = (ra * rb * rc)
-
- End Def
-
-
-
- Def FnFindFirst$(f$)
- local strseg,a$,aseg,aptr,temp,dtaseg,dtaoff,dtaatt,c$,c%,lp%
-
- rem Written by Brett Jones
- rem 01/17/89 - Original
- rem
- rem FnFindFirst$ finds the first file that matches the mask
- rem 'f$'. 'f$' can contain wildcard characters {* and ?}.
- rem 'f$' is any valid path + filename. If FnFindfirst$ does not
- rem find a file, it will return a null string.
- rem Requires dos 2.00 and above.
-
-
- rem Format of the DTA after a file has been found:
- rem
- rem Offset Size(bytes) Description
- rem 0 21 Used by DOS for find next
- rem 21 1 Attribute of file found
- rem 22 2 Time Stamp of file
- rem 24 2 Date Stamp of file
- rem 26 4 File size in bytes
- rem 30 13 Filename and extension (asciiz)
- rem
- rem Attributes:
- rem bit 0 - Read Only
- rem 1 - Hidden
- rem 2 - System
- rem 3 - Volume Label
- rem 4 - Subdirectory
- rem 5 - Archive
- rem 6 - Unused
- rem 7 - Unused
- rem
- rem Time = Hour * 2048 + Minute * 32 + Second / 2
- rem Date = (Year - 1980) * 512 + Month * 32 + Day
- rem
- rem Filesize is a 4 byte unsigned integer
-
-
- def seg ' set default segment
- strseg = cvi(chr$(peek(0)) + chr$(peek(1))) ' get string segment
-
- if f$ = null$ then f$ = "*.*" ' avoid trying to find nothing
- a$ = ucase$(f$) + chr$(0) ' make f$ asciiz
-
- aseg = varseg(a$) ' segment for string pointer
- aptr = varptr(a$) ' pointer to string descriptor
-
- def seg=aseg ' set segment
- temp = cvi(chr$(peek(aptr + 2)) + chr$(peek(aptr + 3))) ' pointer to filename
-
- reg 1,&h4E00 ' ah = 4E (find first)
- ' al = 00h
- reg 3,23 ' cx = 23 (all but vol label)
- reg 8,strseg ' ds = string segment
- reg 4,temp ' dx = string offset
-
- call interrupt &h21 ' perform dos call
-
- ' abort on errors
- if reg(1) = 2 or reg(1) = 18 then fnfindfirst$ = null$ : exit def
-
- reg 1,&h2F00 ' ah = 2F (Get DTA)
- call interrupt &h21 ' perform dos call
-
- dtaseg = reg(9) ' DTA segment = ES
- dtaatt = reg(2) + 21 ' offset of attributes
- dtaoff = reg(2) + 30 ' offset of filename
-
- c$ = null$ ' prepare to retrieve filename
-
- def seg=dtaseg ' set segment = DTA segment
-
- for lp% = 0 to 12 ' retrieve filename
- c% = peek(dtaoff + lp%) ' from DTA
- if c% = 0 then exit for
- c$ = c$ + chr$(peek(dtaoff + lp%))
- next lp%
-
- if (peek(dtaatt) and 16) = 16 then c$ = "\"+c$ ' indicate subdirectories
-
- def seg ' reset segment to default
-
- fnfindfirst$ = c$
-
- End Def
-
-
- Def FnFindNext$
- local strseg,a$,aseg,aptr,temp,dtaseg,dtaoff,dtaatt,c$,c%,lp%
-
- rem Written by Brett Jones
- rem 01/17/89 - Original
- rem
- rem FnFindNext$ finds the next file that matches the mask
- rem used with FnFindFirst$. FnFindFirst$ MUST have been called prior
- rem to using FnFindNext$. If FnFindNext$ does not find any matching
- rem files, then a null string will be returned.
- rem Repeat FnFindNext$ until a null string is returned to find ALL
- rem files that match the mask.
- rem Requires dos 2.00 and above.
-
- reg 1,&h4F00 ' ah = 4E (find first)
- ' al = 00h
-
- call interrupt &h21 ' perform dos call
-
- ' return if error/no files
- if reg(1) = 18 then fnfindnext$ = null$ : exit def
-
- reg 1,&h2F00 ' ah = 2F (Get DTA)
- call interrupt &h21 ' perform dos call
-
- dtaseg = reg(9) ' DTA segment = ES
- dtaatt = reg(2) + 21 ' offset of attributes
- dtaoff = reg(2) + 30 ' filename offset
-
- c$ = null$ ' prepare to transfer filename
- def seg=dtaseg ' set segment to DTA segment
-
- for lp% = 0 to 12 ' retrieve filename
- c% = peek(dtaoff + lp%) ' from DTA
- if c% = 0 then exit for
- c$ = c$ + chr$(peek(dtaoff + lp%))
- next lp%
-
- if (peek(dtaatt) and 16) = 16 then c$ = "\"+c$ ' indicate subdirectories
-
- def seg ' restore default segment
-
- fnfindnext$ = c$
-
- End Def
-
-
- Def FnVol$
- local strseg,a$,aseg,aptr,temp,dtaseg,dtaoff,c$,c%,lp%
-
- rem Written by Brett Jones
- rem 01/19/89 - Original
- rem
- rem FnVol$ locates the volume label of a disk.
- rem If FnVol$ does not find a file, it will return a null string.
- rem Requires dos 2.00 and above.
-
-
- def seg ' set default segment
- strseg = cvi(chr$(peek(0)) + chr$(peek(1))) ' get string segment
-
- a$ = "*.*" + chr$(0) ' make a$ asciiz
-
- aseg = varseg(a$) ' segment for string pointer
- aptr = varptr(a$) ' pointer to string descriptor
-
- def seg=aseg ' set segment
- temp = cvi(chr$(peek(aptr + 2)) + chr$(peek(aptr + 3))) ' pointer to filename
-
- reg 1,&h4E00 ' ah = 4E (find first)
- reg 3,8 ' cx = 8 (find vol label)
- reg 8,strseg ' ds = string segment
- reg 4,temp ' dx = string offset
-
- call interrupt &h21 ' perform dos call
-
- ' abort on errors
- if reg(1) = 2 or reg(1) = 18 then fnvol$ = null$ : exit def
-
- reg 1,&h2F00 ' ah = 2F (Get DTA)
- call interrupt &h21 ' perform dos call
-
- dtaseg = reg(9) ' DTA segment = ES
- dtaoff = reg(2) + 30 ' offset of filename
-
- c$ = null$ ' prepare to retrieve filename
-
- def seg=dtaseg ' set segment = DTA segment
-
- for lp% = 0 to 12 ' retrieve filename
- c% = peek(dtaoff + lp%) ' from DTA
- if c% = 0 then exit for
- c$ = c$ + chr$(peek(dtaoff + lp%))
- next lp%
-
- def seg ' reset segment to default
-
- lp% = instr(1,c$,".") ' combine the filename
- c$ = left$(c$,lp%-1) + mid$(c$,lp%+1,255) ' and extension
-
- fnvol$ = c$
-
- End Def
-
-
-
-
- Def FnDosVer#
- local tmp$,tmplow%,tmphi%
-
- rem FnDosVer#
- rem Written by Brett Jones
- rem 01/18/89 - Original
- rem
- rem return the current dos version {i.e. 3.3}
- rem requires dos 2.00 or later.
-
- reg 1,&h3000
- call interrupt &h21
-
- tmp$ = mki$(reg(1))
- tmphi% = cvi(left$(tmp$,1)+chr$(0))
- tmplow% = cvi(right$(tmp$,1)+chr$(0))
-
- FnDosVer# = tmphi% + (tmplow% / 100.0)
-
- End Def
-
-
- Def FnCurrDir$
- local f$,strseg,aseg,aptr,a%,ma%
-
- rem FnCurrPath$
- rem
- rem Written by Brett Jones
- rem 01/18/89 - Original
- rem
- rem Return a string containing the currently active directory.
- rem FnCurrDir$ will return a null string if the drive is invalid.
- rem Requires Dos 2.00 or later.
-
- f$ = string$(64,chr$(0)) ' create variable to hold path
-
- def seg ' set default segment
- strseg = cvi(chr$(peek(0)) + chr$(peek(1))) ' get string segment
-
- aseg = varseg(f$) ' segment for string pointer
- aptr = varptr(f$) ' pointer to string descriptor
-
- def seg=aseg ' set segment
- temp = cvi(chr$(peek(aptr + 2)) + chr$(peek(aptr + 3))) ' pointer to filename
-
- reg 1,&h4700 ' ah = 47h (Get current dir)
- reg 4,&h0000 ' dx = 00h (current drive)
- reg 8,strseg ' ds = string segment
- reg 5,temp ' si = string offset
-
- call interrupt &h21 ' perform dos call
-
- a% = reg(1) ' a% = ax
-
- if a% = 15 then FnCurrDir$ = null$ : exit def ' no such drive
-
- def seg ' reset segment
-
- ma% = instr(1,f$,chr$(0)) ' asciiz is returned
- f$ = fncurrdrive$ + ":\"+left$(f$,ma% - 1) ' truncate to displayable
-
- FnCurrDir$ = f$
-
-
- End Def
-
-
- Rem ++
- Rem
- Rem End Module DOSSTUFF
- Rem
- Rem --
-
-
-
-
- Rem ++
- Rem
- Rem Begin Module ByteStuf
- Rem
- Rem
- Rem Purpose:
- Rem Routines to allow byte storage as integer values
- Rem These routines could be used to avoid Turbo Basic's
- Rem limitation of 64K of string space (although fixed
- Rem length strings would be required to do so easily).
- Rem
- Rem Routines:
- Rem Byte2Int% - Build integer from 2 byte values
- Rem Int2Byte - Return 2 bytes from integer value
- Rem Int2Str$ - Return 2 character string representation of
- Rem Integer in hibyte%/lobyte% format
- Rem Str2Int% - Convert 2 character string to integer
- Rem
- Rem Environment:
- Rem Turbo Basic
- Rem
- Rem Author: Creation Date:
- Rem Brett Jones 01/15/89
- Rem
- Rem Modified By:
- Rem 1, Brett Jones, 01/15/89 - Original
- Rem
- Rem --
-
-
- Rem ++
- Rem
- Rem Note:
- Rem Byte values are in range [0..255]
- Rem Resulting integers are in range [-32767..+32767]
- Rem Validity checking is NOT performed.
- Rem
- Rem The Hibyte%, Lobyte% format returns the leftmost and
- Rem rightmost values accordingly. Reverse these for the
- Rem actual high and low byte values.
- Rem
- Rem --
-
-
- Def FnByte2Int%(highbyte%,lowbyte%)
- Rem Store 2 bytes in an integer
-
- FnByte2Int% = cvi(chr$(highbyte%)+chr$(lowbyte%))
-
- End Def
-
-
- Sub Int2Byte(integervalue%)
- shared hibyte%,lobyte%
- local temp$
-
- Rem Return 2 bytes (numeric) from integer
-
- Rem This routine will return results in the global
- Rem variables hibyte% and lobyte%
-
- Temp$ = FnInt2Str$(integervalue%)
- Hibyte% = asc(left$ (temp$,1))
- Lobyte% = asc(right$(temp$,1))
- Temp$ = null$
-
- End Sub
-
-
- Def FnInt2Str$(integervalue%)
- Rem Retrieve 2 bytes from integer. Return values in string
-
- FnInt2Str$ = mki$(integervalue%)
-
- End Def
-
-
- Def FnStr2Int%(inputstring$,start%)
- Rem Convert 2 bytes of string to integer
-
- FnStr2Int% = cvi(mid$(inputstring$,start%,2))
-
- End Def
-
-
- Rem ++
- Rem
- Rem End Module ByteStuf
- Rem
- Rem --
-
-
-
-
- Rem ++
- Rem Sample program to demonstrate the directory/path/file
- Rem routines defined in DOSSTUFF.
- Rem --
-
- cls
-
- ' FnDosVer#
- print "Current DOS Version is ";fndosver#
-
- ' fncurrdrive$
- print "The current drive is: ";fncurrdrive$
-
- ' fnvol$
- print "The volume label is : ";
- tvol$ = fnvol$
- if tvol$ = null$ then tvol$ = "{no volume label}
- print tvol$
-
- ' FnCurrDir$
- print "Current Directory is : ";fncurrdir$
-
- ' fnfreespace
- fr = fnfreespace(0)
- print "Free space for drive ";fncurrdrive$;": is: ";fr;" Bytes, ";(fr/1024);"K."
-
-
- print
- print
-
- 'fnexist%
- input "Enter a file name for FnExist: ";file$
-
- ex% = fnexist%(file$)
-
- if ex% = -1 then
- print file$ + " Does Not Exist "
- else
- print file$ + " Exists - ";
- ' show attributes
- if (ex% and 1) = 1 then print "Read Only ";
- if (ex% and 2) = 2 then print "Hidden ";
- if (ex% and 4) = 4 then print "System ";
- if (ex% and 8) = 8 then print "Volume Label ";
- if (ex% and 16) = 16 then print "Subdirectory ";
- if (ex% and 32) = 32 then print "Archive";
- print
- end if
-
- print
-
-
- ' FnFindFirst$ and FnFindNext$
-
- totalfiles% = 0
- input "Enter the directory mask: ";mask$
- print
- print "Files matching "+mask$+" = "
- print
- tfil$ = fnfindfirst$(mask$)
- if tfil$ = null$ then print "No Files!" : stop ' no files matched
-
- tfil$ = left$(tfil$ + " ",16) ' format the entry
- incr totalfiles%
-
- a$ = " "
- while a$ <> null$
- a$ = fnfindnext$
- if a$ <> null$ then a$ = left$(a$ + " ",16) :_
- tfil$ = tfil$ + a$ : incr totalfiles% ' format the entry
- wend
-
- print tfil$
- print using "#### Files Found_.";totalfiles%
- End