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

📄 txtload.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
cProc	LoadFile,<PUBLIC,FAR>,<si,di>
	parmW	psdFilename
	parmW	otxInsert
	localW	oRsSave
	localW	otxCurSave
cBegin
	DbAssertRel [b$CurFrame],a,bp,CP,<LoadFile: b$CurFrame .GE. bp>
	;otherwise, runtime error recovery fails

	push	WORD PTR ([grs.GRS_fDirect]) ;save caller's fDirect
	push	[chanCur]		;save caller's current chan
					; (for recursive calls)
	call	RtPushHandler		;save caller's runtime error handler
					; (NOTE: alters stack pointer)
	mov	ax,CPOFFSET LfDone	;if any runtime errors occur,
	call	RtSetTrap		; branch to LfDone with sp,di =
					; current values

	;Runtime ensures we never enter the user interface with less
	;than STACK_CHECK bytes free.  Make sure that STACK_CHECK is big enough
	;to satisfy parser's requirements.
	
DbAssertRel <STKCHK_ToLoadFile+STKCHK_LoadFile>,b,STACK_CHECK,CP,<LoadFile stk>
	mov	ax,[b$pend]
	add	ax,STKCHK_LoadFile
	cmp	sp,ax
	jbe	J1_RtErrOmStack		;brif almost out of stack space

	mov	ax,[grs.GRS_oRsCur]
	mov	[oRsSave],ax

	mov	ax,[grs.GRS_otxCur]
	mov	[otxCurSave],ax

	sub	ax,ax
	mov	[chanCur],ax		;in case we don't get file opened
					; before we branch to LfDone (error)
	SetfDirect al			;we're dealing with text tables
					;       not direct stmt buffer
	dec	ax			;ax = UNDEFINED
	FLoadActive
	jne	Not1stLoad		;brif we're being called for
					; recursive load ($INCLUDE or
					; from LoadMakFile)
	mov	[oRsDupErr],ax		;so we can tell if any Duplicate
					; Prs or Mrs errors occur during
					; load

	mov	[cbAftMerge],0
	test	[txdCur.TXD_flags],FTX_mrs
	je	LfNotMerge		;brif we're in a SUB or FUNCTION
	mov	ax,[otxInsert]
	cmp	ax,LF_NewDoc
	jae	LfNotMerge		;brif we're not MERGEing a file
	sub	ax,[txdCur.TXD_bdlText_cbLogical]
	neg	ax			;ax = #bytes beyond insertion point
	mov	[cbAftMerge],ax

LfNotMerge:
Not1stLoad:

	mov	bx,[psdFilename]	;bx points to source filename sd
	push	ss			
	pop	es			; assure es==dgroup

	cmp	[fLoadInclude],NULL	; loading include file?
	jz	SkipSearch		; no, go process as usual

	mov	al,ER_ADF		; "advanced feature unavailable"
	jmp	short J1_LfDone 	; exit
SkipSearch:				
	mov	di,dataOFFSET NormFname
	mov	si,dataOFFSET sdNormFname

	call	NormFilename		;normalize path of filename and
					; append .bas to sd pointed to by si
	jne	J1_LfDone		;brif bad filename

Lf_Cont:				
	cmp	[fInitialized],FALSE
	je	InInit			;if we're initializing we want to
					;create the mrs for the module even
					;if the file isn't found.

;Before we toss the current text table (via NewStmt), make sure
;file exists, so we can report an error.  Note: this doesn't cover
;case where one of the modules in a multi-module load was not found.
;It is VERY expensive to handle the multi-module case, and
;handling the single module case lets the user test any error
;trapping code the same way as it would work in the compiler,
;since in the compiler, even a multi-module program consists of
;a single EXE file.  Handling multi-modules would be of little
;value if we didn't handle missing $INCLUDE files, which
;would be more than prohibitive.
;
	cCall	FileExists,<di>		;see if file [di] found
	or	ax,ax
	mov	al,ER_FNF
	jne	InInit
J1_LfDone:
	jmp	LfDone			;brif couldn't find filename

InInit:
	;Any errors encountered after this point are untrappable.
	call	CantCont		;loading/re-including a file prevents
					; CONTinue (because we can't back out
					; of it after the n'th line)
					; NOTE: CantCont closes all files
					; if CONT was possible, so this
					; must be called before OpenChan.
					; It also calls _BRUNINI which
					; shows and clears the user screen.
	mov	ax,[otxInsert]
	.errnz	LF_NewDoc - 0FFFCh
	cmp	ax,LF_NewDoc
	jb	LoadFile_Cont		;brif doing a MERGE or $INCLUDE
	.errnz	LF_NewProg - 0FFFFH
DbAssertRelB [cChansOpen],e,0,CP,<NewStmt called for recursive LoadFile()>
	call	NewStmt			;erase content of this module
	call	StatusMsg0CP		;NewStmt erases function key line (25)
					; which is same as status line
	mov	[otxCurSave],2		;so we will position cursor @
					; top of new window if ExStRunFile
					; calls RtErrorCODE
	mov	[oRsSave],UNDEFINED	;remember that we can't restore
					; the caller's oRs for error
					; recovery.  NewStmt also sets
					; grs.otxCont to UNDEFINED,
					; for runtime error recovery.
NoNewStmt:
	cCall	OgNamOfPsd,<si>		; get ogNam of given filename
	or	ax,ax			; OM error return?
	jnz	GotOgNam		;   brif not

	mov	al,ER_OM		
	jmp	SHORT J1_LfDone

GotOgNam:				
	push	ax			; parm to MrsMake
	mov	cx,FM_TEMPORARY + (100h * FM2_File) 
					;set TEMP in case LOAD fails somewhere
					;so we'll know to discard the mrs
	mov	ax,[otxInsert]
	cmp	ax,LF_ViewIncl
	jne	NotIncl
	or	ch,FM2_Include		;so we'll know to do a ReInclude
					;if/when this file gets saved.
NotIncl:
	cmp	ax,LF_NewDoc
	jne	NotDoc			;brif not loading a Document file
	or	ch,FM2_NoPcode
NotDoc:
	push	cx			;pass flags
	call	MrsMake			;create new mrs for this file
	or	ax,ax
	jne	J1_LfDone		;brif error, al = error code
	or	[mrsCur.MRS_flags3], FM3_NotFound 
	call	ModuleRudeEdit
LoadFile_Cont:
	push	[rsNew] 		;DoDrawDebugScr resets rsNew,
					; which was set by MrsMake.
					; We need to preserve this so correct
					; rs is active after MakeExe, or
					; MakeLib.
	call	DoDrawDebugScrFar	;so screen isn't blank with just
					; title bar for too long during a
					; binary load. (It was cleared by
					; CantCont above, and title may
					; have changed by MrsMake above)

	pop	[rsNew]
	;If we could assume DOS 3.0 or greater, (we can't yet) we could set
	;dx to (ACCESS_READ OR LOCK_WRITE) SHL 8 OR MD_SQI
	
	fLoadActive			
	jne	@F			
	call	TDataStart		;init for movement of DATA stmts
					; from prs(s) to mrs
	jne	LfDone			;[37] brif no error occurred
@@:					

	mov	dx,MD_SQI
	call	OpenChan		;Sets [chanCur] which tells LfDone to
					; close the file. Tells AsciiLoad/Binary
					; Load to use this channel
	jne	LfDone			;brif error
	and	[mrsCur.MRS_flags3],NOT FM3_NotFound 
	call	B$IDISK_SINP		;al = 1st byte from file
					; errors trapped @ LfDone
	jcxz	Empty_File		;brif trying to load an empty file
	push	ax			;save 1st char
	call	B$IDISK_BAKC		;put the char back in the buffer
	pop	ax			;restore al = 1st char of file
	cmp	al,BINSAV_1stByte	
	jne	DoAsciiLoad		;brif not binsav flag
	call	fEditorActive		; is this the Editor?
	jnz	DoAsciiLoad		; brif so, no binary files
	mov	al,ER_BFM		; otherwise, it is an error
	jmp	LfDone			

Empty_File:
	xchg	ax,cx			;ax = 0 == no error
	jmp	SHORT LfDone

DoAsciiLoad:
	mov	ax,[otxInsert]		;ax = line where text is to be inserted
	cmp	ax,LF_NewDoc
	jb	DoMerge			;brif doing a MERGE or $INCLUDE
	or	[mrsCur.MRS_flags2],FM2_AsciiLoaded
	SetStartOtx ax			;start load at offset 0
DoMerge:
	
DbAssertRelB [txdCur.TXD_scanState],ne,SS_EXECUTE,CP,<LoadFile: bad scan state>
	call	AsciiMerge		;merge file at offset [ax]
					;Note: AsciiLoad can make recursive
					; calls to LoadFile()
					; some errors trapped @ LfDone

;al = error code (0 if no error)
LfDone:
	mov	[txtErr.TXER_oRs],UNDEFINED
					;don't try to position cursor to
					; offending stmt for errors caused
					; by LoadFile.  Values of txtErr.otx
					; and txtErr.oSrc are unimportant
					; if txtErr.oRs = UNDEFINED
	cmp	al,ER_FNF		;test for FileNotFound
	jne	NotInInit		;brif not
	cmp	[fInitialized],FALSE
	jne	NotInInit
	FLoadActive
	jne	NotInInit
	cmp	[cInclNest],0		;test for INCLUDE file not found
	jne	NotInInit		; brif include file not found
	test	[cmdSwitches],CMD_SW_RUN ;Want to Run program, or just load it?
	jne	NotInInit		;brif /RUN <filename>
	and	[mrsCur.MRS_flags3],NOT FM3_NotFound 
	sub	ax,ax			;qb <filename> when filename not
					; found should just create file
;al = error code (0 if no error)
NotInInit:
	sub	ah,ah			;ax = result
	xchg	si,ax			;si = result
	call	CloseChan		;close [chanCur]
					; don't care about int 24 errors
					; here, since we were reading
	FLoadActive
	jne	LfExit1			;brif not done with multi-module load
					; or recursive $INCLUDE
	call	TDataEnd		;move DATA stmts from prs(s) to mrs
	je	NoDataMoveErr
	mov	si,ER_OM		;return out-of-memory error
NoDataMoveErr:
	call	LfDupRs			;if duplicate mrs or prs encountered
					; during load, set si=errcode
					; if dup mrs, (sets txtErr.oRs),
					; it will be reset to UNDEFINED if mrs
					; is discarded.
	or	si,si			;test result
	je	MakeMods_Perm		; brif no error

	or	[flagsTm],FTM_PrsDefDeleted
					;make sure discarded PRSs are freed
	call	MrsDeactivate		; required so NextMrsFile starts
					; at the beginning
TempMrs_Discard_Loop:			
	call	far ptr NextMrsFile	; activate next file mrs
	inc	ax			; no more file mrs's?
	jz	@F			; brif so - exit loop

	test	[mrsCur.MRS_flags],FM_TEMPORARY
	je	TempMrs_Discard_Loop

	mov	ax,[txtErr.TXER_oRs]
	cmp	ax,[grs.GRS_oMrsCur]
	je	DmNotErr

	mov	[txtErr.TXER_oRs],UNDEFINED
					;don't try to position cursor to
					; offending stmt for error.
DmNotErr:
	call	MrsDiscard
	jmp	TempMrs_Discard_Loop	

MakeMods_Perm:				
	mov	al,FE_PcodeMrs+FE_CallMrs+FE_SaveRs+FE_TextMrs 
	mov	bx,OFFSET CP:ModulePermanent ;reset 'fTemporary' in each mrs
	call	ForEachCP
@@:					

; We call ChkAllUndefPrsSaveRs here to make sure that FTM_PrsDefDeleted
; flag is reset.  If this flag didn't get reset, then the next PRS
; that is created would accidentally be freed in TxtChange.  The case
; where this flag doesn't get reset is when we don't find any Temp mrs's.

	call	ChkAllUndefPrsSaveRs	;search for new defining
					;references for Prs entries
					;which had their "defining"
					;reference deleted.

LfExit1:
	mov	ax,[oRsSave]
	inc	ax
	je	LfExit2			;brif entry mrs has been discarded
	dec	ax			;ax = oRs to restore
	push	ax
	call	RsActivateCP		;activate it (for ExStRun)
LfExit2:
	mov	ax,[grs.GRS_oRsCur]
	inc	ax			;test for UNDEFINED
	jne	LfExit3			;brif not - we need an oMrsCur
	DbAssertRel [grs.GRS_oMrsMain],ne,UNDEFINED,CP,<LoadFile: no oMrsMain>
	mov	ax,[grs.GRS_oMrsMain]
	mov	[rsNew],ax		;if UserInterface has not yet been
					; called, we need rsNew non-zero
					; to cause windows to be initialized
	push	ax
	call	RsActivateCP		;activate oRsMain
LfExit3:
	mov	ax,[otxCurSave]
	mov	[grs.GRS_otxCur],ax	;restore caller's grs.otxCur (or
					; set it to 2 if NewStmt was done)
					; This is done for ExStRunFile.
	call	RtPopHandler		;restore caller's runtime error handler
					; (saved on stack by RtPushHandler)
	pop	[chanCur]
	cmp	[chanCur],0		;do we need to update channel for
	jz	NoChanUpd		;recursive opens?
	call	UpdChanCur		;Update channel
NoChanUpd:

	; The user interface needs the source and scratch buffers to be the
	; same size.  If the scratch is smaller, then horizontal scrolling
	; (like CTRL-PGDN) could cause garbage characters to be displayed.
	; This does not cause any data or code corruption, but is visually
	; disconcerting.  Since this is only a visual bug, special out-of-
	; memory handling is not necessary.

	PUSHI	ax,<dataOFFSET bdEMScratch>;pass Scratch buffer
	mov	ax,[ps.PS_bdpSrc.BDP_cbLogical] ; get current size
	push	ax
	call	TxtGrowPsSrcEmScratch	;grow bdEmScratch
	;can ignore OM errors here since cbLogical will have been
	;trimmed to the same value for both buffers.

	PopfDirect ax			;restore direct mode status

	call	fEditorActive		; Did we start with /EDITOR
	jz	@F			; no, ok to exit
	test	[mrsCur.MRS_flags2],FM2_NoPcode ; is it a document table?
	jnz	@F			; brif so, it is ok

	; We must insure that we are using a document table, so create
	; a new one

	mov	ax,DATAOFFSET szUntitled; psz of title
	push	ax			; first parm to OgNamofPsd
	push	ax			; parm to CbSz
	call	CbSz			; get the length
	push	ax			; second parm to OgNamofPsd
	call	OgNamofPbCb		; convert to OgNam
	xchg	bx,ax			; save OgNam in BX
	or	bx,bx			; did we make the OgNam?
	mov	ax,ER_OM		; assume not, prepare OM error
	jz	NoOgName		; no, give OM Error
	push	bx			; ogNam
	PUSHI	ax,<(FM2_File + FM2_NoPCode) * 100h> ; flags
	call	MrsMake 		; create the MRS
NoOgname:
	or	ax,ax			; is there an error
	jz	@F			; brif not, all ok
	or	si,si			; is there already an error?
	jz	SaveError		; brif not, use the new error
@@:					
	xchg	ax,si			;ax = result
	or	ax,ax			;set condition codes for caller
	je	LfExit			;brif no error occurred
SaveError:
	mov	[txtErr.TXER_errCode],ax
LfExit:
cEnd



;*********************************************************************
; SetPsErrMsg
; Purpose:
;	Set the parser's error message buffer to the name of a
;	register set (module or procedure).
; Entry:
;	ax = oRs (condition codes set based on value in ax)
; Exit:
;	ps.bdErr contains ASCII name of module/procedure.
;	ax = 0 if out-of-memory (condition codes set based on value in ax)
;
;*********************************************************************
cProc	SetPsErrMsg,<PUBLIC,NEAR>
cBegin
	push	ax			;preserve the oRs
	cCall	RsActivateCP,<ax>	;activate the oRs
	pop	ax			;ax = oRs
	mov	bx,[prsCur.PRS_ogNam]	
	or	ax,ax			;test the 

⌨️ 快捷键说明

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