📄 exmisc.asm
字号:
page 49,132
TITLE EXMISC - Miscellaneous Executors
;***
;exmisc.asm - executors for simple id references.
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
; This module contains:
; - all BOS executor varients.
; - nonspeed-critical NOP executors. They are kept in one
; place for size reduction.
; - WATCH statement executors.
;
; This module also contains the following debugging aids:
; - Dispatch - nonRELEASE versions jmp to a single dispatch entrypoint
; in this module for easier debugging.
;
;
;****************************************************************************
.xlist
NOTEXT = 1
NORASTOPS = 1
NOMB = 1
NOWM = 1
NOMST = 1
include windows.inc
include version.inc
EXMISC_ASM = ON
IncludeOnce architec
IncludeOnce conint
IncludeOnce context
IncludeOnce executor
IncludeOnce exint
IncludeOnce heap
IncludeOnce opmin
IncludeOnce opintrsc
IncludeOnce opstmt
IncludeOnce opcontrl
IncludeOnce opid
IncludeOnce opaftqb4
IncludeOnce pcode
IncludeOnce ui
IncludeOnce variable
.list
assumes es, NOTHING
assumes ss, DATA
sBegin DATA
staticW tempWord,0 ;temp storage for a word value
sEnd DATA
externFP B$EVCK
externFP B$Break
externFP B$StackReset
externFP B$ClearRange
sBegin CODE
assumes cs, CODE
;-----------------------------------------------------------------------------
; Dispatch - non-RELEASE versions dispatch each pcode from here
;-----------------------------------------------------------------------------
Public Dispatch
Dispatch:
mov cx,es ; for later verification
SETSEG_EQ_SS es ; in case fDirect is TRUE
lea bx,[grs.GRS_bdlDirect_seg]
cmp [grs.GRS_fDirect],FALSE
jnz Dispatch_Cont ;brif active text table is bdlDirect
GETRS_SEG es,bx,<SIZE,LOAD> ;[14]
mov bx,[grs.GRS_offsetTxdSeg]
RS_BASE add,bx ; bx points to appropriate Rs
Dispatch_Cont:
cmp si,PTRRS[bx.BDL_cbLogical - BDL_seg] ;[14]
jae SI_Error
GETSEG ax,PTRRS[bx],,<SIZE,LOAD> ;[14][9] ax == segment address for current seg
cmp ax,cx
jnz ES_Error ;brif ES incorrect
ES_Okay:
xchg ax,cx ; ensure cx has correct seg address
mov bx,[grs.GRS_pMrsCur]
mov ax,PTRRS[bx.MRS_bdVar.BD_pb]
add ax,VAR_value
cmp di,ax
jz DispEx_Cont ; brif di is okay
DI_Error:
DbHalt CODE,<DI Error in exmisc.asm at Dispatch>
DispEx_Cont:
DbChk Heaps ;Check the heap if -tglCheckHeaps set
mov es,cx ; restore pcode segment
LODSWTX ;Pick up an executor
Public DispEx
DispEx: ;useful public for debugging
jmp ax ;And dispatch
ES_Error:
DbHalt CODE,<ES Error in exmisc.asm at Dispatch>
SI_Error:
DbHalt CODE,<Error in exmisc.asm at Dispatch: si past end of text tbl>
subttl Begin of Statement Handling
page
;Table of exception handlers
ExDispTbl LABEL WORD
DW codeOFFSET DoFBosResetStk
DW codeOFFSET DoFBosEvent
DW codeOFFSET DoFBosStop
DW codeOFFSET DoFBosDebug
;ExDispTbl assumes following mask values:
.errnz FBOSRESETSTK - 01h
.errnz FBOSEVENT - 02h
.errnz FBOSSTOP - 04h
.errnz FBOSDEBUG - 08h
;***
;B$IEvSet - set the FBOSEVENT bit in BosFlags
;
; NOTE: This routine will be called with interrupts disabled.
;
;Input:
; none.
;Output:
; The FBOSEVENT bit is set in BosFlags
;Preserves:
; ALL but flags
;*******************************************************************************
cProc B$IEvSet,<PUBLIC,FAR,NODATA>
cBegin
.errnz HIGH FBOSEVENT ;assuming FBOSEVENT in low byte of word
or BYTE PTR [BosFlags],FBOSEVENT ; set the bit
cEnd
;***
;B$IEvReset - reset the FBOSEVENT bit in BosFlags
;
; NOTE: This routine will be called with interrupts disabled.
;
;Input:
; none.
;Output:
; The FBOSEVENT bit is reset in BosFlags
;Preserves:
; ALL but flags
;*******************************************************************************
cProc B$IEvReset,<PUBLIC,FAR,NODATA>
cBegin
and [BosFlags],NOT FBOSEVENT
cEnd
;*******************************************************************************
;DoFBosStop - handle BOS flag FBOSSTOP
;Purpose:
; This routine is invoked the runtime calls us back to inform us that
; the user hit Ctl-Break.
;
; This routine does not return - - execution is halted, control is
; returned to Direct Mode.
;
;Input:
; ax contains the FBOSSTOP bit
;*******************************************************************************
DoFBosStop:
pop ax ;Throw away the return address
FBosStop_Event: ;(entry from DoFBosEvent if untrapped
; ctl-break detected)
and [BosFlags],NOT FBOSSTOP ;turn off bit
jmp B$Break ;ends up jumping to exStStop
;***
;B$IBreak - call-back from runtime to cause us to STOP at next BOS/BOL
;
;Input:
; none.
;Exit:
; none.
;Preserves:
; ALL but PSW
;
;***************************************************************************
cProc B$IBreak,<PUBLIC,FAR,NODATA>
cBegin
.errnz HIGH FBOSSTOP ;assuming FBOSSTOP in low byte of word
or BYTE PTR [BosFlags],FBOSSTOP ; set the bit
cEnd
;*******************************************************************************
;DoFBosEvent - handle BOS flag FBOSEVENT
;Purpose:
; This routine is invoked when an event has occured during the previous
; statement (and the runtime set FBOSEVENT via B$IEVSet).
;
; We push our current context on the stack, and call the runtime; the
; runtime will in turn call back to QBI code if there's an event handler
; in QBI text, or start a compiled-basic event handler, or just return
; if there's no handler for the posted event.
; If there is a handler invoked, as long as it returns, we'll get control
; back here, to take up execution where it was left off.
;
; NOTE: the other Bos exception handlers turn off their own bit in
; NOTE: BosFlags. This had been done just prior to the call, but it's
; NOTE: important that our code NEVER change the FBOSEVENT bit in
; NOTE: BosFlags, or we introduce the possiblity of missing events.
;
;*******************************************************************************
DoFBosEvent:
pop dx ;Throw away the return address.
; Must not re-execute BOS code; to be
; compatable with BC3, must allow
; at least one statement to execute
; between event traps
cmp [grs.GRS_fDirect],FALSE ;Are we executing in Direct Mode?
jnz BosEvent_Exit ; brif so - - - ignore events
; (note that ax, bx, cx are still
; set up from BOS exception loop)
test [grs.GRS_flags],FG_WatchActive
jnz BosEvent_Exit ;Ignore events while WATCH expression
; is being evaluated.
mov [grs.GRS_oTxCur],si ;must do this for case where QBI event
; handler fires up - - - IT preserves
; oTxCur and oRsCur in event frame
mov [fNonQBI_Active],bp ;in case non-QBI code is envoked
push [b$curlevel]
pop [bcurlevel_QBI] ;in case we must later restore
; b$curlevel to what it is now
push [BosFlags] ;remember if FBOSDEBUG bit was on
and [BosFlags],NOT FBOSDEBUG ;don't allow user to trace into an
; event handler
call B$EVCK ;runtime invokes event handler if
; there is one.
;B$EVCK returns:
; al = non-zero if an untrapped
; ctl-break occured
pop bx ;old BosFlags
and bx,FBOSDEBUG
or [BosFlags],bx ;if FBOSDEBUG bit had been set prior to
; calling B$EVCK, turn it back on. If
; it was turned on in a QBI event
; handler, leave it on
mov [fNonQBI_Active],0 ;reset (QBI code is definitely active
; now)
mov si,[grs.GRS_oTxCur] ;in case a non-QBI event occured
or al,al
jnz FBosStop_Event ;brif untrapped ctl-break
;go back to BOS Flag handling loop, but only if one or more flags
;of lower priority (than the Event flag) are set. This ensures that
;we'll allow at least one statement to be executed between event
;handler invocations (which is compatable with the compiler design),
;and that we'll allow break-points to function correctly after an event
;handler returns
mov ax,FBOSEVENT
.errnz FBOSEVENT - 2
mov bx,ax ;FBOSEVENT == 2^N, then bx must be 2*N
; here we're depending on the fact that
; for N = 1, 2^N == 2*N (N is the bit#)
mov cx,[BosFlags]
BosEvent_Exit:
TESTX cx,<NOT (FBOSEVENT OR (FBOSEVENT - 1))>
;are any lower priority bits set?
jnz BosContLoop ; brif so - handle other bit(s)
jmp DispMov ; brif not - - - infinite loop would
; result if we went back to
; BosContLoop without any other
; bits set
DbCheckBos MACRO
DispMac
ENDM
;***
;exBreakPoint
;Purpose:
; This pcode follows the opBol[Lab][Sp] opcode on any line which
; has a breakpoint set. It causes the executor to call UserInterface().
;Exit:
; DEBUG_STOP flag is set in [debugFlags]
;
;******************************************************************************
;***
;BosException - Handle the beginning of statement flags
;Purpose:
; Some executor has set a begin of statement flag. This routine
; handles the case that BosFlags have been set. Flag specific
; handlers may be invoked.
;
; Some flags have no handlers.
;Entry:
; si points beyond the bos/bol for current statement
;Exit:
;Modifies:
;*******************************************************************************
;***
;exBos,exBosSp,exBol,exBolSp,exBolLab,exBolLabSp,exBolInclude,exBolIncludeSp
;Pupose:
; Handle begin of statement.
; Each of these handlers performs any unique work (skipping operands, etc)
; and Then checks end of statement flags.
;Inpup:
;Output:
;Modifies:
;******************************************************************************
;NOTE: Even though we could share code in following executors, we don't
; for the sake of execution speed.
;
MakeBol MACRO cSpace
MakeExe exBol&cSpace,opBol+cSpace*(OPCODE_MASK+1)
endm
MakeBol 23
SkipExHeader
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -