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

📄 cmdline.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 3 页
字号:
;    File              : $CMDLINE.A86$
;
;    Description       :
;
;    Original Author   : DIGITAL RESEARCH
;
;    Last Edited By    : $CALDERA$
;
;-----------------------------------------------------------------------;
;    Copyright Work of Caldera, Inc. All Rights Reserved.
;      
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
;    CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
;    *** Current Edit History ***
;    *** End of Current Edit History ***
;
;    $Log$
;    CMDLINE.A86 1.8 93/03/25 15:06:03
;    tweak console block output
;    ENDLOG
;
; 	DOSPLUS Command Line Editor Routines
;

	include	pcmode.equ
	include	i:msdos.equ
	include i:char.def
	include	i:cmdline.equ
	include	i:reqhdr.equ
	include	i:driver.equ


PCM_CODE	CSEG	BYTE
	public	read_line, edit_size

	extrn	dbcs_lead:near
	extrn	cmdline_read:near
	extrn	raw_read:near
	extrn	cooked_write:near
	extrn	get_dseg:near
	extrn	device_driver:near

; WARNING - the following routines are to support history buffers
; As these are optional we muset NEVER call these routines unless
; the HISTORY_ON bit is set in @hist_flag.

	extrn	init_history:near
	extrn	save_history:near
	extrn	prev_cmd:near
	extrn	next_cmd:near
	extrn	match_cmd:near
	extrn	search_cmd:near
	extrn	match_word:near
	extrn	del_cur_history_buffer:near
	extrn	del_history_buffers:near
	extrn	goto_eol:near
	extrn	next_word:near
	extrn	prev_word:near
	extrn	del_bol:near
	extrn	deln_word:near

; The following are public for HISTORY.PCM
	public	next_char, save_line
	public	space_out, bs_out, put_string
	public	goto_bol
	public	del_eol, del_line
	public	char_info
	public	prev_w20
	public	deln_w10


;	READ_LINE will read an editted line from the handle passed in BX
;	into a buffer with the following format:-
;
;	BYTE	Maximum String Length
;	BYTE	Current String Length
;	BYTE(s)	String Buffer
;
;	On Entry:-
;		BX		Input Handle
;		CX		Output Handle
;		ES:DX		Buffer Address
;
;	On Exit:-
;		String input by user
;
;	The following conventions apply for the READ_LINE function
;
;	ES	Buffer segment
;	SI	Current cursor location in buffer (Index)
;	DX	Last Character in Buffer (Index)
;
DISABLE		equ	80h	; Disable when advanced editing is off.
DISABLE_MASK	equ	8000h
ESC_CODE	equ	01h	; Scan code must be preceeded by escape byte.
NESC_CODE	equ	00h	; No lead zero needed.

read_line:
	push	bp			; Save the Stack Frame Pointer
	mov	bp,sp			; Intialise it to the top of the
	sub	sp,RL_LENGTH		; READ_LINE control block and reserve
					; control block
	mov	RL_INPUT,bx		; Initialize the INPUT Handle
	mov	RL_OUTPUT,cx		; the OUTPUT Handle
	inc dx ! inc dx			; Skip max and Returned Length
	mov	RL_BUFOFF,dx		; and save the buffer offset
	mov	RL_BUFSEG,es		;  and segment
	xor	ax,ax			; now we zero
	mov	RL_SAVPOS,ax		;  both position in it
	mov	RL_SAVMAX,ax		;  and it's size
	mov	al,column
	mov	RL_INICOL,ax		; save initial column
	mov	ax,cle_state		; use to set initial editing state
	and	ax,not (RLF_MATCH+RLF_DIRTY+RLF_RECALLED)
	mov	RL_FLAGS,ax		; save in flags
	test	ax,RLF_ENHANCED
	 jz	read_line10
	call	init_history		;  setup the history buffers
	jmps	read_line20
read_line10:
	and	RL_FLAGS,not RLF_INS	; clear insert mode
read_line20:
	mov	di,dx			; di -> buffer
	xor	bx,bx
	or	bl,es:byte ptr -2[di]	; Get the Maximum number of chars
	mov	RL_MAXLEN,bx		; and save for later
	 jnz	read_line30		; make sure some chars are requested
	jmps	ret_string10		; if no chars just return
	
ret_string:
	pop	ax			; Remove local return address
	mov	ax,RL_FLAGS		; get command line editor state
	mov	cle_state,ax		;  save state for next time
	mov	di,RL_BUFOFF		; Get the buffer Offset
	mov	es:byte ptr -1[di],dl	; Return the number of characters
	push	dx			; Save length of entry
	add	di,dx			; Point to the end of the buffer
	mov	al,CR
	stosb				; Save CR
	call	write_char		; Print a CR and return to the user
	pop	dx
	test	RL_FLAGS,RLF_ENHANCED	; Do not add to history if in
	 jz	ret_string10		; compatibility mode
	call	save_history		; Save state of history buffer
ret_string10:
	mov	sp,bp			; Remove READ_LINE control Block
	pop	bp			; Restore BP and return to the caller
	ret


read_line30:
	xor	si,si			; Currently at start of buffer
	mov	dx,si			; with an empty buffer.

	xor	bx,bx
	or	bl,es:byte ptr -1[di]	; Check if the buffer contains any
	 jz	read_line40		; data which is terminated by a CR
	cmp	es:byte ptr [bx+di],CR
	 jnz	read_line40
	mov	dx,bx
read_line40:
	call	save_line		; Update Save Buffer variables
	mov	dx,si
;
; This is out main command loop - we get a character and try to match it
; with a command in our edit_table. If History is on we look at commands
; with the DISABLED bit set ie. enhanced commands.
; It a match isn't found we insert the character in the buffer, and optionally
; try to match with previous lines in the history buffer.
;
read_line_loop:
	and	RL_FLAGS,not RLF_KANJI	; initial flags
	call	get_char		; read the first character (AH Esc Flg)

	mov	cx,edit_size		; now scan the control table looking
	mov	bx,offset edit_table	;  for a match
read_ll_next_cmd:
	and	ax,not DISABLE_MASK	; assume normal function
	test 	RL_FLAGS,RLF_ENHANCED	; compatibilty required? then it
	 jz 	read_ll10		;  has to be a normal function
	test	EDIT_CNTRL,DISABLE_MASK	; history enabled, so we make
	 jz	read_ll10		;  our code match DISABLE mask
	or	ax,DISABLE_MASK		;  of table entry
read_ll10:
	cmp	ax,EDIT_CNTRL		; check for a match (Escape Flag
	 je	read_ll_found_cmd	;  and the character)
	add	bx,EDIT_LEN		; Add the entry length
	loop	read_ll_next_cmd	; and scan the whole table

; We have failed to find a command so insert char in buffer

	test	ah,ESC_CODE		; Ignore non-matched escaped keys
	 jnz	read_line_loop

	call	save_char		; not an command so save the character
	or	RL_FLAGS,RLF_DIRTY	;  and remember we have something new

; Are we in search mode ?

	test 	RL_FLAGS,RLF_ENHANCED	; Compatibilty required?  
	 jz 	read_line_loop
	test	RL_FLAGS,RLF_SEARCH+RLF_MATCH
	 jz	read_line_loop		; is searching/matching on ?
	push	si			; save current offset
	call	search_cmd
	pop	ax			; this is our target offset
read_ll20:
	cmp	ax,si			; are we there yet ?
	 jae	read_line_loop
	push	ax			; no, keep rewinding cursor
	call	prev_char		;  until we reach position
	pop	ax			;  before we tried to match
	jmps	read_ll20

read_ll_found_cmd:			; get the address of the corresponding
	mov	cx,EDIT_FUNC		;  function from the table	
	call	cx			;  execute the correct function
	jmps	read_line_loop		;  and go back for next character

eject
;
;	the SAVE_CHAR routine will write the character in AL into 
;	the buffer in memory and then update the screen image. The
;	RLF_INS flag is used to determine if INSERT is active.
;
save_c10:
	ret

save_char:
	cmp	ah,TRUE			; Ignore any un-matched escape 
	jz	save_c10		; sequences
	call	save_kanji		; Test if AL is a Kanji Character
					; and setup up the parameter blocks
					; for the INTSAVE_CHAR routine
;
;	INTSAVE_CHAR is the internal entry point to the Character Save
;	routine. It assumes the following:-
;
;	On Entry:-	AX(AL)	    Contains the character
;			CX	    the new character length in bytes
;			RLF_KANJI   Flag is set for a Kanji Character
;			RL_KANJI    Contains the kanji charater
;			
intsave_char:
	mov	bx,cx
	test	RL_FLAGS,RLF_INS	; Overwrite the character in the
	 jnz	save_c50		; buffer currently
	add	bx,si			; Add the current index to the character
	cmp	bx,RL_MAXLEN		; size and compare against the buffer len
	 jae	bell_char		; Full ? Yes Ring dat Bell !

	cmp	dx,si			; Are we at the end of the line
	 jnz	intsave_c10		; No so check character types
	push ax ! push cx
	call	skip_one_char		; Skip the coresponding character in
	pop cx ! pop ax			; the save buffer
	jmps	simple_save

intsave_c10:
	push	ax			; Save the Input Character
	call	char_type		; Get the character type
	mov	bx,ax			; and save in BX
	mov	al,es:[di]		; get the byte to be replaced
	call	char_type		; and get its type
	and	ah,CHAR_SIZE		; Mask the Character SIZE attributes
	and	bh,CHAR_SIZE		; and check both storage and display
					; sizes are the same for old and new
	cmp	ah,bh			; and do simple save if the character
	pop	ax			; Restore the input character to AX(AL)
	 jnz	save_c30		; type match
	sub	dx,cx			; Character overwritten so prevent
					; Max Index being incremented

simple_save:
	add	si,cx			; Assume at the EOL
	add	dx,cx
	stosb				; Save the character typed
	test	RL_FLAGS,RLF_KANJI	; is this a Kanji character
	 jz	simple_s10		; No so just output 1 character
	call	put_char		; and echo it to the user
	mov	al,byte ptr RL_KANJI+1	; Get the high byte of the Kanji
	stosb				; character save and then display it.
simple_s10:
	jmp	put_char
;	ret

;
;	The SAVE_C30 function supports the Complex overwrite conditions
;	where the size of the character in memory or on the display do not
;	match with those of the present incumbent. eg a SPACE character
;	overwriting a TAB or a KANJI character overwriting a SPACE.
;
;	To minimize the complexity of the code the character to be 
;	overwritten is deleted and the new character then inserted.
;	This is not an optimal solution but drastically reduces the
;	amount of code required.
;
save_c30:
	push ax ! push cx
	call	deln_char
	pop cx ! pop ax
	cmp	dx,si
	 jz	simple_save
	or	RL_FLAGS,RLF_INS
	call	save_c50
	and	RL_FLAGS,not RLF_INS
	ret

bell_char:
	mov	al,BELL
	jmp	write_char
;
;	This code is called when INSERT mode is active and a 
;	character (possibly Kanji) is to be inserted in the buffer
;
;	On Entry:-	CX	    the new character length in bytes
;
save_c50:
	mov	bx,cx			; Save new character length
	add	cx,dx			; Add the current max to the character
	cmp	cx,RL_MAXLEN		; size and compare against the buffer len
	 jae	bell_char		; Full ? Yes Ring dat Bell !
	mov	cx,bx			; Restore Character Length
	cmp	dx,si			; If we are at the end of the line
	 je	simple_save		; Use the simple save code
;
;	Create space in the current buffer for the new character
;
	push ds
	push si ! push di
	mov cx,dx ! sub cx,si		; CX -> Number of bytes to move
	mov di,dx ! add di,RL_BUFOFF	; DI -> End of Destination Offset
	add di,bx ! dec di		;    -> + Insert Char len - 1
	mov si,di ! sub si,bx		; SI -> DI - Insert Char Len
	push es ! pop ds		; DS == ES
	std				; Make the right amount of space in
	rep	movsb			; the buffer	
	cld
	pop di ! pop si
	pop	ds

	add	dx,bx			; Update the Buffer Length
	stosb				; Save the New character
	test	RL_FLAGS,RLF_KANJI	; Check if this was a Kanji Character
	 jz	save_c60		; No
	xchg al,ah ! stosb		; Yes Save high byte

save_c60:
	mov cx,dx ! sub cx,si		; Display the updated string
	add si,bx ! push si		; Save the Updated Index
	mov si,di ! sub si,bx		; Get the offset of the new char
	call	put_string		; in the buffer and display all
	pop	si			; Restore the new index
	xchg	di,dx			; and calculate the number of BS
	call	calc_chars		; characters required to get back
	xchg	di,dx
	jmp	bs_out

⌨️ 快捷键说明

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