📄 context.asm
字号:
jnz Search_Table ;brif not
mov [oTyp],dl ;save type of DEF FN (else oTyp stays 0)
DbAssertRelB ET_MAX,ae,dl,CP,<RsTableSearch input oTyp not predefined>
Search_Table:
mov [oRsFree],bx ;offset to first free struct
GETRS_SEG es,bx,<SIZE,LOAD>
;At this point, [oTyp]=0 for MRS, SUB, FUNCTION, non-zero for DEF FN
; si is the oRs for the first struct to examine
; [procType] = PT_xxx of entry being searched for
; di = input ogNam
Search_Loop:
inc si
.errnz UNDEFINED - 0FFFFH
jz Quit_Search ;brif end of chain found
dec si
RS_BASE add,si ;add base of table
DbAssertRel PTRRS[si.MRS_ogNam],nz,UNDEFINED,CP,<RsTableSearch: err 1>
mov ax,PTRRS[si.MRS_ogNam]
.errnz OGNAM_UNNAMED - 0
or di,di ; special case where ogNam = 0?
jz Untitled_Mrs ;brif so
cmp di,ax
jnz Not_A_Match ;brif names don't match
mov al,[oTyp]
or al,al ;searching for a DEF FN?
jz Match_Found ; brif not
mov dx,[grs.GRS_oMrsCur] ;oMrs of the DEF must be oMrsCur ...
cmp dx,PTRRS[si.PRS_oMrs]
jnz Not_A_Match ; brif they're not the same
mov ah,BPTRRS[si.PRS_oType]
and ah,M_PT_OTYPE ; mask out any flags in this byte
cmp al,ah ; oTyp's must match if it's a DEF
jz Match_Found
Not_A_Match:
cmp [procType],PT_NOT_PROC
jz MrsSearch ;brif we're walking the mrs chain
mov si,PTRRS[si.PRS_oPrsNext] ;move to next entry
jmp Search_Loop ;loop to consider next entry
MrsSearch:
mov si,PTRRS[si.MRS_oMrsNext] ;move to next entry
jmp Search_Loop ;loop to consider next entry
Untitled_Mrs:
or ax,ax ;is this the special 'untitled' entry?
.errnz OGNAM_UNNAMED - 0
jnz Not_A_Match ;brif not
Match_Found:
xchg ax,si ;pointer to found entry
RS_BASE sub,ax ;pRs --> oRs
jmp short Exit_Table_Search ;found entry - exit routine
Quit_Search:
mov ax,UNDEFINED ;entry not found
mov bx,[oRsFree] ;first free struct of appropriate
; size
Exit_Table_Search:
cEnd RsTableSearch
;***
;PrsFind - find a prs in the tRs
;Purpose:
; Given the name of a prs, return the oPrs for it, or UNDEFINED if it's
; not found.
; Preserve the Mrs & Prs state of the caller.
;
; NOTE: This should never be called to search for a DEF FN's, only
; NOTE: a SUB or a FUNCTION.
;
; For complete details of the matching algorithm, see RsTableSearch.
;Entry:
; ogNam - name of the prs to search for
;Exit:
; AX = UNDEFINED if no match found, otherwise it's the oPrs for the
; desired prs.
;Exceptions:
; none.
;****
;***
;MrsFind - find an mrs in tRs
;Purpose:
; Given the name of an mrs, return the oMrs for it, or UNDEFINED if it's
; not found.
; Preserve the Mrs & Prs state of the caller.
;
; For complete details of the matching algorithm, see RsTableSearch.
;Entry:
; ogNam - name of the mrs to search for
;Exit:
; AX = UNDEFINED if no match found, otherwise it's the oMrs for the
; desired mrs.
;Exceptions:
; none.
;****
cProc PrsFind,<PUBLIC,FAR,NODATA>
cBegin <nogen>
mov al,PT_SUB ;search for prs's
SKIP2_PSW ;skip MrsFind, fall into RsFind
cEnd <nogen>
cProc MrsFind,<PUBLIC,FAR,NODATA>
cBegin <nogen>
mov al,PT_NOT_PROC ;search for mrs's
cEnd <nogen>
?DFP = DFP_NONE ; don't smash regs on entry
cProc RsFind,<FAR,NODATA>,<si>
parmW ogNam
cBegin
?DFP = DFP_CP ; restore switch
DbChk ogNam,ogNam
push ax
mov si,[grs.GRS_oRsCur] ;save, so we can restore at exit
cCall MrsDeActivate
pop ax
cCall RsTableSearch,<ogNam>
push ax ;save retval
cCall RsActivateCP,<si> ;reactivate original RsCur
pop ax ;restore retval
cEnd
;***
;MoveTheMrs
;
;Purpose:
; This code is intended to be used by the Mrs[De]Activate routines,
; to copy a structure from static data into the table or vice versa.
;
; Changed significantly and renamed (was CopyNchg2Bds) as part of
; revision [10].
;Entry:
; si == pointer to the start of the source mrs
; bx == pointer to the start of the dest. mrs
; if FV_FAR_RSTBL, ds is source seg, es is dest. seg
; NOTE: if FV_FAR_RSTBL, one CANNOT assume ds == ss!
;Exit:
; none.
;Uses:
; si
;Exceptions:
; None.
;****
MoveTheMrs PROC NEAR
push di
mov di,bx ;so pDst is saved across calls
mov cx,SIZE MRS ; cx == cbMrs
mov dx,MRS_txd.TXD_bdlText
call CopyNchgMrs ;Common code for mrs's and prs's
mov ax,[si.MRS_bdlnam.FHD_pNext] ;special case: in case call to
mov [di.MRS_bdlnam.FHD_pNext],ax ; BdlChgOwner in CopyNchgMrs
; changed the pNext field
; in source bdl
mov ax,MRS_bdlnam
mov bx,di
add bx,ax ;bx = destination pBdlNam
add ax,si ;ax = source pBdlNam
cCall BdlChgOwner,<ax,bx> ;NOTE: We MUST call this AFTER
; the block copy
mov ax,MRS_bdVar
add si,ax
add di,ax
cCall BdChgOwner_NoCopy,<si,di> ;change owner of 2nd bd
; copies the mrs
pop di
ret
MoveTheMrs ENDP
;***
;CopyNchgMrs, CopyNchgPrs
;
;Purpose:
; This code is intended to be used by the Mrs/Prs[De]Activate routines,
; for copying a structure from static data into a table or vice versa.
; In addition, the owner to the bdlText is also updated (via bdmgr)
; for CopyNchgMrs.
;Entry:
; si == pointer to the start of the source struct
; bx == pointer to the start of the dest. struct
; For Mrs callers:
; cx == count of bytes in the structure to copy
; dx == offset into structure to prs/mrs text bdl
; For Prs callers:
; if FV_FAR_RSTBL, ds is source seg, es is dest. seg,
; and NOTE that in this case, one CANNOT assume ss == ds
;Exit:
; none.
;Exceptions:
; None.
;****
CopyNchgPrs PROC NEAR
mov ax,sp
mov cx,SIZE PRS - SIZE TXD
.errnz (SIZE PRS - SIZE TXD) - PRS_txd ;we're counting on the txd
; being the last element in
; the prs structure
SKIP2_PSW
CopyNChgMrs:
sub ax,ax
push di
push ss
pop es
xchg di,ax ;save flag in di
mov ax,dx
add ax,bx ;points to dest. bdlText
add dx,si ;points to source bdlText
push dx ;pass to BdlChgOwner
push ax ;pass to BdlChgOwner
push si ;pass pbSrc to CopyBlk
push bx ;pass bpDst to CopyBlk
push cx ;pass cbStruct to CopyBlk
call CopyBlk
or di,di
jnz CopyNchg_Cont ;brif don't want to move bdl
; owner from the table
cCall BdlChgOwner ;must do this AFTER block copy
SKIP2_AX
CopyNchg_Cont:
pop ax ;disgard parms to BdlChgOwner
pop ax
mov [si.MRS_ogNam],UNDEFINED ; indicate struct not active
pop di
ret
CopyNchgPrs ENDP
;***
;SetMrsUndef, SetMrsAx
;Purpose:
; Set grs.oMrsCur and grs.oRsCur to [ax] or UNDEFINED
;Entry:
; SetMrsAx: ax = new grs.oMrsCur
;Preserves:
; Caller's assume that no registers other than ax are modified
;
;***************************************************************************
SetMrsUndef PROC NEAR
mov ax,UNDEFINED
SetMrsUndef ENDP
;fall into SetMrsAx
SetMrsAx PROC NEAR
mov [grs.GRS_oMrsCur],ax
mov [grs.GRS_oRsCur],ax
ret
SetMrsAx ENDP
;***
;SetPrsUndef, SetPrsAx
;Purpose:
; Set grs.oPrsCur to [ax] or UNDEFINED, keeping grs.oRsCur consistent.
;Entry:
; SetPrsAx: ax = new grs.oPrsCur
;Preserves:
; Caller's assume that no registers other than ax are modified
;
;***************************************************************************
SetPrsUndef PROC NEAR
mov ax,UNDEFINED
SetPrsUndef ENDP
;fall into SetPrsAx
SetPrsAx PROC NEAR
mov [grs.GRS_oPrsCur],ax
inc ax ;test for UNDEFINED
jz NoPrs ;brif no prs is active
dec ax
or ah,80h ;high bit indicates prs active
mov [grs.GRS_oRsCur],ax
ret
NoPrs:
mov ax,[grs.GRS_oMrsCur]
mov [grs.GRS_oRsCur],ax ;oRsCur = oMrsCur (no prs active)
ret
SetPrsAx ENDP
;##############################################################################
;# #
;# Module related Context Manager Functions #
;# #
;##############################################################################
;***
;MrsDiscard()
;
;Purpose:
; Release all resources associated with current module. This includes the
; module's type table, static value table, and text table.
; This routine calls DiscardPrs for every procedure in this module.
;
; TxtDiscard is also called (prior to setting grs.oMrsCur to UNDEFINED).
;
;Entry:
; static bit flag F_CON_LeaveTMrsEmpty in conFlags - - - if we're
; discarding the last mrs and this bit flag is set (TRUE), just
; leave no mrs in tRs, otherwise, call MrsMake to create a
; new unnamed module.
;Exit:
; AX = non-zero
; Special case: AX = UNDEFINED if MakeInitMrs is called. [47]
; grs.oMrsCur = grs.oPrsCur = UNDEFINED
;Uses:
; none.
;Exceptions:
; if the module has been modified and user cancels, triggers a runtime
; error.
;*******************************************************************************
cProc MrsDiscard,<PUBLIC,FAR,NODATA>
cBegin MrsDiscard
DbAssertRel mrsCur.MRS_ogNam,nz,OGNAM_GMRS,CP,<MrsDiscard: global mrs!>
DbAssertRel mrsCur.MRS_ogNam,nz,OGNAM_CLIPBOARD,CP,<MrsDiscard: err 1>
DbAssertRel mrsCur.MRS_ogNam,nz,OGNAM_IMMEDIATE,CP,<MrsDiscard: err 2>
cCall PrsDeActivate
call AlphaORsFree ;release table of sorted oRs's
call VarDealloc ;deallocate any owners in
; the module variable table
cCall DiscardHistoryORs,<grs.GRS_oMrsCur> ; throw away help
; history for mrs.
;Note that the below scheme depends on the fact that NextPrsInMrs
;finds the first prs in the table if grs.GRS_oPrsCur is UNDEFINED, and
;then subsequent prs's based on grs.GRS_oPrsCur. It is not safe to
;call ForEachCP to do this, because that scheme depends on walking
;the prs chain, and PrsDiscard1 might discard the current entry.
;In essense we are starting from the top of the prs chain each time
;through the loop below.
; To further complicate things, PrsDiscard1 might or might not
; free the prs; if it does not, the below still works, but we
; walk from prs to prs, not freeing them, but marking them as
; undefined proc.s and freeing associated resources.
PrsDiscard_Loop:
call far ptr NextPrsInMrs ;activate next prs in this mrs
inc ax ;no more prs's in this module?
jz MrsDiscard_Cont ; brif so
call PrsDiscard1 ;discard active prs it
jmp short PrsDiscard_Loop
MrsDiscard_Cont:
cCall PrsDeActivate ; ensure TxtDeleteAll
; deletes txt in MODULE
; text table, so any
; declares to proc.s in
; this module are removed
; prior to calling
; ChkAllUndefPrsSaveRs
call TxtDeleteAll ;delete all text in txt table,
; but don't free bdl yet
call ChkAllUndefPrsSaveRs ;search for new defining
;references for Prs entries
;which had their "defining"
;reference deleted.
cCall TxtDiscard ;discard current text table
PUSHI ax,<dataOFFSET mrsCur.MRS_bdVar>
cCall BdFree
PUSHI ax,<dataOFFSET mrsCur.MRS_bdlNam>
call BdlFree ;free module name table
test [mrsCur.mrs_flags2],FM2_NoPcode ; is a document mrs?
jz NoDocBuffer ; brif not
push [mrsCur.MRS_pDocumentBuf] ; document table to delete
call FreeBuf ; Free the buffer
NoDocBuffer:
;don't need to modify entry in table - - - without an active mrs,
; it will automatically look like a 'hole'.
mov ax,[grs.GRS_oMrsCur]
cmp ax,[grs.GRS_oMrsMain] ;discarding Main module?
jnz Not_Main_Module ;brif not
mov [grs.GRS_oMrsMain],UNDEFINED ;now there is no current Main
jmp SHORT UndefCur
Not_Main_Module:
call MainModified ;mark main module as modified
; if current mrs is pcode
; mrs (so we will be sure
; to save updated xxx.MAK)
; (preserves ax)
UndefCur:
push ax
call SetMrsUndef ;grs.oMrsCur=oRsCur=UNDEFINED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -