Release 950706

Wed Jul  5 19:06:35 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [controls/scroll.c]
	Fixed drawing bug that caused part of a non-client scroll bar
	to be painted even when the scroll-bar was hidden.

	* [debugger/break.c] [debugger/dbg.y]
	Rewrote breakpoint handling to work in 16-bit mode.
	Implemented single-stepping ('step' and 'next' instructions).

	* [debugger/debug.l]
	Format specifier is now a separate token.
	Entering an empty line at the debugger prompt causes the previous
	command to be repeated, like under gdb.
	
	* [debugger/debug.l] [debugger/registers.c]
	Differentiate 16-bit and 32-bit registers without taking current
	mode into account ($eax is always 32-bit, $ax always 16-bit).

	* [debugger/stack.c]
	Fixed stack information routines to differentiate between 16-bit
	and 32-bit stacks.

	* [loader/task.c]
	Option -debug now sets a breakpoint at the first instruction of
	every loaded task.

	* [miscemu/instr.c]
	Added handling of lock, repe and repne prefixes.

	* [objects/dib.c]
	Changed StretchDIBits() to do the correct thing, even if it's still
	not really optimal.

	* [windows/graphics.c]
	Fixes in RoundRect(), thanks to Babak Masalehdan.

	* [windows/message.c]
	Tried to fix mouse event handling with respect to disabled
	windows.

	* [windows/painting.c]
	Clear WIN_NEEDS_NCPAINT flag before sending WM_NCPAINT to avoid
	infinite loops.

	* [windows/win.c]
	Fixed IsWindowVisible() to return FALSE when one of the parent
	windows is hidden.

Sat Jul  1 22:08:21 1995   Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/compobj.spec][misc/compobj.c]
	CoGetMalloc: New function
	Added relay entries for COMPOBJ ordinals above 100
	CoInitialize: Changed parameter to DWORD

	* [if1632/ole2.spec]
	Exported implementation of OleBuildVersion

	* [if1632/ole2disp.spec][misc/ole2disp.c][misc/Imakefile]
	ole2disp.c: New file
	SysAllocString, SysReallocString, SysAllocStringLen,
	SysReAllocStringLen, SysFreeString, SysStringLen: new functions

	* [if1632/ole2nls.spec][include/winnls.h][misc/ole2nls.c]
	CompareStringA: New function

Thu Jun 29 19:42:02 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>
	* [objects/font.c] [if1632/gdi.spec]
	New stubs for CreateScalableFontResource, GetGlyphOutline.

Thu Jun 29 13:47:08 GMT 1995  Göran Thyni  (goran@norrsken.bildbasen.se)

	* [misc/commdlg.c]
	Extensive changes and bug fixes to FileDialog handling,
        behaves more like native Windows.

Wed Jun 28 13:04:44 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c] [controls/combo.c]
	Some minor optimizations.
	
	* [memory/local.c]
	LOCAL_FindFreeBlock(): Never use the last one.
	
	* [memory/global.c]
	GlobalReAlloc(): GMEM_MODIFY must not be ignored when size==0.
	
	* [misc/file.c]
	read() returns an error when length==0. This is not what Windows
	programs expect, so pay attention to this in _lread(). Changed this
	in _lwrite(), _hread(), _hwrite(), too.

	* [loader/resource.c]
	LoadIcon(): Ignore bih->biSizeImage, some icons have wrong values in
	there.
	
	* [if1632/shell.spec] [misc/shell.c]
	Wrong spec file entries caused havoc: HKEY has 32 bit, not 16.
	Accept some more combinations of parameters in the Reg..() functions.
	
	* [if1632/toolhelp.spec]
	Make InterruptRegister() and InterruptUnregister() return false.

	* [windows/hook.c]
	CallNextHookEx() used to crash when called with a null hhook. Fixed.

Wed Jun 28 10:14:34 1995  Martin von Loewis  <martin@informatik.hu-berlin.de>

	* [include/neexe.h][loader/ne_image.c]
	NE_LoadSegment: Detect iterated segments

	* [misc/ole2nls.c]
	LOCALE_SLONGDATE: fixed typo

	* [miscemu/int5c.c]
	Reordered include files to avoid conflicts with Linux libc.5.1

	* [rc/winerc.c]
	Added -b option to process binary resource files into C arrays

	* [include/callback.h]
	CallWndProc: Added dummy ds parameter for libwine

	* [include/gdi.h][include/user.h]
	USER_HEAP_ALLOC, GDI_HEAP_ALLOC: dropped flags parameter

	* [include/ldt.h][include/stackframe.h]
	defined segment conversion macros for libwine

	* [misc/atom.c]
	Defined USER_HeapSel for libwine

	* [misc/main.c]
	Disable -dll option for libwine

	* [misc/user.c]
	removed GetFreeSystemResources, SystemHeapInfo from libwine for now

	* [toolkit/heap.c]
	fixed LocalLock prototype

	* [toolkit/sup.c]
	sync'ed load_mz_header, load_ne_header with structures

	* [toolkit/winmain.c]
	Disabled resource DLLs for libwine for now

Mon Jun 26 19:30:24 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)

	* [misc/main.c]
	Fixed -enhanced option to report a 386 CPU instead of a 286.

Fri Jun 23 23:18:25 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>

	* [misc/dos_fs.c]
	Remove maximum open dosdirent limit (fixing the winfile.exe
 	problem) by using telldir()/seekdir().
	
Fri Jun 23 13:42:25 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)

	* [misc/profile.c]
	Fixed problem parsing empty lines within sections in .ini files.
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 7b7ea9d..39c46f4 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -16,7 +16,9 @@
 	dbg.tab.c \
 	hash.c \
 	info.c \
-	lex.yy.c
+	lex.yy.c \
+	registers.c \
+	stack.c
 
 SUBDIRS_OBJS = readline/readline.o
 
diff --git a/debugger/break.c b/debugger/break.c
index 711c495..e143669 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -1,3 +1,9 @@
+/*
+ * Debugger break-points handling
+ *
+ * Copyright 1994 Martin von Loewis
+ * Copyright 1995 Alexandre Julliard
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -5,100 +11,42 @@
 #ifdef linux
 #include <sys/utsname.h>
 #endif
-#include <windows.h>
-#include "db_disasm.h"
+#include "windows.h"
+#include "debugger.h"
 
-#define N_BP 25
+#define INT3          0xcc   /* int 3 opcode */
+#define STEP_FLAG     0x100  /* single-step flag */
 
-extern int dbg_mode;
+#define MAX_BREAKPOINTS 25
 
-struct wine_bp{
-  unsigned long addr;
-  unsigned long next_addr;
-  char in_use;
-  char enabled;
-  unsigned char databyte;
-};
-
-static struct wine_bp wbp[N_BP] = {{0,},};
-
-static int current_bp = -1;
-static int cont_mode=0;	/* 0 - continuous execution
-			   1 - advancing after breakpoint
-			   2 - single step - not implemented
-			*/
-
-void info_break(void)
+typedef struct
 {
-  int j;
-  fprintf(stderr,"Breakpoint status\n");
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].in_use)
-      fprintf(stderr,"%d: %c %8lx\n", j, (wbp[j].enabled ? 'y' : 'n'),
-	      wbp[j].addr);
-}
+    unsigned int  segment;
+    unsigned int  addr;
+    BYTE          addrlen;
+    BYTE          opcode;
+    BOOL          enabled;
+    BOOL          in_use;
+} BREAKPOINT;
 
-void disable_break(int bpnum)
+static BREAKPOINT breakpoints[MAX_BREAKPOINTS] = { { 0, }, };
+
+static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
+
+
+/***********************************************************************
+ *           DEBUG_ChangeOpcode
+ *
+ * Change the opcode at segment:addr.
+ */
+static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
 {
-  if(bpnum >= N_BP || bpnum < 0)
-    fprintf(stderr,"Breakpoint number out of range\n");
-
-  wbp[bpnum].enabled = 0;
-}
-
-void enable_break(int bpnum)
-{
-  if(bpnum >= N_BP || bpnum < 0)
-    fprintf(stderr,"Breakpoint number out of range\n");
-
-  wbp[bpnum].enabled = 1;
-}
-
-void add_break(unsigned long addr)
-{
-  int j;
-  for(j=0; j<N_BP; j++)
-    if(!wbp[j].in_use)
-      {
-	wbp[j].in_use = 1;
-	wbp[j].enabled = 1;
-	wbp[j].addr = addr;
-	wbp[j].next_addr = 0;
-	return;
-      }
-  fprintf(stderr,"No more breakpoints\n");
-}
-
-static void bark()
-{
-  static int barked=0;
-  if(barked)return;
-  barked=1;
-  perror("Sorry, can't set break point");
-#ifdef linux
-  {struct utsname buf;
-  uname(&buf);
-  if(strcmp(buf.sysname,"Linux")==0)
-  {	if(strcmp(buf.release,"1.1.62")<0)
-	  fprintf(stderr,"Your current Linux release is %s. "
-		"You should upgrade to 1.1.62 or higher\n"
-		"Alternatively, in /usr/src/linux/fs/exec.c,"
-		" change MAP_SHARED to MAP_PRIVATE.\n", buf.release);
-  } else
-  fprintf(stderr,"Why did you compile for Linux, while your system is"
-   " actually %s?\n",buf.sysname);
-  }
-#endif
-}
-  
-void insert_break(int flag)
-{
-  unsigned char * pnt;
-  int j;
-
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].enabled)
-      {
+    if (segment)
+    {
+        *(BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) = op;
+    }
+    else  /* 32-bit code, so we have to change the protection first */
+    {
         /* 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.
@@ -108,54 +56,221 @@
            Not that portability matters, this code is i386 only anyways...
            How do I get the old protection in order to restore it later on?
         */
-	if(mprotect((caddr_t)(wbp[j].addr & (~4095)), 4096, 
-	  PROT_READ|PROT_WRITE|PROT_EXEC) == -1){
-	    bark();
+        if (mprotect((caddr_t)(addr & (~4095)), 4096,
+                     PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+        {
+            perror( "Can't set break point" );
             return;
 	}
-	pnt = (unsigned char *) wbp[j].addr;
-	if(flag) {
-	  wbp[j].databyte = *pnt;
-	  *pnt = 0xcc;  /* Change to an int 3 instruction */
-	} else {
-	  *pnt = wbp[j].databyte;
-	}
-	mprotect((caddr_t)(wbp[j].addr & ~4095), 4096, PROT_READ|PROT_EXEC);
-      }
-}
-
-/* Get the breakpoint number that we broke upon */
-int get_bpnum(unsigned int addr)
-{
-  int j;
-
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].enabled)
-      if(wbp[j].addr == addr) return j;
-
-  return -1;
-}
-
-void toggle_next(int num)
-{
-   unsigned int addr;
-   addr=wbp[num].addr;
-   if(wbp[num].next_addr == 0)
-	wbp[num].next_addr = db_disasm( 0, addr, (dbg_mode == 16) );
-   wbp[num].addr=wbp[num].next_addr;
-   wbp[num].next_addr=addr;
-}
-
-int should_continue(int bpnum)
-{
-    if(bpnum<0)return 0;
-    toggle_next(bpnum);
-    if(bpnum==current_bp){
-        current_bp=-1;
-	cont_mode=0;
-	return 1;
+        *(BYTE *)addr = op;
+	mprotect((caddr_t)(addr & ~4095), 4096, PROT_READ|PROT_EXEC);
     }
-    cont_mode=1;
-    current_bp=bpnum;
-    return 0;
+}
+
+
+/***********************************************************************
+ *           DEBUG_SetBreakpoints
+ *
+ * Set or remove all the breakpoints.
+ */
+void DEBUG_SetBreakpoints( BOOL set )
+{
+    int i;
+
+    for (i = 0; i < MAX_BREAKPOINTS; i++)
+    {
+        if (breakpoints[i].in_use && breakpoints[i].enabled)
+            DEBUG_SetOpcode( breakpoints[i].segment, breakpoints[i].addr,
+                             set ? INT3 : breakpoints[i].opcode );
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_FindBreakpoint
+ *
+ * Find the breakpoint for a given address. Return the breakpoint
+ * number or -1 if none.
+ */
+int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
+{
+    int i;
+
+    for (i = 0; i < MAX_BREAKPOINTS; i++)
+    {
+        if (breakpoints[i].in_use && breakpoints[i].enabled &&
+            breakpoints[i].segment == segment && breakpoints[i].addr == addr)
+            return i;
+    }
+    return -1;
+}
+
+
+/***********************************************************************
+ *           DEBUG_AddBreakpoint
+ *
+ * Add a breakpoint.
+ */
+void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
+{
+    int num;
+    BYTE *p;
+
+    if (segment == 0xffffffff) segment = CS;
+    if (segment == WINE_CODE_SELECTOR) segment = 0;
+
+    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 (num >= MAX_BREAKPOINTS)
+        {
+            fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
+            return;
+        }
+    }
+    p = segment ? (BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) : (BYTE *)addr;
+    breakpoints[num].segment = segment;
+    breakpoints[num].addr    = addr;
+    breakpoints[num].addrlen = !segment ? 32 :
+                          (GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT) ? 32 : 16;
+    breakpoints[num].opcode  = *p;
+    breakpoints[num].enabled = TRUE;
+    breakpoints[num].in_use  = TRUE;
+    fprintf( stderr, "Breakpoint %d at ", num );
+    print_address( segment, addr, breakpoints[num].addrlen );
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ *           DEBUG_DelBreakpoint
+ *
+ * Delete a breakpoint.
+ */
+void DEBUG_DelBreakpoint( int num )
+{
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    {
+        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        return;
+    }
+    breakpoints[num].enabled = FALSE;
+    breakpoints[num].in_use  = FALSE;
+}
+
+
+/***********************************************************************
+ *           DEBUG_EnableBreakpoint
+ *
+ * Enable or disable a break point.
+ */
+void DEBUG_EnableBreakpoint( int num, BOOL enable )
+{
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    {
+        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        return;
+    }
+    breakpoints[num].enabled = enable;
+}
+
+
+/***********************************************************************
+ *           DEBUG_InfoBreakpoints
+ *
+ * Display break points information.
+ */
+void DEBUG_InfoBreakpoints(void)
+{
+    int i;
+
+    fprintf( stderr, "Breakpoints:\n" );
+    for (i = 1; i < next_bp; i++)
+    {
+        if (breakpoints[i].in_use)
+        {
+            fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
+            print_address( breakpoints[i].segment, breakpoints[i].addr,
+                           breakpoints[i].addrlen );
+            fprintf( stderr, "\n" );
+        }
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_ShouldContinue
+ *
+ * Determine if we should continue execution after a SIGTRAP signal when
+ * executing in the given mode.
+ */
+BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
+                           enum exec_mode mode )
+{
+    unsigned int segment, addr;
+    int bpnum;
+
+      /* If not single-stepping, back up over the int3 instruction */
+    if (!(EFL & STEP_FLAG)) EIP--;
+
+    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+    addr    = EIP;
+    bpnum  = DEBUG_FindBreakpoint( segment, addr );
+    breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
+
+    if ((bpnum != 0) && (bpnum != -1))
+    {
+        fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
+        print_address( breakpoints[bpnum].segment, breakpoints[bpnum].addr,
+                       breakpoints[bpnum].addrlen );
+        fprintf( stderr, "\n" );
+        return FALSE;
+    }
+      /* no breakpoint, continue if in continuous mode */
+    return (mode == EXEC_CONT);
+}
+
+
+/***********************************************************************
+ *           DEBUG_RestartExecution
+ *
+ * Set the breakpoints to the correct state to restart execution
+ * in the given mode.
+ */
+void DEBUG_RestartExecution( struct sigcontext_struct *context,
+                             enum exec_mode mode, int instr_len )
+{
+    unsigned int segment, addr;
+
+    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+    addr    = EIP;
+
+    if (DEBUG_FindBreakpoint( segment, addr ) != -1)
+        mode = EXEC_STEP_INSTR;  /* If there's a breakpoint, skip it */
+
+    switch(mode)
+    {
+    case EXEC_CONT: /* Continuous execution */
+        EFL &= ~STEP_FLAG;
+        DEBUG_SetBreakpoints( TRUE );
+        break;
+
+    case EXEC_STEP_OVER:  /* Stepping over a call */
+        EFL &= ~STEP_FLAG;
+        breakpoints[0].segment = segment;
+        breakpoints[0].addr    = addr + instr_len;
+        breakpoints[0].enabled = TRUE;
+        breakpoints[0].in_use  = TRUE;
+        breakpoints[0].opcode  = segment ?
+           *(BYTE *)PTR_SEG_OFF_TO_LIN(segment,addr+instr_len) : *(BYTE *)addr;
+        DEBUG_SetBreakpoints( TRUE );
+        break;
+
+    case EXEC_STEP_INSTR: /* Single-stepping an instruction */
+        EFL |= STEP_FLAG;
+        break;
+    }
 }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 5d7d176..50474d6 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -61,25 +61,15 @@
 /*
  * Instruction disassembler.
  */
-#if 0
-#include <mach/boolean.h>
-#include "db_machdep.h"
 
-#include "db_access.h"
-#include "db_sym.h"
-
-#include <kern/task.h>
-#endif
 #include <stdio.h>
-#include "db_disasm.h"
+#include "windows.h"
 #include "ldt.h"
 
-extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
-
 /*
  * Switch to disassemble 16-bit code.
  */
-static boolean_t	db_disasm_16 = FALSE;
+static BOOL db_disasm_16 = FALSE;
 
 /*
  * Size attributes
@@ -932,13 +922,9 @@
 /*
  * Read address at location and return updated location.
  */
-db_addr_t
-db_read_address(segment, loc, short_addr, regmodrm, addrp)
-        unsigned int segment;
-	db_addr_t	loc;
-	int		short_addr;
-	int		regmodrm;
-	struct i_addr	*addrp;		/* out */
+unsigned int db_read_address( unsigned int segment, unsigned int loc,
+                              int short_addr, int regmodrm,
+                              struct i_addr *addrp )
 {
 	int		mod, rm, sib, index, disp;
 
@@ -1058,21 +1044,15 @@
 		fprintf(stderr,",%s,%d", addrp->index, 1<<addrp->ss);
 	    fprintf(stderr,")");
 	} else
-	    db_task_printsym((db_addr_t)addrp->disp, size);
+	    db_task_printsym(addrp->disp, size);
 }
 
 /*
  * Disassemble floating-point ("escape") instruction
  * and return updated location.
  */
-db_addr_t
-db_disasm_esc(segment, loc, inst, short_addr, size, seg)
-        unsigned int segment;
-	db_addr_t	loc;
-	int		inst;
-	int		short_addr;
-	int		size;
-	char *		seg;
+unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
+                            int inst, int short_addr, int size, char *seg )
 {
 	int		regmodrm;
 	struct finst	*fp;
@@ -1151,11 +1131,7 @@
  * Disassemble instruction at 'loc'.  Return address of start of
  * next instruction.
  */
-db_addr_t
-db_disasm(segment, loc, flag16)
-        unsigned int segment;
-	db_addr_t	loc;
-        boolean_t       flag16;
+unsigned int db_disasm( unsigned int segment, unsigned int loc )
 {
 	int	inst;
 	int	size;
@@ -1166,7 +1142,7 @@
 	int	i_size;
 	int	i_mode;
 	int	regmodrm = 0;
-	boolean_t	first;
+	BOOL    first;
 	int	displ;
 	int	prefix;
 	int	imm;
@@ -1174,7 +1150,8 @@
 	int	len;
 	struct i_addr	address;
 
-	db_disasm_16 = flag16;
+        if (!segment) db_disasm_16 = FALSE;
+        else db_disasm_16 = !(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT);
 
 	get_value_inc(inst, segment, loc, 1, FALSE);
 
@@ -1240,7 +1217,7 @@
 	} while (prefix);
 
 	if (inst >= 0xd8 && inst <= 0xdf) {
-	    loc = db_disasm_esc(loc, inst, short_addr, size, seg);
+	    loc = db_disasm_esc(segment, loc, inst, short_addr, size, seg);
 	    fprintf(stderr,"\n");
 	    return (loc);
 	}
@@ -1441,8 +1418,7 @@
 		    if (seg)
 			fprintf(stderr,"%s:%d",seg, displ);
 		    else
-			db_task_printsym((db_addr_t)displ,
-                                         short_addr ? WORD : LONG);
+			db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
 
 		case Db:
@@ -1454,8 +1430,7 @@
 		    }
 		    else
 			displ = displ + loc;
-		    db_task_printsym((db_addr_t)displ,
-                                     short_addr ? WORD : LONG);
+		    db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
 
 		case Dl:
@@ -1469,8 +1444,7 @@
 			get_value_inc(displ, segment, loc, 4, TRUE);
 			displ = displ + loc;
 		    }
-		    db_task_printsym((db_addr_t)displ,
-                                     short_addr ? WORD : LONG);
+		    db_task_printsym( displ, short_addr ? WORD : LONG);
 		    break;
 
 		case o1:
diff --git a/debugger/db_disasm.h b/debugger/db_disasm.h
deleted file mode 100644
index 73992d7..0000000
--- a/debugger/db_disasm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define FALSE 0
-#define TRUE 1
-
-typedef unsigned char boolean_t;
-typedef unsigned long db_addr_t;
-
-extern db_addr_t db_disasm(unsigned int segment, db_addr_t loc,
-                           boolean_t flag16);
diff --git a/debugger/dbg.y b/debugger/dbg.y
index fd8748d..c9a5585 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -10,24 +10,25 @@
 
 #include <stdio.h>
 #include <signal.h>
-#include "ldt.h"
+#include <unistd.h>
 #include "windows.h"
-#include "wine.h"
+#include "debugger.h"
 
 #define YYSTYPE int
 
-#include "regpos.h"
 extern FILE * yyin;
-unsigned int * regval = NULL;
-unsigned int dbg_mask = 0;
 unsigned int dbg_mode = 0;
 
+static enum exec_mode dbg_exec_mode = EXEC_CONT;
+
 void issue_prompt(void);
 void mode_command(int);
 %}
 
 
 %token CONT
+%token STEP
+%token NEXT
 %token QUIT
 %token HELP
 %token BACKTRACE
@@ -40,10 +41,13 @@
 %token ENABLE
 %token DISABLE
 %token BREAK
+%token DELETE
 %token SET
 %token MODE
 %token PRINT
+%token EXAM
 %token IDENTIFIER
+%token FORMAT
 %token NO_SYMBOL
 %token SYMBOLFILE
 %token DEFINE
@@ -58,68 +62,59 @@
 	| infocmd '\n'
 	| error '\n'       { yyerrok; }
 	| QUIT  '\n'       { exit(0); }
-	| 'q' '\n'         { exit(0); }
 	| HELP  '\n'       { dbg_help(); }
-	| CONT '\n'        { return 0; }
-	| 'c' '\n'         { return 0; }
+	| CONT '\n'        { dbg_exec_mode = EXEC_CONT; return 0; }
+	| STEP '\n'        { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
+	| NEXT '\n'        { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
 	| ABORT '\n'       { kill(getpid(), SIGABRT); }
- 	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
+ 	| SYMBOLFILE IDENTIFIER '\n'   { read_symboltable($2); }
 	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, 0, $3); }
-	| MODE NUM	   { mode_command($2); }
-	| ENABLE NUM	   { enable_break($2); }
-	| DISABLE NUM	   { disable_break($2); }
-	| BREAK '*' expr   { add_break($3); }
+	| MODE NUM '\n'         { mode_command($2); }
+	| ENABLE NUM '\n'       { DEBUG_EnableBreakpoint( $2, TRUE ); }
+	| DISABLE NUM '\n'      { DEBUG_EnableBreakpoint( $2, FALSE ); }
+	| BREAK '*' expr        { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
+        | BREAK '\n'            { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
+        | DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
+	| BACKTRACE '\n'        { DEBUG_BackTrace(); }
 	| x_command
-	| BACKTRACE '\n'   { dbg_bt(); }
 	| print_command
 	| deposit_command
 
 deposit_command:
-	SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
+	SET REG '=' expr '\n'        { DEBUG_SetRegister( $2, $4 ); }
 	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
-	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
+	| SET symbol '=' expr '\n'   { *((unsigned int *) $2) = $4; }
 
 
 x_command:
-	  'x' expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
-	| 'x' '/' fmt expr  '\n' { examine_memory( 0xffffffff, $4, 1, $3); }
-	| 'x' '/' NUM fmt expr  '\n' { examine_memory( 0xffffffff, $5, $3, $4); }
+	  EXAM expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
+	| EXAM FORMAT expr  '\n' { examine_memory( 0xffffffff, $3,
+                                                  $2 >> 8, $2 & 0xff ); }
 
-print:
-	  'p'
-	| PRINT
-	
  print_command:
-	  print expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1, 'x'); }
-	| print '/' fmt expr '\n' { examine_memory( 0, (unsigned int) &$4, 1, $3); }
+	  PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }
+	| PRINT FORMAT expr '\n' { examine_memory( 0, (unsigned int)&$3,
+                                                   $2 >> 8, $2 & 0xff ); }
 
- fmt:  'x'     { $$ = 'x'; }
-	| 'd'  { $$ = 'd'; }
-	| 'i'  { $$ = 'i'; }
-	| 'w'  { $$ = 'w'; }
-	| 's'  { $$ = 's'; }
-	| 'c'  { $$ = 'c'; }
-	| 'b' { $$ = 'b'; }
-
- symbol: IDENTIFIER             { $$ = find_hash($1);
-			           if($$ == 0xffffffff) {
-					   fprintf(stderr,"Symbol %s not found\n", $1);
-					   YYERROR;
-				   }
-			        } 
+ symbol: IDENTIFIER   { if (($$ = find_hash($1)) == 0xffffffff)
+                        {
+                           fprintf(stderr,"Symbol %s not found\n", (char *)$1);
+                           YYERROR;
+                        }
+                      } 
 
  expr:  NUM			{ $$ = $1;	}
-	| REG			{ if(regval) $$ = regval[$1]; else application_not_running();}
+	| REG			{ $$ = DEBUG_GetRegister($1); }
 	| symbol   		{ $$ = $1; }
 	| expr '+' NUM		{ $$ = $1 + $3; }
 	| expr '-' NUM		{ $$ = $1 - $3; }
 	| '(' expr ')'		{ $$ = $2; }
 	| '*' expr		{ $$ = *((unsigned int *) $2); }
 	
- infocmd: INFO REGS     { info_reg(); }
-	| INFO STACK    { info_stack(); }
+ infocmd: INFO REGS     { DEBUG_InfoRegisters(); }
+	| INFO STACK    { DEBUG_InfoStack(); }
+	| INFO BREAK    { DEBUG_InfoBreakpoints(); }
 	| INFO SEGMENTS { LDT_Print(); }
-	| INFO BREAK    { info_break(); }
 
 
 %%
@@ -133,78 +128,55 @@
 
 void mode_command(int newmode)
 {
-  if(newmode == 16){
-    dbg_mask = 0xffff;
-    dbg_mode = 16;
-    return;
-  }
-  if(newmode == 32){ 
-    dbg_mask = 0xffffffff;
-    dbg_mode = 32;
-    return;
-  }
-  fprintf(stderr,"Invalid mode (use 16 or 32)\n");
+    if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
+    else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
 }
 
-static int loaded_symbols = 0;
 
-void
-wine_debug(int signal, int * regs)
+void wine_debug( int signal, struct sigcontext_struct *regs )
 {
-	static int dummy_regs[32];
-	char SymbolTableFile[256];
+    static int loaded_symbols = 0;
+    char SymbolTableFile[256];
+    int instr_len = 0, newmode;
 #ifdef YYDEBUG
-	yydebug = 0;
+    yydebug = 1;
 #endif
 
-	yyin = stdin;
-	regval = regs ? regs : dummy_regs;
+    yyin = stdin;
+    context = (struct sigcontext_struct *)regs;
 
-	if (SC_CS == WINE_CODE_SELECTOR) dbg_mode = 32;
-        else dbg_mode = (GET_SEL_FLAGS(SC_CS) & LDT_FLAGS_32BIT) ? 32 : 16;
-        dbg_mask = (dbg_mode == 32) ? 0xffffffff : 0xffff;
+    if (CS == WINE_CODE_SELECTOR) newmode = 32;
+    else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16;
 
-	fprintf(stderr,"In %d bit mode.\n", dbg_mode);
+    if (newmode != dbg_mode)
+        fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
 
-	if(dbg_mode == 32 && !loaded_symbols)
-        {
-		loaded_symbols++;
-		GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
-			SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
-		read_symboltable(SymbolTableFile);
-	}
+    if(dbg_mode == 32 && !loaded_symbols)
+    {
+        loaded_symbols++;
+        GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
+                          SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
+        read_symboltable(SymbolTableFile);
+    }
 
-	/* Remove the breakpoints from memory... */
-	insert_break(0);
+    DEBUG_SetBreakpoints( FALSE );
 
-	/* If we stopped on a breakpoint, report this fact */
-	if(signal == SIGTRAP)
-	  {
-	    unsigned int addr;
-	    int bpnum;
-	    addr = SC_EIP(dbg_mask);
-	    if (dbg_mode == 16) addr = PTR_SEG_OFF_TO_LIN( SC_CS, addr );
-	    if(should_continue(bpnum=get_bpnum(addr))){
-		insert_break(1);
-		return;
-	    }
-	    fprintf(stderr,"Stopped on breakpoint %d\n", bpnum);
-	  }
+    if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
+    {
+        unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
 
-	/* Show where we crashed */
-	if(regs)
-	  examine_memory(0xffffffff, SC_EIP(dbg_mask), 1, 'i');
+        /* Show where we crashed */
+        print_address( segment, EIP, dbg_mode );
+        fprintf(stderr,":  ");
+        instr_len = db_disasm( segment, EIP ) - EIP;
+        fprintf(stderr,"\n");
+        
+        issue_prompt();
+        yyparse();
+        flush_symbols();
+    }
 
-	issue_prompt();
-
-	yyparse();
-	flush_symbols();
-
-	/* Re-insert the breakpoints from memory... */
-	insert_break(1);
-
-	fprintf(stderr,"Returning to Wine...\n");
-
+    DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
 }
 
 
diff --git a/debugger/debug.l b/debugger/debug.l
index 68975b7..4b8ccf1 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -7,9 +7,10 @@
 
 %{
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include "dbg.tab.h"
-#include "regpos.h"
+#include "debugger.h"
 
 #ifdef USE_READLINE
 #undef YY_INPUT
@@ -19,102 +20,89 @@
 #endif
 
 extern char * readline(char *);
+extern void add_history(char *);
+static int dbg_read(char * buf, int size);
 static char * make_symbol(char *);
 void flush_symbols();
 static int syntax_error;
 extern int yylval;
 %}
 
-DIGIT	[0-9]
-HEXDIGIT [0-9a-fA-F]
-
+DIGIT	   [0-9]
+HEXDIGIT   [0-9a-fA-F]
+FORMAT     [bcdiswx]
 IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
 
 %%
 
-\n		{ syntax_error = 0; return '\n'; } /* Indicate end of command */
+\n		{ syntax_error = 0; return '\n'; } /*Indicate end of command*/
 
-"+"		{ return '+'; } 
+[-+=()*]        { return *yytext; }
 
-"-"		{ return '-'; } 
+"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval); return NUM; }
+{DIGIT}+             { sscanf(yytext, "%d", &yylval); return NUM; }
 
-"/"		{ return '/'; } 
+"/"{DIGIT}+{FORMAT}  { char *last; yylval = strtol( yytext+1, &last, NULL );
+                       yylval = (yylval << 8) | *last; return FORMAT; }
+"/"{FORMAT}          { yylval = (1 << 8) | yytext[1]; return FORMAT; }
 
-"="		{ return '='; } 
+$pc     { yylval = REG_EIP; return REG; }
+$flags  { yylval = REG_EFL; return REG; }
+$eip    { yylval = REG_EIP; return REG; }
+$ip     { yylval = REG_IP;  return REG; }
+$esp    { yylval = REG_ESP; return REG; }
+$sp     { yylval = REG_SP;  return REG; }
+$eax    { yylval = REG_EAX; return REG; }
+$ebx    { yylval = REG_EBX; return REG; }
+$ecx    { yylval = REG_ECX; return REG; }
+$edx    { yylval = REG_EDX; return REG; }
+$esi    { yylval = REG_ESI; return REG; }
+$edi    { yylval = REG_EDI; return REG; }
+$ebp    { yylval = REG_EBP; return REG; }
+$ax     { yylval = REG_AX;  return REG; }
+$bx     { yylval = REG_BX;  return REG; }
+$cx     { yylval = REG_CX;  return REG; }
+$dx     { yylval = REG_DX;  return REG; }
+$si     { yylval = REG_SI;  return REG; }
+$di     { yylval = REG_DI;  return REG; }
+$bp     { yylval = REG_BP;  return REG; }
+$es     { yylval = REG_ES;  return REG; }
+$ds     { yylval = REG_DS;  return REG; }
+$cs     { yylval = REG_CS;  return REG; }
+$ss     { yylval = REG_SS;  return REG; }
 
-"("		{ return '('; } 
-
-")"		{ return ')'; } 
-
-"*"		{ return '*'; } 
-
-"?"		{ return HELP; }
-
-"0x"+{HEXDIGIT}+   {
-		sscanf(yytext, "%x", &yylval);
-		return NUM;
-		}
-
-{DIGIT}+   {
-		sscanf(yytext, "%d", &yylval);
-		return NUM;
-		}
-
-$pc		{ yylval = RN_EIP; return REG;}
-$sp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
-$eip		{ yylval = RN_EIP; return REG;}
-$esp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
-$ebp		{ yylval = RN_EBP; return REG;}
-$eax		{ yylval = RN_EAX; return REG;}
-$ebx		{ yylval = RN_EBX; return REG;}
-$ecx		{ yylval = RN_ECX; return REG;}
-$edx		{ yylval = RN_EDX; return REG;}
-$esi		{ yylval = RN_ESI; return REG;}
-$edi		{ yylval = RN_EDI; return REG;}
-
-$es		{ yylval = RN_ES;  return REG;}
-$ds		{ yylval = RN_DS;  return REG;}
-$cs		{ yylval = RN_CS;  return REG;}
-$ss		{ yylval = RN_SS;  return REG;}
-
-info|inf|in		{ return INFO; }
-segments|segm           { return SEGMENTS; }
-break|brea|bre          { return BREAK; }
-enable|enabl|enab|ena   { return ENABLE;}
+info|inf|in		      { return INFO; }
+segments|segm                 { return SEGMENTS; }
+break|brea|bre|br|b           { return BREAK; }
+enable|enabl|enab|ena         { return ENABLE;}
 disable|disabl|disab|disa|dis { return DISABLE; }
-
-quit|qui|qu 	{ return QUIT; }
+delete|delet|dele|del         { return DELETE; }
+quit|qui|qu|q                 { return QUIT; }
+x                             { return EXAM; }
 
 help|hel|he	{ return HELP; }
+"?"		{ return HELP; }
 
 set|se		{ return SET; }
 
 bt		{ return BACKTRACE; }
 
-cont|con|co		{ return CONT; }
+cont|con|co|c   { return CONT; }
+step|ste|st|s   { return STEP; }
+next|nex|ne|n   { return NEXT; }
 
 symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
 
 define|defin|defi|def|de        { return DEFINE; }
 abort|abor|abo         	        { return ABORT; }
-print|prin|pri|pr		{ return PRINT; }
+print|prin|pri|pr|p		{ return PRINT; }
 
 mode				{ return MODE; }
 
-regs|reg|re	{ return REGS; }
+registers|regs|reg|re	{ return REGS; }
 
 stack|stac|sta|st     	{ return STACK; }
 
-p  		{ return 'p'; }
-x  		{ return 'x'; }
-d		{ return 'd'; }
-i		{ return 'i'; }
-w		{ return 'w'; }
-b		{ return 'b'; }
-s		{ return 's'; }
-c		{ return 'c'; }
-q		{ return 'q'; }
-
 {IDENTIFIER}	{yylval = (int) make_symbol(yytext); 
 	          return IDENTIFIER;
 	         }
@@ -161,35 +149,45 @@
   string[++i] = '\0';
 }
 
-dbg_read(char * buf, int size){
-	char * line;
-	int len;
+static int dbg_read(char * buf, int size)
+{
+    static char last_line[256] = "";
+    char * line;
+    int len;
+    
+    for (;;)
+    {
+        flush_symbols();
+        line = readline ("Wine-dbg>");
+        if (!line) exit(0);
 
-	do{
-		flush_symbols();
-		line = readline ("Wine-dbg>");
-                if (!line) return 0;
-		len = strlen(line);
+        /* Remove leading and trailing whitespace from the line.
+           Then, if there is anything left, add it to the history list
+           and execute it. */
+        stripwhite (line);
 
-                /* Remove leading and trailing whitespace from the line.
-                   Then, if there is anything left, add it to the history list
-                   and execute it. */
-                stripwhite (line);
-			
-                if (*line)
-                {
-                    add_history (line);
-                    if(size < len + 1){
-                        fprintf(stderr,"Fatal readline goof.\n");
-                        exit(0);
-                    }
-                    strcpy(buf, line);
-                    buf[len] = '\n';
-                    buf[len+1] = 0;
-                    free(line);
-                    return len + 1;
-                }
-	} while (1==1);
+        if (*line)
+        {
+            add_history( line );
+            strncpy( last_line, line, 255 );
+            last_line[255] = '\0'; 
+       }
+        else line = last_line;  /* Repeat previous command */
+
+        if ((len = strlen(line)) > 0)
+        {
+            if (size < len + 1)
+            {
+                fprintf(stderr,"Fatal readline goof.\n");
+                exit(0);
+            }
+            strcpy(buf, line);
+            buf[len] = '\n';
+            buf[len+1] = 0;
+            free(line);
+            return len + 1;
+        }
+    }
 }
 
 static char *local_symbols[10];
diff --git a/debugger/dtest.c b/debugger/dtest.c
deleted file mode 100644
index 3872cbf..0000000
--- a/debugger/dtest.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <signal.h>
-#include <stdio.h>
-
-extern void wine_debug(unsigned int*);
-
-
-#ifdef linux
-#include <linux/sched.h>
-#include <asm/system.h>
-#endif
-
-struct sigaction segv_act;
-
-#ifdef linux
-
-struct sigcontext_struct {
-	unsigned short sc_gs, __gsh;
-	unsigned short sc_fs, __fsh;
-	unsigned short sc_es, __esh;
-	unsigned short sc_ds, __dsh;
-	unsigned long sc_edi;
-	unsigned long sc_esi;
-	unsigned long sc_ebp;
-	unsigned long sc_esp;
-	unsigned long sc_ebx;
-	unsigned long sc_edx;
-	unsigned long sc_ecx;
-	unsigned long sc_eax;
-	unsigned long sc_trapno;
-	unsigned long sc_err;
-	unsigned long sc_eip;
-	unsigned short sc_cs, __csh;
-	unsigned long sc_eflags;
-	unsigned long esp_at_signal;
-	unsigned short sc_ss, __ssh;
-	unsigned long i387;
-	unsigned long oldmask;
-	unsigned long cr2;
-};
-#endif
-
-#ifdef linux
-static void win_fault(int signal, struct sigcontext_struct context){
-        struct sigcontext_struct *scp = &context;
-#else
-static void win_fault(int signal, int code, struct sigcontext *scp){
-#endif
-
-	wine_debug((unsigned int *) scp);  /* Enter our debugger */
-}
-
-char realtext[] = "This is what should really be printed\n";
-
-int 
-main(){
-	char * pnt;
-#ifdef linux
-	segv_act.sa_handler = (__sighandler_t) win_fault;
-	sigaction(SIGSEGV, &segv_act, NULL);
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-        sigset_t sig_mask;
-        
-        sigemptyset(&sig_mask);
-        segv_act.sa_handler = (__sighandler_t) win_fault;
-	segv_act.sa_flags = 0;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
-                perror("sigaction");
-                exit(1);
-        }
-#endif
-
-	fprintf(stderr,"%x\n", realtext);
-
-	/* Now force a segmentation fault */
-	pnt = (char *) 0xc0000000;
-
-	fprintf(stderr,"%s", pnt);
-	return 0;
-
-}
-
-
-unsigned int * wine_files = NULL;
-
-GetEntryPointFromOrdinal(int wpnt, int ordinal) {}
diff --git a/debugger/hash.c b/debugger/hash.c
index 5136c1c..bca6553 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -155,10 +155,6 @@
 }
 
 
-/* Load the entry points from the dynamic linking into the hash tables. 
- * This does not work yet - something needs to be added before it scans the
- * tables correctly 
- */
 
 void load_entrypoints( HMODULE hModule )
 {
diff --git a/debugger/info.c b/debugger/info.c
index 3f99349..65f8bbd 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -6,16 +6,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "ldt.h"
-#include "db_disasm.h"
-#include "regpos.h"
+#include "debugger.h"
 
 extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
 
-extern int * regval;
-extern unsigned int dbg_mask;
-extern unsigned int dbg_mode;
-
 void application_not_running()
 {
   fprintf(stderr,"Application not running\n");
@@ -32,54 +26,6 @@
 }
 
 
-void info_reg(){
-
-	  if(!regval) {
-	    application_not_running();
-	    return;
-	  }
-
-	fprintf(stderr,"Register dump:\n");
-	/* First get the segment registers out of the way */
-	fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n", 
-		SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
-
-	/* Now dump the main registers */
-	fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n", 
-		SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
-
-	/* And dump the regular registers */
-
-	fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n", 
-		SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
-
-	/* Finally dump these main registers */
-	fprintf(stderr," EDI:%8.8x ESI:%8.8x\n", 
-		SC_EDI(dbg_mask), SC_ESI(dbg_mask));
-
-}
-
-void info_stack(){
-	unsigned int * dump;
-	int i;
-
-	if(!regval) {
-	  application_not_running();
-	  return;
-	}
-
-	fprintf(stderr,"Stack dump:\n");
-	dump = (int*) SC_ESP(dbg_mask);
-	for(i=0; i<22; i++) 
-	{
-	    fprintf(stderr," %8.8x", *dump++);
-	    if ((i % 8) == 7)
-		fprintf(stderr,"\n");
-	}
-	fprintf(stderr,"\n");
-}
-
-
 void examine_memory( unsigned int segment, unsigned int addr,
                      int count, char format )
 {
@@ -88,9 +34,10 @@
     unsigned short int * wdump;
     int i;
 
-    if (segment == 0xffffffff)
-        segment = (dbg_mode == 32) ? 0 : (format == 'i' ? SC_CS : SC_DS);
-    
+    if (segment == 0xffffffff) segment = (format == 'i' ? CS : DS);
+    if ((segment == WINE_CODE_SELECTOR) || (segment == WINE_DATA_SELECTOR))
+        segment = 0;
+
     if (format != 'i' && count > 1)
     {
         print_address( segment, addr, dbg_mode );
@@ -114,7 +61,7 @@
 		for(i=0; i<count; i++) {
 			print_address( segment, addr, dbg_mode );
 			fprintf(stderr,":  ");
-			addr = db_disasm( segment, addr, (dbg_mode == 16) );
+			addr = db_disasm( segment, addr );
 			fprintf(stderr,"\n");
 		};
 		return;
@@ -152,7 +99,7 @@
 		wdump = (unsigned short *)pnt;
 		for(i=0; i<count; i++) 
 		{
-			fprintf(stderr," %x", *wdump++);
+			fprintf(stderr," %04x", *wdump++);
                         addr += 2;
 			if ((i % 10) == 7) {
 				fprintf(stderr,"\n");
@@ -205,14 +152,15 @@
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.  The commands currently",
 "are:\n",
-"  break *<addr>                        bt",
+"  break [*<addr>]                      delete break bpnum",
 "  disable bpnum                        enable bpnum",
 "  help                                 quit",
 "  x <expr>                             cont",
+"  step                                 next",
 "  mode [16,32]                         print <expr>",
 "  set <reg> = <expr>                   set *<expr> = <expr>",
-"  info [reg,stack,break,segments]      symbolfile <filename>",
-"  define <identifier> <expr>",
+"  info [reg,stack,break,segments]      bt",
+"  symbolfile <filename>                define <identifier> <expr>",
 "",
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
 "same way that gdb does.",
@@ -230,57 +178,3 @@
 	i = 0;
 	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
 }
-
-
-struct frame{
-  union{
-    struct {
-      unsigned short saved_bp;
-      unsigned short saved_ip;
-      unsigned short saved_cs;
-    } win16;
-    struct {
-      unsigned long saved_bp;
-      unsigned long saved_ip;
-      unsigned short saved_cs;
-    } win32;
-  } u;
-};
-
-
-void dbg_bt(){
-  struct frame * frame;
-  unsigned short cs;
-  int frameno = 0;
-
-  if(!regval) {
-    application_not_running();
-    return;
-  }
-
-  if (dbg_mode == 16)
-      frame = (struct frame *)PTR_SEG_OFF_TO_LIN( SC_SS, SC_BP & ~1 );
-  else
-      frame = (struct frame *)SC_EBP(dbg_mask);
-
-  fprintf(stderr,"Backtrace:\n");
-  cs = SC_CS;
-  while((cs & 3) == 3) {
-    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
-    if ((cs & 7) != 7) {
-      fprintf(stderr,"%d ",frameno++);
-      print_address( 0, frame->u.win32.saved_ip, 32 );
-      fprintf( stderr, "\n" );
-      if (!frame->u.win32.saved_ip) break;
-      frame = (struct frame *) frame->u.win32.saved_bp;
-    } else {
-      if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
-      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
-	      frame->u.win16.saved_ip);
-      if (!frame->u.win16.saved_bp) break;
-      frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
-    }
-  }
-  putchar('\n');
-}
-
diff --git a/debugger/registers.c b/debugger/registers.c
new file mode 100644
index 0000000..4d948e9
--- /dev/null
+++ b/debugger/registers.c
@@ -0,0 +1,119 @@
+/*
+ * Debugger register handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "debugger.h"
+
+
+struct sigcontext_struct *context;
+
+
+
+/***********************************************************************
+ *           DEBUG_SetRegister
+ *
+ * Set a register value.
+ */
+void DEBUG_SetRegister( enum debug_regs reg, int val )
+{
+    switch(reg)
+    {
+        case REG_EAX: EAX = val; break;
+        case REG_EBX: EBX = val; break;
+        case REG_ECX: ECX = val; break;
+        case REG_EDX: EDX = val; break;
+        case REG_ESI: ESI = val; break;
+        case REG_EDI: EDI = val; break;
+        case REG_EBP: EBP = val; break;
+        case REG_EFL: EFL = val; break;
+        case REG_EIP: EIP = val; break;
+        case REG_ESP: ESP = val; break;
+        case REG_AX:  AX  = val; break;
+        case REG_BX:  BX  = val; break;
+        case REG_CX:  CX  = val; break;
+        case REG_DX:  DX  = val; break;
+        case REG_SI:  SI  = val; break;
+        case REG_DI:  DI  = val; break;
+        case REG_BP:  BP  = val; break;
+        case REG_FL:  FL  = val; break;
+        case REG_IP:  IP  = val; break;
+        case REG_SP:  SP  = val; break;
+        case REG_CS:  CS  = val; break;
+        case REG_DS:  DS  = val; break;
+        case REG_ES:  ES  = val; break;
+        case REG_SS:  SS  = val; break;
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_GetRegister
+ *
+ * Get a register value.
+ */
+int DEBUG_GetRegister( enum debug_regs reg )
+{
+    switch(reg)
+    {
+        case REG_EAX: return EAX;
+        case REG_EBX: return EBX;
+        case REG_ECX: return ECX;
+        case REG_EDX: return EDX;
+        case REG_ESI: return ESI;
+        case REG_EDI: return EDI;
+        case REG_EBP: return EBP;
+        case REG_EFL: return EFL;
+        case REG_EIP: return EIP;
+        case REG_ESP: return ESP;
+        case REG_AX:  return AX;
+        case REG_BX:  return BX;
+        case REG_CX:  return CX;
+        case REG_DX:  return DX;
+        case REG_SI:  return SI;
+        case REG_DI:  return DI;
+        case REG_BP:  return BP;
+        case REG_FL:  return FL;
+        case REG_IP:  return IP;
+        case REG_SP:  return SP;
+        case REG_CS:  return CS;
+        case REG_DS:  return DS;
+        case REG_ES:  return ES;
+        case REG_SS:  return SS;
+    }
+    return 0;  /* should not happen */
+}
+
+
+
+/***********************************************************************
+ *           DEBUG_InfoRegisters
+ *
+ * Display registers information. 
+ */
+void DEBUG_InfoRegisters(void)
+{
+    fprintf(stderr,"Register dump:\n");
+
+    /* First get the segment registers out of the way */
+    fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n", CS, SS, DS, ES );
+
+    if (dbg_mode == 16)
+    {
+        fprintf( stderr," IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
+                 IP, SP, BP, FL );
+	fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
+                 AX, BX, CX, DX, SI, DI );
+    }
+    else  /* 32-bit mode */
+    {
+        fprintf( stderr, " EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n", 
+                 EIP, ESP, EBP, EFL );
+	fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
+		 EAX, EBX, ECX, EDX);
+	fprintf( stderr, " ESI:%08lx EDI:%08lx\n", ESI, EDI);
+    }
+}
+
diff --git a/debugger/regpos.h b/debugger/regpos.h
deleted file mode 100644
index e4068e1..0000000
--- a/debugger/regpos.h
+++ /dev/null
@@ -1,106 +0,0 @@
-
-#ifdef linux
-/* Register numbers */
-#define  RN_GS			0
-#define  RN_FS			1
-#define  RN_ES			2
-#define  RN_DS			3
-#define  RN_EDI  		4
-#define  RN_ESI			5
-#define  RN_EBP			6
-#define  RN_ESP			7
-#define  RN_EBX			8
-#define  RN_EDX			9
-#define  RN_ECX			10
-#define  RN_EAX			11
-#define  RN_TRAPNO		12
-#define  RN_ERR			13
-#define  RN_EIP			14
-#define  RN_CS			15
-#define  RN_EFLAGS		16
-#define  RN_ESP_AT_SIGNAL	17
-#define  RN_SS			18
-#define  RN_I387		19
-#define  RN_OLDMASK		20
-#define  RN_CR2			21
-#endif
-
-#ifdef __NetBSD__
-/* Register numbers */
-#define  RN_GS			0
-#define  RN_FS			1
-#define  RN_ES			2
-#define  RN_DS			3
-#define  RN_EDI  		4
-#define  RN_ESI			5
-#define  RN_EBP			6
-#define  RN_EBX			7
-#define  RN_EDX			8
-#define  RN_ECX			9
-#define  RN_EAX			10
-#define  RN_EIP			11
-#define  RN_CS			12
-#define  RN_EFLAGS		13
-#define  RN_ESP_AT_SIGNAL	14
-#define  RN_SS			15
-#define  RN_OLDMASK		17
-#endif
-
-#ifdef __FreeBSD__
-#define  RN_OLDMASK		1
-/* Register numbers */
-#define  RN_ESP			2
-#define  RN_EBP			3
-#define  RN_ESP_AT_SIGNAL	4
-#define  RN_EIP			5
-#define  RN_EFLAGS		6
-#define  RN_ES			7
-#define  RN_DS			8
-#define  RN_CS			9
-#define  RN_SS			10
-#define  RN_EDI  		11
-#define  RN_ESI			12
-#define  RN_EBX			13
-#define  RN_EDX			14
-#define  RN_ECX			15
-#define  RN_EAX			16
-/* FreeBSD doesn't save gs or fs */
-#define  SC_GS			0x27
-#define  SC_FS			0x27
-#endif
-
-#ifdef linux
-#define  SC_GS			regval[RN_GS]
-#define  SC_FS			regval[RN_FS]
-#define  I387			regval[RN_I387]
-#define  CR2			regval[RN_CR2]
-#endif
-#ifdef __NetBSD__
-#define  SC_GS			regval[RN_GS]
-#define  SC_FS			regval[RN_FS]
-#endif
-#define  SC_ES			regval[RN_ES]
-#define  SC_DS			regval[RN_DS]
-#define  SC_EDI(dbg_mask)  	(regval[RN_EDI] & dbg_mask)
-#define  SC_ESI(dbg_mask)	(regval[RN_ESI] & dbg_mask)
-#define  SC_EBP(dbg_mask)	(regval[RN_EBP] & dbg_mask)
-#define  SC_EBX(dbg_mask)	(regval[RN_EBX] & dbg_mask)
-#define  SC_EDX(dbg_mask)	(regval[RN_EDX] & dbg_mask)
-#define  SC_ECX(dbg_mask)	(regval[RN_ECX] & dbg_mask)
-#define  SC_EAX(dbg_mask)	(regval[RN_EAX] & dbg_mask)
-#define  SC_DI                  (regval[RN_EDI] & 0xffff)
-#define  SC_SI                  (regval[RN_ESI] & 0xffff)
-#define  SC_BP                  (regval[RN_EBP] & 0xffff)
-#define  SC_SP                  (regval[RN_ESP] & 0xffff)
-#define  SC_BX                  (regval[RN_EBX] & 0xffff)
-#define  SC_DX                  (regval[RN_EDX] & 0xffff)
-#define  SC_CX                  (regval[RN_ECX] & 0xffff)
-#define  SC_AX                  (regval[RN_EAX] & 0xffff)
-#define  SC_TRAPNO		regval[RN_TRAPNO]
-#define  SC_ERR			regval[RN_ERR]
-#define  SC_EIP(dbg_mask)	(regval[RN_EIP] & dbg_mask)
-#define  SC_CS			regval[RN_CS]
-#define  SC_EFLAGS		regval[RN_EFLAGS]
-#define  SC_ESP(dbg_mask)	(regval[RN_ESP_AT_SIGNAL] & dbg_mask)
-#define  SC_SS			regval[RN_SS]
-#define  OLDMASK		regval[RN_OLDMASK]
diff --git a/debugger/stack.c b/debugger/stack.c
new file mode 100644
index 0000000..16a4b62
--- /dev/null
+++ b/debugger/stack.c
@@ -0,0 +1,89 @@
+/*
+ * Debugger stack handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "windows.h"
+#include "debugger.h"
+
+
+typedef struct
+{
+    WORD bp;
+    WORD ip;
+    WORD cs;
+} FRAME16;
+
+typedef struct
+{
+    DWORD bp;
+    DWORD ip;
+    WORD cs;
+} FRAME32;
+
+
+
+/***********************************************************************
+ *           DEBUG_InfoStack
+ *
+ * Dump the top of the stack
+ */
+void DEBUG_InfoStack(void)
+{
+    fprintf(stderr,"Stack dump:\n");
+    if ((SS == WINE_DATA_SELECTOR) ||
+        (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT))  /* 32-bit mode */
+    {
+        examine_memory( 0, ESP, 10, 'x' );
+    }
+    else  /* 16-bit mode */
+    {
+        examine_memory( SS, SP, 10, 'w' );
+    }
+    fprintf(stderr,"\n");
+}
+
+
+/***********************************************************************
+ *           DEBUG_BackTrace
+ *
+ * Display a stack back-trace.
+ */
+void DEBUG_BackTrace(void)
+{
+  int frameno = 0;
+
+  fprintf(stderr,"Backtrace:\n");
+  if (SS == WINE_DATA_SELECTOR)  /* 32-bit mode */
+  {
+      FRAME32 *frame = (FRAME32 *)EBP;
+      while (frame->ip)
+      {
+          fprintf(stderr,"%d ",frameno++);
+          print_address( 0, frame->ip, 32 );
+          fprintf( stderr, "\n" );
+          frame = (FRAME32 *)frame->bp;
+      }
+  }
+  else  /* 16-bit mode */
+  {
+      FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, BP & ~1 );
+      WORD cs = CS;
+      if (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)
+      {
+          fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
+          return;
+      }
+      while (frame->bp)
+      {
+          if (frame->bp & 1) cs = frame->cs;
+          fprintf( stderr,"%d ", frameno++ );
+          print_address( cs, frame->ip, 16 );
+          fprintf( stderr, "\n" );
+          frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, frame->bp & ~1 );
+      }
+  }
+  fprintf( stderr, "\n" );
+}