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

📄 txtload.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	;this isn't a recursive $INCLUDE call
	push	ax			;save error code

	call	StatusMsg0CP		;tell user interface we're done loading

	;Now delete any redundant DEFxxx statements which were synthetically
	;generated by LoadExitProc.
	
	mov	ax,[txdCur.TXD_bdlText_cbLogical]
	sub	ax,CB_EMPTY_TEXT-StartOtx 
	cmp	ax,[otxDefEnd]
	je	GotRedundant		;brif module-level-code couldn't have
					; been inserted after last loaded proc
	dec	ax			;don't treat a blank line as significant
	dec	ax			; only a blank line could be 2 bytes
	cmp	ax,[otxDefEnd]
	jne	NoRedundant		;brif module-level-code was inserted
					; after last loaded procedure
GotRedundant:
	push	[otxDefStart]
	push	ax			;pass otxDefEnd
	call	TxtDelete
	mov	si,[otxDefStart]	;update links up to deleted text
NoRedundant:
	;update linked lists which thread through pcode
	
	push	[otxUpdLinks]
	push	si
	call	UpdateLinks
	DbChk	TxdOps			;check for bad linked lists through
					; pcode, bad opcodes, etc.

	pop	ax			;restore al = error code

;al = fatal error code (or 0)
StillLoading:
cEnd

;*************************************************************
; MakFilename
; Purpose:
;	Fill a buffer with <filename>.MAK
; Entry:
;	bx points to string descriptor for source of filename
;	di points to destination (must be FILNAML bytes long)
;	si points to destination string descriptor
; Exit:
;	ax = 0, or error code
;	es = ds = dgroup
;	buffer pointed to by di contains 0-terminated filename.MAK
;	si.pb points to 1st byte of destination buffer
;
;	Flags set on value in ax
;*************************************************************
cProc	MakFilename,<PUBLIC,NEAR>,<di>
cBegin
	call	NormFilename		;Normalize path of filename and add
					; .bas extension 
					; if filename doesn't already have ext.
					;We now know that the filename has
					; an extension, either the one supplied
					; by user or .BAS
	jne	BadMakFileName		;brif error - AX = error code

	add	di,[si.SD_cb]		;di points to 0-byte terminator
;search backward for start of extension
OMakLoop:
	cmp	di,[si.SD_pb]
	jbe	OMakDone		;brif got illegal filename like "/"
	dec	[si.SD_cb]
	dec	di
	cmp	BYTE PTR [di],'.'
	jne	OMakLoop		;brif haven't found extention yet
OMakDone:
	mov	WORD PTR [di+1],'AM'	;append "MAK" extension
	mov	WORD PTR [di+3],'K'	;put K and 0-terminator in buf
	add	[si.SD_cb],4
BadMakFileName:
	or	ax,ax			;set flags
cEnd

;*************************************************************
; OpenChan
; Purpose:
;	Call BASIC Runtime to open a named file.
; Entry:
;	dx = open mode
;	si points to string descriptor for filename
; Exit:
;	[chanCur] = channel #
;	al = standard error code if error (0 if not)
;	condition codes set based on value in al
; Exceptions:
;	assumes caller has called SetRtTrap to trap runtime errors
;	like File not found, etc.
;
;*************************************************************
PUBLIC	OpenChan
OpenChan PROC NEAR

	call	RtPushHandler		;save caller's runtime error handler
					; (NOTE: alters stack pointer)
					; (preserves dx)
	mov	ax,CPOFFSET OcExit	;if any runtime errors occur,
	call	RtSetTrap		; branch to OcExit with sp,di =
					; current values  (preserves dx)
	push	dx			;save open mode
	call	B$FREF			;ax = free channel number

	pop	dx			;dx = open mode
	push	ax			;preserve channel #
	push	si			;pass &sdFilenameNew
	push	ax			;pass channel
	sub	ax,ax
	mov	[chanCur],ax		;so CloseChan won't be called
					; if error in B$OPEN
	dec	ax			;ax = UNDEFINED
	push	ax			;no record size specified
	push	dx			;pass open mode
	call	B$OPEN			;open the file. errors trapped OcExit
	inc	[cChansOpen]		;no error, bump # opened channels
	pop	[chanCur]		;save channel
	call	UpdChanCur		;Tell runtime to use [chanCur] for
					; following I/O calls, test device type
	or	al,al			;is this a block device?
	mov	al,0
	jns	OcExit			;brif it is - no error
	mov	al,MSG_NotBlock		;"Can't load from non-block device"
;al = error code (0 if no error)
OcExit:
	call	RtPopHandler		;restore caller's runtime error handler
					; (saved on stack by RtPushHandler)
					; (preserves ax)
	or	al,al			;set condition codes for caller
	ret
OpenChan ENDP


;*************************************************************
; CloseChan/CloseMfh (EB)
; Purpose:
;	Call BASIC Runtime/OMEGA to close a file
; Entry:
;	[chanCur] = the channel-#/module-file-handle to be closed
;
;*************************************************************
cProc	CloseChan,<PUBLIC,NEAR>
cBegin
	mov	cx,[chanCur]
	jcxz	CcNeverOpened		;brif error before got file opened
	sub	ax,ax
	mov	[chanCur],ax		;remember channel is closed

	dec	[cChansOpen]		; assume close will work
	push	cx			;pass channel number of current load
	inc	ax			;ax = 1
	push	ax			;number of channels on stack
	call	B$CLOS			;close current file - no error possible
					; EXCEPT int 24's.
CcNeverOpened:
cEnd

;***
;UpdChanCur
;
;Purpose:
;	Near interface that uses the global 'chanCur' to make sure b$ptrfil
;	is updated to reflect the current input/output channel. Should be
;	called prior to using save/load I/O whenever the channel is changed,
;	or ANY heap movement could have occured.
;Entry:
;	chanCur assumed to be set up.
;Exit:
;	AL = the device number (as returned by B$CHAN).
;	The runtime b$ptrfil is updated.
;Exceptions:
;	Same as B$CHAN
;*******************************************************************************
PUBLIC	UpdChanCur
UpdChanCur	PROC NEAR
	push	[chanCur]
	call	B$CHAN			;ensure current output channel correct
	ret
UpdChanCur	ENDP


;*******************************************************************************
;ModulePermanent
;Purpose:
;	Set mrsCur.flags fTemporary bit to FALSE.
;	This is called via ForEachCP at the successful conclusion of a LOAD
;	for each text table (module and procedures) in every module.
;Entry:
;	none.
;Exit:
;	AX = TRUE (for ForEachCP)
;
;*******************************************************************************
ProcPerm PROC NEAR
	call	ClrBpTxt		;clear all breakpoints in this
					; text table

	;delete all Watch expressions in this text table
	or	[flagsTM],FTM_WatchPcode ;assume we have watch pcode
	call	OtxEndProg		;ax = otx to Watch pcode
	inc	ax			;skip opEndProg
	inc	ax
	push	ax			;pass start of block to delete
	mov	ax,[txdCur.TXD_bdlText_cbLogical]
.erre	CB_EMPTY_TEXT - 4 EQ StartOtx
	dec	ax			;don't count opEot
	dec	ax
	push	ax			;pass end of block to delete
	call	TxtDelete

	call	TblReInclude
	mov	ax,sp			;return non-zero for ForEachCP
ProcPerm ENDP

ModulePermanent	PROC NEAR
	test	[mrsCur.MRS_flags],FM_TEMPORARY
	je	MpExit			;brif this isn't one of the modules
					; we just loaded
	and	[mrsCur.MRS_flags],NOT FM_TEMPORARY
	and	[mrsCur.MRS_flags2],NOT (FM2_Modified or FM2_ReInclude) 
					;reset modified and temp flags

	test	[mrsCur.MRS_flags3],FM3_Translated ; module binary xlated?
	jz	NotTranslated		; brif not -- FM2_Modified stays 0
	and	[mrsCur.MRS_flags3],NOT FM3_Translated	; reset temp flag
	or	[mrsCur.MRS_flags2],FM2_Modified	; mark as modified
					; so it will be saved in new format
NotTranslated:				

	test	[mrsCur.MRS_flags2],FM2_AsciiLoaded	
	jnz	MpExit			;brif module was not binary loaded

	;re-include all $INCLUDE files in this binary module
	;If we did it right after calling BinaryLoad, TxtChange would
	;have screwed up because it would think a LOAD was still active.
	
	mov	al,FE_CallMrs+FE_PcodePrs+FE_SaveRs
	mov	bx,OFFSET CP:ProcPerm
	call	ForEachCP
MpExit:
	mov	ax,sp			;return TRUE for ForEach...
	ret
ModulePermanent	ENDP


;**********************************************************************
; TxtGrowPsSrcEmScratch (pBd, cbNew)
; Purpose:
;	Called whenever we need to grow ps.bdpSrc or bdEmScratch.  The
;	editmgr REQUIRES that the logical size of these buffers are
;	the same.  This routine takes a bd and checks to see if the passed
;	bd is either ps.bdpSrc or bdEmScratch.	If so, both bds are grown
;	to be the same size.  If the bd is not either of these then we just
;	call BdRealloc.  If we get OM while trying to grow either ps.bdpSrc
;	or bdEmScratch, we will trim the cbLogical
;	routine is a nop.
;
;	Added with revision vision [68].
;
; Entry:
;	pBd - ptr to bd.
;	cbNew - new size of Bd
; Exit:
;	AX - 0 if OM error code.
;
;**********************************************************************
cProc	TxtGrowPsSrcEmScratch,<PUBLIC,FAR>,<si,di>
parmW	pBd
parmW	cbNew
cBegin
	mov	si,dataOffset bdEmScratch
	mov	di,dataOffset ps.PS_bdpSrc
	push	pBd			;pass pbdDst to BdRealloc
	push	cbNew			;pass cbNew to BdRealloc
	call	BdRealloc
	or	ax,ax
	je	TGPSES_OM		;brif out-of-memory

	mov	bx,di			;assume ps.bdpSrc needs grown too
	cmp	pBd,si			;is this bdEmScratch?
	je	GrowSpecBuf		;brif so - grow ps.bdpSrc too
	mov	bx,si			;assume bdEmScratch should grow
	cmp	pBd,di			;is this ps.bdpSrc?
	jne	TGPSES_X		;brif not - nothing special to do

; We get here if we have to grow either ps.bdpSrc or bdEmScratch.  These
; two buffers must grow together for the edit mgr.


GrowSpecBuf:
	push	bx
	push	cbNew
	call	BdRealloc		;realloc other buffer too
	or	ax,ax
	je	TGPSES_OM		;brif OM error

TGPSES_X:
DbAssertRel ps.PS_bdpSrc.BDP_cbLogical,e,bdEmScratch.BD_cbLogical,CP,<TxtGrowPsSrcEmScratch:bdEmScratch and ps.bdpSrc not same size>
cEnd

;if we get an out of memory while growing ps.bdpSrc or bdEmScratch.  Trim them
;both back to the smallest cbLogical.

TGPSES_OM:
	cmp	pBd,si			;is this bdEmScratch?
	je	TrimCbLogical		;brif so - trim back size of both
	cmp	pBd,di			;is this ps.bdpSrc?
	jne	TGPSES_X		;brif not - nothing special to do

TrimCbLogical:
	mov	bx,[si].BD_cbLogical	;get size of bdEmScratch
	cmp	bx,[di].BD_cbLogical
	jb	TrimPs			;trim Ps since it is larger
	mov	bx,[di].BD_cbLogical	;get size of ps.bdpSrc
	mov	[si].BD_cbLogical,bx	;set new size of bdEmScratch
	jmp	short TGPSES_X

TrimPs:
	mov	[di].BD_cbLogical,bx	;set new size of ps.bdpSrc
	jmp	short TGPSES_X


STKCHK_LoadFile EQU 350d ;actually 208d, add 142 for maintenance/uncertainty
;
;STKCHK_ToLoadFile is the number of bytes of stack space needed to get from
; UserInterface (where caller ensures STACK_CHECK bytes exist between sp
; and b$pend) and LoadFile().
;   UserInterface->LoadFile (188d) ([67] 174d)
;
STKCHK_ToLoadFile EQU 400d ;actually 188, add 212 for maintenance/uncertainty

;*************************************************************
; ushort LoadFile(psdFilename, otxInsert)
; Purpose:
;	This is called by LOAD executor, File/Load&Merge menu items,
;	and recursively from TxtChange in response to $INCLUDE.
;	If the filename has no extension, .BAS is appended to
;	a copy of psdFilename.  The copy is then 0-byte terminated.
;	It opens the specified file and loads it, optionally doing
;	a NEW.  Based on 1st byte in file, does an ASCII or BINARY load.
;	If a runtime error is encountered at any INCLUDE level,
;	this function backs all the way out, returning directly to
;	the caller for the 1st level of INCLUDE via RtSetTrap.
;
; Entry:
;	psdFilename points to string descriptor for filename to be loaded.
;	   (the filename itself need not be 0-byte terminated, and
;	    psdFilename.cb MUST not include any 0-byte terminator)
;	otxInsert = LF_NewProg if file may be ASCII or BINARY and if
;	            a NEW is to be performed before the load
;	          = LF_NewModule if file may be ASCII or BINARY and if
;	            a NEW is NOT to be performed before the load
;	          = LF_NewDoc if file is ASCII document
;	          = LF_ViewIncl if file is $INCLUDE file which is not
;	 	    to be loaded in-place, but into another mrs so user
;		    can edit it.
;	          = text offset into current module where text is to be inserted
;	            for MERGE or INCLUDE.  File must be ASCII format for this.
;	            For example, if otxInsert == 0, file's content will be
;	            inserted before text offset 0.
;		    It is important to call TxtDescan before computing
;		    the text offset for the insert.
;	stFileName [only used in EB] Fully qualified FileName in st format.
;	OpenMode = [only used in EB] Specifies whether the input file is to
;		    be loaded from the active database, from a file, or 
;		    whether this is unknown. This parameter is just passed
;		    through to OpenChan.
;
; Exit:
;	ax = Standard BASIC error code (i.e. ER_xxx) if error occurred.
;	   Possible errors include Out-of-memory (ER_OM)
;	   file I/O errors, File-not-found (ER_FNF), Duplicate Mrs
;	   (MSG_DupMrs), Duplicate Prs (MSG_DupPrs)
;	For all errors detected by LoadFile, txtErr.oRs is set to UNDEFINED,
;	   meaning no cursor positioning will take place when error is reported.
;	   Errors which can be represented with an opReParse are not reported
;	   until the user attempts to RUN the program, at which time, TxtDirect
;	   will re-parse and report them.
;	If called by an executor, (i.e. ExStRunFile) and an untrappable error
;	   occurred, grs.otxCur is set to 2, in which case, the module with
;	   the error is grs.GRS_oRsCur and the text offset is grs.otxCur.
;	If called by an executor, and a trappable error occurred,
;	   grs.otxCur is not altered, and the module with the error
;	   is grs.GRS_oRsCur and the text offset is grs.otxCur.
;	   
;	txtErr structure is filled in with error info
;	ps.bdpSrc is used.
;	rsNew is set by MrsMake for all cases but Merge (this tells the
;	  user interface to show this rs in a list window)
;	Preserves grs.fDirect in all cases (needed at least by exStRunFile
;	  when entered in direct mode and error (like file not found) occurs)
;	Preserve's caller's runtime-error-trap handler (if any) and [chanCur]
;
;*************************************************************
J1_RtErrOmStack:
	EXTRN	RtErrOmStack:NEAR
	jmp	RtErrOmStack

⌨️ 快捷键说明

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