The following is a typical program sequence to access a file using the FCB, or traditional, functions (Figure 8-4):
1.Zero out the prospective FCB.
2.Obtain the filename from the user, from the default FCBs, or from the command tail in the PSP.
3.If the filename was not obtained from one of the default FCBs, parse the filename into the new FCB using Int 21H Function 29H.
4.Open the file (Int 21H Function 0FH) or, if writing new data only, create the file or truncate any existing file of the same name to zero length (Int 21H Function 16H).
5.Set the record-size field in the FCB, unless you are using the default record size. Recall that it is important to do this after a successful open or create operation. (See Figure 8-5.)
6.Set the relative-record field in the FCB if you are performing random record I/O.
7.Set the disk transfer area address using Int 21H Function 1AH, unless the buffer address has not been changed since the last call to this function. If the application never performs a set DTA, the DTA address defaults to offset 0080H in the PSP.
8.Request the needed read- or write-record operation (Int 21H Function 14H—Sequential Read, 15H—Sequential Write, 21H—Random Read, 22H—Random Write, 27H—Random Block Read, 28H—Random Block Write).
9.If the program is not finished processing the file, go to step 6; otherwise, close the file (Int 21H Function 10H). If the file was used for reading only, you can skip the close operation under early versions of MS-DOS. However, this shortcut can cause problems under MS-DOS versions 3.0 and later, especially when the files are being accessed across a network.
recsize equ 1024 ; file record size
.
.
.
mov ah,29h ; parse input filename
mov al,1 ; skip leading blanks
mov si,offset fname1 ; address of filename
mov di,offset fcb1 ; address of FCB
int 21h
or al,al ; jump if name
jnz name_err ; was bad
.
.
.
mov ah,29h ; parse output filename
mov al,1 ; skip leading blanks
mov si,offset fname2 ; address of filename
mov di,offset fcb2 ; address of FCB
int 21h
or al,al ; jump if name
jnz name_err ; was bad
.
.
.
mov ah,0fh ; open input file
mov dx,offset fcb1
int 21h
or al,al ; open successful?
jnz no_file ; no, jump
.
.
.
mov ah,16h ; create and open
mov dx,offset fcb2 ; output file
int 21h
or al,al ; create successful?
jnz disk_full ; no, jump
.
.
. ; set record sizes
mov word ptr fcb1+0eh,recsize
mov word ptr fcb2+0eh,recsize
.
.
.
mov ah,1ah ; set disk transfer
mov dx,offset buffer ; address for reads
int 21h ; and writes
.
next: . ; process next record
.
mov ah,14h ; sequential read from
mov dx,offset fcb1 ; input file
int 21h
cmp al,01 ; check for end of file
je file_end ; jump if end of file
cmp al,03
je file_end ; jump if end of file
or al,al ; other read fault?
jnz bad_read ; jump if bad read
.
.
.
mov ah,15h ; sequential write to
mov dx,offset fcb2 ; output file
int 21h
or al,al ; write successful?
jnz bad_write ; jump if write failed
.
.
.
jmp next ; process next record
.
file_end: . ; reached end of input
.
mov ah,10h ; close input file
mov dx,offset fcb1
int 21h
.
.
.
mov ah,10h ; close output file
mov dx,offset fcb2
int 21h
.
.
.
mov ax,4c00h ; exit with return
int 21h ; code of zero
.
.
.
fname1 db 'OLDFILE.DAT',0 ; name of input file
fname2 db 'NEWFILE.DAT',0 ; name of output file
fcb1 db 37 dup (0) ; FCB for input file
fcb2 db 37 dup (0) ; FCB for output file
buffer db recsize dup (?) ; buffer for file I/O
Figure 8-4. Skeleton of an assembly-language program that performs file and record I/O using the FCB family of functions.
Figure 8-5. A typical file control block before and after a successful open call (Int 21H Function 0FH).
Please refer to the printed book for this figure.