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]" 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> Content-Language: en-US In-Reply-To: <21e1aa0b-1511-0071-84c0-b20c6a3d1dae@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 Precedence: bulk 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 >