From: Leif Leonhardy Newsgroups: comp.os.msdos.djgpp Subject: Re: __dpmi_simulate_real_mode_procedure_retf[stack](): Links to bug fixes? FAQ? Date: Sat, 08 Sep 2001 12:36:42 +0200 Organization: delta t Computerservice Lines: 254 Message-ID: <3B99F4BA.D0753BF0@dtcs.de> References: <3B9993B7 DOT 7673E4B7 AT dtcs DOT de> <3405-Sat08Sep2001095723+0300-eliz AT is DOT elta DOT co DOT il> NNTP-Posting-Host: pd9e0e1c2.dip0.t-ipconnect.de Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news.online.de 999945327 28875 217.224.225.194 (8 Sep 2001 10:35:27 GMT) X-Complaints-To: abuse AT online DOT de NNTP-Posting-Date: 8 Sep 2001 10:35:27 GMT Cc: leif AT dtcs DOT de X-Mailer: Mozilla 4.01 [de] (Win95; I) X-Priority: 3 (Normal) To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Eli Zaretskii schrieb: > > > From: Leif Leonhardy > > Newsgroups: comp.os.msdos.djgpp > > Date: Sat, 08 Sep 2001 05:42:47 +0200 > > > > PROBLEM: passing arguments to real mode procedures via the (which?!) > > stack > > I tried BOTH __dpmi_simulate_real_mode_procedure_retf_stack() > > AND __dpmi_simulate_real_mode_procedure_retf() setting up > > the stack (regs.x.ss, regs.x.sp) by myself - with exactly > > the same results. > > > > Few minutes ago ;-) I was happy to find a patch for d0301_s.S (from > > about a year ago), not immediately realizing that this patch wouldn't > > solve my problem because the function without the extra stack parame- > > ters behaves exactly (?) the same :-( > > Sorry, I don't understand this. d0301_s.S, as shipped with DJGPP > v2.03 indeed has a bug (all older versions also had a bug, albeit a > different and more grave one). But what do you mean by the last > sentence above? What does ``without the extra stack parameters'' > mean? There are two functions, __dpmi_simulate_real_mode_function_retf(__dpmi_regs r) and __dpmi_simulate_real_mode_function_retf_stack(__dpmi_regs r,int num_stack_words,short *stack), of which the latter does just a little bit more than the first, namely copying stack words supplied in the (protected-mode) array stack onto the (DPMI clients) protected-mode stack. Both functions use _the same_ DPMI int (0301h). The DPMI function 0301h now again copies stack words from the protected- mode stack to the real-mode stack. The number of words to copy is specified by the _processor register_ %ecx (and _not_ regs.x.cx), while the real-mode stack is specified through regs.x.ss:regs.x.sp. If SS:SP in the regs structure is zero, the DPMI host allocates (or reuses) a real-mode (conventional memory) stack area. [Believe me, I try to check all sources and to fix the bug myself before I post a 'all bad-nothing works'.] Since __dpmi_simulate_real_mode_function_retf() clears %ecx, nothing is copied in that case. None of the two djgpp functions deals with the stack specified in the regs structure (zero or not), this is solely handled by the DPMI host. The posted patch applies only to d0301_s.S (...retf_stack()), not to d0301.S (...retf()); the fixed bug was exactly in the stack-copying, so if there really is a bug, it must be in both functions, because their behaviour is identical (see below). > Anyway, I append below the fixed source of d0301_s.S. I think it > should solve your problem, although it's a bit hard to know, what with > all the text you wrote without showing a single code line or > explaining what exactly doesn't work ;-) (It's possible that the patch > you saw was for an earlier version of the function, i.e. for e a > different bug.) This is not the case. Sorry for not providing my code; this is due to its uglyness caused by debugging code and __the_really_very_long_function_names ;-) I first tried to work-around the known bug by using the 'shorter' function, which avoids the copying in question, but both functions fail in the same manner, so the bug must be elsewhere (ok, possibly in my code). > > It's still there because no new versions of DJGPP were released since > the bug was discovered. The patches are published precisely for that > reason: so people who cannot wait for the next official release could > patch their libraries and go on with their coding. Is there a diff-central? I found it hard to track articles dealing with these (or the _go32-)functions posted in 1995, 1997, 1999 and later. > Finally, your ``which stack?'' question seems to indicate that you are > unsure how to pass the data on stack to these functions. The "which %&$*:! stack?" should read: "I am sure the real-mode procedure is using *some* stack, but not the one I've specified nor does this stack in any way relate to (the values of) the protected-mode stack." > Assuming you use __dpmi_simulate_real_mode_procedure_retf_stack (which > is what you _should_ use), ... The DPMI spec limits the size of the stack provided in case no stack is explicitly specified by the caller (SS:SP==0), so the _safe_ way should be to allocate one - big enough for the specific function(s). And, if we do that, the ...retf_stack() function is completely super- fluous because we can poke() (or movedata()) the data directly onto the real-mode stack in conventional memory, saving one or two times copying. > If this still doesn't help, please post the fragment of your code > which invokes __dpmi_simulate_real_mode_procedure_retf_stack to call > the ASPI manager. Ok, but I will abstract from ASPI manager, since my problem can be shown (much?) simpler: ------8<----------------8<------cut-here-------8<---------8<------------ /* bug.c -- test GO32's __dpmi_simulate_real_mode_procedure_retf[_stack]() */ #include #include #include int test_RM_call() { __dpmi_regs regs; int the_RM_address_to_call; /* high word: SEG, low word OFFSET */ short words_to_put_onto_RM_stack[2]; int conv_mem_seg; /* RM segment for conventional memory area */ int conv_mem_sel; /* PM selector for conventional memory area */ unsigned conv_mem_size; /* size of conv. mem. area in bytes */ unsigned conv_mem_paras; /* size of conv. mem. area in paragraphs */ conv_mem_size=0x200; /* 512 bytes */ conv_mem_paras=(conv_mem_size+15)/16; /* round up to paragraph boundary */ /* Allocate conv. mem. area: */ if((conv_mem_seg=__dpmi_allocate_dos_memory(conv_mem_paras,&conv_mem_sel)) ==-1) { printf("__dpmi_allocate_dos_memory() failed!\n"); return 1; } /* Should possibly clear allocated area... (NYI) */ /* Put RM code to call into this area: */ _farpokeb(conv_mem_sel,0,0xB8); /* B8 11 47 = mov ax,4711h */ _farpokeb(conv_mem_sel,1,0x11); _farpokeb(conv_mem_sel,2,0x47); _farpokeb(conv_mem_sel,3,0xCB); /* CB = retf */ /* Address to call is first byte of allocated area: */ the_RM_address_to_call=(conv_mem_seg<<16)|(0/*conv_mem_off*/); /* Now (try to) call it: */ regs.x.flags=0; regs.x.ss=0; /* DPMI function has to provide stack */ regs.x.sp=0; regs.x.cs=the_RM_address_to_call>>16; /* segment of address */ regs.x.ip=the_RM_address_to_call&0xffff; /* offset of address */ if(__dpmi_simulate_real_mode_procedure_retf(®s)!=0) { printf("__dpmi_simulate_real_mode_procedure_retf() failed!\n"); return 2; } printf("Real mode function returned, AX=%hXh\n",regs.x.ax); /* Modify function code such that first parameter on stack will be */ /* returned in AX (second in BX if specified): */ _farpokeb(conv_mem_sel,0,0x5B); /* 5B = pop bx ; return address */ _farpokeb(conv_mem_sel,1,0x58); /* 58 = pop ax ; first parameter */ _farpokeb(conv_mem_sel,2,0x50); /* 50 = push ax ; first parameter */ _farpokeb(conv_mem_sel,3,0x53); /* 53 = push bx ; return address */ _farpokeb(conv_mem_sel,4,0xCB); /* CB = retf */ /* Now call it with parameter(s) on the stack: */ words_to_put_onto_RM_stack[0]=0xAFFE; /* Affe: German for "ape" */ words_to_put_onto_RM_stack[1]=0xDEAD; regs.x.flags=0; regs.x.ss=0; /* DPMI function has to provide stack */ regs.x.sp=0; regs.x.cs=the_RM_address_to_call>>16; /* segment of address */ regs.x.ip=the_RM_address_to_call&0xffff; /* offset of address */ if(__dpmi_simulate_real_mode_procedure_retf_stack(®s, 2 /* words */, words_to_put_onto_RM_stack)!=0) { printf("__dpmi_simulate_real_mode_procedure_retf_stack() failed!\n"); return 3; } printf("Real mode function returned, AX=%hXh, BX=%hXh\n", regs.x.ax,regs.x.bx); printf("Now setting up RM stack by myself...\n"); words_to_put_onto_RM_stack[0]=0x0815; words_to_put_onto_RM_stack[1]=0x4711; regs.x.ss=conv_mem_seg; regs.x.sp=conv_mem_size-4; /* stacks grows from ..._size to 0 */ _farpokew(conv_mem_sel,conv_mem_size-2,words_to_put_onto_RM_stack[0]); _farpokew(conv_mem_sel,conv_mem_size-4,words_to_put_onto_RM_stack[1]); /* Now call it with parameter(s) on my stack: */ regs.x.flags=0; regs.x.cs=the_RM_address_to_call>>16; /* segment of address */ regs.x.ip=the_RM_address_to_call&0xffff; /* offset of address */ regs.x.ax=regs.x.bx=0; /* clear to see that function actually changed it */ if(__dpmi_simulate_real_mode_procedure_retf(®s)!=0) { printf("__dpmi_simulate_real_mode_procedure_retf() failed!\n"); return; } printf("Real mode function returned, AX=%hXh, BX=%hXh\n", regs.x.ax,regs.x.bx); return 0; } main() { return test_RM_call(); } ------8<----------------8<------cut-here-------8<---------8<------------ F:\GCC\go33\dtcs\aspi>gcc -o bug bug.c F:\GCC\go33\dtcs\aspi>bug Real mode function returned, AX=4711h Real mode function returned, AX=FCB2h, BX=2FF7h Now setting up RM stack by myself... Real mode function returned, AX=FCB2h, BX=2FF7h F:\GCC\go33\dtcs\aspi> ------8<----------------8<------cut-here-------8<---------8<------------ In a few words: - I construct the code to be called in a real-mode buffer to assure that the function (address) is actually called and this call works (AX=4711h, set by called function) - Then I call a modified function (same address) with two parameters via ..._retf_stack(), the passed parameters should be returned in AX and BX - Finally I set up the real-mode stack in the same buffer, but on the other end (512 bytes total are enough here) Again, the passed parameters should be returned in AX and BX As you can see, both calls result in the _same_, unexpected values. Would be nice to hear you can observe the same (the unexpected values will probably differ, but be the same for both calls). Nicer to hear would be "Idiot, typo at line...", or "alloc_brain() failed", though I RTFMs [And if someone has a free ASPI library working, this would be fine to hear, too.] Leif tags omitted in last post, sorry.