📄 txtfind.asm
字号:
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 + -