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

📄 context.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	pop	ax				;restore ax = oMrsCur

	;now unlink this entry from the mrs chain and link it into the free
	;  mrs chain
	GETRS_SEG   es,bx,<SIZE,LOAD>		
	mov	bx,ax				;ax = bx = oMrs we're unlinking
	RS_BASE add,bx				;PTRRS:bx = pMrs we're unlinking
	mov	cx,ax
	xchg	cx,[oFreeMrsFirst]		;cx = offset to first free mrs,
						;  this mrs is new first free
	xchg	PTRRS[bx.MRS_oMrsNext],cx	;mrs now linked into free list
	;now, cx is the offset to the next mrs in the active chain; use
	;  that to unlink this mrs from the active chain
	mov	bx,OMRS_GLOBAL			; start from global mrs
UnLink_Loop:
	RS_BASE add,bx
	mov	dx,PTRRS[bx.MRS_oMrsNext]	;offset to next mrs in chain
	cmp	dx,ax				;found previous chain entry?
	jz	UnLinkIt			;  brif so

	mov	bx,dx				;advance to next entry
	jmp	UnLink_Loop

UnLinkIt:
	mov	PTRRS[bx.MRS_oMrsNext],cx	;unlink the discarded mrs

	push	sp				; Default return value
						; Assumes:
						;	 sp != 0
						;	 sp != UNDEFINED

	test	[conFlags],F_CON_LeaveTMrsEmpty ;should we just leave tMrs
						;  empty if this was only mrs?
	jnz	MrsDiscard_Exit			;brif so

Mrs_No_Trim:
	push	ax				;pass oMrsCur to WnReAssign

	call	MrsTableEmpty			;PSW.Z clear if no mrs's
						; bx = remaining oMrs (if any)
	push	bx				;pass oMrsNew to WnReAssign
	jnz	MrsDiscard_Exit1		;brif mrs table not empty

	call	far ptr MakeInitMrs		;make initial mrs
						;  (certain it won't run out
						;   of memory here ...)
	DbAssertRel  ax,z,0,CP,<MrsDiscard: MakeInitMrs returned an error code>	
	pop	bx				;discard invalid oMrsNew
	pop	dx				; Get oMrsOld
	pop	ax				; discard default ret val
	pushi	ax, UNDEFINED			; return UNDEFINED to
						; indicate MakeInitMrs called
	push	dx				; Put oMrsOld back
	push	[grs.GRS_oMrsCur]		;pass oMrsNew to WnReAssign

	cCall	MrsDeActivate			;don't want it active
	
MrsDiscard_Exit1:
	PUSHI	ax,0				;not just renaming an oRs
	call	WnReAssign			;parms already pushed

MrsDiscard_Exit:
	pop	ax				; Get return value
MrsDiscard_Exit2:				
cEnd	MrsDiscard

;***
;UnlinkFreeMrs
;Purpose:
;	Given an oMrs, search the free mrs chain for the oMrs and unlink it
;	from the chain if found.
;Input:
;	ax = oMrs to be unlinked from the free list
;Exit:
;	none
;******************************************************************************
UnlinkFreeMrs  PROC    NEAR
	GETRS_SEG   es,bx,<SIZE,LOAD>		; prepare for link work
	mov	dx,[oFreeMrsFirst]
	inc	dx
	jz	UnlinkEmpty_Done		;free chain is empty

	dec	dx
	cmp	ax,dx
	jnz	Unlink_Unnamed_Entry		;brif unnamed hole not first free

	mov	bx,dx
	RS_BASE add,bx
	mov	dx,PTRRS[bx.MRS_oMrsNext]
	mov	[oFreeMrsFirst],dx		;unlink complete
	jmp	short UnlinkEmpty_Done
Unlink_Unnamed_Entry:
	mov	bx,dx
	RS_BASE add,bx
	mov	dx,PTRRS[bx.MRS_oMrsNext]
	inc	dx
	jz	UnlinkEmpty_Done		;unnamed mrs hole not in free list

	dec	dx
	cmp	ax,dx
	jnz	Unlink_Unnamed_Entry
	xchg	dx,bx
	RS_BASE add,bx
	mov	cx,PTRRS[bx.MRS_oMrsNext]
	xchg	dx,bx
	mov	PTRRS[bx.MRS_oMrsNext],cx	;unlink complete
UnlinkEmpty_Done:
	ret
UnlinkFreeMrs  ENDP

;***
;MrsMake(ogNam, flags)
;
;Purpose:
;     The user-interface is the only QBI component which deals in any way with
;     module names. A module's name is the same as the path name from which it
;     was loaded. This function searches for a module by the name 'ogNam'. If
;     found, an error code is returned (ER_DD).  If not found, it creates
;     a new Mrs entry and names it 'ogNam'.  Calls the TextMgr routine
;     TxtCurInit() to initialize the text table. Calls the Variable Manager's
;     MakeMrsTVar() if this mrs is not for a text object.
;
;	Note that if we're making a named mrs and there exists an empty unnamed
;	mrs (which can only be at a specific offset from the start of the 
;	table), we'll just discard the empty unnamed one, and use that as a 
;	hole to put the new mrs in. 
;
;	Note also that, if there is no MAIN module on successful conclusion of
;	this routine, the new current module will be made the MAIN one.
;
;Entry:
;     ogNam:
;	 If module's name is to be 'Untitled',
;	    ogNam = OGNAM_UNNAMED
;	 else if module is the global module (created only once)
;           ogNam = OGNAM_GMRS
;	 else if module is for some other special purpose
;		ogNam <= OGNAM_PSEUDO_MAX
;        else
;	    ogNam is an offset into the global name table for this module name
;     flags:
;	low byte = initial value of MRS_flags
;	high byte = initial value of MRS_flags2
;	  Command Window:  FM2_NoPcode
;	  ClipBoard:       FM2_NoPcode
;	  Module:          FM2_File
;	  Include File:    FM2_File + FM2_Include
;	  Document File:   FM2_File + FM2_NoPcode
;	  If either FM2_Include or FM2_NoPcode are set:
;	    - we must NOT replace the existing first module even if it's empty
;	    - this mrs can never be made the MAIN module
;	    - it can never have oMrs of 0
;	    - this mrs can never have a variable table (or be scanned to
;	      SS_PARSE or SS_EXECUTE)
;Exit:
;        if no error 
;	    AX = 0
;	    grs.oMrsCur = new module's oMrs
;	    grs.oPrsCur = UNDEFINED
;	    all fields in mrsCur are setup
;	    all fields in txdCur are setup
;	    rsNew = module's oMrs (tell's user interface to show list window)
;	 else
;	    caller can count on the input mrsCur being still active
;	    if out of memory error, AX = ER_OM
;	    if a matching module is found, AX = ER_DD and [oRsDupErr] =
;	       oRs of existing module with same name.
;Uses:
;	none.
;Exceptions:
;	none.
;*******************************************************************************
cProc	MrsMake,<PUBLIC,FAR,NODATA>,<SI,DI>
	parmW	ogNam				
	parmW	flags
	localB	fUsingUnNamed_Mrs
	localB	fGrewRsTable			
cBegin	MrsMake
	mov	word ptr [fGrewRsTable],FALSE	; initialize both
						; fUsingUnNamed_Mrs and
						; fGrewRsTable with one mov
	mov	di,[grs.GRS_oMrsCur]		; save grs.oMrsCur
	cmp	[ogNam],OGNAM_GMRS		; making global mrs?
	DJMP	jz  Make_gMrs			;	brif so - special case
	call	AlphaORsFree			;release table of sorted oRs's
	cCall	MrsDeActivate			;save existing mrs, empty mrsCur

	mov	al,PT_NOT_PROC			;signal to search tMrs, not tPrs
	cCall	RsTableSearch,<ogNam>		; returns oMrs if entry 
						;   found, or
	mov	dx,UNDEFINED
	cmp	ax,dx				;   UNDEFINED if not found
						;   also puts oHole in bx
	jnz	Make_Mrs_DD_ER			;brif entry was found

	inc	dx				;now dx == 0
	.errnz	OGNAM_UNNAMED - 0
	mov	cx,[ogNam]			
	cmp	cx,dx				; making an unnamed mrs?
	jz	Make_Unnamed_Mrs		;  brif so

	cmp	cx,OGNAM_PSEUDO_MAX		; some other special ogNam?
	jbe	Make_Mrs			;   brif so

	DbChk	ogNam,ogNam			
	test	byte ptr ([flags+1]),FM2_NoPcode OR FM2_Include	
						;is this mrs for a text object?
	jnz	Make_Mrs			;  brif so; keep unnamed mrs

	call	EmptyMrs			;see if there's an empty
						;  unnamed mrs
	jcxz	Make_Mrs			; brif there isn't one
	jmp	short Use_Empty_Mrs		

Make_Mrs_DD_ER:
	mov	[oRsDupErr],ax			;tell caller oRs of conflict
	mov	ax,ER_DD
	jmp	MrsMake_Err_Exit1		;reactivate input mrsCur & exit

Use_Empty_Mrs:
	mov	si,SIZE MRS + OMRS_GLOBAL	; oMrs for unnamed entry
	push	si				;parm to MrsActivateCP
	call	MrsActivateCP

	or	[conFlags],F_CON_LeaveTMrsEmpty ;so MrsDiscard won't create a
						;  new module after discarding!
	cCall	MrsDiscard			;discard empty unnamed mrs
	and	[conFlags],NOT F_CON_LeaveTMrsEmpty ;reset to default
	mov	[fUsingUnNamed_Mrs],TRUE	;in case of later OM error
	mov	ax,si				;oMrs to unlink from free list
	call	UnlinkFreeMrs			;unlink the entry from the
						;  free list, (MrsDiscard
						;  linked it in)
	jmp	SHORT Init_New_Mrs1		

Make_Text_Mrs:
	or	bx,bx
	jnz	Make_Mrs

	dec	bx				;if making a text mrs, CANNOT
						;  allow it to go in @ offset 0
	jmp	short Make_Mrs

Make_Unnamed_Mrs:
	mov	ax,SIZE MRS + OMRS_GLOBAL	;offset that empty unnamed mrs
						;  MUST go at (parm to UnlinkFree Mrs)
	mov	si,ax
	call	UnlinkFreeMrs			;unlink the entry from the
	mov	bx,si				; offset that empty unnamed
						;   mrs MUST go at
	cmp	bx,[grs.GRS_bdRs.BD_cbLogical]	;is the table empty?
	jz	Make_Mrs_Grow
Init_New_Mrs1:					
	jmp	short Init_New_Mrs
Make_gMrs:
	mov	si,OMRS_GLOBAL			; new oMrs
	PUSHI	ax,<dataOFFSET grs.GRS_bdRs>	
	PUSHI	ax,<SIZE MRS + OMRS_GLOBAL>	
	call	BdGrow				
	jmp	short Make_Mrs_Grow_1		
Make_Mrs:
	mov	si,bx				;save hole location
	cmp	si,UNDEFINED			;is there a hole in table?
	jz	Make_Mrs_Grow			;  brif not

	DbAssertRel bx,z,oFreeMrsFirst,CP,<MrsMake: given hole not first free>
	RS_BASE add,bx
	mov	bx,PTRRS[bx.MRS_oMrsNext]
	mov	[oFreeMrsFirst],bx		;free entry now unlinked from
						;  free mrs chain
	GETRS_SEG   es,bx,<SIZE,LOAD>		
	jmp	short Init_New_Mrs
Make_Mrs_Grow:
	mov	si,[grs.GRS_bdRs.BD_cbLogical]	;new oMrs
	or	si,si				; Rs table > 32k?
	js	J_MrsMake_OM_Err		; brif so ... give OM error

	PUSHI	ax,<dataOFFSET grs.GRS_bdRs>
	PUSHI	ax,<SIZE MRS>
	call	BdGrow
Make_Mrs_Grow_1:				
	or	ax,ax
	jnz	@F				; brif successful
J_MrsMake_OM_Err:				
	jmp	MrsMake_OM_Err
@@:						
	mov	[fGrewRsTable],TRUE		; remember we grew in case
						; later error
Init_New_Mrs:
	mov	ax,dataOFFSET mrsCur
	mov	bx,SIZE MRS
	mov	cx,MRS_CB_ZERO_INIT
	call	InitStruct
	mov	[mrsCur.MRS_cbFrameVars],-FR_FirstVar	;	
						; reset to init. value. This
						; value is 2 to account for
						; the fact that b$curframe 
						; is always pushed on the
						; stack after bp, so we
						; treat this word as a frame
						; var for ref'ing the real
						; frame vars off of bp
	mov	ax,[flags]
	mov	[mrsCur.MRS_flags],al
	mov	[mrsCur.MRS_flags2],ah
	mov	ax,si
	call	SetMrsAx			;grs.oMrsCur = oRsCur = ax
	GETRS_SEG   es,bx,<SIZE,LOAD>		
	mov	bx,si				;oMrsNew
	RS_BASE add,bx				;add base of tRs to bx
	mov	PTRRS[bx.MRS_ogNam],UNDEFINED	;mark entry as inactive, since
						;  mrsCur has actual mrs
	mov	PTRRS[bx.MRS_oMrsNext],UNDEFINED ;in case someone tries to walk
						 ;  the mrs chain before this
						 ;  mrs gets deactivated
	cCall	TxtCurInit			;init txdCur
	jnz	no_error
	jmp	MrsMake_TxtInit_Err
no_error:

	test	byte ptr ([flags+1]),FM2_NoPcode; is a document mrs?
	jz	MakeVarTables			; brif not, create tables
	call	NewBuf				; allocate document buffer
	mov	WORD PTR [mrsCur.MRS_pDocumentBuf],ax ; set ptr to buffer
	or	ax,ax				; was it successful?
	mov	al,ER_OM			; assume not, set error
	jz	MrsMake_OM_2_Err		; brif out of memory
	jmp	SHORT MrsMake_Name		; finish creating txt tbl

MakeVarTables:

	cCall	MakeMrsTVar			; set up module var table
	or	ax,ax
	jz	MrsMake_OM_2_Err

	mov	ax,SbGNam			; assume global mrs
	cmp	[ogNam],OGNAM_GMRS		; making global mrs?
	jz	MrsMake_TNam			;	brif so

	sub	ax,ax				; don't use special sb
MrsMake_TNam:					
	cCall	TNamInit,<ax>			; set up module name table
	or	ax,ax
	jz	MrsMake_OM_3_Err

MrsMake_Name:
	mov	ax,[ogNam]			
	mov	[mrsCur.MRS_ogNam],ax		; set module name
	mov	[mrsCur.MRS_oMrsNext],UNDEFINED 
	.errnz	1 - OGNAM_GMRS			
	dec	ax				; is this the global module?
	jz	MrsMake_Exit			;  brif so - exit (this
						;      mrs doesn't have to be
						;      linked, as it's known
						;      to be at offset 0)
	;After this point, no errors can occur, so its ok to tell
	;user interface the oRs of the new module
	
	xchg	ax,dx
	mov	ax,[grs.GRS_oMrsCur]
	mov	[rsNew],ax			;tell user interface to
						; show new mrs in list window
Link_Mrs:
	;Now, link this module into mrs chain
	GETRS_SEG   es,bx,<SIZE,LOAD>		
	mov	bx,OMRS_GLOBAL			;start with global mrs
MrsLink_Loop:
	RS_BASE add,bx
	mov	dx,PTRRS[bx.MRS_oMrsNext]
	inc	dx
	.errnz	UNDEFINED - 0FFFFH
	jz	GotChainEnd			;brif bx points to last current
						;  entry in the mrs chain
	dec	dx
	mov	bx,dx
	jmp	MrsLink_Loop
GotChainEnd:
	mov	PTRRS[bx.MRS_oMrsNext],ax	;link new entry at end of chain
	;Note that the oMrsNext field in the new entry will automatically be
	;UNDEFINED in the new entry, and we set it to UNDEFINED earlier in
	;this routine

	xor	ax,ax
	test	byte ptr ([flags+1]),FM2_NoPcode OR FM2_Include	
						;is this mrs for a text or
						;  INCLUDE object?
	jnz	Main_Set2			;  brif so - IT can't be MAIN

	dec	ax
	.errnz	UNDEFINED - 0FFFFh
	cmp	[grs.GRS_oMrsMain],ax		;is there already a MAIN module?
	jz	Main_Set0			;  brif not
	call	MainModified			;mark main module as modified
						; if current mrs is pcode
						; mrs (so we will be sure

⌨️ 快捷键说明

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