diff --git a/avrdude/avr.c b/avrdude/avr.c
index bdff5bfa..9f7fe950 100644
--- a/avrdude/avr.c
+++ b/avrdude/avr.c
@@ -281,7 +281,8 @@ int avr_read(int fd, AVRPART * p, int memtype)
 
   for (i=0; i<size; i++) {
     rbyte = avr_read_byte(fd, p, memtype, i);
-    fprintf(stderr, "                    \r%4lu  0x%02x", i, rbyte);
+    if (i % 1024 == 0)
+      fprintf(stderr, "                    \r%4lu  0x%02x", i, rbyte);
     buf[i] = rbyte;
   }
 
@@ -299,10 +300,26 @@ int avr_write_bank(int fd, AVRPART * p, int memtype,
 {
   unsigned char cmd[4];
   unsigned char res[4];
+  unsigned int shift;
 
   LED_ON(fd, pgm->pinno[PIN_LED_PGM]);
   LED_OFF(fd, pgm->pinno[PIN_LED_ERR]);
 
+  /*
+   * 'bank' indicates which bank is being programmed: 0 for the first
+   * bank_size block, 1 for the second, up to num_banks-1 for the
+   * last.  The MCU actually wants the high-order bits of what would
+   * be the actual address instead, shifted left to the upper most
+   * bits of a 16 bit word.  For a 128K flash, the actual address is a
+   * 17 bits.  To get the right value to send to the MCU, we want to
+   * shift 'bank' left by 16 - the number of bits in the bank
+   * address.
+   */
+  shift = 16 - p->mem[memtype].bankaddrbits;
+  bank = bank << shift;
+
+  fprintf(stderr, "bank address=%u\n", bank);
+
   cmd[0] = 0x4c;
   cmd[1] = bank >> 8;     /* high order bits of address */
   cmd[2] = bank & 0x0ff;  /* low order bits of address  */
@@ -457,7 +474,8 @@ int avr_write(int fd, AVRPART * p, int memtype, int size)
     /* eeprom or low byte of flash */
     data = p->mem[memtype].buf[i];
     rc = avr_write_byte(fd, p, memtype, i, data);
-    fprintf(stderr, "                      \r%4lu 0x%02x", i, data);
+    if (i % 1024 == 0)
+      fprintf(stderr, "                      \r%4lu 0x%02x", i, data);
     if (rc) {
       fprintf(stderr, " ***failed;  ");
       fprintf(stderr, "\n");
diff --git a/avrdude/avr.h b/avrdude/avr.h
index ba488c67..add89a0b 100644
--- a/avrdude/avr.h
+++ b/avrdude/avr.h
@@ -50,6 +50,7 @@ typedef struct avrmem {
   int size;                     /* total memory size in bytes */
   int bank_size;                /* size of memory bank (if bank addressed) */
   int num_banks;                /* number of banks (if bank addressed) */
+  int bankaddrbits;             /* number of bits in the bank address */
   int min_write_delay;          /* microseconds */
   int max_write_delay;          /* microseconds */
   unsigned char readback[2];    /* polled read-back values */
diff --git a/avrdude/avrdude.conf.sample b/avrdude/avrdude.conf.sample
index fa4a2d25..2cbc1014 100644
--- a/avrdude/avrdude.conf.sample
+++ b/avrdude/avrdude.conf.sample
@@ -120,6 +120,7 @@ part
       ;
   ;
 
+
 part
     id               = "2313";
     desc             = "AT90S2313";
@@ -146,7 +147,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "2333";
     desc             = "AT90S2333";
@@ -173,7 +174,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "4433";
     desc             = "AT90S4433";
@@ -200,7 +201,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "4434";
     desc             = "AT90S4434";
@@ -227,7 +228,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "8515";
     desc             = "AT90S8515";
@@ -254,7 +255,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "8535";
     desc             = "AT90S8535";
@@ -281,7 +282,7 @@ part
       ;
   ;
 
-    
+
 part
     id               = "103";
     desc             = "ATMEGA103";
@@ -308,3 +309,30 @@ part
       ;
   ;
 
+
+part
+    id               = "16";
+    desc             = "ATMEGA16";
+    chip_erase_delay = 9000;
+    eeprom
+        banked          = no;
+        size            = 512;
+        bank_size       = 0;
+        num_banks       = 0;
+        min_write_delay = 9000;
+        max_write_delay = 9000;
+        readback_p1     = 0xff;
+        readback_p2     = 0xff;
+      ;
+    flash
+        banked          = yes;
+        size            = 16384;
+        bank_size       = 128;
+        num_banks       = 128;
+        min_write_delay = 4500;
+        max_write_delay = 9000;
+        readback_p1     = 0xff;
+        readback_p2     = 0xff;
+      ;
+  ;
+
diff --git a/avrdude/config_gram.y b/avrdude/config_gram.y
index 050e1fee..d0a1de9a 100644
--- a/avrdude/config_gram.y
+++ b/avrdude/config_gram.y
@@ -101,14 +101,62 @@ prog_def :
 part_def :
   K_PART
     { current_part = avr_new_part(); }
-    part_parms
+    part_parms 
     { 
+      unsigned int i, j, pagebits;
       if (current_part->id[0] == 0) {
         fprintf(stderr,
                 "%s: error at %s:%d: required parameter id not specified\n",
                 progname, infile, lineno);
         exit(1);
       }
+
+      /*
+       * perform some sanity checking
+       */
+      for (i=0; i<AVR_MAXMEMTYPES; i++) {
+        if (current_part->mem[i].banked) {
+          if (!current_part->mem[i].bank_size) {
+            fprintf(stderr, 
+                    "%s: error at %s:%d: must specify bank_size for banked "
+                    "memory\n",
+                    progname, infile, lineno);
+            exit(1);
+          }
+          if (!current_part->mem[i].num_banks) {
+            fprintf(stderr, 
+                    "%s: error at %s:%d: must specify num_banks for banked "
+                    "memory\n",
+                    progname, infile, lineno);
+            exit(1);
+          }
+          if (current_part->mem[i].size != current_part->mem[i].bank_size *
+                                             current_part->mem[i].num_banks) {
+            fprintf(stderr, 
+                    "%s: error at %s:%d: bank size (%u) * num_banks (%u) = "
+                    "%u does not match memory size (%u)\n",
+                    progname, infile, lineno,
+                    current_part->mem[i].bank_size, 
+                    current_part->mem[i].num_banks, 
+                    current_part->mem[i].bank_size * current_part->mem[i].num_banks,
+                    current_part->mem[i].size);
+            exit(1);
+          }
+          pagebits = 0;
+          for (j=0; j<32 && !pagebits; j++) {
+            if ((1 << j) == current_part->mem[i].num_banks)
+              pagebits = j;
+          }
+          if (!pagebits) {
+            fprintf(stderr, 
+                    "%s: error at %s:%d: can't determine the number of bank address bits\n"
+                    "     Are you sure num_banks (=%u) is correct?\n",
+                    progname, infile, lineno, current_part->mem[i].num_banks);
+          }
+          current_part->mem[i].bankaddrbits = pagebits;
+        }
+      }
+
       ladd(part_list, current_part); 
       current_part = NULL; 
     }
diff --git a/avrdude/main.c b/avrdude/main.c
index 520f47d6..7a9e431d 100644
--- a/avrdude/main.c
+++ b/avrdude/main.c
@@ -284,7 +284,7 @@ int read_config(char * file)
   f = fopen(file, "r");
   if (f == NULL) {
     fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
-            progname, infile, strerror(errno));
+            progname, file, strerror(errno));
     return -1;
   }