📄 conmisc.asm
字号:
cCall ResetCommon ;note: must call this BEFORE
;NewDiscard; otherwise, if there
;exists some common value of
;user defined type, and we've
;tossed the type table, then
;access of that variable will
;cause an error
;Note that the below scheme depends on the fact that NextMrsFile
;finds the first mrs in the table if grs.GRS_oMrsCur is UNDEFINED, and
;that MrsDiscard will set that field to UNDEFINED. It is not safe to
;call ForEachCP to do this, because that scheme depends on walking
;the mrs chain, and MrsDiscard discards the current entry. In essense
;we are starting from the top of the mrs chain each time through the
;loop below.
call MrsDeactivate ;required so NextMrsFile
;starts from the beginning
MrsDiscard_Loop:
call far ptr NextMrsFile ;activate next file mrs
inc ax ; no more file mrs's?
jz MrsDiscard_Cont ; brif so - exit loop
call MrsDiscard ;discard active mrs
jmp short MrsDiscard_Loop
MrsDiscard_Cont:
mov [fTraceOn],0 ; do the equivalent of TROFF
PUSHI ax,OMRS_GLOBAL
cCall MrsActivateCP ;[16] activate the global mrs
PUSHI ax,SbGNam ; parm to TNamInit
call TNamInit ; reinit global name table
call VarRudeReset
mov ax,SIZE MRS + OMRS_GLOBAL ; we know new empty unnamed
; mrs will be at this offset
cCall MrsActivateCP,<ax> ;activate the empty unnamed mrs
call ParseNewInit ;parser reinit stuff
DbAssertRel ax,nz,0,CP,<NewStmt: ParseNewInit returned an error code>
or [b$CtrlFlags],NoSTACKINIT ;speed optimization for LOAD
; don't bother to reinit the
; stack
call far ptr RunInit ;note that this alters si & di
and [b$CtrlFlags],NOT NoSTACKINIT ;reset to default value
cmp [fChaining],FALSE
jnz NewStmt_Exit ;brif we're CHAINing
test [conFlags], F_CON_RunFile
jnz NewStmt_Cont ;brif we're clearing the decks
; to load and run a file -
; don't want to show debug
; screen yet in this case
call EnsShowDebugScrFar
NewStmt_Cont:
or [conFlags],F_CON_ResetStkSize ;reset the stack to default
; size on next BOS or BOL
NewStmt_Exit:
and [grs.GRS_flagsDir],NOT FDIR_new ;NewStmt no longer active
cEnd NewStmt
J1_RtError:
call RtError ;error(ax), never returns
;***
;TrimBdlDirect - Trim the direct mode buffer
;
;Purpose:
; We trim the direct mode buffer to give back most of the space to
; the user when we reinitialize basic (NewStmt) or prior to running
; a program, but we must never trim it to less than CB_PCODE_MIN - - -
; this is to ensure that the user can ALWAYS do a CLEAR, SETMEM,
; SYSTEM, etc., even when essentially out of memory.
;Entry:
; none.
;Exit:
; none.
;Uses:
; none.
;Exceptions:
; none.
;*******************************************************************************
cProc TrimBdlDirect,<NEAR,NODATA>
cBegin
PUSHI ax,<dataOFFSET grs.GRS_bdlDirect>
mov ax,[grs.GRS_bdlDirect_cbLogical]
cmp ax,CB_PCODE_MIN
ja Trim_It ;brif cbLogical > CB_PCODE_MIN
mov ax,CB_PCODE_MIN
Trim_It:
push ax ;size to realloc to
call BdlRealloc ;trim Direct mode buffer to
; minimum safe size
cEnd
;***
;ContReinit, ContReinitStat
;
;Purpose:
; This routine does a subset of the work that RunInit does, and is
; called when a user continues.
;Entry:
; none.
;Exit:
; none.
; ContReinit Disables static structs if they weren't already disabled
; ContReinitStat always leaves static structs active.
;Uses:
; none.
;Exceptions:
; none.
;*******************************************************************************
PUBLIC ContReinit
PUBLIC ContReinitStat
ContReinit:
xor ax,ax
SKIP2_PSW ;fall into ContReinitGen
ContReinitStat:
mov ax,sp
?DFP = DFP_NONE ; don't smash regs ...
cProc ContReinitGen,<FAR,NODATA>,<SI>
cBegin ContReinit
?DFP = DFP_CP ; restore switch
xchg ax,si ;save input flag
call EnStaticStructs ;activate static structs for
; call to ForEachCP
mov al,FE_PcodeMRS+FE_CallMRS+FE_SaveRs
mov bx,OFFSET CP:CompressTNam
call ForEachCP ;crunch all module name tables
; down to cbLogical
cCall BdCompressAll ;reduce all entries to cbLogical
; size, compress heap
cCall TrimBdlDirect
or si,si
jnz ContReinit_Exit ;brif want static structs active
call DisStaticStructs ;deactivate static structs
ContReinit_Exit:
cEnd ContReinitGen
;***
;CompressTNam
;
;Purpose:
; Realloc mrsCur.MRS_bdlNam down to it's cbLogical size (to free up as
; much heap space as possible for execution).
;Entry:
; mrsCur assumed set up.
;Exit:
; always returns TRUE
;Uses:
; none.
;Exceptions:
; none.
;*******************************************************************************
cProc CompressTNam,<NEAR,NODATA>
cBegin CompressTNam
PUSHI ax,<dataOFFSET mrsCur.MRS_bdlNam>
call BdlTrim ;crunch module name table down
; to free all unused space
; for execution
mov ax,sp ;return TRUE
cEnd CompressTNam
;***
;FindAnMrs
;Purpose:
; Used to find the first mrs in the mrs table with some special
; characteristics. Called by any of the ForEachXXX routines, just
; saves grs.GRS_oMrsCur in the static 'oMrsDesired' and returns FALSE,
; to terminate the ForEachXXX caller.
;Entry:
; mrsCur is a pcode mrs.
;Exit:
; returns FALSE (ax = 0).
;Exceptions:
; none.
;*******************************************************************************
cProc FindAnMrs,<NEAR,NODATA>
cBegin FindAnMrs
mov ax,[grs.GRS_oMrsCur]
mov [oMrsDesired],ax
xor ax,ax ;terminate ForEachXXX caller.
cEnd FindAnMrs
;***
;RunInit()
;
;Purpose:
; This is called by NewStmt(), and the RUN statement executer to do the
; following:
; - Call ClearStmt
; - reset event handlers and error traps
; - deactivate current prs, if any
; - Set grs.oPrsCur = UNDEFINED,
; - Call RT entry point B$RUNINI to do runtime reinit.
;
;Entry:
; none.
;Exit:
; ax = 0 if no error, else contains a standard error message.
;Uses:
; SI and DI
;Exceptions:
; Does not return in the case of a runtime error.
;
;*******************************************************************************
cProc RunInit,<PUBLIC,FAR,NODATA>
cBegin RunInit
and [grs.GRS_flags],NOT FG_RetDir ;remember there's no ret adr to
; direct mode buffer on stack.
call EnStaticStructs ;activate static mrsCur and
; prsCur for this routine
push ax ; save returned flag
test [mrsCur.MRS_flags2],FM2_NoPcode
jz RunInit_Cont ;brif active module can be
; counted on to have a var tbl,
; a name table, etc.
;search the mrs table and activate the first one encountered that
; is a pcode mrs (MUST be one ...) - - - this is so we don't try to
; CLEAR a non-existent var table, for example, in, say, the mrs for
; Immediate mode (B$RUNINI can also make a call-back that uses the
; nammgr ...)
mov al,FE_PcodeMrs+FE_CallMrs
mov bx,OFFSET CP:FindAnMrs
cCall ForEachCP
push [oMrsDesired]
cCall MrsActivateCP ;activate pcode mrs
RunInit_Cont:
call far ptr Clear_RunInit ;retval must be TRUE, since
; we're not changing memory size
mov [grs.GRS_otxCONT],UNDEFINED
cCall DebugReset ;release WATCH str descriptors,
; reset history buffer
cCall BdCompressAll ;reduce all entries to cbLogical
; size, compress heap
cCall TrimBdlDirect ;trim direct mode buffer
pop cx
jcxz Static_Structs_OK ;brif static structs were
; active on entry
call DisStaticStructs ;deactivate static structs
; (as they were on input)
Static_Structs_OK:
push [grs.GRS_oMrsCur]
cCall RsActivateCP ;ensure no procedure is active
; note we can't just call
; PrsDeActivate here, as static
; structures might not be active
cmp [fChaining],FALSE
jnz Chaining ;brif this is for CHAIN, not RUN
push WORD PTR ([fDebugScr])
call EnsMouseOff ;otherwise, B$RUNINI leaves a
; ghost of mouse cursor
PUSHI ax,<RTOFFSET B$RUNINI>
call CallRtTrap_RT ;ax = 0 if no error, error code
;runtime reinit. for RUN, NEW
pop cx ;cl = old value of fDebugScr
push ax ;error return from B$RUNINI
or cl,cl
je RunInit_Exit1 ;brif debug screen wasn't active
cmp [b$ScreenRestored],0
je NotRestored ;brif B$RUNINI didn't change
; screen modes
call TossOutputScreen ;output screen is activ
NotRestored:
call EnsShowDebugScrFar ;reactivate debug screen
RunInit_Exit1:
pop ax ;error return from B$RUNINI
jmp short RunInit_Exit
Chaining:
mov bx,[grs.GRS_bdtComBlk.BD_pb]
;NOTE: we're depending on there always being an entry for blank COMMON,
;NOTE: and that it's always the entry at offset zero in this table
add bx,COM_bdValue ;point to bdValue for blank
; COMMON
xor ax,ax ;assume no QBI blank common,
; or that it's empty
cmp [bx.BD_cbLogical],ax ;is blank COMMON empty?
jz Chaining_Cont ; brif so
TESTM [bx.BD_pb],1 ; if pb is odd, then this is
; not an owner, but is for
; U.L. blank COMMON
jnz Chaining_Cont ;brif not QBI blank COMMON
xchg ax,bx ;pass pBdValue to B$CHNINI
; so it won't release owners
; in this block
Chaining_Cont:
xchg ax,bx ;bx is a parm to B$CHNINI
EXTRN seg_rt:abs
PUSHI ax,<SEG seg_rt>
PUSHI ax,<RTOFFSET B$CHNINI> ;runtime reinit. for CHAIN
call CallRtTrap_Parm ;ax = 0 if no error, error code
RunInit_Exit:
cEnd RunInit
;***
;ResetData() - reset the data pointer for mrsCur
;
;Purpose:
; Called to reset the data pointer for a given module
; Called as part of CLEAR, NEW, RUN, CHAIN, and whenever scanning
; a text table and Cant CONT. This latter case ensures that DATA
; statements get set correctly for READ's in Direct Mode.
;Entry:
; mrsCur is set up.
;Exit:
; Returns AX != 0
;Preserves:
; es
;*******************************************************************************
PUBLIC ResetData
ResetData PROC NEAR
mov ax,[mrsCur.MRS_data_otxFirst] ;oTx of link field of first DATA
; statement
cmp ax,UNDEFINED
jz ResetData_Exit ;brif no DATA, in case there's a
; READ statement (so we give
; the proper error @ runtime)
mov [mrsCur.MRS_data_oLineCur],6 ;offset into current DATA stmt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -