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

📄 txtfind.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov	ax,[otx]		;stop when we've reached this otx
	call	FindBol
	xchg	ax,dx			;ax = offset to start of line
cEnd	OtxBolOfOtx

;*************************************************************************
; OtxBosOfOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the text offset to the start of statement.
; Entry:
;	parm1: ushort otx
; Exit:
;	grs.fDirect is reset to FALSE
;	AX = byte offset into text table for stmt's opBol/opBos
;
; For example, if pcode contained:
;	[0]opBol,[2]opStop,[4]opBol,[6]opStop,[8]opEndProg,[0A]opEot
; The following inputs would produce the following results:
;	0000 => 0000
;	0001 => 0000
;	0002 => 0000
;	0003 => 0000
;	0004 => 0004
;	0005 => 0004
;	0006 => 0004
;	0007 => 0004
;	0008 => fatal error (only checked in non-release versions)
;
;*************************************************************************
cProc	OtxBosOfOtx,<PUBLIC,FAR>
	parmW	otx
cBegin	OtxBosOfOtx
	DbChk	TxdCur			;perform sanity check on txdCur
	push	[otx]
	call	OtxBolOfOtx		;ax = offset to opBol for this line
BosLoop:
	push	ax			;save potential return value
	push	ax			;pass current text offset
	PUSHI	ax,<CODEOFFSET tOpBos>	;pass ptr to start-of-line table
	call	TxtFindNextOp		;ax = offset to next opBos/opEot
	pop	dx			;dx = potential return value
	cmp	[otx],ax
	ja	BosLoop 		;brif bos is before otx of interest
	xchg	ax,dx			;ax = return value
cEnd	OtxBosOfOtx

;*************************************************************************
; OtxBosNext
; Purpose:
;	Given a text offset into current text table or Direct Mode buffer,
;	find the text offset for the next beginning of statement/line.
;	This is used by UI debugger to find statement boundaries to
;	highlight for trace.
; Entry:
;	parm1 = text offset of interest
;	grs.fDirect, oMrsCur, oPrsCur identify the text table being
;	  searched.  txdCur describes its text table.
; Exit:
;	ax = text offset to next opBol/opBos/opEot opcode
;
;*************************************************************************
cProc	OtxBosNext,<PUBLIC,FAR>		
	parmW	otx			
cBegin	OtxBosNext			
	DbChk	Otx,otx			
	push	[otx]			;pass offset of interest to TxtFind...
	PUSHI	ax,<CODEOFFSET tOpBosBol> ;pass ptr to start-of-line table
	call	TxtFindNextOp		;ax = offset to next opBos/opBol/opEot
cEnd	OtxBosNext			

;*************************************************************************
; OtxBolNext0
; Purpose:
;	Given a text offset into current text table or Direct Mode buffer,
;	find the text offset for the next beginning of line.
;	This is used by CALLS menu and PreScanAsChg().
; Entry:
;	parm1 = text offset of interest
;	grs.fDirect, oMrsCur, oPrsCur identify the text table being
;	  searched.  txdCur describes its text table.
; Exit:
;	ax = text offset to next opBol/opEot opcode
;
;*************************************************************************
cProc	OtxBolNext0,<FAR,PUBLIC>	
	parmW	otx			
cBegin	OtxBolNext0			
	DbChk	Otx,otx			
	push	[otx]			;pass offset of interest
	PUSHI	ax,<CODEOFFSET tOpBol>	;pass ptr to start-of-line table
	call	TxtFindOp		;ax = offset to next opBos/opBol/opEot
cEnd	OtxBolNext0			


;*************************************************************************
; OtxResume
;
; Purpose:
;	Same as OtxBosOfOtx, except that it will also stop at opStIf
;	and opStElse opcodes.  This is needed for RESUME compatability
;	in single line IF statements.
; Entry:
;	parm1: ushort otx
; Exit:
;	grs.fDirect is reset to FALSE
;	AX = byte offset into text table for stmt's opBol/opBos, or
;	     past opStElse, opStIf operand.
;
;*************************************************************************
cProc	OtxResume,<PUBLIC,NEAR>
	parmW	otx
cBegin	OtxResume
	DbChk	TxdCur			;perform sanity check on txdCur
	push	[otx]
	call	OtxBolOfOtx		;ax = offset to opBol for this line
ResLoop:
	push	ax			;save potential return value
	push	ax			;pass current text offset
	PUSHI	ax,<CODEOFFSET tOpResume> ;pass ptr to start-of-line table
	call	TxtFindNextOp		;ax = offset to next opBos/opEot

; We are sensitive to opStIf and opStElse here so that an error in a
; then or else clause will cause RESUME to restart execution in the
; appropriate clause instead of at the beginning of the IF expression.
; This is necessary for compiler compatability. This only applies to
; Single line IF/THEN/ELSE, as the multi line versions are line oriented.

	cmp	dl,RESUME_opIfElseMax	;did we stop at a single IF/ELSE opcode?
	ja	ResNotIfElse		;brif not
	call	TxtSkipOp		;ax = opcode beyond opStIf/opStElse
ResNotIfElse:
	pop	dx			;dx = potential return value
	cmp	[otx],ax
	ja	ResLoop 		;brif bos is before otx of interest
	xchg	ax,dx			;ax = return value
cEnd	OtxResume

;*************************************************************************
; OtxResumeNext
; Purpose:
;	Given a text offset into current text table or Direct Mode buffer,
;	find the text offset for the next beginning of statement/line.
;	This is used by RESUME NEXT statement.
; Entry:
;	parm1 = text offset of interest
;	grs.fDirect, oMrsCur, oPrsCur identify the text table being
;	  searched.  txdCur describes its text table.
; Exit:
;	ax = text offset to next opBol/opBos/opEot opcode, or opcode after
;	  opStIf.
;
;*************************************************************************
cProc	OtxResumeNext,<PUBLIC,FAR>	
	parmW	otx			
cBegin	OtxResumeNext			
	;Preserve and clear grs.fDirect in case RESUME NEXT is being entered
	;from direct mode.
	
	push	WORD PTR ([grs.GRS_fDirect])
	SetfDirect al,FALSE		;switch off direct mode

	push	[otx]			;pass offset of interest to TxtFind...
	PUSHI	ax,<CODEOFFSET tOpResumeNext> ;pass ptr to start-of-line table
	call	TxtFindNextOp		;ax = offset to next opBos/opBol/opEot

;  We need to be sensitive to opStIf in case the error occurred in the IF
;  expression.	An error in the If expresion, and RESUME next in the compiler
;  will cause execution to restart in the THEN clause.	Wierd, but we must
;  do this to be compatable.  An error in the then clause however, will
;  not cause execution to RESUME NEXT into the else clause, execution starts
;  after the else clause, thus we don't need to be sensitive to opStElse here.
;  This is only a concern for Single line IF/THEN/ELSE, as the multi-line
;  variants are line oriented by nature.
;
	cmp	dl,RESUMENEXT_opIfMax	;did we stop at a single IF/ELSE opcode?
	ja	ResNxtNotIf		;brif not
	call	TxtSkipOp		;ax = opcode beyond opStIf/opStElse
ResNxtNotIf:
	PopfDirect dx			
cEnd	OtxResumeNext			

;*************************************************************************
; OtxLabOfOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the text offset for the highest opLab/opBolLab/opLabSp/opBolLabSp
;	opcode which precedes this text offset.
; Entry:
;	ax = otx of interest
; Exit:
;	ax = UNDEFINED if no label precedes this text offset
;	     else, offset into text table to link field of label opcode
;
;*************************************************************************
PUBLIC	OtxLabOfOtx
OtxLabOfOtx PROC NEAR
	DbChk	Otx,ax			
	DbChk	TxdCur			;perform sanity check on txdCur
	xchg	dx,ax			;dx = text offset of interest
	GetSegTxtTblCur	es		;[24]es = seg adr of current text tbl
	mov	ax,UNDEFINED		;ax = default return value (not found)
	mov	bx,[txdCur.TXD_otxLabLink] ;bx = offset to 1st link in list
LinkLoop:
	cmp	bx,dx
	jae	LinkExit		;brif beyond otx of interest
	mov	ax,bx			;ax = previous link
	mov	bx,es:[bx]		;bx points to next in linked list
	jmp	SHORT LinkLoop

LinkExit:
	ret
OtxLabOfOtx ENDP

;**************************************************************
; OtxNoInclude,OtxNoInclPrev
; Purpose:
;	Return the text offset to the next/previous line which did not
;	come from an INCLUDE file.
; Entry:
;	parm ushort otx = text offset where search is to start
; Exit:
;	grs.fDirect is reset to FALSE
;	ax = otx to opBol/opEot for next line which was not INCLUDed
;
;**************************************************************
PUBLIC	OtxNoInclude
OtxNoInclude PROC FAR
	mov	ax,1
	SKIP2_PSW			;skip following sub ax,ax
OtxNoInclude ENDP
PUBLIC	OtxNoInclPrev
OtxNoInclPrev PROC FAR
	sub	ax,ax
OtxNoInclPrev ENDP
;Common entry for OtxNoInclude, OtxNoInclPrev
?DFP = DFP_NONE 			; don't generate non-Release
					;   code to smash regs
cProc	NoIncl,<FAR>			
	ParmW	otx			
cBegin	NoIncl				
?DFP = DFP_CP				; restore switch value
	mov	bx,[otx]		;bx = otx of where to start search
	push	WORD PTR [fViewInclude]
	mov	[fViewInclude],FALSE

	push	ax			;save ln increment
	push	bx			;pass otxStart
	call	LnOfOtx			;ax = line (0..n)
	pop	bx			;bx = ln increment
	add	ax,bx			;bump line# by 1 if OtxNoInclude
	push	ax
	call	OtxOfLn			;ax = text offset to ln

	pop	dx
	mov	[fViewInclude],dl	;restore previous value
cEnd	NoIncl				

;*************************************************************************
; OPrsOfOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the oPrs for the DEF-FN which it falls within.
;	Text table is assumed to not be in SS_EXECUTE state.
; Entry:
;	parm1: ushort otx
; Exit:
;	if text table's scan state = SS_RUDE or if otx does not fall
;	   within a DEF FN, this function returns AX = UNDEFINED
;	else AX = byte offset into procedure table for DEF FN
;
;*************************************************************************
cProc	OPrsOfOtx,<PUBLIC,FAR>
	parmW	otx
cBegin
	DbChk	Otx,otx			
 DbAssertRelB [txdCur.TXD_scanState],ne,SS_EXECUTE,CP,<OPrsOfOtx: bad scanstate>
	DbChk	TxdCur			;perform sanity check on txdCur
	GetSegTxtTblCur	 es		;es = seg adr of cur txt tbl
	mov	ax,UNDEFINED		;default return value = UNDEFINED
	cmp	[grs.GRS_oPrsCur],ax
	je	NotInProc		;branch if not in SUB/FUNCTION
	cmp	[prsCur.PRS_procType],PT_DEFFN
	jne	DefFnExit		;no DEF FNs within SUB/FUNCTION
NotInProc:
	cmp	[txdCur.TXD_scanState],SS_RUDE
	jae	DefFnExit		; return UNDEFINED if SS_RUDE
	mov	bx,[mrsCur.MRS_otxDefFnLink]
DefFnLoop:
	cmp	bx,[otx]
	ja	DefFnExit		;brif beyond otx of interest
	mov	ax,UNDEFINED		;default return value = UNDEFINED
	cmp	WORD PTR es:-4[bx],opStDefFn
	jne	NotInDef		;brif its an END DEF
	mov	ax,es:2[bx]		;ax = oPrs of this DEF FN
NotInDef:
	mov	bx,es:[bx]		;bx points to next in linked list
	jmp	SHORT DefFnLoop

DefFnExit:
cEnd

;*************************************************************************
; OtxTypDefined
;
; Purpose:
;	Given an oNam, return an offset within the current text table,
;	to the TYPE statement that defines type oNam.
;	Text table is assumed to not be in SS_EXECUTE state.
; Entry:
;	parm1: ushort oNam
; Exit:
;	AX = UNDEFINED if type is not defined
;	     else, offset into text table to opStType's link field
;
;*************************************************************************
cProc	OtxTypDefined,<PUBLIC,NEAR>,<si>
	parmW	oNam
cBegin
 DbAssertRelB [txdCur.TXD_scanState],ne,SS_EXECUTE,CP,<OtxTypDefined: bad state>
	DbChk	TxdCur			;perform sanity check on txdCur
	push	[grs.GRS_oPrsCur]	;save caller's prs
	call	PrsDeactivate		;make module's text table active
	GetSegTxtTblCur	es		;es = seg adr of cur txt tbl
	mov	si,[txdCur.TXD_otxTypeLink]
	mov	ax,[oNam]
	DbChk	ONam,ax
OtxTypeLoop:
	cmp	si,UNDEFINED
	je	OtxTypeDone		;brif not found
	cmp	WORD PTR es:2[si],ax
	je	OtxTypeDone		;brif found
	mov	si,es:[si]		;si points to next in linked list
	jmp	SHORT OtxTypeLoop

OtxTypeDone:
	call	PrsActivateCP		;re-activate caller's prs.  Parm pushed
					; at entry to function, may be UNDEFINED
	mov	ax,si			;return result in ax
	inc	si
	je	OtxTypeExit		;brif type is UNDEFINED
	test	[txdCur.TXD_flags],FTX_mrs
	jne	OtxTypeExit		;brif ref is in module text table
	SetStartOtx ax			;for procedure references, forward
					; referncing is not a problem,
					; pretend definition is at start of text
OtxTypeExit:
cEnd




sEnd	CP


end

⌨️ 快捷键说明

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