📄 krun.asm
字号:
;*
;* 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 + -