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

📄 txtload.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
					; pcode, bad opcodes, etc.
	mov	ax,[otxLastProc]
	mov	[otxUpdLinks],ax
	xchg	bx,ax			;bx = otxLastProc
	mov	al,DT_EndProc
	call	TDataEntry		;add entry to table so we can
					;move DATA stmts from prs to mrs
	pushf				;preserve error status
	call	PrsDeactivate		;make module's txt table active
	popf				;recover error status
	je	LexExit 		;return PSW.C if out-of-memory

	;emit DEFxxx statements to module, bringing its state up
	;to the state at the end of the procedure, for BASCOM compatibility.
	;In BASCOM, DEFxxx statements are globally scoped, but in QBI,
	;we want to give the user the feeling that each procedure source
	;window stands independently of the module's source window
	
	mov	si,[txdCur.TXD_bdlText_cbLogical]

	PUSHI	ax,<dataOFFSET tEtTemp>
	PUSHI	ax,<dataOFFSET ps.PS_tEtCur>
	mov	ax,[otxLastProc]	;ax = insertion point
	call	InsertEtDiff
	je	LexExit 		;return PSW.C if out-of-memory

	mov	ax,[otxLastProc]	;ax = insertion point
	mov	dh,[fDynArraysMod]	;dh = old state for module level code
	mov	dl,[fDynArrays]		;dl = new state ($STATIC or $DYNAMIC)
	call	InsertDynDiff
	je	LexExit			;return PSW.C if out-of-memory error

	neg	si			;si = -(old cbLogical)
	add	si,[txdCur.TXD_bdlText_cbLogical]
					;si = txdCur.bdlText.cbLogical-(old)
 					; = #bytes of synthetic pcode emitted
	mov	ax,[otxLastProc]
	cmp	[otxDefEnd],ax
	je	GotDeadCode

	;some module level statements have been emitted since the
	;last synthetically emitted DEFxxx statements, so those
	;DEFxxx statements can't be deleted at the end of AsciiMerge.
	;The reason we try to delete them is to keep the file from
	;growing with every ASCII Save/Load by useless DEFxxx statements.
	
	mov	[otxDefStart],ax
;ax = otxLastProc
;si = #bytes of synthetic pcode generated
GotDeadCode:
	xchg	ax,si			;si = otx of 1st inserted DEFxxx
	xchg	ax,bx			;bx = cbInserted
	add	bx,si			;bx = otx after inserted DEFxxx
	push	bx			;preserve across call
	call	TxtInsUpdate		;update line count for inserted lines
DbAssertRel ax,ne,0,CP,<Unexpected OM error in LoadExitProc>
	pop	ax			;recover oTx after inserted text

	;Tell AsciiMerge that we've changed text tables, and
	;where to insert next line in the module's text table
	
	mov	[otxNewInsert],ax
	mov	[otxDefEnd],ax
	stc				;not out-of-memory
LexExit:
	cmc				;return psw.c set if out of memory
	pop	si			;restore caller's si
	ret
LoadExitProc ENDP


			;***************
			;* ASCII Load  *
			;***************


;*********************************************************************
; ushort NEAR GetLineBd(bx:pbd, cx=cbAppend)
; Purpose:
;	Input an arbitrarily long line into the buffer pointed to by pbd.
;
; Entry:
;	pbd points to destination buffer descriptor
;	cx = number of bytes already in buffer to preserve
;          = 0 if append is not desired
; Exit:
;	returns 0 if got a line, dx = length of line in bytes
;	if out-of-memory,
;	   returns ax = ER_OM
;	if end-of-file
;	   returns UNDEFINED
;	If new line is longer than pbd->cbLogical,
;	   pbd->cbLogical = new length
;	Line is 0-byte terminated
;
; Exceptions:
;	Can cause runtime error (Out of memory, I/O errors)
;
;*********************************************************************
PUBLIC GetALine				;for profiling only
cProc	GetALine,<NEAR>,<si,di>
	parmW	pBufDst			;destination buffer
	parmW	cbMax			;# of free bytes in dest. buffer
cBegin
	;Register usage:
	;	SI contains b$PTRFIL, i.e., ptr to FDB for input channel
	;	DI contains a ptr to the destination buffer
	;	BX contains the offset to next unread char in buffer
	;	CX contains cbMax (input)
	;	DX contains count of chars read in so far

	mov	si,[b$PTRFIL]
	or	si,si			;is the current channel valid?
	jne	GlStart 		;brif so, use it
	call	UpdChanCur		;refresh channel in case of error
	mov	si,[b$PTRFIL]
GlStart:
	FDB_PTR es,si,si		;(ES:)[SI] = *FDB
	mov	bx,FileDB.FD_BUFCNT	;offset to next unread char in FDB
	mov	di,[pBufDst]		;di = start of dest buffer
	sub	dx,dx			;dx = 0 (count of chars read so far)
GlStartLoop:
	mov	cx,[cbMax]
GlLoop:
	cmp	cx,dx
	jbe	J1_GlEol		;brif reached end of dest. buffer

	cmp	bx,FileDB.FD_INBUFCNT	;any unread chars left?
	jz	FillBuff		;  brif not
	mov	al,FileDB.FD_BUFFER[BX] ;fetch char from FDB

	inc	bx			;update offset to next unread char
GlCont1:
	cmp	al,ASC_DBL_QUOTE	;test for ", CR, TAB, LF, CTRL-Z
	jbe	GlQuoteOrLess		;brif TAB, or end-of-line
GlCont:
	mov	[di],al			;put char in dst buffer
	inc	di			;bump dst ptr
	inc	dx			;bump count
	jmp	SHORT GlLoop

J1_GlEol:
	jmp	short GlEol

FillBuff:
	push	dx			;preserve count
	mov	FileDB.FD_BUFCNT,bx	;update based on chars we've read so far
	call	B$IDISK_SINP		;al = next byte from file
	FDB_PTR es			;make sure ES still in FDB segment
	mov	bx,FileDB.FD_BUFCNT	;restore offset to next char in FDB
	pop	dx
	jcxz	GlEof			;brif EOF (cx set by B$IDISK_SINP)
	mov	cx,[cbMax]		;refresh
	jmp	short GlCont1


GlQuote:
	not	[fInQuote]		;toggle "quoted string" state
	jmp	SHORT GlCont

GlQuoteOrLess:
	je	GlQuote
	cmp	al,ASC_EOF		;test for CR, TAB, LF, CTRL-Z
	ja	GlCont			;brif not TAB or end-of-line
	jne	GlCrOrLess		;brif Not CtrlZ
	or	dx,dx			;was CtrlZ at beginning of line?
	je	GlEof			;brif so - treat as EOF
					;fall thru and loop to GlCont
GlCrOrLess:
	cmp	al,ASC_CR		;test for carriage return
	je	GlLoop			;brif carriage return - ignore
	cmp	al,ASC_LF		;test for line feed
	je	GlEol			;brif end-of-line
	cmp	al,ASC_TAB		;test for TAB
	jne	GlCont			;brif not TAB
	cmp	[fInQuote],0
	jne	GlCont			;brif within "quoted string"

	;expand TABs to spaces as follows:
	; emit (tabs - (col MOD tabs)) spaces
	; where col is current column (0..n) and
	;       tabs is #columns per tab stop (from user interface)
	; if buffer gets full before done expanding tabs, don't
	; worry about continuing into next buffer.
	
	or	[mrsCur.MRS_flags2],FM2_EntabSource ;remember to reentab at
						    ;ascii save time
	push	dx			;save current column
	xchg	ax,dx			;ax = current column
	cwd				;DX:AX = current column
	mov	cx,[tabStops]		;gets value from user interface

	; User interface should ensure that 0 is not a valid value
	; for tabstops.
	;
DbAssertRel	cx,nz,0,CP,<tab stops = 0 in ascii load>
	div	cx			;dx = remainder = modulus
	sub	cx,dx			;cx = # spaces to emit
	pop	dx			;restore current column
	mov	al,' '			;for now, map TAB to space
TabLoop:
	mov	[di],al
	inc	di			;bump dst ptr
	inc	dx			;bump count
	cmp	[cbMax],dx
	jbe	GlEol			;brif reached end-of-buffer
	loop	TabLoop
	jmp	GlStartLoop

;Reached end-of-file while reading a line
GlEof:
	or	dx,dx
	jne	GlEol			;brif line had valid data before EOF
	dec	dx			;return -1 for EOF

;Reached end-of-line while reading a line
GlEol:
	mov	FileDB.FD_BUFCNT,bx	;update based on chars we read
	xchg	ax,dx			;return byte count in ax
cEnd

CB_LINE EQU 80
cProc	GetLineBd,<PUBLIC,NEAR>,<si,di>
cBegin
	mov	[fInQuote],0		;toggle "quoted string" state
	mov	si,bx			;si points to buffer descriptor
	mov	di,cx			;di = cbLogical


;The following loop only executes 1 iteration for lines less than
;or equal to CB_LINE bytes in length
;
GlBdLoop:
	;make sure there's room for at least CB_LINE+1 more bytes
	push	si			;pass pointer to buffer descriptor
	lea	ax,[di+CB_LINE+1]	;ax = number bytes we need
	push	ax
	call	BdCheckFree
	or	ax,ax
	mov	ax,ER_OM		;prepare for out-of-memory error
	je	GlBdExit		;brif out-of-memory error
	mov	ax,[si.BD_pb]		;ax points to start of result buffer
	add	ax,di			;add cbLogical
	push	ax			;pass ptr to destination
	mov	ax,[si.BD_cbPhysical]	;ax = size of buffer
	sub	ax,di			;ax = number of free bytes in buffer
	dec	ax			;leave room for 0-byte terminator
	push	ax			;pass maximum byte count
	call	GetALine		;read bytes from the file, stop at CR
	cmp	ax,UNDEFINED		;test for end-of-file
	jne	GotData			;brif not end-of-file
	or	di,di
	jne	GotData1		;brif we've already got part of a line
	jmp	SHORT GlBdExit		;return end-of-file indication
					; ax = UNDEFINED (eof)

GotData:
	add	di,ax			;di = total # bytes read so far
GotData1:
	mov	ax,[si.BD_cbPhysical]
	dec	ax
	cmp	ax,di
	je	GlBdLoop		;brif read stopped because of end-of-buf
	mov	bx,[si.BD_pb]
	mov	BYTE PTR [bx][di],0	;zero terminate the line
	mov	dx,di			;return line length in dx
	inc	di			;include 0-byte terminator in count
	cmp	[si.BD_cbLogical],di
	jae	NotNewHigh
	mov	[si.BD_cbLogical],di	;cbLogical = length of longest
					;line read into this bd
NotNewHigh:
	sub	ax,ax			;not end-of-file return code
GlBdExit:
cEnd

;Near gateway to StatusMsgFar - display msg on status line
PUBLIC	StatusMsgCP, StatusMsg0CP
StatusMsg0CP PROC NEAR
	mov	ax,MSG_StatusEdit	; display edit window status line
StatusMsg0CP ENDP			; fall into StatusMsgCP

StatusMsgCP PROC NEAR
	cCall	StatusMsgFar,<ax>
	ret
StatusMsgCP ENDP

;*************************************************************
; ushort NEAR AsciiMerge(ax:otxInsert)
;
; Purpose:
;	Merge the contents of an ASCII source file into the current
;	text table.
;
; Entry:
;	ax = otxInsert = place to insert text
;	grs.oMrsCur, grs.oPrsCur have their usual meaning
;	Current input channel has been opened to file to be merged.
;	cAsciiLoadsActive == 1 if this file is being loaded/merged,
;		           > 1 if this file is being $INCLUDEd
;
; Exit:
;	grs.fDirect = FALSE
;	al = 0 if no error, else Standard BASIC error code (i.e. ER_xxx)
;	ps.bdpSrc is used
;
; Exceptions:
;	Can cause runtime error (Out of memory, I/O errors)
;
;*************************************************************
DbPub	AsciiMerge
cProc	AsciiMerge,<NEAR>,<si,di>
cBegin
	DbChk	Otx,ax			
	mov	si,ax			;ax = si = otxInsert
	sub	di,di			;initial line count = 0
	inc	[cAsciiLoadsActive]
	cmp	[cAsciiLoadsActive],1
	jne	AmLoop

	;this isn't a recursive $INCLUDE call, init static variables
	mov	[otxUpdLinks],ax
	mov	[otxDefEnd],ax
	mov	[otxDefStart],ax
	mov	[otxLastProc],ax
	sub	ax,ax
	mov	[fDynArrays],al		;default to $STATIC
	mov	[fMergeInSub],al
	dec	ax			;ax = UNDEFINED
	mov	[otxNewInsert],ax
	test	[txdCur.TXD_flags],FTX_mrs
	jne	NotMergingInSub
	mov	[fMergeInSub],al	;set fMergInSub non-zero
NotMergingInSub:
	test	[mrsCur.MRS_flags2],FM2_NoPcode
	jne	NoStatusMsg		;dont display "precompiling" if document
	mov	ax,-MSG_Loading		;display Loading msg in intense video
	call	StatusMsgCP		; to tell user we're loading
NoStatusMsg:

	;init default ps.tEtCur[] (default type array)
	mov	ax,si			;ax = text offset
	call	OtxDefTypeCur

;Get source lines and append them until EOF
AmLoop:
	mov	bx,dataOFFSET ps.PS_bdpSrc
	sub	cx,cx			;don't append, just fill buffer
	call	GetLineBd
	inc	ax			;test for UNDEFINED
	je	AmLoopExit		;brif got End-of-file (with ax=0)
	dec	ax			;ax = error code
	jne	AmLoopExit		;brif out-of-memory error

	test	di,1Fh			;update status line every 32 lines
	jne	NotYet			; just to tell user we're not hung
	cCall	UpdStatusLn,<di>
NotYet:
	inc	di			;bump line count
	push	[txdCur.TXD_bdlText_cbLogical]
					;save current size of text table

	test	[mrsCur.MRS_flags2],FM2_NoPcode ; Document file?
	je	@F			;brif not, insert into text table
	push	WORD PTR [mrsCur.MRS_pDocumentBuf] ; ptr to buffer info
	PUSHI	ax,<dataOFFSET ps.PS_bdpSrc.BD_pb> ; ptr to ptr to text
	call	AppendLineBuf		;Append line to document buffer
	and	ax, ER_OM		; convert 0, -1 to 0, ER_OM
	jmp	short InsertDone	
@@:					
	push	si			;insert the line in the text table
	push	si
	sub	ax,ax			;clear fNoInsert flag
	push	ax			;We have text to insert
	call	TxtChange		;al = error code

InsertDone:				
	pop	cx			;cx = old size of text table
	cmp	al,ER_OM
	je	AmLoopExit		;brif out-of-memory (only fatal error)
	mov	ax,[txdCur.TXD_bdlText_cbLogical]
	sub	ax,cx			;ax = size of inserted line
	add	si,ax			;update insertion point
	cmp	[otxNewInsert],UNDEFINED
	je	AmLoop			;brif we're still in same text table

	;We just got a SUB, FUNCTION, END SUB, or END FUNCTION statement
	;and as a result, have switched text tables
	
	mov	si,[otxNewInsert]	;si = new insertion point
	mov	[otxNewInsert],UNDEFINED
	jmp	SHORT AmLoop

;We are done loading this file.
;[al] = 0 if we've reached end-of-file.
;[al] = error code if fatal error occurred while loading.
;	Fatal errors (like out-of-memory) cause mrs to be discarded
;	unless they occurred within an INCLUDE file.
;
AmLoopExit:
	dec	[cAsciiLoadsActive]
	jne	StillLoading		;brif we're still in nested INCLUDE

⌨️ 快捷键说明

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