?? dkio.asm
字號(hào):
TITLE DKIO - Disk I/O Drivers
page 56,132
;***
; DKIO - Disk I/O Drivers
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module came from iodisk.asm. Iodisk.asm has been split into
; three files, -- diskio.asm, dkopen.asm and fileio.asm. This file
; contains all dispatching routines (drivers) for a disk or a device
; I/O, except disk open. Disk open is in dkopen.asm. Fileio.asm
; contains the file I/O interfaces, for example, LOCK, UNlOCK, etc.
;
; The following is the disk dispatch table. Each entry is the addr.
; of the actual working routine. The routine name is composed by the
; prefix "DISK_" and the function name, e.g., DISK_EOF is the routine
; name for EOF function.
;
; B$D_DISK:
; ________
; | |
; | EOF |
; |--------|
; | LOC |
; |--------|
; | LOF |
; |--------|
; | CLOSE | = $DISK_CLOSE in gwini.asm
; |--------|
; | WIDTH |
; |--------|
; | RANDIO |
; |--------|
; | OPEN | = B$DISKOPEN in dkopen.asm
; |--------|
; | BAKC |
; |--------|
; | SINP |
; |--------|
; | SOUT |
; |--------|
; | GPOS |
; |--------|
; | GWID |
; |--------|
; | DWID |
; |--------|
; | BLKIN |
; |--------|
; | BLKOUT |
; |________|
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ;Runtime Macro Defintions
;Code segmetns
useSeg DK_TEXT
useSeg ER_TEXT
useSeg NH_TEXT
useSeg RT_TEXT
;Data segments
useSeg _DATA
useSeg _BSS
INCLUDE seg.inc
INCLUDE baslibma.inc
INCLUDE devdef.inc
INCLUDE files.inc
INCLUDE ascii.inc
INCLUDE idmac.inc
INCLUDE rtps.inc ; constants shared with QBI
SUBTTL data definitions
page
sBegin _DATA
externW b$CLOS_FDB
externW B$ENTRY_BUFCNT
sEnd;_DATA
sBegin _BSS
externD b$RECPTR ; pointer to random record
externW b$PTRFIL
SUBTTL code externals
page
sBegin DK_TEXT
externNP B$GETEXTERR ;defined in GWIO.ASM
externNP B$DISKOPEN
sEnd;DK_TEXT
sBegin RT_TEXT
externNP B$TEST_CLOSE ; close file and deallocate FDB
externNP B$Mul32x16 ; 32 by 16 bit multiply
sEnd;RT_TEXT
sBegin NH_TEXT
externNP B$LHDALC_CPCT
externNP B$LHFDBLOC
sEnd;NH_TEXT
sBegin ER_TEXT
externNP B$ERR_BFM
externNP B$ERR_BRN
externNP B$ERR_DFL
externNP B$ERR_FOV
externNP B$ERR_IFN
externNP B$ERR_IOE
externNP B$ERR_ACD
externNP B$ERR_FWP
externNP B$ERR_FC
sEnd;ER_TEXT
assumes CS,DK_TEXT
sBegin DK_TEXT
SUBTTL disk dispatch table
page
DSPMAC MACRO func
DW DISK_&func
ENDM
labelNP <PUBLIC,B$D_DISK>
DSPNAM
SUBTTL disk dispatch routines
SUBTTL backup one character
page
;***
;B$DISK_BAKC -- bakcup one character
;B$IDISK_BAKC -- Far (QB3) interface to backup one character
;
;Purpose:
; Backup one character for a disk file. Only valid for input files.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; file position is updated.
;Uses:
; none
;Preserves: (optional)
; all, except flags
;Exceptions:
; none
;*******************************************************************************
labelNP DISK_BAKC
cProc B$DISK_BAKC,<NEAR,PUBLIC>
cBegin
DEC FileDB.FD_BUFCNT ; one less read/unwritten character
cEnd ;exit
cProc B$IDISK_BAKC,<FAR,PUBLIC>,<SI>
cBegin
FDB_PTR ES,SI,b$PTRFIL ;get FDB pointer
DbAssertRel SI,NE,0,DK_TEXT,<Invalid FDB ptr in B$IDISK_BAKC>
cCall B$DISK_BAKC ;Back up a char
cEnd
SUBTTL disk close
page
;***
;DISK_CLOSE -- close disk file. Moved here with [24].
;
;Purpose:
; close disk file.
;*******************************************************************************
DISK_CLOSE:
PUSH BX ; save registers
PUSH CX
PUSH DX
MOV b$CLOS_FDB,SI ; mark that we are closing a file
; in case write prot error
MOV BX,FileDB.FD_HANDLE ; argument is file descriptor
TEST FileDB.FD_FLAGS,FL_CHAR ; is this a character dev?
JNZ CLOSE1 ; brif so -- do not do flushes
TEST FileDB.FD_MODE,MD_SQO OR MD_APP ; Seq. or append output ?
JZ CLOSE1 ; no, nothing to do
CALL B$FLUSH ; flush buffer if it contains data,
; and clear FD_BUFCNT
CALL B$FILESIZE ; seek to end of file before closing
CLOSE1:
CALL B$CLOSE ; close the file and
MOV b$CLOS_FDB,0 ; clear closing file flag
POP DX ; restore registers
POP CX
POP BX
JMP B$LHDALC_CPCT ; deallocate FDB, compact local heap,
; and return
SUBTTL file EOF
page
;***
;DISK_EOF -- detect if EOF
;
;Purpose:
; Return true (-1) if a end-of-file is encountered, otherwise returns
; false (0). This is only significant for a file opened for sequential
; input or for a communications file.
;
; A true (-1) for a communication file means the buffer is empty.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [AX] = 0 or -1
;Uses:
; none
;Preserves: (optional)
; all, except flags
;Exceptions:
; B$ERR_BFM -- bad file mode
;*******************************************************************************
cProc DISK_EOF,<NEAR>
cBegin
TEST FileDB.FD_MODE,MD_SQO+MD_APP ; output or append?
JNZ ERCBFM ; brif so -- bad file mode
MOV AX,-1 ;set to true (AX=-1)
TEST FileDB.FD_FLAGS,FL_NEOF ;bit set if not EOF
JZ DskEofExit ;Brif EOF
TEST FileDB.FD_MODE,MD_RND+MD_BIN ; random or binary?
JNZ Not_Eof ; Brif so -- just return flag value
PUSH AX ;save AX
cCall B$DISK_SINP ;]Get one char, on return [AL]=char
POP AX ;get back AX
JC DskEofExit ;Brif EOF
cCall DISK_BAKC ;backup over it (all register preserved)
Not_Eof:
INC AX ;set to false
DskEofExit: ;result in AX
cEnd ;exit
ERCBFM: JMP B$ERR_BFM
SUBTTL disk LOC
page
;***
;DISK_LOC -- file LOC
;
;Purpose:
; Returns current file position.
;
; For a disk file, LOC returns the last record number been referred.
; A record for a sequential file has 128 bytes. For a character device,
;
; NOTE: This routine takes the advantage of 128-byte record length of
; a sequential file. Should this be changed, the part, Div128,
; has to be changed to "call $div32".
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [DX|AX] = current location in the file
;Uses:
; Per Convention
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc DISK_LOC,<NEAR>
cBegin
CALL GetPosition ; get byte position for seq files
; and record number for random.
JNC LOCExit ; brif char device or random/binary
; Commented the subtraction out. With the ability to seek before the
; initial position, LOC could return a negative result. Also commented
; out code in DISK_OPEN.
; CMP FileDB.FD_MODE,MD_APP ; is it append ?
; JNE NotApp ; Brif not -- don't add initial pos.
; SUB AX,FileDB.FD_LOGREC ; subtract lower and upper words of
; SBB DX,FileDB.FD_HIGHLR ; initial position
; NotApp:
; divide result by 128
MOV CX,7 ;div 128 = shr 7
XOR BX,BX ;BX is for detect whether there is
; the remainder. CLEARS CARRY
RCRLoop: ;divide loop
RCR DX,1 ;rotate upper word one bit
RCR AX,1 ;rotate lower word one bit
RCR BX,1 ;BX is for detect whether there is
; the remainder
;NOTE: carry is reset
LOOP RCRLoop ;loop until done
; The below code needed for compatability reasons. What a waste!
CMP FileDB.FD_MODE,MD_SQI ;is input ? (input is pre-read)
JNZ LOCExit ;Brif not
OR BX,BX ;has partial block ?
JZ TestZero ;Brif not
ADD AX,1 ;include partial block
ADC DX,0
JMP SHORT LOCExit ;exit to caller
TestZero: ;test if LOC is 0
OR BX,DX ;give one if result is zero
OR BX,AX
JNZ LOCExit ;Brif already nonzero
INC AX ;set LOC result to 1
LOCExit:
cEnd ;exit to caller
SUBTTL disk seek supporting routines
page
;***
; GetPosition -- get current byte-position/record number in file.
;
;Purpose:
; Return current byte position for sequential files, or current
; record number for random/binary files.
;
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [DX|AX] = current location in the file
; Carry set if Sequential file and not FL_CHAR
; Carry clear otherwise
;Uses:
; Per Convention
;
;Preserves:
;
;Exceptions:
; B$ERR_BRN -- bad record number
;
;******************************************************************************
cProc GetPosition,<NEAR>
cBegin
TEST FileDB.FD_MODE,MD_RND+MD_BIN ; random or binary?
JNZ RndPosition ; Brif so
MOV AX,1 ; assume LOC = 1
XOR DX,DX
TEST FileDB.FD_FLAGS,FL_CHAR ; is character device ?
JNZ NotSeqFile ; Brif yes -- Exit with LOC = 1
CALL GetFilePos ; [DX|AX] = position
TEST FileDB.FD_MODE,MD_SQI ; mode = input?
JZ OutputMode ; brif not -- just add count
SUB AX,FileDB.FD_INBUFCNT ; subtract # chars placed in
SBB DX,0 ; buffer by last disk read
OutputMode:
ADD AX,FileDB.FD_BUFCNT ; add # read/unwritten chars in
ADC DX,0 ; buffer to get current position
STC ; set carry for test in DISK_LOC
JNS GetPosExit ; exit
JMP B$ERR_BRN ; brif overflow -- bad record number
RndPosition:
MOV AX,FileDB.FD_LOGREC ; get lower word
MOV DX,FileDB.FD_HIGHLR ; get upper word
TEST FileDB.FD_FLAGS,FL_CHAR ; is character device ?
JZ NotSeqFile ; Brif not -- clear carry and exit
XCHG AX,CX ; CX = FD_LOGREC
MOV AX,FileDB.FD_VRECL ; record length
CALL B$MUL32 ; [DX|CX]=[DX|CX]*[AX]
XCHG AX,CX ; [DX|AX]=result
NotSeqFile:
CLC ; clear carry for test in DISK_LOC
GetPosExit: ;exit with flags set
cEnd
SUBTTL disk SEEK
page
;***
; B$FSEK -- get current byte offset into file. Added with revision [19].
;
;Purpose:
; Return the current record number (1-relative). Sequential files
; and BINARY files are considered to have a record length of 1.
;Entry:
; None
;Exit:
; [DX|AX] = 1-relative current record number or byte ofset for the
; next operation.
; 0 for non-disk devices.
;Uses:
; Per convention
;Preserves:
;
;Exceptions:
;
;******************************************************************************
cProc B$FSEK,<FAR,PUBLIC>,<SI>
parmW FileNum ; file number
cBegin
MOV BX,FileNum ; BX = file number
XOR AX,AX ; assume zero value
XOR DX,DX
CALL SeekCommon ;(ES:)[SI] = FDB, do error checking
JNZ FSeekExit ; brif not disk -- exit with value = 0.
CALL GetPosition ; [DX|AX] = current record number
; or byte offset for sequential files
ADD AX,1 ; make 1-relative
ADC DX,0
FSeekExit:
cEnd
;***
; B$SSEK -- Seek to a record in file. Added with revision [19].
;
;Purpose:
;
;Entry:
; None
;Exit:
; FL_NEOF bit of FD_FLAGS set appropriately
;Uses:
; Per convention
;Preserves:
;
;Exceptions:
; B$ERR_BRN -- Bad record number
;
;******************************************************************************
cProc B$SSEK,<FAR,PUBLIC>,<SI>
parmW FileNum ; file number
parmD RecNum ; record number
cBegin
MOV BX,FileNum ; BX = file number
CALL SeekCommon ;(ES:)[SI] = FDB, do error checking
JNZ SSeekExit ; brif not disk -- exit without doing anything
TEST FileDB.FD_FLAGS,FL_CHAR ; char device?
JNZ SSeekExit ; brif so -- exit without doing anything
TEST FileDB.FD_MODE,MD_SQO+MD_APP ; output or append?
JZ NoFlush ; brif not -- don't flush buffer
CALL B$FLUSH ; flush buffer if it contains data
NoFlush:
TEST FileDB.FD_MODE,MD_SQI ; input?
JZ DoSeek ; brif not -- don't touch count
MOV WORD PTR FileDB.FD_INBUFCNT,0 ; clear input buffer count
DoSeek:
MOV CX,off_RecNum ; low word of record number/byte offset
MOV DX,seg_RecNum ; high word of record number/byte offset
MOV AL,RELFLG ; tell Locate record number is specified
CALL Locate ; translate record # to 0-relative byte offset
; in [DX|CX]
CALL B$SeekFromStart ; seek from start of file, and check for error
OR FileDB.FD_FLAGS,FL_NEOF ; assume no EOF after seek
SSeekExit:
cEnd
ERCBRN2: JMP B$ERR_BRN ; bad record number
;***
; SeekCommon -- Common routine used by B$SSEK and B$FSEK to save code.
;
;Purpose:
; Added with [19]
;
;Entry:
; BX = file number
;Exit:
; (ES:)[SI] = *FDB
; ZF if disk file -- NZ if non-disk device
;Uses:
; None
;Preserves:
; All
;Exceptions:
; B$ERR_IFN -- bad file number
;
;******************************************************************************
cProc SeekCommon,<NEAR>
cBegin
CALL B$LHFDBLOC ; SI = *FDB
JZ ERCIFN ; brif FDB not found -- bad file number
FDB_PTR ES,SI,SI ;get FDB ptr from handle in SI
CMP FileDB.FD_DEVICE,0 ; non-disk device?
cEnd
ERCIFN: JMP B$ERR_IFN
page
;***
;B$SeekFromStart -- seek from start of file to specified byte position
;
;Purpose:
; Set file position by seeking from the begining of the file with the
; offset given in [DX|CX]
;Entry:
; (ES:)[SI] = *FDB
; [DX|CX] = offset
;Exit:
; file position is set.
; [DX|AX] = file position
;Uses:
; Per convention
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc B$SeekFromStart,<PUBLIC,NEAR>
cBegin
XOR AX,AX ;seek from the begining of the file
JMP SHORT DosSeek ;do seek, and check for error
cEnd nogen ;exit via DosSeek
page
;***
;B$FILESIZE -- get file size
;
;Purpose:
; Get file size by seeking from the end of the file with offset 0.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; file position is set to EOF.
; [DX|AX] = file size
;Uses:
; Per convention
;Preserves:
; BX
;Exceptions:
; B$ERR_BRN -- bad record number
;*******************************************************************************
cProc B$FILESIZE,<PUBLIC,NEAR>
cBegin
MOV AX,2 ;seek to end + (zero) offset
JMP SHORT SeekZeroOffset
cEnd nogen ;exit via SeekZeroOffset
page
;***
;GetFilePos -- get file position
;
;Purpose:
; Get file position by seeking from the current position with offset 0.
;Entry:
; (ES:)[SI] = *FDB
;Exit:
; [DX|AX] = current file position
;Uses:
; Per convention
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -