📄 csup.asm
字号:
; File : $Workfile: CSUP.ASM$
;
; Description :
;
; Original Author : DIGITAL RESEARCH
;
; Last Edited By : $CALDERA$
;
;-----------------------------------------------------------------------;
; Copyright Work of Caldera, Inc. All Rights Reserved.
;
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
; CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
; *** Current Edit History ***
; *** End of Current Edit History ***
;
; $Log$
; ENDLOG
;
; 28 Jan 88 Change the validation check for the environment. Now we look
; for a valid DOS Memory Descriptor which is owned by the
; Command Processor.
; 12 May 88 Handle Empty environments correctly (Thanks DesqView)
; 26 May 88 ach _stack is only defined for MSC
; 16 Jun 88 Support TURBO C Stack checking and enable CHKSTK for
; MSC only.
; 26 Aug 88 Make the Minimum Stack Address Public
; 14 Apr 89 Make heap_top public
; 14 Jul 89 Move findeof to assembler
; 09 Oct 90 Write heap_size() to return remaining bytes on heap at
; any given instance
;
_DLS_INCLS_ equ 1
include message.def
CGROUP GROUP _TEXT
DGROUP GROUP _DATA
codeOFFSET equ offset CGROUP:
dataOFFSET equ offset DGROUP:
STACKSLOP equ 128 ; Minimum Stack Size
jmps macro label ; Define a Macro to generate the
jmp SHORT label ; Short Jmp instruction
endm
_TEXT SEGMENT byte public 'CODE'
ifdef MWC
extrn longjmp:near ; MetaWare does not preceed library
LONGJUMP equ longjmp ; functions with an UNDERSCORE
else
ifdef WATCOMC
extrn longjmp_:near
LONGJUMP equ longjmp_
else
extrn _longjmp:near
LONGJUMP equ _longjmp
endif
endif
assume cs:CGROUP, ds:DGROUP, es:nothing
public _debug
_debug proc near
out 0fdh,al
ret
_debug endp
; Environment manipulation routines
; =================================
;
;BOOLEAN env_entry(BYTE *buf, WORD entry);
;
; Copy entry number ENTRY into the buffer BUF. Return FAILURE
; if ENTRY cannot be found.
;
assume cs:CGROUP, ds:DGROUP, es:nothing
public _env_entry
_env_entry PROC near
cld
push bp
mov bp,sp
push ds
push si
push es
push di
call get_env ; Get the environment segment
mov es,bx ; Initialise ES
mov cx,ax ; Check the environment size - 1
dec cx ; and FFFF bytes if no env header
xor di,di ; Offset to start scaning for data
xor ax,ax
env_e10:
cmp es:byte ptr [di],al ; Is this a Null string
jz env_fail ; Then hit the end of the search
cmp word ptr 06[bp],0 ; Is this the entry required
jz env_e20
repnz scasb ; Scan for the next zero byte
jcxz env_fail ; and abort if out of space
dec word ptr 06[bp] ; Decrement the string count
jmps env_e10
env_e20: ; Found the correct entry now copy
mov si,di ; Get the correct source offset
push ds
push es
pop ds
pop es
mov di,04[bp]
env_e30:
lodsb
stosb ; Copy byte through AL
or al,al
jnz env_e30 ; and check for end of string
jmps env_exit
_env_entry ENDP
;BOOLEAN env_scan(BYTE *key, BYTE *buf);
;
; Scan through the environment searching for the string KEY then copy
; the result into buffer.
Public _env_scan
_env_scan PROC near
cld
push bp
mov bp,sp
push ds
push si
push es
push di
call get_env ; Get the environment segment
call get_key ; Find the key
jz env_fail ; Abort if an error occurs
add di,dx ; Add the Key length and just copy
mov si,di ; The key definition into the
push ds ; Buffer
push es
pop ds
pop es
mov di,06[bp]
env_s10:
lodsb
stosb ; Copy byte through AL
or al,al
jnz env_s10 ; and check for end of string
jmps env_exit
_env_scan ENDP
;
; Environment handling exit routines
env_err: ; Invalid Environment descriptor
mov ax,-1 ; return with -1
jmps env_ret
env_fail: ; Environment fail the operation
mov ax,1 ; requested has failed.
jmps env_ret
env_exit:
xor ax,ax
env_ret PROC near
pop di
pop es
pop si
pop ds
pop bp
ret
env_ret ENDP
;
;BOOLEAN env_del(BYTE *key);
; Delete the entry matching KEY from the environment and return
; success or failure
;
public _env_del
_env_del PROC near
cld
push bp
mov bp,sp
push ds
push si
push es
push di
call get_env ; Get the environment segment
jz env_err ; Stop if not the real thing
call get_key ; Find the key
jz env_fail ; Abort if an error occurs
mov ds,bx ; Point DS at the environment
mov si,di ; save the destination offset
add di,dx ; and search for the end of this string
xor ax,ax
mov cx,-1
repnz scasb ; Now search for the end of string
xchg si,di ; Swap the source and destination
env_d10:
cmp al,[si] ; Is this the end of the environment
jz env_d20 ; Yes so terminate
env_d15:
lodsb
stosb ; Copy through AL checking for the end
or al,al
jnz env_d15 ; of the environment after each
jmps env_d10 ; end of string.
env_d20:
stosw ; Force 0 word to be placed here to
jmps env_exit ; terminate the string
_env_del ENDP
;BOOLEAN env_ins(BYTE *str);
; Insert the string at the end of the current environment
; checking if there is enough room to save the string.
;
public _env_ins
_env_ins PROC near
cld
push bp
mov bp,sp
push ds
push si
push es
push di
call get_env ; Get the environment segment
jz env_err ; and its segment
sub ax,2 ; Decrement the size of the env
mov cx,ax ; to make sure we can store a 0
xor ax,ax ; word terminator
mov es,bx ; Find the end of the current env
xor di,di
env_i10:
repnz scasb
jcxz env_fail
cmp al,es:byte ptr [di]
jnz env_i10
cmp di,1 ; Is this an empty Environment
jnz env_i25 ; No. If yes then start from offset 0
dec di
env_i25:
mov bx,di ; Save the starting address of string
mov si,04[bp] ; Get the source string offset
env_i20:
lodsb
stosb ; Copy the String until a zero byte
or al,al ; then add the environment terminator
loopnz env_i20
mov es:word ptr [di],0
jz env_exit ; Exit with no error if the string is
mov es:byte ptr [bx],00 ; terminated correctly otherwise remove
jmps env_fail ; all traces of this string and exit
_env_ins ENDP
;
page
;
; Returns environment size in Bytes in AX or zero if error
; and BX is the Environment segment.
;
get_env PROC near
push es
mov dx,__psp ; Get the Current PSP in DX
mov es,dx ; and point ES at Our PSP
xor ax,ax ; and assume an error condition
mov bx,es:002Ch ; get environment segment
dec bx ; Check for memory descriptor
mov es,bx
inc bx
cmp es:byte ptr 00h,'M' ; Byte 0 must contains either an
jz get_e10 ; M or Z and the DMD be owned by
cmp es:byte ptr 00h,'Z' ; the Command Processor
jnz get_e20
get_e10:
if 0
cmp dx,es:word ptr 1h ; Is this "OUR" PSP if not then
jnz get_e20 ; complain bitterly.
endif
mov ax,es:word ptr 3h ; Get the memory size in paragraphs
shl ax,1 ; convert to size in bytes and exit.
shl ax,1
shl ax,1
shl ax,1
get_e20:
pop es
or ax,ax
ret
get_env ENDP
;
; enter this search function with BX == ENVIRONMENT SEGMENT
; 04[bp] == Key string offset
; On exit AX == 0 Failure
; else DX is Key string Length
; DI is Offset
;
get_key PROC near
push ds
pop es ; Calculate the length of the
mov di,04[bp] ; key by scaning the string for
mov al,0 ; a zero byte.
mov cx,-1
repnz scasb
neg cx ; CX is the length of the sting + 2
sub cx,2
mov dx,cx ; Save the count in dx
xor ax,ax
mov es,bx ; Point ES at the environment
xor di,di ; and start from the begining
get_k10:
push di ; Save incase this is a match
mov cx,dx ; Get the string length
mov si,04[bp] ; and offset and check for a match
repz cmpsb
jnz get_k20 ; No match so get the next string
pop di ; This is the starting offset
or ax,-1 ; All ok
ret
get_k20:
pop cx ; Throw away the old DI
mov cx,-1 ; Set the count to maximum
repnz scasb ; and search for the end of the string
cmp al,es:[di] ; exit with error if this is the end
jnz get_k10 ; of the environment
ret
get_key ENDP
page
assume cs:CGROUP, ds:DGROUP, es:nothing
ifdef MSC
;
;
; STACK(WORD) allocates memory from the C STACK if at any stage
; the stack grows to within STACKSLOP of the top of the heap this
; function executes a LONGJUMP using the BREAK_ENV buffer. This will
; terminate any internal function.
;
PUBLIC _stack
_stack:
pop bx ; Get the return address
pop cx ; and the number of bytes required
add cx,1 ; Force CX to be a even value to
and cx,not 1 ; ensure the stack is word aligned
mov ax,sp ; Get the Stack
sub ax,STACKSLOP ; Include STACKSLOP
sub ax,cx ; Subtract requested buffer
jc heap_error ; Exit with error if Carry
cmp ax,heap_top ; Are we still above the heap
jc heap_error ; No
pop ax ; Get possible saved SI
pop dx ; Get possible saved DI
push dx ; Restore the stack to its
push ax ; origibnal format
sub sp,cx ; All OK so update SP
push dx ; Save possible saved DI
push ax ; Save possible saved SI
mov ax,sp ; Return pointer
add ax,4 ; Adjust pointer for saved SI/DI
push cx ; Restore the entry parameter
jmp bx ; and return to the caller
endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -