MUL32	proc
	push si
	push di
	push bp
	push ax
	push dx
	push dx
	mul bx	; 1L * 2L
	mov si,dx
	mov di,ax
	pop ax
	mul cx	; 1H * 2H
	mov bp,dx
	xchg bx,ax
	pop dx
	mul dx	; 1H * 2L
	add si,ax
	adc bx,dx
	pop ax
	mul cx	; 1L * 2H
	add si,ax
	adc bx,dx
	adc bp,0
	mov cx,bp
	mov dx,si
	mov ax,di
	pop bp
	pop di
	pop si
	ret	; CX:BX:DX:AX
MUL32	endp

atol	proc pascal string:dword
	push ds
	push si
	push di
	lds si,string
	cld
    atol_start:
	lodsb
	cmp al,' '
	je atol_start
	mov bh,al
	cmp al,'-'
	je atol_inc
	cmp al,'+'
	jne atol_set
    atol_inc:
	lodsb
    atol_set:
	xor cx,cx
	mov di,cx
    atol_loop:
	cmp al,'0'
	jb atol_break
	cmp al,'9'
	ja atol_break
	mov bl,al
	xchg bx,di
	xor dx,dx
	mov ax,10
	call MUL32
	mov bx,di
	mov bh,0
	sub bl,'0'
	add ax,bx
	adc dx,0
	mov cx,dx
	mov di,ax
	lodsb
	jmp atol_loop
    atol_break:
	cmp bh,'-'
	je atol_neg
    atol_end:
	mov ax,di
	mov dx,cx
	pop di
	pop si
	pop ds
	ret
    atol_neg:
	neg cx
	neg di
	sbb cx,0
	jmp atol_end
atol	endp

sp_file_exist proc
	push bx
	invoke filexist, addr [bp-128]
	cmp ax,1
	pop bx
	ret
sp_file_exist endp

sp_init_file proc
	push es
	push ss
	lea ax,[bp-256]
	push ax
	push 0
	push 0
	push ss
	add ax,128
	push ax
	call strfcat
	pop es
	ret
sp_init_file endp

search_path proc
	push bx
	invoke fullpath, addr [bp-256], 0
	call sp_init_file
	les di,envpath
    search_path_test:
	invoke filexist, addr [bp-256]
	cmp ax,1
	je search_path_found
	cmp byte ptr es:[di],';'
	jne search_path_nul?
	inc di
    search_path_nul?:
	cmp ah,es:[di]
	je search_path_nul
	xor bx,bx
	lea si,[bp-256]
    search_path_cpy:
	mov al,es:[bx+di]
	or al,al
	jz search_path_eof
	cmp al,';'
	je search_path_eof
	mov [bx+si],al
	inc bx
	jmp search_path_cpy
    search_path_found:
	mov ax,bp
	sub ax,256
	mov dx,ss
	jmp search_path_end
    search_path_nul:
	xor ax,ax
	mov dx,ax
    search_path_end:
	or ax,ax
	pop bx
	ret
    search_path_eof:
	add di,bx
	mov [bx+si],ah
	call sp_init_file
	jmp search_path_test
search_path endp

searchp proc pascal, fname:dword
local	path[256]:byte
	push si
	push di
	lodm envpath
	or dx,dx
	jz searchp_nul
	les bx,fname
	or bx,bx
	jz searchp_nul
	mov al,es:[bx]
	or al,al
	jz searchp_nul
	cmp al,'.'
	jz searchp_nul
	cmp al,'\'
	jne searchp_do
    searchp_nul:
	xor ax,ax
	cwd
	jmp searchp_end
    searchp_do:
	invoke strcpy, addr [bp-128], es::bx
	mov si,ax
	invoke strlen, dx::ax
	mov di,si
	add di,ax
	cmp ax,5
	jb searchp_02
	mov al,'.'
	cmp al,[di-4]
	jne searchp_02
	mov ax,si
	mov dx,ss
	call isexec
	cmp ax,2
	jae searchp_03
    searchp_02:
	mov byte ptr [di],'.'
	inc di
	mov bx,di
	mov word ptr [di],'OC'
	mov word ptr [di+2],'M'
	call sp_file_exist
	je searchp_05
	mov word ptr [di],'XE'
	mov word ptr [di+2],'E'
	call sp_file_exist
	je searchp_05
	call search_path
	jnz searchp_end
	mov word ptr [bx],'OC'
	mov word ptr [bx+2],'M'
	jmp searchp_04
    searchp_03:
	call sp_file_exist
	je searchp_05
    searchp_04:
	call search_path
	jmp searchp_end
    searchp_05:
	mov ax,bp
	sub ax,128
	mov dx,ss
    searchp_end:
	pop di
	pop si
	ret
searchp endp

isexec	proc
	invoke strrchr, dx::ax, '.'
	jz isexec_NOT
	mov es,dx
	inc ax
	mov bx,ax
	mov dx,'  '
	mov ax,es:[bx]
	mov bx,es:[bx+2]
	or ax,dx
	or bx,dx
	cmp ax,'ab'
	je isexec_BAT
	cmp ax,'oc'
	je isexec_COM
	cmp ax,'xe'
	je isexec_EXE
    isexec_NOT:
	xor ax,ax
    isexec_END:
	ret
    isexec_EXE:
	cmp bx,' e'
	jne isexec_NOT
	mov ax,3	; 3 = EXE
	jmp isexec_END
    isexec_COM:
	cmp bx,' m'
	jne isexec_NOT
	mov ax,2	; 2 = COM
	jmp isexec_END
    isexec_BAT:
	cmp bx,' t'
	jne isexec_NOT
	mov ax,1	; 1 = BAT
	jmp isexec_END
isexec	endp
