Только в avrdude-5.11.1/: avrdude.spec
diff -B -u -r avrdude-5.11.1/avrpart.h avrdude-5.11.1.new/avrpart.h
--- avrdude-5.11.1/avrpart.h	2011-09-15 18:57:51.000000000 +0400
+++ avrdude-5.11.1.new/avrpart.h	2013-07-25 19:01:28.000000000 +0400
@@ -170,6 +170,7 @@
   int page_size;              /* size of memory page (if page addressed) */
   int num_pages;              /* number of pages (if page addressed) */
   unsigned int offset;        /* offset in IO memory (ATxmega) */
+  int start_address;          /* start address of programming region */
   int min_write_delay;        /* microseconds */
   int max_write_delay;        /* microseconds */
   int pwroff_after_write;     /* after this memory type is written to,
diff -B -u -r avrdude-5.11.1/config_gram.y avrdude-5.11.1.new/config_gram.y
--- avrdude-5.11.1/config_gram.y	2011-09-15 18:57:51.000000000 +0400
+++ avrdude-5.11.1.new/config_gram.y	2013-07-25 19:14:14.000000000 +0400
@@ -336,6 +336,7 @@
        */
       for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
         m = ldata(ln);
+        m->start_address = -1;
         if (m->paged) {
           if (m->page_size == 0) {
             fprintf(stderr, 
Только в avrdude-5.11.1/doc: avrdude.info
Только в avrdude-5.11.1/doc: stamp-vti
Только в avrdude-5.11.1/doc: version.texi
diff -B -u -r avrdude-5.11.1/fileio.c avrdude-5.11.1.new/fileio.c
--- avrdude-5.11.1/fileio.c	2011-09-15 18:37:05.000000000 +0400
+++ avrdude-5.11.1.new/fileio.c	2013-07-26 12:37:16.000000000 +0400
@@ -51,14 +51,14 @@
              int recsize, int startaddr,
              char * outfile, FILE * outf);
 
-static int ihex2b(char * infile, FILE * inf,
+static int ihex2b(char * infile, FILE * inf, unsigned int * startaddr,
              unsigned char * outbuf, int bufsize);
 
 static int b2srec(unsigned char * inbuf, int bufsize, 
            int recsize, int startaddr,
            char * outfile, FILE * outf);
 
-static int srec2b(char * infile, FILE * inf,
+static int srec2b(char * infile, FILE * inf, unsigned int * startaddr,
              unsigned char * outbuf, int bufsize);
 
 static int ihex_readrec(struct ihexrec * ihex, char * rec);
@@ -261,7 +261,7 @@
  * If an error occurs, return -1.
  *
  * */
-static int ihex2b(char * infile, FILE * inf,
+static int ihex2b(char * infile, FILE * inf, unsigned int *start,
              unsigned char * outbuf, int bufsize)
 {
   char buffer [ MAX_LINE_LEN ];
@@ -272,6 +272,7 @@
   int len;
   struct ihexrec ihex;
   int rc;
+  unsigned int startaddr;
 
   lineno      = 0;
   buf         = outbuf;
@@ -279,6 +280,7 @@
   maxaddr     = 0;
   offsetaddr  = 0;
   nextaddr    = 0;
+  startaddr   = 0xffffffff;
 
   while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
     lineno++;
@@ -304,6 +306,8 @@
     switch (ihex.rectyp) {
       case 0: /* data record */
         nextaddr = ihex.loadofs + baseaddr;
+	if (nextaddr-offsetaddr < startaddr)
+		startaddr = nextaddr;
         if ((nextaddr + ihex.reclen) > (bufsize+offsetaddr)) {
           fprintf(stderr, 
                   "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
@@ -318,6 +322,8 @@
         break;
 
       case 1: /* end of file record */
+	if (start)
+		*start = startaddr;
         return maxaddr-offsetaddr;
         break;
 
@@ -353,7 +359,8 @@
           "%s: WARNING: no end of file record found for Intel Hex "
           "file \"%s\"\n",
           progname, infile);
-
+  if (start)
+	  *start = startaddr;
   return maxaddr-offsetaddr;
 }
 
@@ -539,7 +546,7 @@
 }
 
 
-static int srec2b(char * infile, FILE * inf,
+static int srec2b(char * infile, FILE * inf, unsigned int * start,
            unsigned char * outbuf, int bufsize)
 {
   char buffer [ MAX_LINE_LEN ];
@@ -552,6 +559,7 @@
   int rc;
   int reccount;
   unsigned char datarec;
+  unsigned int startaddr;
 
   char * msg = 0;
 
@@ -560,6 +568,7 @@
   baseaddr = 0;
   maxaddr  = 0;
   reccount = 0;
+  startaddr = 0xffffffff;
 
   while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
     lineno++;
@@ -626,6 +635,8 @@
       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 */
+	if (start)
+		*start = startaddr;
         return maxaddr;
 
       default:
@@ -638,6 +649,8 @@
 
     if (datarec == 1) {
       nextaddr = srec.loadofs + baseaddr;
+      if (nextaddr < startaddr)
+	      startaddr = nextaddr;
       if (nextaddr + srec.reclen > bufsize) {
         fprintf(stderr, msg, progname, nextaddr+srec.reclen, lineno, infile);
         return -1;
@@ -655,7 +668,8 @@
           "%s: WARNING: no end of file record found for Motorola S-Records "
           "file \"%s\"\n",
           progname, infile);
-
+  if (start)
+	  *start = startaddr;
   return maxaddr;
 }
 
@@ -776,8 +790,8 @@
 }
 
 
-static int fileio_ihex(struct fioparms * fio, 
-                  char * filename, FILE * f, unsigned char * buf, int size)
+static int fileio_ihex(struct fioparms * fio, char * filename, 
+		FILE * f, unsigned char * buf, int size)
 {
   int rc;
 
@@ -790,7 +804,7 @@
       break;
 
     case FIO_READ:
-      rc = ihex2b(filename, f, buf, size);
+      rc = ihex2b(filename, f, &fio->startaddr, buf, size);
       if (rc < 0)
         return -1;
       break;
@@ -820,7 +834,7 @@
       break;
 
     case FIO_READ:
-      rc = srec2b(filename, f, buf, size);
+      rc = srec2b(filename, f, &fio->startaddr, buf, size);
       if (rc < 0)
         return -1;
       break;
@@ -1037,7 +1051,11 @@
   /* point at the requested memory buffer */
   buf = mem->buf;
   if (fio.op == FIO_READ)
+  {
+    fio.startaddr = 0xffffffff;
+    mem->start_address = -1;
     size = mem->size;
+  }
 
   if (fio.op == FIO_READ) {
     /* 0xff fill unspecified memory */
@@ -1114,10 +1132,20 @@
   switch (format) {
     case FMT_IHEX:
       rc = fileio_ihex(&fio, fname, f, buf, size);
+      if (fio.op == FIO_READ && fio.startaddr != 0xffffffff && mem->paged)
+      {
+        mem->start_address = (int)fio.startaddr;
+	mem->start_address = mem->start_address - (mem->start_address % mem->page_size);
+      }
       break;
 
     case FMT_SREC:
       rc = fileio_srec(&fio, fname, f, buf, size);
+      if (fio.op == FIO_READ && fio.startaddr != 0xffffffff && mem->paged)
+      {
+        mem->start_address = (int)fio.startaddr;
+	mem->start_address = mem->start_address - (mem->start_address % mem->page_size);
+      }
       break;
 
     case FMT_RBIN:
diff -B -u -r avrdude-5.11.1/fileio.h avrdude-5.11.1.new/fileio.h
--- avrdude-5.11.1/fileio.h	2011-09-15 18:37:05.000000000 +0400
+++ avrdude-5.11.1.new/fileio.h	2013-07-26 12:12:04.000000000 +0400
@@ -40,6 +40,7 @@
   char * iodesc;
   char * dir;
   char * rw;
+  unsigned int startaddr;
 };
 
 enum {
Только в avrdude-5.11.1.new/: paged_write
Только в avrdude-5.11.1.new/: page_size
diff -B -u -r avrdude-5.11.1/update.c avrdude-5.11.1.new/update.c
--- avrdude-5.11.1/update.c	2011-09-15 18:37:05.000000000 +0400
+++ avrdude-5.11.1.new/update.c	2013-07-26 11:30:10.000000000 +0400
@@ -332,6 +332,9 @@
     }
 
     report_progress (0,1,"Reading");
+    // copy start_address for upd->memtype from p to v
+    AVRMEM *vmem = avr_locate_mem(v,upd->memtype);
+    vmem->start_address = mem->start_address;
     rc = avr_read(pgm, v, upd->memtype, size, 1);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
diff -B -u -r avrdude-5.11.1/usbasp.c avrdude-5.11.1.new/usbasp.c
--- avrdude-5.11.1/usbasp.c	2011-09-15 18:37:05.000000000 +0400
+++ avrdude-5.11.1.new/usbasp.c	2013-07-26 16:45:17.000000000 +0400
@@ -615,6 +615,9 @@
     return -2;
   }
 
+  int to_read = 0;
+  if ( m->start_address == -1 )
+    to_read = 1;
   /* set blocksize depending on sck frequency */  
   if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
      blocksize = USBASP_READBLOCKSIZE / 10;
@@ -623,10 +626,31 @@
   }
 
   while (wbytes) {
+    if (!to_read)
+    {
+      if (address >= m->start_address)
+      {
+        to_read = 1;
+	if (address > m->start_address)
+	{
+	  wbytes += address - m->start_address;
+	  buffer -= address - m->start_address;
+	  address -= address - m->start_address;
+	}
+      }
+    }
     if (wbytes <= blocksize) {
       blocksize = wbytes;
     }
     wbytes -= blocksize;
+    if (!to_read)
+    {
+      buffer += blocksize;
+      address += blocksize;
+
+      report_progress (address, n_bytes, NULL);
+      continue;
+    }
 
     /* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */
     unsigned char temp[4];
@@ -682,6 +706,9 @@
     return -2;
   }
 
+  int to_write = 0;
+  if ( m->start_address == -1 )
+    to_write = 1;
   /* set blocksize depending on sck frequency */  
   if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
      blocksize = USBASP_WRITEBLOCKSIZE / 10;
@@ -688,14 +715,33 @@
   } else {
      blocksize = USBASP_WRITEBLOCKSIZE;
   }
-
   while (wbytes) {
-
+    if (!to_write)
+    {
+      if (address >= m->start_address)
+      {
+        to_write = 1;
+	if (address > m->start_address)
+	{
+	  wbytes += address - m->start_address;
+	  buffer -= address - m->start_address;
+	  address -= address - m->start_address;
+	}
+      }
+    }
     if (wbytes <= blocksize) {
       blocksize = wbytes;
       blockflags |= USBASP_BLOCKFLAG_LAST;
     }
     wbytes -= blocksize;
+    if (!to_write)
+    {
+      buffer += blocksize;
+      address += blocksize;
+
+      report_progress (address, n_bytes, NULL);
+      continue;
+    }
 
 
     /* set address (new mode) - if firmware on usbasp support newmode, then
