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

📄 txtthr.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	txtthr.asm - Text Table Linked List Maintenance Functions

;==========================================================================
;
;Module:  txtthr.asm - Text Table Linked List Maintenance Functions
;System:  Quick BASIC Interpreter
;
;=========================================================================*/

	include		version.inc
	TXTTHR_ASM = ON
	IncludeOnce	architec
	IncludeOnce	context
	IncludeOnce	opcodes
	IncludeOnce	opaftqb4
	IncludeOnce	qbimsgs
	includeOnce	txtint
	includeOnce	txtmgr
	includeOnce	types
	includeOnce	variable

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

sBegin	CODE

;These opcodes are of special interest whenever they are inserted:
;
PUBLIC	tOpUpdl
tOpUpdl	LABEL WORD
	opTabStart	UPDL
	opTabEntry	UPDL,opLab
	opTabEntry	UPDL,opLabSp
	opTabEntry	UPDL,opBolLab
	opTabEntry	UPDL,opBolLabSp
		UPDL_labMax EQU UPDL_opBolLabSp
	; Put in opBol to keep terminate most searches in update links
	; before encountering opEot.  This significantly speeds up generic
	; edits which don't have any threads past the point of the edit.
	opTabEntry	UPDL,opBol
		UPDL_SkipMax EQU UPDL_opBol
	opTabEntry	UPDL,opReParse
	opTabEntry	UPDL,opStDefType
	opTabEntry	UPDL,opStType
	opTabEntry	UPDL,opStEndType
	opTabEntry	UPDL,opStDefFn
	opTabEntry	UPDL,opStEndDef
	opTabEntry	UPDL,opEndSingleDef
	opTabEntry	UPDL,opEot

;Opcodes which are valid within TYPE/END TYPE blocks
;
tOpTypes LABEL WORD
	opTabStart	TYPES
	opTabEntry	TYPES,opElemRef
	opTabEntry	TYPES,opAsType
	opTabEntry	TYPES,opAsTypeExp
	opTabEntry	TYPES,opAsTypeFixed	
	opTabEntry	TYPES,opStEndType
		TYPES_DispatchMax EQU TYPES_opStEndType
	; the following opcodes are allowed but no processing is required
	; by ScanBlock
	opTabEntry	TYPES,opBol
	opTabEntry	TYPES,opBos
	opTabEntry	TYPES,opBolSp
	opTabEntry	TYPES,opBolInclude
	opTabEntry	TYPES,opBolIncludeSp
	opTabEntry	TYPES,opStRem
	opTabEntry	TYPES,opQuoteRem
	opTabEntry	TYPES,op_Static
	opTabEntry	TYPES,op_Dynamic
	opTabEntry	TYPES,op_Include
	opTabEntry	TYPES,opEot

sEnd	CODE

sBegin	CP
assumes	cs,CP

;Threaded pcode descriptor
THR_DSC STRUC
THR_otxPrev	DW 0	;points to previous thread
THR_fInDS	DW 0	;non-zero if THR_otxPrev is a DS offset
THR_DSC ENDS

;*************************************************************************
; TxtDeThread(ax:pHead, di:otxDelFirst, cx:cbDel)
;
; Purpose:
;	Called when a block of text is deleted.
;	Traverse a linked list through the current text table,
;	removing any nodes which are being deleted, and updating
;	next-node-offsets for those nodes beyond the deleted range.
;	This function is called BEFORE the text has been deleted.
;
; Entry:
;	ax =  pointer to ushort which heads linked list
;	       for example, &txdCur.otxLabLink
;	di =  text offset to 1st byte being deleted
;	cx =  number of bytes being deleted
;
; Preserves:
;	cx (callers depend on this)
;
;*************************************************************************
cProc	TxtDeThread,<PUBLIC,NEAR>,<si>
	localW	segTxtTab		;text table's segment
cBegin
	xchg	si,ax			;si points to head of list
	DbChk	TxdCur			;perform sanity check on txdCur
	GetSegTxtTblCur			;es = seg adr of cur txt tbl
					;preserves cx
	mov	[segTxtTab],es		;save text table's segment
	mov	dx,ds			;dx -> prev link node's segment (DGROUP)
	mov	bx,[si] 		;bx -> 1st node in linked list (in ES)
	mov	ax,di
	add	ax,cx			;ax -> last byte deleted
	DbChk	Otx,ax
DeThrLoop:
	cmp	bx,UNDEFINED
	je	DeThrExit		;branch if done with linked list
	DbChk	Otx,bx
	cmp	bx,di
	jb	DeThrUnaffected 	;brif node is unaffected by delete
					; (i.e. node < 1st byte deleted)
	cmp	bx,ax
	jb	DeThrDeleted		;brif node is in deleted range
					; (i.e. node < last byte deleted)
					;else node is beyond deleted range
	mov	es,dx			;es = segment of predecessor node
					;may be DGROUP:pHead or es:<node>
	mov	es:[si],bx		;update predecessor node
	sub	es:[si],cx
	mov	es,[segTxtTab]		;es = text table's segment
DeThrUnaffected:
	mov	si,bx			;save offset of prev node ptr in si
	mov	dx,es			;save seg of prev node ptr in dx
DeThrDeleted:
	mov	bx,es:[bx]		;bx points to next node in list
	jmp	SHORT DeThrLoop
DeThrExit:
	mov	es,dx			;es = segment of predecessor node
					;may be DGROUP:pHead or es:<node>
	mov	es:[si],bx		;update predecessor node
cEnd

;**********************************************************************
; TxtDelThread
; Purpose:
;	Called BEFORE pcode is deleted from current text table.
;	Traverses all linked lists through the text table,
;	updating the linked lists for the delete.
; Entry:
;	parm1 = offset to start of delete
;	parm2 = cbDel
;
;**********************************************************************
; TxtDeThread(&txdCur.otxLabLink, otxDelFirst, cbDel)
; TxtDeThread(&txdCur.otxReParseLink, otxDelFirst, cbDel)
; TxtDeThread(&txdCur.otxDefTypeLink, otxDelFirst, cbDel)
; TxtDeThread(&txdCur.otxTypeLink, otxDelFirst, cbDel)
;
; NOTE: TxtDeThread takes ax,cx,di as parms and preserves cx
;
cProc	TxtDelThread,<PUBLIC,NEAR>,<si,di>
	parmW	otxStart
	parmW	cbDel
cBegin
	mov	di,[otxStart]
	mov	cx,[cbDel]
	mov	si,CPOFFSET TxtDeThread	;si = adr of function to call
	mov	ax,dataOFFSET txdCur.TXD_otxTypeLink
	call	si			;fixup otxTypeLink list
	mov	ax,dataOFFSET txdCur.TXD_otxDefTypeLink
	call	si			;fixup otxDefTypeLink list
	mov	ax,dataOFFSET txdCur.TXD_otxReParseLink
	call	si			;fixup otxReParseLink list
	mov	ax,dataOFFSET txdCur.TXD_otxLabLink
	call	si			;fixup otxLabLink list

	test	[txdCur.TXD_flags],FTX_mrs
	je	DelNotMod		;brif not module text table

	; The linked list of opcodes headed by mrsCur.MRS_data_otxFirst
	; only needs to be maintained while in SS_EXECUTE state, so
	; we don't need to fix it up here
	
	mov	ax,dataOFFSET mrsCur.MRS_otxDefFnLink
	call	si	
DelNotMod:
cEnd

;*************************************************************************
; TxtInsThread(pHead, pThrDsc, otxInsFirst, cbIns)
;
; Purpose:
;	Called when a block of text is inserted.  Traverse a linked
;	list through the current text table, updating next-node-offsets
;	for those nodes beyond the inserted range.
;	This function is called AFTER the text has been inserted.
;
; Entry:
;	parm1: pointer to ushort which heads linked list
;	       for example, &txdCur.otxLabLink
;	parm2: pointer to thread descriptor which on exit contains fields:
;	       THR_otxPrev: offset to head or node which precedes the node
;			being inserted in the list
;	       THR_fInDS:   non-zero if THR_otxPrev is an offset into DS
;			zero if THR_otxPrev is an offset into text table
;	parm3: text offset to 1st byte inserted
;	parm4: number of bytes being deleted
;
; Exit:
;	*pThrDsc is updated so it refers to the last link which
;	precedes otxInsFirst.
;
;*************************************************************************
cProc	TxtInsThread,<PUBLIC,NEAR>,<si,di>
	parmW	pHead
	parmW	pThrDsc
	parmW	otxInsFirst
	parmW	cbIns
cBegin
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	si,[pHead]		;si -> head of linked list (in DGROUP)
	mov	di,[pThrDsc]
	mov	[di.THR_otxPrev],si	;default THR_otxPrev to head of list
	mov	[di.THR_fInDS],1 	;set flag indicating THR_otxPrev is
					; offset in DS
	GetSegTxtTblCur			;es = seg adr of cur txt tbl
	mov	ax,es			;ax = seg adr of cur txt tbl
					;NOTE: ax=es for remainder of function
	mov	dx,ds			;dx -> prev link node's segment (DGROUP)
	mov	bx,[si] 		;bx -> 1st node in linked list (in ES)
	mov	cx,[cbIns]		;cx = #bytes inserted
InsThrLoop:
	cmp	bx,[otxInsFirst]	;compare with adr of 1st byte inserted
	jb	InsThrUnaffected	;brif node is unaffected by insert
					; (i.e. node < 1st byte inserted)
	cmp	bx,UNDEFINED
	je	InsThrExit		;branch if done with linked list
	mov	es,dx			;es = segment of predecessor node
					;may be DGROUP:pHead or es:<node>
	add	bx,cx			;bx points to where node is after insert
	mov	es:[si],bx		;update predecessor node
	mov	es,ax			;es = text table's segment
	jmp	SHORT NextLink

InsThrUnaffected:
	mov	[di.THR_otxPrev],bx	;THR_otxPrev points to last link before
					; inserted block of text
	mov	[di.THR_fInDS],0 	;reset flag to 0, indicating THR_otxPrev
					; is relative to the text segment
NextLink:
	mov	si,bx			;save offset of prev node ptr in si
	mov	dx,es			;save seg of prev node ptr in dx
	mov	bx,es:[si]		;bx points to next node in list
	jmp	SHORT InsThrLoop

InsThrExit:
cEnd

;*************************************************************************
; TxtAddThread(pThrDsc, otxNewLink)
;
; Purpose:
;	Called AFTER a block of text has been inserted which contains
;	an opcode having an operand that should be added to a linked
;	list through the text table.  This function inserts this opcode
;	in the list.
;
; Entry:
;	parm1: pointer to thread descriptor which contains following fields:
;	       THR_otxPrev: offset to head or node which precedes the node
;			being inserted in the list
;	       THR_fInDS: non-zero if THR_otxPrev is an offset into DS
;			zero if THR_otxPrev is an offset into text table
;	parm2: pointer to new link field to add to linked list
;
;*************************************************************************
cProc	TxtAddThread,<PUBLIC,NEAR>,<si,di>
	parmW	pThrDsc
	parmW	otxNewLink
cBegin
	DbChk	TxdCur			;perform sanity check on txdCur
	GetSegTxtTblCur			;es = seg adr of cur txt tbl
	mov	ax,es			;ax = seg adr of cur txt tbl
	mov	si,[pThrDsc]		;si -> thread descriptor
	mov	bx,[si.THR_otxPrev]	;bx -> prev node / head of list
	cmp	[si.THR_fInDS],0
	je	prevInTxt		;brif bx is offset within text table
	mov	[si.THR_fInDS],0 	;reset THR_fInDS to 0
	push	ds
	pop	es			;es -> DGROUP
prevInTxt:
	mov	dx,es:[bx]		;dx -> next node
	mov	di,[otxNewLink] 	;di -> new node
	DbChk	Otx,di
	mov	es:[bx],di		;prev node -> new node
	mov	es,ax			;es -> text table
	mov	es:[di],dx		;new node -> next node
	mov	[si.THR_otxPrev],di	;save adr of new node in thread dsc
cEnd

;**************************************************************
; void NEAR UpdateLinks(otxInsStart, otxInsEnd)
; void NEAR NoWalkUpdateLinks(otxInsStart, otxInsEnd)
;
; Purpose:
;	Called after some text has been inserted into the current text table.
;	During ASCII Load, it is not called for every line, but every
;	time we switch text tables (speed optimization for LOAD).
;	For each inserted opcode which has a link-field operand, it
;	is inserted into its appropriate linked list.  The NoWalkUpdateLinks
;	entrypoint allows the binary translator to adjust links for pcode
;	growth without looking at the inserted pcode.  This is necessary as
;	the pcode is not valid until after all translation has been performed.
;
; Entry:
;	grs.oMrsCur, grs.oPrsCur have their usual meaning
;	txdCur.bdlText describes the current text table.
;	ps.bdpSrc contains source line to be inserted
;	parm1: ushort otxInsStart - text table offset to opBol
;	   opcode for 1st line inserted.
;	parm2: ushort otxInsEnd - text table offset to opBol
;	   opcode beyond last line inserted.
;	   (parm2 - parm1) should equal the number of bytes inserted.
;	   If this (parm2 - parm1), this function is effectively a nop.
;

⌨️ 快捷键说明

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