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:subject:from:to:content-language :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=p114woUuNH2TXQ9/OqSydOUNLwc0gDLuBMo+elqe5yo=; b=cyQ4RnkRAYftE2NFwKNTOCnMxCsLO6pC10Lufu/nqBhUVv13umXWIeOZnfOtYvzUlQ kZI4cqp5Zmb/wBBYqzC7BzdFJcFxZwkK+hG/rZqwK5bAC1K9qPIIyYDEmN4UNAHdSj2N 3tOtDsTflJbOmISLVad+tx9BD+PGy9RnKzR1B9VYI51Du4Rg9a/if/set7CGWsPSzrsf dE5gLZC8hjj/ZoQKJ7qfYaufVh6zOhLvfvkgtCMZh1JIT7Hfz3rK0KvMRMvMsSS6qjyQ uFpDhMiDK1IE9ZxqD6WBot6jP78SGJ79Cbp4FI0EUnNNG/3jJl/z0jzhzqjtYWxxxZPY 50Mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:subject:from:to:content-language :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=p114woUuNH2TXQ9/OqSydOUNLwc0gDLuBMo+elqe5yo=; b=zVmIL8ClbcfmEJLdNa22NEVYS613UnkIhTr2a2NLDit4CtrqHva4V+MeFBLNJVD4tU xJpNDVnw0AZSh2zNMs7Tdo9IGei7W5swWUE1cwQEGvPQWL4uzfJLLHp4ajU2UBkvn0Qo a9oQBqHWB+KanDXjtULZuq5iwbPzXGI35GQllEozYBGI7MBaGy9pIRwqvD5ZoTYejLQQ kmHx6TDafGbvHQnl+TFKv5H9Qvelyxw9W3+TEb7Ym3NbTSs3Fc0o80npnjAbAVQq2BTy F51cmRoZ/FthqtPYAfLDx4OawhwsmXIPEDzTySKHP5JxCfYTNqPEGnO/BzR0i+gUeT7I WF4A== X-Gm-Message-State: ANoB5pmdDpIULbGoQrgSqnuh27sQ8PWRc1TQZWWuMFHWsITqfI5i23/y zTbmtWrblsgil5/oOG5AUx9oWEvR+5Q= X-Google-Smtp-Source: AA0mqf6qkqf5PqXjGmvhhHX0IbbSyOX6EFX8onguNoWYG14SMboT6Wr6Wyjk3hDYNmcFbl3TGfBe3A== X-Received: by 2002:aa7:ccd3:0:b0:468:f345:aa4a with SMTP id y19-20020aa7ccd3000000b00468f345aa4amr26231002edt.412.1669232826623; Wed, 23 Nov 2022 11:47:06 -0800 (PST) Message-ID: <744f054f-9682-4a05-91ad-684b18c0122b@gmail.com> Date: Wed, 23 Nov 2022 20:47:05 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.5.0 Content-Language: en-US To: djgpp AT delorie DOT com From: "J.W. Jagersma (jwjagersma AT gmail DOT com) [via djgpp AT delorie DOT com]" Subject: [PATCH] stub: ignore host exit status Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com 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. --- a/src/stub/stub.asm +++ b/src/stub/stub.asm @@ -199,33 +199,61 @@ not_path: ;----------------------------------------------------------------------------- ; Get DPMI information before doing anything 386-specific + push di + xor cx, cx + ; 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) +check_dpmi: push es push di - xor cx, cx ; flag for load attempt set cx = 0 - jz @f2 ; We always jump, shorter than jmp -@b1: - 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 -@f2: + push si + push cx mov ax, 0x1687 ; get DPMI entry point int 0x2f + pop cx or ax, ax - jnz @b2 ; if 0 then it's there + jnz @f1 ; if 0 then it's there and bl, 1 ; 32 bit capable? - jz @b2 + jnz have_dpmi +@f1: + jcxz @f2 ; cx=0 while we have more paths to try + mov al, 110 + mov dx, msg_no_dpmi + jmpl error +@f2: + pop si + pop di + pop es + call do_exec ; copy our name to string and try load + ; 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 @f3 ; If ';', continue + dec di ; else point at null for next pass. @f3: + inc cx + cmp si, loadname ; anything there? + je check_dpmi ; final try (no path) + dec cx + mov al, [si-1] + call test_delim ; is final character a path delimiter + je check_dpmi + movb [si], '\\' ; no, add separator between path & name + inc si + jmp check_dpmi +have_dpmi: mov [modesw], di ; store the DPMI entry point mov [modesw+2], es mov [modesw_mem], si pop di + pop di pop es + pop di ;----------------------------------------------------------------------------- ; Now, find the name of the program file we are supposed to load. @@ -699,39 +727,6 @@ pm_dos: int 0x31 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 - -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 - ret - ;----------------------------------------------------------------------------- ; add the string CWSDPMI to path ending @@ -766,13 +761,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. ;----------------------------------------------------------------------------- @@ -840,6 +828,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