📄 txtmgr.asm
字号:
;
DelNoCopy:
cmp [cbDel],0 ;was any text deleted?
jne DelAfterDel ;brif so
; - look for special deleted opcodes
jmp DelGoodExit ;no pcode deleted - exit
DelAfterDel:
push di ;pass [otxDelFirst]
PUSHI ax,<CODEOFFSET tOpDel>
call TxtFindOp ;ax = offset to 1st interesting opcode
;ax = offset to 1st opcode of interest
;dl = [txtFindIndex]
DelLoop:
cmp ax,[otxDelLast]
jae J1_DelDone ;brif reached end of deleted range
xchg si,ax ;si = offset to current opcode (otxCur)
xchg ax,dx ;al = [txtFindIndex]
cmp al,DEL_bolMax
ja DelNotBol ;brif not a label or bol opcode
cmp al,DEL_labMax
ja DelNotLab ;brif not a label definition opcode
lea ax,[si+4] ;ax = text offset to oNam field
call GetWOtx ;ax = oNam for label
xchg bx,ax ;pass oNam in bx
mov al,NM_fLineNumLabel ;pass mask to reset in al
call ResetONamMask ;reset bit that says the label by
; this name is defined
DelNotLab:
mov al,[txtFindIndex]
cmp al,DEL_bolMin
jb J1_DelNext ;brif not a begin of line opcode
dec [txdCur.TXD_cLines] ;decrement text table's line count
cmp al,DEL_bolInclMin
jb J1_DelNext ;brif not included line
dec [txdCur.TXD_cLinesIncl] ;decrement text table's INCLUDE line cnt
jmp SHORT J1_DelNext
DelNotBol:
cmp al,DEL_NonSubRefMax
jle DelNotSubRef ;brif not a procedure reference
DbAssertRelb [txdCur.TXD_SCANSTATE],ne,SS_SUBRUDE,CP,<TxtDelete: tbl in SUBRUDE>
lea ax,[si+4]
call GetWOtx ;ax = oPrs referenced
call pPrsOPrs ;es:bx points to Rs
cmp PTRRS[bx.PRS_procType],PT_SUB
jne J1_DelNext ;brif not a sub Prs
or PTRRS[bx.PRS_flags2],FP_RefDeleted ;[38]set flag indicating that
; a ref has been deleted
or [flagsTm2],FTM2_PrsRefDeleted ;set flag indicating
; that a Prs Ref has been deleted
jmp SHORT J1_DelNext
J1_DelDone:
DJMP jmp SHORT DelDone
DelNotSubRef:
cmp al,DEL_forMax
ja DelNotFor ;brif FOR pcode not being deleted
.errnz DEL_forMax - DEL_opStForStep
je DelForStep ;brif deleted a FOR STEP
inc [cForDel]
jmp SHORT J1_DelNext
DelForStep:
inc [cForStepDel]
jmp SHORT J1_DelNext
DelNotFor:
cmp al,DEL_watchMax
ja NotDelWatch ;brif WATCH pcode not being deleted
call WatchDeleted ;reduce number of lines allocated to
; watch window, remember to redraw
; DebugScreen
J1_DelNext:
jmp SHORT DelNext
NotDelWatch:
cmp al,DEL_opStEndProc
jne DelNotEndProc ;brif not END DEF/SUB/FUNCTION
;user is deleting an END SUB or END FUNCTION
and [prsCur.PRS_flags],NOT FP_ENDPROC
jmp SHORT DelNext
DelNotEndProc:
cmp al,DEL_opAVtRf ;[1]
je DoResetCommon ; brif deleting a DIM statement
cmp al,DEL_opStCommon
jne DelNotCommon ;brif not COMMON
DoResetCommon:
DbAssertRelB cChansOpen,e,0,CP,<TxtDelete: Tried to delete COMMON while load is active>
call ResetCommon ;Eliminate all common type tables
call SystemDescanCP ;scanner will rebuild common tables
jmp SHORT DelNext ; for each txt tbl next scan
DelNotCommon:
cmp al,DEL_opBreakPoint
jne DelNotBreakPoint ;brif no Break Point set on this line
or [flagsTm],FTM_BpDeleted ;we deleted a break point
jmp SHORT DelNext
DelNotBreakPoint:
DbAssertRelB cChansOpen,e,0,CP,<TxtDelete: Tried to delete AS usrtyp while load is active>
DbAssertRelB al,e,DEL_opAsType,CP,<TxtDelete err 3>
;DELETING AS <usertyp>
;remember to call PreScanAsChg before scanning program
mov ax,si ;pass text offset in ax
mov bx,di ;pass otxDelFirst in bx
mov cx,[otxDelLast] ;pass otxDelLast in cx
call ChkLastAsText ;if last instance of 'x AS user-type'
; in module, reset x's NM_fAs name
; table bit and set module's
; FM_asChg bit so we'll call
; PreScanAsChg before scanner
DelNext:
push si
PUSHI ax,<CODEOFFSET tOpDel>
call TxtFindNextOp
jmp DelLoop
DelDone:
mov cx,[cbDel]
cmp [cbBigIns],0
je DelNotBig
sub [cbBigIns],cx
DelNotBig:
FloadActive ;don't update linked lists if Loading
jne DelNoThreads
push di ;pass otxDelFirst
push cx ;pass cbMove
call TxtDelThread ;update linked lists for delete
DelNoThreads:
mov si,[otxDelLast]
push si ;pass otxDelLast
push di ;pass otxDelFirst
call TxtMoveDown ;Actually delete text from text table
sub si,di ;si = cbDel
test [flagsTM],FTM_SaveProcHdr
jne DelGoodExit ;brif SaveProcHdr was in critical
; section. A temp txt table is active,
; which is NOT oRsCur.
;Update program counter and any other runtime text pointers
push di ;pass otxDelFirst
sub ax,ax
push ax ;pass cbIns (0)
push si ;pass cbDel
push ax ;fTestOnly = FALSE
call UpdatePcs
;pass information about the edit to UpdatePrs in static struct updPrs
mov ax,[grs.GRS_oRsCur]
mov [uprs.UPRS_oRsEdit],ax
mov [uprs.UPRS_otxEdit],di ;save otxDelFirst
mov [uprs.UPRS_cbDel],si
mov [uprs.UPRS_cbIns],0
mov bx,CPOFFSET UpdatePrs
call ForEachPrsInPlaceCPSav ;Preserve callers oRs
DelGoodExit:
mov ax,sp ;return TRUE (non zero)
DelExit:
or ax,ax ;set condition codes for caller
cEnd
;-------------------------------------------------------------------
; If delete would prevent continuing, & user wants to back out of edit,
; if bigEditState != BIG_EDIT_FALSE, then bigEditState = BIG_EDIT_CANCEL
; return without changing anything
;
DelBackOut:
cmp [bigEditState],BIG_EDIT_FALSE
je DelNotBigEdit ;brif not in a BigEdit
mov [bigEditState],BIG_EDIT_CANCEL
DelNotBigEdit:
sub ax,ax ;return FALSE
jmp SHORT DelExit
;**************************************************************
; ushort FAR TxtChange(otxDelFirst, otxDelLast, fNoInsert)
;
; Purpose:
; The editor or ASCII Loader calls TxtChange() to
; replace zero or more lines with zero or 1 line of text
; in the current text table. If no new text is to be inserted,
; but only deleted, call TxtChange with fNoInsert <> 0.
; TxtDescan() should be called before this, to ensure that
; the text table is descanned to SS_PARSE state.
;
; Note: This function need not worry about the case where the
; user is trying to insert something between a line with $INCLUDE
; and an included line below it, because the user interface
; does not allow ANY editting while 'View/Include Files' is active.
;
; Entry:
; grs.oMrsCur, grs.oPrsCur have their usual meaning
; ps.bdpSrc contains source line to be inserted
; parm1: ushort otxDelFirst - text table offset to opBol
; opcode for 1st line to delete. It also indicates where
; new line is to be inserted.
; parm2: ushort otxDelLast - text table offset to opBol
; opcode beyond last line to delete
; parm3: ushort fNoInsert - non-zero if no pcode should be inserted
; (i.e. only text deletion should occur
;
; Exit:
; If no errors were encountered,
; the return value = txtErr.errCode = 0.
; Else if an error occurred which we will overlook at entry time,
; but which must be considered fatal when we are going through
; each module's ReParse list in preparation to execute the program,
; return value = 0,
; txtErr.errCode = an offset into the QBI Message Table
; (MSG_xxx) or, if high bit is set, ps.bdpError contains the
; parser-built ASCII error message,
; The text is inserted in text table in an opReParse opcode.
; txtErr.fDirect is set to FALSE,
; txtErr.oMrs identifies the module with the error,
; txtErr.oPrs identifies the procedure (if any) with the error,
; txtErr.otx is an offset into the text table where the error
; was detected (otxDelFirst).
; txtErr.oSrcErr contains the column offset into the source line
; to the offending token.
; Else if its a really serious error (like out-of-memory or syntax error),
; all txtErr fields are set as above, and return value = txtErr.errCode
;
; Major Steps of Algorithm:
; Delete the pcode to be replaced (taking some special action for
; some opcodes being deleted), giving user a chance to
; back out of edit if edit would prevent continuing.
; Parse line to be inserted, checking for variable manager/syntax errors,
; again giving user a chance to back out of the edit
; Scan pcode to be inserted for rude edits, again giving user a chance
; to back out of the edit. This pcode scan can result in calling
; CantCont(), ModuleRudeEdit(), SystemDescan().
; If statement contains variable mgr/syntax errors, change pcode to
; be inserted to an opReParse, which has the actual ASCII source
; as an operand.
; Insert the new pcode (taking some special action for some opcodes
; being inserted).
;
;**************************************************************
cProc TxtChange,<PUBLIC,FAR,NODATA>,<si,di>
parmW otxDelFirst
parmW otxDelLast
parmW fNoInsert
localW fInclude
localW cbIns
localW result
localW otxMrsDelFirst
localW oRsPreParse
localW oPrsPreParse
localW otxEndProc
localB flagsPrsPreParse
localB flagsTc
FTC_GotEndProc EQU 1
FTC_GotEnterProc EQU 2
cBegin
DbAssertRelB [txdCur.TXD_scanState],ne,SS_EXECUTE,CP,<TxtChange err1>
DbChk Otx,otxDelFirst ;error if > txdCur.bdlText.cbLogical
DbChk Otx,otxDelLast ;error if > txdCur.bdlText.cbLogical
mov si,[otxDelFirst]
sub ax,ax
mov [txtErr.TXER_errCode],ax
mov [ps.PS_errCode],ax
mov [result],ax
;We need to init these vars in case we don't call ParseLine.
;(i.e. maybe the caller is only deleting text)
mov [flagsTc],al ;default local flags to 0
mov [fInclude],ax ;assume we'll see no $INCLUDE directive
mov ax,[grs.GRS_oPrsCur]
mov [oPrsPreParse],ax
cmp [bigEditState],BIG_EDIT_ACTIVE
je BigEditActive ;BpDeleted set by first BigEdit Call
; to TxtChange.
and [flagsTm],NOT FTM_BpDeleted ;clear BP deleted flag
BigEditActive:
cmp [bigEditState],BIG_EDIT_CANCEL
jne TcNotBECancel ;brif not backing out of BigEdit
jmp TcRet ;backout of BigEdit if user CANCELed
TcNotBECancel:
FLoadActive
je TcNotLoading ;brif not loading a file
jmp TcLoading1 ;brif LOADing a file - makes ASCII
; load MUCH faster.
;We're not loading, make sure there is enough memory for the
;inserted and deleted text, otherwise, it would be possible for
;Search/Change to loose an existing line entirely - too rude.
;We loosely approximate size of pcode being inserted as 200.
;Don't check it for edits of immediate (FM2_File=0), since that
;could prevent users from executing a SYSTEM statement in
;the immediate window.
TcNotLoading:
test [mrsCur.MRS_flags2],FM2_File
je NotOmErr ;brif not editing a file
cmp [fNoInsert],0 ;is there any text to parse and insert?
jne NotOmErr ;brif not - no need to reserve space
; otherwise, user could get out of
; memory, and not be able to delete
; any text to recover - locked up.
PUSHI ax,200d
call TxtFree
jne NotOmErr
jmp TcOmErr
NotOmErr:
;********************* start of revision [56]
;No edits on pcode tables are allowed if there is a return address to
;the direct mode buffer and the direct mode buffer contains a label reference
mov al,[grs.GRS_flags]
and al,FG_RetDir+FG_OtxInDir
cmp al,FG_RetDir+FG_OtxInDir
jne @F ;brif NOT (RetDir & OtxInDir)
test [mrsCur.MRS_flags2],FM2_NoPcode
jnz @F ;brif this not a pcode buffer
call AskCantCont_CP ;ask user if he wants to continue
djmp jz TcRetGoDirect ;brif user wants to backout
@@:
;*********************** end of revision [56]
;we're not loading, set DEFtypes etc. based on insert point.
;if in module, traverse DEF-FN chain to otxDelFirst
;and if we're inside a DEF-FN, PrsActivate that prs
mov bx,si ;bx = otxDelFirst
cmp [bigEditState],BIG_EDIT_ACTIVE
jne TcFindPrs ;If not in a big edit, use passed
; otxDelFirst.
;If a big edit is active, we need to stop searching the DEF FN chain
; at otxBigIns, since txt change gets called multiple times for a
; big edit. If we didn't do this, splitting a line immediately
; prior to a DEF FN could cause us to search a Bogus DEF FN chain.
mov ax,[otxBigIns] ;get oTx for start of big edit
.errnz UNDEFINED+1
inc ax ;UNDEFINED if first call to txtchg
je TcFindPrs ;brif so, use oTxDelFirst
dec ax ;get back otxBigIns
xchg ax,bx ;bx = oTxBigIns
TcFindPrs:
push bx ;pass offset to 1st byte of edit
call OPrsOfOtx ;ax = oPrs if si falls in DEF FN
inc ax ;test for UNDEFINED
je TcNotDefFn
;if we are in a big edit, we can't depend upon DEF-FN chain after
; the first call to TxtChange. Therefore, ask rude edit, to ensure
; that there is no prs for the DEF-FN. Subsequent calls will use
; the DEF FNs mrs.
cmp [bigEditState],BIG_EDIT_ACTIVE
jne TcNotBigE ;DEF-FN chain is ok.
; Assert that TcUndo won't take unexpected actions for early termination.
DbAssertRel [cbBigIns],e,0,CP,<TxtChange: DEF FN-error1>
DbAssertRel [bdlTxtScrap.BDL_status],e,NOT_OWNER,CP,<TxtChange: DEF FN-error 2>
call AskRudeEdit ;see if user wants to back out of edit
jne short TcNotDefFn ;use module Rs.
jmp TcUndo ;brif user wanted to back out of edit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -