home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-27 | 28.6 KB | 1,039 lines |
- .MODEL small, c
- INCLUDE demo.inc
- .CODE
-
-
- ;* ReadCharAttr - Reads character and display attribute at cursor location.
- ;*
- ;* Shows: BIOS Interrupt - 10h, Function 8 (Read Character and Attribute
- ;* at Cursor)
- ;*
- ;* Uses: vconfig - Video configuration structure, declared in the
- ;* DEMO.INC include file. The structure must first be
- ;* initialized by calling the GetVidConfig procedure.
- ;*
- ;* Params: attr - Pointer to short integer for display attribute
- ;*
- ;* Return: Short integer with ASCII value of character
-
- ReadCharAttr PROC \
- USES di, \
- attr:PTR WORD
-
- mov ah, 8 ; Function 8
- mov bh, vconfig.dpage ; Current page
- int 10h ; Read Character and Attribute
- sub bh, bh
- mov bl, ah ; BX = attribute
- cbw ; AX = character
- LoadPtr es, di, attr ; ES:DI = pointer to int
- mov es:[di], bx ; Copy attribute
- ret
-
- ReadCharAttr ENDP
-
-
- ;* CopyFile - Copies a file from a specified directory to another. Allows
- ;* two different copy methods. See the OpenFile, CloseFile, ReadFile, and
- ;* WriteFile procedures for specific examples on opening, closing, reading
- ;* from, and writing to files.
- ;*
- ;* Shows: DOS Functions - 3Ch (Create File)
- ;* 5Bh (Create New File)
- ;* Instruction - clc
- ;*
- ;* Params: imode - 0 = Create new target file or overwrite existing file
- ;* 1 = Abort and return error code if target file already
- ;* exists (only for DOS versions 3.0 and higher)
- ;* fspec1 - Pointer to ASCIIZ source file specification
- ;* fspec2 - Pointer to ASCIIZ target file specification
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if error
-
- .DATA
- buffer DB BUFFER_SIZE DUP(?) ; Buffer for diskette read
-
- .CODE
- EXTRN GetVer:PROC
-
- CopyFile PROC \
- USES ds si di, \
- imode:WORD, fspec1:PTR BYTE, fspec2:PTR BYTE
-
- LOCAL eof_flag:BYTE
-
- ; Open source file for read only
-
- LoadPtr ds, dx, fspec1 ; Point DS:DX to source file
- mov ax, 3D00h ; AH = function #, AL = access code
- int 21h ; Open File (for read only)
- jc e_exit
- mov si, ax ; SI = file handle for source
-
- ; Open target file according to copy mode
-
- LoadPtr ds, dx, fspec2 ; Point DS:DX to target file
- cmp imode, 1 ; Determine DOS function
- je check ; Imode = 1?
- mov ah, 3Ch ; No? Request Create File
- jmp SHORT set ; (destroy existing)
- check: call GetVer ; Yes? First check DOS version
- cmp ax, 300 ; 3.0 or higher?
- jb close ; No? Abort with error code
- mov ah, 5Bh ; Request Create New File
-
- set: sub cx, cx ; Normal attribute for target
- int 21h ; DOS function for target file
- jc close ; If open error, abort
- mov di, ax ; DI = file handle for target
-
- ; Both files successfully opened. Now read from source and copy to target.
-
- mov ax, @data
- mov ds, ax ; DS:DX = buffer. Read/write
- mov dx, OFFSET buffer ; to and from here.
- mov eof_flag, 0 ; Initialize end-of-file flag
- loop1: mov bx, si ; Handle for source file
- mov cx, BUFFER_SIZE ; CX = number of bytes to read
- mov ah, 3Fh ; Request DOS read
- int 21h ; Read from File
- jc close ; If error, exit
- cmp ax, cx ; All bytes read successfully?
- je @F ; Yes? Continue
- inc eof_flag ; No? Raise flag
- @@: mov bx, di ; Handle for target file
- mov cx, ax ; Write number of bytes read
- mov ah, 40h ; Request DOS write
- int 21h ; Write from buffer to target file
- jc close ; If error, exit
- cmp eof_flag, 0 ; Finished?
- je loop1 ; No? Loop to read next block
- clc ; Yes? Clear CY to indicate
- ; success
- close: pushf ; Preserve flags while closing
- mov bx, di ; Handle for target file
- mov ah, 3Eh ; Request DOS Function 3Eh
- int 21h ; Close File
- sub ax, ax ; Clear error code
- popf ; Recover flags
- jnc exit ; If successful, exit
-
- e_exit: mov ax, 1 ; Else set error code
- exit: ret
-
- CopyFile ENDP
-
-
- ;* ChangeDrive - Changes default drive.
- ;*
- ;* Shows: DOS Function - 0Eh (Select Disk)
- ;*
- ;* Params: drive - Uppercase letter designation for new drive
- ;*
- ;* Return: None
-
- ChangeDrive PROC \
- drive:WORD
-
- mov ah, 0Eh ; DOS Function 0Eh
- mov dx, drive ; Drive designation in DL,
- sub dl, 'A' ; 0=A, 1=B, 2=C, etc
- int 21h ; Select Disk
- ret
-
- ChangeDrive ENDP
-
-
- ;* GetCurDisk - Gets designation of current disk.
- ;*
- ;* Shows: DOS Function - 19h (Get Current Disk)
- ;* Instruction - cbw
- ;*
- ;* Params: None
- ;*
- ;* Return: Short integer with drive designation
- ;* 0 = A, 1 = B, 2 = C, etc.
-
- GetCurDisk PROC
-
- mov ah, 19h ; DOS Function 19h
- int 21h ; Get Current Disk
- cbw ; AX = drive designation
- ret
-
- GetCurDisk ENDP
-
-
- ;* SetDTA - Sets address for new Disk Transfer Area.
- ;*
- ;* Shows: DOS Function - 1Ah (Set DTA Address)
- ;*
- ;* Params: dta - Far pointer to new transfer address
- ;*
- ;* Return: None
-
- SetDTA PROC \
- USES ds, \
- dta:FAR PTR BYTE
-
- lds dx, [dta] ; Point DS:DX to DTA
- mov ah, 1Ah ; DOS Function 1Ah
- int 21h ; Set DTA Address
- ret
-
- SetDTA ENDP
-
-
- ;* GetDTA - Gets address of current Disk Transfer Area.
- ;*
- ;* Shows: DOS Function - 2Fh (Get DTA Address)
- ;*
- ;* Params: dta - Far pointer to receive transfer address
- ;*
- ;* Return: None
-
- GetDTA PROC \
- dta:FAR PTR BYTE
-
- mov ah, 2Fh ; DOS Function 2Fh
- int 21h ; Get DTA Address in ES:BX
- mov ax, es ; Save DTA segment
- mov dx, bx ; Save DTA offset
- les bx, dta ; Now ES:BX points to variable
- mov es:[bx], dx ; Copy DTA address to
- mov es:[bx+2], ax ; dta variable
- ret
-
- GetDTA ENDP
-
-
- ;* CreateFile - Creates file with specified attribute.
- ;*
- ;* Shows: DOS Function - 3Ch (Create File)
- ;*
- ;* Params: attr - Attribute code: 0 = normal 8 = volume label
- ;* 1 = read only 16 = subdirectory
- ;* 2 = hidden 32 = archive
- ;* 4 = system
- ;* fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with file handle or -1 for error
-
- CreateFile PROC \
- USES ds, \
- attr:WORD, fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; Point DS:DX to file spec
- mov cx, attr ; CX = attribute
- mov ah, 3Ch ; AH = function number
- int 21h ; Create file
- jnc exit ; If ok, return AX = handle
- mov ax, -1 ; Else set error code
- exit: ret
-
- CreateFile ENDP
-
-
- ;* OpenFile - Opens specified file for reading or writing. See the CopyFile
- ;* procedure for another example of using DOS Function 3Dh to open files.
- ;*
- ;* Shows: DOS Function - 3Dh (Open File)
- ;*
- ;* Params: access - Access code: 0 = read 1 = write 2 = read/write
- ;* fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with file handle or -1 for error
-
- OpenFile PROC \
- USES ds, \
- access:WORD, fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; Point DS:DX to file spec
- mov ax, access ; AL = access code
- mov ah, 3Dh ; AH = function number
- int 21h ; Open file
- jnc exit ; If ok, return AX = handle
- mov ax, -1 ; Else set error code
- exit: ret
-
- OpenFile ENDP
-
-
- ;* CloseFile - Closes an open file, specified by handle. See the CopyFile
- ;* procedure for another example of using DOS Function 3Eh to close files.
- ;*
- ;* Shows: DOS Function - 3EH (Close File)
- ;*
- ;* Params: handle - File handle
- ;*
- ;* Return: None
-
- CloseFile PROC \
- handle:WORD
-
- mov bx, handle ; BX = file handle
- mov ah, 3Eh ; DOS Function 3Eh
- int 21h ; Close file
- ret
-
- CloseFile ENDP
-
-
- ;* ReadFile - Read from open file to specified buffer. See the CopyFile
- ;* procedure for another example of using DOS Function 3Fh to read files.
- ;*
- ;* Shows: DOS Function - 3Fh (Read File or Device)
- ;*
- ;* Params: handle - File handle
- ;* len - Number of bytes to read
- ;* pbuff - Pointer to buffer
- ;*
- ;* Return: Short integer with number of bytes read, or 0 if read error
-
- ReadFile PROC \
- USES ds di, \
- handle:WORD, len:WORD, pbuff:PTR BYTE
-
- LoadPtr ds, dx, pbuff ; Point DS:DX to buffer
- mov di, dx ; Keep string offset in DI
- mov bx, handle ; BX = handle
- mov cx, len ; CX = number of bytes to read
- mov ah, 3Fh ; Request DOS read
- int 21h ; Read File
- jnc exit ; If ok, exit with bytes read
- sub ax, ax ; Else set error code
- exit: ret
-
- ReadFile ENDP
-
-
- ;* WriteFile - Write ASCIIZ string to file. If handle = 0, the string is
- ;* written to STDOUT (console). See the CopyFile procedure for another
- ;* example of using DOS Function 40h to write to files.
- ;*
- ;* Shows: DOS Function - 40h (Write File or Device)
- ;*
- ;* Params: handle - File handle
- ;* str - Pointer to ASCIIZ string
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if write error
- ;* 2 if number of bytes written not equal to string length
-
- WriteFile PROC \
- USES ds di, \
- handle:WORD, str:PTR BYTE
-
- LoadPtr es, di, str ; Point ES:DI to string
- push di ; Hold on to string pointer
- mov cx, -1 ; Set CX to maximum
- sub al, al ; AL = 0
- repne scasb ; Scan string for NULL
- pop dx ; Recover string pointer
- dec di
- sub di, dx ; Get string length (w/o NULL)
- mov cx, di ; Put it into CX
- mov bx, handle ; Load BX with handle
- push es ; Set DS to ES to ensure
- pop ds ; DS:DX points to string
- mov ah, 40h ; Request DOS write
- int 21h ; Write File or Device
- mov bx, ax ; Get number of bytes written
- mov ax, 0 ; Set error code, preserve CY
- jc e_exit ; If error, exit
- cmp bx, cx ; All bytes written?
- je exit ; Yes? Exit, error code = 0
- inc ax ; Else inc error code twice
- e_exit: inc ax ; Increment error code once
- exit: ret
-
- WriteFile ENDP
-
-
- ;* GetDiskSize - Gets size information from specified disk.
- ;*
- ;* Shows: DOS Function - 36h (Get Drive Allocation Information)
- ;*
- ;* Params: drive - Drive code (0 = default, 1 = A, 2 = B, etc.)
- ;* disk - Pointer to a structure with 4 short integer members:
- ;* Member 1 - Total clusters on disk
- ;* Member 2 - Number of available clusters
- ;* Member 3 - Sectors/cluster (-1 if invalid drive)
- ;* Member 4 - Bytes/sector
- ;*
- ;* Return: None
-
- GetDiskSize PROC \
- USES di, \
- drive:WORD, disk:PTR WORD
-
- mov dx, drive ; DL = drive code
- mov ah, 36h ; DOS Function 36h
- int 21h ; Get Drive Allocation Information
- LoadPtr es, di, disk ; ES:DI = disk structure
- mov es:[di].total, dx ; DX = total clusters
- mov es:[di].avail, bx ; BX = number of free clusters
- mov es:[di].sects, ax ; AX = sectors/cluster
- mov es:[di].bytes, cx ; CX = bytes/sector
- ret
-
- GetDiskSize ENDP
-
-
- ;* MakeDir - Creates a specified subdirectory.
- ;*
- ;* Shows: DOS Function - 39h (Create Directory)
- ;*
- ;* Params: pspec - Pointer to ASCIIZ pathname of new subdirectory
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if create error
-
- MakeDir PROC \
- USES ds, \
- pspec:PTR BYTE
-
- LoadPtr ds, dx, pspec ; Point DS:DX to path spec
- mov ah, 39h ; DOS Function 39h
- int 21h ; Create Directory
- mov ax, 0 ; Set error code, keep flags
- jnc exit ; Exit if successful
- inc ax ; Else set error code to 1
- exit: ret
-
- MakeDir ENDP
-
-
- ;* RemoveDir - Removes a specified subdirectory.
- ;*
- ;* Shows: DOS Function - 3Ah (Delete Directory)
- ;*
- ;* Params: pspec - Pointer to ASCIIZ pathname of subdirectory
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if delete error or subdirectory not empty
-
- RemoveDir PROC \
- USES ds, \
- pspec:PTR BYTE
-
- LoadPtr ds, dx, pspec ; Point DS:DX to path spec
- mov ah, 3Ah ; DOS Function 3Ah
- int 21h ; Delete Directory
- mov ax, 0 ; Set error code, keep flags
- jnc exit ; Exit if successful
- inc ax ; Else set error code to 1
- exit: ret
-
- RemoveDir ENDP
-
-
- ;* ChangeDir - Changes current (default) directory.
- ;*
- ;* Shows: DOS Function - 3Bh (Set Current Directory)
- ;*
- ;* Params: pspec - Pointer to ASCIIZ pathname of target subdirectory
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if delete error or subdirectory not empty
-
- ChangeDir PROC \
- USES ds, \
- pspec:PTR BYTE
-
- LoadPtr ds, dx, pspec ; Point DS:DX to path spec
- mov ah, 3Bh ; DOS Function 3Bh
- int 21h ; Set Current Directory
- mov ax, 0 ; Set error code, keep flags
- jnc exit ; Exit if successful
- inc ax ; Else set error code to 1
- exit: ret
-
- ChangeDir ENDP
-
-
- ;* DelFile - Deletes a specified file.
- ;*
- ;* Shows: DOS Function - 41h (Delete File)
- ;*
- ;* Params: fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if delete error
-
- DelFile PROC \
- USES ds, \
- fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; Point DS:DX to file spec
- mov ah, 41h ; DOS Function 41h
- int 21h ; Delete File
- mov ax, 0 ; Set error code, keep flags
- jnc exit ; Exit if successful
- inc ax ; Else set error code to 1
- exit: ret
-
- DelFile ENDP
-
-
- ;* Rewind - Rewinds an open file, specified by handle. See the GetFileSize
- ;* procedure for an example of using Function 42h to determine file size.
- ;*
- ;* Shows: DOS Function - 42h (Set File Pointer)
- ;*
- ;* Params: handle - File handle
- ;*
- ;* Return: None
-
- Rewind PROC \
- handle:WORD
-
- mov bx, handle ; BX = file handle
- mov ax, 4200h ; AH = function #,
- ; AL = move to beginning of
- sub cx, cx ; file plus offset
- sub dx, dx ; CX:DX = offset (zero)
- int 21h ; Set File Pointer
- ret
-
- Rewind ENDP
-
-
- ;* GetFileSize - Gets the size of an open file, specified by handle.
- ;*
- ;* Shows: DOS Function - 42h (Set File Pointer)
- ;*
- ;* Params: handle - File handle
- ;*
- ;* Return: Long integer with file size in bytes
-
- GetFileSize PROC \
- handle:WORD
-
- mov bx, handle ; BX = file handle
- mov ax, 4202h ; AH = function #,
- ; AL = move to end of
- sub cx, cx ; file plus offset
- sub dx, dx ; CX:DX = offset (zero)
- int 21h ; Set File Pointer
- mov ax, dx ; Set DX:AX = file size in
- mov dx, cx ; bytes, return long int
- ret
-
- GetFileSize ENDP
-
-
- ;* GetAttribute - Gets the attribute(s) of a specified file.
- ;*
- ;* Shows: DOS Function - 43h (Get or Set File Attributes)
- ;*
- ;* Params: fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with file attribute bits set as follows:
- ;* bit 0 = read-only bit 3 = volume label
- ;* bit 1 = hidden bit 4 = subdirectory
- ;* bit 2 = system bit 5 = archive
- ;* 0 indicates normal data file
- ;* -1 indicates error
-
- GetAttribute PROC \
- USES ds, \
- fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; DS:DX = file specification
- mov ax, 4300h ; AH = function #
- ; AL = 0 (return attribute)
- int 21h ; Get File Attributes
- mov ax, -1 ; Set code, keep flags
- jc exit ; If read error, exit
- mov ax, cx ; Else return with
- exit: ret ; file attribute bits
-
- GetAttribute ENDP
-
-
- ;* SetAttribute - Sets the attribute(s) of a specified file.
- ;*
- ;* Shows: DOS Function - 43h (Get or Set File Attributes)
- ;*
- ;* Params: attr - Attribute bits set as follows:
- ;* bit 0 = read-only bit 3 = volume label
- ;* bit 1 = hidden bit 4 = subdirectory
- ;* bit 2 = system bit 5 = archive
- ;* (attr = 0 for normal data file)
- ;* fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if delete error
-
- SetAttribute PROC \
- USES ds, \
- attr:WORD, fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; DS:DX = file specification
- mov cx, attr ; Put attribute code in CX
- mov ax, 4301h ; AH = function #
- ; AL = 1 (set attribute)
- int 21h ; Set File Attributes
- mov ax, 0 ; Clear code, keep flags
- jnc exit ; If successful, exit
- inc ax ; Else set error code
- exit: ret
-
- SetAttribute ENDP
-
-
- ;* GetCurDir - Gets the current directory of default drive.
- ;*
- ;* Shows: DOS Function - 47h (Get Current Directory)
- ;*
- ;* Params: spec - Pointer to 64-byte buffer to receive directory
- ;* path. Path terminates with 0 but does not include
- ;* drive and does not begin with backslash.
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if delete error or subdirectory not empty
-
- GetCurDir PROC \
- USES ds si, \
- spec:PTR BYTE
-
- LoadPtr ds, si, spec ; DS:SI = spec address
- mov ah, 47h ; AH = function number
- sub dl, dl ; DL = current drive (0)
- int 21h ; Get Current Directory
- mov ax, 0 ; Set error code, keep flags
- jnc exit ; Exit if successful
- inc ax ; Else set error code to 1
- exit: ret
-
- GetCurDir ENDP
-
-
- ;* FindFirst - Finds first entry in given directory matching specification.
- ;*
- ;* Shows: DOS Function - 4Eh (Find First File)
- ;* Keywords - USES
- ;* Instructions - ret pushf popf
- ;*
- ;* Params: attr - Attribute code (see header comments for CreateFile)
- ;* fspec - Pointer to ASCIIZ file specification
- ;* finfo - Pointer to 43-byte buffer to receive
- ;* data from matched entry
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if no match found
-
- .DATA
- old_dta DD WORD PTR ? ; Storage for old DTA address
-
- .CODE
-
- FindFirst PROC \
- USES ds, \
- attr:WORD, fspec:PTR BYTE, finfo:PTR BYTE
-
- push ds ; Pass far pointer
- mov ax, OFFSET @data:old_dta; to old_dta
- push ax
- call GetDTA ; Get current DTA address
- add sp, 4 ; Adjust stack
-
- mov cx, attr ; Load CX with file attribute
- LoadPtr ds, dx, finfo ; DS:DX points to 43-byte buffer
- push ds ; Make this new DTA
- push dx
- call SetDTA ; Set 43-byte buffer as DTA
- add sp, 4 ; Adjust stack
- LoadPtr ds, dx, fspec ; Point DS:DX to file spec
- mov ah, 4Eh ; AH = function number
- int 21h ; Find First File
-
- pushf ; Preserve flags
- push WORD PTR @data:old_dta[2] ; Pass far pointer to
- push WORD PTR @data:old_dta[0] ; SetDTA procedure
- call SetDTA ; Restore DTA address to orig
- sub ax, ax ; Set error code
- add sp, 4 ; Adjust stack
- popf ; Recover flags
- jnc exit ; Exit if successful match
- inc ax ; Else set error code to 1
- exit: ret
-
- FindFirst ENDP
-
-
- ;* FindNext - Finds next entry in given directory matching specification.
- ;* (Should be called only after successfully calling the FindFirst procedure.)
- ;*
- ;* Shows: DOS Function - 4Fh (Find Next File)
- ;* Operator - OFFSET
- ;*
- ;* Params: finfo - Pointer to 43-byte buffer. This must be the same buffer
- ;* (or a duplicate) returned from the FindFirst procedure.
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if no more matches found
-
- FindNext PROC \
- USES ds, \
- finfo:PTR BYTE
-
- push ds ; Pass far pointer
- mov ax, OFFSET @data:old_dta; to old_dta
- push ax
- call GetDTA ; Get current DTA address
- add sp, 4 ; Adjust stack
-
- LoadPtr ds, dx, finfo ; DS:DX points to 43-byte buffer
- push ds ; Make this new DTA
- push dx
- call SetDTA ; Set 43-byte buffer as DTA
- add sp, 4 ; Adjust stack
- mov ah, 4Fh ; AH = function number
- int 21h ; Find Next File
-
- pushf ; Preserve flags
- push WORD PTR @data:old_dta[2] ; Pass far pointer to
- push WORD PTR @data:old_dta[0] ; SetDTA procedure
- call SetDTA ; Restore DTA address to orig
- sub ax, ax ; Set error code
- add sp, 4 ; Adjust stack
- popf ; Recover flags
- jnc exit ; Exit if successful match
- inc ax ; Else set error code to 1
- exit: ret
-
- FindNext ENDP
-
-
- ;* RenameFile - Renames specified file.
- ;*
- ;* Shows: DOS Function - 56h (Rename File)
- ;*
- ;* Params: fspec1 - Pointer to old ASCIIZ file specification
- ;* fspec2 - Pointer to new ASCIIZ file specification
- ;*
- ;* The drive must be the same for both arguments, but the path
- ;* does not. This allows files to be moved between directories.
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if error
-
- RenameFile PROC \
- USES ds di, \
- fspec1:PTR BYTE, fspec2:PTR BYTE
-
- LoadPtr ds, dx, fspec1 ; Point DS:DX to old file spec
- LoadPtr es, di, fspec2 ; Point ES:DI to new file spec
- mov ah, 56h ; AH = function number
- int 21h ; Rename File
- mov ax, 0 ; Clear error code, keep flags
- jnc exit ; Return code = 0 if no error
- inc ax ; Else set error code
- exit: ret
-
- RenameFile ENDP
-
-
- ;* GetFileTime - Gets date/time for open file specified by handle.
- ;*
- ;* Shows: DOS Function - 57h (Get or Set File Date and Time)
- ;* Instructions - shl shr
- ;*
- ;* Params: handle - Handle of open file
- ;* str - Pointer to 18-byte buffer to receive date/time
- ;*
- ;* Return: Short integer with error code
- ;* 0 if successful
- ;* 1 if error
-
- GetFileTime PROC \
- USES di, \
- handle:WORD, str:PTR BYTE
-
- mov ax, 5700h ; AH = function number
- ; AL = get request
- mov bx, handle ; BX = file handle
- int 21h ; Get File Date and Time
- mov ax, 1 ; Set error code, keep flags
- jc exit ; Return code = 1 if no error
- mov bx, cx ; Else save time in BX
- mov al, bl ; Get low byte of time
- and al, 00011111b ; Mask to get 2-second incrs,
- shl al, 1 ; convert to seconds
- push ax ; Save seconds
- mov cl, 5
- shr bx, cl ; Shift minutes into low byte
- mov al, bl ; Get new low byte
- and al, 00111111b ; Mask to get minutes
- push ax ; Save minutes
- mov cl, 6
- shr bx, cl ; Shift hours into low byte
- push bx ; Save hours
-
- mov bl, dl ; Get low byte of date
- and bl, 00011111b ; Mask to get day in BX
- mov cl, 5
- shr dx, cl ; Shift month into low byte
- mov al, dl ; Get new low byte
- and al, 00001111b ; Mask to get month
- mov cl, 4
- shr dx, cl ; Shift year into low byte
- add dx, 80 ; Year is relative to 1980
- push dx ; Save year
- push bx ; Save day
- push ax ; Save month
-
- LoadPtr es, di, str ; Point ES:DI to 18-byte
- mov cx, 6 ; string
- loop1: pop ax ; Get 6 numbers sequentially in AL
- aam ; Convert to unpacked BCD
- xchg al, ah ; Switch bytes for word move
- or ax, '00' ; Make ASCII numerals
- stosw ; Copy to string
- mov al, '-' ; Separator for date text
- cmp cl, 4 ; First 3 iters are for date
- jg @F ; If CX=6 or 5, insert hyphen
- mov al, ' ' ; Separator date and time
- je @F ; If CX = 4, insert hyphen
- mov al, ':' ; Separator for time text
- cmp cl, 1
- je eloop ; If CX = 1, skip
- @@: stosb ; Copy separator to string
- eloop: loop loop1
-
- sub ax, ax ; Clear return code
- stosb ; Terminate string with null
- exit: ret ; to make ASCIIZ
-
- GetFileTime ENDP
-
-
- ;* UniqueFile - Creates and opens a new file with a name unique to the
- ;* specified directory. The name is manufactured from the current time,
- ;* making it useful for temporary files. For DOS versions 3.0 and higher.
- ;*
- ;* Shows: DOS Function - 5Ah (Create Temporary File)
- ;*
- ;* Params: attr - Attribute code (see header comments for CreateFile)
- ;* fspec - Pointer to ASCIIZ path specification
- ;*
- ;* Return: Short integer with file handle or -1 for error
-
- UniqueFile PROC \
- USES ds, \
- attr:WORD, pspec:PTR BYTE
-
- call GetVer ; Get DOS version
- cmp ax, 300 ; 3.0 or higher?
- jb e_exit ; No? Quit with error
- LoadPtr ds, dx, pspec ; Point DS:DX to path spec
- mov cx, attr ; CX = attribute
- mov ah, 5Ah ; AH = function number
- int 21h ; Create Temporary File
- jnc exit ; Return AX = handle if ok
- e_exit: mov ax, -1 ; Else set error code
- exit: ret
-
- UniqueFile ENDP
-
-
- ;* CreateNewFile - Creates a new file with specified attribute. Differs
- ;* from the CreateFile procedure in that it returns an error if file
- ;* already exists. For DOS versions 3.0 and higher.
- ;*
- ;* Shows: DOS Function - 5Bh (Create New File)
- ;*
- ;* Params: attr - Attribute code (see header comments for CreateFile)
- ;* fspec - Pointer to ASCIIZ file specification
- ;*
- ;* Return: Short integer with file handle or -1 for error
-
- CreateNewFile PROC \
- USES ds, \
- attr:WORD, fspec:PTR BYTE
-
- LoadPtr ds, dx, fspec ; Point DS:DX to file spec
- mov cx, attr ; CX = attribute
- mov ah, 5Bh ; AH = function number
- int 21h ; Create New File
- jnc exit ; Return AX = handle if ok
- mov ax, -1 ; Else set error code
- exit: ret
-
- CreateNewFile ENDP
-
-
- ;* StrCompare - Compares two strings for equality. See StrWrite, StrFindChar,
- ;* WinOpen, and WinClose procedures for other examples of string instructions.
- ;*
- ;* Shows: Instructions - cmpsb cmpsw repe test jcxz
- ;*
- ;* Params: str1 - Pointer to first string
- ;* str2 - Pointer to second string
- ;* len - Length in bytes for comparison. Strings need not be of
- ;* equal length; however if len is an even number, comparison
- ;* is made on a word-by-word basis and thus is more efficient.
- ;*
- ;* Return: Null pointer if strings match; else pointer to string #1 where
- ;* match failed.
-
- StrCompare PROC \
- USES ds di si, \
- str1:PTR BYTE, str2:PTR BYTE, len:WORD
-
- LoadPtr es, di, str1 ; ES:DI points to string #1
- LoadPtr ds, si, str2 ; DS:SI points to string #2
- mov cx, len ; Length of search in bytes
- and al, 0 ; Set ZR flag in case CX = 0
- jcxz nullp ; Assume success if length = 0
- test cl, 1 ; Even number?
- jz wrdcmp ; Yes? Compare word-by-word
- repe cmpsb ; No? Compare byte-by-byte
- jmp SHORT nullp
-
- wrdcmp: shr cx, 1 ; Decrease count by half
- repe cmpsw ; Compare word-by-word
- sub di, 2 ; Back up 2 characters
- sub si, 2
- cmpsb ; Match?
- jne nullp ; No? Then failure
- cmpsb ; Compare last characters
-
- nullp: mov ax, 0 ; Set null pointer without
- mov dx, 0 ; disturbing flags
- je exit ; If strings match, exit
- dec di ; Else point to failure
- mov ax, di
- mov dx, es
- exit: ret
-
- StrCompare ENDP
-
-
- ;* StrFindChar - Finds first occurence of character in given ASCIIZ string,
- ;* searching either from beginning or end of string. See StrWrite, WinOpen,
- ;* WinClose, and StrCompare procedures for other examples of string
- ;* instructions.
- ;*
- ;* Shows: Instructions - repne scasb cld std
- ;*
- ;* Params: ichar - Character to search for
- ;* str - Pointer to ASCIIZ string in which to search
- ;* direct - Direction flag:
- ;* 0 = search from start to end
- ;* 1 = search from end to start
- ;*
- ;* Return: Null pointer if character not found, else pointer to string where
- ;* character first encountered
-
- StrFindChar PROC \
- USES ds di si, \
- ichar:BYTE, str:PTR BYTE, direct:WORD
-
- LoadPtr es, di, str ; ES:DI points to string
- LoadPtr ds, si, str ; as does DS:SI
- mov cx, -1 ; Set scan counter to maximum
- mov bx, cx ; BX = max string tail
- cld ; Assume head-to-tail search
- cmp direct, 0 ; Assumption correct?
- je loop1 ; Yes? Continue
- mov bx, di ; No? Set BX to byte before
- dec bx ; string head and scan
- sub al, al ; string for null terminator
- push cx ; to find string tail
- repne scasb
- pop cx ; Recover scan counter
- dec di ; Backup pointer to last
- dec di ; character in string and
- mov si, di ; begin search from there
- std ; Set direction flag
-
- loop1: lodsb ; Get first char from string
- cmp si, bx ; At head limit?
- je xmatch ; Yes? Then no match
- or al, al ; At tail limit?
- je xmatch ; Yes? Then no match
- cmp al, ichar ; Character match?
- je match ; Yes? Then exit
- loop loop1 ; No? Resume search
-
- xmatch: sub ax, ax ; Set null pointer if no match
- sub dx, dx
- jmp SHORT exit
-
- match: mov ax, si ; If match, point to first
- dec ax ; occurence
- cmp direct, 0 ; Head-to-tail search?
- je exit ; Yes? Then exit
- inc ax ; No? Then adjust pointer
- inc ax ; forward
- mov dx, ds ; Pointer segment
- exit: ret
-
- StrFindChar ENDP
-
-
- ;* GetStr - Gets a string of up to 128 characters from the user. Since
- ;* this function uses the DOS input mechanism, it can use the DOS editing
- ;* keys or the keys of a DOS command-line editor if one is loaded.
- ;*
- ;* Shows: DOS Function - 0Ah (Buffered Keyboard Input)
- ;*
- ;* Params: buffer - Pointer to area where input string will be placed
- ;* maxlen - Maximum length (up to 128 characters) of string
- ;*
- ;* Return: 0 if successful, 1 if error (maxlen is too long)
-
- .DATA
- MAXSTR EQU 128
- max DB MAXSTR
- actual DB ?
- string DB MAXSTR DUP (?)
-
- .CODE
- GetStr PROC \
- USES si di, \
- strbuf:PTR BYTE, maxlen:WORD
-
- mov ax, 1 ; Assume error
- mov cx, maxlen ; Copy length to register
- jcxz exit ; Error if maxlen is zero
- cmp cx, MAXSTR
- ja exit ; Error if maxlen is too long
-
- mov max, cl ; Load maximum length
- mov ah, 0Ah ; Request DOS Function 0Ah
- mov dx, OFFSET max ; Load offset of string
- int 21h ; Buffered Keyboard Input
-
- mov bl, actual ; Put number of characters read
- sub bh, bh ; in BX
- mov string[bx], 0 ; Null-terminate string
- mov cx, bx ; Put count in CX
- inc cx ; Plus one for the null terminator
-
- LoadPtr es, di, strbuf ; ES:DI points to destination buffer
- mov si, OFFSET string ; DS:SI points to source string
- rep movsb ; Copy source to destination
- sub ax, ax ; Return 0 for success
-
- exit: ret
-
- GetStr ENDP
-
- END
-