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

📄 txtsave.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	TITLE	txtsave.asm - ASCII Save Functions

;==========================================================================
;
;Module:  txtsave.asm - ASCII Save Functions
;System:  Quick BASIC Interpreter
;
;=========================================================================*/

	include		version.inc
	TXTSAVE_ASM = ON
	includeOnce	architec
	includeOnce	context
	includeOnce	heap
	includeOnce	lister
	includeOnce	names
	includeOnce	opcontrl
	includeOnce	opid
	includeOnce	opmin
	includeOnce	opstmt
	includeOnce	parser
	includeOnce	pcode
	includeOnce	qbimsgs
	includeOnce	rtinterp
	includeOnce	rtps
	includeOnce	rttemp
	includeOnce	scanner
	includeOnce	txtmgr
	includeOnce	txtint
	includeOnce	util
	includeOnce	ui
	includeOnce	variable
	includeOnce	edit		

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

	ASC_CRLF	EQU 0A0Dh	;ASCII Carriage return/Line Feed
	ASC_TAB 	EQU 9		;ASCII Tab

sBegin	DATA

	EXTRN	tabStops:WORD	;defined in edit manager
	EXTRN	b$PTRFIL:WORD	;defined by runtime - current channel ptr

CrLf		DW	ASC_CRLF	;for file line termination
oMrsSaveDecl	DW	0		;used by SaveDeclares
sEnd	DATA

sBegin	CODE

;Table of opcodes used to search for DECLARE or CALL statements
;
tOpDecl LABEL WORD
	opTabStart	DECL
	opTabEntry	DECL,opStDeclare
	opTabEntry	DECL,opStCall
	opTabEntry	DECL,opStCalls
	opTabEntry	DECL,opStCallLess
	opTabEntry	DECL,opEot

sEnd	CODE

	EXTRN	B$BUFO:FAR
	EXTRN	B$KILL:FAR

sBegin	CP
assumes	cs,CP

;*************************************************************
; ushort SaveTxdCur(ax:otxStart)
; Purpose:
;	ASCII save the contents of the current text table
; Entry:
;	ax = text offset to start saving text
; Exit:
;	ax = size of last line output (=2 if trailing blank line)
;	ps.bdpSrc is used
; Exceptions:
;	Can cause runtime error (Out of memory, I/O errors)
;
;*************************************************************
SaveTxdCur PROC NEAR
	DbChk	Otx,ax			
	push	si
	push	di
	sub	di,di			;Init cbLastLine = 0
	mov	[otxListNext],ax	;ListLine() updates [otxListNext]
	test	[mrsCur.MRS_flags2],FM2_NoPcode ; document file?
	je	GetOtxEndProg		; file is measured in Otxs, not lines

	DbAssertRel [otxListNext],e,0,CP,<SaveTxdCur:Not starting at the begining of file>
	push	[mrsCur.MRS_pDocumentBuf] 
	call	S_LinesInBuf		; get # lines in document buffer
	jmp	short SetMaximumSave	

GetOtxEndProg:
	call	OtxEndProg		;ax = otx to Watch pcode
SetMaximumSave:
	xchg	si,ax			;si = otx to Watch pcode
StLoop:
	mov	ax,[otxListNext]	;ax=offset for next line to list
	cmp	ax,si
DJMP	jae	SlDone			;brif done with this text table

	test	[mrsCur.MRS_flags2],FM2_NoPcode ; document file?
	je	ListPcodeLine		; brif not, let lister get line

	push	[mrsCur.MRS_pDocumentBuf] ; document table to list from
	push	ax			; line to list
	push	ps.PS_bdpSrc.BDP_cbLogical ; length of buffer
	push	ps.PS_bdpSrc.BDP_pb	;pass ptr to dest buf
	call	S_cbGetLineBuf		; AX = cBytes in line
	inc	[otxListNext]		; bump pointer to next line
	mov	[cLeadingSpaces],0	; start with no leading spaces
	mov	bx,[ps.PS_bdpSrc.BDP_pb]; BX = ptr to 0 terminated string

CheckNextChar:				
	cmp	byte ptr [bx],' '	; Is it a space
	jne	GotLine 		; brif not, say that we got line

	inc	[cLeadingSpaces]	; indicate another space
	inc	bx			; point to next character
	jmp	CheckNextChar		; check it for a space

ListPCodeLine:				

	push	ax			;pass offset to ListLine
	PUSHI	ax,<DATAOFFSET ps.PS_bdpSrc>	;pass dst buf ptr to listline
	call	ListLine		;ax=char count
	inc	ax			;test for UNDEFINED
	jne	NotOmErr		;brif out-of-memory
	jmp	OmErrCP
NotOmErr:
	dec	ax			;restore ax = byte count
GotLine:
	cmp	[fLsIncluded],0
	jne	StLoop			;brif line was part of $INCLUDE file

	test	mrsCur.MRS_flags2,FM2_EntabSource ;do we need to entab leading
					;blanks?
	jz	NoEntab 		;brif not
	mov	cl,[cLeadingSpaces]	;cl = count of leading spaces
	or	cl,cl			;any leading spaces?
	jnz	EntabLeadingSpaces	;brif so, replace with tabs
NoEntab:
	mov	bx,[ps.PS_bdpSrc.BDP_pb]
EntabCont:
	; There is currently no need to call UpdChanCur here, because
	; there is no chance of having nested open files during ascii save.
DbAssertRel b$PTRFIL,ne,0,CP,<SaveTxdCur:Invalid channel>

	; Call OutLine as we can not guarentee that the buffer
	; pointed to by BX contains at least two more bytes.
	; This is slower, but will not trash the heaps.
	mov	di,ax			; DI = new "cbLastLine"
	inc	di			; account for CRLF
	inc	di			
	call	OutLine 		; Print line and CRLF
DJMP	jmp	SHORT StLoop

SlDone:
	xchg	ax,di			;ax = cb last line emitted
	pop	di
	pop	si
	ret
SaveTxdCur ENDP

; We have a line with leading spaces which needs to be entabbed.
; We will convert spaces to tabs in the buffer, and return the
; new buffer char count, and a ptr to the start of the buffer.
;
; Entry:
;	ax = count of chars in line buffer
;	cl = count of leading spaces
; Exit:
;	ax = adjusted count of chars in line buffer
;	bx = ptr to first char in buffer
; Uses:
;	bx,cx,dx

EntabLeadingSpaces:
	push	ax			;preserve buffer char count
	xchg	ax,cx
	sub	ah,ah			;ax = cLeadingSpaces
	mov	dx,ax			;remember cLeadingSpaces
	mov	cx,[tabStops]		;get user defined tabstop settings

; User interface guarantees tabStops will not be set to 0
DbAssertRel cx,nz,0,CP,<tabStops=0 detected in Ascii save>

	div	cl			;al=tab count, ah=space count
	mov	bx,[ps.PS_bdpSrc.BDP_pb] ;bx=ptr to line buffer

	add	bx,dx			;bx=ptr to first non-leading space
	sub	dl,al
	sub	dl,ah			;dx=excess space in buffer
	sub	bl,ah			;backup over remaining spaces
	sbb	bh,0
	xchg	ax,cx
	sub	ch,ch			;cx=tab count
	jcxz	NoTabs			;brif none to replace
	mov	al,ASC_TAB
TabLoop:
	dec	bx			;back up a char
	mov	[bx],al 		;replace space with tab
	loop	TabLoop
NoTabs:
	pop	ax			;recover buffer char count
	sub	ax,dx			;adust for removed spaces
	jmp	EntabCont

;*************************************************************
; OutLine, OutCrLf
; Purpose:
;	OutLine - Output line and CR-LF to current file
;	OutCrLf - Output CR-LF to current file
; Entry:
;	bx points to 1st byte to output
;	ax = byte count
;
;*************************************************************
OutLine PROC NEAR
	; There is currently no need to call UpdChanCur here, because
	; there is no chance of having nested open files during ascii save.
DbAssertRel b$PTRFIL,ne,0,CP,<OutLine:Invalid channel>

	push	ds			;pass segment of buffer
	push	bx			;pass offset of buffer
	push	ax			;pass length of buffer
	call	B$BUFO			;output line via runtime
	;fall into OutCrLf
OutLine ENDP

OutCrLf PROC
	; There is currently no need to call UpdChanCur here, because
	; there is no chance of having nested open files during ascii save.
DbAssertRel b$PTRFIL,ne,0,CP,<OutCrLf:Invalid channel>

	push	ds
	PUSHI	ax,<dataOFFSET CrLf>
	PUSHI	ax,2
	call	B$BUFO			;output CR/LF via runtime
	ret
OutCrLf ENDP

;*************************************************************
; RelShBuf
; Purpose:
;	Release temporary text table used by SaveProcHdr.
;	Called when we're done saving, or when an error occurs.
;
;*************************************************************
RelShBuf PROC NEAR
	mov	[txdCur.TXD_bdlText_cbLogical],0
					;so TxtDiscard won't examine deleted txt
	call	TxtDiscard		;discard temporary text table
	call	TxtActivate		;make module's text table cur again
	mov	[ps.PS_bdpDst.BDP_cbLogical],0 ;release space held by temp bd
	ret
RelShBuf ENDP

;*************************************************************
; ushort SaveProcHdr(ax:otxProcDef)
; Purpose:
;	ASCII save the current procedure's header.
;
; Entry:
;	ax = otxProcDef = offset into procedure's text table to opBol for line
;	   containing SUB/FUNCTION statement.  0 if this table has no
;	   SUB/FUNCTION statement yet.
;
; Exit:
;	ps.bdpSrc is used
;	grs.fDirect = FALSE
;	ax = 0 if no error, else Standard BASIC error code (i.e. ER_xxx)
;
; Exceptions:
;	Can cause runtime error (Out of memory, I/O errors)
;
;*************************************************************
SaveProcHdr PROC NEAR
	push	si			;save caller's si,di
	push	di

	mov	di,ax			;di = otxProcDef
	push	[grs.GRS_oPrsCur]	;pass current oPrs to PrsActivate below

	;fill tEtTemp[] with DEFTYP's from start of proc table to SUB line
	mov	ax,di			;ax = otxProcDef
	mov	bx,dataOFFSET tEtTemp	;bx -> type table
	call	OtxDefType

	;move everything up to proc def from procedure's to temp text table
	PUSHI	ax,<dataOFFSET ps.PS_bdpDst>
	push	di			;pass otxProcDef
	call	BdRealloc
	or	ax,ax
	je	JE1_ShOmErr		;brif out-of-memory error

	PUSHI	ax,<dataOFFSET txdCur.TXD_bdlText>
	SetStartOtx ax			
	push	ax
	push	[ps.PS_bdpDst.BDP_pb]
	push	di			;pass otxProcDef
	call	BdlCopyFrom

	;Now we create a temporary text table for saving the synthetically
	;generated procedure header.  We must go through the following steps
	; to do this:
	;  PrsDeactivate()  ---  causes module's text table to be made active
	;  TxtDeactivate()  ---  causes no text table to be made active
	;  TxtCurInit()     ---  make temp text table active
	;  put synthetically generated pcode into txdCur
	;  ASCII save this pcode buffer to the file
	;  TxtDiscard()     ---  discard temporary text table
	;  TxtActivate()    ---  make module's text table current again
	;  PrsActivate(oPrsSave)
	

	;[flagsTM.FTM_SaveProcHdr] is non-zero while in critical state
	; within function SaveProcHdr. Tells SaveFile's error cleanup
	; to take special action.
	
	or	[flagsTM],FTM_SaveProcHdr ;if err, remember to clean up
	call	PrsDeactivate		;make module's text table active
	call	TxtDeactivate		;causes no text table to be made active
	call	TxtCurInit		;make temp text table active
	je	ShOmErr			;brif out-of-memory error

	;emit synthetic DEFxxx statements as transition from end of last
	;text table to procedure definition line
	PUSHI	ax,<dataOFFSET ps.PS_tEtCur>
	PUSHI	ax,<dataOFFSET tEtTemp>
	SetStartOtx ax			;insert at start of text
	call	InsertEtDiff
JE1_ShOmErr:
	je	ShOmErr			;brif out-of-memory error
	call	OtxEndProg		;ax = otx to Watch pcode
	xchg	si,ax			; = offset beyond synthetic DEFxxx stmts

	;Append everything up to SUB line to temp table
	push	si			;pass otx to Watch pcode
	push	di			;pass otxProcDef
	call	TxtMoveUp
	je	ShOmErr			;brif out-of-memory error
	PUSHI	ax,<dataOFFSET txdCur.TXD_bdlText>
	push	si			;pass otx to Watch pcode
	push	[ps.PS_bdpDst.BDP_pb]
	push	di			;pass otxProcDef
	call	BdlCopyTo
	call	SqueezeDefs		;takes parm in si

	;if setting of $STATIC/$DYNAMIC differs between procedure's header
	;and where procedure will be listed in source file,
	;insert pcode to change the state for the procedure,
	;Note: fLsDynArrays's value will be changed by ListLine() when it
	;      lists the line emitted by InsertDynDiff (if any)
	
	SetStartOtx ax			;insert at start of text
	mov	dh,[fLsDynArrays]	;dh = old $STATIC/$DYNAMIC state
	mov	dl,[fProcDyn]		;dl = new $STATIC/$DYNAMIC state
	call	InsertDynDiff
	je	ShOmErr			;brif out of memory error
	SetStartOtx ax			;start saving at start of text
	call	SaveTxdCur		;save procedure's header to file
	call	RelShBuf		;release temp text tbl
	and	[flagsTM],NOT FTM_SaveProcHdr ;reset critical section flag

	;oPrs parm was pushed on entry to this function

⌨️ 快捷键说明

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