📄 cmdline.a86
字号:
;
; On Entry: AL First byte of Character
;
; On Exit: AX Complete Character Code
; CX Character Size Bytes
; RL_KANJI and RLF_KANJI set correctly
;
save_kanji:
and RL_FLAGS,not RLF_KANJI
mov RL_KANJI,ax ; Save the Character
call char_type ; Is this the first byte of a
test ah,CHAR_KANJI ; two byte Kanji character
mov cx,1 ; Character size in bytes
jz save_k10 ; No
or RL_FLAGS,RLF_KANJI ; Set internal Flag
call get_char ; Get the high byte and save
mov byte ptr RL_KANJI+1,al ; in the local variable
mov ax,RL_KANJI ; Get the complete character
mov cx,2 ; Character size in bytes
save_k10:
ret
eject
;
; The following group of functions modify the flags which control
; the command line editor.
;
toggle_ins:
xor RL_FLAGS,RLF_INS ; Toggle the OverWrite/Insert
ret ; Flag
toggle_search:
and RL_FLAGS,not RLF_MATCH ; clear match bit
xor RL_FLAGS,RLF_SEARCH ; Toggle the Search on/off flag
ret
eject
;
; This group of functions moves the cursor along the display
; as well as updating the local variables.
;
goto_bol:
test si,si ; Move the cursor to the begining of
jz goto_b10 ; the displayed line
mov di,si ; Set the buffer index to the
xor si,si ; start of the line and the current
call calc_chars ; location
call bs_out
xor si,si
mov di,RL_BUFOFF
goto_b10:
ret
next_char:
cmp si,dx
jnz next_c05 ; Treat this as "F1" when we at the
jmp copy_char ; end of the line
next_c05:
mov al,es:[di] ; Get the Offset of the next character
mov cx,1 ; the character itself and assume
call char_type ; it is 1 byte long
test ah,CHAR_KANJI ! jz next_c10
inc cx
next_c10:
xchg si,di ; Get the string offset in SI
call put_string ; display the character and
xchg si,di ; restore the register contents
add si,cx
add di,cx
ret
prev_char:
test si,si ; begining of line ?
jz prev_w30
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_c10:
call char_info ; Get the character information
cmp si,di ; Stop when we get to the current
je prev_w20 ; character location
mov dx,si ; Save current location
jmps prev_c10 ; and repeat
prev_w20:
sub si,dx ; Calculate character length
push si ; save for update
sub di,RL_BUFOFF ; Convert Offset to Index
neg si ! add si,di ; Set the buffer index to the current
call calc_chars ; location and the previous character
call bs_out ; BackSpace over character
pop cx ; Restore the character size
pop di ! pop si ! pop dx
sub si,cx ; Update the Index and Pointer
sub di,cx ; variables.
prev_w30:
ret
eject
;
; This group of functions deletes characters or groups of characters
; from the buffer.
;
delf_char:
cmp si,dx ; any chars to our right ?
jb deln_char ; yes, delete them first
jmp skip_one_char
; ret ; discard next saved char
del_eol:
mov cx,dx ! sub cx,si ; Calculate the number of bytes to
jcxz del_eol10 ; delete and jump to DELN_WORD if
add cx,di ; non zero. Convert to an offset
jmps deln_w10 ; and jmp to common code.
del_eol10:
ret
delp_char:
or si,si ! jz del_eol10 ; Ignore if the user is at the start
call back_one_char ; of the line otherwise move back one
call prev_char ; character in the line buffer
deln_char:
cmp dx,si ! jz del_eol10
mov al,es:[di] ; Get the Offset of the next character
lea cx,1[di] ; the character itself and assume
call char_type ; it is 1 byte long
test ah,CHAR_KANJI ! jz deln_w10
inc cx
; jmps deln_w10
;
; The 3 delete functions come together at this point with the standard
; register format Plus CX is the offset of the first character not to
; be deleted.
;
deln_w10:
push cx ; Save Delete Offset
xchg di,dx ; Determine the no of characters
call calc_chars ; displayed to the end of the line
xchg di,dx
mov bx,cx ; Save the Column count
pop ax ; restore the delete offset
push bx ! push bx ; Save the count twice
push si ! push di
mov cx,dx ! sub cx,si ; No of chars from old EOL
mov si,ax ; Get the Source Offset
sub ax,di ; calculate its length.
sub dx,ax ; Update the string length
sub cx,ax ; Number of chars to copy
push ds ; Move the contents of the
push es ! pop ds ; string down in memory and
rep movsb ; then update the screen image
pop ds
pop si ! pop di ; Get the current buffer offset
; Restore SWAPPED SI <-> DI
mov cx,dx ; Calculate the length of the
sub cx,di ; string and print it alll
call put_string
xchg si,di ; Restore SI and DI
jcxz deln_w20
xchg di,dx ; Calculate the number of columns
call calc_chars ; displayed
xchg di,dx
deln_w20:
pop bx ; Restore the original line length
sub bx,cx ; and calculate the number of spaces
mov cx,bx ; required to overwrite the data
call space_out
pop cx ; Finally move the cursor back to
jmp bs_out ; its correct place
;
; Delete the contents of the complete line
;
del_line:
mov RL_SAVPOS,0 ; Reset the buffer index
test dx,dx
jz del_l10
call goto_bol ; Jump to the begining of the line
mov di,dx ; calculate the number of display
call calc_chars ; columns it currently takes up
call space_out ; Overwrite with spaces
call bs_out ; Move back to the start of the line
xor si,si ; and update all the initial variables
mov dx,si
mov di,RL_BUFOFF
del_l10:
ret
eject
;
; The following routines manipulate the SAVE Buffer data. Which
; is initialised on entry to this function.
;
; SKIP_ONE_CHAR increments the Save Buffer control variables and
; returns the number of bytes skipped in CX.
;
; On Entry: Standard Registers
;
; On Exit: AX Next Character in Buffer
; CX Character Size (Bytes)
;
skip_one_char:
xor cx,cx
mov bx,RL_SAVPOS ; Update the Save Buffer variables
cmp bx,RL_SAVMAX ; Check the current save buffer is
jae soc_20 ; valid and has not been exhausted.
; Otherwise increment the RL_SAVPOS
mov bx,offset savbuf ; pointer by one character. This
add bx,RL_SAVPOS ; means that the RL_SAVPOS can be
mov al,ds:[bx] ; incremented by 1 or 2 depending on
call char_type ; the contents of the buffer
test ah,CHAR_KANJI
jz soc_10
mov ah,ds:1[bx]
inc cx
soc_10:
inc cx
soc_20:
add RL_SAVPOS,cx
ret
;
;
; BACK_ONE_CHAR decrements the Save Buffer control variables and
; returns the number of bytes skipped in CX.
;
; On Entry: Standard Registers
;
; On Exit: RL_SAVPOS points to previous buffer char
; AX,BX,CX,DX Unknown
;
back_one_char:
push dx
mov bx,offset savbuf ; Get the Buffer address
mov cx,bx ! add cx,RL_SAVPOS ; CX is the Current location
mov dx,bx ; DX is last matching character
boc_10:
cmp bx,cx ; Have we reached the current Char
jz boc_20 ; Yes exit and update buffer
mov dx,bx ; Update last character location
mov al,ds:[bx] ; incremented by 1 or 2 depending on
call char_type ; the contents of the buffer
inc bx
test ah,CHAR_KANJI ; Increment pointer by 2 for a Kanji
jz boc_10 ; character
inc bx
jmps boc_10
boc_20:
sub dx,offset savbuf ; Calculate the character Index
mov RL_SAVPOS,dx ; and save in RL_SAVPOS
pop dx
ret
copy_char:
cmp dx,si ; If at end of line copy characters
jz copy_c5
call next_char ; Otherwise just move by 1
jmp copy_c10
copy_c5:
call skip_one_char ; Calculate Bytes to copy
jcxz copy_c10 ; Skip Update in no characters skipped
sub RL_SAVPOS,cx ; Restore the Buffer Position
jmps copy_a10 ; and copy the data
copy_c10:
ret
copy_till_char:
cmp dx,si ; Copy out if at end of line
jnz move_till_char
call skip_till_char ; Returns index to the next char
sub RL_SAVPOS,cx
jmps copy_a10
move_till_char:
mov RL_SAVPOS,si ; Start search from the current
call skip_till_char ; position
jcxz no_move ; CX=0 - dont move
move_along:
push cx
call next_char ; Shuttle along the line until
pop cx ; we reach the character
loop move_along
no_move:
ret
copy_all:
mov cx,RL_SAVMAX ; Calculate the number of bytes to
sub cx,RL_SAVPOS ; copy from the buffer.
copy_a10:
cmp cx,0 ; do we have nothing to copy
jle copy_a30 ; (or less than nothing..)
push RL_FLAGS ; Save State flags and prevent
or RL_FLAGS,RLF_INS ; SAVPOS being modified
copy_a20:
push cx
and RL_FLAGS,not RLF_KANJI
call skip_one_char ; Return the next character and its
cmp cx,1
jz copy_a25 ; size in bytes
mov RL_KANJI,ax ; Save the Kanji Character and
or RL_FLAGS,RLF_KANJI ; set the control flag
pop bx
dec bx
push bx ; Decrement the Loop Count
copy_a25:
call intsave_char ; Save the character
pop cx ; and repeat till all bytes have
loop copy_a20 ; been copied
pop RL_FLAGS ; Restore State Flags
copy_a30:
ret
skip_till_char:
call get_char ; Get the first character
call save_kanji ; Setup RL_KANJI etc.
push dx
call skip_one_char ; don't match on 1st char
mov dx,cx ; remember we've skipped 1st char
jcxz stc_40 ; buffer exhausted
stc_10:
call skip_one_char ; Get the Next Character
jcxz stc_40 ; Buffer exhausted
add dx,cx ; Update the Total Byte Count
cmp cx,2 ! jz stc_20 ; Was this a Kanji Character
test RL_FLAGS,RLF_KANJI ; No but are we looking for one ?
jnz stc_10 ; Yes so get the next character
cmp al,byte ptr RL_KANJI ; Have we got a matching character ?
jnz stc_10 ; No so look again
jmps stc_30 ; Return Sucess
stc_20: ; Kanji Character in Buffer
test RL_FLAGS,RLF_KANJI ; Are we looking for a Kanji Char
jz stc_10 ; No so try again
cmp ax,RL_KANJI ; Check the character and repeat
jnz stc_10 ; if they donot match
stc_30: ; Character Match
sub dx,cx ; Correct the Total Byte Count
sub RL_SAVPOS,cx ; point to the matching char
xchg cx,dx ; and return the Match Count
pop dx
ret
stc_40: ; No Match
sub RL_SAVPOS,dx ; Restore RL_SAVPOS to orginal value
xor cx,cx ; and return 0000 characters skipped
pop dx
ret
;
; Update the Save buffer with the contents of the users
; line buffer.
;
; On Entry: ES:DI -> Current location in Buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -