📄 krun2.asm
字号:
TOGGLE EQU 1 ; degine the toggle
;*
;* COW : Character Oriented Windows
;*
;* krun2.asm : Alternate Run/Exec (for shell)
;* *KLUDGE* included by "krun.asm" if EXEC_ALTERNATE.
.xlist
include togequ.inc
.list
;*****************************************************************************
MovSeg MACRO srDest, srSrc
push srSrc
pop srDest
ENDM
;*****************************************************************************
sBegin DATA
externW <psLom>
externW <pGlobalHeap>
externB <fShellPresent> ;* from kerninit.asm
externB <fCompactLowerHeap> ;* from gcompact.asm
externB fToggle ; Flag indicating toggle state
IFNDEF NOPCODE
externW fNew ;* from interpreter
ENDIF ;!NOPCODE
sEnd DATA
;*****************************************************************************
IFDEF DEBPUB
PUBLIC FzGetEnv, ShrinkGlobalHeap, RestoreGlobalHeap
ENDIF ;DEBPUB
sBegin KERNEL
assumes DS,KERNEL
;* * data that MUST be in code space
staticW ssSave, ? ;* save SS
staticW spSave, ? ;* save SP
externW MgrSP ;* Manager Stack pointer
sEnd KERNEL
;*****************************************************************************
externFPublic <AccessSwapFile> ;* for closing
externFPublic <PromptSwapDisk> ;* from App or stub.
IFDEF DEBUG
externFPublic <PrintGlobalHeap> ;* Print contents of heap
ENDIF ;DEBUG
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
;*****************************************************************************
;********** RerrExecProg **********
;* entry : szCmd = program name (or NULL => shell)
;* bCmdTail = Command Tail.
;* (see kmem.h).
;* * NOTE : it is the application's responsibility to ShrinkLocalHeap()
;* all used local heaps.
;
; M003 - Only three arg pointers now passed.
; execl (szName, szArgs, szTokArg1, szTokArg2)
;
cProc RerrExecProg,<FAR,PUBLIC>,<SI, DI>
parmDP szName
parmDP bCmdTail
cBegin RerrExecProg
;
; * First lets Leave Cow and shrink the global Heap
cCall LeaveCow, <sp> ;* leave + clear screen
cCall ShrinkGlobalHeap, <sp> ;* Make sure we discard everything
PUSH DS ; M004 - ES must be equal to DS for
POP ES ; M004 - STOS's and system calls
mov ax,4b00h ; setup command tail
xor cx,cx ; zero out
MOV DX,szName ; Get command name.
MOV BX,bCmdTail ; Have command tail
CLC
IFDEF TOGGLE
cmp fToggle,FT_LOCKED ; If toggle entries are allowed during
jne EXint ; execs but they are locked out now,
cli ; set fToggle to allow them during
mov fToggle,FT_NOTTOGGLED ; this exec. Only save SP when toggle
mov MgrSP,sp ; entries are allowed.
ENDIF ;TOGGLE
EXint: INT 21h
IFDEF TOGGLE
push ax ; Now if toggle entries were allowed
lahf ; during the exec, lock them out
cmp fToggle,FT_NOTTOGGLED ; again because the exec has finished.
jne EXcln
mov fToggle,FT_LOCKED ; ***> HACK ALERT <***
EXcln: ; The CF flag must be saved and restored
sahf ; around the fToggle setting so that
pop ax ; the success of the exec can be
sti ; determined. This can't be done with
; pushf/popf because of a 286 chip bug
; so lahf/sahf were used instead.
; Gee - this is the 1st time I ever
; used those instructions!
ENDIF ;TOGGLE
JC ExecErr
mov ah, 4dh ;Get the child return code.
int 21h ;to return to the caller.
jmp ExecvDone
ExecErr:
MOV AX,-1
ExecvDone:
;* * restore everything (and repaint screen)
push ax ;* save return value
cCall RestoreGlobalHeap
pop ax ;* return value
;* * now return to the caller.
cEnd RerrExecProg
;********** ShrinkGlobalHeap **********
;* entry : n/a
;* * shrink the global heap
;* exit : n/a
;* * NOTE : this code must be fixed since it throws everything out.
cProc ShrinkGlobalHeap, <PUBLIC, NEAR, ATOMIC>, <SI, DI>
parmW fDiscardCode
cBegin ShrinkGlobalHeap
assumes DS,DGROUP
;* * compact the heap (removing any free gaps) -- throw out code as well
push ds
mov es,pGlobalHeap
xor di,di
mov cx,fDiscardCode
jcxz NoDiscard ;* We dont need to discard
mov ax,1 ;* 1 reserved para
;* NOTE : kludge to get all code
;* discarded !!!
xchg ax,es:[di].gi_reserve ;* get old reserve
push ax
mov ax,-1
cCall GlobalCompact,<ax, ax> ;* (-1) throw everything out
mov es,pGlobalHeap
pop es:[di].gi_reserve ;* restore reserve size
;* * now lets try to compact everything to the lower heap including
NoDiscard:
;* * fixed code blocks.
mov fCompactLowerHeap,1 ;* turn on special mode
mov ax,-1 ;* It does not mater what number
cCall GlobalCompact,<ax, ax> ;* move everything down
;* * everything is as low as it can get, now we need to
;* * shrink memory allocations or release them if they are not needed
mov es,pGlobalHeap
mov fCompactLowerHeap,0 ;* Now turn it off
mov es,es:[di].hi_last ;* es => end sentinal
mov dx,es
;* * scan from end till finding free block
find_free_loop:
mov es,es:[di].ga_prev ;* next block
cmp es:[di].ga_sig, GA_HOLE ;* do we have a hole
jnz ffl_not_hole ;* No not a hole
mov dx,es ;* Save for now we have hole
jmp short find_free_loop ;* continue the search
ffl_not_hole:
mov cx,es:[di].ga_owner
jcxz found_free ;* 0 owner => free
mov ax,es
cmp ax,es:[di].ga_prev ;* previous pointer
jnz find_free_loop ;* -1 owner => MOB or sentinal (stop)
jmp end_shrink ;* No more to process
found_free:
;* * es:0 => free block, dx:0 => end sentinal
;* * see if special case, where previous is Hole and next is sentinal
;* * or hole, in which case we can get rid of allocation.
;;;; cmp es:[di].ga_next,dx ;* see if free space at end
;;;; jnz not_at_end ;* no?
mov ds,es:[di].ga_prev ;* see if special case
assumes ds,NOTHING
cmp ds:[di].ga_sig,GA_HOLE ;* See if we can purge the complet allocation
jnz part_is_used ;* part of allocation still used.
;*
;* * We have a memory allocation that can be freed to system
;* * first turn hole into endsigniture. (or hole)
;* * ds:0 => hole, es:0 => free; dx:0 =>end sentinal
mov es,dx ;* es:0 => End sentinal (or hole)
mov dx,ds:[di].ga_newpara ;* dx => now has the allocated paragraph
mov al,es:[di].ga_sig ;* get it signature
mov ds:[di].ga_sig,al ;* put it in the holes.
cmp ax,GA_HOLE ;* see if it was a hole
jnz no_hole_after_this_one ;* no, not hole
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -