- Return old code for handling parameters to GetCharacterPlacement (+
[wine] / memory / instr.c
index c586cf4..f1a30d2 100644 (file)
@@ -1,51 +1,62 @@
 /*
- * Emulation of priviledged instructions
+ * Emulation of privileged instructions
  *
  * Copyright 1995 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "windef.h"
+#include "wingdi.h"
 #include "wine/winuser16.h"
-#include "ldt.h"
-#include "global.h"
 #include "module.h"
-#include "dosexe.h"
 #include "miscemu.h"
-#include "sig_context.h"
 #include "selectors.h"
-#include "debugtools.h"
+#include "wine/debug.h"
 
-DECLARE_DEBUG_CHANNEL(int)
-DECLARE_DEBUG_CHANNEL(io)
+WINE_DEFAULT_DEBUG_CHANNEL(int);
+WINE_DECLARE_DEBUG_CHANNEL(io);
 
 #ifdef __i386__
 
-#define IS_V86(context) (EFL_sig(context)&V86_FLAG)
-#define IS_SEL_32(context,seg) \
-   (IS_V86(context) ? FALSE : IS_SELECTOR_32BIT(seg))
-
-#define STACK_sig(context) \
-   (IS_SEL_32(context,SS_sig(context)) ? ESP_sig(context) : (DWORD)SP_sig(context))
-
-#define ADD_STACK_sig(context,offset) \
-   do { if (IS_SEL_32(context,SS_sig(context))) ESP_sig(context) += (offset); \
-        else SP_sig(context) += (offset); } while(0)
-
-#define MAKE_PTR(seg,off) \
-   (IS_SELECTOR_SYSTEM(seg) ? (void *)(off) : PTR_SEG_OFF_TO_LIN(seg,off))
-
-#define MK_PTR(context,seg,off) \
-   (IS_V86(context) ? DOSMEM_MapRealToLinear(MAKELONG(off,seg)) \
-                    : MAKE_PTR(seg,off))
-
-#define STACK_PTR(context) \
-   (IS_V86(context) ? DOSMEM_MapRealToLinear(MAKELONG(SP_sig(context),SS_sig(context))) : \
-    (IS_SELECTOR_SYSTEM(SS_sig(context)) ? (void *)ESP_sig(context) : \
-     (PTR_SEG_OFF_TO_LIN(SS_sig(context),STACK_sig(context)))))
+inline static void add_stack( CONTEXT86 *context, int offset )
+{
+    if (ISV86(context) || !IS_SELECTOR_32BIT(context->SegSs))
+        ADD_LOWORD( context->Esp, offset );
+    else
+        context->Esp += offset;
+}
 
-/* For invalid registers fixup */
-extern DWORD CallFrom16_Start,CallFrom16_End;
-extern DWORD CALLTO16_Start,CALLTO16_End;
+inline static void *make_ptr( CONTEXT86 *context, DWORD seg, DWORD off, int long_addr )
+{
+    if (ISV86(context)) return PTR_REAL_TO_LIN( seg, off );
+    if (IS_SELECTOR_SYSTEM(seg)) return (void *)off;
+    if (!long_addr) off = LOWORD(off);
+    return (char *) MapSL( MAKESEGPTR( seg, 0 ) ) + off;
+}
 
+inline static void *get_stack( CONTEXT86 *context )
+{
+    if (ISV86(context))
+        return PTR_REAL_TO_LIN( context->SegSs, context->Esp );
+    if (IS_SELECTOR_SYSTEM(context->SegSs))
+        return (void *)context->Esp;
+    if (IS_SELECTOR_32BIT(context->SegSs))
+        return (char *) MapSL( MAKESEGPTR( context->SegSs, 0 ) ) + context->Esp;
+    return MapSL( MAKESEGPTR( context->SegSs, LOWORD(context->Esp) ) );
+}
 
 /***********************************************************************
  *           INSTR_ReplaceSelector
@@ -53,18 +64,18 @@ extern DWORD CALLTO16_Start,CALLTO16_End;
  * Try to replace an invalid selector by a valid one.
  * The only selector where it is allowed to do "mov ax,40;mov es,ax"
  * is the so called 'bimodal' selector 0x40, which points to the BIOS
- * data segment. Used by (at least) Borland products (and programs compiled 
+ * data segment. Used by (at least) Borland products (and programs compiled
  * using Borland products).
  *
  * See Undocumented Windows, Chapter 5, __0040.
  */
-static BOOL INSTR_ReplaceSelector( SIGCONTEXT *context, WORD *sel )
+static BOOL INSTR_ReplaceSelector( CONTEXT86 *context, WORD *sel )
 {
-    if ( IS_SELECTOR_SYSTEM(CS_sig(context)) )
-        if (    ( EIP_sig(context) >= (DWORD)&CallFrom16_Start &&
-                  EIP_sig(context) <  (DWORD)&CallFrom16_End )
-             || ( EIP_sig(context) >= (DWORD)&CALLTO16_Start &&
-                  EIP_sig(context) <  (DWORD)&CALLTO16_End ) )
+    extern char Call16_Start, Call16_End;
+
+    if (IS_SELECTOR_SYSTEM(context->SegCs))
+        if (    (char *)context->Eip >= &Call16_Start
+             && (char *)context->Eip <  &Call16_End   )
         {
             /* Saved selector may have become invalid when the relay code */
             /* tries to restore it. We simply clear it. */
@@ -81,7 +92,7 @@ static BOOL INSTR_ReplaceSelector( SIGCONTEXT *context, WORD *sel )
         return TRUE;
     }
     if (!IS_SELECTOR_SYSTEM(*sel) && !IS_SELECTOR_FREE(*sel))
-        ERR_(int)("Got protection fault on valid selector, maybe your kernel is too old?\n" );
+        ERR("Got protection fault on valid selector, maybe your kernel is too old?\n" );
     return FALSE;  /* Can't replace selector, crashdump */
 }
 
@@ -91,7 +102,7 @@ static BOOL INSTR_ReplaceSelector( SIGCONTEXT *context, WORD *sel )
  *
  * Return the address of an instruction operand (from the mod/rm byte).
  */
-static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
+static BYTE *INSTR_GetOperandAddr( CONTEXT86 *context, BYTE *instr,
                                    int long_addr, int segprefix, int *len )
 {
     int mod, rm, base, index = 0, ss = 0, seg = 0, off;
@@ -108,14 +119,14 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
     {
         switch(rm)
         {
-        case 0: return (BYTE *)&EAX_sig(context);
-        case 1: return (BYTE *)&ECX_sig(context);
-        case 2: return (BYTE *)&EDX_sig(context);
-        case 3: return (BYTE *)&EBX_sig(context);
-        case 4: return (BYTE *)&ESP_sig(context);
-        case 5: return (BYTE *)&EBP_sig(context);
-        case 6: return (BYTE *)&ESI_sig(context);
-        case 7: return (BYTE *)&EDI_sig(context);
+        case 0: return (BYTE *)&context->Eax;
+        case 1: return (BYTE *)&context->Ecx;
+        case 2: return (BYTE *)&context->Edx;
+        case 3: return (BYTE *)&context->Ebx;
+        case 4: return (BYTE *)&context->Esp;
+        case 5: return (BYTE *)&context->Ebp;
+        case 6: return (BYTE *)&context->Esi;
+        case 7: return (BYTE *)&context->Edi;
         }
     }
 
@@ -129,27 +140,27 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
             ss = sib >> 6;
             switch(sib >> 3)
             {
-            case 0: index = EAX_sig(context); break;
-            case 1: index = ECX_sig(context); break;
-            case 2: index = EDX_sig(context); break;
-            case 3: index = EBX_sig(context); break;
+            case 0: index = context->Eax; break;
+            case 1: index = context->Ecx; break;
+            case 2: index = context->Edx; break;
+            case 3: index = context->Ebx; break;
             case 4: index = 0; break;
-            case 5: index = EBP_sig(context); break;
-            case 6: index = ESI_sig(context); break;
-            case 7: index = EDI_sig(context); break;
+            case 5: index = context->Ebp; break;
+            case 6: index = context->Esi; break;
+            case 7: index = context->Edi; break;
             }
         }
 
         switch(rm)
         {
-        case 0: base = EAX_sig(context); seg = DS_sig(context); break;
-        case 1: base = ECX_sig(context); seg = DS_sig(context); break;
-        case 2: base = EDX_sig(context); seg = DS_sig(context); break;
-        case 3: base = EBX_sig(context); seg = DS_sig(context); break;
-        case 4: base = ESP_sig(context); seg = SS_sig(context); break;
-        case 5: base = EBP_sig(context); seg = SS_sig(context); break;
-        case 6: base = ESI_sig(context); seg = DS_sig(context); break;
-        case 7: base = EDI_sig(context); seg = DS_sig(context); break;
+        case 0: base = context->Eax; seg = context->SegDs; break;
+        case 1: base = context->Ecx; seg = context->SegDs; break;
+        case 2: base = context->Edx; seg = context->SegDs; break;
+        case 3: base = context->Ebx; seg = context->SegDs; break;
+        case 4: base = context->Esp; seg = context->SegSs; break;
+        case 5: base = context->Ebp; seg = context->SegSs; break;
+        case 6: base = context->Esi; seg = context->SegDs; break;
+        case 7: base = context->Edi; seg = context->SegDs; break;
         }
         switch (mod)
         {
@@ -157,7 +168,7 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
             if (rm == 5)  /* special case: ds:(disp32) */
             {
                 GET_VAL( &base, DWORD );
-                seg = DS_sig(context);
+                seg = context->SegDs;
             }
             break;
 
@@ -177,36 +188,36 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
         switch(rm)
         {
         case 0:  /* ds:(bx,si) */
-            base = BX_sig(context) + SI_sig(context);
-            seg  = DS_sig(context);
+            base = LOWORD(context->Ebx) + LOWORD(context->Esi);
+            seg  = context->SegDs;
             break;
         case 1:  /* ds:(bx,di) */
-            base = BX_sig(context) + DI_sig(context);
-            seg  = DS_sig(context);
+            base = LOWORD(context->Ebx) + LOWORD(context->Edi);
+            seg  = context->SegDs;
             break;
         case 2:  /* ss:(bp,si) */
-            base = BP_sig(context) + SI_sig(context);
-            seg  = SS_sig(context);
+            base = LOWORD(context->Ebp) + LOWORD(context->Esi);
+            seg  = context->SegSs;
             break;
         case 3:  /* ss:(bp,di) */
-            base = BP_sig(context) + DI_sig(context);
-            seg  = SS_sig(context);
+            base = LOWORD(context->Ebp) + LOWORD(context->Edi);
+            seg  = context->SegSs;
             break;
         case 4:  /* ds:(si) */
-            base = SI_sig(context);
-            seg  = DS_sig(context);
+            base = LOWORD(context->Esi);
+            seg  = context->SegDs;
             break;
         case 5:  /* ds:(di) */
-            base = DI_sig(context);
-            seg  = DS_sig(context);
+            base = LOWORD(context->Edi);
+            seg  = context->SegDs;
             break;
         case 6:  /* ss:(bp) */
-            base = BP_sig(context);
-            seg  = SS_sig(context);
+            base = LOWORD(context->Ebp);
+            seg  = context->SegSs;
             break;
         case 7:  /* ds:(bx) */
-            base = BX_sig(context);
-            seg  = DS_sig(context);
+            base = LOWORD(context->Ebx);
+            seg  = context->SegDs;
             break;
         }
 
@@ -216,7 +227,7 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
             if (rm == 6)  /* special case: ds:(disp16) */
             {
                 GET_VAL( &base, WORD );
-                seg  = DS_sig(context);
+                seg  = context->SegDs;
             }
             break;
 
@@ -237,8 +248,8 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
     /* Make sure the segment and offset are valid */
     if (IS_SELECTOR_SYSTEM(seg)) return (BYTE *)(base + (index << ss));
     if (((seg & 7) != 7) || IS_SELECTOR_FREE(seg)) return NULL;
-    if (GET_SEL_LIMIT(seg) < (base + (index << ss))) return NULL;
-    return (BYTE *)PTR_SEG_OFF_TO_LIN( seg, (base + (index << ss)) );
+    if (wine_ldt_copy.limit[seg >> 3] < (base + (index << ss))) return NULL;
+    return (char *) MapSL( MAKESEGPTR( seg, 0 ) ) + base + (index << ss);
 #undef GET_VAL
 }
 
@@ -248,8 +259,8 @@ static BYTE *INSTR_GetOperandAddr( SIGCONTEXT *context, BYTE *instr,
  *
  * Emulate the LDS (and LES,LFS,etc.) instruction.
  */
-static BOOL INSTR_EmulateLDS( SIGCONTEXT *context, BYTE *instr, int long_op,
-                                int long_addr, int segprefix, int *len )
+static BOOL INSTR_EmulateLDS( CONTEXT86 *context, BYTE *instr, int long_op,
+                              int long_addr, int segprefix, int *len )
 {
     WORD seg;
     BYTE *regmodrm = instr + 1 + (*instr == 0x0f);
@@ -267,36 +278,36 @@ static BOOL INSTR_EmulateLDS( SIGCONTEXT *context, BYTE *instr, int long_op,
     switch((*regmodrm >> 3) & 7)
     {
     case 0:
-        if (long_op) EAX_sig(context) = *(DWORD *)addr;
-        else AX_sig(context) = *(WORD *)addr;
+        if (long_op) context->Eax = *(DWORD *)addr;
+        else SET_LOWORD(context->Eax,*(WORD *)addr);
         break;
     case 1:
-        if (long_op) ECX_sig(context) = *(DWORD *)addr;
-        else CX_sig(context) = *(WORD *)addr;
+        if (long_op) context->Ecx = *(DWORD *)addr;
+        else SET_LOWORD(context->Ecx,*(WORD *)addr);
         break;
     case 2:
-        if (long_op) EDX_sig(context) = *(DWORD *)addr;
-        else DX_sig(context) = *(WORD *)addr;
+        if (long_op) context->Edx = *(DWORD *)addr;
+        else SET_LOWORD(context->Edx,*(WORD *)addr);
         break;
     case 3:
-        if (long_op) EBX_sig(context) = *(DWORD *)addr;
-        else BX_sig(context) = *(WORD *)addr;
+        if (long_op) context->Ebx = *(DWORD *)addr;
+        else SET_LOWORD(context->Ebx,*(WORD *)addr);
         break;
     case 4:
-        if (long_op) ESP_sig(context) = *(DWORD *)addr;
-        else SP_sig(context) = *(WORD *)addr;
+        if (long_op) context->Esp = *(DWORD *)addr;
+        else SET_LOWORD(context->Esp,*(WORD *)addr);
         break;
     case 5:
-        if (long_op) EBP_sig(context) = *(DWORD *)addr;
-        else BP_sig(context) = *(WORD *)addr;
+        if (long_op) context->Ebp = *(DWORD *)addr;
+        else SET_LOWORD(context->Ebp,*(WORD *)addr);
         break;
     case 6:
-        if (long_op) ESI_sig(context) = *(DWORD *)addr;
-        else SI_sig(context) = *(WORD *)addr;
+        if (long_op) context->Esi = *(DWORD *)addr;
+        else SET_LOWORD(context->Esi,*(WORD *)addr);
         break;
     case 7:
-        if (long_op) EDI_sig(context) = *(DWORD *)addr;
-        else DI_sig(context) = *(WORD *)addr;
+        if (long_op) context->Edi = *(DWORD *)addr;
+        else SET_LOWORD(context->Edi,*(WORD *)addr);
         break;
     }
 
@@ -304,17 +315,13 @@ static BOOL INSTR_EmulateLDS( SIGCONTEXT *context, BYTE *instr, int long_op,
 
     switch(*instr)
     {
-    case 0xc4: ES_sig(context) = seg; break;  /* les */
-    case 0xc5: DS_sig(context) = seg; break;  /* lds */
+    case 0xc4: context->SegEs = seg; break;  /* les */
+    case 0xc5: context->SegDs = seg; break;  /* lds */
     case 0x0f: switch(instr[1])
                {
-               case 0xb2: SS_sig(context) = seg; break;  /* lss */
-#ifdef FS_sig
-               case 0xb4: FS_sig(context) = seg; break;  /* lfs */
-#endif
-#ifdef GS_sig
-               case 0xb5: GS_sig(context) = seg; break;  /* lgs */
-#endif
+               case 0xb2: context->SegSs = seg; break;  /* lss */
+               case 0xb4: context->SegFs = seg; break;  /* lfs */
+               case 0xb5: context->SegGs = seg; break;  /* lgs */
                }
                break;
     }
@@ -325,20 +332,78 @@ static BOOL INSTR_EmulateLDS( SIGCONTEXT *context, BYTE *instr, int long_op,
     return TRUE;
 }
 
+/***********************************************************************
+ *           INSTR_inport
+ *
+ * input on a I/O port
+ */
+static DWORD INSTR_inport( WORD port, int size, CONTEXT86 *context )
+{
+    DWORD res = IO_inport( port, size );
+    if (TRACE_ON(io))
+    {
+        switch(size)
+        {
+        case 1:
+            DPRINTF( "0x%x < %02x @ %04x:%04x\n", port, LOBYTE(res),
+                     (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        case 2:
+            DPRINTF( "0x%x < %04x @ %04x:%04x\n", port, LOWORD(res),
+                     (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        case 4:
+            DPRINTF( "0x%x < %08lx @ %04x:%04x\n", port, res,
+                     (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        }
+    }
+    return res;
+}
+
+
+/***********************************************************************
+ *           INSTR_outport
+ *
+ * output on a I/O port
+ */
+static void INSTR_outport( WORD port, int size, DWORD val, CONTEXT86 *context )
+{
+    IO_outport( port, size, val );
+    if (TRACE_ON(io))
+    {
+        switch(size)
+        {
+        case 1:
+            DPRINTF("0x%x > %02x @ %04x:%04x\n", port, LOBYTE(val),
+                    (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        case 2:
+            DPRINTF("0x%x > %04x @ %04x:%04x\n", port, LOWORD(val),
+                    (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        case 4:
+            DPRINTF("0x%x > %08lx @ %04x:%04x\n", port, val,
+                    (WORD)context->SegCs, LOWORD(context->Eip));
+            break;
+        }
+    }
+}
+
 
 /***********************************************************************
  *           INSTR_EmulateInstruction
  *
- * Emulate a priviledged instruction. Returns TRUE if emulation successful.
+ * Emulate a privileged instruction. Returns TRUE if emulation successful.
  */
-BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
+BOOL INSTR_EmulateInstruction( CONTEXT86 *context )
 {
     int prefix, segprefix, prefixlen, len, repX, long_op, long_addr;
     SEGPTR gpHandler;
     BYTE *instr;
 
-    long_op = long_addr = IS_SEL_32(context,CS_sig(context));
-    instr = (BYTE *)MK_PTR(context,CS_sig(context),EIP_sig(context));
+    long_op = long_addr = (!ISV86(context) && IS_SELECTOR_32BIT(context->SegCs));
+    instr = make_ptr( context, context->SegCs, context->Eip, TRUE );
     if (!instr) return FALSE;
 
     /* First handle any possible prefix */
@@ -352,27 +417,23 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
         switch(*instr)
         {
         case 0x2e:
-            segprefix = CS_sig(context);
+            segprefix = context->SegCs;
             break;
         case 0x36:
-            segprefix = SS_sig(context);
+            segprefix = context->SegSs;
             break;
         case 0x3e:
-            segprefix = DS_sig(context);
+            segprefix = context->SegDs;
             break;
         case 0x26:
-            segprefix = ES_sig(context);
+            segprefix = context->SegEs;
             break;
-#ifdef FS_sig
         case 0x64:
-            segprefix = FS_sig(context);
+            segprefix = context->SegFs;
             break;
-#endif
-#ifdef GS_sig
         case 0x65:
-            segprefix = GS_sig(context);
+            segprefix = context->SegGs;
             break;
-#endif
         case 0x66:
             long_op = !long_op;  /* opcode size prefix */
             break;
@@ -406,17 +467,17 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
         case 0x17: /* pop ss */
         case 0x1f: /* pop ds */
             {
-                WORD seg = *(WORD *)STACK_PTR( context );
+                WORD seg = *(WORD *)get_stack( context );
                 if (INSTR_ReplaceSelector( context, &seg ))
                 {
                     switch(*instr)
                     {
-                    case 0x07: ES_sig(context) = seg; break;
-                    case 0x17: SS_sig(context) = seg; break;
-                    case 0x1f: DS_sig(context) = seg; break;
+                    case 0x07: context->SegEs = seg; break;
+                    case 0x17: context->SegSs = seg; break;
+                    case 0x1f: context->SegDs = seg; break;
                     }
-                    ADD_STACK_sig(context, long_op ? 4 : 2);
-                    EIP_sig(context) += prefixlen + 1;
+                    add_stack(context, long_op ? 4 : 2);
+                    context->Eip += prefixlen + 1;
                     return TRUE;
                 }
             }
@@ -428,10 +489,9 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
            case 0x22: /* mov eax, crX */
                switch (instr[2]) {
                case 0xc0:
-                       fprintf(stderr,"mov eax,cr0 at 0x%08lx, EAX=0x%08lx\n",
-                               EIP_sig(context),EAX_sig(context)
-                       );
-                       EIP_sig(context) += prefixlen+3;
+                       ERR("mov eax,cr0 at 0x%08lx, EAX=0x%08lx\n",
+                            context->Eip,context->Eax );
+                        context->Eip += prefixlen+3;
                        return TRUE;
                default:
                        break; /*fallthrough to bad instruction handling */
@@ -451,61 +511,51 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
                     * bit 7: PGE   Enable global pages
                     * bit 8: PCE       Enable performance counters at IPL3
                     */
-                   fprintf(stderr,"mov cr4,eax at 0x%08lx\n",EIP_sig(context));
-                   EAX_sig(context) = 0;
-                   EIP_sig(context) += prefixlen+3;
+                    ERR("mov cr4,eax at 0x%08lx\n",context->Eip);
+                    context->Eax = 0;
+                    context->Eip += prefixlen+3;
                    return TRUE;
                case 0xc0: /* mov cr0, eax */
-                   fprintf(stderr,"mov cr0,eax at 0x%08lx\n",EIP_sig(context));
-                   EAX_sig(context) = 0x10; /* FIXME: set more bits ? */
-                   EIP_sig(context) += prefixlen+3;
+                    ERR("mov cr0,eax at 0x%08lx\n",context->Eip);
+                    context->Eax = 0x10; /* FIXME: set more bits ? */
+                    context->Eip += prefixlen+3;
                    return TRUE;
                default: /* fallthrough to illegal instruction */
                    break;
                }
                /* fallthrough to illegal instruction */
                break;
-#ifdef FS_sig
             case 0xa1: /* pop fs */
                 {
-                    WORD seg = *(WORD *)STACK_PTR( context );
+                    WORD seg = *(WORD *)get_stack( context );
                     if (INSTR_ReplaceSelector( context, &seg ))
                     {
-                        FS_sig(context) = seg;
-                        ADD_STACK_sig(context, long_op ? 4 : 2);
-                        EIP_sig(context) += prefixlen + 2;
+                        context->SegFs = seg;
+                        add_stack(context, long_op ? 4 : 2);
+                        context->Eip += prefixlen + 2;
                         return TRUE;
                     }
                 }
                 break;
-#endif  /* FS_sig */
-
-#ifdef GS_sig
             case 0xa9: /* pop gs */
                 {
-                    WORD seg = *(WORD *)STACK_PTR( context );
+                    WORD seg = *(WORD *)get_stack( context );
                     if (INSTR_ReplaceSelector( context, &seg ))
                     {
-                        GS_sig(context) = seg;
-                        ADD_STACK_sig(context, long_op ? 4 : 2);
-                        EIP_sig(context) += prefixlen + 2;
+                        context->SegGs = seg;
+                        add_stack(context, long_op ? 4 : 2);
+                        context->Eip += prefixlen + 2;
                         return TRUE;
                     }
                 }
                 break;
-#endif  /* GS_sig */
-
             case 0xb2: /* lss addr,reg */
-#ifdef FS_sig
             case 0xb4: /* lfs addr,reg */
-#endif
-#ifdef GS_sig
             case 0xb5: /* lgs addr,reg */
-#endif
                 if (INSTR_EmulateLDS( context, instr, long_op,
                                       long_addr, segprefix, &len ))
                 {
-                    EIP_sig(context) += prefixlen + len;
+                    context->Eip += prefixlen + len;
                     return TRUE;
                 }
                 break;
@@ -520,10 +570,10 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
              int typ = *instr;  /* Just in case it's overwritten.  */
              int outp = (typ >= 0x6e);
              unsigned long count = repX ?
-                          (long_addr ? ECX_sig(context) : CX_sig(context)) : 1;
+                          (long_addr ? context->Ecx : LOWORD(context->Ecx)) : 1;
              int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
-             int step = (EFL_sig(context) & 0x400) ? -opsize : +opsize;
-             int seg = outp ? DS_sig(context) : ES_sig(context);  /* FIXME: is this right? */
+             int step = (context->EFlags & 0x400) ? -opsize : +opsize;
+             int seg = outp ? context->SegDs : context->SegEs;  /* FIXME: is this right? */
 
              if (outp)
                /* FIXME: Check segment readable.  */
@@ -534,73 +584,50 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
 
              if (repX)
               {
-               if (long_addr)
-                 ECX_sig(context) = 0;
-               else
-                 CX_sig(context) = 0;
+               if (long_addr) context->Ecx = 0;
+               else SET_LOWORD(context->Ecx,0);
               }
 
              while (count-- > 0)
                {
                  void *data;
+                  WORD dx = LOWORD(context->Edx);
                  if (outp)
                   {
-                     data = MK_PTR(context, seg,
-                               long_addr ? ESI_sig(context) : SI_sig(context));
-                     if (long_addr) ESI_sig(context) += step;
-                     else SI_sig(context) += step;
+                      data = make_ptr( context, seg, context->Esi, long_addr );
+                      if (long_addr) context->Esi += step;
+                      else ADD_LOWORD(context->Esi,step);
                   }
                  else
                   {
-                     data = MK_PTR(context, seg,
-                               long_addr ? EDI_sig(context) : DI_sig(context));
-                     if (long_addr) EDI_sig(context) += step;
-                     else DI_sig(context) += step;
+                      data = make_ptr( context, seg, context->Edi, long_addr );
+                      if (long_addr) context->Edi += step;
+                      else ADD_LOWORD(context->Edi,step);
                   }
-                  
+
                  switch (typ)
                   {
                    case 0x6c:
-                     *((BYTE *)data) = IO_inport( DX_sig(context), 1);
-                     TRACE_(io)("0x%x < %02x @ %04x:%04x\n", DX_sig(context),
-                        *((BYTE *)data), CS_sig(context), IP_sig(context));
+                     *(BYTE *)data = INSTR_inport( dx, 1, context );
                      break;
                    case 0x6d:
                      if (long_op)
-                      {
-                       *((DWORD *)data) = IO_inport( DX_sig(context), 4);
-                        TRACE_(io)("0x%x < %08lx @ %04x:%04x\n", DX_sig(context),
-                          *((DWORD *)data), CS_sig(context), IP_sig(context));
-                      }
+                          *(DWORD *)data = INSTR_inport( dx, 4, context );
                      else
-                      {
-                       *((WORD *)data) = IO_inport( DX_sig(context), 2);
-                        TRACE_(io)("0x%x < %04x @ %04x:%04x\n", DX_sig(context),
-                          *((WORD *)data), CS_sig(context), IP_sig(context));
-                      }
+                          *(WORD *)data = INSTR_inport( dx, 2, context );
                      break;
                    case 0x6e:
-                        IO_outport( DX_sig(context), 1, *((BYTE *)data));
-                        TRACE_(io)("0x%x > %02x @ %04x:%04x\n", DX_sig(context),
-                          *((BYTE *)data), CS_sig(context), IP_sig(context));
+                        INSTR_outport( dx, 1, *(BYTE *)data, context );
                         break;
                    case 0x6f:
                         if (long_op)
-                        {
-                            IO_outport( DX_sig(context), 4, *((DWORD *)data));
-                            TRACE_(io)("0x%x > %08lx @ %04x:%04x\n", DX_sig(context),
-                              *((DWORD *)data), CS_sig(context), IP_sig(context)); 
-                        }
+                            INSTR_outport( dx, 4, *(DWORD *)data, context );
                         else
-                        {
-                            IO_outport( DX_sig(context), 2, *((WORD *)data));
-                            TRACE_(io)("0x%x > %04x @ %04x:%04x\n", DX_sig(context),
-                              *((WORD *)data), CS_sig(context), IP_sig(context));
-                        }
+                            INSTR_outport( dx, 2, *(WORD *)data, context );
                         break;
                    }
                }
-              EIP_sig(context) += prefixlen + 1;
+              context->Eip += prefixlen + 1;
            }
             return TRUE;
 
@@ -618,31 +645,27 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
                 switch((instr[1] >> 3) & 7)
                 {
                 case 0:
-                    ES_sig(context) = seg;
-                    EIP_sig(context) += prefixlen + len + 1;
+                    context->SegEs = seg;
+                    context->Eip += prefixlen + len + 1;
                     return TRUE;
                 case 1:  /* cs */
                     break;
                 case 2:
-                    SS_sig(context) = seg;
-                    EIP_sig(context) += prefixlen + len + 1;
+                    context->SegSs = seg;
+                    context->Eip += prefixlen + len + 1;
                     return TRUE;
                 case 3:
-                    DS_sig(context) = seg;
-                    EIP_sig(context) += prefixlen + len + 1;
+                    context->SegDs = seg;
+                    context->Eip += prefixlen + len + 1;
                     return TRUE;
-#ifdef FS_sig
                 case 4:
-                    FS_sig(context) = seg;
-                    EIP_sig(context) += prefixlen + len + 1;
+                    context->SegFs = seg;
+                    context->Eip += prefixlen + len + 1;
                     return TRUE;
-#endif
-#ifdef GS_sig
                 case 5:
-                    GS_sig(context) = seg;
-                    EIP_sig(context) += prefixlen + len + 1;
+                    context->SegGs = seg;
+                    context->Eip += prefixlen + len + 1;
                     return TRUE;
-#endif
                 case 6:  /* unused */
                 case 7:  /* unused */
                     break;
@@ -655,165 +678,130 @@ BOOL INSTR_EmulateInstruction( SIGCONTEXT *context )
             if (INSTR_EmulateLDS( context, instr, long_op,
                                   long_addr, segprefix, &len ))
             {
-                EIP_sig(context) += prefixlen + len;
+                context->Eip += prefixlen + len;
                 return TRUE;
             }
             break;  /* Unable to emulate it */
-            
+
         case 0xcd: /* int <XX> */
             if (long_op)
             {
-                ERR_(int)("int xx from 32-bit code is not supported.\n");
+                ERR("int xx from 32-bit code is not supported.\n");
                 break;  /* Unable to emulate it */
             }
             else
             {
                 FARPROC16 addr = INT_GetPMHandler( instr[1] );
-                WORD *stack = (WORD *)STACK_PTR( context );
+                WORD *stack = get_stack( context );
+                if (!addr)
+                {
+                    FIXME("no handler for interrupt %02x, ignoring it\n", instr[1]);
+                    context->Eip += prefixlen + 2;
+                    return TRUE;
+                }
                 /* Push the flags and return address on the stack */
-                *(--stack) = FL_sig(context);
-                *(--stack) = CS_sig(context);
-                *(--stack) = IP_sig(context) + prefixlen + 2;
-                ADD_STACK_sig(context, -3 * sizeof(WORD));
+                *(--stack) = LOWORD(context->EFlags);
+                *(--stack) = context->SegCs;
+                *(--stack) = LOWORD(context->Eip) + prefixlen + 2;
+                add_stack(context, -3 * sizeof(WORD));
                 /* Jump to the interrupt handler */
-                CS_sig(context)  = HIWORD(addr);
-                EIP_sig(context) = LOWORD(addr);
+                context->SegCs  = HIWORD(addr);
+                context->Eip = LOWORD(addr);
             }
             return TRUE;
 
         case 0xcf: /* iret */
             if (long_op)
             {
-                DWORD *stack = (DWORD *)STACK_PTR( context );
-                EIP_sig(context) = *stack++;
-                CS_sig(context)  = *stack++;
-                EFL_sig(context) = *stack;
-                ADD_STACK_sig(context, 3*sizeof(DWORD));  /* Pop the return address and flags */
+                DWORD *stack = get_stack( context );
+                context->Eip = *stack++;
+                context->SegCs  = *stack++;
+                context->EFlags = *stack;
+                add_stack(context, 3*sizeof(DWORD));  /* Pop the return address and flags */
             }
             else
             {
-                WORD *stack = (WORD *)STACK_PTR( context );
-                EIP_sig(context) = *stack++;
-                CS_sig(context)  = *stack++;
-                FL_sig(context)  = *stack;
-                ADD_STACK_sig(context, 3*sizeof(WORD));  /* Pop the return address and flags */
+                WORD *stack = get_stack( context );
+                context->Eip = *stack++;
+                context->SegCs  = *stack++;
+                SET_LOWORD(context->EFlags,*stack);
+                add_stack(context, 3*sizeof(WORD));  /* Pop the return address and flags */
             }
             return TRUE;
 
         case 0xe4: /* inb al,XX */
-            AL_sig(context) = IO_inport( instr[1], 1 );
-            TRACE_(io)("0x%x < %02x @ %04x:%04x\n", instr[1],
-                AL_sig(context), CS_sig(context), IP_sig(context));
-           EIP_sig(context) += prefixlen + 2;
+            SET_LOBYTE(context->Eax,INSTR_inport( instr[1], 1, context ));
+            context->Eip += prefixlen + 2;
             return TRUE;
 
         case 0xe5: /* in (e)ax,XX */
             if (long_op)
-            {
-                EAX_sig(context) = IO_inport( instr[1], 4 );
-                TRACE_(io)("0x%x < %08lx @ %04x:%04x\n", instr[1],
-                    EAX_sig(context), CS_sig(context), IP_sig(context));
-            }
+                context->Eax = INSTR_inport( instr[1], 4, context );
             else
-            {
-                AX_sig(context) = IO_inport( instr[1], 2 );
-                TRACE_(io)("0x%x < %04x @ %04x:%04x\n", instr[1],
-                    AX_sig(context), CS_sig(context), IP_sig(context));
-            }
-           EIP_sig(context) += prefixlen + 2;
+                SET_LOWORD(context->Eax, INSTR_inport( instr[1], 2, context ));
+            context->Eip += prefixlen + 2;
             return TRUE;
 
         case 0xe6: /* outb XX,al */
-            IO_outport( instr[1], 1, AL_sig(context) );
-            TRACE_(io)("0x%x > %02x @ %04x:%04x\n", instr[1],
-                AL_sig(context), CS_sig(context), IP_sig(context));
-           EIP_sig(context) += prefixlen + 2;
+            INSTR_outport( instr[1], 1, LOBYTE(context->Eax), context );
+            context->Eip += prefixlen + 2;
             return TRUE;
 
         case 0xe7: /* out XX,(e)ax */
             if (long_op)
-            {
-                IO_outport( instr[1], 4, EAX_sig(context) );
-                TRACE_(io)("0x%x > %08lx @ %04x:%04x\n", instr[1],
-                    EAX_sig(context), CS_sig(context), IP_sig(context));
-            }
+                INSTR_outport( instr[1], 4, context->Eax, context );
             else
-            {
-                IO_outport( instr[1], 2, AX_sig(context) );
-                TRACE_(io)("0x%x > %04x @ %04x:%04x\n", instr[1],
-                    AX_sig(context), CS_sig(context), IP_sig(context));
-            }
-           EIP_sig(context) += prefixlen + 2;
+                INSTR_outport( instr[1], 2, LOWORD(context->Eax), context );
+            context->Eip += prefixlen + 2;
             return TRUE;
 
         case 0xec: /* inb al,dx */
-            AL_sig(context) = IO_inport( DX_sig(context), 1 );
-            TRACE_(io)("0x%x < %02x @ %04x:%04x\n", DX_sig(context),
-                AL_sig(context), CS_sig(context), IP_sig(context));
-           EIP_sig(context) += prefixlen + 1;
+            SET_LOBYTE(context->Eax, INSTR_inport( LOWORD(context->Edx), 1, context ) );
+            context->Eip += prefixlen + 1;
             return TRUE;
 
         case 0xed: /* in (e)ax,dx */
             if (long_op)
-            {
-                EAX_sig(context) = IO_inport( DX_sig(context), 4 );
-                TRACE_(io)("0x%x < %08lx @ %04x:%04x\n", DX_sig(context),
-                    EAX_sig(context), CS_sig(context), IP_sig(context));
-            }
+                context->Eax = INSTR_inport( LOWORD(context->Edx), 4, context );
             else
-            {
-                AX_sig(context) = IO_inport( DX_sig(context), 2 );
-                TRACE_(io)("0x%x < %04x @ %04x:%04x\n", DX_sig(context),
-                    AX_sig(context), CS_sig(context), IP_sig(context));
-            }
-           EIP_sig(context) += prefixlen + 1;
+                SET_LOWORD(context->Eax, INSTR_inport( LOWORD(context->Edx), 2, context ));
+            context->Eip += prefixlen + 1;
             return TRUE;
 
         case 0xee: /* outb dx,al */
-            IO_outport( DX_sig(context), 1, AL_sig(context) );
-            TRACE_(io)("0x%x > %02x @ %04x:%04x\n", DX_sig(context),
-                AL_sig(context), CS_sig(context), IP_sig(context));
-           EIP_sig(context) += prefixlen + 1;
+            INSTR_outport( LOWORD(context->Edx), 1, LOBYTE(context->Eax), context );
+            context->Eip += prefixlen + 1;
             return TRUE;
-      
+
         case 0xef: /* out dx,(e)ax */
             if (long_op)
-            {
-                IO_outport( DX_sig(context), 4, EAX_sig(context) );
-                TRACE_(io)("0x%x > %08lx @ %04x:%04x\n", DX_sig(context),
-                    EAX_sig(context), CS_sig(context), IP_sig(context));
-            }
+                INSTR_outport( LOWORD(context->Edx), 4, context->Eax, context );
             else
-            {
-                IO_outport( DX_sig(context), 2, AX_sig(context) );
-                TRACE_(io)("0x%x > %04x @ %04x:%04x\n", DX_sig(context),
-                    AX_sig(context), CS_sig(context), IP_sig(context));
-            }
-           EIP_sig(context) += prefixlen + 1;
+                INSTR_outport( LOWORD(context->Edx), 2, LOWORD(context->Eax), context );
+            context->Eip += prefixlen + 1;
             return TRUE;
 
         case 0xfa: /* cli, ignored */
-           EIP_sig(context) += prefixlen + 1;
+            context->Eip += prefixlen + 1;
             return TRUE;
 
         case 0xfb: /* sti, ignored */
-           EIP_sig(context) += prefixlen + 1;
+            context->Eip += prefixlen + 1;
             return TRUE;
     }
 
 
     /* Check for Win16 __GP handler */
-    gpHandler = HasGPHandler16( PTR_SEG_OFF_TO_SEGPTR( CS_sig(context),
-                                                     EIP_sig(context) ) );
+    gpHandler = HasGPHandler16( MAKESEGPTR( context->SegCs, context->Eip ) );
     if (gpHandler)
     {
-        WORD *stack = (WORD *)STACK_PTR( context );
-        *--stack = CS_sig(context);
-        *--stack = EIP_sig(context);
-        ADD_STACK_sig(context, -2*sizeof(WORD));
+        WORD *stack = get_stack( context );
+        *--stack = context->SegCs;
+        *--stack = context->Eip;
+        add_stack(context, -2*sizeof(WORD));
 
-        CS_sig(context) = SELECTOROF( gpHandler );
-        EIP_sig(context) = OFFSETOF( gpHandler );
+        context->SegCs = SELECTOROF( gpHandler );
+        context->Eip   = OFFSETOF( gpHandler );
         return TRUE;
     }
     return FALSE;  /* Unable to emulate it */