delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2023/01/24/16:54:56

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20210112;
h=content-transfer-encoding:in-reply-to:content-language:references
:to:from:subject:user-agent:mime-version:date:message-id:from:to:cc
:subject:date:message-id:reply-to;
bh=4zGNpDcOsODzpURnLHYFVozYOKJdppS+5OLLaApUr18=;
b=kLQinljZOh3YsU1rRztQJNo3mhOy87oeqOegL4HZMyVLEzNU2rFQVg9a/XT/vo6MRw
g1j7oDGJq2avIJ/AufXortpua0q7yjDAyNN+tGONtCIoNQNtBJXFXnClEd24TnuFA4dZ
QQVFtLYViKWi7HaZz6vGkoYuoztRRUaH8paRekIwAi1Nd/EhWu+6MoMnD7DltZzOcS0f
K9V5EIFR5EsQtpMt4jVcPRRVr3tnYCQb5h/Y6tEmCexcKgSZ5vFyt6zLrd/RIwyEq51m
OvnoeU3HefVnCmxjdb1L2I1vjIMoZu2sMHcFrAaNeqtgCzQ1n+awfWENdfWmuDr2/uGu
NwgQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=content-transfer-encoding:in-reply-to:content-language:references
:to:from:subject:user-agent:mime-version:date:message-id
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=4zGNpDcOsODzpURnLHYFVozYOKJdppS+5OLLaApUr18=;
b=VLryqdV+fS3t2u16I5PVMJvS4rri971lekxleNxf604VLK07Pig1FhlfGY3APyzkOW
RSm+Plh52+9YnEBgbhVl09elfOBAIMk4VLT6gKVfvjMVRJ+WZNhtcoRzwA77cUvRSu5F
bLD2y6k/5TKazT+8ArlqUa5CqvjpTHsUB4Am9NGilBRsZcvmsSjGy6JUvSec/Yf3FqiE
VhtJ9SjudQRXqhncSt+vJzacT2t41bpXaoL46wrjCRfrOjxkIHF0ON5JUSOa2Bt3UB1n
1jOiFovM9k++AbDItYKETP/QwlELOJvS/79DwC0yUsmelRCuW2lq2AhXG8tTw/15TwWV
/23w==
X-Gm-Message-State: AFqh2krFdu3bOIZNVE51FiLwiJATl/7Dgo6LNUVWTfCFbJaRMTdyhab7
J5QgBg+0yxccdLuu4UCUHQLEBAn07zA/LQ==
X-Google-Smtp-Source: AMrXdXsHDEKTB55OCmOyIEozkYM1tb5awHkq7TwDzPoNIRo+M0sXoz7Y5sekTwsMbvDL67pu6Aafqw==
X-Received: by 2002:a17:906:80d:b0:870:d15a:c2e0 with SMTP id e13-20020a170906080d00b00870d15ac2e0mr30903206ejd.51.1674583822255;
Tue, 24 Jan 2023 10:10:22 -0800 (PST)
Message-ID: <5de28b44-10f2-c824-def1-d451035ecaad@gmail.com>
Date: Tue, 24 Jan 2023 19:10:21 +0100
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.6.1
Subject: [PING][PATCH v2] stub: ignore host exit status
From: "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" <djgpp AT delorie DOT com>
To: djgpp AT delorie DOT com
References: <744f054f-9682-4a05-91ad-684b18c0122b AT gmail DOT com>
<21e1aa0b-1511-0071-84c0-b20c6a3d1dae AT gmail DOT com>
In-Reply-To: <21e1aa0b-1511-0071-84c0-b20c6a3d1dae@gmail.com>
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

Would appreciate any feedback on this.  I know there's a small mistake in one
comment, but the code works.

On 2022-11-25 00:26, J.W. Jagersma wrote:
> On 2022-11-23 20:47, J.W. Jagersma wrote:
>> Hi all,
>>
>> If you've ever tried using hdpmi32 with a djgpp program, you may have
>> noticed some strange behavior.  The program first fails to run with
>> "Load error: no DPMI", but on the second try, it suddenly works.  Then
>> a third invocation fails again, the fourth runs fine, etc.
>>
>> When you rename 'hdpmi32.exe' to 'cwsdpmi.exe', your program seems to
>> run consistently.  But this is only because there is a second (real)
>> cwsdpmi in your PATH somewhere.  What really happens, is that your
>> program alternates between running under hdpmi and cwsdpmi.
>>
>> I finally figured out why this happens, and it's very simple: hdpmi uses
>> the exit status to indicate if it was loaded via xms, vcpi, or int15.
>> And the djgpp stub considers any non-zero exit status to be a failure,
>> so it keeps searching PATH until cwsdpmi is found, which always returns
>> zero.
>>
>> For a possible solution, I would suggest to ignore the return status
>> from the host, and just check int 2f/1687 after every exec.  As an added
>> bonus, this saves 13 bytes of stub space.
> 
> Amended patch follows - it no longer skips the last iteration (exec
> with no path).
> 
> It's a bit larger, but still saves 6 bytes in total.
> 
> --- a/src/stub/stub.asm
> +++ b/src/stub/stub.asm
> @@ -199,38 +199,49 @@ not_path:
>  ;-----------------------------------------------------------------------------
>  ;  Get DPMI information before doing anything 386-specific
>  
> -	push	es
>  	push	di
> -	xor	cx, cx			; flag for load attempt set cx = 0
> -	jz	@f2			; We always jump, shorter than jmp
> +					; Set up loadname in case of no DPMI.
> +					; First try current dir.
> +	xor	ah, ah			; Copy until this character (=0)
> +	call	store_env_string	; copy stub image to "loadname"
> +	mov	si, bx			; remove name so we can add DPMI name
> +	mov	di, [path_off]		; Pointer to path contents (next try)
>  @b1:
> +	xor	cx, cx			; flag to signal end of loop
> +@b2:
> +	call	check_dpmi		; int 2f, ax=1687
> +	jz	@f3
> +	call	do_exec			; copy our name to string and try load
> +	jcxz	@f1			; cx=0 while we have more paths to try
> +	call	check_dpmi		; last chance...
> +	jz	@f3
>  	mov	al, 110
>  	mov	dx, msg_no_dpmi
>  	jmpl	error
> -@b2:
> -	or	cx, cx
> -	jnz	@b1			; we already tried load once before
> -	inc	cx
> -	call	load_dpmi
> -	jc	@b1
> +@f1:
> +					; Set up loadname for next attempt.
> +	mov	ah, ';'			; Copy until this character
> +	call	store_env_string	; to "loadname"
> +	or	al, al			; Check terminating character
> +	jne	@f2			; If ';', continue
> +	dec	di			; else point at null for next pass.
>  @f2:
> -	mov	ax, 0x1687		; get DPMI entry point
> -	int	0x2f
> -	or	ax, ax
> -	jnz	@b2			; if 0 then it's there
> -	and	bl, 1			; 32 bit capable?
> -	jz	@b2
> +	inc	cx
> +	cmp	si, loadname		; anything there?
> +	je	@b2			; final try (no path)
> +	mov	al, [si-1]
> +	call	test_delim		; is final character a path delimiter
> +	je	@b1
> +	movb	[si], '\\'		; no, add separator between path & name
> +	inc	si
> +	jmp	@b1
>  @f3:
> -	mov	[modesw], di		; store the DPMI entry point
> -	mov	[modesw+2], es
> -	mov	[modesw_mem], si
>  	pop	di
> -	pop	es
>  
>  ;-----------------------------------------------------------------------------
>  ;  Now, find the name of the program file we are supposed to load.
>  
> -;	xor	ah, ah			; termination character (set above!)
> +;	xor	ah, ah			; termination char (set by check_dpmi)
>  	call	store_env_string	; copy it to loadname, set bx
>  
>  	mov	[stubinfo_env_size], di
> @@ -700,36 +711,29 @@ pm_dos:
>  	ret
>  
>  ;-----------------------------------------------------------------------------
> -;  load DPMI server if not present
> -;   First check directory from which stub is loaded, then path, then default
> -;   On entry di points to image name
> +; Check for presence of a DPMI host, and save the mode switch address.
> +; Zero flag is clear on success.  Clobbers ax/bx/dx.
>  
> -path_off:
> -	.dw	0			; If stays zero, no path
> -
> -load_dpmi:
> -	xor	ah, ah			; Copy until this character (=0)
> -	call	store_env_string	; copy stub image to "loadname"
> -	mov	si, bx			; remove name so we can add DPMI name
> -	mov	di, [path_off]		; Pointer to path contents (next try)
> -	jmp	@f2
> -loadloop:
> -	mov	ah, ';'			; Copy until this character
> -	call	store_env_string	; to "loadname"
> -	or	al,al			; Check terminating character
> -	jne	@f1			; If ';', continue
> -	dec	di			; else point at null for next pass.
> -@f1:	
> -	cmp	si, loadname		; anything there?
> -	je	do_exec			; final try (no path) let it return
> -	mov	al, [si-1]
> -	call	test_delim		; is final character a path delimiter
> -	je	@f2
> -	movb	[si], '\\'		; no, add separator between path & name
> -	inc	si
> -@f2:
> -	call	do_exec			; copy our name to string and try load
> -	jc	loadloop
> +check_dpmi:
> +	push	es
> +	push	cx
> +	push	di
> +	push	si
> +	mov	ax, 0x1687		; get DPMI entry point
> +	int	0x2f
> +	mov	dx, bx
> +	or	dl, 1			; bx bit 0: 32-bit capable
> +	xor	bx, dx
> +	or	ax, bx			; DPMI present if ax = 0
> +	jnz	@f1
> +	mov	[modesw], di		; store the DPMI entry point
> +	mov	[modesw+2], es
> +	mov	[modesw_mem], si
> +@f1:
> +	pop	si
> +	pop	di
> +	pop	cx
> +	pop	es
>  	ret
>  
>  ;-----------------------------------------------------------------------------
> @@ -766,13 +770,6 @@ do_exec:
>  	int	0x21
>  	pop	di
>  	pop	es
> -	jc	@f1			;carry set if exec failed
> -
> -	mov	ah, 0x4d		;get return code
> -	int	0x21
> -	sub	ax, 0x300		;ah=3 TSR, al=code (success)
> -	neg	ax			;CY, if not originally 0x300
> -@f1:
>  	jmp	restore_umb		;called func. return for us.
>  
>  ;-----------------------------------------------------------------------------
> @@ -796,10 +793,9 @@ include_umb:
>  @f1:
>  	ret
>  
> -; Restore upper memory status.  All registers and flags preserved.
> +; Restore upper memory status.  All registers preserved.
>  
>  restore_umb:
> -	pushf
>  	cmpb	[dos_major], 5		; Won't work before dos 5
>  	jb	@f1
>  	push	ax
> @@ -815,7 +811,6 @@ restore_umb:
>  	pop	bx
>  	pop	ax
>  @f1:
> -	popf
>  	ret
>  
>  ;-----------------------------------------------------------------------------
> @@ -840,6 +835,8 @@ msg_no_selectors:
>  	.db	"no DPMI selectors$"
>  msg_no_dpmi_memory:
>  	.db	"no DPMI memory$"
> +path_off:
> +	.dw	0			; Points to PATH, stays zero if none.
>  
>  ;-----------------------------------------------------------------------------
>  ;  Unstored Data, available during and after mode switch
> 

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019