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

📄 dkstmt.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;Uses:
;	AX,CX,DX
;
;Preserves:
;
;Exceptions:
;
;******************************************************************************
Search:				
	mov	cx,ATTR_SUBDIR	; Search attributes
	SKIP	2		; eat the XOR and fall into common code

cProc	SearchNoDir,<NEAR>	; no directory
cBegin				
	xor	cx,cx		;no search attributes (files only)

	MOV	DX,OFFSET DGROUP:b$PATHNAM2 
	CALLOS	BUFF		;Set buffer address
	MOV	DX,OFFSET DGROUP:b$PATHNAM ; Address of pathname to search
	CALLOS	FINDF		; Use new one
	JC	ERCFNF2		; brif error -- file not found
cEnd				

	SUBTTL	B$REST - Reset statement
	PAGE
;***
; B$REST - Reset statement
;
;Purpose:
; Runtime entry. Close all open files.
;
;******************************************************************************
cProc	B$REST,<FAR,PUBLIC,FORCEFRAME> 
cBegin
	CALL	B$CLOSF		;Close all files

	CALLOS	GDRV		;Get drive number
	PUSH	AX
	CALLOS	REST		;Restore
	POP	AX
	MOV	DL,AL
	CALLOS	SDRV		;Set drive number

cEnd				

	SUBTTL	FILE interface
	page
newlin: 			;moved here from below
	CALL	B$TTY_GPOS
	XCHG	AL,AH
	ADD	AL,18		;Position after next file name
	CALL	B$TTY_GWID
	CMP	AL,AH
	RET


;***
;B$FILS - FILES Statement
;
;Purpose:
; Print a listing of all files in the current directory, which match the given
; string pattern
;
;Input:
; fname = filename sd
;
;Output:
; None
;
;Modifies:
; Per convention
;
;Exceptions:
; Control could be transfered to error code, such as B$ERR_FNF
;
;******************************************************************************
cProc	B$FILS,<FAR,PUBLIC>,<ES,DI,SI> 
parmW	fname
cBegin


	PUSH	DS		; set ES=DS for string operations
	POP	ES		
	MOV	BX,fname
	MOV	DI,OFFSET DGROUP:b$PATHNAM 
	call	B$GET_PATHNAME	; convert to standard pathname format
	CALL	B$STDALCTMP	;delete string if temp

	PUSH	DI		; save pathname buffer address
	
	MOV	AX,[DI]		; load drive letter and colon into AX
	MOV	DI,OFFSET DGROUP:b$PATHNAM2 ; buffer for current directory
	PUSH	DI		; save buffer address (for printing)
	STOSW			; store drive letter and ":" into buffer
	SUB	AX,':' SHL 8 + 'A' - 1 ; convert AX to drive number (1-26)
	XCHG	AX,DX		; DX = drive number

	CALL	B$GET_CUR_DIR 	; store current directory path for this
				; drive into buffer, after the drive letter

	; print the current directory for specified drive
	POP	AX		; AX = buffer offset
	PUSH	DX		; save drive number
	MOV	DX,DS		; DX = buffer segment
	CALL	B$PUTS		; print the null-terminated buffer
	CALL	B$$TCR		; print a CR

	; add "*.*" to the pathname if necessary
				; CX and DX preserved from above
	POP	DX		; restore drive number
	POP	DI		; restore pathname buffer address
	PUSH	DX		; save drive number for free space check
	ADD	DI,CX		; one past null byte
	DEC	DI		; DI = address of null byte
	CMP	DI,b$PN_NAME	; does pathname end with a "\"?
	JNZ	NO_ADD_EXT	; brif not -- don't add the extention
	MOV	AX,".*"		; add "*." to the pathname
	STOSW			
	MOV	AX,"*"		; add "*0" to the pathname
	STOSW			

NO_ADD_EXT:			

	CALL	Search		; search for first file with this name
				; or give "file not found"
d2off:
	mov	si,offset dgroup:b$PATHNAM2+30 ; name
	mov	cx,8
	mov	dx,"."
	call	outnam
	mov	cx,4
	xor	dx,dx
	call	outnam
	mov	si,offset dgroup:b$EightSpaces	
	cmp	byte ptr b$PATHNAM2+21,ATTR_SUBDIR ; check for directory attr
	jne	d2space
	mov	si,offset dgroup:DirStr
d2space:
	mov	cx,6		; print 6 chars
	CALL	B$OUTCNT		; print CX bytes

	call	newlin
	jl	findn
	call	B$$TCR
findn:
	callos	findn
	jnb	d2off

	CALL	B$$TCR		; list of files done -- output a CR
	POP	DX		; get back drive number
	CALLOS	FREES		;get disk free space
	mul	cx		;[ax]=bytes/sect*sect/alloc
	mul	bx		;[dxax]=[ax]*free alloc units
	PUSH	DX		; pass the I4
	PUSH	AX		
	call	B$PSI4		; and output that
	MOV	AX,MS_BYTESFREE ;output "Bytes free"
	cCall	B$PUTNUM	;output the message


cEnd				

outnam:
	mov	al," "
	cmp	byte ptr[si],dh ;end of string?
	je	atend
	cmp	byte ptr[si],dl ;possible end of name
	je	atend
	lodsb
atend:
	call	B$$WCHT		;write char
	loop	outnam
	ret

	page

	SUBTTL	LOCK/UNLOCK interfaces
	page

ERCFNF: JMP	B$ERR_FNF	;file not found
ERCAFE: JMP	B$ERR_AFE	;advanced feature

;***
;B$LOCK -- LOCK/UNLOCK statement interface
;void B$LOCK (I2 channel, I4 first_rec, I4 last_rec, U2 mode)
;
;Purpose:
;	Lock or unlock an opened file according to the value of mode.  The
;	file must be opened using the new OPEN syntax with the lock clause,
;	and DOS version must be 3.0 or above;otherwise a runtime error will
;	occur.	Between 2.0 and 3.0, the range of record number is slightly
;	different.  In 2.0, a 24-bit record number is supported, whereas a
;	31-bit record number is supported.
;
;	Note: BASICA 3.2 supports 32-bit record number.
;
;	BASCOM 2.0 uses two separate interfaces, $ULK & $LK0, for UNLOCK and
;	LOCK statement respectively.  In BASCOM 3.0, a single interface is
;	used with mode containing valuable information. The beauty of the mode
;	is that the first bit tells whether it is a lock or an unlock, and the
;	second bit tells whether it is to lock/unlock the whole file or not.
;
;	The syntax for LOCK/UNLOCK is as follows:
;	LOCK/UNLOCK [#]channel [,[first-rec] [TO last-rec]]
;
;	B$CHAN WILL NOT be called prior to B$LOCK, this routine has to
;	check the file is opened or not.
;
;	The 'first-rec' is the 'from' record # and 'last-rec' is the 'to'
;	record #.  The default 'first-rec' is 1 and the default 'last-rec'
;	is the same record number as the 'first-rec.'  For example,
;	"LOCK #1, TO 3" will generate first=1, last=3 & mode=2, and
;	"UNLOCK #1, 5" will generate first=5, last=5 & mode=3.
;
;	NOTE: Currently, record number is only meaningful to the random file.
;		Sequential file is always lock/unlocked the whole file, and
;		there is no range check of 'first-rec' or 'last-rec' for a
;		sequential file.  (the compiler or the interpreter parser
;		does check whether the parameter is a numerical type.)
;
;	The low order byte of mode may contain the following values according
;	to different situations (the high order word should wlays be IGNORED,
;	as the interpeter uses it):
;
;	mode = 0 -- lock entire file
;	mode = 2 -- lock from first to last
;
;	mode = 1 -- unlock entire file
;	mode = 3 -- unlock from first to last
;
;	The reason is illustrated as the following bit map.
;	mode:
;		_________________________________
;		| 0 | 0 | 0 | 0 | 0 | 0 | X | Y |
;		---------------------------------
;		MSB				LSB
;	where:
;	X is used to represent whether to lock/unlock the whole file, and
;	Y is used to decide whether it is a lock or is an unlock.
;
;	The runtime may then use one AND, instead of one AND & one SHR, before
;	call DOS lock/unlock function. (The value needed in AL is 0 for lock
;	and 1 for unlock.  Refer to the next paragraph.)
;
;	The DOS function call for lock/unlock a file needs:
;	[AH]	=	5CH
;	[AL]	=	0	-- lock
;			1	-- unlock
;	[BX]	=	file handle
;	[CX]	=	offset high
;	[DX]	=	offset low
;	[SI]	=	length high
;	[DI]	=	length low
;Entry:
;	Parameters are pushed in stack
;	int		channel
;	long int	first_rec
;	long int	last_rec
;	ushort		mode
;Exit:
;	none
;Uses:
;	none
;Exceptions:
;
;*******************************************************************************

cProc	B$LOCK,<PUBLIC,FAR>,<SI,DI>	;push di,si
	ParmW	Channel 	;I2 file number
	ParmD	First		;I4 first record number
	ParmD	Last		;I4 last record number
	ParmW	Mode		;U2 mode
cBegin				;set up stack frame
	cCall	B$DOS3CHECK	;must be DOS 3.0 or above
	JB	ERCAFE		;Brif not, give "advanced feature"
	MOV	BX,Channel	;get file number
	CALL	B$LHFDBLOC	;NZ then SI has the pointer to FDB
	JZ	ERCIFN		; Brif not, give "bad file number"
	FDB_PTR ES,SI,SI	;(ES:)[SI] = *FDB
	MOV	BX,FileDB.FD_HANDLE ; get file handle in BX
	PUSH	BX		;save file handle
	TEST	Mode,LOCK_1stToLast ; test the "entire file" bit
	JZ	LockEntire	; jump if we want to lock it all
	TEST	FileDB.FD_MODE,MD_RND+MD_BIN	
				; is opened for random or binary ?
	JNZ	 LockOffset	; Brif yes, record number is meaningful

LockEntire:			
	XOR	CX,CX		;starting record
	MOV	DX,CX		;(0-relative)
	MOV	SI,CX		;offset
	DEC	SI		;SI=0FFFFh
	MOV	DI,SI		;lock the whole file
	JMP	SHORT LockFile	;go lock it
ERCIFN: JMP	B$ERR_IFN	; bad file number
LockOffset:
	MOV	CX,Off_First	; get first record number low
	MOV	DX,Seg_First	; get first record number high
	OR	DX,DX		; negative number?
	JS	ERCBRN		; Brif yes, give "bad record number"
	SUB	CX,1		;decrement one, set carry if not big enough
	SBB	DX,0		;if CY ([DX|CX] = 0), then give error
	PUSH	CX		;save 0-relative first rec# low
	PUSH	DX		;save 0-relative first rec# high
	JB	ERCBRN		;give "bad record number"
	MOV	AX,CX		;get a copy of rec# low
	OR	AX,DX		;is 0 ?
	MOV	AX,FileDB.FD_VRECL ; [AX] = multiplicant (also used below)
	JZ	LockLen 	;Brif yes, no translate needed, to get length

	PUSH	AX		;save multiplicand
	cCall	B$MUL32	;[DX|CX]=[DX|CX]*[AX], if CY then overflow
				; generates Bad record number on overflow
	POP	AX		
LockLen:
	POP	SI		;get first 0-relative first rec# high
	POP	DI		;get first 0-relative first rec# low
	PUSH	CX		;push low offset
	PUSH	DX		;push high offset
	MOV	CX,Off_Last	; get Second record number low
	MOV	DX,Seg_Last	; get Second record number high
	MOV	BX,CX		
	OR	BX,DX		; Make sure non-zero
	JZ	ERCBRN		
	OR	DX,DX		; negative number?
	JS	ERCBRN		; Brif yes, give "bad record number"
	SUB	CX,DI		;calculate how many records
	SBB	DX,SI		;[DX|CX]= second# - (first# - 1)
	JB	ERCBRN		; Brif second > first, give bad record num
				; [AX] = multiplicant, set up above...
	cCall	B$MUL32	;[DX|CX]=[DX|CX]*[AX], if CY then overflow
				; generates Bad record number on overflow
	MOV	DI,CX		;DI=length low
	MOV	SI,DX		;SI=length high
	POP	CX		;CX=offset high
	POP	DX		;DX=offset low
LockFile:
	POP	BX		;get back file handle
	MOV	AX,Mode 	;get mode
	AND	AL,1		;lock or unlock
	CALLOS	LOCKING,ULKERR	;go lock it
cEnd				;pop si,di and exit to caller

ULKERR:
	CMP	AX,ERRIVH	;invalid handle ?
	JZ	ERCIFN		;bad file number
	JMP	B$ERR_FWP	;now "Permission Denied"
ERCBRN: JMP	B$ERR_BRN	; bad record number


cEnd

sEnd	DK_TEXT

	END

⌨️ 快捷键说明

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