diff -urN fuse-0.4.2/Makefile.in fuse-0.4.2_debugger/Makefile.in
--- fuse-0.4.2/Makefile.in	Tue Jul 23 20:17:43 2002
+++ fuse-0.4.2_debugger/Makefile.in	Tue Jul 23 20:06:09 2002
@@ -76,7 +76,7 @@
 
 SUBDIRS = lib libspectrum man myglib perl roms ui utils widget z80
 
-fuse_SOURCES = ay.c display.c event.c 	fuse.c keyboard.c keysyms.c machine.c osssound.c rzx.c settings.c 	snapshot.c sound.c spec128.c spec48.c specplus2.c specplus3.c 	spectrum.c sunsound.c tape.c timer.c uidisplay.c utils.c 	joystick.c printer.c
+fuse_SOURCES = ay.c display.c debugger.c event.c 	fuse.c keyboard.c keysyms.c machine.c osssound.c rzx.c settings.c 	snapshot.c sound.c spec128.c spec48.c specplus2.c specplus3.c 	spectrum.c sunsound.c tape.c timer.c uidisplay.c utils.c 	joystick.c printer.c
 
 
 BUILT_SOURCES = keysyms.c
@@ -85,7 +85,7 @@
 LDADD = @GLIB_LIBS@ @GTK_LIBS@ libspectrum/libspectrum.a myglib/libmyglib.a ui/aalib/libuiaalib.a ui/fb/libuifb.a ui/gtk/libuigtk.a ui/svga/libuisvga.a ui/xlib/libuixlib.a widget/libwidget.a z80/libz80.a
 
 
-noinst_HEADERS = ay.h display.h event.h 	fuse.h keyboard.h keysyms.h 	machine.h osssound.h rzx.h settings.h snapshot.h sound.h spec128.h 	spec48.h specplus2.h specplus3.h spectrum.h sunsound.h 	tape.h timer.h types.h utils.h 	joystick.h printer.h
+noinst_HEADERS = ay.h display.h debugger.h event.h 	fuse.h keyboard.h keysyms.h 	machine.h osssound.h rzx.h settings.h snapshot.h sound.h spec128.h 	spec48.h specplus2.h specplus3.h spectrum.h sunsound.h 	tape.h timer.h types.h utils.h 	joystick.h printer.h
 
 
 EXTRA_DIST = AUTHORS README THANKS hacking/coding_style.txt hacking/ui.txt 	keysyms.dat keysyms.pl
@@ -105,7 +105,7 @@
 X_LIBS = @X_LIBS@
 X_EXTRA_LIBS = @X_EXTRA_LIBS@
 X_PRE_LIBS = @X_PRE_LIBS@
-fuse_OBJECTS =  ay.o display.o event.o fuse.o keyboard.o keysyms.o \
+fuse_OBJECTS =  ay.o display.o debugger.o event.o fuse.o keyboard.o keysyms.o \
 machine.o osssound.o rzx.o settings.o snapshot.o sound.o spec128.o \
 spec48.o specplus2.o specplus3.o spectrum.o sunsound.o tape.o timer.o \
 uidisplay.o utils.o joystick.o printer.o
@@ -378,6 +378,7 @@
 	printer.h sound.h
 display.o: display.c config.h display.h types.h event.h machine.h ay.h \
 	spectrum.h ui/ui.h ui/uidisplay.h
+debugger.o: debugger.c
 event.o: event.c config.h display.h types.h event.h machine.h ay.h \
 	spectrum.h rzx.h libspectrum/rzx.h libspectrum/libspectrum.h \
 	tape.h ui/ui.h
diff -urN fuse-0.4.2/debugger.c fuse-0.4.2_debugger/debugger.c
--- fuse-0.4.2/debugger.c	Thu Jan  1 01:00:00 1970
+++ fuse-0.4.2_debugger/debugger.c	Tue Jul 23 20:01:38 2002
@@ -0,0 +1,237 @@
+/* debugger.c
+
+   Copyright (c) 2002 Anders Holmberg
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+   Author contact information:
+   Mail : aagholmberg@yahoo.se
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+
+#include "config.h"
+#include "machine.h"
+#include "spectrum.h"
+#include "settings.h"
+#include "debugger.h"
+
+#include "z80/z80.h"
+#include "z80/z80_macros.h"
+
+/* ----------------------------------------------------------------------------
+ *  Defines
+ * ---------------------------------------------------------------------------- */
+#define PORT 3490 
+#define MAXDATASIZE 100 
+
+/* ----------------------------------------------------------------------------
+ *  Local variables
+ * ---------------------------------------------------------------------------- */
+static int sockfd;  
+static struct hostent *he;
+static struct sockaddr_in addr; // connector's address information 
+static struct sockaddr_in rec_addr;
+static char hostname[]="127.0.0.1";
+static debugger_mode_t debugger_mode = not_connected;
+static breakpoint_mode_t breakpoint_mode = not_active;
+static char buffer[100];   
+static char debugger_msg[400];
+static int breakpoint_addr = 0;
+
+/* ----------------------------------------------------------------------------
+ *  Local functions
+ * ---------------------------------------------------------------------------- */
+void build_debugger_msg( int user_addr )
+{
+   int i, mem_addr;
+
+   sprintf( &debugger_msg[0],  "%02x", A );
+   sprintf( &debugger_msg[2],  "%02x", F );
+   sprintf( &debugger_msg[4],  "%02x", B );
+   sprintf( &debugger_msg[6],  "%02x", C );
+   sprintf( &debugger_msg[8],  "%02x", D );
+   sprintf( &debugger_msg[10], "%02x", E );
+   sprintf( &debugger_msg[12], "%02x", H );
+   sprintf( &debugger_msg[14], "%02x", L );
+   sprintf( &debugger_msg[16], "%02x", IXH );
+   sprintf( &debugger_msg[18], "%02x", IXL );
+   sprintf( &debugger_msg[20], "%02x", IYH );
+   sprintf( &debugger_msg[22], "%02x", IYL );
+   sprintf( &debugger_msg[24], "%02x", SPH );
+   sprintf( &debugger_msg[26], "%02x", SPL );
+   sprintf( &debugger_msg[28], "%02x", PCH );
+   sprintf( &debugger_msg[30], "%02x", PCL );
+   sprintf( &debugger_msg[32], "%02x", I );
+   sprintf( &debugger_msg[34], "%02x", R );
+   sprintf( &debugger_msg[36], "%02x", IFF1 );
+   sprintf( &debugger_msg[38], "%02x", IFF2 );
+   sprintf( &debugger_msg[40], "%02x", IM );
+   sprintf( &debugger_msg[42], "%04x", tstates );
+   
+   if( user_addr < 0 )
+      mem_addr = PC;
+   else 
+      mem_addr = user_addr;
+
+   sprintf( &debugger_msg[46], "%04x", mem_addr );
+
+   for( i=0; i<16*10; i++ )
+      sprintf( &debugger_msg[50+i*2], "%02x", readbyte( mem_addr + i ) );
+}
+
+/* ----------------------------------------------------------------------------
+ *  External functions
+ * ---------------------------------------------------------------------------- */
+
+void debugger_init()
+{
+   if( !settings_current.debugger )
+      return;
+
+   sockfd = socket( AF_INET, SOCK_DGRAM, 0 );
+   if( sockfd == -1 )
+   {
+      perror( "Socket error" );
+      debugger_mode = not_connected;
+      return;  
+   }
+
+   he = gethostbyname( hostname );
+   if( he == 0 )
+   {
+      perror( "Hostname error" );
+      debugger_mode = not_connected;
+      return;
+   }
+
+   memcpy(&addr.sin_addr,he->h_addr, he->h_length );
+   addr.sin_family = AF_INET;
+   addr.sin_port = htons(3490);
+
+   rec_addr.sin_addr.s_addr = INADDR_ANY;
+   rec_addr.sin_family = AF_INET;
+   rec_addr.sin_port = htons(3491);
+
+   if( bind( sockfd, (struct sockaddr *)&rec_addr, sizeof( rec_addr ) ) < 0 )
+   {
+      perror( "Bind error" );
+      debugger_mode = not_connected;
+      return;
+   }
+
+   /* Make the socket a non-blocking socket */
+   fcntl( sockfd, F_SETFL, O_NONBLOCK );
+
+   debugger_mode = executing;
+}
+
+debugger_action_t debugger_check_socket()
+{  
+   int nr;
+   unsigned int mem_addr;
+
+   /* Is the UDP socket really configured correctly */
+   if( debugger_mode == not_connected )
+      return no_action;
+
+   /* Try to read data from socket (non-blocking) */
+   nr = read( sockfd, (void *)buffer, sizeof( buffer ) ); 
+
+   /* Did not get any data this time - better luck next time! */
+   if( nr <= 0 )
+   {
+      return no_action;
+   }
+   
+   buffer[nr] = '\0';
+
+   /* Check command */
+   if( buffer[0] == 'h' )
+   {
+      debugger_mode = halted;
+   }
+   else if( buffer[0] == 'c' )
+   {
+      debugger_mode = executing;
+   }
+   else if( buffer[0] == 'i' )
+   {
+      build_debugger_msg( -1 );
+      sendto( sockfd, (void *)debugger_msg, 370, 0, (struct sockaddr *)&addr, sizeof( addr ) );
+   }
+   else if( buffer[0] == 'm' )
+   {
+      mem_addr = (int)strtol( &buffer[1], NULL, 16 );
+      build_debugger_msg( mem_addr );
+      sendto( sockfd, (void *)debugger_msg, 370, 0, (struct sockaddr *)&addr, sizeof( addr ) );
+   }
+   else if( buffer[0] =='b' && buffer[1] =='d' )
+   {
+      breakpoint_mode = not_active;
+   }
+   else if( buffer[0] == 'b' && buffer[1]!='x' )
+   {
+      mem_addr = (int)strtol( &buffer[1], NULL, 16 );
+      breakpoint_mode = active;
+      breakpoint_addr = mem_addr;
+   }
+   else if( buffer[0] == 's' )
+   {
+      /* Make sure we are in halted mode when single stepping */
+      debugger_mode = halted;
+      return single_step;
+   }
+   else
+   {
+   }
+
+   return no_action;
+
+}
+
+void debugger_end()
+{
+   if( settings_current.debugger )
+      close(sockfd);
+}
+
+debugger_mode_t debugger_check_mode()
+{
+   return debugger_mode;
+}
+
+void debugger_check_breakpoint()
+{
+   if( breakpoint_mode == active )
+   {
+      if( breakpoint_addr == PC )
+      {
+         printf( "BREAKPOINT TRIGGERED AT 0x%04x\n", breakpoint_addr );
+         debugger_mode = halted;
+      }
+   }
+}
+
+
diff -urN fuse-0.4.2/debugger.h fuse-0.4.2_debugger/debugger.h
--- fuse-0.4.2/debugger.h	Thu Jan  1 01:00:00 1970
+++ fuse-0.4.2_debugger/debugger.h	Tue Jul 23 20:01:38 2002
@@ -0,0 +1,32 @@
+
+
+#ifndef __DEBUGGER_H__
+#define __DEBUGGER_H__
+
+/* Mode of debugging  */
+typedef enum debugger_mode_t 
+{
+  not_connected,halted, executing
+} debugger_mode_t;
+
+
+typedef enum debugger_action_t
+{
+  no_action, single_step
+} debugger_action_t;
+
+typedef enum breakpoint_mode_t 
+{
+  active, not_active
+} breakpoint_mode_t;
+
+void debugger_end();
+void debugger_init();
+void debugger_check_breakpoint();
+debugger_action_t debugger_check_socket();
+debugger_mode_t debugger_check_mode();
+
+#endif
+
+
+
diff -urN fuse-0.4.2/fuse.c fuse-0.4.2_debugger/fuse.c
--- fuse-0.4.2/fuse.c	Tue Jul 23 20:17:43 2002
+++ fuse-0.4.2_debugger/fuse.c	Tue Jul 23 20:01:38 2002
@@ -44,6 +44,7 @@
 #include "ui/ui.h"
 #include "widget/widget.h"
 #include "z80/z80.h"
+#include "debugger.h"
 
 /* What name were we called under? */
 char* fuse_progname;
@@ -143,6 +144,8 @@
     rzx_start_recording( settings_current.record_file );
   }
 
+  debugger_init();
+
   fuse_emulation_paused = 0;
 
   return 0;
@@ -253,6 +256,8 @@
 
   widget_end();
 
+  debugger_end();
+
   return 0;
 }
 
diff -urN fuse-0.4.2/settings.c fuse-0.4.2_debugger/settings.c
--- fuse-0.4.2/settings.c	Tue Jul 23 20:17:43 2002
+++ fuse-0.4.2_debugger/settings.c	Tue Jul 23 20:01:38 2002
@@ -63,6 +63,8 @@
 /* Fill the settings structure with sensible defaults */
 int settings_defaults( settings_info *settings )
 {
+  settings->debugger = 0;
+   
   settings->issue2 = 0;
   settings->joy_kempston = 0;
   settings->tape_traps = 1;
@@ -101,6 +103,9 @@
 
   struct option long_options[] = {
 
+    {      "debugger", 0, &(settings->debugger), 1 },
+    {   "no-debugger", 0, &(settings->debugger), 0 }, 
+
     {	    "machine", 1, NULL, 'm' },
 
     {      "snapshot", 1, NULL, 's' },
@@ -197,6 +202,7 @@
 /* Copy one settings object to another */
 int settings_copy( settings_info *dest, settings_info *src )
 {
+  dest->debugger     = src->debugger;
   dest->issue2       = src->issue2;
   dest->joy_kempston = src->joy_kempston;
   dest->tape_traps   = src->tape_traps;
diff -urN fuse-0.4.2/settings.h fuse-0.4.2_debugger/settings.h
--- fuse-0.4.2/settings.h	Tue Jul 23 20:17:43 2002
+++ fuse-0.4.2_debugger/settings.h	Tue Jul 23 20:01:38 2002
@@ -33,6 +33,7 @@
 
   /* General options */
 
+  int debugger;         /* Is the debugger activated? */
   int issue2;		/* Issue 2 keyboard emulation? */
   int joy_kempston;	/* Kempston joystick emulation? */
   int tape_traps;	/* Use tape loading traps? */
diff -urN fuse-0.4.2/z80/z80_ops.c fuse-0.4.2_debugger/z80/z80_ops.c
--- fuse-0.4.2/z80/z80_ops.c	Tue Jul 23 20:17:43 2002
+++ fuse-0.4.2_debugger/z80/z80_ops.c	Tue Jul 23 20:01:38 2002
@@ -1,3 +1,5 @@
+/* ex: set ts=2: */
+
 /* z80_ops.c: Process the next opcode
    Copyright (c) 1999-2000,2002 Philip Kendall
 
@@ -25,7 +27,7 @@
 */
 
 #include <config.h>
-
+#include <unistd.h>
 #include <stdio.h>
 
 #include "event.h"
@@ -37,6 +39,8 @@
 
 #include "z80_macros.h"
 
+#include "debugger.h"
+
 #ifndef HAVE_ENOUGH_MEMORY
 static void z80_cbxx(BYTE opcode2);
 static void z80_ddxx(BYTE opcode2);
@@ -49,10 +53,32 @@
 void z80_do_opcodes()
 {
 
+  /* There is a very small chance that a single step can be missed (2 single step
+     commands has to be sent with appr. 20 ms interval at the exact right moment)
+     but we do not care! */
+  if( settings_current.debugger )
+  {
+    (void)debugger_check_socket();
+  }
+
   while(tstates < event_next_event ) {
 
     BYTE opcode;
 
+    if( settings_current.debugger )
+    {
+      debugger_check_breakpoint();
+
+      while( debugger_check_mode() == halted )
+      {
+        if( debugger_check_socket() == single_step )
+        {
+          break;
+        }
+        sleep( 1 ); /* Change this to 100ms */
+      }   
+    }
+
     /* If we're due an interrupt from RZX playback, generate one */
     if( rzx_playback &&
 	rzx_instructions >= rzx.frames[ rzx_current_frame ].instructions ) {
