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

📄 txtfind.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov	[otxFindLast],ax	;otxFindLast = offset of 0th line
	jmp	SHORT StartFromLast

; We are in SS_EXECUTE state. Map executor address in ax to opcode.
FBLGotExec:
	xchg	ax,bx			;executor address is in bx
	mov	ax,es:[bx-2]		;get opcode
DJMP	jmp	short FBLGotExecRet

;This value of CLINES_CACHE means in the QBI screen editor, a time
;consuming OtxOfLn search is performed every few page-up keys
;when the user is scrolling up through his file.

CLINES_CACHE EQU 60
DbPub	FindBol
cProc	FindBol,<NEAR>,<si,di,es>
localW	cLnCache
localW	oTxBolPrev
cBegin
	DbChk	Otx,ax			
	SetfDirect dl,FALSE		;turn off direct mode
					;	 for TxtFindNextOp
	mov	[fLnNotIncl],NOT FALSE
	xchg	di,ax			;di = stopping text offset
	mov	ax,[otxFindLast]	;ax = oTxCur
	mov	dx,ax			;dx = oTxPrev

	cmp	di,ax
	jb	StartFromTop		;brif can't used cached value
	cmp	cx,[lnFindLast]
	jb	StartFromTop		;brif can't used cached value
	sub	cx,[lnFindLast]		;start search from last saved location
StartFromLast:
	inc	di			;Adjust otxMax since Lodsw in loop will
	inc	di			; advance 2 bytes past current opcode.
DJMP	jcxz	FindBolExit		;brif we've skipped enough lines (0)
	mov	[cLnCache],CLINES_CACHE+1 ;load count-down counter
	push	dx
	push	cx
	call	TxtSkipOp		;skip first opcode
	xchg	ax,si			;update oTxCur

	GetSegAddr CODE			;ax = current address of CODE seg
	push	ax			;save addr of CODE seg
	GetSegTxtCur			;[24]es = seg of curr txt table
	push	es			
	pop	ds			;ds = seg addr of current text table
assumes	ds,NOTHING
	pop	es			;es = seg addr of CODE seg

	pop	cx			
	pop	dx			

	;*******************************************************************
	; Register useage during loop
	;  DS - register points to text table until end-of-loop
	;  ES - points to CODE, where opcodes in execute state
	;	  can be accessed
	;  SS - still points to DGROUP, so local vars can be accessed
	;  DI - otxMax (stop search if beyond otxMax)
	;  SI - otxCur (current otx of opcode we are searching)
	;  DX - otxBolCur (otx of last BOL encountered)
	;  CX - cLnMax (maximum number of BOLs to visit)
	;  BX - scratch
	;  AX - scratch
	;*******************************************************************

FindBolLoop:
	dec	[cLnCache]
	je	UpdateCache		;brif time to save reference point

FindBolLoop1:
	mov	[oTxBolPrev],dx 	;remember Bol of previous line
FBLInnerLoop:

	lodsw				;ax = opcode/executor
	cmp	[txdCur.TXD_scanState],SS_EXECUTE ;is this table in execute?
DJMP	je	FBLGotExec		;brif so, map executor to opcode

FBLGotExecRet:
	and	ah,HIGH OPCODE_MASK	;upper bits sometimes used for operands
	mov	bx,ax			;bx = opcode
.errnz	opBol
.errnz	opBolSp-1
.errnz	opBolInclude-opBolSp-1
.errnz	opBolIncludeSp-opBolInclude-1
.errnz	opBolLab-opBolIncludeSp-1
.errnz	opBolLabSp-opBolLab-1
.errnz	opBos-opBolLabSp-1
.errnz	opBosSp-opBos-1
.errnz	opEot-opBosSp-1
.errnz	opEndProg-opEot-1

	cmp	ax,opEndProg		;is this opBol -> opEndProg?
	jbe	FBLGotHit		;brif so, we have an interesting opcode

FBLGotHitCont:
	mov	al,cs:[mpOpAtr_UNDONE + bx]    ; al = #bytes in opcode
	and	ax,OPA_CntMask		;Isolate attribute count
.errnz	OPA_CntMask AND 0FF00H
	cmp	al,OPA_CntMask		;is this a variable length opcode?
	je	FBLVarLenOpcode 	;brif so

FBLVarLenRet:
	add	si,ax			;si points to next opcode
	jmp	short FBLInnerLoop	;go grab next opcode

FBLLoopCont:
	loop	FindBolLoop		;brif haven't reached line count limit

;We ran out of lines before we passed oTxMax.  Return the otx of the
; last Bol encountered.
	xchg	ax,dx			;return oTxBolCur
	jmp	short FBLExit1

FindBolDone:
	xchg	ax,si			;return text offset of Bol in ax.
	dec	ax
	dec	ax			;back up to opcode
FBLExit1:
	mov	dx,[oTxBolPrev] 	;return BOL of previous line

FindBolExit:
	push	ss			
	pop	ds			;recover ds=DGROUP
;	DbChk	AtBosBol,ax		;sanity check on ret val
	DbChk	AtBosBol,dx		;sanity check on ret val
cEnd

;We have a variable length opcode. Grab and return count of bytes for opcode
;
FBLVarLenOpcode:
	lodsw				;ax = # bytes of operands
	inc	ax			;round up to odd count as follows:
	and	al,-2			; {0,1,2,3,4,...} => {1,3,3,5,5,...}
	jmp	short FBLVarLenRet


;This gets invoked every CLINES_CACHE times through FindBol's loop
;
UpdateCache:
	mov	[otxFindLast],dx	;save reference text offset
	mov	ax,CLINES_CACHE 	;reload count-down counter
	mov	[cLnCache],ax
	add	[lnFindLast],ax 	;update reference line number
	jmp	FindBolLoop1

;We have an interesting opcode.  It is either an opBos/Bol variant, or
; it is an opEot, opEndProg
FBLGotHit:
	cmp	ax,opBos		;is it an opBol variant?
	jb	FBLGotBol		;brif so
	cmp	ax,opEot		;is it an opBos variant?
	jb	FBLGotHitCont		;brif so, continue search

;We must have either an opEot, or and opEndProg.
;If we found an opEndProg, we're done.  If we found an opEot, it could only
;mean that we were called with an empty text table, and a search line > 0.
;In this case, we force the otxFound to 0.
;
	jne	FindBolDone		;it was an opEndProg
	SetStartOtx ax			;oTxBol = first line
	mov	dx,ax			;oTxBolPrev = first line
	jmp	SHORT FindBolExit

FBLGotBol:
	cmp	si,di			;are we beyond oTxMax?
	ja	FindBolDone		;brif so

	mov	dx,si			;remember this BOL
	dec	dx
	dec	dx			;back up to opBol opcode
;Advance to next opcode
	mov	al,cs:[mpOpAtr_UNDONE + bx]    ; al = #bytes in opcode
	and	ax,OPA_CntMask		;Isolate attribute count
.errnz	OPA_CntMask AND 0FF00H

	add	si,ax			;si points to next opcode
	cmp	[fViewInclude],FALSE
FBLLoopCont_NE:
	jne	FBLLoopCont		;brif user wants to see INCLUDEd text

	mov	[fLnNotIncl],NOT FALSE	;assume line was not included
	cmp	bx,opBolInclude
	jb	FBLLoopCont		;brif line not included
	cmp	bx,opBolIncludeSp
	ja	FBLLoopCont_NE		;brif line not included
	mov	[fLnNotIncl],FALSE	;Line was included
	jmp	FindBolLoop1		;dont count this line if it was included

assumes ds,DGROUP

;*************************************************************************
; TxtChkCache
; Purpose:
;	This function is called whenever:
;	 - Text is editted in the text table (TxtChange, TxtDelete)
;	It resets Watch and History, as well as calling TxtFlushCache if
;	  the editted pcode was prior to the previous cached value.
; Entry:
;	si - oTx of lowest text offset affected by pcode movement
;
;*************************************************************************
;*************************************************************************
; TxtMoved
; Purpose:
;	This function is called whenever:
;	 - Text is moved in the text table (TxtChange, TxtDelete, SsScan,
;	   SsDeScan)
;	It resets Watch and History, as well as calling TxtFlushCache.
;
;*************************************************************************
;*************************************************************************
; TxtFlushCache
; Purpose:
;	This function is called whenever:
;	 - The current text table changes (TxtActivate, TxtCurInit)
;	It discards any static variables used to speed up searching
;	of text tables.
;
;*************************************************************************
PUBLIC	TxtChkCache
TxtChkCache PROC NEAR
	cmp	si,[otxFindLast]	;is affected pcode after cached otx?
	jb	TxtMoved	 	;brif not
					;else txtmgr's cached otx still valid
	call	UiFlushCache		;tell User Interface to flush its cache
	jmp	SHORT TxtMovedNoFlush 	;brif so, cached otx still valid
TxtChkCache ENDP

PUBLIC	TxtMoved
TxtMoved PROC NEAR
	call	TxtFlushCache		;flush cached values
TxtMovedNoFlush:
	test	[mrsCur.MRS_flags2],FM2_NoPcode OR FM2_Include
	jne	NoPcode			;brif editing INCLUDE or DOCUMENT
	cmp	[grs.GRS_fDirect],FALSE
	jne	NoPcode			;brif editing direct mode stmt
	call	HistReset
	call	WatchMoved
NoPcode:
	ret
TxtMoved ENDP

PUBLIC	TxtFlushCache
TxtFlushCache PROC NEAR
	mov	ax,UNDEFINED
	mov	[lnFindLast],ax
	mov	[otxFindLast],ax
	call	UiFlushCache		;tell User Interface to flush its buffer
	ret
TxtFlushCache ENDP

;*************************************************************************
; LnOfOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the physical line number of the line containing the text.
;	Used for error reporting.
;
; Entry:
;	parm1: ushort otx
;
; Exit:
;	grs.fDirect is reset to FALSE
;	AX = 0 relative line number for line containing the offset
;	[fLnNotIncl] = zero if given line was an INCLUDEd line
;
; 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 => 0001
;	0005 => 0001
;	0006 => 0001
;	0007 => 0001
;	0008 => fatal error (only checked in non-release versions)
;
;*************************************************************************
cProc	LnOfOtx,<PUBLIC,FAR>
	parmW	otx
cBegin	LnOfOtx
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	cx,0FFFFH		;don't stop on line count
	mov	ax,[otx]		;stop when we've reached this otx
	call	FindBol 		;search current text table
	mov	ax,0FFFFH
	sub	ax,cx			;ax = line number (0..n)
cEnd	LnOfOtx

;*************************************************************************
; OtxOfLn
;
; Purpose:
;	Given a  physical line	offset (0..n) within the current text
;	table, return  the byte offset into the text table for
;	its opBol opcode.
;
; Entry:
;	parm1: ushort lnSearch
;
; Exit:
;	grs.fDirect is reset to FALSE
;	AX = byte offset into text table
;	[fLnNotIncl] = zero if given line was an INCLUDEd line
;
; 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  => 0004
;	0002  => 0008
;	0003  => fatal error (only checked in non-release versions)
;
;*************************************************************************
cProc	OtxOfLn,<PUBLIC,FAR>
	parmW	ln
cBegin
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	cx,[ln]			;cx = # lines to skip
	mov	ax,[txdCur.TXD_bdlText_cbLogical] ;ax = offset to end-of-text
	call	FindBol 		;ax = offset to bol
cEnd

;*************************************************************************
; OtxBolOfOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the text offset to the start of line.
; Entry:
;	parm1: ushort otx
; Exit:
;	grs.fDirect is reset to FALSE
;	AX = byte offset into text table for line's opBol
;	[fLnNotIncl] = zero if given line was an INCLUDEd line
;
; 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	OtxBolOfOtx,<PUBLIC,FAR>
	parmW	otx
cBegin	OtxBolOfOtx
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	cx,0FFFFH		;don't stop on line count

⌨️ 快捷键说明

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