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 |