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

📄 cwswapr.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov	ax,0ffffh
	stosb
	mov	cx,7
	rep stosw
;
;
;	Handle Redirection
;
	IF	REDIRECT
	mov	es,pspseg
	mov	di,lstdinsav
	mov	ax,-1
	stosw
	stosw
	stosw
	mov	di,lstdinsav
	xor	cx,cx
	IF	ptrsize
	lds	si,stdin
	mov	ax,ds
	or	ax,si
	ELSE
	mov	si,stdin
	mov	ds,datseg
	or	si,si
	ENDIF
	call	@redirect
	jc	failed_redir
	inc	cx
	IF	ptrsize
	lds	si,stdout
	mov	ax,ds
	or	ax,si
	ELSE
	mov	si,stdout
	or	si,si
	ENDIF
	call	@redirect
	jc	failed_redir
	inc	cx
	IF	ptrsize
	lds	si,stderr
	mov	ax,ds
	or	ax,si
	ELSE
	mov	si,stderr
	or	si,si
	ENDIF
	call	@redirect
	jnc	redir_complete
;
failed_redir:
	push	ax
;
;	restore handle table and pointer
;
	mov	ds,pspseg
	mov	si,lstdinsav
	xor	cx,cx
;
redirclose:
	lodsw
	cmp	ax,-1
	je	redclosenext
	mov	bx,ax
	mov	ah,46h
	int	21h
;
redclosenext:
	inc	cx
	cmp	cx,3
	jb	redirclose
;
	mov	ds,pspseg
	mov	es,pspseg
	mov	si,lhandlesave
	mov	di,psp_handletab
	mov	cx,10
	rep movsw
	mov	di,psp_handlenum
	movsw
	movsw
	movsw
;
;	Restore overwritten part of program
;
	mov	ds,datseg
	mov	es,pspseg
	mov	si,offset save_dat
	mov	di,5ch
	mov	cx,savespace
	rep movsb
;
	pop	ax
	mov	ah,RC_REDIRFAIL SHR 8
	jmp	swapout_kill
;
redir_complete:
	mov	ds,pspseg
	mov	es,pspseg
	mov	si,psp_handletab+5
	mov	di,lredirsav
	mov	cx,3
	rep movsw
	mov	di,psp_handletab+5
	mov	cx,3
	mov	ax,0ffffh
	rep stosw
	ENDIF
;
;	Prepare exec parameter block
;
	mov	ax,es
	mov	es:expar.fcb1seg,ax
	mov	es:expar.fcb2seg,ax
	mov	es:expar.pparseg,ax
	mov	es:expar.envseg,0
;
;	The 'zero' word is located at 80h in the PSP, the start of
;	the command line. So as not to confuse MCB walking programs,
;	a command line length of zero is inserted here.
;
	mov	es:zero,0d00h		; 00h,0dh = empty command line
;
;	Init default fcb's by parsing parameter string
;
;	IF	ptrsize
;	lds	si,params
;	ELSE
	mov	si,OFFSET params
	mov	ds,datseg
;	ENDIF
	push	si
	mov	di,xfcb1
	mov	es:expar.fcb1,di
	push	di
	mov	cx,16
	xor	ax,ax
	rep stosw			; init both fcb's to 0
	pop	di
	mov	ax,2901h
	int	21h
	mov	di,xfcb2
	mov	es:expar.fcb2,di
	mov	ax,2901h
	int	21h
	pop	si
;
;	move command tail string into low core
;
	mov	di,progpars
	mov	es:expar.ppar,di
	xor	cx,cx
	inc	di
cmdcpy:
	lodsb
	or	al,al
	jz	cmdcpy_end
	stosb
	inc	cx
	jmp	cmdcpy
;
cmdcpy_end:
	mov	al,0dh
	stosb
	mov	es:progpars,cl
;
;	move filename string into low core
;
;	IF	ptrsize
;	lds	si,execfname
;	ELSE
	mov	si,OFFSET execfname
;	ENDIF
	mov	di,filename
fncpy:
	lodsb
	stosb
	or	al,al
	jnz	fncpy
;
;	Setup environment copy
;
	mov	bx,keep_paras		; paras to keep

;	xor	bx,bx

COMMENT !
	mov	cx,envlen		; environment size
	jcxz	no_environ		; go jump if no environment

	cmp	swapping,0
	jne	do_envcopy
;
;	Not swapping, use the environment pointer directly.
;	Note that the environment copy must be paragraph aligned.
;
	IF	ptrsize
	mov	ax,word ptr (envp)+2
	mov	bx,word ptr (envp)
	ELSE
	mov	ax,ds
	mov	bx,envp
	ENDIF
	add	bx,15			; make sure it's paragraph aligned
	mov	cl,4
	shr	bx,cl			; and convert to segment addr
	add	ax,bx
	mov	es:expar.envseg,ax	; new environment segment
	xor	cx,cx			; mark no copy
	xor	bx,bx			; and no shrink
	jmp	short no_environ
;
;	Swapping or EXECing without return. Set up the pointers for
;	an environment copy (we can't do the copy yet, it might overwrite
;	this code).
;
do_envcopy:
	inc	cx
	shr	cx,1			; words to copy
	mov	ax,cx			; convert envsize to paras
	add	ax,7
	shr	ax,1
	shr	ax,1
	shr	ax,1
	add	bx,ax			; add envsize to paras to keep
	IF	ptrsize
	lds	si,envp
	ELSE
	mov	si,envp
	ENDIF
;
	mov	ax,es			; low core segment
	add	ax,keep_paras		; plus fixed paras
	mov	es:expar.envseg,ax	; = new environment segment
END COMMENT !
;
;	Save stack regs, switch to local stack
;
no_environ:
	mov	es:save_ss,ss
	mov	es:save_sp,sp
	mov	ax,es
	cli
	mov	ss,ax
	mov	sp,mystack
	sti
;
;	push	cx			; save env length
;	push	si			; save env pointer
	push	ds			; save env segment
;
;	save and patch INT0 (division by zero) vector
;
	xor	ax,ax
	mov	ds,ax
	mov	ax,word ptr ds:0
	mov	es:div0_off,ax
	mov	ax,word ptr ds:2
	mov	es:div0_seg,ax
	mov	word ptr ds:0,codebeg + iretoff
	mov	word ptr ds:2,es
;
	pop	ds			; pop environment segment
;	pop	si			; pop environment offset
;	pop	cx			; pop environment length
	mov	di,swapbeg		; environment destination
;
;	Push return address on local stack
;
	push	cs			; push return segment
	mov	ax,offset exec_cont
	push	ax			; push return offset
	mov	es:spx,sp		; save stack pointer
;
;	Goto low core code
;
	push	es			; push entry segment
    mov	ax,codebeg + doexec_entry
    push	ax			; push entry offset
	retf
;
;----------------------------------------------------------------
;
;	Low core code will return to this location, with DS set to
;	the PSP segment.
;
exec_cont:
	push	ds
	pop	es
	cli
	mov	ss,ds:save_ss		; reload stack
	mov	sp,ds:save_sp
	sti
;
;	restore handle table and pointer
;
	mov	si,lhandlesave
	mov	di,psp_handletab
	mov	cx,10
	rep movsw
	mov	di,psp_handlenum
	movsw
	movsw
	movsw
;
;	restore INT0 (division by zero) vector
;
	xor	cx,cx
	mov	ds,cx
	mov	cx,es:div0_off
	mov	word ptr ds:0,cx
	mov	cx,es:div0_seg
	mov	word ptr ds:2,cx
;
	mov	ds,datseg
;
;
	mov	ax,es:eretcode
	mov	bx,es:retflags
;
;	Restore overwritten part of program
;
	mov	si,offset save_dat
	mov	di,5ch
	mov	cx,savespace
	rep movsb
;

;	int	3

	test	bx,1			; carry set?
	jnz	exec_fault		; return EXEC error code if fault
	mov	ah,4dh			; else get program return code
	int	21h
	xor	ah,ah			; zap high value
	ret
;
exec_fault:
	mov	ax,SWAPPERERROR
;	mov	ah,3			; return error as 03xx
	ret
;
do_spawn	ENDP
;
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;
emm_name	db	'EMMXXXX0'
;
;	prep_swap - prepare for swapping.
;
;	This routine checks all parameters necessary for swapping,
;	and attempts to set up the swap-out area in EMS/XMS, or on file.
;	In detail:
;
;	     1) Check whether the do_spawn routine is located
;		too low in memory, so it would get overwritten.
;		If this is true, return an error code (-2).
;
;	     2) Walk the memory control block chain, adding up the
;		paragraphs in all blocks assigned to this process.
;
;	     3) Check EMS (if the method parameter allows EMS):
;		- is an EMS driver installed?
;		- are sufficient EMS pages available?
;		if all goes well, the EMS pages are allocated, and the
;		routine returns success (1).
;
;	     4) Check XMS (if the method parameter allows XMS):
;		- is an XMS driver installed?
;		- is a sufficient XMS block available?
;		if all goes well, the XMS block is allocated, and the
;		routine returns success (2).
;
;	     5) Check file swap (if the method parameter allows it):
;		- try to create the file
;		- pre-allocate the file space needed by seeking to the end
;		  and writing a byte.
;		If the file can be written, the routine returns success (4).
;
;	     6) Return an error code (-1).
;
		pmethod	DW	?

;prep_swap	PROC	uses si di,pmethod:word,swapfname:ptr byte
prep_swap	PROC	FAR

	LOCAL	totparas: word
;
;
	mov	ax,fs		; ax -> wedge segment
	dec	ax
	cmp	DPMIFlag,0	; see if using DPMI
	jne	isdpmi
	dec	ax			; CauseWay uses 1 para for its own purposes, compute MCB

isdpmi:
	mov	swap_prep.noswap2_mcb,ax	; don't swap out wedge segment

	mov	ax,PSP
	mov	es,ax		; es -> PSP
	mov	ax,es:[36h]	; es -> file handle table segment
	dec	ax
	cmp	DPMIFlag,0	; see if using DPMI
	jne	isdpmi2
	dec	ax			; CauseWay uses 1 para for its own purposes, compute MCB

isdpmi2:
	mov	swap_prep.noswap3_mcb,ax	; don't swap out file handle table segment

	mov	ax,PSP
	dec	ax
	mov	swap_prep.psp_mcb,ax
	mov	swap_prep.first_mcb,ax	; init first MCB to PSP
;
;	Make a copy of the environment pointer in the PSP
;
	inc	ax
	mov	es,ax
	mov	bx,es:psp_envptr
	dec	bx
	mov	swap_prep.env_mcb,bx
;	mov	swap_prep.noswap_mcb,0
;	test	pmethod,DONT_SWAP_ENV
;	jz	can_swap_env
	mov	swap_prep.noswap_mcb,bx
;
can_swap_env:
;
;	Check if spawn is too low in memory
;
	mov	bx,cs
	mov	dx,offset lowcode_begin
	mov	cl,4
	shr	dx,cl
	add	bx,dx			; normalized start of this code
	mov	dx,keep_paras		; the end of the modified area
	add	dx,ax			; plus PSP = end paragraph
	cmp	bx,dx
	ja	prepswap_ok	; ok if start of code > end of low mem
	mov	ax,-2
	mov	swap_prep.swapmethod,al
	ret
;
;	Walk the chain of memory blocks, adding up the paragraphs
;	in all blocks belonging to this process.
;	We try to find the first MCB by getting DOS's "list of lists",
;	and fetching the word at offset -2 of the returned address.
;	If this fails, we use our PSP as the starting point.
;
prepswap_ok:
	xor	bx,bx
	mov	es,bx
	mov	ah,52h			; get list of lists
	int	21h
	mov	ax,es
	or	ax,bx
	jz	prep_no_first
	mov	es,es:[bx-2]		; first MCB
	cmp	es:id,4dh		; normal ID?
	jne	prep_no_first
	mov	swap_prep.first_mcb,es
;
prep_no_first:
	mov	es,swap_prep.psp_mcb	; ES points to base MCB
	mov	cx,es			; save this value
	mov	bx,es:owner		; the current process
	mov	dx,es:paras		; memory size in the base block
	sub	dx,keep_paras		; minus resident paragraphs
	mov	si,0			; number of MCBs except base
	mov	di,swap_prep.noswap_mcb
	mov	bp,swap_prep.noswap2_mcb
	mov	ax,swap_prep.first_mcb
	mov	swap_prep.first_mcb,0
;
prep_mcb_walk:
	mov	es,ax
	cmp	ax,cx			; base block?
	jbe	prep_walk_next		; then don't count again
	cmp	ax,di			; Non-swap MCB?
	je	prep_walk_next		; then don't count
	cmp	ax,bp			; Non-swap MCB?
	je	prep_walk_next		; then don't count
	cmp	ax,swap_prep.noswap3_mcb	; non-swap MCB
	je	prep_walk_next		; then don't count

;
	cmp	bx,es:owner		; our process?
	jne	prep_walk_next		; next if not
	inc	si
	mov	ax,es:paras		; else get number of paragraphs
	add	ax,2			; + 1 for descriptor + 1 for MCB
	add	dx,ax			; total number of paras
	cmp	swap_prep.first_mcb,0
	jne	prep_walk_next
	mov	swap_prep.first_mcb,es
;
prep_walk_next:
	cmp	es:id,4dh		; normal block?
	jne	prep_mcb_ready		; ready if end of chain
	mov	ax,es
	add	ax,es:paras		; start + length
	inc	ax			; next MCB
	jmp	prep_mcb_walk
;
prep_mcb_ready:
	mov	totparas,dx
	mov	swap_prep.total_mcbs,si
;
;
	test	pmethod,XMS_FIRST
	jnz	check_xms
;
;	Check for EMS swap
;
check_ems:
	test	pmethod,USE_EMS
	jz	prep_no_ems
;
	push	ds
	mov	al,EMM_INT
	mov	ah,35h
	int	21h			; get EMM int vector
	mov	ax,cs
	mov	ds,ax
	mov	si,offset emm_name
	mov	di,10
	mov	cx,8
	repz cmpsb			; EMM name present?
	pop	ds
	jnz	prep_no_ems
;
	mov	ah,40h			; get EMS status
	int	EMM_INT
	or	ah,ah			; EMS ok?
	jnz	prep_no_ems
;
	mov	ah,46h			; get EMS version
	int	EMM_INT
	or	ah,ah			; AH must be 0
	jnz	prep_no_ems
;
	cmp	al,30h			; >= version 3.0?
	jb	prep_no_ems
;
	mov	ah,41h			; Get page frame address
	int	EMM_INT
	or	ah,ah
	jnz	prep_no_ems
;
;	EMS present, try to allocate pages
;
	mov	swap_prep.ems_pageframe,bx
	mov	bx,totparas
	add	bx,ems_paramask
	mov	cl,ems_shift
	shr	bx,cl
	mov	ah,43h			; allocate handle and pages
	int	EMM_INT
	or	ah,ah			; success?
	jnz	prep_no_ems
;
;	EMS pages allocated, swap to EMS
;
	mov	swap_prep.handle,dx
	mov	ax,USE_EMS
	mov	swap_prep.swapmethod,al
	ret
;
;	No EMS allowed, or EMS not present/full. Try XMS.
;
prep_no_ems:
	test	pmethod,XMS_FIRST
	jnz	check_file		; don't try again
;
check_xms:
	test	pmethod,USE_XMS
	jz	prep_no_xms
;
	mov	ax,4300h		; check if XMM driver present
	int	2fh
	cmp	al,80h			; is XMM installed?
	jne	prep_no_xms
	mov	ax,4310h		; get XMM entrypoint
	int	2fh
	mov	word ptr swap_prep.xmm,bx	; save entry address
	mov	word ptr swap_prep.xmm+2,es
;
	mov	dx,totparas
	add	dx,xms_paramask		; round to nearest multiple of 1k
	mov	cl,xms_shift
	shr	dx,cl			; convert to k
	mov	ah,9			; allocate extended memory block
	call	swap_prep.xmm
	or	ax,ax
	jz	prep_no_xms
;
;	XMS block allocated, swap to XMS

⌨️ 快捷键说明

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