📄 context.asm
字号:
; to save updated xxx.MAK)
jmp SHORT Main_Set1
Main_Set0:
mov dx,[grs.GRS_oMrsCur]
mov [grs.GRS_oMrsMain],dx ;this mrs gets set as MAIN
Main_Set1:
inc ax ;inc ax back to 0
Main_Set2:
.errnz FALSE
MrsMake_Exit:
cEnd MrsMake
MrsMake_OM_3_Err:
mov bx,dataOFFSET mrsCur.MRS_bdVar
cCall BdFree,<bx>
mov bx,dataOFFSET mrsCur.MRS_bdlNam
cCall BdlFree,<bx>
MrsMake_OM_2_Err:
call TxtDiscard
MrsMake_TxtInit_Err:
cmp [fGrewRsTable],FALSE ; did we grow Rs table?
jz @F ; brif not
sub [grs.GRS_bdRs.BD_cbLogical],SIZE MRS
@@:
MrsMake_OM_Err: ;Tried to grow the Rs table but failed
call SetMrsUndef ;grs.oMrsCur=oRsCur=UNDEFINED
cmp [fUsingUnNamed_Mrs],FALSE ;special case where we tried
; to reuse unnamed mrs?
jz Not_Unnamed ; brif not
cmp di,SIZE MRS + OMRS_GLOBAL ; was the unnamed one the
; active one on entry?
jnz Not_Unnamed ; brif not
;can't reactivate the one that was active on input, as we've
; tried to reuse that one but failed. For this special case, we
; must recurse to restore the unnamed empty mrs
call far ptr MakeInitMrs ;remake empty unnamed mrs
; (certain it won't run out
; of memory here ...)
DbAssertRel ax,z,0,CP,<MrsMake: MakeInitMrs returned an error code>
DbAssertRel di,z,grs.GRS_oMrsCur,CP,<MrsMake: di not equal to oMrsCur>
Not_Unnamed:
mov ax,ER_OM
MrsMake_Err_Exit1:
push ax ;save error code
push di ;input oMrsCur
call MrsActivateCP ;re-activate original mrs
pop ax ;restore error code for retval
jmp MrsMake_Exit
;***
; MakeInitMrs
; Purpose:
; Make an unnamed module mrs.
; Entry:
; none
; Exit:
; ax = error code
;
;*******************************************************************************
cProc MakeInitMrs,<FAR,NODATA>
cBegin MakeInitMrs
xor ax,ax ; set to OGNAM_UNNAMED
.errnz OGNAM_UNNAMED - 0
push ax ;make untitled module
PUSHI ax,<100h * FM2_File> ;initial flags for module mrs
call MrsMake ;make initial (untitled) mrs
cEnd MakeInitMrs
;***
; MainModified
; Purpose:
; Mark main module as modified if current mrs is pcode mrs.
; This is done so we will be sure to save updated xxx.MAK)
; Preserves:
; ax (caller's assume this)
; es is either preserved, or explicitly set to seg of tRs
;
;*******************************************************************************
PUBLIC MainModified ;for debugging only
MainModified PROC NEAR
DbAssertRel [grs.GRS_oMrsMain],ne,[grs.GRS_oMrsCur],CP,<MainModified: err1>
mov bx,[grs.GRS_oMrsMain]
inc bx ;test for UNDEFINED
jz MmExit ;brif no main module
; (can happen when we're terminating
; and main module discarded before
; command window's mrs)
test [mrsCur.MRS_flags2],FM2_NoPcode OR FM2_Include
jnz MmExit ;brif current mrs is not a pcode mrs
dec bx
RS_BASE add,bx ;bx now points to main mrs
; (we know mrs oMrsMain is in table,
; i.e. not in mrsCur struct)
or BPTRRS[bx.MRS_flags2],FM2_Modified
GETRS_SEG es,bx,<SIZE,LOAD>
MmExit:
ret
MainModified ENDP
;***
;MrsDeActivate()
;
;Purpose:
; Save the current module's register set (mrsCur) back into the tRs
; entry. This includes a call to TxtDeActivate prior to actually
; deactivating the mrs, as well as deactivating the current procedure
; (via PrsDeActivate).
;
; NOTE: This routine is guaranteed to cause no heap movement.
;
;Entry:
; grs.oMrsCur = current module to be deactivated
; UNDEFINED if there is no current module
;Exit:
; grs.oMrsCur = UNDEFINED
; grs.oPrsCur = UNDEFINED
;Uses:
; none.
;Exceptions:
; none.
;*******************************************************************************
cProc MrsDeActivate,<PUBLIC,NEAR,NODATA>,<SI>
cBegin MrsDeActivate
cmp [grs.GRS_oMrsCur],UNDEFINED ;is there an active mrs?
jz MrsDeAct_Exit ;just return if not
DbHeapMoveOff ;assert no heap movement here
DbChk ConStatStructs
cCall PrsDeActivate ;deactivate current prs, if any
cCall TxtDeActivate ;deactivate current txd, if any
mov bx,[grs.GRS_oMrsCur]
RS_BASE add,bx
GETRS_SEG es,si,<SIZE,LOAD> ; es set to mrs dst. seg
mov si,dataOFFSET mrsCur ;now ds:si == mrs src. address
call MoveTheMrs ; move mrsCur into tRs
call SetMrsUndef ;grs.oMrsCur=oRsCur=UNDEFINED
DbHeapMoveOn
MrsDeAct_Exit:
cEnd MrsDeActivate
;***
;MrsActivate(oMrsNew)
;
;Purpose:
; Make the module indicated by oMrsNew the current active module. The
; current module's register set (if any) will be saved via MrsDeActivate,
; and TxtActivate will be called at the end.
;
; NOTE: This routine is guaranteed to cause no heap movement.
;
;Entry:
; 'oMrsNew' is an offset into the tRs for module to be made current.
; Note that if oMrsNew is UNDEFINED or if the entry at offset oMrsNew is
; a discarded entry, the current mrs (if any) will be
; deactivated, and no new mrs will be activated.
;Exit:
; grs.oMrsCur = oMrsNew
; grs.oPrsCur = UNDEFINED
; if oMrsNew != UNDEFINED,
; all fields in mrsCur are setup
; all fields in txdCur are setup
;Uses:
; none.
;Exceptions:
; none.
;
;*******************************************************************************
cProc MrsActivate,<PUBLIC,FAR,NODATA>
parmW oMrsNew
cBegin MrsActivate
cCall MrsActivateCP,<oMrsNew>
cEnd MrsActivate
cProc MrsActivateCP,<PUBLIC,NEAR,NODATA>,<SI>
parmW oMrsNew
cBegin MrsActivateCP
DbHeapMoveOff ;assert no heap movement here
call PrsDeActivate
mov ax,[oMrsNew]
cmp ax,[grs.GRS_oMrsCur]
jz MrsActivate_Exit
push ax ;save oMrsNew
cCall MrsDeActivate ;deactivate current mrs, if any
pop ax ;ax = oMrsNew
inc ax ;test for UNDEFINED
jz MrsActivate_Exit ;brif no mrs is to be activated
dec ax ;restore ax = oMrsNew
DbChk oMrs,ax ;ife RELEASE - ensure validity
xchg ax,si ;si = oMrs to activate
RS_BASE add,si ;si = pMrs to activate
GETRS_SEG ds,bx,<SIZE,LOAD> ; ds set to mrs src. seg
assumes DS,NOTHING
mov bx,dataOFFSET mrsCur ;bx == mrs dest. address
SETSEG_EQ_SS es ;es:bx = mrs dest. address
call MoveTheMrs ; move mrsCur into tRs
SETSEG_EQ_SS ds ;restore ds = ss
assumes DS,DATA
mov ax,[oMrsNew] ;note new oMrsCur
call SetMrsAx ;grs.oMrsCur = oRsCur = ax
cCall TxtActivate ;activate txdCur from this mrs
MrsActivate_Exit:
DbHeapMoveOn
cEnd MrsActivate
;***
;EmptyMrs
;Purpose:
; This boolean function is used to determine whether there is an
; empty unnamed module.
; [52] NOTE: more than one caller of this routine assumes that if
; [52] there IS an empty unnamed mrs, then there is no other
; [52] (pcode) mrs loaded.
;Entry:
; none.
;Exit:
; CX = 0 if there is not an empty unnamed module
; else CX is the offset in the Rs table to the empty unnamed module
;Uses:
; none.
;Preserves:
; BX
;Exceptions:
; none.
;*******************************************************************************
PUBLIC EmptyMrs
EmptyMrs PROC NEAR
push bx
;---------------------------------------------------------------------
;NOTE: an inherent assumption is that, if there exists an unnamed mrs,
; it will be at offset SIZE MRS + OMRS_GLOBAL in the table (the
; global mrs is at offset OMRSGLOBAL in the table). The user
; cannot create an unnamed mrs, so this seems a safe assumption.
;---------------------------------------------------------------------
mov cx,SIZE MRS + OMRS_GLOBAL ;[60]
mov bx,OFFSET DGROUP:mrsCur ;assume this is the current module
mov ax,[txdCur.TXD_bdlText_cbLogical]
SETSEG_EQ_SS es ;seg of mrsCur is always same as ss
cmp [grs.GRS_oMrsCur],cx ;is this the current module?
jz EmptyMrs_Cont ; brif so
GETRS_SEG es,bx,<SIZE,LOAD>
mov bx,cx ;bx = oMrs
RS_BASE add,bx ;bx = pMrs
mov ax,PTRRS[bx.MRS_txd.TXD_bdlText_cbLogical]
EmptyMrs_Cont:
cmp PTRRS[bx.MRS_ogNam],OGNAM_UNNAMED ;[10] is MAIN mrs unnamed?
jnz EmptyMrs_FalseExit ; brif not
cmp ax,CB_EMPTY_TEXT ;is it's text table empty?
ja EmptyMrs_FalseExit ; brif not
;This block checks to see if module has any procedures
mov ax,UNDEFINED
mov bx,cx ;bx == oMrs of interest for call below
DbAssertRel grs.GRS_oPrsCur,z,UNDEFINED,CP,<EmptyMrs: prsCur active>
call GetNextPrsInMrs ;ax = oPrs of 1st prs in module
js EmptyMrs_Exit ; brif module contains no prs's
EmptyMrs_FalseExit:
xor cx,cx ; indicate no empty unnamed mrs
EmptyMrs_Exit:
pop bx
ret
EmptyMrs ENDP
;##############################################################################
;# #
;# Procedure related Context Manager Functions #
;# #
;##############################################################################
;------------------------------------------------------------------------------
;
; Prs Transition States
;
; Due to the user interface, prs handling is more complicated than mrs
; handling. For a Module Register Set, there are just 2 states: no mrs, or
; an mrs, with two arcs connecting the states: MrsMake, and MrsDiscard.
;
; Procedure Register Sets have the following states and transitions:
;
; S0 - No prs entry
; S1 - SUB has been referenced, but not declared or defined
; This only applies to SUBs, not FUNCTIONS or DEFFNs.
; (i.e. FUNCTIONS and DEF FNs never enter this state)
; If a prs entry is still in this state at runtime,
; We bind to a compiled SUB on first execution.
; S2 - procedure has no text tbl, has been DECLAREd but not defined.
; If a prs entry is still in this state at runtime,
; We bind to a compiled SUB/FUNCTION on first execution.
; The procedure may or may not have declarations.
; (DEF FNs never enter this state)
; S3 - procedure text tbl & window allocated, but no definition.
; The procedure may or may not have declarations.
; (DEF FNs never enter this state)
; S4 - procedure has a definition (i.e. SUB/FUNCTION/DEF FN stmt)
;
; These states can be uniquely determined by these fields in the prs structure:
; (But note: txd.bdlText.status should only be tested while the
; prs is not active, i.e., in the tPrs. To see if prsCur has
; a text table, test txdCur.TXD_flags - - if FTX_mrs is set,
; prsCur has no text table)
; S0: bdName.pb == NULL
; S1: bdName.pb != NULL, txd.bdlText.status == NOT_OWNER,
; FP_DECLARED and FP_DEFINED are NOT set,
; (mrs,prs,otx refer to the CALL reference)
; S2: bdName.pb != NULL, txd.bdlText.status == NOT_OWNER
; FP_DECLARED IS set, FP_DEFINED is NOT set,
; (mrs,prs,otx refer to DECLARE stmt's pcode),
; S3: bdName.pb != NULL, txd.bdlText.status != NOT_OWNER,
; FP_DEFINED is NOT set,
; S4: bdName.pb != NULL, txd.bdlText.status != NOT_OWNER for SUB/FUNC
; but is UNDEFINED for DEF FNs, FP_DEFINED is set, The setting of
; FP_DECLARED is not important in this state.
; (mrs,prs,otx refer to SUB/FUNCTION/ DEF FN statement's pcode)
;
; With these states defined, and arcs connecting them being functions
; defined below, the following table shows how the arcs connect the states:
; In this table, PrsDefine refers to when PrsDefine is called with fNotDefine=0,
; i.e. for a SUB/FUNCTION/DEF FN statement.
; PrsDeclare refers to when PrsDefine is called with fNotDefine != 0,
; i.e. for a DECLARE SUB/FUNCTION/DEF FN statement.
;
; Initial State Arc Final State
; ------------- --- -----------
; S0 PrsRef(FUNC/DEF)S0
; S0 PrsRef(SUB) S1
; S0 PrsDeclare S2
; S0 PrsMake S3
; S0 PrsDefine S4
;
; S1 <txt mgr sees defining reference deleted and:
; finds another SUB reference -> S1
; finds no other references -> PrsFree -> S0
; S1 PrsRef(SUB) S1
; S1 PrsDeclare S2
; S1 PrsMake S3
; S1 PrsDefine S4
;
; S2 <txt mgr sees defining DECLARE stmt deleted and:
; finds another DECLARE -> S2
; finds another SUB reference -> S1
; finds no other declares or references -> PrsFree -> S0
; S2 PrsRef S2
; S2 PrsDeclare S2
; S2 PrsMake S3
; S2 PrsDefine S4
;
; S3 PrsRef S3
; S3 PrsMake S3
; S3 PrsDeclare S3
; S3 PrsDefine S4
; S3 <txt mgr sees text table and window removed and:
; finds a SUB reference -> S1
; finds no SUB reference -> PrsFree -> S0
;
; S4 PrsRef S4
; S4 PrsMake S4
; S4 PrsDeclare S4
; S4 <txt mgr sees defining SUB/FUNC/DEF stmt deleted and:
; finds text table and window still active -> S3
; finds a DECLARE -> S2
; finds a SUB reference -> S1
; finds no declares or references -> PrsFree -> S0
;
;
; Note that PrsDiscard cannot directly eliminate the Prs Entry if there
; are references to the prs in other text tables. It can only
; eliminate the text table associated with the entry by calling TxdDiscard,
; which will cause the text manager to see the definition be deleted.
; If the text manager is unable to find a DECLARE to replace as the new
; definition of the prs, the text manager calls PrsFree to completely
; eliminate the Prs entry.
;
; The above table describes a state-transition diagram, which was not
; attempted in this source file due to the number of transitions.
;------------------------------------------------------------------------------
;***
;PrsRef(oNam,procType,oTyp)
;
;Purpose:
; This function searches for a procedure in the tRs by the name oNam.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -