; ============================================================================
;
; LT-DOS - Int 21h files
;
; ============================================================================
MAXFILES EQU 128 ; total maximum number of open files
NAMELEN EQU 8 ; file name length
EXTLEN EQU 3 ; file extension length
FILENAMELEN EQU NAMELEN+EXTLEN ; file name length with extension
; ------------- Unopen File Control Block, UFCB
struc UFCB
UFCB_Disk: resb 1 ; 0: disk number (0=default, 1=A:, ...)
UFCB_Name: resb NAMELEN ; 1: blank-padded file name
UFCB_Ext: resb EXTLEN ; 9: blank-padded file extension
UFCB_Cluster: resw 1 ; 0ch: current cluster number
UFCB_RecSize: resw 1 ; 0eh: logical record size
endstruc
UFCB_SIZE EQU UFCB_size ; 10h = 16 bytes
; ------------- File Control Block, FCB
struc FCB
FCB_Disk: resb 1 ; 0: disk number (0=default, 1=A:, ...)
FCB_Name: resb NAMELEN ; 1: blank-padded file name
FCB_Ext: resb EXTLEN ; 9: blank-padded file extension
FCB_Cluster: resw 1 ; 0Ch: current cluster number
FCB_RecSize: resw 1 ; 0Eh: logical record size
FCB_Size: resd 1 ; 10h: file size
FCB_Date: resw 1 ; 14h: date of last write
; bit 0-4: day
; bit 5-8: month
; bit 9-15: year - 1980
FCB_Time: resw 1 ; 16h: time of last write
; bit 0-4: second/2
; bit 5-10: minute
; bit 11-15: hour
resb 8 ; 18h: ...reserved
; 18h: (1) device attributes
; 19h: (2) starting cluster number
; 1bh: (2) current cluster on disk
; 1dh: (2) current cluster in file
FCB_RecClust: resb 1 ; 20h: record within current cluster
FCB_Record: resd 1 ; 21h: current record number
endstruc
FCB_SIZE EQU FCB_size ; 25h = 37 bytes
; ------------- Extended File Control Block, XFCB
struc XFCB
XFCB_Sign: resb 1 ; 0: 0ffh signature to XFCB
resb 5 ; 1: ...reserved
XFCB_Attr: resb 1 ; 6: file attributes
XFCB_FCB: resb FCB_SIZE ; 7: standard FCB
endstruc
XFCB_SIZE EQU XFCB_size ; 2Ch = 44 bytes
; ------------- Open File Table, OFT
struc OFT
OFT_Ref: resb 1 ; 0: file handles referring to this file
OFT_Mode: resb 1 ; 1: file open mode (see "Open mode")
OFT_Attr: resb 1 ; 2: file attribute
; --- FCB of the file
OFT_FCB: ; 3: FCB of the file
OFT_Disk: resb 1 ; 3: drive (0=character, 1=A:, ...)
OFT_Filename: resb FILENAMELEN ; 4: blank-padded filename with ext.
resw 2 ; 0Fh: ...reserved (unused)
OFT_Size: resd 1 ; 13h: file size
OFT_Date: resw 1 ; 17h: file date
; bit 0-4: day
; bit 5-8: month
; bit 9-15: year - 1980
OFT_Time: resw 1 ; 19h: file time
; bit 0-4: second/2
; bit 5-10: minute
; bit 11-15: hour
OFT_DevAttr: resb 1 ; 1Bh: device attributes
; bit 7: 1=character device
; Character device
OFT_Device: ; 1Ch: pointer to device driver
; Block device
OFT_Cluster: resw 1 ; 1Ch: starting cluster
OFT_ClustRel: resw 1 ; 1Eh: relative current cluster in file
OFT_ClustAbs: resw 1 ; 20h: absolute current cluster
OFT_ClustPos: resw 1 ; 22h: position in current cluster
OFT_Seek: resd 1 ; 24h: current file position
endstruc
OFT_SIZE EQU OFT_size ; 28h = 40 bytes
; ------------- System File Table, SFT
struc SFT
SFT_Next: resd 1 ; 0: pointer to next SFT (-1=last)
SFT_Files: resw 1 ; 4: number of files in this table
SFT_File: resb OFT_SIZE ; 6: OFT tables (40 bytes each)
endstruc
SFT_SIZE EQU SFT_size ; 2Eh = 46 bytes (if 1 file in table)
; ------------- Open mode
OPEN_MASK EQU B0+B1+B2 ; access mode mask
OPEN_RO EQU 0 ; read only
OPEN_WO EQU 1 ; write only
OPEN_RW EQU 2 ; read/write
OPEN_INHER EQU B7 ; 1=file is private and cannot be
; inherited by child processes
; ----------------------------------------------------------------------------
; Get pointer to file handle in current PSP
; ----------------------------------------------------------------------------
; INPUT: BX = local file handle (0 to 19)
; OUTPUT: ES:DI = pointer to file handle
; CY = error, invalid local file handle
; ----------------------------------------------------------------------------
; ------------- Check file handle (on error sets CF)
GetFileAddr: cmp bx,byte PSPFILES ; check file handle
cmc ; complement carry flag
jc GetFileAddr4 ; error, invalid file handle
; ------------- Get pointer to file handle (clears CF)
mov di,bx ; DI <- local file handle
add di,byte PSP_File ; DI <- pointer to JFT (clears CF)
mov es,[cs:CurrentPSP] ; ES <- segment of current PSP
GetFileAddr4: ret
; ----------------------------------------------------------------------------
; Get open file table
; ----------------------------------------------------------------------------
; INPUT: AX = global file handle (0 to 127)
; OUTPUT: CY = file not found
; ES:DI = Open File Table
; ----------------------------------------------------------------------------
; ------------- Push registers
GetOFT: push ax ; push AX
; ------------- Prepare pointer to first table
push cs ; push CS
pop es ; ES <- CS
mov di,FirstSFT ; DI <- pointer to first SFT
; ------------- Pointer to next SFT (System File Table)
GetOFT2: les di,[es:di] ; ES:DI <- next SFT
inc di ; is any other table?
stc ; set error flag
jz GetOFT8 ; error, end of table
dec di ; return pointer LOW
; ------------- Check number of files in this table
sub ax,[es:di+SFT_Files] ; AX <- check number of files
jge GetOFT2 ; file is not in this table
; ------------- Calculate offset of OFT (Open File Table)
add ax,[es:di+SFT_Files] ; return number of file
mov ah,OFT_SIZE ; AH <- size of OFT structure
mul ah ; offset of table
add ax,byte SFT_File; offset of first SFT
add di,ax ; DI <- offset of SFT (it clears CF)
; ------------- Pop registers
GetOFT8: pop ax ; pop AX
ret
; ----------------------------------------------------------------------------
; Get open file table from PSP
; ----------------------------------------------------------------------------
; INPUT: BX = local file handle (0 to 19)
; OUTPUT: CY = file not found
; ES:DI = Open File Table
; ----------------------------------------------------------------------------
; ------------- Push registers
GetFilePSP: push ax ; push AX
; ------------- Get pointer to file handle -> ES:DI
call GetFileAddr ; get pointer to file handle
jc GetFilePSP8 ; error
; ------------- Global file handle (-> AX)
xor ax,ax ; AX <- 0
mov al,[es:di] ; AL <- global file handle
cmp al,0ffh ; is this file closed?
cmc ; set CF if file is closed
jc GetFilePSP8 ; file is closed
; ------------- Get open file table (-> ES:DI)
call GetOFT ; get open file table
; ------------- Pop registers
GetFilePSP8: pop ax ; pop AX
ret
; ----------------------------------------------------------------------------
; Get FCB of open file from PSP
; ----------------------------------------------------------------------------
; INPUT: BX = local file handle (0 to 19)
; OUTPUT: CY = file not found
; ES:DI = FCB of the file
; ----------------------------------------------------------------------------
GetFileFCB: call GetFilePSP ; get open file table
jc GetFileFCB4 ; error
add di,byte OFT_FCB ; DI <- FCB of the file (it clears CF)
GetFileFCB4: ret
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
|