diff --git a/ChangeLog b/ChangeLog
index 3a467f7a..2edfbef3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-11-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+	Implement debugWire programming support.
+	* avrpart.h: Implement debugWire support.
+	* config_gram.y: (Ditto.)
+	* jtagmkII.c: (Ditto.)
+	* jtagmkII.h: (Ditto.)
+	* lexer.l: (Ditto.)
+	* avrdude.conf.in: Add the new dW programmers.
+	* avrdude.1: Document the dW support.
+	* doc/avrdude.texi: (Ditto.)
+
 2006-11-20 Joerg Wunsch <j@uriah.heep.sax.de>
 
 	* jtagmkI.c (jtagmkI_close): remove two unused variables.
diff --git a/avrdude.1 b/avrdude.1
index 5907e42b..f5f8de26 100644
--- a/avrdude.1
+++ b/avrdude.1
@@ -112,10 +112,11 @@ supported on a serial port.
 .Pp
 Atmel's JTAG ICE (both mkI and mkII) is supported as well to up- or download memory
 areas from/to an AVR target (no support for on-chip debugging).
-For the JTAG ICE mkII, both JTAG and ISP mode are supported.
+For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
+See below for the limitations of debugWire.
 .Pp
-The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP).
-When used in JTAG mode, the AVR Dragon behaves similar to a
+The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
+When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
 JTAG ICE mkII, so all device-specific comments for that device
 will apply as well.
 When used in ISP mode, the AVR Dragon behaves similar to an
@@ -710,6 +711,33 @@ ll.
 10	MISO (from MCU)
 18-25	GND
 .TE
+.Ss debugWire limitations
+The debugWire protocol is Atmel's proprietary one-wire (plus ground)
+protocol to allow an in-circuit emulation of the smaller AVR devices,
+using the
+.Ql /RESET
+line.
+DebugWire mode is initiated by activating the
+.Ql DWEN
+fuse, and then power-cycling the target.
+While this mode is mainly intented for debugging/emulation, it
+also offers limited programming capabilities.
+Effectively, the only memory area that can be read or programmed
+in this mode is the flash ROM.
+It is also possible to read out the signature.
+All other memory areas cannot be accessed.
+There is no
+.Em chip erase
+functionality in debugWire mode; instead, while reprogramming the
+flash ROM, each flash ROM page is erased right before updating it.
+This is done transparently by the JTAG ICE mkII (or AVR Dragon).
+The only way back from debugWire mode is to initiate a special
+sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
+debugWire mode will be temporarily disabled, and the target can
+be accessed using normal ISP programming.
+This sequence is automatically initiated by using the JTAG ICE mkII
+or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
+entered.
 .Sh FILES
 .Bl -tag -offset indent -width /dev/ppi0XXX
 .It Pa /dev/ppi0
diff --git a/avrdude.conf.in b/avrdude.conf.in
index 365b6367..762a8679 100644
--- a/avrdude.conf.in
+++ b/avrdude.conf.in
@@ -17,8 +17,8 @@
 #       desc     = <description> ;                  # quoted string
 #       type     = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
 #                  avr910 | butterfly | usbasp |
-#                  jtagmki | jtagmkii | jtagmkii_isp |
-#                  dragon_jtag | dragon_isp | dragon_pp |
+#                  jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
+#                  dragon_dw | dragon_jtag | dragon_isp | dragon_pp |
 #                  dragon_hvsp; # programmer type
 #       baudrate = <num> ;                          # baudrate for avr910-programmer
 #       vcc      = <num1> [, <num2> ... ] ;         # pin number(s)
@@ -36,6 +36,7 @@
 #       id               = <id> ;                 # quoted string
 #       desc             = <description> ;        # quoted string
 #       has_jtag         = <yes/no> ;             # part has JTAG i/f
+#       has_debugwire    = <yes/no> ;             # part has debugWire i/f
 #       devicecode       = <num> ;            # deprecated, use stk500_devcode
 #       stk500_devcode   = <num> ;                # numeric
 #       avr910_devcode   = <num> ;                # numeric
@@ -443,6 +444,14 @@ programmer
   type  = jtagmkii_isp;
 ;
 
+# JTAG ICE mkII in debugWire mode
+programmer
+  id    = "jtag2dw";
+  desc  = "Atmel JTAG ICE mkII in debugWire mode";
+  baudrate = 115200;
+  type  = jtagmkii_dw;
+;
+
 # AVR Dragon in JTAG mode
 programmer
   id    = "dragon_jtag";
@@ -475,6 +484,14 @@ programmer
   type  = dragon_hvsp;
 ;
 
+# AVR Dragon in debugWire mode
+programmer
+  id    = "dragon_dw";
+  desc  = "Atmel AVR Dragon in debugWire mode";
+  baudrate = 115200;
+  type  = dragon_dw;
+;
+
 programmer
   id    = "pavr";
   desc  = "Jason Kyle's pAVR Serial Programmer";
@@ -9182,6 +9199,7 @@ part
 part
      id            = "t44";
      desc          = "ATtiny44";
+     has_debugwire = yes;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
@@ -9228,6 +9246,8 @@ part
     programfusepolltimeout = 25;
     programlockpolltimeout = 25;
 
+    flash_instr         = 0xb4, 0x07, 0x17;
+
      memory "eeprom"
          size            = 256;
         paged           = no;
diff --git a/avrpart.h b/avrpart.h
index 0b90faae..2e5bc48d 100644
--- a/avrpart.h
+++ b/avrpart.h
@@ -89,10 +89,12 @@ typedef struct opcode {
 #define AVRPART_HAS_JTAG       0x0008  /* part has a JTAG i/f */
 #define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
 #define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
+#define AVRPART_HAS_DW         0x0040  /* part has a debugWire i/f */
 
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
 #define CTL_STACK_SIZE 32
+#define FLASH_INSTR_SIZE 3
 typedef struct avrpart {
   char          desc[AVR_DESCLEN];  /* long part name */
   char          id[AVR_IDLEN];      /* short part name */
@@ -120,6 +122,7 @@ typedef struct avrpart {
 
   enum ctl_stack_t ctl_stack_type;  /* what to use the ctl stack for */
   unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
+  unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */
 
   int           hventerstabdelay;   /* stk500 v2 hv mode parameter */
   int           progmodedelay;      /* stk500 v2 hv mode parameter */
diff --git a/config_gram.y b/config_gram.y
index ad8978d7..185e4725 100644
--- a/config_gram.y
+++ b/config_gram.y
@@ -88,6 +88,7 @@ static int parse_cmdbits(OPCODE * op);
 %token K_DEFAULT_SERIAL
 %token K_DESC
 %token K_DEVICECODE
+%token K_DRAGON_DW
 %token K_DRAGON_HVSP
 %token K_DRAGON_ISP
 %token K_DRAGON_JTAG
@@ -101,6 +102,7 @@ static int parse_cmdbits(OPCODE * op);
 %token K_IO
 %token K_JTAG_MKI
 %token K_JTAG_MKII
+%token K_JTAG_MKII_DW
 %token K_JTAG_MKII_ISP
 %token K_LOADPAGE
 %token K_MAX_WRITE_DELAY
@@ -194,10 +196,12 @@ static int parse_cmdbits(OPCODE * op);
 				 */
 %token K_ENABLEPAGEPROGRAMMING	/* ? yes for mega256*, mega406 */
 %token K_HAS_JTAG		/* MCU has JTAG i/f. */
+%token K_HAS_DW			/* MCU has debugWire i/f. */
 %token K_IDR			/* address of OCD register in IO space */
 %token K_RAMPZ			/* address of RAMPZ reg. in IO space */
 %token K_SPMCR			/* address of SPMC[S]R in memory space */
 %token K_EECR    		/* address of EECR in memory space */
+%token K_FLASH_INSTR		/* flash instructions */
 
 %token TKN_COMMA
 %token TKN_EQUAL
@@ -435,12 +439,24 @@ prog_parm :
     }
   } |
 
+  K_TYPE TKN_EQUAL K_JTAG_MKII_DW {
+    {
+      jtagmkII_dw_initpgm(current_prog);
+    }
+  } |
+
   K_TYPE TKN_EQUAL K_JTAG_MKII_ISP {
     {
       stk500v2_jtagmkII_initpgm(current_prog);
     }
   } |
 
+  K_TYPE TKN_EQUAL K_DRAGON_DW {
+    {
+      jtagmkII_dragon_dw_initpgm(current_prog);
+    }
+  } |
+
   K_TYPE TKN_EQUAL K_DRAGON_HVSP {
     {
       stk500v2_dragon_hvsp_initpgm(current_prog);
@@ -703,6 +719,38 @@ part_parm :
     }
   } |
 
+  K_FLASH_INSTR TKN_EQUAL num_list {
+    {
+      TOKEN * t;
+      unsigned nbytes;
+      int ok;
+
+      nbytes = 0;
+      ok = 1;
+
+      while (lsize(number_list)) {
+        t = lrmv_n(number_list, 1);
+	if (nbytes < FLASH_INSTR_SIZE)
+	  {
+	    current_part->flash_instr[nbytes] = t->value.number;
+	    nbytes++;
+	  }
+	else
+	  {
+	    ok = 0;
+	  }
+        free_token(t);
+      }
+      if (!ok)
+	{
+	  fprintf(stderr,
+                  "%s: Warning: line %d of %s: "
+		  "too many bytes in flash instructions\n",
+                  progname, lineno, infile);
+        }
+    }
+  } |
+
   K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
     {
       current_part->chip_erase_delay = $3->value.number;
@@ -909,6 +957,16 @@ part_parm :
       free_token($3);
     } |
 
+  K_HAS_DW TKN_EQUAL yesno
+    {
+      if ($3->primary == K_YES)
+        current_part->flags |= AVRPART_HAS_DW;
+      else if ($3->primary == K_NO)
+        current_part->flags &= ~AVRPART_HAS_DW;
+
+      free_token($3);
+    } |
+
   K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
     {
       if ($3->primary == K_YES)
diff --git a/doc/avrdude.texi b/doc/avrdude.texi
index 5a81c9e2..472a323f 100644
--- a/doc/avrdude.texi
+++ b/doc/avrdude.texi
@@ -182,11 +182,12 @@ protocol is more sophisticated.
 (The JTAG ICE mkII protocol can also be run on top of USB.)
 Only the memory programming functionality of the JTAG ICE is supported
 by AVRDUDE.
-For the JTAG ICE mkII, both JTAG and ISP mode are supported.
+For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
+See below for the limitations of debugWire.
 
-The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP).
+The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
 (High-voltage programming is not yet supported.)
-When used in JTAG mode, the AVR Dragon behaves similar to a
+When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
 JTAG ICE mkII, so all device-specific comments for that device
 will apply as well.
 When used in ISP mode, the AVR Dragon behaves similar to an
@@ -385,6 +386,8 @@ Brian Dean's Programmer,@*
 Atmel Butterfly Development Board
 @item @code{dt006}       @tab
 Dontronics DT006
+@item @code{dragon_dw}   @tab
+AVR Dragon in debugWire mode
 @item @code{dragon_hvsp} @tab
 AVR Dragon in high-voltage serial programming mode
 @item @code{dragon_isp}  @tab
@@ -409,6 +412,8 @@ Atmel JTAG ICE mkII, running at 115200 Bd
 @emph{Same as before.}
 @item @code{jtag2isp}    @tab
 Atmel JTAG ICE mkII in ISP mode.
+@item @code{jtag2dw}     @tab
+Atmel JTAG ICE mkII in debugWire mode.
 @item @code{pavr}        @tab
 Jason Kyle's pAVR Serial Programmer
 @item @code{picoweb}     @tab
@@ -1927,6 +1932,36 @@ Solution: none at this time.  The simplicity of the USBasp programmer
 doesn't offer a method to distinguish multiple programmers that are
 connected simultaneously, so effectively only one USBasp is supported.
 
+@item
+Problem: I cannot do @dots{} when the target is in debugWire mode.
+
+Solution: debugWire mode imposes several limitations.
+
+The debugWire protocol is Atmel's proprietary one-wire (plus ground)
+protocol to allow an in-circuit emulation of the smaller AVR devices,
+using the @var{/RESET} line.
+DebugWire mode is initiated by activating the @var{DWEN}
+fuse, and then power-cycling the target.
+While this mode is mainly intented for debugging/emulation, it
+also offers limited programming capabilities.
+Effectively, the only memory area that can be read or programmed
+in this mode is the flash ROM.
+It is also possible to read out the signature.
+All other memory areas cannot be accessed.
+There is no
+@emph{chip erase}
+functionality in debugWire mode; instead, while reprogramming the
+flash ROM, each flash ROM page is erased right before updating it.
+This is done transparently by the JTAG ICE mkII (or AVR Dragon).
+The only way back from debugWire mode is to initiate a special
+sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
+debugWire mode will be temporarily disabled, and the target can
+be accessed using normal ISP programming.
+This sequence is automatically initiated by using the JTAG ICE mkII
+or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
+entered.
+
+
 @end itemize
 
 
diff --git a/jtagmkII.c b/jtagmkII.c
index 505b0107..7e6f38a1 100644
--- a/jtagmkII.c
+++ b/jtagmkII.c
@@ -106,6 +106,11 @@ static struct {
   RC(RSP_SET_N_PARAMETERS)
 };
 
+/*
+ * pgm->flag is marked as "for private use of the programmer".
+ * The following defines this programmer's use of that field.
+ */
+#define PGM_FL_IS_DW		(0x0001)
 
 /* The length of the device descriptor is firmware-dependent. */
 static size_t device_descriptor_length;
@@ -801,6 +806,18 @@ static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
+/*
+ * There is no chip erase functionality in debugWire mode.
+ */
+static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
+{
+
+  fprintf(stderr, "%s: Chip erase not supported in debugWire mode\n",
+	  progname);
+
+  return 0;
+}
+
 static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
 {
   int status;
@@ -829,6 +846,8 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
       u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
       u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize);
       u16_to_b2(sendbuf.dd.uiFlashpages, m->size / flash_pagesize);
+      if (p->flags & AVRPART_HAS_DW)
+	memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
     } else if (strcmp(m->desc, "eeprom") == 0) {
       sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size;
     }
@@ -874,11 +893,21 @@ static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
   int status;
   unsigned char buf[2], *resp, c;
 
-  buf[0] = CMND_RESET;
-  buf[1] = flags;
+  /*
+   * In debugWire mode, don't reset.  Do a forced stop, and tell the
+   * ICE to stop any timers, too.
+   */
+  if (pgm->flag & PGM_FL_IS_DW) {
+    unsigned char parm[] = { 0 };
+
+    (void)jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm);
+  }
+
+  buf[0] = (pgm->flag & PGM_FL_IS_DW)? CMND_FORCED_STOP: CMND_RESET;
+  buf[1] = (pgm->flag & PGM_FL_IS_DW)? 1: flags;
   if (verbose >= 2)
-    fprintf(stderr, "%s: jtagmkII_reset(): Sending reset command: ",
-	    progname);
+    fprintf(stderr, "%s: jtagmkII_reset(): Sending %s command: ",
+	    progname, (pgm->flag & PGM_FL_IS_DW)? "stop": "reset");
   jtagmkII_send(pgm, buf, 2);
 
   status = jtagmkII_recv(pgm, &resp);
@@ -1038,10 +1067,23 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
 {
   AVRMEM hfuse;
   unsigned char b;
+  int ok;
+  const char *ifname;
 
-  if (!(p->flags & AVRPART_HAS_JTAG)) {
-    fprintf(stderr, "%s: jtagmkII_initialize(): part %s has no JTAG interface\n",
-	    progname, p->desc);
+  ok = 0;
+  if (pgm->flag & PGM_FL_IS_DW) {
+    ifname = "debugWire";
+    if (p->flags & AVRPART_HAS_DW)
+      ok = 1;
+  } else {
+    ifname = "JTAG";
+    if (p->flags & AVRPART_HAS_JTAG)
+      ok = 1;
+  }
+
+  if (!ok) {
+    fprintf(stderr, "%s: jtagmkII_initialize(): part %s has no %s interface\n",
+	    progname, p->desc, ifname);
     return -1;
   }
 
@@ -1058,7 +1100,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
 	serial_setspeed(pgm->fd, pgm->baudrate);
     }
   }
-  if (pgm->bitclock != 0.0) {
+  if (!(pgm->flag & PGM_FL_IS_DW) && pgm->bitclock != 0.0) {
     if (verbose >= 2)
       fprintf(stderr, "%s: jtagmkII_initialize(): "
 	      "trying to set JTAG clock period to %.1f us\n",
@@ -1090,14 +1132,16 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
   if (jtagmkII_reset(pgm, 0x01) < 0)
     return -1;
 
-  strcpy(hfuse.desc, "hfuse");
-  if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
-    return -1;
-  if ((b & OCDEN) != 0)
-    fprintf(stderr,
-	    "%s: jtagmkII_initialize(): warning: OCDEN fuse not programmed, "
-	    "single-byte EEPROM updates not possible\n",
-	    progname);
+  if (!(pgm->flag & PGM_FL_IS_DW)) {
+    strcpy(hfuse.desc, "hfuse");
+    if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
+      return -1;
+    if ((b & OCDEN) != 0)
+      fprintf(stderr,
+	      "%s: jtagmkII_initialize(): warning: OCDEN fuse not programmed, "
+	      "single-byte EEPROM updates not possible\n",
+	      progname);
+  }
 
   return 0;
 }
@@ -1111,7 +1155,8 @@ static void jtagmkII_disable(PROGRAMMER * pgm)
   free(eeprom_pagecache);
   eeprom_pagecache = NULL;
 
-  (void)jtagmkII_program_disable(pgm);
+  if (!(pgm->flag & PGM_FL_IS_DW))
+    (void)jtagmkII_program_disable(pgm);
 }
 
 static void jtagmkII_enable(PROGRAMMER * pgm)
@@ -1165,6 +1210,51 @@ static int jtagmkII_open(PROGRAMMER * pgm, char * port)
 }
 
 
+static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
+{
+  long baud;
+
+  if (verbose >= 2)
+    fprintf(stderr, "%s: jtagmkII_open_dw()\n", progname);
+
+  /*
+   * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+   * attaching.  If the config file or command-line parameters specify
+   * a higher baud rate, we switch to it later on, after establishing
+   * the connection with the ICE.
+   */
+  baud = 19200;
+
+  /*
+   * If the port name starts with "usb", divert the serial routines
+   * to the USB ones.  The serial_open() function for USB overrides
+   * the meaning of the "baud" parameter to be the USB device ID to
+   * search for.
+   */
+  if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+    serdev = &usb_serdev;
+    baud = USB_DEVICE_JTAGICEMKII;
+#else
+    fprintf(stderr, "avrdude was compiled without usb support.\n");
+    return -1;
+#endif
+  }
+
+  strcpy(pgm->port, port);
+  pgm->fd = serial_open(port, baud);
+
+  /*
+   * drain any extraneous input
+   */
+  jtagmkII_drain(pgm, 0);
+
+  jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE);
+
+  return 0;
+}
+
+
 static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
 {
   long baud;
@@ -1210,6 +1300,51 @@ static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
 }
 
 
+static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
+{
+  long baud;
+
+  if (verbose >= 2)
+    fprintf(stderr, "%s: jtagmkII_dragon_open_dw()\n", progname);
+
+  /*
+   * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+   * attaching.  If the config file or command-line parameters specify
+   * a higher baud rate, we switch to it later on, after establishing
+   * the connection with the ICE.
+   */
+  baud = 19200;
+
+  /*
+   * If the port name starts with "usb", divert the serial routines
+   * to the USB ones.  The serial_open() function for USB overrides
+   * the meaning of the "baud" parameter to be the USB device ID to
+   * search for.
+   */
+  if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+    serdev = &usb_serdev;
+    baud = USB_DEVICE_AVRDRAGON;
+#else
+    fprintf(stderr, "avrdude was compiled without usb support.\n");
+    return -1;
+#endif
+  }
+
+  strcpy(pgm->port, port);
+  pgm->fd = serial_open(port, baud);
+
+  /*
+   * drain any extraneous input
+   */
+  jtagmkII_drain(pgm, 0);
+
+  jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE);
+
+  return 0;
+}
+
+
 void jtagmkII_close(PROGRAMMER * pgm)
 {
   int status;
@@ -1299,7 +1434,7 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     fprintf(stderr, "%s: jtagmkII_paged_write(.., %s, %d, %d)\n",
 	    progname, m->desc, page_size, n_bytes);
 
-  if (jtagmkII_program_enable(pgm) < 0)
+  if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
     return -1;
 
   if (page_size == 0) page_size = 256;
@@ -1319,6 +1454,10 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     cmd[1] = MTYPE_EEPROM_PAGE;
     eeprom_pageaddr = (unsigned long)-1L;
     page_size = eeprom_pagesize;
+    if (pgm->flag & PGM_FL_IS_DW) {
+      free(cmd);
+      return -1;
+    }
   }
 
   serial_recv_timeout = 100;
@@ -1393,6 +1532,7 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       return -1;
     }
     free(resp);
+    usleep(1000000);
   }
 
   free(cmd);
@@ -1414,7 +1554,7 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     fprintf(stderr, "%s: jtagmkII_paged_load(.., %s, %d, %d)\n",
 	    progname, m->desc, page_size, n_bytes);
 
-  if (jtagmkII_program_enable(pgm) < 0)
+  if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
     return -1;
 
   page_size = m->readsize;
@@ -1424,6 +1564,8 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     cmd[1] = MTYPE_FLASH_PAGE;
   } else if (strcmp(m->desc, "eeprom") == 0) {
     cmd[1] = MTYPE_EEPROM_PAGE;
+    if (pgm->flag & PGM_FL_IS_DW)
+      return -1;
   }
 
   serial_recv_timeout = 100;
@@ -1497,7 +1639,7 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 {
   unsigned char cmd[10];
   unsigned char *resp = NULL, *cache_ptr = NULL;
-  int status, tries;
+  int status, tries, unsupp;
   unsigned long paddr = 0UL, *paddr_ptr = NULL;
   unsigned int pagesize = 0;
 
@@ -1505,10 +1647,11 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     fprintf(stderr, "%s: jtagmkII_read_byte(.., %s, 0x%lx, ...)\n",
 	    progname, mem->desc, addr);
 
-  if (jtagmkII_program_enable(pgm) < 0)
+  if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
     return -1;
 
   cmd[0] = CMND_READ_MEMORY;
+  unsupp = 0;
 
   if (strcmp(mem->desc, "flash") == 0) {
     cmd[1] = MTYPE_FLASH_PAGE;
@@ -1522,21 +1665,71 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     paddr = addr & ~(pagesize - 1);
     paddr_ptr = &eeprom_pageaddr;
     cache_ptr = eeprom_pagecache;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "lfuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 0;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "hfuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 1;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "efuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 2;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "lock") == 0) {
     cmd[1] = MTYPE_LOCK_BITS;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "calibration") == 0) {
     cmd[1] = MTYPE_OSCCAL_BYTE;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "signature") == 0) {
     cmd[1] = MTYPE_SIGN_JTAG;
+
+    if (pgm->flag & PGM_FL_IS_DW) {
+      /*
+       * In debugWire mode, there is no accessible memory area to read
+       * the signature from, but the essential two bytes can be read
+       * as a parameter from the ICE.
+       */
+      unsigned char parm[4];
+
+      switch (addr) {
+      case 0:
+	*value = 0x1E;		/* Atmel vendor ID */
+	break;
+
+      case 1:
+      case 2:
+	if (jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0)
+	  return -1;
+	*value = parm[2 - addr];
+	break;
+
+      default:
+	fprintf(stderr, "%s: illegal address %lu for signature memory\n",
+		progname, addr);
+	*value = 42;
+	return -1;
+      }
+      return 0;
+    }
+  }
+
+  /*
+   * If the respective memory area is not supported under debugWire,
+   * leave here.
+   */
+  if (unsupp) {
+    *value = 42;
+    return -1;
   }
 
   /*
@@ -1720,6 +1913,17 @@ fail:
 }
 
 
+static int jtagmkII_write_byte_dw(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+				  unsigned long addr, unsigned char data)
+{
+
+  fprintf(stderr,
+	  "%s: jtagmkII_write_byte_dw(): no single-byte writes supported in debugWire\n",
+	  progname);
+
+  return -1;
+}
+
 /*
  * Set the JTAG clock.  The actual frequency is quite a bit of
  * guesswork, based on the values claimed by AVR Studio.  Inside the
@@ -1824,6 +2028,7 @@ static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
   case PAR_BAUD_RATE: size = 1; break;
   case PAR_OCD_VTARGET: size = 2; break;
   case PAR_OCD_JTAG_CLK: size = 1; break;
+  case PAR_TIMERS_RUNNING: size = 1; break;
   default:
     fprintf(stderr, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n",
 	    progname, parm);
@@ -1895,28 +2100,33 @@ static void jtagmkII_print_parms1(PROGRAMMER * pgm, char * p)
   char clkbuf[20];
   double clk;
 
-  if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0 ||
-      jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
+  if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0)
     return;
 
-  if (jtag_clock[0] == 0) {
-    strcpy(clkbuf, "6.4 MHz");
-    clk = 6.4e6;
-  } else if (jtag_clock[0] == 1) {
-    strcpy(clkbuf, "2.8 MHz");
-    clk = 2.8e6;
-  } else if (jtag_clock[0] <= 5) {
-    sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]);
-    clk = 5.35e6 / (double)jtag_clock[0];
-  } else {
-    sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
-    clk = 5.35e6 / (double)jtag_clock[0];
-  }
-
   fprintf(stderr, "%sVtarget         : %.1f V\n", p,
 	  b2_to_u16(vtarget) / 1000.0);
-  fprintf(stderr, "%sJTAG clock      : %s (%.1f us)\n", p, clkbuf,
-	  1.0e6 / clk);
+
+  if (!(pgm->flag & PGM_FL_IS_DW)) {
+    if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
+      return;
+
+    if (jtag_clock[0] == 0) {
+      strcpy(clkbuf, "6.4 MHz");
+      clk = 6.4e6;
+    } else if (jtag_clock[0] == 1) {
+      strcpy(clkbuf, "2.8 MHz");
+      clk = 2.8e6;
+    } else if (jtag_clock[0] <= 5) {
+      sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]);
+      clk = 5.35e6 / (double)jtag_clock[0];
+    } else {
+      sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
+      clk = 5.35e6 / (double)jtag_clock[0];
+
+      fprintf(stderr, "%sJTAG clock      : %s (%.1f us)\n", p, clkbuf,
+	      1.0e6 / clk);
+    }
+  }
 
   return;
 }
@@ -1957,6 +2167,35 @@ void jtagmkII_initpgm(PROGRAMMER * pgm)
 }
 
 
+void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
+{
+  strcpy(pgm->type, "JTAGMKII_DW");
+
+  /*
+   * mandatory functions
+   */
+  pgm->initialize     = jtagmkII_initialize;
+  pgm->display        = jtagmkII_display;
+  pgm->enable         = jtagmkII_enable;
+  pgm->disable        = jtagmkII_disable;
+  pgm->program_enable = jtagmkII_program_enable_dummy;
+  pgm->chip_erase     = jtagmkII_chip_erase_dw;
+  pgm->open           = jtagmkII_open_dw;
+  pgm->close          = jtagmkII_close;
+  pgm->read_byte      = jtagmkII_read_byte;
+  pgm->write_byte     = jtagmkII_write_byte_dw;
+
+  /*
+   * optional functions
+   */
+  pgm->paged_write    = jtagmkII_paged_write;
+  pgm->paged_load     = jtagmkII_paged_load;
+  pgm->print_parms    = jtagmkII_print_parms;
+  pgm->page_size      = 256;
+  pgm->flag           = PGM_FL_IS_DW;
+}
+
+
 void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
 {
   strcpy(pgm->type, "DRAGON_JTAG");
@@ -1984,3 +2223,32 @@ void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
   pgm->set_sck_period = jtagmkII_set_sck_period;
   pgm->page_size      = 256;
 }
+
+
+void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
+{
+  strcpy(pgm->type, "DRAGON_DW");
+
+  /*
+   * mandatory functions
+   */
+  pgm->initialize     = jtagmkII_initialize;
+  pgm->display        = jtagmkII_display;
+  pgm->enable         = jtagmkII_enable;
+  pgm->disable        = jtagmkII_disable;
+  pgm->program_enable = jtagmkII_program_enable_dummy;
+  pgm->chip_erase     = jtagmkII_chip_erase_dw;
+  pgm->open           = jtagmkII_dragon_open_dw;
+  pgm->close          = jtagmkII_close;
+  pgm->read_byte      = jtagmkII_read_byte;
+  pgm->write_byte     = jtagmkII_write_byte_dw;
+
+  /*
+   * optional functions
+   */
+  pgm->paged_write    = jtagmkII_paged_write;
+  pgm->paged_load     = jtagmkII_paged_load;
+  pgm->print_parms    = jtagmkII_print_parms;
+  pgm->page_size      = 256;
+  pgm->flag           = PGM_FL_IS_DW;
+}
diff --git a/jtagmkII.h b/jtagmkII.h
index 39eea580..87023357 100644
--- a/jtagmkII.h
+++ b/jtagmkII.h
@@ -30,7 +30,9 @@ int  jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
 		      unsigned char * value);
 
 void jtagmkII_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
 void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
 
 #endif
 
diff --git a/lexer.l b/lexer.l
index a52f914a..22a35dda 100644
--- a/lexer.l
+++ b/lexer.l
@@ -135,6 +135,7 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
 default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
 default_serial   { yylval=NULL; return K_DEFAULT_SERIAL; }
 devicecode       { yylval=NULL; return K_DEVICECODE; }
+dragon_dw        { yylval=NULL; return K_DRAGON_DW; }
 dragon_hvsp      { yylval=NULL; return K_DRAGON_HVSP; }
 dragon_isp       { yylval=NULL; return K_DRAGON_ISP; }
 dragon_jtag      { yylval=NULL; return K_DRAGON_JTAG; }
@@ -145,10 +146,12 @@ enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
 errled           { yylval=NULL; return K_ERRLED; }
 flash            { yylval=NULL; return K_FLASH; }
 has_jtag         { yylval=NULL; return K_HAS_JTAG; }
+has_debugwire    { yylval=NULL; return K_HAS_DW; }
 id               { yylval=NULL; return K_ID; }
 idr              { yylval=NULL; return K_IDR; }
 jtagmki          { yylval=NULL; return K_JTAG_MKI; }
 jtagmkii         { yylval=NULL; return K_JTAG_MKII; }
+jtagmkii_dw      { yylval=NULL; return K_JTAG_MKII_DW; }
 jtagmkii_isp     { yylval=NULL; return K_JTAG_MKII_ISP; }
 max_write_delay  { yylval=NULL; return K_MAX_WRITE_DELAY; }
 memory           { yylval=NULL; return K_MEMORY; }
@@ -220,7 +223,7 @@ programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
 programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
 programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
 programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
-
+flash_instr      { yylval=NULL; return K_FLASH_INSTR; }
 
 dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
 io               { yylval=new_token(K_IO); return K_IO; }