📄 conmisc.asm
字号:
sub ax,4 ;oTx of first exStData pcode
ResetData_Exit:
mov [mrsCur.MRS_data_otxCur],ax ;otxFirst - 4 or UNDEFINED
mov ax,sp
ret
ResetData ENDP
;***
;Clear_Mod
;Purpose:
; Tasks that must be performed for each module, lumped together here
; to reduce context switching (for speed)
;Entry:
; none.
;Exit:
; always returns AX != 0
;*******************************************************************************
Clear_Mod PROC NEAR
mov [mrsCur.MRS_otxHandler],UNDEFINED
;reset module error trap
call ResetData ;reset DATA statements
;Reclaim space in module name table. Only really needs to be done for
;RUN init, but who cares about the extra time for CLEAR ...
call CompressTNam ;returns AX != 0
ret
Clear_Mod ENDP
;***
;ClearStmt, Clear_RunInit
;
;Purpose:
;
; This is called by CLEAR and by RunInit() for RUN, LOAD, NEW, CHAIN etc.
; statements to do the following:
;
; - Call the Variable Mgr functions ClearCommon,
; ClearMV() for each module, and ClearPVStat() for
; each procedure in each module, and ClearPVFrame()
; for each procedure on the stack to:
; - Set all numeric static variables to zero
; - Release all string variables
; - Do the equivalent of an ERASE on all arrays
; - Remember that we can't CONT
; - Reset the module data pointer for each module
; - Reset the module error trap for each module
; - Reclaim free space in each module name table
; - Close all user files (not system files like the
; file being loaded etc.)
; - Perform special version-specific reinitialization
; (graphics, sound, pen, strig, etc.)
; - Reinitialize the random number seed
; - Sets bosFlags FBOSRESETSTK bit to cause stack to be reset @ next
; BOS/BOL
;
; Since CLEAR causes the stack to get reset, we have chosen not to allow a
; program to execute CLEAR from within a procedure or function; the text
; manager will issue an error message to prevent this.
;
; Clear_RunInit is just like ClearStmt, except that it is assumed that
; static structs are already set up on input, and that this routine need
; not reset the DATA statements in each module; this is a speed optimization
; to prevent needless context switching.
;Entry:
; none.
;Exit:
; none.
;Uses:
; none.
;Exceptions:
; none.
;
;*******************************************************************************
cProc Clear_RunInit,<FAR,NODATA>
cBegin Clear_RunInit
push es ;save for executor
xor ax,ax
jmp short Clear_Spt_Common
cEnd Clear_RunInit,<nogen>
cProc ClearStmt,<PUBLIC,FAR,NODATA>
cBegin ClearStmt
push es ;save for executor
call EnStaticStructs ;activate static mrsCur and
; prsCur for this routine
Clear_Spt_Common:
push ax ; save flag
mov al,FE_PcodeMrs+FE_CallMrs+FE_SaveRs
mov bx,OFFSET CP:Clear_Mod
call ForEachCP ;retval guaranteed to be TRUE
call ClearTheWorld
or BosFlags,FBOSRESETSTK ;cause stack to be reset @ next
; BOS/BOL
mov [pGosubLast],0 ;reset - - - can't RETURN now
and [grs.GRS_flagsDir],NOT FDIR_cleared ;reset flag, so next call to
; ClearTheWorld doesn't
; assume world is clear
pop cx
jcxz StaticStructs_OK ;brif context state is okay
call DisStaticStructs ;deactivate static prsCur &
; mrsCur again (as they were
; on input)
StaticStructs_OK:
pop es
cEnd
;***
;CantCont()
;
;Purpose:
; Sets grs.otxCONT to UNDEFINED, i.e., makes it so the user
; can no longer CONTINUE.
;Note:
; When UserInterface() is entered, if we were not executing out of the
; direct mode buffer, grs.otxCONT is set to the current
; text pointer (grs.otxCur).
;Entry:
; none.
;Exit:
; none.
;Uses:
; none.
;Exceptions:
; none.
;
;*******************************************************************************
cProc CantCont,<PUBLIC,FAR,NODATA>
cBegin CantCont
mov cx,UNDEFINED
xchg [grs.GRS_otxCONT],cx ;ensure this gets set to UNDEFINED
inc cx
.errnz 0FFFFH - UNDEFINED
jcxz CantCont_Exit ;brif already couldn't CONTinue
; (because RunInit closes files)
test [conFlags], F_CON_RunFile
jnz CantCont_Exit ;brif we're clearing the decks
; to load and run a file -
; don't want to show debug screen
push [grs.GRS_oRsCur] ;pass caller's oRs to RsActivateCP below
; RunInit deactivates current prs
call RunInit
call RsActivateCP ;parm pushed above
call EnsShowDebugScrFar
CantCont_Exit:
cEnd CantCont
sEnd CP
sBegin SCAN
assumes cs,SCAN
;***
;FCanCont
;
;Purpose:
; tests grs.otxCONT for UNDEFINED, i.e., sees if the user
; can CONTINUE.
;Entry:
; none.
;Exit:
; ax = 0 and psw.Z is set if the user cannot continue
;Uses:
; none.
;Exceptions:
; none.
;
;*******************************************************************************
cProc FCanCont,<PUBLIC,NEAR,NODATA>
cBegin
mov ax,[grs.GRS_otxCONT]
inc ax ;ax = 0 if can't continue
cEnd
sEnd SCAN
sBegin CP
assumes cs,CP
;***
;NextQBI_Frame
;Purpose:
; Given a frame pointer, return the next higher frame pointer if it's
; a QBI frame. Indicate whether a QBI frame was found or not, and if
; the end of frame chain or broken chain or non-QBI frame was found.
;Input:
; di = pointer to a pointer to a frame
;Output:
; PSW.C set if invalid frame found (broken chain, or non-QBI frame found)
; if PSW.C clear,
; PSW.Z set if end of BP chain found ,i.e., there exist no more frames
; If both of the above flags are clear, di on exit points to the next
; higher QBI frame on the stack, and the oRs for this frame is
; activated
; ax also contains PSW flags
;*******************************************************************************
cProc NextQBI_Frame,<PUBLIC,FAR>
cBegin
mov ax,[di]
mov bx,[b$mainframe]
DbAssertRel [bx],z,0,CP,<NextQBI_Frame: BP chain not zero terminated>
cmp bx,ax ;end of frame chain?
jc Flags_Set_Exit ; brif new ptr above stack
jz No_Carry_Exit ; brif so
cmp ax,di ;is new ptr > old?
jc Flags_Set_Exit ; brif not - broken chain
mov di,ax
shr al,1 ;is the new frame ptr odd?
jc Flags_Set_Exit ; brif so - broken chain
call ValidORs ;ax = 0 if valid QBI frame
or ax,ax
jnz Set_Carry_Exit ;brif QBI frame not found
;success - ensure PSW.Z and PSW.C are reset and exit
inc ax ;reset PSW.Z
SKIP2_AX ;skip to No_Carry_Exit
Set_Carry_Exit:
stc
SKIP1_AL ;skip the clc, leave PSW intact
No_Carry_Exit:
clc ;success or end of BP chain
Flags_Set_Exit:
pushf
pop ax
cEnd NextQBI_Frame
;***
;ActiveORs_Frame
;Purpose:
; Given a pointer to a pointer to a frame and grs.GRS_oRsCur, walk
; the stack checking each QBI frame on the stack until we find
; one that was pushed from the context of the given oRs, or until
; we find the end of the chain, a broken chain, or a non-QBI frame.
;Input:
; ppFrame == pointer to a pointer to a frame (ex: mov bx,dataOFFSET
; b$curframe)
; grs.GRS_oRsCur is set for the register set we're looking for on stack.
;Output:
; PSW.C set if given oRs definitely has no active frame on the stack.
; PSW.C clear if given oRs IS found, OR if it MIGHT have an active
; frame on the stack.
;
; ax == 0 if given oRs definitely has no active frame on the stack.
; ax != 0 if given oRs IS found, OR if it MIGHT have an active
; frame on the stack.
;Note:
; Note that this routine could THINK a frame is a QBI frame
; when it really isn't. It only checks the oRs part of the frame.
;*******************************************************************************
cProc ActiveORs_Frame,<PUBLIC,FAR>,<SI,DI>
parmW ppFrame
cBegin
mov bx,[ppFrame]
mov si,[grs.GRS_oRsCur] ;oRs we're looking for
cmp word ptr [bx],0
jz ORsFrame_Exit ;brif special case of no frames to
; search
mov di,bx
ORsFrame_Loop:
call NextQBI_Frame
push ax
popf
jc ORsFrame_Success ;brif broken chain or non-QBI frame
jz ORsFrame_Exit ;brif end of frame chain found
cmp si,[grs.GRS_oRsCur]
jnz ORsFrame_Loop ;brif this frame for a different oRs
;success - - - given oRs frame IS on stack
ORsFrame_Success:
clc
SKIP1_AL ;skip stc and exit
ORsFrame_Exit:
stc ;indicate failure
pushf
cCall RsActivate,<si> ; reactivate input oRsCur
mov bx,di ;retval if success
sub ax,ax ; assume no active frame found
popf
jc @F ; brif no active frame found
mov ax,sp
@@:
cEnd
;***
;FindORsFrame
;Purpose:
; Given b$curframe and grs.GRS_oRsCur, walk the stack checking each
; QBI frame on the stack until we find one that was pushed from the
; context of the given oRs, or until we find the end of the chain, a
; broken chain, or a non-QBI frame.
;
; NOTE: This does NOT look at the active frame, only previously pushed
; frames. If you want to examine the active frame, use oRsCont.
;Input:
; b$curframe is the first frame to examine.
; grs.GRS_oRsCur is set for the register set we're looking for on stack.
;Output:
; AX = 0 if the given oRs has no active frame on the stack.
; AX != 0 means that there is PROBABLY an active frame for this oRs.
;*******************************************************************************
cProc FindORsFrame,<PUBLIC,NEAR>
cBegin
mov bx,dataOFFSET b$curframe ;ptr to ptr to first frame
cCall ActiveORs_Frame,<bx>
cEnd
sEnd CP
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -