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

📄 uiedit.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
; Entry:
;	ax = otx to next opcode to be executed by interpreter, or
;	     FFFF if next opcode is not in this text table.
;	si = otx to start of line to be listed.
;	di = ptr to buffer descriptor for destination.
; Exit:
;	ax = number of bytes listed (as returned by ListLine)
;	dx = column offset that corresponds to entry's ax
;
;**************************************************************************
ListAxSiDi PROC NEAR
	mov	[otxLsCursor],ax
	cCall	ListLine,<si,di>	; cbLine = ListLine(otx, pbd)
	ret
ListAxSiDi ENDP

;**************************************************************************
; ushort cbGetLineBuf(hbuf, ln, cbMax, szDst)
; Purpose:
;  Called by TextWin's editor, even when the current buffer has been
;  modified and the line needs to be refreshed.  This routine gets
;  the specified ASCII line of text even it is the current line (i.e. UNDO).
;
; Entry:
;  hbuf     - buffer handle.
;  ln       - line to copy
;  cbMax    - Max number of character to copy to buffer.
;  szDst    - where to put the zero terminated line
;  grs.otxCONT = text offset to next instruction to be executed
;
; Exit:
;  if grs.otxCONT points into line being listed:
;     colStmtStart = column of start of next statement
;     colStmtEnd = column of end of next statement
;  else
;     colStmtStart = colStmtEnd = UNDEFINED
;  return number of characters put in buffer (excluding terminating zero)
;  If out-of-memory, sets [uierr] to ER_OM and returns 0
;
;**************************************************************************
cProc	cbGetLineBuf,<PUBLIC,FAR>,<si,di>
	parmW	hbuf
	parmW	ln
	parmW	cbMax
	parmDP	szDst
cBegin
	;Caller can only call us to list to 1 of 2 buffers:
	; ps.bdpSrc or bdEMScratch, see which it is
	; The reason twin passes an absolute pointer is because twin is used
	; by other products that have static buffers.
	
	mov	di,DATAOFFSET ps.PS_bdpSrc
	mov	ax,[szDst]
	cmp	ax,[di.BD_pb]
	je	GotBdPtr		; brif ps.bdpSrc is our buffer
	mov	di,DATAOFFSET bdEMScratch
	DbAssertRel ax,e,[di.BD_pb],UI,<cbGetLineBuf called with bad pointer>

;di = ptr to output buffer descriptor
GotBdPtr:
	mov	bx,[hbuf]
	cmp	bx,hbufHelp		; Check for help buffer
	jne	@F			; if not, skip ahead

	mov	ax,WM_HELPLINE		; message to send
	mov	bx,OFFSET DGROUP:wndHelp ; window to send to
	cCall	SendMessage,<bx,ax,[ln],[szDst],[cbMax]>
	inc	[fWndHelp]		; Set flag for GetLineAttrs
	jmp	GlbExit 		

@@:
	mov	[fWndHelp],0		; make sure flag is reset
	call	ActivateHbuf

	call	fDocumentBuf		; Is this a large document buffer?
	jz	GLB_NotDocument		; brif not, let txtmgr handle it
	push	[mrsCur.MRS_pDocumentBuf] 
	push	ln			
	push	cbMax			
	push	szDst			
	call	S_cbGetLineBuf		; Get line from document buffer
	jmp	SHORT GlbExit		

GLB_NotDocument:
; [otxGetNext] is a cached otx for line [lnGetNext].
; See if we can use it.
	mov	si,[otxGetNext]
	mov	ax,[ln]
	mov	cx,[lnGetNext]
	inc	ax			;cache the otx for [ln]+1
	mov	[lnGetNext],ax
	dec	ax

	jcxz	RefreshCache		;brif cached otx is invalid
	cmp	ax,cx
	je	GotOtx

; Cached otx was no good, we have to search for the otx.
;
RefreshCache:
	cCall	OtxOfLn,<ax>
	xchg	si,ax				; mov si,ax

;Save cached otx for next call
GotOtx:
	mov	[otxLnLast],si

; ListLine checks to see if otxLsCursor is in the current line, and if so
; it returns dx=the equivalent column for the opcode at that otx.
; If the current text table is the `active text table' (i.e. the text table
; containing the next statement to be executed), then otxLsCursor is setup
; appropriately.  grs.oRsContTxtTbl gets set whenever grs.oRsCONT gets set.
; The only time it is different then grs.oRsCONT is when grs.oRsCONT is
; for a DEF FN, in which case, this gets set to the oRs for the module
; that contains the DEF FN.
;
	mov	ax,UNDEFINED		;assume line doesn't contain next stmt
					; to be executed by interpreter
	mov	[colStmtStart],ax
	mov	[colStmtEnd],ax
	xchg	dx,ax			;dx = UNDEFINED
	mov	ax,[grs.GRS_oRsContTxtTbl]
	cmp	ax,[grs.GRS_oRsCur]
	jne	ListTheLine		;brif this isn't the oRs with next
					; stmt to exec
	mov	ax,[grs.GRS_otxCONT]
	inc	ax			;test for UNDEFINED
	jz	ListTheLine		;brif grs.GRS_otxCONT == UNDEFINED
	xchg	dx,ax			;dx = otxCONT
	dec	dx			;undo above inc

	;Don't be tempted to enable this...  Keep the comment around
	; as a reminder, because it is very tempting...
	; This causes bug where if you edit the line with
	; the current instruction, afterward, it looks like the
	; previous line contains the next instruction.
	; Maybe fix this another way, or always keep a NOP after
	; opStSub, opStFunction, opStDefFn, opStStop
	
	;;;;Set dx to otxCONT - 1, so if STOP and BreakPoint after DEF FN,
	;;;; SUB, or FUNCTION will highlight the STOPPED stmt.
	
	;;;;je	ListTheLine		;brif grs.GRS_otxCONT == 0
	;;;;dec	dx

;dx = new otxLsCursor, si = otx to list, di = bdDestination
ListTheLine:
	xchg	ax,dx			; ax = new otxLsCursor
	call	ListAxSiDi		; cbLine = ListLine(otx, pbd)
	inc	ax			; test for UNDEFINED
	je	GlbOmErr		; return 0 if out-of-memory
	dec	ax			; restore ax = cbLine
	push	ax			; save cbLine (return value)
	mov	ax,[otxListNext]	; cache this value for next time
	mov	[otxGetNext],ax
	inc	dx			; test for UNDEFINED
	je	NotOnLine		; brif line doesn't contain next stmt

	;Since we know this line contains next stmt to be executed,
	;call ListLine twice more to find column offset for start and
	;end of stmt, LineAttr can highlight the statement.
	
	push	[otxLsCursor]
	call	OtxBosOfOtx		; ax = otx for next stmt's bos
	call	ListAxSiDi		; cbLine = ListLine(otx, pbd)
					;  since this line was just listed,
					;  we are assured not out-of-memory
	mov	[colStmtStart],dx
	inc	dx
	je	NotOnLine


	push	[otxLsCursor]		; push otx arg.
	call	OtxBosNext		; ax = otx for next stmt's eos
	call	ListAxSiDi		; cbLine = ListLine(otx, pbd)
					;  since this line was just listed,
					;  we are assured not out-of-memory
	mov	[colStmtEnd],dx
	inc	dx
	jne	NotOnLine		; brif not UNDEFINED
	dec	dx			; dx = UNDEFINED
	mov	[colStmtStart],dx	; if colStmtEnd is UNDEFINED,
					; so is colStmtStart
NotOnLine:
	pop	ax			; restore ax = cbLine (return value)
GlbExit:
cEnd

GlbOmErr:
	call	SetUiErrOm		; report error in msg loop
	jmp	SHORT GlbExit		; return ax=0


;**************************************************************************
; LineAttr(attrDefault)
; Purpose:
;  Returns an array discribing the screen attributes for the last line
;  fetched by cbGetLineBuf.
;
; Entry:
;  attrDefault is the screen attribute to use for non-standout text.
;  colStmtStart and colStmtEnd are as set by last call to cbGetLineBuf.
;
; Exit:
;  returns pointer to array of LineAttr's.
;  Each LineAttr consists of a count (cb) and an attribute (attr)
;  attr is the attribute to be used for the next cb characters in the line.
;  The array is terminated with an attr of 0xffff
;  cb may be zero.
;  If cb is 0xffff then attr is used for the rest of the line.
;
;**************************************************************************
cProc	GetLineAttrs,<PUBLIC,FAR>,<si,di>
	parmW	attrDefault
cBegin
	cmp	[fWndHelp],0		; Is being called for help window
	je	@F
	mov	[fWndHelp],0		; Clear fWndHelp
	mov	ax,WM_HELPATTR		; message to send
	cCall	SendHelpMsg,<ax,ax>	; Send message to help system
	jmp	short AttrEnd		

@@:
	mov	si,[attrDefault]
	mov	di,dataOFFSET rgLineAttr

	cCall	fCodeWnd
	jz	UseDefaultAttrs		;brif DOCUMENT text table

	cmp	[fLsIncluded],0
	je	NotIncluded
	mov	si,isaIncludeFileHilite 
NotIncluded:

	cCall	fBpSet,<otxLnLast>
	or	ax,ax
	je	NoBpSet
	mov	si,isaBreakpoint
NoBpSet:
	mov	ax,[colStmtStart]
	mov	dx,[colStmtEnd]
	inc	ax			;test for UNDEFINED
	je	UseDefaultAttrs
	inc	dx			;test for UNDEFINED
	je	UseDefaultAttrs
	dec	ax			;ax = [colStmtStart]
					;dx = [colStmtEnd] + 1
	

; Ahh, this line has the current statement on it.
; We must setup so that it gets highlighted properly
; ax = [colStmtStart], dx = [colStmtEnd]
;
	mov	[di.LA_cb],ax
	mov	[di.LA_attr],si
	sub	dx,ax			;dx = [colStmtEnd]+1-[colStmtStart]
	mov	ax,isaCurBreakpoint
	cmp	si,isaBreakpoint
	je	GotCurBp		;brif current stmt has breakpoint too
	mov	ax,isaCurStmt
GotCurBp:
	mov	[di + (size LINEATTR) + LA_cb],dx
	mov	[di + (size LINEATTR) + LA_attr],ax
	mov	ax,UNDEFINED
	mov	[di + (2*(size LINEATTR)) + LA_cb],ax
	mov	[di + (2*(size LINEATTR)) + LA_attr],si	
	mov	[di + (3*(size LINEATTR)) + LA_attr],ax
	jmp	short GLA_End

UseDefaultAttrs:
	mov	ax,UNDEFINED
	mov	[di + LA_cb],ax
	mov	[di + LA_attr],si
	mov	[di + (size LINEATTR) + LA_attr],ax
GLA_End:
	xchg	ax,di			;return ax = &rgLineAttr
AttrEnd:
cEnd


;**************************************************************************
; StartBigEdit
; Purpose:
;  Called by the Edit Mgr at the start of some operation which results
;  multiple calls to InsertLineBuf/ReplaceLineBuf/DeleteLinesBuf.
;  Examples include multi-line-paste/cut/copy, line-split, line-join.
;
; Entry:
;
; Exit:
;**************************************************************************
cProc	StartBigEdit,<PUBLIC,FAR>
cBegin
	cCall	TxtStartBigEdit
cEnd


;**************************************************************************
; EndBigEdit
; Purpose:
;  Called by the Edit Mgr at the end of some operation which results
;  multiple calls to InsertLineBuf/ReplaceLineBuf/DeleteLinesBuf.
;  Since during a BIG EDIT, all lines are emitted within opReParse
;  operands, and not really parsed to pcode until TxtEndBigEdit,
;  syntax errors may be discovered during TxtEndBigEdit().
;
; Exit:
;  if error encountered, uierr is set to standard error code
;
;**************************************************************************
cProc	EndBigEdit,<PUBLIC,FAR>
cBegin
	cCall	TxtEndBigEdit		;ax = non-zero if serious error
	or	ax,ax
	je	EndBigEdit_End
	mov	[uierr],ax
EndBigEdit_End:
cEnd

;**************************************************************************
; InsertBufInBuf()
; Purpose:
;  Insert the contents of 1 buffer (usually the scrap) into another buffer
;
; Entry:
;  hbufDst - buffer to insert other buffer into.
;  lnDst   - line before which the buffer is to be inserted.
;  hbufSrc - the buffer the be inserted.
;
; Exit:
;  returns zero if out-of-memory, non-zero if success
;
;**************************************************************************
cProc	InsertBufInBuf,<PUBLIC,FAR>,<si,di>
	parmW	hbufDst
	parmW	lnDst
	parmW	hbufSrc
cBegin

	call	StartBigEdit		;so we don't stop inserting just
					; because of a syntax error
	mov	bx,[hbufDst]
	call	ModifyAndGrab

	call	fDocumentBuf		; Is this a large document buffer
	jz	IBIB_NotDocument	; brif not, let txtmgr handle it
	push	[mrsCur.MRS_pDocumentBuf] 
	push	lnDst			

	mov	bx,hbufSrc		; bx = oPrs
	and	bh,7Fh			; mask off bit saying it is PRS.
	RS_BASE add,bx			
	push	[bx.MRS_pDocumentBuf]	
	call	S_InsertBufInBuf	
	jmp	SHORT IBIB_TestRetVal	

IBIB_NotDocument:
	push	[lnDst]
	call	oTxOfLn 		;get oTxInsert for destination buf
	push	ax			;pass oTxInsert
	push	[hBufSrc]		;pass src hBuf
	call	TxtPaste		;insert src buffer at insertion point
IBIB_TestRetVal:
	or	ax,ax			;Out of memory
	jne	IBIB_NotOm		;brif not out of memory
IBIB_OM:
	call	SetUiErrOm		;set out of memory error
IBIB_NotOm:
	call	EndBigEdit		;destination text table is active
	sub	ax,ax			;prepare to return 0 (error)
	cmp	[uierr],ax
	jne	IBIB_Done		;brif got an error
	dec	ax			;return non-zero (success)
IBIB_Done:
	push	ax
	mov	ax,[hbufDst]
	call	UnGrab			;free space reserved by ModifyAndGrab
	pop	ax
cEnd

;**************************************************************************
; ushort near hbufScrap()
; Purpose:
;  Return the handle for the Scrap buffer, allocating the buffer if necessary.
;
; Exit:
;  If out-of-memory, returns NULL
;
;**************************************************************************
cProc	hbufScrap,<PUBLIC,FAR>
	localV	sdName,<size sd>
cBegin
	mov	ax,[hbufOfScrap]
	cmp	ax,UNDEFINED
	jne	hbufScrap_End

; Make a text table (the name is unimportant, but cbName must be non-zero -
; otherwise it is the UNTITLED module), so use the 1 byte string starting
; at address 1 as the name of the scrap.
	lea	bx,sdName
	mov	[bx.SD_pb],DATAOFFSET hbufOfScrap
					;pb -> FF (impossible mrs name)
	mov	[bx.SD_cb],1
	push	bx			;pass &sdName
	PUSHI	ax,RS_scrap		;rsType
	cCall	RsMake			;ax = oRs of scrap
	mov	[hbufOfScrap],ax
	mov	[rsNew],UNDEFINED	;don't tell WnReset to display 
					; scrap in a list window

	DbAssertRel ax,ne,0,UI,<hbufScrap oRs==0>
hbufScrap_End:
cEnd

;**************************************************************************
; UiDelAll
; Purpose:
;	Delete all text from a specified text table
; Entry:
;	bx = hbuf
;
;**************************************************************************
cProc	UiDelAll,<NEAR>
cBegin
	call	ActivateHbuf		;activate text table bx
	call	TxtDelAll		;delete all text in the text
					; table except endprog and eot

	call	fDocumentBuf		; is this a large document
	jz	DelAllExit		; brif not, all done
	push	[mrsCur.MRS_pDocumentBuf] 
	call	FreeBuf 		; Release buffer
	call	NewBuf			; get a new one
	mov	[mrsCur.MRS_pDocumentBuf],ax ; and use that one instead
	DbAssertRel ax,ne,0,UI,<UiDelAll:NewBuf failed>

DelAllExit:
cEnd

;**************************************************************************
;FreeCmdHistory
;Purpose:
;	This is called when we're getting real tight on memory
;	and something needs to be done to free up enough to do
;	the most primitive operations
;Exit:
;	Caller's grs.oRsCur and txtErr are preserved
;
;**************************************************************************
cProc	FreeCmdHistory,<PUBLIC,NEAR>

⌨️ 快捷键说明

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