--- butterfly.c.orig	2008-06-07 23:03:41.000000000 +0200
+++ butterfly.c	2009-03-11 23:19:39.000000000 +0100
@@ -110,8 +110,8 @@
 
   butterfly_recv(pgm, &c, 1);
   if (c != '\r') {
-    fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
-            progname, errmsg);
+    fprintf(stderr, "%s: error: programmer did not respond to command: %s (%x)\n",
+            progname, errmsg, c);
     exit(1);
   }
 }
@@ -268,8 +268,13 @@
 
   /* See if programmer supports autoincrement of address. */
 
-  butterfly_send(pgm, "a", 1);
-  butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
+  if (strcmp(id,"NET-I/O") == 0) {
+    // AVR-NET-I/O does decrement instead of increment!!!
+    PDATA(pgm)->has_auto_incr_addr = '?';
+  } else {
+    butterfly_send(pgm, "a", 1);
+    butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
+  }
   if (PDATA(pgm)->has_auto_incr_addr == 'Y')
       fprintf(stderr, "Programmer supports auto addr increment.\n");
 
@@ -278,18 +283,24 @@
   butterfly_send(pgm, "b", 1);
   butterfly_recv(pgm, &c, 1);
   if (c != 'Y') {
+  #ifdef UNBUFFERED_NOT_ALLOWED
     fprintf(stderr,
             "%s: error: buffered memory access not supported. Maybe it isn't\n"\
             "a butterfly/AVR109 but a AVR910 device?\n", progname);
     exit(1);
+  #endif
+    PDATA(pgm)->buffersize = 0;
+    fprintf(stderr,
+      "Programmer requires unbuffered memory access. So please be patient...\n");
+  } else {
+    butterfly_recv(pgm, &c, 1);
+    PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
+    butterfly_recv(pgm, &c, 1);
+    PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
+    fprintf(stderr,
+      "Programmer supports buffered memory access with buffersize=%i bytes.\n",
+       PDATA(pgm)->buffersize);
   };
-  butterfly_recv(pgm, &c, 1);
-  PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
-  butterfly_recv(pgm, &c, 1);
-  PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
-  fprintf(stderr,
-    "Programmer supports buffered memory access with buffersize=%i bytes.\n",
-     PDATA(pgm)->buffersize);
 
   /* Get list of devices that the programmer supports. */
 
@@ -476,7 +487,11 @@
       butterfly_set_addr(pgm, addr >> 1);
     }
 
-    butterfly_send(pgm, "g\000\002F", 4);
+    if (PDATA(pgm)->buffersize) {
+      butterfly_send(pgm, "g\000\002F", 4);
+    } else {
+      butterfly_send(pgm, "R", 1);
+    }
 
     /* Read back the program mem word (MSB first) */
     butterfly_recv(pgm, buf, sizeof(buf));
@@ -500,7 +515,11 @@
                                    unsigned long addr, unsigned char * value)
 {
   butterfly_set_addr(pgm, addr);
-  butterfly_send(pgm, "g\000\001E", 4);
+  if (PDATA(pgm)->buffersize) {
+    butterfly_send(pgm, "g\000\001E", 4);
+  } else {
+    butterfly_send(pgm, "d", 1);
+  }
   butterfly_recv(pgm, (char *)value, 1);
   return 0;
 }
@@ -545,51 +564,135 @@
 static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
                               int page_size, int n_bytes)
 {
-  unsigned int addr = 0;
+  unsigned int addr = 0, i;
   unsigned int max_addr = n_bytes;
   char *cmd;
   unsigned int blocksize = PDATA(pgm)->buffersize;
+  unsigned char autoinc = PDATA(pgm)->has_auto_incr_addr;
   int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
 
   if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom")) 
     return -2;
 
-  if (m->desc[0] == 'e')
-    blocksize = 1;		/* Write to eeprom single bytes only */
-
-  if (use_ext_addr) {
-    butterfly_set_extaddr(pgm, addr);
+  if (!blocksize) {
+    // emulate paged write!
+    
+    if (m->desc[0] == 'e')
+      blocksize = 1;		/* Write to eeprom single bytes only */
+    else
+      blocksize = m->blocksize;
+  
+    // here we don't care about shr addr for flash/eeprom, as we start at 0
+    if (use_ext_addr) {
+      butterfly_set_extaddr(pgm, addr);
+    } else {
+      butterfly_set_addr(pgm, addr);
+    }
+  
+    cmd = malloc(2);
+    if (!cmd) return -1;
+  
+    while (addr < max_addr) {
+  
+      if ((max_addr - addr) < blocksize) {
+        blocksize = max_addr - addr;
+      };
+  
+      if (m->desc[0] == 'e') {
+        cmd[0] = 'D';
+        cmd[1] = m->buf[addr];
+        butterfly_send(pgm, cmd, 2);
+        butterfly_vfy_cmd_sent(pgm, "write byte");
+        addr++;
+        if (use_ext_addr) {
+          butterfly_set_extaddr(pgm, addr);
+        } else {
+          butterfly_set_addr(pgm, addr);
+        }
+      } else {
+        for(i=0;i<blocksize;i++) {
+          cmd[0] = 'c';
+          cmd[1] = m->buf[addr];
+          butterfly_send(pgm, cmd, 2);
+          butterfly_vfy_cmd_sent(pgm, "write lowbyte");
+          addr++;
+          cmd[0] = 'C';
+          cmd[1] = m->buf[addr];
+          butterfly_send(pgm, cmd, 2);
+          butterfly_vfy_cmd_sent(pgm, "write highbyte");
+          addr++;
+        }
+        if (use_ext_addr) {
+          butterfly_set_extaddr(pgm, (addr-blocksize)>>1);
+        } else {
+          butterfly_set_addr(pgm, (addr-blocksize)>>1);
+        }
+        cmd[0] = 'm';
+        butterfly_send(pgm, cmd, 1);
+        butterfly_vfy_cmd_sent(pgm, "write page");
+        if (use_ext_addr) {
+          butterfly_set_extaddr(pgm, addr>>1);
+        } else {
+          butterfly_set_addr(pgm, addr>>1);
+        }
+      }
+  
+      report_progress (addr, max_addr, NULL);
+    } /* while */
+    free(cmd);
+    
   } else {
-    butterfly_set_addr(pgm, addr);
-  }
 
-#if 0
-  usleep(1000000);
-  butterfly_send(pgm, "y", 1);
-  butterfly_vfy_cmd_sent(pgm, "clear LED");
-#endif
-
-  cmd = malloc(4+blocksize);
-  if (!cmd) return -1;
-  cmd[0] = 'B';
-  cmd[3] = toupper(m->desc[0]);
-
-  while (addr < max_addr) {
-    if ((max_addr - addr) < blocksize) {
-      blocksize = max_addr - addr;
-    };
-    memcpy(&cmd[4], &m->buf[addr], blocksize);
-    cmd[1] = (blocksize >> 8) & 0xff;
-    cmd[2] = blocksize & 0xff;
-
-    butterfly_send(pgm, cmd, 4+blocksize);
-    butterfly_vfy_cmd_sent(pgm, "write block");
-
-    addr += blocksize;
-
-    report_progress (addr, max_addr, NULL);
-  } /* while */
-  free(cmd);
+    if (m->desc[0] == 'e')
+      blocksize = 1;		/* Write to eeprom single bytes only */
+  
+    // here we don't care about shr addr for flash/eeprom, as we start at 0
+    if (use_ext_addr) {
+      butterfly_set_extaddr(pgm, addr);
+    } else {
+      butterfly_set_addr(pgm, addr);
+    }
+  
+    cmd = malloc(4+blocksize);
+    if (!cmd) return -1;
+    cmd[0] = 'B';
+    cmd[3] = toupper(m->desc[0]);
+  
+    while (addr < max_addr) {
+  
+      if ((max_addr - addr) < blocksize) {
+        blocksize = max_addr - addr;
+      };
+  
+      memcpy(&cmd[4], &m->buf[addr], blocksize);
+      cmd[1] = (blocksize >> 8) & 0xff;
+      cmd[2] = blocksize & 0xff;
+  
+      butterfly_send(pgm, cmd, 4+blocksize);
+      butterfly_vfy_cmd_sent(pgm, "write block");
+      addr += blocksize;
+  
+      if (autoinc!='Y') {
+        if (m->desc[0] == 'e') {
+            if (use_ext_addr) {
+              butterfly_set_extaddr(pgm, addr);
+            } else {
+              butterfly_set_addr(pgm, addr);
+            }
+        } else {
+            if (use_ext_addr) {
+              butterfly_set_extaddr(pgm, addr>>1);
+            } else {
+              butterfly_set_addr(pgm, addr>>1);
+            }
+        } 
+      }
+  
+      report_progress (addr, max_addr, NULL);
+    } /* while */
+    free(cmd);
+  
+  }
 
   return addr;
 }
