diff --git a/ChangeLog b/ChangeLog
index ebe09c6b..b8b89813 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,21 @@
-2003/11/14  Brian S. Dean  <bsd@bsdhome.com>
+2003-11-19  Theodore A. Roth  <troth@openavr.org>
+[Contributed by Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>]
 
-        * avrdude.conf.in:
-          Add ATmega64 part.
-          
-          Contributed by Erik Christiansen <erik@dd.nec.com.au>
+	* avr.c (avr_write_byte_default): Improve polling algorithm to speed up
+	programming of byte oriented parallel programmers.
 
-2003/11/08  Joerg Wunsch  <j@uriah.heep.sax.de>
+2003-11-14  Brian S. Dean  <bsd@bsdhome.com>
+[Contributed by Erik Christiansen <erik@dd.nec.com.au>]
 
-        * avrdude.conf.in:
-          Add "fuse" and "lock" definitions for the AT90S8535.  Actually,
-	  this is stolen from the AT90S8515 since the datasheet says it's
-	  the same there.
+	* avrdude.conf.in:
+	Add ATmega64 part.
+
+2003-11-08  Joerg Wunsch  <j@uriah.heep.sax.de>
+
+	* avrdude.conf.in:
+	Add "fuse" and "lock" definitions for the AT90S8535.  Actually,
+	this is stolen from the AT90S8515 since the datasheet says it's
+	the same there.
 
 2003-10-13  Bill Somerville  <bill@classdesign.com>
 
@@ -19,11 +24,11 @@
 	(stk500_paged_write): Send whole block at once.
 	(stk500_paged_load): Limit blocks read to no bigger than memory
 	device size.
-    [This fixes bug #5713.]
+	[This fixes bug #5713.]
 
 2003-10-13  Eric B. Weddington  <eric@ecentral.com>
 
-	*avrdude.conf.in: Fix for unterminated character error.
+	* avrdude.conf.in: Fix for unterminated character error.
 
 2003-10-13  Eric B. Weddington  <eric@ecentral.com>
 
diff --git a/avr.c b/avr.c
index 819195ed..066f4070 100644
--- a/avr.c
+++ b/avr.c
@@ -25,6 +25,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <sys/time.h>
+#include <time.h>
 
 
 #include "avr.h"
@@ -521,11 +523,14 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   unsigned char r;
   int ready;
   int tries;
+  unsigned long start_time;
+  unsigned long prog_time;
   unsigned char b;
   unsigned short caddr;
   OPCODE * writeop;
   int rc;
   int readok=0;
+  struct timeval tv;
 
   if (!mem->paged) {
     /* 
@@ -615,13 +620,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   tries = 0;
   ready = 0;
   while (!ready) {
-    usleep(mem->min_write_delay);
-    rc = avr_read_byte(pgm, p, mem, addr, &r);
-    if (rc != 0) {
-      pgm->pgm_led(pgm, OFF);
-      pgm->err_led(pgm, ON);
-      return -4;
-    }
 
     if ((data == mem->readback[0]) ||
         (data == mem->readback[1])) {
@@ -639,6 +637,29 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
         return -5;
       }
     }
+    else {
+      gettimeofday (&tv, NULL);
+      start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
+      do {
+        /*
+         * Do polling, but timeout after max_write_delay.
+	 */
+        rc = avr_read_byte(pgm, p, mem, addr, &r);
+        if (rc != 0) {
+          pgm->pgm_led(pgm, OFF);
+          pgm->err_led(pgm, ON);
+          return -4;
+        }
+        gettimeofday (&tv, NULL);
+        prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
+      } while ((r != data) &&
+               ((prog_time-start_time) < mem->max_write_delay));
+    }
+
+    /*
+     * At this point we either have a valid readback or the
+     * max_write_delay is expired.
+     */
     
     if (r == data) {
       ready = 1;
@@ -651,7 +672,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
        * memory bits but not all.  We only actually power-off the
        * device if the data read back does not match what we wrote.
        */
-      usleep(mem->max_write_delay); /* maximum write delay */
       pgm->pgm_led(pgm, OFF);
       fprintf(stderr,
               "%s: this device must be powered off and back on to continue\n",