📄 osstmt.asm
字号:
ExecNullCmd:
XOR AX,AX ;tell B$SHELL to use current ENV block
cCall B$Shell ;call common code to do the SHELL.
PUSH AX ;Save return code for later
cCall B$ShellRecover ;reset runtime to PreSHELL state.
; Now that runtime is restored, check return code
POP AX ;recover error code
OR AX,AX ;error
JZ SHL_NOT_FAILED ;if not, then jump
CMP AX,8 ;test if out of memory
JE ShellMemErr ;if so, then jump
JMP B$ERR_FC ;else illegal function call
ShellMemErr:
JMP B$ERR_OM ;give out-of-memory error
SHL_NOT_FAILED:
cEnd
;***
; B$SENV - Environ statement
; Purpose:
; Argument is a string of the syntax <env_name>=<env_value>.
; If <env_value> is nonnull and <env_name> exists, replace it.
; If <env_value> is nonnull and <env_name> does not exist, add it.
; If <env_value> is null, delete <env_name> if it exists.
;
; Inputs:
; string descriptor of argument string
; Outputs:
; None.
; Modifies:
; None.
; Exceptions:
; B$ERR_FC if function argument error.
;******************************************************************************
cProc B$SENV,<PUBLIC,FAR>,<SI,DI,ES>
parmSD sdEnviron
cBegin
PUSH DS ; Set es=DS
POP ES
MOV BX,sdEnviron ;get environment descriptor in BX
mov cx,[bx] ;length of string
mov si,[bx+2] ;count in string
push bx
mov dx,cx
push dx
push si
jcxz errfc
envsf1: ;look for blank or equals: address of
lodsb ;string to move into environment
cmp al,' '
jz envsf2
cmp al,'='
jz envsf2
loop envsf1
JMP SHORT ERRFC ;error if no delimiter
envsf2:
sub dx,cx ;size of parm
jz errfc ;zero is bad
envsf3:
dec cx ;adjust length
jz envsf4 ;no text follows - delete
lodsb
CMP AL,'=' ;test for equals sign
JNZ ENVS3A ;if not, then jump
DEC CX ;adjust length
JZ ENVSF4 ;no text follows - delete
LODSB ;get character after '='
JMP SHORT ENVS3B ;jump to test for semicolon, etc.
ENVS3A:
cmp al,' '
jz envsf3 ;strip leading blanks
ENVS3B:
cmp cx,1 ;if 1 left
jne envsf4
cmp al,';' ; and it is semi-colon
jz envsf3 ;then assume delete
envsf4:
dec si ;adjust to beginning of text
pop di ;start of string
push cx ;save length of arg text
CALL B$FIRST_ENV ;get start of env in bx
mov cx,dx ;cx = length of parm
envsf5:
mov dx,si ;dx = start of next
mov si,bx ;si = start of this
push di ;save string start
jz envsf9 ;if end, add new parm and text
push cx ;save parm length
cld
repz cmpsb ;compare parm with env parm
je envsf7 ;matched
envsf6:
mov si,dx ;don't want tz unless real end
CALL B$NEXT_ENV ;go to next env parm
pop cx ;length and
pop di ; parm start back
jmp envsf5
errfc: jmp B$ERR_fc
envsf7:
lodsb ;get next byte from environment
cmp al,'=' ;must have equals to be a match
jne envsf6 ;try next
pop ax ;trash parm length
mov si,dx ;si = address of next parm
mov di,bx ;di = address of this parm
mov cx,es:b$env_len ;get total length of environment
sub cx,dx ;cx=endnext (length to compress)
inc cx ;copy includes table terminator
push di
push es ;save seg of string
push ds ;move env. seg into es
pop es
rep movsb ;compress
pop es ;restore seg of string
pop si ;start of this parm or end
envsf9:
CALL B$NEXT_ENV ;find end of table
jnz envsf9
mov di,si ;di = end of env table
push ds
push es
pop ds
pop es ;ds = string seg, es = env seg
pop si ;string start
pop ax ;ax = length of arg text
pop cx ;string length
or ax,ax
jz envsfx ;if arg text length then done
mov ax,di ;ax = current length of environ
add ax,cx ;+ new size
;INC AX ;include terminator byte in length
assumes ES,NOTHING
cmp ax,b$env_len ;check if overflow
jb envs10 ; no overflow
push ds
pop es
jmp B$ERR_om ;give out of memory error
envs10:
lodsb
cmp al,'=' ;blanks to right of '=' are included
jz envs11
cmp al,' ' ;skip blanks
jz envs11
stosb
loop envs10
jmp SHORT envsft ;terminate
envs11:
DEC CX ;one less character
CMP AL,' ' ;test for blank character
JNE ENVS12 ;if not blank, then jump
JCXZ ENVSFT ;if end of string, jump
LODSB ;get the next character
JMP SHORT ENVS11 ;process the character
ENVS12: ;character after leading blanks
CMP AL,'=' ;test for equals sign
JE ENVS13 ;process rest of string as is
PUSH AX ;save character after blanks
MOV AL,'=' ;put in equals sign
STOSB ;and place it in the table
POP AX ;restore old character
ENVS13: ;start of text string
STOSB ;store first char (or explicit =)
rep movsb
envsft: ;terminate label
xor ax,ax
stosw ;00 ends env table
envsfx: ;exit label
push ds
pop es
pop bx
CALL B$STDALCTMP ; delete if temp string desciptor
cEnd
;***
; B$SICT - IOCTL statement
; Purpose:
; Send the specified string argument as an I/O-control
; function to the file.
;
; Inputs:
; file number
; string to send
; Outputs:
; None.
; Modifies:
; None.
; Exceptions:
; B$ERR_IFN if illegal file number.
; B$ERR_FC if function error.
; B$ERR_IOC if IOCTL error.
;******************************************************************************
cProc B$SICT,<PUBLIC,FAR>,<SI>
parmW fileNum
parmSD sdCtl
cBegin
MOV BX,fileNum ;put file number in BX
CALL B$LHFDBLOC ; find FDB
JZ BADIFN2
MOV BX,sdCtl ; [BX] = string desc
MOV DX,[BX+2]
MOV CX,[BX]
PUSH BX ; save
MOV AL,3
FDB_PTR ES,SI,SI ;get FDB pointer
MOV BX,FileDB.FD_HANDLE
OR BX,BX ;if zero, one of basic's devices
JZ ERRCTL2
CALLOS IOCTL,ERRCTL,BX,CX,DX
POP BX
cCall B$STDALCTMP ; deallocate it if it was temp
cEnd
ERRCTL2:
JMP SHORT ERRCTL
BADIFN2:
JMP SHORT BADIFN
;***
; B$FEVS - ENVIRON$ function with string argument
; Purpose:
; With <env_name> as an input argument, return <env_value> if
; the entry "<env_name>=<env_value>" is in the environment table.
;
; Inputs:
; string descriptor of <env_name>
; Outputs:
; AX = ptr to string descriptor of <env_value>
; Modifies:
; None.
; Exceptions:
; B$ERR_FC if function error.
;******************************************************************************
cProc B$FEVS,<PUBLIC,FAR>,<SI,DI,DS,ES>
parmSD sdEnv
cBegin
PUSH DS
POP ES
assumes ES,DGROUP
MOV BX,sdEnv ;get string desc. in BX
MOV SI,[BX+2] ;address of string
MOV CX,[BX] ;length
MOV DX,CX ;save
PUSH SI
JCXZ BADFC
ENVRS1:
LODSB
CMP AL,' ' ;error if embedded blanks
JZ BADFC
CMP AL,'=' ;or '='
JZ BADFC
LOOP ENVRS1
POP DI ;address of string
PUSH DX ;save length
CALL B$FIRST_ENV ;get first env parm
MOV AX,CX ;save length of env table entry
POP CX ;length back
ENVRS5:
MOV DX,SI ;start of next
MOV SI,BX ;start of this
JNZ ENVR5A ;not end of list (yet)
XOR CX,CX ;end of list returns null string
JMP SHORT GOGOTENV ;and jump to process it
ENVR5A:
PUSH DI ;save
PUSH CX
REPZ CMPSB ;compare parms
JZ ENVRS7 ;matched
ENVRS6:
MOV SI,DX
CALL B$NEXT_ENV ;get next
MOV AX,CX ;save length of env table entry
POP CX
POP DI
JMP ENVRS5
ENVRS7:
CMP BYTE PTR [SI],'=' ;must have equals
JNE ENVRS6
INC SI ;SI points after '=' now
POP CX ;restore string length
POP DI
XCHG CX,AX ;CX now length of table entry...
;AX now length of string parameter
SUB CX,AX ;CX now length of '=' and value
DEC CX ;CX now length of just value
GOGOTENV:
CALL GOTENV ; do the common code (returns DX:AX = sd)
PUSH AX ; save psd returned by GOTENV
MOV BX,sdEnv
PUSH ES
POP DS ; [DS] = dgroup again
assumes ES,NOTHING
cCall B$STDALCTMP ; deallocate it if it was temp
POP AX ; ax = pointer to descriptor
cEnd
ERRCTL:
CMP AX,ERRIDT
JNE BADFC
JMP B$ERR_IOE
BADIFN:
JMP B$ERR_IFN
BADFC:
JMP B$ERR_FC
;***
; B$FEVI - ENVIRON$ function with integer argument
; Purpose:
; Returns the ordinal i environment table entry, where
; i is the input integer argument.
;
; Inputs:
; integer value in range 1 to 255.
; Outputs:
; AX = ptr to string descriptor to a copy of the table entry.
; Modifies:
; None.
; Exceptions:
; B$ERR_FC if function error.
;******************************************************************************
cProc B$FEVI,<PUBLIC,FAR>,<SI,DI,DS,ES>
parmW EnvInt
cBegin
PUSH DS
POP ES ;set es=ds
MOV BX,EnvInt ;get integer in BX
MOV DX,BX
OR BX,BX ;test for zero argument
JZ BADFC ;and error if so...
CMP BX,255
JA BADFC
CALL B$FIRST_ENV ;get first parm in env
ENVNF1:
JZ ENVNF2 ;end, return null
DEC DX
JZ ENVNF2 ;return pointer in BX
CALL B$NEXT_ENV
JMP SHORT ENVNF1
ENVNF2:
MOV SI,BX ;GOTENV needs pointer in SI
CALL GOTENV ;call common code (returns DX:AX = sd)
cEnd
GOTENV:
PUSH DS ;save ENV segment
PUSH ES ;put DGROUP seg on stack
POP DS ;restore DS to DGROUP
PUSH CX ;save length
MOV BX,CX
CALL B$STALCTMP ; allocate string temp
POP CX ;count
POP DS ;get ENV segment back in DS
XCHG AX,BX ; [AX] = psd
MOV DI,DX ;target
REP MOVSB ;move into target
RET ; return with [DX:AX] = sd or [AX] = psd
;***
; B$FICT - IOCTL$ function
; Purpose:
; Returns a status string from the specified file using
; an IOCTL call.
;
; Inputs:
; file number to get status
; Outputs:
; AX = pointer to string descriptor of status string
; Modifies:
; None.
; Exceptions:
; B$ERR_FC if function call error.
; B$ERR_IOC if IOCTL error.
;******************************************************************************
cProc B$FICT,<PUBLIC,FAR>,<SI,DI,ES>
parmW fileNum
cBegin
MOV BX,fileNum ;get file number in BX
CALL B$LHFDBLOC
JZ BADIFN
FDB_PTR ES,SI,SI ;get FDB pointer
MOV BX,FileDB.FD_HANDLE
OR BX,BX ;if zero, one of basic's devices
JZ ERRCTL
MOV DX,OFFSET DGROUP:b$PATHNAM ; DX = buffer address
MOV AL,2 ;read IOCTL info
CALLOS IOCTL,ERRCTL,BX,255,DX
MOV CX,AX ;[CX] = number of bytes read
XCHG AX,BX
MOV SI,DX ;address of ioctl data
CALL B$STALCTMP ; allocate string temp
MOV DI,DX ;target work area
PUSH DS
POP ES
REP MOVSB
XCHG AX,BX ;return sd in AX
cEnd
;***
; B$ERDV - return device error word
; Purpose:
; Return the value of the device error word set by the
; last error.
;
; Inputs:
; None.
; Outputs:
; AX = device error word.
; Modifies:
; None.
; Exceptions:
; None.
;******************************************************************************
cProc B$ERDV,<PUBLIC,FAR>
cBegin
MOV AX,b$ERDEV
cEnd
;***
; B$ERDS - get device error string
; Purpose:
; Returns the descriptor of the device error string.
;
; Inputs:
; None.
; Outputs:
; AX = address of device error string if set, otherwise null string.
; Modifies:
; None.
; Exceptions:
; None.
;******************************************************************************
cProc B$ERDS,<PUBLIC,FAR>
cBegin
MOV BX,OFFSET DGROUP:b$ERDEVP ;address of string
CMP WORD PTR [BX],0 ;set yet ?
MOV AX,BX ;put sd in AX
JNE DVRET
MOV AX,OFFSET DGROUP:b$nuldes ;no - use null
DVRET:
cEnd
sEnd OS_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -