📄 editmgr2.asm
字号:
add ax,si
push ax
call _memmove
add sp,6
endif ;PROJECT_QB
@@:
add di,si
jmp SHORT DoInsCh ; ldCur.cb += cbAdd;
OverwriteInsCh:
mov ax,[ipCur.IP_ob]
add ax,si
cmp ax,di
jle DoInsCh
mov di,ax ; ldCur.cb = ipCur.ob + cbAdd;
DoInsCh:
push si
mov al,[char]
cbw
push ax
push [pIns]
call _memset
add sp,6
EndInsCh:
mov [ldCur.LD_cb], di ; Save cached value
mov ax,si
cEnd
;*******************************************************************************
;_DelCh
;
;Purpose:
; Low level routine to delete character from ldCur at specified loc.
;Entry:
; cbDel - # of characters to delete
; ob - where to delete
;Exit:
; ldCur
;Uses:
; cb - temp. for # of bytes
; si - pszDst - buffer destination pointer
; di - pszSrc - buffer source pointer
;Exceptions:
;
;*******************************************************************************
cProc DelCh,<NEAR>,<SI,DI>
parmW cbDel
parmW ob
localW cb
cBegin
;
; Adjust if trying to delete past end of line.
;
mov ax,[ob]
sub ax,[ldCur.ld_cb]
jle DelCh1
cmp ax, [cbDel]
jae DelCh_Exit
sub [ob],ax
sub [cbDel],ax
DelCh1:
cmp ldCur.ld_cb,0 ;make sure something to delete
je DelCh_Exit ;brif nothing to delete
cmp [cbDel],0 ;make sure need to delete something
je DelCh_Exit ;brif no need to delete
mov ax,ldCur.ld_cb
cmp [cbDel],ax
jb DelCh2
xor ax,ax
mov [ldCur.ld_cb],ax
jmp short DelCh_Exit
DelCh2:
cmp [ob],ax ;check if deleting from with line
jae $I535 ;brif deleting to right of eol
sub ax,[ob] ;trim buffer back display does rest
mov [cb],ax
mov di,[ob]
add di,ldCur.ld_prgch ;di - pointer into buffer
mov ax,di ;ax - prgch[ob]
sub ax,[cbDel]
mov si,ax ;dst
jmp SHORT $L20049
; UNDONE: fix this
;!!! why isn't this either a memcpy? if not then make it string move!
;While loop till cb == 0 move buffer down by cb.
$WC536:
mov al,[di]
inc di
mov [si],al
inc si
$L20049:
mov ax,[cb]
dec [cb]
or ax,ax
jne $WC536
;Here after moving buffer down
$I535:
mov ax,[cbDel] ;adjust buffer size
sub ldCur.ld_cb,ax
DelCh_Exit:
cEnd
;*******************************************************************************
;_obGetFirst
;
;Purpose:
; Get first non-whilte space character on line
;Entry:
; ldCur
;
;Exit:
; return - offset to start of text
;Uses:
; si - ob current offset
; di - obLim limit of search with line (ldCur.cb)
; bx
;Exceptions:
;
;*******************************************************************************
cProc obGetFirst,<NEAR,PUBLIC>,<DI>
cBegin
mov di, [ldCur.ld_prgch]
mov cx, [ldCur.ld_cb]
cCall $obGetFirst
cEnd
cProc obGetFirstScratch,<NEAR>,<DI>
cBegin
mov di, [ldEMScratch.ld_prgch]
mov cx, [ldEMScratch.ld_cb]
cCall $obGetFirst
cEnd
cProc $obGetFirst,<NEAR>
cBegin
mov ax, cx
jcxz $obGetFirst_Exit
push ds
pop es
mov al, ' '
mov bx, di
repe scasb
jne NoClear
sub ax,ax
jmp short $obGetFirst_Exit
NoClear:
mov ax, di
sub ax, bx
dec ax
$obGetFirst_Exit:
cEnd
;*******************************************************************************
;_obGetPrev
;
;Purpose:
; Get the indent level for the line above and to the left
; of the current ip. If none then 0 returned.
;Entry:
; ipCur
;Exit:
; return - indent level
;Uses:
; si == indent level of ldCur
;Exceptions:
;
;*******************************************************************************
cProc obGetPrev,<NEAR,PUBLIC>,<SI,DI>
cBegin
mov ax, [ipCur.ip_ob]
mov cx, [ldCur.ld_cb]
jcxz GP1
cCall obGetFirst
GP1:
mov si, ax
mov di, [ipCur.ip_oln]
GP2:
mov ax, di ; If oln == 0 return 0
or ax, ax
jz GP4
dec di
cCall GetLineScratch,<di>
mov cx, [ldEMScratch.ld_cb] ; Ignore blank lines.
jcxz GP2
cCall obGetFirstScratch
cmp ax,si
jae GP2
GP4:
cEnd
;*******************************************************************************
;_RefreshScreen
;
;Purpose:
; Redraw the entire visible screen
;Entry:
; none.
;Exit:
; none.
;Uses:
; none.
;Exceptions:
;
;*******************************************************************************
cProc RefreshScreen,<NEAR,PUBLIC>
cBegin
mov bx,-1 ;refresh max. number of lines
sub ax,ax
cCall RefreshLines,<ax,bx> ;refresh 0 to max. lines
cEnd
;*******************************************************************************
;_RefreshLines
;
;Purpose:
; Redraw the specified line if present on screen
;Entry:
; olnFirst - first line offset to redraw
; olnLast - last line offset to redraw
;Exit:
; none.
;Uses:
; olnBottom - offset for bottom of screen
;Exceptions:
;
;*******************************************************************************
cProc RefreshLines,<NEAR,PUBLIC>,<SI,DI>
parmW olnFirst
parmW olnLast
cBegin
test [emState], ES_NOREDRAW
jnz $EX558
mov si,[olnFirst]
mov di,[olnLast]
cmp si,di
jbe $I561 ;brif olnFirst <= olnLast
;Here if order was wrong on range
xchg si,di
;Here when order is correct
$I561:
;!!! get structure definition for this
mov cx,[cLinesCur]
add cx,[pdCur.pd_olntop]
dec cx
cmp cx, si ;if first line below screen
jl $EX558 ;then exit ;????
cmp [pdCur.pd_olntop],di ;or if last line above screen
ja $EX558 ;exit
cmp [pdCur.pd_olntop],si
jbe $I564 ;brif first above top of screen
mov si,[pdCur.pd_olntop] ;make first in range top of screen
$I564:
cmp cx, di
jae $L20052 ;brif if last above bottom of screen
mov di, cx
jmp SHORT $L20052
;Loop refreshing line at a time within range that is entirely on screen
$WC566:
cCall RefreshLine,<si>
inc si
$L20052:
cmp si,di ;
jbe $WC566 ;brif olnFirst <= olnLast
$EX558:
cEnd
cProc RefreshLine,<NEAR,PUBLIC>,<SI,DI>
parmW ln
localW row
localW olnFirst
localW obFirst
localW olnLast
localW obLast
localW attrSave
localW ob
localW cb
localW obRight
localW pLineAttr
cBegin
mov si,[ln]
test [emState], ES_NOREDRAW
jz RL1
jmp RL_Exit
; Do nothing if line is not in the window
RL1:
mov ax,[pdCur.PD_olnTop]
cmp si,ax
jae RL2
jmp RL_Exit
RL2:
add ax,[cLinesCur]
cmp ax,si
ja RL3
jmp RL_Exit
RL3:
mov ax,si
sub ax,[pdCur.PD_olnTop]
mov [row],ax
cCall GetLineScratchPad,<si>
;
; See if we should display the line (or part of it) in reverse video
;
test [emState], ES_NOSELECT
jnz RL6a
mov bx,[pefCur]
cmp [bx.EF_fSelection],0
je RL6a
;
; Get the selection extents
;
lea ax,[olnFirst]
lea bx,[obFirst]
lea cx,[olnLast]
lea dx,[obLast]
cCall BuildSelection,<ax,bx,cx,dx>
;
; See if the entire line should be selected
;
mov ax,si
cmp [olnFirst],ax
ja RL6a
cmp [olnLast],ax
ja RL6
cmp WORD PTR [obLast],0
je RL6a
cmp [olnLast],ax
jne RL6a
RL6:
mov ax,[olnLast]
cmp [olnFirst],ax
je RL7
mov [obFirst],0
mov [obLast],0ffffH
jmp short RL7
RL6a:
; There is a selection but the line we are refreshing is not part of the
; selected area.
sub ax,ax
mov [obLast],ax
mov [obFirst],ax
jmp short RL7a ; al MUST be zero
;
; At this point we are ready to build the line attributes
;
RL7:
mov bx,[pefCur]
mov al, [bx.EF_fSelection]
RL7a:
mov di,[CurattrCur]
or al, al
jnz RL8
test [emState], ES_MULTILINE
jz RL8
test [ldEMScratch.ld_flags],ld_fDirty
jne RL8
cmp si,[clnCur]
jae RL8
;
; There is no selection, the line is not dirty, and not single line edit field.
; So, ask the application for the line attributes.
;
cCall GetLineAttrs,<di>
jmp SHORT RL9
RL8:
mov ax,[obFirst]
mov [rgLineAttr0.LA_cb],ax
mov [rgLineAttr0.LA_attr],di ; attrDefault
mov ax,[obLast]
sub ax,[obFirst]
mov [rgLineAttr1.LA_cb],ax
cCall SetInverseIsa, <di> ; sets up isaUserMax-1
mov [rgLineAttr1.LA_attr],ax
mov [rgLineAttr2.LA_cb],0ffffH
mov [rgLineAttr2.LA_attr],di ; attrDefault
mov [rgLineAttr3.LA_attr],0ffffH
lea ax,[rgLineAttr0]
RL9:
mov [pLineAttr],ax
;
; Ok now, let's print out the line.
;
mov ax,[CurattrCur]
mov [attrSave],ax
mov ax,[cColumnsCur]
add ax,[pdCur.PD_obLeft]
mov [obRight],ax
mov [ob],0
RL10:
mov bx,[pLineAttr]
cmp WORD PTR [bx.LA_attr],-1
je JRL15
mov ax,[obRight]
cmp [ob],ax
jae JRL15
mov ax,[bx.LA_cb]
and ax,07fffH ;clear high bit, so no overflow in add
mov [cb],ax
mov ax,[pdCur.PD_obLeft]
cmp [ob],ax
jae RL12
mov ax,[cb]
add [ob],ax
mov ax,[pdCur.PD_obLeft]
cmp [ob],ax
jae RL11
jmp short RL13
JRL15:
jmp RL15
RL11:
mov ax,[ob]
sub ax,[pdCur.PD_obLeft]
mov [cb],ax
mov ax,[pdCur.PD_obLeft]
mov [ob],ax
RL12:
cmp WORD PTR [cb],0
je RL13
mov di,[pLineAttr]
mov ax,[di.LA_attr]
mov [CurattrCur],ax
mov si,[ob]
mov bx,[ldEMScratch.LD_prgch]
add si,bx
ifdef KANJI
cmp si,bx
je NoKanjiPad
cCall PchPrevDbcs,<si,bx>
cCall PchNextDbcs,<ax>
cmp si,ax
je NoKanjiPad
mov byte ptr [si],' '
NoKanjiPad:
endif ; KANJI
mov cx,[ob]
sub cx,[pdCur.PD_obLeft]
cCall TextOut,<[pwndEditCur],cx,[row],si,[cb],[CurattrCur]>
mov ax,[cb]
add [ob],ax
RL13:
add [pLineAttr],size LINEATTR
jmp RL10
RL15:
mov ax,[attrSave]
mov [CurattrCur],ax
ifdef KK_UNIT
mov ax,[ln]
cmp ax,[ipCur.ip_oln]
jne @F
mov ax,[ipCur.ip_ob]
sub ax,[pdCur.PD_obLeft]
cCall DisplayKKBuf,<[pwndEditCur],ax,[row]>
@@:
endif ; KK_UNIT
RL_Exit:
cEnd
;*******************************************************************************
; _HomeScn
;
;Purpose:
; Move cursor to top of screen
;Entry:
; pdCur
; ipCur
;Exit:
; ipCur
;Uses:
; none.
;Exceptions:
;
;*******************************************************************************
cProc HomeScn,<NEAR,PUBLIC>
cBegin
cCall UpdateLine
mov ax,[pdCur.pd_olntop]
mov [ipCur.ip_oln],ax ;make current line top of screen
cEnd
;*******************************************************************************
;_EndScn
;
;Purpose:
; Move cursor to end of screen
; - the global register set (grs)
; - the module register set (mrsCur and bdtMrs), via MrsMake
;Entry:
; pwndEditCur
; ipCur
; pdCur
;Exit:
; ipCur
; pdCur
;Uses:
; none.
;Exceptions:
; If run out of memory trying to allocate a buffer, runtime error
; "Error during Initialization" or some such.
;*******************************************************************************
cProc EndScn,<NEAR,PUBLIC>
cBegin
cCall UpdateLine
mov ax,[cLinesCur] ;pwndEditCur.cLines
add ax,[pdCur.pd_olntop] ;set ip to bottom of screen
dec ax
mov cx, [clnCur]
cmp ax, cx
jbe $I597
mov ax, cx
$I597:
mov [ipCur.ip_oln],ax
cEnd
;*******************************************************************************
;_BeginPgm
;
;Purpose:
; Move cursor to beginning of program
;Entry:
; none.
;Exit:
; ipCur
; pdCur
;Uses:
; none.
;Exceptions:
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -