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

📄 rtmload.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;	CX - contains count of bytes in name pointed to by SI.
;	DX - advanced to next sd in segment name list.
;Uses:
;	None.
;Exceptions:
;	None.
;****


;***
; ULFindData - Get ptr to Data item. (UL only)
;
;Purpose:
;	Added as part of revision [15].
;	Find a data item in user library.
;Entry:
;	DX - points to string descriptor for data item.
;Exit:
;	AX - DGROUP offset of data item (0 if not found).
;Uses:
;	BX, CX, DX, SI, DI
;Exceptions:
;	Consistency error if not found.
;****

	SUBTTL QBC Exec support
	PAGE
;***
; LoadQBExe - Reload the interpreter into memory (QBI only)
;
;Purpose:
;	Added with revision [18].
;	Reloads the interpreter into memory after completing a COMPILE
;	Dialog.
;Entry:
;	BX - QB.EXE file handle.
;Exit:
;	None.
;Uses:
;	AX,CX,DX,SI,DI,BP.
;Exceptions:
;	DOS Memory allocation error.
;	Out of memory error.
;******************************************************************************

	PAGE
;***
; SearchForChar - Search for specified char in buffer (QBI Only)
;
;Purpose:
;	Added with revision [18].
;	Searches for a specified char in a buffer and returns
;	the distance from buffer start to the specified char.
;	ASSUMES THAT CHAR WILL ALWAYS BE FOUND.
;Entry:
;	AL - Char to search for.
;	ES:DI - points to buffer
;Exit:
;	CX - distance from ES:DI on entry to specified Char (not including char)
;	ES:DI - points to requested char.
;Uses:
;	None.
;Exceptions:
;	None.
;******************************************************************************

	PAGE
;***
; ExecCommands - Exec list of commands for COMPILE dialog (QBI Only)
;
;Purpose:
;	Added with revision [18].
;	Execs the list of commands built from the COMPILE dialog box.
;Entry:
;	envSeg = ENV seg to pass on to B$SHELL
;Exit:
;	b$QBCData.fErrorCode - non-zero if error occurred.
;Uses:
;	AX,BX,CX,DX,SI,DI,ES,BP.
;Exceptions:
;	Disk IO Error.
;******************************************************************************


	PAGE
;***
; B$ExecQBC - Exec list of commands as requested from COMPILE Dialog (QBI Only)
;
;Purpose:
;	Added with revision [18].
;	Invokes list of commands generated by the user interface in
;	response to a COMPILE dialog box.  The interpreter will be
;	released except for this loader, the error messages, and DGROUP.
;	The list of commands will then be processed.
;Entry:
;	psdCommands - ptr to sd containing command list.
;Exit:
;	AX = 0 if no error occurred.
;Uses:
;	Per Convention.
;Exceptions:
;	Out of memory error.
;	Disk IO error.
;****


;****
;B$FindFileOnPaths (pszFile, pszUserPath, pEnvVar, cbEnvVar)
;
;Purpose:
;	Moved here from uipaths.asm with revision [69].
;	Searches the current directory, the appropriate user-specified
;	search path, and the appropriate environment variable for the
;	file pszFile and returns a pointer to a fully-qualified pathfile
;	name where the file was found.	If the filename contains a path
;	then we just look in that one place and no further searching is
;	done.
;
;Input:
;	pszFile     - far pointer to null-terminated file name to open
;	pszUserPath - near pointer to user-specified path from Options menu
;	pEnvVar     - far pointer to environment variable name specifying
;			  last-chance search path
;	cbEnvVar    - length of environment variable pointed to by pEnvVar
;
;Output:
;	if successful
;	   DX:AX == pointer to pathfile name where file was found
;	else
;	   AX == 0
;
;****
cProc	B$FindFileOnPaths,<PUBLIC,FAR>,<SI>
	parmD	pszFile
	parmW	pszUserPath
	parmD	pEnvVar
	parmW	cbEnvVar
cBegin
ASSUMES DS,NOTHING

; First check for a path/file name.

	LES	SI,[pszFile]		; es:si points to file name
SearchLoop:
	LODS	BYTE PTR ES:[SI]	; read a byte
	OR	AL,AL			; end of string?
	JZ	NotPathFile		; yes, no path found, go do search
	CMP	AL,'\'                  ; found a path specifier?
	JE	PathSpecified		; yes, go try open without search
	CMP	AL,'/'			; found a path specifier?
	JE	PathSpecified		; yes, go try open without search
	CMP	AL,':'			; found a path specifier?
	JNE	SearchLoop		; no, keep searching

; If we fall through to here then the filename contains an explicit path.
; Check for existence of the specified path/file and do no more searching.
PathSpecified:
	PUSH	DS
	LDS	DX,[pszFile]		; ds:dx points to path/file name
	CALL	OpenFile2		; try to open the file
	XCHG	AX,BX			; BX = file handle (if open worked)
	MOV	AX,0			; can't use XOR because we need PSW.C
	JC	FileNotFound		; it's not there, exit with ax = 0
	PUSH	DX			; save offset of successful filespec
	CALL	CloseFile		; close the file
	MOV	DX,DS
	POP	AX			; DX:AX = ptr to successful filespec
FileNotFound:
	POP	DS
	JMP	SHORT FindFileExit	; exit

; Look for file in current directory first

NotPathFile:
; Note: We have to use fully-qualified pathspec to current directory for
;	many reasons, including checking for "File already loaded" and
;	disabling DPATH.

	PUSH	DS			; preserve ds
	PUSH	CS			
	POP	DS			; DS = LOADRTM
	MOV	SI,OFFSET LOADRTM:SpecBuffer ; point to target buffer
	PUSH	SI			; save ptr to SpecBuffer for call
	MOV	AH,19h			; "get current drive" function
	INT	21h			
	PUSH	AX			; save drive number (0 relative)
	ADD	AL,'A'			; drive number -> drive letter
	MOV	[SI],AL 		; store drive letter
	MOV	WORD PTR [SI+1],"\:"	; store ":" and "\"
	ADD	SI,3			; DS:SI points to target
	POP	DX			; DL = drive number (0 relative)
	INC	DX			; make 1 relative
	MOV	AH,47h			; "get current dir" function
	INT	21h			; get the current directory
	POP	BX			; CS:BX = ptr to SpecBuffer for call
	POP	DS			; restore DS
	JC	NotInCurDir		; current dir is invalid, the file
					;  we're looking for can't be there
	XOR	AX,AX
	cCall	B$SearchOnePath,<seg_pszFile,off_pszFile,AX,CS,BX>
	OR	AX,AX			; find file in current directory?
	JNZ	FindFileExit		; yes, exit with DX:AX = pointer

NotInCurDir:				
; Didn't find it in the current directory, try the user-specified
; search path from the options menu.

	cCall	B$SearchOnePath,<seg_pszFile,off_pszFile,AX,SS,pszUserPath>
	OR	AX,AX			; find file on that path?
	JNZ	FindFileExit		; yes, exit with DX:AX = pointer

; Didn't find it there either, try the path defined by the
; specified environment variable.

	cCall	B$SearchEnv,<seg_pEnvVar,off_pEnvVar,cbEnvVar>
	OR	AX,AX			; find the environment variable?
	JZ	FindFileExit		; no, exit with AX = 0

	XOR	BX,BX			; get a zero
	cCall	B$SearchOnePath,<seg_pszFile,off_pszFile,BX,DX,AX>

; B$SearchOnePath returns exactly what we want to return here,
; so no further processing is necessary.

FindFileExit:
cEnd

;****
;B$SearchOnePath - find a file on a search path
;
;Purpose:
;	Searches the specified path for the specified file.
;	Return a pointer to a fully-qualified pathname if search
;	is successful, otherwise return AX = 0.
;
;Input:
;	pFileName	far pointer to filename to open
;	cbFileName	length of filename
;	pSearchPath	far pointer to search path (list of directories
;				separated by ";" terminated by null)
;Output:
;	if successful
;	   DX:AX = far pointer to fully-qualified pathname
;	else
;	   AX = 0
;
;****

cProc	B$SearchOnePath,<NEAR>,<DS,SI,DI>
ParmD	pFileName
ParmW	cbFileName
ParmD	pszSearchPath

CalcLength:
	XOR	AX,AX			; get a zero for scanning
	DEC	CX			; CX = -1 for long search
	LES	DI,[pFileName]		; ES:DI points to filename
	REPNE	SCASB			; scan for a 0
	NOT	CX			; length of string (including null)
	DEC	CX			; length without null
	MOV	[cbFileName],CX 	; store that length
	JMP	SHORT HaveLength
cBegin
	MOV	CX,[cbFileName]
	JCXZ	CalcLength
HaveLength:

ASSUMES DS,NOTHING

	LDS	SI,[pszSearchPath]	; DS:SI points to search path
SearchPathLoop:
	PUSH	CS
	POP	ES
	MOV	DI,OFFSET LOADRTM:SpecBuffer ; ES:DI points to buffer
CopyPathToBuf:
	XOR	CX,CX			; initialize count of bytes moved
CopyLoop:
	LODSB				; get next byte
	OR	AL,AL			; done with list?
	JE	CopyEnd 		; yes

	CMP	AL,';'			; is it path separator?
	JE	CopyDone		; yes, copy is done
	STOSB				; put the byte in the buffer
	INC	CX			; count this byte
	XCHG	AH,AL			; save stored byte in AH
	JMP	SHORT CopyLoop

CopyEnd:
	XOR	DX,DX			; if CX=0, we want to jump with DX=0
	JCXZ	OpenError		; ran out of paths, file not found
	DEC	SI			; point to null terminator

CopyDone:
	JCXZ	CopyPathToBuf		; skip null path, go get next one
	MOV	AL,'\'
	CMP	AH,AL			; was last char backslash?
	JE	AppendFileName		; yes, don't add another
	CMP	AH,'/'			; was last char forward slash?
	JE	AppendFileName		; yes, don't add backslash
	CMP	AH,':'			; was last char from drive spec?
	JE	AppendFileName		; yes, don't add backslash
	STOSB				; append a backslash to pathname

AppendFileName:
	PUSH	DS
	PUSH	SI			; save pointer to next pathname in list
	LDS	SI,[pFileName]		; DS:SI points to filename
	MOV	CX,[cbFileName] 	; CX = length of filename
	REP	MOVSB			; append filename to pathname
	XCHG	AX,CX			; AX = zero
	STOSB				; null terminate the filename
	PUSH	ES
	POP	DS			; DS = LOADRTM
	CALL	OpenFile		; attempt to open the file
	MOV	DI,DS			; save DS in DI in case open worked
	POP	SI
	POP	DS			; get back pointer to next path in list
	JNC	FoundIt 		; found it, stop looking
	XOR	DX,DX			; DX=0 in case we go to OpenError
	CMP	[off_pszSearchPath],OFFSET LOADRTM:SpecBuffer 
	JNE	SearchPathLoop		; brif input path not in SpecBuffer
	MOV	AX,CS			; can't use CS for CMP
	CMP	[seg_pszSearchPath],AX	
	JNE	SearchPathLoop		; brif input path not in SpecBuffer

;	If we fall through to here, [pszSearchPath] was really pointing to a
;	single-directory path which had been placed in SpecBuffer.  Now that
;	we have changed SpecBuffer, we can't loop back up.  But we don't have
;	to because we have already checked the single directory and not found
;	the file.  So we just exit with "Not Found".

	JMP	SHORT OpenError 	

; DI:DX = pointer to pathspec that worked
; AX = file handle returned by open
FoundIt:				
	XCHG	AX,BX			; put handle in BX
	CALL	CloseFile		; close the file

DbAssertFlags	nc,LOADRTM,<B$SearchOnePath: error on close>

OpenError:
	XCHG	AX,DX
	MOV	DX,DI			; DX:AX = ptr to filespec that worked,
					; or AX = 0 if got here via OpenError
cEnd

;****
;B$SearchEnv - search the environment table
;
;Purpose:
;	Searches the environment table for the specified variable.
;	If found, return a pointer to the value associated with the
;	variable.  Otherwise return 0.
;
; Note: we can make no assumptions about the value of DS on input.
;
;Input:
;	pEnvVar 	far pointer to environment variable name
;	cbEnvVar	length of EnvVar
;
;Output:
;	if EnvVar found in environment table
;	    DX:AX = ptr to value associated with the variable
;	else
;	    AX = 0
;
;****
cProc	B$SearchEnv,<NEAR>,<DS,DI,SI>
parmD	pEnvVar
parmW	cbEnvVar
cBegin
	MOV	ES,SS:[__psp]	; ProgramPSP doesn't get set up for LQB
	MOV	ES,ES:[2Ch]	   ;...get segment of environment table
	XOR	AX,AX		;zero AX for scan test and zero test
	XOR	DI,DI		;ES:DI = ptr to start of environment table

SearchEnvLoop:
	LDS	SI,[pEnvVar]	;DS:SI = ptr to string to search for
	MOV	CX,[cbEnvVar]	;CX = length of string to search for
	REP	CMPSB
	JE	SearchEnvFound	;brif found a match
TryAgain:
	MOV	CX,0FFFFh	;search for a long time
	REPNZ	SCASB		;scan to past next zero byte
	CMP	ES:[DI],AL	;test for double zero for end of table
	JNZ	SearchEnvLoop	;brif not end of table

; Got to end of table without finding a match.	Return zero.

	JMP	SHORT SearchEnvExit

SearchEnvFound:
	CMP	BYTE PTR ES:[DI],'=' ;did we match the whole name or just part?
	JNE	TryAgain	;brif partial match, not good enough
	INC	DI		;bump pointer past equal sign to value
	MOV	DX,ES
	MOV	AX,DI		;DX:AX = pointer to value
SearchEnvExit:

cEnd

sEnd	LOADRTM

;	The data below is used when the QBI interpreter is reloaded
;	after a compile dialog.  The values are used prior to fixup, to
;	determine what the Fixup boundaries of the reloaded code should
;	be.
sBegin	LOADRTMEND			;end of Resident loader

QBVersion DW	BINSAV_BASICVersion	;QB version
QBRevision DB	BINSAV_REVISION_BYTE	;QB revision number
QBCode	DW	SEG LOADRTMEND		;start of code that gets reloaded
QBData	DW	DGROUP			;start of DGROUP for QB
sEnd	LOADRTMEND			

	CondEnd	StartupStub		; END StartupStub if NOT EI_QB

⌨️ 快捷键说明

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