Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

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

posted by tgr(R), 07.11.2011, 16:31


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
    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.



Complete thread:

Back to the forum
Board view  Mix view
15297 Postings in 1378 Threads, 254 registered users, 12 users online (0 registered, 12 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum