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

📄 dkio.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;Preserves:
;	BX
;Exceptions:
;	B$ERR_BRN -- bad record number
;*******************************************************************************

cProc	GetFilePos,<NEAR>
cBegin
	MOV	AX,1		; ask for seek to current + (zero) offset
	SKIP	2		; skip over SeekToStart
cEnd	<nogen>			; fall into SeekZeroOffset


;***
;SeekToStart -- seek to start of file.  Added with [19].
;
;Purpose:
;	Seek from start of file with offset 0
;Entry:
;	(ES:)[SI]   = *FDB
;Exit:
;	file position is set to start of file.
;	[DX|AX] = start file position
;Uses:
;	Per convention
;Preserves:
;	BX
;Exceptions:
;	B$ERR_BRN -- bad record number
;*******************************************************************************

cProc	SeekToStart,<NEAR>
cBegin
	XOR	AX,AX		; seek from start
cEnd	<nogen>			; fall into SeekZeroOffset

;***
;SeekZeroOffset -- Do seek from offset zero.  Added with [19].
;
;Purpose:
;	Get file position by seeking with method in AX with offset 0.
;Entry:
;	(ES:)[SI]   = *FDB
;	AX = seek method (described in DosSeek)
;Exit:
;	[DX|AX] = current file position
;Uses:
;	Per convention
;Preserves:
;	BX
;Exceptions:
;	B$ERR_BRN -- bad record number
;*******************************************************************************

cProc	SeekZeroOffset,<NEAR>
cBegin
	XOR	CX,CX		; set offset to zero
	MOV	DX,CX
cEnd	<nogen>			; fall into DosSeek


;***
;DosSeek
;
;Purpose:
;	Seek to the location desired.
;Entry:
;	(ES:)[SI]   = *FDB
;	[DX|CX] = distance to move
;	[AX]	= seek method (0, 1 or 2)
;			0 = seek from start
;			1 = seek from current
;			2 = seek from end
;Exit:
;	If no error
;		[DX|AX] = has the result (seg:off)
;Uses:
;	Per convention
;
;Preserves:
;	BX
;Exceptions:
;	B$ERR_BRN -- bad record number
;
;*******************************************************************************

cProc	DosSeek,<NEAR>,<BX>
cBegin

	XCHG	CX,DX		; [CX|DX] = position
	CALLOS	LSeek,ERCBRN2,<FileDB.FD_HANDLE> 
	FDB_PTR ES		;refresh FDB SEG jic global memory moved

cEnd

	SUBTTL	disk LOF
	page
;***
;DISK_LOF -- length of the file
;
;Purpose:
;	Returns the length of the file.
;
;	If the file is a communications file, LOF returns the free spaces in
;	the buffer.
;Entry:
;	(ES:)[SI]   = *FDB
;Exit:
;	[DX|AX] = length of the file
;Uses:
;	none
;Exceptions:
;	B$ERR_BRN -- bad record number
;*******************************************************************************

cProc	DISK_LOF,<NEAR>

cBegin
	TEST	FileDB.FD_FLAGS,FL_CHAR ;is character device ?
	JNZ	CharDevLOF		;Brif yes
	TEST	FileDB.FD_MODE,MD_SQO OR MD_APP ; output or append?
	JZ	NotOutApp		; Brif not -- don't flush buffer
	CALL	B$FLUSH		; flush buffer if it contains data
					; (this MIGHT increase file size)
NotOutApp:
	CALL	GetFilePos 		; [DX|AX] = position
	PUSH	DX			; save current position
	PUSH	AX			
	cCall	B$FILESIZE		; get file size in [DX|AX]
	POP	CX			; CX = low word of current pos
	POP	BX			; BX = high word of current pos
	PUSH	DX			; save file size
	PUSH	AX			
	MOV	DX,BX			; [DX|CX] = original position
	CALL	B$SeekFromStart	; set file original position
	POP	AX			; get file size back
	POP	DX			

	JMP	SHORT LOFExit
CharDevLOF:
	MOV	AX,1		;non-random length is 1
	XOR	DX,DX
	TEST	FileDB.FD_MODE,MD_RND+MD_BIN ; random or binary?
	JE	LOFExit			; Brif not -- exit
	MOV	AX,FileDB.FD_FSIZ_LO	
	MOV	DX,FileDB.FD_FSIZ_HI	

LOFExit:
cEnd				;exit

	SUBTTL	disk WIDTH
	page
;***
;DISK_WIDTH -- set file width
;
;Purpose:
;	Set file width while the file is open.
;Entry:
;	(ES:)[SI]   = *FDB
;	[DL]	= file width
;Exit:
;	file width is set.
;Uses:
;	none
;Preserves: (optional)
;	all
;Exceptions:
;	none
;*******************************************************************************

cProc	DISK_WIDTH,<NEAR>

cBegin
	MOV	FileDB.FD_WIDTH,DL	;set file width
cEnd

	SUBTTL	get output position
	page
;***
;DISK_GPOS -- get output position
;
;Purpose:
;	Get current output position.
;Entry:
;	(ES:)[SI]   = *FDB
;Exit:
;	[AH]	= current output position
;Uses:
;	none
;Preserves: (optional)
;	all
;Exceptions:
;	none
;*******************************************************************************

cProc	DISK_GPOS,<NEAR>

cBegin
	MOV	AH,FileDB.FD_OUTPS	;get file output position
cEnd

	SUBTTL	get file width
	page
;***
;DISK_GWID -- get file width
;
;Purpose:
;	Get file width.
;Entry:
;	(ES:)[SI]   = *FDB
;Exit:
;	[AH]	= file width
;Uses:
;	none
;Preserves: (optional)
;	all
;Exceptions:
;	none
;*******************************************************************************

cProc	DISK_GWID,<NEAR>

cBegin
	MOV	AH,FileDB.FD_WIDTH	;get file width
cEnd

DISK_DWID	EQU	B$ERR_FC	; illegal funtion call error

	SUBTTL	disk serial input
	page
;***
;B$DISK_SINP --disk serial input
;B$IDISK_SINP -- Far (QB3) interface for disk serial input
;
;Purpose:
;	Input one character from disk.
;
;	This routine is terrible.  It has four exit points -- namely,
;
;	SetEofFlag -- when read null from disk, set flag and carry and exit
;	EofFlag    -- when an EOF character is read, or the EOF flag has been
;			set, set carry and exit
;	NotEofExit -- when a normal character is get, clear carry and exit
;	SinpExit   -- final exit point, just exit (usually the carry has been
;			processed and exit via this point)
;Entry:
;Exit:
;	[AL]	= char
;	[CX]	= 0 if EOF detected (B$IDISK_SINP only)
;	FDB deallocated and file closed if error and called from OPEN
;Uses:
;	none
;Preserves:
;	BX,CX,DX,DI
;Exceptions:
;	B$ERR_FWP -- permission denied
;	B$ERR_ACD -- path/file access error
;	B$ERR_FOV -- field overflow (from FovChk)
;*******************************************************************************

cProc	B$IDISK_SINP,<PUBLIC,FAR>,<SI> 

cBegin					
	FDB_PTR ES,SI,b$PTRFIL		;get FDB pointer
	DbAssertRel	SI,NE,0,DK_TEXT,<Invalid FDB ptr in B$IDISK_SINP> 
	OR	FileDB.FD_FLAGS,FL_BIN	; specify binary access (no ^Z EOF)
	cCall	B$DISK_SINP		;call disk seq input
	MOV	CX,0			; don't touch flags
	JC	BISINPExit		;brif end of file
	DEC	CX			;set CX non zero
BISINPExit:				
cEnd					


labelNP  DISK_SINP			
cProc	B$DISK_SINP,<PUBLIC,NEAR>,<BX,CX,DX,DI> ;save BX,CX,DX,DI

cBegin

	TEST	FileDB.FD_FLAGS,FL_NEOF ;had EOF encountered ?
	JZ	EofExit 		;Brif EOF

	CMP	FileDB.FD_MODE,MD_RND	
	JE	RndGetChar		;input from random

	LEA	DI,FileDB.FD_BUFFER	;DI=*buffer

	MOV	BX,FileDB.FD_BUFCNT	;BX = next unread char position
	CMP	BX,FileDB.FD_INBUFCNT	;any unread chars left ?
	JNE	GetOneChar		;Brif yes, go get it

	MOV	AL,NOT PUTFLG		;indicate read
	MOV	BX,FileDB.FD_VRECL	;length to be read

	PUSH	ES			;preserve ES
	PUSH	DS			;set ES=DS
	POP	ES			

	cCall	DosReadWrite		;fill one buffer, on return
					; if CY then error, & AX=error code
					; else AX has the actual read/write
					; bytes
	POP	ES			;recover ES
	JB	B$AnalyzeErr		; Brif error

	FDB_PTR ES			;freshen FDB seg
	OR	AX,AX			; is end-of-file ?
	JZ	SetEofFlag		;Brif yes, set FD_FLAGS

	MOV	FileDB.FD_INBUFCNT,AX	; set # bytes in input buffer
	XOR	BX,BX			; get from the begining of buffer
	MOV	FileDB.FD_BUFCNT,BX	; # read bytes in buffer = 0

GetOneChar:
	MOV	AL,FileDB.FD_BUFFER[BX] ;get byte from buffer[BX]
	INC	FileDB.FD_BUFCNT	;one less in the buffer

	TEST	FileDB.FD_FLAGS,FL_CHAR+FL_BIN ;EOF is nonsensical for char
					; devices or binary files
	JNZ	SinpExit		;Brif yes (exit with NC)
	CMP	AL,EOFCHR		;is EOF char ?
	JNZ	NotEofExit		;exit

	cCall	DISK_BAKC		;backup to keep EOF

SetEofFlag:
	AND	FileDB.FD_FLAGS,NOT FL_NEOF ;set EOF flag
EofExit:				;EOF encountered
	MOV	AL,EOFCHR		;return EOF character
	STC				;set carry
	JMP	SHORT SinpExit		;exit

RndGetChar:				;input from random file
	CALL	FovChk			;field overflow check, on return
					; BX has the current offset
	MOV	AL,FileDB.FD_BUFFER[BX-1] ;get character
NotEofExit:				;clear carry and exit
	CLC				;clear carry

SinpExit:
cEnd					; pop bx,di, and exit

	PAGE
;*** 
; B$AnalyzeErr, B$OpenErr -- analyze error code, and give proper error.
;
;Purpose:
;	Save some code and standardize error reporting by file I/O routines.
;Entry:
;	AX = error code from DosReadWrite
;	For B$AnalyzeErr, SI = *FDB (or 0 if no FDB)
;Exit:
;	None
;Uses:
;	None
;
;Exceptions:
;	B$ERR_IOE -- device I/O error
;	B$ERR_FWP -- permission denied
;	B$ERR_ACD -- path/file access error
;
;******************************************************************************
cProc	B$AnalyzeErr,<NEAR>		
cBegin

	OR	SI,SI			; valid FDB?
	JZ	B$OpenErr		; brif not
	FDB_PTR ES			; restore FDB SEG in ES
	TEST	FileDB.FD_FLAGS,FL_CHAR ; char device ?
	PUSHF				; save this test
	CALL	B$TEST_CLOSE		; if closing flag set, close file
					; and deallocate FDB
	POPF				; char device?
	JNZ	DeviceIOError		; brif so -- device I/O error

labelNP	<PUBLIC,B$OpenErr>		

	cCall	B$GETEXTERR		; ZF if DOS 3 and sharing/locking error
	JNZ	PathAccessError		; brif not (DOS 3 and sharing/locking)

PermissionDenied:
	JMP	B$ERR_FWP		; Permission denied error
PathAccessError:
	JMP	B$ERR_ACD		; Path/File access error
DeviceIOError:
	JMP	B$ERR_IOE		; device I/O error

cEnd	<nogen>			; nothing leaves from here


;***
;FovChk -- field overflow check
;
;Purpose:
;	Check whether the field is overflow.
;Entry:
;	(ES:)[SI]   = *FDB
;Exit:
;	[BX]	= updated position in the buffer
;Uses:
;	none
;Exceptions:
;	B$ERR_FOV -- field overflow
;*******************************************************************************

cProc	FovChk,<NEAR>

cBegin
	MOV	BX,FileDB.FD_BUFCNT	;get current position
	CMP	BX,FileDB.FD_VRECL	;check for end of record
	JE	ERCFOV			;Yes - field overflow
	INC	BX			;bump pointer
	MOV	FileDB.FD_BUFCNT,BX	;update position
cEnd					;exit

ERCFOV:
	MOV	AX,B$ENTRY_BUFCNT	; Restoring the buffer position
	MOV	FileDB.FD_BUFCNT,AX	; to what it was before execution
					; of current statement

	JMP	B$ERR_FOV		; Field Over Flow Error
	page

;*** 
; B$CHK_WRITE -- Check to see that we got what we requested.
;		Added as part of [20].
;
;Purpose:
;
;Entry:
;	(ES:)[SI]   = *FDB
;
;Exit:
;	None
;Uses:
;	Flags
;
;Preserves:
;	All
;
;Exceptions:
;	B$ERR_DFL -- disk full
;	B$ERR_IOE -- I/O error
;
;******************************************************************************
cProc	B$CHK_WRITE,<NEAR>		
cBegin
	CMP	AX,CX			; bytes written the same as required ?
	JE	GotAll			; Brif yes -- no error

;	Check for DOS 2.0 bug when writing to CONOUT.  DOS 2.0 reports
;	n-1 bytes written when requested to write n bytes to CON when
;	CON is in raw mode.

	TEST	FileDB.FD_FLAGS,FL_CONOUT ; Is this CON OUT?
	JZ	Shortchanged		; brif not -- error
	PUSH	AX			; save return count
	INC	AX			; Add one to count
	CMP	AX,CX			; did DOS report 1 less requested count?
	POP	AX			; restore register
	JE	GotAll			; Brif so -- no error

Shortchanged:
	TEST	FileDB.FD_FLAGS,FL_CHAR ; char device?
	PUSHF				; save this test
	MOV	b$CLOS_FDB,SI		; make B$TEST_CLOSE close file
	CALL	B$TEST_CLOSE		; close file with NO ERROR CHECKING,
					; and deallocate FDB
	POPF				; was it a char device?
	JNZ	DeviceIOError		; brif so -- I/O error
	JMP	B$ERR_DFL		; give disk full error

GotAll:
cEnd

	SUBTTL	disk serial output
	page
;***
;DISK_SOUT -- disk serial output
;
;Purpose:
;	Output one char to a file.
;Entry:
;	(ES:)[SI]   = *FDB
;	[AL]	= character
;Exit:
;	none
;Uses:
;	none
;Preserves:
;	BX
;Exceptions:
;	B$ERR_FOV -- field overflow (from FovChk)
;*******************************************************************************

;***
;B$UpdateOUTPS - Update the OUTPS field of a FDB
;
;Purpose:
;	This shared code correctly sets the OUTPS field of a FDB for
;	a new character that is entered into the output buffer.
;
;Entry:
;	AL - character being entered into FDB output buffer
;	(ES:)[SI]   = *FDB
;
;Exit:
;	FileDB.FD_OUTPS set properly
;
;Uses:
;	Flags.
;
;Preserves:
;	None.
;
;Exceptions:
;	None.
;*******************************************************************************

DbPub	DISK_SOUT
cProc	DISK_SOUT,<NEAR>

cBegin
	CMP	FileDB.FD_MODE,MD_RND	
	JE	RndWrtChar	;serial output to random


	TEST	FileDB.FD_FLAGS,FL_CHAR ;can't write EOF char to a char device
	JZ	NotCharDev
	CMP	AL,EOFCHR		;is EOF char ?
	JE	SoutExit		;Brif yes, exit
NotCharDev:
	PUSH	BX			; save BX
	MOV	BX,FileDB.FD_BUFCNT	;# in buffer
	CMP	BX,FileDB.FD_VRECL	;is full ?
	JB	BufferReady		;Brif not, no flush buffer
	PUSH	CX			; B$FLUSH destroys CX
	CALL	B$FLUSH		; flush the buffer
	POP	CX			
	XOR	BX,BX			; new offset into buffer is 0
	; prior to this change, the buffer was cleared with ClearBuffer
	; each flush.  This should not be needed for output files.

BufferReady:
	MOV	FileDB.FD_BUFFER[BX],AL ;store char in buffer
	INC	FileDB.FD_BUFCNT	;update buffer count
	JMP	SHORT UpdateCurloc	

RndWrtChar:				;serial output to random file
	PUSH	BX			; save BX
	cCall	FovChk			;check for field overflow, on return
					; BX is the updated buffer offset
	MOV	FileDB.FD_BUFFER[BX-1],AL   ;store character

UpdateCurloc:
	POP	BX			; get back BX


	CMP	AL,NEWLINE		;is new line ?
	JNZ	UpdateOutpos		;Brif not
	MOV	FileDB.FD_OUTPS,0	;zero position
	JMP	SHORT SoutExit		;exit

UpdateOutpos:				;update current location
	CMP	AL,' '			;is printable character ?
					; (NC if yes)
	CMC				;reverse the carry

⌨️ 快捷键说明

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