No longer directly accessing debuggee memory.
Execution context (mode, steps...) are now linked to a thread.
Removed some X11 crst hacks.
Rewrote info/walk commands.
Removed direct debugger invocation code (and moved the rest to the new
winedbg.c file).

diff --git a/debugger/Makefile.in b/debugger/Makefile.in
index d3ee22a..a5524d7 100644
--- a/debugger/Makefile.in
+++ b/debugger/Makefile.in
@@ -20,7 +20,8 @@
 	source.c \
 	stabs.c	\
 	stack.c \
-	types.c
+	types.c \
+	winedbg.c
 
 EXTRA_SRCS = dbg.y debug.l
 EXTRA_OBJS = y.tab.o lex.yy.o
diff --git a/debugger/break.c b/debugger/break.c
index 68150d1..db80414 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -7,83 +7,43 @@
 
 #include "config.h"
 #include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include "wine/winbase16.h"
-#include "module.h"
-#include "neexe.h"
-#include "process.h"
-#include "task.h"
-#include "miscemu.h"
-#include "toolhelp.h"
 #include "debugger.h"
-#include "dosexe.h"
 
 #define INT3          0xcc   /* int 3 opcode */
 
 #define MAX_BREAKPOINTS 100
 
-typedef struct
-{
-    DBG_ADDR      addr;
-    BYTE          addrlen;
-    BYTE          opcode;
-    BOOL16        enabled;
-    WORD	  skipcount;
-    BOOL16        in_use;
-    struct expr * condition;
-} BREAKPOINT;
-
 static BREAKPOINT breakpoints[MAX_BREAKPOINTS];
 
 static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
 
 
 /***********************************************************************
- *           DEBUG_ChangeOpcode
- *
- * Change the opcode at segment:addr.
- */
-static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
-{
-    BYTE *ptr = DBG_ADDR_TO_LIN(addr);
-
-    /* There are a couple of problems with this. On Linux prior to
-       1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
-       This code is currently not tested at all on BSD.
-       How do I get the old protection in order to restore it later on?
-       */
-    if (mprotect((caddr_t)((int)ptr & (~4095)), 4096,
-                 PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
-    {
-        perror( "Can't set break point" );
-        return;
-    }
-    *ptr = op;
-    /* mprotect((caddr_t)(addr->off & ~4095), 4096,
-       PROT_READ | PROT_EXEC ); */
-}
-
-
-/***********************************************************************
  *           DEBUG_IsStepOverInstr
  *
  * Determine if the instruction at CS:EIP is an instruction that
  * we need to step over (like a call or a repetitive string move).
  */
-static BOOL DEBUG_IsStepOverInstr()
+static BOOL DEBUG_IsStepOverInstr(void)
 {
 #ifdef __i386__
-    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
-                                              CS_reg(&DEBUG_context),
-                                              EIP_reg(&DEBUG_context) );
+    BYTE*	instr;
+    BYTE	ch;
+    DBG_ADDR	addr;
+
+    addr.seg = DEBUG_context.SegCs;
+    addr.off = DEBUG_context.Eip;
+    /* FIXME: old code was using V86BASE(DEBUG_context)
+     * instead of passing thru DOSMEM_MemoryBase
+     */
+    instr = (BYTE*)DEBUG_ToLinear(&addr);
 
     for (;;)
     {
-        switch(*instr)
+        if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
+	    return FALSE;
+
+        switch (ch)
         {
           /* Skip all prefixes */
 
@@ -109,8 +69,9 @@
             return TRUE;
 
         case 0xff:  /* call <regmodrm> */
-            return (((instr[1] & 0x38) == 0x10) ||
-                    ((instr[1] & 0x38) == 0x18));
+	    if (!DEBUG_READ_MEM(instr + 1, &ch, sizeof(ch)))
+	        return FALSE;
+	    return (((ch & 0x38) == 0x10) || ((ch & 0x38) == 0x18));
 
           /* Handle string instructions */
 
@@ -149,21 +110,21 @@
 BOOL DEBUG_IsFctReturn(void)
 {
 #ifdef __i386__
-    BYTE *instr = (BYTE *)CTX_SEG_OFF_TO_LIN( &DEBUG_context,
-                                              CS_reg(&DEBUG_context),
-                                              EIP_reg(&DEBUG_context) );
+    BYTE*	instr;
+    BYTE  	ch;
+    DBG_ADDR	addr;
 
-    for (;;)
-    {
-        switch(*instr)
-        {
-	case 0xc2:
-	case 0xc3:
-	  return TRUE;
-        default:
-            return FALSE;
-        }
-    }
+    addr.seg = DEBUG_context.SegCs;
+    addr.off = DEBUG_context.Eip;
+    /* FIXME: old code was using V86BASE(DEBUG_context)
+     * instead of passing thru DOSMEM_MemoryBase
+     */
+    instr = (BYTE*)DEBUG_ToLinear(&addr);
+
+    if (!DEBUG_READ_MEM(instr, &ch, sizeof(ch)))
+       return FALSE;
+
+    return (ch == 0xc2) || (ch == 0xc3);
 #else
     return FALSE;
 #endif
@@ -177,21 +138,20 @@
  */
 void DEBUG_SetBreakpoints( BOOL set )
 {
-    int i;
+    int 	i;
+    char	ch;
 
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
-        if (breakpoints[i].in_use && breakpoints[i].enabled)
+        if (breakpoints[i].refcount && breakpoints[i].enabled)
         {
-            /* Note: we check for read here, because if reading is allowed */
-            /*       writing permission will be forced in DEBUG_SetOpcode. */
-            if (DEBUG_IsBadReadPtr( &breakpoints[i].addr, 1 ))
+	    ch = set ? INT3 : breakpoints[i].opcode;
+
+            if (!DEBUG_WRITE_MEM( (void*)DEBUG_ToLinear(&breakpoints[i].addr), &ch, sizeof(ch) ))
             {
                 fprintf( stderr, "Invalid address for breakpoint %d, disabling it\n", i );
                 breakpoints[i].enabled = FALSE;
             }
-            else DEBUG_SetOpcode( &breakpoints[i].addr,
-                                  set ? INT3 : breakpoints[i].opcode );
         }
     }
 }
@@ -209,7 +169,7 @@
 
     for (i = 0; i < MAX_BREAKPOINTS; i++)
     {
-        if (breakpoints[i].in_use && breakpoints[i].enabled &&
+        if (breakpoints[i].refcount && breakpoints[i].enabled &&
             breakpoints[i].addr.seg == addr->seg &&
             breakpoints[i].addr.off == addr->off) return i;
     }
@@ -227,9 +187,9 @@
     DBG_ADDR addr = *address;
     int num;
     unsigned int seg2;
-    BYTE *p;
+    BYTE ch;
 
-    DBG_FIX_ADDR_SEG( &addr, CS_reg(&DEBUG_context) );
+    DEBUG_FixAddress( &addr, DEBUG_context.SegCs );
 
     if( addr.type != NULL && addr.type == DEBUG_TypeIntConst )
       {
@@ -243,27 +203,38 @@
 	addr.off = DEBUG_GetExprValue(&addr, NULL);
 	addr.seg = seg2;
       }
-    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
+
+    if ((num = DEBUG_FindBreakpoint(&addr)) >= 1) 
+    {
+       breakpoints[num].refcount++;
+       return;
+    }
+
+    if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, sizeof(ch)))
+	return;
 
     if (next_bp < MAX_BREAKPOINTS)
         num = next_bp++;
     else  /* try to find an empty slot */  
     {
         for (num = 1; num < MAX_BREAKPOINTS; num++)
-            if (!breakpoints[num].in_use) break;
+            if (!breakpoints[num].refcount) break;
         if (num >= MAX_BREAKPOINTS)
         {
             fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
             return;
         }
     }
-    p = DBG_ADDR_TO_LIN( &addr );
     breakpoints[num].addr    = addr;
-    breakpoints[num].addrlen = !addr.seg ? 32 :
-                         (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
-    breakpoints[num].opcode  = *p;
+    breakpoints[num].addrlen = 32;
+#ifdef __i386__
+    if (addr.seg)
+       breakpoints[num].addrlen = DEBUG_GetSelectorType( addr.seg );
+    if (breakpoints[num].addrlen == 0) fprintf(stderr, "in bad shape\n");
+#endif
+    breakpoints[num].opcode  = ch;
     breakpoints[num].enabled = TRUE;
-    breakpoints[num].in_use  = TRUE;
+    breakpoints[num].refcount = 1;
     breakpoints[num].skipcount = 0;
     fprintf( stderr, "Breakpoint %d at ", num );
     DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen,
@@ -279,12 +250,15 @@
  */
 void DEBUG_DelBreakpoint( int num )
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return;
     }
 
+    if (--breakpoints[num].refcount > 0)
+       return;
+
     if( breakpoints[num].condition != NULL )
       {
 	DEBUG_FreeExpr(breakpoints[num].condition);
@@ -292,7 +266,7 @@
       }
 
     breakpoints[num].enabled = FALSE;
-    breakpoints[num].in_use  = FALSE;
+    breakpoints[num].refcount = 0;
     breakpoints[num].skipcount = 0;
 }
 
@@ -304,12 +278,12 @@
  */
 void DEBUG_EnableBreakpoint( int num, BOOL enable )
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return;
     }
-    breakpoints[num].enabled = enable;
+    breakpoints[num].enabled = (enable) ? TRUE : FALSE;
     breakpoints[num].skipcount = 0;
 }
 
@@ -326,67 +300,21 @@
     fprintf( stderr, "Breakpoints:\n" );
     for (i = 1; i < next_bp; i++)
     {
-        if (breakpoints[i].in_use)
+        if (breakpoints[i].refcount)
         {
             fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
-            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen,
-				TRUE);
-            fprintf( stderr, "\n" );
+            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen, TRUE);
+            fprintf( stderr, " (%u)\n", breakpoints[i].refcount );
 	    if( breakpoints[i].condition != NULL )
-	      {
-		fprintf(stderr, "\t\tstop when  ");
+	    {
+	        fprintf(stderr, "\t\tstop when  ");
  		DEBUG_DisplayExpr(breakpoints[i].condition);
 		fprintf(stderr, "\n");
-	      }
+	    }
         }
     }
 }
 
-
-/***********************************************************************
- *           DEBUG_AddTaskEntryBreakpoint
- *
- * Add a breakpoint at the entry point of the given task
- */
-void DEBUG_AddTaskEntryBreakpoint( HTASK16 hTask )
-{
-    TDB *pTask = (TDB *)GlobalLock16( hTask );
-    NE_MODULE *pModule;
-    DBG_ADDR addr = { NULL, 0, 0 };
-
-    if ( pTask )
-    {
-        if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
-        if (pModule->flags & NE_FFLAGS_LIBMODULE) return;  /* Library */
-
-        if (pModule->lpDosTask) { /* DOS module */
-            addr.seg = pModule->lpDosTask->init_cs | ((DWORD)pModule->self << 16);
-            addr.off = pModule->lpDosTask->init_ip;
-            fprintf( stderr, "DOS task '%s': ", NE_MODULE_NAME( pModule ) );
-            DEBUG_AddBreakpoint( &addr );
-        } else
-        if (!(pModule->flags & NE_FFLAGS_WIN32))  /* NE module */
-        {
-            addr.seg =
-		GlobalHandleToSel16(NE_SEG_TABLE(pModule)[pModule->cs-1].hSeg);
-            addr.off = pModule->ip;
-            fprintf( stderr, "Win16 task '%s': ", NE_MODULE_NAME( pModule ) );
-            DEBUG_AddBreakpoint( &addr );
-	}
-	else /* PE module */
-	{
-	    addr.seg = 0;
-	    addr.off = (DWORD)RVA_PTR( pModule->module32,
-			   OptionalHeader.AddressOfEntryPoint);
-	    fprintf( stderr, "Win32 task '%s': ", NE_MODULE_NAME( pModule ) );
-	    DEBUG_AddBreakpoint( &addr );
-	}
-    }
-
-    DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
-}
-
-
 /***********************************************************************
  *           DEBUG_ShouldContinue
  *
@@ -401,21 +329,22 @@
     struct list_id list;
 
 #ifdef __i386__
-      /* If not single-stepping, back up over the int3 instruction */
-    if (!(EFL_reg(&DEBUG_context) & STEP_FLAG)) EIP_reg(&DEBUG_context)--;
+    /* If not single-stepping, back up over the int3 instruction */
+    if (!(DEBUG_context.EFlags & STEP_FLAG)) 
+       DEBUG_context.Eip--;
 #endif
 
     DEBUG_GetCurrentAddress( &addr );
     bpnum = DEBUG_FindBreakpoint( &addr );
-    breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
+    breakpoints[0].enabled = FALSE;  /* disable the step-over breakpoint */
 
     if ((bpnum != 0) && (bpnum != -1))
     {
         if( breakpoints[bpnum].condition != NULL )
-	  {
+	{
 	    cond_addr = DEBUG_EvalExpr(breakpoints[bpnum].condition);
 	    if( cond_addr.type == NULL )
-	      {
+	    {
 		/*
 		 * Something wrong - unable to evaluate this expression.
 		 */
@@ -423,21 +352,21 @@
  		DEBUG_DisplayExpr(breakpoints[bpnum].condition);
 		fprintf(stderr, "\nTurning off condition\n");
 		DEBUG_AddBPCondition(bpnum, NULL);
-	      }
+	    }
 	    else if( ! DEBUG_GetExprValue( &cond_addr, NULL) )
-	      {
+	    {
 		return TRUE;
-	      }
-	  }
+	    }
+	}
 
         if( breakpoints[bpnum].skipcount > 0 )
-	  {
+	{
 	    breakpoints[bpnum].skipcount--;
 	    if( breakpoints[bpnum].skipcount > 0 )
-	      {
+	    {
 		return TRUE;
-	      }
-	  }
+	    }
+	}
         fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
         DEBUG_PrintAddress( &breakpoints[bpnum].addr,
                             breakpoints[bpnum].addrlen, TRUE );
@@ -449,9 +378,9 @@
 	 */
 	DEBUG_FindNearestSymbol( &addr, TRUE, NULL, 0, &list);
 	if( list.sourcefile != NULL )
-	  {
+	{
 	    DEBUG_List(&list, NULL, 0);
-	  }
+	}
         return FALSE;
     }
 
@@ -460,8 +389,7 @@
      * get the current function, and figure out if we are exactly
      * on a line number or not.
      */
-    if( mode == EXEC_STEP_OVER 
-	|| mode == EXEC_STEP_INSTR )
+    if( mode == EXEC_STEP_OVER || mode == EXEC_STEP_INSTR )
       {
 	if( DEBUG_CheckLinenoStatus(&addr) == AT_LINENUMBER )
 	  {
@@ -499,14 +427,24 @@
 #ifdef __i386__
     /* If there's no breakpoint and we are not single-stepping, then we     */
     /* must have encountered an int3 in the Windows program; let's skip it. */
-    if ((bpnum == -1) && !(EFL_reg(&DEBUG_context) & STEP_FLAG))
-        EIP_reg(&DEBUG_context)++;
+    if ((bpnum == -1) && !(DEBUG_context.EFlags & STEP_FLAG))
+        DEBUG_context.Eip++;
 #endif
 
-      /* no breakpoint, continue if in continuous mode */
+    /* no breakpoint, continue if in continuous mode */
     return (mode == EXEC_CONT || mode == EXEC_PASS || mode == EXEC_FINISH);
 }
 
+/***********************************************************************
+ *           DEBUG_RestartExecution
+ *
+ * Remove all breakpoints before entering the debug loop
+ */
+void	DEBUG_SuspendExecution( void )
+{
+   DEBUG_SetBreakpoints( FALSE );
+   breakpoints[0] = DEBUG_CurrThread->stepOverBP;
+}
 
 /***********************************************************************
  *           DEBUG_RestartExecution
@@ -522,7 +460,8 @@
     int	delta;
     int status;
     enum exec_mode ret_mode;
-    BYTE *instr;
+    DWORD instr;
+    unsigned char ch;
 
     DEBUG_GetCurrentAddress( &addr );
 
@@ -548,7 +487,7 @@
       {
 	if( mode == EXEC_CONT && count > 1 )
 	  {
-	    fprintf(stderr,"Not stopped at any breakpoint; argument ignored.\n");
+	    fprintf(stderr, "Not stopped at any breakpoint; argument ignored.\n");
 	  }
       }
     
@@ -557,16 +496,17 @@
 	mode = ret_mode = EXEC_STEPI_INSTR;
       }
 
-    instr = DBG_ADDR_TO_LIN( &addr );
+    instr = DEBUG_ToLinear( &addr );
+    DEBUG_READ_MEM((void*)instr, &ch, sizeof(ch));
     /*
      * See if the function we are stepping into has debug info
      * and line numbers.  If not, then we step over it instead.
      * FIXME - we need to check for things like thunks or trampolines,
      * as the actual function may in fact have debug info.
      */
-    if( *instr == 0xe8 )
+    if( ch == 0xe8 )
       {
-	delta = *(unsigned int*) (instr + 1);
+	DEBUG_READ_MEM((void*)(instr + 1), &delta, sizeof(delta));
 	addr2 = addr;
 	DEBUG_Disasm(&addr2, FALSE);
 	addr2.off += delta;
@@ -612,7 +552,7 @@
     case EXEC_CONT: /* Continuous execution */
     case EXEC_PASS: /* Continue, passing exception */
 #ifdef __i386__
-        EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+        DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
         DEBUG_SetBreakpoints( TRUE );
         break;
@@ -625,14 +565,16 @@
        * address just after the call.
        */
 #ifdef __i386__
-      addr.off = *((unsigned int *) ESP_reg(&DEBUG_context) + 2);
-      EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+      DEBUG_READ_MEM((void*)(DEBUG_context.Esp + 
+			     2 * sizeof(unsigned int)), 
+		     &addr.off, sizeof(addr.off));
+      DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
       breakpoints[0].addr    = addr;
       breakpoints[0].enabled = TRUE;
-      breakpoints[0].in_use  = TRUE;
+      breakpoints[0].refcount = 1;
       breakpoints[0].skipcount = 0;
-      breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
+      DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
       DEBUG_SetBreakpoints( TRUE );
       break;
 
@@ -642,14 +584,14 @@
         if (DEBUG_IsStepOverInstr())
         {
 #ifdef __i386__
-            EFL_reg(&DEBUG_context) &= ~STEP_FLAG;
+            DEBUG_context.EFlags &= ~STEP_FLAG;
 #endif
             DEBUG_Disasm(&addr, FALSE);
             breakpoints[0].addr    = addr;
             breakpoints[0].enabled = TRUE;
-            breakpoints[0].in_use  = TRUE;
+            breakpoints[0].refcount = 1;
 	    breakpoints[0].skipcount = 0;
-            breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
+	    DEBUG_READ_MEM((void*)DEBUG_ToLinear( &addr ), &breakpoints[0].opcode, sizeof(char));
             DEBUG_SetBreakpoints( TRUE );
             break;
         }
@@ -658,17 +600,18 @@
     case EXEC_STEP_INSTR: /* Single-stepping an instruction */
     case EXEC_STEPI_INSTR: /* Single-stepping an instruction */
 #ifdef __i386__
-        EFL_reg(&DEBUG_context) |= STEP_FLAG;
+        DEBUG_context.EFlags |= STEP_FLAG;
 #endif
         break;
     }
+    DEBUG_CurrThread->stepOverBP = breakpoints[0];
     return ret_mode;
 }
 
 int
 DEBUG_AddBPCondition(int num, struct expr * exp)
 {
-    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].refcount)
     {
         fprintf( stderr, "Invalid breakpoint number %d\n", num );
         return FALSE;
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 42cf385..e6783a9 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -892,27 +892,29 @@
 static unsigned int db_get_task_value( const DBG_ADDR *addr,
                                        int size, int is_signed )
 {
-    unsigned int result;
-    unsigned char *p = DBG_ADDR_TO_LIN( addr );
+    unsigned int 	result = 0;
+    char       		buffer[4];
 
-    switch(size)
-    {
-    case 4:
-        if (is_signed) result = (unsigned int) *(int *)p;
-        else result = *(unsigned int *)p;
-        break;
-    case 2:
-        if (is_signed) result = (unsigned int) *(short int *)p;
-        else result = *(unsigned short int *)p;
-        break;
-    case 1:
-        if (is_signed) result = (unsigned int) *(char *)p;
-        else result = *(unsigned char *)p;
-        break;
-    default:
+    if (size != 1 && size != 2 && size != 4) {
         fprintf(stderr, "Illegal size specified\n");
-        result = 0;
-        break;
+    } else {
+       DEBUG_READ_MEM((void*)DEBUG_ToLinear( addr ), buffer, size);
+
+       switch(size)
+       {
+       case 4:
+	   if (is_signed) result = (unsigned int) *(int *)buffer;
+	   else result = *(unsigned int *)buffer;
+	   break;
+       case 2:
+	   if (is_signed) result = (unsigned int) *(short int *)buffer;
+	   else result = *(unsigned short int *)buffer;
+	   break;
+       case 1:
+	   if (is_signed) result = (unsigned int) *(char *)buffer;
+	   else result = *(unsigned char *)buffer;
+	   break;
+       }
     }
     return result;
 }
@@ -1041,18 +1043,16 @@
 	    /* try to get destination of indirect call
 	       does not work for segmented adresses */	
 	    if (!seg && byref) {
-               DBG_ADDR dbg_addr = {NULL, 0, 0};
+	       void*	a1;
+	       void*	a2;
 
-               dbg_addr.off = addrp->disp;
                fprintf(stderr,"0x%x -> ", addrp->disp);
-               if (DEBUG_IsBadReadPtr( &dbg_addr, sizeof(LPDWORD))) {
-                   fprintf(stderr, "(invalid source)");
-               } else {
-                  dbg_addr.off = *(LPDWORD)(addrp->disp);
-                  if (DEBUG_IsBadReadPtr( &dbg_addr, sizeof(DWORD)))
-                     fprintf(stderr, "(invalid destination)");
-                  else
-                     db_task_printsym(dbg_addr.off, 0);
+	       if (!DEBUG_READ_MEM((void*)addrp->disp, &a1, sizeof(a1))) {
+		   fprintf(stderr, "(invalid source)");
+	       } else if (!DEBUG_READ_MEM(a1, &a2, sizeof(a2))) {
+		  fprintf(stderr, "(invalid destination)");
+	       } else {
+		  db_task_printsym((unsigned long)a1, 0);
                }
 	    }
 	    else
@@ -1172,7 +1172,11 @@
 	 * Set this so we get can supress the printout if we need to.
 	 */
 	db_display = display;
-        db_disasm_16 = IS_SELECTOR_V86(addr->seg) || !IS_SELECTOR_32BIT(addr->seg);
+        switch (DEBUG_GetSelectorType(addr->seg)) {
+	case 16: db_disasm_16 = 1; break;
+	case 32: db_disasm_16 = 0; break;
+	default: fprintf(stderr, "Bad selector %ld\n", addr->seg); return;
+	}
 
 	get_value_inc( inst, addr, 1, FALSE );
 
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 663a4e3..30e26ec 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -12,51 +12,21 @@
 #include <stdlib.h>
 #include <string.h>
 #include <signal.h>
-#include <sys/stat.h>
 #include <unistd.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
 
-#include "winbase.h"
-#include "module.h"
-#include "task.h"
-#include "options.h"
-#include "queue.h"
-#include "wine/winbase16.h"
-#include "winnt.h"
-#include "x11drv.h"
-#include "win.h"
 #include "debugger.h"
-#include "neexe.h"
-#include "process.h"
-#include "server.h"
-#include "main.h"
 #include "expr.h"
-#include "user.h"
+#include "wine/exception.h"
 
 extern FILE * yyin;
-unsigned int dbg_mode = 0;
-HANDLE dbg_heap = 0;
 int curr_frame = 0;
 
-static enum exec_mode dbg_exec_mode = EXEC_CONT;
-static int dbg_exec_count = 0;
-
 void issue_prompt(void);
 void mode_command(int);
 void flush_symbols(void);
 int yylex(void);
 int yyerror(char *);
 
-#ifdef DBG_need_heap
-#define malloc(x) DBG_alloc(x)
-#define realloc(x,y) DBG_realloc(x,y)
-#define free(x) DBG_free(x)
-#endif
-
-extern void VIRTUAL_Dump(void);  /* memory/virtual.c */
-
 %}
 
 %union
@@ -126,41 +96,41 @@
       tQUIT tEOL               { DEBUG_Exit(0); }
     | tHELP tEOL               { DEBUG_Help(); }
     | tHELP tINFO tEOL         { DEBUG_HelpInfo(); }
-    | tCONT tEOL               { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_CONT; return 0; }
-    | tPASS tEOL               { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_PASS; return 0; }
-    | tCONT tNUM tEOL          { dbg_exec_count = $2; 
-				 dbg_exec_mode = EXEC_CONT; return 0; }
-    | tSTEP tEOL               { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
-    | tNEXT tEOL               { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_STEP_OVER; return 0; }
-    | tSTEP tNUM tEOL          { dbg_exec_count = $2; 
-				 dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
-    | tNEXT tNUM tEOL          { dbg_exec_count = $2; 
-				 dbg_exec_mode = EXEC_STEP_OVER; return 0; }
-    | tSTEPI tEOL              { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
-    | tNEXTI tEOL              { dbg_exec_count = 1; 
-				 dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
-    | tSTEPI tNUM tEOL         { dbg_exec_count = $2; 
-				 dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
-    | tNEXTI tNUM tEOL         { dbg_exec_count = $2; 
-				 dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
+    | tCONT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return 0; }
+    | tPASS tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_PASS; return 0; }
+    | tCONT tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_CONT; return 0; }
+    | tSTEP tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
+    | tNEXT tEOL               { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return 0; }
+    | tSTEP tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
+    | tNEXT tNUM tEOL          { DEBUG_CurrThread->dbg_exec_count = $2; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEP_OVER; return 0; }
+    | tSTEPI tEOL              { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
+    | tNEXTI tEOL              { DEBUG_CurrThread->dbg_exec_count = 1; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
+    | tSTEPI tNUM tEOL         { DEBUG_CurrThread->dbg_exec_count = $2; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_INSTR; return 0; }
+    | tNEXTI tNUM tEOL         { DEBUG_CurrThread->dbg_exec_count = $2; 
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_STEPI_OVER; return 0; }
     | tABORT tEOL              { kill(getpid(), SIGABRT); }
     | tMODE tNUM tEOL          { mode_command($2); }
     | tENABLE tNUM tEOL        { DEBUG_EnableBreakpoint( $2, TRUE ); }
     | tDISABLE tNUM tEOL       { DEBUG_EnableBreakpoint( $2, FALSE ); }
     | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
-    | tBACKTRACE tEOL	       { DEBUG_BackTrace(); }
+    | tBACKTRACE tEOL	       { DEBUG_BackTrace(TRUE); }
     | tUP tEOL		       { DEBUG_SetFrame( curr_frame + 1 );  }
     | tUP tNUM tEOL	       { DEBUG_SetFrame( curr_frame + $2 ); }
     | tDOWN tEOL	       { DEBUG_SetFrame( curr_frame - 1 );  }
     | tDOWN tNUM tEOL	       { DEBUG_SetFrame( curr_frame - $2 ); }
     | tFRAME tNUM tEOL         { DEBUG_SetFrame( $2 ); }
-    | tFINISH tEOL	       { dbg_exec_count = 0;
-				 dbg_exec_mode = EXEC_FINISH; return 0; }
+    | tFINISH tEOL	       { DEBUG_CurrThread->dbg_exec_count = 0;
+				 DEBUG_CurrThread->dbg_exec_mode = EXEC_FINISH; return 0; }
     | tSHOW tDIR tEOL	       { DEBUG_ShowDir(); }
     | tDIR pathname tEOL       { DEBUG_AddPath( $2 ); }
     | tDIR tEOL		       { DEBUG_NukePath(); }
@@ -173,7 +143,6 @@
     | tUNDISPLAY tEOL          { DEBUG_DelDisplay( -1 ); }
     | tCOND tNUM tEOL          { DEBUG_AddBPCondition($2, NULL); }
     | tCOND tNUM expr tEOL     { DEBUG_AddBPCondition($2, $3); }
-    | tDEBUGMSG tDEBUGSTR tEOL { MAIN_ParseDebugOptions($2); }
     | tSYMBOLFILE pathname tEOL{ DEBUG_ReadSymbolTable($2); }
     | list_command
     | disassemble_command
@@ -274,32 +243,30 @@
 
 info_command:
       tINFO tBREAK tEOL         { DEBUG_InfoBreakpoints(); }
-    | tINFO tCLASS expr_value tEOL    { CLASS_DumpClass( (struct tagCLASS *)$3 ); 
- 					     DEBUG_FreeExprMem(); }
+    | tINFO tCLASS tSTRING tEOL	{ DEBUG_InfoClass( $3 ); DEBUG_FreeExprMem(); }
     | tINFO tSHARE tEOL		{ DEBUG_InfoShare(); }
-    | tINFO tMODULE expr_value tEOL   { NE_DumpModule( $3 ); 
+    | tINFO tMODULE expr_value tEOL   { DEBUG_DumpModule( $3 ); 
  					     DEBUG_FreeExprMem(); }
-    | tINFO tQUEUE expr_value tEOL    { QUEUE_DumpQueue( $3 ); 
+    | tINFO tQUEUE expr_value tEOL    { DEBUG_DumpQueue( $3 ); 
  					     DEBUG_FreeExprMem(); }
     | tINFO tREGS tEOL          { DEBUG_InfoRegisters(); }
-    | tINFO tSEGMENTS expr_value tEOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); 
- 					     DEBUG_FreeExprMem(); }
-    | tINFO tSEGMENTS tEOL      { LDT_Print( 0, -1 ); }
+    | tINFO tSEGMENTS expr_value tEOL { DEBUG_InfoSegments( $3, 1 ); DEBUG_FreeExprMem(); }
+    | tINFO tSEGMENTS tEOL      { DEBUG_InfoSegments( 0, -1 ); }
     | tINFO tSTACK tEOL         { DEBUG_InfoStack(); }
-    | tINFO tMAPS tEOL          { VIRTUAL_Dump(); }
-    | tINFO tWND expr_value tEOL      { WIN_DumpWindow( $3 ); 
+    | tINFO tMAPS tEOL          { DEBUG_InfoVirtual(); }
+    | tINFO tWND expr_value tEOL      { DEBUG_InfoWindow( (HWND)$3 ); 
  					     DEBUG_FreeExprMem(); }
     | tINFO tLOCAL tEOL         { DEBUG_InfoLocals(); }
     | tINFO tDISPLAY tEOL       { DEBUG_InfoDisplay(); }
 
 walk_command:
-      tWALK tCLASS tEOL         { CLASS_WalkClasses(); }
-    | tWALK tMODULE tEOL        { NE_WalkModules(); }
-    | tWALK tQUEUE tEOL         { QUEUE_WalkQueues(); }
-    | tWALK tWND tEOL           { WIN_WalkWindows( 0, 0 ); }
-    | tWALK tWND tNUM tEOL      { WIN_WalkWindows( $3, 0 ); }
-    | tWALK tPROCESS tEOL       { PROCESS_WalkProcess(); }
-    | tWALK tMODREF expr_value tEOL   { MODULE_WalkModref( $3 ); }
+      tWALK tCLASS tEOL         { DEBUG_WalkClasses(); }
+    | tWALK tMODULE tEOL        { DEBUG_WalkModules(); }
+    | tWALK tQUEUE tEOL         { DEBUG_WalkQueues(); }
+    | tWALK tWND tEOL           { DEBUG_WalkWindows( 0, 0 ); }
+    | tWALK tWND tNUM tEOL      { DEBUG_WalkWindows( $3, 0 ); }
+    | tWALK tPROCESS tEOL       { DEBUG_WalkProcess(); }
+    | tWALK tMODREF expr_value tEOL   { DEBUG_WalkModref( $3 ); }
 
 
 type_cast: 
@@ -326,11 +293,13 @@
     | tENUM tIDENTIFIER		{ $$ = DEBUG_TypeCast(DT_ENUM, $2); }
 
 expr_addr:
-    expr			 { $$ = DEBUG_EvalExpr($1); }
+      expr			{ $$ = DEBUG_EvalExpr($1); }
 
 expr_value:
-      expr        { DBG_ADDR addr  = DEBUG_EvalExpr($1);
-		    $$ = addr.off ? *(unsigned int *) addr.off : 0; }
+      expr        { DBG_ADDR addr = DEBUG_EvalExpr($1); 
+                    /* expr_value is typed as an integer */
+		    if (!addr.off || !DEBUG_READ_MEM((void*)addr.off, &$$, sizeof($$)))
+		       $$ = 0; }
 /*
  * The expr rule builds an expression tree.  When we are done, we call
  * EvalExpr to evaluate the value of the expression.  The advantage of
@@ -410,50 +379,27 @@
 
 void mode_command(int newmode)
 {
-    if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
+    if ((newmode == 16) || (newmode == 32)) DEBUG_CurrThread->dbg_mode = newmode;
     else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
 }
 
-/***********************************************************************
- *           DEBUG_Freeze
- */
-static void DEBUG_Freeze( BOOL freeze )
+static WINE_EXCEPTION_FILTER(no_symbol)
 {
-    static BOOL frozen = FALSE;
-
-    if ( freeze && !frozen )
-    {
-        if ( X11DRV_CritSection.LockSemaphore )
-        {
-            /* Don't freeze thread currently holding the X crst! */
-            EnterCriticalSection( &X11DRV_CritSection );
-            CLIENT_DebuggerRequest( DEBUGGER_FREEZE_ALL );
-            LeaveCriticalSection( &X11DRV_CritSection );
-        }
-        else
-            CLIENT_DebuggerRequest( DEBUGGER_FREEZE_ALL );
-
-        frozen = TRUE;
-    }
-
-    if ( !freeze && frozen )
-    {
-        CLIENT_DebuggerRequest( DEBUGGER_UNFREEZE_ALL );
-        frozen = FALSE;
-    }
+    if (GetExceptionCode() == DEBUG_STATUS_NO_SYMBOL)
+        return EXCEPTION_EXECUTE_HANDLER;
+    return EXCEPTION_CONTINUE_SEARCH;
 }
 
 /***********************************************************************
  *           DEBUG_Exit
  *
  * Kill current process.
+ *
  */
 void DEBUG_Exit( DWORD exit_code )
 {
-    DEBUG_Freeze( FALSE );
-
-    TASK_KillTask( 0 );  /* FIXME: should not be necessary */
-    TerminateProcess( GetCurrentProcess(), exit_code );
+    TASK_KillTask( 0 ); /* FIXME: should not be necessary */
+    TerminateProcess( DEBUG_CurrProcess->handle, exit_code );
 }
 
 /***********************************************************************
@@ -461,261 +407,131 @@
  *
  * Debugger main loop.
  */
-static void DEBUG_Main( BOOL is_debug )
+BOOL DEBUG_Main( BOOL is_debug, BOOL force )
 {
-    static int loaded_symbols = 0;
-    static BOOL in_debugger = FALSE;
-    char SymbolTableFile[256];
     int newmode;
     BOOL ret_ok;
+    char ch;
+
 #ifdef YYDEBUG
     yydebug = 0;
 #endif
 
-    if (in_debugger)
-    {
-        fprintf( stderr, " inside debugger, trying to invoke external debugger.\n" );
-        DEBUG_ExternalDebugger();
-        DEBUG_Exit(1);
-    }
-    in_debugger = TRUE;
     yyin = stdin;
 
-    DEBUG_SetBreakpoints( FALSE );
+    DEBUG_SuspendExecution();
 
     if (!is_debug)
     {
 #ifdef __i386__
-        if (IS_SELECTOR_SYSTEM(CS_reg(&DEBUG_context)))
-            fprintf( stderr, " in 32-bit code (0x%08lx).\n", EIP_reg(&DEBUG_context));
+        if (DEBUG_IsSelectorSystem(DEBUG_context.SegCs))
+            fprintf( stderr, " in 32-bit code (0x%08lx).\n", DEBUG_context.Eip );
         else
             fprintf( stderr, " in 16-bit code (%04x:%04lx).\n",
-                     (WORD)CS_reg(&DEBUG_context), EIP_reg(&DEBUG_context) );
+                     (WORD)DEBUG_context.SegCs, DEBUG_context.Eip );
 #else
-        fprintf( stderr, " (%p).\n", GET_IP(&DEBUG_context) );
+        fprintf( stderr, " (%p).\n", GET_IP(DEBUG_CurrThread->context) );
 #endif
     }
 
-    if (!loaded_symbols)
-    {
-        loaded_symbols++;
+    if (DEBUG_LoadEntryPoints("Loading new modules symbols:\n"))
+       DEBUG_ProcessDeferredDebug();
 
-        DEBUG_Freeze( TRUE );
-
-#ifdef DBG_need_heap
-	/*
-	 * Initialize the debugger heap.
-	 */
-	dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */
-#endif
-
-	/*
-	 * Initialize the type handling stuff.
-	 */
-	DEBUG_InitTypes();
-	DEBUG_InitCVDataTypes();
-
-	/*
-	 * In some cases we can read the stabs information directly
-	 * from the executable.  If this is the case, we don't need
-	 * to bother with trying to read a symbol file, as the stabs
-	 * also have line number and local variable information.
-	 * As long as gcc is used for the compiler, stabs will
-	 * be the default.  On SVr4, DWARF could be used, but we
-	 * don't grok that yet, and in this case we fall back to using
-	 * the wine.sym file.
-	 */
-	if( DEBUG_ReadExecutableDbgInfo() == FALSE )
-        {
-	    char *symfilename = "wine.sym";
-	    struct stat statbuf;
-	    if (-1 == stat(symfilename, &statbuf) )
-                symfilename = LIBDIR "wine.sym";
-
-	    PROFILE_GetWineIniString( "wine", "SymbolTableFile", symfilename,
-                                     SymbolTableFile, sizeof(SymbolTableFile));
-	    DEBUG_ReadSymbolTable( SymbolTableFile );
-        }
-	DEBUG_LoadEntryPoints(NULL);
-	DEBUG_ProcessDeferredDebug();
-    }
-    else 
-    {
-        if (DEBUG_LoadEntryPoints("Loading new modules symbols:\n"))
-	    DEBUG_ProcessDeferredDebug();
-    }
-
-#if 0
-    fprintf(stderr, "Entering debugger 	PC=%x, mode=%d, count=%d\n",
-	    EIP_reg(&DEBUG_context),
-	    dbg_exec_mode, dbg_exec_count);
-    
-    sleep(1);
-#endif
-
-    if (!is_debug || !DEBUG_ShouldContinue( dbg_exec_mode, &dbg_exec_count ))
+    if (force || !(is_debug && DEBUG_ShouldContinue( DEBUG_CurrThread->dbg_exec_mode, &DEBUG_CurrThread->dbg_exec_count )))
     {
         DBG_ADDR addr;
         DEBUG_GetCurrentAddress( &addr );
 
-        DEBUG_Freeze( TRUE );
-
-        /* Put the display in a correct state */
-	if (USER_Driver) USER_Driver->pBeginDebugging();
+/* EPP 	if (USER_Driver) USER_Driver->pBeginDebugging(); */
 
 #ifdef __i386__
-        newmode = ISV86(&DEBUG_context) ? 16 : IS_SELECTOR_32BIT(addr.seg) ? 32 : 16;
+        switch (newmode = DEBUG_GetSelectorType(addr.seg)) {
+	case 16: case 32: break;
+	default: fprintf(stderr, "Bad CS (%ld)\n", addr.seg); newmode = 32;
+	}
 #else
         newmode = 32;
 #endif
-        if (newmode != dbg_mode)
-            fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
+        if (newmode != DEBUG_CurrThread->dbg_mode)
+            fprintf(stderr,"In %d bit mode.\n", DEBUG_CurrThread->dbg_mode = newmode);
 
 	DEBUG_DoDisplay();
 
-        if (!is_debug)  /* This is a real crash, dump some info */
-        {
-            DEBUG_InfoRegisters();
-            DEBUG_InfoStack();
-#ifdef __i386__
-            if (dbg_mode == 16)
-            {
-                LDT_Print( SELECTOR_TO_ENTRY(DS_reg(&DEBUG_context)), 1 );
-                if (ES_reg(&DEBUG_context) != DS_reg(&DEBUG_context))
-                    LDT_Print( SELECTOR_TO_ENTRY(ES_reg(&DEBUG_context)), 1 );
-            }
-            LDT_Print( SELECTOR_TO_ENTRY(FS_reg(&DEBUG_context)), 1 );
-#endif
-            DEBUG_BackTrace();
-        }
-	else
+        if (is_debug || force)
 	{
 	  /*
 	   * Do a quiet backtrace so that we have an idea of what the situation
 	   * is WRT the source files.
 	   */
-	    DEBUG_SilentBackTrace();
+	    DEBUG_BackTrace(FALSE);
 	}
+	else
+        {
+	    /* This is a real crash, dump some info */
+            DEBUG_InfoRegisters();
+            DEBUG_InfoStack();
+#ifdef __i386__
+            if (DEBUG_CurrThread->dbg_mode == 16)
+            {
+	        DEBUG_InfoSegments( DEBUG_context.SegDs >> 3, 1 );
+                if (DEBUG_context.SegEs != DEBUG_context.SegDs)
+                    DEBUG_InfoSegments( DEBUG_context.SegEs >> 3, 1 );
+            }
+            DEBUG_InfoSegments( DEBUG_context.SegFs >> 3, 1 );
+#endif
+            DEBUG_BackTrace(TRUE);
+        }
 
 	if (!is_debug ||
-            (dbg_exec_mode == EXEC_STEPI_OVER) ||
-            (dbg_exec_mode == EXEC_STEPI_INSTR))
+            (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_OVER) ||
+            (DEBUG_CurrThread->dbg_exec_mode == EXEC_STEPI_INSTR))
         {
 	    /* Show where we crashed */
 	    curr_frame = 0;
-	    DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
+	    DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
 	    fprintf(stderr,":  ");
-	    if (DBG_CHECK_READ_PTR( &addr, 1 ))
-	      {
-		DEBUG_Disasm( &addr, TRUE );
-		fprintf(stderr,"\n");
-	      }
+	    DEBUG_Disasm( &addr, TRUE );
+	    fprintf( stderr, "\n" );
         }
 
         ret_ok = 0;
         do
         {
-            issue_prompt();
-            yyparse();
-            flush_symbols();
+	    __TRY 
+	    {
+	       issue_prompt();
+	       yyparse();
+	       flush_symbols();
 
-            DEBUG_GetCurrentAddress( &addr );
-            ret_ok = DEBUG_ValidateRegisters();
-            if (ret_ok) ret_ok = DBG_CHECK_READ_PTR( &addr, 1 );
+	       DEBUG_GetCurrentAddress( &addr );
+	       if ((ret_ok = DEBUG_ValidateRegisters()))
+		  ret_ok = DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &addr ), &ch, 1 );
+	    } 
+	    __EXCEPT(no_symbol)
+	    {
+	       fprintf(stderr, "Undefined symbol\n");
+	       ret_ok = 0;
+	    }
+	    __ENDTRY;
+
         } while (!ret_ok);
     }
 
-    dbg_exec_mode = DEBUG_RestartExecution( dbg_exec_mode, dbg_exec_count );
+    DEBUG_CurrThread->dbg_exec_mode = DEBUG_RestartExecution( DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count );
     /*
      * This will have gotten absorbed into the breakpoint info
      * if it was used.  Otherwise it would have been ignored.
      * In any case, we don't mess with it any more.
      */
-    if ((dbg_exec_mode == EXEC_CONT) || (dbg_exec_mode == EXEC_PASS))
-      {
-	dbg_exec_count = 0;
+    if ((DEBUG_CurrThread->dbg_exec_mode == EXEC_CONT) || (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS))
+	DEBUG_CurrThread->dbg_exec_count = 0;
 
-        DEBUG_Freeze( FALSE );
-      }
-
-    in_debugger = FALSE;
-
-    if (USER_Driver) USER_Driver->pEndDebugging();
+/* EPP     if (USER_Driver) USER_Driver->pEndDebugging(); */
+    
+    return (DEBUG_CurrThread->dbg_exec_mode == EXEC_PASS) ? 0 : DBG_CONTINUE;
 }
 
-
-DWORD wine_debugger( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
-{
-    BOOL is_debug = FALSE;
-
-    if (first_chance && !Options.debug) return 0;  /* pass to app first */
-
-    switch(rec->ExceptionCode)
-    {
-    case EXCEPTION_BREAKPOINT:
-    case EXCEPTION_SINGLE_STEP:
-        is_debug = TRUE;
-        break;
-    case CONTROL_C_EXIT:
-        if (!Options.debug) DEBUG_Exit(0);
-        break;
-    }
-
-    if (!is_debug)
-    {
-        /* print some infos */
-        fprintf( stderr, "%s: ",
-                 first_chance ? "First chance exception" : "Unhandled exception" );
-        switch(rec->ExceptionCode)
-        {
-        case EXCEPTION_INT_DIVIDE_BY_ZERO:
-            fprintf( stderr, "divide by zero" );
-            break;
-        case EXCEPTION_INT_OVERFLOW:
-            fprintf( stderr, "overflow" );
-            break;
-        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
-            fprintf( stderr, "array bounds " );
-            break;
-        case EXCEPTION_ILLEGAL_INSTRUCTION:
-            fprintf( stderr, "illegal instruction" );
-            break;
-        case EXCEPTION_STACK_OVERFLOW:
-            fprintf( stderr, "stack overflow" );
-            break;
-        case EXCEPTION_PRIV_INSTRUCTION:
-            fprintf( stderr, "priviledged instruction" );
-            break;
-        case EXCEPTION_ACCESS_VIOLATION:
-            if (rec->NumberParameters == 2)
-                fprintf( stderr, "page fault on %s access to 0x%08lx", 
-                         rec->ExceptionInformation[0] ? "write" : "read",
-                         rec->ExceptionInformation[1] );
-            else
-                fprintf( stderr, "page fault" );
-            break;
-        case EXCEPTION_DATATYPE_MISALIGNMENT:
-            fprintf( stderr, "Alignment" );
-            break;
-        case CONTROL_C_EXIT:
-            fprintf( stderr, "^C" );
-            break;
-        case EXCEPTION_CRITICAL_SECTION_WAIT:
-            fprintf( stderr, "critical section %08lx wait failed", rec->ExceptionInformation[0] );
-            break;
-        default:
-            fprintf( stderr, "%08lx", rec->ExceptionCode );
-            break;
-        }
-    }
-
-    DEBUG_context = *context;
-    DEBUG_Main( is_debug );
-    *context = DEBUG_context;
-    return (dbg_exec_mode == EXEC_PASS) ? 0 : DBG_CONTINUE;
-}
-
-int yyerror(char * s)
+int yyerror(char* s)
 {
 	fprintf(stderr,"%s\n", s);
         return 0;
diff --git a/debugger/debug.l b/debugger/debug.l
index 045ec39..de15577 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -119,7 +119,6 @@
 <INITIAL>frame|fram|fra|fr		{ BEGIN(NOCMD); return tFRAME; }
 <INITIAL>list|lis|li|l			{ BEGIN(PATH_EXPECTED); return tLIST; }
 <INITIAL>enable|enabl|enab|ena		{ BEGIN(NOCMD); return tENABLE;}
-<INITIAL>debugmsg|debugms|debugm|debug|debu|deb { BEGIN(DEBUGSTR); return tDEBUGMSG;}
 <INITIAL>disable|disabl|disab|disa|dis  { BEGIN(NOCMD); return tDISABLE; }
 <INITIAL>disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; }
 <INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp	{ BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
diff --git a/debugger/debugger.h b/debugger/debugger.h
new file mode 100644
index 0000000..d51ddc3
--- /dev/null
+++ b/debugger/debugger.h
@@ -0,0 +1,395 @@
+/*
+ * Debugger definitions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef __WINE_DEBUGGER_H
+#define __WINE_DEBUGGER_H
+
+#include <sys/types.h> /* u_long ... */
+#include "windef.h"
+#include "winbase.h"
+
+#ifdef __i386__
+#define STEP_FLAG 0x100 /* single step flag */
+#define V86_FLAG  0x00020000
+#endif
+
+#define SYM_FUNC	 0x0
+#define SYM_DATA	 0x1
+#define SYM_WIN32	 0x2
+#define SYM_WINE	 0x4
+#define SYM_INVALID	 0x8
+#define SYM_TRAMPOLINE	 0x10
+#define SYM_STEP_THROUGH 0x20
+
+enum	debug_type {DT_BASIC, DT_CONST, DT_POINTER, DT_ARRAY, DT_STRUCT, DT_ENUM, DT_TYPEDEF, DT_FUNC, DT_BITFIELD};
+
+
+/*
+ * Return values for DEBUG_CheckLinenoStatus.  Used to determine
+ * what to do when the 'step' command is given.
+ */
+#define FUNC_HAS_NO_LINES	(0)
+#define NOT_ON_LINENUMBER	(1)
+#define AT_LINENUMBER		(2)
+#define FUNC_IS_TRAMPOLINE	(3)
+
+/*
+ * For constants generated by the parser, we use this datatype
+ */
+extern struct datatype * DEBUG_TypeInt;
+extern struct datatype * DEBUG_TypeIntConst;
+extern struct datatype * DEBUG_TypeUSInt;
+extern struct datatype * DEBUG_TypeString;
+
+typedef struct
+{
+    struct datatype * type;
+    DWORD seg;  /* 0xffffffff means current default segment (cs or ds) */
+    DWORD off;
+} DBG_ADDR;
+
+struct list_id
+{
+    char * sourcefile;
+    int    line;
+};
+
+struct  wine_lines {
+  unsigned long		line_number;
+  DBG_ADDR		pc_offset;
+};
+
+struct symbol_info
+{
+  struct name_hash * sym;
+  struct list_id     list;
+};
+
+typedef struct wine_lines WineLineNo;
+
+/*
+ * This structure holds information about stack variables, function
+ * parameters, and register variables, which are all local to this
+ * function.
+ */
+struct  wine_locals {
+  unsigned int		regno:8;	/* For register symbols */
+  signed int		offset:24;	/* offset from esp/ebp to symbol */
+  unsigned int		pc_start;	/* For RBRAC/LBRAC */
+  unsigned int		pc_end;		/* For RBRAC/LBRAC */
+  char		      * name;		/* Name of symbol */
+  struct datatype     * type;		/* Datatype of symbol */
+};
+
+typedef struct wine_locals WineLocals;
+
+enum exec_mode
+{
+    EXEC_CONT,       		/* Continuous execution */
+    EXEC_PASS,       		/* Continue, passing exception to app */
+    EXEC_STEP_OVER,  		/* Stepping over a call to next source line */
+    EXEC_STEP_INSTR,  		/* Step to next source line, stepping in if needed */
+    EXEC_STEPI_OVER,  		/* Stepping over a call */
+    EXEC_STEPI_INSTR,  		/* Single-stepping an instruction */
+    EXEC_FINISH,		/* Step until we exit current frame */
+    EXEC_STEP_OVER_TRAMPOLINE  	/* Step over trampoline.  Requires that
+				 * we dig the real return value off the stack
+				 * and set breakpoint there - not at the
+				 * instr just after the call.
+				 */
+};
+ 
+typedef struct
+{
+    DBG_ADDR      addr;
+    BYTE          addrlen;
+    BYTE          opcode;
+    WORD	  skipcount;
+    WORD	  enabled : 1, 
+                  refcount;
+    struct expr * condition;
+} BREAKPOINT;
+
+typedef struct tagWINE_DBG_THREAD {
+    struct tagWINE_DBG_PROCESS*	process;
+    HANDLE			handle;
+    DWORD			tid;
+    LPVOID			start;
+    LPVOID			teb;
+    int				wait_for_first_exception;
+    int				dbg_mode;
+    enum exec_mode 		dbg_exec_mode;
+    int 			dbg_exec_count;
+    BREAKPOINT			stepOverBP;
+    struct tagWINE_DBG_THREAD* 	next;
+    struct tagWINE_DBG_THREAD* 	prev;
+} WINE_DBG_THREAD;
+
+typedef struct tagWINE_DBG_PROCESS {
+    HANDLE			handle;
+    DWORD			pid;
+    WINE_DBG_THREAD*		threads;
+    struct tagWINE_DBG_PROCESS*	next;
+    struct tagWINE_DBG_PROCESS*	prev;
+} WINE_DBG_PROCESS;
+
+extern	WINE_DBG_PROCESS* DEBUG_CurrProcess;
+extern	WINE_DBG_THREAD*  DEBUG_CurrThread;
+extern  CONTEXT		  DEBUG_context;
+
+#define DEBUG_READ_MEM(addr, buf, len) \
+      (ReadProcessMemory(DEBUG_CurrProcess->handle, (addr), (buf), (len), NULL))
+
+#define DEBUG_WRITE_MEM(addr, buf, len) \
+      (WriteProcessMemory(DEBUG_CurrProcess->handle, (addr), (buf), (len), NULL))
+
+#define DEBUG_READ_MEM_VERBOSE(addr, buf, len) \
+      (DEBUG_READ_MEM((addr), (buf), (len)) || (DEBUG_InvalLinAddr( addr ),0))
+
+#define DEBUG_WRITE_MEM_VERBOSE(addr, buf, len) \
+      (DEBUG_WRITE_MEM((addr), (buf), (len)) || (DEBUG_InvalLinAddr( addr ),0))
+
+#ifdef __i386__
+#ifdef REG_SP  /* Some Sun includes define this */
+#undef REG_SP
+#endif
+
+enum debug_regs
+{
+    REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI,
+    REG_EDI, REG_EBP, REG_EFL, REG_EIP, REG_ESP,
+    REG_AX,  REG_BX,  REG_CX,  REG_DX,  REG_SI,
+    REG_DI,  REG_BP,  REG_FL,  REG_IP,  REG_SP,
+    REG_CS,  REG_DS,  REG_ES,  REG_SS,  REG_FS, REG_GS
+};
+#endif
+
+#define	OFFSET_OF(__c,__f)		((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
+
+  /* debugger/break.c */
+extern void DEBUG_SetBreakpoints( BOOL set );
+extern int  DEBUG_FindBreakpoint( const DBG_ADDR *addr );
+extern void DEBUG_AddBreakpoint( const DBG_ADDR *addr );
+extern void DEBUG_DelBreakpoint( int num );
+extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
+extern void DEBUG_InfoBreakpoints(void);
+extern BOOL DEBUG_HandleTrap(void);
+extern BOOL DEBUG_ShouldContinue( enum exec_mode mode, int * count );
+extern void DEBUG_SuspendExecution( void );
+extern enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count );
+extern BOOL DEBUG_IsFctReturn(void);
+
+  /* debugger/db_disasm.c */
+extern void DEBUG_Disasm( DBG_ADDR *addr, int display );
+
+  /* debugger/expr.c */
+extern void DEBUG_FreeExprMem(void);
+struct expr * DEBUG_RegisterExpr(enum debug_regs);
+struct expr * DEBUG_SymbolExpr(const char * name);
+struct expr * DEBUG_ConstExpr(int val);
+struct expr * DEBUG_StringExpr(const char * str);
+struct expr * DEBUG_SegAddr(struct expr *, struct expr *);
+struct expr * DEBUG_USConstExpr(unsigned int val);
+struct expr * DEBUG_BinopExpr(int oper, struct expr *, struct expr *);
+struct expr * DEBUG_UnopExpr(int oper, struct expr *);
+struct expr * DEBUG_StructPExpr(struct expr *, const char * element);
+struct expr * DEBUG_StructExpr(struct expr *, const char * element);
+struct expr * DEBUG_ArrayExpr(struct expr *, struct expr * index);
+struct expr * DEBUG_CallExpr(const char *, int nargs, ...);
+struct expr * DEBUG_TypeCastExpr(struct datatype *, struct expr *);
+extern int  DEBUG_ExprValue(const DBG_ADDR *, unsigned int *);
+extern DBG_ADDR DEBUG_EvalExpr(struct expr *);
+extern int DEBUG_DelDisplay(int displaynum);
+extern struct expr * DEBUG_CloneExpr(struct expr * exp);
+extern int DEBUG_FreeExpr(struct expr * exp);
+extern int DEBUG_DisplayExpr(struct expr * exp);
+
+  /* more debugger/break.c */
+extern int DEBUG_AddBPCondition(int bpnum, struct expr * exp);
+
+  /* debugger/display.c */
+extern int DEBUG_DoDisplay(void);
+extern int DEBUG_AddDisplay(struct expr * exp, int count, char format);
+extern int DEBUG_DoDisplay(void);
+extern int DEBUG_DelDisplay(int displaynum);
+extern int DEBUG_InfoDisplay(void);
+
+  /* debugger/hash.c */
+extern struct name_hash * DEBUG_AddSymbol( const char *name, 
+					   const DBG_ADDR *addr,
+					   const char * sourcefile,
+					   int flags);
+extern struct name_hash * DEBUG_AddInvSymbol( const char *name, 
+					   const DBG_ADDR *addr,
+					   const char * sourcefile);
+extern BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
+				     DBG_ADDR *addr, int );
+extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_ADDR *addr );
+extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
+					     struct name_hash ** rtn,
+					     unsigned int ebp,
+					     struct list_id * source);
+extern void DEBUG_ReadSymbolTable( const char * filename );
+extern int  DEBUG_LoadEntryPoints( const char * prefix );
+extern void DEBUG_AddLineNumber( struct name_hash * func, int line_num, 
+		     unsigned long offset );
+extern struct wine_locals *
+            DEBUG_AddLocal( struct name_hash * func, int regno, 
+			    int offset,
+			    int pc_start,
+			    int pc_end,
+			    char * name);
+extern int DEBUG_CheckLinenoStatus(const DBG_ADDR *addr);
+extern void DEBUG_GetFuncInfo(struct list_id * ret, const char * file, 
+			      const char * func);
+extern int DEBUG_SetSymbolSize(struct name_hash * sym, unsigned int len);
+extern int DEBUG_SetSymbolBPOff(struct name_hash * sym, unsigned int len);
+extern int DEBUG_GetSymbolAddr(struct name_hash * sym, DBG_ADDR * addr);
+extern int DEBUG_cmp_sym(const void * p1, const void * p2);
+extern BOOL DEBUG_GetLineNumberAddr( struct name_hash *, const int lineno, 
+				DBG_ADDR *addr, int bp_flag );
+
+extern int DEBUG_SetLocalSymbolType(struct wine_locals * sym, 
+				    struct datatype * type);
+BOOL DEBUG_Normalize(struct name_hash * nh );
+
+  /* debugger/info.c */
+extern void DEBUG_PrintBasic( const DBG_ADDR *addr, int count, char format );
+extern struct symbol_info DEBUG_PrintAddress( const DBG_ADDR *addr, 
+					      int addrlen, int flag );
+extern void DEBUG_Help(void);
+extern void DEBUG_HelpInfo(void);
+extern struct symbol_info DEBUG_PrintAddressAndArgs( const DBG_ADDR *addr, 
+						     int addrlen, 
+						     unsigned int ebp, 
+						     int flag );
+extern void DEBUG_InfoClass(const char* clsName);
+extern void DEBUG_WalkClasses(void);
+extern void DEBUG_WalkModref(DWORD p);
+extern void DEBUG_DumpModule(DWORD mod);
+extern void DEBUG_WalkModules(void);
+extern void DEBUG_WalkProcess(void);
+extern void DEBUG_DumpQueue(DWORD q);
+extern void DEBUG_WalkQueues(void);
+extern void DEBUG_InfoSegments(DWORD s, int v);
+extern void DEBUG_InfoVirtual(void);
+extern void DEBUG_InfoWindow(HWND hWnd);
+extern void DEBUG_WalkWindows(HWND hWnd, int indent);
+
+  /* debugger/memory.c */
+extern int DEBUG_ReadMemory( const DBG_ADDR *address );
+extern void DEBUG_WriteMemory( const DBG_ADDR *address, int value );
+extern void DEBUG_ExamineMemory( const DBG_ADDR *addr, int count, char format);
+extern void DEBUG_InvalLinAddr( void* addr );
+#ifdef __i386__
+extern void DEBUG_GetCurrentAddress( DBG_ADDR * );
+extern DWORD DEBUG_ToLinear( const DBG_ADDR *address );
+extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
+extern BOOL DEBUG_FixSegment( DBG_ADDR* addr );
+extern int  DEBUG_GetSelectorType( WORD sel );
+extern int  DEBUG_IsSelectorSystem( WORD sel );
+#endif
+
+  /* debugger/registers.c */
+extern void DEBUG_SetRegister( enum debug_regs reg, int val );
+extern int DEBUG_GetRegister( enum debug_regs reg );
+extern void DEBUG_InfoRegisters(void);
+extern BOOL DEBUG_ValidateRegisters(void);
+extern int DEBUG_PrintRegister(enum debug_regs reg);
+
+  /* debugger/stack.c */
+extern void DEBUG_InfoStack(void);
+extern void DEBUG_BackTrace(BOOL noisy);
+extern int  DEBUG_InfoLocals(void);
+extern int  DEBUG_SetFrame(int newframe);
+extern int  DEBUG_GetCurrentFrame(struct name_hash ** name, 
+				  unsigned int * eip,
+				  unsigned int * ebp);
+
+  /* debugger/stabs.c */
+extern int DEBUG_ReadExecutableDbgInfo(void);
+extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff, int stablen, unsigned int strtaboff, int strtablen);
+
+  /* debugger/msc.c */
+extern int DEBUG_RegisterDebugInfo( HMODULE, const char *);
+extern int DEBUG_ProcessDeferredDebug(void);
+extern int DEBUG_RegisterELFDebugInfo(int load_addr, u_long size, const char * name);
+extern void DEBUG_InfoShare(void);
+extern void DEBUG_InitCVDataTypes(void);
+
+  /* debugger/types.c */
+extern int DEBUG_nchar;
+extern void DEBUG_InitTypes(void);
+extern struct datatype * DEBUG_NewDataType(enum debug_type xtype, 
+					   const char * typename);
+extern unsigned int 
+DEBUG_TypeDerefPointer(const DBG_ADDR * addr, struct datatype ** newtype);
+extern int DEBUG_AddStructElement(struct datatype * dt, 
+				  char * name, struct datatype * type, 
+				  int offset, int size);
+extern int DEBUG_SetStructSize(struct datatype * dt, int size);
+extern int DEBUG_SetPointerType(struct datatype * dt, struct datatype * dt2);
+extern int DEBUG_SetArrayParams(struct datatype * dt, int min, int max,
+				struct datatype * dt2);
+extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level );
+extern unsigned int DEBUG_FindStructElement(DBG_ADDR * addr, 
+					    const char * ele_name, int * tmpbuf);
+extern struct datatype * DEBUG_GetPointerType(struct datatype * dt);
+extern int DEBUG_GetObjectSize(struct datatype * dt);
+extern unsigned int DEBUG_ArrayIndex(const DBG_ADDR * addr, DBG_ADDR * result, int index);
+extern struct datatype * DEBUG_FindOrMakePointerType(struct datatype * reftype);
+extern long long int DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format);
+extern int DEBUG_SetBitfieldParams(struct datatype * dt, int offset, 
+				   int nbits, struct datatype * dt2);
+extern int DEBUG_CopyFieldlist(struct datatype * dt, struct datatype * dt2);
+extern enum debug_type DEBUG_GetType(struct datatype * dt);
+extern struct datatype * DEBUG_TypeCast(enum debug_type, const char *);
+extern int DEBUG_PrintTypeCast(struct datatype *);
+
+  /* debugger/source.c */
+extern void DEBUG_ShowDir(void);
+extern void DEBUG_AddPath(const char * path);
+extern void DEBUG_List(struct list_id * line1, struct list_id * line2,  
+		       int delta);
+extern void DEBUG_NukePath(void);
+extern void DEBUG_Disassemble( const DBG_ADDR *, const DBG_ADDR*, int offset );
+
+  /* debugger/external.c */
+extern void DEBUG_ExternalDebugger(void);
+
+  /* debugger/dbg.y */
+extern void DEBUG_Exit( DWORD exit_code );
+extern BOOL DEBUG_Main( BOOL is_debug, BOOL force );
+
+  /* Choose your allocator! */
+#if 1
+/* this one is libc's fast one */
+extern void*	DEBUG_XMalloc(size_t size);
+extern void*	DEBUG_XReAlloc(void *ptr, size_t size);
+extern char*	DEBUG_XStrDup(const char *str);
+
+#define DBG_alloc(x)		DEBUG_XMalloc(x)
+#define DBG_realloc(x,y) 	DEBUG_XReAlloc(x,y)
+#define DBG_free(x) 		free(x)
+#define DBG_strdup(x) 		DEBUG_XStrDup(x)
+#else
+/* this one is slow (takes 5 minutes to load the debugger on my machine),
+   but is pretty crash-proof (can step through malloc() without problems,
+   malloc() arena (and other heaps) can be totally wasted and it'll still
+   work, etc... if someone could make optimized routines so it wouldn't
+   take so long to load, it could be made default) */
+#include "heap.h"
+#define DBG_alloc(x) HEAP_xalloc(dbg_heap,0,x)
+#define DBG_realloc(x,y) HEAP_xrealloc(dbg_heap,0,x,y)
+#define DBG_free(x) HeapFree(dbg_heap,0,x)
+#define DBG_strdup(x) HEAP_strdupA(dbg_heap,0,x)
+#define DBG_need_heap
+extern HANDLE dbg_heap;
+#endif
+
+#define		DEBUG_STATUS_NO_SYMBOL	0x80003000
+
+#endif  /* __WINE_DEBUGGER_H */
diff --git a/debugger/display.c b/debugger/display.c
index df9f9fc..431a289 100644
--- a/debugger/display.c
+++ b/debugger/display.c
@@ -11,9 +11,6 @@
 #include <limits.h>
 #include <sys/types.h>
 
-#include "neexe.h"
-#include "module.h"
-#include "selectors.h"
 #include "debugger.h"
 
 #include <stdarg.h>
diff --git a/debugger/expr.c b/debugger/expr.c
index fbee595..b4e4345 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -299,7 +299,6 @@
   DBG_ADDR	exp1;
   DBG_ADDR	exp2;
   unsigned int	cexp[5];
-  int		(*fptr)();
   int		    scale1;
   int		    scale2;
   int		    scale3;
@@ -332,12 +331,20 @@
       rtn.seg = 0;
       break;
     case EXPR_TYPE_SYMBOL:
-      if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE ) )
-	{
-	  rtn.type = NULL;
-	  rtn.off = 0;
-	  rtn.seg = 0;
-	};
+      if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
+	{    
+#if 1
+	   RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
+#else
+	   static        char    ret[128];
+
+	   /* FIXME: this is an ugly hack... but at least we know
+	    * the symbol is not defined
+	    */
+	   sprintf(ret, "\"Symbol %s is not defined.\"", exp->un.symbol.name);
+	   rtn = DEBUG_EvalExpr(DEBUG_StringExpr(ret));
+#endif
+	}
       break;
     case EXPR_TYPE_PSTRUCT:
       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
@@ -388,6 +395,13 @@
 	  break;
 	}
 
+#if 0
+      /* FIXME: NEWDBG NIY */
+      /* Anyway, I wonder how this could work depending on the calling order of
+       * the function (cdecl vs pascal for example)
+       */
+      int		(*fptr)();
+
       fptr = (int (*)()) rtn.off;
       switch(exp->un.call.nargs)
 	{
@@ -410,8 +424,16 @@
 	  exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
 	  break;
 	}
+#else
+      fprintf(stderr, "Function call no longer implemented\n");
+      /* would need to set up a call to this function, and then restore the current
+       * context afterwards...
+       */
+      exp->un.call.result = 0;
+#endif
       rtn.type = DEBUG_TypeInt;
       rtn.off = (unsigned int) &exp->un.call.result;
+
       break;
     case EXPR_TYPE_REGISTER:
       rtn.type = DEBUG_TypeIntConst;
@@ -419,11 +441,11 @@
       rtn.off = (unsigned int) &exp->un.rgister.result;
 #ifdef __i386__
       if( exp->un.rgister.reg == REG_EIP )
-	  rtn.seg = CS_reg(&DEBUG_context);
+	  rtn.seg = DEBUG_context.SegCs;
       else
-	  rtn.seg = DS_reg(&DEBUG_context);
+	  rtn.seg = DEBUG_context.SegDs;
 #endif
-      DBG_FIX_ADDR_SEG( &rtn, 0 );
+      DEBUG_FixAddress( &rtn, 0 );
       break;
     case EXPR_TYPE_BINOP:
       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
@@ -497,11 +519,7 @@
 	  rtn.seg = VAL(exp1);
           exp->un.binop.result = VAL(exp2);
 #ifdef __i386__
-          if (ISV86(&DEBUG_context)) {
-            TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
-            rtn.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16;
-            GlobalUnlock16( GetCurrentTask() );
-          }
+	  DEBUG_FixSegment(&rtn);
 #endif
 	  break;
 	case EXP_OP_LOR:
@@ -623,12 +641,12 @@
 	  exp->un.unop.result = ~VAL(exp1);
 	  break;
 	case EXP_OP_DEREF:
-	  rtn.seg = 0;
+ 	  rtn.seg = 0;
 	  rtn.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
 	  break;
 	case EXP_OP_FORCE_DEREF:
 	  rtn.seg = exp1.seg;
-	  rtn.off = *(unsigned int *) exp1.off;
+	  rtn.off = DEBUG_READ_MEM((void*)exp1.off, &rtn.off, sizeof(rtn.off));
 	  break;
 	case EXP_OP_ADDR:
 	  rtn.seg = 0;
@@ -686,10 +704,6 @@
       fprintf(stderr, ".%s", exp->un.structure.element_name);
       break;
     case EXPR_TYPE_CALL:
-      /*
-       * First, evaluate all of the arguments.  If any of them are not
-       * evaluable, then bail.
-       */
       fprintf(stderr, "%s(",exp->un.call.funcname);
       for(i=0; i < exp->un.call.nargs; i++)
 	{
@@ -841,10 +855,6 @@
       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
       break;
     case EXPR_TYPE_CALL:
-      /*
-       * First, evaluate all of the arguments.  If any of them are not
-       * evaluable, then bail.
-       */
       for(i=0; i < exp->un.call.nargs; i++)
 	{
 	  rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
@@ -898,10 +908,6 @@
       DBG_free((char *) exp->un.structure.element_name);
       break;
     case EXPR_TYPE_CALL:
-      /*
-       * First, evaluate all of the arguments.  If any of them are not
-       * evaluable, then bail.
-       */
       for(i=0; i < exp->un.call.nargs; i++)
 	{
 	  DEBUG_FreeExpr(exp->un.call.arg[i]);
diff --git a/debugger/hash.c b/debugger/hash.c
index 8d79102..35aaf6b 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -14,7 +14,6 @@
 #include "neexe.h"
 #include "module.h"
 #include "process.h"
-#include "selectors.h"
 #include "debugger.h"
 #include "toolhelp.h"
 
@@ -335,7 +334,7 @@
  * Get the address of a named symbol.
  */
 BOOL DEBUG_GetSymbolValue( const char * name, const int lineno, 
-			     DBG_ADDR *addr, int bp_flag )
+			   DBG_ADDR *addr, int bp_flag )
 {
     char buffer[256];
     struct name_hash *nh;
@@ -450,7 +449,7 @@
     if (!nh) return FALSE;
     nh->addr = *addr;
     nh->flags &= SYM_INVALID;
-    DBG_FIX_ADDR_SEG( &nh->addr, DS_reg(&DEBUG_context) );
+    DEBUG_FixAddress( &nh->addr, DEBUG_context.SegDs );
     return TRUE;
 }
 
@@ -477,6 +476,7 @@
     char * lineinfo, *sourcefile;
     int i;
     char linebuff[16];
+    unsigned val;
 
     if( rtn != NULL )
       {
@@ -637,9 +637,9 @@
 	      {
 		strcat(arglist, ", ");
 	      }
+	    DEBUG_READ_MEM_VERBOSE(ptr, &val, sizeof(val));
+	    sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name, val);
 
-	    sprintf(argtmp, "%s=0x%x", nearest->local_vars[i].name,
-		    *ptr);
 	    strcat(arglist, argtmp);
 	  }
 	if( arglist[0] == '(' )
@@ -1367,13 +1367,26 @@
 	  /* FIXME: what if regno == 0 ($eax) */
 	  if( curr_func->local_vars[i].regno != 0 )
 	    {
+#if 0
+	       /* FIXME: NEWDBG NIY */
+	       /* this is a hack: addr points to the current processor context
+		* (as defined while entering the debugger), and uses a pointer
+		* to main memory (thus sharing the process address space *AND*
+		* the debugger address space, which is not good with address
+		* space separation in place)
+		*/
 	      /*
 	       * Register variable.  Point to DEBUG_context field.
 	       */
 	      addr->seg = 0;
-	      addr->off = ((DWORD)&DEBUG_context) + reg_ofs[curr_func->local_vars[i].regno];
+	      addr->off = ((DWORD)DEBUG_context) + reg_ofs[curr_func->local_vars[i].regno];
 	      addr->type = curr_func->local_vars[i].type;
-	      
+#else
+	      fprintf(stderr, "No longer supported: value of register variable\n");
+	      addr->seg = 0;
+	      addr->off = 0;
+	      addr->type = NULL;
+#endif	      
 	      return TRUE;
 	    }
 
@@ -1395,7 +1408,7 @@
   unsigned int	      eip;
   int		      i;
   unsigned int      * ptr;
-  int		      rtn = FALSE;
+  unsigned int	      val;
 
   if( DEBUG_GetCurrentFrame(&curr_func, &eip, &ebp) == FALSE )
     {
@@ -1433,16 +1446,14 @@
 	}
       else
 	{
-	  ptr = (unsigned int *) (ebp + curr_func->local_vars[i].offset);
+	  DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset), 
+				 &val, sizeof(val));
 	  fprintf(stderr, "%s:%s == 0x%8.8x\n",
-		  curr_func->name, curr_func->local_vars[i].name,
-		  *ptr);
+		  curr_func->name, curr_func->local_vars[i].name, val);
 	}
     }
 
-  rtn = TRUE;
-
-  return (rtn);
+  return TRUE;
 }
 
 int
diff --git a/debugger/info.c b/debugger/info.c
index ec1f098..2a6e00b 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -8,6 +8,10 @@
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "toolhelp.h"
 #include "debugger.h"
 #include "expr.h"
 
@@ -28,7 +32,7 @@
     }
   
   default_format = NULL;
-  value = DEBUG_GetExprValue((DBG_ADDR *) addr, &default_format);
+  value = DEBUG_GetExprValue(addr, &default_format);
 
   switch(format)
     {
@@ -188,3 +192,264 @@
 
     while(infotext[i]) fprintf(stderr,"%s\n", infotext[i++]);
 }
+
+/* FIXME: merge InfoClass and InfoClass2 */
+void DEBUG_InfoClass(const char* name)
+{
+   WNDCLASSEXA	wca;
+
+   if (!GetClassInfoExA(0, name, &wca)) {
+      fprintf(stderr, "Cannot find class '%s'\n", name);
+      return;
+   }
+
+   fprintf(stderr,  "Class '%s':\n", name);
+   fprintf(stderr,  
+	   "style=%08x  wndProc=%08lx\n"
+	   "inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+	   "clsExtra=%d  winExtra=%d\n",
+	   wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
+	   wca.hIcon, wca.hCursor, wca.hbrBackground,
+	   wca.cbClsExtra, wca.cbWndExtra);
+
+   /* FIXME: 
+    * + print #windows (or even list of windows...)
+    * + print extra bytes => this requires a window handle on this very class...
+    */
+}
+
+static	void DEBUG_InfoClass2(HWND hWnd, const char* name)
+{
+   WNDCLASSEXA	wca;
+
+   if (!GetClassInfoExA(GetWindowLongA(hWnd, GWL_HINSTANCE), name, &wca)) {
+      fprintf(stderr, "Cannot find class '%s'\n", name);
+      return;
+   }
+
+   fprintf(stderr,  "Class '%s':\n", name);
+   fprintf(stderr,  
+	   "style=%08x  wndProc=%08lx\n"
+	   "inst=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+	   "clsExtra=%d  winExtra=%d\n",
+	   wca.style, (DWORD)wca.lpfnWndProc, wca.hInstance,
+	   wca.hIcon, wca.hCursor, wca.hbrBackground,
+	   wca.cbClsExtra, wca.cbWndExtra);
+
+   if (wca.cbClsExtra) {
+      int		i;
+      WORD		w;
+
+      fprintf(stderr,  "Extra bytes:" );
+      for (i = 0; i < wca.cbClsExtra / 2; i++) {
+	 w = GetClassWord(hWnd, i * 2);
+	 /* FIXME: depends on i386 endian-ity */
+	 fprintf(stderr,  " %02x", HIBYTE(w));
+	 fprintf(stderr,  " %02x", LOBYTE(w));
+      }
+      fprintf(stderr,  "\n" );
+    }
+    fprintf(stderr,  "\n" );
+}
+
+struct class_walker {
+   ATOM*	table;
+   int		used;
+   int		alloc;
+};
+
+static	void DEBUG_WalkClassesHelper(HWND hWnd, struct class_walker* cw)
+{
+   char	clsName[128];
+   int	i;
+   ATOM	atom;
+   HWND	child;
+
+   if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+      return;
+   if ((atom = FindAtomA(clsName)) == 0)
+      return;
+
+   for (i = 0; i < cw->used; i++) {
+      if (cw->table[i] == atom)
+	 break;
+   }
+   if (i == cw->used) {
+      if (cw->used >= cw->alloc) {
+	 cw->alloc += 16;
+	 cw->table = DBG_realloc(cw->table, cw->alloc * sizeof(ATOM));
+      }
+      cw->table[cw->used++] = atom;
+      DEBUG_InfoClass2(hWnd, clsName);
+   }
+   do {
+      if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
+	 DEBUG_WalkClassesHelper(child, cw);
+   } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
+}
+
+void DEBUG_WalkClasses(void)
+{
+   struct class_walker cw;
+
+   cw.table = NULL;
+   cw.used = cw.alloc = 0;
+   DEBUG_WalkClassesHelper(GetDesktopWindow(), &cw);
+   DBG_free(cw.table);
+}
+
+void DEBUG_DumpModule(DWORD mod)
+{
+   fprintf(stderr, "No longer doing info module '0x%08lx'\n", mod);
+}
+
+void DEBUG_WalkModules(void)
+{
+   fprintf(stderr, "No longer walking modules list\n");
+}
+
+void DEBUG_DumpQueue(DWORD q)
+{
+   fprintf(stderr, "No longer doing info queue '0x%08lx'\n", q);
+}
+
+void DEBUG_WalkQueues(void)
+{
+   fprintf(stderr, "No longer walking queues list\n");
+}
+
+void DEBUG_InfoWindow(HWND hWnd)
+{
+   char	clsName[128];
+   char	wndName[128];
+   RECT	clientRect;
+   RECT	windowRect;
+   int	i;
+   WORD	w;
+
+   if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+       strcpy(clsName, "-- Unknown --");
+   if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
+      strcpy(wndName, "-- Empty --");
+   if (!GetClientRect(hWnd, &clientRect))
+      SetRectEmpty(&clientRect);
+   if (!GetWindowRect(hWnd, &windowRect))
+      SetRectEmpty(&windowRect);
+
+   /* FIXME missing fields: hmemTaskQ, hrgnUpdate, dce, flags, pProp, scroll */
+   fprintf(stderr,
+	   "next=0x%04x  child=0x%04x  parent=0x%04x  owner=0x%04x  class='%s'\n"
+	   "inst=%08lx  active=%04x  idmenu=%08lx\n"
+	   "style=%08lx  exstyle=%08lx  wndproc=%08lx  text='%s'\n"
+	   "client=%d,%d-%d,%d  window=%d,%d-%d,%d sysmenu=%04x\n",
+	   GetWindow(hWnd, GW_HWNDNEXT), 
+	   GetWindow(hWnd, GW_CHILD),
+	   GetParent(hWnd), 
+	   GetWindow(hWnd, GW_OWNER),
+	   clsName,
+	   GetWindowLongA(hWnd, GWL_HINSTANCE), 
+	   GetLastActivePopup(hWnd),
+	   GetWindowLongA(hWnd, GWL_ID),
+	   GetWindowLongA(hWnd, GWL_STYLE),
+	   GetWindowLongA(hWnd, GWL_EXSTYLE),
+	   GetWindowLongA(hWnd, GWL_WNDPROC),
+	   wndName, 
+	   clientRect.left, clientRect.top, clientRect.right, clientRect.bottom, 
+	   windowRect.left, windowRect.top, windowRect.right, windowRect.bottom, 
+	   GetSystemMenu(hWnd, FALSE));
+
+    if (GetClassLongA(hWnd, GCL_CBWNDEXTRA)) {
+        fprintf(stderr,  "Extra bytes:" );
+        for (i = 0; i < GetClassLongA(hWnd, GCL_CBWNDEXTRA) / 2; i++) {
+	   w = GetWindowWord(hWnd, i * 2);
+	   /* FIXME: depends on i386 endian-ity */
+	   fprintf(stderr,  " %02x", HIBYTE(w));
+	   fprintf(stderr,  " %02x", LOBYTE(w));
+	}
+        fprintf(stderr, "\n");
+    }
+    fprintf(stderr, "\n");
+}
+
+void DEBUG_WalkWindows(HWND hWnd, int indent)
+{
+   char	clsName[128];
+   char	wndName[128];
+   HWND	child;
+
+   if (!IsWindow(hWnd))
+      hWnd = GetDesktopWindow();
+
+    if (!indent)  /* first time around */
+       fprintf(stderr,  
+	       "%-16.16s %-17.17s %-8.8s %s\n",
+	       "hwnd", "Class Name", " Style", " WndProc Text");
+
+    do {
+       if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
+	  strcpy(clsName, "-- Unknown --");
+       if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
+	  strcpy(wndName, "-- Empty --");
+       
+       /* FIXME: missing hmemTaskQ */
+       fprintf(stderr, "%*s%04x%*s", indent, "", hWnd, 13-indent,"");
+       fprintf(stderr, "%-17.17s %08lx %08lx %.14s\n",
+	       clsName, GetWindowLongA(hWnd, GWL_STYLE),
+	       GetWindowLongA(hWnd, GWL_WNDPROC), wndName);
+
+       if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
+	  DEBUG_WalkWindows(child, indent + 1 );
+    } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
+}
+
+void DEBUG_WalkProcess(void)
+{
+   fprintf(stderr, "No longer walking processes list\n");
+}
+
+void DEBUG_WalkModref(DWORD p)
+{
+   fprintf(stderr, "No longer walking module references list\n");
+}
+
+void DEBUG_InfoSegments(DWORD start, int length)
+{
+    char 	flags[3];
+    DWORD 	i;
+    LDT_ENTRY	le;
+
+    if (length == -1) length = (8192 - start);
+
+    for (i = start; i < start + length; i++)
+    {
+       if (!GetThreadSelectorEntry(DEBUG_CurrThread->handle, (i << 3)|7, &le))
+	  continue;
+
+        if (le.HighWord.Bits.Type & 0x08) 
+        {
+            flags[0] = (le.HighWord.Bits.Type & 0x2) ? 'r' : '-';
+            flags[1] = '-';
+            flags[2] = 'x';
+        }
+        else
+        {
+            flags[0] = 'r';
+            flags[1] = (le.HighWord.Bits.Type & 0x2) ? 'w' : '-';
+            flags[2] = '-';
+        }
+        fprintf(stderr, 
+		"%04lx: sel=%04lx base=%08x limit=%08x %d-bit %c%c%c\n",
+		i, (i<<3)|7, 
+		(le.HighWord.Bits.BaseHi << 24) + 
+		    (le.HighWord.Bits.BaseMid << 16) + le.BaseLow,
+		((le.HighWord.Bits.LimitHi << 8) + le.LimitLow) << 
+		    (le.HighWord.Bits.Granularity ? 12 : 0),
+		le.HighWord.Bits.Default_Big ? 32 : 16,
+		flags[0], flags[1], flags[2] );
+    }
+}
+
+void DEBUG_InfoVirtual(void)
+{
+   fprintf(stderr, "No longer providing virtual mapping information\n");
+}
diff --git a/debugger/memory.c b/debugger/memory.c
index 63d1d52..07759ee 100644
--- a/debugger/memory.c
+++ b/debugger/memory.c
@@ -8,147 +8,126 @@
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
-#include "wine/winbase16.h"
+#include <string.h>
 #include "debugger.h"
-#include "miscemu.h"
+#include "winbase.h"
 
-
-/************************************************************
- *   
- *  Check if linear pointer in [addr, addr+size[
- *     read  (rwflag == 1)
- *   or
- *     write (rwflag == 0)
- ************************************************************/
-
-BOOL DEBUG_checkmap_bad( const char *addr, size_t size, int rwflag)
-{
-  FILE *fp;
-  char buf[200];      /* temporary line buffer */
-  char prot[5];      /* protection string */
-  char *start, *end;
-  int ret = TRUE;
-
-#ifdef linux
-  /* 
-     The entries in /proc/self/maps are of the form:
-     08000000-08002000 r-xp 00000000 03:41 2361
-     08002000-08003000 rw-p 00001000 03:41 2361
-     08003000-08005000 rwxp 00000000 00:00 0
-     40000000-40005000 r-xp 00000000 03:41 67219
-     40005000-40006000 rw-p 00004000 03:41 67219
-     40006000-40007000 rw-p 00000000 00:00 0
-     ...
-      start    end     perm   ???    major:minor inode
-
-     Only permissions start and end are used here
-     */
-#else
-/*
-    % cat /proc/curproc/map
-    start      end         resident   private perm    type
-    0x1000     0xe000            12         0 r-x COW vnode
-    0xe000     0x10000            2         2 rwx COW vnode
-    0x10000    0x27000            4         4 rwx     default
-    0x800e000  0x800f000          1         1 rw-     default
-    0xefbde000 0xefbfe000         1         1 rwx     default
-    
-    COW = "copy on write"
-
-
-    % cat /proc/curproc/map on FreeBSD 3.0
-    start     end       ?  ?  ?      prot ? ? ?   ?   ?  ?
-    0x8048000 0x8054000 12 14 114770 r-x  2 1 0x0 COW NC vnode
-    0x8054000 0x8055000 1 0 166664 rwx 1 0 0x2180 COW NNC vnode
-    0x8055000 0x806a000 5 0 166662 rwx 1 0 0x2180 NCOW NNC default
-    0x28054000 0x28055000 1 0 166666 rwx 1 0 0x2180 NCOW NNC default
-    0xefbde000 0xefbfe000 1 0 166663 rwx 1 0 0x2180 NCOW NNC default
-
-*/
-#endif
-
-  
-  if (!(fp = fopen("/proc/self/maps","r")) && 
-      !(fp = fopen("/proc/curproc/map","r"))
-  )
-    return FALSE; 
-
-#ifdef __FreeBSD__
-  /*
-   * *FOO*  read(2) less than length of /proc/.../map fails with EFBIG
-   *
-   * $ dd bs=256 </proc/curproc/map 
-   * dd: stdin: File too large
-   * 0+0 records in
-   * 0+0 records out
-   * 0 bytes transferred in 0.001595 secs (0 bytes/sec)
-   */
-  setvbuf(fp, (char *)NULL, _IOFBF, 0x4000);
-#endif
-  while (fgets( buf, sizeof(buf)-1, fp)) {
-#ifdef linux
-    sscanf(buf, "%x-%x %3s", (int *) &start, (int *) &end, prot);
-#else
-    sscanf(buf, "%x %x %*d %*d %3s", (int *) &start, (int *) &end, prot);
-    if (prot[0]!='r' && prot[0]!='-') /* FreeBSD 3.0 format */
-       sscanf(buf, "%x %x %*d %*d %*d %3s", (int *) &start, (int *) &end, prot);
-#endif
-    if ( end <= addr)
-      continue;
-    if (start <= addr && addr+size <= end) {
-      if (rwflag) 
-	ret = (prot[0] != 'r'); /* test for reading */
-      else
-	ret = (prot[1] != 'w'); /* test for writing */
-    }
-    break;
-  }
-  fclose( fp);
-  return ret;
-}
-
-
-/***********************************************************************
- *           DEBUG_IsBadReadPtr
- *
- * Check if we are allowed to read memory at 'address'.
- */
-BOOL DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size )
-{
 #ifdef __i386__
-    if (!IS_SELECTOR_V86(address->seg))
-    if (address->seg)  /* segmented addr */
-    {
-        if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
-                                              (WORD)address->seg ), size ))
-            return TRUE;
-    }
-#endif
-    return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 1);
-}
+#include "wine/winbase16.h"
 
+#define DBG_V86_MODULE(seg) ((seg)>>16)
+#define IS_SELECTOR_V86(seg) DBG_V86_MODULE(seg)
 
-/***********************************************************************
- *           DEBUG_IsBadWritePtr
- *
- * Check if we are allowed to write memory at 'address'.
- */
-BOOL DEBUG_IsBadWritePtr( const DBG_ADDR *address, int size )
+static	void	DEBUG_Die(const char* msg)
 {
-#ifdef __i386__
-    if (!IS_SELECTOR_V86(address->seg))
-    if (address->seg)  /* segmented addr */
-    {
-        /* Note: we use IsBadReadPtr here because we are */
-        /* always allowed to write to read-only segments */
-        if (IsBadReadPtr16( (SEGPTR)MAKELONG( (WORD)address->off,
-                                              (WORD)address->seg ), size ))
-            return TRUE;
-    }
-#endif
-    return DEBUG_checkmap_bad( DBG_ADDR_TO_LIN(address), size, 0);
+   fprintf(stderr, msg);
+   exit(1);
 }
 
+void*	DEBUG_XMalloc(size_t size)
+{
+   void *res = malloc(size ? size : 1);
+   if (res == NULL)
+      DEBUG_Die("Memory exhausted.\n");
+   memset(res, 0, size);
+   return res;
+}
+
+void* DEBUG_XReAlloc(void *ptr, size_t size)
+{
+   void* res = realloc(ptr, size);
+   if ((res == NULL) && size)
+      DEBUG_Die("Memory exhausted.\n");
+   return res;
+}
+
+char*	DEBUG_XStrDup(const char *str)
+{
+   char *res = strdup(str);
+   if (!res)
+      DEBUG_Die("Memory exhausted.\n");
+   return res;
+}
+
+void DEBUG_FixAddress( DBG_ADDR *addr, DWORD def) 
+{
+   if (addr->seg == 0xffffffff) addr->seg = def;
+   if (!IS_SELECTOR_V86(addr->seg) && DEBUG_IsSelectorSystem(addr->seg)) addr->seg = 0;
+}
+
+BOOL  DEBUG_FixSegment( DBG_ADDR* addr )
+{
+   /* V86 mode ? */
+   if (DEBUG_context.EFlags & V86_FLAG) {
+      addr->seg |= (DWORD)(GetExePtr(GetCurrentTask())) << 16;
+      return TRUE;
+   }
+   return FALSE;
+}
+
+DWORD DEBUG_ToLinear( const DBG_ADDR *addr )
+{
+   LDT_ENTRY	le;
+   
+   if (IS_SELECTOR_V86(addr->seg))
+      return DOSMEM_MemoryBase(DBG_V86_MODULE(addr->seg)) + (((addr->seg)&0xFFFF)<<4) + addr->off;
+   if (DEBUG_IsSelectorSystem(addr->seg))
+      return addr->off;
+   
+   if (GetThreadSelectorEntry( DEBUG_CurrThread->handle, addr->seg, &le)) {
+      return (le.HighWord.Bits.BaseHi << 24) + (le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->off;
+   }
+   return 0;
+}
+
+int	DEBUG_GetSelectorType( WORD sel )
+{
+    LDT_ENTRY	le;
+
+    if (sel == 0)
+        return 32;
+    if (IS_SELECTOR_V86(sel))
+        return 16;
+    if (GetThreadSelectorEntry( DEBUG_CurrThread->handle, sel, &le)) 
+        return le.HighWord.Bits.Default_Big ? 32 : 16;
+	 /* selector doesn't exist */
+    return 0;
+}
+
+/* Determine if sel is a system selector (i.e. not managed by Wine) */
+BOOL	DEBUG_IsSelectorSystem(WORD sel)
+{
+   return !(sel & 4) || (((sel & 0xFFFF) >> 3) < 17);
+}
+#endif /* __i386__ */
+
+void DEBUG_GetCurrentAddress( DBG_ADDR *addr )
+{
+    addr->type = NULL;
+#ifdef __i386__
+    addr->seg  = DEBUG_context.SegCs;
+
+    if (!DEBUG_FixSegment( addr ) && DEBUG_IsSelectorSystem(addr->seg)) 
+       addr->seg = 0;
+    addr->off  = DEBUG_context.Eip;
+#else
+    addr->seg  = 0;
+    addr->off  = 0;
+#endif
+}
+
+void	DEBUG_InvalLinAddr( void* addr )
+{
+   DBG_ADDR address;
+
+   address.type = NULL;
+   address.seg = 0;
+   address.off = (unsigned long)addr;
+
+   fprintf(stderr,"*** Invalid address ");
+   DEBUG_PrintAddress(&address, DEBUG_CurrThread->dbg_mode, FALSE);
+   fprintf(stderr,"\n");
+}
 
 /***********************************************************************
  *           DEBUG_ReadMemory
@@ -157,11 +136,15 @@
  */
 int DEBUG_ReadMemory( const DBG_ADDR *address )
 {
-    DBG_ADDR addr = *address;
-
-    DBG_FIX_ADDR_SEG( &addr, DS_reg(&DEBUG_context) );
-    if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return 0;
-    return *(int *)DBG_ADDR_TO_LIN( &addr );
+    DBG_ADDR	addr = *address;
+    void*	lin;
+    int		value;
+	
+    DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
+    lin = (void*)DEBUG_ToLinear( &addr );
+    if (!DEBUG_READ_MEM_VERBOSE(lin, &value, sizeof(value)))
+       value = 0;
+    return value;
 }
 
 
@@ -172,11 +155,12 @@
  */
 void DEBUG_WriteMemory( const DBG_ADDR *address, int value )
 {
-    DBG_ADDR addr = *address;
+    DBG_ADDR 	addr = *address;
+    void*	lin;
 
-    DBG_FIX_ADDR_SEG( &addr, DS_reg(&DEBUG_context) );
-    if (!DBG_CHECK_WRITE_PTR( &addr, sizeof(int) )) return;
-    *(int *)DBG_ADDR_TO_LIN( &addr ) = value;
+    DEBUG_FixAddress( &addr, DEBUG_context.SegDs );
+    lin = (void*)DEBUG_ToLinear( &addr );
+    DEBUG_WRITE_MEM_VERBOSE(lin, &value, sizeof(value));
 }
 
 
@@ -188,15 +172,14 @@
 void DEBUG_ExamineMemory( const DBG_ADDR *address, int count, char format )
 {
     DBG_ADDR addr =	* address;
-    unsigned int	* dump;
     int			  i;
     unsigned char	* pnt;
-    unsigned int	  seg2;
     struct datatype	* testtype;
-    unsigned short int	* wdump;
 
-    DBG_FIX_ADDR_SEG( &addr, (format == 'i') ?
-                             CS_reg(&DEBUG_context) : DS_reg(&DEBUG_context) );
+    DEBUG_FixAddress( &addr, 
+		      (format == 'i') ?
+		      DEBUG_context.SegCs : 
+		      DEBUG_context.SegDs );
 
     /*
      * Dereference pointer to get actual memory address we need to be
@@ -212,15 +195,15 @@
 	     * else in 32-bit space.  Grab it, and we
 	     * should be all set.
 	     */
-	    seg2 = addr.seg;
+	    unsigned int  seg2 = addr.seg;
 	    addr.seg = 0;
 	    addr.off = DEBUG_GetExprValue(&addr, NULL);
 	    addr.seg = seg2;
 	  }
 	else
 	  {
-	    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
-	    DEBUG_TypeDerefPointer(&addr, &testtype);
+	    if (DEBUG_TypeDerefPointer(&addr, &testtype) == 0)
+	      return;
 	    if( testtype != NULL || addr.type == DEBUG_TypeIntConst )
 	      {
 		addr.off = DEBUG_GetExprValue(&addr, NULL);
@@ -235,135 +218,71 @@
 
     if (format != 'i' && count > 1)
     {
-        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
+        DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, FALSE );
         fprintf(stderr,": ");
     }
 
-    pnt = DBG_ADDR_TO_LIN( &addr );
+    pnt = (void*)DEBUG_ToLinear( &addr );
 
     switch(format)
     {
 	case 'u': {
-		WCHAR *ptr = (WCHAR*)pnt;
+		WCHAR wch;
 		if (count == 1) count = 256;
                 while (count--)
                 {
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(WCHAR) )) return;
-                    if (!*ptr) break;
-                    addr.off++;
-                    fputc( (char)*ptr++, stderr );
+		    if (!DEBUG_READ_MEM_VERBOSE(pnt, &wch, sizeof(wch)))
+		       break;
+                    pnt += sizeof(wch);
+                    fputc( (char)wch, stderr );
                 }
 		fprintf(stderr,"\n");
 		return;
 	    }
-	case 's':
+          case 's': {
+	        char ch;
+
 		if (count == 1) count = 256;
                 while (count--)
                 {
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
-                    if (!*pnt) break;
-                    addr.off++;
-                    fputc( *pnt++, stderr );
+                    if (!DEBUG_READ_MEM_VERBOSE(pnt, &ch, sizeof(ch)))
+		       break;
+                    pnt++;
+                    fputc( ch, stderr );
                 }
 		fprintf(stderr,"\n");
 		return;
-
+	  }
 	case 'i':
 		while (count--)
                 {
-                    DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
+                    DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, TRUE );
                     fprintf(stderr,": ");
-                    if (!DBG_CHECK_READ_PTR( &addr, 1 )) return;
                     DEBUG_Disasm( &addr, TRUE );
                     fprintf(stderr,"\n");
 		}
 		return;
-	case 'x':
-		dump = (unsigned int *)pnt;
-		for(i=0; i<count; i++) 
-		{
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return;
-                    fprintf(stderr," %8.8x", *dump++);
-                    addr.off += sizeof(int);
-                    if ((i % 4) == 3)
-                    {
-                        fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
-                        fprintf(stderr,": ");
-                    }
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'd':
-		dump = (unsigned int *)pnt;
-		for(i=0; i<count; i++) 
-		{
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(int) )) return;
-                    fprintf(stderr," %10d", *dump++);
-                    addr.off += sizeof(int);
-                    if ((i % 4) == 3)
-                    {
-                        fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
-                        fprintf(stderr,": ");
-                    }
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'w':
-		wdump = (unsigned short *)pnt;
-		for(i=0; i<count; i++) 
-		{
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(short) )) return;
-                    fprintf(stderr," %04x", *wdump++);
-                    addr.off += sizeof(short);
-                    if ((i % 8) == 7)
-                    {
-                        fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
-                        fprintf(stderr,": ");
-                    }
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'c':
-		for(i=0; i<count; i++) 
-		{
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
-                    if(*pnt < 0x20)
-                    {
-                        fprintf(stderr,"  ");
-                        pnt++;
-                    }
-                    else fprintf(stderr," %c", *pnt++);
-                    addr.off++;
-                    if ((i % 32) == 31)
-                    {
-                        fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
-                        fprintf(stderr,": ");
-                    }
-		}
-		fprintf(stderr,"\n");
-		return;
-	
-	case 'b':
-		for(i=0; i<count; i++) 
-		{
-                    if (!DBG_CHECK_READ_PTR( &addr, sizeof(char) )) return;
-                    fprintf(stderr," %02x", (*pnt++) & 0xff);
-                    addr.off++;
-                    if ((i % 16) == 15)
-                    {
-                        fprintf(stderr,"\n");
-                        DEBUG_PrintAddress( &addr, dbg_mode, FALSE );
-                        fprintf(stderr,": ");
-                    }
-		}
-		fprintf(stderr,"\n");
-		return;
+#define DO_DUMP2(_t,_l,_f,_vv) { \
+	        _t _v; \
+		for(i=0; i<count; i++) { \
+                    if (!DEBUG_READ_MEM_VERBOSE(pnt, &_v, sizeof(_t))) break; \
+                    fprintf(stderr,_f,(_vv)); \
+                    pnt += sizeof(_t); addr.off += sizeof(_t); \
+                    if ((i % (_l)) == (_l)-1) { \
+                        fprintf(stderr,"\n"); \
+                        DEBUG_PrintAddress( &addr, DEBUG_CurrThread->dbg_mode, FALSE );\
+                        fprintf(stderr,": ");\
+                    } \
+		} \
+		fprintf(stderr,"\n"); \
+        } \
+	return
+#define DO_DUMP(_t,_l,_f) DO_DUMP2(_t,_l,_f,_v) 
+
+        case 'x': DO_DUMP(int, 4, " %8.8x");
+	case 'd': DO_DUMP(unsigned int, 4, " %10d");	
+	case 'w': DO_DUMP(unsigned short, 8, " %04x");
+        case 'c': DO_DUMP2(char, 32, " %c", (_v < 0x20) ? ' ' : _v);
+	case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
 	}
 }
diff --git a/debugger/registers.c b/debugger/registers.c
index 65f953a..9f6610f 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -7,11 +7,8 @@
 #include "config.h"
 #include <stdio.h>
 #include <string.h>
-#include "selectors.h"
 #include "debugger.h"
 
-CONTEXT DEBUG_context;
-
 /***********************************************************************
  *           DEBUG_SetRegister
  *
@@ -22,70 +19,73 @@
 #ifdef __i386__
     switch(reg)
     {
-        case REG_EAX: EAX_reg(&DEBUG_context) = val; break;
-        case REG_EBX: EBX_reg(&DEBUG_context) = val; break;
-        case REG_ECX: ECX_reg(&DEBUG_context) = val; break;
-        case REG_EDX: EDX_reg(&DEBUG_context) = val; break;
-        case REG_ESI: ESI_reg(&DEBUG_context) = val; break;
-        case REG_EDI: EDI_reg(&DEBUG_context) = val; break;
-        case REG_EBP: EBP_reg(&DEBUG_context) = val; break;
-        case REG_EFL: EFL_reg(&DEBUG_context) = val; break;
-        case REG_EIP: EIP_reg(&DEBUG_context) = val; break;
-        case REG_ESP: ESP_reg(&DEBUG_context) = val; break;
-        case REG_CS:  CS_reg(&DEBUG_context)  = val; break;
-        case REG_DS:  DS_reg(&DEBUG_context)  = val; break;
-        case REG_ES:  ES_reg(&DEBUG_context)  = val; break;
-        case REG_SS:  SS_reg(&DEBUG_context)  = val; break;
-        case REG_FS:  FS_reg(&DEBUG_context)  = val; break;
-        case REG_GS:  GS_reg(&DEBUG_context)  = val; break;
-        case REG_AX:  SET_LOWORD(EAX_reg(&DEBUG_context),val); break;
-        case REG_BX:  SET_LOWORD(EBX_reg(&DEBUG_context),val); break;
-        case REG_CX:  SET_LOWORD(ECX_reg(&DEBUG_context),val); break;
-        case REG_DX:  SET_LOWORD(EDX_reg(&DEBUG_context),val); break;
-        case REG_SI:  SET_LOWORD(ESI_reg(&DEBUG_context),val); break;
-        case REG_DI:  SET_LOWORD(EDI_reg(&DEBUG_context),val); break;
-        case REG_BP:  SET_LOWORD(EBP_reg(&DEBUG_context),val); break;
-        case REG_FL:  SET_LOWORD(EFL_reg(&DEBUG_context),val); break;
-        case REG_IP:  SET_LOWORD(EIP_reg(&DEBUG_context),val); break;
-        case REG_SP:  SET_LOWORD(ESP_reg(&DEBUG_context),val); break;
+        case REG_EAX: DEBUG_context.Eax = val; break;
+        case REG_EBX: DEBUG_context.Ebx = val; break;
+        case REG_ECX: DEBUG_context.Ecx = val; break;
+        case REG_EDX: DEBUG_context.Edx = val; break;
+        case REG_ESI: DEBUG_context.Esi = val; break;
+        case REG_EDI: DEBUG_context.Edi = val; break;
+        case REG_EBP: DEBUG_context.Ebp = val; break;
+        case REG_EFL: DEBUG_context.EFlags = val; break;
+        case REG_EIP: DEBUG_context.Eip = val; break;
+        case REG_ESP: DEBUG_context.Esp = val; break;
+        case REG_CS:  DEBUG_context.SegCs = val; break;
+        case REG_DS:  DEBUG_context.SegDs = val; break;
+        case REG_ES:  DEBUG_context.SegEs = val; break;
+        case REG_SS:  DEBUG_context.SegSs = val; break;
+        case REG_FS:  DEBUG_context.SegFs = val; break;
+        case REG_GS:  DEBUG_context.SegGs = val; break;
+#define SET_LOW_WORD(dw,lw)	((dw) = ((dw) & 0xFFFF0000) | LOWORD(lw))
+        case REG_AX:  SET_LOW_WORD(DEBUG_context.Eax,val); break;
+        case REG_BX:  SET_LOW_WORD(DEBUG_context.Ebx,val); break;
+        case REG_CX:  SET_LOW_WORD(DEBUG_context.Ecx,val); break;
+        case REG_DX:  SET_LOW_WORD(DEBUG_context.Edx,val); break;
+        case REG_SI:  SET_LOW_WORD(DEBUG_context.Esi,val); break;
+        case REG_DI:  SET_LOW_WORD(DEBUG_context.Edi,val); break;
+        case REG_BP:  SET_LOW_WORD(DEBUG_context.Ebp,val); break;
+        case REG_FL:  SET_LOW_WORD(DEBUG_context.EFlags,val); break;
+        case REG_IP:  SET_LOW_WORD(DEBUG_context.Eip,val); break;
+        case REG_SP:  SET_LOW_WORD(DEBUG_context.Esp,val); break;
+#undef SET_LOWORD
     }
 #endif
 }
 
 
-int
-DEBUG_PrintRegister(enum debug_regs reg)
+int DEBUG_PrintRegister(enum debug_regs reg)
 {
 #ifdef __i386__
+    char* 	val = NULL;
     switch(reg)
     {
-        case REG_EAX: fprintf(stderr, "%%eax"); break;
-        case REG_EBX: fprintf(stderr, "%%ebx"); break;
-        case REG_ECX: fprintf(stderr, "%%ecx"); break;
-        case REG_EDX: fprintf(stderr, "%%edx"); break;
-        case REG_ESI: fprintf(stderr, "%%esi"); break;
-        case REG_EDI: fprintf(stderr, "%%edi"); break;
-        case REG_EBP: fprintf(stderr, "%%ebp"); break;
-        case REG_EFL: fprintf(stderr, "%%efl"); break;
-        case REG_EIP: fprintf(stderr, "%%eip"); break;
-        case REG_ESP: fprintf(stderr, "%%esp"); break;
-        case REG_AX:  fprintf(stderr, "%%ax"); break;
-        case REG_BX:  fprintf(stderr, "%%bx"); break;
-        case REG_CX:  fprintf(stderr, "%%cx"); break;
-        case REG_DX:  fprintf(stderr, "%%dx"); break;
-        case REG_SI:  fprintf(stderr, "%%si"); break;
-        case REG_DI:  fprintf(stderr, "%%di"); break;
-        case REG_BP:  fprintf(stderr, "%%bp"); break;
-        case REG_FL:  fprintf(stderr, "%%fl"); break;
-        case REG_IP:  fprintf(stderr, "%%ip"); break;
-        case REG_SP:  fprintf(stderr, "%%sp"); break;
-        case REG_CS:  fprintf(stderr, "%%cs"); break;
-        case REG_DS:  fprintf(stderr, "%%ds"); break;
-        case REG_ES:  fprintf(stderr, "%%es"); break;
-        case REG_SS:  fprintf(stderr, "%%ss"); break;
-        case REG_FS:  fprintf(stderr, "%%fs"); break;
-        case REG_GS:  fprintf(stderr, "%%gs"); break;
+        case REG_EAX: val = "%%eax"; break;
+        case REG_EBX: val = "%%ebx"; break;
+        case REG_ECX: val = "%%ecx"; break;
+        case REG_EDX: val = "%%edx"; break;
+        case REG_ESI: val = "%%esi"; break;
+        case REG_EDI: val = "%%edi"; break;
+        case REG_EBP: val = "%%ebp"; break;
+        case REG_EFL: val = "%%efl"; break;
+        case REG_EIP: val = "%%eip"; break;
+        case REG_ESP: val = "%%esp"; break;
+        case REG_AX:  val = "%%ax";  break;
+        case REG_BX:  val = "%%bx";  break;
+        case REG_CX:  val = "%%cx";  break;
+        case REG_DX:  val = "%%dx";  break;
+        case REG_SI:  val = "%%si";  break;
+        case REG_DI:  val = "%%di";  break;
+        case REG_BP:  val = "%%bp";  break;
+        case REG_FL:  val = "%%fl";  break;
+        case REG_IP:  val = "%%ip";  break;
+        case REG_SP:  val = "%%sp";  break;
+        case REG_CS:  val = "%%cs";  break;
+        case REG_DS:  val = "%%ds";  break;
+        case REG_ES:  val = "%%es";  break;
+        case REG_SS:  val = "%%ss";  break;
+        case REG_FS:  val = "%%fs";  break;
+        case REG_GS:  val = "%%gs";  break;
     }
+    if (val) fprintf(stderr, val);
     return TRUE;
 #else
     return FALSE;
@@ -102,32 +102,32 @@
 #ifdef __i386__
     switch(reg)
     {
-        case REG_EAX: return EAX_reg(&DEBUG_context);
-        case REG_EBX: return EBX_reg(&DEBUG_context);
-        case REG_ECX: return ECX_reg(&DEBUG_context);
-        case REG_EDX: return EDX_reg(&DEBUG_context);
-        case REG_ESI: return ESI_reg(&DEBUG_context);
-        case REG_EDI: return EDI_reg(&DEBUG_context);
-        case REG_EBP: return EBP_reg(&DEBUG_context);
-        case REG_EFL: return EFL_reg(&DEBUG_context);
-        case REG_EIP: return EIP_reg(&DEBUG_context);
-        case REG_ESP: return ESP_reg(&DEBUG_context);
-        case REG_CS:  return CS_reg(&DEBUG_context);
-        case REG_DS:  return DS_reg(&DEBUG_context);
-        case REG_ES:  return ES_reg(&DEBUG_context);
-        case REG_SS:  return SS_reg(&DEBUG_context);
-        case REG_FS:  return FS_reg(&DEBUG_context);
-        case REG_GS:  return GS_reg(&DEBUG_context);
-        case REG_AX:  return LOWORD(EAX_reg(&DEBUG_context));
-        case REG_BX:  return LOWORD(EBX_reg(&DEBUG_context));
-        case REG_CX:  return LOWORD(ECX_reg(&DEBUG_context));
-        case REG_DX:  return LOWORD(EDX_reg(&DEBUG_context));
-        case REG_SI:  return LOWORD(ESI_reg(&DEBUG_context));
-        case REG_DI:  return LOWORD(EDI_reg(&DEBUG_context));
-        case REG_BP:  return LOWORD(EBP_reg(&DEBUG_context));
-        case REG_FL:  return LOWORD(EFL_reg(&DEBUG_context));
-        case REG_IP:  return LOWORD(EIP_reg(&DEBUG_context));
-        case REG_SP:  return LOWORD(ESP_reg(&DEBUG_context));
+        case REG_EAX: return DEBUG_context.Eax;
+        case REG_EBX: return DEBUG_context.Ebx;
+        case REG_ECX: return DEBUG_context.Ecx;
+        case REG_EDX: return DEBUG_context.Edx;
+        case REG_ESI: return DEBUG_context.Esi;
+        case REG_EDI: return DEBUG_context.Edi;
+        case REG_EBP: return DEBUG_context.Ebp;
+        case REG_EFL: return DEBUG_context.EFlags;
+        case REG_EIP: return DEBUG_context.Eip;
+        case REG_ESP: return DEBUG_context.Esp;
+        case REG_CS:  return DEBUG_context.SegCs;
+        case REG_DS:  return DEBUG_context.SegDs;
+        case REG_ES:  return DEBUG_context.SegEs;
+        case REG_SS:  return DEBUG_context.SegSs;
+        case REG_FS:  return DEBUG_context.SegFs;
+        case REG_GS:  return DEBUG_context.SegGs;
+        case REG_AX:  return LOWORD(DEBUG_context.Eax);
+        case REG_BX:  return LOWORD(DEBUG_context.Ebx);
+        case REG_CX:  return LOWORD(DEBUG_context.Ecx);
+        case REG_DX:  return LOWORD(DEBUG_context.Edx);
+        case REG_SI:  return LOWORD(DEBUG_context.Esi);
+        case REG_DI:  return LOWORD(DEBUG_context.Edi);
+        case REG_BP:  return LOWORD(DEBUG_context.Ebp);
+        case REG_FL:  return LOWORD(DEBUG_context.EFlags);
+        case REG_IP:  return LOWORD(DEBUG_context.Eip);
+        case REG_SP:  return LOWORD(DEBUG_context.Esp);
     }
 #endif
     return 0;  /* should not happen */
@@ -200,35 +200,35 @@
 #ifdef __i386__
     /* First get the segment registers out of the way */
     fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x FS:%04x GS:%04x",
-             (WORD)CS_reg(&DEBUG_context), (WORD)SS_reg(&DEBUG_context),
-             (WORD)DS_reg(&DEBUG_context), (WORD)ES_reg(&DEBUG_context),
-             (WORD)FS_reg(&DEBUG_context), (WORD)GS_reg(&DEBUG_context) );
-    if (dbg_mode == 16)
+             (WORD)DEBUG_context.SegCs, (WORD)DEBUG_context.SegSs,
+             (WORD)DEBUG_context.SegDs, (WORD)DEBUG_context.SegEs,
+             (WORD)DEBUG_context.SegFs, (WORD)DEBUG_context.SegGs );
+    if (DEBUG_CurrThread->dbg_mode == 16)
     {
         char flag[33];
 
         fprintf( stderr,"\n IP:%04x SP:%04x BP:%04x FLAGS:%04x(%s)\n",
-                 LOWORD(EIP_reg(&DEBUG_context)), LOWORD(ESP_reg(&DEBUG_context)),
-                 LOWORD(EBP_reg(&DEBUG_context)), LOWORD(EFL_reg(&DEBUG_context)),
-		 DEBUG_Flags(LOWORD(EFL_reg(&DEBUG_context)), flag));
+                 LOWORD(DEBUG_context.Eip), LOWORD(DEBUG_context.Esp),
+                 LOWORD(DEBUG_context.Ebp), LOWORD(DEBUG_context.EFlags),
+		 DEBUG_Flags(LOWORD(DEBUG_context.EFlags), flag));
 	fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
-                 AX_reg(&DEBUG_context), BX_reg(&DEBUG_context),
-                 CX_reg(&DEBUG_context), DX_reg(&DEBUG_context),
-                 SI_reg(&DEBUG_context), DI_reg(&DEBUG_context) );
+                 LOWORD(DEBUG_context.Eax), LOWORD(DEBUG_context.Ebx),
+                 LOWORD(DEBUG_context.Ecx), LOWORD(DEBUG_context.Edx),
+                 LOWORD(DEBUG_context.Esi), LOWORD(DEBUG_context.Edi) );
     }
     else  /* 32-bit mode */
     {
         char flag[33];
 
         fprintf( stderr, "\n EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx(%s)\n", 
-                 EIP_reg(&DEBUG_context), ESP_reg(&DEBUG_context),
-                 EBP_reg(&DEBUG_context), EFL_reg(&DEBUG_context),
-		 DEBUG_Flags(EFL_reg(&DEBUG_context), flag));
+                 DEBUG_context.Eip, DEBUG_context.Esp,
+                 DEBUG_context.Ebp, DEBUG_context.EFlags,
+		 DEBUG_Flags(DEBUG_context.EFlags, flag));
 	fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
-		 EAX_reg(&DEBUG_context), EBX_reg(&DEBUG_context),
-                 ECX_reg(&DEBUG_context), EDX_reg(&DEBUG_context) );
+		 DEBUG_context.Eax, DEBUG_context.Ebx,
+                 DEBUG_context.Ecx, DEBUG_context.Edx );
 	fprintf( stderr, " ESI:%08lx EDI:%08lx\n",
-                 ESI_reg(&DEBUG_context), EDI_reg(&DEBUG_context) );
+                 DEBUG_context.Esi, DEBUG_context.Edi );
     }
 #endif
 }
@@ -243,15 +243,12 @@
 BOOL DEBUG_ValidateRegisters(void)
 {
 #ifdef __i386__
-    WORD cs, ds;
+    if (DEBUG_context.EFlags & V86_FLAG) return TRUE;
 
-    if (ISV86(&DEBUG_context)) return TRUE;
-
+#if 0
 /* Check that a selector is a valid ring-3 LDT selector, or a NULL selector */
 #define CHECK_SEG(seg,name) \
-    if (((seg) & ~3) && \
-        ((((seg) & 7) != 7) || IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(seg)))) \
-    { \
+    if (((seg) & ~3) && ((((seg) & 7) != 7) || !DEBUG_IsSelector(seg))) { \
         fprintf( stderr, "*** Invalid value for %s register: %04x\n", \
                  (name), (WORD)(seg) ); \
         return FALSE; \
@@ -259,26 +256,26 @@
 
     cs = __get_cs();
     ds = __get_ds();
-    if (CS_reg(&DEBUG_context) != cs) CHECK_SEG(CS_reg(&DEBUG_context), "CS");
-    if (SS_reg(&DEBUG_context) != ds) CHECK_SEG(SS_reg(&DEBUG_context), "SS");
-    if (DS_reg(&DEBUG_context) != ds) CHECK_SEG(DS_reg(&DEBUG_context), "DS");
-    if (ES_reg(&DEBUG_context) != ds) CHECK_SEG(ES_reg(&DEBUG_context), "ES");
-    if (FS_reg(&DEBUG_context) != ds) CHECK_SEG(FS_reg(&DEBUG_context), "FS");
-    if (GS_reg(&DEBUG_context) != ds) CHECK_SEG(GS_reg(&DEBUG_context), "GS");
+    if (CS_reg(DEBUG_context) != cs) CHECK_SEG(CS_reg(DEBUG_context), "CS");
+    if (SS_reg(DEBUG_context) != ds) CHECK_SEG(SS_reg(DEBUG_context), "SS");
+    if (DS_reg(DEBUG_context) != ds) CHECK_SEG(DS_reg(DEBUG_context), "DS");
+    if (ES_reg(DEBUG_context) != ds) CHECK_SEG(ES_reg(DEBUG_context), "ES");
+    if (FS_reg(DEBUG_context) != ds) CHECK_SEG(FS_reg(DEBUG_context), "FS");
+    if (GS_reg(DEBUG_context) != ds) CHECK_SEG(GS_reg(DEBUG_context), "GS");
+#endif
 
     /* Check that CS and SS are not NULL */
 
-    if (!ISV86(&DEBUG_context))
-    if (!(CS_reg(&DEBUG_context) & ~3))
+    if (!(DEBUG_context.SegCs & ~3))
     {
         fprintf( stderr, "*** Invalid value for CS register: %04x\n",
-                 (WORD)CS_reg(&DEBUG_context) );
+                 (WORD)DEBUG_context.SegCs );
         return FALSE;
     }
-    if (!(SS_reg(&DEBUG_context) & ~3))
+    if (!(DEBUG_context.SegSs & ~3))
     {
         fprintf( stderr, "*** Invalid value for SS register: %04x\n",
-                 (WORD)SS_reg(&DEBUG_context) );
+                 (WORD)DEBUG_context.SegSs );
         return FALSE;
     }
     return TRUE;
diff --git a/debugger/source.c b/debugger/source.c
index 6ce1aee..0b7e7c6 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -22,11 +22,7 @@
 #define PATH_MAX _MAX_PATH
 #endif
 
-#include "wine/winbase16.h"
-#include "pe_image.h"
-#include "peexe.h"
 #include "debugger.h"
-#include "task.h"
 
 struct searchlist
 {
@@ -428,36 +424,17 @@
 
 DBG_ADDR DEBUG_LastDisassemble={NULL,0,0};
 
-void DEBUG_GetCurrentAddress( DBG_ADDR *addr )
-{
-#ifdef __i386__
-    TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
-
-    addr->type = NULL;
-    addr->seg  = CS_reg(&DEBUG_context);
-    addr->off  = EIP_reg(&DEBUG_context);
-
-    if (ISV86(&DEBUG_context)) addr->seg |= (DWORD)(pTask? pTask->hModule : 0) << 16; 
-    else if (IS_SELECTOR_SYSTEM(addr->seg)) addr->seg = 0;
-
-    GlobalUnlock16( GetCurrentTask() );
-#else
-    addr->type = NULL;
-    addr->seg  = 0;
-    addr->off  = (DWORD)GET_IP(&DEBUG_context);
-#endif
-}
-
-
 static int
 _disassemble(DBG_ADDR *addr)
 {
-	DEBUG_PrintAddress( addr, dbg_mode, TRUE );
-	fprintf(stderr,": ");
-	if (!DBG_CHECK_READ_PTR( addr, 1 )) return 0;
-	DEBUG_Disasm( addr, TRUE );
-	fprintf(stderr,"\n");
-	return 1;
+   char	ch;
+
+   DEBUG_PrintAddress( addr, DEBUG_CurrThread->dbg_mode, TRUE );
+   fprintf(stderr,": ");
+   if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) return 0;
+   DEBUG_Disasm( addr, TRUE );
+   fprintf(stderr,"\n");
+   return 1;
 }
 
 void
@@ -465,7 +442,7 @@
     DWORD seg2;
     struct datatype *testtype;
 
-    DBG_FIX_ADDR_SEG(addr,CS_reg(&DEBUG_context));
+    DEBUG_FixAddress(addr, DEBUG_context.SegCs);
     if( addr->type != NULL )
       {
         if( addr->type == DEBUG_TypeIntConst )
@@ -482,7 +459,6 @@
           }
         else
           {
-            if (!DBG_CHECK_READ_PTR( addr, 1 )) return;
             DEBUG_TypeDerefPointer(addr, &testtype);
             if( testtype != NULL || addr->type == DEBUG_TypeIntConst )
                 addr->off = DEBUG_GetExprValue(addr, NULL);
diff --git a/debugger/stabs.c b/debugger/stabs.c
index e0376d8..7407847 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -134,8 +134,6 @@
   *dest++ = '\0';
 }
 
-extern void DEBUG_PrintAType(struct datatype*, int);
-
 typedef struct {
    char*		name;
    unsigned long	value;
diff --git a/debugger/stack.c b/debugger/stack.c
index 4965e1b..62f9b43 100644
--- a/debugger/stack.c
+++ b/debugger/stack.c
@@ -12,7 +12,7 @@
 #include "debugger.h"
 #include "stackframe.h"
 
-
+#ifdef __i386__
 /*
  * We keep this info for each frame, so that we can
  * find local variable information correctly.
@@ -43,7 +43,7 @@
     DWORD ip;
     WORD cs;
 } FRAME32;
-
+#endif
 
 
 /***********************************************************************
@@ -57,18 +57,20 @@
     DBG_ADDR addr;
 
     addr.type = NULL;
-    addr.seg = SS_reg(&DEBUG_context);
-    addr.off = ESP_reg(&DEBUG_context);
+    addr.seg = DEBUG_context.SegSs;
+    addr.off = DEBUG_context.Esp;
 
     fprintf(stderr,"Stack dump:\n");
-    if (IS_SELECTOR_32BIT(addr.seg))
-    {  /* 32-bit mode */
-        DEBUG_ExamineMemory( &addr, 24, 'x' );
-    }
-    else  /* 16-bit mode */
-    {
+    switch (DEBUG_GetSelectorType(addr.seg)) {
+    case 32: /* 32-bit mode */
+       DEBUG_ExamineMemory( &addr, 24, 'x' );
+       break;
+    case 16:  /* 16-bit mode */
         addr.off &= 0xffff;
         DEBUG_ExamineMemory( &addr, 24, 'w' );
+	break;
+    default:
+       fprintf(stderr, "Bad segment (%ld)\n", addr.seg);
     }
     fprintf(stderr,"\n");
 #endif
@@ -79,7 +81,7 @@
 {
     int theframe = nframe++;
     frames = (struct bt_info *)DBG_realloc(frames,
-                                        nframe*sizeof(struct bt_info));
+					   nframe*sizeof(struct bt_info));
     if (noisy)
       fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
               frameno);
@@ -87,7 +89,7 @@
     frames[theframe].eip = code->off;
     if (noisy)
       frames[theframe].frame = DEBUG_PrintAddressAndArgs( code, bits, 
-						stack->off, TRUE );
+							  stack->off, TRUE );
     else
       DEBUG_FindNearestSymbol( code, TRUE, 
 			       &frames[theframe].frame.sym, stack->off, 
@@ -101,265 +103,284 @@
 
 static BOOL DEBUG_Frame16(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy)
 {
-    unsigned int ss = addr->seg, possible_cs = 0;
-    FRAME16 *frame = (FRAME16 *)DBG_ADDR_TO_LIN(addr);
-    int theframe = nframe;
-
-    if (DEBUG_IsBadReadPtr( addr, sizeof(FRAME16) )) {
-       if (noisy) {
-	  fprintf(stderr,"*** Invalid address ");
-	  DEBUG_PrintAddress(addr, dbg_mode, FALSE);
-	  fprintf(stderr,"\n");
-       }
-       return FALSE;
+    unsigned int	ss = addr->seg, possible_cs = 0;
+    FRAME16 		frame;
+    int 		theframe = nframe;
+    void*		p = (void*)DEBUG_ToLinear(addr);
+    
+    if (!p) return FALSE;
+    
+    if (!DEBUG_READ_MEM(p, &frame, sizeof(frame))) {
+        if (noisy) {
+	    fprintf(stderr,"*** Invalid address ");
+	    DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
+	    fprintf(stderr,"\n");
+	}
+	return FALSE;
     }
-    if (!frame->bp) return FALSE;
+    if (!frame.bp) return FALSE;
     nframe++;
     frames = (struct bt_info *)DBG_realloc(frames,
-                                        nframe*sizeof(struct bt_info));
+					   nframe*sizeof(struct bt_info));
     if (noisy)
-      fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
-              frameno);
-    if (frame->bp & 1) *cs = frame->cs;
+        fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
+		frameno);
+    if (frame.bp & 1) *cs = frame.cs;
     else {
-      /* not explicitly marked as far call,
-       * but check whether it could be anyway */
-      if (((frame->cs&7)==7) && (frame->cs != *cs) && !IS_SELECTOR_FREE(frame->cs)) {
-        ldt_entry tcs;
-        LDT_GetEntry( SELECTOR_TO_ENTRY(frame->cs), &tcs );
-        if ( tcs.type == SEGMENT_CODE ) {
-          /* it is very uncommon to push a code segment cs as
-           * a parameter, so this should work in most cases */
-          *cs = possible_cs = frame->cs;
-        }
-      }
+        /* not explicitly marked as far call,
+	 * but check whether it could be anyway */
+        if (((frame.cs&7)==7) && (frame.cs != *cs)) {
+	    LDT_ENTRY	le;
+	 
+	    if (GetThreadSelectorEntry( DEBUG_CurrThread->handle, frame.cs, &le) &&
+		(le.HighWord.Bits.Type & 0x08)) { /* code segment */
+	        /* it is very uncommon to push a code segment cs as
+		 * a parameter, so this should work in most cases */
+	        *cs = possible_cs = frame.cs;
+	    }
+	}
     }
     frames[theframe].cs = addr->seg = *cs;
-    frames[theframe].eip = addr->off = frame->ip;
+    frames[theframe].eip = addr->off = frame.ip;
     if (noisy)
-      frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 16, 
-						frame->bp, TRUE );
+        frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 16, 
+							    frame.bp, TRUE );
     else
-      DEBUG_FindNearestSymbol( addr, TRUE, 
-			       &frames[theframe].frame.sym, frame->bp, 
-			       &frames[theframe].frame.list);
+        DEBUG_FindNearestSymbol( addr, TRUE, 
+				 &frames[theframe].frame.sym, frame.bp, 
+				 &frames[theframe].frame.list);
     frames[theframe].ss = addr->seg = ss;
-    frames[theframe].ebp = addr->off = frame->bp & ~1;
+    frames[theframe].ebp = addr->off = frame.bp & ~1;
     if (noisy) {
-      fprintf( stderr, " (bp=%04lx", addr->off );
-      if (possible_cs) {
-        fprintf( stderr, ", far call assumed" );
-      }
-      fprintf( stderr, ")\n" );
+        fprintf( stderr, " (bp=%04lx", addr->off );
+        if (possible_cs) {
+	    fprintf( stderr, ", far call assumed" );
+	}
+	fprintf( stderr, ")\n" );
     }
     return TRUE;
 }
 
 static BOOL DEBUG_Frame32(DBG_ADDR *addr, unsigned int *cs, int frameno, int noisy)
 {
-    unsigned int ss = addr->seg;
-    FRAME32 *frame = (FRAME32 *)DBG_ADDR_TO_LIN(addr);
-    int theframe = nframe;
-
-    if (DEBUG_IsBadReadPtr( addr, sizeof(FRAME32) )) {
+    unsigned int 	ss = addr->seg;
+    FRAME32 		frame;
+    int 		theframe = nframe;
+    void*		p = (void*)DEBUG_ToLinear(addr);
+    
+    if (!p) return FALSE;
+    
+    if (!DEBUG_READ_MEM(p, &frame, sizeof(frame))) {
        if (noisy) {
 	  fprintf(stderr,"*** Invalid address ");
-	  DEBUG_PrintAddress(addr, dbg_mode, FALSE);
+	  DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, FALSE);
 	  fprintf(stderr,"\n");
        }
        return FALSE;
     }
-    if (!frame->ip) return FALSE;
+    if (!frame.ip) return FALSE;
+    
     nframe++;
     frames = (struct bt_info *)DBG_realloc(frames,
-                                        nframe*sizeof(struct bt_info));
+					   nframe*sizeof(struct bt_info));
     if (noisy)
-      fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
-              frameno);
+       fprintf(stderr,"%s%d ", (theframe == curr_frame ? "=>" : "  "),
+	       frameno);
     frames[theframe].cs = addr->seg = *cs;
-    frames[theframe].eip = addr->off = frame->ip;
+    frames[theframe].eip = addr->off = frame.ip;
     if (noisy)
-      frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 32, 
-						frame->bp, TRUE );
+        frames[theframe].frame = DEBUG_PrintAddressAndArgs( addr, 32, 
+							    frame.bp, TRUE );
     else
-      DEBUG_FindNearestSymbol( addr, TRUE, 
-			       &frames[theframe].frame.sym, frame->bp, 
-			       &frames[theframe].frame.list);
-    if (noisy) fprintf( stderr, " (ebp=%08lx)\n", frame->bp );
+        DEBUG_FindNearestSymbol( addr, TRUE, 
+				 &frames[theframe].frame.sym, frame.bp, 
+				 &frames[theframe].frame.list);
+    if (noisy) fprintf( stderr, " (ebp=%08lx)\n", frame.bp );
     frames[theframe].ss = addr->seg = ss;
-    frames[theframe].ebp = frame->bp;
-    if (addr->off == frame->bp) return FALSE;
-    addr->off = frame->bp;
+    frames[theframe].ebp = frame.bp;
+    if (addr->off == frame.bp) return FALSE;
+    addr->off = frame.bp;
     return TRUE;
 }
-
-static void DEBUG_DoBackTrace(int noisy)
-{
-    DBG_ADDR addr, sw_addr;
-    unsigned int ss = SS_reg(&DEBUG_context), cs = CS_reg(&DEBUG_context);
-    int frameno = 0, is16, ok;
-    DWORD next_switch, cur_switch;
-
-    if (noisy) fprintf( stderr, "Backtrace:\n" );
-
-    nframe = 1;
-    if (frames) DBG_free( frames );
-    frames = (struct bt_info *) DBG_alloc( sizeof(struct bt_info) );
-    if (noisy)
-      fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno);
-
-    if (IS_SELECTOR_SYSTEM(ss)) ss = 0;
-    if (IS_SELECTOR_SYSTEM(cs)) cs = 0;
-
-    /* first stack frame from registers */
-    if (IS_SELECTOR_32BIT(ss))
-    {
-        frames[0].cs = addr.seg = cs;
-        frames[0].eip = addr.off = EIP_reg(&DEBUG_context);
-        if (noisy)
-          frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE );
-        else
-	  DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, 
-						&frames[0].frame.list);
-        frames[0].ss = addr.seg = ss;
-	frames[0].ebp = addr.off = EBP_reg(&DEBUG_context);
-        if (noisy) fprintf( stderr, " (ebp=%08x)\n", frames[0].ebp );
-        is16 = FALSE;
-    } else {
-        frames[0].cs = addr.seg = cs;
-        frames[0].eip = addr.off = LOWORD(EIP_reg(&DEBUG_context));
-        if (noisy)
-          frames[0].frame = DEBUG_PrintAddress( &addr, 16, TRUE );
-        else
-	  DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, 
-						&frames[0].frame.list);
-        frames[0].ss = addr.seg = ss;
-	frames[0].ebp = addr.off = BP_reg(&DEBUG_context);
-        if (noisy) fprintf( stderr, " (bp=%04x)\n", frames[0].ebp );
-        is16 = TRUE;
-    }
-
-    next_switch = NtCurrentTeb()->cur_stack;
-    if (is16) {
-      if (IsBadReadPtr((STACK32FRAME*)next_switch, sizeof(STACK32FRAME))) {
-	 if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
-	 return;
-      }
-      cur_switch = (DWORD)((STACK32FRAME*)next_switch)->frame16;
-      sw_addr.seg = SELECTOROF(cur_switch);
-      sw_addr.off = OFFSETOF(cur_switch);
-    } else {
-      if (IsBadReadPtr((STACK16FRAME*)PTR_SEG_TO_LIN(next_switch), sizeof(STACK16FRAME))) {
-	 if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK16FRAME*)PTR_SEG_TO_LIN(next_switch) );
-	 return;
-      }
-      cur_switch = (DWORD)((STACK16FRAME*)PTR_SEG_TO_LIN(next_switch))->frame32;
-      sw_addr.seg = ss;
-      sw_addr.off = cur_switch;
-    }
-    if (DEBUG_IsBadReadPtr(&sw_addr,1)) {
-      sw_addr.seg = (DWORD)-1;
-      sw_addr.off = (DWORD)-1;
-    }
-
-    for (ok = TRUE; ok;) {
-      if ((frames[frameno].ss == sw_addr.seg) &&
-          (frames[frameno].ebp >= sw_addr.off)) {
-        /* 16<->32 switch...
-         * yes, I know this is confusing, it gave me a headache too */
-        if (is16) {
-          STACK32FRAME *frame = (STACK32FRAME*)next_switch;
-          DBG_ADDR code;
-
-	  if (IsBadReadPtr((STACK32FRAME*)next_switch, sizeof(STACK32FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
-	    return;
-	  }
-	  code.type = NULL;
-	  code.seg  = 0;
-	  code.off  = frame->retaddr;
-
-          cs = 0;
-          addr.seg = 0;
-          addr.off = frame->ebp;
-          DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy );
-
-          next_switch = cur_switch;
-	  if (IsBadReadPtr((STACK16FRAME*)PTR_SEG_TO_LIN(next_switch), sizeof(STACK16FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK16FRAME*)PTR_SEG_TO_LIN(next_switch) );
-	    return;
-	  }
-          cur_switch = (DWORD)((STACK16FRAME*)PTR_SEG_TO_LIN(next_switch))->frame32;
-          sw_addr.seg = 0;
-          sw_addr.off = cur_switch;
-
-          is16 = FALSE;
-        } else {
-          STACK16FRAME *frame = (STACK16FRAME*)PTR_SEG_TO_LIN(next_switch);
-          DBG_ADDR code;
-
-	  if (IsBadReadPtr((STACK16FRAME*)PTR_SEG_TO_LIN(next_switch), sizeof(STACK16FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK16FRAME*)PTR_SEG_TO_LIN(next_switch) );
-	    return;
-	  }
-
-	  code.type = NULL;
-	  code.seg  = frame->cs;
-	  code.off  = frame->ip;
-
-          cs = frame->cs;
-          addr.seg = SELECTOROF(next_switch);
-          addr.off = frame->bp;
-          DEBUG_ForceFrame( &addr, &code, ++frameno, 16, noisy );
-
-          next_switch = cur_switch;
-	  if (IsBadReadPtr((STACK32FRAME*)next_switch, sizeof(STACK32FRAME))) {
-	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
-	    return;
-	  }
-          cur_switch = (DWORD)((STACK32FRAME*)next_switch)->frame16;
-          sw_addr.seg = SELECTOROF(cur_switch);
-          sw_addr.off = OFFSETOF(cur_switch);
-
-          is16 = TRUE;
-        }
-        if (DEBUG_IsBadReadPtr(&sw_addr,1)) {
-          sw_addr.seg = (DWORD)-1;
-          sw_addr.off = (DWORD)-1;
-        }
-      } else {
-        /* ordinary stack frame */
-        ok = is16 ? DEBUG_Frame16( &addr, &cs, ++frameno, noisy)
-                  : DEBUG_Frame32( &addr, &cs, ++frameno, noisy);
-      }
-    }
-    if (noisy) fprintf( stderr, "\n" );
-}
 #endif
 
 
-
 /***********************************************************************
  *           DEBUG_BackTrace
  *
  * Display a stack back-trace.
  */
-void DEBUG_BackTrace(void)
+void DEBUG_BackTrace(BOOL noisy)
 {
-#ifdef __i386__
-    DEBUG_DoBackTrace( TRUE );
-#endif
-}
+#ifdef __i386
+    DBG_ADDR 		addr, sw_addr, code, tmp;
+    unsigned int 	ss = DEBUG_context.SegSs;
+    unsigned int	cs = DEBUG_context.SegCs;
+    int 		frameno = 0, is16, ok;
+    DWORD 		next_switch, cur_switch, p;
+    STACK16FRAME       	frame16;
+    STACK32FRAME       	frame32;
+    char		ch;
 
-/***********************************************************************
- *           DEBUG_SilentBackTrace
- *
- * Display a stack back-trace.
- */
-void DEBUG_SilentBackTrace(void)
-{
-#ifdef __i386__
-    DEBUG_DoBackTrace( FALSE );
+    if (noisy) fprintf( stderr, "Backtrace:\n" );
+
+    nframe = 1;
+    if (frames) DBG_free( frames );
+    frames = (struct bt_info *) DBG_alloc( sizeof(struct bt_info) );
+    if (noisy)
+        fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno);
+
+    if (DEBUG_IsSelectorSystem(ss)) ss = 0;
+    if (DEBUG_IsSelectorSystem(cs)) cs = 0;
+
+    /* first stack frame from registers */
+    switch (DEBUG_GetSelectorType(ss))
+    {
+    case 32:
+        frames[0].cs = addr.seg = cs;
+        frames[0].eip = addr.off = DEBUG_context.Eip;
+        if (noisy)
+            frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE );
+        else
+	    DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, 
+				     &frames[0].frame.list);
+        frames[0].ss = addr.seg = ss;
+	frames[0].ebp = addr.off = DEBUG_context.Ebp;
+        if (noisy) fprintf( stderr, " (ebp=%08x)\n", frames[0].ebp );
+        is16 = FALSE;
+	break;
+    case 16:
+        frames[0].cs = addr.seg = cs;
+        frames[0].eip = addr.off = LOWORD(DEBUG_context.Eip);
+        if (noisy)
+	    frames[0].frame = DEBUG_PrintAddress( &addr, 16, TRUE );
+        else
+	    DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, 
+				     &frames[0].frame.list);
+        frames[0].ss = addr.seg = ss;
+	frames[0].ebp = addr.off = LOWORD(DEBUG_context.Ebp);
+        if (noisy) fprintf( stderr, " (bp=%04x)\n", frames[0].ebp );
+        is16 = TRUE;
+	break;
+    default:
+        if (noisy) fprintf( stderr, "Bad segment '%u'\n", ss);
+	return;
+    }
+
+    /* cur_switch holds address of curr_stack's field in TEB in debuggee 
+     * address space 
+     */
+    cur_switch = (DWORD)DEBUG_CurrThread->teb + OFFSET_OF(TEB, cur_stack);
+    if (!DEBUG_READ_MEM((void*)cur_switch, &next_switch, sizeof(next_switch))) {
+        if (noisy) fprintf( stderr, "Can't read TEB:cur_stack\n");
+	return;
+    }
+
+    if (is16) {
+        if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
+	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
+				(STACK32FRAME*)next_switch );
+	    return;
+	}
+	cur_switch = (DWORD)frame32.frame16;
+	sw_addr.seg = SELECTOROF(cur_switch);
+	sw_addr.off = OFFSETOF(cur_switch);
+    } else {
+        tmp.seg = SELECTOROF(next_switch);
+	tmp.off = OFFSETOF(next_switch);
+	p = DEBUG_ToLinear(&tmp);
+	
+	if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
+	    if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK16FRAME*)p );
+	    return;
+	}
+	cur_switch = (DWORD)frame16.frame32;
+	sw_addr.seg = ss;
+	sw_addr.off = cur_switch;
+    }
+    if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear(&sw_addr), &ch, sizeof(ch))) {
+        sw_addr.seg = (DWORD)-1;
+	sw_addr.off = (DWORD)-1;
+    }
+    
+    for (ok = TRUE; ok;) {
+        if ((frames[frameno].ss == sw_addr.seg) &&
+	    (frames[frameno].ebp >= sw_addr.off)) {
+	   /* 16<->32 switch...
+	    * yes, I know this is confusing, it gave me a headache too */
+	   if (is16) {
+	      
+	       if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
+		  if (noisy) fprintf( stderr, "Bad stack frame %p\n", (STACK32FRAME*)next_switch );
+		  return;
+	       }
+	       code.type = NULL;
+	       code.seg  = 0;
+	       code.off  = frame32.retaddr;
+	       
+	       cs = 0;
+	       addr.seg = 0;
+	       addr.off = frame32.ebp;
+	       DEBUG_ForceFrame( &addr, &code, ++frameno, 32, noisy );
+	       
+	       next_switch = cur_switch;
+	       tmp.seg = SELECTOROF(next_switch);
+	       tmp.off = OFFSETOF(next_switch);
+	       p = DEBUG_ToLinear(&tmp);
+	       
+	       if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
+		   if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
+				       (STACK16FRAME*)p );
+		   return;
+	       }
+	       cur_switch = (DWORD)frame16.frame32;
+	       sw_addr.seg = 0;
+	       sw_addr.off = cur_switch;
+	       
+	       is16 = FALSE;
+	   } else {
+	      tmp.seg = SELECTOROF(next_switch);
+	      tmp.off = OFFSETOF(next_switch);
+	      p = DEBUG_ToLinear(&tmp);
+	      
+	      if (!DEBUG_READ_MEM((void*)p, &frame16, sizeof(STACK16FRAME))) {
+		  if (noisy) fprintf( stderr, "Bad stack frame %p\n",
+				      (STACK16FRAME*)p );
+		  return;
+	      }
+	      
+	      code.type = NULL;
+	      code.seg  = frame16.cs;
+	      code.off  = frame16.ip;
+	      
+	      cs = frame16.cs;
+	      addr.seg = SELECTOROF(next_switch);
+	      addr.off = frame16.bp;
+	      DEBUG_ForceFrame( &addr, &code, ++frameno, 16, noisy );
+	      
+	      next_switch = cur_switch;
+	      if (!DEBUG_READ_MEM((void*)next_switch, &frame32, sizeof(STACK32FRAME))) {
+		 if (noisy) fprintf( stderr, "Bad stack frame %p\n", 
+				     (STACK32FRAME*)next_switch );
+		 return;
+	      }
+	      cur_switch = (DWORD)frame32.frame16;
+	      sw_addr.seg = SELECTOROF(cur_switch);
+	      sw_addr.off = OFFSETOF(cur_switch);
+	      
+	      is16 = TRUE;
+	   }
+	   if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear(&sw_addr), &ch, sizeof(ch))) {
+	      sw_addr.seg = (DWORD)-1;
+	      sw_addr.off = (DWORD)-1;
+	   }
+	} else {
+	    /* ordinary stack frame */
+	   ok = is16 ? DEBUG_Frame16( &addr, &cs, ++frameno, noisy)
+	      : DEBUG_Frame32( &addr, &cs, ++frameno, noisy);
+	}
+    }
+    if (noisy) fprintf( stderr, "\n" );
 #endif
 }
 
diff --git a/debugger/types.c b/debugger/types.c
index 1719586..c827866 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -345,7 +345,7 @@
 }
 
 long long int
-DEBUG_GetExprValue(DBG_ADDR * addr, char ** format)
+DEBUG_GetExprValue(const DBG_ADDR * addr, char ** format)
 {
   DBG_ADDR address = *addr;
   unsigned int rtn;
@@ -360,12 +360,10 @@
   switch(addr->type->type)
     {
     case DT_BASIC:
-      if (!DBG_CHECK_READ_PTR( &address,  addr->type->un.basic.basic_size)) 
-	{
-	  return 0;
-	}
+       
+      if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, addr->type->un.basic.basic_size))
+	 return 0;
 
-      memcpy(&rtn, (char *) addr->off, addr->type->un.basic.basic_size);
       if(    (addr->type->un.basic.b_signed)
 	  && ((addr->type->un.basic.basic_size & 3) != 0)
 	  && ((rtn >> (addr->type->un.basic.basic_size * 8 - 1)) != 0) )
@@ -388,8 +386,9 @@
 	}
       break;
     case DT_POINTER:
-      if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
-      rtn = (unsigned int)  *((unsigned char **)addr->off);
+      if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(void*)))
+	 return 0;
+
       type2 = addr->type->un.pointer.pointsto;
 
       if (!type2)
@@ -402,9 +401,8 @@
       if( type2->type == DT_BASIC && type2->un.basic.basic_size == 1 )
 	{
 	  def_format = "\"%s\"";
-	  address.off = rtn;
-	  address.seg = 0;
-	  if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
+	  if (!DEBUG_READ_MEM_VERBOSE((void*)rtn, &rtn, 1))
+	     return 0;
 	  break;
 	}
       else
@@ -414,13 +412,13 @@
       break;
     case DT_ARRAY:
     case DT_STRUCT:
-      if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
-      rtn = (unsigned int)  *((unsigned char **)addr->off);
+      if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(rtn)))
+	 return 0;
       def_format = "0x%8.8x";
       break;
     case DT_ENUM:
-      if (!DBG_CHECK_READ_PTR( &address, 1 )) return 0;
-      rtn = (unsigned int)  *((unsigned char **)addr->off);
+      if (!DEBUG_READ_MEM_VERBOSE((void*)addr->off, &rtn, sizeof(rtn)))
+	 return 0;
       for(e = addr->type->un.enumeration.members; e; e = e->next )
 	{
 	  if( e->value == rtn )
@@ -452,22 +450,23 @@
 }
 
 unsigned int
-DEBUG_TypeDerefPointer(DBG_ADDR * addr, struct datatype ** newtype)
+DEBUG_TypeDerefPointer(const DBG_ADDR * addr, struct datatype ** newtype)
 {
   DBG_ADDR address = *addr;
+  unsigned int val;
 
   /*
    * Make sure that this really makes sense.
    */
-  if( addr->type->type != DT_POINTER )
+  if( addr->type->type != DT_POINTER || !DEBUG_READ_MEM((void*)addr->off, &val, sizeof(val)))
     {
       *newtype = NULL;
       return 0;
     }
 
   *newtype = addr->type->un.pointer.pointsto;
-  address.off = *(unsigned int*) (addr->off);
-  return (unsigned int)DBG_ADDR_TO_LIN(&address); /* FIXME: is this right (or "better") ? */
+  address.off = val;
+  return DEBUG_ToLinear(&address); /* FIXME: is this right (or "better") ? */
 }
 
 unsigned int
@@ -718,7 +717,7 @@
 }
 
 unsigned int
-DEBUG_ArrayIndex(DBG_ADDR * addr, DBG_ADDR * result, int index)
+DEBUG_ArrayIndex(const DBG_ADDR * addr, DBG_ADDR * result, int index)
 {
   int size;
 
diff --git a/debugger/winedbg.c b/debugger/winedbg.c
new file mode 100644
index 0000000..c5fe7d4
--- /dev/null
+++ b/debugger/winedbg.c
@@ -0,0 +1,479 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/* Wine internal debugger
+ * Interface to Windows debugger API
+ * Eric Pouech (c) 2000
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include "debugger.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "debugtools.h"
+#include "options.h"
+
+#ifdef DBG_need_heap
+HANDLE dbg_heap = 0;
+#endif
+
+DEFAULT_DEBUG_CHANNEL(winedbg);
+    
+WINE_DBG_PROCESS* DEBUG_CurrProcess = NULL;
+WINE_DBG_THREAD*  DEBUG_CurrThread = NULL;
+CONTEXT		  DEBUG_context;
+
+static WINE_DBG_PROCESS* proc = NULL;
+
+static	WINE_DBG_PROCESS*	DEBUG_GetProcess(DWORD pid)
+{
+    WINE_DBG_PROCESS*	p;
+    
+    for (p = proc; p; p = p->next)
+	if (p->pid == pid) break;
+    return p;
+}
+
+static	WINE_DBG_PROCESS*	DEBUG_AddProcess(DWORD pid, HANDLE h)
+{
+    WINE_DBG_PROCESS*	p = DBG_alloc(sizeof(WINE_DBG_PROCESS));
+    if (!p)
+	return NULL;
+    p->handle = h;
+    p->pid = pid;
+    p->threads = NULL;
+
+    p->next = proc;
+    p->prev = NULL;
+    if (proc) proc->prev = p;
+    proc = p;
+    return p;
+}
+
+static	void			DEBUG_DelThread(WINE_DBG_THREAD* p);
+
+static	void			DEBUG_DelProcess(WINE_DBG_PROCESS* p)
+{
+    if (p->threads != NULL) {
+	ERR("Shouldn't happen\n");
+	while (p->threads) DEBUG_DelThread(p->threads);
+    }
+    if (p->prev) p->prev->next = p->next;
+    if (p->next) p->next->prev = p->prev;
+    if (p == proc) proc = p->next;
+    DBG_free(p);
+}
+
+static	void			DEBUG_InitCurrProcess(void)
+{
+#ifdef DBG_need_heap
+    /*
+     * Initialize the debugger heap.
+     */
+    dbg_heap = HeapCreate(HEAP_NO_SERIALIZE, 0x1000, 0x8000000); /* 128MB */
+#endif
+    
+    /*
+     * Initialize the type handling stuff.
+     */
+    DEBUG_InitTypes();
+    DEBUG_InitCVDataTypes();
+    
+    /*
+     * In some cases we can read the stabs information directly
+     * from the executable.  If this is the case, we don't need
+     * to bother with trying to read a symbol file, as the stabs
+     * also have line number and local variable information.
+     * As long as gcc is used for the compiler, stabs will
+     * be the default.  On SVr4, DWARF could be used, but we
+     * don't grok that yet, and in this case we fall back to using
+     * the wine.sym file.
+     */
+    if( DEBUG_ReadExecutableDbgInfo() == FALSE )
+    {
+	char*		symfilename = "wine.sym";
+	struct stat	statbuf;
+	HKEY 		hWineConf, hkey;
+	DWORD 		count;
+	char 		symbolTableFile[256];
+	
+	if (-1 == stat(symfilename, &statbuf) )
+	    symfilename = LIBDIR "wine.sym";
+	
+	strcpy(symbolTableFile, symfilename);
+	if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) {
+	    if (!RegOpenKeyA(hWineConf, "wine", &hkey)) {
+		count = sizeof(symbolTableFile);
+		RegQueryValueA(hkey, "SymbolTableFile", symbolTableFile, &count);
+		RegCloseKey(hkey);
+	    }
+	    RegCloseKey(hWineConf);
+	}
+	DEBUG_ReadSymbolTable(symbolTableFile);
+    }
+    DEBUG_LoadEntryPoints(NULL);
+    DEBUG_ProcessDeferredDebug();
+}
+
+static	BOOL			DEBUG_ProcessGetString(char* buffer, int size, 
+						       HANDLE hp, LPVOID addr)
+{
+    LPVOID	ad;
+    DWORD	sz;
+    
+    if (   addr 
+	&& ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) 
+	&& sz == sizeof(ad) 
+        && ad 
+        && ReadProcessMemory(hp, ad, buffer, size, &sz))
+	return TRUE;
+    *(WCHAR*)buffer = 0;
+    return FALSE;
+}
+
+static	WINE_DBG_THREAD*	DEBUG_GetThread(WINE_DBG_PROCESS* p, DWORD tid)
+{
+    WINE_DBG_THREAD*	t;
+    
+    for (t = p->threads; t; t = t->next)
+	if (t->tid == tid) break;
+    return t;
+}
+
+static	WINE_DBG_THREAD*	DEBUG_AddThread(WINE_DBG_PROCESS* p, DWORD tid, 
+						HANDLE h, LPVOID start, LPVOID teb)
+{
+    WINE_DBG_THREAD*	t = DBG_alloc(sizeof(WINE_DBG_THREAD));
+    if (!t)
+	return NULL;
+    
+    t->handle = h;
+    t->tid = tid;
+    t->start = start;
+    t->teb = teb;
+    t->process = p;
+    t->wait_for_first_exception = 0;
+    t->dbg_exec_mode = EXEC_CONT;
+    t->dbg_exec_count = 0;
+    
+    t->next = p->threads;
+    t->prev = NULL;
+    if (p->threads) p->threads->prev = t;
+    p->threads = t;
+
+    return t;
+}
+
+static	void			DEBUG_InitCurrThread(void)
+{
+    if (!Options.debug) return;
+
+    if (DEBUG_CurrThread->start) {
+	DBG_ADDR	addr;
+	
+	DEBUG_SetBreakpoints(FALSE);
+	addr.seg = 0;
+	addr.off = (DWORD)DEBUG_CurrThread->start;
+	DEBUG_AddBreakpoint(&addr);
+	DEBUG_SetBreakpoints(TRUE);
+    } else {
+	DEBUG_CurrThread->wait_for_first_exception = 1;
+    }
+}
+
+static	void			DEBUG_DelThread(WINE_DBG_THREAD* t)
+{
+    if (t->prev) t->prev->next = t->next;
+    if (t->next) t->next->prev = t->prev;
+    if (t == t->process->threads) t->process->threads = t->next;
+    DBG_free(t);
+}
+
+static	BOOL	DEBUG_HandleException( EXCEPTION_RECORD *rec, BOOL first_chance, BOOL force )
+{
+    BOOL	is_debug = FALSE;
+    BOOL	ret;
+
+    if (first_chance && !Options.debug && !force ) return 0;  /* pass to app first */
+
+    switch (rec->ExceptionCode)
+    {
+    case EXCEPTION_BREAKPOINT:
+    case EXCEPTION_SINGLE_STEP:
+        is_debug = TRUE;
+        break;
+    case CONTROL_C_EXIT:
+        if (!Options.debug) DEBUG_Exit(0);
+        break;
+    }
+
+    if (!is_debug)
+    {
+        /* print some infos */
+        fprintf( stderr, "%s: ",
+                 first_chance ? "First chance exception" : "Unhandled exception" );
+        switch(rec->ExceptionCode)
+        {
+        case EXCEPTION_INT_DIVIDE_BY_ZERO:
+            fprintf( stderr, "divide by zero" );
+            break;
+        case EXCEPTION_INT_OVERFLOW:
+            fprintf( stderr, "overflow" );
+            break;
+        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+            fprintf( stderr, "array bounds " );
+            break;
+        case EXCEPTION_ILLEGAL_INSTRUCTION:
+            fprintf( stderr, "illegal instruction" );
+            break;
+        case EXCEPTION_STACK_OVERFLOW:
+            fprintf( stderr, "stack overflow" );
+            break;
+        case EXCEPTION_PRIV_INSTRUCTION:
+            fprintf( stderr, "priviledged instruction" );
+            break;
+        case EXCEPTION_ACCESS_VIOLATION:
+            if (rec->NumberParameters == 2)
+                fprintf( stderr, "page fault on %s access to 0x%08lx", 
+                         rec->ExceptionInformation[0] ? "write" : "read",
+                         rec->ExceptionInformation[1] );
+            else
+                fprintf( stderr, "page fault" );
+            break;
+        case EXCEPTION_DATATYPE_MISALIGNMENT:
+            fprintf( stderr, "Alignment" );
+            break;
+        case CONTROL_C_EXIT:
+            fprintf( stderr, "^C" );
+            break;
+        case EXCEPTION_CRITICAL_SECTION_WAIT:
+            fprintf( stderr, "critical section %08lx wait failed", 
+		     rec->ExceptionInformation[0] );
+            break;
+        default:
+            fprintf( stderr, "%08lx", rec->ExceptionCode );
+            break;
+        }
+    }
+
+#if 1
+    fprintf(stderr, "Entering debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
+	    DEBUG_context.Eip, DEBUG_context.EFlags, 
+	    DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
+#endif
+
+    ret = DEBUG_Main( is_debug, force );
+#if 1
+    fprintf(stderr, "Exiting debugger 	PC=%lx EFL=%08lx mode=%d count=%d\n",
+	    DEBUG_context.Eip, DEBUG_context.EFlags, 
+	    DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
+#endif
+
+    return ret;
+}
+
+
+static	DWORD	CALLBACK	DEBUG_MainLoop(LPVOID pid)
+{
+    DEBUG_EVENT		de;
+    char		buffer[256];
+    DWORD		cont;
+
+    TRACE("WineDbg started on pid %ld\n", (DWORD)pid);
+    
+    if (!DebugActiveProcess((DWORD)pid))
+	TRACE("Can't debug process %ld: %ld\n", (DWORD)pid, GetLastError());
+    
+    while (WaitForDebugEvent(&de, INFINITE)) {
+	cont = 0L;
+
+	if ((DEBUG_CurrProcess = DEBUG_GetProcess(de.dwProcessId)) != NULL)
+	    DEBUG_CurrThread = DEBUG_GetThread(DEBUG_CurrProcess, de.dwThreadId);
+	else 
+	    DEBUG_CurrThread = NULL;
+
+	switch (de.dwDebugEventCode) {
+	case EXCEPTION_DEBUG_EVENT:
+	    if (!DEBUG_CurrThread) break;
+
+	    TRACE("%08lx:%08lx: exception code=%08lx %d\n", 
+		  de.dwProcessId, de.dwThreadId, 
+		  de.u.Exception.ExceptionRecord.ExceptionCode,
+		  DEBUG_CurrThread->wait_for_first_exception);
+
+	    DEBUG_context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS|CONTEXT_DEBUG_REGISTERS;
+	    if (!GetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context)) {
+		WARN("Can't get thread's context\n");
+		break;
+	    }
+
+	    TRACE("%p:%p\n", de.u.Exception.ExceptionRecord.ExceptionAddress, 
+		  (void*)DEBUG_context.Eip);
+
+	    cont = DEBUG_HandleException(&de.u.Exception.ExceptionRecord, 
+					 de.u.Exception.dwFirstChance, 
+					 DEBUG_CurrThread->wait_for_first_exception);
+
+	    if (DEBUG_CurrThread->wait_for_first_exception) {
+		DEBUG_CurrThread->wait_for_first_exception = 0;
+#ifdef __i386__
+		DEBUG_context.Eip--;
+#endif
+	    }
+	    SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
+	    break;
+	    
+	case CREATE_THREAD_DEBUG_EVENT:
+	    TRACE("%08lx:%08lx: create thread D @%p\n", de.dwProcessId, de.dwThreadId, 
+		  de.u.CreateThread.lpStartAddress);
+	    
+	    if (DEBUG_CurrProcess == NULL) {
+		ERR("Unknown process\n");
+		break;
+	    }
+	    if (DEBUG_GetThread(DEBUG_CurrProcess, de.dwThreadId) != NULL) {
+		TRACE("Thread already listed, skipping\n");
+		break;
+	    }
+
+	    DEBUG_CurrThread = DEBUG_AddThread(DEBUG_CurrProcess, 
+					       de.dwThreadId, 
+					       de.u.CreateThread.hThread, 
+					       de.u.CreateThread.lpStartAddress, 
+					       de.u.CreateThread.lpThreadLocalBase);
+	    if (!DEBUG_CurrThread) {
+		ERR("Couldn't create thread\n");
+		break;
+	    }
+	    DEBUG_InitCurrThread();
+	    break;
+	    
+	case CREATE_PROCESS_DEBUG_EVENT:
+	    DEBUG_ProcessGetString(buffer, sizeof(buffer), 
+				   de.u.CreateProcessInfo.hProcess, 
+				   de.u.LoadDll.lpImageName);
+	    
+	    /* FIXME unicode ? de.u.CreateProcessInfo.fUnicode */
+	    TRACE("%08lx:%08lx: create process %s @%p\n", 
+		  de.dwProcessId, de.dwThreadId, 
+		  buffer,
+		  de.u.CreateProcessInfo.lpStartAddress);
+	    
+	    if (DEBUG_GetProcess(de.dwProcessId) != NULL) {
+		TRACE("Skipping already defined process\n");
+		break;
+	    }
+	    DEBUG_CurrProcess = DEBUG_AddProcess(de.dwProcessId,
+						 de.u.CreateProcessInfo.hProcess);
+	    if (DEBUG_CurrProcess == NULL) {
+		ERR("Unknown process\n");
+		break;
+	    }
+	    
+	    TRACE("%08lx:%08lx: create thread I @%p\n", de.dwProcessId, de.dwThreadId, 
+		  de.u.CreateProcessInfo.lpStartAddress);
+	    
+	    DEBUG_CurrThread = DEBUG_AddThread(DEBUG_CurrProcess, 	
+					       de.dwThreadId, 
+					       de.u.CreateProcessInfo.hThread, 
+					       de.u.CreateProcessInfo.lpStartAddress, 
+					       de.u.CreateProcessInfo.lpThreadLocalBase);
+	    if (!DEBUG_CurrThread) {
+		ERR("Couldn't create thread\n");
+		break;
+	    }
+	    
+	    DEBUG_InitCurrProcess();
+	    DEBUG_InitCurrThread();
+	    break;
+	    
+	case EXIT_THREAD_DEBUG_EVENT:
+	    TRACE("%08lx:%08lx: exit thread (%ld)\n", 
+		  de.dwProcessId, de.dwThreadId, de.u.ExitThread.dwExitCode);
+
+	    if (DEBUG_CurrThread == NULL) {
+		ERR("Unknown thread\n");
+		break;
+	    }
+	    /* FIXME: remove break point set on thread startup */
+	    DEBUG_DelThread(DEBUG_CurrThread);
+	    break;
+	    
+	case EXIT_PROCESS_DEBUG_EVENT:
+	    TRACE("%08lx:%08lx: exit process (%ld)\n", 
+		  de.dwProcessId, de.dwThreadId, de.u.ExitProcess.dwExitCode);
+
+	    if (DEBUG_CurrProcess == NULL) {
+		ERR("Unknown process\n");
+		break;
+	    }
+	    /* kill last thread */
+	    DEBUG_DelThread(DEBUG_CurrProcess->threads);
+	    /* FIXME: remove break point set on thread startup */
+	    DEBUG_DelProcess(DEBUG_CurrProcess);
+	    break;
+	    
+	case LOAD_DLL_DEBUG_EVENT:
+	    if (DEBUG_CurrThread == NULL) {
+		ERR("Unknown thread\n");
+		break;
+	    }
+	    DEBUG_ProcessGetString(buffer, sizeof(buffer), 
+				   DEBUG_CurrThread->process->handle, 
+				   de.u.LoadDll.lpImageName);
+	    
+	    /* FIXME unicode: de.u.LoadDll.fUnicode */
+	    TRACE("%08lx:%08lx: loads DLL %s @%p\n", de.dwProcessId, de.dwThreadId, 
+		  buffer, de.u.LoadDll.lpBaseOfDll);
+	    break;
+	    
+	case UNLOAD_DLL_DEBUG_EVENT:
+	    TRACE("%08lx:%08lx: unload DLL @%p\n", de.dwProcessId, de.dwThreadId, 
+		  de.u.UnloadDll.lpBaseOfDll);
+	    break;
+	    
+	case OUTPUT_DEBUG_STRING_EVENT:
+	    if (DEBUG_CurrThread == NULL) {
+		ERR("Unknown thread\n");
+		break;
+	    }
+
+	    DEBUG_ProcessGetString(buffer, sizeof(buffer), 
+				   DEBUG_CurrThread->process->handle, 
+				   de.u.DebugString.lpDebugStringData);
+	    
+	    
+	    /* fixme unicode de.u.DebugString.fUnicode ? */
+	    TRACE("%08lx:%08lx: output debug string (%s)\n", 
+		  de.dwProcessId, de.dwThreadId, 
+		  buffer);
+	    break;
+	    
+	case RIP_EVENT:
+	    TRACE("%08lx:%08lx: rip error=%ld type=%ld\n", 
+		  de.dwProcessId, de.dwThreadId, de.u.RipInfo.dwError, 
+		  de.u.RipInfo.dwType);
+	    break;
+	    
+	default:
+	    TRACE("%08lx:%08lx: unknown event (%ld)\n", 
+		  de.dwProcessId, de.dwThreadId, de.dwDebugEventCode);
+	}
+	ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
+    }
+    
+    TRACE("WineDbg terminated on pid %ld\n", (DWORD)pid);
+    
+    return 0L;
+}
+
+#include "thread.h"
+#include "process.h"
+
+void	DEBUG_StartDebugger(DWORD pid)
+{
+    if (Options.debug)
+	CreateThread(NULL, 0, DEBUG_MainLoop, (LPVOID)pid, 0, NULL);
+}
+