⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dkio.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	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	
sEnd;_BSS

	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
	JS	ERCBRN2		; brif overflow -- bad record number
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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -