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

📄 cmdedit.asm

📁 random.zip 随机数产生器的汇编源代码 cmdsrc.zip 一个文本编辑器的汇编源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;
; CMDEDIT.ASM
;(c) 1989, 1990 PC Magazine and Ashok P. Nadkarni
;

SIGNATURE1 equ <"CMDEDIT 2.0 (c) 1990 Ziff Communications Co.">
SIGNATURE2 equ <"PC Magazine">
SIGNATURE3 equ <"Ashok P. Nadkarni">

; Main module for command line editor.

	INCLUDE common.inc
	INCLUDE general.inc
	INCLUDE ascii.inc
	INCLUDE buffers.inc
	INCLUDE dos.inc
	INCLUDE bios.inc

	PUBLIC	dos_version_major
	PUBLIC	dos_version_minor
	PUBLIC	resident
	PUBLIC	macro_level
	PUBLIC	cur_macro
	PUBLIC	cur_macro_len
	PUBLIC	linebuf
	PUBLIC	linelimit
	PUBLIC	dot
	PUBLIC	lastchar
	PUBLIC	LINEBUF_END
	PUBLIC	edit_mode
	PUBLIC	default_imode
	PUBLIC	caller_cursor
	PUBLIC	omode_cursor
	PUBLIC	pgm_name
	PUBLIC	macrosize
	PUBLIC	symsize
	PUBLIC	dossize
	PUBLIC	dirsize
	PUBLIC	mfilename
	PUBLIC	mfile_seen
	PUBLIC	macro_ignore_char
	PUBLIC	cmdlen
	PUBLIC	silent
	PUBLIC	endm_cmd
	PUBLIC	defs
	PUBLIC	defm
	PUBLIC	tsr_install_end
	PUBLIC	source
	PUBLIC	abort_processing
	PUBLIC	disp_line
	PUBLIC	set_disp_marks
	PUBLIC	insert_at_dot
	PUBLIC	insert_chars
	PUBLIC	remove_chars
	PUBLIC	erase_to_dot
	PUBLIC	init_over
	PUBLIC	line_to_scr
	PUBLIC	get_next_line
	PUBLIC	reset_line
	PUBLIC	in_appl
	PUBLIC	user_command
	PUBLIC	our_break_handler
	PUBLIC	prev_isr1b
	PUBLIC	old_int21vec
	PUBLIC	cmdedit_isr
	PUBLIC	makeroom
	PUBLIC	locate_dosenv
	PUBLIC	cmdedit

	IFE	TSR
	PUBLIC	cmdedit_cmd
	PUBLIC	debug_loop
	PUBLIC	freadline
	PUBLIC	get_file_line
	PUBLIC	read_cmdfile
	PUBLIC	disp_prompt
	PUBLIC	prompt
	PUBLIC	init_screen
	ENDIF


DGROUP	GROUP	CSEG

CSEG	SEGMENT	PARA PUBLIC 'CODE'
	EXTRN	install_begin:BYTE
	EXTRN	install:PROC
	EXTRN	execute_defs:PROC
	EXTRN	execute_defm:PROC
	EXTRN	execute_dels:PROC
	EXTRN	execute_delm:PROC
	EXTRN	execute_cmdstat:PROC
	EXTRN	execute_pushd:PROC
	EXTRN	execute_popd:PROC
	EXTRN	execute_chd:PROC
	EXTRN	hist_init:PROC
	EXTRN	hist_type:PROC
	EXTRN	hist_top:PROC
	EXTRN	dirs_init:PROC
	EXTRN	macro_init:PROC
	EXTRN	symbol_init:PROC
	EXTRN	expand_macro:PROC
	EXTRN	expand_symbol:PROC
	EXTRN	get_macro_line:PROC
	EXTRN	skip_whitespace:PROC
	EXTRN	skip_nonwhite:PROC
	EXTRN	stre_cmp:PROC
	EXTRN	get_kbd_line:PROC
	EXTRN	getargs:PROC
	EXTRN	file_error:BYTE
	EXTRN	abort_install:PROC
	EXTRN	expand_var:PROC
	EXTRN	execute_rsthist:PROC
	EXTRN	execute_rstmac:PROC
	EXTRN	execute_rstsym:PROC
	EXTRN	execute_rstdir:PROC

; Define important fields in the PSP.
	ASSUME	CS:DGROUP
	ORG	2Ch
env	dw	?	;Segment of environment block

	ORG	80h
PROMPT_BUF_SIZE EQU 80
prompt	LABEL	BYTE	;buffer used for prompt after TSRing
cmdlen	DB	?	;Offset 80h in the PSP contains length of command
;			 line when program is invoked

	ORG	80h+PROMPT_BUF_SIZE
prompt_length	dw	?
cur_macro LABEL	BYTE	;Start of area used after TSRing to
;			 store the current macro expansion.


	ASSUME	CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
	ORG	100h
entry:	jmp	install

; The following variables are LOST after TSRing since the space is
; reused for other purposes.

mfilename	db	64 DUP (0)	;Storage for ASCIIZ filename
mfile_seen	db	0		;Indicate if command line
;					 specified an init file
mfile_handle	dw	?		;Handle for open file

; Entry init_over is jumped to from the installation code after all the
; command line parsing has been done. This part of the installation
; remains resident. It is not kept with the install code because that
; code sections gets overwritten with various buffers.

init_over proc	near

; The command parameters have been parsed. Now get ready to terminate.
	mov	si,offset DGROUP:install_begin
					;First location in installation code
	mov	bx,si			; is where the buffers start.
	mov	ax,dossize		;Size of DOS history buffer
	add	si,ax			;SI <- end of DOS buffer
	xor	cx,cx			;Indicate DOS mode
	call	near ptr hist_init	;Initialize DOS history buffer
	mov	bx,si			;Repeat for directory stack
	mov	ax,dirsize
	add	si,ax
	call	near ptr dirs_init
	mov	bx,si			;And finally for the macros
	mov	ax,macrosize
	add	si,ax
	call	near ptr macro_init
	mov	bx,si			;And finally for the macros
	mov	ax,symsize
	add	si,ax
	call	near ptr symbol_init

	; SI->end of buffer area
; Read in the command file
	call	near ptr init_screen 	;Need to do this because
;					 reset_line (called by
;					 execute_defm) restores cursor shape.
	call	near ptr read_cmdfile

; Initialize var source to get the next line from the keyboard.
	mov	source,offset DGROUP:get_kbd_line
; All data structures initalized. Now setup stack pointer, release
; unneeded memory back to DOS, set up interrupt handler and TSR.
	push	es			;save ES
	mov	es,env			;Don't need environment block
	ASSUME	ES:NOTHING
	mov	ah,49h
	int	21h			;Release the block
	IF	TSR
	mov	ax,3521h		;Get old interrupt vector
	int	21h
	mov	old_int21vec,bx		;Remember offset
	mov	old_int21vec+2,es		;Remember segment

	mov	dx,offset DGROUP:cmdedit_isr ;Our handler
					;DS = CS already
	mov	ax,2521h		;Set intr vector
	int	21h
	ENDIF
	pop	es			;Restore ES
	ASSUME	ES:DGROUP

	lea	dx,STACK_SIZE+15[si]	;Calculate end of TSR portion
;					 DX<-num bytes to keep resident
	and	dl,0f0h			;    rounded to para
; 	Note DX->BEYOND last byte of program
	mov	new_sp,dx		;Remember it

	mov	resident,1		;Indicate we're TSR

	IFE	TSR
; Don't actually TSR
debug_loop:
@init_over_10:
	@DispCh	CR
	@DispCh	LF
	lea	dx,dummy_prompt
	@DispStr dx
	mov	dx,offset DGROUP:debug_buf 	;Offset
	mov	debug_buf,DEBUG_BUFSIZE-2
	mov	ah,0Ah			;Function code
	pushf				;Simulate interrupt
	push	cs			;Simulate interrupt
	call	near ptr cmdedit_isr	;Simulate interrupt
	jmp	short @init_over_10	;Keep looping
debug_buf	db	256 DUP (?)
DEBUG_BUFSIZE	equ $-debug_buf
dummy_prompt	db	"dummy>",DOLLAR
	ENDIF

	int	27h			;TSR
init_over endp


;+
; FUNCTION : read_cmdfile
;
;	Reads commands from a file. The filename is in the variable
;	mfilename. The space occupied this function is overwritten
;	after TSRing so it must NOT be called once the program is resident.
;
; Parameters:
;	None.
;
; Returns:
;	AX =	0 on success, any other value if failure
;
; Register(s) destroyed:
;	AX,BX,CX,DX
;-
read_cmdfile proc near
	@save	si,di
	cmp	mfile_seen,0
	je	@read_cmdfile_100	;No file specified

	@OpenFil mfilename,0
	jc	@read_cmdfile_92	;CF=1 for errors
@read_cmdfile_30:
	mov	source,offset DGROUP:get_file_line
;					We want get_next_line to read
;					from the file.
	mov	mfile_handle,ax		;Save file handle

@read_cmdfile_50:
	mov	dx,offset DGROUP:linebuf ;Destination for file line
	mov	ax,LINEBUF_SIZE
	call	near ptr freadline	;Get next line into buffer
					;AX contains line length
	jnc	@read_cmdfile_80	;no error or EOF
	or	ax,ax			;No more bytes ?
	jz	@read_cmdfile_99	;EOF is not error
	jmp	short @read_cmdfile_90	;Error, abort install
@read_cmdfile_80:
	mov	dx,offset DGROUP:linebuf
	add	dx,ax
	mov	lastchar,dx		;Update end of line
	call	near ptr cmdedit_cmd	;Execute as a command
	jnc	@read_cmdfile_50	;If not a command, better be a
;					 blank line
	call	near ptr blankline
	jnc	@read_cmdfile_50	;Ignore blank lines
; 	If not blank line and not CMDEDIT command, then error error handler

@read_cmdfile_90:
; Come here for error
	@ClosFil mfile_handle		;Close the file
@read_cmdfile_92:
	@DispStr file_error
	mov	ax,-1			;Indicate exit code
	jmp	abort_install		;Exit program

@read_cmdfile_99:
	@ClosFil mfile_handle		;Close the file
	jc	@read_cmdfile_92	;Abort if error closnig file
@read_cmdfile_100:
	@restore
	ret
read_cmdfile endp



;+
; FUNCTION : get_file_line
;
;	Called indirectly through the global variable 'source'.
;	Currently this routine exists only during installation and must
;	NOT be called once the program is a TSR. The next line from the
;	file is copied to linebuf. If there is no next line, the
;	installation is aborted.
;
; Parameters:
;	None.
;
; Returns:
;	Nothing.
; Register(s) destroyed:
;	AX,BX,CX,DX
;-
get_file_line proc near
	mov	dx,offset DGROUP:linebuf
	mov	ax,LINEBUF_SIZE
	call	near ptr freadline
	jnc	@get_file_line_99
;Error reading file or EOF
	@DispStr file_error
	jmp	abort_install
@get_file_line_99:
	mov	dx,offset DGROUP:linebuf
	add	dx,ax
	mov	lastchar,dx		;Update end of line
	ret
get_file_line	endp




;+
; FUNCTION : freadline
;
;	Reads a line at a time from the file whose handle is in
;	mfile_handle into the buffer pointed to by AX. If the buffer is
;	too small or if there are any errors, the routine returns with CF set.
;	If EOF, then AX = 0 and CF is set.
;
; Parameters:
;	DX	= address of buffer
; 	AX	= size of buffer
;
; Returns:
;	CF 	= 0 if no errors (and not EOF), else 1.
;	AX	= num chars in line if CF = 0.
;		  0 if EOF, ffff for other errors if CF = 1
;
; Register(s) destroyed:
;-
freadline proc	near
	@save	si,di
	mov	di,dx			;DI->buffer
	mov	bx,mfile_handle
	mov	si,ax			;SI<-num bytes to read
	xchg	cx,ax			;CX<-num bytes to read
	mov	ah,3Fh			;File read function
	int	21h
	jc	@freadline_99		;Error!
	mov	cx,ax			;CX<-num bytes read
	jcxz	@freadline_99_a		;EOF (note AX is 0 indicating EOF)
	xchg	dx,ax			;DX<-num bytes read
	mov	bx,di			;BX->start of buffer
	mov	al,CR
	repne	scasb			;Hunt for CR
	je	@freadline_50		;Found
;	No CR found, this better be the last line in file.
	cmp	dx,si			;Were fewer bytes read than requested?
	cmc
	jc	@freadline_99		;Error
	push	dx			;Save length of line
	xor	ax,ax			;AX<-num extra bytes read
	jmp	short @freadline_60
@freadline_50:
	stc				;Assume line too long
	jcxz	@freadline_99		;error if match in last char
;					 (line too long)
	cmp	BYTE PTR [di],LF	;Next char must be linefeed
	stc				;Assume error
	jne	@freadline_99		;Indeed an error if not LF
	mov	ax,di
	sub	ax,bx			;AX<-num chars including CR
	sub	dx,ax
	xchg	ax,dx
	dec	dx			;DX<-num chars in line
	dec	ax			;AX<-num extra chars read
	push	dx			;Save num chars in line

@freadline_60:
; Top of stack contains num bytes in line.
; Now position file pointer to 'unread' characters.
; AX contains the num of extra characters read.
	neg	ax
	cwd
	mov	cx,ax
	xchg	cx,dx			;CX:DX<-num bytes to 'unread'
	mov	bx,mfile_handle
	mov	ax,4201h		;Move file ptr relative
	int	21h			;Seek file relative
; CF set/reset by error status
	pop	ax			;AX<-num bytes in line
	clc				;No errors
	jmp	short @freadline_100
@freadline_99:
	mov	ax,0ffffh		;Non-EOF error
@freadline_99_a:
	stc				;Indicate error or EOF
@freadline_100:
	@restore
	ret
freadline endp



;+
; FUNCTION : blankline
;
;	Checks whether the line in linebuf is blank or not. Also treats it
;	as blank line if it begins with a `-'.
;
; Parameters:
;	None.
;
; Returns:
;	CF	= 0 if blank line, else 1.
; Register(s) destroyed:
;	AX,BX,CX,DX
;-
blankline proc	near
	@save	si
	mov	si,offset DGROUP:linebuf

⌨️ 快捷键说明

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