Release 940510

May 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [controls/scroll.c]
	Make thumbtrack button disappear if scroll box ratio < 3:1.
	Make arrow buttons rectangular if scroll box ratio < 2:1.
	Add code for SBS_TOPALIGN, SBS_BOTTOMALIGN, 
				SBS_LEFTALIGN & SBS_RIGHTALIGN.
	Bug fix in NC_CreateScrollBars(), no more bigbutt in calendar.exe... :-)

	* [loader/library.c] [loader/task.c] [misc/exec.c]
	Continue playing around trying to get a second task running.

	* [windows/mdi.c]
	Change OBM_CLOSE for OBM_OLD_CLOSE, a smaller dot button when maximized.

	* [everywhere]
	Adding previous works of the Apr 25, 94.

Tue May 10 18:09:14 1994 Erik Bos (erik@trashcan.hacktic.nl)

	* [if1632/mmsystem.spec] [misc/mmsystem.c] [include/mmsystem.h]
	Added Martin's mmsystem.dll stubs.

	* [misc/sound.c]
	Added remaining stubs for sound.dll.

	* [if1632/shell.spec] [misc/shell.c]
	Fixed prototypes (I found them in BC 4) and added ShellAbout()
	and AboutDlgProc().
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 2e481f0..5958e7d 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -1,18 +1,21 @@
 #include "../Wine.tmpl"
 
 #define IHavSubDirs
-#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)'
+#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'
 
 MODULE = debugger
 
 SUBDIRS = readline
 
+DEFINES = -DUSE_READLINE
+
 /* Quick and dirt hack, since i386 is defined as 1. sigh */
 #define temp i386
 #undef i386
 
 SRCS = \
 	dbg.tab.c \
+	break.c \
 	hash.c \
 	lex.yy.c \
 	info.c \
@@ -20,6 +23,7 @@
 
 OBJS = \
 	dbg.tab.o \
+	break.o \
 	hash.o \
 	lex.yy.o \
 	info.o \
diff --git a/debugger/dbg.y b/debugger/dbg.y
index a627962..7dea72f 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -9,6 +9,8 @@
  */
 
 #include <stdio.h>
+#include <signal.h>
+
 #define YYSTYPE int
 
 #include "regpos.h"
@@ -24,12 +26,17 @@
 %token CONT
 %token QUIT
 %token HELP
+%token BACKTRACE
 %token INFO
 %token STACK
 %token REG
 %token REGS
 %token NUM
+%token ENABLE
+%token DISABLE
+%token BREAK
 %token SET
+%token MODE
 %token PRINT
 %token IDENTIFIER
 %token NO_SYMBOL
@@ -49,12 +56,17 @@
 	| CONT '\n'        { return; };
 	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); };
 	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, $3); };
+	| MODE NUM	   { mode_command($2); };
+	| ENABLE NUM	   { enable_break($2); };
+	| DISABLE NUM	   { disable_break($2); };
+	| BREAK '*' expr   { add_break($3); };
 	| x_command
+	| BACKTRACE '\n'   { dbg_bt(); };
 	| print_command
 	| deposit_command
 
 deposit_command:
-	SET REG '=' expr '\n' { regval[$2] = $4; }
+	SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
 	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
 	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
 
@@ -83,7 +95,7 @@
 			        }; 
 
  expr:  NUM			{ $$ = $1;	}
-	| REG			{ $$ = regval[$1]; }
+	| REG			{ if(regval) $$ = regval[$1]; else application_not_running();}
 	| symbol   		{ $$ = *((unsigned int *) $1); }
 	| expr '+' NUM		{ $$ = $1 + $3; }
 	| expr '-' NUM		{ $$ = $1 - $3; };
@@ -92,6 +104,7 @@
 	
  infocmd: INFO REGS { info_reg(); }
 	| INFO STACK  { info_stack(); };
+	| INFO BREAK  { info_break(); };
 
 
 %%
@@ -103,10 +116,25 @@
 #endif
 }
 
+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");
+}
+
 static int loaded_symbols = 0;
 
 void
-wine_debug(int * regs)
+wine_debug(int signal, int * regs)
 {
 	int i;
 #ifdef YYDEBUG
@@ -143,13 +171,31 @@
 	};
 #endif
 
+	/* Remove the breakpoints from memory... */
+	insert_break(0);
+
+	/* If we stopped on a breakpoint, report this fact */
+	if(signal == SIGTRAP)
+	  {
+	    unsigned int addr;
+	    addr = SC_EIP(dbg_mask);
+	    if((addr & 0xffff0000) == 0 && dbg_mode == 16)
+	      addr |= SC_CS << 16;
+	    fprintf(stderr,"Stopped on breakpoint %d\n", get_bpnum(addr));
+	  }
+
 	/* Show where we crashed */
-	examine_memory(SC_EIP(dbg_mask), 1, 'i');
+	if(regval)
+	  examine_memory(SC_EIP(dbg_mask), 1, 'i');
 
 	issue_prompt();
 
 	yyparse();
 	flush_symbols();
+
+	/* Re-insert the breakpoints from memory... */
+	insert_break(1);
+
 	fprintf(stderr,"Returning to Wine...\n");
 
 }
diff --git a/debugger/debug.l b/debugger/debug.l
index 005c556..90effe0 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -58,7 +58,7 @@
 		}
 
 {DIGIT}+   {
-		sscanf(yytext, "%lx", &yylval);
+		sscanf(yytext, "%ld", &yylval);
 		return NUM;
 		}
 
@@ -74,14 +74,25 @@
 $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; }
 
+break|brea|bre          { return BREAK; }
+enable|enabl|enab|ena   { return ENABLE;}
+disable|disabl|disab|disa|dis { return DISABLE; }
+
 quit|qui|qu 	{ return QUIT; }
 
 help|hel|he	{ return HELP; }
 
 set|se		{ return SET; }
 
+bt		{ return BACKTRACE; }
+
 cont|con|co		{ return CONT; }
 
 symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
@@ -89,6 +100,8 @@
 define|defin|defi|def|de        { return DEFINE; }
 print|prin|pri|pr		{ return PRINT; }
 
+mode				{ return MODE; }
+
 regs|reg|re	{ return REGS; }
 
 stack|stac|sta|st     	{ return STACK; }
diff --git a/debugger/info.c b/debugger/info.c
index 87aec59..0a98d89 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -16,6 +16,11 @@
 /* THese three helper functions eliminate the need for patching the
 module from gdb for disassembly of code */
 
+void application_not_running()
+{
+  fprintf(stderr,"Application not running\n");
+}
+
 void read_memory(char * memaddr, char * buffer, int len){
 	memcpy(buffer, memaddr, len);
 }
@@ -36,6 +41,12 @@
 
 
 void info_reg(){
+
+	  if(!regval) {
+	    application_not_running();
+	    return 0;
+	  }
+
 	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", 
@@ -60,6 +71,10 @@
 	unsigned int * dump;
 	int i;
 
+	if(!regval) {
+	  application_not_running();
+	  return 0;
+	}
 
 	fprintf(stderr,"Stack dump:\n");
 	dump = (int*) SC_EIP(dbg_mask);
@@ -192,11 +207,15 @@
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.  The commands currently",
 "are:\n",
-"  info reg",
-"  info stack",
+"  info [reg,stack,break]",
+"  break <addr>",
+"  enable bpnum",
+"  disable bpnum",
 "  help",
 "  quit",
 "  print <expr>",
+"  bt",
+"  mode [16,32]",
 "  symbolfile <filename>",
 "  define <identifier> <expr>",
 "  x <expr>",
@@ -228,3 +247,52 @@
 	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 0;
+  }
+
+  fprintf(stderr,"Backtrace:\n");
+  fprintf(stderr,"%d: %4.4x:%4.4x\n", frameno++, SC_CS, SC_EIP(dbg_mask));
+  cs = SC_CS;
+
+  frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
+  while((cs & 3) == 3) {
+    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
+    if ((cs & 7) != 7) {
+      cs = frame->u.win32.saved_cs;
+      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
+	      frame->u.win32.saved_ip);
+      frame = (struct frame *) frame->u.win32.saved_bp;
+    } else {
+      cs = frame->u.win16.saved_cs;
+      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
+	      frame->u.win16.saved_ip);
+      frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
+				(SC_SS << 16));
+    }
+  }
+}
+