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

📄 history.asm

📁 random.zip 随机数产生器的汇编源代码 cmdsrc.zip 一个文本编辑器的汇编源代码
💻 ASM
字号:
; HISTORY.ASM
; (c) 1989, 1990 Ashok P. Nadkarni
;
; This module implements the history feature of the cmdedit program.

	INCLUDE common.inc
	INCLUDE	buffers.inc

	PUBLIC	hist_top
	PUBLIC	hist_init
	PUBLIC	hist_fwd
	PUBLIC	hist_back
	PUBLIC	hist_fwd_match
	PUBLIC	hist_bck_match
	PUBLIC	remember
	PUBLIC	hist_type
	PUBLIC	execute_auto_recall
	PUBLIC	execute_rsthist
	PUBLIC	hist_ptr
	PUBLIC	history

CSEG	SEGMENT	PARA PUBLIC 'CODE'


	EXTRN	linebuf:BYTE		;line buffer
	EXTRN	lastchar:WORD
	EXTRN	dot:WORD		;current position in line buffer


; The history stack is maintained as a string stack using the functions in
; the string stack library. The top and bottom of the stack are always
; zero length strings (the bottom is always a zero length sentinel
; implemented by the string stack package but the top is explicitly 
; maintained by the history code.
history	$string_stack 2 DUP (<>)	;Buffer descriptors
hist_ptr	DW	?		;Ptr to current buffer descriptor


DGROUP	GROUP	CSEG

	EXTRN	bell:PROC
	EXTRN	set_disp_marks:PROC
	EXTRN	erase_to_dot:PROC

	ASSUME	CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP


;+
; FUNCTION : hist_init
;
; Initializes the various data structures associated with the
; command history buffers. CALLER MUST ENSURE PASSED ADDRESSES ARE VALID
; AND BUFFER IS LARGE ENOUGH.
;
; Parameters:
;	AX 	- length of buffer in bytes
;	BX	- address of buffer
;	CX	- 0 if DOS buffer, any other value if application buffer
; 
; Returns:
;	Nothing.
; Registers destroyed : BX,CX
;-
hist_init proc	near
	push	bx
	mov	bx,offset DGROUP:history ;bx := address of buffer descriptors
	jcxz	@hist_init_1		;if DOS, bx OK
	add	bx,TYPE $string_stack	;else point to application descriptor
@hist_init_1:
	xchg	ax,cx			;CX = buffer size
	pop	ax			;AX = Buffer address
					;BX points to appropriate descriptor
	call	near ptr strstk_init	;Initialize buffer and descriptor
	xor	al,al			;Push a zero length string onto stack
	mov	cl,1			;Force onto stack
	call	near ptr strstk_push	;Assumes no errors
	ret
hist_init	endp


;+
; FUNCTION : execute_rsthist
execute_rsthist proc	near
	mov	bx,offset DGROUP:history ;bx := address of buffer descriptors
	jcxz	@execute_rsthist_1	;if DOS, bx OK
	add	bx,TYPE $string_stack	;else point to application descriptor
@execute_rsthist_1:
	call	near ptr strstk_reset	;Initialize buffer and descriptor
	xor	al,al			;Push a zero length string onto stack
	mov	cl,1			;Force onto stack
	call	near ptr strstk_push	;Assumes no errors
	ret
execute_rsthist	endp



;+
; FUNCTION : hist_type
;
;	Sets the hist_ptr global to point at the descriptor for the
;	current caller (DOS or application).
;
; Parameters:
;	CX =	0 if DOS, anything else for application
;
; Returns:
;	Nothing.
; Registers destroyed : BX
;-
hist_type proc near
	mov	bx,offset DGROUP:history ;address of first descriptor
	mov	hist_ptr,bx
	ret
hist_type endp


;+
; FUNCTION : hist_top
;
;	Resets the history pointer to the null string at top of history stack.
;	The line buffer itslef is NOT changed.
; Parameters:
;	None.
;
; Returns:
;	Nothing.
; Registers destroyed:  BX
;-
hist_top proc near
	mov	bx,hist_ptr		;Point to current descriptor
	call	near ptr strstk_settop	;Set to top of history stack.

	ret
hist_top endp


;+
; FUNCTION : hist_back
;
;	Gets the previous history line (if there is one) and stores it
;	in the line buffer. Also makes it the current line.
;
; Parameters:
;	None.
;
; Returns:
;	Nothing.
; Registers destroyed: AX,BX,CX
;-
hist_back proc near
	mov	dot,offset DGROUP:linebuf
	jmp	hist_bck_match		;Will return to caller
hist_back endp



;+
; FUNCTION : hist_fwd
;
;	Gets the next history line (if there is one) and stores it
;	in the line buffer. Also makes it the current line.
;
; Parameters:
;	None.
;
; Returns:
;	Nothing.
; Registers destroyed :
;-
hist_fwd proc near
	mov	dot,offset DGROUP:linebuf
	jmp	hist_fwd_match		;Will return to caller
hist_fwd endp



;+
; 
; FUNCTION : hist_copy
;
;	Copies the current history line into the line buffer. The dot
;	is set to the beginning of the line.
;
; Parameters:
;	BX =	points to the beginning of a line in the history buffer.
;
; Returns:
;	Nothing.
;
; Registers destroyed: 
;-
hist_copy proc near
	mov	bx,hist_ptr	;Current descriptor
	mov	ax,offset DGROUP:linebuf ;the history line storage
	push	ax		;Remember
	mov	dot,ax		;Cursor will be at the beginning of line
	xchg	ax,dx		;dx->first char in line (parameter)
	mov	ax,lastchar	;ax->upper limit (parameter)
	call	near ptr set_disp_marks ;Indicate changed range
				;No registers destroyed
	mov	ax,dx		;Restore beginning of line
	sub	cx,LINEBUF_SIZE	;cx<-max length of line
	push	cx		;Save it
	call	near ptr strstk_copy ;Copy history line into linebuf
				;AX == length of history string
	pop	cx		;
	jnc	@hist_copy_90	;Jump if no error from strstk_copy
	call	near ptr bell	;History line too long for buffer
	mov	ax,cx		;Number of bytes = max length of line
@hist_copy_90:
	pop	dx		;dx->beginning of line
	add	ax,dx		;ax->end
	mov	lastchar,ax	;Update end of line
	call	near ptr set_disp_marks ;Indicate changed range
				;No registers destroyed
	ret
hist_copy endp



;+
; 
; FUNCTION : remember
;
;	Saves the line buffer in the history area. If the line already
;	exists, it is moved to the top of the stack.
;
; Parameters:
;	None.
;
; Returns:
;	Nothing.
;
; Registers destroyed:
;	AX,BX,CX,DX
;-
remember proc near
	mov	bx,hist_ptr		;Descriptor
	call	near ptr strstk_settop	;Reset stack pointer
	mov	ax,offset DGROUP:linebuf ;AX->line to be stored
	mov	cx,lastchar
	sub	cx,ax			;CX<-length of line
	call	near ptr strstk_bck_find ;Look for it in history
;					  buffer. Note that if it is a
;					  null string, the sentinel at
;					  top of the stack is not found
;					  which is at it should be.
	jc	@remember_10		;Not in stack
	call	near ptr strstk_kill	;If found delete it from stack
@remember_10:
	call	near ptr strstk_settop	;Point to sentinel at top of stack
	call	near ptr strstk_kill	;Delete it
	mov	dx,offset DGROUP:linebuf ;String to be remembered
	mov	ax,lastchar		;Length of string
	sub	ax,dx			;AX(AL)<-length of string
	mov	cl,1			;Force the push
	call	near ptr strstk_push	;ignore success/fail status
	xor	ax,ax			;Zero length sentinel
	mov	cl,1
	call	near ptr strstk_push	;Push it
	ret
remember endp



;+
; 
; FUNCTION : hist_fwd_match, hist_bck_match
;
;	Looks fwd/back thru the history buffer starting from the current
;	history location looking for a line whose first n chracters match
;	the n characters before the current position in the line buffer.
;
; Parameters:
;	None.
;
; Returns:
;	CF	= 0 if match found
;		  1 if no match
;
; Registers destroyed:
;-
hist_match proc near
hist_fwd_match LABEL near
	mov	dx,offset DGROUP:strstk_fwd_match
	jmp	short @hist_match_10
hist_bck_match label near
	mov	dx,offset DGROUP:strstk_bck_match
@hist_match_10:
	mov	bx,hist_ptr	;Descriptor address
	mov	ax,offset DGROUP:linebuf ;start of pattern
	mov	cx,dot		;Current position in linebuffer
	sub	cx,ax		;Number of chars to match
	push	cx		;Save
	push	ax
	call	dx		;Will set CF if no match, else sets
				; 'current' to matched string
	pushf			;Remember flags
	jc	@hist_match_20	;No match
	call	near ptr hist_copy ;Copy and display the history line
				;Now reset it to original position
@hist_match_20:
	popf			;Restore flags
	pop	ax		;Line address
	pop	cx		;Restore count
	pushf			;Save flags
	add	ax,cx		;AX->dot
	mov	dot,ax
	popf			;Restore flags
	jnc	@hist_match_99	;If match was found, exit
	mov	ax,lastchar	;AX->end-of-line
	call	erase_to_dot	;Else delete remaining chars in the
;				 line (chars between AX and dot)
	stc			;Indicate no match
@hist_match_99:
	ret
hist_match endp



;+
; FUNCTION : execute_auto_recall
;
;	This function looks backward through the history buffer for a
;	line with a prefix that matches the characters to the left of
;	the dot. The search begins with the CURRENT history line. ie.
;	if the current history line has a matching prefix, the current
;	pointer is not changed. If no match is found, the history stack
;	is reset.
;
; Parameters:
;	None.
;
; Returns:
;	CF	= 0 if match found
;		  1 if no match
; Register(s) destroyed:
;	AX,BX,CX,DX
;-
execute_auto_recall proc near
	mov	bx,hist_ptr		;BX->current history stack descriptor
	mov	ax,offset DGROUP:linebuf ;AX->pattern
	mov	cx,dot
	sub	cx,ax			;CX<-length of pattern
	call	near ptr strstk_prefix	;Current history line matches?
	jne	@execute_auto_recall_50	;No
	clc				;Yes, current line matches
	jmp	short @execute_auto_recall_99

@execute_auto_recall_50:
	call	near ptr hist_bck_match	;Search backward
	jnc	@execute_auto_recall_99	;Found a match
;	No match, reset history stack pointer
	mov	bx,hist_ptr		;BX->current history stack descriptor
	call	near ptr hist_top	;Reset history stack
	stc				;Indicate no match
@execute_auto_recall_99:
	ret
execute_auto_recall endp

CSEG	ENDS

	END

⌨️ 快捷键说明

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