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

📄 edit.asm

📁 random.zip 随机数产生器的汇编源代码 cmdsrc.zip 一个文本编辑器的汇编源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	dec	dx				;length of string is 2
	jmp	short @expand_fnkey_15
@expand_fnkey_10:
	sub	ax,84-59
@expand_fnkey_15:
	cmp	ax,9				;F10 must appear as F0
	jne	@expand_fnkey_20
	mov	al,'0'-'1'
@expand_fnkey_20:
	add	al,'1'
	mov	2[di],al			;Store in 'SFn' string
; OK now try and expand the symbol.
;						 SI->symbol
	mov	ax,LINEBUF_SIZE
	xchg	ax,dx				;AX<-length of synbol
;						 DX<-length of expansion buffer
	lea	di,exp_buf
	call	near ptr get_symbol		;Params SI,AX,DI,DX
	jc	@expand_fnkey_99		;No symbol (buffer too
;						 small case not possible).
;						 AX will be 0 for this case.
; OK now we have the symbol expansion, so try insert it into the linebuffer.
;	AX contains length of expansion
	mov	si,di				;SI->expansion
	add	di,ax
	dec	di				;DI->last char of expansion
	xor	dx,dx
	mov	dl,byte ptr [di]		
	sub	dl,fnkey_exec_char		;Is this line to be
;						 immediately executed
	jne	@expand_fnkey_80		;No
	dec	ax				;The last char of expansion
;						 is a special char. Do not
;						 include it in the insert
;						 string 
@expand_fnkey_80:
	push	dx
	call	near ptr insert_at_dot		;Params SI,AX
;	pushf					;Save CF
;	call	disp_line
;	popf					;Restore CF
	mov	ax,1				;AX<-exit code
	pop	dx				;DX is 0 if line is to be
;						 executed immediately
@expand_fnkey_99:
	mov	sp,bp
	pop	bp
	@restore
	ret

expand_fnkey endp


;+
; FUNCTION : store_char
;
;	Stores	the character in AX into the line buffer if max line
;	length will not be exceeded. Characters may be inserted or
;	overwrite chars in the buffer depending on the edit mode and whether
;	auto-recall is on.
;
; Parameters:
;	AX	= character
;
; Returns:
;	CF	= 0 if no error, else 1
; Register(s) destroyed:
; 	<TBA>
;-
store_char proc near
	@save	si
	cmp	ax,256			;char >= 256
	jnb	@store_char_90		;Ignore if so
	cmp	edit_mode,0		;1 if insert mode
	je	@store_char_20		;Jump if overtype mode
	cmp	auto_recall_on,1	;Is auto-recall on ?
	je	@store_char_20		;Yes, behave as if in overtype mode
	mov	si,offset dgroup:tempchar ;temporary storage
	mov	[si],al			;Store char
	mov	ax,1			;Length of string
	call	near ptr insert_at_dot	;Insert the character
	jnc	@store_char_99		;No problemo
	jmp	short @store_char_90	;No room in buffer
@store_char_20:
	mov	si,dot			;Current position in line
	cmp	si,LINEBUF_END		;At line end?
	jae	@store_char_90
;	Enough room for a char
	mov	[si],al			;Store the char
	mov	dx,si			;DX->changed character
	mov	ax,si
	inc	ax			;AX->char after change
	mov	dot,ax			;Store it as new dot position
	cmp	si,lastchar		;Was it end of line ?
	jb	@store_char_30
	mov	lastchar,ax		;Store new end of line
@store_char_30:
	call	near ptr set_disp_marks	;ax,dx parameters
	clc				;Indicate no error
	jmp	short @store_char_99
@store_char_90:
	call	near ptr bell
	stc				;Indicate error
@store_char_99:
	@restore
	ret
store_char endp


;+
; FUNCTION : word_left
;
;	Move one word left.
;
; Parameters:
;	Globals linebuf and dot.
;
; Returns:
;	CF = 1 if dot was at beginning of the line already
;	     0 otherwise.
; Register(s) destroyed:
;-
word_left proc near
@word_left_10:
	call	near ptr char_left	;Move one char left
	jc	@word_left_99		;Already at beginning of line
@word_left_12:
	;Loop to backup over non-alphanum
	call	near ptr isalphnum	;AL alphanumeric?
	jnc	@word_left_15		;Yes
	call	near ptr char_left	;One char left.
					;AL<-char at dot
	jnc	@word_left_12		;Not at beginning of line
@word_left_15:				;Now backup to beginning of word
;	At this point, dot is always at a alphabetic char or beginning
;	of the line
	call	near ptr char_left
	jc	@word_left_98		;Were already at beginning of line
	call	near ptr isalphnum	;Alphanumeric?
	jnc	@word_left_15		;Yes, loop back
					;Found non-alphanumeric char
	call	near ptr char_right	;move over one
@word_left_98:
	clc				;Clear carry flag
@word_left_99:
	ret
word_left endp



;+
; FUNCTION : word_right
;
;	Move one word right.
;
; Parameters:
;	Globals linebuf and dot.
;
; Returns:
;	Nothing.
; Register(s) destroyed:
;-
word_right proc near
@word_right_10:				;Loop fwd over alphanumerics
	call	near ptr char_right	;One char right
					;AL<-char at dot
	jc	@word_right_99		;Already at end of line
	call	near ptr isalphnum	;Is AL alphanumeric ?
	jnc	@word_right_10		;Yes, loop back
@word_right_15:				;Now move to beginning of word
	call	near ptr char_right
	jc	@word_right_99		;Already at end of line
	call	near ptr isalphnum	;Alphanumeric?
	jc	@word_right_15		;Not alphanum char, loop back
@word_right_99:
	ret
word_right endp




;+
; FUNCTION : char_left
;
;	Moves the 'dot' one character to the left unless
;	already at the beginning of the line.
;
; Parameters:
;	Global	dot is current position in the line.
;
; Returns:
;	AL	= char at new dot position.
;	CF	= 1 if OLD dot was at beginning of line
;		  0 otherwise.
; Register(s) destroyed:
;-
char_left proc	near
	@save	si
	mov	ax,dot			;Current position in line
	cmp	ax,offset dgroup:linebuf
	jne	@char_left_5
	stc				;Dot already at beginning of line
	jmp	short @char_left_99
@char_left_5:
	dec	ax			;Move dot left
	mov	dot,ax
@char_left_99:
	xchg	ax,si
	lodsb				;AL<-char at dot
	@restore
	ret
char_left endp







;+
; FUNCTION : char_right
;
;	Moves the 'dot' one character to the right unless
;	already at the end of the line.
;
; Parameters:
;	Global	dot is current position in the line.
;
; Returns:
;	AL	= char at new dot position. Undefined if new dot is at
;		  the end of the line.
;	CF	= 1 if OLD dot was already at end of the line.
;		  0 otherwise.
; Register(s) destroyed:
;-
char_right proc	near
	@save	si
	mov	si,dot			;Current position in line
	mov	ax,lastchar		;AX->Beyond last char
	dec	ax			;AX->last char in line
	cmp	ax,si			;Dot at end ?
	jc	@char_right_99		;Already at line end
	inc	si			;Move dot right, CF not affected
	mov	dot,si
	lodsb				;AL<-char at dot, (undefined if
;					 dot is now at end of line).
;	CF	already clear
@char_right_99:
	@restore
	ret
char_right endp



;+
; FUNCTION : go_bol
;
;	Sets	dot to pint to the beginning of the line
;
; Register(s) destroyed: None.
;-
go_bol	proc	near
	mov	dot,offset dgroup:linebuf
	ret
go_bol	endp



;+
; FUNCTION : go_eol
;
;	Sets	dot to pint to the end of the line
;
; Register(s) destroyed: AX.
;-
go_eol	proc	near
	mov	ax,lastchar
	mov	dot,ax
	ret
go_eol	endp




;+
; FUNCTION : match_file
;
;	match_file tries to expand the filename to the left of the
;	cursor. If there are several matching files, the longest common
;	prefix is placed on the line.
;
; Parameters:
;	None.
;
; Returns:
;	Nothing.
; Register(s) destroyed:
;-
match_file proc	near
	@save	si,di
	push	bp
	mov	bp,sp
	sub	sp,64+44+2+2+2+2+2+2	;Locals
pname		equ	64		;Storage for entire filename with path
ffblk		equ	pname+44
ffblk_attr 	equ	ffblk-15h	;Attr byte within ffblk
ffblk_name 	equ	ffblk-1Eh	;filename within ffblk
fname		equ	ffblk+2		;Points to start of filename in name
oldDTAseg 	equ	fname+2
oldDTAoff 	equ	oldDTAseg+2
lineptr		equ	oldDTAoff+2	;Pointer to location in linebuf	
remaining	equ	lineptr+2	;Remembers remaining space in path
breakstate	equ	remaining+2	;Remembers break state

	mov	ax,3300h		;Get current break state
	int	21h			;DL<-current break state
	mov	byte ptr [bp-breakstate],dl ;Remember it
	xor	dl,dl
	mov	ax,3301h		;Disable break check during
;					 disk i/O
	int	21h
	lea	di,[bp-pname]		;OK 'cause SS==DS
	mov	si,dot			;Current line position
	mov	cx,63			;Max length of path
@match_file_10:
	cmp	si,offset dgroup:linebuf
	je	@match_file_51		;Beginning of line and filename
	dec	si
	mov	al,[si]			;AL<-next char
@match_file_25:
	call	near ptr isspace
	je	@match_file_50		;Beginning of filename
@match_file_45:				;Check for next char if
;					 pathname not too long
	loop	@match_file_10
	jmp	@match_file_99		;Pathname too long, just exit
@match_file_50:
	inc	si
@match_file_51:
;	Copy	filename into ASCIIZ buffer
;	SI->first char of filename in path buffer
	xor	dx,dx			;Flags
	mov	ax,63
	sub	ax,cx			;Length of name
	mov	[bp-remaining],cx	;remember num bytes left in
;					 path buffer
	xchg	ax,cx			;CX<-length of name
	mov	[bp-lineptr],si		;Save start of path name in linebuf
	mov	[bp-fname],di		;Remember start of filename in
;					 path buffer as well (assumed)
	or	cx,cx			;Too far for jcxz
	jne	@match_file_55
	jmp	@match_file_99		;No name, just exit
@match_file_55:
	lodsb				;AL<-next char
	stosb				;Store it
	cmp	al,'.'
	jne	@match_file_56
	or	dl,1			;Set flag to remember file type '.'
	jmp	short @match_file_65	;Check out next character
@match_file_56:
	cmp	al,'\'			;Directory separator?
	jne	@match_file_59
@match_file_57:
	mov	[bp-fname],di		;Update start of filename in
;					 path buffer
@match_file_58:
	and	dl,0FEh			;Forget file type flag
	jmp	short @match_file_65
@match_file_59:
	cmp	al,'/'			;Same thing
	je	@match_file_57
	cmp	al,':'			;Disk?
	jne	@match_file_65
	and	dl,0FEh			;Forget file type (shouldn't really 
;					 occur)
	mov	[bp-fname],di		;Update start of filename in
;					 path buffer

@match_file_65:
	loop	@match_file_55

	mov	cx,[bp-remaining]	;CX<-remaining space
	jcxz	@match_file_52		;Only space for terminator
	mov	al,'*'
	stosb				;Attach a '*'
	cmp	cl,3			;Enough space for ".*"
	jb	@match_file_52
	and	dl,1			;Saw a file type ?
	jne	@match_file_52		;Yes, go attach terminator
	mov	[di],2A2Eh		;Attach a ".*"
	inc	di
	inc	di
@match_file_52:
	xor	al,al			;AL<-0
	stosb				;Terminating 0

;	name	contains the filename
	push	es
	@GetDTA				;Get and save old DTA
	mov	[bp-oldDTAseg],es
	mov	[bp-oldDTAoff],bx
	pop	es
;
	lea	dx,[bp-ffblk]
	@SetDTA	dx			;Set DTA to our DTA

	lea	dx,[bp-pname]		;dx->ASCII name
	@GetFirst dx,16			;Include subdirs in search
	jnc	@match_file_70		;No error
	call	near ptr bell		;No files found
	jmp	@match_file_90		;Restore DTA and exit 


@match_file_70:				;At least one file found
	mov	di,[bp-fname]		;DI->filename portion
	lea	si,[bp-ffblk_name]	;Name returned by GetFirst
@match_file_71:				;Copy the file name
	lodsb
	stosb
	or	al,al
	jne	@match_file_71

	mov	al,SPACE		;If file, add a space
	test	byte ptr [bp-ffblk_attr],16 ;Subdirectory?
	je	@match_file_72		;No
	mov	al,'\'			;If subdir, add a backslash
@match_file_72:
	mov	byte ptr [di-1],al	;Add a space or a '\'
	mov	byte ptr [di],0

;	Now hunt for more files. For each file found, keep the longest 
;	prefix in common so far.

	@GetNext			;Get the next file name
	jc	@match_file_80		;No more files

	mov	di,[bp-fname]		;DI->start of file name
	lea	si,[bp-ffblk_name]	;Name returned by GetNext
	mov	cx,13			;Max Length of field
	repe	cmpsb			;Compare strings
	mov	byte ptr [di-1],0	;Terminating null
	jmp	short @match_file_72	;Try for more files

@match_file_80:
;	Found one or more files, copy the longest common prefix
;	into the line buffer
	mov	ax,[bp-lineptr]		;AX->start of chars to be deleted
	call	near ptr erase_to_dot	;Delete characters between dot
;					 and start of name
	lea	si,[bp-pname]		;SI->name to be copied
	mov	di,si
	xor	al,al
	mov	cx,64
	repne	scasb			;Hunt for terminating null
	mov	ax,63
	sub	ax,cx			;AX<-length of string
; SI->string, AX is length
	push	ax
	call	near ptr xlate_lower	;Convert to lowercase
	pop	ax	
	call	near ptr insert_at_dot	;SI->source, AX == length

@match_file_90:
	push	ds
	mov	ds,[bp-oldDTAseg]
	mov	dx,[bp-oldDTAoff]
	@SetDTA	dx			;Restore DTA
	pop	ds
@match_file_99:
; Restore previous state of break checking
	mov	dl,byte ptr [bp-breakstate]
	mov	ax,3301h
	int	21h
	mov	sp,bp
	pop	bp
	@restore
	ret
match_file endp



CSEG	ENDS

	END

⌨️ 快捷键说明

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