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

📄 msspawn.asm

📁 dos 6.0 源代码 .对大家提高有一定的帮助。
💻 ASM
📖 第 1 页 / 共 3 页
字号:
swinxms_main:
	mov	ax,lmem lcurrdesc.swsize ; size in paragraphs
	mov	cl,4
	rol	ax,cl			; size in bytes + high nibble
	mov	dx,ax
	and	ax,0fff0h		; low word
	and	dx,0000fh		; high word
	mov	lmem lxmsctl.lenlo,ax	; into control block
	mov	lmem lxmsctl.lenhi,dx
	mov	ax,lmem lcurrdesc.swoffset	; swap offset
	mov	lmem lxmsctl.destlo,ax 		; into control block
	mov	ax,lmem lcurrdesc.addr		; segment to swap
	mov	lmem lxmsctl.desthi,ax
	mov	si,lxmsctl
	mov	ah,0bh
	call	lmem lprep.xmm		; move it
	or	ax,ax
	jz	swinxms_error
	mov	ax,lmem lxmsctl.lenlo	; adjust source addr
	add	lmem lxmsctl.srclo,ax
	mov	ax,lmem lxmsctl.lenhi
	adc	lmem lxmsctl.srchi,ax
;
	cmp	lmem lcurrdesc.num_follow,0	; another MCB?
	je	swinxms_complete
;
	mov	lmem lxmsctl.lenlo,TYPE mcbdesc
	mov	lmem lxmsctl.lenhi,0
	mov	lmem lxmsctl.desthi,ds
	mov	lmem lxmsctl.destlo,lcurrdesc
	mov	si,lxmsctl
	mov	ah,0bh
	call	lmem lprep.xmm		; move it
	or	ax,ax
	jz	swinxms_error
	add	lmem lxmsctl.srclo,16	; one paragraph
	adc	lmem lxmsctl.srchi,0
;
	call	lmem cgetmcb
	jc	swinxms_error
	jmp	swinxms_main
;
swinxms_complete:
	mov	ah,0ah			; release XMS frame
	mov	dx,lmem lprep.handle   	; XMS handle
	call	lmem lprep.xmm
	ret
;
swinxms_error:
	mov	ah,0ah			; release XMS frame on error
	call	lmem lprep.xmm
	mov	ax,4c00h
	int	21h
;
swapin_xms	endp
;
swinxms_length	= offset $ - offset swapin_xms
;
;
;	swapin_file:	swap in from file.
;
swapin_file	proc	far
;
	mov	dx,lprep.swapfilename
	mov	ax,3d00h			; open file
	int	21h
	jc	swinfile_error2
	mov	bx,ax				; file handle
;
swinfile_main:
	push	ds
	mov	cx,lmem lcurrdesc.swsize	; size in paragraphs
	mov	dx,lmem lcurrdesc.swoffset	; swap offset
	mov	ds,lmem lcurrdesc.addr		; segment to swap
;
swinfile_loop:
	mov	ax,cx
	cmp	ah,8h			; above 32k?
	jbe	swinfile_ok		; go read if not
	mov	ax,800h			; else read 32k
;
swinfile_ok:
	sub	cx,ax			; remaining length
	push	cx			; save it
	push	ax			; and save paras to read
	mov	cl,4
	shl	ax,cl			; convert to bytes
	mov	cx,ax
	mov	ah,3fh			; read
	int	21h
	jc	swinfile_error
	cmp	ax,cx
	jne	swinfile_error
	pop	cx			; paras read
	mov	ax,ds
	add	ax,cx			; bump up dest segment
	mov	ds,ax
	pop	cx			; remaining length
	or	cx,cx			; anything left?
	jnz	swinfile_loop		; go loop if yes
;
	pop	ds
	cmp	lmem lcurrdesc.num_follow,0	; another MCB?
	je	swinfile_complete	; ready if not
	mov	cx,16			; read one paragraph
	mov	dx,lcurrdesc
	mov	ah,3fh
	int	21h
	jc	swinfile_error1
	cmp	ax,cx
	jne	swinfile_error1
;
	push	bx
	call	lmem cgetmcb
	pop	bx
	jc	swinfile_error1
	jmp	swinfile_main
;
;
swinfile_complete:
	mov	ah,3eh			; close file
	int	21h
	mov	dx,lprep.swapfilename
	mov	ah,41h			; delete file
	int	21h
	ret
;
swinfile_error:
	pop	cx
	pop	cx
	pop	ds
swinfile_error1:
	mov	ah,3eh			; close file
	int	21h
swinfile_error2:
	mov	dx,lprep.swapfilename
	mov	ah,41h			; delete file
	int	21h
	mov	ax,4cffh
	int	21h
;
swapin_file	endp
;
swinfile_length	= offset $ - offset swapin_file
;
;
;	swapin_none:	no swap, return immediately.
;
swapin_none	proc	far
;
	ret
;
swapin_none	endp
;
;
	IF	swinems_length GT swinxms_length
swcodelen	=	swinems_length
	ELSE
swcodelen	=	swinxms_length
	ENDIF
	IF	swinfile_length GT swcodelen
swcodelen	=	swinfile_length
	ENDIF
;
swap_codelen	=	((swcodelen + 1) / 2) * 2
;
codelen		=	base_length + swap_codelen
reslen		=	codebeg + codelen
keep_paras	=	(reslen + 15) shr 4	; paragraphs to keep
swapbeg		=	keep_paras shl 4	; start of swap space
savespace	=	swapbeg - 5ch	; length of overwritten area
;
;--------------------------------------------------------------------
;
	.data?
;
;
;	Space for saving the part of the memory image below the
;	swap area that is overwritten by our code.
;
save_dat	db	savespace dup(?)
;
;	Variables used while swapping out.
;	The "prep" structure is initialized by prep_swap.
;
prep		prep_block	<>
nextmcb		mcbdesc		<>
currdesc	mcbdesc		<>
xmsctl		xms_control	<>
ems_curpage	dw		?	; current EMS page number
ems_curoff	dw		?	; current EMS offset (paragraph)
;
;--------------------------------------------------------------------
;       
	.code
;
;	swapout_ems:	swap out an MCB block to EMS.
;
;	Entry:	"currdesc" 	contains description of block to swap
;		"nextmcb"	contains MCB-descriptor of next block
;				if currdesc.num_follow is nonzero
;
;	Exit:	0 if OK, != 0 if error, Zero-flag set accordingly.
;
;	Uses:	All regs excpt DS
;
swapout_ems	proc	near
;
	push	ds
	mov	cx,currdesc.swsize	; block length in paras
	mov	si,currdesc.swoffset	; swap offset
	mov	dx,prep.handle		; EMS handle
	mov	bx,ems_curpage		; current EMS page
	mov	di,ems_curoff		; current EMS page offset (paras)
	mov	es,prep.ems_pageframe	; page frame address
	mov	ds,currdesc.addr	; segment to swap
;
	mov	ax,ems_parasize		; max length
	sub	ax,di			; minus current offset
	jnz	swems_ok		; go copy if there's room
;
swems_loop:
	mov	ax,4400h		; map in next page
	int	EMM_INT
	or	ah,ah
	jnz	swems_error
	mov	di,0			; reset offset
	inc	bx			; bump up page number
	mov	ax,ems_parasize		; max length to copy
;
swems_ok:
	cmp	ax,cx			; length to copy
	jbe	swems_doit		; go do it if <= total length
	mov	ax,cx			; else use total length
;
swems_doit:
	sub	cx,ax			; subtract copy length from total
	push	cx			; and save
	push	ax			; save the copy length in paras
	push	si
	push	di
	mov	cl,3
	shl	ax,cl			; convert to number of words (!)
	inc	cl
	shl	di,cl			; convert to byte address
	mov	cx,ax
	rep movsw
	pop	di
	pop	si
	pop	cx			; copy length in paras
	mov	ax,ds
	add	ax,cx			; add copy length to source segment
	add	di,cx			; and EMS page offset
	mov	ds,ax
	pop	cx			; remaining length
	or	cx,cx			; did we copy everything?
	jnz	swems_loop		; go loop if not
;
	pop	ds
	cmp	currdesc.num_follow,0	; another MCB?
	je	swems_complete		; exit if not
;
;	Another MCB follows, append nextmcb to save block.
;
	cmp	di,ems_parasize
	jb	swems_nonewpage		; no new block needed
	mov	ax,4400h		; map page, phys = 0
	int	EMM_INT
	or	ah,ah
	jnz	swems_error1
	mov	di,0
	inc	bx
;
swems_nonewpage:
	push	di
	mov	cl,4
	shl	di,cl			; convert to byte address
	mov	cx,TYPE mcbdesc
	mov	si,offset nextmcb
	rep movsb
	pop	di
	inc	di			; one paragraph
;
swems_complete:
	mov	ems_curpage,bx
	mov	ems_curoff,di
	xor	ax,ax
	ret
;
swems_error:
	pop	ds
swems_error1:
	mov	ah,45h			; release EMS pages on error
	int	EMM_INT
	mov	ax,RC_SWAPERROR
	or	ax,ax
	ret
;
swapout_ems	endp
;
;
;	swapout_xms:	swap out an MCB block to XMS.
;
;	Entry:	"currdesc" 	contains description of block to swap
;		"nextmcb"	contains MCB-descriptor of next block
;				if currdesc.num_follow is nonzero
;
;	Exit:	0 if OK, -1 if error, Zero-flag set accordingly.
;
;	Uses:	All regs excpt DS
;
swapout_xms	proc	near
;
	mov	ax,currdesc.swsize	; size in paragraphs
	mov	cl,4
	rol	ax,cl			; size in bytes + high nibble
	mov	dx,ax
	and	ax,0fff0h		; low word
	and	dx,0000fh		; high word
	mov	xmsctl.lenlo,ax		; into control block
	mov	xmsctl.lenhi,dx
	mov	xmsctl.srchnd,0		; source is normal memory
	mov	ax,currdesc.swoffset	; swap offset
	mov	xmsctl.srclo,ax		; into control block
	mov	ax,currdesc.addr	; segment to swap
	mov	xmsctl.srchi,ax
	mov	ax,prep.handle		; XMS handle
	mov	xmsctl.desthnd,ax
	mov	si,offset xmsctl
	mov	ah,0bh
	call	prep.xmm		; move it
	or	ax,ax
	jz	swxms_error
	mov	ax,xmsctl.lenlo		; adjust destination addr
	add	xmsctl.destlo,ax
	mov	ax,xmsctl.lenhi
	adc	xmsctl.desthi,ax
;
	cmp	currdesc.num_follow,0	; another MCB?
	je	swxms_complete
;
	mov	xmsctl.lenlo,TYPE mcbdesc
	mov	xmsctl.lenhi,0
	mov	xmsctl.srchi,ds
	mov	xmsctl.srclo,offset nextmcb
	mov	si,offset xmsctl
	mov	ah,0bh
	call	prep.xmm		; move it
	or	ax,ax
	jz	swxms_error
	add	xmsctl.destlo,16	; one paragraph
	adc	xmsctl.desthi,0
;
swxms_complete:
	xor	ax,ax
	ret
;
swxms_error:
	mov	ah,0ah			; release XMS frame on error
	mov	dx,prep.handle		; XMS handle
	call	prep.xmm
	mov	ax,RC_SWAPERROR
	or	ax,ax
	ret
;
swapout_xms	endp
;
;
;	swapout_file:	swap out an MCB block to file.
;
;	Entry:	"currdesc" 	contains description of block to swap
;		"nextmcb"	contains MCB-descriptor of next block
;				if currdesc.num_follow is nonzero
;
;	Exit:	0 if OK, -1 if error, Zero-flag set accordingly.
;
;	Uses:	All regs excpt DS
;
swapout_file	proc	near
;
	push	ds
	mov	cx,currdesc.swsize	; size in paragraphs
	mov	bx,prep.handle		; file handle
	mov	dx,currdesc.swoffset	; swap offset
	mov	ds,currdesc.addr	; segment to swap
;
swfile_loop:
	mov	ax,cx
	cmp	ah,8h			; above 32k?
	jbe	swfile_ok		; go write if not
	mov	ax,800h			; else write 32k
;
swfile_ok:
	sub	cx,ax			; remaining length
	push	cx			; save it
	push	ax			; and save paras to write
	mov	cl,4
	shl	ax,cl			; convert to bytes
	mov	cx,ax
	mov	ah,40h			; write
	int	21h
	jc	swfile_error
	cmp	ax,cx
	jne	swfile_error
	pop	cx			; paras written
	mov	ax,ds
	add	ax,cx			; bump up source segment
	mov	ds,ax
	pop	cx			; remaining length
	or	cx,cx			; anything left?
	jnz	swfile_loop		; go loop if yes
;
	pop	ds
	cmp	currdesc.num_follow,0	; another MCB?
	je	swfile_complete		; ready if not
	mov	cx,16			; write one paragraph
	mov	dx,offset nextmcb
	mov	ah,40h
	int	21h
	jc	swfile_error1
	cmp	ax,cx
	jne	swfile_error1
;
swfile_complete:
	xor	ax,ax
	ret
;
swfile_error:
	pop	cx
	pop	cx
	pop	ds
swfile_error1:
	mov	ah,3eh			; close file
	int	21h
	mov	dx,offset prep.swapfilename
	mov	ah,41h			; delete file
	int	21h
	mov	ax,RC_SWAPERROR
	or	ax,ax
	ret
;
swapout_file	endp
;
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;
;
do_spawn	PROC	uses si di,swapping: word, execfname:ptr byte,params:ptr byte,envlen:word,envp:ptr byte
	local	datseg,pspseg,currmcb
;
	mov	datseg,ds		; save default DS
;
	mov	bx,_psp
	mov	pspseg,bx
;
;
;	Check if spawn is too low in memory
;
	mov	ax,cs
	mov	dx,offset lowcode_begin
	mov	cl,4
	shr	dx,cl
	add	ax,dx			; normalized start of this code
	mov	dx,keep_paras		; the end of the modified area
	add	dx,bx			; plus PSP = end paragraph
	cmp	ax,dx
	ja	doswap_ok	; ok if start of code > end of low mem
	mov	ax,RC_TOOLOW
	ret
;
doswap_ok:
	cmp	swapping,0
	jle	method_ok
;
;	check the swap method, to make sure prep_swap has been called
;
	mov	al,prep.swapmethod
	cmp	al,USE_EMS
	je	method_ok
	cmp	al,USE_XMS
	je	method_ok
	cmp	al,USE_FILE
	je	method_ok
	mov	ax,RC_BADPREP
	ret
;
;	Save the memory below the swap space.
;	We must do this before swapping, so the saved memory is
;	in the swapped out image.
;	Anything else we'd want to save on the stack or anywhere
;	else in "normal" memory also has to be saved here, any
;	modifications done to memory after the swap will be lost.
;
;	Note that the memory save is done even when not swapping,
;	because we use some of the variables in low core for
;	simplicity.
;
method_ok:
	push	ds
	pop	es
	push	ds
	mov	ds,pspseg		; DS points to PSP
	mov	si,5ch
	mov	di,offset save_dat
	mov	cx,savespace / 2	; NOTE: savespace is always even
	rep movsw
	pop	ds
;
	mov	ax,swapping
	cmp	ax,0
	jg	begin_swap
;
;	not swapping, prep_swap wasn't called. Init those variables in
;  	the 'prep' block we need in any case.
;
	mov	prep.swapmethod,al
	je	no_reduce
;
	mov	ax,pspseg
	dec	ax
	mov	prep.psp_mcb,ax
	mov	prep.first_mcb,ax
	inc	ax
	mov	es,ax
	mov	bx,es:psp_envptr
	mov	prep.env_mcb,bx
	mov	prep.noswap_mcb,0
	cmp	envlen,0
	jne	swp_can_swap_env
	mov	prep.noswap_mcb,bx
;
swp_can_swap_env:
	xor	bx,bx
	mov	es,bx
	mov	ah,52h			; get list of lists
	int	21h
	mov	ax,es
	or	ax,bx
	jz	no_reduce
	mov	es,es:[bx-2]		; first MCB
	cmp	es:id,4dh		; normal ID?
	jne	no_reduce
	mov	prep.first_mcb,es
;
no_reduce:
	jmp	no_swap1
;
;	set up first block descriptor
;
begin_swap:
	mov	ax,prep.first_mcb
	mov	currmcb,ax
	mov	es,prep.psp_mcb		; let ES point to base MCB
	mov	ax,es:paras
	mov	currdesc.msize,ax
	sub	ax,keep_paras
	mov	currdesc.swsize,ax
	mov	currdesc.addr,es
	mov	currdesc.swoffset,swapbeg + 16
;		NOTE: swapbeg is 1 para higher when seen from MCB
	mov	ax,prep.total_mcbs
	mov	currdesc.num_follow,ax
;
;	init other vars
;
	mov	xmsctl.destlo,0
	mov	xmsctl.desthi,0
	mov	ems_curpage,0
	mov	ems_curoff,ems_parasize
;
;	Do the swapping. Each MCB block (except the last) has an 
;	"mcbdesc" structure appended that gives location and size 
;	of the next MCB.
;
swapout_main:
	cmp	currdesc.num_follow,0	; next block?
	je	swapout_no_next		; ok if not
;
;	There is another MCB block to be saved. So we don't have
;	to do two calls to the save routine with complicated
;	parameters, we set up the next MCB descriptor beforehand.
;	Walk the MCB chain starting at the current MCB to find
;	the next one belonging to this process.
;
	mov	ax,currmcb
	mov	bx,pspseg
	mov	cx,prep.psp_mcb
	mov	dx,prep.noswap_mcb
;
swm_mcb_walk:
	mov	es,ax
	cmp	ax,cx
	je	swm_next_mcb
	cmp	ax,dx
	je	swm_next_mcb
;
	cmp	bx,es:owner		; our process?
	je	swm_mcb_found		; found it if yes
;
swm_next_mcb:
	cmp	es:id,4dh		; normal block?
	jne	swm_mcb_error		; error if end of chain
	add	ax,es:paras		; start + length
	inc	ax			; next MCB
	jmp	swm_mcb_walk
;
;	MCB found, set up an mcbdesc in the "nextmcb" structure
;
swm_mcb_found:
	mov	nextmcb.addr,es
	mov	ax,es:paras		; get number of paragraphs
	mov	nextmcb.msize,ax	; and save
	inc	ax
	mov	nextmcb.swsize,ax
	mov	bx,es
	add	bx,ax
	mov	currmcb,bx
	mov	nextmcb.swoffset,0
	mov	ax,currdesc.num_follow
	dec	ax
	mov	nextmcb.num_follow,ax
;
swapout_no_next:
	cmp	prep.swapmethod,USE_EMS
	je	swm_ems
	cmp	prep.swapmethod,USE_XMS
	je	swm_xms
	call	swapout_file
	jmp	short swm_next
;
swm_ems:
	call	swapout_ems
	jmp	short swm_next
;
swm_xms:
	call	swapout_xms
;
swm_next:
	jnz	swapout_error
	cmp	currdesc.num_follow,0
	je	swapout_complete
;
;	next MCB exists, copy the "nextmcb" descriptor into
;	currdesc, and loop.
;
	mov	es,datseg
	mov	si,offset nextmcb
	mov	di,offset currdesc
	mov	cx,TYPE mcbdesc
	rep movsb
	jmp	swapout_main
;
;
swm_mcb_error:
	cmp	prep.swapmethod,USE_FILE
	je	swm_mcberr_file
	cmp	prep.swapmethod,USE_EMS
	je	swm_mcberr_ems
;
	mov	ah,0ah			; release XMS frame on error
	mov	dx,prep.handle		; XMS handle
	call	prep.xmm
	mov	ax,RC_MCBERROR
	jmp	short swapout_error
;
swm_mcberr_ems:

⌨️ 快捷键说明

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