Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the board
Thread view  Mix view  Order
tgr(R)

07.11.2011, 16:31
 

Unable to return from DPMI real mode callback. (Miscellaneous)

Hi,

I am in the process of porting a 16 bit application (running in RM under DOS 6.22) to a 32 bit (PM) application by compiling it using the Watcom compiler and using the Causeway DOS extender.

The 16 bit application is communicating over TCP/IP using the WATTCP (16 bit) driver. The application registers a callback with the driver.
I have found that I should be able to register a callback function from my 32 bit PM application in same manor using DPMI.

I have made a small test application to first get a better understanding of DPMI. I am able to allocate DOS memory and to get packet driver info and MAC address using the DPMI "simulate real mode interrupt" function on the packet driver interrupt functions... works like a charm.
I have also managed to register my callback function. My callback gets called whenever a packet of the desired type arrives. By the time my callback is called, the real mode register data structure contains the values that I expect in relation to the packet driver documentation (-> BX= handle; -> AX= rqst buffer for data rcvd; ->CX = size of data) .

The part that is currently causing me a HUGE headache is returning from the callback function to the packet driver. I can't seem to correctly obtain the real mode return address from DS:ESI and put it into CS:IP of my real mode data structure.

The behavior that I am observing is that my test application just hangs once it has finished executing my callback (I would expect packet driver to discard packet and call callback again at arrival of next packet).

At first glance the description in the DPMI spec seems pretty straight forward. I have also googled a lot of examples that also seem pretty straigt forward... I just can't get it to work in my case. I have noticed that most of the examples I have seen appears to be 16bit (i.e. using 16 bit registers rather than 32 bit). Are there any pitfalls for 32bit?

The DPMI spec mentions that obtaining the return address is typically done by extracting it from the real mode stack - are there any other ways? I could really use some input of how to deal with the real mode stack.

Currently my callback looks something like this:


void interrupt callback(void)
{
    unsigned short ArgIP, ArgCS, RetFlags; 
    _asm { 
        cld              ; Clear direction (incr DS:ESI index after lodsw)
        lodsw            ; Load word at address DS:ESI into AX
        mov ArgIP, ax      ; AX into variable ArgIP
        lodsw            ; Load word at address DS:ESI + 1
        mov ArgCS, ax      ; AX into variable ArgCS
        lodsw            ; Load word at address DS:ESI + 2
        mov RetFlags, ax ; AX into variable RetFlags
    }
    cbCount++;
    callbackFlag= true;

    pRmRegs->es= 0;   // tell packet driver to discard packet (no buffer)
    pRmRegs->edi= 0; // tell packet driver to discard packet (no buffer)
    pRmRegs->ip= ArgIP;
    pRmRegs->cs= ArgCS;
    pRmRegs->flags= RetFlags;
    pRmRegs->sp+= 6;
}

I have verified that for the above code, the ip, cs and flags fields of my real mode register data structure contains the values of the first 6 bytes adressed by DS:ESI

What am I missing? Thanks in advance.

BR
Thomas

Japheth(R)

Homepage

Germany (South),
07.11.2011, 17:29

@ tgr

Unable to return from DPMI real mode callback.

> What am I missing? Thanks in advance.

It might be that you are NOT supposed to "pop" the flags from the real-mode stack. This depends on how your callback is called from real-mode. If it is just a far call, then you "should" NOT "pop" the flags - that is, pRmRegs->sp is to be increased by 4 only, not 6.

---
MS-DOS forever!

tgr(R)

08.11.2011, 23:15

@ Japheth

Unable to return from DPMI real mode callback.

> > What am I missing? Thanks in advance.
>
> It might be that you are NOT supposed to "pop" the flags from the real-mode
> stack. This depends on how your callback is called from real-mode. If it is
> just a far call, then you "should" NOT "pop" the flags - that is,
> pRmRegs->sp is to be increased by 4 only, not 6.

Thanks for the quick response.

I have tried incrementing pRmRegs->sp by only 4 but with same result (application seems to hang at end of execution of callback)

Is it correctly understood that the real mode stack is a "raw" copy reflecting a 16 bit environment having 16 bit register pushed to it (meaning it is IP rather than EIP that is on top of the real mode stack)?


BR
Thomas

Japheth(R)

Homepage

Germany (South),
09.11.2011, 05:33

@ tgr

Unable to return from DPMI real mode callback.

> Is it correctly understood that the real mode stack is a "raw" copy
> reflecting a 16 bit environment having 16 bit register pushed to it
> (meaning it is IP rather than EIP that is on top of the real mode stack)?

Yes. The Highword of EIP cannot be accessed in real-mode - and it is always 0.

Looking at your code sample, I wonder where register DS is loaded to access global variables ( i.e. cbCount and pRmRegs ). IMO it's very unlikely that the real-mode stack (DS:ESI) and your application's data segment are the same.

---
MS-DOS forever!

Back to the board
Thread view  Mix view  Order
15112 Postings in 1359 Threads, 247 registered users, 16 users online (0 registered, 16 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum