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

📄 lsmain.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;   in the buffer, which is large enough for all the nodes that could
;   be emitted by a single dispatch.  Any dispatches that could require
;   more than this call GrowBdNodes themselves.
;   The outer loop is the only place during Stage1 which
;   grows bdNodes, which is the only time heap movement can
;   occur.  When it does this, it fixes up ES and DI.
;
PUBLIC	Stg1Loop
Stg1Loop:
	DbAssertRel [oNodeTemp],e,0,LIST,<node found on temp stack at Stg1Loop>

	;make sure bdNodes > CB_NODES_MIN bytes, updating ES for movement
	
	mov	ax,CB_NODES_MIN 	;ax = min free we need
	add	ax,di			;ax = size we need buffer to be
	sub	ax,[bdNodes.BD_cbLogical] ;ax = free space
	jnc	GetRoom 		;brif not enough free bytes exist
GotRoom:

	cmp	si,[otxLsCursorTmp]
	jae	SetNdLsCursor		;brif caller wants to know column
					; of token for the last opcode listed.
					; Control returns to SetNdRet.
SetNdRet:
	lods	WORD PTR es:[si]	;ax = opcode
	cmp	[txdCur.TXD_scanState],SS_EXECUTE
	jne	GotOpcode
	;convert to opcode since text table's scan state is SS_EXECUTE
	xchg	bx,ax			;bx = executor's adr
	GetSegAddr CODE		 	;ax = adr of CODE seg
	mov	ds,ax			;ds = adr of CODE seg
	mov	ax,[bx-2]		;ax = executor's opcode
	push	ss			
	pop	ds			;restore ds = DGROUP
GotOpcode:
	mov	[opList],ax		;save for individual list rules
	and	ah,HIGH OPCODE_MASK	;upper bits sometimes used for operands
	mov	bx,ax			;bx = opcode
	shl	bx,1			;bx = opcode * 2
	mov	[opList2],bx		;save index for individual list rules
	jmp	[mpOpLister + bx]	;dispatch to lister function
					;function will branch back to Stg1Loop
					; or Stage2

;Some serious error has occured while listing (like out-of-memory)
; return error code
;
ListErrExit:
	mov	ax,UNDEFINED		;return error result
	jmp	ListLineExit		;return ax

;!!!WARNING!!!  No heap movement can occur during Stage2, because
; we convert all bdNode offsets to pointers while reversing the direction
; of the list. 
;This is not a problem in EB since the node buffer is static.
;
; Stage2:
;   Taking the tree which was built in step1, do a post-order traversal
;   dispatching to a special function for each node type.  Each of these
;   functions appends text to the current output line.
;   global register conventions:
;
; Stage2Inc is branched to when the terminating bol is for an included
;   line.  In this case, otxListNextInc has already been set.
;   
;
PUBLIC	Stage2, Stage2Inc
Stage2:
	call	GrowBdNodes		;this test will ensure that we
					;  have not written past end of buffer
	mov	[otxListNextInc],si	;save it for caller
Stage2Inc:
	mov	[otxListNext],si	;save it for caller


	;If there was a node that contained token of interest, replace
	;the node type with LNT_CURSOR (similar to a break-point), so
	;we don't have to compare at every stage2 dispatch.
	
	mov	bx,[ndLsCursor]
	inc	bx
	je	NoNdLsCursor		;brif line doesn't contain otxLsCursor
	add	bx,[bdNodes.BD_pb]	;convert offset to ptr
	mov	al,LNT_CURSOR
	xchg	[bx+LN_type-1],al
	mov	[lnTypeFindSave],al
NoNdLsCursor:




	mov	di,[pbdDst]		;di points to destination buffer dsc
	mov	ax,[di.BD_cbLogical]	;ax = max size of buffer
	mov	di,[di.BD_pb]		;di points to destination buffer
	mov	[colLastTok],di
	mov	[colLastLine],di
	add	ax,di			;ax points beyond end of buffer
	sub	ax,42d			;42 bytes is enough for an id, reserved
					; word, number, or char[s] node
					; Spaces/String/Col nodes check
					; for themselves
	DJMP	jc ListDstFull		;brif dst doesn't even have 42 bytes
	mov	[pbDstWarning],ax
	mov	si,[oNodeRoot]		;si = offset to root node
	or	si,si
	je	Stg2Done		;brif nothing to list
	sub	ax,ax			;prev node = NULL
	push	ax			;this will stop EndOfListLoop
;si=offset to start of list of nodes, to be listed in reverse order, i.e. last
;   node in list will be listed first, start of list will be listed last.
FindEndOfList:
	sub	cx,cx			;prev node = NULL
;si = offset to current node,
;cx points to previous node (if start of list, cx = 0),
;Traverse si's list to the end, then start listing nodes in reverse order
;
EndOfListLoop:
	add	si,[bdNodes.BD_pb]	;convert offset to ptr
	xchg	cx,LN_sib[si]		;cx = offset to next node (if any)
					;swap ptr from prev->next to next->prev
					; so we can work our way back
	jcxz	ListNodeSi		;brif we're at the end-of-list
	xchg	cx,si			;cx points to prev node
					;si = offset to current node
	jmp	SHORT EndOfListLoop

;si points to last node in list, list it, then list all the nodes which
; came before it in the linked-list
;di points to destination of next ASCII byte to be listed
;
DbPub	ListNodeSi
ListNodeSi:
	cmp	di,[pbDstWarning]
DJMP	jae	ListDstFull		;brif destination buf almost full
	mov	bl,LN_type[si]		;bx = node type
DispNodeBl:
	sub	bh,bh			;bh = 0
	jmp	[mpNodeLister + bx]	;dispatch to lister function
					;function will branch back to Stg2Cont

;si still points to node which was just listed.
; now, advance to previous sibling to be listed and list it.
;
DbPub	Stg2Cont
Stg2Cont:
	mov	si,LN_sib[si]		;si points to left sibling of node
	FLoadActive
	jne	ChkLineWrap		;see if _CrLf needs to be inserted
					; for a line > 250 chars long
					; (so BASCOM can read it)
					; jumps back to either LineWrapRet
LineWrapRet:
	or	si,si			; we just listed (0 if start-of-list)
	jne	ListNodeSi		;brif not at start of list yet
EndOfList:
	pop	si			;recover node stacked by ListChildList:
	or	si,si			;test for stopper pushed just before
					; FindEndOfList:
	jne	Stg2Cont		;brif still more to list
					;else, we've reached the 0 stopper
					; pushed by ListChildList

;NOTE: This is branched to by StaticBufFull
Stg2Done:
	sub	ch,ch			;clear high byte
	mov	cl,[fGotBol]		;cl = number of leading spaces or
					;UNDEFINED.
	inc	cl			;check for UNDEFINED
	jz	NoLeadingSpc		;return 0 if no leading spaces
	dec	cl			;return number of leading spaces
NoLeadingSpc:
	;Many opcode listers leave a space at the end, in case they are
	;followed by something else.  If the last char in the line is
	;a space, and the line does not contain only white space,
	;eliminate the last space, and then 0-byte terminate the line.
	
	mov	ax,di			;ax points beyond last destination byte
	mov	bx,[pbdDst]
	sub	ax,[bx.BD_pb]		;ax = number bytes listed to buffer
	je	NoTrailSpc		;brif 0 bytes listed
	cmp	BYTE PTR -1[di],' '
	jne	NoTrailSpc		;brif last byte is not " "
	cmp	ax,cx			;is the line blank?
	je	NoTrailSpc		;brif so, preserve trailing space
	dec	di			;eliminate trailing space
	dec	ax			;decrement return value (byte count)
NoTrailSpc:
	mov	BYTE PTR [di],0 	;0-byte terminate text
ListLineExit:				;return ax
	push	cx			;save leading space count
	push	ax			;save byte count
	mov	bx,[pbdDst]		
	call	SetLsCursor		;dx = col equivalent to otxLsCursor
	pop	ax			;ax = byte count
	pop	cx			;cx = leading space count
	mov	[cLeadingSpaces],cl	;record leading space count in 
					;	static
;NOTE: we can't release space held by bdNodes, or else we risk
;causing an out-of-memory error while trying to draw the debug
;screen, which would be an infinite loop.  If necessary, we could
;reset it in ParseNewInit
;;;	mov	[bdNodes.BD_cbLogical],0 ;Reset the buffer which holds nodes

cEnd	ListLine

;******
;NOTE
; Code below this point accesses variables on ListLine's BP frame.
; Don't insert any CEND macros between here and the next CEND.
;
;******
; ListDstFull
;
;Branched to when destination buffer is almost full
;Grows destination buffer (if possible) and tries again from the start
;of ListLine.  We have to do it from the start, since no heap movement
;can occur during stage 2 (for speed of typical case).
;
;For RELEASE code in EB we just assume that when we get here it must be
;  
ListDstFullDS:				
ListDstFull:
	mov	sp,[spSave]
					; destination buffer
	mov	bx,[pbdDst]		;bx points to destination buf desc.
	mov	ax,[bx.BD_cbLogical]
	cmp	ax,80d
	jb	StaticBufFull
	add	ax,128d			;try 128 bytes more
	push	bx			;pass pbdDst to BdRealloc
	push	ax			;pass cbNew to BdRealloc
	call	TxtGrowPsSrcEmScratch	;make sure bdEmScratch and
					;ps.bdpSrc both get updated
	or	ax,ax
	jne	NotOm			;brif not out-of-memory
	jmp	ListErrExit		;return UNDEFINED
NotOm:
	jmp	ListLineRestart

StaticBufFull:

	jmp	Stg2Done		;0-terminate line and return to caller

;We're doing an ASCII Save
;see if _<space><CR><LF> needs to be emitted for a line > 250 chars long
; (so BASCOM can read it)
; si points to node for next token to list
; di = column we're about to write next token to
; [colLastTok] = column we wrote last token to (initially 0)
; [colLastLine] = column which began last physical line (initially 0)
;
DbPub ChkLineWrap
ChkLineWrap:
	.errnz	LNT_CHAR_TOK	- 0
	.errnz	LNT_STR		- 2
	.errnz	LNT_ENSTR	- 4
	.errnz	LNT_CSSTR	- 6
	.errnz  LNT_LITSTR	- 8	
	;The following node types start lexical tokens
	.errnz	LNT_ONAM	- 10
	.errnz	LNT_LIST	- 12
	.errnz	LNT_RW		- 14
	.errnz	LNT_SPACES	- 16
	.errnz	LNT_NUM 	- 18
	.errnz	LNT_COL 	- 20
	.errnz	LNT_CHAR	- 22
	.errnz	LNT_CURSOR	- 24


	or	si,si
	je	EndOfList1		;brif end of linked list of nodes
	cmp	LN_type[si],LNT_ONAM
	jb	J1_LineWrapRet		;brif this node does not necessarily
					; begin a lexical token.  For example:
					; "string" = 3 nodes: char,str,char
					; X$ = 2 nodes: oNam,char
EndOfList1:
	mov	[colLastTok],di
J1_LineWrapRet:
	jmp	LineWrapRet

;***************************************************************************
; ChkDstFull
; Purpose:
;	Make sure there's room in destination buffer for a new item.
;	If pbdDst.cbLogical < 80, buffer is static and cannot be grown,
;	just truncate listing  (used by WatchName)
; Entry:
;	di = current pointer into destination buffer
;	cx = number new bytes needed in destination buffer
;	[18]for EB ds need not point to DGROUP. If there is no room then DS 
;		is restored to DGROUP before restarting ListLine.
; Exit:
;	If there's room, this function returns, else, ListLine
;	is restarted after growing buffer.
; Preserves:
;	all registers except flags and ax
;
;***************************************************************************
assumes	DS,NOTHING			
DbPub	ChkDstFull
ChkDstFull PROC NEAR
	mov	ax,di			;ax = current dest ptr
	add	ax,cx			;ax = result dest ptr (end of string)
	jc	ListDstFullDS		;brif wrapped past FFFF 
					;		(buf too small)
	cmp	ax,[pbDstWarning]
	jae	ListDstFullDS		;brif string too big - 
					;		grow dst buffer
	ret
ChkDstFull ENDP
assumes DS,DGROUP			

;***************************************************************************
; GrowBdNodes
; Purpose:
;	Grow the temporary buffer filled by Stg1Loop if necessary.
; Entry:
;	di = current offset into bdNodes buffer
; Exit:
;	ax = zero if out-of-memory (or out of static buffer space),
;	     condition codes set accordingly
;	es = segment adr of current text table
; Preserves:	cx
;
;***************************************************************************
PUBLIC	GrowBdNodes
GrowBdNodes PROC NEAR
	mov	ax,CB_NODES_MIN 	;ax = min free we need
	add	ax,di			;ax = size we need buffer to be
	sub	ax,[bdNodes.BD_cbLogical] ;ax = free space
	jc	GrowExit		;brif enough free bytes exist
					;ax is nonzero, psw.ZR is FALSE
	push	cx			;save caller's cx
	PUSHI	ax,<dataOFFSET bdNodes>
	PUSHI	ax,CB_NODES_GROW
	call	BdGrow
	GETSEG	es,[txdCur.TXD_bdlText_seg],,<SIZE,LOAD> ;[4]
					;es = segment for current text tbl
	pop	cx			;restore caller's cx
	or	ax,ax			;test BdGrow's return value
GrowExit:
	ret
GrowBdNodes ENDP

sEnd	LIST
sBegin	DATA

mpNodeLister LABEL WORD
	DW	LISTOFFSET ListCharsNode
	DW	LISTOFFSET ListStrNode
	DW	LISTOFFSET ListEnStrNode
	DW	LISTOFFSET ListCsStrNode
	DW	LISTOFFSET ListLitStrNode 
	DW	LISTOFFSET ListONamNode
	DW	LISTOFFSET ListChildList
	DW	LISTOFFSET ListRwNode
	DW	LISTOFFSET ListSpacesNode
	DW	LISTOFFSET ListNumNode
	DW	LISTOFFSET ListColNode
	DW	LISTOFFSET ListCharsNode
	DW	LISTOFFSET ListCursorNode
.errnz	LNT_CHAR_TOK	- 0
.errnz	LNT_STR		- 2
.errnz	LNT_ENSTR	- 4
.errnz	LNT_CSSTR	- 6
.errnz	LNT_LITSTR	- 8
.errnz	LNT_ONAM	- 10
.errnz	LNT_LIST	- 12
.errnz	LNT_RW		- 14
.errnz	LNT_SPACES	- 16
.errnz	LNT_NUM 	- 18
.errnz	LNT_COL 	- 20
.errnz	LNT_CHAR	- 22
.errnz	LNT_CURSOR	- 24

sEnd	DATA
sBegin	LIST
assumes CS,LIST

⌨️ 快捷键说明

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