Index: config_gram.y
===================================================================
--- config_gram.y	(revision 1018)
+++ config_gram.y	(working copy)
@@ -127,6 +127,7 @@
 %token K_PAGEL
 %token K_PAR
 %token K_PARALLEL
+%token K_PARENT
 %token K_PART
 %token K_PGMLED
 %token K_PROGRAMMER
@@ -311,13 +312,7 @@
 
 
 part_def :
-  K_PART
-    {
-      current_part = avr_new_part();
-      strcpy(current_part->config_file, infile);
-      current_part->lineno = lineno;
-    }
-    part_parms 
+  part_decl part_parms 
     { 
       LNODEID ln;
       AVRMEM * m;
@@ -371,7 +366,31 @@
     }
 ;
 
+part_decl :
+  K_PART
+    {
+      current_part = avr_new_part();
+      strcpy(current_part->config_file, infile);
+      current_part->lineno = lineno;
+    } |
+  K_PART K_PARENT TKN_STRING 
+    {
+      AVRPART * parent_part = locate_part(part_list, $3->value.string);
+      if (parent_part == NULL) {
+        fprintf(stderr, 
+              "%s: error at %s:%d: can't find parent part",
+              progname, infile, lineno);
+        exit(1);
+      }
 
+      current_part = avr_dup_part(parent_part);
+      strcpy(current_part->config_file, infile);
+      current_part->lineno = lineno;
+
+      free_token($3);
+    }
+;
+
 string_list :
   TKN_STRING { ladd(string_list, $1); } |
   string_list TKN_COMMA TKN_STRING { ladd(string_list, $3); }
@@ -789,19 +808,11 @@
       unsigned nbytes;
       int ok;
 
-      if (current_part->ctl_stack_type != CTL_STACK_NONE)
-	{
-	  fprintf(stderr,
-		  "%s: error at line %d of %s: "
-		  "control stack already defined\n",
-		  progname, lineno, infile);
-	  exit(1);
-	}
-
       current_part->ctl_stack_type = CTL_STACK_PP;
       nbytes = 0;
       ok = 1;
 
+      memset(current_part->controlstack, 0, CTL_STACK_SIZE);
       while (lsize(number_list)) {
         t = lrmv_n(number_list, 1);
 	if (nbytes < CTL_STACK_SIZE)
@@ -831,19 +842,11 @@
       unsigned nbytes;
       int ok;
 
-      if (current_part->ctl_stack_type != CTL_STACK_NONE)
-	{
-	  fprintf(stderr,
-		  "%s: error at line %d of %s: "
-		  "control stack already defined\n",
-		  progname, lineno, infile);
-	  exit(1);
-	}
-
       current_part->ctl_stack_type = CTL_STACK_HVSP;
       nbytes = 0;
       ok = 1;
 
+      memset(current_part->controlstack, 0, CTL_STACK_SIZE);
       while (lsize(number_list)) {
         t = lrmv_n(number_list, 1);
 	if (nbytes < CTL_STACK_SIZE)
@@ -876,6 +879,7 @@
       nbytes = 0;
       ok = 1;
 
+      memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
       while (lsize(number_list)) {
         t = lrmv_n(number_list, 1);
 	if (nbytes < FLASH_INSTR_SIZE)
@@ -908,6 +912,7 @@
       nbytes = 0;
       ok = 1;
 
+      memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
       while (lsize(number_list)) {
         t = lrmv_n(number_list, 1);
 	if (nbytes < EEPROM_INSTR_SIZE)
Index: avrdude.conf.in
===================================================================
--- avrdude.conf.in	(revision 1018)
+++ avrdude.conf.in	(working copy)
@@ -137,6 +137,17 @@
 # values.  If a required parameter is left empty, AVRDUDE will
 # complain.
 #
+# Parts can also inherit parameters from previously defined parts
+# using the following syntax. In this case specified integer and 
+# string values override parameter values from the parent part. New 
+# memory definitions are added to the definitions inherited from the 
+# parent.
+#
+#   part parent <id>                              # quoted string
+#       id               = <id> ;                 # quoted string
+#       <any set of other parameters from the list above>
+#     ;
+#
 # NOTES:
 #   * 'devicecode' is the device code used by the STK500 (see codes 
 #       listed below)
@@ -9232,12 +9243,12 @@
   ;
 
 #------------------------------------------------------------
-# ATmega328P
+# ATmega328
 #------------------------------------------------------------
 
 part
-    id			= "m328p";
-    desc		= "ATMEGA328P";
+    id			= "m328";
+    desc		= "ATMEGA328";
     has_debugwire	= yes;
     flash_instr		= 0xB6, 0x01, 0x11;
     eeprom_instr	= 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
@@ -9245,7 +9256,7 @@
 			  0x99, 0xF9, 0xBB, 0xAF;
     stk500_devcode	= 0x86;
     # avr910_devcode	= 0x;
-    signature		= 0x1e 0x95 0x0F;
+    signature		= 0x1e 0x95 0x14;
     pagel		= 0xd7;
     bs2			= 0xc2;
     chip_erase_delay	= 9000;
@@ -9419,6 +9430,12 @@
     ;
 ;
 
+part parent "m328"
+    id			= "m328p";
+    desc		= "ATMEGA328P";
+    signature		= 0x1e 0x95 0x0F;
+;
+
 #------------------------------------------------------------
 # ATtiny2313
 #------------------------------------------------------------
Index: avrpart.c
===================================================================
--- avrpart.c	(revision 1018)
+++ avrpart.c	(working copy)
@@ -253,23 +253,27 @@
 
   *n = *m;
 
-  n->buf = (unsigned char *)malloc(n->size);
-  if (n->buf == NULL) {
-    fprintf(stderr,
-            "avr_dup_mem(): out of memory (memsize=%d)\n",
-            n->size);
-    exit(1);
+  if (m->buf != NULL) {
+    n->buf = (unsigned char *)malloc(n->size);
+    if (n->buf == NULL) {
+      fprintf(stderr,
+              "avr_dup_mem(): out of memory (memsize=%d)\n",
+              n->size);
+      exit(1);
+    }
+    memcpy(n->buf, m->buf, n->size);
   }
-  memcpy(n->buf, m->buf, n->size);
 
-  n->tags = (unsigned char *)malloc(n->size);
-  if (n->tags == NULL) {
-    fprintf(stderr,
-            "avr_dup_mem(): out of memory (memsize=%d)\n",
-            n->size);
-    exit(1);
+  if (m->tags != NULL) {
+    n->tags = (unsigned char *)malloc(n->size);
+    if (n->tags == NULL) {
+      fprintf(stderr,
+              "avr_dup_mem(): out of memory (memsize=%d)\n",
+              n->size);
+      exit(1);
+    }
+    memcpy(n->tags, m->tags, n->size);
   }
-  memcpy(n->tags, m->tags, n->size);
 
   return n;
 }
Index: lexer.l
===================================================================
--- lexer.l	(revision 1018)
+++ lexer.l	(working copy)
@@ -177,6 +177,7 @@
 pagel            { yylval=NULL; return K_PAGEL; }
 par              { yylval=NULL; return K_PAR; }
 parallel         { yylval=NULL; return K_PARALLEL; }
+parent           { yylval=NULL; return K_PARENT; }
 part             { yylval=NULL; return K_PART; }
 pgmled           { yylval=NULL; return K_PGMLED; }
 programmer       { yylval=NULL; return K_PROGRAMMER; }
