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

📄 context.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
						; 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 + -