📄 cmdedit.asm
字号:
xor ch,ch ;Clear high bits
mov cl,[si] ;CX<-Length of command
jcxz @cmdedit_cmd_98 ;End of table, exit
inc si ;SI->command
cmp cx,ax ;Lengths match
jne @cmdedit_cmd_30 ;No, go try next command
xchg bx,ax ;BX<-num chars in word
call near ptr stre_cmp ;Compare strings
xchg ax,bx ;AX<-num chars in word
je @cmdedit_cmd_50 ;Command matched
@cmdedit_cmd_30:
xor ch,ch
mov cl,-1[si] ;AX<-length of command
add si,cx ;SI->length of next command
inc dx ;Increment the command number
jmp short @cmdedit_cmd_10 ;Try next command
@cmdedit_cmd_50: ;Found command
mov si,di ;SI->first char of command
add si,ax ;SI->first char after command
mov cx,lastchar
sub cx,si ;CX<-num chars after command
mov di,dx ;BX<-command number
shl di,1 ;BX<-offset into table
call cmd_func_table[di] ;Execute it
; Params:
; SI->first char after command
; CX = remaining length of line
; (after command)
cmp source,offset DGROUP:get_kbd_line
jne @cmdedit_cmd_60
call near ptr disp_prompt ;Display user prompt
@cmdedit_cmd_60:
clc ;CF = 0
jmp short @cmdedit_cmd_99
@cmdedit_cmd_98: ;No command found
stc ;CF = 1
@cmdedit_cmd_99:
@restore
ret
cmdedit_cmd endp
;+
; FUNCTION : abort_processing
;
; Called by various routines in case of any errors that require
; aborting of any ongoing processing. An error message is
; displayed and CMDEDIT state is reset to accept input from the
; keyboard. The routine adjusts the stack pointer to a previously
; stored state. Execution then continues at a `abort entry'
; point. The routine does NOT return to the caller.
;
; Parameters:
; AX = Error message number.
;
; Returns:
; Does NOT return to caller.
;
; Register(s) destroyed:
; Potentially all but irrelevant since routine does not return to
; caller.
;-
abort_processing proc near
mov macro_level,0 ;Reset macro level
mov source,offset DGROUP:get_kbd_line ;Set input to keyboard
; Display a message
mov si,offset DGROUP:abort_msg_hd
mov di,offset DGROUP:linebuf
mov dot,di ;dot MUST be at
; beginning of line
; since this position is
; stored in the main routine
mov cx,ABORT_HDR_LEN
rep movsb ;Copy message header
sal ax,1
sal ax,1 ;AX is now index into msg table
xchg ax,bx
mov si,abort_msg_ptrs[bx] ;SI->message
mov cx,abort_msg_ptrs[bx+2] ;CX<-length of message
rep movsb ;Copy msg into linebuf
mov si,offset DGROUP:abort_msg_tl
mov cx,ABORT_TAIL_LEN
rep movsb ;Copy tail of message
mov lastchar,di
mov ax,di ;Set display marks
mov dx,offset DGROUP:linebuf
call near ptr set_disp_marks
call disp_line ;Display message
call near ptr restore_cursor ;Restore cursor to user shape
@DispCh CR
@DispCh LF
call near ptr disp_prompt
mov sp,abort_entry_stack
jmp near ptr cmdedit_abort_entry
abort_processing endp
;+
; FUNCTION : restore_cursor
;
; Restores the cursor to the user's shape.
;
; Parameters:
; Global caller_cursor contains original shape
;
; Returns:
;
; Register(s) destroyed:
; None.
;-
restore_cursor proc near
@save ax,cx
mov cx,caller_cursor
IF TOGGLE_CURSOR
@SetCurSz ch,cl
ENDIF
@restore
ret
restore_cursor endp
;+
; FUNCTION : reset_line
;
; Called to init various things like cursor shape, history buffer
; character positions etc.
;
; Parameters:
; None.
;
; Returns:
; Nothing.
;
; Register(s) destroyed:
; AX,BX,CX,DX
;-
reset_line proc near
call near ptr hist_top ;Reset history stack ptr to top
call near ptr restore_cursor ;Reset cursor shape
mov ax,offset dgroup:linebuf
mov lastchar,ax ;End of line
mov dot,ax ;current pos in line
mov disp_begin,ax ;first pos that changed
mov disp_end,ax ;last pos that changed
; Init overstrike/insert mode
mov bl,default_imode ;Default edit mode
; (insert/overstrike)
mov edit_mode,bl ;Init insert/overtype mode
; Initialize the cursor shapes for insert and overstrike mode
mov ax,caller_cursor ;Caller's cursor shape
IF TOGGLE_CURSOR
mov ah,al
sub ah,3
mov imode_cursor,ax ;Insert mode cursor
mov ah,al
sub ah,1
mov omode_cursor,ax ;Overtype mode cursor
; Init cursor shape
xor bh,bh
add bx,bx
mov cx,omode_cursor[bx]
mov ah,01h
int 10h
ELSE
mov omode_cursor,ax
mov imode_cursor,ax
ENDIF
mov bh,video_page
@GetCur bh
mov initial_curpos,dx ;Initial cursor position
ret
reset_line endp
;+
; FUNCTION : init_screen
;
; Inits various screen parameters. Reads the current prompt from
; the screen and store in the prompt buffer. prompt buffer is
; assumed to be at most the width of the screen.
;
; Parameters:
; None.
;
; Returns:
; Nothing.
; Register(s) destroyed:
; AX,BX,CX,DX
;-
init_screen proc near
@save si,di
@GetMode ;Get the video mode
mov video_page,bh ;Store page
mov screen_width,ah ; and width of display
@GetCur bh ;Get the cursor shape and position
mov initial_curpos,dx ;Initial cursor position
mov caller_cursor,cx ;Caller's cursor shape
mov di,offset DGROUP:prompt
mov cx,PROMPT_BUF_SIZE ;CX<-size of prompt buffer
; (assumed not 0)
mov si,dx ;DX<-cursor pos
xor dl,dl ;DX<-position at start of row
@init_screen_5:
; BH holds video page, DX is cursor position, SI is ending cursor
; position, CX is remaining space in prompt buffer
@SetCurPos ,,bh ;Set cursor position
cmp dx,si ;Reached original position ?
je @init_screen_10 ;Yes, all done
@GetChAtr bh ;Get char at cursor
stosb ;Store in prompt buffer
inc dl ;Increment cursor position
loop @init_screen_5 ;loop unless prompt buffer full
@init_screen_10:
sub di,offset DGROUP:prompt
mov prompt_length,di ;Store length of prompt
@restore
ret
init_screen endp
;+
; FUNCTION : disp_prompt
;
; Called to display the user's prompt. The prompt is taken from
; the buffer 'prompt'.
;
; Parameters:
; None.
;
; Returns:
; Nothing.
; Register(s) destroyed:
; <TBA>
;-
disp_prompt proc near
@save si
@DispCh CR
@DispCh LF
mov cx,prompt_length
jcxz @disp_prompt_99
mov si,offset DGROUP:prompt
@disp_prompt_10:
lodsb
@DispCh al
loop @disp_prompt_10
@disp_prompt_99:
@restore
ret
disp_prompt endp
;+
; FUNCTION : makeroom
;
; Called to push a specified number of characters from the end of a
; line to the back of the line buffer.
;
; Parameters:
; CX - number of chars to push back
;
; Returns:
; DI - points to the first char of the string pushed back.
; Register(s) destroyed:
; CX
;-
makeroom proc near
@save si
mov si,lastchar ;end of line
dec si
mov di,offset DGROUP:linebuf_suffix ;Di->end of linebuf (we
; want to move chars in
; reverse order)
std
rep movsb ;Move up characters
cld
inc di ;DI->start of string
@restore
ret
makeroom endp
;+
; FUNCTION : getpsp
;
; Returns the PSP of the current process
;
; Returns:
; BX - segment of current PSP
;
; Registers destroyed :
; AX,BX
;-
getpsp proc near
; Get the PSP of the current process
cmp dos_version_major,2
jbe @getpsp_10
; DOS 3.x or above - use documented call
mov ah,62h
jmp short @getpsp_90
@getpsp_10:
; DOS version 2.x - use undocumented call
mov ah,51h
@getpsp_90:
int 21h ;BX->PSP segment
ret
getpsp endp
;+
; Function : locate_dosenv
;
; Locates the segment in which the current environment is located.
; This environment is the 'current' environment which may not
; necessarily be the root environment.
;
; Parameters:
; None.
;
; Returns:
; AX - segment of environment
;
; Register(s) destroyed:
; AX
;-
locate_dosenv proc near
@save bx,si,es
call near ptr getpsp ;BX->segment of psp
mov es,bx ;ES->segment of psp
; Loop to find the current command.com psp
mov si,16h ;ES:SI->parent psp
xor ax,ax ;Init for loop
jmp short @locate_dosenv_20 ;'while' loop
@locate_dosenv_10:
mov ax,es:[si] ;AX<-psp seg
mov es,ax ;ES->psp of parent
@locate_dosenv_20:
cmp ax,es:[si] ;Is psp == parent psp ?
jne @locate_dosenv_10
; ES contains DOS PSP.
mov ax,es:[2ch] ;Offset 2c is env address
; AX->DOS environment
; mov dos_envseg,ax
cmp dos_version_major,2 ;DOS 2.x ?
je @locate_dosenv_50
; Versions 3.x or higher
cmp dos_version_minor,10 ;3.1 or below ?
jle @locate_dosenv_50 ;If so handle like 2.x
cmp dos_version_minor,30 ;3,3 or above ?
jge @locate_dosenv_99 ;Then all done
; DOS version higher than 3.1 but below 3.3.
jmp short @locate_dosenv_60
@locate_dosenv_50:
; DOS version 2.x-3.1. If the environement is non-0, all done. Else the
; environment is the memory block below the command.com.
or ax,ax ;0 ?
jne @locate_dosenv_99 ;No, all done
@locate_dosenv_60:
mov si,es
dec si ;SI is segment of memory
; control block of command.com
mov es,si
mov ax,es:[3] ;AX->size of command.com in
; paragraphs
inc ax ;Add size of MCB to AX (in
; paras)
add ax,si ;AX->MCB of environment
inc ax ;AX->environment
; mov dos_envseg,ax ;Store it.
@locate_dosenv_99:
; OK, now dos_envseg supposedly contains the environment segment. DO some
; heuristics to make sure it is really what we think it is.
@restore
ret
locate_dosenv endp
;+
; FUNCTION : our_break_handler
;
; This takes over the Ctrl-Break interrupt and sets a flag when
; Ctrl-Break is hit. It then jumps to the original Ctrl-Break handler.
;
; Parameters:
;
;
; Returns:
;
; Register(s) destroyed:
;-
our_break_handler proc near
inc CS:check_break
cmp CS:trap_break,1
jne @our_break_handler_10
iret
@our_break_handler_10:
jmp CS:prev_isr1b
our_break_handler endp
CSEG ENDS
END entry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -