home *** CD-ROM | disk | FTP | other *** search
- ;=============================================================================
- ; File Routines
- ;
- ; These are routines open, close, read, and write to files. All reading and
- ; writing is sequential and buffered. Information for each open file is
- ; contained in a special record which consists of 12 consecutive bytes. A
- ; record must be declared in the calling program for each open file. The
- ; information within a record is assigned and maintained by the file routines.
- ;
- ; The file record format is:
- ;
- ; dw ? ;status offset 0
- ; dw ? ;buffer size offset 2
- ; dw ? ;buffer data offset offset 4
- ; dw ? ;buffer segment offset 6
- ; dw ? ;file handle offset 8
- ; dw ? ;bytes in buffer offset 10
- ;
- ; All all registers are preserved except those used to return parameters. All
- ; parameters are passed through registers. It is assumed that DS = ES = CS.
-
- ;================================================
- ; Allocate a read/write buffer.
- ;
- ; In: BX= file record offset; [BX+2]= buffer
- ; size.
- ;
- ; Out: CY= set if error; AX= error number.
-
- File_Alloc PROC NEAR
- push cx
- push dx
- push bx
- mov bx, [bx+2] ;size in bytes
- mov cl, 4 ;paragraph shift
- shr bx, cl ;get size in paragraphs
- inc bx ;round up
- mov dx, bx
- shl dx, cl ;shift back to byte form
- mov ah, 48h ;function
- int 21h ;execute
- pop bx
- jc filall1
- mov [bx+2], dx ;save size
- mov WORD [bx+4], 0 ;clear data pointer
- mov [bx+6], ax ;save segment
- mov WORD [bx+10], 0 ;clear bytes in buffer
- filall1 pop dx
- pop cx
- ret
- ENDP ;File_Alloc
-
- ;================================================
- ; Deallocate a read/write buffer.
- ;
- ; In: BX= file record offset.
-
- File_Free PROC NEAR
- push ax
- push es
- mov es, [bx+6] ;segment
- mov ah, 49h ;function
- int 21h ;execute
- pop es
- pop ax
- ret
- ENDP ;File_Free
-
- ;================================================
- ; Create or truncate a file. File is opened for
- ; writing.
- ;
- ; In: BX= file record offset; CX= buffer size;
- ; DX= offset of filespec.
- ;
- ; Out: CY= set if error; AX= returns error code.
-
- File_Create PROC NEAR
- mov WORD [bx], 1 ;set status
- mov [bx+2], cx ;save size
- call File_Alloc ;allocate buffer
- jc filcre1 ;jump if error
- mov ah, 3ch ;function
- sub cx, cx ;file attribute
- int 21h ;execute
- mov [bx+8], ax ;save handle
- jnc filcre1
- call File_Free ;deallocate buffer
- stc
- filcre1 ret
- ENDP ;File_Create
-
- ;================================================
- ; Open a file for reading.
- ;
- ; In: BX= file record offset; CX= buffer size;
- ; DX= offset of filespec.
- ;
- ; Out: CY= set if error; AX= returns error code.
-
- File_OpenR PROC NEAR
- mov WORD [bx+0], 0 ;set status
- mov [bx+2], cx ;save size
- call File_Alloc ;allocate buffer
- jc filopn1 ;jump if error
- mov ax, 3d00h ;function and access
- int 21h ;execute
- mov [bx+8], ax ;save handle
- jnc filopn1
- call File_Free ;deallocate
- stc
- filopn1 ret
- ENDP ;File_OpenR
-
- ;================================================
- ; Open a file for writing.
- ;
- ; In: BX= file record offset; CX= buffer size;
- ; DX= offset of filespec.
- ;
- ; Out: CY= set if error; AX= returns error code.
-
- File_OpenW PROC NEAR
- mov WORD [bx], 1 ;set status
- mov [bx+2], cx ;save size
- call File_Alloc ;allocate buffer
- jc filopw1 ;jump if error
- mov ax, 3d01h ;function and access
- int 21h ;execute
- mov [bx+8], ax ;save handle
- jnc filopw1
- call File_Free ;deallocate
- stc
- filopw1 ret
- ENDP ;File_OpenW
-
- ;================================================
- ; Fill a read buffer.
- ;
- ; In: BX= file record offset.
- ;
- ; Out: CY= set if error; AX= error code (AX= 0 if
- ; EOF and 0 bytes are read).
-
-
- File_Fill PROC NEAR
- push cx
- push dx
- push bx
- push ds
- mov ax, [bx+8] ;file handle
- mov cx, [bx+2] ;buffer size
- sub dx, dx ;start of segment
- mov [bx+4], dx ;set data offset
- mov ds, [bx+6] ;buffer segment
- mov bx, ax
- mov ah, 3fh ;function
- int 21h ;execute
- pop ds
- pop bx
- mov [bx+10], ax ;save bytes read
- jc filfil1
- or ax, ax ;check if no bytes
- jnz filfil1
- stc
- filfil1 pop dx
- pop cx
- ret
- ENDP ;File_Fill
-
- ;================================================
- ; Read from a file.
- ;
- ; In: BX= file record offset; CX= number of
- ; bytes; DI= location of bytes.
- ;
- ; Out: CY= set if error; AX= error code (CY= set
- ; and AX= 0 if EOF); CX= bytes read.
-
- File_Read PROC NEAR
- pushf
- push cx
- push dx
- push di
- push si
- cld
- mov dx, [bx+6] ;buffer segment
-
- ;--- read bytes from buffer
-
- filred1 mov ax, [bx+10] ;bytes in buffer
- mov si, [bx+4] ;data pointer
- sub ax, si ;bytes available
- jz filred3 ;jump if none
-
- push ds
- push cx
- cmp ax, cx ;check if enough
- jae filred2
- mov cx, ax ;read what's available
-
- filred2 push cx
- mov ds, dx
- rep
- movsb ;copy bytes
- pop ax
- pop cx
- pop ds
- mov [bx+4], si ;save data pointer
- sub cx, ax ;get bytes not yet read
- jz filred4 ;jump if finished
-
- ;--- read into buffer
-
- filred3 call File_Fill ;read a buffer full
- jnc filred1
-
- ;--- finished
-
- filred4 pop si
- pop di
- pop dx
- pop cx
- jc filred5
- popf
- clc
- ret
-
- filred5 popf
- stc
- ret
- ENDP ;File_Read
-
- ;================================================
- ; Flush the a write buffer.
- ;
- ; In: BX= file record offset; CX= file record
- ; offset.
- ;
- ; Out: CY= set if error; AX= error code (0 if
- ; disk full).
-
- File_Flush PROC NEAR
- push cx
- push dx
- push ds
-
- ;--- check if buffer needs flushing
-
- mov ax, [bx+8] ;handle
- lds cx, [bx+4] ;data pointer
- or cx, cx ;check if any data
- jz filflu3
-
- ;--- write buffer
-
- es:
- mov WORD [bx+4], 0 ;clear data pointer
- push bx
- mov bx, ax
- sub dx, dx ;start of segment
- mov ah, 40h ;function
- int 21h ;execute
- pop bx
- jc filflu2 ;jump if error
- cmp ax, cx ;check if all bytes written
- je filflu3
-
- ;--- finished, error writing buffer
-
- filflu1 sub ax, ax ;code 0 if bytes not all written
- filflu2 stc
- pop ds
- pop dx
- pop cx
- ret
-
- ;--- finished, no error
-
- filflu3 clc
- pop ds
- pop dx
- pop cx
- ret
- ret
- ENDP ;File_Flush
-
- ;================================================
- ; Write to a file.
- ;
- ; In: BX= file record offset; CX= number of
- ; bytes; SI= location of bytes.
- ;
- ; Out: CY= set if error; AX= error code (CY= set
- ; and AX= 0 is disk full).
-
- File_Write PROC NEAR
- pushf
- push cx
- push dx
- push di
- push si
- cld
- mov dx, [bx+6] ;buffer segment
-
- ;--- copy bytes to buffer
-
- Filwrt1 mov ax, [bx+2] ;buffer size
- mov di, [bx+4] ;data pointer
- sub ax, di ;buffer space available
- jz filwrt3 ;jump if none, must flush first
-
- push es
- push cx
- cmp ax, cx ;check if all bytes fit
- jae filwrt2
- mov cx, ax ;set to maximum
-
- filwrt2 push cx
- mov es, dx
- rep
- movsb
- pop ax
- pop cx
- pop es
- mov [bx+4], di ;save data pointer
- sub cx, ax ;get bytes not yet written
- jz filwrt4 ;jump if finished
-
- ;--- write buffer
-
- filwrt3 call File_Flush ;flush buffer first
- jnc filwrt1 ;loop back if no error
-
- ;--- finished
-
- filwrt4 pop si
- pop di
- pop dx
- pop cx
- jc filwrt5
- popf
- clc
- ret
-
- filwrt5 popf
- stc
- ret
- ENDP ;File_Write
-
- ;================================================
- ; Close a file.
- ;
- ; In: BX= file record offset.
- ;
- ; Out: CY= set if error; AX= error code (0 if
- ; disk full).
-
- File_Close PROC NEAR
- push bx
-
- ;--- flush file buffer
-
- test WORD [bx], 1 ;test if open for writing
- jz filclo1
- call File_Flush ;flush buffer
- jc filclo2
-
- ;--- close file
-
- filclo1 mov ah, 3eh ;function
- mov bx, [bx+8] ;handle
- int 21h ;execute
- pop bx
- ret
-
- ;--- close file, error on flush
-
- filclo2 push ax
- mov ah, 3eh ;function
- mov bx, [bx+8] ;handle
- int 21h ;execute
- pop ax
- pop bx
- stc
- ret
- ENDP ;File_Close
-