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

📄 rtmload.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;Exit:
;	None.
;Uses:
;	AX, SI, DI, ES.
;Exceptions:
;	None.
;****


;***
; ULAdjustDXAX - back up far ptr in DX:AX by number of bytes in ULSquishSize
;
;Purpose:
;	Because of leading-zero compression in QLib files, the file pointers
;	need to be adjusted before calling LoadRtmBlock to load the Data
;	and Symbol segments.  The number of bytes compressed from the file
;	is in ULSquishSize.  This routine takes a far pointer in DX:AX and
;	backs it up ULSquishSize bytes. (Added with revision [38].)
;Entry:
;	DX:AX - far pointer to be adjusted
;	DS:[ULSquishSize] - number of bytes for adjustment
;	DS - LOADRTM
;Exit:
;	DX:AX - adjusted far pointer
;Uses:
;	None
;Exceptions:
;	None
;******************************************************************************


;***
; FixupRtmFile - apply fixups to RTM load  (RTM only)
;
;Purpose:
;	Read the fixup items from the RTM file and apply them
;	appropriately to the code and data section loaded into
;	memory.
;Entry:
;	BX - handle of opened RTM file
;	SI - zero to fixup both code and data (used in init)
;	     nonzero to fixup just code (used in SHELL)
;	BP - segment RTM is loaded in
;Exit:
;	None.
;Uses:
;	AX, CX, DX, DI, BP, ES.
;Exceptions:
;	DiskIOError if error during disk read of RTM file.
;******************************************************************************


;*** 
; FixupULFile - apply fixups to UL load  (UL only)
;
;Purpose:
;	Added as part of revision [10].
;	Read the fixup items from the UL file and apply them
;	appropriately to the code, data, and segment sections
;	loaded into memory.
;Entry:
;	BX - handle of opened RTM file
;	CX - symbol table fixup value (0 if already done).
;Exit:
;	None.
;Uses:
;	AX, CX, DX, SI, DI, BP, ES.
;Exceptions:
;	DiskIOError if error during disk read of RTM file.
;******************************************************************************




;*** 
; AppendExt - Append def extension to Filename in SpecBuffer if needed (UL Only)
;
;Purpose:
;	Added with revision [24].
;	Appends appropriate extension to the file in SpecBuffer if an extension
;	does not already exist.  If we are opening a user library, then .QLB
;	will be appended, otherwise .EXE is appended.
;
;	In addition to appending an extension to the file in SpecBuffer,
;	this routine will also save a copy of the basename and extension
;	in FNameBuff
;
;	If SpecBuffer contains a pathname without a filename (recognized by
;	the last char being a path char), then append the filename in FNameBuff
;	to the path in SpecBuffer.
;
;	No matter what the entry conditions, on exit from this routine the
;	following will be set up:
;	  FNameBuff has null-terminated filename part of filespec
;	  FNameBuffLen has length of what is in FNameBuff
;	  SpecBuffer has null-terminated filespec (ready for dos open)
;	  InputStrLen has length of what is in SpecBuffer
;
;Entry:
;	ES:DI = pointer in spec buffer after last byte of filespec.
;Exit:
;	ES:DI = pointer to first byte of filename part of filespec.
;		(if DI = OFFSET SpecBuffer, then there is no path specified)
;Uses:
;	AX, CX, DX, SI.
;Exceptions:
;	None.
;******************************************************************************


SearchChars	DB ':','/','\','.'      ;List of chars in order of search
cbSearchChars = $ - SearchChars 	;size of list

DbPub	AppendExt
cProc	AppendExt,<NEAR>
cBegin
	MOV	AX,DI			; In case buffer is empty
	CMP	DI,OFFSET SpecBuffer	; Is the buffer empty?
	JE	JE_NoFileName		; Yes, go special-case it

	MOV	CX,cbSearchChars	;get number of chars to search for
	MOV	SI,OFFSET SearchChars	;point to list
	XOR	DX,DX

;	Search for path chars, '/' and '\'.  Remember the address of
;	the last such char found.  Then search for an extension char
;	'.'.  If the address of this char is > than the address of the
;	last path char, then the filename had an extension.  This is
;	true since it is impossible to have a '.' after a path char
;	and not have it be part of a filename (eg it cannot be part
;	of a directory spec.


AppendSearchLoop:
	PUSH	CX			;save loop count
	PUSH	DI			;save end of file name
	MOV	CX,DI
	DEC	DI			;point to last char in name
	SUB	CX,OFFSET SpecBuffer	;compute char count in SpecBuffer
	LODSB				;[AL] = search char
	STD				;search backwards in file name
	REPNE	SCASB			;search backward for char
	CLD				;go forward again
	JNE	CharNotFound		;brif we did not find character
	INC	DI			;Set DI to char before last
CharNotFound:
	INC	DI			; REPNE SCASB subtracts 1 at end.
	XCHG	AX,DI			;save address of char/start of buffer

;NOTE:	Be careful here.  The results of the Next compare are used after
;	the loop is terminated. The current algorithm ensures that the
;	instructions used between this compare and the next branch after
;	the loop is terminated do not alter the carry and/or zero flag.


	CMP	AX,DX			;Is this char after prev char?
	JB	AppendSearchNext	;brif not
	XCHG	AX,DX			;remember address of char

AppendSearchNext:
	POP	DI			;recover end of filename
	POP	CX			;recover loop count
	LOOP	AppendSearchLoop	;continue until all chars searched for


;NOTE:	See NOTE above.

	JA	AppendExtExit		;brif already have the extension

; There are two conditions in which we do not have a filename:
;	 1.) An empty buffer, in which case we wont get here.
;	 2.) A path without a name, when DX = DI

	MOV	AX,DX			; Set AX = ptr to last path char
	CMP	DI,DX			; Check for no name specified
JE_NoFileName:
	JE	NoFileName		; None given, append the old one

;	File name needs an extension appended.	If we are loading a user lib,
;	then the extension is .QLB, otherwise, we must be loading an .EXE
;	file as the result of a QBC exec.  All of these files are .EXE
;	files.

	MOV	SI,EXEExt		;get ptr to .EXE extension
	CMP	fQBCExec,CL		;are we loading a user lib?
	JNZ	AddExt			;brif not - QBC exec loads .EXE files
	MOV	SI,QLBExt		;get ptr to .QLB extension for ulib

AddExt:
	MOVSW				; add 4-byte extension to file name
	MOVSW				

AppendExtExit:

DbAssertRel	CX,Z,0,LOADRTM,<AppendExt: trying to use CX for 0 and it's not>

	XCHG	CX,AX			; AL = zero, saving AX in CX
	STOSB				; null terminate the filename
	XCHG	CX,AX			; restore AX

; The starting point to copy is AX	=> SI
; The number of characters in the name is DI - AX => CX

	MOV	CX,DI			; Calculate Length of name
	SUB	CX,AX			;	without path
	CMP	CX,MaxFNameBuff 	; Are there too many characters
					;	in filename?
	JBE	ValidLength		; No, name is valid

;	There are a couple cases where we will have a double-null terminated
;	name here.  That could create a name 1 byte longer than ValidLength,
;	but it's not really a problem.  The release code will fall through
;	and cut back the length by 1, removing 1 null.	If there is a name
;	even longer than that, it's a bug.  Assert it.

DbAssertRel	CX,E,<MaxFNameBuff+1>,LOADRTM,<AppendExt: filename is too long>

	MOV	CX,MaxFNameBuff 	; Truncate name to max length
ValidLength:
	MOV	FNameBuffLen,CX 	; Save Length of FName
	MOV	SI,AX			; DS:SI points to begining of name
	MOV	DI,OFFSET FNameBuff	; ES:DI points to FNameBuff
	REP	MOVSB			; Copy the name only into FNameBuff
	MOV	DI,SI			; DI points 1 past end of filespec

;	Set InputStrLen = length of filespec in SpecBuffer

Return:
	SUB	DI,OFFSET LOADRTM:SpecBuffer ; DI = length of filespec
	XCHG	AX,DI			; DI = return value, AX = length
	MOV	[InputStrLen],AL	; Store the length

DbAssertRelB	AH,Z,0,LOADRTM,<AppendExt: filespec longer than 127 characters>

cEnd

NoFileName:
;	If we get here, SpecBuffer has a pathname (terminated with a path char)
;	but no filename.  If we already have a filename in FNameBuff, we'll
;	append it to the path in SpecBuffer

	MOV	CX,FNameBuffLen 	; length of name in FNameBuff
	MOV	SI,OFFSET LOADRTM:FNameBuff ; source pointer
	REP	MOVSB			; append the filename
	JMP	SHORT Return		; set return value and exit

;***
; OpenFile - Open the file specified in SpecBuffer.
;
;Purpose:
;	Added with revision [13].
;	Opens the filespec in SpecBuffer
;Entry:
;	SpecBuffer set up.
;Exit:
;	if open worked
;	    PSW.C reset
;	    AX = file handle
;	else
;	    PSW.C set
;	endif
;Uses:
;	Per convention.
;Exceptions:
;	Disk IO Error.
;******************************************************************************
cProc	OpenFile,<NEAR> 	;common routine to open file
cBegin				
	MOV	DX,OFFSET SpecBuffer ;DS:DX has pointer to file specification
OpenFile2:
	cmp	ss:fDebugScr,0		; brif not initialized and not
	jz	NoCheckDrive		; displaying QB's screen
	push	ds			; save LOADRTM segment

	mov	bx,dx			; put ptr into index register
	push	ds:[bx]			; OpenCheckDrive parm = first 2
					; of file spec (possible DRIVE:)

	push	ss			; DS = DGROUP for UI call
	pop	ds			
	call	OpenCheckDrive		; if required, switch DOS's logical
					; disk drive, and display message
					; "insert disk in drive X:"
					; PRESERVES ALL REGISTERS
	pop	ds			; restore register
NoCheckDrive:				
	MOV	AX,(C_OPEN SHL 8)+0  ;DOS function to open the file for input only
	INT	21H		;perform the open - carry set if failed
cEnd

;***
; CloseFile - Close the file handle in BX (RTM and UL)
;
;Purpose:
;	Added with revision [18].
;	Closes the file handle in BX.
;Entry:
;	BX - file handle to close.
;Exit:
;	None.
;Uses:
;	AX.
;Exceptions:
;	Disk IO Error.
;******************************************************************************

cProc	CloseFile,<NEAR>
cBegin
	MOV	AH,C_CLOSE
	INT	21H			;close the file
	JC	DiskError		;brif error
cEnd

DiskError:
	JMP	DiskIOError		;report the error and die.


assumes	DS,DGROUP


;***
; ULConsisCheck - performs consistency checks on user libs (UL only)
;
;Purpose:
;	Added as part of [10].
;	Does user library consistency checking.  Verifies correct
;	segment ordering and size of hole allocated in UL for
;	QB4 static data.
;Entry:
;	SI - size of QB4 static data
;Exit:
;	SI - offset of XIB in UL data
;	DI - offset of XIE in UL data
;	CX - offset of BC_SAB in UL data
;Uses:
;	AX, BX, DX
;Exceptions:
;	Consistency errors.
;****


;***
; ULCheckNextName - Verify that next segment is expected. (UL only)
;
;Purpose:
;	Added as part of [10].
;	Checks the next segment name in the symbol table and see
;	if it matches the expected segment name.  If not then
;	segments are out of order, and a consistency error is issued.
;Entry:
;	DX - points to expected segment name string descriptor
;	ES:BX - points to previous symbol table entry
;Exit:
;	DX - advanced to next sd in segment name list
;	ES:BX - advanced to next symbol table entry
;Uses:
;	CX, SI, DI
;Exceptions:
;	Consistency error if next segment isn't the expected segment.
;****


;***
; ULFindName - Finds a specified segment name in symbol table (UL Only)
;
;Purpose:
;	Added as part of revision [10].
;	Finds the specified segment name in the symbol table.
;	If the segment name is not found, a consistency error
;	is detected.
;Entry:
;	ES:BX - points to next symbol table entry
;	SI - points to segment name to search for
;	CX - count of characters in segment name
;Exit:
;	ES:BX - points to symbol table entry containing segment name
;Uses:
;	DI
;Exceptions:
;	Consistency error if name not found.
;****



;***
; ULFindNameBegin - Finds a specified segment name in symbol table (UL Only)
;
;Purpose:
;	Added as part of revision [10].
;	Finds the specified segment name in the symbol table.
;	This routine starts searching from beginning of symbol table
;	If the segment name is not found, a consistency error
;	is detected.
;Entry:
;	ES - symbol table segment
;	DX - points to sd of segment to search for
;Exit:
;	ES:BX - points to symbol table entry containing segment name
;	AX - offset of segment that was found from DS:0
;	DX - advanced to next sd in segment name list
;Uses:
;	CX, DI
;Exceptions:
;	Consistency error if name not found.
;****


;***
; ULNextName - Get ptr to next expected segment name. (UL only)
;
;Purpose:
;	Added as part of revision [10].
;	Get next segment name from list of segment name string
;	descriptors.  Set up a ptr to the actual name in SI
;	and the length of the name in CX.  Advance DX to point
;	to next sd in list.
;Entry:
;	DX - points to expected segment name string descriptor
;Exit:
;	SI - points to zero terminated segment name.

⌨️ 快捷键说明

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