diff --git a/src/avr.c b/src/avr.c
index 333f531a..dee653c0 100644
--- a/src/avr.c
+++ b/src/avr.c
@@ -1088,8 +1088,7 @@ int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) {
  *
  * Return the number of bytes verified, or -1 if they don't match.
  */
-int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size)
-{
+int avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, const char *memtype, int size) {
   int i;
   unsigned char * buf1, * buf2;
   int vsize;
@@ -1118,14 +1117,34 @@ int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int s
     size = vsize;
   }
 
+  int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size+1: 10;
   for (i=0; i<size; i++) {
     if ((b->tags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) {
       uint8_t bitmask = get_fuse_bitmask(a);
-      if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
+      if(pgm->readonly && pgm->readonly(pgm, p, a, i)) {
+        if(quell_progress < 2) {
+          if(vroerror < 10) {
+            if(!(verror + vroerror))
+              pmsg_warning("verification mismatch%s\n",
+                avr_mem_is_flash_type(a)? " in r/o areas, expected for vectors and/or bootloader": "");
+            imsg_warning("device 0x%02x != input 0x%02x at addr 0x%04x (read only location)\n",
+              buf1[i], buf2[i], i);
+          } else if(vroerror == 10)
+            imsg_warning("suppressing further mismatches in read-only areas\n");
+        }
+        vroerror++;
+      } else if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
         // Mismatch is not just in unused bits
-        pmsg_error("verification mismatch, first encountered at addr 0x%04x\n", i);
-        imsg_error("device 0x%02x != input 0x%02x\n", buf1[i], buf2[i]);
-        return -1;
+        if(verror < maxerrs) {
+          if(!(verror + vroerror))
+            pmsg_warning("verification mismatch\n");
+          imsg_error("device 0x%02x != input 0x%02x at addr 0x%04x (error)\n", buf1[i], buf2[i], i);
+        } else if(verror == maxerrs) {
+          imsg_warning("suppressing further verification errors\n");
+        }
+        verror++;
+        if(verbose < 1)
+          return -1;
       } else {
         // Mismatch is only in unused bits
         if ((buf1[i] | bitmask) != 0xff) {
@@ -1143,7 +1162,7 @@ int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int s
     }
   }
 
-  return size;
+  return verror? -1: size;
 }
 
 
diff --git a/src/libavrdude.h b/src/libavrdude.h
index 9683255b..83556af3 100644
--- a/src/libavrdude.h
+++ b/src/libavrdude.h
@@ -889,7 +889,7 @@ int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, int
 
 int avr_signature(const PROGRAMMER *pgm, const AVRPART *p);
 
-int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size);
+int avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, const char *m, int size);
 
 int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles);
 
diff --git a/src/update.c b/src/update.c
index 48e2b94f..0a7166cd 100644
--- a/src/update.c
+++ b/src/update.c
@@ -616,7 +616,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, UPDATE *upd, enum updateflags
     if (quell_progress < 2)
       pmsg_notice2("verifying ...\n");
 
-    rc = avr_verify(p, v, upd->memtype, size);
+    rc = avr_verify(pgm, p, v, upd->memtype, size);
     if (rc < 0) {
       pmsg_error("verification mismatch\n");
       pgm->err_led(pgm, ON);
diff --git a/src/urclock.c b/src/urclock.c
index d828c24f..b51b8ffa 100644
--- a/src/urclock.c
+++ b/src/urclock.c
@@ -2194,9 +2194,16 @@ static int urclock_readonly(const struct programmer_t *pgm, const AVRPART *p_unu
     if(ur.blstart) {
       if(addr >= (unsigned int) ur.blstart)
         return 1;
-      if(ur.vbllevel)
-       if(addr < (unsigned int) (ur.uP.flashsize <= 8192? 2: 4))
-         return 1;
+      if(addr < 512 && ur.vbllevel) {
+        unsigned int vecsz = ur.uP.flashsize <= 8192? 2u: 4u;
+        if(addr < vecsz)
+          return 1;
+        if(ur.vblvectornum > 0) {
+          unsigned int appvecloc = ur.vblvectornum*vecsz;
+          if(addr >= appvecloc && addr < appvecloc+vecsz)
+            return 1;
+        }
+      }
     }
   } else if(!avr_mem_is_eeprom_type(mem))
     return 1;