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

📄 krun.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;*
;*	COW : Character Oriented Windows
;*
;*	krun.asm : Run/Exec

	TITLE	KRUN - Kernel RUN

	include	kernel.inc
	include	galloc.inc


ifdef	Exec_Alternate
	include	krun2.asm		;* REVIEW -- integrate better !!
else	; Use this file
	.xlist
	include pbi.inc
	.list

;----------------------------------------------------------------------------

MovSeg	MACRO	srDest, srSrc
	push	srSrc
	pop	srDest
ENDM

;----------------------------------------------------------------------------

sBegin	DATA

ifdef	Debug
externB	fCheckCwHeap
endif	; Debug

externW	psLom
externW	pGlobalHeap

externB	fShellPresent				;* from kerninit.asm

ifndef	NopCode
externW	 fNew				;* from interpreter
endif	; !NopCode

ifdef	WINDOWS_OLD_APP
externW	fWoaPresent
externW	psDosRealloc
endif	; WINDOWS_OLD_APP

sEnd	DATA

;----------------------------------------------------------------------------

IFDEF DEBPUB
	PUBLIC	FzGetEnv, ShrinkGlobalHeap, RestoreGlobalHeap
	PUBLIC	PromptMissingExec
ENDIF ;DEBPUB

IFDEF	WINDOWS_OLD_APP
externFP	<WoaToDos, WoaFromDos>
ENDIF	; WINDOWS_OLD_APP

;----------------------------------------------------------------------------

sBegin	KERNEL
    assumes DS,KERNEL


;*	* data that MUST be in code space

ifdef	QC_LINKER
globalD	ShlLinkSave,?			;* save SS:SP
else	; ! QC_LINKER
staticW	ssSave, ?			;* save SS
staticW	spSave, ?			;* save SP
endif	; QCLINKER


;*	* code strings
staticB	szComspec, <"COMSPEC=">		;* COMSPEC name
cchComspec	 EQU	$-szComspec

staticB	szCmdProg, <"\COMMAND.COM", 0>	;* if COMSPEC not found


sEnd	KERNEL

;----------------------------------------------------------------------------

externFPublic <AccessSwapFile>			;* for closing
externFPublic <PromptSwapDisk>			;* from App or stub.


;----------------------------------------------------------------------------

sBegin	KERNEL

    assumes CS,KERNEL
    assumes DS,DGROUP
    assumes SS,DATA
    assumes ES,NOTHING

;********** PromptMissingExec **********
;*	entry : lszPath = far pointer to path name
;*	* Prompt for a missing EXEC program
;*	* NOTE : this function must be in the EXIT module
;*	exit : n/a (trashes SI/DI)

cProc	PromptMissingExec, <FAR, ATOMIC>
    parmD lszPath
cBegin	PromptMissingExec
    assumes DS,DGROUP

;*	* assumes INIT module loaded (from call to BackToCow)
;*	* this routine gets loaded from the EXIT module

;*	* we will not swap from this point on (both INIT and EXIT resident)
;*	* we must close the swap file in order to use the Kernel buffer
	xor	ax,ax
	cCall	AccessSwapFile,<ax>

ifndef	NopCode
	push	fNew
endif	; !NopCode

	mov	es,psLom
	lds	si,lszPath
    assumes DS,NOTHING
	mov	di,es:[offRlbLom]		;* ES:DI => far kernel buffer
	push	es
	push	di				;* TOS = lszPath

@@:	lodsb
	stosb
	or	al,al
	jnz	@B

	MovSeg	ds,ss
    assumes DS,DGROUP

;*	* (TOS) = lszPath
	mov	ax,-1				;* special iexe for exec
	push	ax
	cCall	PromptSwapDisk			;* PromptSwapDisk(lszPath, -1);

	mov	ah,0DH
	int	21h				;* reset disk to try again
ifndef	NopCode
	pop	fNew				;* pcode may have changed fNew
endif	; !NopCode

cEnd	PromptMissingExec

sEnd	KERNEL

;----------------------------------------------------------------------------

sBegin	EXIT
    assumes CS,EXIT
    assumes DS,NOTHING
    assumes SS,DATA

;*	* NOTE :
;*	*  GetEnv is in EXIT segment since LeaveCow will be called first

;********** FzGetEnv **********
;*	entry : ES:DI => environment string to look for (with ending '=')
;*		CX = length of string
;*	* scan environment for Variable
;*	exit : Z => DS:SI => contents on ENV variable
;*	    else NZ=> not found
;*	* NOTE : uses AX/SI/DS
;*
cProc	FzGetEnv,<FAR, ATOMIC>
cBegin	FzGetEnv
	AssertNE	cx,0			; Would produce a "found".
	mov	ds,psLom
	mov	ds,ds:[pdbLom.PDB_environ]	;* psEnvironment
    assumes ds,nothing
	xor	si,si				;* ds:si => environment
	cld
getenv_lp:
	push	di
	push	cx
	repz	cmpsb
	pop	cx
	pop	di
	jz	getenv_end
getenv_skip:
	lodsb
	or	al,al
	jnz	getenv_skip
	cmp	byte ptr ds:[si],al	;* is this the real end ?
	jnz	getenv_lp
	or	cx,cx			;* NZ => not found
getenv_end:
cEnd	FzGetEnv
    assumes ds,nothing



sEnd	EXIT

;----------------------------------------------------------------------------

externFP	GlobalCompact
externFPublic	<LeaveCow, BackToCow>		;* in INIT

;----------------------------------------------------------------------------

sBegin	KERNEL
    assumes CS,KERNEL
    assumes DS,NOTHING
    assumes SS,DATA

externNP	<genter>			; GINTERF.ASM
externNP	<gjoin,gmarkfree,gcheckfree>	; GALLOC.ASM
externNP	<gnotify>		 	; GINTERF.ASM

;-----------------------------------------------

run_special_shell:		; It's up here to be within jcxz range.
	mov	ax,1801h			;* run shell
	int	2fh				;* al = return code
	xor	ah,ah
	jmp	done_run_shell

;********** RerrExec **********
;*	entry : szCmd = program name (or NULL => shell)
;*		pchParm = parameter string:
;*		   Byte-length prefixed, 0Dh terminated.
;*		   Null is invalid, use 01,"0Dh" for subshell.
;*		   Use <length> "/C xxxxx" when szCmd == NULL.
;*		rgchPrompt = "Press a key to resume MangoSoft$"; -1 if none.
;*		fClearScreen = whether to clear it or not.
;*		fRestoreScreenMode = whether to reset mode on way back in.
;*	* shrink memory / run subshell / restore memory
;*	exit : AX = 0 if ok, AX != 0 if error (interpreted as "rerr" code,
;*		(see kmem.h).
;*	       DX = return code of child process (undefined if AX != 0)

cPublic	RerrExec, <>, <DS, SI, DI>		;* NOT ATOMIC !
    parmDP  szCmd
    parmDP  pchParm
    parmDP  rgchPrompt				;* Dollar-sign terminated!
    parmW   fClearScreen
    parmW   fRestoreScreenMode
    localD  lszPath				;* far pointer to path
    localV  pbiT,<SIZE PBI>			;* parameter block
    localW  ChildCode
    localW  ExecCode
cBegin	RerrExec
    assumes DS,DGROUP

ifdef	Debug
	xor	ax,ax				; Set fCheckCWHeap to false,
	xchg	al,fCheckCWHeap			;   and push its old value.
	push	ax
endif	; Debug

;RetryRerrExec:
	AssertNE pchParm,0			;* NULL invalid

	MovSeg	es,cs
	mov	di,kernelOffset szComspec	;* ES:DI => string
	mov	cx,cchComspec
	cCall	FzGetEnv
    assumes DS,NOTHING
	jz	got_comspec			;* DS:SI => comspec

	MovSeg	ds,cs
	mov	si,kernelOffset szCmdProg ;* use COMMAND.COM
got_comspec:	;* ds:si => path/file for COMMAND shell

	mov	OFF_lszPath,si
	mov	SEG_lszPath,ds

	MovSeg	ds,ss
    assumes DS,DGROUP
	cCall	LeaveCow, <fClearScreen>	;* leave & maybe clear screen

	cCall	ShrinkGlobalHeap

	mov	di,pchParm			;* ss:di => string
;*	* lszPath => cmd, SS:DI => parm.

;*	* if szCmd != NULL then exec named program
	mov	cx,szCmd
	jcxz	exec_a_shell
	mov	OFF_lszPath,cx
	mov	SEG_lszPath,ss			;* szCmd
	jmp	short exec_command

exec_a_shell:  ;* (ch == 0)
;*	* if pchParm == "" then we can run a special shell if present
	mov	cl,fShellPresent		;* ch == 0.
	jcxz	exec_command
	mov	cl,ds:[di]			;* ds == ss, ch == 0.
ifdef	QC_LINKER
	jcxz	F@
	jmp	short exec_command
F@:	jmp	run_special_shell
else	; !QC_LINKER
	jcxz	run_special_shell
endif	; QC_LINKER

exec_command:
;*	* Exec a command (SS:DI => command line, lszPath => command).
;*	* set up PBI
	mov	es,psLom
	lea	bx,pbiT
	mov	ax,es:[pdbLom+PDB_environ]
	mov	[bx].psEnviron,ax
	mov	[bx].offCmdLine,di
	mov	[bx].psCmdLine,ss		;* command (on stack)
	mov	[bx].offFcb1,5CH
	mov	[bx].psFcb1,es
	mov	[bx].offFcb2,6CH
	mov	[bx].psFcb2,es

;*	* save the important part of the world
	push	ds
	push	bp
;*	* Save DWORD PTR SS:[2E] since DOS 2.0 has a bug which thinks that SS
;*	*  is pointing to a PSP (and hence stuffs the old stack at this address)
	push	word ptr ss:[2EH]
	push	word ptr ss:[30H]

ifdef	QC_LINKER
	mov	WORD PTR (ShlLinkSave+2),ss	;* Save SS
	mov	WORD PTR (ShlLinkSave),sp	;* Save SP
	sub	WORD PTR (ShlLinkSave),6	;* Add some slop
else	; !QC_LINKER
	mov	ssSave,ss
	mov	spSave,sp
endif	; QC_LINKER

	push	ss
	pop	es

	lds	dx,lszPath			;* command path

	mov	ax,4B00H			;* exec : load + execute
	int	21h

	jc	exec_error
	xor	ax,ax				;* no error
exec_error:

	cli
ifdef	QC_LINKER
	mov	ss, WORD PTR (ShlLinkSave+2)	;* Restore ss
	mov	sp, WORD PTR (ShlLInkSave)	;* Restore sp
	add	sp,6				;* Remove slop
else	; ! QC_LINKER
	mov	ss,ssSave
	mov	sp,spSave
endif	; QC_LINKER
	sti

	pop	word ptr ss:[30H]
	pop	word ptr ss:[2EH]		;* Dos 2.0 tromping restored
	pop	bp
	pop	ds
    assumes DS,DGROUP

	mov	ExecCode,ax			;* save the exec return code
	mov	ChildCode,0			;* init the child return code

	cmp	ax,2				;* If file not found, then
	je	done_run_shell			;*   don't bother with prompt
;	je	run_shell_not_found

	mov	dx,rgchPrompt			;* ds:dx -> "Press a key$"

	or	ax,ax				;* Don't get the child code
	jnz	CheckPrompt			;*   if Exec failed.

	mov	ah,4Dh
	int	21h
	mov	ChildCode,ax			;* save the child return code

ifndef	FOR_QC			;* This should be ifdef'ed for project
	cmp	ax,4				;* This is Word's special

⌨️ 快捷键说明

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