Date: Wed, 17 Feb 1999 09:26:56 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: DJ Delorie , Charles Sandmann cc: djgpp-workers AT delorie DOT com Subject: Passing FLAGS from RMCBs Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com Somebody complained on c.o.m.d. that the flags set in an RMCB don't get reflected back to the real-mode. See the thread called "How to check the carry flag?" for details (the case in point was the keyboard intercept call-out, Int 15h/AH=4Fh). It turns out the wrapper set up by gormcb.c overwrites the flags in the real-mode call structure with its original value (taken from the real-mode stack). A relevant portion of the wrapper is attached to this message. As you see, it takes the flags pushed onto the real-mode stack from [esi+4] and plugs them into [edi+32], where the flags are stored in the __dpmi_regs structure passed to the user-defined callback. This means it is impossible to modify flags that are returned to the real mode. I'm guessing that this was done for safety reasons (e.g., imagine that the user code messes with the flags and sets, say, the V86 flag there ;-). Is that the only reason? If safety is all we need to be concerned about, we could mask off the dangerous bits (i.e. pass them as they were originally pushed onto the real-mode stack), but allow to pass those which cannot hurt. I think at least CF and ZF should be passed, and possibly some more. Comments? static unsigned char wrapper_iret[] = { 0x66, 0x8b, 0x46, 0x04, /* mov ax,[esi+4] */ 0x66, 0x26, 0x89, 0x47, 0x20, /* mov es:[edi+32],ax */ 0x66, 0x26, 0x83, 0x47, 0x2e, 0x06, /* add es:[edi+46],0x6 */ 0xcf /* iret */ };