430 lines
7.0 KiB
NASM
430 lines
7.0 KiB
NASM
FindStruc struc
|
||
|
||
db 21 dup (?) ;reserved area
|
||
Attr db ? ;attribute of file
|
||
Time dw ? ;time of last write
|
||
Date dw ? ;date of last write
|
||
Fsize dd ? ;filesize
|
||
Fname db 13 dup (?) ;filename
|
||
|
||
FindStruc ends
|
||
|
||
CMDSIZE equ 94h ;current resident size of
|
||
;command.com is 94h paras
|
||
|
||
code segment byte public 'CODE'
|
||
assume cs:code, ds:code, es:code
|
||
|
||
org 100h
|
||
public start
|
||
start:
|
||
mov sp,offset MyStack ;set ss:sp to our stack
|
||
|
||
mov ax,offset EndProg
|
||
add ax,15
|
||
mov cl,4
|
||
shr ax,cl ;para size of this program
|
||
mov bx,ax ;bx = this program's size
|
||
mov cx,es
|
||
add ax,cx ;ax = top of this program
|
||
sub ax,1000h - CMDSIZE ;are we below the first 64K?
|
||
jae no_mem ;no, dont reserve memory
|
||
neg ax ;additional memory to be reserved
|
||
add bx,ax
|
||
no_mem: ;bx = #paras needed
|
||
mov ah,4ah
|
||
int 21h ;resize to desired size
|
||
;
|
||
;Prepare to execute the desired program
|
||
;
|
||
call Exec_prepare
|
||
jnc do_exec
|
||
|
||
mov al,1 ;return error
|
||
jmp short exit
|
||
do_exec:
|
||
cmp helpflg,1
|
||
je do_help
|
||
mov ah,4bh
|
||
mov dx,offset ExecPath
|
||
mov bx,offset ExecBlk
|
||
int 21h ;do the Exec
|
||
jc exec_err ;error while executing
|
||
;
|
||
;No error on execution. Get the return code of the program we executed and
|
||
;return that as our return code.
|
||
;
|
||
mov ah,4dh
|
||
int 21h ;al = return code now
|
||
exit:
|
||
mov ah,4ch
|
||
int 21h ;terminate ourselves
|
||
exec_err:
|
||
mov dx,offset ErrMsg ;Error executing command.com
|
||
ifdef BILINGUAL
|
||
call IsDBCSCodePage
|
||
jz @f
|
||
mov dx,offset ErrMsg2
|
||
@@:
|
||
endif
|
||
mov al,1
|
||
call dispmsg
|
||
jmp short exit
|
||
do_help:
|
||
mov dx,offset HelpMsg ;Display help for loadfix
|
||
ifdef BILINGUAL
|
||
call IsDBCSCodePage
|
||
jz @f
|
||
mov dx,offset HelpMsg2
|
||
@@:
|
||
endif
|
||
call dispmsg
|
||
xor al,al
|
||
jmp short exit
|
||
|
||
;***
|
||
;Dispmsg -- Displays messages that are terminated by '$'
|
||
;
|
||
;Input: ds:dx = pointer to message
|
||
;
|
||
;Output: None
|
||
;
|
||
;Registers: ax
|
||
;***
|
||
|
||
dispmsg proc near
|
||
|
||
mov ah,9
|
||
int 21h
|
||
ret
|
||
|
||
dispmsg endp
|
||
|
||
;***
|
||
;Exec_prepare -- Searches the environment for the COMSPEC and sets up the
|
||
;command line and FCBs for the Exec call
|
||
;
|
||
;Input: None
|
||
;
|
||
;Output: Carry set => error. Error message is displayed here
|
||
; Carry clear => all parameters set successfully
|
||
;
|
||
;Registers: ax, cx, dx, si, di
|
||
;***
|
||
|
||
Exec_prepare proc near
|
||
|
||
push ds
|
||
push es
|
||
|
||
mov si,81h ;ds:si points at our command line
|
||
call skip_white ;skip all leading whitespace
|
||
|
||
cmp byte ptr [si],0dh ;Did we hit a CR?
|
||
je no_parms ;yes, no parameters given
|
||
;
|
||
;Check if we have a /? here
|
||
;
|
||
cmp byte ptr [si],'/'
|
||
jne no_help
|
||
cmp byte ptr [si+1],'?'
|
||
jne no_help
|
||
|
||
inc helpflg ;/? given -- print help
|
||
jmp short exefnd
|
||
|
||
no_help:
|
||
mov dx,si ;ds:dx now points at the program
|
||
|
||
mov si,offset CmdOpt
|
||
mov di,offset CmdParms
|
||
inc di
|
||
mov cl,CmdOptLen
|
||
xor ch,ch
|
||
rep movsb
|
||
|
||
mov si,dx
|
||
xor cx,cx
|
||
st_lp:
|
||
lodsb
|
||
stosb
|
||
inc cx
|
||
cmp al,0dh
|
||
jne st_lp
|
||
|
||
dec cx
|
||
add cl,CmdOptLen ;command line cannot be >128
|
||
mov CmdParms,cl
|
||
|
||
mov si,offset CmdParms
|
||
|
||
mov word ptr CmdPtr,si
|
||
mov word ptr CmdPtr+2,cs ;store command line pointer
|
||
|
||
mov word ptr Fcb1+2,cs
|
||
mov word ptr Fcb2+2,cs
|
||
|
||
call find_comspec
|
||
jc no_comspec
|
||
|
||
mov si,offset ExecPath
|
||
xchg si,di
|
||
push ds
|
||
push es
|
||
pop ds
|
||
pop es
|
||
comspec_lp:
|
||
lodsb
|
||
stosb
|
||
or al,al
|
||
jnz comspec_lp
|
||
|
||
exefnd:
|
||
clc
|
||
execp_ret:
|
||
pop es
|
||
pop ds
|
||
ret
|
||
no_parms:
|
||
mov dx,offset NoParms
|
||
ifdef BILINGUAL
|
||
call IsDBCSCodePage
|
||
jz @f
|
||
mov dx,offset NoParms2
|
||
@@:
|
||
endif
|
||
call dispmsg
|
||
stc
|
||
jmp short execp_ret
|
||
no_comspec:
|
||
mov dx,offset NoComspec
|
||
ifdef BILINGUAL
|
||
call IsDBCSCodePage
|
||
jz @f
|
||
mov dx,offset NoComspec2
|
||
@@:
|
||
endif
|
||
call dispmsg
|
||
stc
|
||
jmp short execp_ret
|
||
|
||
Exec_prepare endp
|
||
|
||
;***
|
||
;skip_white -- Skips all whitespace characters until it hits a non-whitespace
|
||
;
|
||
;Input: ds:si = string to be looked at
|
||
;
|
||
;Output: ds:si points at the first non-whitespace char in the string
|
||
;
|
||
;Registers: ax, si
|
||
;***
|
||
|
||
skip_white proc near
|
||
|
||
lodsb
|
||
cmp al,20h ;Blank?
|
||
je skip_white ;yes, skip
|
||
cmp al,9 ;Tab?
|
||
je skip_white ;yes, skip
|
||
|
||
dec si ;point at the first non-white
|
||
|
||
ret
|
||
|
||
skip_white endp
|
||
|
||
;***
|
||
;find_comspec -- searches in the environment for the COMSPEC variable
|
||
;
|
||
;Input: None
|
||
;
|
||
;Output: es:di points at the arguments of the COMSPEC= variable
|
||
;
|
||
;Registers: si
|
||
;***
|
||
|
||
find_comspec proc near
|
||
|
||
mov si,offset Comspec_Text
|
||
|
||
;
|
||
; input: ds:si points to a "=" terminated string
|
||
; output: es:di points to the arguments in the environment
|
||
; zero is set if name not found
|
||
; carry flag is set if name not valid format
|
||
;
|
||
call find ; find the name
|
||
jc done_findp ; carry means not found
|
||
call scasb1 ; scan for = sign
|
||
done_findp:
|
||
ret
|
||
|
||
find_comspec endp
|
||
|
||
;***
|
||
;find -- scans the environment for the variable whose name is passed in
|
||
;
|
||
;Input: ds:si points at the environment variable to be scanned for
|
||
;
|
||
;Output: es:di points at the environment variable
|
||
;
|
||
;Registers: ax, di
|
||
;***
|
||
|
||
find proc near
|
||
|
||
cld
|
||
call count0 ; cx = length of name
|
||
mov es,es:[2ch] ; get environment segment
|
||
;
|
||
;Bugbug: What if the environment segment here is 0?
|
||
;
|
||
xor di,di
|
||
|
||
find1:
|
||
push cx
|
||
push si
|
||
push di
|
||
|
||
find11:
|
||
lodsb
|
||
inc di
|
||
cmp al,es:[di-1]
|
||
jnz find12
|
||
loop find11
|
||
|
||
find12:
|
||
pop di
|
||
pop si
|
||
pop cx
|
||
jz end_find
|
||
push cx
|
||
call scasb2 ; scan for a nul
|
||
pop cx
|
||
cmp byte ptr es:[di],0
|
||
jnz find1
|
||
stc ; indicate not found
|
||
end_find:
|
||
ret
|
||
|
||
find endp
|
||
|
||
;***
|
||
;count0 -- returns length of string until the first '=' char
|
||
;
|
||
;Input: ds:si points at the string
|
||
;
|
||
;Output: cx = length until '='
|
||
;
|
||
;Registers: di
|
||
;***
|
||
|
||
count0 proc near
|
||
|
||
mov di,si ;ds = es = cs
|
||
|
||
push di ; count number of chars until "="
|
||
call scasb1
|
||
pop cx
|
||
sub di,cx
|
||
xchg di,cx
|
||
ret
|
||
|
||
count0 endp
|
||
|
||
;***
|
||
;scasb1 -- scans string for the first '='
|
||
;scasb2 -- scans string for the first null
|
||
;
|
||
;Input: es:di = string
|
||
;
|
||
;Output: es:di points after the desired char
|
||
;
|
||
;Registers: ax, cx
|
||
;***
|
||
|
||
scasb1 proc near
|
||
|
||
mov al,'=' ; scan for an =
|
||
jmp short scasbx
|
||
scasb2:
|
||
xor al,al ; scan for a nul
|
||
scasbx:
|
||
mov cx,100h
|
||
repnz scasb
|
||
ret
|
||
|
||
scasb1 endp
|
||
|
||
|
||
ifdef BILINGUAL
|
||
IsDBCSCodePage proc near
|
||
push ax
|
||
push bx
|
||
|
||
mov ax,4f01h ; get code page
|
||
xor bx,bx
|
||
int 2fh
|
||
|
||
ifdef JAPAN
|
||
cmp bx,932
|
||
endif
|
||
ifdef KOREA
|
||
cmp bx,949
|
||
endif
|
||
ifdef TAIWAN
|
||
cmp bx,950
|
||
endif
|
||
ifdef PRC
|
||
cmp bx,936
|
||
endif
|
||
|
||
pop bx
|
||
pop ax
|
||
ret
|
||
IsDBCSCodePage endp
|
||
endif
|
||
|
||
|
||
;**************************
|
||
;Data
|
||
;**************************
|
||
|
||
ExecBlk label word
|
||
dw 0
|
||
CmdPtr dd ?
|
||
Fcb1 dw offset MyFcb1
|
||
dw ?
|
||
Fcb2 dw offset MyFcb2
|
||
dw ?
|
||
|
||
dw 128 dup (1)
|
||
MyStack label word
|
||
|
||
CmdOpt db '/C '
|
||
CmdOptLen db $ - CmdOpt
|
||
|
||
CmdParms db 128 dup (?) ;buffer to hold prog to be Exec'ed
|
||
|
||
ExecPath db 67 dup (?) ;holds path to COMMAND.COM
|
||
|
||
ComSpec_Text db 'COMSPEC=',0
|
||
|
||
MyFcb1 db 0
|
||
db 11 dup (' ')
|
||
|
||
MyFcb2 db 0
|
||
db 11 dup (' ')
|
||
|
||
Helpflg db 0 ;default is no help
|
||
|
||
include loadmsg.msg
|
||
|
||
EndProg label byte
|
||
|
||
code ends
|
||
end start
|
||
|
||
|
||
|