diff --git a/avr.c b/avr.c
index 961487db..d5fdde3c 100644
--- a/avr.c
+++ b/avr.c
@@ -206,37 +206,33 @@ int avr_mem_hiaddr(AVRMEM * mem)
 
 /*
  * Read the entirety of the specified memory type into the
- * corresponding buffer of the avrpart pointed to by 'p'.  If size =
- * 0, read the entire contents, otherwise, read 'size' bytes.
+ * corresponding buffer of the avrpart pointed to by 'p'.
+ * If v is non-NULL, verify against v's memory area, only
+ * those cells that are tagged TAG_ALLOCATED are verified.
  *
  * 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,
+             AVRPART * v, int verb)
 {
-  unsigned char    rbyte;
-  unsigned long    i;
-  unsigned char  * buf;
+  unsigned long    i, lastaddr;
   unsigned char    cmd[4];
-  AVRMEM * mem;
+  AVRMEM * mem, * vmem = NULL;
   int rc;
 
   mem = avr_locate_mem(p, memtype);
+  if (v != NULL)
+      vmem = avr_locate_mem(v, memtype);
   if (mem == NULL) {
     fprintf(stderr, "No \"%s\" memory for part %s\n",
             memtype, p->desc);
     return -1;
   }
 
-  buf  = mem->buf;
-  if (size == 0) {
-    size = mem->size;
-  }
-
   /*
    * start with all 0xff
    */
-  memset(buf, 0xff, size);
+  memset(mem->buf, 0xff, mem->size);
 
   /* supports "paged load" thru post-increment */
   if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0) {
@@ -252,32 +248,70 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
     avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION);
 
     /* load bytes */
-    for (i = 0; i < size; i++) {
-      cmd[0] = TPI_CMD_SLD_PI;
-      rc = pgm->cmd_tpi(pgm, cmd, 1, &buf[i], 1);
-      if (rc == -1) {
-        fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
-        return -1;
+    for (lastaddr = i = 0; i < mem->size; i++) {
+      if (vmem == NULL ||
+          (vmem->tags[i] & TAG_ALLOCATED) != 0)
+      {
+        if (lastaddr != i) {
+          /* need to setup new address */
+          avr_tpi_setup_rw(pgm, mem, i, TPI_NVMCMD_NO_OPERATION);
+          lastaddr = i;
+        }
+        cmd[0] = TPI_CMD_SLD_PI;
+        rc = pgm->cmd_tpi(pgm, cmd, 1, mem->buf + i, 1);
+        lastaddr++;
+        if (rc == -1) {
+          fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
+          return -1;
+        }
       }
-
-      report_progress(i, size, NULL);
+      report_progress(i, mem->size, NULL);
     }
     return avr_mem_hiaddr(mem);
   }
 
   if (pgm->paged_load != NULL && mem->page_size != 0) {
     /*
-     * the programmer supports a paged mode read, perhaps more
-     * efficiently than we can read it directly, so use its routine
-     * instead
+     * the programmer supports a paged mode read
      */
-    rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
-    if (rc >= 0) {
+    int need_read, failure;
+    unsigned int pageaddr;
+
+    for (pageaddr = 0, failure = 0;
+         !failure && pageaddr < mem->size;
+         pageaddr += mem->page_size) {
+      /* check whether this page must be read */
+      for (i = pageaddr, need_read = 0;
+           i < pageaddr + mem->page_size;
+           i++)
+        if (vmem == NULL /* no verify, read everything */ ||
+            (vmem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only
+                                                    read pages that
+                                                    are needed in
+                                                    input file */) {
+          need_read = 1;
+          break;
+        }
+      if (need_read) {
+        i = pgm->paged_load(pgm, p, mem, mem->page_size,
+                            pageaddr, mem->page_size);
+        if (i < 0)
+          /* paged load failed, fall back to byte-at-a-time read below */
+          failure = 1;
+      } else if (verbose >= 3) {
+        fprintf(stderr,
+                "%s: avr_read(): skipping page %u: no interesting data\n",
+                progname, pageaddr / mem->page_size);
+      }
+      report_progress(pageaddr, mem->size, NULL);
+    }
+    if (!failure) {
       if (strcasecmp(mem->desc, "flash") == 0)
         return avr_mem_hiaddr(mem);
       else
-        return rc;
+        return mem->size;
     }
+    /* else: fall back to byte-at-a-time write, for historical reasons */
   }
 
   if (strcmp(mem->desc, "signature") == 0) {
@@ -286,18 +320,21 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
     }
   }
 
-  for (i=0; i<size; i++) {
-    rc = pgm->read_byte(pgm, p, mem, i, &rbyte);
-    if (rc != 0) {
-      fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
-      if (rc == -1) 
-        fprintf(stderr, 
-                "    read operation not supported for memory \"%s\"\n",
-                memtype);
-      return -2;
+  for (i=0; i < mem->size; i++) {
+    if (vmem == NULL ||
+	(vmem->tags[i] & TAG_ALLOCATED) != 0)
+    {
+      rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
+      if (rc != 0) {
+	fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
+	if (rc == -1) 
+	  fprintf(stderr, 
+		  "    read operation not supported for memory \"%s\"\n",
+		  memtype);
+	return -2;
+      }
     }
-    buf[i] = rbyte;
-    report_progress(i, size, NULL);
+    report_progress(i, mem->size, NULL);
   }
 
   if (strcasecmp(mem->desc, "flash") == 0)
@@ -679,11 +716,12 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
  * 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 verb)
 {
   int              rc;
+  int              newpage, page_tainted, flush_page, do_write;
   int              wsize;
-  long             i;
+  unsigned int     i, lastaddr;
   unsigned char    data;
   int              werror;
   unsigned char    cmd[4];
@@ -733,15 +771,27 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
     }
 
     /* write words, low byte first */
-    for (i = 0; i < wsize; i++) {
-      cmd[0] = TPI_CMD_SST_PI;
-      cmd[1] = m->buf[i];
-      rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+    for (lastaddr = i = 0; i < wsize; i += 2) {
+      if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
+          (m->tags[i + 1] & TAG_ALLOCATED) != 0) {
 
-      cmd[1] = m->buf[++i];
-      rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+        if (lastaddr != i) {
+          /* need to setup new address */
+          avr_tpi_setup_rw(pgm, m, i, TPI_NVMCMD_WORD_WRITE);
+          lastaddr = i;
+        }
 
-      while (avr_tpi_poll_nvmbsy(pgm));
+        cmd[0] = TPI_CMD_SST_PI;
+        cmd[1] = m->buf[i];
+        rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+        cmd[1] = m->buf[i + 1];
+        rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+        lastaddr += 2;
+
+        while (avr_tpi_poll_nvmbsy(pgm));
+      }
       report_progress(i, wsize, NULL);
     }
     return i;
@@ -749,48 +799,110 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
 
   if (pgm->paged_write != NULL && m->page_size != 0) {
     /*
-     * the programmer supports a paged mode write, perhaps more
-     * efficiently than we can read it directly, so use its routine
-     * instead
+     * the programmer supports a paged mode write
      */
-    if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0)
-      return i;
+    int need_write, failure;
+    unsigned int pageaddr;
+
+    for (pageaddr = 0, failure = 0;
+         !failure && pageaddr < wsize;
+         pageaddr += m->page_size) {
+      /* check whether this page must be written to */
+      for (i = pageaddr, need_write = 0;
+           i < pageaddr + m->page_size;
+           i++)
+        if ((m->tags[i] & TAG_ALLOCATED) != 0) {
+          need_write = 1;
+          break;
+        }
+      if (need_write) {
+          i = pgm->paged_write(pgm, p, m, m->page_size, pageaddr, m->page_size);
+        if (i < 0)
+          /* paged write failed, fall back to byte-at-a-time write below */
+          failure = 1;
+      } else if (verbose >= 3) {
+        fprintf(stderr,
+                "%s: avr_write(): skipping page %u: no interesting data\n",
+                progname, pageaddr / m->page_size);
+      }
+      report_progress(pageaddr, m->size, NULL);
+    }
+    if (!failure)
+      return wsize;
+    /* else: fall back to byte-at-a-time write, for historical reasons */
   }
 
   if (pgm->write_setup) {
       pgm->write_setup(pgm, p, m);
   }
 
+  newpage = 1;
+  page_tainted = 0;
+  flush_page = 0;
+
   for (i=0; i<wsize; i++) {
     data = m->buf[i];
     report_progress(i, wsize, NULL);
 
-    rc = avr_write_byte(pgm, p, m, i, data);
-    if (rc) {
-      fprintf(stderr, " ***failed;  ");
-      fprintf(stderr, "\n");
-      pgm->err_led(pgm, ON);
-      werror = 1;
+    /*
+     * Find out whether the write action must be invoked for this
+     * byte.
+     *
+     * For non-paged memory, this only happens if TAG_ALLOCATED is
+     * set for the byte.
+     *
+     * For paged memory, TAG_ALLOCATED also invokes the write
+     * operation, which is actually a page buffer fill only.  This
+     * "taints" the page, and upon encountering the last byte of each
+     * tainted page, the write operation must also be invoked in order
+     * to actually write the page buffer to memory.
+     */
+    do_write = (m->tags[i] & TAG_ALLOCATED) != 0;
+    if (m->paged) {
+      if (newpage) {
+        page_tainted = do_write;
+      } else {
+        page_tainted |= do_write;
+      }
+      if (i % m->page_size == m->page_size - 1 ||
+          i == wsize - 1) {
+        /* last byte this page */
+        flush_page = page_tainted;
+        newpage = 1;
+      } else {
+        flush_page = newpage = 0;
+      }
     }
 
-    if (m->paged) {
-      /*
-       * check to see if it is time to flush the page with a page
-       * write
-       */
-      if (((i % m->page_size) == m->page_size-1) ||
-          (i == wsize-1)) {
-        rc = avr_write_page(pgm, p, m, i);
-        if (rc) {
-          fprintf(stderr,
-                  " *** page %ld (addresses 0x%04lx - 0x%04lx) failed "
-                  "to write\n",
-                  i % m->page_size, 
-                  i - m->page_size + 1, i);
-          fprintf(stderr, "\n");
-          pgm->err_led(pgm, ON);
+    if (!do_write && !flush_page) {
+      continue;
+    }
+
+    if (do_write) {
+      rc = avr_write_byte(pgm, p, m, i, data);
+      if (rc) {
+        fprintf(stderr, " ***failed;  ");
+        fprintf(stderr, "\n");
+        pgm->err_led(pgm, ON);
+        werror = 1;
+      }
+    }
+
+    /*
+     * check to see if it is time to flush the page with a page
+     * write
+     */
+    if (flush_page) {
+      rc = avr_write_page(pgm, p, m, i);
+      if (rc) {
+        fprintf(stderr,
+                " *** page %d (addresses 0x%04x - 0x%04x) failed "
+                "to write\n",
+                i % m->page_size, 
+                i - m->page_size + 1, i);
+        fprintf(stderr, "\n");
+        pgm->err_led(pgm, ON);
           werror = 1;
-        }
       }
     }
 
@@ -875,7 +987,8 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
   }
 
   for (i=0; i<size; i++) {
-    if (buf1[i] != buf2[i]) {
+    if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
+        buf1[i] != buf2[i]) {
       fprintf(stderr, 
               "%s: verification error, first mismatch at byte 0x%04x\n"
               "%s0x%02x != 0x%02x\n",
diff --git a/avr.h b/avr.h
index 477ab9df..1a85ed4f 100644
--- a/avr.h
+++ b/avr.h
@@ -41,7 +41,7 @@ int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
 int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 			  unsigned long addr, unsigned char * value);
 
-int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
+int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v,
              int verbose);
 
 int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
diff --git a/avr910.c b/avr910.c
index 1bce60fa..4a168f85 100644
--- a/avr910.c
+++ b/avr910.c
@@ -506,12 +506,12 @@ static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                                    int page_size, int n_bytes)
+                                    unsigned int page_size,
+                                    unsigned int addr, unsigned int n_bytes)
 {
   unsigned char cmd[] = {'c', 'C'};
   char buf[2];
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int max_addr = addr + n_bytes;
   unsigned int page_addr;
   int page_bytes = page_size;
   int page_wr_cmd_pending = 0;
@@ -548,8 +548,6 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
       avr910_set_addr(pgm, addr>>1);
     }
-
-    report_progress (addr, max_addr, NULL);
   }
 
   /* If we didn't send the page wr cmd after the last byte written in the
@@ -567,11 +565,12 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
-                                     AVRMEM * m, int page_size, int n_bytes)
+                                     AVRMEM * m,
+                                     unsigned int page_size,
+                                     unsigned int addr, unsigned int n_bytes)
 {
   char cmd[2];
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int max_addr = addr + n_bytes;
 
   avr910_set_addr(pgm, addr);
 
@@ -588,8 +587,6 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
     if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
       avr910_set_addr(pgm, addr);
     }
-
-    report_progress (addr, max_addr, NULL);
   }
 
   return addr;
@@ -597,22 +594,22 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
 
 
 static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                              int page_size, int n_bytes)
+                              unsigned int page_size,
+                              unsigned int addr, unsigned int n_bytes)
 {
   int rval = 0;
   if (PDATA(pgm)->use_blockmode == 0) {
     if (strcmp(m->desc, "flash") == 0) {
-      rval = avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
+      rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
     } else if (strcmp(m->desc, "eeprom") == 0) {
-      rval = avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
+      rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes);
     } else {
       rval = -2;
     }
   }
 
   if (PDATA(pgm)->use_blockmode == 1) {
-    unsigned int addr = 0;
-    unsigned int max_addr = n_bytes;
+    unsigned int max_addr = addr + n_bytes;
     char *cmd;
     unsigned int blocksize = PDATA(pgm)->buffersize;
 
@@ -640,8 +637,6 @@ static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       avr910_vfy_cmd_sent(pgm, "write block");
 
       addr += blocksize;
-
-      report_progress (addr, max_addr, NULL);
     } /* while */
     free(cmd);
 
@@ -651,79 +646,41 @@ static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 
-static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                             unsigned int page_size,
+                             unsigned int addr, unsigned int n_bytes)
 {
-  char cmd;
-  int rd_size = 1;
-  unsigned int addr = 0;
+  char cmd[4];
+  int rd_size;
   unsigned int max_addr;
   char buf[2];
   int rval=0;
 
-  if (PDATA(pgm)->use_blockmode == 0) {
+  max_addr = addr + n_bytes;
 
-    if (strcmp(m->desc, "flash") == 0) {
-      cmd = 'R';
-      rd_size = 2;                /* read two bytes per addr */
-    } else if (strcmp(m->desc, "eeprom") == 0) {
-      cmd = 'd';
-      rd_size = 1;
-    } else {
-      rval = -2;
-    }
-
-    max_addr = n_bytes/rd_size;
-
-    avr910_set_addr(pgm, addr);
-
-    while (addr < max_addr) {
-      avr910_send(pgm, &cmd, 1);
-      if (cmd == 'R') {
-        /* The 'R' command returns two bytes, MSB first, we need to put the data
-           into the memory buffer LSB first. */
-        avr910_recv(pgm, buf, 2);
-        m->buf[addr*2]   = buf[1];  /* LSB */
-        m->buf[addr*2+1] = buf[0];  /* MSB */
-      }
-      else {
-        avr910_recv(pgm, (char *)&m->buf[addr], 1);
-      }
-
-      addr++;
-
-      if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
-        avr910_set_addr(pgm, addr);
-      }
-
-      report_progress (addr, max_addr, NULL);
-    }
-
-    rval = addr * rd_size;
+  if (strcmp(m->desc, "flash") == 0) {
+    cmd[0] = 'R';
+    rd_size = 2;                /* read two bytes per addr */
+  } else if (strcmp(m->desc, "eeprom") == 0) {
+    cmd[0] = 'd';
+    rd_size = 1;
+  } else {
+    return -2;
   }
 
-  if (PDATA(pgm)->use_blockmode == 1) {
-    unsigned int addr = 0;
-    unsigned int max_addr = n_bytes;
-    int rd_size = 1;
-
-    /* check parameter syntax: only "flash" or "eeprom" is allowed */
-    if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
-      rval = -2;
-
-  	/* use buffered mode */
-    char cmd[4];
+  if (PDATA(pgm)->use_blockmode) {
+    /* use buffered mode */
     int blocksize = PDATA(pgm)->buffersize;
 
     cmd[0] = 'g';
     cmd[3] = toupper((int)(m->desc[0]));
 
-    avr910_set_addr(pgm, addr);
+    avr910_set_addr(pgm, addr / rd_size);
 
     while (addr < max_addr) {
       if ((max_addr - addr) < blocksize) {
         blocksize = max_addr - addr;
-      };
+      }
       cmd[1] = (blocksize >> 8) & 0xff;
       cmd[2] = blocksize & 0xff;
 
@@ -731,11 +688,34 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
 
       addr += blocksize;
-
-      report_progress (addr, max_addr, NULL);
     }
 
-    rval = addr * rd_size;
+    rval = addr;
+  } else {
+
+    avr910_set_addr(pgm, addr / rd_size);
+
+    while (addr < max_addr) {
+      avr910_send(pgm, cmd, 1);
+      if (rd_size == 2) {
+        /* The 'R' command returns two bytes, MSB first, we need to put the data
+           into the memory buffer LSB first. */
+        avr910_recv(pgm, buf, 2);
+        m->buf[addr]   = buf[1];  /* LSB */
+        m->buf[addr + 1] = buf[0];  /* MSB */
+      }
+      else {
+        avr910_recv(pgm, (char *)&m->buf[addr], 1);
+      }
+
+      addr += rd_size;
+
+      if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
+        avr910_set_addr(pgm, addr / rd_size);
+      }
+    }
+
+    rval = addr;
   }
 
   return rval;
diff --git a/avrftdi.c b/avrftdi.c
index 37d883b6..cd9bdc7d 100644
--- a/avrftdi.c
+++ b/avrftdi.c
@@ -740,8 +740,6 @@ static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 		E(avrftdi_transmit(TX, cmd, cmd, 4) < 0);
 
 		usleep((m->max_write_delay));
-		if(verbose < 3)
-			report_progress(add, len, NULL);
 	}
 	return len;
 }
@@ -764,8 +762,6 @@ static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
 		E(avrftdi_transmit(TRX, cmd, cmd, 4) < 0);
 
 		avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++);
-		if(verbose < 3)
-			report_progress(add, len, NULL);
 	}
 
 	memcpy(m->buf, buffer, len);
@@ -973,8 +969,6 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 				o_ptr = o_buf;
 			}
 		}
-		if (verbose < 3)
-			report_progress(2 * address, len, NULL);
 	}
 	memcpy(m->buf, buffer, sizeof(buffer));
 
diff --git a/avrpart.c b/avrpart.c
index 61994aac..55f56b68 100644
--- a/avrpart.c
+++ b/avrpart.c
@@ -233,6 +233,12 @@ int avr_initmem(AVRPART * p)
               progname, m->desc, m->size);
       return -1;
     }
+    m->tags = (unsigned char *) malloc(m->size);
+    if (m->tags == NULL) {
+      fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
+              progname, m->desc, m->size);
+      return -1;
+    }
   }
 
   return 0;
@@ -254,7 +260,16 @@ AVRMEM * avr_dup_mem(AVRMEM * m)
             n->size);
     exit(1);
   }
-  memset(n->buf, 0, n->size);
+  memcpy(n->buf, m->buf, n->size);
+
+  n->tags = (unsigned char *)malloc(n->size);
+  if (n->tags == NULL) {
+    fprintf(stderr,
+            "avr_dup_mem(): out of memory (memsize=%d)\n",
+            n->size);
+    exit(1);
+  }
+  memcpy(n->tags, m->tags, n->size);
 
   return n;
 }
diff --git a/avrpart.h b/avrpart.h
index f868e948..f4fd35f3 100644
--- a/avrpart.h
+++ b/avrpart.h
@@ -100,6 +100,9 @@ typedef struct opcode {
 #define CTL_STACK_SIZE 32
 #define FLASH_INSTR_SIZE 3
 #define EEPROM_INSTR_SIZE 20
+
+#define TAG_ALLOCATED          1    /* memory byte is allocated */
+
 typedef struct avrpart {
   char          desc[AVR_DESCLEN];  /* long part name */
   char          id[AVR_IDLEN];      /* short part name */
@@ -185,6 +188,7 @@ typedef struct avrmem {
   int pollindex;              /* stk500 v2 xml file parameter */
 
   unsigned char * buf;        /* pointer to memory buffer */
+  unsigned char * tags;       /* allocation tags */
   OPCODE * op[AVR_OP_MAX];    /* opcodes */
 } AVRMEM;
 
diff --git a/butterfly.c b/butterfly.c
index bb7c35c9..014f3ff3 100644
--- a/butterfly.c
+++ b/butterfly.c
@@ -582,11 +582,11 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 
-static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int max_addr = addr + n_bytes;
   char *cmd;
   unsigned int blocksize = PDATA(pgm)->buffersize;
   int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
@@ -626,8 +626,6 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     butterfly_vfy_cmd_sent(pgm, "write block");
 
     addr += blocksize;
-
-    report_progress (addr, max_addr, NULL);
   } /* while */
   free(cmd);
 
@@ -636,11 +634,11 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
 
 
-static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr = 0;
-  unsigned int max_addr = n_bytes;
+  unsigned int max_addr = addr + n_bytes;
   int rd_size = 1;
   int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
 
@@ -671,8 +669,6 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
 
       addr += blocksize;
-
-      report_progress (addr, max_addr, NULL);
     } /* while */
   }
 
diff --git a/fileio.c b/fileio.c
index 5af91bab..ad523253 100644
--- a/fileio.c
+++ b/fileio.c
@@ -52,30 +52,30 @@ static int b2ihex(unsigned char * inbuf, int bufsize,
              char * outfile, FILE * outf);
 
 static int ihex2b(char * infile, FILE * inf,
-             unsigned char * outbuf, int bufsize);
+             AVRMEM * mem, 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,
-             unsigned char * outbuf, int bufsize);
+             AVRMEM * mem, int bufsize);
 
 static int ihex_readrec(struct ihexrec * ihex, char * rec);
 
 static int srec_readrec(struct ihexrec * srec, char * rec);
 
 static int fileio_rbin(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size);
+                  char * filename, FILE * f, AVRMEM * mem, int size);
 
 static int fileio_ihex(struct fioparms * fio, 
-                  char * filename, FILE * f, unsigned char * buf, int size);
+                  char * filename, FILE * f, AVRMEM * mem, int size);
 
 static int fileio_srec(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size);
+                  char * filename, FILE * f, AVRMEM * mem, int size);
 
 static int fileio_num(struct fioparms * fio,
-		char * filename, FILE * f, unsigned char * buf, int size,
+		char * filename, FILE * f, AVRMEM * mem, int size,
 		FILEFMT fmt);
 
 static int fmt_autodetect(char * fname);
@@ -262,10 +262,9 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
  *
  * */
 static int ihex2b(char * infile, FILE * inf,
-             unsigned char * outbuf, int bufsize)
+             AVRMEM * mem, int bufsize)
 {
   char buffer [ MAX_LINE_LEN ];
-  unsigned char * buf;
   unsigned int nextaddr, baseaddr, maxaddr, offsetaddr;
   int i;
   int lineno;
@@ -274,7 +273,6 @@ static int ihex2b(char * infile, FILE * inf,
   int rc;
 
   lineno      = 0;
-  buf         = outbuf;
   baseaddr    = 0;
   maxaddr     = 0;
   offsetaddr  = 0;
@@ -311,7 +309,8 @@ static int ihex2b(char * infile, FILE * inf,
           return -1;
         }
         for (i=0; i<ihex.reclen; i++) {
-          buf[nextaddr+i-offsetaddr] = ihex.data[i];
+          mem->buf[nextaddr+i-offsetaddr] = ihex.data[i];
+          mem->tags[nextaddr+i-offsetaddr] = TAG_ALLOCATED;
         }
         if (nextaddr+ihex.reclen > maxaddr)
           maxaddr = nextaddr+ihex.reclen;
@@ -540,10 +539,9 @@ static int srec_readrec(struct ihexrec * srec, char * rec)
 
 
 static int srec2b(char * infile, FILE * inf,
-           unsigned char * outbuf, int bufsize)
+           AVRMEM * mem, int bufsize)
 {
   char buffer [ MAX_LINE_LEN ];
-  unsigned char * buf;
   unsigned int nextaddr, baseaddr, maxaddr;
   int i;
   int lineno;
@@ -556,7 +554,6 @@ static int srec2b(char * infile, FILE * inf,
   char * msg = 0;
 
   lineno   = 0;
-  buf      = outbuf;
   baseaddr = 0;
   maxaddr  = 0;
   reccount = 0;
@@ -642,8 +639,10 @@ static int srec2b(char * infile, FILE * inf,
         fprintf(stderr, msg, progname, nextaddr+srec.reclen, lineno, infile);
         return -1;
       }
-      for (i=0; i<srec.reclen; i++) 
-        buf[nextaddr+i] = srec.data[i];
+      for (i=0; i<srec.reclen; i++) {
+        mem->buf[nextaddr+i] = srec.data[i];
+        mem->tags[nextaddr+i] = TAG_ALLOCATED;
+      }
       if (nextaddr+srec.reclen > maxaddr)
         maxaddr = nextaddr+srec.reclen;
       reccount++;	
@@ -700,13 +699,16 @@ static char *itoa_simple(int n, char *buf, int base)
 
 
 static int fileio_rbin(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size)
+                  char * filename, FILE * f, AVRMEM * mem, int size)
 {
   int rc;
+  unsigned char *buf = mem->buf;
 
   switch (fio->op) {
     case FIO_READ:
       rc = fread(buf, 1, size, f);
+      if (rc > 0)
+        memset(mem->tags, TAG_ALLOCATED, rc);
       break;
     case FIO_WRITE:
       rc = fwrite(buf, 1, size, f);
@@ -730,7 +732,7 @@ static int fileio_rbin(struct fioparms * fio,
 
 
 static int fileio_imm(struct fioparms * fio,
-               char * filename, FILE * f, unsigned char * buf, int size)
+               char * filename, FILE * f, AVRMEM * mem, int size)
 {
   int rc = 0;
   char * e, * p;
@@ -753,7 +755,8 @@ static int fileio_imm(struct fioparms * fio,
                   progname, p);
           return -1;
         }
-        buf[loc++] = b;
+        mem->buf[loc] = b;
+        mem->tags[loc++] = TAG_ALLOCATED;
         p = strtok(NULL, " ,");
         rc = loc;
       }
@@ -777,20 +780,20 @@ static int fileio_imm(struct fioparms * fio,
 
 
 static int fileio_ihex(struct fioparms * fio, 
-                  char * filename, FILE * f, unsigned char * buf, int size)
+                  char * filename, FILE * f, AVRMEM * mem, int size)
 {
   int rc;
 
   switch (fio->op) {
     case FIO_WRITE:
-      rc = b2ihex(buf, size, 32, 0, filename, f);
+      rc = b2ihex(mem->buf, size, 32, 0, filename, f);
       if (rc < 0) {
         return -1;
       }
       break;
 
     case FIO_READ:
-      rc = ihex2b(filename, f, buf, size);
+      rc = ihex2b(filename, f, mem, size);
       if (rc < 0)
         return -1;
       break;
@@ -807,20 +810,20 @@ static int fileio_ihex(struct fioparms * fio,
 
 
 static int fileio_srec(struct fioparms * fio,
-                  char * filename, FILE * f, unsigned char * buf, int size)
+                  char * filename, FILE * f, AVRMEM * mem, int size)
 {
   int rc;
 
   switch (fio->op) {
     case FIO_WRITE:
-      rc = b2srec(buf, size, 32, 0, filename, f);
+      rc = b2srec(mem->buf, size, 32, 0, filename, f);
       if (rc < 0) {
         return -1;
       }
       break;
 
     case FIO_READ:
-      rc = srec2b(filename, f, buf, size);
+      rc = srec2b(filename, f, mem, size);
       if (rc < 0)
         return -1;
       break;
@@ -838,7 +841,7 @@ static int fileio_srec(struct fioparms * fio,
 
 
 static int fileio_num(struct fioparms * fio,
-	       char * filename, FILE * f, unsigned char * buf, int size,
+	       char * filename, FILE * f, AVRMEM * mem, int size,
 	       FILEFMT fmt)
 {
   const char *prefix;
@@ -883,7 +886,7 @@ static int fileio_num(struct fioparms * fio,
       if (putc(',', f) == EOF)
 	goto writeerr;
     }
-    num = (unsigned int)buf[i];
+    num = (unsigned int)(mem->buf[i]);
     /*
      * For a base of 8 and a value < 8 to convert, don't write the
      * prefix.  The conversion will be indistinguishable from a
@@ -1017,7 +1020,6 @@ int fileio(int op, char * filename, FILEFMT format,
   int rc;
   FILE * f;
   char * fname;
-  unsigned char * buf;
   struct fioparms fio;
   AVRMEM * mem;
   int using_stdio;
@@ -1034,15 +1036,14 @@ int fileio(int op, char * filename, FILEFMT format,
   if (rc < 0)
     return -1;
 
-  /* 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, size);
   }
+  memset(mem->tags, 0, size);
 
   using_stdio = 0;
 
@@ -1113,26 +1114,26 @@ int fileio(int op, char * filename, FILEFMT format,
 
   switch (format) {
     case FMT_IHEX:
-      rc = fileio_ihex(&fio, fname, f, buf, size);
+      rc = fileio_ihex(&fio, fname, f, mem, size);
       break;
 
     case FMT_SREC:
-      rc = fileio_srec(&fio, fname, f, buf, size);
+      rc = fileio_srec(&fio, fname, f, mem, size);
       break;
 
     case FMT_RBIN:
-      rc = fileio_rbin(&fio, fname, f, buf, size);
+      rc = fileio_rbin(&fio, fname, f, mem, size);
       break;
 
     case FMT_IMM:
-      rc = fileio_imm(&fio, fname, f, buf, size);
+      rc = fileio_imm(&fio, fname, f, mem, size);
       break;
 
     case FMT_HEX:
     case FMT_DEC:
     case FMT_OCT:
     case FMT_BIN:
-      rc = fileio_num(&fio, fname, f, buf, size, format);
+      rc = fileio_num(&fio, fname, f, mem, size, format);
       break;
 
     default:
diff --git a/jtagmkI.c b/jtagmkI.c
index cb1f84a6..c9521b52 100644
--- a/jtagmkI.c
+++ b/jtagmkI.c
@@ -737,9 +737,11 @@ static void jtagmkI_close(PROGRAMMER * pgm)
 
 
 static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+                               unsigned int page_size,
+                               unsigned int addr, unsigned int n_bytes)
 {
-  int addr, block_size, send_size, tries;
+  int block_size, send_size, tries;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char cmd[6], *datacmd;
   unsigned char resp[2];
   int is_flash = 0;
@@ -781,9 +783,7 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   datacmd[0] = CMD_DATA;
 
   serial_recv_timeout = 1000;
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes,NULL);
-
+  for (; addr < maxaddr; addr += page_size) {
     tries = 0;
     again:
 
@@ -875,9 +875,11 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+			      unsigned int page_size,
+                              unsigned int addr, unsigned int n_bytes)
 {
-  int addr, block_size, read_size, is_flash = 0, tries;
+  int block_size, read_size, is_flash = 0, tries;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char cmd[6], resp[256 * 2 + 3];
   long otimeout = serial_recv_timeout;
 #define MAXTRIES 3
@@ -906,9 +908,7 @@ static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 
   serial_recv_timeout = 1000;
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes,NULL);
-
+  for (; addr < maxaddr; addr += page_size) {
     tries = 0;
     again:
     if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) {
diff --git a/jtagmkII.c b/jtagmkII.c
index 268b4198..bf2cb522 100644
--- a/jtagmkII.c
+++ b/jtagmkII.c
@@ -136,7 +136,8 @@ static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
                             unsigned char * value);
 static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
 static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                int page_size, int n_bytes);
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes);
 
 // AVR32
 #define ERROR_SAB 0xFFFFFFFF
@@ -154,14 +155,16 @@ static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
                                   unsigned char ret1, unsigned char ret2);
 static int jtagmkII_smc_init32(PROGRAMMER * pgm);
 static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                                  int page_size, int n_bytes);
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes);
 static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock,
                                   unsigned int page);
 static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page);
 static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page);
 static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm);
 static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes);
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes);
 
 void jtagmkII_setup(PROGRAMMER * pgm)
 {
@@ -1750,9 +1753,11 @@ void jtagmkII_close(PROGRAMMER * pgm)
 }
 
 static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes)
 {
-  int addr, block_size;
+  unsigned int block_size;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char *cmd;
   unsigned char *resp;
   unsigned char par[4];
@@ -1792,9 +1797,8 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
        * jtagmkII_paged_write() to EEPROM attempted while in
        * DW mode.  Use jtagmkII_write_byte() instead.
        */
-      for (addr = 0; addr < n_bytes; addr++) {
+      for (; addr < maxaddr; addr++) {
 	status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]);
-	report_progress(addr, n_bytes, NULL);
 	if (status < 0) {
 	  free(cmd);
 	  return -1;
@@ -1808,11 +1812,9 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     page_size = PDATA(pgm)->eeprom_pagesize;
   }
   serial_recv_timeout = 100;
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes,NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
     if (verbose >= 3)
@@ -1888,9 +1890,11 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+                               unsigned int page_size,
+                               unsigned int addr, unsigned int n_bytes)
 {
-  int addr, block_size;
+  unsigned int block_size;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char cmd[10];
   unsigned char *resp;
   int status, tries;
@@ -1917,11 +1921,9 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     cmd[1] = MTYPE_USERSIG;
   }
   serial_recv_timeout = 100;
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes,NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
     if (verbose >= 3)
@@ -3233,9 +3235,11 @@ static void jtagmkII_close32(PROGRAMMER * pgm)
 }
 
 static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr, block_size;
+  unsigned int block_size;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char cmd[7];
   unsigned char *resp;
   int lineno, status;
@@ -3274,11 +3278,8 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   cmd[1] = 0x40;
   cmd[2] = 0x05;
 
-  addr = 0;
-  for (addr = 0; addr < n_bytes; addr += block_size) {
-    report_progress(addr, n_bytes, NULL);
-
-    block_size = ((n_bytes-addr) < pgm->page_size) ? (n_bytes - addr) : pgm->page_size;
+  for (; addr < maxaddr; addr += block_size) {
+    block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
     if (verbose >= 3)
       fprintf(stderr, "%s: jtagmkII_paged_load32(): "
               "block_size at addr %d is %d\n",
@@ -3326,14 +3327,16 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 }
 
 static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr, block_size;
+  unsigned int block_size;
   unsigned char *cmd=NULL;
   unsigned char *resp;
-  int lineno, status, pages, pageNum, blocks;
+  int lineno, status, pages, sPageNum, pageNum, blocks;
   unsigned long val=0;
   unsigned long otimeout = serial_recv_timeout;
+  unsigned int maxaddr = addr + n_bytes;
 
   serial_recv_timeout = 256;
 
@@ -3343,7 +3346,8 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   if(status != 0) {lineno = __LINE__; goto eRR;}
   p->flags |= AVRPART_WRITE;
 
-  pages = (n_bytes-1)/page_size + 1;
+  pages = (n_bytes - addr - 1)/page_size + 1;
+  sPageNum = addr/page_size;
   //fprintf(stderr, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
   //        page_size, n_bytes, pages, m->offset, pgm->page_size);
 
@@ -3361,13 +3365,13 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 
   // First unlock the pages
-  for(pageNum=0; pageNum < pages; ++pageNum) {
+  for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
     status =jtagmkII_flash_lock32(pgm, 0, pageNum);
     if(status < 0) {lineno = __LINE__; goto eRR;}
   }
 
   // Then erase them (guess could do this in the same loop above?)
-  for(pageNum=0; pageNum < pages; ++pageNum) {
+  for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
     status =jtagmkII_flash_erase32(pgm, pageNum);
     if(status < 0) {lineno = __LINE__; goto eRR;}
   }
@@ -3376,16 +3380,13 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   u32_to_b4r(&cmd[1], 0x40000000);  // who knows
   cmd[5] = 0x5;
 
-  addr = 0;
-  for(pageNum=0; pageNum < pages; ++pageNum) {
-
-    report_progress(addr, n_bytes, NULL);
+  for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
 
     status = jtagmkII_flash_clear_pagebuffer32(pgm);
     if(status != 0) {lineno = __LINE__; goto eRR;}
 
     for(blocks=0; blocks<2; ++blocks) {
-      block_size = ((n_bytes-addr) < pgm->page_size) ? (n_bytes - addr) : pgm->page_size;
+      block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
       if (verbose >= 3)
         fprintf(stderr, "%s: jtagmkII_paged_write32(): "
                 "block_size at addr %d is %d\n",
diff --git a/main.c b/main.c
index 13c7fa48..5de2bd25 100644
--- a/main.c
+++ b/main.c
@@ -250,7 +250,6 @@ int main(int argc, char * argv [])
   int              ch;          /* options flag */
   int              len;         /* length for various strings */
   struct avrpart * p;           /* which avr part we are programming */
-  struct avrpart * v;           /* used for verify */
   AVRMEM         * sig;         /* signature data */
   struct stat      sb;
   UPDATE         * upd;
@@ -739,13 +738,13 @@ int main(int argc, char * argv [])
     safemode = 0;
   }
 
-  /*
-   * set up seperate instances of the avr part, one for use in
-   * programming, one for use in verifying.  These are separate
-   * because they need separate flash and eeprom buffer space
-   */
-  p = avr_dup_part(p);
-  v = avr_dup_part(p);
+
+  if (avr_initmem(p) != 0)
+  {
+    fprintf(stderr, "\n%s: failed to initialize memories\n",
+            progname);
+    exit(1);
+  }
 
   /*
    * open the programmer
@@ -1081,7 +1080,7 @@ int main(int argc, char * argv [])
 
   for (ln=lfirst(updates); ln; ln=lnext(ln)) {
     upd = ldata(ln);
-    rc = do_op(pgm, p, upd, nowrite, verify);
+    rc = do_op(pgm, p, upd, nowrite);
     if (rc) {
       exitrc = 1;
       break;
diff --git a/pgm.h b/pgm.h
index db4c6bc3..2f7ba36e 100644
--- a/pgm.h
+++ b/pgm.h
@@ -96,9 +96,11 @@ typedef struct programmer_t {
   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);
+                          unsigned int page_size, unsigned int baseaddr,
+                          unsigned int n_bytes);
   int  (*paged_load)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
-                          int page_size, int n_bytes);
+                          unsigned int page_size, unsigned int baseaddr,
+                          unsigned 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);
diff --git a/stk500.c b/stk500.c
index 08050440..32842ad4 100644
--- a/stk500.c
+++ b/stk500.c
@@ -48,8 +48,6 @@
 static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
 static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
 static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
-static int stk500_is_page_empty(unsigned int address, int page_size, 
-    const unsigned char *buf);
 
 
 static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
@@ -739,12 +737,12 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
 }
 
 
-static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                              unsigned int page_size,
+                              unsigned int addr, unsigned int n_bytes)
 {
   unsigned char buf[page_size + 16];
   int memtype;
-  unsigned int addr;
   int a_div;
   int block_size;
   int tries;
@@ -752,16 +750,6 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   unsigned int i;
   int flash;
 
-  if (page_size == 0) {
-    // MIB510 uses page size of 256 bytes
-    if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
-      page_size = 256;
-    }
-    else {
-      page_size = 128;
-    }
-  }
-
   if (strcmp(m->desc, "flash") == 0) {
     memtype = 'F';
     flash = 1;
@@ -779,19 +767,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   else
     a_div = 1;
 
-  if (n_bytes > m->size) {
-    n_bytes = m->size;
-    n = m->size;
-  }
-  else {
-    if ((n_bytes % page_size) != 0) {
-      n = n_bytes + page_size - (n_bytes % page_size);
-    }
-    else {
-      n = n_bytes;
-    }
-  }
-
+  n = addr + n_bytes;
 #if 0
   fprintf(stderr, 
           "n_bytes   = %d\n"
@@ -801,23 +777,15 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
           n_bytes, n, a_div, page_size);
 #endif     
 
-  for (addr = 0; addr < n; addr += page_size) {
-    report_progress (addr, n_bytes, NULL);
-    
+  for (; addr < n; addr += block_size) {
     // MIB510 uses fixed blocks size of 256 bytes
-    if ((strcmp(ldata(lfirst(pgm->id)), "mib510") != 0) &&
-	(addr + page_size > n_bytes)) {
-	   block_size = n_bytes % page_size;
-	}
-	else {
-	   block_size = page_size;
-	}
-  
-    /* Only skip on empty page if programming flash. */
-    if (flash) {
-      if (stk500_is_page_empty(addr, block_size, m->buf)) {
-          continue;
-      }
+    if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
+      block_size = 256;
+    } else {
+      if (n - addr < page_size)
+        block_size = n - addr;
+      else
+        block_size = page_size;
     }
     tries = 0;
   retry:
@@ -870,27 +838,12 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   return n_bytes;
 }
 
-static int stk500_is_page_empty(unsigned int address, int page_size, 
-                                const unsigned char *buf)
-{
-    int i;
-    for(i = 0; i < page_size; i++) {
-        if(buf[address + i] != 0xFF) {
-            /* Page is not empty. */
-            return(0);
-        }
-    }
-    
-    /* Page is empty. */
-    return(1);
-}
-
-static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                             int page_size, int n_bytes)
+static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                             unsigned int page_size,
+                             unsigned int addr, unsigned int n_bytes)
 {
   unsigned char buf[16];
   int memtype;
-  unsigned int addr;
   int a_div;
   int tries;
   unsigned int n;
@@ -911,31 +864,18 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   else
     a_div = 1;
 
-  if (n_bytes > m->size) {
-    n_bytes = m->size;
-    n = m->size;
-  }
-  else {
-    if ((n_bytes % page_size) != 0) {
-      n = n_bytes + page_size - (n_bytes % page_size);
-    }
-    else {
-      n = n_bytes;
-    }
-  }
-
-  for (addr = 0; addr < n; addr += page_size) {
-    report_progress (addr, n_bytes, NULL);
-
+  n = addr + n_bytes;
+  for (; addr < n; addr += block_size) {
     // MIB510 uses fixed blocks size of 256 bytes
-    if ((strcmp(ldata(lfirst(pgm->id)), "mib510") != 0) &&
-	(addr + page_size > n_bytes)) {
-	   block_size = n_bytes % page_size;
-	}
-	else {
-	   block_size = page_size;
-	}
-  
+    if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
+      block_size = 256;
+    } else {
+      if (n - addr < page_size)
+        block_size = n - addr;
+      else
+        block_size = page_size;
+    }
+
     tries = 0;
   retry:
     tries++;
diff --git a/stk500v2.c b/stk500v2.c
index 5fde88a1..239ccf02 100644
--- a/stk500v2.c
+++ b/stk500v2.c
@@ -267,8 +267,6 @@ static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int
 static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value);
 static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
 static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p);
-static int stk500v2_is_page_empty(unsigned int address, int page_size,
-                                  const unsigned char *buf);
 
 static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
 
@@ -1716,17 +1714,20 @@ static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
-                              int page_size, int n_bytes)
+static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr, block_size, last_addr, hiaddr, addrshift, use_ext_addr;
+  unsigned int block_size, last_addr, hiaddr, addrshift, use_ext_addr;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char commandbuf[10];
   unsigned char buf[266];
   unsigned char cmds[4];
   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,%u,%u,%u)\n",
+        m->desc, page_size, addr, n_bytes);
 
   if (page_size == 0) page_size = 256;
   hiaddr = UINT_MAX;
@@ -1809,22 +1810,14 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   last_addr=UINT_MAX;		/* impossible address */
 
-  for (addr=0; addr < n_bytes; addr += page_size) {
-    report_progress(addr,n_bytes,NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
 
     DEBUG("block_size at addr %d is %d\n",addr,block_size);
 
-    if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP){
-      if (stk500v2_is_page_empty(addr, block_size, m->buf)) {
-          continue;
-      }
-    }
-
     memcpy(buf,commandbuf,sizeof(commandbuf));
 
     buf[1] = block_size >> 8;
@@ -1854,14 +1847,17 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
  * Write pages of flash/EEPROM, generic HV mode
  */
 static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				  int page_size, int n_bytes,
-				  enum hvmode mode)
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes,
+                                enum hvmode mode)
 {
-  unsigned int addr, block_size, last_addr, hiaddr, addrshift, use_ext_addr;
+  unsigned int block_size, last_addr, hiaddr, addrshift, use_ext_addr;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char commandbuf[5], buf[266];
   int result;
 
-  DEBUG("STK500V2: stk500hv_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+  DEBUG("STK500V2: stk500hv_paged_write(..,%s,%u,%u)\n",
+        m->desc, page_size, addr, n_bytes);
 
   hiaddr = UINT_MAX;
   addrshift = 0;
@@ -1906,22 +1902,14 @@ static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   last_addr = UINT_MAX;		/* impossible address */
 
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr,n_bytes,NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
 
     DEBUG("block_size at addr %d is %d\n",addr,block_size);
 
-    if (addrshift == 1) {
-      if (stk500v2_is_page_empty(addr, block_size, m->buf)) {
-          continue;
-      }
-    }
-
     memcpy(buf, commandbuf, sizeof(commandbuf));
 
     buf[1] = page_size >> 8;
@@ -1953,46 +1941,36 @@ static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
  * Write pages of flash/EEPROM, PP mode
  */
 static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				int page_size, int n_bytes)
+                                unsigned int page_size,
+                                unsigned int addr, unsigned int n_bytes)
 {
-  return stk500hv_paged_write(pgm, p, m, page_size, n_bytes, PPMODE);
+  return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, PPMODE);
 }
 
 /*
  * Write pages of flash/EEPROM, HVSP mode
  */
 static int stk500hvsp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				  int page_size, int n_bytes)
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes)
 {
-  return stk500hv_paged_write(pgm, p, m, page_size, n_bytes, HVSPMODE);
-}
-
-static int stk500v2_is_page_empty(unsigned int address, int page_size,
-                                const unsigned char *buf)
-{
-    int i;
-    for(i = 0; i < page_size; i++) {
-        if(buf[address + i] != 0xFF) {
-            /* Page is not empty. */
-            return(0);
-        }
-    }
-
-    /* Page is empty. */
-    return(1);
+  return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, HVSPMODE);
 }
 
 static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                             int page_size, int n_bytes)
+                               unsigned int page_size,
+                               unsigned int addr, unsigned int n_bytes)
 {
-  unsigned int addr, block_size, hiaddr, addrshift, use_ext_addr;
+  unsigned int block_size, hiaddr, addrshift, use_ext_addr;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char commandbuf[4];
   unsigned char buf[275];	// max buffer size for stk500v2 at this point
   unsigned char cmds[4];
   int result;
   OPCODE * rop;
 
-  DEBUG("STK500V2: stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+  DEBUG("STK500V2: stk500v2_paged_load(..,%s,%u,%u,%u)\n",
+        m->desc, page_size, addr, n_bytes);
 
   page_size = m->readsize;
 
@@ -2030,11 +2008,9 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   avr_set_bits(rop, cmds);
   commandbuf[3] = cmds[0];
 
-  for (addr=0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes,NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
     DEBUG("block_size at addr %d is %d\n",addr,block_size);
@@ -2077,14 +2053,17 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
  * Read pages of flash/EEPROM, generic HV mode
  */
 static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes,
-			       enum hvmode mode)
+                               unsigned int page_size,
+                               unsigned int addr, unsigned int n_bytes,
+                               enum hvmode mode)
 {
-  unsigned int addr, block_size, hiaddr, addrshift, use_ext_addr;
+  unsigned int block_size, hiaddr, addrshift, use_ext_addr;
+  unsigned int maxaddr = addr + n_bytes;
   unsigned char commandbuf[3], buf[266];
   int result;
 
-  DEBUG("STK500V2: stk500hv_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
+  DEBUG("STK500V2: stk500hv_paged_load(..,%s,%u,%u,%u)\n",
+        m->desc, page_size, addr, n_bytes);
 
   page_size = m->readsize;
 
@@ -2110,11 +2089,9 @@ static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     commandbuf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP;
   }
 
-  for (addr = 0; addr < n_bytes; addr += page_size) {
-    report_progress(addr, n_bytes, NULL);
-
-    if ((n_bytes-addr) < page_size)
-      block_size = n_bytes - addr;
+  for (; addr < maxaddr; addr += page_size) {
+    if ((maxaddr - addr) < page_size)
+      block_size = maxaddr - addr;
     else
       block_size = page_size;
     DEBUG("block_size at addr %d is %d\n",addr,block_size);
@@ -2156,18 +2133,20 @@ static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
  * Read pages of flash/EEPROM, PP mode
  */
 static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+                               unsigned int page_size,
+                               unsigned int addr, unsigned int n_bytes)
 {
-  return stk500hv_paged_load(pgm, p, m, page_size, n_bytes, PPMODE);
+  return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, PPMODE);
 }
 
 /*
  * Read pages of flash/EEPROM, HVSP mode
  */
 static int stk500hvsp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-				 int page_size, int n_bytes)
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes)
 {
-  return stk500hv_paged_load(pgm, p, m, page_size, n_bytes, HVSPMODE);
+  return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, HVSPMODE);
 }
 
 
@@ -3305,10 +3284,10 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 
 
 static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
-				   int page_size, int n_bytes)
+                                   unsigned int page_size,
+                                   unsigned int addr, unsigned int n_bytes)
 {
     unsigned char *b;
-    unsigned int addr;
     unsigned int offset;
     unsigned char memtype;
     int n_bytes_orig = n_bytes;
@@ -3358,7 +3337,6 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 
     offset = 0;
     while (n_bytes != 0) {
-	report_progress(offset, n_bytes_orig, NULL);
 	b[0] = XPRG_CMD_READ_MEM;
 	b[1] = memtype;
 	b[2] = addr >> 24;
@@ -3387,10 +3365,10 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
-				    int page_size, int n_bytes)
+                                    unsigned int page_size,
+                                    unsigned int addr, unsigned int n_bytes)
 {
     unsigned char *b;
-    unsigned int addr;
     unsigned int offset;
     unsigned char memtype;
     int n_bytes_orig = n_bytes;
@@ -3435,7 +3413,7 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                 progname, mem->desc);
         return -1;
     }
-    addr = mem->offset;
+    addr += mem->offset;
 
     if ((b = malloc(page_size + 9)) == NULL) {
 	fprintf(stderr,
@@ -3449,8 +3427,6 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 
     offset = 0;
     while (n_bytes != 0) {
-	report_progress(offset, n_bytes_orig, NULL);
-
 	if (page_size > 256) {
 	    /*
 	     * AVR079 is not quite clear.  While it suggests that
diff --git a/update.c b/update.c
index 4350eb8c..ef8de509 100644
--- a/update.c
+++ b/update.c
@@ -200,8 +200,7 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
   return u;
 }
 
-int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
-          int verify)
+int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite)
 {
   struct avrpart * v;
   AVRMEM * mem;
@@ -307,8 +306,6 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
      */
     pgm->vfy_led(pgm, ON);
 
-    v = avr_dup_part(p);
-
     if (quell_progress < 2) {
       fprintf(stderr, "%s: verifying %s memory against %s:\n",
             progname, mem->desc, upd->filename);
@@ -323,6 +320,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
               progname, upd->filename);
       return -1;
     }
+    v = avr_dup_part(p);
     size = rc;
     if (quell_progress < 2) {
       fprintf(stderr, "%s: input file %s contains %d bytes\n",
@@ -332,7 +330,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
     }
 
     report_progress (0,1,"Reading");
-    rc = avr_read(pgm, v, upd->memtype, size, 1);
+    rc = avr_read(pgm, p, upd->memtype, v, 1);
     if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
               progname, mem->desc, rc);
diff --git a/update.h b/update.h
index 32e445d4..dde48b9a 100644
--- a/update.h
+++ b/update.h
@@ -46,7 +46,7 @@ extern UPDATE * dup_update(UPDATE * upd);
 extern UPDATE * new_update(int op, char * memtype, int filefmt,
 			   char * filename);
 extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
-		 int nowrite, int verify);
+		 int nowrite);
 
 #ifdef __cplusplus
 }
diff --git a/usbasp.c b/usbasp.c
index e85d0a9f..30c33f88 100644
--- a/usbasp.c
+++ b/usbasp.c
@@ -145,16 +145,24 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p);
 static int usbasp_spi_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res[4]);
 static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p);
 static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes);
-static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes);
+static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes);
+static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes);
 static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
 // TPI specific functions
 static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b);
 static int usbasp_tpi_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res[4]);
 static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
 static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
-static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes);
-static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes);
+static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes);
+static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes);
 static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
 static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value);
 static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data);
@@ -597,11 +605,11 @@ static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 }
 
 static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                             int page_size, int n_bytes)
+                                 unsigned int page_size,
+                                 unsigned int address, unsigned int n_bytes)
 {
   int n;
   unsigned char cmd[4];
-  int address = 0;
   int wbytes = n_bytes;
   int blocksize;
   unsigned char * buffer = m->buf;
@@ -655,19 +663,17 @@ static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
     buffer += blocksize;
     address += blocksize;
-
-    report_progress (address, n_bytes, NULL);
   }
 
   return n_bytes;
 }
 
 static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-                              int page_size, int n_bytes)
+                                  unsigned int page_size,
+                                  unsigned int address, unsigned int n_bytes)
 {
   int n;
   unsigned char cmd[4];
-  int address = 0;
   int wbytes = n_bytes;
   int blocksize;
   unsigned char * buffer = m->buf;
@@ -728,8 +734,6 @@ static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
     buffer += blocksize;
     address += blocksize;
-
-    report_progress (address, n_bytes, NULL);
   }
 
   return n_bytes;
@@ -926,7 +930,9 @@ static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
   return 0;
 }
 
-static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes)
+static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                 unsigned int page_size,
+                                 unsigned int addr, unsigned int n_bytes)
 {
   unsigned char cmd[4];
   unsigned char* dptr;
@@ -935,7 +941,7 @@ static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int
 
 
   dptr = m->buf;
-  pr = m->offset;
+  pr = addr + m->offset;
   readed = 0;
 
   while(readed < n_bytes)
@@ -959,14 +965,14 @@ static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int
     readed += clen;
     pr += clen;
     dptr += clen;
-
-    report_progress(readed, n_bytes, NULL);
   }
 
   return n_bytes;
 }
 
-static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int page_size, int n_bytes)
+static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+                                  unsigned int page_size,
+                                  unsigned int addr, unsigned int n_bytes)
 {
   unsigned char cmd[4];
   unsigned char dummy[8];
@@ -976,7 +982,7 @@ static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int
 
 
   sptr = m->buf;
-  pr = m->offset;
+  pr = addr + m->offset;
   writed = 0;
 
   /* Set PR to flash */
@@ -1015,8 +1021,6 @@ static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int
     writed += clen;
     pr += clen;
     sptr += clen;
-
-    report_progress(writed, n_bytes, NULL);
   }
   
   /* finishing write */
diff --git a/usbtiny.c b/usbtiny.c
index 56467577..afc7fe29 100644
--- a/usbtiny.c
+++ b/usbtiny.c
@@ -423,9 +423,10 @@ static void usbtiny_disable ( PROGRAMMER* pgm ) {}
  *  per byte
 */
 static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
-				    int page_size, int n_bytes )
+                               unsigned int page_size,
+                               unsigned int i, unsigned int n_bytes)
 {
-  int i;
+  unsigned int maxaddr = i + n_bytes;
   int chunk;
   int function;
 
@@ -437,7 +438,7 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
     function = USBTINY_EEPROM_READ;
   }
 
-  for (i = 0; i < n_bytes; i += chunk) {
+  for (; i < maxaddr; i += chunk) {
     chunk = PDATA(pgm)->chunk_size;         // start with the maximum chunk size possible
 
     // If we want to xmit less than a chunk, thats OK
@@ -457,9 +458,6 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
                               // usb_in() multiplies this per byte.
       return -1;
     }
-
-    // Tell avrdude how we're doing to provide user feedback
-    report_progress(i + chunk, n_bytes, NULL );
   }
 
   check_retries(pgm, "read");
@@ -472,9 +470,10 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
  *  per byte.
 */
 static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
-			       int page_size, int n_bytes)
+                               unsigned int page_size,
+                               unsigned int i, unsigned int n_bytes)
 {
-  int i;
+  unsigned int maxaddr = i + n_bytes;
   int chunk;        // Size of data to write at once
   int next;
   int function;     // which SPI command to use
@@ -496,7 +495,7 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     delay = m->max_write_delay;
   }
 
-  for (i=0; i < n_bytes; i=next) {
+  for (; i < maxaddr; i=next) {
     // start with the max chunk size
     chunk = PDATA(pgm)->chunk_size;
 
@@ -527,8 +526,6 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       // If we're at a page boundary, send the SPI command to flush it.
       avr_write_page(pgm, p, m, (unsigned long) i);
     }
-
-    report_progress( next, n_bytes, NULL );
   }
   return n_bytes;
 }