⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 txtdeb.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	txtdeb.asm - Text Mgr's Debugger support

;==========================================================================
;
;	Module:  txtdeb.asm - Text Mgr's Debugger support
;	System:  Quick BASIC Interpreter
;
;=========================================================================*/

	.xlist
	include		version.inc
	TXTDEB_ASM = ON
	includeOnce	architec
	includeOnce	context
	includeOnce	heap
	includeOnce	lister
	includeOnce	opcontrl
	includeOnce	opid
	includeOnce	opmin
	includeOnce	opstmt
	includeOnce	opintrsc
	IncludeOnce	opaftqb4
	includeOnce	parser
	includeOnce	pcode
	includeOnce	qbimsgs
	includeOnce	scanner
	includeOnce	txtint
	includeOnce	txtmgr
	includeOnce	ui
	.list

	EXTRN	B$SASS:FAR

	assumes	DS,DATA
	assumes	SS,DATA
	assumes	ES,NOTHING

sBegin	DATA
PUBLIC		cWatch
cWatch		DW	0	;number of Watch expressions in system
pWatch		DW	0	;used during WatchInfo
fWatchBuild	DB	0	;non-zero if tWatch contains out-of-date info

;Watch table contains 1 entry for every watch expression/watchpoint
WT_ST		STRUC
WT_oRs		DW	0	;identifies text table with watch expression
WT_otxStart	DW	0	;text offset to start of watch expression
WT_otxEnd	DW	0	;text offset to end of watch expression
WT_filler	DB	0	;WT_value needs to be even byte aligned
WT_valTyp	DB	0	;type of value
WT_value	DB 8 DUP(?)	;holds R8,R4,I4,I2, or SD
WT_ST		ENDS

		EVEN
;runtime needs string descriptors on even byte boundaries.
tWatch		DB (WATCH_MAX+1) * SIZE WT_ST DUP(0) ; "+1" is for instant watch
tWatchEnd	LABEL WORD

sEnd	DATA

sBegin	CODE
;These opcodes mark the start and end of WATCH expressions
;
PUBLIC	tOpWatch
tOpWatch LABEL WORD
	opTabStart	W
	opTabEntry	W,opEndProg
	opTabEntry	W,opWatchExp
	opTabEntry	W,opWatchStop
	opTabEntry	W,opEot

;Table of all the opcodes (1) that are opBreakPoint
;
tOpBp	LABEL WORD
	opTabStart	BP
	opTabEntry	BP,opBreakPoint
	opTabEntry	BP,opEot

;These opcodes can cause screen I/O
; opcodes opPrintSpc opPrintTab opPrintComma opPrintSemi opPrintEos
; opPrintItemComma opPrintItemSemi and opPrintItemEos are all caught
; by executors, so we don't cause screen flicker on File I/O.
;
; END/EXIT FUNCTION/DEF can cause I/O if their caller included
; the function invocation within any I/O stmt, i.e.
;    PAINT (x,y),FNx
; This causes screen flicker for every END/EXIT DEF/FUNCTION/SUB but
; fNextStmtDoesIO() would have to add a lot of slow special-case code
; to catch the cases where the function was not within an I/O stmt.
;
;Certain control structure opcodes must also be included in the
;list since they branch past the bol/bos of other statements
;which may contain I/O opcodes.


tOpIO	LABEL WORD
	opTabStartAll	IO
	opTabEntry	IO,opStElseLabDirect
	;The reason EndDef, EndProc, ExitProc are listed here is
	;for the case when the user does something like:
	; PAINT (x,y),FNx(z)
	
	opTabEntry	IO,opStEndDef
	opTabEntry	IO,opEndSingleDef
	opTabEntry	IO,opStEndProc
	opTabEntry	IO,opStExitProc
	opTabEntry	IO,opStGotoDirect
	opTabEntry	IO,opStGosubDirect
	opTabEntry	IO,opStRunMain
	opTabEntry	IO,opStRunLabel
	opTabEntry	IO,opStBload1
	opTabEntry	IO,opStBload2
	opTabEntry	IO,opStCircle
	opTabEntry	IO,opStCircleColor
	opTabEntry	IO,opStCls
	opTabEntry	IO,opStColor
	opTabEntry	IO,opStDraw
	opTabEntry	IO,opStFiles0
	opTabEntry	IO,opStFiles1
	opTabEntry	IO,opStGraphicsGet
	opTabEntry	IO,opStGraphicsPut
	opTabEntry	IO,opStInput
	opTabEntry	IO,opStKey
	opTabEntry	IO,opStKeyMap
	opTabEntry	IO,opStLine
	opTabEntry	IO,opStLineColor
	opTabEntry	IO,opStLineStyle
	opTabEntry	IO,opStLineStyleColor
	opTabEntry	IO,opStLineInput
	opTabEntry	IO,opStLocate
	opTabEntry	IO,opStPaint2
	opTabEntry	IO,opStPaint3
	opTabEntry	IO,opStPalette0
	opTabEntry	IO,opStPalette2
	opTabEntry	IO,opStPaletteUsing
	opTabEntry	IO,opStPoke
	opTabEntry	IO,opStPreset
	opTabEntry	IO,opStPresetColor
	opTabEntry	IO,opStPset
	opTabEntry	IO,opStPsetColor
	opTabEntry	IO,opStRandomize1
	opTabEntry	IO,opStScreen
	opTabEntry	IO,opStShell0
	opTabEntry	IO,opStShell1
	opTabEntry	IO,opStSystem
	opTabEntry	IO,opStView
	opTabEntry	IO,opStView0
	opTabEntry	IO,opStViewPrint0
	opTabEntry	IO,opStViewPrint2
	opTabEntry	IO,opStViewScreen
	opTabEntry	IO,opStWidth2
	opTabEntry	IO,opStWindow
	opTabEntry	IO,opStWindow0
	opTabEntry	IO,opStWindowScreen
	opTabEntry	IO,opFnInkey_
	opTabEntry	IO,opFnInput_1
	opTabEntry	IO,opFnInput_2
	opTabEntry	IO,opFnPeek
	opTabEntry	IO,opFnPoint2
	opTabEntry	IO,opFnScreen2
	opTabEntry	IO,opFnScreen3
	opTabEntry	IO,opFnShell
	opTabEntry	IO,opStLoop		
	opTabEntry	IO,opStWend		
	opTabEntry	IO,opStNext		
	opTabEntry	IO,opStNextId		
	opTabEntry	IO,opStSelectCase	
	opTabEntry	IO,opStRandomize0	
	opTabEntry	IO,opBol
		IO_bosMin EQU IO_opBol
	opTabEntry	IO,opBolSp
	opTabEntry	IO,opBolInclude
	opTabEntry	IO,opBolIncludeSp
	opTabEntry	IO,opBolLab
	opTabEntry	IO,opBolLabSp
	opTabEntry	IO,opBos
	opTabEntry	IO,opBosSp
	opTabEntry	IO,opEot


;Table of opcodes used by ToggleBp to ensure that BP line is not a 
;CASE, CASE ELSE, or END CASE statement.

tOpCaseStmt LABEL WORD
	opTabStart	CASESTMT
	opTabEntry	CASESTMT,opStCase
	opTabEntry	CASESTMT,opStCaseTo
	opTabEntry	CASESTMT,opStCaseElse
	opTabEntry	CASESTMT,opStEndSelect
		CASESTMT_CASEMAX = CASESTMT_opStEndSelect
	opTabEntry	CASESTMT,opBol
	opTabEntry	CASESTMT,opBolLab
	opTabEntry	CASESTMT,opBolSp
	opTabEntry	CASESTMT,opBolLabSp
	opTabEntry	CASESTMT,opBolInclude
	opTabEntry	CASESTMT,opBolIncludeSp
	opTabEntry	CASESTMT,opEot

sEnd	CODE

sBegin	CP
assumes	cs,CP

;--------------------------------------------------------------
;		BASIC Debugging support functions
;--------------------------------------------------------------

;**************************************************************
; boolean fBpSet(otxBol)
; Purpose:
;	Return TRUE if indicated line has a breakpoint set.
; Entry:
;	otxBol = text offset to beginning of line opcode for line
;	grs.fDirect must be FALSE
; Exit:
;	al = ax = non-zero if breakpoint was set
;	dx = text offset to opBreakPoint, or where opBreakPoint
;	     could be inserted
;
;**************************************************************
cProc	fBpSet,<PUBLIC,FAR>
	parmW	otxBol
cBegin
	DbAssertRelB [grs.GRS_fDirect],e,FALSE,CP,<fBpSet: fDirect TRUE>
	mov	dx,[otxBol]		
	DbChk	Otx,dx			;error if bx > txdCur.bdlText.cbLogical

;bx = otx to opcode to skip
FbSkipLoop:
	xchg	ax,dx			;pass otx to TxtSkipOp in ax
	call	TxtSkipOp		;skip opBol[Lab][Sp] (or opStSub) opcode
	push	ax			;save ax = otx to potential opBreakPoint
	call	GetDescannedOpcode	;ax = opcode at text offset ax
	pop	dx			;dx = otx to potential opBreakPoint
	cmp	ax,opNoList1
	je	FbSkipLoop		;brif got an opNoList1
	cmp	ax,opStSub
	je	FbSkipLoop		;brif we want to skip a SUB opcode
	cmp	ax,opStFunction
	je	FbSkipLoop		;brif we want to skip a FUNCTION opcode
	cmp	ax,opStDefFn
	je	FbSkipLoop		;brif we want to skip a DEF FN opcode
	sub	cx,cx			;prepare to return FALSE
	cmp	ax,opBreakPoint
	jne	FbExit			;brif breakpoint is not set
	dec	cx			;return TRUE
FbExit:
	xchg	ax,cx			;return boolean in ax
cEnd

;**************************************************************
; GetDescannedOpcode
; Entry:
;	ax = text offset into current text table
; Exit:
;	ax = opcode
;
;**************************************************************
GetDescannedOpcode PROC NEAR
	call	GetWOtx			;ax = opcode at text offset ax
	cmp	[txdCur.TXD_scanState],SS_EXECUTE
	jne	GdNotExec		;brif not scanned to SS_EXECUTE
	push	ax
	call	DescanOpcode		;ax = descanned opcode
GdNotExec:
	and	ah,HIGH OPCODE_MASK
	ret
GetDescannedOpcode ENDP

;**************************************************************
; ToggleBp(ln)
; Purpose:
;	Sets or Reset a breakpoint at the indicated line.
;	For most lines, the opBreakPoint is inserted immediately
;	after the opBolXXX.  For SUB, FUNCTION, and DEF FNs,
;	the opBreakPoint is inserted immediately after the
;	opStSub/Function/DefFn opcode so when the procedure is
;	invoked, the breakpoint will be executed.
; Exit:
;	[17]if no error occurs then ax = 0 otherwise
;	[17] ax = txtErr.errcode = error code
;	cBreakpoints - Incremented or decremented.
;
;**************************************************************
cProc	ToggleBp,<PUBLIC,FAR>,<si>
	parmW	ln
cBegin
	call	TxtDescanCP
	push	[ln]
	call	OtxOfLn			;ax = text offset to start of line
	cCall	fBpSet,<ax>		;ax = 0 if line has no breakpoint
	mov	si,dx			;si = dx = otx to opBreakPoint
	or	ax,ax			
	jne	TglBpSet		;brif breakpoint is set

;if target statement of break point is CASE, CASE ELSE, or END SELECT
;then report an error
	push	si			
	PUSHI	ax,<CODEOFFSET tOpCaseStmt> 
	call	TxtFindOp		;dl = txtFindIndex
	cmp	dl,CASESTMT_CASEMAX	
	ja	SetBp			;brif hit end of line before case
	mov	[txtErr.TXER_fDirect],0	;error not in direct mode
	mov	[txtErr.TXER_oRs],UNDEFINED ;don't try to position cursor
	mov	ax,MSG_NoBpCase		;"no bp on case clause or end select"
	mov	[txtErr.TXER_errCode],ax 
	jmp	SHORT TgbErrExit	
SetBp:

;si = text offset to where BreakPoint is to be inserted
;make room for new breakpoint opcode by copying old text up in memory
;
	push	si
	PUSHI	ax,2
	call	TxtMoveUp
	je	TgbExit			;return FALSE if no memory

	push	si
	PUSHI	ax,opBreakPoint
	call	PutWOtx			;insert breakpoint pcode in text table

	;Update program counter, prs.otxDef fields for affected PRSs,
	; and linked lists through this text table's pcode
	
	mov	bx,si			;bx = updated otxInsert
	inc	bx
	inc	bx			;bx = offset beyond inserted pcode
	call	TxtInsUpdate
	jmp	SHORT TgbExit

;si = text offset to breakpoint to be deleted
TglBpSet:
	push	si
	inc	si
	inc	si
	push	si
	call	TxtDelete
TgbExit:
	xor	ax,ax			;return ax = 0 for no error
TgbErrExit:				
cEnd

;**************************************************************
; ClrBpAll()
; Purpose:
;	Reset all breakpoints in the loaded program.
;
; Input:
;	fCountBp - If fCountBp is TRUE then the breakpoints are only counted.
;
;**************************************************************
PUBLIC	ClrBpTxt
ClrBpTxt PROC NEAR
	push	si			;save caller's si
	call	TxtDescanCP
	sub	si,si			;start at beginning of text table
CbLoop:
	push	si
	PUSHI	ax,<CODEOFFSET tOpBp>
	call	TxtFindOp		;ax = offset to next opBreakPoint
					;dl = [txtFindIndex]
	cmp	dl,BP_opEot
	je	CbDone			;brif done with loop
	xchg	si,ax			;si = otxNext
	push	si
	lea	ax,[si+2]		;ax = offset beyond opBreakPoint
	push	ax
	call	TxtDelete		;delete the break point
	jmp	SHORT CbLoop

CbDone:
	mov	ax,sp			;return TRUE (non-zero)
	pop	si			;restore caller's si
	ret	
ClrBpTxt ENDP

PUBLIC	ClrBpAll
cProc	ClrBpAll,<FAR,PUBLIC>		
cBegin	ClrBpAll			
	mov	bx,CPOFFSET ClrBpTxt
	call	ForEachTxtTbl


cEnd	ClrBpAll			



;**************************************************************
; SkipStop
; Purpose:
;	If the next opcode to be executed is an opStStop
;	or opBreakPoint, skip it.  This is called by the
;	user interface for SingleStep and GoTillCursor
;	so the user doesn't have to step twice for a stmt
;	that has a STOP or BREAK-POINT.
; Entry:
;	grs.oRsCur, grs.otxCONT and grs.fDirect identify 
;	next opcode to be executed
; Exit:
;	grs.otxCONT is bumped by 2 if it was opStStop or opBreakPoint
;
;**************************************************************
cProc	SkipStop,<PUBLIC,FAR>
cBegin
	mov	ax,[grs.GRS_otxCONT]
	inc	ax
	je	DontSkipIt		;brif can't CONT
	dec	ax
	call	GetDescannedOpcode	;ax = opcode at text offset ax
	cmp	ax,opBreakPoint
	je	SkipIt
	cmp	ax,opStStop
	jne	DontSkipIt
SkipIt:
	add	[grs.GRS_otxCONT],2
DontSkipIt:
cEnd


;Table of opcodes skipped over while tracing
tNops	LABEL WORD
	DW opLabSp			; Moved these 2 to start of table
	DW opLab			; to make special case easier.
	DW opStConst
	DW opStData
	DW opStDeclare
	DW opStDefType
	DW opStRem 
	DW opQuoteRem
	DW opStShared
	DW opStStatic
	DW opStType
	DW opStEndType
	DW op_Static
	DW op_Dynamic
	DW op_Include
	DW opBol
	DW opBolSp
	DW opBolInclude
	DW opBolIncludeSp
	DW opBolLab
	DW opBolLabSp
	DW opBos
	DW opBosSp
	DW opEndProg
CW_TNOPS EQU ($-tNops) SHR 1

;**************************************************************
; boolean FAR FExecutable()
; Purpose:
;	Called by User Interface code to determine if we need to
;	show the tracing of the next statement.
;
;	WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING
;
;	Slime.	This routine is currently only called from
;	DebugTrace to determine whether or not we should stop
;	on the current line.  For this case we need to skip past
;	opLab[Sp] so we recognize that we need to break on lines
;	like "10 foo: print" or on included lines with line #'s
;	(which get opBolInclude + opLab).  If this routine is

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -