Metropoli BBS
VIEWER: stub.asm MODE: TEXT (ASCII)
;*****************************************************************************
;            Stub loader for DOS32 executibles.
;
; This stub loader attempts to loads and execute DOS32.EXE.
;  and is searched in the following order.
;
;  1) The directory in which the executible exists ( i.e this stub file )
;  2) Directories entries in the PATH environment varible.
;
; Note: This is the default stub loader use in DLINK.
;*****************************************************************************
; Filename: STUB.ASM
;   Author: Oleg Pliss
;   Version: 1.00
;   Created: 1995.09
;
;   Note: After linking this program use the EXERID utility to remove
;         wasted header space.
;*****************************************************************************

		.8086

		StubSeg	SEGMENT stack 'STACK'
		Assume	DS:StubSeg, CS:StubSeg

ReleaseMemory	macro
		mov	ax, ds
		mov	bx, cs
		sub	bx, ax

		mov	ax, sp
		mov	cl, 4
		shr	ax, cl

		add	bx, ax
		inc	bx

		mov	ah, 4Ah
		int	21h
		endm

SearchForPath	macro
		local	Next, Done, Entry
; ES	- env seg
; DS	- data seg

		cld
		xor	ax, ax
		xor	di, di
		jmp	Entry
Next:
		xor	cx, cx
		dec	cx
		repne	scasb
Entry:
		lea	si, Path
		mov	cx, 5
		repe	cmpsb
		jz	Done

		dec	di
		scasb
		jnz	Next

		xor	di, di
Done:
		endm

CopyPath	macro		; Copy a path to FileName buffer
		local	Done, Next, Skip
; ES	- data seg
; DS	- env  seg
; [SI]	- PATH

		cld
		mov	di, offset FileName-1
Next:
		stosb
Skip:
		lodsb
		cmp     al, ';'
		jz	Done

		cmp	al, ' '
		jz	Skip

		test	al, al
		jnz	Next

		xor	si, si
Done:
		endm

AppendBackslash	macro
		local	BackslashFound

		dec	di
		mov	al, '\'
		scasb
		jz	BackslashFound
		stosb
BackslashFound:
		endm

AppendDos32	macro	; Append "DOS32.EXE" to file name
		lea	si, DOS32_EXE
		mov     cx, 5
		rep	movsw
		endm

Run		macro	; Try to run DOS32.EXE
		lea	bx, ExecParams
		lea	dx, FileName
		mov	ax, 4B00h
		int	21h
		endm


Stub:
		ReleaseMemory
		mov	es, ds:[2Ch]		; Load ES with environment segment.

		mov	ax, ds

		push	cs			; Load DS with data segment
		pop	ds

; Fixup Execute Parameter Table.
		mov	word ptr ExecParams[ 04h ], ax	; command tail segment
		mov	word ptr ExecParams[ 08h ], ax	; FCB 1 segment
		mov	word ptr ExecParams[ 0Ch ], ax	; FCB 2 segment

		SearchForPath

		push	es
		push	di

		push	ds
		pop	es

		lea	di, FileName
		jmp	TryFirst

TryAgain:
		pop	si
		test	si, si
		jz	LoadError	; Error if no DOS32 was found

		pop	ds

		CopyPath

		AppendBackslash

		push	ds		; Save DS
		push	si		; Save SI

		push	es
		pop	ds

TryFirst:
		AppendDos32
		Run
		jc	CheckRetCode

		mov	ah, 4Dh		; Get return code from DOS32 application
		Int	21h
Exit:
		mov	ah, 4Ch		; Terminate to DOS
		int	21h

CheckRetCode:
		cmp	al, 3
		jle	TryAgain
LoadError:
		lea	dx, ExecErrMsg
		mov	ah, 9
		int	21h

		xor	al, al
		jmp	Exit

Path		db	'PATH='
ExecErrMsg	equ	$
DOS32_EXE	db	'DOS32.EXE', 0, 'not found', 10, 13, '$'
ExecParams	dw	0		; childs Environemnt segment
		dw	80h, 0		; childs command tail seg:ofs
		dw	5Ch, 0		; FCB 1  seg:ofs
		dw	6Ch
		dw	?

		db	?
FileName	db	128 dup( ? )	; 128 chars for file the name.

		align 2
		db	100 dup( ? )	; The stack space
The_Stack	equ	$

StubSeg		ends

End  Stub
[ RETURN TO DIRECTORY ]