diff --git a/avr.c b/avr.c
index 06cffe4c..b52222ae 100644
--- a/avr.c
+++ b/avr.c
@@ -186,7 +186,7 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p,
       fprintf(stderr, 
               "%s: avr_read_byte(); internal error: invalid memtype=%d\n",
               progname, memtype);
-      exit(1);
+      return -1;
       break;
   }
 
@@ -201,8 +201,10 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p,
 
 
 /*
- * read the entirety of the specified memory type into the
- * corresponding buffer of the avrpart pointed to by 'p'.  
+ * Read the entirety of the specified memory type into the
+ * corresponding buffer of the avrpart pointed to by 'p'.
+ *
+ * Return the number of bytes read, or -1 if an error occurs.  
  */
 int avr_read ( int fd, struct avrpart * p, AVRMEM memtype )
 {
@@ -231,7 +233,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype )
     default:
       fprintf(stderr, "%s: avr_read(); internal error: invalid memtype=%d\n",
               progname, memtype);
-      exit(1);
+      return -1;
       break;
   }
 
@@ -259,7 +261,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype )
 
   fprintf ( stderr, "\n" );
 
-  return 0;
+  return bi;
 }
 
 
@@ -298,7 +300,7 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype,
       fprintf(stderr,
               "%s: avr_write_byte(); internal error: invalid memtype=%d\n",
               progname, memtype);
-      exit(1);
+      return -1;
       break;
   }
 
@@ -345,11 +347,13 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype,
 /*
  * Write the whole memory region (flash or eeprom, specified by
  * 'memtype') from the corresponding buffer of the avrpart pointed to
- * by 'p'.  All of the memory is updated, however, input data of 0xff
- * is not actually written out, because empty flash and eeprom
- * contains 0xff, and you can't actually write 1's, only 0's.
+ * 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.
+ *
+ * Return the number of bytes written, or -1 if an error occurs.
  */
-int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
+int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size )
 {
   unsigned char data, memt;
   unsigned short start, end, i, bi;
@@ -357,6 +361,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
   int rc;
   unsigned char * buf;
   int bufsize;
+  int wsize;
 
   start = 0;
 
@@ -364,22 +369,39 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
     case AVR_FLASH  : 
       buf     = p->flash;
       bufsize = p->flash_size;
+      wsize   = bufsize;
+      if (size < wsize) {
+        bufsize = size;
+      }
       end     = start+bufsize/2;
       memt    = AVR_FLASH_LO;
       break;
     case AVR_EEPROM : 
       buf     = p->eeprom;
       bufsize = p->eeprom_size;
+      wsize   = bufsize;
+      if (size < wsize) {
+        bufsize = size;
+      }
       end     = start+bufsize;
       memt    = memtype;
       break;
     default:
       fprintf(stderr, "%s: avr_write(); internal error: invalid memtype=%d\n",
               progname, memtype);
-      exit(1);
+      return -1;
       break;
   }
 
+  /* were we asked to write out more data than the device can hold? */
+  if (wsize < size) {
+    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, bufsize,
+            progbuf, bufsize);
+  }
+
   bi = 0;
 
   for (i=start; i<end; i++) {
@@ -392,7 +414,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
       fprintf(stderr, " ***failed;  ");
       nl = 1;
     }
-    
+
     if (memtype == AVR_FLASH) {
       /* high byte of flash */
       data = buf[bi++];
@@ -409,7 +431,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
 
   fprintf ( stderr, "\n" );
 
-  return 0;
+  return bi;
 }
 
 
@@ -552,37 +574,41 @@ int avr_initmem ( struct avrpart * p )
   if (p->flash == NULL) {
     fprintf(stderr, "%s: can't alloc buffer for flash size of %d bytes\n",
             progname, p->flash_size);
-    exit(1);
+    return -1;
   }
 
   p->eeprom = (unsigned char *) malloc(p->eeprom_size);
   if (p->eeprom == NULL) {
     fprintf(stderr, "%s: can't alloc buffer for eeprom size of %d bytes\n",
             progname, p->eeprom_size);
-    exit(1);
+    return -1;
   }
 
   return 0;
 }
 
 
-int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype)
+/*
+ * Verify up to 'size' bytes of p against v.  Return the number of
+ * bytes verified, or -1 if they don't match.  
+ */
+int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype, int size)
 {
   int i;
   unsigned char * buf1, * buf2;
-  int size;
+  int vsize;
 
   switch (memtype) {
     case AVR_FLASH:
       buf1 = p->flash;
       buf2 = v->flash;
-      size = p->flash_size;
+      vsize = p->flash_size;
       break;
 
     case AVR_EEPROM:
       buf1 = p->eeprom;
       buf2 = v->eeprom;
-      size = p->eeprom_size;
+      vsize = p->eeprom_size;
       break;
 
     default:
@@ -591,6 +617,17 @@ int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype)
       return -1;
   }
 
+  if (vsize < size) {
+    fprintf(stderr, 
+            "%s: WARNING: requested verification for %d bytes\n"
+            "%s%s memory region only contains %d bytes\n"
+            "%sOnly %d bytes will be verified.\n",
+            progname, size,
+            progbuf, avr_memtstr(memtype), vsize,
+            progbuf, vsize);
+    size = vsize;
+  }
+
   for (i=0; i<size; i++) {
     if (buf1[i] != buf2[i]) {
       fprintf(stderr, 
@@ -602,7 +639,7 @@ int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype)
     }
   }
 
-  return 0;
+  return size;
 }
 
 
diff --git a/avr.h b/avr.h
index a0f06eb1..160b3301 100644
--- a/avr.h
+++ b/avr.h
@@ -90,7 +90,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype );
 int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype, 
                      unsigned short addr, unsigned char data );
 
-int avr_write ( int fd, struct avrpart * p, AVRMEM memtype );
+int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size );
 
 int avr_program_enable ( int fd );
 
@@ -108,7 +108,8 @@ char * avr_memtstr ( AVRMEM memtype );
 
 int avr_initmem ( struct avrpart * p );
 
-int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype);
+int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype, 
+               int size);
 
 void avr_display ( FILE * f, struct avrpart * p, char * prefix );
 
diff --git a/fileio.c b/fileio.c
index 79db1f05..2386003c 100644
--- a/fileio.c
+++ b/fileio.c
@@ -81,7 +81,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
 {
   unsigned char * buf;
   unsigned int nextaddr;
-  int n;
+  int n, nbytes;
   int i;
   unsigned char cksum;
 
@@ -92,8 +92,9 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
   }
 
   nextaddr = startaddr;
+  buf      = inbuf;
+  nbytes   = 0;
 
-  buf = inbuf;
   while (bufsize) {
     n = recsize;
     if (n > bufsize)
@@ -111,6 +112,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
       fprintf ( outf, "%02X\n", cksum );
       
       nextaddr += n;
+      nbytes   += n;
     }
 
     /* advance to next 'recsize' bytes */
@@ -129,7 +131,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
   cksum = -cksum;
   fprintf ( outf, "%02X\n", cksum );
 
-  return 0;
+  return nbytes;
 }
 
 
@@ -138,16 +140,16 @@ int ihex2b ( char * infile, FILE * inf,
 {
   unsigned char buffer [ MAX_LINE_LEN ];
   unsigned char * buf;
-  unsigned int prevaddr, nextaddr;
+  unsigned int nextaddr;
   unsigned int b;
-  int n;
+  int n, nbytes;
   int i, j;
   unsigned int cksum, rectype;
   int lineno;
 
   lineno   = 0;
-  prevaddr = 0;
   buf      = outbuf;
+  nbytes   = 0;
 
   while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
     lineno++;
@@ -194,6 +196,8 @@ int ihex2b ( char * infile, FILE * inf,
       cksum += b;
     }
 
+    nbytes += n;
+
     /*-----------------------------------------------------------------
       read the cksum value from the record and compare it with our
       computed value
@@ -221,13 +225,12 @@ int ihex2b ( char * infile, FILE * inf,
 
     if (rectype == 1) {
       /* end of record */
-      return 0;
+      return nbytes;
     }
 
-    prevaddr = nextaddr + n;
-  }
+  } /* while */
 
-  return 0;
+  return nbytes;
 }
 
 
@@ -250,7 +253,7 @@ int fileio_rbin ( struct fioparms * fio,
       return -1;
   }
 
-  if (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", 
             progname, fio->iodesc, fio->dir, filename, strerror(errno),
@@ -270,14 +273,14 @@ int fileio_ihex ( struct fioparms * fio,
   switch (fio->op) {
     case FIO_WRITE:
       rc = b2ihex(buf, size, 32, 0, filename, f);
-      if (rc) {
+      if (rc < 0) {
         return -1;
       }
       break;
 
     case FIO_READ:
       rc = ihex2b(filename, f, buf, size);
-      if (rc)
+      if (rc < 0)
         return -1;
       break;
 
@@ -288,7 +291,7 @@ int fileio_ihex ( struct fioparms * fio,
       break;
   }
 
-  return 0;
+  return rc;
 }
 
 
@@ -397,13 +400,12 @@ int fmt_autodetect ( char * fname )
 
 
 int fileio ( int op, char * filename, FILEFMT format, 
-             struct avrpart * p, AVRMEM memtype )
+             struct avrpart * p, AVRMEM memtype, int size )
 {
   int rc;
   FILE * f;
   char * fname;
   unsigned char * buf;
-  int size;
   struct fioparms fio;
   int i;
 
@@ -434,12 +436,14 @@ int fileio ( int op, char * filename, FILEFMT format,
   switch (memtype) {
     case AVR_EEPROM:
       buf = p->eeprom;
-      size = p->eeprom_size;
+      if (fio.op == FIO_READ)
+        size = p->eeprom_size;
       break;
 
     case AVR_FLASH:
       buf = p->flash;
-      size = p->flash_size;
+      if (fio.op == FIO_READ)
+        size = p->flash_size;
       break;
       
     default:
diff --git a/fileio.h b/fileio.h
index 4cf5ef2c..87477bc0 100644
--- a/fileio.h
+++ b/fileio.h
@@ -59,6 +59,6 @@ char * fmtstr ( FILEFMT format );
 int fileio_setparms ( int op, struct fioparms * fp );
 
 int fileio ( int op, char * filename, FILEFMT format, 
-             struct avrpart * p, AVRMEM memtype );
+             struct avrpart * p, AVRMEM memtype, int size );
 
 #endif
diff --git a/main.c b/main.c
index f3fb7d96..7ad73eff 100644
--- a/main.c
+++ b/main.c
@@ -83,7 +83,7 @@ void usage ( void )
 {
   fprintf(stderr,
           "\nUsage: %s -p partno [-e] [-E exitspec[,exitspec]] [-f format] [-F]\n"
-          "     %s[-i filename] [-m memtype] [-o filename] [-P parallel] [-t]\n\n",
+          "      %s[-i filename] [-m memtype] [-o filename] [-P parallel] [-t]\n\n",
           progname, progbuf);
 
 #if 0
@@ -143,6 +143,7 @@ int main ( int argc, char * argv [] )
   struct avrpart * v, ap2;      /* used for verify */
   int              readorwrite; /* true if a chip read/write op was selected */
   int              ppidata;	/* cached value of the ppi data register */
+  int              vsize=-1;    /* number of bytes to verify */
 
   /* options / operating mode variables */
   int     memtype;     /* AVR_FLASH or AVR_EEPROM */
@@ -463,16 +464,17 @@ int main ( int argc, char * argv [] )
     fprintf(stderr, "%s: reading %s memory:\n", 
             progname, avr_memtstr(memtype));
     rc = avr_read ( fd, p, memtype );
-    if (rc) {
+    if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", 
               progname, avr_memtstr(memtype), rc);
       exitrc = 1;
       goto main_exit;
     }
+    size = rc;
 
     fprintf(stderr, "%s: writing output file \"%s\"\n",
             progname, outputf);
-    rc = fileio(FIO_WRITE, outputf, filefmt, p, memtype);
+    rc = fileio(FIO_WRITE, outputf, filefmt, p, memtype, size);
     if (rc < 0) {
       fprintf(stderr, "%s: terminating\n", progname);
       exitrc = 1;
@@ -487,7 +489,7 @@ int main ( int argc, char * argv [] )
      */
     fprintf(stderr, "%s: reading input file \"%s\"\n",
             progname, inputf);
-    rc = fileio(FIO_READ, inputf, filefmt, p, memtype );
+    rc = fileio(FIO_READ, inputf, filefmt, p, memtype, -1);
     if (rc < 0) {
       fprintf(stderr, "%s: terminating\n", progname);
       exitrc = 1;
@@ -502,23 +504,28 @@ int main ( int argc, char * argv [] )
             progname, avr_memtstr(memtype));
 
     if (!nowrite) {
-      rc = avr_write ( fd, p, memtype );
+      rc = avr_write ( fd, p, memtype, size );
     }
     else {
       /* 
        * 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, memtype);
+      rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype, size);
     }
 
-    if (rc) {
+    if (rc < 0) {
       fprintf ( stderr, "%s: failed to write flash memory, rc=%d\n", 
                 progname, rc );
       exitrc = 1;
       goto main_exit;
     }
 
+    vsize = rc;
+
+    fprintf(stderr, "%s: %d bytes of %s written\n", progname, 
+            vsize, avr_memtstr(memtype));
+
   }
 
   if (!doread && verify) {
@@ -531,23 +538,24 @@ int main ( int argc, char * argv [] )
     fprintf(stderr, "%s: reading on-chip %s data:\n", 
             progname, avr_memtstr(memtype));
     rc = avr_read ( fd, v, memtype );
-    if (rc) {
+    if (rc < 0) {
       fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", 
               progname, avr_memtstr(memtype), rc);
       exitrc = 1;
       goto main_exit;
     }
-    
-    fprintf(stderr, "%s: verifying\n", progname);
-    rc = avr_verify(p, v, memtype);
-    if (rc) {
+
+    fprintf(stderr, "%s: verifying ...\n", progname);
+    rc = avr_verify(p, v, memtype, vsize);
+    if (rc < 0) {
       fprintf(stderr, "%s: verification error; content mismatch\n", 
               progname);
       exitrc = 1;
       goto main_exit;
     }
     
-    fprintf(stderr, "%s: data verified\n", progname);
+    fprintf(stderr, "%s: %d bytes of %s verified\n", 
+            progname, rc, avr_memtstr(memtype));
   }