📄 uidebug.asm
字号:
mov al,TRACE_STEP
cmp [fPStep],FALSE
je CsNotPStep ;brif F8 was pressed (step into proc)
.errnz TRACE_STEP - 3
.errnz TRACE_PSTEP - 4
inc ax ;al = TRACE_PSTEP (F10=step around proc)
CsNotPStep:
call SetTraceMode
call DoCont ;continue program execution
cEnd
;**************************************************************************
; CmdToggleBp()
; Purpose:
; Toggles the breakpoint setting of the current line.
; Note: will only be called if the current window contains code.
;
; Exit:
; If an edit window is active a breakpoint is set/reset at the
; current line.
; ax active edit line (UNDEFINED if none)
;
;**************************************************************************
cProc CmdToggleBp,<PUBLIC,NEAR>
cBegin
call UiGrabSpace
call GetEditLine ;ax = current edit line (from EditMgr)
push ax ;save for return value
inc ax ;test for UNDEFINED
je CsNoEditLine
dec ax
push ax ;pass to ToggleBp
call ToggleBp
mov [uierr],ax ;store possible error code
call DrawDebugScr ;Refresh any lines containing
;this breakpoint
CsNoEditLine:
call UiReleaseSpace
pop ax ;ax = edit line
cEnd
;**************************************************************************
; CmdGoUntilHere()
; Purpose:
; Sets a non-sticky breakpoint at the current line and runs until it
; gets there. When the breakpoint is reached it will automatically be cleared.
; Note: will only be called if the current window contains code.
;
;**************************************************************************
cProc CmdGoUntilHere,<PUBLIC,NEAR>
cBegin
call UiRsActivateWnd ;activate active window's context
test [mrsCur.MRS_flags2],FM2_Include OR FM2_NoPcode
jne CgExit ;brif not a pcode window
call GetEditLine ;get line number
cCall OtxOfLn,<ax> ;get otx
cCall fBpSet,<ax> ;see if bp is set
or ax,ax
jnz CgGo ;do nothing if bp already set
call CmdToggleBp ;set break point on current line
inc ax ;test for UNDEFINED
je CgExit ;brif no active edit line
dec ax ;restore ax = line number
mov [nonStickyBpLn],ax ;remember to reset break point
mov ax,[grs.GRS_oRsCur]
mov [nonStickyBpRs],ax
CgGo:
call ContContext ;activate program counter's context
call SkipStop ;skip past the opBreakPoint
xor ax,ax
cCall CmdGo,<ax> ;continue program execution
CgExit:
cEnd
;**************************************************************************
; ClrNonStickyBp()
; Purpose:
; Called on entry to GetCmd()
; Clears any breakpoint set by CmdGoUntilHere().
; Exit:
; Context may be switched to another text table.
;
;**************************************************************************
cProc ClrNonStickyBp,<PUBLIC,NEAR>
cBegin
mov ax,[nonStickyBpLn]
inc ax ;test for UNDEFINED
je ClrNoBp
dec ax
push ax ;pass to ToggleBp
push [nonStickyBpRs] ;pass to UiRsActivate
call UiRsActivate
call ToggleBp
mov [nonStickyBpLn],UNDEFINED
call DrawDebugScr ;Refresh any lines containing
;this breakpoint
ClrNoBp:
cEnd
;**************************************************************************
; DebugError()
; Purpose:
; Setup to report a runtime error.
;
; Exit:
; uierr and txtErr structure are setup so error will be reported in GetCmd.
; Returns mask which tells UserInterface to stop for commands.
;
;**************************************************************************
PUBLIC DebugError
DebugError PROC NEAR
mov ax,[b$ErrNum]
cmp ax,MSG_GoDirect
je DeExit ;Ignore MSG_GoDirect - it is used
; when user presses CANCEL button
; in some dialog. Easy way to
; back all the way out of the dialog.
or HelpFlags,HLP_RTERR ; this error came from execution
;Setup so GetCmd() will call ReportError()
mov dx,ER_UE ;dx = max standard runtimer error code
cmp ax,dx ;see if error was generated by user
; via ERROR(x) statement
jbe StdRtErr ;brif std runtime error code
xchg ax,dx ;ax = "Unprintable error"
StdRtErr:
mov [uierr],ax ;error will be reported by GetCmd
; calling ReportError()
mov al,[grs.GRS_fDirect]
mov [txtErr.TXER_fDirect],al
mov ax,[grs.GRS_oRsCur]
mov [txtErr.TXER_oRs],ax
mov ax,[grs.GRS_otxCur]
mov [txtErr.TXER_otx],ax
mov [txtErr.TXER_oSrc],0
DeExit:
mov ax,FDM_GetCmd
jmp SHORT TrOffExit
DebugError ENDP
;**************************************************************************
; DebugStop()
; Purpose:
; Setup to report stop statement.
;
; Exit:
; returns mask which tells UserInterface to show the current statement
; and stop for commands.
;
;**************************************************************************
PUBLIC DebugStop
DebugStop PROC NEAR
mov ax,FDM_GetCmd OR FDM_ShowStmt
jmp SHORT TrOffExit
DebugStop ENDP
;**************************************************************************
; DebugEnd()
; Purpose:
; Called when the program reaches end-of-pcode or END statement
;
; Exit:
; returns mask which tells UserInterface to stop for commands.
;
;**************************************************************************
PUBLIC DebugEnd
DebugEnd PROC NEAR
cmp [fDebugScr],FALSE
jne ShowDeb ;brif debug screen is visible
cmp [fRecord],FALSE
jne ShowDeb ;brif recording a playback file
; brif not reading a playback file. Since RUNTIME consumes the
; keystroke in B$Pause, this would hang the playback file up.
cmp [fPlayBack],FALSE
jne ShowDeb
; The user has just finished running a program up to an END stmt.
; The output screen is still visible. Display the prompt:
; 'Press any key to return to editor'
; on the bottom line of the output window and wait for the
; user to press a key.
call B$Pause
ShowDeb:
cmp [grs.GRS_fDirect],FALSE
jne DeDirMode ;brif end-of-direct mode execution
call EnsShowDebugScr ;init debug screen, make it visible
call DrawDebugScr ;turn off old current stmt highlight
DeDirMode:
mov ax,FDM_GetCmd
TrOffExit:
mov [traceMode],TRACE_OFF
ret
DebugEnd ENDP
;**************************************************************************
; DebugTrace()
; Purpose:
; This is invoked when we enter UserInterface with DEBUG_TRACE set in
; debugFlags.
; Setup to show current statement and depending on the trace mode stop
; for commands.
;
; Entry:
; traceMode = TRACE_HISTORY if we are to do nothing more than record
; the pcode address of the instruction for History Playback
; TRACE_ANIMATE if we are to show stmt and exit direct mode,
; TRACE_STEP if we are stopping for each statement (F8),
; TRACE_PSTEP if we are stepping around procedure calls (F10).
;
; Exit:
; The current statement's location is recorded in the history buffer.
; Returns mask to tell UserInterface to show the current statement
; and/or tell it to stop and interact with the user.
;
;**************************************************************************
cProc DebugTrace,<PUBLIC,NEAR>,<di>
cBegin
call FExecutable ;see if next stmt to be executed
; contains any executable code
jne ItsExecutable ;brif stmt is executable
sub di,di ;tell UserInterface to take no action
J1_TrSetTraceFlag:
jmp SHORT TrSetTraceFlag
ItsExecutable:
;set debugFlags, traceMode, fGotCmd, and al (return value) as follows:
;switch (traceMode)
; case TRACE_OFF:
; fGotCmd remains 0
; return al = 0
; case TRACE_HISTORY:
; fGotCmd remains 0
; return al = 0
; case TRACE_ANIMATE:
; if alternateListWindow is showing new oRs, activate it
; if fCantCont, directModeCmd = RUN
; fGotCmd = TRUE
; return al = FDM_ShowStmt
; case TRACE_PSTEP:
; if ([pGosubLast] != 0 && ([pGosubLast] < [pStepFrame])) ||
; ([pGosubLast] == 0 && ([b$CurFrame] < [pStepFrame]))
; fGotCmd = TRUE
; return al = 0
; else
; fall into case TRACE_STEP
; case TRACE_WATCHSTEP:
; case TRACE_STEP:
; fGotCmd remains 0
; traceMode = TRACE_OFF
; return al = FDM_GetCmd OR (case WATCHSTEP ? 0 :FDM_ShowStmt)
;end switch
;if traceMode != TRACE_OFF
; debugFlags != DEBUG_TRACE
;
sub di,di ;tell UserInterface to take no action
sub cx,cx
mov cl,[traceMode] ;cx = traceMode
dec cx
.errnz TRACE_OFF
js SHORT TrSetTraceFlag ;brif traceMode == TRACE_OFF
.errnz TRACE_HISTORY - 1
je TrSetTraceFlag ;brif traceMode == TRACE_HISTORY
loop TrNotAnim ;brif traceMode != TRACE_ANIMATE
.errnz TRACE_ANIMATE - 2
sub ax,ax
push ax
call CmdGo
TrShow:
or di,FDM_ShowStmt
jmp SHORT TrSetTraceFlag
TrNotAnim:
loop TrNotStep ;brif traceMode != TRACE_STEP
.errnz TRACE_STEP - 3
.errnz TRACE_WATCHSTEP - 5
TrStep:
mov di,FDM_ShowStmt
TrWatchStep:
or di,FDM_GetCmd
mov [traceMode],TRACE_OFF
jmp SHORT TrSetTraceFlag
.errnz TRACE_PSTEP - 4
;traceMode == TRACE_PSTEP
TrNotStep:
loop TrWatchStep
mov ax,[b$CurFrame] ;get current frame
mov cx,[pGosubLast] ;get gosub stack value
jcxz TrUseBp ;zero, use current frame as frame
cmp cx,ax
ja TrUseBp ; brif no gosubs for this frame
xchg ax,cx ;else use top of stack
TrUseBp:
cmp [pStepFrame],ax ;compare, and if pstepframe
jbe TrStep ;watermark is below or equal, step
TrSkip:
call DoCont ;continue program execution
;di = FDM_xxx actionMask return value
TrSetTraceFlag:
cmp [traceMode],TRACE_OFF
je TrExit ;leave trace flag 0 if not tracing
or [debugFlags],DEBUG_TRACE
TrExit:
xchg ax,di ;ax = return value
cEnd ;DebugTrace
;**************************************************************************
; HistReset()
; Purpose:
; This is called when we Scan/Descan a program to flush the history
; buffer.
;
;**************************************************************************
cProc HistReset,<PUBLIC,FAR>
cBegin
cEnd
;**************************************************************************
; CmdWatchDelAll()
; Purpose:
; Called when 'View/Watch Delete' menu is selected.
; Delete all active WATCH expressions
;
;**************************************************************************
cProc CmdWatchDelAll,<PUBLIC,FAR>
cBegin
WDelLoop:
call WatchInfoUI ;make sure cWatch is up-to-date
mov bx,[cWatch]
dec bx
js WDelExit ;brif no watch expressions left
cCall WatchDel,<bx> ;delete watch expression [bx]
jmp SHORT WDelLoop
WDelExit:
cEnd
;**************************************************************************
; WatchDeleted
; Purpose:
; Called by Text Mgr whenever a Watch expression is deleted.
; It releases 1 line from the Watch Window in the Debug Screen
; and remembers to redraw the debug screen.
;
;**************************************************************************
cProc WatchDeleted,<PUBLIC,FAR>
cBegin
call WatchRelease ;release any existing WATCH values
call DrawDebugScr ; remember to redraw screen
cEnd
;**************************************************************************
; WatchInfoUI
; Purpose:
; Given an index for a watch expression, load registers with info
; about that watch expression.
; Entry:
; iWatch = watch index (0 to n)
; Exit:
; ax = oRs for text table containing expression
; bx = pointer to 1 byte valTyp, 8 byte value structure
; cx = otx to start of expression
; [cWatch] = number of watch expressions in all loaded modules
; grs.fDirect is set to FALSE
;
;**************************************************************************
PUBLIC WatchInfoUI
WatchInfoUI PROC NEAR
mov bx,[iWatch]
WatchInfoUI ENDP
WatchInfoBx PROC NEAR
call WatchInfo
ret
WatchInfoBx ENDP
;**************************************************************************
; WatchName
; Purpose:
; Fill bufStdMsg with the title of a watch expression.
; The text table containing the watch expression is also activated.
; Entry:
; ax = oRs for watch pcode
; cx = otx for watch pcode
; Exit:
; entry's register set is activated
; bufStdMsg = '<context> <expression>: '
; bx = &bufStdMsg, ax = #bytes in message
;
;**************************************************************************
cProc WatchName,<PUBLIC,NEAR>,<si>
localV bdBuf,<size BD>
cBegin
dec cx
dec cx ;back up to opEndProg or prev opWatch
; ListLine treats these like opBol
mov si,cx ;si = otx for expression
push ax ;preserve ax
push ax ;pass oRs to UiRsActivate
call UiRsActivate
pop ax ;ax = oRs
push ax ;pass oRs to GetRsName
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -