📄 krun.asm
字号:
je DoPrompt ;* "Do Prompt" return code.
endif ; !FOR_QC
CheckPrompt:
cmp dx,-1
je done_run_shell
DoPrompt:
mov ah,09h
int 21h ; Prompt to press any key
mov ax,0C07h
int 21h ; Wait for key input
done_run_shell:
;* * restore everything (and repaint screen)
cCall RestoreGlobalHeap
;* * the following call calls an INIT procedure
cCall BackToCow,<fRestoreScreenMode> ;* in INIT segment
ifdef Debug
pop ax ; Restore fCheckCWHeap to
mov fCheckCWHeap,al ; its old value.
endif ; Debug
mov ax,ExecCode ;* restore these for
mov dx,ChildCode ;* return values.
cEnd RerrExec
;* * special case if exec program is not found
;run_shell_not_found:
; cCall RestoreGlobalHeap
;;* * re-init CW for windowing
; cCall BackToCow ;* Load in INIT module
; cCall PromptMissingExec, <lszPath>
;
; jmp RetryRerrExec ;* retry
;-----------------------------------------------
;********** ShrinkGlobalHeap **********
;* entry : n/a
;* * shrink the global heap
;* exit : n/a
;* * NOTE : this code must be fixed since it throws everything out.
cProc ShrinkGlobalHeap, <NEAR, ATOMIC>, <DS, SI, DI>
cBegin ShrinkGlobalHeap
assumes DS,DGROUP
IFDEF WINDOWS_OLD_APP
;*
;* If win-old-app model is present then claim as much as
;* possible from it. It will also modify the address
;* which is to be used for reallocing the segment.
;*
cmp fWoaPresent,0
jz @F
cCall WoaToDos ;* Shut down win-old-app code
@@:
ENDIF ; WINDOWS_OLD_APP
;* * compact the heap (removing any free gaps) -- throw out code as well
mov es,pGlobalHeap
xor di,di
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
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
mov cx,es:[di].ga_owner
jcxz found_free ;* 0 owner => free
inc cx
jnz find_free_loop ;* -1 owner => MOB or sentinal (stop)
jmp end_shrink ;* can't shrink
found_free:
;* * es:0 => free block, dx:0 => end sentinal
cmp es:[di].ga_next,dx
je dont_move_bound
;* * move the bound segments from high to low memory
mov ds,es:[di].ga_next ;* 1 after block
assumes ds,NOTHING
mov dx,es:[di].ga_prev
move_bound_seg_loop:
;* ds:0 => source, es:0 => dest
;* dx = prev link
mov ds:[di].ga_prev,dx
mov dx,ds
mov cx,ds:[di].ga_next
sub cx,dx
mov ax,es
add ax,cx ;* ax = new dest
;* * move from source to dest (dest before source => move up)
xor si,si
shl cx,1
shl cx,1
shl cx,1 ;* cpara -> cw (<64K blocks)
rep movsw ;* move arena + data
xor di,di
;* * notify everyone
push ds
push es
push ax
mov al,GN_MOVE
mov bx,es:[di].ga_handle ;* handle
mov cx,es
inc cx ;* psNew
mov dx,es:[di].ga_owner ;* set up owner for gnotify
mov ds,pGlobalHeap
push cx ;* new address
push bx ;* handle
call gnotify ; Call global notify procedure
pop bx
pop ds:[bx].he_address
pop ax
pop es
pop ds
;* * update link to next
mov dx,es ;* next link
mov bx,ax
xchg ax,es:[di].ga_next
mov es,bx ;* next destination
mov ds,ax ;* next block
cmp ds:[di].ga_owner,-1 ;* stop at sentinal
jne move_bound_seg_loop
;* * ds:0 => end sentinal, es:0 => where sentinal should be
mov bx,es
mov ds,bx
mov ds:[di].ga_prev,dx ;* back link
jmp update_end_sentinal
dont_move_bound:
;* * at the end of the heap MUST be a free block of a reasonably
;* * large size (the free block due to freeing all code)
cCall genter ;* DS:DI => mob
assumes ds,NOTHING
mov es,ds:[di].hi_last ;* pointer to sentinal
mov cx,es ;* last block
mov bx,es:[di].ga_prev ;* must be a free block
mov ds,bx
cmp ds:[di].ga_owner,0
jne end_shrink
;* * es:di => free block that should be sentinal
mov es,cx ;* es:di =>old sentinal
ifdef Debug
;* * check out state of old sentinal
cmp es:[di].ga_sig,GA_ENDSIG
je ok_old_sent
bad_old_sent:
bad_new_sent:
int 3
ok_old_sent:
cmp es:[di].ga_owner,-1
jne bad_old_sent
cmp es:[di].ga_size,GA_ALIGN
jne bad_old_sent
cmp es:[di].ga_flags,0
jne bad_old_sent
;* * check new sentinal
cmp ds:[di].ga_sig,GA_SIGNATURE
jne bad_new_sent
endif ; Debug
update_end_sentinal: ; ds==bx == para address of end block
mov ds:[di].ga_sig,GA_ENDSIG
mov ds:[di].ga_owner,-1
mov ds:[di].ga_size,GA_ALIGN
mov ds:[di].ga_flags,0
mov ds:[di].ga_next,ds ;* link to self
cCall genter ;* DS:DI => mob
mov ds:[di].hi_last,bx ;* now the last block
dec ds:[di].hi_count ;* remove free object
;* * now free up anything to DOS
IFDEF WINDOWS_OLD_APP
mov ax,psDosRealloc
ELSE ; !WINDOWS_OLD_APP
mov ax,psLom ;* 1 big block
ENDIF ; WINDOWS_OLD_APP
mov es,ax
sub bx,ax ;* size of new block (in para)
add bx,1+cparaRunShell ;* add slush (+1 to keep end sentinal)
mov ah,4ah ;* modify allocated memory
int 21h
;* * resume with smaller global heap
end_shrink:
cEnd ShrinkGlobalHeap
;-----------------------------------------------
;********** RestoreGlobalHeap **********
;* entry : n/a
;* * restore global heap after ShrinkGlobalHeap
;* exit : n/a
cProc RestoreGlobalHeap, <NEAR, ATOMIC>, <DS, SI, DI>
cBegin RestoreGlobalHeap
assumes ds,DGROUP
;* * modify block to make as large as possible
IFDEF WINDOWS_OLD_APP
mov es,psDosRealloc
ELSE ; !WINDOWS_OLD_APP
mov es,psLom ;* 1 big block
ENDIF ; WINDOWS_OLD_APP
mov bx,0ffffh ;* i want it all
mov ah,4ah
int 21h
ifdef Debug
jc ok_we_asked_for_too_much
int 3 ;* we got 1MB ???
ok_we_asked_for_too_much:
endif ; Debug
;* * now do it for real
mov ah,4ah
int 21h
ifdef Debug
jnc ok_we_got_it_back
int 3 ;* we got 1MB ???
ok_we_got_it_back:
endif ; Debug
;* * get address of new end sentinal
mov ax,es
add ax,bx ;* ax = new end
;* * check to make sure we are within the useable limits
IFDEF WINDOWS_OLD_APP
mov es,psLom
ENDIF ; WINDOWS_OLD_APP
cmp ax,es:[psUseMax]
jb have_high_limit
;* * we must adjust our block size (free the rest to DOS)
;* * (not efficient -- clean up later)
mov bx,es:[psUseMax]
push bx ;* limit
mov ax,es
sub bx,ax ;* size we will use
mov ah,4AH
int 21h ;* modify memory size
pop ax
AssertEQ ax,es:[psUseMax]
have_high_limit:
sub ax,GA_ALIGN ;* room for arena
and al,LOW(GA_MASK) ;* make even
mov ds,ax ;* es => new sentinal
assumes ds,NOTHING
;* * create new sentinal
xor bx,bx
mov ds:[bx].ga_sig,GA_ENDSIG
mov ds:[bx].ga_owner,-1 ;* sentinal
mov ds:[bx].ga_size,GA_ALIGN
mov ds:[bx].ga_flags,bl
mov ds:[bx].ga_handle,bx ;* no handle
mov ds:[bx].ga_next,ds ;* link to self
mov cx,ax ;* psNew
cCall genter ;* DS:DI => mob
xchg ax,ds:[bx].hi_last ;* set new last, get old
inc ds:[di].hi_count ;* adding free object
mov ds,ax
mov es,cx
mov es:[bx].ga_prev,ds ;* link to other free
ifdef Debug
cmp ds:[bx].ga_sig,GA_ENDSIG
je ok_end_sig
int 3
ok_end_sig:
endif ; Debug
sub cx,ax ;* psNew - psOld
sub cx,GA_ALIGN ;* less overhead
mov ds:[bx].ga_sig,GA_SIGNATURE
mov ds:[bx].ga_owner,bx ;* FREE !!!
mov ds:[bx].ga_flags,GA_MOVEABLE
mov ds:[bx].ga_size,cx ;* new size
mov ds:[bx].ga_next,es ;* point to new sentinal
IFDEF WINDOWS_OLD_APP
;* Restore win-old-app model if present
cmp fWoaPresent,0 ;* Is win-old-app segment present?
jz @F ;* No -- skip around
mov ax,DGROUP ;* Calling c procedure
mov ds,ax ;*
cCall WoaFromDos ;* Restore win-old-app code
@@:
ENDIF ; WINDOWS_OLD_APP
cEnd RestoreGlobalHeap
sEnd KERNEL
endif ; !Exec_Alternate
;*****************************************************************************
sBegin INIT
assumes CS,INIT
assumes DS,DGROUP
assumes SS,DGROUP
;********** GetProgDir **********
;* entry : szBuff => string buffer to put path name
;* (must be 66 characters or longer)
;* * copy startup directory to this near buffer
;* exit : n/a
assumes DS,DGROUP
cPublic GetProgDir, <ATOMIC>, <DS, SI, DI>
parmDP szBuff
cBegin GetProgDir
push ds
pop es ;* destination a near pointer
assumes ES,NOTHING
mov di,szBuff
mov ds,psLom
assumes DS,NOTHING
mov si,lomOffset szBootPathLom
@@: lodsb
stosb
or al,al
jnz @B ;* assumes zero terminated
szBPL equ lomOffset szBootPathLom
szBPLRoot equ szBPL + 4
cmp si,szBPLRoot
je AtRoot
mov es:[di-2],al
AtRoot:
cEnd GetProgDir
sEnd INIT
;*****************************************************************************
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -