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

📄 txtmove.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;	within the current text table.  Typically used to make room
;	for text to be inserted.
;
; Entry:
;	parmW otxSrcLow: offset of source of lowest byte to be moved
;	parmW cbIns: number of bytes to make room for
;	if grs.fDirect is TRUE,
;	   grs.bdlDirect (the direct mode pcode buffer) is the buffer to
;	   be shifted, and grs.bdlDirect.cbLogical = current logical
;	   size of text table
;	else txdCur.bdlText is the buffer to be shifted and
;	   txdCur.bdlText.cbLogical = current logical size of text table
;
; Exit:
;	returns ax = zero if out-of-memory, else non-zero
;	condition codes set based on value in ax
;	if grs.fDirect is TRUE
;	   grs.bdlDirect.cbLogical is updated for the move
;	else
;	   txdCur.bdlText.cbLogical is updated for the move
;
; Example:
;   Before:
;	high memory 	
;	  txdCur.TXD_bdlText_cbLogical->+-----+
;					|  E  |
;	  otxSrcLow + cbIns------------>|  D  |
;					|  C  |
;	  otxSrcLow-------------------->|  B  |
;					|  A  |
;	low memory			+-----+
;
;   After:
;	high memory 	
;	  txdCur.TXD_bdlText_cbLogical->+-----+
;					|  E  |
;					|  D  |
;					|  C  |
;	  otxSrcLow + cbIns------------>|  B  |
;					|  -  |
;	  otxSrcLow-------------------->|  -  |
;					|  A  |
;	low memory			+-----+
;
;*************************************************************************
cProc	TxtMoveUp,<PUBLIC,NODATA,NEAR>,<si,di>
	parmW otxSrcLow
	parmW cbIns
cBegin	TxtMoveUp
	DbChk	Otx,otxSrcLow		;assert otxSrcLow is valid
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	si,[otxSrcLow]		;si = source offset
					; (is parm for TxtAdjust)
	call	TxtChkCache		;adjust/reset cached text offsets
					;reset History and Watch info too
	push	[cbIns]
	call	TxtFree			;make sure we have enough free space
	je	TxtMoveUpExit		;brif out-of-memory
	GetSegTxtCur			;es = seg adr of current txt tbl
					; (this may be direct mode buffer)
	mov	dx,[cbIns]		;dx = #bytes to insert
	mov	bx,dataOFFSET grs.GRS_bdlDirect_cbLogical
	cmp	[grs.GRS_fDirect],FALSE
	jne	Up_InDirMode		;branch if in direct mode
	mov	bx,dataOFFSET txdCur.TXD_bdlText_cbLogical
Up_InDirMode:
	mov	di,si			;di = source offset
	add	di,dx			;di = destination offset
	mov	cx,[bx]			;cx = current size of text table
	add	[bx],dx			;update cbLogical for move
	sub	cx,si			;cx = # bytes to copy
	add	di,cx			;start copying at top of block
	dec	di			; so we don't overwrite end of
	dec	di			; source before we've copied it
	add	si,cx
	dec	si
	dec	si
	shr	cx,1			;we will move words
DbAssertFlags	nc,CP,<TxtMoveUp: err1>
	push	ds			;save caller's ds
	push	es			;push seg adr of current txt tbl
	pop	ds			;set up source seg
	std				;copy moving down
	rep movsw
	cld				;always leave D flag clear by convention
	pop	ds			;restore caller's ds
	mov	ax,sp			;success result
TxtMoveUpExit:
	or	ax,ax			;set condition codes for caller
cEnd	TxtMoveUp

cProc	TxtMoveUpFar,<PUBLIC,NODATA,FAR> 
	parmW otxSrcLow 		
	parmW cbIns			
cBegin	TxtMoveUpFar			
	cCall	TxtMoveUp,<otxSrcLow, cbIns>  
cEnd	TxtMoveUpFar			

;*************************************************************************
; TxtMoveDown(otxSrcLow, otxDstLow)
;
; Purpose:
;	Move a block of text from a high address to a lower address
;	within the current text table.  Typically used to delete text.
;
; Entry:
;	parmW otxSrcLow: offset of source of lowest byte to be moved
;	parmW otxDstLow: offset of destination of lowest byte to be moved
;	if grs.fDirect is TRUE,
;	   grs.bdlDirect (the direct mode pcode buffer) is the buffer to
;	   be shifted, and grs.bdlDirect.cbLogical = current logical
;	   size of text table
;	else txdCur.bdlText is the buffer to be shifted and
;	   txdCur.bdlText.cbLogical = current logical size of text table
;
; Exit:
;	if grs.fDirect is TRUE
;	   grs.bdlDirect.cbLogical is updated for the move
;	else
;	   txdCur.bdlText.cbLogical is updated for the move
;
; Example:
;   Before:
;	high memory 	
;	  txdCur.TXD_bdlText_cbLogical->+-----+
;					|  F  |
;					|  E  |
;	  otxSrcLow-------------------->|  D  |
;					|  C  |
;	  otxDstLow-------------------->|  B  |
;					|  A  |
;	low memory			+-----+
;
;   After:
;	high memory 	
;	  txdCur.TXD_bdlText_cbLogical->+-----+
;	  otxSrcLow-------------------->|  F  |
;					|  E  |
;	  otxDstLow-------------------->|  D  |
;					|  A  |
;	low memory			+-----+
;
;*************************************************************************
cProc	TxtMoveDown,<PUBLIC,NODATA,NEAR>,<si,di>
	parmW otxSrcLow
	parmW otxDstLow
cBegin	TxtMoveDown
	DbChk	Otx,otxDstLow		
	DbChk	Otx,otxSrcLow		
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	si,[otxDstLow]		;si = destination offset
					; (is parm for TxtAdjust)
	call	TxtChkCache		;adjust/reset cached text offsets
					;reset History and Watch info too
	GetSegTxtCur			;es = seg adr of cur txt tbl
	mov	di,si			;di = destination offset
	mov	si,[otxSrcLow]		;si = source offset
	mov	dx,si			;dx = source offset
	sub	dx,di			;dx = number of bytes being deleted
	mov	bx,dataOFFSET grs.GRS_bdlDirect_cbLogical
	cmp	[grs.GRS_fDirect],FALSE
	jne	Dn_InDirMode		;branch if in direct mode
	mov	bx,dataOFFSET txdCur.TXD_bdlText_cbLogical
Dn_InDirMode:
	mov	cx,[bx]			;cx = current size of text table
	sub	[bx],dx			;update cbLogical for move
	sub	cx,si			;cx = # bytes to copy
	shr	cx,1			;move words instead of bytes
DbAssertFlags nc,CP,<TxtMoveDown: err1>
	push	ds			;save caller's ds
	push	es			;push seg adr of current text tbl
	pop	ds			;set up source seg
	rep movsw			;copy block
	pop	ds			;restore caller's ds
cEnd	TxtMoveDown

;*************************************************************************
; TxtFree
;
; Purpose:
;	Ensure that the current text table's cbPhysical exceeds its cbLogical
;	by a given value, i.e. guarentee a given amount of free space.
; Entry:
;	parm1: ushort cbFree
;	if grs.fDirect is TRUE,
;	   table grs.bdlDirect is checked
;	else
;	   table txdCur.bdlText is checked
; Exit:
;	returns ax = zero if out-of-memory, else non-zero
;	condition codes set based on value in ax
;
;*************************************************************************
cProc	TxtFree,<PUBLIC,NODATA,NEAR>
	parmW	cbFree
	localW	fDirectMode
cBegin	TxtFree
	DbChk	TxdCur			;perform sanity check on txdCur
	mov	[fDirectMode],0 	;default not directmode buffer
	mov	ax,dataOFFSET txdCur.TXD_bdlText
	cmp	[grs.GRS_fDirect],FALSE
	je	NotDirMode		;branch if not in direct mode
	mov	ax,dataOFFSET grs.GRS_bdlDirect
	mov	[fDirectMode],sp
NotDirMode:
	push	ax			;pass adr of bdl for text table
	push	cbFree
	call	BdlCheckFree		;ax = result
	or	ax,ax			;set condition codes for caller
	jne	TxtFreeExit		;brif not out of memory

; We have an out of memory error.  Determine what caused the error so
; we can give the user a better idea of how to resolve the problem.
; If the we attempted to grow the text table beyond 64k then we will
; set the variable b$errinfo to one of the following values:
;	Not changed - Was direct mode buffer, or legit out of memory.
;	OMErr_Mod   - Module level code blew past 64k.
;	OMErr_Proc  - Procedure level code blew past 64k.
;	OMErr_Inc   - Include file blew past 64k.
;	OMErr_Doc   - Document blew past 64k.

	cmp	[fDirectMode],0 	;was it the direct mode buffer?
	jne	TxtFreeOmExit		;brif so, standard OM error
	mov	ax,[txdCur.TXD_bdlText_cbLogical] ;get current size of text table
	add	ax,[cbFree]		;add requested increment
	jnc	TxtFreeOMExit		;brif request wasn't > 64K

.errnz	OMErr_Mod-OMErr_Proc-1
.errnz	OMErr_Inc-OMErr_Mod-1
.errnz	OMErr_Doc-OMErr_Inc-1
	mov	cx,OMErr_Proc		;assume we are in a SUB/FUNC
	test	[txdCur.TXD_flags],FTX_mrs ;is this a SUB/FUNC?
	je	TxtFreeOMSet		;brif so, set b$errinfo
	mov	al,[mrsCur.MRS_flags2]
	inc	cx			;assume in a MODULE
	test	al,FM2_NoPcode OR FM2_Include ;is this an Include/Document?
	je	TxtFreeOMSet		;brif not, module text table
	inc	cx			;assume an INCLUDE file
	test	al,FM2_Include		;is this an include?
	jne	TxtFreeOMSet		;brif so
	inc	cx			;must be a document
DbAssertTst al,ne,FM2_NoPcode,CP,<TxtFree: Expected a Document txt table>

TxtFreeOMSet:
	mov	[b$errinfo],cl 	;set extended OM error code

TxtFreeOMExit:
	sub	ax,ax			;set ax and condition codes for caller
TxtFreeExit:
cEnd	TxtFree

cProc	TxtFreeFar,<PUBLIC,NODATA,FAR>	
	parmW	cbFree			
cBegin	TxtFreeFar			
	cCall	TxtFree,<cbFree>	
cEnd	TxtFreeFar			

;*************************************************************************
; TxtPrsInit
; Purpose:
;	This is called by User Interface code after File/New/Sub
;	to put the following pcode into the newly created text table:
;	   DEFxxx state from the end of the module so user who has
;	   DEFINT A-Z in module will get it in SUB as well.
;	   SUB/FUNCTION name
;	   END SUB/FUNCTION
; Entry:
;	prs in question is active
;	otype - If proc is a FUNCTION then otype is its return type
; Exit:
;	No error return.  If out of memory, the user just gets an
;	empty text table.
;
;*************************************************************************
cProc	TxtPrsInit,<PUBLIC,FAR>,<si,di>
	parmB	oType				
cBegin
	;Following is guarenteed by by PrsMake()
	DbAssertRel [grs.GRS_oMrsCur],e,[prsCur.PRS_oMrs],CP,<TxtPrsInit: err2>
	DbAssertTst [txdCur.TXD_flags],Z,FTX_mrs,CP,<TxtPrsInit: got an mrs>

	and	[prsCur.PRS_flags],NOT FP_STATIC
					;in case this prs used to have a
					; txt tbl, with FP_STATIC bit set,
					; and then prs was discarded.  FP_STATIC
					; would still be set.
	SetStartOtx di			;otxInsert = 0
	push	di			;pass otxInsert
	PUSHI	ax,16d			;we're about to insert 16 bytes
	call	TxtMoveUp		;make room for pcode to be inserted
	je	TxtPExit		;brif out-of-memory

	GetSegTxtTblCur	es		;es = seg adr of txt tbl
	sub	ax,ax			;ax = opBol
	.errnz	opBol
	stosw				;emit opBol
	mov	ax,opStSub
	cmp	[prsCur.PRS_procType],PT_SUB
	je	TxtSub
	mov	ax,opStFunction
TxtSub:
	stosw				;emit opStSub/opStFunction
	mov	ax,6
	stosw				;emit cntEos operand
	mov	ax,[grs.GRS_oPrsCur]
	stosw				;emit oPrs operand
.errnz	ET_IMP
	sub	ax,ax			;al = ET_IMP
	mov	ah,[prsCur.PRS_procType];ah = PT_SUB or PT_FUNCTION
	cmp	ah, PT_FUNCTION 	
	jne	@F			
	mov	al, [otype]		
	.errnz	ET_IMP			
	or	al,al			;ET_IMP?
	jz	@F			;brif yes.
	or	ax, DCLA_Explicit	
@@:					
	stosw				;emit oTypFn operand
	sub	ax,ax
	stosw				;emit parm count operand (0)
.errnz	opBol				;ax = 0 = opBol
	stosw				;emit opBol
	mov	ax,opStEndProc
	stosw
	or	[mrsCur.MRS_flags2],FM2_Modified
	push	[grs.GRS_oPrsCur]	;save caller's oPrs
	call	PrsDeactivate
	call	OtxDefTypeEot		;fill ps.tEtCur with module's def state
	call	PrsActivateCP		;reactivate caller's prs

	;init default ps.tEtCur[] (default type array)
	SetStartOtx ax			;ax = start of text
	mov	bx,dataOFFSET tEtTemp
	call	OtxDefType		;fill tEtTemp with default types
					; i.e. ET_R4 for all letters

	PUSHI	ax,<DATAOFFSET tEtTemp>
	PUSHI	ax,<DATAOFFSET ps.PS_tEtCur>
	SetStartOtx ax			;ax = otxInsert = start of text
	call	InsertEtDiff
	SetStartOtx si			;otx for inserted pcode
	mov	bx,[txdCur.TXD_bdlText_cbLogical]
	sub	bx,CB_EMPTY_TEXT-StartOtx ;otx beyond end of inserted pcode
	call	TxtInsUpdate		;update any static structures
					; as a result of inserting this pcode.
TxtPExit:
cEnd

;*************************************************************************
; GetWOtx
;
; Purpose:
;	Given an  offset within the current text table, return
;	the 16 bit value stored at that offset.
; Entry:
;	ax = otx
; Exit:
;	ax = 16 bit value from text table
;
;*************************************************************************
PUBLIC	GetWOtx
GetWOtx	PROC NEAR
	DbChk	Otx,ax			;check for invalid text offset
	;NOTE - we can't call DbChkTxdCur here because DebChkTxdCur
	; calls GetWOtx, which causes infinite recursion.
	

DbAssertTst [conFlags],nz,F_CON_StaticStructs,CP,<GetWOtx: static structs not enabled>

	GetSegTxtTblCur			;es = seg addr of current text table
	xchg	bx,ax			;bx = offset into text table
	mov	ax,es:[bx]		;ax = value at that offset
	ret
GetWOtx	ENDP

;*************************************************************************
; PutWOtx
;
; Purpose:
;	Store a 16 bit value at a given offset within the current text table
; Entry:
;	parm1: ushort otx
;	parm2: ushort value
;
;*************************************************************************
cProc	PutWOtx,<PUBLIC,NODATA,NEAR>
	parmW	otx
	parmW	value
cBegin	PutWOtx
	DbChk	Otx,otx			;check for invalid text offset
	DbChk	TxdCur			;perform sanity check on txdCur
	GetSegTxtTblCur es		;es = seg adr of txt tbl
	mov	bx,[otx]		;bx = offset into text table
	mov	ax,[value]		;ax = value to store at that offset
	mov	es:[bx],ax		;store it
cEnd	PutWOtx


;-----------------------------------------
;	Non-RELEASE CP segment Functions
;-----------------------------------------
sEnd	CP



end

⌨️ 快捷键说明

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