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

📄 history.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 2 页
字号:
found_cmd:
	call	copy_from_hist		; Copy from history to user buffer
	pop	di
	pop	si
;	jmp	goto_eol		; Display new line.

goto_eol:				; Move the cursor to the end of the
	mov cx,dx ! sub cx,si		; displayed line
	 jcxz	goto_e10		; Already at the EOL
	add	si,RL_BUFOFF		; Get the Offset in the buffer
	call	put_string		; Output the sub_string
	add	di,cx			; Update the local variables
	mov	si,dx			; and return
goto_e10:
	ret

; DI-> Current entry in history buffer
;
copy_from_hist:
	or	RL_FLAGS,RLF_RECALLED	; remember we have recalled something
	and	RL_FLAGS,not RLF_DIRTY	; this entry is already in buffers
	mov	RL_HIST_RECL,di		; update pointer for next time
	call	find_next_null		; how big is this entry ?
	mov	cx,di
	mov	si,RL_HIST_RECL
	sub	cx,si			; (CX-SI)=No of bytes to copy
	cmp	cx,RL_MAXLEN		; is the line bigger than our buffer ?
	 jb	copy_from_hist1		; if so we want to clip it
	mov	cx,RL_MAXLEN		; to the maximum possible value
copy_from_hist1:
	mov	dx,cx
	push	ds
	mov	ds,RL_HIST_SEG
	mov	di,RL_BUFOFF
	rep	movsb			; copy to line buffer
	pop	ds
	call	save_line		; save the line
	mov	cx,RL_SAVMAX		; we can't copy any more
	mov	RL_SAVPOS,cx
	ret

; Some primitives for history buffer handling:
;
; find_free_hist	Find the next free entry in the history buffer
; find_next_null	Finds the end of the current entry
; find_prev_hist	Finds the start of the previous entry
; find_next_hist	Finds the start of the next entry
; find_current_hist	Finds the start of current entry

;
; Make DI-> next entry of sufficient length for the current cmd buffer
; If we can't fit at the end zero the remainder of the buffer then wrap
; back to the start.
;

find_free_hist:
	mov	di,RL_HIST_SAVE		; Point at current last entry
	push	di			; Will DX bytes fit?
	add	di,dx
	cmp	di,RL_HIST_SIZE		; Did we run out of buffer?
	pop	di
	 jb	find_free_hist20
	xor	ax,ax			; doesn't fit, so zero to end of buffer
find_free_hist10:
	push	es
	mov	es,RL_HIST_SEG
	stosb				; keep on zeroing
	pop	es
	cmp	di,RL_HIST_SIZE
	 jb	find_free_hist10
	xor	di,di			; wrap back to start of history buffer
find_free_hist20:
	ret

; Entry DI-> entry in the history buffer
; Make DI-> next NULL in the history buffer ( end of current entry )
;
find_next_null:
	mov	cx,RL_HIST_SIZE
	sub	cx,di			; Calc no of bytes left
	xor	ax,ax			; Look for next terminator
	push	es
	mov	es,RL_HIST_SEG
	repnz	scasb	
	dec	di			; point at the NUL
	pop	es
	ret

; Entry DI-> entry in the history buffer
; Make DI-> previous entry in the history buffer
; Preserve CX
find_prev_hist:
	call	find_current_hist	; handle any wrapping
	mov	ax,di			; AX = entry we want previous for
find_prev_hist10:
	push	ax			; save current offset
	push	di			; save initial offset
	xchg	ax,di			; find next from here until
	call	find_next_hist		;  we get back where we started
	xchg	ax,di			; AX = current offset
	pop	di			; recover initial value
	pop	bx			; recover previous offset
	cmp	ax,di			; have we wrapped yet ?
	 je	find_prev_hist20	; yes, BX = previous entry
	 ja	find_prev_hist10	; we are above target so continue
	cmp	bx,di			; we are below target - if previous
	 jae	find_prev_hist10	;  was above target we are OK
	cmp	ax,bx			; if new below previous then we
	 jnb	find_prev_hist10	;  have ERROR wrap, so stop
find_prev_hist20:
	mov	di,bx			; DI -> Previous entry
	ret

find_next_hist:	
	call	find_current_hist	; handle any wrapping
	call	find_next_null		; point to end of current entry
;	jmp	find_current_hist	; handle any wrapping

find_current_hist:
; This routine is complicated by the need to handle switchers, where
;  our buffers and pointers may get out of step
	push	es
	xor	ax,ax
	mov	es,RL_HIST_SEG		; now work backwards to start of line
find_current_hist10:
	cmp	di,1			; are we at the start of the buffer
	 jb	find_current_hist30	;  then don't wrap
	std
	scasb				; is previous char a NUL ?
	cld				;  (it should be!)
	 jne	find_current_hist10
	inc	di			; ES:DI -> 1st char of line
find_current_hist20:
	mov	cx,RL_HIST_SIZE
	sub	cx,di			; CX= Remaining no: of bytes in buffer
	 jbe	find_current_hist30
	repe	scasb			; skip over zero's
	 jne	find_current_hist40
find_current_hist30:
	mov	di,1			; wrap to start of buffer
find_current_hist40:
	dec	di
	pop	es
	ret

del_history_buffers:
;-------------------
; Delete contents of both history buffers
;
	mov	ax,histbuf1		; Segment of 1st history buffer
	mov	cx,histsiz1		; End of 1st history buffer
	call	zap_buffer
	mov	ax,histbuf2		; Segment of 2nd history buffer
	mov	cx,histsiz2		; End of 2nd history buffer
	jmps	zap_buffer
	
del_cur_history_buffer:
;----------------------
; Delete contents of the current history buffer
;
	mov	ax,RL_HIST_SEG		; zero the current buffer
	mov	cx,RL_HIST_SIZE
zap_buffer:
	push	es			; zero fill CX bytes at AX:0
	push	di
	mov	es,ax
	xor	ax,ax
	mov	RL_HIST_RECL,ax
	mov	RL_HIST_SAVE,ax
	xor	di,di
	rep	stosb			; zero fill the buffer
	pop	di
	pop	es
	call	del_line		; then delete current line
	jmp	save_line


next_word:
	mov	cx,dx			; Calculate the number of bytes
	sub	cx,si			; left to scan
	jcxz	next_w10		; Skip if at the EOL
	push	si			; Save the current Index
	mov	si,di			; Scan from the current location
	call	match_word		; Get the next word boundary
	mov	cx,si
	sub	cx,di			; Calculate the string length
	mov	si,di			; to be displayed from the current
	call	put_string		; location and output the data
	pop	si
	add	si,cx			; Update the Index and Offset pointers
	add	di,cx
next_w10:
	ret

;
;	MATCH_WORD scans the buffer at ES:SI for word boundaries
;	and returns to the calling routine whenever it detects such
;	a boundary.
;
;	On Entry:	ES:SI	Buffer Address
;			CX	Maximum No of bytes to Scan
;
;	On Exit:	ES:SI	Next Word Boundary
;
match_word:
	call	char_info
	test	ah,CHAR_ALPHAN or CHAR_KANJI
	loopnz	match_word		; scan the rest of the current word
	 jcxz	match_w30		; end of word or kanji ?

	push	dx
match_w10:
	mov	dx,si
	call	char_info
	test	ah,CHAR_ALPHAN or CHAR_KANJI
	loopz	match_w10
	 jz	match_w20
	sub	si,dx			; Correct the count in CX
	add	cx,si			; and return the location of the
	mov	si,dx			; word boundary

match_w20:
	pop	dx
match_w30:
	ret

prev_word:
	mov cx,si ! jcxz match_w30	; Initialize the count
	push dx ! push si ! push di
	mov	si,RL_BUFOFF		; Scan from the begining of the buffer
	mov	dx,si			; keeping the last match in DX
prev_w10:
	call	match_word		; Find the next word boundary
	jcxz	prev_w15		; Stop when we get to the current offset
	mov	dx,si			; Save current location
	jmps	prev_w10		; and repeat
prev_w15:
	jmp	prev_w20

del_bol:				; Delete to the begining of the line
	or si,si ! jz del_bol10		; Ignore if at the begining
	or dx,dx ! jz del_bol10		; Or the line is empty
	push	di			; Save the current index
	call	goto_bol		; Move to the start of the line
	pop	cx			; Restore the current offset
	jmp	deln_w10		; and jump to common code
del_bol10:
	ret

deln_word:
	mov	cx,dx			; Calculate the number of bytes
	sub	cx,si			; left to scan
	jcxz	del_bol10		; Skip if at the EOL
	push	si			; Save the current Index
	mov	si,di			; Scan from the current location
	call	match_word		; Get the next word boundary
	mov	cx,si
	pop	si
	jmp	deln_w10

PCMODE_DATA	DSEG	WORD

	extrn	@hist_flg:byte		; To select between histbufs 1 or 2

GLOBAL_DATA	dseg	word

	extrn	histbuf1:word, histsiz1:word, histbuf2:word, histsiz2:word

	end

⌨️ 快捷键说明

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