📄 conmisc.asm
字号:
TITLE conmisc.asm - miscellaneous context-related routines
;***
;conmisc.asm - miscellaneous context-related routines for QBI
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; - CLEAR support
; - NEW support
; - Runtime Initialization
; - Context-sensitive heap management support (updating backpointers ...)
; - other miscellaneous context-related support
;
;
;*******************************************************************************
.xlist
include version.inc
CONMISC_ASM = ON
includeOnce architec
includeOnce conint
includeOnce context
includeOnce executor
includeOnce heap
includeOnce names
includeOnce parser
includeOnce qbimsgs
includeOnce rtinterp
includeOnce rtps
includeOnce scanner
includeOnce txtmgr
includeOnce ui
includeOnce variable
.list
assumes CS,CP
assumes DS,DATA
assumes SS,DATA
assumes ES,NOTHING
sBegin DATA
globalB fChaining,FALSE ;TRUE while reinit code is being used
; while loading a new program we're
; CHAINing to
staticW oMrsDesired,0 ;used to find an oMrs of specified type
externB fInitialized
externB b$CtrlFlags ;a byte of various runtime bit flags
externB b$ScreenRestored ;flag set by B$RUNINI
sEnd DATA
EXTRN B$RUNINI:FAR
EXTRN B$CHNINI:FAR
sBegin RT ;so RTOFFSET is defined
sEnd RT
sBegin CP
;***
;AdjustRsTable
;Purpose:
; Adjust owners in the global Rs table when it moves.
; This amounts to walking the mrs chain, adjust the var table
; backpointers.
;Entry:
; SI = pbTable = pointer to the start of the appropriate table
; DI = an adjustment factor to be passed via BdAdjust to update the
; backpointer for each bd in grs.bdtComBlk.
;Exit:
; none.
;Exceptions:
; none.
;
;***************************************************************************
cProc AdjustRsTable,<PUBLIC,NEAR,NODATA>
cBegin
mov si,OMRS_GLOBAL
test [conFlags],F_CON_StaticStructs
jnz RsAdjust_Cont ;brif static structs - pMrsCur not used
add [grs.GRS_pMrsCur],di ;update pointer to mrsCur for use
; at execution
TESTM grs.GRS_oRsCur,08000H ; is active Rs an mrs?
jnz RsAdjust_Cont ; brif so
add [grs.GRS_pRsCur],di ;update pointer to current Rs for use
; at execution
RsAdjust_Cont:
;--------------------------------------------------------------------
; now, SI = offset to current mrs
; DI = adjustment factor for the backpointer into this table
;--------------------------------------------------------------------
RsAdjust_Entry:
cmp si,[grs.GRS_oMrsCur]
jnz RsAdjust_It
test [conFlags],F_CON_StaticStructs
jz RsAdjust_It ;brif not static structs
mov si,dataOFFSET mrsCur
jmp short RsAdjust_Next ;brif this is mrsCur - - - static struct
; won't move
RsAdjust_It:
add si,[grs.GRS_bdRs.BD_pb] ;si points to an mrs in table
mov ax,si
add ax,MRS_bdVar
cCall BdAdjust,<ax> ;adjust bdVar in current mrs
RsAdjust_Next:
mov si,[si.MRS_oMrsNext]
inc si
jz RsAdjust_Done
dec si
jmp short RsAdjust_Entry
RsAdjust_Done:
cEnd
;***
;AdjustITable
;Purpose:
; Given a pointer to either grs.bdtMrs or grs.bdtComBlk
; and the constant IT_MRS or IT_COMMON_BLOCK to indicate which
; one, walk through through the table, calling the Heap Manager (via
; BdAdjust) to adjust the backpointer for each of the bd structures in
; each entry by the constant given in DI.
;
; This routine is called when the heap manager finds it necessary to
; move one of these tables, in order to update backpointers to owners
; in the table as quickly as possible.
;
; Note that this routine depends on the fact that each of these tables
; contain entries which have one or two bd structures, depending
; on the table type. We also assume that the bd structures are contiguous.
;Entry:
; pbTable = pointer to the start of the appropriate table
; oPastLast is the cbLogical of the appropriate table. This amounts
; to an offset to where the NEXT entry would go into the table,
; and is thus a measure of where the table ends (cbLogical is
; kept to the actual size of the table).
; heapType is one of IT_MRS or IT_COMMON_BLOCK.
; DI = an adjustment factor to be passed via BdAdjust to update the
; backpointer for each bd in grs.bdtComBlk.
;Exit:
; none.
;Exceptions:
; none.
;
;***************************************************************************
cProc AdjustITable,<PUBLIC,FAR,NODATA>,<SI>
parmW pbTable
parmW oPastLast
parmB heapType
LocalW cbAdvance ;cb to advance to next entry
LocalW pbInvalid ;pointer to 1st byte past last entry
cBegin AdjustITable
mov cx,[oPastLast]
jcxz Adjust_Done ;Stop right now if empty table
mov al,[heapType]
mov si,[pbTable]
cmp al,IT_COMMON_BLOCK ;is it grs.bdtComBlk?
jz Adjust_Cont ; brif so
DbAssertRelB al,z,IT_MRS,CP,<AdjustITable: unknown heapType>
call AdjustRsTable
jmp short Adjust_Done
Adjust_Cont:
add cx,si ;now cx equals end-of-table pointer
mov [pbInvalid],cx
add si,COM_bdType
mov [cbAdvance],(SIZE COM - SIZE BD)
;--------------------------------------------------------------------
; now, SI = pointer to current bd to be adjusted
; DI = adjustment factor for each backpointer into this table
; cbAdvance = count of bytes from start of last bd to first
; bd in next entry
; pbInvalid = pointer to first byte past last entry in table
;--------------------------------------------------------------------
Adjust_Entry:
cmp si,[pbInvalid] ;any entries left?
jae Adjust_Done ; brif not
cCall BdAdjust,<si> ;adjust first bd in current entry
add si,SIZE BD ;move to next bd
cmp [si.BD_cbPhysical],UNDEFINED
;is this bd really used to store info.
; about a U.L. COMMON block?
jz Adjust_Advance ; brif so
cCall BdAdjust,<si> ;adjust it
Adjust_Advance:
add si,[cbAdvance] ;advance to next entry in table
jnc Adjust_Entry ; brif not special case: wrap
; past FFFF
Adjust_Done:
cEnd AdjustITable
;***
;ClearTheWorld()
;
;Purpose:
; Clear all common variables and clear all module and procedure static
; variables. Does NOT clear (release) frame variables.
;Entry:
; none.
;Exit:
; none.
;*******************************************************************************
cProc ClearTheWorld,<PUBLIC,NEAR,NODATA>
cBegin ClearTheWorld
DbChk ConStatStructs ;ensure static structures
test [grs.GRS_flagsDir],FDIR_cleared ;is the world already clear?
jnz ClearWorld_Exit ; brif so - no work to do
Clear_Common:
cCall ClearCommon
mov bx,OFFSET CP:ClearPV
call ForEachPrsInPlaceCPSav ;clear all prs var tables
mov al,FE_PcodeMrs+FE_CallMrs+FE_SaveRs
mov bx,OFFSET CP:ClearMV
call ForEachCP ;clear all mrs tables
;retval guaranteed TRUE
or [grs.GRS_flagsDir],FDIR_cleared ;note that world is now clear
and [mrsCur.MRS_flags],NOT FM_VARNEW ;reset bit in mrs flags, in
; case we were called as
; VarDealloc
ClearWorld_Exit:
cEnd ClearTheWorld
;***
;VarDealloc()
;
;Purpose:
; Use ClearTheWorld to deallocate all variables in the current module
;
; Note: shares exit with ClearTheWorld.
;
; Note: For QB, this clears all variables in the system, whereas for
; EB, just the variables for the current module (and all proc-
; level statics for procedures in the module) are cleared.
;Entry:
; none in FV_QB4LANG versions.
; in other versions, fClearPV TRUE means we should clear proc-level
; (static) vars as well as module-level vars for the module
;Exit:
; none.
;*******************************************************************************
cProc VarDealloc,<PUBLIC,NEAR,NODATA>
cBegin VarDealloc
DbChk ConStatStructs ;ensure static structures
or [mrsCur.MRS_flags],FM_VARNEW ;tell CLEAR code we want to
; deallocate $static arrays,
; not just zero-fill them (in
; this module only)
jmp short Clear_Common ;share exit with ClearTheWorld
cEnd <nogen>
;***
;NewStmt()
;
;Purpose:
; This is called by the NEW, CHAIN, LOAD statement executers to do the
; following:
; - ForEachMrs, discard the mrs
; - Calls RunInit()
; - Trims the mrs table so that it includes only the mrs for module Untitled
; - releases all prs table entries
; - reinitializes the procedure table
; - Calls the variable manager's ResetCommon() function to discard all
; COMMON value and type blocks and reset the grs.bdComBlk block to empty.
; - Perform the equivalent of a TROFF
; - Calls ParseNewInit
; - Collapse the heap (garbage collect)
;
; Before doing anything, this function calls the user-interface function
; NotSaved(), which lets the user save any unsaved modules, or CANCEL the
; action. If the user selected the CANCEL button (in response to NotSaved),
; a Runtime Error occurs, which allows us to get back to UserInterface and
; cancel the current operation. The user-interface does not report this
; error to the user.
;
;Entry:
; none.
;Exit:
; none.
;Uses:
; DI (preserves ES since this is used by exStNew).
;Exceptions:
; If a module was modified and not saved, NotSaved will allow user to
; cancel - - - if he does so, a runtime error is generated, and this
; routine does not return.
; Does not return in the case of a runtime error.
;
;*******************************************************************************
extrn EmptyMrs:near
cProc NewStmt,<PUBLIC,FAR,NODATA>,<ES,SI>
cBegin NewStmt
call EnStaticStructs ;ensure static mrsCur and
; prsCur are activated
cCall NotSaved ;notify user, get his response.
; if CANCEL, ax=MSG_GoDirect
; if user said NO, ax=FFFF
; if I/O error, ax = error code
; if files saved ok, ax=0
DJMP jg J1_RtError ;brif runtime error while
; saving files, or CANCEL
or [grs.GRS_flagsDir],FDIR_new ;note that NewStmt is active
; (speed optimization)
mov [grs.GRS_otxCONT],UNDEFINED ;NOTE must be done before any
;text tables are discarded
;so we don't tell user "This
;will prevent CONT"
call CmdWatchDelAll ;eliminate all Watch expressions
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -