diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index c5ea0b7f..1544e00c 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,12 @@
+2003-03-23  Theodore A. Roth  <troth@openavr.org>
+
+	* avr.c: Add avr_read_byte_default().
+	Have avr_read_byte() call pgm->read_byte() or avr_read_byte_default().
+	Add avr_write_byte_default().
+	Have avr_write_byte() call pgm->write_byte or avr_write_byte_default().
+	* pgm.c: Initialize pgm->write_byte and pgm->read_byte.
+	* pgm.h: Add write_byte and read_byte fields to struct programmer_t.
+
 2003-03-17  Theodore A. Roth  <troth@openavr.org>
 
 	* avrdude.conf.in: Fix typo for devicecode deprecation comment.
diff --git a/avrdude/avr.c b/avrdude/avr.c
index af5bc0f4..8d7e8742 100644
--- a/avrdude/avr.c
+++ b/avrdude/avr.c
@@ -287,11 +287,8 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
 }
 
 
-/*
- * read a byte of data from the indicated memory region
- */
-int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
-                  unsigned long addr, unsigned char * value)
+int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
+                          unsigned long addr, unsigned char * value)
 {
   unsigned char cmd[4];
   unsigned char res[4];
@@ -340,6 +337,21 @@ int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
+/*
+ * read a byte of data from the indicated memory region
+ */
+int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, 
+                  unsigned long addr, unsigned char * value)
+{
+  if (pgm->read_byte) {
+    return pgm->read_byte(pgm, p, mem, addr, value);
+  }
+  else {
+    return avr_read_byte_default(pgm, p, mem, addr, value);
+  }
+}
+
+
 /*
  * Read the entirety of the specified memory type into the
  * corresponding buffer of the avrpart pointed to by 'p'.  If size =
@@ -465,10 +477,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
-/*
- * write a byte of data at the specified address
- */
-int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                    unsigned long addr, unsigned char data)
 {
   unsigned char cmd[4];
@@ -653,6 +662,21 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 }
 
 
+/*
+ * write a byte of data at the specified address
+ */
+int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+                   unsigned long addr, unsigned char data)
+{
+  if (pgm->write_byte) {
+    return pgm->write_byte(pgm, p, mem, addr, data);
+  }
+  else {
+    return avr_write_byte_default(pgm, p, mem, addr, data);
+  }
+}
+
+
 /*
  * Write the whole memory region of the specified memory from the
  * corresponding buffer of the avrpart pointed to by 'p'.  Write up to
diff --git a/avrdude/pgm.c b/avrdude/pgm.c
index c369cead..64bf561d 100644
--- a/avrdude/pgm.c
+++ b/avrdude/pgm.c
@@ -89,6 +89,8 @@ PROGRAMMER * pgm_new(void)
    */
   pgm->paged_write    = NULL;
   pgm->paged_load     = NULL;
+  pgm->write_byte     = NULL;
+  pgm->read_byte      = NULL;
   pgm->read_sig_bytes = NULL;
 
   return pgm;
diff --git a/avrdude/pgm.h b/avrdude/pgm.h
index f18a8ff2..e8fe6a32 100644
--- a/avrdude/pgm.h
+++ b/avrdude/pgm.h
@@ -66,6 +66,10 @@ typedef struct programmer_t {
                           int page_size, int n_bytes);
   int  (*paged_load)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
                           int page_size, int n_bytes);
+  int  (*write_byte)     (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+                          unsigned long addr, unsigned char value);
+  int  (*read_byte)      (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+                          unsigned long addr, unsigned char * value);
   int  (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
   char config_file[PATH_MAX]; /* config file where defined */
   int  lineno;                /* config file line number */