home *** CD-ROM | disk | FTP | other *** search
- .MODEL small, pascal, os_dos
- 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 (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:PWORD
-
- 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 BYTE BUFFERSIZE DUP (?) ; Buffer for diskette read
-
- .CODE
-
- CopyFile PROC USES ds si di,
- Imode:WORD,
- Fspec1:PBYTE,
- Fspec2:PBYTE
-
- 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
- .IF Imode != 1 ; If Imode (DOS function) is not 1
- mov ah, 3Ch ; Request Create File
- .ELSE
-
- ; Check DOS version
- INVOKE GetVer
-
- cmp ax, 300 ; 3.0 or higher?
- jb close ; No? Abort with error code
- mov ah, 5Bh ; Request Create New File
- .ENDIF
- 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
-
- .REPEAT
- mov bx, si ; Handle for source file
- mov cx, BUFFERSIZE ; CX = number of bytes to read
- mov ah, 3Fh ; Request DOS read
- int 21h ; Read from File
- jc close ; If error, exit
- .IF ax != cx ; If bytes not read successfully:
- inc eof_flag ; Raise flag
- .ENDIF
- 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
- .UNTIL eof_flag != 0 ; Loop to read next block
- clc ; Clear CY to indicate
- 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
- .IF carry?
- e_exit:
- mov ax, 1 ; Else set error code
- .ENDIF
- 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
-
-
- ;* GetCurDrive - Gets designation of current drive.
- ;*
- ;* Shows: DOS Function - 19h (Get Current Disk)
- ;* Instruction - cbw
- ;*
- ;* Params: None
- ;*
- ;* Return: Short integer with drive designation
- ;* 0 = A, 1 = B, 2 = C, etc.
-
- GetCurDrive PROC
-
- mov ah, 19h ; DOS Function 19h
- int 21h ; Get Current Disk
- cbw ; AX = drive designation
- ret
-
- GetCurDrive 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:FPBYTE
-
- 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:FPBYTE
-
- 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:PBYTE
-
- 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
- .IF carry?
- mov ax, -1 ; Set error code
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- mov ax, -1 ; Set error code
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- sub ax, ax ; Set error code
- .ENDIF
- 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)
- ;* Instructions - inc dec
- ;*
- ;* Params: Handle - File handle
- ;* SPtr - 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, Sptr:PBYTE
-
- LoadPtr es, di, Sptr ; 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 carry
- .IF carry? ; If carry:
- inc ax ; Increment once for write error
- .ENDIF ; carry
- .IF bx != cx ; If bytes not all written:
- inc ax ; Increment twice
- .ENDIF ; bx ! cx
- 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:PDISKSTAT
-
- 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 (DISKSTAT PTR es:[di]).\
- total, dx ; DX = total clusters
- mov (DISKSTAT PTR es:[di]).\
- avail, bx ; BX = number of free clusters
- mov (DISKSTAT PTR es:[di]).\
- sects, ax ; AX = sectors/cluster
- mov (DISKSTAT PTR 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE
-
- 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
- .IF !carry?
- mov ax, cx ; Return with file attribute bits
- .ENDIF
- ret
-
- 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- ret
-
- GetCurDir ENDP
-
-
- ;* FindFirst - Finds first entry in given directory matching specification.
- ;*
- ;* Shows: DOS Function - 4Eh (Find First File)
- ;* Instructions - 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
- OldDta FPVOID ? ; Storage for old DTA address
-
- .CODE
-
- FindFirst PROC USES ds,
- Attr:WORD,
- Fspec:PBYTE,
- Finfo:PFILEINFO
-
- ; Get current DTA address, pass address of pointer to hold value
- INVOKE GetDTA,
- ADDR OldDta
-
- mov cx, Attr ; Load CX with file attribute
-
- ; Set DTA address, pass pointer to structure
- INVOKE SetDTA,
- Finfo
-
- LoadPtr ds, dx, Fspec ; Point DS:DX to file spec
- mov ah, 4Eh ; AH = function number
- int 21h ; Find First File
-
- pushf ; Preserve flags
-
- ; Restore DTA address, pass pointer
- INVOKE SetDTA,
- OldDta
-
- sub ax, ax ; Set error code
- popf ; Recover flags
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PFILEINFO
-
- ; Get current DTA address, pass address of pointer to hold value
- INVOKE GetDTA,
- ADDR OldDta
-
- ; Set DTA address, pass pointer to structure
- INVOKE SetDTA,
- Finfo
-
- mov ah, 4Fh ; AH = function number
- int 21h ; Find Next File
-
- pushf ; Preserve flags
-
- ; Restore DTA address, pass pointer
- INVOKE SetDTA,
- OldDta
-
- sub ax, ax ; Set error code
- popf ; Recover flags
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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:PBYTE,
- Fspec2:PBYTE
-
- 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
- .IF carry?
- inc ax ; Set error code to 1
- .ENDIF
- 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
- ;* Sptr - 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,
- Sptr:PBYTE
-
- 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
- .IF !carry? ; If not carry, continue
- mov bx, cx ; Else save time in BX
- mov al, bl ; Get low byte of time
- and al, 00011111y ; 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, 00111111y ; 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, 00011111y ; 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, 00001111y ; 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, Sptr ; Point ES:DI to 18-byte
- mov cx, 6 ; string
-
- .REPEAT
- 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
- .IF cl != 1
- @@: stosb ; Copy separator to string
- .ENDIF
- .UNTILCXZ
-
- sub ax, ax ; Clear return code
- stosb ; Terminate string with null
- .ENDIF ; to make ASCIIZ
- ret
-
- 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)
- ;* Pspec - Pointer to ASCIIZ path specification
- ;*
- ;* Return: Short integer with file handle or -1 for error
-
- UniqueFile PROC USES ds,
- Attr:WORD,
- Pspec:PBYTE
-
- ; Get DOS version
- INVOKE GetVer
-
- 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
- .IF carry?
- e_exit: mov ax, -1 ; Set error code
- .ENDIF
- 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:PBYTE
-
- 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
- .IF carry?
- mov ax, -1 ; Set error code
- .ENDIF
- 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 jcxz
- ;*
- ;* Params: Sptr1 - Pointer to first string
- ;* Sptr2 - 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,
- Sptr1:PBYTE,
- Sptr2:PBYTE,
- Len:WORD
-
- LoadPtr es, di, Sptr1 ; ES:DI points to string #1
- LoadPtr ds, si, Sptr2 ; DS:SI points to string #2
- mov cx, Len ; Length of search in bytes
- and al, 0 ; Set ZR flag in case CX = 0
- .IF cx != 0 ; If length is not 0:
- .IF !(cl & 1) ; If not even number:
- repe cmpsb ; Compare byte-by-byte
- .ELSE ; Else compare word-by-word
- 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?
- .IF zero? ; No? Then failure
- cmpsb ; Compare last characters
- .ENDIF ; zero
- .ENDIF ; cl & 1
- .ENDIF ; cx != 0
-
- mov ax, 0 ; Set null pointer without
- mov dx, 0 ; disturbing flags
- .IF !zero? ; If no match:
- dec di ; Point to failure
- mov ax, di
- mov dx, es
- .ENDIF
- 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
- ;* Sptr - 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:SBYTE,
- Sptr:PBYTE,
- Direct:WORD
-
- LoadPtr es, di, Sptr ; ES:DI points to string
- LoadPtr ds, si, Sptr ; 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
-
- .IF Direct != 0 ; If assumption correct:
- mov bx, di ; 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
- .ENDIF
-
- .REPEAT
- lodsb ; Get first char from string
- .IF (si == bx) || (al == 0) ; If at head or tail limit:
- sub ax, ax ; No match
- sub dx, dx ; Set null pointer
- jmp exit
- .ENDIF
- .UNTILCXZ al == IChar
-
- mov ax, si ; Match, so point to first
- dec ax ; occurence
- .IF Direct != 0 ; If head-to-tail search:
- inc ax ; Adjust pointer forward
- inc ax
- mov dx, ds ; Pointer segment
- .ENDIF
- 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)
- ;* Directive - EQU
- ;*
- ;* Params: Strbuf - 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 BYTE MAXSTR
- actual BYTE ?
- string BYTE MAXSTR DUP (?)
-
- .CODE
- GetStr PROC USES si di,
- Strbuf:PBYTE,
- Maxlen:WORD
-
- mov ax, 1 ; Assume error
- mov cx, Maxlen ; Copy length to register
-
- .IF (cx != 0) && (cx <= MAXSTR) ; Error if 0 or 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
- .ENDIF
-
- ret
-
- GetStr ENDP
-
- END
-