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

📄 txtmgr.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;
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 + -