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

📄 txtmgr.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:


TcNotBigE:
	dec	ax			;restore ax = oPrs we're in
	push	ax			;otxDelFirst falls within a DEF FN
	call	PrsActivateCP		;activate it (for var mgr)

;     *--------------------------------------------------------------
;     * Examine the block of pcode being deleted opcode by
;     * opcode, taking special action for each opcode of
;     * interest.  May result in AskCantCont, ModuleRudeEdit, SystemDescan.
;     * 
;     *---------------------------------------------------------------

TcNotDefFn:
	test	[mrsCur.MRS_flags2],FM2_NoPcode
	jne	TcInBigEdit		;brif editing document or immediate
					; window - no need to ever back out
					; of edit.  If we didn't do this,
					; we could get out-of-memory error
					; when trying to delete immediate window
					; history, which we do when we're
					; trying to recover from tight memory
	cmp	[bigEditState],BIG_EDIT_FALSE
	jne	TcInBigEdit		;brif we're in a BigEdit, if so
					;TxtStartBigEdit already set this
					;flag, and TxtDelete may have been
					;called independantly of TxtChange
	mov	[fFillScrap],1		;tell TxtDelete to copy text to scrap
					; so we can back-out of edit
TcInBigEdit:
	push	si			;pass otxDelFirst
	push	[otxDelLast]
	call	TxtDelete		;delete the text
	mov	[fFillScrap],FALSE
	jne	TcDelOk			;brif TxtDelete returned FALSE in ax

TcRetGoDirect:				
	mov	[result], MSG_GoDirect	

J1_TcRet:
	jmp	TcRet			;brif user wants to back out of edit
					;just return without doing anything

;Set up ps.tEtCur[] with the default types for this point in the source
;
TcDelOk:
					;save current oRs for reactivation
					; after Redefining/Deleting undefined
					; prs entries. It is guaranteed that
					; that this is safe, since SUB/FUNCs
					; only get PrsFreed at ?rsDiscard time.
					; DEF FNs have the Mrs active at edit
					; time.
	call	ChkAllUndefPrsSaveRs	;Find new "defining" references for all
					; Prs entries which had defining.
					; references deleted. If no more
					; references to prs exist, free it.
	cmp	[fNoInsert],0		;is there any text to parse and insert?
	jne	J1_TcRet		;brif not - finished

; We can't call OtxDefTypeCur if accumulating opReparses for BigEdit,
; since the linked list are not updated until we start processing the
; reparse list at TxtEndBigEdit time.  The processing of the reparse
; list will insure the the DEF type state is accurate.

	cmp	[bigEditState],BIG_EDIT_ACTIVE
	je	TcDoReParse		;brif we're accumulating BigEdit
					;changes, but TxtEndBigEdit has not
					;been called yet
	mov	ax,si			;ax = text offset
	call	OtxDefTypeCur

TcLoading1:
	test	[mrsCur.MRS_flags2],FM2_NoPcode
	je	TcNotDoc		;brif not a document module

	;this module is not BASIC source, just text (maybe Scrap,
	; command window, document file)
	
TcDoReParse:
	call	ResetDstPbCur		;so ParseUndo won't do anything
	jmp	TcReParse1

;Parse the source line to pcode
TcNotDoc:
	;tell parser (and type manager) to recognize any TYPEs which have been
	; declared before the place this line is being inserted.  This
	; prevents forward referencing of types, which BASCOM cannot support.
	
	mov	[ps.PS_otxLine],si	

	;Call the parser to parse the source line.  grs.oPrs is updated
	;if a SUB/FUNCTION/DEF statement for an as yet undefined procedure
	;is parsed, in which case, the we insert the text at the beginning
	;of the new text table.
	
	mov	ax,[grs.GRS_oPrsCur]
	mov	[oPrsPreParse],ax
	mov	ax,[grs.GRS_oRsCur]	;save Entry so we can tell UI to
	mov	[oRsPreParse],ax	; display new text table if we create
					; a new SUB/FUNCTION.
	mov	al,[prsCur.PRS_flags]	;get prs flags in case we insert a
	mov	[flagsPrsPreParse],al	;SUB/FUNCTION statement.  If we are
					; just renaming then FP_DEFINED will
					; have be cleared when the Sub/Func
					; was deleted.

Retry:
	mov	[ps.PS_flags],0
	call	ParseLine
	jnc	TcNoParseErr		;brif parser encountered no error

	;ParseLine encountered some error
	mov	ax,[oPrsPreParse]
	call	TxtParseUndo
	test	[ps.PS_flags],PSF_UndoEdit
	jne	J1_TcUndo		;brif user said he wants to back out
					; of the edit while we were in ParseLine
					; (i.e. ParseLine called AskCantCont)
	test	BYTE PTR [ps.PS_errCode + 1],PSERR_fRude / 100h
	je	TcNotRude		;brif error isn't cause for a rude-edit

	;Variable manager returned an error code which
	;means a RudeEdit is being performed.
	;Save the line in an opReParse, but do not report the error to
	;the user.  SsDescan the module to SS_Rude (if the user wants
	;to go through with the edit).
	;See if user wants to back out of edit or descan to SS_RUDE
	
	call	AskRudeEdit		;see if user wants to back out of edit
	jne	TcNotRude		;brif user didn't back out of edit
J1_TcUndo:
	jmp	TcUndo			;undo delete (if any) and return

;See if the parser wants us to try parsing this line again.  This can
;happen when:
; We saw something that made us need to ModuleRudeEdit, but part
;     of the line's pcode had already been emitted in SS_PARSE
; Variable manager could not add a variable, because variable heap
;     was locked (because we can CONTinue).  Parser called AskCantCont
;     and now wants us to try again (much easier than trying to call
;     varmgr again from within parser).
;
TcNotRude:
	test	[ps.PS_flags],PSF_fRetry
	jne	Retry			;brif ParseLine wants us to try again
	jmp	SHORT TcParseErr	

TcNoParseErr:				
	
;     *--------------------------------------------------------------
;     * At this point, source line has been parsed with no errors.
;     * Examine the block of pcode being inserted opcode by
;     * opcode, calling a text-mgr routine for each opcode of interest.
;     * Each of these routines in addition to doing other work,
;     * returns a value which will cause either
;     * No Action, ModuleRudeEdit(), SystemDescan(), or CantCont().
;     * 
;     * NOTE: When reviewing changes to this block, make sure it isn't possible
;     * to take some state-changing action, then encounter an error which
;     * causes the edit to be discarded (AskCantCont or MakeOpReParse).
;     * In general, it is safer to 'remember' state changing actions to
;     * be taken, and take them when the pcode has actually been inserted.
;     *
;     *--------------------------------------------------------------

	call	ChkAllUndefPrsSaveRs	;check all undefed prs entries
					;in case this was a rename

	push	[ps.PS_bdpDst.BDP_pb]
	PUSHI	ax,<CODEOFFSET tOpPreIns>
	call	TxtFindOpDS		;ax = ptr to 1st interesting opcode
PiLoop:
	cmp	dl,PI_opEot
	je	J1_PiDone		;brif done with loop
	xchg	di,ax			;di = ptr to current opcode
	sub	dh,dh			;dx = dispatch index
	shl	dx,1			;dx = dispatch offset
	mov	ax,di			;ax = pointer to opcode of interest
	sub	di,[ps.PS_bdpDst.BDP_pb] ;convert ptr to offset in case
 					; dispatched function causes
					; ps.bdpDst to move
	mov	bx,dx			;bx = dispatch offset
	jmp	WORD PTR cs:PiDispatch[bx]

;All the PiOpxxx dispatches either branch to an error handler, or PiNext
PiNext:
	add	di,[ps.PS_bdpDst.BDP_pb] ;convert offset back to pointer
	push	di			;pass otxCur
	PUSHI	ax,<CODEOFFSET tOpPreIns>
	call	TxtFindNextOpDS		;ax = pointer to next opcode of interest
	jmp	SHORT PiLoop

J1_PiDone:
	jmp	SHORT PiDone		;finished with loop

TcParseErr:				
	mov	ax,[ps.PS_oSrcErr]
	mov	[txtErr.TXER_oSrc],ax
	mov	ax,[ps.PS_errCode]
	mov	dx,ax
	.errnz  PSERR_fAsciiMsg - 8000h	;TxtChange callers assume it is high bit
	and	ah,(PSERR_fAsciiMsg + PSERR_errCode) / 100h
					;mask off parser flags
	;pass error code in ax to TcReParse or TcAlert
	test	dh,PSERR_fAlert / 100h
	jne	TcAlert			;serious error, event at entry time,
					; let alone reparse time
	jmp	SHORT TcReParse		;brif not a serious error

;ax = error code
TcAlert0:
	mov	[txtErr.TXER_oSrc],UNDEFINED
					;for txtmgr detected errors, we cant 
					;detect the column, compute from otx
	
	;Encountered some error, make sure entry prs is active before
	;Undoing the change.  This solves the bug where you enter a
	;SUB line and the SUB already exists, but is undefined
	; (SUB stmt is a reparse).  The line parses without error, and
	;the parser changes to the new prs.  When we call PrsMake, we
	;get a duplicate definition error.  We were getting here with
	;the wrong prs active.
	
	mov	bx,[oPrsPreParse]
	cmp	bx,[grs.GRS_oPrsCur]
	je	TcAlert 		;brif parser didn't move into a new PRS
	push	ax			;save error code
	push	bx
	call	PrsActivateCP		;get back to module level/old prs
	pop	ax			;recover error code
TcAlert:
	cmp	[fSyntaxCheck],0
	je	TcReParse		;brif user has disabled editor
					; syntax error reporting
	mov	[result],ax		;serious error - return code in ax
TcReParse:
	mov	[txtErr.TXER_errCode],ax
TcReParse1:
	mov	ax,[oPrsPreParse]
	call	TxtParseUndo		;undo any changes to prs table or
					; name table which parsing this
					; line caused.

	test	[ps.PS_flags],PSF_fRudeIfErr
	je	MakeOpRp

	;Some irreversible action took place, like calling varmgr to
	;create a CONSTant, and then some error took place.  The user
	;already said he didn't want to CONT before PSF_fRudeIfErr was
	;set, so its ok to blow away the module's variable table.
	
	call	ModuleRudeEdit	
MakeOpRp:
	call	MakeOpReParse
	and	[flagsTc],NOT (FTC_GotEndProc+FTC_GotEnterProc)
	jmp	SHORT TcPrescanDone	;don't call LoadEnterProc, LoadExitProc

;si = otxDelFirst
PiDone:
	FLoadActive
	jne	TcPrescanDone		;brif LOADing a file
	test	[txdCur.TXD_flags],FTX_mrs
	jne	TcPrescanDone		;brif we're in a module's text table

	call	ChkInsProc		;see if valid line to insert in proc
	je	TcPrescanDone		;brif valid line
	jns	TcAlert0		;brif illegal
	jmp	J1_TcUndo		;user wants to back out of edit

;MakeOpReParse could have resulted in an out-of-memory error
;check for it
;si = otxDelFirst
;
TcPrescanDone:
	mov	ax,[ps.PS_errCode]
	cmp	al,ER_OM
	je	J1_TcOmErr		;brif out-of-memory error

;     *--------------------------------------------------------------
;     * At this point, the user does not want to back out of the edit
;     * for the sake of edit & continue, and we are not going to
;     * convert the line to an opReParse due to errors.
;     *--------------------------------------------------------------

	sub	[ps.PS_bdpDst.BDP_cbLogical],2 ;don't count opEot as part
					   ; of the line to be inserted

;make room for new text by copying old text up in memory
;making sure there's enough free space in the current text table
;to insert the pcode we want to insert
;si = otxDelFirst
;
TcDoMove1:
	mov	ax,[ps.PS_bdpDst.BDP_cbLogical]
	mov	[cbIns],ax
	call	TxtInsert		;insert ps.bdpDst in text table @ si
	je	J1_TcOmErr		;brif out-of-memory

;     *--------------------------------------------------------------
;     * If we've gotten a SUB or FUNCTION statement
;     *    Move SUB/FUNCTION statement to a new PRS text table,
;     *    generating synthetic DEFxxx statements, and keeping leading
;     *    comments in SUB/FUNCTION's text table.
;     *
;     * NOTE: LoadEnterProc modifies ps.bdpDst
;     * It also moves REMs from the module table to the start of
;     * the procedure text table, since these REMs may be a proc header.
;     * otxDelFirst (si) is updated to reflect this insert.
;     * 
;     *--------------------------------------------------------------
;
TcAfterIns:
	test	[flagsTc],FTC_GotEnterProc
	je	TcNoEnterProc		;brif not inserting SUB/FUNC stmt
	sub	si,[txdCur.TXD_bdlText_cbLogical]
	push	[otxMrsDelFirst]
	call	LoadEnterProc		;move pcode from module to proc tbl
	jne	TcNotOm3
	call	PrsDeactivate		;make module active for error recovery
J1_TcOmErr:
	jmp	TcOmErr			;brif out-of-memory error

TcNotOm3:
	;update otxDelFirst after copying leading remarks, defints etc. to prs
	add	si,[txdCur.TXD_bdlText_cbLogical]

;     *--------------------------------------------------------------
;     * Call TxtInsUpdate to examine every opcode which was inserted
;     * in the text table, taking any opcode specific action required.
;     * 
;     *--------------------------------------------------------------
;
TcNoEnterProc:
	mov	bx,si			;bx = updated otxDelFirst
	add	bx,[cbIns]		;bx = offset beyond inserted pcode
	call	TxtInsUpdate		;update program counter and other
					; static entries which are affected
					; by pcode movement.
	je	J1_TcOmErr		;brif out-of-memory

	cmp	[bigEditState],BIG_EDIT_FALSE
	je	TcNotInBigEdit		;brif we're not accumulating BigEdit
					; changes
	test	[flagsTc],FTC_GotEnterProc 
	jnz	TcNoIncr		;don't increment cbBigIns if proc
	mov	ax,[cbIns]		
	add	[cbBigIns],ax		;remember how much text we've inserted
TcNoIncr:
	cmp	si,[otxBigIns]
	jae	TcNotInBigEdit
	mov	[otxBigIns],si		;remember base of inserted pcode
					; (so we can later back out of BigEdit)

;     *--------------------------------------------------------------
;     * If we've gotten an END SUB or END FUNCTION statement
;     * restore the module's text table.
;     * 
;     *--------------------------------------------------------------
;
TcNotInBigEdit:
	test	[flagsTc],FTC_GotEndProc
	je	TcNoExitProc
	FLoadActive
	je	TcNoExitProc		;brif not LOADing a file
	call	LoadExitProc		;clean up, return to Module level
	jnc	TcNoExitProc
	jmp	TcOmErr			;brif out of memory error

TcNoExitProc:
	test	[flagsTm],FTM_BpDeleted
	je	TcNoBp			;brif breakpoint was not deleted
	push	si			;pass otxDelFirst
	call	LnOfOtx			;ax = line text was inserted
	push	ax
	call	FAR PTR ToggleBp	;s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -