diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index a5b93d12..b9883568 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,9 @@
+2012-04-19  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* stk500v2_private.h (struct pdata): add boot_start
+	* stk500v2.c: For the "flash" pseudo-memory of Xmega devices,
+	distinguish addresses between "application" and "boot" area.
+
 2012-04-18  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* fileio.c (elf2b): When checking the bounds of the current
diff --git a/avrdude/stk500v2.c b/avrdude/stk500v2.c
index d70b219f..5db352af 100644
--- a/avrdude/stk500v2.c
+++ b/avrdude/stk500v2.c
@@ -289,6 +289,7 @@ void stk500v2_setup(PROGRAMMER * pgm)
   }
   memset(pgm->cookie, 0, sizeof(struct pdata));
   PDATA(pgm)->command_sequence = 1;
+  PDATA(pgm)->boot_start = ULONG_MAX;
 }
 
 static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
@@ -1095,6 +1096,21 @@ static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
      * This is an ATxmega device, must use XPROG protocol for the
      * remaining actions.
      */
+    if ((p->flags & AVRPART_HAS_PDI) != 0) {
+      /*
+       * Find out where the border between application and boot area
+       * is.
+       */
+      AVRMEM *bootmem = avr_locate_mem(p, "boot");
+      AVRMEM *flashmem = avr_locate_mem(p, "flash");
+      if (bootmem == NULL || flashmem == NULL) {
+        fprintf(stderr,
+                "%s: stk500v2_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
+                progname);
+      } else {
+        PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
+      }
+    }
     stk600_setup_xprog(pgm);
   } else {
     stk600_setup_isp(pgm);
@@ -3144,6 +3160,15 @@ static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
     return 0;
 }
 
+static unsigned char stk600_xprog_memtype(PROGRAMMER * pgm, unsigned long addr)
+{
+    if (addr >= PDATA(pgm)->boot_start)
+        return XPRG_MEM_TYPE_BOOT;
+    else
+        return XPRG_MEM_TYPE_APPL;
+}
+
+
 static void stk600_xprog_disable(PROGRAMMER * pgm)
 {
     unsigned char buf[2];
@@ -3166,9 +3191,10 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 
     memset(b, 0, sizeof(b));
 
-    if (strcmp(mem->desc, "flash") == 0 ||
-        strcmp(mem->desc, "application") == 0 ||
-        strcmp(mem->desc, "apptable") == 0) {
+    if (strcmp(mem->desc, "flash") == 0) {
+        memcode = stk600_xprog_memtype(pgm, addr);
+    } else if (strcmp(mem->desc, "application") == 0 ||
+               strcmp(mem->desc, "apptable") == 0) {
         memcode = XPRG_MEM_TYPE_APPL;
     } else if (strcmp(mem->desc, "boot") == 0) {
         memcode = XPRG_MEM_TYPE_BOOT;
@@ -3244,9 +3270,10 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 {
     unsigned char b[8];
 
-    if (strcmp(mem->desc, "flash") == 0 ||
-        strcmp(mem->desc, "application") == 0 ||
-        strcmp(mem->desc, "apptable") == 0) {
+    if (strcmp(mem->desc, "flash") == 0) {
+        b[1] = stk600_xprog_memtype(pgm, addr);
+    } else if (strcmp(mem->desc, "application") == 0 ||
+               strcmp(mem->desc, "apptable") == 0) {
         b[1] = XPRG_MEM_TYPE_APPL;
     } else if (strcmp(mem->desc, "boot") == 0) {
         b[1] = XPRG_MEM_TYPE_BOOT;
@@ -3295,7 +3322,7 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     unsigned char *b;
     unsigned int offset;
     unsigned char memtype;
-    int n_bytes_orig = n_bytes;
+    int n_bytes_orig = n_bytes, dynamic_memtype = 0;
     unsigned long use_ext_addr = 0;
 
     /*
@@ -3310,9 +3337,13 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
      * This is probably what AVR079 means when writing about the
      * "TIF address space".
      */
-    if (strcmp(mem->desc, "flash") == 0 ||
-        strcmp(mem->desc, "application") == 0 ||
-        strcmp(mem->desc, "apptable") == 0) {
+    if (strcmp(mem->desc, "flash") == 0) {
+        memtype = 0;
+        dynamic_memtype = 1;
+        if (mem->size > 64 * 1024)
+            use_ext_addr = (1UL << 31);
+    } else if (strcmp(mem->desc, "application") == 0 ||
+               strcmp(mem->desc, "apptable") == 0) {
         memtype = XPRG_MEM_TYPE_APPL;
         if (mem->size > 64 * 1024)
             use_ext_addr = (1UL << 31);
@@ -3356,6 +3387,9 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     }
 
     while (n_bytes != 0) {
+	if (dynamic_memtype)
+	    memtype = stk600_xprog_memtype(pgm, addr - mem->offset);
+
 	b[0] = XPRG_CMD_READ_MEM;
 	b[1] = memtype;
 	b[2] = addr >> 24;
@@ -3391,7 +3425,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     unsigned char *b;
     unsigned int offset;
     unsigned char memtype;
-    int n_bytes_orig = n_bytes;
+    int n_bytes_orig = n_bytes, dynamic_memtype = 0;
     size_t writesize;
     unsigned long use_ext_addr = 0;
     unsigned char writemode;
@@ -3412,9 +3446,14 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
      * This is probably what AVR079 means when writing about the
      * "TIF address space".
      */
-    if (strcmp(mem->desc, "flash") == 0 ||
-        strcmp(mem->desc, "application") == 0 ||
-        strcmp(mem->desc, "apptable") == 0) {
+    if (strcmp(mem->desc, "flash") == 0) {
+        memtype = 0;
+        dynamic_memtype = 1;
+        writemode = (1 << XPRG_MEM_WRITE_WRITE);
+        if (mem->size > 64 * 1024)
+            use_ext_addr = (1UL << 31);
+    } else if (strcmp(mem->desc, "application") == 0 ||
+               strcmp(mem->desc, "apptable") == 0) {
         memtype = XPRG_MEM_TYPE_APPL;
         writemode = (1 << XPRG_MEM_WRITE_WRITE);
         if (mem->size > 64 * 1024)
@@ -3466,6 +3505,10 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     }
 
     while (n_bytes != 0) {
+
+	if (dynamic_memtype)
+	    memtype = stk600_xprog_memtype(pgm, addr - mem->offset);
+
 	if (page_size > 256) {
 	    /*
 	     * AVR079 is not quite clear.  While it suggests that
diff --git a/avrdude/stk500v2_private.h b/avrdude/stk500v2_private.h
index 66a419b7..05b66d9d 100644
--- a/avrdude/stk500v2_private.h
+++ b/avrdude/stk500v2_private.h
@@ -312,6 +312,9 @@ struct pdata
 
   AVRPART *lastpart;
 
+  /* Start address of Xmega boot area */
+  unsigned long boot_start;
+
   /*
    * Chained pdata for the JTAG ICE mkII backend.  This is used when
    * calling the backend functions for ISP/HVSP/PP programming