diff -rup avrdude-5.4-orig/avr.c avrdude-5.4/avr.c
--- avrdude-5.4-orig/avr.c	2007-05-16 16:15:13.000000000 -0400
+++ avrdude-5.4/avr.c	2007-05-26 13:44:49.000000000 -0400
@@ -146,7 +146,7 @@ int avr_mem_hiaddr(AVRMEM * mem)
  * 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 verbose, int moffset, int foffset)
 {
   unsigned char    rbyte;
   unsigned long    i;
@@ -172,7 +172,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART *
   memset(buf, 0xff, size);
 
   if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
-    if (pgm->paged_load != NULL && mem->page_size != 0) {
+    if ((pgm->paged_load != NULL) && (mem->page_size != 0) && (foffset == 0) && (moffset == 0)) {
       /*
        * the programmer supports a paged mode read, perhaps more
        * efficiently than we can read it directly, so use its routine
@@ -194,7 +194,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART *
     }
   }
 
-  for (i=0; i<size; i++) {
+  for (i = moffset; i < (size + moffset); i++) {
     rc = pgm->read_byte(pgm, p, mem, i, &rbyte);
     if (rc != 0) {
       fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
@@ -204,8 +204,8 @@ int avr_read(PROGRAMMER * pgm, AVRPART *
                 memtype);
       return -2;
     }
-    buf[i] = rbyte;
-    report_progress(i, size, NULL);
+    buf[(i - moffset)] = rbyte;
+    report_progress((i - moffset), size, NULL);
   }
 
   if (strcasecmp(mem->desc, "flash") == 0)
@@ -535,7 +535,7 @@ int avr_write_byte(PROGRAMMER * pgm, AVR
  * 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 verbose, int moffset, int foffset)
 {
   int              rc;
   int              wsize;
@@ -569,7 +569,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART 
   }
 
   if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
-    if (pgm->paged_write != NULL && m->page_size != 0) {
+    if ((pgm->paged_write != NULL) && (m->page_size != 0) && (foffset == 0) && (moffset == 0)) {
       /*
        * the programmer supports a paged mode write, perhaps more
        * efficiently than we can read it directly, so use its routine
@@ -584,9 +584,9 @@ int avr_write(PROGRAMMER * pgm, AVRPART 
       pgm->write_setup(pgm, p, m);
   }
 
-  for (i=0; i<wsize; i++) {
-    data = m->buf[i];
-    report_progress(i, wsize, NULL);
+  for (i = moffset; i < (moffset + wsize); i++) {
+    data = m->buf[(i - moffset) + foffset];
+    report_progress((i - moffset), wsize, NULL);
 
     rc = avr_write_byte(pgm, p, m, i, data);
     if (rc) {
@@ -602,7 +602,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART 
        * write
        */
       if (((i % m->page_size) == m->page_size-1) ||
-          (i == wsize-1)) {
+          (i == (moffset + wsize - 1))) {
         rc = avr_write_page(pgm, p, m, i);
         if (rc) {
           fprintf(stderr,
@@ -626,7 +626,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART 
     }
   }
 
-  return i;
+  return (i - moffset);
 }
 
 
@@ -639,7 +639,7 @@ int avr_signature(PROGRAMMER * pgm, AVRP
   int rc;
 
   report_progress (0,1,"Reading");
-  rc = avr_read(pgm, p, "signature", 0, 0);
+  rc = avr_read(pgm, p, "signature", 0, 0, 0, 0);
   if (rc < 0) {
     fprintf(stderr,
             "%s: error reading signature data for part \"%s\", rc=%d\n",
@@ -659,7 +659,7 @@ int avr_signature(PROGRAMMER * pgm, AVRP
  *
  * 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, AVRPART * v, char * memtype, int size, int moffset, int foffset)
 {
   int i;
   unsigned char * buf1, * buf2;
@@ -698,12 +698,12 @@ int avr_verify(AVRPART * p, AVRPART * v,
   }
 
   for (i=0; i<size; i++) {
-    if (buf1[i] != buf2[i]) {
+    if (buf1[i + foffset] != buf2[i]) {
       fprintf(stderr, 
-              "%s: verification error, first mismatch at byte 0x%04x\n"
-              "%s0x%02x != 0x%02x\n",
+              "%s: verification error, first mismatch at byte %d\n"
+              "%s(file 0x%04x) 0x%02x != 0x%02x (memory 0x%04x)\n",
               progname, i, 
-              progbuf, buf1[i], buf2[i]);
+              progbuf, (i + foffset), buf1[i + foffset], buf2[i + moffset], (i + moffset));
       return -1;
     }
   }
Only in avrdude-5.4: avrdude.kdevelop
Only in avrdude-5.4-orig: avrdude.spec
diff -rup avrdude-5.4-orig/avr.h avrdude-5.4/avr.h
--- avrdude-5.4-orig/avr.h	2007-01-24 17:43:46.000000000 -0500
+++ avrdude-5.4/avr.h	2007-05-26 13:45:51.000000000 -0400
@@ -41,7 +41,7 @@ int avr_read_byte_default(PROGRAMMER * p
 			  unsigned long addr, unsigned char * value);
 
 int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
-             int verbose);
+             int verbose, int moffset, int foffset);
 
 int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                    unsigned long addr);
@@ -53,11 +53,11 @@ int avr_write_byte_default(PROGRAMMER * 
 			   unsigned long addr, unsigned char data);
 
 int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
-              int verbose);
+              int verbose, int moffset, int foffset);
 
 int avr_signature(PROGRAMMER * pgm, AVRPART * p);
 
-int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
+int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size, int moffset, int foffset);
 
 int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
 
Only in avrdude-5.4: debug
Only in avrdude-5.4-orig/doc: avrdude.info
Only in avrdude-5.4-orig/doc: stamp-vti
Only in avrdude-5.4-orig/doc: version.texi
Only in avrdude-5.4: Doxyfile
diff -rup avrdude-5.4-orig/main.c avrdude-5.4/main.c
--- avrdude-5.4-orig/main.c	2007-05-05 17:33:01.000000000 -0400
+++ avrdude-5.4/main.c	2007-05-26 13:47:48.000000000 -0400
@@ -100,10 +100,13 @@ static void usage(void)
  "  -F                         Override invalid signature check.\n"
  "  -e                         Perform a chip erase.\n"
  "  -O                         Perform RC oscillator calibration (see AVR053). \n"
- "  -U <memtype>:r|w|v:<filename>[:format]\n"
+ "  -U <memtype>:r|w|v:<filename>[:format][,length][,fileoffset][,memoffset]\n"
  "                             Memory operation specification.\n"
  "                             Multiple -U options are allowed, each request\n"
  "                             is performed in the order specified.\n"
+ "                             Length and offsets are measured in bytes,\n"
+ "                             therefore must be multiples of two,\n"
+ "                             because the AVR memory is arranged in words.\n"
  "  -n                         Do not write anything to the device.\n"
  "  -V                         Do not verify.\n"
  "  -u                         Disable safemode, default when running from a script.\n"
diff -rup avrdude-5.4-orig/update.c avrdude-5.4/update.c
--- avrdude-5.4-orig/update.c	2007-01-24 17:43:46.000000000 -0500
+++ avrdude-5.4/update.c	2007-05-26 14:34:19.000000000 -0400
@@ -36,7 +36,7 @@
 UPDATE * parse_op(char * s)
 {
   char buf[1024];
-  char * p, * cp, c;
+  char * p, * cp, c, * end;
   UPDATE * upd;
   int i;
   size_t fnlen;
@@ -131,9 +131,6 @@ UPDATE * parse_op(char * s)
     fnlen = p - cp;
     upd->filename = (char *)malloc(fnlen +1);
     c = *++p;
-    if (c && p[1])
-      /* More than one char - force failure below. */
-      c = '?';
     switch (c) {
       case 'a': upd->format = FMT_AUTO; break;
       case 's': upd->format = FMT_SREC; break;
@@ -153,6 +150,75 @@ UPDATE * parse_op(char * s)
     }
   }
 
+  // allow the use of offsets if accessing flash or eeprom
+  if ((strcmp(upd->memtype, "flash") == 0) || (strcmp(upd->memtype, "eeprom") == 0)) 
+  {
+    /*
+     * parse the length component.  
+    */
+    if (p != NULL) {
+      p = strchr(p, ',');
+    }
+    if (p == NULL) {
+      // no length specified so do nothing
+      upd->length = 0;
+      upd->foffset = 0;
+      upd->moffset = 0;
+    } else {
+      p++;
+      upd->length = (int) strtol(p, &end, 0);
+      if ((upd->length % 2) == 1) {
+        fprintf(stderr, "\n%s: length specifier must be a multiple of two, you specified %d\n",
+                progname, upd->length);
+        free(upd->memtype);
+        free(upd);
+        return NULL;
+      }
+    }
+    /*
+     * parse the file offset component.  
+    */
+    if (p != NULL) {
+      p = strchr(p, ',');
+    }
+    if (p == NULL) {
+      // no offset specified so do nothing
+      upd->foffset = 0;
+      upd->moffset = 0;
+    } else {
+      p++;
+      upd->foffset = (int) strtol(p, &end, 0);
+      if ((upd->foffset % 2) == 1) {
+        fprintf(stderr, "\n%s: file offset specifier must be a multiple of two, you specified %d\n",
+                progname, upd->foffset);
+        free(upd->memtype);
+        free(upd);
+        return NULL;
+      }
+    }
+
+    /*
+     * Now, parse the memory offset component.  
+    */
+    if (p != NULL) {
+      p = strchr(p, ',');
+    }
+    if (p == NULL) {
+      // no offset specified so do nothing
+      upd->moffset = 0;
+    } else {
+      p++;
+      upd->moffset = (int) strtol(p, &end, 0);
+      if ((upd->moffset % 2) == 1) {
+        fprintf(stderr, "\n%s: memory offset specifier must be a multiple of two, you specified %d\n",
+                progname, upd->moffset);
+        free(upd->memtype);
+        free(upd);
+        return NULL;
+      }
+    }
+  }
+
   if (upd->filename == NULL) {
     fprintf(stderr, "%s: out of memory\n", progname);
     free(upd->memtype);
@@ -224,8 +290,14 @@ int do_op(PROGRAMMER * pgm, struct avrpa
       fprintf(stderr, "%s: reading %s memory:\n",
             progname, mem->desc);
 	  }
+
+    if (upd->moffset > 0) {
+      fprintf(stderr, "%s: reading %d bytes from %s starting at address 0x%04x\n",
+              progname, upd->length, upd->memtype, upd->moffset);
+    }
+
     report_progress(0,1,"Reading");
-    rc = avr_read(pgm, p, upd->memtype, 0, 1);
+    rc = avr_read(pgm, p, upd->memtype, upd->length, 1, upd->moffset, upd->foffset);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
               progname, mem->desc, rc);
@@ -258,14 +330,23 @@ int do_op(PROGRAMMER * pgm, struct avrpa
             progname,
             strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
     }
+
+    if (upd->length > 0) {
+      fprintf(stderr, "%s: writing %d bytes to %s starting at offset 0x%04x\n",
+              progname, upd->length, upd->memtype, upd->moffset);
+    }
+
     rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
     if (rc < 0) {
-      fprintf(stderr, "%s: write to file '%s' failed\n",
+      fprintf(stderr, "%s: reading file '%s' failed\n",
               progname, upd->filename);
       return -1;
     }
     size = rc;
 
+    if (upd->length > 0) {
+      size = upd->length;
+    }
     /*
      * write the buffer contents to the selected memory type
      */
@@ -276,7 +357,7 @@ int do_op(PROGRAMMER * pgm, struct avrpa
 
     if (!nowrite) {
       report_progress(0,1,"Writing");
-      rc = avr_write(pgm, p, upd->memtype, size, 1);
+      rc = avr_write(pgm, p, upd->memtype, size, 1, upd->moffset, upd->foffset);
       report_progress(1,1,NULL);
     }
     else {
@@ -325,6 +406,11 @@ int do_op(PROGRAMMER * pgm, struct avrpa
       return -1;
     }
     size = rc;
+
+    if (upd->length > 0) {
+      size = upd->length;
+    }
+
     if (quell_progress < 2) {
       fprintf(stderr, "%s: input file %s contains %d bytes\n",
             progname, upd->filename, size);
@@ -333,7 +419,7 @@ int do_op(PROGRAMMER * pgm, struct avrpa
     }
 
     report_progress (0,1,"Reading");
-    rc = avr_read(pgm, v, upd->memtype, size, 1);
+    rc = avr_read(pgm, v, upd->memtype, size, 1, upd->moffset, upd->foffset);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
               progname, mem->desc, rc);
@@ -347,7 +433,7 @@ int do_op(PROGRAMMER * pgm, struct avrpa
     if (quell_progress < 2) {
       fprintf(stderr, "%s: verifying ...\n", progname);
     }
-    rc = avr_verify(p, v, upd->memtype, size);
+    rc = avr_verify(p, v, upd->memtype, size, upd->moffset, upd->foffset);
     if (rc < 0) {
       fprintf(stderr, "%s: verification error; content mismatch\n",
               progname);
diff -rup avrdude-5.4-orig/update.h avrdude-5.4/update.h
--- avrdude-5.4-orig/update.h	2007-01-24 17:43:46.000000000 -0500
+++ avrdude-5.4/update.h	2007-05-26 14:04:27.000000000 -0400
@@ -31,6 +31,9 @@ enum {
 
 
 typedef struct update_t {
+  int    length;
+  int    foffset;
+  int    moffset;
   char * memtype;
   int    op;
   char * filename;
