Index: avrdude/ChangeLog
===================================================================
RCS file: /sources/avrdude/avrdude/ChangeLog,v
retrieving revision 1.163
diff -u -r1.163 ChangeLog
--- avrdude/ChangeLog	27 Feb 2006 17:18:42 -0000	1.163
+++ avrdude/ChangeLog	20 Mar 2006 04:34:37 -0000
@@ -1,3 +1,25 @@
+2006-03-12  Wim Lewis <wiml@hhhh.org>
+    Support for programming blocks of memory starting at addresses
+    other than 0.
+    * avrpart.h: new members 'use_start' and 'use_end' in AVRMEM
+    * avr.c: avr_mem_hiaddr() becomes avr_mem_trim(); added a start-address
+      parameter to avr_read(); split body of avr_read() into avr_read_mem();
+      removed 'size' parameter from avr_write() iand avr_verify() (now uses
+      the range info from AVRMEM). 
+    * avr.h, avrpart.h: function signature changes for above.
+    * pgm.h: paged_write and paged_read methods now take a start as well
+      as a length parameter
+    * avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500.c, stk500v2.c:
+      Dummy implementation of change to programmer interface, just
+      adjusts start to 0 to imitate old behavior; use avr_touch_mem()
+      to maintain correct use_start and use_end values in AVRMEM
+    * avrpart.c: maintain use_start/use_end values for each AVRMEM
+    * fileio.c, fileio.h: use (and produce) the use_range info in AVRMEM
+      instead of passing sizes in function calls
+    * main.c: only duplicate the AVRMEM, not the whole AVRPART, when
+      verifying; allow called functions to use the use_range info instead
+      of passing explicit ranges
+
 2006-02-27  Colin O'Flynn <coflynn@newae.com>
     Contributed by Wim Lewis, add support for checking device
         signatures in detail (patch #4924 and #4925)
Index: avrdude/avr.c
===================================================================
RCS file: /sources/avrdude/avrdude/avr.c,v
retrieving revision 1.65
diff -u -r1.65 avr.c
--- avrdude/avr.c	21 Sep 2005 01:26:54 -0000	1.65
+++ avrdude/avr.c	20 Mar 2006 04:34:38 -0000
@@ -116,31 +116,46 @@
 
 
 /*
- * Return the number of "interesting" bytes in a memory buffer,
- * "interesting" being defined as up to the last non-0xff data
- * value. This is useful for determining where to stop when dealing
+ * Trim "uninteresting" bytes from a memory buffer's used range,
+ * "interesting" being defined as any byte other than 0xff.
+ * This is useful for determining where to stop when dealing
  * with "flash" memory, since writing 0xff to flash is typically a
  * no-op. Always return an even number since flash is word addressed.
  */
-int avr_mem_hiaddr(AVRMEM * mem)
+void avr_mem_trim(AVRMEM * mem)
 {
-  int i, n;
+  int i;
 
-  /* return the highest non-0xff address regardless of how much
-     memory was read */
-  for (i=mem->size-1; i>0; i--) {
-    if (mem->buf[i] != 0xff) {
-      n = i+1;
-      if (n & 0x01)
-        return n+1;
-      else
-        return n;
-    }
-  }
+  if (mem->use_start >= mem->use_end)
+    return;
 
-  return 0;
-}
+  /* Trim bytes off the start */
+  i = mem->use_start;
+  while(i < mem->use_end && mem->buf[i] == 0xff)
+    i ++;
+/*  if (i > mem->use_start)
+    fprintf(stderr, "[mem_trim %u bytes from front of %s]\n",
+            i - mem->use_start, mem->desc); */
+  if (i & 1)
+    mem->use_start = i - 1;
+  else
+    mem->use_start = i;
 
+  /* Trim bytes off the end */
+  /* note that use_end points to the first unused byte, not the last used byte;
+     this is so that len=(end-start), and also so that an empty range is easily
+     represented */
+  i = mem->use_end;
+  while(i > mem->use_start && mem->buf[i-1] == 0xff)
+    i--;
+/*  if (i < mem->use_end)
+    fprintf(stderr, "[mem_trim %u bytes from end of %s]\n",
+            mem->use_end - i, mem->desc); */
+  if (i & 1)
+    mem->use_end = i + 1;
+  else
+    mem->use_end = i;
+}
 
 /*
  * Read the entirety of the specified memory type into the
@@ -149,14 +164,10 @@
  *
  * Return the number of bytes read, or < 0 if an error occurs.  
  */
-int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, 
-             int verbose)
+int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+	     int start, int size, int verbose)
 {
-  unsigned char    rbyte;
-  unsigned long    i;
-  unsigned char  * buf;
   AVRMEM * mem;
-  int rc;
 
   mem = avr_locate_mem(p, memtype);
   if (mem == NULL) {
@@ -165,15 +176,26 @@
     return -1;
   }
 
-  buf  = mem->buf;
+  return avr_read_mem(pgm, p, mem, start, size, verbose);
+}
+
+int avr_read_mem(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+		 int start, int size, int verbose)
+{
+  unsigned char    rbyte;
+  unsigned long    i, addr;
+  unsigned char  * buf;
+  int rc;
+
   if (size == 0) {
+    start = 0;
     size = mem->size;
   }
 
   /*
    * start with all 0xff
    */
-  memset(buf, 0xff, size);
+  memset(mem->buf+start, 0xff, size);
 
   if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
     if (pgm->paged_load != NULL) {
@@ -183,19 +205,18 @@
        * instead
        */
       if (mem->paged) {
-        rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
+        rc = pgm->paged_load(pgm, p, mem, mem->page_size, start, size);
         if (rc < 0)
           return rc;
       }
       else {
-        rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
+        rc = pgm->paged_load(pgm, p, mem, pgm->page_size, start, size);
         if (rc < 0)
           return rc;
       }
       if (strcasecmp(mem->desc, "flash") == 0)
-        return avr_mem_hiaddr(mem);
-      else
-        return rc;
+	avr_mem_trim(mem);
+      return rc;
     }
   }
 
@@ -205,14 +226,16 @@
     }
   }
 
+  buf = avr_touch_mem(mem, start, size);
   for (i=0; i<size; i++) {
-    rc = avr_read_byte(pgm, p, mem, i, &rbyte);
+    addr = start+i;
+    rc = avr_read_byte(pgm, p, mem, addr, &rbyte);
     if (rc != 0) {
-      fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
+      fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", addr);
       if (rc == -1) 
         fprintf(stderr, 
                 "    read operation not supported for memory \"%s\"\n",
-                memtype);
+                mem->desc);
       return -2;
     }
     buf[i] = rbyte;
@@ -220,12 +243,10 @@
   }
 
   if (strcasecmp(mem->desc, "flash") == 0)
-    return avr_mem_hiaddr(mem);
-  else
-    return i;
+    avr_mem_trim(mem);
+  return i;
 }
 
-
 /*
  * write a page data at the specified address
  */
@@ -520,17 +541,18 @@
 /*
  * Write the whole memory region of the specified memory from the
  * corresponding buffer of the avrpart pointed to by 'p'.  Write up to
- * 'size' bytes from the buffer.  Data is only written if the new data
- * value is different from the existing data value.  Data beyond
- * 'size' bytes is not affected.
+ * 'size' bytes from the buffer, starting with the byte at address 'start'.
+ * Data is only written if the new data value is different from the existing
+ * data value.  Data beyond 'start+size' bytes is not affected.
  *
  * Return the number of bytes written, or -1 if an error occurs.
  */
-int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, 
-              int verbose)
+int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+	      int verbose)
 {
+  unsigned int     start, size;
   int              rc;
-  int              wsize;
+  int              wrend;
   unsigned long    i;
   unsigned char    data;
   int              werror;
@@ -547,18 +569,25 @@
 
   werror  = 0;
 
-  wsize = m->size;
-  if (size < wsize) {
-    wsize = size;
-  }
-  else if (size > wsize) {
+  start = m->use_start;
+  size = m->use_end - start;
+
+  if (start+size > m->size) {
+    fprintf(stderr, 
+            "%s: WARNING: bytes %d-%d requested, "
+            "but %s memory region is only %d bytes\n",
+            progname, start, start+size-1, m->desc, m->size);
+    if (start >= m->size) {
+      start = m->size;
+      size = 0;
+    } else {
+      size = m->size - start;
+    }
     fprintf(stderr, 
-            "%s: WARNING: %d bytes requested, but memory region is only %d"
-            "bytes\n"
             "%sOnly %d bytes will actually be written\n",
-            progname, size, wsize,
-            progbuf, wsize);
+            progbuf, size);
   }
+  wrend = start + size;
 
   if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
     if (pgm->paged_write != NULL) {
@@ -567,7 +596,7 @@
        * efficiently than we can read it directly, so use its routine
        * instead
        */
-      return pgm->paged_write(pgm, p, m, m->page_size, size);
+      return pgm->paged_write(pgm, p, m, m->page_size, start, size);
     }
   }
 
@@ -575,11 +604,12 @@
       pgm->write_setup(pgm, p, m);
   }
 
-  for (i=0; i<wsize; i++) {
-    data = m->buf[i];
-    report_progress(i, wsize, NULL);
+  for (i=0; i<size; i++) {
+    int addr = i + start;
+    data = m->buf[addr];
+    report_progress(i, size, NULL);
 
-    rc = avr_write_byte(pgm, p, m, i, data);
+    rc = avr_write_byte(pgm, p, m, addr, data);
     if (rc) {
       fprintf(stderr, " ***failed;  ");
       fprintf(stderr, "\n");
@@ -590,17 +620,17 @@
     if (m->paged) {
       /*
        * check to see if it is time to flush the page with a page
-       * write
+       * write: at a page boundary or at the end of the write
        */
-      if (((i % m->page_size) == m->page_size-1) ||
-          (i == wsize-1)) {
-        rc = avr_write_page(pgm, p, m, i);
+      if (((addr % m->page_size) == m->page_size-1) ||
+          (i == size-1)) {
+        rc = avr_write_page(pgm, p, m, addr);
         if (rc) {
+	  unsigned long int pagenum = addr % m->page_size;
           fprintf(stderr,
-                  " *** page %ld (addresses 0x%04lx - 0x%04lx) failed "
+                  " *** page %lu (addresses 0x%04lx - 0x%04lx) failed "
                   "to write\n",
-                  i % m->page_size, 
-                  i - m->page_size + 1, i);
+                  pagenum, pagenum * m->page_size, (unsigned long)addr);
           fprintf(stderr, "\n");
           pgm->err_led(pgm, ON);
           werror = 1;
@@ -620,8 +650,6 @@
   return i;
 }
 
-
-
 /*
  * read the AVR device's signature bytes
  */
@@ -630,7 +658,7 @@
   int rc;
 
   report_progress (0,1,"Reading");
-  rc = avr_read(pgm, p, "signature", 0, 0);
+  rc = avr_read(pgm, p, "signature", 0, 0, 0);
   if (rc < 0) {
     fprintf(stderr,
             "%s: error reading signature data for part \"%s\", rc=%d\n",
@@ -650,45 +678,46 @@
  *
  * Return the number of bytes verified, or -1 if they don't match.
  */
-int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
+int avr_verify(AVRPART * p, AVRMEM * v)
 {
   int i;
   unsigned char * buf1, * buf2;
-  int vsize;
+  unsigned vstart, vend;
   AVRMEM * a, * b;
 
-  a = avr_locate_mem(p, memtype);
+  a = avr_locate_mem(p, v->desc);
   if (a == NULL) {
     fprintf(stderr, 
             "avr_verify(): memory type \"%s\" not defined for part %s\n",
-            memtype, p->desc);
+            v->desc, p->desc);
     return -1;
   }
 
-  b = avr_locate_mem(v, memtype);
-  if (b == NULL) {
-    fprintf(stderr, 
-            "avr_verify(): memory type \"%s\" not defined for part %s\n",
-            memtype, v->desc);
-    return -1;
-  }
+  b = v;
 
   buf1  = a->buf;
   buf2  = b->buf;
-  vsize = a->size;
+  vstart = b->use_start;
+  vend = b->use_end;
 
-  if (vsize < size) {
+  if (vstart < a->use_start || vend > a->use_end) {
+    if (vstart < a->use_start)
+      vstart = a->use_start;
+    if (vend > a->use_end)
+      vend = a->use_end;
     fprintf(stderr, 
-            "%s: WARNING: requested verification for %d bytes\n"
+            "%s: WARNING: requested verification for %d bytes (%u-%u)\n"
             "%s%s memory region only contains %d bytes\n"
-            "%sOnly %d bytes will be verified.\n",
-            progname, size,
-            progbuf, memtype, vsize,
-            progbuf, vsize);
-    size = vsize;
+            "%sOnly bytes %u-%u will be verified.\n",
+            progname, b->use_end-b->use_start, b->use_start, b->use_end-1,
+            progbuf, a->desc, a->size,
+            progbuf, vstart, vend);
   }
 
-  for (i=0; i<size; i++) {
+  if (vstart >= vend)
+    return -1;
+
+  for (i=vstart; i<vend; i++) {
     if (buf1[i] != buf2[i]) {
       fprintf(stderr, 
               "%s: verification error, first mismatch at byte 0x%04x\n"
@@ -699,7 +728,7 @@
     }
   }
 
-  return size;
+  return vend-vstart;
 }
 
 
Index: avrdude/avr.h
===================================================================
RCS file: /sources/avrdude/avrdude/avr.h,v
retrieving revision 1.31
diff -u -r1.31 avr.h
--- avrdude/avr.h	22 Dec 2004 01:52:45 -0000	1.31
+++ avrdude/avr.h	20 Mar 2006 04:34:38 -0000
@@ -35,8 +35,11 @@
 int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                   unsigned long addr, unsigned char * value);
 
-int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
-             int verbose);
+int avr_read_mem(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+		 int start, int size, int verbose);
+
+int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+	     int start, int size, int verbose);
 
 int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                    unsigned long addr);
@@ -44,18 +47,18 @@
 int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                    unsigned long addr, unsigned char data);
 
-int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
-              int verbose);
+int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+	      int verbose);
 
 int avr_signature(PROGRAMMER * pgm, AVRPART * p);
 
-int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
+int avr_verify(AVRPART * p, AVRMEM *v);
 
 int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
 
 int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
 
-int avr_mem_hiaddr(AVRMEM * mem);
+void avr_mem_trim(AVRMEM * mem);
 
 int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
 
Index: avrdude/avr910.c
===================================================================
RCS file: /sources/avrdude/avrdude/avr910.c,v
retrieving revision 1.22
diff -u -r1.22 avr910.c
--- avrdude/avr910.c	18 Sep 2005 00:28:19 -0000	1.22
+++ avrdude/avr910.c	20 Mar 2006 04:34:38 -0000
@@ -151,7 +151,10 @@
   avr910_recv(pgm, sw, sizeof(sw));
 
   avr910_send(pgm, "v", 1);
-  avr910_recv(pgm, hw, sizeof(hw));
+  avr910_recv(pgm, hw, 1);	/* first, read only _one_ byte */
+  if (hw[0]!='?') {
+    avr910_recv(pgm, &hw[1], sizeof(hw)-1);/* now, read second byte */
+  };
 
   /* Get the programmer type (serial or parallel). Expect serial. */
 
@@ -398,12 +401,12 @@
 
 
 static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                                    int page_size, int n_bytes)
+                                    int page_size, int start_byte, int n_bytes)
 {
   unsigned char cmd[] = {'c', 'C'};
   char buf[2];
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int addr = start_byte;
+  unsigned int max_addr = start_byte + n_bytes;
   unsigned int page_addr;
   int page_bytes = page_size;
   int page_wr_cmd_pending = 0;
@@ -459,11 +462,12 @@
 
 
 static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
-                                     AVRMEM * m, int page_size, int n_bytes)
+                                     AVRMEM * m, int page_size, 
+				     int start_byte, int n_bytes)
 {
   char cmd[2];
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int addr = start_byte;
+  unsigned int max_addr = start_byte + n_bytes;
 
   avr910_set_addr(pgm, addr);
 
@@ -489,13 +493,13 @@
 
 
 static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                              int page_size, int n_bytes)
+                              int page_size, int start_byte, int n_bytes)
 {
   if (strcmp(m->desc, "flash") == 0) {
-    return avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
+    return avr910_paged_write_flash(pgm, p, m, page_size, start_byte, n_bytes);
   }
   else if (strcmp(m->desc, "eeprom") == 0) {
-    return avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
+    return avr910_paged_write_eeprom(pgm, p, m, page_size, start_byte, n_bytes);
   }
   else {
     return -2;
@@ -504,7 +508,7 @@
 
 
 static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+                             int page_size, int start_byte, int n_bytes)
 {
   char cmd;
   int rd_size;
@@ -512,6 +516,12 @@
   unsigned int max_addr;
   char buf[2];
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   if (strcmp(m->desc, "flash") == 0) {
     cmd = 'R';
     rd_size = 2;                /* read two bytes per addr */
@@ -536,9 +546,11 @@
       avr910_recv(pgm, buf, 2);
       m->buf[addr*2]   = buf[1];  /* LSB */
       m->buf[addr*2+1] = buf[0];  /* MSB */
+      avr_touch_mem(m, addr*2, 2);
     }
     else {
       avr910_recv(pgm, (char *)&m->buf[addr], 1);
+      avr_touch_mem(m, addr, 1);
     }
 
     addr++;
@@ -563,7 +575,7 @@
   }
 
   avr910_send(pgm, "s", 1);
-  avr910_recv(pgm, (char *)m->buf, 3);
+  avr910_recv(pgm, avr_touch_mem(m, 0, 3), 3);
 
   return 3;
 }
Index: avrdude/avrpart.c
===================================================================
RCS file: /sources/avrdude/avrdude/avrpart.c,v
retrieving revision 1.7
diff -u -r1.7 avrpart.c
--- avrdude/avrpart.c	27 Feb 2006 17:18:42 -0000	1.7
+++ avrdude/avrpart.c	20 Mar 2006 04:34:39 -0000
@@ -233,6 +233,8 @@
               progname, m->desc, m->size);
       return -1;
     }
+    m->use_start = 0;
+    m->use_end = 0;
   }
 
   return 0;
@@ -255,6 +257,8 @@
     exit(1);
   }
   memset(n->buf, 0, n->size);
+  n->use_start = 0;
+  n->use_end = 0;
 
   return n;
 }
@@ -284,6 +288,31 @@
   return NULL;
 }
 
+unsigned char * avr_touch_mem(AVRMEM * m,
+			      unsigned int addr,
+			      unsigned int len)
+{
+  if (addr + len > m->size)
+    return NULL;
+  
+  if (m->use_start >= m->use_end) {
+    m->use_start = addr;
+    m->use_end = addr+len;
+  } else {
+    if (addr < m->use_start)
+      m->use_start = addr;
+    if (addr+len > m->use_end)
+      m->use_end = addr+len;
+  }
+
+#if 0
+  fprintf(stderr, "[touchmem %s %u-%u --> %u-%u]\n",
+	  m->desc, addr, len+addr,
+	  m->use_start, m->use_end);
+#endif
+  
+  return m->buf + addr;
+}
 
 void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
                      int verbose)
Index: avrdude/avrpart.h
===================================================================
RCS file: /sources/avrdude/avrdude/avrpart.h,v
retrieving revision 1.19
diff -u -r1.19 avrpart.h
--- avrdude/avrpart.h	27 Feb 2006 17:18:42 -0000	1.19
+++ avrdude/avrpart.h	20 Mar 2006 04:34:40 -0000
@@ -143,6 +143,8 @@
   int pollindex;              /* stk500 v2 xml file parameter */
 
   unsigned char * buf;        /* pointer to memory buffer */
+  unsigned int use_start,     /* first byte in buf that's been written to */
+               use_end;       /* byte after last used byte of buf */
   OPCODE * op[AVR_OP_MAX];    /* opcodes */
 } AVRMEM;
 
@@ -158,6 +160,7 @@
 int avr_initmem(AVRPART * p);
 AVRMEM * avr_dup_mem(AVRMEM * m);
 AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
+unsigned char * avr_touch_mem(AVRMEM * m, unsigned int addr, unsigned int len);
 void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
                      int verbose);
 
Index: avrdude/butterfly.c
===================================================================
RCS file: /sources/avrdude/avrdude/butterfly.c,v
retrieving revision 1.12
diff -u -r1.12 butterfly.c
--- avrdude/butterfly.c	20 Oct 2005 11:36:19 -0000	1.12
+++ avrdude/butterfly.c	20 Mar 2006 04:34:41 -0000
@@ -64,7 +64,6 @@
 
 #define no_show_func_info()
 
-
 static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
 {
   no_show_func_info();
@@ -106,6 +105,8 @@
   if (c != '\r') {
     fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
             progname, errmsg);
+    fprintf(stderr, "%s: got 0x%02x '%c' when expecting CR\n",
+            progname, c, c);
     exit(1);
   }
 }
@@ -309,14 +310,17 @@
   butterfly_send(pgm, "t", 1);
   fprintf(stderr, "\nProgrammer supports the following devices:\n");
   while (1) {
+    int devcode;
+    AVRPART *part;
     butterfly_recv(pgm, &c, 1);
     if (c == 0)
       break;
-    fprintf(stderr, "    Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
-
-    /* FIXME: Need to lookup devcode and report the device. */
+    devcode = (int)(unsigned char)c;
+    part = locate_part_by_avr910_devcode(part_list, devcode);
+    fprintf(stderr, "    Device code: 0x%02x (%s)\n", devcode,
+	    part? part->desc : "unknown");
 
-    if (p->avr910_devcode == (int)(unsigned char)c)
+    if (p->avr910_devcode == devcode)
       dev_supported = 1;
   };
   fprintf(stderr,"\n");
@@ -325,8 +329,8 @@
     /* FIXME: if nothing matched, we should rather compare the device
        signatures. */
     fprintf(stderr,
-            "%s: error: selected device is not supported by programmer: %s\n",
-            progname, p->id);
+            "%s: error: selected device is not supported by programmer: %s (code 0x%02x)\n",
+            progname, p->id, p->avr910_devcode);
   }
 
   /* Tell the programmer which part we selected. */
@@ -544,10 +548,10 @@
 
 
 static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+                              int page_size, int start_byte, int n_bytes)
 {
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int addr = start_byte;
+  unsigned int max_addr = start_byte + n_bytes;
   char *cmd;
   unsigned int blocksize = buffersize;
 
@@ -593,12 +597,18 @@
 
 
 static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+                             int page_size, int start_byte, int n_bytes)
 {
   unsigned int addr = 0;
   unsigned int max_addr = n_bytes;
   int rd_size = 1;
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   /* check parameter syntax: only "flash" or "eeprom" is allowed */
   if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom")) 
     return -2;
@@ -619,7 +629,7 @@
       cmd[2] = blocksize & 0xff;
 
       butterfly_send(pgm, cmd, 4);
-      butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
+      butterfly_recv(pgm, avr_touch_mem(m, addr, blocksize), blocksize);
 
       addr += blocksize;
 
@@ -644,7 +654,7 @@
   }
 
   butterfly_send(pgm, "s", 1);
-  butterfly_recv(pgm, (char *)m->buf, 3);
+  butterfly_recv(pgm, avr_touch_mem(m, 0, 3), 3);
   /* Returned signature has wrong order. */
   tmp = m->buf[2];
   m->buf[2] = m->buf[0];
Index: avrdude/fileio.c
===================================================================
RCS file: /sources/avrdude/avrdude/fileio.c,v
retrieving revision 1.33
diff -u -r1.33 fileio.c
--- avrdude/fileio.c	16 Sep 2005 21:52:42 -0000	1.33
+++ avrdude/fileio.c	20 Mar 2006 04:34:41 -0000
@@ -54,28 +54,26 @@
              int recsize, int startaddr,
              char * outfile, FILE * outf);
 
-int ihex2b(char * infile, FILE * inf,
-             unsigned char * outbuf, int bufsize);
+int ihex2b(char * infile, FILE * inf, AVRMEM * outmem);
 
 int b2srec(unsigned char * inbuf, int bufsize, 
            int recsize, int startaddr,
            char * outfile, FILE * outf);
 
-int srec2b(char * infile, FILE * inf,
-             unsigned char * outbuf, int bufsize);
+int srec2b(char * infile, FILE * inf, AVRMEM * outmem);
 
 int ihex_readrec(struct ihexrec * ihex, char * rec);
 
 int srec_readrec(struct ihexrec * srec, char * rec);            
 
 int fileio_rbin(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size);
+		char * filename, FILE * f, AVRMEM * buf);
 
 int fileio_ihex(struct fioparms * fio, 
-                  char * filename, FILE * f, unsigned char * buf, int size);
+		char * filename, FILE * f, AVRMEM * buf);
 
 int fileio_srec(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size);
+		char * filename, FILE * f, AVRMEM * buf);
 
 int fmt_autodetect(char * fname);
 
@@ -253,30 +251,27 @@
  *
  * Given an open file 'inf' which contains Intel Hex formated data,
  * parse the file and lay it out within the memory buffer pointed to
- * by outbuf.  The size of outbuf, 'bufsize' is honored; if data would
+ * by outbuf.  The size of outmem, 'outmem->size' is honored; if data would
  * fall outsize of the memory buffer outbuf, an error is generated.
  *
- * Return the maximum memory address within 'outbuf' that was written.
+ * Return the number of bytes transferred to 'outbuf'.
+ * The used range of outbuf is updated.
  * If an error occurs, return -1.
  *
  * */
 
-int ihex2b(char * infile, FILE * inf,
-             unsigned char * outbuf, int bufsize)
+int ihex2b(char * infile, FILE * inf, AVRMEM * outmem)
 {
   char buffer [ MAX_LINE_LEN ];
-  unsigned char * buf;
-  unsigned int nextaddr, baseaddr, maxaddr;
-  int i;
+  unsigned int nextaddr, baseaddr, bytecount;
   int lineno;
   int len;
   struct ihexrec ihex;
   int rc;
 
   lineno   = 0;
-  buf      = outbuf;
   baseaddr = 0;
-  maxaddr  = 0;
+  bytecount = 0;
 
   while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
     lineno++;
@@ -303,21 +298,18 @@
 
       case 0: /* data record */
         nextaddr = ihex.loadofs + baseaddr;
-        if (nextaddr + ihex.reclen > bufsize) {
+        if (nextaddr + ihex.reclen > outmem->size) {
           fprintf(stderr, 
                   "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
                   progname, nextaddr+ihex.reclen, lineno, infile);
           return -1;
         }
-        for (i=0; i<ihex.reclen; i++) {
-          buf[nextaddr+i] = ihex.data[i];
-        }
-        if (nextaddr+ihex.reclen > maxaddr)
-          maxaddr = nextaddr+ihex.reclen;
+	memcpy(avr_touch_mem(outmem, nextaddr, ihex.reclen), ihex.data, ihex.reclen);
+	bytecount += ihex.reclen;
         break;
 
       case 1: /* end of file record */
-        return maxaddr;
+	return bytecount;
         break;
 
       case 2: /* extended segment address record */
@@ -352,7 +344,7 @@
           "file \"%s\"\n",
           progname, infile);
 
-  return maxaddr;
+  return bytecount;
 }
 
 
@@ -538,13 +530,10 @@
 }
 
 
-int srec2b(char * infile, FILE * inf,
-           unsigned char * outbuf, int bufsize)
+int srec2b(char * infile, FILE * inf, AVRMEM * outmem)
 {
   char buffer [ MAX_LINE_LEN ];
-  unsigned char * buf;
-  unsigned int nextaddr, baseaddr, maxaddr;
-  int i;
+  unsigned int nextaddr, baseaddr, bytecount;
   int lineno;
   int len;
   struct ihexrec srec;
@@ -555,9 +544,8 @@
   char * msg = 0;
 
   lineno   = 0;
-  buf      = outbuf;
   baseaddr = 0;
-  maxaddr  = 0;
+  bytecount= 0;
   reccount = 0;
 
   while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
@@ -625,7 +613,7 @@
       case 0x37: /* S7 Record - end record for 32 bit address data */
       case 0x38: /* S8 Record - end record for 24 bit address data */
       case 0x39: /* S9 Record - end record for 16 bit address data */
-        return maxaddr;
+        return bytecount;
 
       default:
         fprintf(stderr, 
@@ -637,14 +625,13 @@
 
     if (datarec == 1) {
       nextaddr = srec.loadofs + baseaddr;
-      if (nextaddr + srec.reclen > bufsize) {
+      if (nextaddr + srec.reclen > outmem->size) {
         fprintf(stderr, msg, progname, nextaddr+srec.reclen, lineno, infile);
         return -1;
       }
-      for (i=0; i<srec.reclen; i++) 
-        buf[nextaddr+i] = srec.data[i];
-      if (nextaddr+srec.reclen > maxaddr)
-        maxaddr = nextaddr+srec.reclen;
+      memcpy(avr_touch_mem(outmem, nextaddr, srec.reclen),
+	     srec.data, srec.reclen);
+      bytecount+=srec.reclen;
       reccount++;	
     }
 
@@ -655,21 +642,28 @@
           "file \"%s\"\n",
           progname, infile);
 
-  return maxaddr;
+  return bytecount;
 }
 
 
 int fileio_rbin(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size)
+		char * filename, FILE * f, AVRMEM * mem)
 {
   int rc;
+  int size;
 
   switch (fio->op) {
     case FIO_READ:
-      rc = fread(buf, 1, size, f);
+      size = mem->size;
+      rc = fread(mem->buf, 1, mem->size, f);
+      if (rc > 0)
+	  avr_touch_mem(mem, 0, rc);
       break;
     case FIO_WRITE:
-      rc = fwrite(buf, 1, size, f);
+      /* Raw binary can't store addresses, so always write starting
+	 from address 0 */
+      size = mem->use_end;
+      rc = fwrite(mem->buf, 1, mem->use_end, f);
       break;
     default:
       fprintf(stderr, "%s: fileio: invalid operation=%d\n",
@@ -677,7 +671,7 @@
       return -1;
   }
 
-  if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
+  if (rc < 0 || (fio->op == FIO_WRITE && rc < mem->use_end)) {
     fprintf(stderr, 
             "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n", 
             progname, fio->iodesc, fio->dir, filename, strerror(errno),
@@ -690,7 +684,7 @@
 
 
 int fileio_imm(struct fioparms * fio,
-               char * filename, FILE * f, unsigned char * buf, int size)
+               char * filename, FILE * f, AVRMEM * mem)
 {
   int rc = 0;
   char * e, * p;
@@ -701,7 +695,7 @@
     case FIO_READ:
       loc = 0;
       p = strtok(filename, " ,");
-      while (p != NULL && loc < size) {
+      while (p != NULL && loc < mem->size) {
         b = strtoul(p, &e, 0);
         if (*e != 0) {
           fprintf(stderr,
@@ -709,7 +703,7 @@
                   progname, p);
           return -1;
         }
-        buf[loc++] = b;
+	*avr_touch_mem(mem, loc++, 1) = b;
         p = strtok(NULL, " ,");
         rc = loc;
       }
@@ -720,11 +714,11 @@
       return -1;
   }
 
-  if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
+  if (rc < 0 /* || (fio->op == FIO_WRITE && rc < size) */ ) {
     fprintf(stderr, 
-            "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n", 
+            "%s: %s error %s %s: %s; %s %d bytes\n", 
             progname, fio->iodesc, fio->dir, filename, strerror(errno),
-            fio->rw, rc, size);
+            fio->rw, rc);
     return -1;
   }
 
@@ -733,20 +727,20 @@
 
 
 int fileio_ihex(struct fioparms * fio, 
-                  char * filename, FILE * f, unsigned char * buf, int size)
+		char * filename, FILE * f, AVRMEM * mem)
 {
   int rc;
 
   switch (fio->op) {
     case FIO_WRITE:
-      rc = b2ihex(buf, size, 32, 0, filename, f);
+      rc = b2ihex(mem->buf + mem->use_start, mem->use_end - mem->use_start, 32, 0, filename, f);
       if (rc < 0) {
         return -1;
       }
       break;
 
     case FIO_READ:
-      rc = ihex2b(filename, f, buf, size);
+      rc = ihex2b(filename, f, mem);
       if (rc < 0)
         return -1;
       break;
@@ -763,20 +757,20 @@
 
 
 int fileio_srec(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size)
+		char * filename, FILE * f, AVRMEM * mem)
 {
   int rc;
 
   switch (fio->op) {
     case FIO_WRITE:
-      rc = b2srec(buf, size, 32, 0, filename, f);
+      rc = b2srec(mem->buf + mem->use_start, mem->use_end - mem->use_start, 32, 0, filename, f);
       if (rc < 0) {
         return -1;
       }
       break;
 
     case FIO_READ:
-      rc = srec2b(filename, f, buf, size);
+      rc = srec2b(filename, f, mem);
       if (rc < 0)
         return -1;
       break;
@@ -886,15 +880,19 @@
   return -1;
 }
 
-
-
+/*
+ * Perform operation 'op' (FIO_READ or FIO_WRITE) with the specified
+ * file and format, and the specified memory space. Returns the number
+ * of bytes read or written (may be different from the maxaddr, if it
+ * started at a nonzero address) and, when reading, updates the memory
+ * buffer's use range.
+ */
 int fileio(int op, char * filename, FILEFMT format, 
-             struct avrpart * p, char * memtype, int size)
+	   struct avrpart * p, char * memtype)
 {
   int rc;
   FILE * f;
   char * fname;
-  unsigned char * buf;
   struct fioparms fio;
   AVRMEM * mem;
   int using_stdio;
@@ -926,14 +924,12 @@
   }
   #endif
 
-  /* point at the requested memory buffer */
-  buf = mem->buf;
-  if (fio.op == FIO_READ)
-    size = mem->size;
-
   if (fio.op == FIO_READ) {
     /* 0xff fill unspecified memory */
-    memset(buf, 0xff, size);
+    memset(mem->buf, 0xff, mem->size);
+    /* mark as untouched */
+    mem->use_start = 0;
+    mem->use_end = 0;
   }
 
   using_stdio = 0;
@@ -990,19 +986,19 @@
 
   switch (format) {
     case FMT_IHEX:
-      rc = fileio_ihex(&fio, fname, f, buf, size);
+      rc = fileio_ihex(&fio, fname, f, mem);
       break;
 
     case FMT_SREC:
-      rc = fileio_srec(&fio, fname, f, buf, size);
+      rc = fileio_srec(&fio, fname, f, mem);
       break;
 
     case FMT_RBIN:
-      rc = fileio_rbin(&fio, fname, f, buf, size);
+      rc = fileio_rbin(&fio, fname, f, mem);
       break;
 
     case FMT_IMM:
-      rc = fileio_imm(&fio, fname, f, buf, size);
+      rc = fileio_imm(&fio, fname, f, mem);
       break;
 
     default:
@@ -1017,7 +1013,7 @@
        * if we are reading flash, just mark the size as being the
        * highest non-0xff byte
        */
-      rc = avr_mem_hiaddr(mem);
+      avr_mem_trim(mem);
     }
   }
 
Index: avrdude/fileio.h
===================================================================
RCS file: /sources/avrdude/avrdude/fileio.h,v
retrieving revision 1.14
diff -u -r1.14 fileio.h
--- avrdude/fileio.h	22 Dec 2004 01:52:45 -0000	1.14
+++ avrdude/fileio.h	20 Mar 2006 04:34:41 -0000
@@ -48,6 +48,6 @@
 int fileio_setparms(int op, struct fioparms * fp);
 
 int fileio(int op, char * filename, FILEFMT format, 
-           struct avrpart * p, char * memtype, int size);
+           struct avrpart * p, char * memtype);
 
 #endif
Index: avrdude/jtagmkI.c
===================================================================
RCS file: /sources/avrdude/avrdude/jtagmkI.c,v
retrieving revision 1.3
diff -u -r1.3 jtagmkI.c
--- avrdude/jtagmkI.c	28 Nov 2005 21:11:18 -0000	1.3
+++ avrdude/jtagmkI.c	20 Mar 2006 04:34:43 -0000
@@ -726,7 +726,7 @@
 
 
 static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+			       int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size, send_size, tries;
   unsigned char cmd[6], *datacmd;
@@ -736,9 +736,15 @@
 #define MAXTRIES 3
 
   if (verbose >= 2)
-    fprintf(stderr, "%s: jtagmkI_paged_write(.., %s, %d, %d)\n",
-	    progname, m->desc, page_size, n_bytes);
+    fprintf(stderr, "%s: jtagmkI_paged_write(.., %s, %d, %d, %d)\n",
+	    progname, m->desc, page_size, start_byte, n_bytes);
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+  
   if (jtagmkI_program_enable(pgm) < 0)
     return -1;
 
@@ -864,13 +870,19 @@
 }
 
 static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+			      int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size, read_size, is_flash = 0, tries;
   unsigned char cmd[6], resp[256 * 2 + 3];
   long otimeout = serial_recv_timeout;
 #define MAXTRIES 3
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkI_paged_load(.., %s, %d, %d)\n",
 	    progname, m->desc, page_size, n_bytes);
@@ -950,7 +962,7 @@
         fprintf(stderr, "OK\n");
     }
 
-    memcpy(m->buf + addr, resp + 1, block_size);
+    memcpy(avr_touch_mem(m, addr, block_size), resp + 1, block_size);
   }
   serial_recv_timeout = otimeout;
 
Index: avrdude/jtagmkII.c
===================================================================
RCS file: /sources/avrdude/avrdude/jtagmkII.c,v
retrieving revision 1.11
diff -u -r1.11 jtagmkII.c
--- avrdude/jtagmkII.c	12 Jan 2006 23:13:50 -0000	1.11
+++ avrdude/jtagmkII.c	20 Mar 2006 04:34:45 -0000
@@ -1159,7 +1159,7 @@
 
 
 static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+				int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size;
   unsigned char *cmd;
@@ -1168,9 +1168,15 @@
   long otimeout = serial_recv_timeout;
 
   if (verbose >= 2)
-    fprintf(stderr, "%s: jtagmkII_paged_write(.., %s, %d, %d)\n",
-	    progname, m->desc, page_size, n_bytes);
+    fprintf(stderr, "%s: jtagmkII_paged_write(.., %s, %d, %d, %d)\n",
+	    progname, m->desc, page_size, start_byte, n_bytes);
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+  
   if (jtagmkII_program_enable(pgm) < 0)
     return -1;
 
@@ -1274,7 +1280,7 @@
 }
 
 static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+			       int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size;
   unsigned char cmd[10];
@@ -1282,6 +1288,12 @@
   int status, tries;
   long otimeout = serial_recv_timeout;
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkII_paged_load(.., %s, %d, %d)\n",
 	    progname, m->desc, page_size, n_bytes);
@@ -1356,7 +1368,7 @@
       serial_recv_timeout = otimeout;
       return -1;
     }
-    memcpy(m->buf + addr, resp + 1, status);
+    memcpy(avr_touch_mem(m, addr, status), resp + 1, status);
     free(resp);
   }
   serial_recv_timeout = otimeout;
Index: avrdude/main.c
===================================================================
RCS file: /sources/avrdude/avrdude/main.c,v
retrieving revision 1.114
diff -u -r1.114 main.c
--- avrdude/main.c	27 Feb 2006 17:18:42 -0000	1.114
+++ avrdude/main.c	20 Mar 2006 04:34:46 -0000
@@ -489,8 +489,7 @@
 int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
           int verify)
 {
-  struct avrpart * v;
-  AVRMEM * mem;
+    AVRMEM * mem, * vmem;
   int size, vsize;
   int rc;
 
@@ -510,7 +509,7 @@
             progname, mem->desc);
 	  }
     report_progress(0,1,"Reading");
-    rc = avr_read(pgm, p, upd->memtype, 0, 1);
+    rc = avr_read(pgm, p, upd->memtype, 0, 0, 1);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", 
               progname, mem->desc, rc);
@@ -525,7 +524,7 @@
             progname, 
             strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
     }
-    rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
+    rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype);
     if (rc < 0) {
       fprintf(stderr, "%s: write to file '%s' failed\n", 
               progname, upd->filename);
@@ -543,7 +542,7 @@
             progname, 
             strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
     }
-    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
+    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype);
     if (rc < 0) {
       fprintf(stderr, "%s: write to file '%s' failed\n", 
               progname, upd->filename);
@@ -561,7 +560,7 @@
 
     if (!nowrite) {
       report_progress(0,1,"Writing");
-      rc = avr_write(pgm, p, upd->memtype, size, 1);
+      rc = avr_write(pgm, p, upd->memtype, 1);
       report_progress(1,1,NULL);
     }
     else {
@@ -569,7 +568,7 @@
        * test mode, don't actually write to the chip, output the buffer
        * to stdout in intel hex instead 
        */
-      rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
+      rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype);
     }
 
     if (rc < 0) {
@@ -593,7 +592,7 @@
      */
     pgm->vfy_led(pgm, ON);
 
-    v = avr_dup_part(p);
+    vmem = avr_dup_mem(mem);
 
     if (quell_progress < 2) {
       fprintf(stderr, "%s: verifying %s memory against %s:\n", 
@@ -603,7 +602,7 @@
             progname, mem->desc, upd->filename);
     }
 
-    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
+    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype);
     if (rc < 0) {
       fprintf(stderr, "%s: read from file '%s' failed\n", 
               progname, upd->filename);
@@ -618,7 +617,8 @@
     }
 
     report_progress (0,1,"Reading");
-    rc = avr_read(pgm, v, upd->memtype, size, 1);
+    rc = avr_read_mem(pgm, p, vmem,
+		      mem->use_start, mem->use_end - mem->use_start, 1);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", 
               progname, mem->desc, rc);
@@ -632,7 +632,7 @@
     if (quell_progress < 2) {
       fprintf(stderr, "%s: verifying ...\n", progname);
     }
-    rc = avr_verify(p, v, upd->memtype, size);
+    rc = avr_verify(p, vmem);
     if (rc < 0) {
       fprintf(stderr, "%s: verification error; content mismatch\n", 
               progname);
Index: avrdude/pgm.h
===================================================================
RCS file: /sources/avrdude/avrdude/pgm.h,v
retrieving revision 1.24
diff -u -r1.24 pgm.h
--- avrdude/pgm.h	3 Nov 2005 22:37:37 -0000	1.24
+++ avrdude/pgm.h	20 Mar 2006 04:34:46 -0000
@@ -67,9 +67,9 @@
   int  (*open)           (struct programmer_t * pgm, char * port);
   void (*close)          (struct programmer_t * pgm);
   int  (*paged_write)    (struct programmer_t * pgm, AVRPART * p, AVRMEM * m, 
-                          int page_size, int n_bytes);
+                          int page_size, int start_byte, int n_bytes);
   int  (*paged_load)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
-                          int page_size, int n_bytes);
+                          int page_size, int start_byte, int n_bytes);
   void (*write_setup)    (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
   int  (*write_byte)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
                           unsigned long addr, unsigned char value);
Index: avrdude/stk500.c
===================================================================
RCS file: /sources/avrdude/avrdude/stk500.c,v
retrieving revision 1.48
diff -u -r1.48 stk500.c
--- avrdude/stk500.c	30 Aug 2005 01:30:05 -0000	1.48
+++ avrdude/stk500.c	20 Mar 2006 04:34:47 -0000
@@ -623,7 +623,7 @@
 
 
 static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+                              int page_size, int start_byte, int n_bytes)
 {
   unsigned char buf[16];
   int memtype;
@@ -634,6 +634,12 @@
   unsigned int n;
   int flash;
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+  
   if (page_size == 0) {
     page_size = 128;
   }
@@ -703,7 +709,7 @@
     buf[3] = memtype;
     stk500_send(pgm, buf, 4);
 
-	stk500_send(pgm, &m->buf[addr], block_size);
+    stk500_send(pgm, &m->buf[addr], block_size);
 
     buf[0] = Sync_CRC_EOP;
     stk500_send(pgm, buf, 1);
@@ -755,7 +761,7 @@
 }
 
 static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+                             int page_size, int start_byte, int n_bytes)
 {
   unsigned char buf[16];
   int memtype;
@@ -765,6 +771,12 @@
   unsigned int n;
   int block_size;
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   if (strcmp(m->desc, "flash") == 0) {
     memtype = 'F';
   }
@@ -842,6 +854,7 @@
               progname, Resp_STK_INSYNC, buf[0]);
       return -5;
     }
+    avr_touch_mem(m, addr, block_size);
   }
 
   return n_bytes;
Index: avrdude/stk500v2.c
===================================================================
RCS file: /sources/avrdude/avrdude/stk500v2.c,v
retrieving revision 1.11
diff -u -r1.11 stk500v2.c
--- avrdude/stk500v2.c	17 Jan 2006 21:11:39 -0000	1.11
+++ avrdude/stk500v2.c	20 Mar 2006 04:34:49 -0000
@@ -552,7 +552,7 @@
 
 
 static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+				int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size, last_addr;
   int a_div=1;
@@ -562,7 +562,13 @@
   int result;
   OPCODE * rop, * wop;
 
-  DEBUG("STK500V2: stk500v2_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+  DEBUG("STK500V2: stk500v2_paged_write(..,%s,%d,%d,%d)\n",m->desc,page_size,start_byte,n_bytes);
+
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
 
   if (page_size == 0) page_size = 256;
 
@@ -688,7 +694,7 @@
 }
 
 static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                             int page_size, int n_bytes)
+			       int page_size, int start_byte, int n_bytes)
 {
   int addr, block_size;
   unsigned char commandbuf[4];
@@ -697,6 +703,12 @@
   int result;
   OPCODE * rop;
 
+#warning FIXME: support nonzero start_byte
+  if (start_byte > 0) {
+      n_bytes += start_byte;
+      start_byte = 0;
+  }
+
   DEBUG("STK500V2: stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
 
   page_size = m->readsize;
@@ -750,7 +762,7 @@
     }
 #endif
 
-    memcpy(&m->buf[addr], &buf[2], block_size);
+    memcpy(avr_touch_mem(m, addr, block_size), &buf[2], block_size);
   }
 
   return n_bytes;
