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

📄 process.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 3 页
字号:
	loop	reloc_i30

	xchg	ax,di			; restore fixup to DI
	pop	bx			; recover handle
	pop	ax			; recover # left to do
	test	ax,ax
	 jnz	reloc_image		; keep going until all done
	ret
	
;READFILE
;
;	This function reads in the load image of the file into memory
;	(Paragraph DI) the size of the load image is calculated using
;	the EXE_SIZE and EXE_FINAL fields enough memory exists at DI
;	to load the image. The valid .EXE header has been moved to 
;	exe_buffer.
;
;	Read in a Binary Image .COM or .EXE
;	entry:	bx -> handle
;		di = load segment
;	
;	exit:	bx, si, di Preserved
;		cf = 1, ax = Error Code if load fails
;
MAX_READPARA	equ	3200		; Maximum Number of Paragraphs to 
					; read in one command 50Kb
readfile:
	push si ! push di
	mov	si,offset exe_buffer	; Get the .EXE header
	mov	dx,EXE_HEADER[si]	; get the header size in paragraphs
	mov	cx,4			; and seek to that offset in the
	rol	dx,cl			; file before reading any data
	mov	cl,dl
	and cx,0Fh ! and dx,not 0Fh
	mov	ax,(MS_X_LSEEK*256)+0
	call	dos_entry		; Execute LSEEK Function
	jc	rf_error
	call	image_size		; Get the Load Image Sizes in Paras
	mov	si,dx			; Returned in DX save in SI
rf_10:
	mov	es,di			; Set the Buffer address
	sub	dx,dx			; es:dx -> load segment

	cmp	si,MAX_READPARA		 ; Can we read the rest of the file
	jbe	rf_20		 	 ; in one command jif YES
	sub	si,MAX_READPARA		 ; Decrement the Image Size
	mov	cx,MAX_READPARA * 16	 ; Number of bytes to read
	add	di,MAX_READPARA		 ; Number of Paragraphs Read
	mov	ah,MS_X_READ		 ; Read the Block into the
	call	dos_entry		 ; buffer Exit if Error
	jc	rf_error
	jmps	rf_10			 ; Else go for the next bit

rf_20:					; Now reading the last part of
	mov	cl,4			; the image so convert remainder
	shl	si,cl			; in SI to bytes and Read File
	mov	cx,si
	mov	ah,MS_X_READ		; Read data into the buffer
	call	dos_entry
	jc	rf_error		; Stop on Error
	xor	ax,ax			; Reset the carry Flag and Zero AX
rf_error:				; Error exit Carry Flag Set and AX
	pop di ! pop si			; contains the error code.
	ret

;	Copy old PSP contents to new PSP.
;	Parameter block supplied by user contains command line
;	and default FCB's - copy these into the load_psp.
;	save:	bx -> Handle
pblk_to_psp:
	push	ds			; Save the PcMode Data Segment
	push	bx			; and file handle
	mov	dx,load_psp
	call	point_param_block	; ES:DI -> users parameter block

	push es ! push di
	lds	si,es:dword ptr 2[di]	; Get the Source Pointer
	mov	cx,128			; Copy the complete command line
	mov	di,offset PSP_COMLEN	; because BASCOM places a segment value
	mov	es,dx			; after the CR which was not previously
	rep	movsb			; copied.
	pop di ! pop es

	lds	si,es:dword ptr 6[di]	; get 1st FCB address
	mov	ax,offset PSP_FCB1	; First FCB Offset
	call	copy_fcb		; copy FCB
	lds	si,es:dword ptr 10[di]	; Get the Source Pointer
	mov	ax,offset PSP_FCB2	; Second FCB Offset
	call	copy_fcb		; copy FCB
	pop	bx			; file handle back again
	pop	ds			; Restore PcMode Data Segment
	ret

copy_fcb:
;--------
; On Entry:
;	DS:SI -> source
;	DX:AX -> destination
; On Exit:
;	None
;	ES:DI, DX preserved
;
	push	es
	push	di
	mov	es,dx
	xchg	ax,di			; ES:DI -> destination
	mov	cx,12			; Copy Drive, Name and Extension
	rep	movsb			;  and copy it
	xchg	ax,cx			; AX = 0
	stosw ! stosw			; zero last 4 bytes
	pop	di
	pop	es
	ret



;	Set up a new psp for the child
;
set_up_psp:
	mov	ax,load_psp		; Change the ownership of the
	mov	bx,load_env		; Environment and Load Memory
	call	set_owner		; partitions.
	mov	ax,load_psp
	mov	bx,ax
	call	set_owner
	
	cmp	current_psp,1		; Is This the ROOT DOS process
	jnz	setup_psp10		; No! Continue as Normal

	mov	ax,load_psp		; Force the LOAD_PSP to
	mov	current_psp,ax		; to be the current PSP

	mov	es,ax			; Now Zero Fill the New PSP
	mov	cx,(offset PSP_FCB1)/2	;  up to user supplied parameters
	xor ax,ax ! mov di,ax
	rep	stosw
	jmps	setup_psp20		; and skip the INT22 Fudge

setup_psp10:				; Get the Function return address
	xor di,di ! mov es,di		;  and force into INT 22
	mov	di,INT22_OFFSET		; Set Interrupt Vectors 22
	push	ds
	lds	si,int21regs_ptr
	lea	si,reg_IP[si]		; DS:SI -> callers IP
	movsw				; Save User IP
	movsw				; Save User CS
	pop	ds
setup_psp20:
	mov	dx,load_psp		; Get the new PSP address
	mov	si,load_top		; Get the last paragraph allocated
	mov	cx,(offset PSP_FCB1)/2	; Copy PSP up to user supplied bits
;
;	CREATE_PSP is a local function called by the DOS EXEC function (4B)
;	to create a new PSP and initialize it as a new process. 
;
;	The PSP_MEMORY field was original calculated as the highest memory
;	location that could be allocated to a process. However this caused
;	Carbon Copy Plus to Fail so the routine now uses the LOAD_TOP
;	value calculated by the CALC_PSP function. This is the last
;	paragraph allocated to the current PSP.
;
	call	create_psp		; Create the New Process
	mov	ax,load_env		; Now Update the Environment
	mov	PSP_ENVIRON,ax
	mov	si,offset load_file	; Copy the process name into the DMD
;	jmp	SetPspNameAndVersion

SetPspNameAndVersion:
;---------------------
; On Entry:
;	ES = PSP
;	DS:SI -> pathaname (nb. DS need not be dos data seg!)
; On Exit:
;	None
;
	mov	bx,es
	dec	bx
	mov	es,bx			; ES points at DMD (We Hope)
	call	check_dmd_id		; Check for a valid DMD
	 jc	SetPspNameAndVersion10	; bail out now if none
if DOS5
	inc	bx			; BX -> PSP again
	push	bx			; keep it on the stack
endif
	call	FindName		; DS:SI -> start of name
	push	si
	call	SetName			; update the name field
	pop	si
if DOS5
	call	GetVersion		; AX = version to return
	pop	es			; ES = PSP
	mov	PSP_VERSION,ax		; set version number
endif
SetPspNameAndVersion10:
	ret

FindName:
;--------
; On Entry:
;	DS:SI -> pathname of file
; On Exit:
;	DS:SI -> final leaf name of file
;	CX = length of leaf name
;
	mov	cx,si			; remember start of leaf
FindName10:
	lodsb
	cmp	al,' '			; end of the name ?
	 jbe	FindName30
	call	dbcs_lead		; is it a double byte pair ?
	 jne	FindName20
	lodsb				; include the second byte
	jmps	FindName10
FindName20:
	cmp	al,'\'			; is it a seperator ?
	 je	FindName
	cmp	al,'/'
	 je	FindName
	jmps	FindName10
FindName30:
	xchg	cx,si			; SI -> start of leaf name
	sub	cx,si
	dec	cx			; CX = length
	ret


SetName:
;-------
; On Entry:
;	DS:SI -> leaf name to update
;	ES = DMD to update
; On Exit:
;	CX preserved
;
	mov	di,offset DMD_NAME	; point at the owners name field
SetName10:
	lodsb
	cmp	al,' '			; end of the name ?
	 jbe	SetName30
	call	dbcs_lead		; is it a double byte pair ?
	 jne	SetName20
	stosb				; copy 1st byte of pair
	cmp	di,(offset DMD_NAME)+DMD_NAME_LEN
	 jae	SetName30		; don't overflow if name too long
	movsb				; and the second
	jmps	SetName10

SetName20:
	stosb
	cmp	al,'.'			; discard all following '.'
	 je	SetName30
	cmp	di,(offset DMD_NAME)+DMD_NAME_LEN
	 jb	SetName10		; don't overflow if name too long
	ret

SetName30:
	dec	di
	xor	ax,ax
SetName40:
	stosb				; zero the '.'
	cmp	di,(offset DMD_NAME)+DMD_NAME_LEN
	 jb	SetName40		; zero the rest of the name
	ret

if DOS5
GetVersion:
;----------
; On Entry:
;	DS:SI -> start of name
;	CX = length
; On Exit:
;	AX = dos version to return
;
	les	di,ss:setverPtr
	mov	ax,es
	or	ax,di			; check for a setver list
	 jnz	GetVersion30
GetVersion10:
	mov	ax,ss:dos_version	; better use default version
	ret

GetVersion20:
	mov	al,es:0FFFFh[di]	; skip the name
	cbw
	inc ax ! inc ax			; skip the version
	add	di,ax			; try the next entry
GetVersion30:
	mov	al,es:byte ptr [di]	; get length field
	test	al,al			; end of the list ?
	 jz	GetVersion10

	inc	di			; point at potential name
	cmp	al,cl			; do the lengths match ?
	 jne	GetVersion20
	xor	bx,bx			; start scan with 1st character
GetVersion40:
	mov	ax,ds:[bx+si]		; get a character from filename
	call	dbcs_lead		; is it a DBCS character ?
	 jne	GetVersion50
	inc	bx			; we will skip 2 characters
	cmp	ax,es:[bx+di]		; do both character match ?
	jmps	GetVersion60

GetVersion50:
	call	toupper			; upper case it
	mov	ah,al			; save it
	mov	al,es:[bx+di]		; get a character from setver list
	call	toupper			; upper case it
	cmp	al,ah			; do we match ?
GetVersion60:
	 jne	GetVersion20		; no, try next name in list
	inc	bx			; we match, have we done them all ?
	cmp	bx,cx			; check against length
	 jb	GetVersion40
	mov	ax,es:[bx+di]		; get version number from setver list
	ret
endif

eject
;
;	GET_DATA reads the EXE header using the handle passed in BX
;

get_execdata:
; On Entry:
;	BX = handle
;	ES:SI = buffer
; On Exit:
;	CY set if error, AX = error code
;	BX/SI preserved

	mov	ah,MS_X_READ
	mov	cx,EXE_LENGTH		; read the exe header
	mov	dx,si			; ES:DX -> buffer
	call	dos_entry		; try and read the data
	 jc	gd_exit			; Error Exit
	mov	EXE_FINAL[si],0200h	; Force value to Full Page
	call	check_exe		; all done if it's an .EXE
	 jnc	gd_exit
	mov	ax,(MS_X_LSEEK*256)+2	; it's a .COM
	xor	cx,cx			; seek to end of file
	xor	dx,dx
	call	dos_entry		; get file length in DX:AX
	 jc	gd_exit
	xchg al,ah ! mov ah,dl		; DX:AX / 512
	shr dx,1 ! rcr ax,1
	inc	ax			; Handle Final Partial Page
	mov	EXE_SIZE[si],ax		; No. of 512 Byte Pages
	xor	ax,ax
	mov	EXE_HEADER[si],ax	; Load Image starts a 0000
	mov	EXE_RELCNT[si],ax	; No Relocation Items
	dec	ax			; Force Maximum Memory Allocation
	mov	EXE_MAXPARA[si],ax	;  to the .COM
	mov	EXE_MINPARA[si],0010h	; give it at least an extra 100h
					; bytes for the Default Stack
gd_exit:
	ret

eject
;
;	Determine if the file to be loaded is a DOS EXE format file
;	if YES then return with the carry flag reset. Assume that the
;	header has already been read into EXE_HEADER
;
	public	check_exe
check_exe:
	cmp	EXE_SIGNATURE[si],'ZM'	; look for exe signature
	 jz	check_e10
	cmp	EXE_SIGNATURE[si],'MZ'	; look for exe signature
	 jz	check_e10
	stc 				; flag the error
check_e10:
	ret

;
;	IMAGE_SIZE assumes SI points to a valid EXE header and from this
;	it calculates the size of the load image and returns this value
;	in paragraphs in DX. AX and CX are corrupted.
;
	Public	image_size
image_size:
	mov	dx,EXE_SIZE[si]		; No of 512 pages in System Image
	dec	dx			; Adjust for Final Partial Page
	mov cl,5 ! shl dx,cl		; No. 512 Byte Blocks to Para
	sub	dx,EXE_HEADER[si]	; Remove the Header Size	

	mov 	ax,EXE_FINAL[si]
	add	ax,15
	dec cl ! shr ax,cl		; AX is Partial Block in PARA
	add	dx,ax			; DX is Image Size in PARA's
	ret

mem_alloc:
	mov	ah,MS_M_ALLOC			; call DOS to allocate
	jmp	dos_entry			; some memory

mem_setblock:
	mov	ah,MS_M_SETBLOCK		; call DOS to ajust
	jmp	dos_entry			; a memory block

conditional_mem_free:
; On Entry:
;	CX = para to free
;	    (0 = none to free)
; On Exit:
;	None
;
	 jcxz	cmem_free10			; only free up allocated
	push	ds				;  memory
	mov	ds,cx
	mov	ah,MS_M_FREE			; free up a memory block
	call	dos_entry
	pop	ds 
cmem_free10:
	ret

point_param_block:
;-----------------
; On Entry:
;	None
; On Exit:
;	CL = subfunction number (callers AL)
;	ES:DI -> parameter block (callers ES:BX)
;	AX corrupted
;
	les	di,int21regs_ptr	; point at callers registers
	mov	cl,es:reg_AL[di]	; CL = subfunction# (range-checked)
	mov	ax,es:reg_BX[di]
	mov	es,es:reg_ES[di]	; callers ES:BX -> parameter block
	xchg	ax,di			; ES:DI -> parameter block
	ret

	
		
PCMODE_DATA	DSEG	WORD
	extrn	current_dsk:byte
	extrn	current_psp:word
	extrn	retcode:word		; Complete return code passed to F4B
	extrn	user_retcode:byte	; User retcode set by funcs 4C and 31
	extrn	system_retcode:byte	; System retcode returns the cause of
	extrn	switch_char:byte
	extrn	mem_strategy:byte	; memory allocation strategy
	extrn	int21AX:word		; Int 21's AX
	extrn	indos_flag:byte
	extrn	int21regs_ptr:dword
	extrn	int21regs_off:word
	extrn	int21regs_seg:word
	extrn	prev_int21regs_off:word
	extrn	prev_int21regs_seg:word
	extrn	error_flag:byte
	extrn	exe_buffer:word
	extrn	valid_flg:byte
	extrn	retry_off:word
	extrn	retry_sp:word
	extrn	last_drv:byte
	extrn	exec_stub:dword
	extrn	func4B05_stub:dword

if DOS5
	extrn	dos_version:word
	extrn	setverPtr:dword
endif

eject
;	To improve Network performance the EXE relocation items are
;	now read into the following buffer. All the data items contained
;	between RELOC_BUF and RELOC_SIZE are destroyed by the LOADIMAGE
;	sub-routine when it relocates a DOS .EXE file.
;
;	Only variables which are unused after the LOADIMAGE function can
;	be placed in this buffer.
;
;	******** Start of .EXE Relocation Buffer ******** 
;

; We can re-use the MSNET pathname buffers during an EXEC

	extrn	reloc_buf:byte
	extrn	load_file:byte
	extrn	RELOC_CNT:abs

;
;	******** End of .EXE Relocation Buffer ******** 
;

	extrn	exit_type:byte
	extrn	term_psp:word
	extrn	load_handle:word
	extrn	load_env:word			; Paragraph of the new environment
	extrn	load_envsize:word		; Size of new environment
	extrn	load_psp:word			; Paragraph of the new PSP.
	extrn	load_image:word			; Paragraph of the Load Image.
	extrn	load_top:word			; Last paragraph of Allocated Memory
	extrn	load_max:word			; ditto, but not messed with
	extrn	exe_loadhigh:byte		; load high flag

	end

⌨️ 快捷键说明

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