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

📄 filename.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	INC	DI		; pretend there's another "\" on the end
	CALL	PROCESS_SLASH	; and process as if there is a slash char,
				; removing the dots.
CheckDir:			
	CMP	DL,SLASH_SEEN	; does it end with a '\'?
	JNE	ADD_NULL	; brif not -- just add the null byte
	OR	DH,FN_IS_DIR	; set directory flag so B$ADD_EXT won't
				; try to add an extension to directory name
ADD_NULL:
	XCHG	AX,CX		; set AX = 0, since CX will always = 0 here
	STOSB			; store terminating null byte

; complete null-terminated pathname without "\." or "\.." is now in buffer.

	MOV	CX,DI		; one past the last position (past null byte)
	POP	DI		; restore DI to point to the processed pathname
	SUB	CX,DI		; and set CX to the count of chars in pathname
				; (including the null)
	MOV	AL,DH		; return flags in AL
cEnd

ERBFN:				; centrally located
	jmp	B$ERR_BFN	; give bad filename error

CHK_BAD_CHAR:		; Check if char is a valid filename character.
	CMP	AL,' '		; control character?
	JB	ERBFN		; brif so -- bad filename

			; search table of invalid chars for current char
	PUSH	DI		; save registers
	PUSH	CX		
	MOV	DI,OFFSET DGROUP:BAD_CHAR_TBL ; table to search
	MOV	CX,b$BadCharCnt ; number of chars to search (changes)
	REPNE	SCASB		; search for char in table
	JZ	ERBFN		; brif char found -- bad filename
	POP	CX		; restore registers
	POP	DI		
	JMP	VALID_CHAR	; valid char -- continue processing





;*** 
;PROCESS_SLASH -- perform processing for a "\" in the pathname
;
;Purpose:
;	Eliminates "\.\" and "\dir\..\" from pathname string, and checks
;	for underflow (".." at the root directory level).
;
;Entry: (same conditions as within pathname processing loop)
;	ES:DI = pointer to next char in processed pathname
;	DH    = flags:
;		    FN_WILD -- name portion of pathname contains a wildcard
;		    FN_HAS_EXT -- name portion of pathname has extension
;	DL    = last char(s) flag:
;		    SLASH_SEEN	    -- last char in path is "\"
;		    SLASHDOT_SEEN   -- last chars in path are "\."
;		    SLASHDOTDOT_SEEN - last chars in path are "\.."
;Exit:
;	DI updated
;	DH = NOT FN_WILD and NOT FN_HAS_EXT
;	DL = SLASH_SEEN
;	b$PN_NAME = address of last "\" in pathname.
;
;Uses:
;	AL
;
;Preserves:
;
;Exceptions:
;	Bad File Name
;
;******************************************************************************
PROCESS_SLASH:			;Transform "\.\" or "\dir_name\..\" to "\"
	CMP	DL,SLASHDOT_SEEN ; seen "\.\"?
	JNE	CHK_SLASHDOTDOT	; brif not -- check for "\..\"
	DEC	DI		; remove the last "\"
	DEC	DI		; remove the "."
	JMP	SHORT SLASH_END	; indicate slash char seen

CHK_SLASHDOTDOT:
	CMP	DL,SLASHDOTDOT_SEEN ; seen "\..\"?
	JNE	SLASH_END	; brif not -- indicate slash char seen
	SUB	DI,4		; get rid of the "\..\"
				; [DI] = addr of the first "\"

REMOVE_SLASHES:
	DEC	DI		; remove another char
	MOV	AL,[DI]		; get deleted char
	CALL	CHK_FOR_SLASH	; just removed a previous "\"?
	JE	REMOVE_SLASHES	; remove another char

	CMP	DI,FIRST_SLASH	; have we deleted the first "\"?
	JB	ERBFN		; brif so -- underflow -- too many "\..\"'s
REMOVE_NAME:
	DEC	DI		; remove another char of the name
	MOV	AL,[DI]		; get deleted char
	CALL	CHK_FOR_SLASH	; just removed a previous "\"?
	JNE	REMOVE_NAME	; brif not -- delete another character
	INC	DI		; put back the last "\"

SLASH_END:
	MOV	DX,SLASH_SEEN	; indicate slash character seen, no wildcards,
				; and no extension
	MOV	b$PN_NAME,DI	; set address of name.ext in pathname
	RET			; return to caller


;*** 
; CHK_FOR_SLASH -- check if char is "\" or "/"
;
;Purpose:
;	Since we're to allow both forward and backwards slashes in the
;	pathname, check if char is "\" or "/".  Extracted to save code.
;
;Entry:
;	AL = char to check.
;Exit:
;	ZF if AL = "\" or "/", NZ otherwise.
;Uses:
;	None
;Preserves:
;	All
;Exceptions:
;	None
;
;******************************************************************************
CHK_FOR_SLASH:			; check for forward slash and back slash
	CMP	AL,'\'		; is it a back slash?
	JE	CHK_SLASH_EXIT	; brif so -- return to caller
	CMP	AL,'/'		; is it a forward slash?
CHK_SLASH_EXIT:
	RET			; return to caller


;*** 
; B$ADD_EXT -- add extension to pathname
;
;Purpose:
;	Adds a 4-byte extension to a name, updating the count and checking
;	for overflow.  It first checks to see that there is not already an
;	extension on the last name of the file.
;
;Entry:
;	ES:DI = address of null-terminated pathname to append extension to
;	CX = index into the pathname of the char past the char to overwrite
;		(usually the pathname length returned from B$GET_PATHNAME)
;	DS:SI = address of 4-bytes to be appended to name
;	AL = flags returned from B$GET_PATHNAME
;
;Exit:
;	if not already an extension
;	    extension appended to name at ES:DI
;	    CX = new length of name (INCLUDING the NULL)
;
;Uses:
;	SI,AX
;
;Preserves:
;	BX,DX
;
;Exceptions:
;	Bad file name
;
;******************************************************************************
cProc	B$ADD_EXT,<NEAR,PUBLIC>,<DI>
cBegin

	TEST	AL,FN_HAS_EXT or FN_IS_DIR ; does the filename already have
				; an extension (or end with a '\')?
	JNZ	NO_EXTENSION	; brif so -- don't add an extension

	DEC	CX		; CX = # chars w/o the null
	ADD	DI,CX		; set destination pointer to point to null byte

NextChar:			
	INC	cx		; advance count
	CMP	CX,FILNAML	; will we overflow with this char?
	JA	ERBFN		; brif so -- Bad file name error
	LODSB			; get char
	STOSB			; store it
	OR	AL,AL		; got the null yet?
	JNZ	NextChar	

NO_EXTENSION:
cEnd



;*** 
; B$GET_CUR_DRIVE -- get current drive letter and number
;
;Purpose:
;
;	get current drive number (1-26) and letter (A-Z) from DOS
;
;Entry:
;	none
;
;Exit:
;	AL    = current drive letter (A-Z)
;	AH    = ':'
;
;Uses:
;	DX
;
;Preserves:
;	BX,CX
;
;Exceptions:
;	None
;
;******************************************************************************
cProc	B$GET_CUR_DRIVE,<NEAR,PUBLIC>
cBegin

	CALLOS	GDRV		; AL = default drive  (A=0, B=1, etc)
	CBW			; clear high byte
	ADD	AX,':' SHL 8 + 'A' ; return drive letter in AL and ':' in AH

cEnd


;*** 
; B$GET_CUR_DIR -- return current directory for a given drive number.
;
;Purpose:
;
;Algorithm:
;	Add "\" to string
;	Get current directory from DOS into string
;
;Entry:
;	ES:DI = address of area to place current directory
;	DX = drive number (1-26)
;	ES=DS
;
;	Note: IF FV_FARSTR, DS is not necessarily DGROUP on entry.
;
;Exit:
;	current directory (null-terminated) loaded into buffer
;
;Uses:
;	AX,DX
;
;Preserves:
;	BX,CX
;
;Exceptions:
;	Device not available
;
;******************************************************************************
cProc	B$GET_CUR_DIR,<NEAR,PUBLIC>,<CX>
cBegin

	MOV	AL,'\'		; add a beginning "\"
	STOSB

	PUSH	SI		; save register
	MOV	SI,DI		; set SI to current location in buffer
	CALLOS	CURDIR,ERDNA	; load current directory into DS:SI
	POP	SI		; restore register
cEnd


ERDNA:
	jmp	B$ERR_DNA	; give Device unavailable error


;*** 
; B$GET_DEV_NUM
;
;Purpose:
;	Checks if the first 5 chars of a string are equal to some BASIC
;	device, and if so, returns the device number for that device.
;	Accepts names of the form "XXXX:yyyyyy" as a valid devices, and
;	copies the options string for valid devices into the specified buffer.
;
;Entry:
;	BX    = pointer to filename string descriptor
;
;Exit:
;	AL = device number if device, or 0 if not a valid BASIC device
;	FLAGS = result of "OR AL,AL"
;
;Uses:
;	None
;
;Preserves:
;	BX,CX,DX
;
;Exceptions:
;	none
;
;******************************************************************************

cProc	B$GET_DEV_NUM,<NEAR,PUBLIC>,<ES,SI,DI,CX>	
cBegin
	MOV	SI,[BX+2]	; [DS:SI] = pointer to string data
	CMP	WORD PTR [BX],5	; length < 5?
	JB	NOT_DEV		; brif so -- not a valid BASIC device
	CMP	BYTE PTR [SI+4],':' ; name of the form "xxxx:" ?
	JNZ	NOT_DEV		; brif not -- not a BASIC device

; No checks will need to be done for KANJI characters, because there are
; none in our tables.  The call to B$UPCASE will not matter, as it can not
; do anything to make a match succeed. (The first byte of a KANJI character
; will not be converted, nor will it be in the table.)

	MOV	DI,OFFSET DEVICE_NAME_TABLE
	PUSH	CS		; set ES = CS for table reference
	POP	ES

DEV_LOOP:			; for each device in table
	CMP	BYTE PTR ES:[DI],0 ; end of table?
	JZ	NOT_DEV		; brif so -- not a valid BASIC device
	PUSH	SI		; save start of name
	MOV	CX,4		; compare 4 chars
CMP_LOOP:
	LODSB			; get character from the name into AL
	CALL	B$UPCASE	; convert to upper case
	SCASB			; does it match char in the device table?
	JE	NEXT_CHAR	; brif so -- try next char
	ADD	DI,CX		; skip over remaining chars and dev # in table
	POP	SI		; retrieve start of name
	JMP	SHORT DEV_LOOP	; and try to match the next entry
NEXT_CHAR:
	LOOP	CMP_LOOP	; falls through if device matched

	POP	SI		; clean off stack
	MOV	AL,ES:[DI]	; return device number in AL
	OR	AL,AL		; set flags for calling routine
	JMP	SHORT DEV_EXIT
NOT_DEV:
	XOR	AL,AL		; not a device -- clear AL and flags
DEV_EXIT:
cEnd

sEnd	DK_TEXT
	END

⌨️ 快捷键说明

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